xref: /freebsd-src/contrib/llvm-project/libcxx/include/__compare/ordering.h (revision cb14a3fe5122c879eae1fb480ed7ce82a699ddb6)
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>
13bdd1243dSDimitry Andric #include <__type_traits/enable_if.h>
14bdd1243dSDimitry 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 
2206c3fb27SDimitry Andric #if _LIBCPP_STD_VER >= 20
23349cc55cSDimitry Andric 
24349cc55cSDimitry Andric // exposition only
25*cb14a3feSDimitry Andric enum class _OrdResult : signed char { __less = -1, __equiv = 0, __greater = 1 };
26349cc55cSDimitry Andric 
27*cb14a3feSDimitry Andric enum class _NCmpResult : signed char { __unordered = -127 };
28349cc55cSDimitry Andric 
29349cc55cSDimitry Andric class partial_ordering;
30349cc55cSDimitry Andric class weak_ordering;
31349cc55cSDimitry Andric class strong_ordering;
32349cc55cSDimitry Andric 
33349cc55cSDimitry Andric template <class _Tp, class... _Args>
34349cc55cSDimitry Andric inline constexpr bool __one_of_v = (is_same_v<_Tp, _Args> || ...);
35349cc55cSDimitry Andric 
36349cc55cSDimitry Andric struct _CmpUnspecifiedParam {
_CmpUnspecifiedParam_CmpUnspecifiedParam37*cb14a3feSDimitry Andric   _LIBCPP_HIDE_FROM_ABI constexpr _CmpUnspecifiedParam(int _CmpUnspecifiedParam::*) noexcept {}
38349cc55cSDimitry Andric 
39349cc55cSDimitry Andric   template <class _Tp, class = enable_if_t<!__one_of_v<_Tp, int, partial_ordering, weak_ordering, strong_ordering>>>
40349cc55cSDimitry Andric   _CmpUnspecifiedParam(_Tp) = delete;
41349cc55cSDimitry Andric };
42349cc55cSDimitry Andric 
43349cc55cSDimitry Andric class partial_ordering {
44349cc55cSDimitry Andric   using _ValueT = signed char;
45349cc55cSDimitry Andric 
partial_ordering(_OrdResult __v)46*cb14a3feSDimitry Andric   _LIBCPP_HIDE_FROM_ABI explicit constexpr partial_ordering(_OrdResult __v) noexcept : __value_(_ValueT(__v)) {}
47349cc55cSDimitry Andric 
partial_ordering(_NCmpResult __v)48*cb14a3feSDimitry Andric   _LIBCPP_HIDE_FROM_ABI explicit constexpr partial_ordering(_NCmpResult __v) noexcept : __value_(_ValueT(__v)) {}
49349cc55cSDimitry Andric 
__is_ordered()50*cb14a3feSDimitry Andric   _LIBCPP_HIDE_FROM_ABI constexpr bool __is_ordered() const noexcept {
51349cc55cSDimitry Andric     return __value_ != _ValueT(_NCmpResult::__unordered);
52349cc55cSDimitry Andric   }
53*cb14a3feSDimitry Andric 
54349cc55cSDimitry Andric public:
55349cc55cSDimitry Andric   // valid values
56349cc55cSDimitry Andric   static const partial_ordering less;
57349cc55cSDimitry Andric   static const partial_ordering equivalent;
58349cc55cSDimitry Andric   static const partial_ordering greater;
59349cc55cSDimitry Andric   static const partial_ordering unordered;
60349cc55cSDimitry Andric 
61349cc55cSDimitry Andric   // comparisons
62*cb14a3feSDimitry Andric   _LIBCPP_HIDE_FROM_ABI friend constexpr bool operator==(partial_ordering, partial_ordering) noexcept = default;
63349cc55cSDimitry Andric 
64*cb14a3feSDimitry Andric   _LIBCPP_HIDE_FROM_ABI friend constexpr bool operator==(partial_ordering __v, _CmpUnspecifiedParam) noexcept {
65349cc55cSDimitry Andric     return __v.__is_ordered() && __v.__value_ == 0;
66349cc55cSDimitry Andric   }
67349cc55cSDimitry Andric 
68*cb14a3feSDimitry Andric   _LIBCPP_HIDE_FROM_ABI friend constexpr bool operator<(partial_ordering __v, _CmpUnspecifiedParam) noexcept {
69349cc55cSDimitry Andric     return __v.__is_ordered() && __v.__value_ < 0;
70349cc55cSDimitry Andric   }
71349cc55cSDimitry Andric 
72*cb14a3feSDimitry Andric   _LIBCPP_HIDE_FROM_ABI friend constexpr bool operator<=(partial_ordering __v, _CmpUnspecifiedParam) noexcept {
73349cc55cSDimitry Andric     return __v.__is_ordered() && __v.__value_ <= 0;
74349cc55cSDimitry Andric   }
75349cc55cSDimitry Andric 
76*cb14a3feSDimitry Andric   _LIBCPP_HIDE_FROM_ABI friend constexpr bool operator>(partial_ordering __v, _CmpUnspecifiedParam) noexcept {
77349cc55cSDimitry Andric     return __v.__is_ordered() && __v.__value_ > 0;
78349cc55cSDimitry Andric   }
79349cc55cSDimitry Andric 
80*cb14a3feSDimitry Andric   _LIBCPP_HIDE_FROM_ABI friend constexpr bool operator>=(partial_ordering __v, _CmpUnspecifiedParam) noexcept {
81349cc55cSDimitry Andric     return __v.__is_ordered() && __v.__value_ >= 0;
82349cc55cSDimitry Andric   }
83349cc55cSDimitry Andric 
84*cb14a3feSDimitry Andric   _LIBCPP_HIDE_FROM_ABI friend constexpr bool operator<(_CmpUnspecifiedParam, partial_ordering __v) noexcept {
85349cc55cSDimitry Andric     return __v.__is_ordered() && 0 < __v.__value_;
86349cc55cSDimitry Andric   }
87349cc55cSDimitry Andric 
88*cb14a3feSDimitry Andric   _LIBCPP_HIDE_FROM_ABI friend constexpr bool operator<=(_CmpUnspecifiedParam, partial_ordering __v) noexcept {
89349cc55cSDimitry Andric     return __v.__is_ordered() && 0 <= __v.__value_;
90349cc55cSDimitry Andric   }
91349cc55cSDimitry Andric 
92*cb14a3feSDimitry Andric   _LIBCPP_HIDE_FROM_ABI friend constexpr bool operator>(_CmpUnspecifiedParam, partial_ordering __v) noexcept {
93349cc55cSDimitry Andric     return __v.__is_ordered() && 0 > __v.__value_;
94349cc55cSDimitry Andric   }
95349cc55cSDimitry Andric 
96*cb14a3feSDimitry Andric   _LIBCPP_HIDE_FROM_ABI friend constexpr bool operator>=(_CmpUnspecifiedParam, partial_ordering __v) noexcept {
97349cc55cSDimitry Andric     return __v.__is_ordered() && 0 >= __v.__value_;
98349cc55cSDimitry Andric   }
99349cc55cSDimitry Andric 
100*cb14a3feSDimitry Andric   _LIBCPP_HIDE_FROM_ABI friend constexpr partial_ordering
101*cb14a3feSDimitry Andric   operator<=>(partial_ordering __v, _CmpUnspecifiedParam) noexcept {
102349cc55cSDimitry Andric     return __v;
103349cc55cSDimitry Andric   }
104349cc55cSDimitry Andric 
105*cb14a3feSDimitry Andric   _LIBCPP_HIDE_FROM_ABI friend constexpr partial_ordering
106*cb14a3feSDimitry Andric   operator<=>(_CmpUnspecifiedParam, partial_ordering __v) noexcept {
107349cc55cSDimitry Andric     return __v < 0 ? partial_ordering::greater : (__v > 0 ? partial_ordering::less : __v);
108349cc55cSDimitry Andric   }
109*cb14a3feSDimitry Andric 
110349cc55cSDimitry Andric private:
111349cc55cSDimitry Andric   _ValueT __value_;
112349cc55cSDimitry Andric };
113349cc55cSDimitry Andric 
114349cc55cSDimitry Andric inline constexpr partial_ordering partial_ordering::less(_OrdResult::__less);
115349cc55cSDimitry Andric inline constexpr partial_ordering partial_ordering::equivalent(_OrdResult::__equiv);
116349cc55cSDimitry Andric inline constexpr partial_ordering partial_ordering::greater(_OrdResult::__greater);
117349cc55cSDimitry Andric inline constexpr partial_ordering partial_ordering::unordered(_NCmpResult ::__unordered);
118349cc55cSDimitry Andric 
119349cc55cSDimitry Andric class weak_ordering {
120349cc55cSDimitry Andric   using _ValueT = signed char;
121349cc55cSDimitry Andric 
weak_ordering(_OrdResult __v)122*cb14a3feSDimitry Andric   _LIBCPP_HIDE_FROM_ABI explicit constexpr weak_ordering(_OrdResult __v) noexcept : __value_(_ValueT(__v)) {}
123349cc55cSDimitry Andric 
124349cc55cSDimitry Andric public:
125349cc55cSDimitry Andric   static const weak_ordering less;
126349cc55cSDimitry Andric   static const weak_ordering equivalent;
127349cc55cSDimitry Andric   static const weak_ordering greater;
128349cc55cSDimitry Andric 
partial_ordering()129*cb14a3feSDimitry Andric   _LIBCPP_HIDE_FROM_ABI constexpr operator partial_ordering() const noexcept {
130349cc55cSDimitry Andric     return __value_ == 0 ? partial_ordering::equivalent
131349cc55cSDimitry Andric                          : (__value_ < 0 ? partial_ordering::less : partial_ordering::greater);
132349cc55cSDimitry Andric   }
133349cc55cSDimitry Andric 
134349cc55cSDimitry Andric   // comparisons
135*cb14a3feSDimitry Andric   _LIBCPP_HIDE_FROM_ABI friend constexpr bool operator==(weak_ordering, weak_ordering) noexcept = default;
136349cc55cSDimitry Andric 
137*cb14a3feSDimitry Andric   _LIBCPP_HIDE_FROM_ABI friend constexpr bool operator==(weak_ordering __v, _CmpUnspecifiedParam) noexcept {
138349cc55cSDimitry Andric     return __v.__value_ == 0;
139349cc55cSDimitry Andric   }
140349cc55cSDimitry Andric 
141*cb14a3feSDimitry Andric   _LIBCPP_HIDE_FROM_ABI friend constexpr bool operator<(weak_ordering __v, _CmpUnspecifiedParam) noexcept {
142349cc55cSDimitry Andric     return __v.__value_ < 0;
143349cc55cSDimitry Andric   }
144349cc55cSDimitry Andric 
145*cb14a3feSDimitry Andric   _LIBCPP_HIDE_FROM_ABI friend constexpr bool operator<=(weak_ordering __v, _CmpUnspecifiedParam) noexcept {
146349cc55cSDimitry Andric     return __v.__value_ <= 0;
147349cc55cSDimitry Andric   }
148349cc55cSDimitry Andric 
149*cb14a3feSDimitry Andric   _LIBCPP_HIDE_FROM_ABI friend constexpr bool operator>(weak_ordering __v, _CmpUnspecifiedParam) noexcept {
150349cc55cSDimitry Andric     return __v.__value_ > 0;
151349cc55cSDimitry Andric   }
152349cc55cSDimitry Andric 
153*cb14a3feSDimitry Andric   _LIBCPP_HIDE_FROM_ABI friend constexpr bool operator>=(weak_ordering __v, _CmpUnspecifiedParam) noexcept {
154349cc55cSDimitry Andric     return __v.__value_ >= 0;
155349cc55cSDimitry Andric   }
156349cc55cSDimitry Andric 
157*cb14a3feSDimitry Andric   _LIBCPP_HIDE_FROM_ABI friend constexpr bool operator<(_CmpUnspecifiedParam, weak_ordering __v) noexcept {
158349cc55cSDimitry Andric     return 0 < __v.__value_;
159349cc55cSDimitry Andric   }
160349cc55cSDimitry Andric 
161*cb14a3feSDimitry Andric   _LIBCPP_HIDE_FROM_ABI friend constexpr bool operator<=(_CmpUnspecifiedParam, weak_ordering __v) noexcept {
162349cc55cSDimitry Andric     return 0 <= __v.__value_;
163349cc55cSDimitry Andric   }
164349cc55cSDimitry Andric 
165*cb14a3feSDimitry Andric   _LIBCPP_HIDE_FROM_ABI friend constexpr bool operator>(_CmpUnspecifiedParam, weak_ordering __v) noexcept {
166349cc55cSDimitry Andric     return 0 > __v.__value_;
167349cc55cSDimitry Andric   }
168349cc55cSDimitry Andric 
169*cb14a3feSDimitry Andric   _LIBCPP_HIDE_FROM_ABI friend constexpr bool operator>=(_CmpUnspecifiedParam, weak_ordering __v) noexcept {
170349cc55cSDimitry Andric     return 0 >= __v.__value_;
171349cc55cSDimitry Andric   }
172349cc55cSDimitry Andric 
173*cb14a3feSDimitry Andric   _LIBCPP_HIDE_FROM_ABI friend constexpr weak_ordering operator<=>(weak_ordering __v, _CmpUnspecifiedParam) noexcept {
174349cc55cSDimitry Andric     return __v;
175349cc55cSDimitry Andric   }
176349cc55cSDimitry Andric 
177*cb14a3feSDimitry Andric   _LIBCPP_HIDE_FROM_ABI friend constexpr weak_ordering operator<=>(_CmpUnspecifiedParam, weak_ordering __v) noexcept {
178349cc55cSDimitry Andric     return __v < 0 ? weak_ordering::greater : (__v > 0 ? weak_ordering::less : __v);
179349cc55cSDimitry Andric   }
180349cc55cSDimitry Andric 
181349cc55cSDimitry Andric private:
182349cc55cSDimitry Andric   _ValueT __value_;
183349cc55cSDimitry Andric };
184349cc55cSDimitry Andric 
185349cc55cSDimitry Andric inline constexpr weak_ordering weak_ordering::less(_OrdResult::__less);
186349cc55cSDimitry Andric inline constexpr weak_ordering weak_ordering::equivalent(_OrdResult::__equiv);
187349cc55cSDimitry Andric inline constexpr weak_ordering weak_ordering::greater(_OrdResult::__greater);
188349cc55cSDimitry Andric 
189349cc55cSDimitry Andric class strong_ordering {
190349cc55cSDimitry Andric   using _ValueT = signed char;
191349cc55cSDimitry Andric 
strong_ordering(_OrdResult __v)192*cb14a3feSDimitry Andric   _LIBCPP_HIDE_FROM_ABI explicit constexpr strong_ordering(_OrdResult __v) noexcept : __value_(_ValueT(__v)) {}
193349cc55cSDimitry Andric 
194349cc55cSDimitry Andric public:
195349cc55cSDimitry Andric   static const strong_ordering less;
196349cc55cSDimitry Andric   static const strong_ordering equal;
197349cc55cSDimitry Andric   static const strong_ordering equivalent;
198349cc55cSDimitry Andric   static const strong_ordering greater;
199349cc55cSDimitry Andric 
200349cc55cSDimitry Andric   // conversions
partial_ordering()201*cb14a3feSDimitry Andric   _LIBCPP_HIDE_FROM_ABI constexpr operator partial_ordering() const noexcept {
202349cc55cSDimitry Andric     return __value_ == 0 ? partial_ordering::equivalent
203349cc55cSDimitry Andric                          : (__value_ < 0 ? partial_ordering::less : partial_ordering::greater);
204349cc55cSDimitry Andric   }
205349cc55cSDimitry Andric 
weak_ordering()206*cb14a3feSDimitry Andric   _LIBCPP_HIDE_FROM_ABI constexpr operator weak_ordering() const noexcept {
207*cb14a3feSDimitry Andric     return __value_ == 0 ? weak_ordering::equivalent : (__value_ < 0 ? weak_ordering::less : weak_ordering::greater);
208349cc55cSDimitry Andric   }
209349cc55cSDimitry Andric 
210349cc55cSDimitry Andric   // comparisons
211*cb14a3feSDimitry Andric   _LIBCPP_HIDE_FROM_ABI friend constexpr bool operator==(strong_ordering, strong_ordering) noexcept = default;
212349cc55cSDimitry Andric 
213*cb14a3feSDimitry Andric   _LIBCPP_HIDE_FROM_ABI friend constexpr bool operator==(strong_ordering __v, _CmpUnspecifiedParam) noexcept {
214349cc55cSDimitry Andric     return __v.__value_ == 0;
215349cc55cSDimitry Andric   }
216349cc55cSDimitry Andric 
217*cb14a3feSDimitry Andric   _LIBCPP_HIDE_FROM_ABI friend constexpr bool operator<(strong_ordering __v, _CmpUnspecifiedParam) noexcept {
218349cc55cSDimitry Andric     return __v.__value_ < 0;
219349cc55cSDimitry Andric   }
220349cc55cSDimitry Andric 
221*cb14a3feSDimitry Andric   _LIBCPP_HIDE_FROM_ABI friend constexpr bool operator<=(strong_ordering __v, _CmpUnspecifiedParam) noexcept {
222349cc55cSDimitry Andric     return __v.__value_ <= 0;
223349cc55cSDimitry Andric   }
224349cc55cSDimitry Andric 
225*cb14a3feSDimitry Andric   _LIBCPP_HIDE_FROM_ABI friend constexpr bool operator>(strong_ordering __v, _CmpUnspecifiedParam) noexcept {
226349cc55cSDimitry Andric     return __v.__value_ > 0;
227349cc55cSDimitry Andric   }
228349cc55cSDimitry Andric 
229*cb14a3feSDimitry Andric   _LIBCPP_HIDE_FROM_ABI friend constexpr bool operator>=(strong_ordering __v, _CmpUnspecifiedParam) noexcept {
230349cc55cSDimitry Andric     return __v.__value_ >= 0;
231349cc55cSDimitry Andric   }
232349cc55cSDimitry Andric 
233*cb14a3feSDimitry Andric   _LIBCPP_HIDE_FROM_ABI friend constexpr bool operator<(_CmpUnspecifiedParam, strong_ordering __v) noexcept {
234349cc55cSDimitry Andric     return 0 < __v.__value_;
235349cc55cSDimitry Andric   }
236349cc55cSDimitry Andric 
237*cb14a3feSDimitry Andric   _LIBCPP_HIDE_FROM_ABI friend constexpr bool operator<=(_CmpUnspecifiedParam, strong_ordering __v) noexcept {
238349cc55cSDimitry Andric     return 0 <= __v.__value_;
239349cc55cSDimitry Andric   }
240349cc55cSDimitry Andric 
241*cb14a3feSDimitry Andric   _LIBCPP_HIDE_FROM_ABI friend constexpr bool operator>(_CmpUnspecifiedParam, strong_ordering __v) noexcept {
242349cc55cSDimitry Andric     return 0 > __v.__value_;
243349cc55cSDimitry Andric   }
244349cc55cSDimitry Andric 
245*cb14a3feSDimitry Andric   _LIBCPP_HIDE_FROM_ABI friend constexpr bool operator>=(_CmpUnspecifiedParam, strong_ordering __v) noexcept {
246349cc55cSDimitry Andric     return 0 >= __v.__value_;
247349cc55cSDimitry Andric   }
248349cc55cSDimitry Andric 
249*cb14a3feSDimitry Andric   _LIBCPP_HIDE_FROM_ABI friend constexpr strong_ordering
250*cb14a3feSDimitry Andric   operator<=>(strong_ordering __v, _CmpUnspecifiedParam) noexcept {
251349cc55cSDimitry Andric     return __v;
252349cc55cSDimitry Andric   }
253349cc55cSDimitry Andric 
254*cb14a3feSDimitry Andric   _LIBCPP_HIDE_FROM_ABI friend constexpr strong_ordering
255*cb14a3feSDimitry Andric   operator<=>(_CmpUnspecifiedParam, strong_ordering __v) noexcept {
256349cc55cSDimitry Andric     return __v < 0 ? strong_ordering::greater : (__v > 0 ? strong_ordering::less : __v);
257349cc55cSDimitry Andric   }
258349cc55cSDimitry Andric 
259349cc55cSDimitry Andric private:
260349cc55cSDimitry Andric   _ValueT __value_;
261349cc55cSDimitry Andric };
262349cc55cSDimitry Andric 
263349cc55cSDimitry Andric inline constexpr strong_ordering strong_ordering::less(_OrdResult::__less);
264349cc55cSDimitry Andric inline constexpr strong_ordering strong_ordering::equal(_OrdResult::__equiv);
265349cc55cSDimitry Andric inline constexpr strong_ordering strong_ordering::equivalent(_OrdResult::__equiv);
266349cc55cSDimitry Andric inline constexpr strong_ordering strong_ordering::greater(_OrdResult::__greater);
267349cc55cSDimitry Andric 
268bdd1243dSDimitry Andric /// [cmp.categories.pre]/1
269bdd1243dSDimitry Andric /// The types partial_ordering, weak_ordering, and strong_ordering are
270bdd1243dSDimitry Andric /// collectively termed the comparison category types.
271bdd1243dSDimitry Andric template <class _Tp>
272bdd1243dSDimitry Andric concept __comparison_category = __one_of_v<_Tp, partial_ordering, weak_ordering, strong_ordering>;
273bdd1243dSDimitry Andric 
27406c3fb27SDimitry Andric #endif // _LIBCPP_STD_VER >= 20
275349cc55cSDimitry Andric 
276349cc55cSDimitry Andric _LIBCPP_END_NAMESPACE_STD
277349cc55cSDimitry Andric 
278349cc55cSDimitry Andric #endif // _LIBCPP___COMPARE_ORDERING_H
279