Simple-Utility v2.3.1
Loading...
Searching...
No Matches
Compare.hpp
Go to the documentation of this file.
1// Copyright Dominic Koepke 2019 - 2023.
2// Distributed under the Boost Software License, Version 1.0.
3// (See accompanying file LICENSE_1_0.txt or copy at
4// https://www.boost.org/LICENSE_1_0.txt)
5
6#ifndef SL_UTILITY_FUNCTIONAL_COMPARE_HPP
7#define SL_UTILITY_FUNCTIONAL_COMPARE_HPP
8
9#pragma once
10
14
16{
29 inline constexpr auto less = envelop<Predicate>(
30 []<class Lhs, class Rhs>(Lhs&& lhs, Rhs&& rhs) noexcept(noexcept(std::declval<Lhs>() < std::declval<Rhs>()))
31 {
32 if constexpr (std::integral<std::remove_cvref_t<Lhs>> && std::integral<std::remove_cvref_t<Rhs>>)
33 {
34 return std::cmp_less(std::forward<Lhs>(lhs), std::forward<Rhs>(rhs));
35 }
36 else
37 {
38 static_assert(
39 requires { { lhs < rhs } -> std::convertible_to<bool>; },
40 "Operands are not usable in operator < expressions.");
41
42 return std::forward<Lhs>(lhs) < std::forward<Rhs>(rhs);
43 }
44 });
45
50 inline constexpr auto less_equal = envelop<Predicate>(
51 []<class Lhs, class Rhs>(Lhs&& lhs, Rhs&& rhs) noexcept(noexcept(std::declval<Lhs>() <= std::declval<Rhs>()))
52 {
53 if constexpr (std::integral<std::remove_cvref_t<Lhs>> && std::integral<std::remove_cvref_t<Rhs>>)
54 {
55 return std::cmp_less_equal(std::forward<Lhs>(lhs), std::forward<Rhs>(rhs));
56 }
57 else
58 {
59 static_assert(
60 requires { { lhs <= rhs } -> std::convertible_to<bool>; },
61 "Operands are not usable in operator <= expressions.");
62
63 return std::forward<Lhs>(lhs) <= std::forward<Rhs>(rhs);
64 }
65 });
66
71 inline constexpr auto greater = envelop<Predicate>(
72 []<class Lhs, class Rhs>(Lhs&& lhs, Rhs&& rhs) noexcept(noexcept(std::declval<Lhs>() > std::declval<Rhs>()))
73 {
74 if constexpr (std::integral<std::remove_cvref_t<Lhs>> && std::integral<std::remove_cvref_t<Rhs>>)
75 {
76 return std::cmp_greater(std::forward<Lhs>(lhs), std::forward<Rhs>(rhs));
77 }
78 else
79 {
80 static_assert(
81 requires { { lhs > rhs } -> std::convertible_to<bool>; },
82 "Operands are not usable in operator > expressions.");
83
84 return std::forward<Lhs>(lhs) > std::forward<Rhs>(rhs);
85 }
86 });
87
92 inline constexpr auto greater_equal = envelop<Predicate>(
93 []<class Lhs, class Rhs>(Lhs&& lhs, Rhs&& rhs) noexcept(noexcept(std::declval<Lhs>() >= std::declval<Rhs>()))
94 {
95 if constexpr (std::integral<std::remove_cvref_t<Lhs>> && std::integral<std::remove_cvref_t<Rhs>>)
96 {
97 return std::cmp_greater_equal(std::forward<Lhs>(lhs), std::forward<Rhs>(rhs));
98 }
99 else
100 {
101 static_assert(
102 requires { { lhs >= rhs } -> std::convertible_to<bool>; },
103 "Operands are not usable in operator >= expressions.");
104
105 return std::forward<Lhs>(lhs) >= std::forward<Rhs>(rhs);
106 }
107 });
108
113 inline constexpr auto equal = envelop<Predicate>(
114 []<class Lhs, class Rhs>(Lhs&& lhs, Rhs&& rhs) noexcept(noexcept(std::declval<Lhs>() == std::declval<Rhs>()))
115 {
116 if constexpr (std::integral<std::remove_cvref_t<Lhs>> && std::integral<std::remove_cvref_t<Rhs>>)
117 {
118 return std::cmp_equal(std::forward<Lhs>(lhs), std::forward<Rhs>(rhs));
119 }
120 else
121 {
122 static_assert(
123 requires { { lhs == rhs } -> std::convertible_to<bool>; },
124 "Operands are not usable in operator == expressions.");
125
126 return std::forward<Lhs>(lhs) == std::forward<Rhs>(rhs);
127 }
128 });
129
134 inline constexpr auto not_equal = envelop<Predicate>(
135 []<class Lhs, class Rhs>(Lhs&& lhs, Rhs&& rhs) noexcept(noexcept(std::declval<Lhs>() != std::declval<Rhs>()))
136 {
137 if constexpr (std::integral<std::remove_cvref_t<Lhs>> && std::integral<std::remove_cvref_t<Rhs>>)
138 {
139 return std::cmp_not_equal(std::forward<Lhs>(lhs), std::forward<Rhs>(rhs));
140 }
141 else
142 {
143 static_assert(
144 requires { { lhs != rhs } -> std::convertible_to<bool>; },
145 "Operands are not usable in operator != expressions.");
146
147 return std::forward<Lhs>(lhs) != std::forward<Rhs>(rhs);
148 }
149 });
150
154 inline constexpr auto three_way = envelop<Transform>(
155 []<class Lhs, class Rhs>(Lhs&& lhs, Rhs&& rhs) noexcept(concepts::nothrow_weakly_three_way_comparable_with<Lhs, Rhs>)
156 {
158 "Operands are not usable in operator <=> expressions.");
159
160 return std::forward<Lhs>(lhs) <=> std::forward<Rhs>(rhs);
161 });
162
166}
167
168#endif
Checks whether a symmetrical set of operator <=> to compare both types with each other with noexcept ...
Definition: stl_extensions.hpp:260
Checks whether a symmetrical set of operator <=> to compare both types with each other exists.
Definition: stl_extensions.hpp:242
constexpr auto greater
Functional object, which compares its two operands greater.
Definition: Compare.hpp:71
constexpr auto less_equal
Functional object, which compares its two operands less-equal.
Definition: Compare.hpp:50
constexpr auto three_way
Functional object, which performs a three-way comparison on its two operands..
Definition: Compare.hpp:154
constexpr auto less
Functional object, which compares its two operands less.
Definition: Compare.hpp:29
constexpr auto not_equal
Functional object, which compares its two operands not-equal.
Definition: Compare.hpp:134
constexpr auto equal
Functional object, which compares its two operands equal.
Definition: Compare.hpp:113
constexpr auto greater_equal
Functional object, which compares its two operands greater-equal.
Definition: Compare.hpp:92
Definition: Compare.hpp:16