1#ifndef NEFORCE_CORE_ALGORITHM_COMPARE_HPP__
2#define NEFORCE_CORE_ALGORITHM_COMPARE_HPP__
12#include <initializer_list>
16#ifdef NEFORCE_PLATFORM_WINDOWS
24NEFORCE_BEGIN_NAMESPACE__
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)) {
76template <
typename Iterator1,
typename Iterator2>
77NEFORCE_NODISCARD
constexpr bool equal(Iterator1 first1, Iterator1 last1, Iterator2 first2)
noexcept(
96template <
typename Iterator,
typename T,
typename Compare>
100 auto len = _NEFORCE
distance(first, last);
102 Iterator middle, left, right;
107 _NEFORCE
advance(middle, half);
109 if (comp(*middle, value)) {
112 len = len - half - 1;
113 }
else if (comp(value, *middle)) {
116 left = _NEFORCE
lower_bound(first, middle, value, comp);
118 right = _NEFORCE
upper_bound(++middle, first, value, comp);
134template <
typename Iterator,
typename T>
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;
166constexpr const T&
max(
const T& a,
const T& b)
noexcept(
noexcept(a < b)) {
167 return a < b ? b : a;
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;
196constexpr const T&
min(
const T& a,
const T& b)
noexcept(
noexcept(b < a)) {
197 return b < a ? b : a;
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))) {
218 }
else if (comp(a, c)) {
223 }
else if (comp(a, c)) {
225 }
else if (comp(b, c)) {
241constexpr const T&
median(
const T& a,
const T& b,
242 const T& c)
noexcept(
noexcept(_NEFORCE
median(a, b, c, _NEFORCE
less<T>()))) {
259template <
typename Iterator,
typename Compare>
270 for (; first != last; ++first) {
271 if (comp(*first, min_val)) {
273 }
else if (!comp(*first, max_val)) {
277 return _NEFORCE
make_pair(min_val, max_val);
287template <
typename Iterator>
305template <
typename Iterator,
typename Compare>
306constexpr Iterator
max_element(Iterator first, Iterator last, Compare comp) {
311 Iterator result = first;
312 while (++first != last) {
313 if (comp(*result, *first)) {
327template <
typename Iterator>
339constexpr const T&
max(std::initializer_list<T>
list) {
356template <
typename Iterator,
typename Compare>
357constexpr Iterator
min_element(Iterator first, Iterator last, Compare comp) {
362 Iterator result = first;
363 while (++first != last) {
364 if (comp(*first, *result)) {
378template <
typename Iterator>
390constexpr const T&
min(std::initializer_list<T>
list) {
406template <
typename Iterator,
typename Compare>
421template <
typename Iterator>
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)) {
449 }
else if (comp(upper, value)) {
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>());
487template <
typename Iterator1,
typename Iterator2,
typename Compare>
488NEFORCE_NODISCARD
constexpr bool
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)) {
499 if (comp(*first2, *first1)) {
503 return first1 == last1 && first2 != last2;
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);
530 return result != 0 ? result < 0 : len1 < len2;
543template <
typename Iterator1,
typename Iterator2>
545__lexicographical_compare_aux(Iterator1 first1, Iterator1 last1, Iterator2 first2, Iterator2 last2)
noexcept(
noexcept(
565template <
typename Iterator1,
typename Iterator2>
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);
590template <
typename Iterator1,
typename Iterator2,
typename Compare>
593 "Iterator must be input_iterator");
594 while (first1 != last1 && comp(*first1, *first2)) {
610template <
typename Iterator1,
typename Iterator2>
619NEFORCE_END_NAMESPACE__
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的便捷别名