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 _PartialOrdResult
: signed char {
28 __less
= static_cast<signed char>(_OrdResult::__less
),
29 __equiv
= static_cast<signed char>(_OrdResult::__equiv
),
30 __greater
= static_cast<signed char>(_OrdResult::__greater
),
34 class partial_ordering
;
36 class strong_ordering
;
38 struct _CmpUnspecifiedParam
{
39 // If anything other than a literal 0 is provided, the behavior is undefined by the Standard.
41 // The alternative to the `__enable_if__` attribute would be to use the fact that a pointer
42 // can be constructed from literal 0, but this conflicts with `-Wzero-as-null-pointer-constant`.
43 template <class _Tp
, class = __enable_if_t
<is_same_v
<_Tp
, int> > >
44 _LIBCPP_HIDE_FROM_ABI consteval
_CmpUnspecifiedParam(_Tp __zero
) noexcept
45 # if __has_attribute(__enable_if__)
46 __attribute__((__enable_if__(
47 __zero
== 0, "Only literal 0 is allowed as the operand of a comparison with one of the ordering types")))
54 class partial_ordering
{
55 _LIBCPP_HIDE_FROM_ABI
explicit constexpr partial_ordering(_PartialOrdResult __v
) noexcept
: __value_(__v
) {}
59 static const partial_ordering less
;
60 static const partial_ordering equivalent
;
61 static const partial_ordering greater
;
62 static const partial_ordering unordered
;
65 _LIBCPP_HIDE_FROM_ABI
friend constexpr bool operator==(partial_ordering
, partial_ordering
) noexcept
= default;
67 _LIBCPP_HIDE_FROM_ABI
friend constexpr bool operator==(partial_ordering __v
, _CmpUnspecifiedParam
) noexcept
{
68 return __v
.__value_
== _PartialOrdResult::__equiv
;
71 _LIBCPP_HIDE_FROM_ABI
friend constexpr bool operator<(partial_ordering __v
, _CmpUnspecifiedParam
) noexcept
{
72 return __v
.__value_
== _PartialOrdResult::__less
;
75 _LIBCPP_HIDE_FROM_ABI
friend constexpr bool operator<=(partial_ordering __v
, _CmpUnspecifiedParam
) noexcept
{
76 return __v
.__value_
== _PartialOrdResult::__equiv
|| __v
.__value_
== _PartialOrdResult::__less
;
79 _LIBCPP_HIDE_FROM_ABI
friend constexpr bool operator>(partial_ordering __v
, _CmpUnspecifiedParam
) noexcept
{
80 return __v
.__value_
== _PartialOrdResult::__greater
;
83 _LIBCPP_HIDE_FROM_ABI
friend constexpr bool operator>=(partial_ordering __v
, _CmpUnspecifiedParam
) noexcept
{
84 return __v
.__value_
== _PartialOrdResult::__equiv
|| __v
.__value_
== _PartialOrdResult::__greater
;
87 _LIBCPP_HIDE_FROM_ABI
friend constexpr bool operator<(_CmpUnspecifiedParam
, partial_ordering __v
) noexcept
{
88 return __v
.__value_
== _PartialOrdResult::__greater
;
91 _LIBCPP_HIDE_FROM_ABI
friend constexpr bool operator<=(_CmpUnspecifiedParam
, partial_ordering __v
) noexcept
{
92 return __v
.__value_
== _PartialOrdResult::__equiv
|| __v
.__value_
== _PartialOrdResult::__greater
;
95 _LIBCPP_HIDE_FROM_ABI
friend constexpr bool operator>(_CmpUnspecifiedParam
, partial_ordering __v
) noexcept
{
96 return __v
.__value_
== _PartialOrdResult::__less
;
99 _LIBCPP_HIDE_FROM_ABI
friend constexpr bool operator>=(_CmpUnspecifiedParam
, partial_ordering __v
) noexcept
{
100 return __v
.__value_
== _PartialOrdResult::__equiv
|| __v
.__value_
== _PartialOrdResult::__less
;
103 _LIBCPP_HIDE_FROM_ABI
friend constexpr partial_ordering
104 operator<=>(partial_ordering __v
, _CmpUnspecifiedParam
) noexcept
{
108 _LIBCPP_HIDE_FROM_ABI
friend constexpr partial_ordering
109 operator<=>(_CmpUnspecifiedParam
, partial_ordering __v
) noexcept
{
110 return __v
< 0 ? partial_ordering::greater
: (__v
> 0 ? partial_ordering::less
: __v
);
114 _PartialOrdResult __value_
;
117 inline constexpr partial_ordering
partial_ordering::less(_PartialOrdResult::__less
);
118 inline constexpr partial_ordering
partial_ordering::equivalent(_PartialOrdResult::__equiv
);
119 inline constexpr partial_ordering
partial_ordering::greater(_PartialOrdResult::__greater
);
120 inline constexpr partial_ordering
partial_ordering::unordered(_PartialOrdResult::__unordered
);
122 class weak_ordering
{
123 using _ValueT
= signed char;
125 _LIBCPP_HIDE_FROM_ABI
explicit constexpr weak_ordering(_OrdResult __v
) noexcept
: __value_(_ValueT(__v
)) {}
128 static const weak_ordering less
;
129 static const weak_ordering equivalent
;
130 static const weak_ordering greater
;
132 _LIBCPP_HIDE_FROM_ABI
constexpr operator partial_ordering() const noexcept
{
133 return __value_
== 0 ? partial_ordering::equivalent
134 : (__value_
< 0 ? partial_ordering::less
: partial_ordering::greater
);
138 _LIBCPP_HIDE_FROM_ABI
friend constexpr bool operator==(weak_ordering
, weak_ordering
) noexcept
= default;
140 _LIBCPP_HIDE_FROM_ABI
friend constexpr bool operator==(weak_ordering __v
, _CmpUnspecifiedParam
) noexcept
{
141 return __v
.__value_
== 0;
144 _LIBCPP_HIDE_FROM_ABI
friend constexpr bool operator<(weak_ordering __v
, _CmpUnspecifiedParam
) noexcept
{
145 return __v
.__value_
< 0;
148 _LIBCPP_HIDE_FROM_ABI
friend constexpr bool operator<=(weak_ordering __v
, _CmpUnspecifiedParam
) noexcept
{
149 return __v
.__value_
<= 0;
152 _LIBCPP_HIDE_FROM_ABI
friend constexpr bool operator>(weak_ordering __v
, _CmpUnspecifiedParam
) noexcept
{
153 return __v
.__value_
> 0;
156 _LIBCPP_HIDE_FROM_ABI
friend constexpr bool operator>=(weak_ordering __v
, _CmpUnspecifiedParam
) noexcept
{
157 return __v
.__value_
>= 0;
160 _LIBCPP_HIDE_FROM_ABI
friend constexpr bool operator<(_CmpUnspecifiedParam
, weak_ordering __v
) noexcept
{
161 return 0 < __v
.__value_
;
164 _LIBCPP_HIDE_FROM_ABI
friend constexpr bool operator<=(_CmpUnspecifiedParam
, weak_ordering __v
) noexcept
{
165 return 0 <= __v
.__value_
;
168 _LIBCPP_HIDE_FROM_ABI
friend constexpr bool operator>(_CmpUnspecifiedParam
, weak_ordering __v
) noexcept
{
169 return 0 > __v
.__value_
;
172 _LIBCPP_HIDE_FROM_ABI
friend constexpr bool operator>=(_CmpUnspecifiedParam
, weak_ordering __v
) noexcept
{
173 return 0 >= __v
.__value_
;
176 _LIBCPP_HIDE_FROM_ABI
friend constexpr weak_ordering
operator<=>(weak_ordering __v
, _CmpUnspecifiedParam
) noexcept
{
180 _LIBCPP_HIDE_FROM_ABI
friend constexpr weak_ordering
operator<=>(_CmpUnspecifiedParam
, weak_ordering __v
) noexcept
{
181 return __v
< 0 ? weak_ordering::greater
: (__v
> 0 ? weak_ordering::less
: __v
);
188 inline constexpr weak_ordering
weak_ordering::less(_OrdResult::__less
);
189 inline constexpr weak_ordering
weak_ordering::equivalent(_OrdResult::__equiv
);
190 inline constexpr weak_ordering
weak_ordering::greater(_OrdResult::__greater
);
192 class strong_ordering
{
193 using _ValueT
= signed char;
195 _LIBCPP_HIDE_FROM_ABI
explicit constexpr strong_ordering(_OrdResult __v
) noexcept
: __value_(_ValueT(__v
)) {}
198 static const strong_ordering less
;
199 static const strong_ordering equal
;
200 static const strong_ordering equivalent
;
201 static const strong_ordering greater
;
204 _LIBCPP_HIDE_FROM_ABI
constexpr operator partial_ordering() const noexcept
{
205 return __value_
== 0 ? partial_ordering::equivalent
206 : (__value_
< 0 ? partial_ordering::less
: partial_ordering::greater
);
209 _LIBCPP_HIDE_FROM_ABI
constexpr operator weak_ordering() const noexcept
{
210 return __value_
== 0 ? weak_ordering::equivalent
: (__value_
< 0 ? weak_ordering::less
: weak_ordering::greater
);
214 _LIBCPP_HIDE_FROM_ABI
friend constexpr bool operator==(strong_ordering
, strong_ordering
) noexcept
= default;
216 _LIBCPP_HIDE_FROM_ABI
friend constexpr bool operator==(strong_ordering __v
, _CmpUnspecifiedParam
) noexcept
{
217 return __v
.__value_
== 0;
220 _LIBCPP_HIDE_FROM_ABI
friend constexpr bool operator<(strong_ordering __v
, _CmpUnspecifiedParam
) noexcept
{
221 return __v
.__value_
< 0;
224 _LIBCPP_HIDE_FROM_ABI
friend constexpr bool operator<=(strong_ordering __v
, _CmpUnspecifiedParam
) noexcept
{
225 return __v
.__value_
<= 0;
228 _LIBCPP_HIDE_FROM_ABI
friend constexpr bool operator>(strong_ordering __v
, _CmpUnspecifiedParam
) noexcept
{
229 return __v
.__value_
> 0;
232 _LIBCPP_HIDE_FROM_ABI
friend constexpr bool operator>=(strong_ordering __v
, _CmpUnspecifiedParam
) noexcept
{
233 return __v
.__value_
>= 0;
236 _LIBCPP_HIDE_FROM_ABI
friend constexpr bool operator<(_CmpUnspecifiedParam
, strong_ordering __v
) noexcept
{
237 return 0 < __v
.__value_
;
240 _LIBCPP_HIDE_FROM_ABI
friend constexpr bool operator<=(_CmpUnspecifiedParam
, strong_ordering __v
) noexcept
{
241 return 0 <= __v
.__value_
;
244 _LIBCPP_HIDE_FROM_ABI
friend constexpr bool operator>(_CmpUnspecifiedParam
, strong_ordering __v
) noexcept
{
245 return 0 > __v
.__value_
;
248 _LIBCPP_HIDE_FROM_ABI
friend constexpr bool operator>=(_CmpUnspecifiedParam
, strong_ordering __v
) noexcept
{
249 return 0 >= __v
.__value_
;
252 _LIBCPP_HIDE_FROM_ABI
friend constexpr strong_ordering
253 operator<=>(strong_ordering __v
, _CmpUnspecifiedParam
) noexcept
{
257 _LIBCPP_HIDE_FROM_ABI
friend constexpr strong_ordering
258 operator<=>(_CmpUnspecifiedParam
, strong_ordering __v
) noexcept
{
259 return __v
< 0 ? strong_ordering::greater
: (__v
> 0 ? strong_ordering::less
: __v
);
266 inline constexpr strong_ordering
strong_ordering::less(_OrdResult::__less
);
267 inline constexpr strong_ordering
strong_ordering::equal(_OrdResult::__equiv
);
268 inline constexpr strong_ordering
strong_ordering::equivalent(_OrdResult::__equiv
);
269 inline constexpr strong_ordering
strong_ordering::greater(_OrdResult::__greater
);
271 /// [cmp.categories.pre]/1
272 /// The types partial_ordering, weak_ordering, and strong_ordering are
273 /// collectively termed the comparison category types.
275 concept __comparison_category
=
276 is_same_v
<_Tp
, partial_ordering
> || is_same_v
<_Tp
, weak_ordering
> || is_same_v
<_Tp
, strong_ordering
>;
278 #endif // _LIBCPP_STD_VER >= 20
280 _LIBCPP_END_NAMESPACE_STD
282 #endif // _LIBCPP___COMPARE_ORDERING_H