MSTL 1.4.0
A Modern C++ Library with extended functionality, web components, and utility libraries
载入中...
搜索中...
未找到
compare.hpp
浏览该文件的文档.
1#ifndef MSTL_CORE_ALGORITHM_COMPARE_HPP__
2#define MSTL_CORE_ALGORITHM_COMPARE_HPP__
3
11
15#include <initializer_list>
16#ifdef MSTL_PLATFORM_WINDOWS__
17#ifdef max
18#undef max
19#endif
20#ifdef min
21#undef min
22#endif
23#endif
25
31
47template <typename Iterator1, typename Iterator2, typename BinaryPredicate, enable_if_t<
49MSTL_NODISCARD constexpr bool equal(Iterator1 first1, Iterator1 last1, Iterator2 first2, BinaryPredicate binary_pred)
50noexcept(noexcept(++first1) && noexcept(++first2) && noexcept(binary_pred(*first1, *first2))) {
51 for (; first1 != last1; ++first1, ++first2) {
52 if (!binary_pred(*first1, *first2)) return false;
53 }
54 return true;
55}
56
66template <typename Iterator1, typename Iterator2>
67MSTL_NODISCARD constexpr bool equal(Iterator1 first1, Iterator1 last1, Iterator2 first2)
68noexcept(noexcept(_MSTL equal(first1, last1, first2, _MSTL equal_to<iter_value_t<Iterator1>>()))) {
69 return _MSTL equal(first1, last1, first2, _MSTL equal_to<iter_value_t<Iterator1>>());
70}
71
86template <typename Iterator, typename T, typename Compare, enable_if_t<is_ranges_fwd_iter_v<Iterator>, int> = 0>
87constexpr pair<Iterator, Iterator> equal_range(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, left, right;
92 while (len > 0) {
93 half = len >> 1;
94 middle = first;
95 _MSTL advance(middle, half);
96 if (comp(*middle, value)) {
97 first = middle;
98 ++first;
99 len = len - half - 1;
100 } else if (comp(value, *middle)) {
101 len = half;
102 } else {
103 left = _MSTL lower_bound(first, middle, value, comp);
104 _MSTL advance(first, len);
105 right = _MSTL upper_bound(++middle, first, value, comp);
106 return pair<Iterator, Iterator>(left, right);
107 }
108 }
109 return pair<Iterator, Iterator>(first, first);
110}
111
121template <typename Iterator, typename T>
122constexpr pair<Iterator, Iterator> equal_range(Iterator first, Iterator last, const T& value) {
123 return _MSTL equal_range(first, last, value, _MSTL less<iter_value_t<Iterator>>());
124}
125
126
140template <typename T, typename Compare>
141constexpr const T& max(const T& a, const T& b, Compare comp)
142noexcept(noexcept(comp(a, b))) {
143 return comp(a, b) ? b : a;
144}
145
153template <typename T>
154constexpr const T& max(const T& a, const T& b)
155noexcept(noexcept(a < b)) {
156 return a < b ? b : a;
157}
158
172template <typename T, typename Compare>
173constexpr const T& min(const T& a, const T& b, Compare comp)
174noexcept(noexcept(comp(b, a))) {
175 return comp(b, a) ? b : a;
176}
177
185template <typename T>
186constexpr const T& min(const T& a, const T& b)
187noexcept(noexcept(b < a)) {
188 return b < a ? b : a;
189}
190
204template <typename T, typename Compare>
205constexpr const T& median(const T& a, const T& b, const T& c, Compare comp)
206noexcept(noexcept(comp(a, b))) {
207 if (comp(a, b)) {
208 if (comp(b, c))
209 return b;
210 else if (comp(a, c))
211 return c;
212 else
213 return a;
214 }
215 else if (comp(a, c))
216 return a;
217 else if (comp(b, c))
218 return c;
219 else
220 return b;
221}
222
231template <typename T>
232constexpr const T& median(const T& a, const T& b, const T& c)
233noexcept(noexcept(_MSTL median(a, b, c, _MSTL less<T>()))) {
234 return _MSTL median(a, b, c, _MSTL less<T>());
235}
236
237
250template <typename Iterator, typename Compare, enable_if_t<is_ranges_input_iter_v<Iterator>, int> = 0>
252constexpr minmax(Iterator first, Iterator last, Compare comp) {
253 using T = iter_value_t<Iterator>;
254 if (first == last) {
255 return _MSTL make_pair(T(), T());
256 }
257 T min_val = *first;
258 T max_val = *first;
259
260 ++first;
261 for (; first != last; ++first) {
262 if (comp(*first, min_val))
263 min_val = *first;
264 else if (!comp(*first, max_val))
265 max_val = *first;
266 }
267 return _MSTL make_pair(min_val, max_val);
268}
269
277template <typename Iterator>
278constexpr pair<iter_value_t<Iterator>, iter_value_t<Iterator>> minmax(Iterator first, Iterator last) {
279 return _MSTL minmax(first, last, _MSTL less<iter_value_t<Iterator>>());
280}
281
282
295template <typename Iterator, typename Compare, enable_if_t<is_ranges_input_iter_v<Iterator>, int> = 0>
296constexpr Iterator max_element(Iterator first, Iterator last, Compare comp) {
297 if (first == last) return first;
298 Iterator result = first;
299 while (++first != last)
300 if (comp(*result, *first)) result = first;
301 return result;
302}
303
311template <typename Iterator>
312constexpr Iterator max_element(Iterator first, Iterator last) {
313 return _MSTL max_element(first, last, _MSTL less<iter_value_t<Iterator>>());
314}
315
322template <typename T>
323constexpr const T& max(std::initializer_list<T> list) {
324 auto iter = _MSTL max_element(list.begin(), list.end());
325 return *iter;
326}
327
340template <typename Iterator, typename Compare, enable_if_t<is_ranges_input_iter_v<Iterator>, int> = 0>
341constexpr Iterator min_element(Iterator first, Iterator last, Compare comp) {
342 if (first == last) return first;
343 Iterator result = first;
344 while (++first != last)
345 if (comp(*first, *result)) result = first;
346 return result;
347}
348
356template <typename Iterator>
357constexpr Iterator min_element(Iterator first, Iterator last) {
358 return _MSTL min_element(first, last, _MSTL less<iter_value_t<Iterator>>());
359}
360
367template <typename T>
368constexpr const T& min(std::initializer_list<T> list) {
369 return *_MSTL min_element(list.begin(), list.end());
370}
371
384template <typename Iterator, typename Compare, enable_if_t<is_ranges_input_iter_v<Iterator>, int> = 0>
385constexpr pair<Iterator, Iterator> minmax_element(Iterator first, Iterator last, Compare comp) {
386 Iterator min = _MSTL min_element(first, last, comp);
387 Iterator max = _MSTL max_element(first, last, comp);
388 return _MSTL make_pair(min, max);
389}
390
398template <typename Iterator>
399constexpr pair<Iterator, Iterator> minmax_element(Iterator first, Iterator last) {
400 return _MSTL minmax_element(first, last, _MSTL less<iter_value_t<Iterator>>());
401}
402
403
421template <typename T, typename Compare>
422constexpr const T& clamp(const T& value, const T& lower, const T& upper, Compare comp)
423noexcept(noexcept(comp(value, lower))) {
424 if (comp(value, lower))
425 return lower;
426 else if (comp(upper, value))
427 return upper;
428 return value;
429}
430
439template <typename T>
440constexpr const T& clamp(const T& value, const T& lower, const T& upper)
441noexcept(noexcept(_MSTL clamp(value, lower, upper, _MSTL less<T>()))) {
442 return _MSTL clamp(value, lower, upper, _MSTL less<T>());
443}
444
445
463template <typename Iterator1, typename Iterator2, typename Compare, enable_if_t<
465MSTL_NODISCARD constexpr bool lexicographical_compare(
466 Iterator1 first1, Iterator1 last1, Iterator2 first2, Iterator2 last2, Compare comp)
467noexcept(
468 noexcept(++first1) && noexcept(++first2) &&
469 noexcept(comp(*first1, *first2)) &&
470 noexcept(first1 == last1 && first2 != last2)
471 ) {
472 for (; first1 != last1 && first2 != last2; ++first1, ++first2) {
473 if (comp(*first1, *first2)) return true;
474 if (comp(*first2, *first1)) return false;
475 }
476 return first1 == last1 && first2 != last2;
477}
478
481
494template <typename Iterator1, typename Iterator2, enable_if_t<
496MSTL_NODISCARD constexpr bool __lexicographical_compare_aux(
497 Iterator1 first1, Iterator1 last1, Iterator2 first2, Iterator2 last2) noexcept {
498 const auto len1 = static_cast<size_t>(last1 - first1);
499 const auto len2 = static_cast<size_t>(last2 - first2);
500 const size_t clp = _MSTL min(len1, len2);
501
502 const int result = _MSTL memory_compare(
503 _MSTL addressof(*first1), _MSTL addressof(*first2),
504 clp * sizeof(iter_value_t<Iterator1>));
505 return result != 0 ? result < 0 : len1 < len2;
506}
507
518template <typename Iterator1, typename Iterator2, enable_if_t<
520MSTL_NODISCARD constexpr bool __lexicographical_compare_aux(
521 Iterator1 first1, Iterator1 last1, Iterator2 first2, Iterator2 last2)
522noexcept(noexcept(_MSTL lexicographical_compare(first1, last1, first2, last2, _MSTL less<iter_value_t<Iterator1>>()))) {
523 return _MSTL lexicographical_compare(first1, last1, first2, last2, _MSTL less<iter_value_t<Iterator1>>());
524}
525
528
541template <typename Iterator1, typename Iterator2, enable_if_t<
543MSTL_NODISCARD constexpr bool lexicographical_compare(
544 Iterator1 first1, Iterator1 last1, Iterator2 first2, Iterator2 last2)
545noexcept(noexcept(_INNER __lexicographical_compare_aux(first1, last1, first2, last2))) {
546 return _INNER __lexicographical_compare_aux(first1, last1, first2, last2);
547}
548
549
565template <typename Iterator1, typename Iterator2, typename Compare, enable_if_t<
568constexpr mismatch(Iterator1 first1, Iterator1 last1, Iterator2 first2, Compare comp) {
569 while (first1 != last1 && comp(*first1, *first2)) {
570 ++first1; ++first2;
571 }
572 return _MSTL make_pair<Iterator1, Iterator2>(first1, first2);
573}
574
584template <typename Iterator1, typename Iterator2>
585constexpr pair<Iterator1, Iterator2> mismatch(Iterator1 first1, Iterator1 last1, Iterator2 first2) {
586 return _MSTL mismatch(first1, last1, first2, _MSTL equal_to<iter_value_t<Iterator1>>());
587}
588 // CompareAlgorithms
590
592#endif // MSTL_CORE_ALGORITHM_COMPARE_HPP__
MSTL_NODISCARD constexpr T * addressof(T &x) noexcept
获取对象的地址
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 const T & max(const T &a, const T &b, Compare comp) noexcept(noexcept(comp(a, b)))
返回两个值中的较大者
MSTL_NODISCARD constexpr bool equal(Iterator1 first1, Iterator1 last1, Iterator2 first2, BinaryPredicate binary_pred) noexcept(noexcept(++first1) &&noexcept(++first2) &&noexcept(binary_pred(*first1, *first2)))
比较两个范围是否相等
constexpr Iterator max_element(Iterator first, Iterator last, Compare comp)
查找范围中的最大元素
constexpr Iterator min_element(Iterator first, Iterator last, Compare comp)
查找范围中的最小元素
MSTL_NODISCARD constexpr bool lexicographical_compare(Iterator1 first1, Iterator1 last1, Iterator2 first2, Iterator2 last2, Compare comp) noexcept(noexcept(++first1) &&noexcept(++first2) &&noexcept(comp(*first1, *first2)) &&noexcept(first1==last1 &&first2 !=last2))
字典序比较两个范围
pair< Iterator1, Iterator2 > constexpr mismatch(Iterator1 first1, Iterator1 last1, Iterator2 first2, Compare comp)
查找两个范围中首个不匹配的元素
constexpr pair< Iterator, Iterator > equal_range(Iterator first, Iterator last, const T &value, Compare comp)
查找值的相等范围
constexpr const T & median(const T &a, const T &b, const T &c, Compare comp) noexcept(noexcept(comp(a, b)))
返回三个值的中位数
constexpr const T & clamp(const T &value, const T &lower, const T &upper, Compare comp) noexcept(noexcept(comp(value, lower)))
将值限制在指定范围内
pair< iter_value_t< Iterator >, iter_value_t< Iterator > > constexpr minmax(Iterator first, Iterator last, Compare comp)
查找范围中的最小值和最大值
constexpr pair< Iterator, Iterator > minmax_element(Iterator first, Iterator last, Compare comp)
同时查找范围中的最小和最大元素
constexpr const T & min(const T &a, const T &b, Compare comp) noexcept(noexcept(comp(b, a)))
返回两个值中的较小者
MSTL_INLINE17 constexpr bool is_ranges_input_iter_v
检查是否为范围输入迭代器
MSTL_INLINE17 constexpr bool is_ranges_cot_iter_v
检查是否为范围连续迭代器
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
获取迭代器的差值类型
MSTL_PURE_FUNCTION MSTL_CONSTEXPR14 int memory_compare(const void *lhs, const void *rhs, size_t count) noexcept
比较两个内存区域的内容
#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 pair< unwrap_ref_decay_t< T1 >, unwrap_ref_decay_t< T2 > > make_pair(T1 &&x, T2 &&y) noexcept(conjunction< is_nothrow_constructible< unwrap_ref_decay_t< T1 >, T1 >, is_nothrow_constructible< unwrap_ref_decay_t< T2 >, T2 > >::value)
创建pair的辅助函数
typename enable_if< Test, T >::type enable_if_t
enable_if的便捷别名
MSTL内存操作函数
MSTL键值对
MSTL查找和搜索算法
相等比较仿函数
小于比较仿函数
存储两个值的元组对