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 { __less
= -1, __equiv
= 0, __greater
= 1 };
27 enum class _NCmpResult
: signed char { __unordered
= -127 };
29 class partial_ordering
;
31 class strong_ordering
;
33 template <class _Tp
, class... _Args
>
34 inline constexpr bool __one_of_v
= (is_same_v
<_Tp
, _Args
> || ...);
36 struct _CmpUnspecifiedParam
{
37 _LIBCPP_HIDE_FROM_ABI
constexpr _CmpUnspecifiedParam(int _CmpUnspecifiedParam::*) noexcept
{}
39 template <class _Tp
, class = enable_if_t
<!__one_of_v
<_Tp
, int, partial_ordering
, weak_ordering
, strong_ordering
>>>
40 _CmpUnspecifiedParam(_Tp
) = delete;
43 class partial_ordering
{
44 using _ValueT
= signed char;
46 _LIBCPP_HIDE_FROM_ABI
explicit constexpr partial_ordering(_OrdResult __v
) noexcept
: __value_(_ValueT(__v
)) {}
48 _LIBCPP_HIDE_FROM_ABI
explicit constexpr partial_ordering(_NCmpResult __v
) noexcept
: __value_(_ValueT(__v
)) {}
50 _LIBCPP_HIDE_FROM_ABI
constexpr bool __is_ordered() const noexcept
{
51 return __value_
!= _ValueT(_NCmpResult::__unordered
);
56 static const partial_ordering less
;
57 static const partial_ordering equivalent
;
58 static const partial_ordering greater
;
59 static const partial_ordering unordered
;
62 _LIBCPP_HIDE_FROM_ABI
friend constexpr bool operator==(partial_ordering
, partial_ordering
) noexcept
= default;
64 _LIBCPP_HIDE_FROM_ABI
friend constexpr bool operator==(partial_ordering __v
, _CmpUnspecifiedParam
) noexcept
{
65 return __v
.__is_ordered() && __v
.__value_
== 0;
68 _LIBCPP_HIDE_FROM_ABI
friend constexpr bool operator<(partial_ordering __v
, _CmpUnspecifiedParam
) noexcept
{
69 return __v
.__is_ordered() && __v
.__value_
< 0;
72 _LIBCPP_HIDE_FROM_ABI
friend constexpr bool operator<=(partial_ordering __v
, _CmpUnspecifiedParam
) noexcept
{
73 return __v
.__is_ordered() && __v
.__value_
<= 0;
76 _LIBCPP_HIDE_FROM_ABI
friend constexpr bool operator>(partial_ordering __v
, _CmpUnspecifiedParam
) noexcept
{
77 return __v
.__is_ordered() && __v
.__value_
> 0;
80 _LIBCPP_HIDE_FROM_ABI
friend constexpr bool operator>=(partial_ordering __v
, _CmpUnspecifiedParam
) noexcept
{
81 return __v
.__is_ordered() && __v
.__value_
>= 0;
84 _LIBCPP_HIDE_FROM_ABI
friend constexpr bool operator<(_CmpUnspecifiedParam
, partial_ordering __v
) noexcept
{
85 return __v
.__is_ordered() && 0 < __v
.__value_
;
88 _LIBCPP_HIDE_FROM_ABI
friend constexpr bool operator<=(_CmpUnspecifiedParam
, partial_ordering __v
) noexcept
{
89 return __v
.__is_ordered() && 0 <= __v
.__value_
;
92 _LIBCPP_HIDE_FROM_ABI
friend constexpr bool operator>(_CmpUnspecifiedParam
, partial_ordering __v
) noexcept
{
93 return __v
.__is_ordered() && 0 > __v
.__value_
;
96 _LIBCPP_HIDE_FROM_ABI
friend constexpr bool operator>=(_CmpUnspecifiedParam
, partial_ordering __v
) noexcept
{
97 return __v
.__is_ordered() && 0 >= __v
.__value_
;
100 _LIBCPP_HIDE_FROM_ABI
friend constexpr partial_ordering
101 operator<=>(partial_ordering __v
, _CmpUnspecifiedParam
) noexcept
{
105 _LIBCPP_HIDE_FROM_ABI
friend constexpr partial_ordering
106 operator<=>(_CmpUnspecifiedParam
, partial_ordering __v
) noexcept
{
107 return __v
< 0 ? partial_ordering::greater
: (__v
> 0 ? partial_ordering::less
: __v
);
114 inline constexpr partial_ordering
partial_ordering::less(_OrdResult::__less
);
115 inline constexpr partial_ordering
partial_ordering::equivalent(_OrdResult::__equiv
);
116 inline constexpr partial_ordering
partial_ordering::greater(_OrdResult::__greater
);
117 inline constexpr partial_ordering
partial_ordering::unordered(_NCmpResult ::__unordered
);
119 class weak_ordering
{
120 using _ValueT
= signed char;
122 _LIBCPP_HIDE_FROM_ABI
explicit constexpr weak_ordering(_OrdResult __v
) noexcept
: __value_(_ValueT(__v
)) {}
125 static const weak_ordering less
;
126 static const weak_ordering equivalent
;
127 static const weak_ordering greater
;
129 _LIBCPP_HIDE_FROM_ABI
constexpr operator partial_ordering() const noexcept
{
130 return __value_
== 0 ? partial_ordering::equivalent
131 : (__value_
< 0 ? partial_ordering::less
: partial_ordering::greater
);
135 _LIBCPP_HIDE_FROM_ABI
friend constexpr bool operator==(weak_ordering
, weak_ordering
) noexcept
= default;
137 _LIBCPP_HIDE_FROM_ABI
friend constexpr bool operator==(weak_ordering __v
, _CmpUnspecifiedParam
) noexcept
{
138 return __v
.__value_
== 0;
141 _LIBCPP_HIDE_FROM_ABI
friend constexpr bool operator<(weak_ordering __v
, _CmpUnspecifiedParam
) noexcept
{
142 return __v
.__value_
< 0;
145 _LIBCPP_HIDE_FROM_ABI
friend constexpr bool operator<=(weak_ordering __v
, _CmpUnspecifiedParam
) noexcept
{
146 return __v
.__value_
<= 0;
149 _LIBCPP_HIDE_FROM_ABI
friend constexpr bool operator>(weak_ordering __v
, _CmpUnspecifiedParam
) noexcept
{
150 return __v
.__value_
> 0;
153 _LIBCPP_HIDE_FROM_ABI
friend constexpr bool operator>=(weak_ordering __v
, _CmpUnspecifiedParam
) noexcept
{
154 return __v
.__value_
>= 0;
157 _LIBCPP_HIDE_FROM_ABI
friend constexpr bool operator<(_CmpUnspecifiedParam
, weak_ordering __v
) noexcept
{
158 return 0 < __v
.__value_
;
161 _LIBCPP_HIDE_FROM_ABI
friend constexpr bool operator<=(_CmpUnspecifiedParam
, weak_ordering __v
) noexcept
{
162 return 0 <= __v
.__value_
;
165 _LIBCPP_HIDE_FROM_ABI
friend constexpr bool operator>(_CmpUnspecifiedParam
, weak_ordering __v
) noexcept
{
166 return 0 > __v
.__value_
;
169 _LIBCPP_HIDE_FROM_ABI
friend constexpr bool operator>=(_CmpUnspecifiedParam
, weak_ordering __v
) noexcept
{
170 return 0 >= __v
.__value_
;
173 _LIBCPP_HIDE_FROM_ABI
friend constexpr weak_ordering
operator<=>(weak_ordering __v
, _CmpUnspecifiedParam
) noexcept
{
177 _LIBCPP_HIDE_FROM_ABI
friend constexpr weak_ordering
operator<=>(_CmpUnspecifiedParam
, weak_ordering __v
) noexcept
{
178 return __v
< 0 ? weak_ordering::greater
: (__v
> 0 ? weak_ordering::less
: __v
);
185 inline constexpr weak_ordering
weak_ordering::less(_OrdResult::__less
);
186 inline constexpr weak_ordering
weak_ordering::equivalent(_OrdResult::__equiv
);
187 inline constexpr weak_ordering
weak_ordering::greater(_OrdResult::__greater
);
189 class strong_ordering
{
190 using _ValueT
= signed char;
192 _LIBCPP_HIDE_FROM_ABI
explicit constexpr strong_ordering(_OrdResult __v
) noexcept
: __value_(_ValueT(__v
)) {}
195 static const strong_ordering less
;
196 static const strong_ordering equal
;
197 static const strong_ordering equivalent
;
198 static const strong_ordering greater
;
201 _LIBCPP_HIDE_FROM_ABI
constexpr operator partial_ordering() const noexcept
{
202 return __value_
== 0 ? partial_ordering::equivalent
203 : (__value_
< 0 ? partial_ordering::less
: partial_ordering::greater
);
206 _LIBCPP_HIDE_FROM_ABI
constexpr operator weak_ordering() const noexcept
{
207 return __value_
== 0 ? weak_ordering::equivalent
: (__value_
< 0 ? weak_ordering::less
: weak_ordering::greater
);
211 _LIBCPP_HIDE_FROM_ABI
friend constexpr bool operator==(strong_ordering
, strong_ordering
) noexcept
= default;
213 _LIBCPP_HIDE_FROM_ABI
friend constexpr bool operator==(strong_ordering __v
, _CmpUnspecifiedParam
) noexcept
{
214 return __v
.__value_
== 0;
217 _LIBCPP_HIDE_FROM_ABI
friend constexpr bool operator<(strong_ordering __v
, _CmpUnspecifiedParam
) noexcept
{
218 return __v
.__value_
< 0;
221 _LIBCPP_HIDE_FROM_ABI
friend constexpr bool operator<=(strong_ordering __v
, _CmpUnspecifiedParam
) noexcept
{
222 return __v
.__value_
<= 0;
225 _LIBCPP_HIDE_FROM_ABI
friend constexpr bool operator>(strong_ordering __v
, _CmpUnspecifiedParam
) noexcept
{
226 return __v
.__value_
> 0;
229 _LIBCPP_HIDE_FROM_ABI
friend constexpr bool operator>=(strong_ordering __v
, _CmpUnspecifiedParam
) noexcept
{
230 return __v
.__value_
>= 0;
233 _LIBCPP_HIDE_FROM_ABI
friend constexpr bool operator<(_CmpUnspecifiedParam
, strong_ordering __v
) noexcept
{
234 return 0 < __v
.__value_
;
237 _LIBCPP_HIDE_FROM_ABI
friend constexpr bool operator<=(_CmpUnspecifiedParam
, strong_ordering __v
) noexcept
{
238 return 0 <= __v
.__value_
;
241 _LIBCPP_HIDE_FROM_ABI
friend constexpr bool operator>(_CmpUnspecifiedParam
, strong_ordering __v
) noexcept
{
242 return 0 > __v
.__value_
;
245 _LIBCPP_HIDE_FROM_ABI
friend constexpr bool operator>=(_CmpUnspecifiedParam
, strong_ordering __v
) noexcept
{
246 return 0 >= __v
.__value_
;
249 _LIBCPP_HIDE_FROM_ABI
friend constexpr strong_ordering
250 operator<=>(strong_ordering __v
, _CmpUnspecifiedParam
) noexcept
{
254 _LIBCPP_HIDE_FROM_ABI
friend constexpr strong_ordering
255 operator<=>(_CmpUnspecifiedParam
, strong_ordering __v
) noexcept
{
256 return __v
< 0 ? strong_ordering::greater
: (__v
> 0 ? strong_ordering::less
: __v
);
263 inline constexpr strong_ordering
strong_ordering::less(_OrdResult::__less
);
264 inline constexpr strong_ordering
strong_ordering::equal(_OrdResult::__equiv
);
265 inline constexpr strong_ordering
strong_ordering::equivalent(_OrdResult::__equiv
);
266 inline constexpr strong_ordering
strong_ordering::greater(_OrdResult::__greater
);
268 /// [cmp.categories.pre]/1
269 /// The types partial_ordering, weak_ordering, and strong_ordering are
270 /// collectively termed the comparison category types.
272 concept __comparison_category
= __one_of_v
<_Tp
, partial_ordering
, weak_ordering
, strong_ordering
>;
274 #endif // _LIBCPP_STD_VER >= 20
276 _LIBCPP_END_NAMESPACE_STD
278 #endif // _LIBCPP___COMPARE_ORDERING_H