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