MSTL 1.4.0
A Modern C++ Library with extended functionality, web components, and utility libraries
载入中...
搜索中...
未找到
search.hpp
浏览该文件的文档.
1#ifndef MSTL_CORE_ALGORITHM_SEARCH_HPP__
2#define MSTL_CORE_ALGORITHM_SEARCH_HPP__
3
11
15
21
36template <typename Iterator, typename T, typename Compare, enable_if_t<is_ranges_fwd_iter_v<Iterator>, int> = 0>
37constexpr Iterator lower_bound(Iterator first, Iterator last, const T& value, Compare comp) {
38 using Distance = iter_difference_t<Iterator>;
39 Distance len = _MSTL distance(first, last);
40 Distance half;
41 Iterator middle;
42 while (len > 0) {
43 half = len >> 1;
44 middle = first;
45 _MSTL advance(middle, half);
46 if (comp(*middle, value)) {
47 first = middle;
48 ++first;
49 len = len - half - 1;
50 }
51 else len = half;
52 }
53 return first;
54}
55
67template <typename Iterator, typename T>
68constexpr Iterator lower_bound(Iterator first, Iterator last, const T& value) {
69 return _MSTL lower_bound(first, last, value, _MSTL less<iter_value_t<Iterator>>());
70}
71
86template <typename Iterator, typename T, typename Compare, enable_if_t<is_ranges_fwd_iter_v<Iterator>, int> = 0>
87constexpr Iterator upper_bound(Iterator first, Iterator last, const T& value, Compare comp) {
88 using Distance = iter_difference_t<Iterator>;
89 Distance len = _MSTL distance(first, last);
90 Distance half;
91 Iterator middle;
92 while (len > 0) {
93 half = len >> 1;
94 middle = first;
95 _MSTL advance(middle, half);
96 if (comp(value, *middle)) {
97 first = middle;
98 ++first;
99 len = len - half - 1;
100 }
101 else len = half;
102 }
103 return first;
104}
105
117template <typename Iterator, typename T>
118constexpr Iterator upper_bound(Iterator first, Iterator last, const T& value) {
119 return _MSTL upper_bound(first, last, value, _MSTL greater<iter_value_t<Iterator>>());
120}
121
131template <typename Iterator, typename T, enable_if_t<is_ranges_fwd_iter_v<Iterator>, int> = 0>
132constexpr bool binary_search(Iterator first, Iterator last, const T& value) {
133 Iterator i = _MSTL lower_bound(first, last, value);
134 return i != last && !(value < *i);
135}
136
148template <typename Iterator, typename T, typename Compare, enable_if_t<is_ranges_fwd_iter_v<Iterator>, int> = 0>
149constexpr bool binary_search(Iterator first, Iterator last, const T& value, Compare comp) {
150 Iterator i = _MSTL lower_bound(first, last, value, comp);
151 return i != last && !comp(value, *i);
152}
153
166template <typename Iterator1, typename Iterator2, typename Compare,
168constexpr bool includes(Iterator1 first1, Iterator1 last1, Iterator2 first2, Iterator2 last2, Compare comp) {
169 while (first1 != last1 && first2 != last2) {
170 if (comp(*first2, *first1)) return false;
171
172 if (comp(*first1, *first2)) ++first1;
173 else ++first1, ++first2;
174 }
175 return first2 == last2;
176}
177
188template <typename Iterator1, typename Iterator2>
189constexpr bool includes(Iterator1 first1, Iterator1 last1, Iterator2 first2, Iterator2 last2) {
190 return _MSTL includes(first1, last1, first2, last2, _MSTL less<iter_value_t<Iterator1>>());
191}
192 // BoundAlgorithms
194
200
210template <typename Iterator, typename Predicate, enable_if_t<is_ranges_input_iter_v<Iterator>, int> = 0>
211constexpr bool all_of(Iterator first, Iterator last, Predicate pred) {
212 for (; first != last; ++first) {
213 if (!pred(*first)) return false;
214 }
215 return true;
216}
217
227template <typename Iterator, typename Predicate, enable_if_t<is_ranges_input_iter_v<Iterator>, int> = 0>
228constexpr bool any_of(Iterator first, Iterator last, Predicate pred) {
229 for (; first != last; ++first) {
230 if (pred(*first)) return true;
231 }
232 return false;
233}
234
244template <typename Iterator, typename Predicate, enable_if_t<is_ranges_input_iter_v<Iterator>, int> = 0>
245constexpr bool none_of(Iterator first, Iterator last, Predicate pred) {
246 for (; first != last; ++first) {
247 if (pred(*first)) return false;
248 }
249 return true;
250}
251 // QuantifierAlgorithms
253
259
269template <typename Iterator, typename BinaryPredicate, enable_if_t<is_ranges_fwd_iter_v<Iterator>, int> = 0>
270constexpr Iterator adjacent_find(Iterator first, Iterator last, BinaryPredicate binary_pred) {
271 if (first == last) return last;
272 Iterator next = first;
273 while (++next != last) {
274 if (binary_pred(*first, *next)) return first;
275 first = next;
276 }
277 return last;
278}
279
287template <typename Iterator, enable_if_t<is_ranges_input_iter_v<Iterator>, int> = 0>
288constexpr Iterator adjacent_find(Iterator first, Iterator last) {
290}
291 // AdjacentAlgorithms
293
299
311template <typename Iterator, typename T, typename BinaryPredicate,
313constexpr iter_difference_t<Iterator> count_if(Iterator first, Iterator last, const T& value, BinaryPredicate pred) {
315 for (; first != last; ++first) {
316 if (pred(*first, value)) ++n;
317 }
318 return n;
319}
320
330template <typename Iterator, typename Predicate,
332constexpr iter_difference_t<Iterator> count_if(Iterator first, Iterator last, Predicate pred) {
334 for (; first != last; ++first) {
335 if (pred(*first)) ++n;
336 }
337 return n;
338}
339
349template <typename Iterator, typename T>
350constexpr iter_difference_t<Iterator> count(Iterator first, Iterator last, const T& value) {
351 return _MSTL count_if(first, last, value, _MSTL equal_to<iter_value_t<Iterator>>());
352}
353 // CountingAlgorithms
355
361
371template <typename Iterator, typename T>
372MSTL_NODISCARD constexpr Iterator find(Iterator first, Iterator last, const T& value) {
373 while (first != last && *first != value) ++first;
374 return first;
375}
376
386template <typename Iterator, typename Predicate,
388constexpr Iterator find_if(Iterator first, Iterator last, Predicate pred) {
389 while (first != last && !pred(*first)) ++first;
390 return first;
391}
392
402template <typename Iterator, typename Predicate,
404constexpr Iterator find_if_not(Iterator first, Iterator last, Predicate pred) {
405 while (first != last && pred(*first)) ++first;
406 return first;
407}
408 // FindingAlgorithms
410
416
429template <typename Iterator1, typename Iterator2, typename BinaryPredicate,
431constexpr Iterator1 search(Iterator1 first1, Iterator1 last1, Iterator2 first2,
432 Iterator2 last2, BinaryPredicate binary_pred) {
433 iter_difference_t<Iterator1> d1 = _MSTL distance(first1, last1);
434 iter_difference_t<Iterator2> d2 = _MSTL distance(first2, last2);
435 if (d1 < d2) return last1;
436
437 Iterator1 current1 = first1;
438 Iterator2 current2 = first2;
439
440 while (current2 != last2) {
441 if (binary_pred(*current1, *current2)) {
442 ++current1;
443 ++current2;
444 } else {
445 if (d1 == d2) return last1;
446
447 current1 = ++first1;
448 current2 = first2;
449 --d1;
450 }
451 }
452 return first1;
453}
454
465template <typename Iterator1, typename Iterator2>
466constexpr Iterator1 search(Iterator1 first1, Iterator1 last1, Iterator2 first2, Iterator2 last2) {
467 return _MSTL search(first1, last1, first2, last2, _MSTL equal_to<iter_value_t<Iterator1>>());
468}
469
480template <typename Iterator, typename T, enable_if_t<is_ranges_fwd_iter_v<Iterator>, int> = 0>
481constexpr Iterator search_n(Iterator first, Iterator last, const size_t count, const T& value) {
482 first = _MSTL find(first, last, value);
483 while (first != last) {
484 size_t n = count - 1;
485 Iterator i = first;
486 ++i;
487 while (i != last && n != 0 && *i == value) {
488 ++i;
489 --n;
490 }
491 if (n == 0) return first;
492
493 first = _MSTL find(i, last, value);
494 }
495 return last;
496}
497
510template <typename Iterator, typename T, typename BinaryPredicate, enable_if_t<is_ranges_fwd_iter_v<Iterator>, int> = 0>
511constexpr Iterator search_n(Iterator first, Iterator last, const size_t count, const T& value, BinaryPredicate binary_pred) {
512 while (first != last) {
513 if (binary_pred(*first, value)) break;
514 ++first;
515 }
516 while (first != last) {
517 size_t n = count - 1;
518 Iterator i = first;
519 ++i;
520 while (i != last && n != 0 && binary_pred(*i, value)) {
521 ++i;
522 --n;
523 }
524 if (n == 0) return first;
525
526 while (i != last) {
527 if (binary_pred(*i, value)) break;
528 ++i;
529 }
530 first = i;
531 }
532 return last;
533}
534
535#ifndef MSTL_STANDARD_17__
538template <typename Iterator1, typename Iterator2,
540constexpr Iterator1 __find_end_aux(Iterator1 first1, Iterator1 last1, Iterator2 first2, Iterator2 last2) {
541 using reviter1 = _MSTL reverse_iterator<Iterator1>;
542 using reviter2 = _MSTL reverse_iterator<Iterator2>;
543 reviter1 rlast1(first1);
544 reviter2 rlast2(first2);
545 reviter1 rresult = _MSTL search(reviter1(last1), rlast1, reviter2(last2), rlast2);
546 if (rresult == rlast1) return last1;
547 Iterator1 result = rresult.base();
548 _MSTL advance(result, -distance(first2, last2));
549 return result;
550}
551template <typename Iterator1, typename Iterator2,
553constexpr Iterator1 __find_end_aux(Iterator1 first1, Iterator1 last1, Iterator2 first2, Iterator2 last2) {
554 Iterator1 result = last1;
555 while (true) {
556 Iterator1 new_result = _MSTL search(first1, last1, first2, last2);
557 if (new_result == last1) return result;
558 result = new_result;
559 first1 = new_result;
560 ++first1;
561 }
562}
565#endif // MSTL_STANDARD_17__
566
577template <typename Iterator1, typename Iterator2,
579constexpr Iterator1 find_end(Iterator1 first1, Iterator1 last1, Iterator2 first2, Iterator2 last2) {
580 if (first2 == last2) return last1;
581#ifdef MSTL_STANDARD_17__
583 using reviter1 = _MSTL reverse_iterator<Iterator1>;
584 using reviter2 = _MSTL reverse_iterator<Iterator2>;
585
586 reviter1 rlast1(first1);
587 reviter2 rlast2(first2);
588 reviter1 rresult = _MSTL search(reviter1(last1), rlast1, reviter2(last2), rlast2);
589 if (rresult == rlast1) return last1;
590
591 Iterator1 result = rresult.base();
592 _MSTL advance(result, -distance(first2, last2));
593 return result;
594 }
595 else {
596 Iterator1 result = last1;
597 while (true) {
598 Iterator1 new_result = _MSTL search(first1, last1, first2, last2);
599 if (new_result == last1) return result;
600 result = new_result;
601 first1 = new_result;
602 ++first1;
603 }
604 }
605#else
606 return _INNER __find_end_aux(first1, last1, first2, last2);
607#endif
608}
609
622template <typename Iterator1, typename Iterator2, typename BinaryPredicate,
624constexpr Iterator1 find_first_of(Iterator1 first1, Iterator1 last1,
625 Iterator2 first2, Iterator2 last2, BinaryPredicate comp) {
626 for (; first1 != last1; ++first1) {
627 for (Iterator2 iter = first2; iter != last2; ++iter) {
628 if (comp(*first1, *iter)) return first1;
629 }
630 }
631 return last1;
632}
633
644template <typename Iterator1, typename Iterator2>
645constexpr Iterator1 find_first_of(Iterator1 first1, Iterator1 last1, Iterator2 first2, Iterator2 last2) {
646 return _MSTL find_first_of(first1, last1, first2, last2, _MSTL equal_to<iter_value_t<Iterator1>>());
647}
648 // PatternMatchingAlgorithms
650
652#endif // MSTL_CORE_ALGORITHM_SEARCH_HPP__
反向迭代器模板类
MSTL仿函数
constexpr Iterator adjacent_find(Iterator first, Iterator last, BinaryPredicate binary_pred)
查找第一对满足条件的相邻元素
constexpr Iterator lower_bound(Iterator first, Iterator last, const T &value, Compare comp)
查找有序范围中第一个不小于指定值的元素位置
constexpr Iterator upper_bound(Iterator first, Iterator last, const T &value, Compare comp)
查找有序范围中第一个大于指定值的元素位置
constexpr bool binary_search(Iterator first, Iterator last, const T &value)
在有序范围内进行二分查找
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)
查找范围内第一个不满足谓词的元素
MSTL_NODISCARD constexpr Iterator find(Iterator first, Iterator last, const T &value)
查找范围内第一个等于指定值的元素
constexpr Iterator find_if(Iterator first, Iterator last, Predicate pred)
查找范围内第一个满足谓词的元素
MSTL_INLINE17 constexpr bool is_ranges_fwd_iter_v
检查是否为范围前向迭代器
MSTL_INLINE17 constexpr bool is_ranges_input_iter_v
检查是否为范围输入迭代器
MSTL_INLINE17 constexpr bool is_ranges_bid_iter_v
检查是否为范围双向迭代器
constexpr Iterator next(Iterator iter, iter_difference_t< Iterator > n=1)
获取迭代器的后一个位置
constexpr iter_difference_t< Iterator > distance(Iterator first, Iterator last)
计算两个迭代器之间的距离
constexpr void advance(Iterator &i, Distance n)
将迭代器前进指定距离
typename iterator_traits< Iterator >::value_type iter_value_t
获取迭代器的值类型
typename iterator_traits< Iterator >::difference_type iter_difference_t
获取迭代器的差值类型
#define _MSTL
全局命名空间MSTL前缀
#define MSTL_END_INNER__
结束inner命名空间
#define _INNER
inner命名空间前缀
#define MSTL_END_NAMESPACE__
结束全局命名空间MSTL
#define MSTL_BEGIN_NAMESPACE__
开始全局命名空间MSTL
#define MSTL_BEGIN_INNER__
开始inner命名空间
constexpr Iterator1 search(Iterator1 first1, Iterator1 last1, Iterator2 first2, Iterator2 last2, BinaryPredicate binary_pred)
在范围内查找子序列的第一次出现
constexpr Iterator1 find_end(Iterator1 first1, Iterator1 last1, Iterator2 first2, Iterator2 last2)
在范围内查找子序列的最后一次出现
constexpr Iterator search_n(Iterator first, Iterator last, const size_t count, const T &value)
查找范围内连续n个等于指定值的子序列
constexpr Iterator1 find_first_of(Iterator1 first1, Iterator1 last1, Iterator2 first2, Iterator2 last2, BinaryPredicate comp)
查找范围内第一个出现在指定集合中的元素
constexpr bool all_of(Iterator first, Iterator last, Predicate pred)
检查所有元素是否都满足谓词
constexpr bool any_of(Iterator first, Iterator last, Predicate pred)
检查是否有任意元素满足谓词
constexpr bool none_of(Iterator first, Iterator last, Predicate pred)
检查是否没有元素满足谓词
typename enable_if< Test, T >::type enable_if_t
enable_if的便捷别名
MSTL反向迭代器
相等比较仿函数
大于比较仿函数
小于比较仿函数