1#ifndef NEFORCE_CORE_ALGORITHM_SEARCH_HPP__
2#define NEFORCE_CORE_ALGORITHM_SEARCH_HPP__
14NEFORCE_BEGIN_NAMESPACE__
42template <
typename Iterator,
typename T,
typename Compare>
43constexpr Iterator
lower_bound(Iterator first, Iterator last,
const T& value, Compare comp) {
47 Distance len = _NEFORCE
distance(first, last);
54 if (comp(*middle, value)) {
76template <
typename Iterator,
typename T>
77constexpr Iterator
lower_bound(Iterator first, Iterator last,
const T& value) {
95template <
typename Iterator,
typename T,
typename Compare>
96constexpr Iterator
upper_bound(Iterator first, Iterator last,
const T& value, Compare comp) {
100 Distance len = _NEFORCE
distance(first, last);
106 _NEFORCE
advance(middle, half);
107 if (comp(value, *middle)) {
110 len = len - half - 1;
129template <
typename Iterator,
typename T>
130constexpr Iterator
upper_bound(Iterator first, Iterator last,
const T& value) {
143template <
typename Iterator,
typename T>
144constexpr bool binary_search(Iterator first, Iterator last,
const T& value) {
145 Iterator i = _NEFORCE
lower_bound(first, last, value);
146 return i != last && !(value < *i);
160template <
typename Iterator,
typename T,
typename Compare>
161constexpr bool binary_search(Iterator first, Iterator last,
const T& value, Compare comp) {
162 Iterator i = _NEFORCE
lower_bound(first, last, value, comp);
163 return i != last && !comp(value, *i);
178template <
typename Iterator1,
typename Iterator2,
typename Compare>
179constexpr bool includes(Iterator1 first1, Iterator1 last1, Iterator2 first2, Iterator2 last2, Compare comp) {
181 "Iterator must be input_iterator");
183 while (first1 != last1 && first2 != last2) {
184 if (comp(*first2, *first1)) {
188 if (comp(*first1, *first2)) {
194 return first2 == last2;
207template <
typename Iterator1,
typename Iterator2>
208constexpr bool includes(Iterator1 first1, Iterator1 last1, Iterator2 first2, Iterator2 last2) {
229template <
typename Iterator,
typename Predicate>
230constexpr bool all_of(Iterator first, Iterator last, Predicate pred) {
233 for (; first != last; ++first) {
250template <
typename Iterator,
typename Predicate>
251constexpr bool any_of(Iterator first, Iterator last, Predicate pred) {
254 for (; first != last; ++first) {
271template <
typename Iterator,
typename Predicate>
272constexpr bool none_of(Iterator first, Iterator last, Predicate pred) {
275 for (; first != last; ++first) {
300template <
typename Iterator,
typename BinaryPredicate>
301constexpr Iterator
adjacent_find(Iterator first, Iterator last, BinaryPredicate binary_pred) {
307 Iterator
next = first;
308 while (++
next != last) {
309 if (binary_pred(*first, *
next)) {
324template <
typename Iterator>
348template <
typename Iterator,
typename T,
typename BinaryPredicate,
352 for (; first != last; ++first) {
353 if (pred(*first, value)) {
369template <
typename Iterator,
typename Predicate>
374 for (; first != last; ++first) {
391template <
typename Iterator,
typename T>
413template <
typename Iterator,
typename T>
414NEFORCE_NODISCARD
constexpr Iterator
find(Iterator first, Iterator last,
const T& value) {
417 while (first != last && *first != value) {
432template <
typename Iterator,
typename Predicate>
433constexpr Iterator
find_if(Iterator first, Iterator last, Predicate pred) {
436 while (first != last && !pred(*first)) {
451template <
typename Iterator,
typename Predicate, enable_if_t<is_ranges_input_iter_v<Iterator>,
int> = 0>
452constexpr Iterator
find_if_not(Iterator first, Iterator last, Predicate pred) {
455 while (first != last && pred(*first)) {
481template <
typename Iterator1,
typename Iterator2,
typename BinaryPredicate>
482constexpr Iterator1
search(Iterator1 first1, Iterator1 last1, Iterator2 first2, Iterator2 last2,
483 BinaryPredicate binary_pred) {
486 "Iterator must be forward_iterator");
488 const auto d1 = _NEFORCE
distance(first1, last1);
489 const auto d2 = _NEFORCE
distance(first2, last2);
494 Iterator1 current1 = first1;
495 Iterator2 current2 = first2;
497 while (current2 != last2) {
498 if (binary_pred(*current1, *current2)) {
524template <
typename Iterator1,
typename Iterator2>
525constexpr Iterator1
search(Iterator1 first1, Iterator1 last1, Iterator2 first2, Iterator2 last2) {
539template <
typename Iterator,
typename T>
540constexpr Iterator
search_n(Iterator first, Iterator last,
const size_t count,
const T& value) {
543 first = _NEFORCE
find(first, last, value);
544 while (first != last) {
545 size_t n =
count - 1;
548 while (i != last && n != 0 && *i == value) {
556 first = _NEFORCE
find(i, last, value);
573template <
typename Iterator,
typename T,
typename BinaryPredicate>
574constexpr Iterator
search_n(Iterator first, Iterator last,
const size_t count,
const T& value,
575 BinaryPredicate binary_pred) {
578 while (first != last) {
579 if (binary_pred(*first, value)) {
585 while (first != last) {
586 size_t n =
count - 1;
590 while (i != last && n != 0 && binary_pred(*i, value)) {
599 if (binary_pred(*i, value)) {
609#ifndef NEFORCE_STANDARD_17
613template <
typename Iterator1,
typename Iterator2>
615__find_end_aux(Iterator1 first1, Iterator1 last1, Iterator2 first2, Iterator2 last2) {
618 reviter1 rlast1(first1);
619 reviter2 rlast2(first2);
620 reviter1 rresult = _NEFORCE
search(reviter1(last1), rlast1, reviter2(last2), rlast2);
621 if (rresult == rlast1) {
624 Iterator1 result = rresult.base();
629template <
typename Iterator1,
typename Iterator2>
631__find_end_aux(Iterator1 first1, Iterator1 last1, Iterator2 first2, Iterator2 last2) {
632 Iterator1 result = last1;
634 Iterator1 new_result = _NEFORCE
search(first1, last1, first2, last2);
635 if (new_result == last1) {
658template <
typename Iterator1,
typename Iterator2>
659constexpr Iterator1
find_end(Iterator1 first1, Iterator1 last1, Iterator2 first2, Iterator2 last2) {
661 "Iterator must be forward_iterator");
663 if (first2 == last2) {
666#ifdef NEFORCE_STANDARD_17
671 reviter1 rlast1(first1);
672 reviter2 rlast2(first2);
673 reviter1 rresult = _NEFORCE
search(reviter1(last1), rlast1, reviter2(last2), rlast2);
674 if (rresult == rlast1) {
678 Iterator1 result = rresult.base();
682 Iterator1 result = last1;
684 Iterator1 new_result = _NEFORCE
search(first1, last1, first2, last2);
685 if (new_result == last1) {
694 return inner::__find_end_aux(first1, last1, first2, last2);
710template <
typename Iterator1,
typename Iterator2,
typename BinaryPredicate>
711constexpr Iterator1
find_first_of(Iterator1 first1, Iterator1 last1, Iterator2 first2, Iterator2 last2,
712 BinaryPredicate comp) {
714 "Iterator must be input_iterator");
716 for (; first1 != last1; ++first1) {
717 for (Iterator2 iter = first2; iter != last2; ++iter) {
718 if (comp(*first1, *iter)) {
736template <
typename Iterator1,
typename Iterator2>
737constexpr Iterator1
find_first_of(Iterator1 first1, Iterator1 last1, Iterator2 first2, Iterator2 last2) {
745NEFORCE_END_NAMESPACE__
constexpr Iterator adjacent_find(Iterator first, Iterator last, BinaryPredicate binary_pred)
查找第一对满足条件的相邻元素
constexpr bool binary_search(Iterator first, Iterator last, const T &value)
在有序范围内进行二分查找
constexpr Iterator upper_bound(Iterator first, Iterator last, const T &value, Compare comp)
查找有序范围中第一个大于指定值的元素位置
constexpr Iterator lower_bound(Iterator first, Iterator last, const T &value, Compare comp)
查找有序范围中第一个不小于指定值的元素位置
constexpr bool includes(Iterator1 first1, Iterator1 last1, Iterator2 first2, Iterator2 last2, Compare comp)
检查一个有序范围是否包含另一个有序范围的所有元素
constexpr iter_difference_t< Iterator > count_if(Iterator first, Iterator last, const T &value, BinaryPredicate pred)
统计范围内满足二元谓词的元素数量
constexpr iter_difference_t< Iterator > count(Iterator first, Iterator last, const T &value)
统计范围内等于指定值的元素数量
constexpr Iterator find_if_not(Iterator first, Iterator last, Predicate pred)
查找范围内第一个不满足谓词的元素
constexpr Iterator find_if(Iterator first, Iterator last, Predicate pred)
查找范围内第一个满足谓词的元素
NEFORCE_NODISCARD constexpr Iterator find(Iterator first, Iterator last, const T &value)
查找范围内第一个等于指定值的元素
NEFORCE_INLINE17 constexpr bool is_ranges_input_iter_v
检查是否为范围输入迭代器
NEFORCE_INLINE17 constexpr bool is_ranges_fwd_iter_v
检查是否为范围前向迭代器
NEFORCE_INLINE17 constexpr bool is_ranges_bid_iter_v
检查是否为范围双向迭代器
constexpr void advance(Iterator &i, Distance n)
将迭代器前进指定距离
constexpr Iterator next(Iterator iter, iter_difference_t< Iterator > n=1)
获取迭代器的后一个位置
constexpr iter_difference_t< Iterator > distance(Iterator first, Iterator last)
计算两个迭代器之间的距离
typename iterator_traits< Iterator >::value_type iter_value_t
获取迭代器的值类型
typename iterator_traits< Iterator >::difference_type iter_difference_t
获取迭代器的差值类型
constexpr Iterator1 search(Iterator1 first1, Iterator1 last1, Iterator2 first2, Iterator2 last2, BinaryPredicate binary_pred)
在范围内查找子序列的第一次出现
constexpr Iterator1 find_first_of(Iterator1 first1, Iterator1 last1, Iterator2 first2, Iterator2 last2, BinaryPredicate comp)
查找范围内第一个出现在指定集合中的元素
constexpr Iterator search_n(Iterator first, Iterator last, const size_t count, const T &value)
查找范围内连续n个等于指定值的子序列
constexpr Iterator1 find_end(Iterator1 first1, Iterator1 last1, Iterator2 first2, Iterator2 last2)
在范围内查找子序列的最后一次出现
constexpr bool any_of(Iterator first, Iterator last, Predicate pred)
检查是否有任意元素满足谓词
constexpr bool none_of(Iterator first, Iterator last, Predicate pred)
检查是否没有元素满足谓词
constexpr bool all_of(Iterator first, Iterator last, Predicate pred)
检查所有元素是否都满足谓词
typename enable_if< Test, T >::type enable_if_t
enable_if的便捷别名