xref: /freebsd-src/contrib/llvm-project/libcxx/include/__compare/ordering.h (revision bdd1243df58e60e85101c09001d9812a789b6bc4)
1349cc55cSDimitry Andric //===----------------------------------------------------------------------===//
2349cc55cSDimitry Andric //
3349cc55cSDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4349cc55cSDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
5349cc55cSDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6349cc55cSDimitry Andric //
7349cc55cSDimitry Andric //===----------------------------------------------------------------------===//
8349cc55cSDimitry Andric 
9349cc55cSDimitry Andric #ifndef _LIBCPP___COMPARE_ORDERING_H
10349cc55cSDimitry Andric #define _LIBCPP___COMPARE_ORDERING_H
11349cc55cSDimitry Andric 
12349cc55cSDimitry Andric #include <__config>
13*bdd1243dSDimitry Andric #include <__type_traits/enable_if.h>
14*bdd1243dSDimitry Andric #include <__type_traits/is_same.h>
15349cc55cSDimitry Andric 
16349cc55cSDimitry Andric #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
17349cc55cSDimitry Andric #  pragma GCC system_header
18349cc55cSDimitry Andric #endif
19349cc55cSDimitry Andric 
20349cc55cSDimitry Andric _LIBCPP_BEGIN_NAMESPACE_STD
21349cc55cSDimitry Andric 
22349cc55cSDimitry Andric #if _LIBCPP_STD_VER > 17
23349cc55cSDimitry Andric 
24349cc55cSDimitry Andric // exposition only
25349cc55cSDimitry Andric enum class _LIBCPP_ENUM_VIS _OrdResult : signed char {
26349cc55cSDimitry Andric   __less = -1,
27349cc55cSDimitry Andric   __equiv = 0,
28349cc55cSDimitry Andric   __greater = 1
29349cc55cSDimitry Andric };
30349cc55cSDimitry Andric 
31349cc55cSDimitry Andric enum class _LIBCPP_ENUM_VIS _NCmpResult : signed char {
32349cc55cSDimitry Andric   __unordered = -127
33349cc55cSDimitry Andric };
34349cc55cSDimitry Andric 
35349cc55cSDimitry Andric class partial_ordering;
36349cc55cSDimitry Andric class weak_ordering;
37349cc55cSDimitry Andric class strong_ordering;
38349cc55cSDimitry Andric 
39349cc55cSDimitry Andric template<class _Tp, class... _Args>
40349cc55cSDimitry Andric inline constexpr bool __one_of_v = (is_same_v<_Tp, _Args> || ...);
41349cc55cSDimitry Andric 
42349cc55cSDimitry Andric struct _CmpUnspecifiedParam {
43349cc55cSDimitry Andric   _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEVAL
44349cc55cSDimitry Andric   _CmpUnspecifiedParam(int _CmpUnspecifiedParam::*) noexcept {}
45349cc55cSDimitry Andric 
46349cc55cSDimitry Andric   template<class _Tp, class = enable_if_t<!__one_of_v<_Tp, int, partial_ordering, weak_ordering, strong_ordering>>>
47349cc55cSDimitry Andric   _CmpUnspecifiedParam(_Tp) = delete;
48349cc55cSDimitry Andric };
49349cc55cSDimitry Andric 
50349cc55cSDimitry Andric class partial_ordering {
51349cc55cSDimitry Andric   using _ValueT = signed char;
52349cc55cSDimitry Andric 
53349cc55cSDimitry Andric   _LIBCPP_HIDE_FROM_ABI
54349cc55cSDimitry Andric   explicit constexpr partial_ordering(_OrdResult __v) noexcept
55349cc55cSDimitry Andric       : __value_(_ValueT(__v)) {}
56349cc55cSDimitry Andric 
57349cc55cSDimitry Andric   _LIBCPP_HIDE_FROM_ABI
58349cc55cSDimitry Andric   explicit constexpr partial_ordering(_NCmpResult __v) noexcept
59349cc55cSDimitry Andric       : __value_(_ValueT(__v)) {}
60349cc55cSDimitry Andric 
61349cc55cSDimitry Andric   _LIBCPP_HIDE_FROM_ABI
62349cc55cSDimitry Andric   constexpr bool __is_ordered() const noexcept {
63349cc55cSDimitry Andric     return __value_ != _ValueT(_NCmpResult::__unordered);
64349cc55cSDimitry Andric   }
65349cc55cSDimitry Andric public:
66349cc55cSDimitry Andric   // valid values
67349cc55cSDimitry Andric   static const partial_ordering less;
68349cc55cSDimitry Andric   static const partial_ordering equivalent;
69349cc55cSDimitry Andric   static const partial_ordering greater;
70349cc55cSDimitry Andric   static const partial_ordering unordered;
71349cc55cSDimitry Andric 
72349cc55cSDimitry Andric   // comparisons
73349cc55cSDimitry Andric   _LIBCPP_HIDE_FROM_ABI
74349cc55cSDimitry Andric   friend constexpr bool operator==(partial_ordering, partial_ordering) noexcept = default;
75349cc55cSDimitry Andric 
76349cc55cSDimitry Andric   _LIBCPP_HIDE_FROM_ABI
77349cc55cSDimitry Andric   friend constexpr bool operator==(partial_ordering __v, _CmpUnspecifiedParam) noexcept {
78349cc55cSDimitry Andric     return __v.__is_ordered() && __v.__value_ == 0;
79349cc55cSDimitry Andric   }
80349cc55cSDimitry Andric 
81349cc55cSDimitry Andric   _LIBCPP_HIDE_FROM_ABI
82349cc55cSDimitry Andric   friend constexpr bool operator< (partial_ordering __v, _CmpUnspecifiedParam) noexcept {
83349cc55cSDimitry Andric     return __v.__is_ordered() && __v.__value_ < 0;
84349cc55cSDimitry Andric   }
85349cc55cSDimitry Andric 
86349cc55cSDimitry Andric   _LIBCPP_HIDE_FROM_ABI
87349cc55cSDimitry Andric   friend constexpr bool operator<=(partial_ordering __v, _CmpUnspecifiedParam) noexcept  {
88349cc55cSDimitry Andric     return __v.__is_ordered() && __v.__value_ <= 0;
89349cc55cSDimitry Andric   }
90349cc55cSDimitry Andric 
91349cc55cSDimitry Andric   _LIBCPP_HIDE_FROM_ABI
92349cc55cSDimitry Andric   friend constexpr bool operator> (partial_ordering __v, _CmpUnspecifiedParam) noexcept  {
93349cc55cSDimitry Andric     return __v.__is_ordered() && __v.__value_ > 0;
94349cc55cSDimitry Andric   }
95349cc55cSDimitry Andric 
96349cc55cSDimitry Andric   _LIBCPP_HIDE_FROM_ABI
97349cc55cSDimitry Andric   friend constexpr bool operator>=(partial_ordering __v, _CmpUnspecifiedParam) noexcept  {
98349cc55cSDimitry Andric     return __v.__is_ordered() && __v.__value_ >= 0;
99349cc55cSDimitry Andric   }
100349cc55cSDimitry Andric 
101349cc55cSDimitry Andric   _LIBCPP_HIDE_FROM_ABI
102349cc55cSDimitry Andric   friend constexpr bool operator< (_CmpUnspecifiedParam, partial_ordering __v) noexcept  {
103349cc55cSDimitry Andric     return __v.__is_ordered() && 0 < __v.__value_;
104349cc55cSDimitry Andric   }
105349cc55cSDimitry Andric 
106349cc55cSDimitry Andric   _LIBCPP_HIDE_FROM_ABI
107349cc55cSDimitry Andric   friend constexpr bool operator<=(_CmpUnspecifiedParam, partial_ordering __v) noexcept  {
108349cc55cSDimitry Andric     return __v.__is_ordered() && 0 <= __v.__value_;
109349cc55cSDimitry Andric   }
110349cc55cSDimitry Andric 
111349cc55cSDimitry Andric   _LIBCPP_HIDE_FROM_ABI
112349cc55cSDimitry Andric   friend constexpr bool operator> (_CmpUnspecifiedParam, partial_ordering __v) noexcept  {
113349cc55cSDimitry Andric     return __v.__is_ordered() && 0 > __v.__value_;
114349cc55cSDimitry Andric   }
115349cc55cSDimitry Andric 
116349cc55cSDimitry Andric   _LIBCPP_HIDE_FROM_ABI
117349cc55cSDimitry Andric   friend constexpr bool operator>=(_CmpUnspecifiedParam, partial_ordering __v) noexcept  {
118349cc55cSDimitry Andric     return __v.__is_ordered() && 0 >= __v.__value_;
119349cc55cSDimitry Andric   }
120349cc55cSDimitry Andric 
121349cc55cSDimitry Andric   _LIBCPP_HIDE_FROM_ABI
122349cc55cSDimitry Andric   friend constexpr partial_ordering operator<=>(partial_ordering __v, _CmpUnspecifiedParam) noexcept  {
123349cc55cSDimitry Andric     return __v;
124349cc55cSDimitry Andric   }
125349cc55cSDimitry Andric 
126349cc55cSDimitry Andric   _LIBCPP_HIDE_FROM_ABI
127349cc55cSDimitry Andric   friend constexpr partial_ordering operator<=>(_CmpUnspecifiedParam, partial_ordering __v) noexcept  {
128349cc55cSDimitry Andric     return __v < 0 ? partial_ordering::greater : (__v > 0 ? partial_ordering::less : __v);
129349cc55cSDimitry Andric   }
130349cc55cSDimitry Andric private:
131349cc55cSDimitry Andric   _ValueT __value_;
132349cc55cSDimitry Andric };
133349cc55cSDimitry Andric 
134349cc55cSDimitry Andric inline constexpr partial_ordering partial_ordering::less(_OrdResult::__less);
135349cc55cSDimitry Andric inline constexpr partial_ordering partial_ordering::equivalent(_OrdResult::__equiv);
136349cc55cSDimitry Andric inline constexpr partial_ordering partial_ordering::greater(_OrdResult::__greater);
137349cc55cSDimitry Andric inline constexpr partial_ordering partial_ordering::unordered(_NCmpResult ::__unordered);
138349cc55cSDimitry Andric 
139349cc55cSDimitry Andric class weak_ordering {
140349cc55cSDimitry Andric   using _ValueT = signed char;
141349cc55cSDimitry Andric 
142349cc55cSDimitry Andric   _LIBCPP_HIDE_FROM_ABI
143349cc55cSDimitry Andric   explicit constexpr weak_ordering(_OrdResult __v) noexcept : __value_(_ValueT(__v)) {}
144349cc55cSDimitry Andric 
145349cc55cSDimitry Andric public:
146349cc55cSDimitry Andric   static const weak_ordering less;
147349cc55cSDimitry Andric   static const weak_ordering equivalent;
148349cc55cSDimitry Andric   static const weak_ordering greater;
149349cc55cSDimitry Andric 
150349cc55cSDimitry Andric   _LIBCPP_HIDE_FROM_ABI
151349cc55cSDimitry Andric   constexpr operator partial_ordering() const noexcept {
152349cc55cSDimitry Andric     return __value_ == 0 ? partial_ordering::equivalent
153349cc55cSDimitry Andric         : (__value_ < 0 ? partial_ordering::less : partial_ordering::greater);
154349cc55cSDimitry Andric   }
155349cc55cSDimitry Andric 
156349cc55cSDimitry Andric   // comparisons
157349cc55cSDimitry Andric   _LIBCPP_HIDE_FROM_ABI
158349cc55cSDimitry Andric   friend constexpr bool operator==(weak_ordering, weak_ordering) noexcept = default;
159349cc55cSDimitry Andric 
160349cc55cSDimitry Andric   _LIBCPP_HIDE_FROM_ABI
161349cc55cSDimitry Andric   friend constexpr bool operator==(weak_ordering __v, _CmpUnspecifiedParam) noexcept {
162349cc55cSDimitry Andric     return __v.__value_ == 0;
163349cc55cSDimitry Andric   }
164349cc55cSDimitry Andric 
165349cc55cSDimitry Andric   _LIBCPP_HIDE_FROM_ABI
166349cc55cSDimitry Andric   friend constexpr bool operator< (weak_ordering __v, _CmpUnspecifiedParam) noexcept {
167349cc55cSDimitry Andric     return __v.__value_ < 0;
168349cc55cSDimitry Andric   }
169349cc55cSDimitry Andric 
170349cc55cSDimitry Andric   _LIBCPP_HIDE_FROM_ABI
171349cc55cSDimitry Andric   friend constexpr bool operator<=(weak_ordering __v, _CmpUnspecifiedParam) noexcept {
172349cc55cSDimitry Andric     return __v.__value_ <= 0;
173349cc55cSDimitry Andric   }
174349cc55cSDimitry Andric 
175349cc55cSDimitry Andric   _LIBCPP_HIDE_FROM_ABI
176349cc55cSDimitry Andric   friend constexpr bool operator> (weak_ordering __v, _CmpUnspecifiedParam) noexcept {
177349cc55cSDimitry Andric     return __v.__value_ > 0;
178349cc55cSDimitry Andric   }
179349cc55cSDimitry Andric 
180349cc55cSDimitry Andric   _LIBCPP_HIDE_FROM_ABI
181349cc55cSDimitry Andric   friend constexpr bool operator>=(weak_ordering __v, _CmpUnspecifiedParam) noexcept {
182349cc55cSDimitry Andric     return __v.__value_ >= 0;
183349cc55cSDimitry Andric   }
184349cc55cSDimitry Andric 
185349cc55cSDimitry Andric   _LIBCPP_HIDE_FROM_ABI
186349cc55cSDimitry Andric   friend constexpr bool operator< (_CmpUnspecifiedParam, weak_ordering __v) noexcept {
187349cc55cSDimitry Andric     return 0 < __v.__value_;
188349cc55cSDimitry Andric   }
189349cc55cSDimitry Andric 
190349cc55cSDimitry Andric   _LIBCPP_HIDE_FROM_ABI
191349cc55cSDimitry Andric   friend constexpr bool operator<=(_CmpUnspecifiedParam, weak_ordering __v) noexcept {
192349cc55cSDimitry Andric     return 0 <= __v.__value_;
193349cc55cSDimitry Andric   }
194349cc55cSDimitry Andric 
195349cc55cSDimitry Andric   _LIBCPP_HIDE_FROM_ABI
196349cc55cSDimitry Andric   friend constexpr bool operator> (_CmpUnspecifiedParam, weak_ordering __v) noexcept {
197349cc55cSDimitry Andric     return 0 > __v.__value_;
198349cc55cSDimitry Andric   }
199349cc55cSDimitry Andric 
200349cc55cSDimitry Andric   _LIBCPP_HIDE_FROM_ABI
201349cc55cSDimitry Andric   friend constexpr bool operator>=(_CmpUnspecifiedParam, weak_ordering __v) noexcept {
202349cc55cSDimitry Andric     return 0 >= __v.__value_;
203349cc55cSDimitry Andric   }
204349cc55cSDimitry Andric 
205349cc55cSDimitry Andric   _LIBCPP_HIDE_FROM_ABI
206349cc55cSDimitry Andric   friend constexpr weak_ordering operator<=>(weak_ordering __v, _CmpUnspecifiedParam) noexcept {
207349cc55cSDimitry Andric     return __v;
208349cc55cSDimitry Andric   }
209349cc55cSDimitry Andric 
210349cc55cSDimitry Andric   _LIBCPP_HIDE_FROM_ABI
211349cc55cSDimitry Andric   friend constexpr weak_ordering operator<=>(_CmpUnspecifiedParam, weak_ordering __v) noexcept {
212349cc55cSDimitry Andric     return __v < 0 ? weak_ordering::greater : (__v > 0 ? weak_ordering::less : __v);
213349cc55cSDimitry Andric   }
214349cc55cSDimitry Andric 
215349cc55cSDimitry Andric private:
216349cc55cSDimitry Andric   _ValueT __value_;
217349cc55cSDimitry Andric };
218349cc55cSDimitry Andric 
219349cc55cSDimitry Andric inline constexpr weak_ordering weak_ordering::less(_OrdResult::__less);
220349cc55cSDimitry Andric inline constexpr weak_ordering weak_ordering::equivalent(_OrdResult::__equiv);
221349cc55cSDimitry Andric inline constexpr weak_ordering weak_ordering::greater(_OrdResult::__greater);
222349cc55cSDimitry Andric 
223349cc55cSDimitry Andric class strong_ordering {
224349cc55cSDimitry Andric   using _ValueT = signed char;
225349cc55cSDimitry Andric 
226349cc55cSDimitry Andric   _LIBCPP_HIDE_FROM_ABI
227349cc55cSDimitry Andric   explicit constexpr strong_ordering(_OrdResult __v) noexcept : __value_(_ValueT(__v)) {}
228349cc55cSDimitry Andric 
229349cc55cSDimitry Andric public:
230349cc55cSDimitry Andric   static const strong_ordering less;
231349cc55cSDimitry Andric   static const strong_ordering equal;
232349cc55cSDimitry Andric   static const strong_ordering equivalent;
233349cc55cSDimitry Andric   static const strong_ordering greater;
234349cc55cSDimitry Andric 
235349cc55cSDimitry Andric   // conversions
236349cc55cSDimitry Andric   _LIBCPP_HIDE_FROM_ABI
237349cc55cSDimitry Andric   constexpr operator partial_ordering() const noexcept {
238349cc55cSDimitry Andric     return __value_ == 0 ? partial_ordering::equivalent
239349cc55cSDimitry Andric         : (__value_ < 0 ? partial_ordering::less : partial_ordering::greater);
240349cc55cSDimitry Andric   }
241349cc55cSDimitry Andric 
242349cc55cSDimitry Andric   _LIBCPP_HIDE_FROM_ABI
243349cc55cSDimitry Andric   constexpr operator weak_ordering() const noexcept {
244349cc55cSDimitry Andric     return __value_ == 0 ? weak_ordering::equivalent
245349cc55cSDimitry Andric         : (__value_ < 0 ? weak_ordering::less : weak_ordering::greater);
246349cc55cSDimitry Andric   }
247349cc55cSDimitry Andric 
248349cc55cSDimitry Andric   // comparisons
249349cc55cSDimitry Andric   _LIBCPP_HIDE_FROM_ABI
250349cc55cSDimitry Andric   friend constexpr bool operator==(strong_ordering, strong_ordering) noexcept = default;
251349cc55cSDimitry Andric 
252349cc55cSDimitry Andric   _LIBCPP_HIDE_FROM_ABI
253349cc55cSDimitry Andric   friend constexpr bool operator==(strong_ordering __v, _CmpUnspecifiedParam) noexcept {
254349cc55cSDimitry Andric     return __v.__value_ == 0;
255349cc55cSDimitry Andric   }
256349cc55cSDimitry Andric 
257349cc55cSDimitry Andric   _LIBCPP_HIDE_FROM_ABI
258349cc55cSDimitry Andric   friend constexpr bool operator< (strong_ordering __v, _CmpUnspecifiedParam) noexcept {
259349cc55cSDimitry Andric     return __v.__value_ < 0;
260349cc55cSDimitry Andric   }
261349cc55cSDimitry Andric 
262349cc55cSDimitry Andric   _LIBCPP_HIDE_FROM_ABI
263349cc55cSDimitry Andric   friend constexpr bool operator<=(strong_ordering __v, _CmpUnspecifiedParam) noexcept {
264349cc55cSDimitry Andric     return __v.__value_ <= 0;
265349cc55cSDimitry Andric   }
266349cc55cSDimitry Andric 
267349cc55cSDimitry Andric   _LIBCPP_HIDE_FROM_ABI
268349cc55cSDimitry Andric   friend constexpr bool operator> (strong_ordering __v, _CmpUnspecifiedParam) noexcept {
269349cc55cSDimitry Andric     return __v.__value_ > 0;
270349cc55cSDimitry Andric   }
271349cc55cSDimitry Andric 
272349cc55cSDimitry Andric   _LIBCPP_HIDE_FROM_ABI
273349cc55cSDimitry Andric   friend constexpr bool operator>=(strong_ordering __v, _CmpUnspecifiedParam) noexcept {
274349cc55cSDimitry Andric     return __v.__value_ >= 0;
275349cc55cSDimitry Andric   }
276349cc55cSDimitry Andric 
277349cc55cSDimitry Andric   _LIBCPP_HIDE_FROM_ABI
278349cc55cSDimitry Andric   friend constexpr bool operator< (_CmpUnspecifiedParam, strong_ordering __v) noexcept {
279349cc55cSDimitry Andric     return 0 < __v.__value_;
280349cc55cSDimitry Andric   }
281349cc55cSDimitry Andric 
282349cc55cSDimitry Andric   _LIBCPP_HIDE_FROM_ABI
283349cc55cSDimitry Andric   friend constexpr bool operator<=(_CmpUnspecifiedParam, strong_ordering __v) noexcept {
284349cc55cSDimitry Andric     return 0 <= __v.__value_;
285349cc55cSDimitry Andric   }
286349cc55cSDimitry Andric 
287349cc55cSDimitry Andric   _LIBCPP_HIDE_FROM_ABI
288349cc55cSDimitry Andric   friend constexpr bool operator> (_CmpUnspecifiedParam, strong_ordering __v) noexcept {
289349cc55cSDimitry Andric     return 0 > __v.__value_;
290349cc55cSDimitry Andric   }
291349cc55cSDimitry Andric 
292349cc55cSDimitry Andric   _LIBCPP_HIDE_FROM_ABI
293349cc55cSDimitry Andric   friend constexpr bool operator>=(_CmpUnspecifiedParam, strong_ordering __v) noexcept {
294349cc55cSDimitry Andric     return 0 >= __v.__value_;
295349cc55cSDimitry Andric   }
296349cc55cSDimitry Andric 
297349cc55cSDimitry Andric   _LIBCPP_HIDE_FROM_ABI
298349cc55cSDimitry Andric   friend constexpr strong_ordering operator<=>(strong_ordering __v, _CmpUnspecifiedParam) noexcept {
299349cc55cSDimitry Andric     return __v;
300349cc55cSDimitry Andric   }
301349cc55cSDimitry Andric 
302349cc55cSDimitry Andric   _LIBCPP_HIDE_FROM_ABI
303349cc55cSDimitry Andric   friend constexpr strong_ordering operator<=>(_CmpUnspecifiedParam, strong_ordering __v) noexcept {
304349cc55cSDimitry Andric     return __v < 0 ? strong_ordering::greater : (__v > 0 ? strong_ordering::less : __v);
305349cc55cSDimitry Andric   }
306349cc55cSDimitry Andric 
307349cc55cSDimitry Andric private:
308349cc55cSDimitry Andric   _ValueT __value_;
309349cc55cSDimitry Andric };
310349cc55cSDimitry Andric 
311349cc55cSDimitry Andric inline constexpr strong_ordering strong_ordering::less(_OrdResult::__less);
312349cc55cSDimitry Andric inline constexpr strong_ordering strong_ordering::equal(_OrdResult::__equiv);
313349cc55cSDimitry Andric inline constexpr strong_ordering strong_ordering::equivalent(_OrdResult::__equiv);
314349cc55cSDimitry Andric inline constexpr strong_ordering strong_ordering::greater(_OrdResult::__greater);
315349cc55cSDimitry Andric 
316*bdd1243dSDimitry Andric /// [cmp.categories.pre]/1
317*bdd1243dSDimitry Andric /// The types partial_ordering, weak_ordering, and strong_ordering are
318*bdd1243dSDimitry Andric /// collectively termed the comparison category types.
319*bdd1243dSDimitry Andric template <class _Tp>
320*bdd1243dSDimitry Andric concept __comparison_category = __one_of_v<_Tp, partial_ordering, weak_ordering, strong_ordering>;
321*bdd1243dSDimitry Andric 
322349cc55cSDimitry Andric #endif // _LIBCPP_STD_VER > 17
323349cc55cSDimitry Andric 
324349cc55cSDimitry Andric _LIBCPP_END_NAMESPACE_STD
325349cc55cSDimitry Andric 
326349cc55cSDimitry Andric #endif // _LIBCPP___COMPARE_ORDERING_H
327