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
78equal(Iterator1 first1, Iterator1 last1,
79 Iterator2 first2)
noexcept(
noexcept(_NEFORCE
equal(first1, last1, first2, _NEFORCE
equal_to<>()))) {
97template <
typename Iterator,
typename T,
typename Compare>
113template <
typename Iterator,
typename T>
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;
145constexpr const T&
max(
const T& a,
const T& b)
noexcept(
noexcept(a < b)) {
146 return a < b ? b : a;
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;
175constexpr const T&
min(
const T& a,
const T& b)
noexcept(
noexcept(b < a)) {
176 return b < a ? b : a;
192template <
typename T,
typename Compare>
193constexpr T
median(
const T& a,
const T& b,
const T& c, Compare comp)
noexcept(
noexcept(comp(a, b))) {
197 }
else if (comp(a, c)) {
202 }
else if (comp(a, c)) {
204 }
else if (comp(b, c)) {
220constexpr T
median(
const T& a,
const T& b,
const T& c)
noexcept(
noexcept(a < b)) {
236template <
typename Iterator,
typename Compare>
237constexpr Iterator
max_element(Iterator first, Iterator last, Compare comp) {
242 Iterator result = first;
243 while (++first != last) {
244 if (comp(*result, *first)) {
258template <
typename Iterator>
270constexpr const T&
max(std::initializer_list<T>
list) {
286template <
typename Iterator,
typename Compare>
287constexpr Iterator
min_element(Iterator first, Iterator last, Compare comp) {
292 Iterator result = first;
293 while (++first != last) {
294 if (comp(*first, *result)) {
308template <
typename Iterator>
320constexpr const T&
min(std::initializer_list<T>
list) {
336template <
typename Iterator,
typename Compare>
343 Iterator
min = first;
344 Iterator
max = first;
346 while (first != last) {
347 Iterator
next = first;
350 if (comp(*first, *
min)) {
352 }
else if (!comp(*first, *
max)) {
357 if (comp(*
next, *first)) {
361 if (!comp(*first, *
max)) {
365 if (comp(*first, *
min)) {
385template <
typename Iterator>
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)) {
412 if (comp(upper, value)) {
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<>());
448template <
typename Iterator1,
typename Iterator2,
typename Compare>
449NEFORCE_NODISCARD
constexpr bool
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)) {
460 if (comp(*first2, *first1)) {
464 return first1 == last1 && first2 != last2;
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);
478 return result != 0 ? result < 0 : len1 < len2;
481template <
typename Iterator1,
typename Iterator2>
483__lexicographical_compare_aux(Iterator1 first1, Iterator1 last1, Iterator2 first2, Iterator2 last2)
noexcept(
503template <
typename Iterator1,
typename Iterator2>
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);
527template <
typename Iterator1,
typename Iterator2,
typename Compare>
530 "Iterator must be input_iterator");
531 while (first1 != last1 && comp(*first1, *first2)) {
535 return _NEFORCE
make_pair(first1, first2);
547template <
typename Iterator1,
typename Iterator2>
556NEFORCE_END_NAMESPACE__
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的便捷别名