blob: 717859a1e3af5b08338e27655c3607c72f903886 [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
18 class weak_equality;
19 class strong_equality;
20 class partial_ordering;
21 class weak_ordering;
22 class strong_ordering;
23
24 // named comparison functions
25 constexpr bool is_eq (weak_equality cmp) noexcept { return cmp == 0; }
26 constexpr bool is_neq (weak_equality cmp) noexcept { return cmp != 0; }
27 constexpr bool is_lt (partial_ordering cmp) noexcept { return cmp < 0; }
28 constexpr bool is_lteq(partial_ordering cmp) noexcept { return cmp <= 0; }
29 constexpr bool is_gt (partial_ordering cmp) noexcept { return cmp > 0; }
30 constexpr bool is_gteq(partial_ordering cmp) noexcept { return cmp >= 0; }
31
32 // [cmp.common], common comparison category type
33 template<class... Ts>
34 struct common_comparison_category {
35 using type = see below;
36 };
37 template<class... Ts>
38 using common_comparison_category_t = typename common_comparison_category<Ts...>::type;
39
40 // [cmp.alg], comparison algorithms
41 template<class T> constexpr strong_ordering strong_order(const T& a, const T& b);
42 template<class T> constexpr weak_ordering weak_order(const T& a, const T& b);
43 template<class T> constexpr partial_ordering partial_order(const T& a, const T& b);
44 template<class T> constexpr strong_equality strong_equal(const T& a, const T& b);
45 template<class T> constexpr weak_equality weak_equal(const T& a, const T& b);
Christopher Di Bella3f33a1e2020-06-18 10:17:57 -040046
47 // [cmp.partialord], Class partial_ordering
48 class partial_ordering {
49 public:
50 // valid values
51 static const partial_ordering less;
52 static const partial_ordering equivalent;
53 static const partial_ordering greater;
54 static const partial_ordering unordered;
55
56 // comparisons
57 friend constexpr bool operator==(partial_ordering v, unspecified) noexcept;
58 friend constexpr bool operator==(partial_ordering v, partial_ordering w) noexcept = default;
59 friend constexpr bool operator< (partial_ordering v, unspecified) noexcept;
60 friend constexpr bool operator> (partial_ordering v, unspecified) noexcept;
61 friend constexpr bool operator<=(partial_ordering v, unspecified) noexcept;
62 friend constexpr bool operator>=(partial_ordering v, unspecified) noexcept;
63 friend constexpr bool operator< (unspecified, partial_ordering v) noexcept;
64 friend constexpr bool operator> (unspecified, partial_ordering v) noexcept;
65 friend constexpr bool operator<=(unspecified, partial_ordering v) noexcept;
66 friend constexpr bool operator>=(unspecified, partial_ordering v) noexcept;
67 friend constexpr partial_ordering operator<=>(partial_ordering v, unspecified) noexcept;
68 friend constexpr partial_ordering operator<=>(unspecified, partial_ordering v) noexcept;
69 };
70
71 // [cmp.weakord], Class weak_ordering
72 class weak_ordering {
73 public:
74 // valid values
75 static const weak_ordering less;
76 static const weak_ordering equivalent;
77 static const weak_ordering greater;
78
79 // conversions
80 constexpr operator partial_ordering() const noexcept;
81
82 // comparisons
83 friend constexpr bool operator==(weak_ordering v, unspecified) noexcept;
84 friend constexpr bool operator==(weak_ordering v, weak_ordering w) noexcept = default;
85 friend constexpr bool operator< (weak_ordering v, unspecified) noexcept;
86 friend constexpr bool operator> (weak_ordering v, unspecified) noexcept;
87 friend constexpr bool operator<=(weak_ordering v, unspecified) noexcept;
88 friend constexpr bool operator>=(weak_ordering v, unspecified) noexcept;
89 friend constexpr bool operator< (unspecified, weak_ordering v) noexcept;
90 friend constexpr bool operator> (unspecified, weak_ordering v) noexcept;
91 friend constexpr bool operator<=(unspecified, weak_ordering v) noexcept;
92 friend constexpr bool operator>=(unspecified, weak_ordering v) noexcept;
93 friend constexpr weak_ordering operator<=>(weak_ordering v, unspecified) noexcept;
94 friend constexpr weak_ordering operator<=>(unspecified, weak_ordering v) noexcept;
95 };
96
97 // [cmp.strongord], Class strong_ordering
98 class strong_ordering {
99 public:
100 // valid values
101 static const strong_ordering less;
102 static const strong_ordering equal;
103 static const strong_ordering equivalent;
104 static const strong_ordering greater;
105
106 // conversions
107 constexpr operator partial_ordering() const noexcept;
108 constexpr operator weak_ordering() const noexcept;
109
110 // comparisons
111 friend constexpr bool operator==(strong_ordering v, unspecified) noexcept;
112 friend constexpr bool operator==(strong_ordering v, strong_ordering w) noexcept = default;
113 friend constexpr bool operator< (strong_ordering v, unspecified) noexcept;
114 friend constexpr bool operator> (strong_ordering v, unspecified) noexcept;
115 friend constexpr bool operator<=(strong_ordering v, unspecified) noexcept;
116 friend constexpr bool operator>=(strong_ordering v, unspecified) noexcept;
117 friend constexpr bool operator< (unspecified, strong_ordering v) noexcept;
118 friend constexpr bool operator> (unspecified, strong_ordering v) noexcept;
119 friend constexpr bool operator<=(unspecified, strong_ordering v) noexcept;
120 friend constexpr bool operator>=(unspecified, strong_ordering v) noexcept;
121 friend constexpr strong_ordering operator<=>(strong_ordering v, unspecified) noexcept;
122 friend constexpr strong_ordering operator<=>(unspecified, strong_ordering v) noexcept;
123 };
Eric Fiseliere0074fc2018-04-06 21:37:23 +0000124}
125*/
126
127#include <__config>
128#include <type_traits>
129#include <array>
130
131#ifndef _LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER
132#pragma GCC system_header
133#endif
134
135_LIBCPP_BEGIN_NAMESPACE_STD
136
137#if _LIBCPP_STD_VER > 17
138
139// exposition only
140enum class _LIBCPP_ENUM_VIS _EqResult : unsigned char {
141 __zero = 0,
142 __equal = __zero,
143 __equiv = __equal,
144 __nonequal = 1,
145 __nonequiv = __nonequal
146};
147
148enum class _LIBCPP_ENUM_VIS _OrdResult : signed char {
149 __less = -1,
150 __greater = 1
151};
152
153enum class _LIBCPP_ENUM_VIS _NCmpResult : signed char {
154 __unordered = -127
155};
156
157struct _CmpUnspecifiedType;
158using _CmpUnspecifiedParam = void (_CmpUnspecifiedType::*)();
159
160class weak_equality {
161 _LIBCPP_INLINE_VISIBILITY
162 constexpr explicit weak_equality(_EqResult __val) noexcept : __value_(__val) {}
163
164public:
165 static const weak_equality equivalent;
166 static const weak_equality nonequivalent;
167
Louis Dionne05aca382018-07-10 13:21:03 +0000168 _LIBCPP_INLINE_VISIBILITY friend constexpr bool operator==(weak_equality __v, _CmpUnspecifiedParam) noexcept;
169 _LIBCPP_INLINE_VISIBILITY friend constexpr bool operator==(_CmpUnspecifiedParam, weak_equality __v) noexcept;
170 _LIBCPP_INLINE_VISIBILITY friend constexpr bool operator!=(weak_equality __v, _CmpUnspecifiedParam) noexcept;
171 _LIBCPP_INLINE_VISIBILITY friend constexpr bool operator!=(_CmpUnspecifiedParam, weak_equality __v) noexcept;
Eric Fiseliere0074fc2018-04-06 21:37:23 +0000172
173#ifndef _LIBCPP_HAS_NO_SPACESHIP_OPERATOR
Louis Dionne05aca382018-07-10 13:21:03 +0000174 _LIBCPP_INLINE_VISIBILITY friend constexpr weak_equality operator<=>(weak_equality __v, _CmpUnspecifiedParam) noexcept;
175 _LIBCPP_INLINE_VISIBILITY friend constexpr weak_equality operator<=>(_CmpUnspecifiedParam, weak_equality __v) noexcept;
Eric Fiseliere0074fc2018-04-06 21:37:23 +0000176#endif
177
178private:
179 _EqResult __value_;
180};
181
182_LIBCPP_INLINE_VAR constexpr weak_equality weak_equality::equivalent(_EqResult::__equiv);
183_LIBCPP_INLINE_VAR constexpr weak_equality weak_equality::nonequivalent(_EqResult::__nonequiv);
184
185_LIBCPP_INLINE_VISIBILITY
186inline constexpr bool operator==(weak_equality __v, _CmpUnspecifiedParam) noexcept {
187 return __v.__value_ == _EqResult::__zero;
188}
189
190_LIBCPP_INLINE_VISIBILITY
191inline constexpr bool operator==(_CmpUnspecifiedParam, weak_equality __v) noexcept {
192 return __v.__value_ == _EqResult::__zero;
193}
194
195_LIBCPP_INLINE_VISIBILITY
196inline constexpr bool operator!=(weak_equality __v, _CmpUnspecifiedParam) noexcept {
197 return __v.__value_ != _EqResult::__zero;
198}
199
200_LIBCPP_INLINE_VISIBILITY
201inline constexpr bool operator!=(_CmpUnspecifiedParam, weak_equality __v) noexcept {
202 return __v.__value_ != _EqResult::__zero;
203}
204
205#ifndef _LIBCPP_HAS_NO_SPACESHIP_OPERATOR
206_LIBCPP_INLINE_VISIBILITY
207inline constexpr weak_equality operator<=>(weak_equality __v, _CmpUnspecifiedParam) noexcept {
208 return __v;
209}
210
211_LIBCPP_INLINE_VISIBILITY
212inline constexpr weak_equality operator<=>(_CmpUnspecifiedParam, weak_equality __v) noexcept {
213 return __v;
214}
215#endif
216
217class strong_equality {
218 _LIBCPP_INLINE_VISIBILITY
219 explicit constexpr strong_equality(_EqResult __val) noexcept : __value_(__val) {}
220
221public:
222 static const strong_equality equal;
223 static const strong_equality nonequal;
224 static const strong_equality equivalent;
225 static const strong_equality nonequivalent;
226
227 // conversion
Louis Dionne05aca382018-07-10 13:21:03 +0000228 _LIBCPP_INLINE_VISIBILITY constexpr operator weak_equality() const noexcept {
Eric Fiseliere0074fc2018-04-06 21:37:23 +0000229 return __value_ == _EqResult::__zero ? weak_equality::equivalent
230 : weak_equality::nonequivalent;
231 }
232
233 // comparisons
Louis Dionne05aca382018-07-10 13:21:03 +0000234 _LIBCPP_INLINE_VISIBILITY friend constexpr bool operator==(strong_equality __v, _CmpUnspecifiedParam) noexcept;
235 _LIBCPP_INLINE_VISIBILITY friend constexpr bool operator!=(strong_equality __v, _CmpUnspecifiedParam) noexcept;
236 _LIBCPP_INLINE_VISIBILITY friend constexpr bool operator==(_CmpUnspecifiedParam, strong_equality __v) noexcept;
237 _LIBCPP_INLINE_VISIBILITY friend constexpr bool operator!=(_CmpUnspecifiedParam, strong_equality __v) noexcept;
Eric Fiseliere0074fc2018-04-06 21:37:23 +0000238
239#ifndef _LIBCPP_HAS_NO_SPACESHIP_OPERATOR
Louis Dionne05aca382018-07-10 13:21:03 +0000240 _LIBCPP_INLINE_VISIBILITY friend constexpr strong_equality operator<=>(strong_equality __v, _CmpUnspecifiedParam) noexcept;
241 _LIBCPP_INLINE_VISIBILITY friend constexpr strong_equality operator<=>(_CmpUnspecifiedParam, strong_equality __v) noexcept;
Eric Fiseliere0074fc2018-04-06 21:37:23 +0000242#endif
243private:
244 _EqResult __value_;
245};
246
247_LIBCPP_INLINE_VAR constexpr strong_equality strong_equality::equal(_EqResult::__equal);
248_LIBCPP_INLINE_VAR constexpr strong_equality strong_equality::nonequal(_EqResult::__nonequal);
249_LIBCPP_INLINE_VAR constexpr strong_equality strong_equality::equivalent(_EqResult::__equiv);
250_LIBCPP_INLINE_VAR constexpr strong_equality strong_equality::nonequivalent(_EqResult::__nonequiv);
251
252_LIBCPP_INLINE_VISIBILITY
253constexpr bool operator==(strong_equality __v, _CmpUnspecifiedParam) noexcept {
254 return __v.__value_ == _EqResult::__zero;
255}
256
257_LIBCPP_INLINE_VISIBILITY
258constexpr bool operator==(_CmpUnspecifiedParam, strong_equality __v) noexcept {
259 return __v.__value_ == _EqResult::__zero;
260}
261
262_LIBCPP_INLINE_VISIBILITY
263constexpr bool operator!=(strong_equality __v, _CmpUnspecifiedParam) noexcept {
264 return __v.__value_ != _EqResult::__zero;
265}
266
267_LIBCPP_INLINE_VISIBILITY
268constexpr bool operator!=(_CmpUnspecifiedParam, strong_equality __v) noexcept {
269 return __v.__value_ != _EqResult::__zero;
270}
271
272#ifndef _LIBCPP_HAS_NO_SPACESHIP_OPERATOR
273_LIBCPP_INLINE_VISIBILITY
274constexpr strong_equality operator<=>(strong_equality __v, _CmpUnspecifiedParam) noexcept {
275 return __v;
276}
277
278_LIBCPP_INLINE_VISIBILITY
279constexpr strong_equality operator<=>(_CmpUnspecifiedParam, strong_equality __v) noexcept {
280 return __v;
281}
282#endif // _LIBCPP_HAS_NO_SPACESHIP_OPERATOR
283
284class partial_ordering {
285 using _ValueT = signed char;
286
287 _LIBCPP_INLINE_VISIBILITY
288 explicit constexpr partial_ordering(_EqResult __v) noexcept
289 : __value_(_ValueT(__v)) {}
290
291 _LIBCPP_INLINE_VISIBILITY
292 explicit constexpr partial_ordering(_OrdResult __v) noexcept
293 : __value_(_ValueT(__v)) {}
294
295 _LIBCPP_INLINE_VISIBILITY
296 explicit constexpr partial_ordering(_NCmpResult __v) noexcept
297 : __value_(_ValueT(__v)) {}
298
299 constexpr bool __is_ordered() const noexcept {
300 return __value_ != _ValueT(_NCmpResult::__unordered);
301 }
302public:
303 // valid values
304 static const partial_ordering less;
305 static const partial_ordering equivalent;
306 static const partial_ordering greater;
307 static const partial_ordering unordered;
308
309 // conversion
310 constexpr operator weak_equality() const noexcept {
311 return __value_ == 0 ? weak_equality::equivalent : weak_equality::nonequivalent;
312 }
313
314 // comparisons
Louis Dionne05aca382018-07-10 13:21:03 +0000315 _LIBCPP_INLINE_VISIBILITY friend constexpr bool operator==(partial_ordering __v, _CmpUnspecifiedParam) noexcept;
316 _LIBCPP_INLINE_VISIBILITY friend constexpr bool operator!=(partial_ordering __v, _CmpUnspecifiedParam) noexcept;
317 _LIBCPP_INLINE_VISIBILITY friend constexpr bool operator< (partial_ordering __v, _CmpUnspecifiedParam) noexcept;
318 _LIBCPP_INLINE_VISIBILITY friend constexpr bool operator<=(partial_ordering __v, _CmpUnspecifiedParam) noexcept;
319 _LIBCPP_INLINE_VISIBILITY friend constexpr bool operator> (partial_ordering __v, _CmpUnspecifiedParam) noexcept;
320 _LIBCPP_INLINE_VISIBILITY friend constexpr bool operator>=(partial_ordering __v, _CmpUnspecifiedParam) noexcept;
321 _LIBCPP_INLINE_VISIBILITY friend constexpr bool operator==(_CmpUnspecifiedParam, partial_ordering __v) noexcept;
322 _LIBCPP_INLINE_VISIBILITY friend constexpr bool operator!=(_CmpUnspecifiedParam, partial_ordering __v) noexcept;
323 _LIBCPP_INLINE_VISIBILITY friend constexpr bool operator< (_CmpUnspecifiedParam, partial_ordering __v) noexcept;
324 _LIBCPP_INLINE_VISIBILITY friend constexpr bool operator<=(_CmpUnspecifiedParam, partial_ordering __v) noexcept;
325 _LIBCPP_INLINE_VISIBILITY friend constexpr bool operator> (_CmpUnspecifiedParam, partial_ordering __v) noexcept;
326 _LIBCPP_INLINE_VISIBILITY friend constexpr bool operator>=(_CmpUnspecifiedParam, partial_ordering __v) noexcept;
Eric Fiseliere0074fc2018-04-06 21:37:23 +0000327
328#ifndef _LIBCPP_HAS_NO_SPACESHIP_OPERATOR
Christopher Di Bella3f33a1e2020-06-18 10:17:57 -0400329 _LIBCPP_INLINE_VISIBILITY friend constexpr bool operator==(partial_ordering, partial_ordering) noexcept = default;
330
Louis Dionne05aca382018-07-10 13:21:03 +0000331 _LIBCPP_INLINE_VISIBILITY friend constexpr partial_ordering operator<=>(partial_ordering __v, _CmpUnspecifiedParam) noexcept;
332 _LIBCPP_INLINE_VISIBILITY friend constexpr partial_ordering operator<=>(_CmpUnspecifiedParam, partial_ordering __v) noexcept;
Eric Fiseliere0074fc2018-04-06 21:37:23 +0000333#endif
334
335private:
336 _ValueT __value_;
337};
338
339_LIBCPP_INLINE_VAR constexpr partial_ordering partial_ordering::less(_OrdResult::__less);
340_LIBCPP_INLINE_VAR constexpr partial_ordering partial_ordering::equivalent(_EqResult::__equiv);
341_LIBCPP_INLINE_VAR constexpr partial_ordering partial_ordering::greater(_OrdResult::__greater);
342_LIBCPP_INLINE_VAR constexpr partial_ordering partial_ordering::unordered(_NCmpResult ::__unordered);
343
344_LIBCPP_INLINE_VISIBILITY
345constexpr bool operator==(partial_ordering __v, _CmpUnspecifiedParam) noexcept {
346 return __v.__is_ordered() && __v.__value_ == 0;
347}
348_LIBCPP_INLINE_VISIBILITY
349constexpr bool operator< (partial_ordering __v, _CmpUnspecifiedParam) noexcept {
350 return __v.__is_ordered() && __v.__value_ < 0;
351}
352_LIBCPP_INLINE_VISIBILITY
353constexpr bool operator<=(partial_ordering __v, _CmpUnspecifiedParam) noexcept {
354 return __v.__is_ordered() && __v.__value_ <= 0;
355}
356_LIBCPP_INLINE_VISIBILITY
357constexpr bool operator> (partial_ordering __v, _CmpUnspecifiedParam) noexcept {
358 return __v.__is_ordered() && __v.__value_ > 0;
359}
360_LIBCPP_INLINE_VISIBILITY
361constexpr bool operator>=(partial_ordering __v, _CmpUnspecifiedParam) noexcept {
362 return __v.__is_ordered() && __v.__value_ >= 0;
363}
364
365_LIBCPP_INLINE_VISIBILITY
366constexpr bool operator==(_CmpUnspecifiedParam, partial_ordering __v) noexcept {
367 return __v.__is_ordered() && 0 == __v.__value_;
368}
369_LIBCPP_INLINE_VISIBILITY
370constexpr bool operator< (_CmpUnspecifiedParam, partial_ordering __v) noexcept {
371 return __v.__is_ordered() && 0 < __v.__value_;
372}
373_LIBCPP_INLINE_VISIBILITY
374constexpr bool operator<=(_CmpUnspecifiedParam, partial_ordering __v) noexcept {
375 return __v.__is_ordered() && 0 <= __v.__value_;
376}
377_LIBCPP_INLINE_VISIBILITY
378constexpr bool operator> (_CmpUnspecifiedParam, partial_ordering __v) noexcept {
379 return __v.__is_ordered() && 0 > __v.__value_;
380}
381_LIBCPP_INLINE_VISIBILITY
382constexpr bool operator>=(_CmpUnspecifiedParam, partial_ordering __v) noexcept {
383 return __v.__is_ordered() && 0 >= __v.__value_;
384}
385
386_LIBCPP_INLINE_VISIBILITY
387constexpr bool operator!=(partial_ordering __v, _CmpUnspecifiedParam) noexcept {
388 return !__v.__is_ordered() || __v.__value_ != 0;
389}
390_LIBCPP_INLINE_VISIBILITY
391constexpr bool operator!=(_CmpUnspecifiedParam, partial_ordering __v) noexcept {
392 return !__v.__is_ordered() || __v.__value_ != 0;
393}
394
395#ifndef _LIBCPP_HAS_NO_SPACESHIP_OPERATOR
396_LIBCPP_INLINE_VISIBILITY
397constexpr partial_ordering operator<=>(partial_ordering __v, _CmpUnspecifiedParam) noexcept {
398 return __v;
399}
400_LIBCPP_INLINE_VISIBILITY
401constexpr partial_ordering operator<=>(_CmpUnspecifiedParam, partial_ordering __v) noexcept {
402 return __v < 0 ? partial_ordering::greater : (__v > 0 ? partial_ordering::less : __v);
403}
404#endif // _LIBCPP_HAS_NO_SPACESHIP_OPERATOR
405
406class weak_ordering {
407 using _ValueT = signed char;
408
409 _LIBCPP_INLINE_VISIBILITY
410 explicit constexpr weak_ordering(_EqResult __v) noexcept : __value_(_ValueT(__v)) {}
411 _LIBCPP_INLINE_VISIBILITY
412 explicit constexpr weak_ordering(_OrdResult __v) noexcept : __value_(_ValueT(__v)) {}
413
414public:
415 static const weak_ordering less;
416 static const weak_ordering equivalent;
417 static const weak_ordering greater;
418
419 // conversions
420 _LIBCPP_INLINE_VISIBILITY
421 constexpr operator weak_equality() const noexcept {
422 return __value_ == 0 ? weak_equality::equivalent
423 : weak_equality::nonequivalent;
424 }
425
426 _LIBCPP_INLINE_VISIBILITY
427 constexpr operator partial_ordering() const noexcept {
428 return __value_ == 0 ? partial_ordering::equivalent
429 : (__value_ < 0 ? partial_ordering::less : partial_ordering::greater);
430 }
431
432 // comparisons
Louis Dionne05aca382018-07-10 13:21:03 +0000433 _LIBCPP_INLINE_VISIBILITY friend constexpr bool operator==(weak_ordering __v, _CmpUnspecifiedParam) noexcept;
434 _LIBCPP_INLINE_VISIBILITY friend constexpr bool operator!=(weak_ordering __v, _CmpUnspecifiedParam) noexcept;
435 _LIBCPP_INLINE_VISIBILITY friend constexpr bool operator< (weak_ordering __v, _CmpUnspecifiedParam) noexcept;
436 _LIBCPP_INLINE_VISIBILITY friend constexpr bool operator<=(weak_ordering __v, _CmpUnspecifiedParam) noexcept;
437 _LIBCPP_INLINE_VISIBILITY friend constexpr bool operator> (weak_ordering __v, _CmpUnspecifiedParam) noexcept;
438 _LIBCPP_INLINE_VISIBILITY friend constexpr bool operator>=(weak_ordering __v, _CmpUnspecifiedParam) noexcept;
439 _LIBCPP_INLINE_VISIBILITY friend constexpr bool operator==(_CmpUnspecifiedParam, weak_ordering __v) noexcept;
440 _LIBCPP_INLINE_VISIBILITY friend constexpr bool operator!=(_CmpUnspecifiedParam, weak_ordering __v) noexcept;
441 _LIBCPP_INLINE_VISIBILITY friend constexpr bool operator< (_CmpUnspecifiedParam, weak_ordering __v) noexcept;
442 _LIBCPP_INLINE_VISIBILITY friend constexpr bool operator<=(_CmpUnspecifiedParam, weak_ordering __v) noexcept;
443 _LIBCPP_INLINE_VISIBILITY friend constexpr bool operator> (_CmpUnspecifiedParam, weak_ordering __v) noexcept;
444 _LIBCPP_INLINE_VISIBILITY friend constexpr bool operator>=(_CmpUnspecifiedParam, weak_ordering __v) noexcept;
Eric Fiseliere0074fc2018-04-06 21:37:23 +0000445
446#ifndef _LIBCPP_HAS_NO_SPACESHIP_OPERATOR
Christopher Di Bella3f33a1e2020-06-18 10:17:57 -0400447 _LIBCPP_INLINE_VISIBILITY friend constexpr bool operator==(weak_ordering, weak_ordering) noexcept = default;
448
Louis Dionne05aca382018-07-10 13:21:03 +0000449 _LIBCPP_INLINE_VISIBILITY friend constexpr weak_ordering operator<=>(weak_ordering __v, _CmpUnspecifiedParam) noexcept;
450 _LIBCPP_INLINE_VISIBILITY friend constexpr weak_ordering operator<=>(_CmpUnspecifiedParam, weak_ordering __v) noexcept;
Eric Fiseliere0074fc2018-04-06 21:37:23 +0000451#endif
452
453private:
454 _ValueT __value_;
455};
456
457_LIBCPP_INLINE_VAR constexpr weak_ordering weak_ordering::less(_OrdResult::__less);
458_LIBCPP_INLINE_VAR constexpr weak_ordering weak_ordering::equivalent(_EqResult::__equiv);
459_LIBCPP_INLINE_VAR constexpr weak_ordering weak_ordering::greater(_OrdResult::__greater);
460
461_LIBCPP_INLINE_VISIBILITY
462constexpr bool operator==(weak_ordering __v, _CmpUnspecifiedParam) noexcept {
463 return __v.__value_ == 0;
464}
465_LIBCPP_INLINE_VISIBILITY
466constexpr bool operator!=(weak_ordering __v, _CmpUnspecifiedParam) noexcept {
467 return __v.__value_ != 0;
468}
469_LIBCPP_INLINE_VISIBILITY
470constexpr bool operator< (weak_ordering __v, _CmpUnspecifiedParam) noexcept {
471 return __v.__value_ < 0;
472}
473_LIBCPP_INLINE_VISIBILITY
474constexpr bool operator<=(weak_ordering __v, _CmpUnspecifiedParam) noexcept {
475 return __v.__value_ <= 0;
476}
477_LIBCPP_INLINE_VISIBILITY
478constexpr bool operator> (weak_ordering __v, _CmpUnspecifiedParam) noexcept {
479 return __v.__value_ > 0;
480}
481_LIBCPP_INLINE_VISIBILITY
482constexpr bool operator>=(weak_ordering __v, _CmpUnspecifiedParam) noexcept {
483 return __v.__value_ >= 0;
484}
485_LIBCPP_INLINE_VISIBILITY
486constexpr bool operator==(_CmpUnspecifiedParam, weak_ordering __v) noexcept {
487 return 0 == __v.__value_;
488}
489_LIBCPP_INLINE_VISIBILITY
490constexpr bool operator!=(_CmpUnspecifiedParam, weak_ordering __v) noexcept {
491 return 0 != __v.__value_;
492}
493_LIBCPP_INLINE_VISIBILITY
494constexpr bool operator< (_CmpUnspecifiedParam, weak_ordering __v) noexcept {
495 return 0 < __v.__value_;
496}
497_LIBCPP_INLINE_VISIBILITY
498constexpr bool operator<=(_CmpUnspecifiedParam, weak_ordering __v) noexcept {
499 return 0 <= __v.__value_;
500}
501_LIBCPP_INLINE_VISIBILITY
502constexpr bool operator> (_CmpUnspecifiedParam, weak_ordering __v) noexcept {
503 return 0 > __v.__value_;
504}
505_LIBCPP_INLINE_VISIBILITY
506constexpr bool operator>=(_CmpUnspecifiedParam, weak_ordering __v) noexcept {
507 return 0 >= __v.__value_;
508}
509
510#ifndef _LIBCPP_HAS_NO_SPACESHIP_OPERATOR
511_LIBCPP_INLINE_VISIBILITY
512constexpr weak_ordering operator<=>(weak_ordering __v, _CmpUnspecifiedParam) noexcept {
513 return __v;
514}
515_LIBCPP_INLINE_VISIBILITY
516constexpr weak_ordering operator<=>(_CmpUnspecifiedParam, weak_ordering __v) noexcept {
517 return __v < 0 ? weak_ordering::greater : (__v > 0 ? weak_ordering::less : __v);
518}
519#endif // _LIBCPP_HAS_NO_SPACESHIP_OPERATOR
520
521class strong_ordering {
522 using _ValueT = signed char;
523
524 _LIBCPP_INLINE_VISIBILITY
525 explicit constexpr strong_ordering(_EqResult __v) noexcept : __value_(_ValueT(__v)) {}
526 _LIBCPP_INLINE_VISIBILITY
527 explicit constexpr strong_ordering(_OrdResult __v) noexcept : __value_(_ValueT(__v)) {}
528
529public:
530 static const strong_ordering less;
531 static const strong_ordering equal;
532 static const strong_ordering equivalent;
533 static const strong_ordering greater;
534
535 // conversions
536 _LIBCPP_INLINE_VISIBILITY
537 constexpr operator weak_equality() const noexcept {
538 return __value_ == 0 ? weak_equality::equivalent
539 : weak_equality::nonequivalent;
540 }
541
542 _LIBCPP_INLINE_VISIBILITY
543 constexpr operator strong_equality() const noexcept {
544 return __value_ == 0 ? strong_equality::equal
545 : strong_equality::nonequal;
546 }
547
548 _LIBCPP_INLINE_VISIBILITY
549 constexpr operator partial_ordering() const noexcept {
550 return __value_ == 0 ? partial_ordering::equivalent
551 : (__value_ < 0 ? partial_ordering::less : partial_ordering::greater);
552 }
553
554 _LIBCPP_INLINE_VISIBILITY
555 constexpr operator weak_ordering() const noexcept {
556 return __value_ == 0 ? weak_ordering::equivalent
557 : (__value_ < 0 ? weak_ordering::less : weak_ordering::greater);
558 }
559
560 // comparisons
Louis Dionne05aca382018-07-10 13:21:03 +0000561 _LIBCPP_INLINE_VISIBILITY friend constexpr bool operator==(strong_ordering __v, _CmpUnspecifiedParam) noexcept;
562 _LIBCPP_INLINE_VISIBILITY friend constexpr bool operator!=(strong_ordering __v, _CmpUnspecifiedParam) noexcept;
563 _LIBCPP_INLINE_VISIBILITY friend constexpr bool operator< (strong_ordering __v, _CmpUnspecifiedParam) noexcept;
564 _LIBCPP_INLINE_VISIBILITY friend constexpr bool operator<=(strong_ordering __v, _CmpUnspecifiedParam) noexcept;
565 _LIBCPP_INLINE_VISIBILITY friend constexpr bool operator> (strong_ordering __v, _CmpUnspecifiedParam) noexcept;
566 _LIBCPP_INLINE_VISIBILITY friend constexpr bool operator>=(strong_ordering __v, _CmpUnspecifiedParam) noexcept;
567 _LIBCPP_INLINE_VISIBILITY friend constexpr bool operator==(_CmpUnspecifiedParam, strong_ordering __v) noexcept;
568 _LIBCPP_INLINE_VISIBILITY friend constexpr bool operator!=(_CmpUnspecifiedParam, strong_ordering __v) noexcept;
569 _LIBCPP_INLINE_VISIBILITY friend constexpr bool operator< (_CmpUnspecifiedParam, strong_ordering __v) noexcept;
570 _LIBCPP_INLINE_VISIBILITY friend constexpr bool operator<=(_CmpUnspecifiedParam, strong_ordering __v) noexcept;
571 _LIBCPP_INLINE_VISIBILITY friend constexpr bool operator> (_CmpUnspecifiedParam, strong_ordering __v) noexcept;
572 _LIBCPP_INLINE_VISIBILITY friend constexpr bool operator>=(_CmpUnspecifiedParam, strong_ordering __v) noexcept;
Eric Fiseliere0074fc2018-04-06 21:37:23 +0000573
574#ifndef _LIBCPP_HAS_NO_SPACESHIP_OPERATOR
Christopher Di Bella3f33a1e2020-06-18 10:17:57 -0400575 _LIBCPP_INLINE_VISIBILITY friend constexpr bool operator==(strong_ordering, strong_ordering) noexcept = default;
576
Louis Dionne05aca382018-07-10 13:21:03 +0000577 _LIBCPP_INLINE_VISIBILITY friend constexpr strong_ordering operator<=>(strong_ordering __v, _CmpUnspecifiedParam) noexcept;
578 _LIBCPP_INLINE_VISIBILITY friend constexpr strong_ordering operator<=>(_CmpUnspecifiedParam, strong_ordering __v) noexcept;
Eric Fiseliere0074fc2018-04-06 21:37:23 +0000579#endif
580
581private:
582 _ValueT __value_;
583};
584
585_LIBCPP_INLINE_VAR constexpr strong_ordering strong_ordering::less(_OrdResult::__less);
586_LIBCPP_INLINE_VAR constexpr strong_ordering strong_ordering::equal(_EqResult::__equal);
587_LIBCPP_INLINE_VAR constexpr strong_ordering strong_ordering::equivalent(_EqResult::__equiv);
588_LIBCPP_INLINE_VAR constexpr strong_ordering strong_ordering::greater(_OrdResult::__greater);
589
590_LIBCPP_INLINE_VISIBILITY
591constexpr bool operator==(strong_ordering __v, _CmpUnspecifiedParam) noexcept {
592 return __v.__value_ == 0;
593}
594_LIBCPP_INLINE_VISIBILITY
595constexpr bool operator!=(strong_ordering __v, _CmpUnspecifiedParam) noexcept {
596 return __v.__value_ != 0;
597}
598_LIBCPP_INLINE_VISIBILITY
599constexpr bool operator< (strong_ordering __v, _CmpUnspecifiedParam) noexcept {
600 return __v.__value_ < 0;
601}
602_LIBCPP_INLINE_VISIBILITY
603constexpr bool operator<=(strong_ordering __v, _CmpUnspecifiedParam) noexcept {
604 return __v.__value_ <= 0;
605}
606_LIBCPP_INLINE_VISIBILITY
607constexpr bool operator> (strong_ordering __v, _CmpUnspecifiedParam) noexcept {
608 return __v.__value_ > 0;
609}
610_LIBCPP_INLINE_VISIBILITY
611constexpr bool operator>=(strong_ordering __v, _CmpUnspecifiedParam) noexcept {
612 return __v.__value_ >= 0;
613}
614_LIBCPP_INLINE_VISIBILITY
615constexpr bool operator==(_CmpUnspecifiedParam, strong_ordering __v) noexcept {
616 return 0 == __v.__value_;
617}
618_LIBCPP_INLINE_VISIBILITY
619constexpr bool operator!=(_CmpUnspecifiedParam, strong_ordering __v) noexcept {
620 return 0 != __v.__value_;
621}
622_LIBCPP_INLINE_VISIBILITY
623constexpr bool operator< (_CmpUnspecifiedParam, strong_ordering __v) noexcept {
624 return 0 < __v.__value_;
625}
626_LIBCPP_INLINE_VISIBILITY
627constexpr bool operator<=(_CmpUnspecifiedParam, strong_ordering __v) noexcept {
628 return 0 <= __v.__value_;
629}
630_LIBCPP_INLINE_VISIBILITY
631constexpr bool operator> (_CmpUnspecifiedParam, strong_ordering __v) noexcept {
632 return 0 > __v.__value_;
633}
634_LIBCPP_INLINE_VISIBILITY
635constexpr bool operator>=(_CmpUnspecifiedParam, strong_ordering __v) noexcept {
636 return 0 >= __v.__value_;
637}
638
639#ifndef _LIBCPP_HAS_NO_SPACESHIP_OPERATOR
640_LIBCPP_INLINE_VISIBILITY
641constexpr strong_ordering operator<=>(strong_ordering __v, _CmpUnspecifiedParam) noexcept {
642 return __v;
643}
644_LIBCPP_INLINE_VISIBILITY
645constexpr strong_ordering operator<=>(_CmpUnspecifiedParam, strong_ordering __v) noexcept {
646 return __v < 0 ? strong_ordering::greater : (__v > 0 ? strong_ordering::less : __v);
647}
648#endif // _LIBCPP_HAS_NO_SPACESHIP_OPERATOR
649
650// named comparison functions
651_LIBCPP_INLINE_VISIBILITY
652constexpr bool is_eq(weak_equality __cmp) noexcept { return __cmp == 0; }
653
654_LIBCPP_INLINE_VISIBILITY
655constexpr bool is_neq(weak_equality __cmp) noexcept { return __cmp != 0; }
656
657_LIBCPP_INLINE_VISIBILITY
658constexpr bool is_lt(partial_ordering __cmp) noexcept { return __cmp < 0; }
659
660_LIBCPP_INLINE_VISIBILITY
661constexpr bool is_lteq(partial_ordering __cmp) noexcept { return __cmp <= 0; }
662
663_LIBCPP_INLINE_VISIBILITY
664constexpr bool is_gt(partial_ordering __cmp) noexcept { return __cmp > 0; }
665
666_LIBCPP_INLINE_VISIBILITY
667constexpr bool is_gteq(partial_ordering __cmp) noexcept { return __cmp >= 0; }
668
669namespace __comp_detail {
670
671enum _ClassifyCompCategory : unsigned{
672 _None,
673 _WeakEq,
674 _StrongEq,
675 _PartialOrd,
676 _WeakOrd,
677 _StrongOrd,
678 _CCC_Size
679};
680
681template <class _Tp>
682_LIBCPP_INLINE_VISIBILITY
683constexpr _ClassifyCompCategory __type_to_enum() noexcept {
684 if (is_same_v<_Tp, weak_equality>)
685 return _WeakEq;
686 if (is_same_v<_Tp, strong_equality>)
687 return _StrongEq;
688 if (is_same_v<_Tp, partial_ordering>)
689 return _PartialOrd;
690 if (is_same_v<_Tp, weak_ordering>)
691 return _WeakOrd;
692 if (is_same_v<_Tp, strong_ordering>)
693 return _StrongOrd;
694 return _None;
695}
696
697template <size_t _Size>
698constexpr _ClassifyCompCategory
699__compute_comp_type(std::array<_ClassifyCompCategory, _Size> __types) {
700 std::array<int, _CCC_Size> __seen = {};
701 for (auto __type : __types)
702 ++__seen[__type];
703 if (__seen[_None])
704 return _None;
705 if (__seen[_WeakEq])
706 return _WeakEq;
707 if (__seen[_StrongEq] && (__seen[_PartialOrd] || __seen[_WeakOrd]))
708 return _WeakEq;
709 if (__seen[_StrongEq])
710 return _StrongEq;
711 if (__seen[_PartialOrd])
712 return _PartialOrd;
713 if (__seen[_WeakOrd])
714 return _WeakOrd;
715 return _StrongOrd;
716}
717
718template <class ..._Ts>
719constexpr auto __get_comp_type() {
720 using _CCC = _ClassifyCompCategory;
Eric Fiselier0ee99402018-04-07 01:28:54 +0000721 constexpr array<_CCC, sizeof...(_Ts)> __type_kinds{{__comp_detail::__type_to_enum<_Ts>()...}};
Eric Fiseliere0074fc2018-04-06 21:37:23 +0000722 constexpr _CCC _Cat = sizeof...(_Ts) == 0 ? _StrongOrd
723 : __compute_comp_type(__type_kinds);
724 if constexpr (_Cat == _None)
Eric Fiselierafcb4b82018-04-07 04:28:11 +0000725 return void();
Eric Fiseliere0074fc2018-04-06 21:37:23 +0000726 else if constexpr (_Cat == _WeakEq)
727 return weak_equality::equivalent;
728 else if constexpr (_Cat == _StrongEq)
729 return strong_equality::equivalent;
730 else if constexpr (_Cat == _PartialOrd)
731 return partial_ordering::equivalent;
732 else if constexpr (_Cat == _WeakOrd)
733 return weak_ordering::equivalent;
734 else if constexpr (_Cat == _StrongOrd)
735 return strong_ordering::equivalent;
736 else
737 static_assert(_Cat != _Cat, "unhandled case");
738}
739} // namespace __comp_detail
740
741// [cmp.common], common comparison category type
742template<class... _Ts>
743struct _LIBCPP_TEMPLATE_VIS common_comparison_category {
744 using type = decltype(__comp_detail::__get_comp_type<_Ts...>());
745};
746
747template<class... _Ts>
748using common_comparison_category_t = typename common_comparison_category<_Ts...>::type;
749
750// [cmp.alg], comparison algorithms
751// TODO: unimplemented
752template<class _Tp> constexpr strong_ordering strong_order(const _Tp& __lhs, const _Tp& __rhs);
753template<class _Tp> constexpr weak_ordering weak_order(const _Tp& __lhs, const _Tp& __rhs);
754template<class _Tp> constexpr partial_ordering partial_order(const _Tp& __lhs, const _Tp& __rhs);
755template<class _Tp> constexpr strong_equality strong_equal(const _Tp& __lhs, const _Tp& __rhs);
756template<class _Tp> constexpr weak_equality weak_equal(const _Tp& __lhs, const _Tp& __rhs);
757
758#endif // _LIBCPP_STD_VER > 17
759
760_LIBCPP_END_NAMESPACE_STD
761
762#endif // _LIBCPP_COMPARE