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 len = half;
109 } else {
110 first = middle;
111 ++first;
112 len = len - half - 1;
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 less<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 if (comp(*first1, *first2)) {
188 ++first1;
189 } else {
190 ++first1, ++first2;
191 }
192 }
193 return first2 == last2;
194}
195
206template <typename Iterator1, typename Iterator2>
207constexpr bool includes(Iterator1 first1, Iterator1 last1, Iterator2 first2, Iterator2 last2) {
208 return _NEFORCE includes(first1, last1, first2, last2, _NEFORCE less<iter_value_t<Iterator1>>());
209}
210 // BoundAlgorithms
212
218
228template <typename Iterator, typename Predicate>
229constexpr bool all_of(Iterator first, Iterator last, Predicate pred) {
230 static_assert(is_ranges_input_iter_v<Iterator>, "Iterator must be input_iterator");
231
232 for (; first != last; ++first) {
233 if (!pred(*first)) {
234 return false;
235 }
236 }
237 return true;
238}
239
249template <typename Iterator, typename Predicate>
250constexpr bool any_of(Iterator first, Iterator last, Predicate pred) {
251 static_assert(is_ranges_input_iter_v<Iterator>, "Iterator must be input_iterator");
252
253 for (; first != last; ++first) {
254 if (pred(*first)) {
255 return true;
256 }
257 }
258 return false;
259}
260
270template <typename Iterator, typename Predicate>
271constexpr bool none_of(Iterator first, Iterator last, Predicate pred) {
272 static_assert(is_ranges_input_iter_v<Iterator>, "Iterator must be input_iterator");
273
274 for (; first != last; ++first) {
275 if (pred(*first)) {
276 return false;
277 }
278 }
279 return true;
280}
281 // QuantifierAlgorithms
283
289
299template <typename Iterator, typename BinaryPredicate>
300constexpr Iterator adjacent_find(Iterator first, Iterator last, BinaryPredicate binary_pred) {
301 static_assert(is_ranges_input_iter_v<Iterator>, "Iterator must be input_iterator");
302
303 if (first == last) {
304 return last;
305 }
306 Iterator next = first;
307 while (++next != last) {
308 if (binary_pred(*first, *next)) {
309 return first;
310 }
311 first = next;
312 }
313 return last;
314}
315
323template <typename Iterator>
324constexpr Iterator adjacent_find(Iterator first, Iterator last) {
325 return _NEFORCE adjacent_find(first, last, _NEFORCE equal_to<iter_value_t<Iterator>>());
326}
327 // AdjacentAlgorithms
329
335
347template <typename Iterator, typename T, typename BinaryPredicate,
349constexpr iter_difference_t<Iterator> count_if(Iterator first, Iterator last, const T& value, BinaryPredicate pred) {
351 for (; first != last; ++first) {
352 if (pred(*first, value)) {
353 ++n;
354 }
355 }
356 return n;
357}
358
368template <typename Iterator, typename Predicate>
369constexpr iter_difference_t<Iterator> count_if(Iterator first, Iterator last, Predicate pred) {
370 static_assert(is_ranges_input_iter_v<Iterator>, "Iterator must be input_iterator");
371
373 for (; first != last; ++first) {
374 if (pred(*first)) {
375 ++n;
376 }
377 }
378 return n;
379}
380
390template <typename Iterator, typename T>
391constexpr iter_difference_t<Iterator> count(Iterator first, Iterator last, const T& value) {
392 return _NEFORCE count_if(first, last, value, _NEFORCE equal_to<iter_value_t<Iterator>>());
393}
394 // CountingAlgorithms
396
402
412template <typename Iterator, typename T>
413NEFORCE_NODISCARD constexpr Iterator find(Iterator first, Iterator last, const T& value) {
414 static_assert(is_ranges_input_iter_v<Iterator>, "Iterator must be input_iterator");
415
416 while (first != last && *first != value) {
417 ++first;
418 }
419 return first;
420}
421
431template <typename Iterator, typename Predicate>
432constexpr Iterator find_if(Iterator first, Iterator last, Predicate pred) {
433 static_assert(is_ranges_input_iter_v<Iterator>, "Iterator must be input_iterator");
434
435 while (first != last && !pred(*first)) {
436 ++first;
437 }
438 return first;
439}
440
450template <typename Iterator, typename Predicate, enable_if_t<is_ranges_input_iter_v<Iterator>, int> = 0>
451constexpr Iterator find_if_not(Iterator first, Iterator last, Predicate pred) {
452 static_assert(is_ranges_input_iter_v<Iterator>, "Iterator must be input_iterator");
453
454 while (first != last && pred(*first)) {
455 ++first;
456 }
457 return first;
458}
459 // FindingAlgorithms
461
467
480template <typename Iterator1, typename Iterator2, typename BinaryPredicate>
481constexpr Iterator1 search(Iterator1 first1, Iterator1 last1, Iterator2 first2, Iterator2 last2,
482 BinaryPredicate binary_pred) {
483
485 "Iterator must be forward_iterator");
486
487 auto d1 = _NEFORCE distance(first1, last1);
488 const auto d2 = _NEFORCE distance(first2, last2);
489 if (d1 < d2) {
490 return last1;
491 }
492
493 Iterator1 current1 = first1;
494 Iterator2 current2 = first2;
495
496 while (current2 != last2) {
497 if (binary_pred(*current1, *current2)) {
498 ++current1;
499 ++current2;
500 } else {
501 if (d1 == d2) {
502 return last1;
503 }
504
505 current1 = ++first1;
506 current2 = first2;
507 --d1;
508 }
509 }
510 return first1;
511}
512
523template <typename Iterator1, typename Iterator2>
524constexpr Iterator1 search(Iterator1 first1, Iterator1 last1, Iterator2 first2, Iterator2 last2) {
525 return _NEFORCE search(first1, last1, first2, last2, _NEFORCE equal_to<iter_value_t<Iterator1>>());
526}
527
538template <typename Iterator, typename T>
539constexpr Iterator search_n(Iterator first, Iterator last, const size_t count, const T& value) {
540 static_assert(is_ranges_fwd_iter_v<Iterator>, "Iterator must be forward_iterator");
541
542 if (count == 0) {
543 return first;
544 }
545
546 first = _NEFORCE find(first, last, value);
547 while (first != last) {
548 size_t n = count - 1;
549 Iterator i = first;
550 ++i;
551 while (i != last && n != 0 && *i == value) {
552 ++i;
553 --n;
554 }
555 if (n == 0) {
556 return first;
557 }
558
559 first = _NEFORCE find(i, last, value);
560 }
561 return last;
562}
563
576template <typename Iterator, typename T, typename BinaryPredicate>
577constexpr Iterator search_n(Iterator first, Iterator last, const size_t count, const T& value,
578 BinaryPredicate binary_pred) {
579 static_assert(is_ranges_fwd_iter_v<Iterator>, "Iterator must be forward_iterator");
580
581 if (count == 0) {
582 return first;
583 }
584
585 while (first != last) {
586 if (binary_pred(*first, value)) {
587 break;
588 }
589 ++first;
590 }
591
592 while (first != last) {
593 size_t n = count - 1;
594 Iterator i = first;
595 ++i;
596
597 while (i != last && n != 0 && binary_pred(*i, value)) {
598 ++i;
599 --n;
600 }
601 if (n == 0) {
602 return first;
603 }
604
605 while (i != last) {
606 if (binary_pred(*i, value)) {
607 break;
608 }
609 ++i;
610 }
611 first = i;
612 }
613 return last;
614}
615
616#ifndef NEFORCE_STANDARD_17
618NEFORCE_BEGIN_INNER__
619
620template <typename Iterator1, typename Iterator2>
622__find_end_aux(Iterator1 first1, Iterator1 last1, Iterator2 first2, Iterator2 last2) {
623 using reviter1 = _NEFORCE reverse_iterator<Iterator1>;
624 using reviter2 = _NEFORCE reverse_iterator<Iterator2>;
625 reviter1 rlast1(first1);
626 reviter2 rlast2(first2);
627 reviter1 rresult = _NEFORCE search(reviter1(last1), rlast1, reviter2(last2), rlast2);
628 if (rresult == rlast1) {
629 return last1;
630 }
631 Iterator1 result = rresult.base();
632 _NEFORCE advance(result, -distance(first2, last2));
633 return result;
634}
635
636template <typename Iterator1, typename Iterator2>
638__find_end_aux(Iterator1 first1, Iterator1 last1, Iterator2 first2, Iterator2 last2) {
639 Iterator1 result = last1;
640 while (true) {
641 Iterator1 new_result = _NEFORCE search(first1, last1, first2, last2);
642 if (new_result == last1) {
643 return result;
644 }
645 result = new_result;
646 first1 = new_result;
647 ++first1;
648 }
649}
650
651NEFORCE_END_INNER__
653#endif // NEFORCE_STANDARD_17
654
665template <typename Iterator1, typename Iterator2>
666constexpr Iterator1 find_end(Iterator1 first1, Iterator1 last1, Iterator2 first2, Iterator2 last2) {
668 "Iterator must be forward_iterator");
669
670 if (first2 == last2) {
671 return last1;
672 }
673#ifdef NEFORCE_STANDARD_17
675 using reviter1 = _NEFORCE reverse_iterator<Iterator1>;
676 using reviter2 = _NEFORCE reverse_iterator<Iterator2>;
677
678 reviter1 rlast1(first1);
679 reviter2 rlast2(first2);
680 reviter1 rresult = _NEFORCE search(reviter1(last1), rlast1, reviter2(last2), rlast2);
681 if (rresult == rlast1) {
682 return last1;
683 }
684
685 Iterator1 result = rresult.base();
686 _NEFORCE advance(result, -distance(first2, last2));
687 return result;
688 } else {
689 Iterator1 result = last1;
690 while (true) {
691 Iterator1 new_result = _NEFORCE search(first1, last1, first2, last2);
692 if (new_result == last1) {
693 return result;
694 }
695 result = new_result;
696 first1 = new_result;
697 ++first1;
698 }
699 }
700#else
701 return inner::__find_end_aux(first1, last1, first2, last2);
702#endif
703}
704
717template <typename Iterator1, typename Iterator2, typename BinaryPredicate>
718constexpr Iterator1 find_first_of(Iterator1 first1, Iterator1 last1, Iterator2 first2, Iterator2 last2,
719 BinaryPredicate comp) {
721 "Iterator must be input_iterator");
722
723 for (; first1 != last1; ++first1) {
724 for (Iterator2 iter = first2; iter != last2; ++iter) {
725 if (comp(*first1, *iter)) {
726 return first1;
727 }
728 }
729 }
730 return last1;
731}
732
743template <typename Iterator1, typename Iterator2>
744constexpr Iterator1 find_first_of(Iterator1 first1, Iterator1 last1, Iterator2 first2, Iterator2 last2) {
745 return _NEFORCE find_first_of(first1, last1, first2, last2, _NEFORCE equal_to<iter_value_t<Iterator1>>());
746}
747 // PatternMatchingAlgorithms
749 // StandardAlgorithms
751
752NEFORCE_END_NAMESPACE__
753#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)
查找范围内第一个满足谓词的元素
constexpr Iterator find(Iterator first, Iterator last, const T &value)
查找范围内第一个等于指定值的元素
constexpr bool is_ranges_fwd_iter_v
检查是否为范围前向迭代器
constexpr bool is_ranges_input_iter_v
检查是否为范围输入迭代器
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的便捷别名
反向迭代器
相等比较仿函数
小于比较仿函数