xref: /openbsd-src/gnu/llvm/libcxx/include/__compare/ordering.h (revision 4bdff4bed0e3d54e55670334c7d0077db4170f86)
1*4bdff4beSrobert //===----------------------------------------------------------------------===//
2*4bdff4beSrobert //
3*4bdff4beSrobert // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4*4bdff4beSrobert // See https://llvm.org/LICENSE.txt for license information.
5*4bdff4beSrobert // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6*4bdff4beSrobert //
7*4bdff4beSrobert //===----------------------------------------------------------------------===//
8*4bdff4beSrobert 
9*4bdff4beSrobert #ifndef _LIBCPP___COMPARE_ORDERING_H
10*4bdff4beSrobert #define _LIBCPP___COMPARE_ORDERING_H
11*4bdff4beSrobert 
12*4bdff4beSrobert #include <__config>
13*4bdff4beSrobert #include <__type_traits/enable_if.h>
14*4bdff4beSrobert #include <__type_traits/is_same.h>
15*4bdff4beSrobert 
16*4bdff4beSrobert #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
17*4bdff4beSrobert #  pragma GCC system_header
18*4bdff4beSrobert #endif
19*4bdff4beSrobert 
20*4bdff4beSrobert _LIBCPP_BEGIN_NAMESPACE_STD
21*4bdff4beSrobert 
22*4bdff4beSrobert #if _LIBCPP_STD_VER > 17
23*4bdff4beSrobert 
24*4bdff4beSrobert // exposition only
25*4bdff4beSrobert enum class _LIBCPP_ENUM_VIS _OrdResult : signed char {
26*4bdff4beSrobert   __less = -1,
27*4bdff4beSrobert   __equiv = 0,
28*4bdff4beSrobert   __greater = 1
29*4bdff4beSrobert };
30*4bdff4beSrobert 
31*4bdff4beSrobert enum class _LIBCPP_ENUM_VIS _NCmpResult : signed char {
32*4bdff4beSrobert   __unordered = -127
33*4bdff4beSrobert };
34*4bdff4beSrobert 
35*4bdff4beSrobert class partial_ordering;
36*4bdff4beSrobert class weak_ordering;
37*4bdff4beSrobert class strong_ordering;
38*4bdff4beSrobert 
39*4bdff4beSrobert template<class _Tp, class... _Args>
40*4bdff4beSrobert inline constexpr bool __one_of_v = (is_same_v<_Tp, _Args> || ...);
41*4bdff4beSrobert 
42*4bdff4beSrobert struct _CmpUnspecifiedParam {
43*4bdff4beSrobert   _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEVAL
_CmpUnspecifiedParam_CmpUnspecifiedParam44*4bdff4beSrobert   _CmpUnspecifiedParam(int _CmpUnspecifiedParam::*) noexcept {}
45*4bdff4beSrobert 
46*4bdff4beSrobert   template<class _Tp, class = enable_if_t<!__one_of_v<_Tp, int, partial_ordering, weak_ordering, strong_ordering>>>
47*4bdff4beSrobert   _CmpUnspecifiedParam(_Tp) = delete;
48*4bdff4beSrobert };
49*4bdff4beSrobert 
50*4bdff4beSrobert class partial_ordering {
51*4bdff4beSrobert   using _ValueT = signed char;
52*4bdff4beSrobert 
53*4bdff4beSrobert   _LIBCPP_HIDE_FROM_ABI
partial_ordering(_OrdResult __v)54*4bdff4beSrobert   explicit constexpr partial_ordering(_OrdResult __v) noexcept
55*4bdff4beSrobert       : __value_(_ValueT(__v)) {}
56*4bdff4beSrobert 
57*4bdff4beSrobert   _LIBCPP_HIDE_FROM_ABI
partial_ordering(_NCmpResult __v)58*4bdff4beSrobert   explicit constexpr partial_ordering(_NCmpResult __v) noexcept
59*4bdff4beSrobert       : __value_(_ValueT(__v)) {}
60*4bdff4beSrobert 
61*4bdff4beSrobert   _LIBCPP_HIDE_FROM_ABI
__is_ordered()62*4bdff4beSrobert   constexpr bool __is_ordered() const noexcept {
63*4bdff4beSrobert     return __value_ != _ValueT(_NCmpResult::__unordered);
64*4bdff4beSrobert   }
65*4bdff4beSrobert public:
66*4bdff4beSrobert   // valid values
67*4bdff4beSrobert   static const partial_ordering less;
68*4bdff4beSrobert   static const partial_ordering equivalent;
69*4bdff4beSrobert   static const partial_ordering greater;
70*4bdff4beSrobert   static const partial_ordering unordered;
71*4bdff4beSrobert 
72*4bdff4beSrobert   // comparisons
73*4bdff4beSrobert   _LIBCPP_HIDE_FROM_ABI
74*4bdff4beSrobert   friend constexpr bool operator==(partial_ordering, partial_ordering) noexcept = default;
75*4bdff4beSrobert 
76*4bdff4beSrobert   _LIBCPP_HIDE_FROM_ABI
77*4bdff4beSrobert   friend constexpr bool operator==(partial_ordering __v, _CmpUnspecifiedParam) noexcept {
78*4bdff4beSrobert     return __v.__is_ordered() && __v.__value_ == 0;
79*4bdff4beSrobert   }
80*4bdff4beSrobert 
81*4bdff4beSrobert   _LIBCPP_HIDE_FROM_ABI
82*4bdff4beSrobert   friend constexpr bool operator< (partial_ordering __v, _CmpUnspecifiedParam) noexcept {
83*4bdff4beSrobert     return __v.__is_ordered() && __v.__value_ < 0;
84*4bdff4beSrobert   }
85*4bdff4beSrobert 
86*4bdff4beSrobert   _LIBCPP_HIDE_FROM_ABI
87*4bdff4beSrobert   friend constexpr bool operator<=(partial_ordering __v, _CmpUnspecifiedParam) noexcept  {
88*4bdff4beSrobert     return __v.__is_ordered() && __v.__value_ <= 0;
89*4bdff4beSrobert   }
90*4bdff4beSrobert 
91*4bdff4beSrobert   _LIBCPP_HIDE_FROM_ABI
92*4bdff4beSrobert   friend constexpr bool operator> (partial_ordering __v, _CmpUnspecifiedParam) noexcept  {
93*4bdff4beSrobert     return __v.__is_ordered() && __v.__value_ > 0;
94*4bdff4beSrobert   }
95*4bdff4beSrobert 
96*4bdff4beSrobert   _LIBCPP_HIDE_FROM_ABI
97*4bdff4beSrobert   friend constexpr bool operator>=(partial_ordering __v, _CmpUnspecifiedParam) noexcept  {
98*4bdff4beSrobert     return __v.__is_ordered() && __v.__value_ >= 0;
99*4bdff4beSrobert   }
100*4bdff4beSrobert 
101*4bdff4beSrobert   _LIBCPP_HIDE_FROM_ABI
102*4bdff4beSrobert   friend constexpr bool operator< (_CmpUnspecifiedParam, partial_ordering __v) noexcept  {
103*4bdff4beSrobert     return __v.__is_ordered() && 0 < __v.__value_;
104*4bdff4beSrobert   }
105*4bdff4beSrobert 
106*4bdff4beSrobert   _LIBCPP_HIDE_FROM_ABI
107*4bdff4beSrobert   friend constexpr bool operator<=(_CmpUnspecifiedParam, partial_ordering __v) noexcept  {
108*4bdff4beSrobert     return __v.__is_ordered() && 0 <= __v.__value_;
109*4bdff4beSrobert   }
110*4bdff4beSrobert 
111*4bdff4beSrobert   _LIBCPP_HIDE_FROM_ABI
112*4bdff4beSrobert   friend constexpr bool operator> (_CmpUnspecifiedParam, partial_ordering __v) noexcept  {
113*4bdff4beSrobert     return __v.__is_ordered() && 0 > __v.__value_;
114*4bdff4beSrobert   }
115*4bdff4beSrobert 
116*4bdff4beSrobert   _LIBCPP_HIDE_FROM_ABI
117*4bdff4beSrobert   friend constexpr bool operator>=(_CmpUnspecifiedParam, partial_ordering __v) noexcept  {
118*4bdff4beSrobert     return __v.__is_ordered() && 0 >= __v.__value_;
119*4bdff4beSrobert   }
120*4bdff4beSrobert 
121*4bdff4beSrobert   _LIBCPP_HIDE_FROM_ABI
122*4bdff4beSrobert   friend constexpr partial_ordering operator<=>(partial_ordering __v, _CmpUnspecifiedParam) noexcept  {
123*4bdff4beSrobert     return __v;
124*4bdff4beSrobert   }
125*4bdff4beSrobert 
126*4bdff4beSrobert   _LIBCPP_HIDE_FROM_ABI
127*4bdff4beSrobert   friend constexpr partial_ordering operator<=>(_CmpUnspecifiedParam, partial_ordering __v) noexcept  {
128*4bdff4beSrobert     return __v < 0 ? partial_ordering::greater : (__v > 0 ? partial_ordering::less : __v);
129*4bdff4beSrobert   }
130*4bdff4beSrobert private:
131*4bdff4beSrobert   _ValueT __value_;
132*4bdff4beSrobert };
133*4bdff4beSrobert 
134*4bdff4beSrobert inline constexpr partial_ordering partial_ordering::less(_OrdResult::__less);
135*4bdff4beSrobert inline constexpr partial_ordering partial_ordering::equivalent(_OrdResult::__equiv);
136*4bdff4beSrobert inline constexpr partial_ordering partial_ordering::greater(_OrdResult::__greater);
137*4bdff4beSrobert inline constexpr partial_ordering partial_ordering::unordered(_NCmpResult ::__unordered);
138*4bdff4beSrobert 
139*4bdff4beSrobert class weak_ordering {
140*4bdff4beSrobert   using _ValueT = signed char;
141*4bdff4beSrobert 
142*4bdff4beSrobert   _LIBCPP_HIDE_FROM_ABI
weak_ordering(_OrdResult __v)143*4bdff4beSrobert   explicit constexpr weak_ordering(_OrdResult __v) noexcept : __value_(_ValueT(__v)) {}
144*4bdff4beSrobert 
145*4bdff4beSrobert public:
146*4bdff4beSrobert   static const weak_ordering less;
147*4bdff4beSrobert   static const weak_ordering equivalent;
148*4bdff4beSrobert   static const weak_ordering greater;
149*4bdff4beSrobert 
150*4bdff4beSrobert   _LIBCPP_HIDE_FROM_ABI
partial_ordering()151*4bdff4beSrobert   constexpr operator partial_ordering() const noexcept {
152*4bdff4beSrobert     return __value_ == 0 ? partial_ordering::equivalent
153*4bdff4beSrobert         : (__value_ < 0 ? partial_ordering::less : partial_ordering::greater);
154*4bdff4beSrobert   }
155*4bdff4beSrobert 
156*4bdff4beSrobert   // comparisons
157*4bdff4beSrobert   _LIBCPP_HIDE_FROM_ABI
158*4bdff4beSrobert   friend constexpr bool operator==(weak_ordering, weak_ordering) noexcept = default;
159*4bdff4beSrobert 
160*4bdff4beSrobert   _LIBCPP_HIDE_FROM_ABI
161*4bdff4beSrobert   friend constexpr bool operator==(weak_ordering __v, _CmpUnspecifiedParam) noexcept {
162*4bdff4beSrobert     return __v.__value_ == 0;
163*4bdff4beSrobert   }
164*4bdff4beSrobert 
165*4bdff4beSrobert   _LIBCPP_HIDE_FROM_ABI
166*4bdff4beSrobert   friend constexpr bool operator< (weak_ordering __v, _CmpUnspecifiedParam) noexcept {
167*4bdff4beSrobert     return __v.__value_ < 0;
168*4bdff4beSrobert   }
169*4bdff4beSrobert 
170*4bdff4beSrobert   _LIBCPP_HIDE_FROM_ABI
171*4bdff4beSrobert   friend constexpr bool operator<=(weak_ordering __v, _CmpUnspecifiedParam) noexcept {
172*4bdff4beSrobert     return __v.__value_ <= 0;
173*4bdff4beSrobert   }
174*4bdff4beSrobert 
175*4bdff4beSrobert   _LIBCPP_HIDE_FROM_ABI
176*4bdff4beSrobert   friend constexpr bool operator> (weak_ordering __v, _CmpUnspecifiedParam) noexcept {
177*4bdff4beSrobert     return __v.__value_ > 0;
178*4bdff4beSrobert   }
179*4bdff4beSrobert 
180*4bdff4beSrobert   _LIBCPP_HIDE_FROM_ABI
181*4bdff4beSrobert   friend constexpr bool operator>=(weak_ordering __v, _CmpUnspecifiedParam) noexcept {
182*4bdff4beSrobert     return __v.__value_ >= 0;
183*4bdff4beSrobert   }
184*4bdff4beSrobert 
185*4bdff4beSrobert   _LIBCPP_HIDE_FROM_ABI
186*4bdff4beSrobert   friend constexpr bool operator< (_CmpUnspecifiedParam, weak_ordering __v) noexcept {
187*4bdff4beSrobert     return 0 < __v.__value_;
188*4bdff4beSrobert   }
189*4bdff4beSrobert 
190*4bdff4beSrobert   _LIBCPP_HIDE_FROM_ABI
191*4bdff4beSrobert   friend constexpr bool operator<=(_CmpUnspecifiedParam, weak_ordering __v) noexcept {
192*4bdff4beSrobert     return 0 <= __v.__value_;
193*4bdff4beSrobert   }
194*4bdff4beSrobert 
195*4bdff4beSrobert   _LIBCPP_HIDE_FROM_ABI
196*4bdff4beSrobert   friend constexpr bool operator> (_CmpUnspecifiedParam, weak_ordering __v) noexcept {
197*4bdff4beSrobert     return 0 > __v.__value_;
198*4bdff4beSrobert   }
199*4bdff4beSrobert 
200*4bdff4beSrobert   _LIBCPP_HIDE_FROM_ABI
201*4bdff4beSrobert   friend constexpr bool operator>=(_CmpUnspecifiedParam, weak_ordering __v) noexcept {
202*4bdff4beSrobert     return 0 >= __v.__value_;
203*4bdff4beSrobert   }
204*4bdff4beSrobert 
205*4bdff4beSrobert   _LIBCPP_HIDE_FROM_ABI
206*4bdff4beSrobert   friend constexpr weak_ordering operator<=>(weak_ordering __v, _CmpUnspecifiedParam) noexcept {
207*4bdff4beSrobert     return __v;
208*4bdff4beSrobert   }
209*4bdff4beSrobert 
210*4bdff4beSrobert   _LIBCPP_HIDE_FROM_ABI
211*4bdff4beSrobert   friend constexpr weak_ordering operator<=>(_CmpUnspecifiedParam, weak_ordering __v) noexcept {
212*4bdff4beSrobert     return __v < 0 ? weak_ordering::greater : (__v > 0 ? weak_ordering::less : __v);
213*4bdff4beSrobert   }
214*4bdff4beSrobert 
215*4bdff4beSrobert private:
216*4bdff4beSrobert   _ValueT __value_;
217*4bdff4beSrobert };
218*4bdff4beSrobert 
219*4bdff4beSrobert inline constexpr weak_ordering weak_ordering::less(_OrdResult::__less);
220*4bdff4beSrobert inline constexpr weak_ordering weak_ordering::equivalent(_OrdResult::__equiv);
221*4bdff4beSrobert inline constexpr weak_ordering weak_ordering::greater(_OrdResult::__greater);
222*4bdff4beSrobert 
223*4bdff4beSrobert class strong_ordering {
224*4bdff4beSrobert   using _ValueT = signed char;
225*4bdff4beSrobert 
226*4bdff4beSrobert   _LIBCPP_HIDE_FROM_ABI
strong_ordering(_OrdResult __v)227*4bdff4beSrobert   explicit constexpr strong_ordering(_OrdResult __v) noexcept : __value_(_ValueT(__v)) {}
228*4bdff4beSrobert 
229*4bdff4beSrobert public:
230*4bdff4beSrobert   static const strong_ordering less;
231*4bdff4beSrobert   static const strong_ordering equal;
232*4bdff4beSrobert   static const strong_ordering equivalent;
233*4bdff4beSrobert   static const strong_ordering greater;
234*4bdff4beSrobert 
235*4bdff4beSrobert   // conversions
236*4bdff4beSrobert   _LIBCPP_HIDE_FROM_ABI
partial_ordering()237*4bdff4beSrobert   constexpr operator partial_ordering() const noexcept {
238*4bdff4beSrobert     return __value_ == 0 ? partial_ordering::equivalent
239*4bdff4beSrobert         : (__value_ < 0 ? partial_ordering::less : partial_ordering::greater);
240*4bdff4beSrobert   }
241*4bdff4beSrobert 
242*4bdff4beSrobert   _LIBCPP_HIDE_FROM_ABI
weak_ordering()243*4bdff4beSrobert   constexpr operator weak_ordering() const noexcept {
244*4bdff4beSrobert     return __value_ == 0 ? weak_ordering::equivalent
245*4bdff4beSrobert         : (__value_ < 0 ? weak_ordering::less : weak_ordering::greater);
246*4bdff4beSrobert   }
247*4bdff4beSrobert 
248*4bdff4beSrobert   // comparisons
249*4bdff4beSrobert   _LIBCPP_HIDE_FROM_ABI
250*4bdff4beSrobert   friend constexpr bool operator==(strong_ordering, strong_ordering) noexcept = default;
251*4bdff4beSrobert 
252*4bdff4beSrobert   _LIBCPP_HIDE_FROM_ABI
253*4bdff4beSrobert   friend constexpr bool operator==(strong_ordering __v, _CmpUnspecifiedParam) noexcept {
254*4bdff4beSrobert     return __v.__value_ == 0;
255*4bdff4beSrobert   }
256*4bdff4beSrobert 
257*4bdff4beSrobert   _LIBCPP_HIDE_FROM_ABI
258*4bdff4beSrobert   friend constexpr bool operator< (strong_ordering __v, _CmpUnspecifiedParam) noexcept {
259*4bdff4beSrobert     return __v.__value_ < 0;
260*4bdff4beSrobert   }
261*4bdff4beSrobert 
262*4bdff4beSrobert   _LIBCPP_HIDE_FROM_ABI
263*4bdff4beSrobert   friend constexpr bool operator<=(strong_ordering __v, _CmpUnspecifiedParam) noexcept {
264*4bdff4beSrobert     return __v.__value_ <= 0;
265*4bdff4beSrobert   }
266*4bdff4beSrobert 
267*4bdff4beSrobert   _LIBCPP_HIDE_FROM_ABI
268*4bdff4beSrobert   friend constexpr bool operator> (strong_ordering __v, _CmpUnspecifiedParam) noexcept {
269*4bdff4beSrobert     return __v.__value_ > 0;
270*4bdff4beSrobert   }
271*4bdff4beSrobert 
272*4bdff4beSrobert   _LIBCPP_HIDE_FROM_ABI
273*4bdff4beSrobert   friend constexpr bool operator>=(strong_ordering __v, _CmpUnspecifiedParam) noexcept {
274*4bdff4beSrobert     return __v.__value_ >= 0;
275*4bdff4beSrobert   }
276*4bdff4beSrobert 
277*4bdff4beSrobert   _LIBCPP_HIDE_FROM_ABI
278*4bdff4beSrobert   friend constexpr bool operator< (_CmpUnspecifiedParam, strong_ordering __v) noexcept {
279*4bdff4beSrobert     return 0 < __v.__value_;
280*4bdff4beSrobert   }
281*4bdff4beSrobert 
282*4bdff4beSrobert   _LIBCPP_HIDE_FROM_ABI
283*4bdff4beSrobert   friend constexpr bool operator<=(_CmpUnspecifiedParam, strong_ordering __v) noexcept {
284*4bdff4beSrobert     return 0 <= __v.__value_;
285*4bdff4beSrobert   }
286*4bdff4beSrobert 
287*4bdff4beSrobert   _LIBCPP_HIDE_FROM_ABI
288*4bdff4beSrobert   friend constexpr bool operator> (_CmpUnspecifiedParam, strong_ordering __v) noexcept {
289*4bdff4beSrobert     return 0 > __v.__value_;
290*4bdff4beSrobert   }
291*4bdff4beSrobert 
292*4bdff4beSrobert   _LIBCPP_HIDE_FROM_ABI
293*4bdff4beSrobert   friend constexpr bool operator>=(_CmpUnspecifiedParam, strong_ordering __v) noexcept {
294*4bdff4beSrobert     return 0 >= __v.__value_;
295*4bdff4beSrobert   }
296*4bdff4beSrobert 
297*4bdff4beSrobert   _LIBCPP_HIDE_FROM_ABI
298*4bdff4beSrobert   friend constexpr strong_ordering operator<=>(strong_ordering __v, _CmpUnspecifiedParam) noexcept {
299*4bdff4beSrobert     return __v;
300*4bdff4beSrobert   }
301*4bdff4beSrobert 
302*4bdff4beSrobert   _LIBCPP_HIDE_FROM_ABI
303*4bdff4beSrobert   friend constexpr strong_ordering operator<=>(_CmpUnspecifiedParam, strong_ordering __v) noexcept {
304*4bdff4beSrobert     return __v < 0 ? strong_ordering::greater : (__v > 0 ? strong_ordering::less : __v);
305*4bdff4beSrobert   }
306*4bdff4beSrobert 
307*4bdff4beSrobert private:
308*4bdff4beSrobert   _ValueT __value_;
309*4bdff4beSrobert };
310*4bdff4beSrobert 
311*4bdff4beSrobert inline constexpr strong_ordering strong_ordering::less(_OrdResult::__less);
312*4bdff4beSrobert inline constexpr strong_ordering strong_ordering::equal(_OrdResult::__equiv);
313*4bdff4beSrobert inline constexpr strong_ordering strong_ordering::equivalent(_OrdResult::__equiv);
314*4bdff4beSrobert inline constexpr strong_ordering strong_ordering::greater(_OrdResult::__greater);
315*4bdff4beSrobert 
316*4bdff4beSrobert /// [cmp.categories.pre]/1
317*4bdff4beSrobert /// The types partial_ordering, weak_ordering, and strong_ordering are
318*4bdff4beSrobert /// collectively termed the comparison category types.
319*4bdff4beSrobert template <class _Tp>
320*4bdff4beSrobert concept __comparison_category = __one_of_v<_Tp, partial_ordering, weak_ordering, strong_ordering>;
321*4bdff4beSrobert 
322*4bdff4beSrobert #endif // _LIBCPP_STD_VER > 17
323*4bdff4beSrobert 
324*4bdff4beSrobert _LIBCPP_END_NAMESPACE_STD
325*4bdff4beSrobert 
326*4bdff4beSrobert #endif // _LIBCPP___COMPARE_ORDERING_H
327