blob: 0a2b3d05a1ab4c08e19e1e5edbfe1a8e0a7cdb17 [file] [log] [blame]
Eric Fiseliere0074fc2018-04-06 21:37:23 +00001// -*- C++ -*-
2//===-------------------------- compare -----------------------------------===//
3//
Chandler Carruthd2012102019-01-19 10:56:40 +00004// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
5// See https://llvm.org/LICENSE.txt for license information.
6// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
Eric Fiseliere0074fc2018-04-06 21:37:23 +00007//
8//===----------------------------------------------------------------------===//
9
10#ifndef _LIBCPP_COMPARE
11#define _LIBCPP_COMPARE
12
13/*
14 compare synopsis
15
16namespace std {
17 // [cmp.categories], comparison category types
Eric Fiseliere0074fc2018-04-06 21:37:23 +000018 class partial_ordering;
19 class weak_ordering;
20 class strong_ordering;
21
22 // named comparison functions
Christopher Di Bellac50acf72021-04-12 05:23:09 +000023 constexpr bool is_eq (partial_ordering cmp) noexcept { return cmp == 0; }
24 constexpr bool is_neq (partial_ordering cmp) noexcept { return cmp != 0; }
Eric Fiseliere0074fc2018-04-06 21:37:23 +000025 constexpr bool is_lt (partial_ordering cmp) noexcept { return cmp < 0; }
26 constexpr bool is_lteq(partial_ordering cmp) noexcept { return cmp <= 0; }
27 constexpr bool is_gt (partial_ordering cmp) noexcept { return cmp > 0; }
28 constexpr bool is_gteq(partial_ordering cmp) noexcept { return cmp >= 0; }
29
30 // [cmp.common], common comparison category type
31 template<class... Ts>
32 struct common_comparison_category {
33 using type = see below;
34 };
35 template<class... Ts>
36 using common_comparison_category_t = typename common_comparison_category<Ts...>::type;
37
38 // [cmp.alg], comparison algorithms
39 template<class T> constexpr strong_ordering strong_order(const T& a, const T& b);
40 template<class T> constexpr weak_ordering weak_order(const T& a, const T& b);
41 template<class T> constexpr partial_ordering partial_order(const T& a, const T& b);
Christopher Di Bella3f33a1e2020-06-18 10:17:57 -040042
43 // [cmp.partialord], Class partial_ordering
44 class partial_ordering {
45 public:
46 // valid values
47 static const partial_ordering less;
48 static const partial_ordering equivalent;
49 static const partial_ordering greater;
50 static const partial_ordering unordered;
51
52 // comparisons
53 friend constexpr bool operator==(partial_ordering v, unspecified) noexcept;
54 friend constexpr bool operator==(partial_ordering v, partial_ordering w) noexcept = default;
55 friend constexpr bool operator< (partial_ordering v, unspecified) noexcept;
56 friend constexpr bool operator> (partial_ordering v, unspecified) noexcept;
57 friend constexpr bool operator<=(partial_ordering v, unspecified) noexcept;
58 friend constexpr bool operator>=(partial_ordering v, unspecified) noexcept;
59 friend constexpr bool operator< (unspecified, partial_ordering v) noexcept;
60 friend constexpr bool operator> (unspecified, partial_ordering v) noexcept;
61 friend constexpr bool operator<=(unspecified, partial_ordering v) noexcept;
62 friend constexpr bool operator>=(unspecified, partial_ordering v) noexcept;
63 friend constexpr partial_ordering operator<=>(partial_ordering v, unspecified) noexcept;
64 friend constexpr partial_ordering operator<=>(unspecified, partial_ordering v) noexcept;
65 };
66
67 // [cmp.weakord], Class weak_ordering
68 class weak_ordering {
69 public:
70 // valid values
71 static const weak_ordering less;
72 static const weak_ordering equivalent;
73 static const weak_ordering greater;
74
75 // conversions
76 constexpr operator partial_ordering() const noexcept;
77
78 // comparisons
79 friend constexpr bool operator==(weak_ordering v, unspecified) noexcept;
80 friend constexpr bool operator==(weak_ordering v, weak_ordering w) noexcept = default;
81 friend constexpr bool operator< (weak_ordering v, unspecified) noexcept;
82 friend constexpr bool operator> (weak_ordering v, unspecified) noexcept;
83 friend constexpr bool operator<=(weak_ordering v, unspecified) noexcept;
84 friend constexpr bool operator>=(weak_ordering v, unspecified) noexcept;
85 friend constexpr bool operator< (unspecified, weak_ordering v) noexcept;
86 friend constexpr bool operator> (unspecified, weak_ordering v) noexcept;
87 friend constexpr bool operator<=(unspecified, weak_ordering v) noexcept;
88 friend constexpr bool operator>=(unspecified, weak_ordering v) noexcept;
89 friend constexpr weak_ordering operator<=>(weak_ordering v, unspecified) noexcept;
90 friend constexpr weak_ordering operator<=>(unspecified, weak_ordering v) noexcept;
91 };
92
93 // [cmp.strongord], Class strong_ordering
94 class strong_ordering {
95 public:
96 // valid values
97 static const strong_ordering less;
98 static const strong_ordering equal;
99 static const strong_ordering equivalent;
100 static const strong_ordering greater;
101
102 // conversions
103 constexpr operator partial_ordering() const noexcept;
104 constexpr operator weak_ordering() const noexcept;
105
106 // comparisons
107 friend constexpr bool operator==(strong_ordering v, unspecified) noexcept;
108 friend constexpr bool operator==(strong_ordering v, strong_ordering w) noexcept = default;
109 friend constexpr bool operator< (strong_ordering v, unspecified) noexcept;
110 friend constexpr bool operator> (strong_ordering v, unspecified) noexcept;
111 friend constexpr bool operator<=(strong_ordering v, unspecified) noexcept;
112 friend constexpr bool operator>=(strong_ordering v, unspecified) noexcept;
113 friend constexpr bool operator< (unspecified, strong_ordering v) noexcept;
114 friend constexpr bool operator> (unspecified, strong_ordering v) noexcept;
115 friend constexpr bool operator<=(unspecified, strong_ordering v) noexcept;
116 friend constexpr bool operator>=(unspecified, strong_ordering v) noexcept;
117 friend constexpr strong_ordering operator<=>(strong_ordering v, unspecified) noexcept;
118 friend constexpr strong_ordering operator<=>(unspecified, strong_ordering v) noexcept;
119 };
Eric Fiseliere0074fc2018-04-06 21:37:23 +0000120}
121*/
122
123#include <__config>
124#include <type_traits>
Eric Fiseliere0074fc2018-04-06 21:37:23 +0000125
126#ifndef _LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER
127#pragma GCC system_header
128#endif
129
130_LIBCPP_BEGIN_NAMESPACE_STD
131
Christopher Di Bellaea4a60c2021-04-12 20:55:05 +0000132#if _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_SPACESHIP_OPERATOR)
Eric Fiseliere0074fc2018-04-06 21:37:23 +0000133// exposition only
134enum class _LIBCPP_ENUM_VIS _EqResult : unsigned char {
135 __zero = 0,
136 __equal = __zero,
137 __equiv = __equal,
138 __nonequal = 1,
139 __nonequiv = __nonequal
140};
141
142enum class _LIBCPP_ENUM_VIS _OrdResult : signed char {
143 __less = -1,
144 __greater = 1
145};
146
147enum class _LIBCPP_ENUM_VIS _NCmpResult : signed char {
148 __unordered = -127
149};
150
Richard Smith55a75c82020-07-31 15:03:21 -0700151struct _CmpUnspecifiedParam {
152 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEVAL
Richard Smith758569c2020-09-29 17:08:42 -0700153 _CmpUnspecifiedParam(int _CmpUnspecifiedParam::*) noexcept {}
Richard Smith55a75c82020-07-31 15:03:21 -0700154
Mark de Wever9d7aa7a2021-05-09 18:22:52 +0200155 template<typename _Tp, typename = enable_if_t<!is_same_v<_Tp, int>>>
Richard Smith55a75c82020-07-31 15:03:21 -0700156 _CmpUnspecifiedParam(_Tp) = delete;
157};
Eric Fiseliere0074fc2018-04-06 21:37:23 +0000158
Eric Fiseliere0074fc2018-04-06 21:37:23 +0000159class partial_ordering {
160 using _ValueT = signed char;
161
162 _LIBCPP_INLINE_VISIBILITY
163 explicit constexpr partial_ordering(_EqResult __v) noexcept
164 : __value_(_ValueT(__v)) {}
165
166 _LIBCPP_INLINE_VISIBILITY
167 explicit constexpr partial_ordering(_OrdResult __v) noexcept
168 : __value_(_ValueT(__v)) {}
169
170 _LIBCPP_INLINE_VISIBILITY
171 explicit constexpr partial_ordering(_NCmpResult __v) noexcept
172 : __value_(_ValueT(__v)) {}
173
174 constexpr bool __is_ordered() const noexcept {
175 return __value_ != _ValueT(_NCmpResult::__unordered);
176 }
177public:
178 // valid values
179 static const partial_ordering less;
180 static const partial_ordering equivalent;
181 static const partial_ordering greater;
182 static const partial_ordering unordered;
183
Eric Fiseliere0074fc2018-04-06 21:37:23 +0000184 // comparisons
Louis Dionne05aca382018-07-10 13:21:03 +0000185 _LIBCPP_INLINE_VISIBILITY friend constexpr bool operator==(partial_ordering __v, _CmpUnspecifiedParam) noexcept;
Louis Dionne05aca382018-07-10 13:21:03 +0000186 _LIBCPP_INLINE_VISIBILITY friend constexpr bool operator< (partial_ordering __v, _CmpUnspecifiedParam) noexcept;
187 _LIBCPP_INLINE_VISIBILITY friend constexpr bool operator<=(partial_ordering __v, _CmpUnspecifiedParam) noexcept;
188 _LIBCPP_INLINE_VISIBILITY friend constexpr bool operator> (partial_ordering __v, _CmpUnspecifiedParam) noexcept;
189 _LIBCPP_INLINE_VISIBILITY friend constexpr bool operator>=(partial_ordering __v, _CmpUnspecifiedParam) noexcept;
Louis Dionne05aca382018-07-10 13:21:03 +0000190 _LIBCPP_INLINE_VISIBILITY friend constexpr bool operator< (_CmpUnspecifiedParam, partial_ordering __v) noexcept;
191 _LIBCPP_INLINE_VISIBILITY friend constexpr bool operator<=(_CmpUnspecifiedParam, partial_ordering __v) noexcept;
192 _LIBCPP_INLINE_VISIBILITY friend constexpr bool operator> (_CmpUnspecifiedParam, partial_ordering __v) noexcept;
193 _LIBCPP_INLINE_VISIBILITY friend constexpr bool operator>=(_CmpUnspecifiedParam, partial_ordering __v) noexcept;
Eric Fiseliere0074fc2018-04-06 21:37:23 +0000194
Christopher Di Bella3f33a1e2020-06-18 10:17:57 -0400195 _LIBCPP_INLINE_VISIBILITY friend constexpr bool operator==(partial_ordering, partial_ordering) noexcept = default;
196
Louis Dionne05aca382018-07-10 13:21:03 +0000197 _LIBCPP_INLINE_VISIBILITY friend constexpr partial_ordering operator<=>(partial_ordering __v, _CmpUnspecifiedParam) noexcept;
198 _LIBCPP_INLINE_VISIBILITY friend constexpr partial_ordering operator<=>(_CmpUnspecifiedParam, partial_ordering __v) noexcept;
Eric Fiseliere0074fc2018-04-06 21:37:23 +0000199
200private:
201 _ValueT __value_;
202};
203
204_LIBCPP_INLINE_VAR constexpr partial_ordering partial_ordering::less(_OrdResult::__less);
205_LIBCPP_INLINE_VAR constexpr partial_ordering partial_ordering::equivalent(_EqResult::__equiv);
206_LIBCPP_INLINE_VAR constexpr partial_ordering partial_ordering::greater(_OrdResult::__greater);
207_LIBCPP_INLINE_VAR constexpr partial_ordering partial_ordering::unordered(_NCmpResult ::__unordered);
208
209_LIBCPP_INLINE_VISIBILITY
210constexpr bool operator==(partial_ordering __v, _CmpUnspecifiedParam) noexcept {
211 return __v.__is_ordered() && __v.__value_ == 0;
212}
213_LIBCPP_INLINE_VISIBILITY
214constexpr bool operator< (partial_ordering __v, _CmpUnspecifiedParam) noexcept {
215 return __v.__is_ordered() && __v.__value_ < 0;
216}
217_LIBCPP_INLINE_VISIBILITY
218constexpr bool operator<=(partial_ordering __v, _CmpUnspecifiedParam) noexcept {
219 return __v.__is_ordered() && __v.__value_ <= 0;
220}
221_LIBCPP_INLINE_VISIBILITY
222constexpr bool operator> (partial_ordering __v, _CmpUnspecifiedParam) noexcept {
223 return __v.__is_ordered() && __v.__value_ > 0;
224}
225_LIBCPP_INLINE_VISIBILITY
226constexpr bool operator>=(partial_ordering __v, _CmpUnspecifiedParam) noexcept {
227 return __v.__is_ordered() && __v.__value_ >= 0;
228}
229
230_LIBCPP_INLINE_VISIBILITY
Eric Fiseliere0074fc2018-04-06 21:37:23 +0000231constexpr bool operator< (_CmpUnspecifiedParam, partial_ordering __v) noexcept {
232 return __v.__is_ordered() && 0 < __v.__value_;
233}
234_LIBCPP_INLINE_VISIBILITY
235constexpr bool operator<=(_CmpUnspecifiedParam, partial_ordering __v) noexcept {
236 return __v.__is_ordered() && 0 <= __v.__value_;
237}
238_LIBCPP_INLINE_VISIBILITY
239constexpr bool operator> (_CmpUnspecifiedParam, partial_ordering __v) noexcept {
240 return __v.__is_ordered() && 0 > __v.__value_;
241}
242_LIBCPP_INLINE_VISIBILITY
243constexpr bool operator>=(_CmpUnspecifiedParam, partial_ordering __v) noexcept {
244 return __v.__is_ordered() && 0 >= __v.__value_;
245}
246
247_LIBCPP_INLINE_VISIBILITY
Eric Fiseliere0074fc2018-04-06 21:37:23 +0000248constexpr partial_ordering operator<=>(partial_ordering __v, _CmpUnspecifiedParam) noexcept {
249 return __v;
250}
251_LIBCPP_INLINE_VISIBILITY
252constexpr partial_ordering operator<=>(_CmpUnspecifiedParam, partial_ordering __v) noexcept {
253 return __v < 0 ? partial_ordering::greater : (__v > 0 ? partial_ordering::less : __v);
254}
Eric Fiseliere0074fc2018-04-06 21:37:23 +0000255
256class weak_ordering {
257 using _ValueT = signed char;
258
259 _LIBCPP_INLINE_VISIBILITY
260 explicit constexpr weak_ordering(_EqResult __v) noexcept : __value_(_ValueT(__v)) {}
261 _LIBCPP_INLINE_VISIBILITY
262 explicit constexpr weak_ordering(_OrdResult __v) noexcept : __value_(_ValueT(__v)) {}
263
264public:
265 static const weak_ordering less;
266 static const weak_ordering equivalent;
267 static const weak_ordering greater;
268
Eric Fiseliere0074fc2018-04-06 21:37:23 +0000269 _LIBCPP_INLINE_VISIBILITY
270 constexpr operator partial_ordering() const noexcept {
271 return __value_ == 0 ? partial_ordering::equivalent
272 : (__value_ < 0 ? partial_ordering::less : partial_ordering::greater);
273 }
274
275 // comparisons
Louis Dionne05aca382018-07-10 13:21:03 +0000276 _LIBCPP_INLINE_VISIBILITY friend constexpr bool operator==(weak_ordering __v, _CmpUnspecifiedParam) noexcept;
Louis Dionne05aca382018-07-10 13:21:03 +0000277 _LIBCPP_INLINE_VISIBILITY friend constexpr bool operator< (weak_ordering __v, _CmpUnspecifiedParam) noexcept;
278 _LIBCPP_INLINE_VISIBILITY friend constexpr bool operator<=(weak_ordering __v, _CmpUnspecifiedParam) noexcept;
279 _LIBCPP_INLINE_VISIBILITY friend constexpr bool operator> (weak_ordering __v, _CmpUnspecifiedParam) noexcept;
280 _LIBCPP_INLINE_VISIBILITY friend constexpr bool operator>=(weak_ordering __v, _CmpUnspecifiedParam) noexcept;
Louis Dionne05aca382018-07-10 13:21:03 +0000281 _LIBCPP_INLINE_VISIBILITY friend constexpr bool operator< (_CmpUnspecifiedParam, weak_ordering __v) noexcept;
282 _LIBCPP_INLINE_VISIBILITY friend constexpr bool operator<=(_CmpUnspecifiedParam, weak_ordering __v) noexcept;
283 _LIBCPP_INLINE_VISIBILITY friend constexpr bool operator> (_CmpUnspecifiedParam, weak_ordering __v) noexcept;
284 _LIBCPP_INLINE_VISIBILITY friend constexpr bool operator>=(_CmpUnspecifiedParam, weak_ordering __v) noexcept;
Eric Fiseliere0074fc2018-04-06 21:37:23 +0000285
Christopher Di Bella3f33a1e2020-06-18 10:17:57 -0400286 _LIBCPP_INLINE_VISIBILITY friend constexpr bool operator==(weak_ordering, weak_ordering) noexcept = default;
287
Louis Dionne05aca382018-07-10 13:21:03 +0000288 _LIBCPP_INLINE_VISIBILITY friend constexpr weak_ordering operator<=>(weak_ordering __v, _CmpUnspecifiedParam) noexcept;
289 _LIBCPP_INLINE_VISIBILITY friend constexpr weak_ordering operator<=>(_CmpUnspecifiedParam, weak_ordering __v) noexcept;
Eric Fiseliere0074fc2018-04-06 21:37:23 +0000290
291private:
292 _ValueT __value_;
293};
294
295_LIBCPP_INLINE_VAR constexpr weak_ordering weak_ordering::less(_OrdResult::__less);
296_LIBCPP_INLINE_VAR constexpr weak_ordering weak_ordering::equivalent(_EqResult::__equiv);
297_LIBCPP_INLINE_VAR constexpr weak_ordering weak_ordering::greater(_OrdResult::__greater);
298
299_LIBCPP_INLINE_VISIBILITY
300constexpr bool operator==(weak_ordering __v, _CmpUnspecifiedParam) noexcept {
301 return __v.__value_ == 0;
302}
303_LIBCPP_INLINE_VISIBILITY
Eric Fiseliere0074fc2018-04-06 21:37:23 +0000304constexpr bool operator< (weak_ordering __v, _CmpUnspecifiedParam) noexcept {
305 return __v.__value_ < 0;
306}
307_LIBCPP_INLINE_VISIBILITY
308constexpr bool operator<=(weak_ordering __v, _CmpUnspecifiedParam) noexcept {
309 return __v.__value_ <= 0;
310}
311_LIBCPP_INLINE_VISIBILITY
312constexpr bool operator> (weak_ordering __v, _CmpUnspecifiedParam) noexcept {
313 return __v.__value_ > 0;
314}
315_LIBCPP_INLINE_VISIBILITY
316constexpr bool operator>=(weak_ordering __v, _CmpUnspecifiedParam) noexcept {
317 return __v.__value_ >= 0;
318}
319_LIBCPP_INLINE_VISIBILITY
Eric Fiseliere0074fc2018-04-06 21:37:23 +0000320constexpr bool operator< (_CmpUnspecifiedParam, weak_ordering __v) noexcept {
321 return 0 < __v.__value_;
322}
323_LIBCPP_INLINE_VISIBILITY
324constexpr bool operator<=(_CmpUnspecifiedParam, weak_ordering __v) noexcept {
325 return 0 <= __v.__value_;
326}
327_LIBCPP_INLINE_VISIBILITY
328constexpr bool operator> (_CmpUnspecifiedParam, weak_ordering __v) noexcept {
329 return 0 > __v.__value_;
330}
331_LIBCPP_INLINE_VISIBILITY
332constexpr bool operator>=(_CmpUnspecifiedParam, weak_ordering __v) noexcept {
333 return 0 >= __v.__value_;
334}
335
Eric Fiseliere0074fc2018-04-06 21:37:23 +0000336_LIBCPP_INLINE_VISIBILITY
337constexpr weak_ordering operator<=>(weak_ordering __v, _CmpUnspecifiedParam) noexcept {
338 return __v;
339}
340_LIBCPP_INLINE_VISIBILITY
341constexpr weak_ordering operator<=>(_CmpUnspecifiedParam, weak_ordering __v) noexcept {
342 return __v < 0 ? weak_ordering::greater : (__v > 0 ? weak_ordering::less : __v);
343}
Eric Fiseliere0074fc2018-04-06 21:37:23 +0000344class strong_ordering {
345 using _ValueT = signed char;
346
347 _LIBCPP_INLINE_VISIBILITY
348 explicit constexpr strong_ordering(_EqResult __v) noexcept : __value_(_ValueT(__v)) {}
349 _LIBCPP_INLINE_VISIBILITY
350 explicit constexpr strong_ordering(_OrdResult __v) noexcept : __value_(_ValueT(__v)) {}
351
352public:
353 static const strong_ordering less;
354 static const strong_ordering equal;
355 static const strong_ordering equivalent;
356 static const strong_ordering greater;
357
358 // conversions
359 _LIBCPP_INLINE_VISIBILITY
Eric Fiseliere0074fc2018-04-06 21:37:23 +0000360 constexpr operator partial_ordering() const noexcept {
361 return __value_ == 0 ? partial_ordering::equivalent
362 : (__value_ < 0 ? partial_ordering::less : partial_ordering::greater);
363 }
364
365 _LIBCPP_INLINE_VISIBILITY
366 constexpr operator weak_ordering() const noexcept {
367 return __value_ == 0 ? weak_ordering::equivalent
368 : (__value_ < 0 ? weak_ordering::less : weak_ordering::greater);
369 }
370
371 // comparisons
Louis Dionne05aca382018-07-10 13:21:03 +0000372 _LIBCPP_INLINE_VISIBILITY friend constexpr bool operator==(strong_ordering __v, _CmpUnspecifiedParam) noexcept;
Louis Dionne05aca382018-07-10 13:21:03 +0000373 _LIBCPP_INLINE_VISIBILITY friend constexpr bool operator< (strong_ordering __v, _CmpUnspecifiedParam) noexcept;
374 _LIBCPP_INLINE_VISIBILITY friend constexpr bool operator<=(strong_ordering __v, _CmpUnspecifiedParam) noexcept;
375 _LIBCPP_INLINE_VISIBILITY friend constexpr bool operator> (strong_ordering __v, _CmpUnspecifiedParam) noexcept;
376 _LIBCPP_INLINE_VISIBILITY friend constexpr bool operator>=(strong_ordering __v, _CmpUnspecifiedParam) noexcept;
Louis Dionne05aca382018-07-10 13:21:03 +0000377 _LIBCPP_INLINE_VISIBILITY friend constexpr bool operator< (_CmpUnspecifiedParam, strong_ordering __v) noexcept;
378 _LIBCPP_INLINE_VISIBILITY friend constexpr bool operator<=(_CmpUnspecifiedParam, strong_ordering __v) noexcept;
379 _LIBCPP_INLINE_VISIBILITY friend constexpr bool operator> (_CmpUnspecifiedParam, strong_ordering __v) noexcept;
380 _LIBCPP_INLINE_VISIBILITY friend constexpr bool operator>=(_CmpUnspecifiedParam, strong_ordering __v) noexcept;
Eric Fiseliere0074fc2018-04-06 21:37:23 +0000381
Christopher Di Bella3f33a1e2020-06-18 10:17:57 -0400382 _LIBCPP_INLINE_VISIBILITY friend constexpr bool operator==(strong_ordering, strong_ordering) noexcept = default;
383
Louis Dionne05aca382018-07-10 13:21:03 +0000384 _LIBCPP_INLINE_VISIBILITY friend constexpr strong_ordering operator<=>(strong_ordering __v, _CmpUnspecifiedParam) noexcept;
385 _LIBCPP_INLINE_VISIBILITY friend constexpr strong_ordering operator<=>(_CmpUnspecifiedParam, strong_ordering __v) noexcept;
Eric Fiseliere0074fc2018-04-06 21:37:23 +0000386
387private:
388 _ValueT __value_;
389};
390
391_LIBCPP_INLINE_VAR constexpr strong_ordering strong_ordering::less(_OrdResult::__less);
392_LIBCPP_INLINE_VAR constexpr strong_ordering strong_ordering::equal(_EqResult::__equal);
393_LIBCPP_INLINE_VAR constexpr strong_ordering strong_ordering::equivalent(_EqResult::__equiv);
394_LIBCPP_INLINE_VAR constexpr strong_ordering strong_ordering::greater(_OrdResult::__greater);
395
396_LIBCPP_INLINE_VISIBILITY
397constexpr bool operator==(strong_ordering __v, _CmpUnspecifiedParam) noexcept {
398 return __v.__value_ == 0;
399}
400_LIBCPP_INLINE_VISIBILITY
Eric Fiseliere0074fc2018-04-06 21:37:23 +0000401constexpr bool operator< (strong_ordering __v, _CmpUnspecifiedParam) noexcept {
402 return __v.__value_ < 0;
403}
404_LIBCPP_INLINE_VISIBILITY
405constexpr bool operator<=(strong_ordering __v, _CmpUnspecifiedParam) noexcept {
406 return __v.__value_ <= 0;
407}
408_LIBCPP_INLINE_VISIBILITY
409constexpr bool operator> (strong_ordering __v, _CmpUnspecifiedParam) noexcept {
410 return __v.__value_ > 0;
411}
412_LIBCPP_INLINE_VISIBILITY
413constexpr bool operator>=(strong_ordering __v, _CmpUnspecifiedParam) noexcept {
414 return __v.__value_ >= 0;
415}
416_LIBCPP_INLINE_VISIBILITY
Eric Fiseliere0074fc2018-04-06 21:37:23 +0000417constexpr bool operator< (_CmpUnspecifiedParam, strong_ordering __v) noexcept {
418 return 0 < __v.__value_;
419}
420_LIBCPP_INLINE_VISIBILITY
421constexpr bool operator<=(_CmpUnspecifiedParam, strong_ordering __v) noexcept {
422 return 0 <= __v.__value_;
423}
424_LIBCPP_INLINE_VISIBILITY
425constexpr bool operator> (_CmpUnspecifiedParam, strong_ordering __v) noexcept {
426 return 0 > __v.__value_;
427}
428_LIBCPP_INLINE_VISIBILITY
429constexpr bool operator>=(_CmpUnspecifiedParam, strong_ordering __v) noexcept {
430 return 0 >= __v.__value_;
431}
432
Eric Fiseliere0074fc2018-04-06 21:37:23 +0000433_LIBCPP_INLINE_VISIBILITY
434constexpr strong_ordering operator<=>(strong_ordering __v, _CmpUnspecifiedParam) noexcept {
435 return __v;
436}
437_LIBCPP_INLINE_VISIBILITY
438constexpr strong_ordering operator<=>(_CmpUnspecifiedParam, strong_ordering __v) noexcept {
439 return __v < 0 ? strong_ordering::greater : (__v > 0 ? strong_ordering::less : __v);
440}
Eric Fiseliere0074fc2018-04-06 21:37:23 +0000441
442// named comparison functions
443_LIBCPP_INLINE_VISIBILITY
Eric Fiseliere0074fc2018-04-06 21:37:23 +0000444constexpr bool is_lt(partial_ordering __cmp) noexcept { return __cmp < 0; }
445
446_LIBCPP_INLINE_VISIBILITY
447constexpr bool is_lteq(partial_ordering __cmp) noexcept { return __cmp <= 0; }
448
449_LIBCPP_INLINE_VISIBILITY
450constexpr bool is_gt(partial_ordering __cmp) noexcept { return __cmp > 0; }
451
452_LIBCPP_INLINE_VISIBILITY
453constexpr bool is_gteq(partial_ordering __cmp) noexcept { return __cmp >= 0; }
454
455namespace __comp_detail {
456
457enum _ClassifyCompCategory : unsigned{
458 _None,
Eric Fiseliere0074fc2018-04-06 21:37:23 +0000459 _PartialOrd,
460 _WeakOrd,
461 _StrongOrd,
462 _CCC_Size
463};
464
465template <class _Tp>
466_LIBCPP_INLINE_VISIBILITY
467constexpr _ClassifyCompCategory __type_to_enum() noexcept {
Eric Fiseliere0074fc2018-04-06 21:37:23 +0000468 if (is_same_v<_Tp, partial_ordering>)
469 return _PartialOrd;
470 if (is_same_v<_Tp, weak_ordering>)
471 return _WeakOrd;
472 if (is_same_v<_Tp, strong_ordering>)
473 return _StrongOrd;
474 return _None;
475}
476
477template <size_t _Size>
478constexpr _ClassifyCompCategory
Arthur O'Dwyer6bee3232021-03-24 19:14:51 -0400479__compute_comp_type(const _ClassifyCompCategory (&__types)[_Size]) {
480 int __seen[_CCC_Size] = {};
Eric Fiseliere0074fc2018-04-06 21:37:23 +0000481 for (auto __type : __types)
482 ++__seen[__type];
483 if (__seen[_None])
484 return _None;
Eric Fiseliere0074fc2018-04-06 21:37:23 +0000485 if (__seen[_PartialOrd])
486 return _PartialOrd;
487 if (__seen[_WeakOrd])
488 return _WeakOrd;
489 return _StrongOrd;
490}
491
492template <class ..._Ts>
493constexpr auto __get_comp_type() {
494 using _CCC = _ClassifyCompCategory;
Arthur O'Dwyer6bee3232021-03-24 19:14:51 -0400495 constexpr _CCC __type_kinds[] = {_StrongOrd, __type_to_enum<_Ts>()...};
496 constexpr _CCC _Cat = __compute_comp_type(__type_kinds);
Eric Fiseliere0074fc2018-04-06 21:37:23 +0000497 if constexpr (_Cat == _None)
Eric Fiselierafcb4b82018-04-07 04:28:11 +0000498 return void();
Eric Fiseliere0074fc2018-04-06 21:37:23 +0000499 else if constexpr (_Cat == _PartialOrd)
500 return partial_ordering::equivalent;
501 else if constexpr (_Cat == _WeakOrd)
502 return weak_ordering::equivalent;
503 else if constexpr (_Cat == _StrongOrd)
504 return strong_ordering::equivalent;
505 else
506 static_assert(_Cat != _Cat, "unhandled case");
507}
508} // namespace __comp_detail
509
510// [cmp.common], common comparison category type
511template<class... _Ts>
512struct _LIBCPP_TEMPLATE_VIS common_comparison_category {
513 using type = decltype(__comp_detail::__get_comp_type<_Ts...>());
514};
515
516template<class... _Ts>
517using common_comparison_category_t = typename common_comparison_category<_Ts...>::type;
518
519// [cmp.alg], comparison algorithms
520// TODO: unimplemented
521template<class _Tp> constexpr strong_ordering strong_order(const _Tp& __lhs, const _Tp& __rhs);
522template<class _Tp> constexpr weak_ordering weak_order(const _Tp& __lhs, const _Tp& __rhs);
523template<class _Tp> constexpr partial_ordering partial_order(const _Tp& __lhs, const _Tp& __rhs);
Eric Fiseliere0074fc2018-04-06 21:37:23 +0000524
Christopher Di Bellaea4a60c2021-04-12 20:55:05 +0000525#endif // _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_SPACESHIP_OPERATOR)
Eric Fiseliere0074fc2018-04-06 21:37:23 +0000526
527_LIBCPP_END_NAMESPACE_STD
528
529#endif // _LIBCPP_COMPARE