1#ifndef MSTL_CORE_ALGORITHM_COMPARE_HPP__
2#define MSTL_CORE_ALGORITHM_COMPARE_HPP__
15#include <initializer_list>
16#ifdef MSTL_PLATFORM_WINDOWS__
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;
66template <
typename Iterator1,
typename Iterator2>
67MSTL_NODISCARD
constexpr bool equal(Iterator1 first1, Iterator1 last1, Iterator2 first2)
86template <
typename Iterator,
typename T,
typename Compare, enable_if_t<is_ranges_fwd_iter_v<Iterator>,
int> = 0>
91 Iterator middle, left, right;
96 if (comp(*middle, value)) {
100 }
else if (comp(value, *middle)) {
121template <
typename Iterator,
typename T>
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;
154constexpr const T&
max(
const T& a,
const T& b)
155noexcept(
noexcept(a < b)) {
156 return a < b ? b : a;
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;
186constexpr const T&
min(
const T& a,
const T& b)
187noexcept(
noexcept(b < a)) {
188 return b < a ? b : a;
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))) {
232constexpr const T&
median(
const T& a,
const T& b,
const T& c)
250template <
typename Iterator,
typename Compare, enable_if_t<is_ranges_input_iter_v<Iterator>,
int> = 0>
252constexpr minmax(Iterator first, Iterator last, Compare comp) {
261 for (; first != last; ++first) {
262 if (comp(*first, min_val))
264 else if (!comp(*first, max_val))
277template <
typename Iterator>
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;
311template <
typename Iterator>
323constexpr const T&
max(std::initializer_list<T> list) {
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;
356template <
typename Iterator>
368constexpr const T&
min(std::initializer_list<T> list) {
384template <
typename Iterator,
typename Compare, enable_if_t<is_ranges_input_iter_v<Iterator>,
int> = 0>
398template <
typename Iterator>
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))
426 else if (comp(upper, value))
440constexpr const T&
clamp(
const T& value,
const T& lower,
const T& upper)
463template <
typename Iterator1,
typename Iterator2,
typename Compare,
enable_if_t<
466 Iterator1 first1, Iterator1 last1, Iterator2 first2, Iterator2 last2, Compare comp)
468 noexcept(++first1) &&
noexcept(++first2) &&
469 noexcept(comp(*first1, *first2)) &&
470 noexcept(first1 == last1 && first2 != last2)
472 for (; first1 != last1 && first2 != last2; ++first1, ++first2) {
473 if (comp(*first1, *first2))
return true;
474 if (comp(*first2, *first1))
return false;
476 return first1 == last1 && first2 != last2;
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);
505 return result != 0 ? result < 0 : len1 < len2;
518template <
typename Iterator1,
typename Iterator2,
enable_if_t<
520MSTL_NODISCARD
constexpr bool __lexicographical_compare_aux(
521 Iterator1 first1, Iterator1 last1, Iterator2 first2, Iterator2 last2)
541template <
typename Iterator1,
typename Iterator2,
enable_if_t<
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);
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)) {
584template <
typename Iterator1,
typename Iterator2>
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的便捷别名