NexusForce 1.0.0
A Modern C++ Library with extended functionality, web components, and utility libraries
载入中...
搜索中...
未找到
search.hpp
浏览该文件的文档.
1#ifndef NEFORCE_CORE_ALGORITHM_SEARCH_HPP__
2#define NEFORCE_CORE_ALGORITHM_SEARCH_HPP__
3
11
14NEFORCE_BEGIN_NAMESPACE__
15
21
27
42template <typename Iterator, typename T, typename Compare>
43constexpr Iterator lower_bound(Iterator first, Iterator last, const T& value, Compare comp) {
44 static_assert(is_ranges_fwd_iter_v<Iterator>, "Iterator must be forward_iterator");
45
46 using Distance = iter_difference_t<Iterator>;
47 Distance len = _NEFORCE distance(first, last);
48 Distance half;
49 Iterator middle;
50 while (len > 0) {
51 half = len >> 1;
52 middle = first;
53 _NEFORCE advance(middle, half);
54 if (comp(*middle, value)) {
55 first = middle;
56 ++first;
57 len = len - half - 1;
58 } else {
59 len = half;
60 }
61 }
62 return first;
63}
64
76template <typename Iterator, typename T>
77constexpr Iterator lower_bound(Iterator first, Iterator last, const T& value) {
78 return _NEFORCE lower_bound(first, last, value, _NEFORCE less<iter_value_t<Iterator>>());
79}
80
95template <typename Iterator, typename T, typename Compare>
96constexpr Iterator upper_bound(Iterator first, Iterator last, const T& value, Compare comp) {
97 static_assert(is_ranges_fwd_iter_v<Iterator>, "Iterator must be forward_iterator");
98
99 using Distance = iter_difference_t<Iterator>;
100 Distance len = _NEFORCE distance(first, last);
101 Distance half;
102 Iterator middle;
103 while (len > 0) {
104 half = len >> 1;
105 middle = first;
106 _NEFORCE advance(middle, half);
107 if (comp(value, *middle)) {
108 first = middle;
109 ++first;
110 len = len - half - 1;
111 } else {
112 len = half;
113 }
114 }
115 return first;
116}
117
129template <typename Iterator, typename T>
130constexpr Iterator upper_bound(Iterator first, Iterator last, const T& value) {
131 return _NEFORCE upper_bound(first, last, value, _NEFORCE greater<iter_value_t<Iterator>>());
132}
133
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);
147}
148
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);
164}
165
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");
182
183 while (first1 != last1 && first2 != last2) {
184 if (comp(*first2, *first1)) {
185 return false;
186 }
187
188 if (comp(*first1, *first2)) {
189 ++first1;
190 } else {
191 ++first1, ++first2;
192 }
193 }
194 return first2 == last2;
195}
196
207template <typename Iterator1, typename Iterator2>
208constexpr bool includes(Iterator1 first1, Iterator1 last1, Iterator2 first2, Iterator2 last2) {
209 return _NEFORCE includes(first1, last1, first2, last2, _NEFORCE less<iter_value_t<Iterator1>>());
210}
211 // BoundAlgorithms
213
219
229template <typename Iterator, typename Predicate>
230constexpr bool all_of(Iterator first, Iterator last, Predicate pred) {
231 static_assert(is_ranges_input_iter_v<Iterator>, "Iterator must be input_iterator");
232
233 for (; first != last; ++first) {
234 if (!pred(*first)) {
235 return false;
236 }
237 }
238 return true;
239}
240
250template <typename Iterator, typename Predicate>
251constexpr bool any_of(Iterator first, Iterator last, Predicate pred) {
252 static_assert(is_ranges_input_iter_v<Iterator>, "Iterator must be input_iterator");
253
254 for (; first != last; ++first) {
255 if (pred(*first)) {
256 return true;
257 }
258 }
259 return false;
260}
261
271template <typename Iterator, typename Predicate>
272constexpr bool none_of(Iterator first, Iterator last, Predicate pred) {
273 static_assert(is_ranges_input_iter_v<Iterator>, "Iterator must be input_iterator");
274
275 for (; first != last; ++first) {
276 if (pred(*first)) {
277 return false;
278 }
279 }
280 return true;
281}
282 // QuantifierAlgorithms
284
290
300template <typename Iterator, typename BinaryPredicate>
301constexpr Iterator adjacent_find(Iterator first, Iterator last, BinaryPredicate binary_pred) {
302 static_assert(is_ranges_input_iter_v<Iterator>, "Iterator must be input_iterator");
303
304 if (first == last) {
305 return last;
306 }
307 Iterator next = first;
308 while (++next != last) {
309 if (binary_pred(*first, *next)) {
310 return first;
311 }
312 first = next;
313 }
314 return last;
315}
316
324template <typename Iterator>
325constexpr Iterator adjacent_find(Iterator first, Iterator last) {
326 return _NEFORCE adjacent_find(first, last, _NEFORCE equal_to<iter_value_t<Iterator>>());
327}
328 // AdjacentAlgorithms
330
336
348template <typename Iterator, typename T, typename BinaryPredicate,
350constexpr iter_difference_t<Iterator> count_if(Iterator first, Iterator last, const T& value, BinaryPredicate pred) {
352 for (; first != last; ++first) {
353 if (pred(*first, value)) {
354 ++n;
355 }
356 }
357 return n;
358}
359
369template <typename Iterator, typename Predicate>
370constexpr iter_difference_t<Iterator> count_if(Iterator first, Iterator last, Predicate pred) {
371 static_assert(is_ranges_input_iter_v<Iterator>, "Iterator must be input_iterator");
372
374 for (; first != last; ++first) {
375 if (pred(*first)) {
376 ++n;
377 }
378 }
379 return n;
380}
381
391template <typename Iterator, typename T>
392constexpr iter_difference_t<Iterator> count(Iterator first, Iterator last, const T& value) {
393 return _NEFORCE count_if(first, last, value, _NEFORCE equal_to<iter_value_t<Iterator>>());
394}
395 // CountingAlgorithms
397
403
413template <typename Iterator, typename T>
414NEFORCE_NODISCARD constexpr Iterator find(Iterator first, Iterator last, const T& value) {
415 static_assert(is_ranges_input_iter_v<Iterator>, "Iterator must be input_iterator");
416
417 while (first != last && *first != value) {
418 ++first;
419 }
420 return first;
421}
422
432template <typename Iterator, typename Predicate>
433constexpr Iterator find_if(Iterator first, Iterator last, Predicate pred) {
434 static_assert(is_ranges_input_iter_v<Iterator>, "Iterator must be input_iterator");
435
436 while (first != last && !pred(*first)) {
437 ++first;
438 }
439 return first;
440}
441
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) {
453 static_assert(is_ranges_input_iter_v<Iterator>, "Iterator must be input_iterator");
454
455 while (first != last && pred(*first)) {
456 ++first;
457 }
458 return first;
459}
460 // FindingAlgorithms
462
468
481template <typename Iterator1, typename Iterator2, typename BinaryPredicate>
482constexpr Iterator1 search(Iterator1 first1, Iterator1 last1, Iterator2 first2, Iterator2 last2,
483 BinaryPredicate binary_pred) {
484
486 "Iterator must be forward_iterator");
487
488 const auto d1 = _NEFORCE distance(first1, last1);
489 const auto d2 = _NEFORCE distance(first2, last2);
490 if (d1 < d2) {
491 return last1;
492 }
493
494 Iterator1 current1 = first1;
495 Iterator2 current2 = first2;
496
497 while (current2 != last2) {
498 if (binary_pred(*current1, *current2)) {
499 ++current1;
500 ++current2;
501 } else {
502 if (d1 == d2) {
503 return last1;
504 }
505
506 current1 = ++first1;
507 current2 = first2;
508 --d1;
509 }
510 }
511 return first1;
512}
513
524template <typename Iterator1, typename Iterator2>
525constexpr Iterator1 search(Iterator1 first1, Iterator1 last1, Iterator2 first2, Iterator2 last2) {
526 return _NEFORCE search(first1, last1, first2, last2, _NEFORCE equal_to<iter_value_t<Iterator1>>());
527}
528
539template <typename Iterator, typename T>
540constexpr Iterator search_n(Iterator first, Iterator last, const size_t count, const T& value) {
541 static_assert(is_ranges_fwd_iter_v<Iterator>, "Iterator must be forward_iterator");
542
543 first = _NEFORCE find(first, last, value);
544 while (first != last) {
545 size_t n = count - 1;
546 Iterator i = first;
547 ++i;
548 while (i != last && n != 0 && *i == value) {
549 ++i;
550 --n;
551 }
552 if (n == 0) {
553 return first;
554 }
555
556 first = _NEFORCE find(i, last, value);
557 }
558 return last;
559}
560
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) {
576 static_assert(is_ranges_fwd_iter_v<Iterator>, "Iterator must be forward_iterator");
577
578 while (first != last) {
579 if (binary_pred(*first, value)) {
580 break;
581 }
582 ++first;
583 }
584
585 while (first != last) {
586 size_t n = count - 1;
587 Iterator i = first;
588 ++i;
589
590 while (i != last && n != 0 && binary_pred(*i, value)) {
591 ++i;
592 --n;
593 }
594 if (n == 0) {
595 return first;
596 }
597
598 while (i != last) {
599 if (binary_pred(*i, value)) {
600 break;
601 }
602 ++i;
603 }
604 first = i;
605 }
606 return last;
607}
608
609#ifndef NEFORCE_STANDARD_17
611NEFORCE_BEGIN_INNER__
612
613template <typename Iterator1, typename Iterator2>
615__find_end_aux(Iterator1 first1, Iterator1 last1, Iterator2 first2, Iterator2 last2) {
616 using reviter1 = _NEFORCE reverse_iterator<Iterator1>;
617 using reviter2 = _NEFORCE reverse_iterator<Iterator2>;
618 reviter1 rlast1(first1);
619 reviter2 rlast2(first2);
620 reviter1 rresult = _NEFORCE search(reviter1(last1), rlast1, reviter2(last2), rlast2);
621 if (rresult == rlast1) {
622 return last1;
623 }
624 Iterator1 result = rresult.base();
625 _NEFORCE advance(result, -distance(first2, last2));
626 return result;
627}
628
629template <typename Iterator1, typename Iterator2>
631__find_end_aux(Iterator1 first1, Iterator1 last1, Iterator2 first2, Iterator2 last2) {
632 Iterator1 result = last1;
633 while (true) {
634 Iterator1 new_result = _NEFORCE search(first1, last1, first2, last2);
635 if (new_result == last1) {
636 return result;
637 }
638 result = new_result;
639 first1 = new_result;
640 ++first1;
641 }
642}
643
644NEFORCE_END_INNER__
646#endif // NEFORCE_STANDARD_17
647
658template <typename Iterator1, typename Iterator2>
659constexpr Iterator1 find_end(Iterator1 first1, Iterator1 last1, Iterator2 first2, Iterator2 last2) {
661 "Iterator must be forward_iterator");
662
663 if (first2 == last2) {
664 return last1;
665 }
666#ifdef NEFORCE_STANDARD_17
668 using reviter1 = _NEFORCE reverse_iterator<Iterator1>;
669 using reviter2 = _NEFORCE reverse_iterator<Iterator2>;
670
671 reviter1 rlast1(first1);
672 reviter2 rlast2(first2);
673 reviter1 rresult = _NEFORCE search(reviter1(last1), rlast1, reviter2(last2), rlast2);
674 if (rresult == rlast1) {
675 return last1;
676 }
677
678 Iterator1 result = rresult.base();
679 _NEFORCE advance(result, -distance(first2, last2));
680 return result;
681 } else {
682 Iterator1 result = last1;
683 while (true) {
684 Iterator1 new_result = _NEFORCE search(first1, last1, first2, last2);
685 if (new_result == last1) {
686 return result;
687 }
688 result = new_result;
689 first1 = new_result;
690 ++first1;
691 }
692 }
693#else
694 return inner::__find_end_aux(first1, last1, first2, last2);
695#endif
696}
697
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");
715
716 for (; first1 != last1; ++first1) {
717 for (Iterator2 iter = first2; iter != last2; ++iter) {
718 if (comp(*first1, *iter)) {
719 return first1;
720 }
721 }
722 }
723 return last1;
724}
725
736template <typename Iterator1, typename Iterator2>
737constexpr Iterator1 find_first_of(Iterator1 first1, Iterator1 last1, Iterator2 first2, Iterator2 last2) {
738 return _NEFORCE find_first_of(first1, last1, first2, last2, _NEFORCE equal_to<iter_value_t<Iterator1>>());
739}
740 // PatternMatchingAlgorithms
742 // StandardAlgorithms
744
745NEFORCE_END_NAMESPACE__
746#endif // NEFORCE_CORE_ALGORITHM_SEARCH_HPP__
反向迭代器模板类
仿函数
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的便捷别名
反向迭代器
相等比较仿函数
大于比较仿函数
小于比较仿函数