NexusForce 1.0.0
A Modern C++ Library with extended functionality, web components, and utility libraries
载入中...
搜索中...
未找到
compare.hpp
浏览该文件的文档.
1#ifndef NEFORCE_CORE_ALGORITHM_COMPARE_HPP__
2#define NEFORCE_CORE_ALGORITHM_COMPARE_HPP__
3
11
12#include <initializer_list>
16#ifdef NEFORCE_PLATFORM_WINDOWS
17# ifdef max
18# undef max
19# endif
20# ifdef min
21# undef min
22# endif
23#endif
24NEFORCE_BEGIN_NAMESPACE__
25
31
37
53template <typename Iterator1, typename Iterator2, typename BinaryPredicate>
54NEFORCE_NODISCARD constexpr bool equal(Iterator1 first1, Iterator1 last1, Iterator2 first2,
55 BinaryPredicate binary_pred) noexcept(noexcept(++first1) && noexcept(++first2) &&
56 noexcept(binary_pred(*first1, *first2))) {
58 "Iterator must be input_iterator");
59 for (; first1 != last1; ++first1, ++first2) {
60 if (!binary_pred(*first1, *first2)) {
61 return false;
62 }
63 }
64 return true;
65}
66
76template <typename Iterator1, typename Iterator2>
77NEFORCE_NODISCARD constexpr bool equal(Iterator1 first1, Iterator1 last1, Iterator2 first2) noexcept(
78 noexcept(_NEFORCE equal(first1, last1, first2, _NEFORCE equal_to<iter_value_t<Iterator1>>()))) {
79 return _NEFORCE equal(first1, last1, first2, _NEFORCE equal_to<iter_value_t<Iterator1>>());
80}
81
96template <typename Iterator, typename T, typename Compare>
97constexpr pair<Iterator, Iterator> equal_range(Iterator first, Iterator last, const T& value, Compare comp) {
98 static_assert(is_ranges_fwd_iter_v<Iterator>, "Iterator must be forward_iterator");
99
100 auto len = _NEFORCE distance(first, last);
101 auto half = len;
102 Iterator middle, left, right;
103
104 while (len > 0) {
105 half = len >> 1;
106 middle = first;
107 _NEFORCE advance(middle, half);
108
109 if (comp(*middle, value)) {
110 first = middle;
111 ++first;
112 len = len - half - 1;
113 } else if (comp(value, *middle)) {
114 len = half;
115 } else {
116 left = _NEFORCE lower_bound(first, middle, value, comp);
117 _NEFORCE advance(first, len);
118 right = _NEFORCE upper_bound(++middle, first, value, comp);
119 return pair<Iterator, Iterator>(left, right);
120 }
121 }
122 return pair<Iterator, Iterator>(first, first);
123}
124
134template <typename Iterator, typename T>
135constexpr pair<Iterator, Iterator> equal_range(Iterator first, Iterator last, const T& value) {
136 return _NEFORCE equal_range(first, last, value, _NEFORCE less<iter_value_t<Iterator>>());
137}
138
139
153template <typename T, typename Compare>
154constexpr const T& max(const T& a, const T& b, Compare comp) noexcept(noexcept(comp(a, b))) {
155 return comp(a, b) ? b : a;
156}
157
165template <typename T>
166constexpr const T& max(const T& a, const T& b) noexcept(noexcept(a < b)) {
167 return a < b ? b : a;
168}
169
183template <typename T, typename Compare>
184constexpr const T& min(const T& a, const T& b, Compare comp) noexcept(noexcept(comp(b, a))) {
185 return comp(b, a) ? b : a;
186}
187
195template <typename T>
196constexpr const T& min(const T& a, const T& b) noexcept(noexcept(b < a)) {
197 return b < a ? b : a;
198}
199
213template <typename T, typename Compare>
214constexpr const T& median(const T& a, const T& b, const T& c, Compare comp) noexcept(noexcept(comp(a, b))) {
215 if (comp(a, b)) {
216 if (comp(b, c)) {
217 return b;
218 } else if (comp(a, c)) {
219 return c;
220 } else {
221 return a;
222 }
223 } else if (comp(a, c)) {
224 return a;
225 } else if (comp(b, c)) {
226 return c;
227 } else {
228 return b;
229 }
230}
231
240template <typename T>
241constexpr const T& median(const T& a, const T& b,
242 const T& c) noexcept(noexcept(_NEFORCE median(a, b, c, _NEFORCE less<T>()))) {
243 return _NEFORCE median(a, b, c, _NEFORCE less<T>());
244}
245
246
259template <typename Iterator, typename Compare>
260pair<iter_value_t<Iterator>, iter_value_t<Iterator>> constexpr minmax(Iterator first, Iterator last, Compare comp) {
261 static_assert(is_ranges_input_iter_v<Iterator>, "Iterator must be input_iterator");
262 using T = iter_value_t<Iterator>;
263 if (first == last) {
264 return _NEFORCE make_pair(T(), T());
265 }
266 T min_val = *first;
267 T max_val = *first;
268
269 ++first;
270 for (; first != last; ++first) {
271 if (comp(*first, min_val)) {
272 min_val = *first;
273 } else if (!comp(*first, max_val)) {
274 max_val = *first;
275 }
276 }
277 return _NEFORCE make_pair(min_val, max_val);
278}
279
287template <typename Iterator>
288constexpr pair<iter_value_t<Iterator>, iter_value_t<Iterator>> minmax(Iterator first, Iterator last) {
289 return _NEFORCE minmax(first, last, _NEFORCE less<iter_value_t<Iterator>>());
290}
291
292
305template <typename Iterator, typename Compare>
306constexpr Iterator max_element(Iterator first, Iterator last, Compare comp) {
307 static_assert(is_ranges_input_iter_v<Iterator>, "Iterator must be input_iterator");
308 if (first == last) {
309 return first;
310 }
311 Iterator result = first;
312 while (++first != last) {
313 if (comp(*result, *first)) {
314 result = first;
315 }
316 }
317 return result;
318}
319
327template <typename Iterator>
328constexpr Iterator max_element(Iterator first, Iterator last) {
329 return _NEFORCE max_element(first, last, _NEFORCE less<iter_value_t<Iterator>>());
330}
331
338template <typename T>
339constexpr const T& max(std::initializer_list<T> list) {
340 auto iter = _NEFORCE max_element(list.begin(), list.end());
341 return *iter;
342}
343
356template <typename Iterator, typename Compare>
357constexpr Iterator min_element(Iterator first, Iterator last, Compare comp) {
358 static_assert(is_ranges_input_iter_v<Iterator>, "Iterator must be input_iterator");
359 if (first == last) {
360 return first;
361 }
362 Iterator result = first;
363 while (++first != last) {
364 if (comp(*first, *result)) {
365 result = first;
366 }
367 }
368 return result;
369}
370
378template <typename Iterator>
379constexpr Iterator min_element(Iterator first, Iterator last) {
380 return _NEFORCE min_element(first, last, _NEFORCE less<iter_value_t<Iterator>>());
381}
382
389template <typename T>
390constexpr const T& min(std::initializer_list<T> list) {
391 return *_NEFORCE min_element(list.begin(), list.end());
392}
393
406template <typename Iterator, typename Compare>
407constexpr pair<Iterator, Iterator> minmax_element(Iterator first, Iterator last, Compare comp) {
408 static_assert(is_ranges_input_iter_v<Iterator>, "Iterator must be input_iterator");
409 Iterator min = _NEFORCE min_element(first, last, comp);
410 Iterator max = _NEFORCE max_element(first, last, comp);
411 return _NEFORCE make_pair(min, max);
412}
413
421template <typename Iterator>
422constexpr pair<Iterator, Iterator> minmax_element(Iterator first, Iterator last) {
423 return _NEFORCE minmax_element(first, last, _NEFORCE less<iter_value_t<Iterator>>());
424}
425
426
444template <typename T, typename Compare>
445constexpr const T& clamp(const T& value, const T& lower, const T& upper,
446 Compare comp) noexcept(noexcept(comp(value, lower))) {
447 if (comp(value, lower)) {
448 return lower;
449 } else if (comp(upper, value)) {
450 return upper;
451 }
452 return value;
453}
454
463template <typename T>
464constexpr const T& clamp(const T& value, const T& lower,
465 const T& upper) noexcept(noexcept(_NEFORCE clamp(value, lower, upper, _NEFORCE less<T>()))) {
466 return _NEFORCE clamp(value, lower, upper, _NEFORCE less<T>());
467}
468
469
487template <typename Iterator1, typename Iterator2, typename Compare>
488NEFORCE_NODISCARD constexpr bool
489lexicographical_compare(Iterator1 first1, Iterator1 last1, Iterator2 first2, Iterator2 last2,
490 Compare comp) noexcept(noexcept(++first1) && noexcept(++first2) &&
491 noexcept(comp(*first1, *first2)) &&
492 noexcept(first1 == last1 && first2 != last2)) {
494 "Iterator must be input_iterator");
495 for (; first1 != last1 && first2 != last2; ++first1, ++first2) {
496 if (comp(*first1, *first2)) {
497 return true;
498 }
499 if (comp(*first2, *first1)) {
500 return false;
501 }
502 }
503 return first1 == last1 && first2 != last2;
504}
505
507NEFORCE_BEGIN_INNER__
508
521template <typename Iterator1, typename Iterator2>
523__lexicographical_compare_aux(Iterator1 first1, Iterator1 last1, Iterator2 first2, Iterator2 last2) noexcept {
524 const auto len1 = static_cast<size_t>(last1 - first1);
525 const auto len2 = static_cast<size_t>(last2 - first2);
526 const size_t clp = _NEFORCE min(len1, len2);
527
528 const int result = _NEFORCE memory_compare(_NEFORCE addressof(*first1), _NEFORCE addressof(*first2),
529 clp * sizeof(iter_value_t<Iterator1>));
530 return result != 0 ? result < 0 : len1 < len2;
531}
532
543template <typename Iterator1, typename Iterator2>
545__lexicographical_compare_aux(Iterator1 first1, Iterator1 last1, Iterator2 first2, Iterator2 last2) noexcept(noexcept(
546 _NEFORCE lexicographical_compare(first1, last1, first2, last2, _NEFORCE less<iter_value_t<Iterator1>>()))) {
547 return _NEFORCE lexicographical_compare(first1, last1, first2, last2, _NEFORCE less<iter_value_t<Iterator1>>());
548}
549
550NEFORCE_END_INNER__
552
565template <typename Iterator1, typename Iterator2>
566NEFORCE_NODISCARD constexpr bool lexicographical_compare(
567 Iterator1 first1, Iterator1 last1, Iterator2 first2,
568 Iterator2 last2) noexcept(noexcept(inner::__lexicographical_compare_aux(first1, last1, first2, last2))) {
570 "Iterator must be input_iterator");
571 return inner::__lexicographical_compare_aux(first1, last1, first2, last2);
572}
573
574
590template <typename Iterator1, typename Iterator2, typename Compare>
591pair<Iterator1, Iterator2> constexpr mismatch(Iterator1 first1, Iterator1 last1, Iterator2 first2, Compare comp) {
593 "Iterator must be input_iterator");
594 while (first1 != last1 && comp(*first1, *first2)) {
595 ++first1;
596 ++first2;
597 }
598 return _NEFORCE make_pair<Iterator1, Iterator2>(first1, first2);
599}
600
610template <typename Iterator1, typename Iterator2>
611constexpr pair<Iterator1, Iterator2> mismatch(Iterator1 first1, Iterator1 last1, Iterator2 first2) {
612 return _NEFORCE mismatch(first1, last1, first2, _NEFORCE equal_to<iter_value_t<Iterator1>>());
613}
614 // CompareAlgorithms
616 // StandardAlgorithms
618
619NEFORCE_END_NAMESPACE__
620#endif // NEFORCE_CORE_ALGORITHM_COMPARE_HPP__
双向链表容器
NEFORCE_NODISCARD iterator begin() noexcept
获取起始迭代器
NEFORCE_NODISCARD iterator end() noexcept
获取结束迭代器
NEFORCE_NODISCARD constexpr T * addressof(T &x) noexcept
获取对象的地址
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 const T & max(const T &a, const T &b, Compare comp) noexcept(noexcept(comp(a, b)))
返回两个值中的较大者
constexpr pair< Iterator, Iterator > equal_range(Iterator first, Iterator last, const T &value, Compare comp)
查找值的相等范围
NEFORCE_NODISCARD constexpr bool equal(Iterator1 first1, Iterator1 last1, Iterator2 first2, BinaryPredicate binary_pred) noexcept(noexcept(++first1) &&noexcept(++first2) &&noexcept(binary_pred(*first1, *first2)))
比较两个范围是否相等
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)
查找范围中的最小值和最大值
NEFORCE_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 Iterator min_element(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)))
返回两个值中的较小者
constexpr Iterator max_element(Iterator first, Iterator last, Compare comp)
查找范围中的最大元素
NEFORCE_INLINE17 constexpr bool is_ranges_input_iter_v
检查是否为范围输入迭代器
NEFORCE_INLINE17 constexpr bool is_ranges_fwd_iter_v
检查是否为范围前向迭代器
NEFORCE_INLINE17 constexpr bool is_ranges_cot_iter_v
检查是否为范围连续迭代器
constexpr void advance(Iterator &i, Distance n)
将迭代器前进指定距离
constexpr iter_difference_t< Iterator > distance(Iterator first, Iterator last)
计算两个迭代器之间的距离
typename iterator_traits< Iterator >::value_type iter_value_t
获取迭代器的值类型
NEFORCE_PURE_FUNCTION NEFORCE_CONSTEXPR14 int memory_compare(const void *lhs, const void *rhs, size_t count) noexcept
比较两个内存区域的内容
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的便捷别名
内存操作函数
键值对
查找和搜索算法
相等比较仿函数
小于比较仿函数
存储两个值的元组对