1 //===----------------------------------------------------------------------===//
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
7 //===----------------------------------------------------------------------===//
9 #ifndef _LIBCPP___COMPARE_ORDERING_H
10 #define _LIBCPP___COMPARE_ORDERING_H
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
20 _LIBCPP_BEGIN_NAMESPACE_STD
22 #if _LIBCPP_STD_VER >= 20
25 enum class _OrdResult
: signed char {
31 enum class _NCmpResult
: signed char {
35 class partial_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;
54 explicit constexpr partial_ordering(_OrdResult __v
) noexcept
55 : __value_(_ValueT(__v
)) {}
58 explicit constexpr partial_ordering(_NCmpResult __v
) noexcept
59 : __value_(_ValueT(__v
)) {}
62 constexpr bool __is_ordered() const noexcept
{
63 return __value_
!= _ValueT(_NCmpResult::__unordered
);
67 static const partial_ordering less
;
68 static const partial_ordering equivalent
;
69 static const partial_ordering greater
;
70 static const partial_ordering unordered
;
74 friend constexpr bool operator==(partial_ordering
, partial_ordering
) noexcept
= default;
77 friend constexpr bool operator==(partial_ordering __v
, _CmpUnspecifiedParam
) noexcept
{
78 return __v
.__is_ordered() && __v
.__value_
== 0;
82 friend constexpr bool operator< (partial_ordering __v
, _CmpUnspecifiedParam
) noexcept
{
83 return __v
.__is_ordered() && __v
.__value_
< 0;
87 friend constexpr bool operator<=(partial_ordering __v
, _CmpUnspecifiedParam
) noexcept
{
88 return __v
.__is_ordered() && __v
.__value_
<= 0;
92 friend constexpr bool operator> (partial_ordering __v
, _CmpUnspecifiedParam
) noexcept
{
93 return __v
.__is_ordered() && __v
.__value_
> 0;
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
{
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
);
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
)) {}
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
);
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
{
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
);
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
)) {}
230 static const strong_ordering less
;
231 static const strong_ordering equal
;
232 static const strong_ordering equivalent
;
233 static const strong_ordering greater
;
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
);
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
{
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
);
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.
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