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
78equal(Iterator1 first1, Iterator1 last1,
79 Iterator2 first2) noexcept(noexcept(_NEFORCE equal(first1, last1, first2, _NEFORCE equal_to<>()))) {
80 return _NEFORCE equal(first1, last1, first2, _NEFORCE equal_to<>());
81}
82
97template <typename Iterator, typename T, typename Compare>
98constexpr pair<Iterator, Iterator> equal_range(Iterator first, Iterator last, const T& value, Compare comp) {
99 static_assert(is_ranges_fwd_iter_v<Iterator>, "Iterator must be forward_iterator");
100 return _NEFORCE make_pair(_NEFORCE lower_bound(first, last, value, comp),
101 _NEFORCE upper_bound(first, last, value, comp));
102}
103
113template <typename Iterator, typename T>
114constexpr pair<Iterator, Iterator> equal_range(Iterator first, Iterator last, const T& value) {
115 return _NEFORCE equal_range(first, last, value, _NEFORCE less<>());
116}
117
118
132template <typename T, typename Compare>
133constexpr const T& max(const T& a, const T& b, Compare comp) noexcept(noexcept(comp(a, b))) {
134 return comp(a, b) ? b : a;
135}
136
144template <typename T>
145constexpr const T& max(const T& a, const T& b) noexcept(noexcept(a < b)) {
146 return a < b ? b : a;
147}
148
162template <typename T, typename Compare>
163constexpr const T& min(const T& a, const T& b, Compare comp) noexcept(noexcept(comp(b, a))) {
164 return comp(b, a) ? b : a;
165}
166
174template <typename T>
175constexpr const T& min(const T& a, const T& b) noexcept(noexcept(b < a)) {
176 return b < a ? b : a;
177}
178
192template <typename T, typename Compare>
193constexpr T median(const T& a, const T& b, const T& c, Compare comp) noexcept(noexcept(comp(a, b))) {
194 if (comp(a, b)) {
195 if (comp(b, c)) {
196 return b;
197 } else if (comp(a, c)) {
198 return c;
199 } else {
200 return a;
201 }
202 } else if (comp(a, c)) {
203 return a;
204 } else if (comp(b, c)) {
205 return c;
206 } else {
207 return b;
208 }
209}
210
219template <typename T>
220constexpr T median(const T& a, const T& b, const T& c) noexcept(noexcept(a < b)) {
221 return _NEFORCE median(a, b, c, _NEFORCE less<>());
222}
223
236template <typename Iterator, typename Compare>
237constexpr Iterator max_element(Iterator first, Iterator last, Compare comp) {
238 static_assert(is_ranges_input_iter_v<Iterator>, "Iterator must be input_iterator");
239 if (first == last) {
240 return first;
241 }
242 Iterator result = first;
243 while (++first != last) {
244 if (comp(*result, *first)) {
245 result = first;
246 }
247 }
248 return result;
249}
250
258template <typename Iterator>
259constexpr Iterator max_element(Iterator first, Iterator last) {
260 return _NEFORCE max_element(first, last, _NEFORCE less<>());
261}
262
269template <typename T>
270constexpr const T& max(std::initializer_list<T> list) {
271 return *_NEFORCE max_element(list.begin(), list.end());
272}
273
286template <typename Iterator, typename Compare>
287constexpr Iterator min_element(Iterator first, Iterator last, Compare comp) {
288 static_assert(is_ranges_input_iter_v<Iterator>, "Iterator must be input_iterator");
289 if (first == last) {
290 return first;
291 }
292 Iterator result = first;
293 while (++first != last) {
294 if (comp(*first, *result)) {
295 result = first;
296 }
297 }
298 return result;
299}
300
308template <typename Iterator>
309constexpr Iterator min_element(Iterator first, Iterator last) {
310 return _NEFORCE min_element(first, last, _NEFORCE less<>());
311}
312
319template <typename T>
320constexpr const T& min(std::initializer_list<T> list) {
321 return *_NEFORCE min_element(list.begin(), list.end());
322}
323
336template <typename Iterator, typename Compare>
337constexpr pair<Iterator, Iterator> minmax_element(Iterator first, Iterator last, Compare comp) {
338 static_assert(is_ranges_input_iter_v<Iterator>, "Iterator must be input_iterator");
339 if (first == last) {
340 return _NEFORCE make_pair(first, first);
341 }
342
343 Iterator min = first;
344 Iterator max = first;
345 ++first;
346 while (first != last) {
347 Iterator next = first;
348 ++next;
349 if (next == last) {
350 if (comp(*first, *min)) {
351 min = first;
352 } else if (!comp(*first, *max)) {
353 max = first;
354 }
355 break;
356 }
357 if (comp(*next, *first)) {
358 if (comp(*next, *min)) {
359 min = next;
360 }
361 if (!comp(*first, *max)) {
362 max = first;
363 }
364 } else {
365 if (comp(*first, *min)) {
366 min = first;
367 }
368 if (!comp(*next, *max)) {
369 max = next;
370 }
371 }
372 first = next;
373 ++first;
374 }
375 return _NEFORCE make_pair(min, max);
376}
377
385template <typename Iterator>
386constexpr pair<Iterator, Iterator> minmax_element(Iterator first, Iterator last) {
387 return _NEFORCE minmax_element(first, last, _NEFORCE less<>());
388}
389
407template <typename T, typename Compare>
408constexpr T clamp(const T& value, const T& lower, const T& upper, Compare comp) noexcept(noexcept(comp(value, lower))) {
409 if (comp(value, lower)) {
410 return lower;
411 }
412 if (comp(upper, value)) {
413 return upper;
414 }
415 return value;
416}
417
426template <typename T>
427constexpr T clamp(const T& value, const T& lower, const T& upper) noexcept(noexcept(lower < upper)) {
428 return _NEFORCE clamp(value, lower, upper, _NEFORCE less<>());
429}
430
448template <typename Iterator1, typename Iterator2, typename Compare>
449NEFORCE_NODISCARD constexpr bool
450lexicographical_compare(Iterator1 first1, Iterator1 last1, Iterator2 first2, Iterator2 last2,
451 Compare comp) noexcept(noexcept(++first1) && noexcept(++first2) &&
452 noexcept(comp(*first1, *first2)) &&
453 noexcept(first1 == last1 && first2 != last2)) {
455 "Iterator must be input_iterator");
456 for (; first1 != last1 && first2 != last2; ++first1, ++first2) {
457 if (comp(*first1, *first2)) {
458 return true;
459 }
460 if (comp(*first2, *first1)) {
461 return false;
462 }
463 }
464 return first1 == last1 && first2 != last2;
465}
466
468NEFORCE_BEGIN_INNER__
469
470template <typename Iterator1, typename Iterator2>
472__lexicographical_compare_aux(Iterator1 first1, Iterator1 last1, Iterator2 first2, Iterator2 last2) noexcept {
473 const auto len1 = static_cast<size_t>(last1 - first1);
474 const auto len2 = static_cast<size_t>(last2 - first2);
475 const size_t clp = _NEFORCE min(len1, len2);
476 const int result = _NEFORCE memory_compare(_NEFORCE addressof(*first1), _NEFORCE addressof(*first2),
477 clp * sizeof(iter_value_t<Iterator1>));
478 return result != 0 ? result < 0 : len1 < len2;
479}
480
481template <typename Iterator1, typename Iterator2>
483__lexicographical_compare_aux(Iterator1 first1, Iterator1 last1, Iterator2 first2, Iterator2 last2) noexcept(
484 noexcept(_NEFORCE lexicographical_compare(first1, last1, first2, last2, _NEFORCE less<>()))) {
485 return _NEFORCE lexicographical_compare(first1, last1, first2, last2, _NEFORCE less<>());
486}
487
488NEFORCE_END_INNER__
490
503template <typename Iterator1, typename Iterator2>
504NEFORCE_NODISCARD constexpr bool lexicographical_compare(
505 Iterator1 first1, Iterator1 last1, Iterator2 first2,
506 Iterator2 last2) noexcept(noexcept(inner::__lexicographical_compare_aux(first1, last1, first2, last2))) {
508 "Iterator must be input_iterator");
509 return inner::__lexicographical_compare_aux(first1, last1, first2, last2);
510}
511
527template <typename Iterator1, typename Iterator2, typename Compare>
528constexpr pair<Iterator1, Iterator2> mismatch(Iterator1 first1, Iterator1 last1, Iterator2 first2, Compare comp) {
530 "Iterator must be input_iterator");
531 while (first1 != last1 && comp(*first1, *first2)) {
532 ++first1;
533 ++first2;
534 }
535 return _NEFORCE make_pair(first1, first2);
536}
537
547template <typename Iterator1, typename Iterator2>
548constexpr pair<Iterator1, Iterator2> mismatch(Iterator1 first1, Iterator1 last1, Iterator2 first2) {
549 return _NEFORCE mismatch(first1, last1, first2, _NEFORCE equal_to<>());
550}
551 // CompareAlgorithms
553 // StandardAlgorithms
555
556NEFORCE_END_NAMESPACE__
557#endif // NEFORCE_CORE_ALGORITHM_COMPARE_HPP__
双向链表容器
iterator begin() noexcept
获取起始迭代器
iterator end() noexcept
获取结束迭代器
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)
查找值的相等范围
constexpr T clamp(const T &value, const T &lower, const T &upper, Compare comp) noexcept(noexcept(comp(value, lower)))
将值限制在指定范围内
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))
字典序比较两个范围
constexpr pair< Iterator1, Iterator2 > mismatch(Iterator1 first1, Iterator1 last1, Iterator2 first2, Compare comp)
查找两个范围中首个不匹配的元素
constexpr bool equal(Iterator1 first1, Iterator1 last1, Iterator2 first2, BinaryPredicate binary_pred) noexcept(noexcept(++first1) &&noexcept(++first2) &&noexcept(binary_pred(*first1, *first2)))
比较两个范围是否相等
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 T median(const T &a, const T &b, const T &c, Compare comp) noexcept(noexcept(comp(a, b)))
返回三个值的中位数
constexpr Iterator max_element(Iterator first, Iterator last, Compare comp)
查找范围中的最大元素
constexpr bool is_ranges_cot_iter_v
检查是否为范围连续迭代器
constexpr bool is_ranges_fwd_iter_v
检查是否为范围前向迭代器
constexpr bool is_ranges_input_iter_v
检查是否为范围输入迭代器
constexpr Iterator next(Iterator iter, iter_difference_t< Iterator > n=1)
获取迭代器的后一个位置
typename iterator_traits< Iterator >::value_type iter_value_t
获取迭代器的值类型
constexpr 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的便捷别名
内存操作函数
键值对
查找和搜索算法
相等比较仿函数
小于比较仿函数
存储两个值的元组对