Run DCE after a LoopFlatten test to reduce spurious output [nfc]
[llvm-project.git] / libcxx / include / __compare / ordering.h
blobc9a15efb3c2fc47a1942a3dee1ab38dab2653393
1 //===----------------------------------------------------------------------===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
9 #ifndef _LIBCPP___COMPARE_ORDERING_H
10 #define _LIBCPP___COMPARE_ORDERING_H
12 #include <__config>
13 #include <__type_traits/enable_if.h>
14 #include <__type_traits/is_same.h>
16 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
17 # pragma GCC system_header
18 #endif
20 _LIBCPP_BEGIN_NAMESPACE_STD
22 #if _LIBCPP_STD_VER >= 20
24 // exposition only
25 enum class _OrdResult : signed char {
26 __less = -1,
27 __equiv = 0,
28 __greater = 1
31 enum class _NCmpResult : signed char {
32 __unordered = -127
35 class partial_ordering;
36 class weak_ordering;
37 class strong_ordering;
39 template<class _Tp, class... _Args>
40 inline constexpr bool __one_of_v = (is_same_v<_Tp, _Args> || ...);
42 struct _CmpUnspecifiedParam {
43 _LIBCPP_HIDE_FROM_ABI constexpr
44 _CmpUnspecifiedParam(int _CmpUnspecifiedParam::*) noexcept {}
46 template<class _Tp, class = enable_if_t<!__one_of_v<_Tp, int, partial_ordering, weak_ordering, strong_ordering>>>
47 _CmpUnspecifiedParam(_Tp) = delete;
50 class partial_ordering {
51 using _ValueT = signed char;
53 _LIBCPP_HIDE_FROM_ABI
54 explicit constexpr partial_ordering(_OrdResult __v) noexcept
55 : __value_(_ValueT(__v)) {}
57 _LIBCPP_HIDE_FROM_ABI
58 explicit constexpr partial_ordering(_NCmpResult __v) noexcept
59 : __value_(_ValueT(__v)) {}
61 _LIBCPP_HIDE_FROM_ABI
62 constexpr bool __is_ordered() const noexcept {
63 return __value_ != _ValueT(_NCmpResult::__unordered);
65 public:
66 // valid values
67 static const partial_ordering less;
68 static const partial_ordering equivalent;
69 static const partial_ordering greater;
70 static const partial_ordering unordered;
72 // comparisons
73 _LIBCPP_HIDE_FROM_ABI
74 friend constexpr bool operator==(partial_ordering, partial_ordering) noexcept = default;
76 _LIBCPP_HIDE_FROM_ABI
77 friend constexpr bool operator==(partial_ordering __v, _CmpUnspecifiedParam) noexcept {
78 return __v.__is_ordered() && __v.__value_ == 0;
81 _LIBCPP_HIDE_FROM_ABI
82 friend constexpr bool operator< (partial_ordering __v, _CmpUnspecifiedParam) noexcept {
83 return __v.__is_ordered() && __v.__value_ < 0;
86 _LIBCPP_HIDE_FROM_ABI
87 friend constexpr bool operator<=(partial_ordering __v, _CmpUnspecifiedParam) noexcept {
88 return __v.__is_ordered() && __v.__value_ <= 0;
91 _LIBCPP_HIDE_FROM_ABI
92 friend constexpr bool operator> (partial_ordering __v, _CmpUnspecifiedParam) noexcept {
93 return __v.__is_ordered() && __v.__value_ > 0;
96 _LIBCPP_HIDE_FROM_ABI
97 friend constexpr bool operator>=(partial_ordering __v, _CmpUnspecifiedParam) noexcept {
98 return __v.__is_ordered() && __v.__value_ >= 0;
101 _LIBCPP_HIDE_FROM_ABI
102 friend constexpr bool operator< (_CmpUnspecifiedParam, partial_ordering __v) noexcept {
103 return __v.__is_ordered() && 0 < __v.__value_;
106 _LIBCPP_HIDE_FROM_ABI
107 friend constexpr bool operator<=(_CmpUnspecifiedParam, partial_ordering __v) noexcept {
108 return __v.__is_ordered() && 0 <= __v.__value_;
111 _LIBCPP_HIDE_FROM_ABI
112 friend constexpr bool operator> (_CmpUnspecifiedParam, partial_ordering __v) noexcept {
113 return __v.__is_ordered() && 0 > __v.__value_;
116 _LIBCPP_HIDE_FROM_ABI
117 friend constexpr bool operator>=(_CmpUnspecifiedParam, partial_ordering __v) noexcept {
118 return __v.__is_ordered() && 0 >= __v.__value_;
121 _LIBCPP_HIDE_FROM_ABI
122 friend constexpr partial_ordering operator<=>(partial_ordering __v, _CmpUnspecifiedParam) noexcept {
123 return __v;
126 _LIBCPP_HIDE_FROM_ABI
127 friend constexpr partial_ordering operator<=>(_CmpUnspecifiedParam, partial_ordering __v) noexcept {
128 return __v < 0 ? partial_ordering::greater : (__v > 0 ? partial_ordering::less : __v);
130 private:
131 _ValueT __value_;
134 inline constexpr partial_ordering partial_ordering::less(_OrdResult::__less);
135 inline constexpr partial_ordering partial_ordering::equivalent(_OrdResult::__equiv);
136 inline constexpr partial_ordering partial_ordering::greater(_OrdResult::__greater);
137 inline constexpr partial_ordering partial_ordering::unordered(_NCmpResult ::__unordered);
139 class weak_ordering {
140 using _ValueT = signed char;
142 _LIBCPP_HIDE_FROM_ABI
143 explicit constexpr weak_ordering(_OrdResult __v) noexcept : __value_(_ValueT(__v)) {}
145 public:
146 static const weak_ordering less;
147 static const weak_ordering equivalent;
148 static const weak_ordering greater;
150 _LIBCPP_HIDE_FROM_ABI
151 constexpr operator partial_ordering() const noexcept {
152 return __value_ == 0 ? partial_ordering::equivalent
153 : (__value_ < 0 ? partial_ordering::less : partial_ordering::greater);
156 // comparisons
157 _LIBCPP_HIDE_FROM_ABI
158 friend constexpr bool operator==(weak_ordering, weak_ordering) noexcept = default;
160 _LIBCPP_HIDE_FROM_ABI
161 friend constexpr bool operator==(weak_ordering __v, _CmpUnspecifiedParam) noexcept {
162 return __v.__value_ == 0;
165 _LIBCPP_HIDE_FROM_ABI
166 friend constexpr bool operator< (weak_ordering __v, _CmpUnspecifiedParam) noexcept {
167 return __v.__value_ < 0;
170 _LIBCPP_HIDE_FROM_ABI
171 friend constexpr bool operator<=(weak_ordering __v, _CmpUnspecifiedParam) noexcept {
172 return __v.__value_ <= 0;
175 _LIBCPP_HIDE_FROM_ABI
176 friend constexpr bool operator> (weak_ordering __v, _CmpUnspecifiedParam) noexcept {
177 return __v.__value_ > 0;
180 _LIBCPP_HIDE_FROM_ABI
181 friend constexpr bool operator>=(weak_ordering __v, _CmpUnspecifiedParam) noexcept {
182 return __v.__value_ >= 0;
185 _LIBCPP_HIDE_FROM_ABI
186 friend constexpr bool operator< (_CmpUnspecifiedParam, weak_ordering __v) noexcept {
187 return 0 < __v.__value_;
190 _LIBCPP_HIDE_FROM_ABI
191 friend constexpr bool operator<=(_CmpUnspecifiedParam, weak_ordering __v) noexcept {
192 return 0 <= __v.__value_;
195 _LIBCPP_HIDE_FROM_ABI
196 friend constexpr bool operator> (_CmpUnspecifiedParam, weak_ordering __v) noexcept {
197 return 0 > __v.__value_;
200 _LIBCPP_HIDE_FROM_ABI
201 friend constexpr bool operator>=(_CmpUnspecifiedParam, weak_ordering __v) noexcept {
202 return 0 >= __v.__value_;
205 _LIBCPP_HIDE_FROM_ABI
206 friend constexpr weak_ordering operator<=>(weak_ordering __v, _CmpUnspecifiedParam) noexcept {
207 return __v;
210 _LIBCPP_HIDE_FROM_ABI
211 friend constexpr weak_ordering operator<=>(_CmpUnspecifiedParam, weak_ordering __v) noexcept {
212 return __v < 0 ? weak_ordering::greater : (__v > 0 ? weak_ordering::less : __v);
215 private:
216 _ValueT __value_;
219 inline constexpr weak_ordering weak_ordering::less(_OrdResult::__less);
220 inline constexpr weak_ordering weak_ordering::equivalent(_OrdResult::__equiv);
221 inline constexpr weak_ordering weak_ordering::greater(_OrdResult::__greater);
223 class strong_ordering {
224 using _ValueT = signed char;
226 _LIBCPP_HIDE_FROM_ABI
227 explicit constexpr strong_ordering(_OrdResult __v) noexcept : __value_(_ValueT(__v)) {}
229 public:
230 static const strong_ordering less;
231 static const strong_ordering equal;
232 static const strong_ordering equivalent;
233 static const strong_ordering greater;
235 // conversions
236 _LIBCPP_HIDE_FROM_ABI
237 constexpr operator partial_ordering() const noexcept {
238 return __value_ == 0 ? partial_ordering::equivalent
239 : (__value_ < 0 ? partial_ordering::less : partial_ordering::greater);
242 _LIBCPP_HIDE_FROM_ABI
243 constexpr operator weak_ordering() const noexcept {
244 return __value_ == 0 ? weak_ordering::equivalent
245 : (__value_ < 0 ? weak_ordering::less : weak_ordering::greater);
248 // comparisons
249 _LIBCPP_HIDE_FROM_ABI
250 friend constexpr bool operator==(strong_ordering, strong_ordering) noexcept = default;
252 _LIBCPP_HIDE_FROM_ABI
253 friend constexpr bool operator==(strong_ordering __v, _CmpUnspecifiedParam) noexcept {
254 return __v.__value_ == 0;
257 _LIBCPP_HIDE_FROM_ABI
258 friend constexpr bool operator< (strong_ordering __v, _CmpUnspecifiedParam) noexcept {
259 return __v.__value_ < 0;
262 _LIBCPP_HIDE_FROM_ABI
263 friend constexpr bool operator<=(strong_ordering __v, _CmpUnspecifiedParam) noexcept {
264 return __v.__value_ <= 0;
267 _LIBCPP_HIDE_FROM_ABI
268 friend constexpr bool operator> (strong_ordering __v, _CmpUnspecifiedParam) noexcept {
269 return __v.__value_ > 0;
272 _LIBCPP_HIDE_FROM_ABI
273 friend constexpr bool operator>=(strong_ordering __v, _CmpUnspecifiedParam) noexcept {
274 return __v.__value_ >= 0;
277 _LIBCPP_HIDE_FROM_ABI
278 friend constexpr bool operator< (_CmpUnspecifiedParam, strong_ordering __v) noexcept {
279 return 0 < __v.__value_;
282 _LIBCPP_HIDE_FROM_ABI
283 friend constexpr bool operator<=(_CmpUnspecifiedParam, strong_ordering __v) noexcept {
284 return 0 <= __v.__value_;
287 _LIBCPP_HIDE_FROM_ABI
288 friend constexpr bool operator> (_CmpUnspecifiedParam, strong_ordering __v) noexcept {
289 return 0 > __v.__value_;
292 _LIBCPP_HIDE_FROM_ABI
293 friend constexpr bool operator>=(_CmpUnspecifiedParam, strong_ordering __v) noexcept {
294 return 0 >= __v.__value_;
297 _LIBCPP_HIDE_FROM_ABI
298 friend constexpr strong_ordering operator<=>(strong_ordering __v, _CmpUnspecifiedParam) noexcept {
299 return __v;
302 _LIBCPP_HIDE_FROM_ABI
303 friend constexpr strong_ordering operator<=>(_CmpUnspecifiedParam, strong_ordering __v) noexcept {
304 return __v < 0 ? strong_ordering::greater : (__v > 0 ? strong_ordering::less : __v);
307 private:
308 _ValueT __value_;
311 inline constexpr strong_ordering strong_ordering::less(_OrdResult::__less);
312 inline constexpr strong_ordering strong_ordering::equal(_OrdResult::__equiv);
313 inline constexpr strong_ordering strong_ordering::equivalent(_OrdResult::__equiv);
314 inline constexpr strong_ordering strong_ordering::greater(_OrdResult::__greater);
316 /// [cmp.categories.pre]/1
317 /// The types partial_ordering, weak_ordering, and strong_ordering are
318 /// collectively termed the comparison category types.
319 template <class _Tp>
320 concept __comparison_category = __one_of_v<_Tp, partial_ordering, weak_ordering, strong_ordering>;
322 #endif // _LIBCPP_STD_VER >= 20
324 _LIBCPP_END_NAMESPACE_STD
326 #endif // _LIBCPP___COMPARE_ORDERING_H