2 //===-------------------------- compare -----------------------------------===//
4 // 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
8 //===----------------------------------------------------------------------===//
10 #ifndef _LIBCPP_COMPARE
11 #define _LIBCPP_COMPARE
17 // [cmp.categories], comparison category types
19 class strong_equality;
20 class partial_ordering;
22 class strong_ordering;
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; }
32 // [cmp.common], common comparison category type
34 struct common_comparison_category {
35 using type = see below;
38 using common_comparison_category_t = typename common_comparison_category<Ts...>::type;
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);
47 // [cmp.partialord], Class partial_ordering
48 class partial_ordering {
51 static const partial_ordering less;
52 static const partial_ordering equivalent;
53 static const partial_ordering greater;
54 static const partial_ordering unordered;
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;
71 // [cmp.weakord], Class weak_ordering
75 static const weak_ordering less;
76 static const weak_ordering equivalent;
77 static const weak_ordering greater;
80 constexpr operator partial_ordering() const noexcept;
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;
97 // [cmp.strongord], Class strong_ordering
98 class strong_ordering {
101 static const strong_ordering less;
102 static const strong_ordering equal;
103 static const strong_ordering equivalent;
104 static const strong_ordering greater;
107 constexpr operator partial_ordering() const noexcept;
108 constexpr operator weak_ordering() const noexcept;
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;
128 #include <type_traits>
131 #ifndef _LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER
132 #pragma GCC system_header
135 _LIBCPP_BEGIN_NAMESPACE_STD
137 #if _LIBCPP_STD_VER > 17
140 enum class _LIBCPP_ENUM_VIS _EqResult : unsigned char {
145 __nonequiv = __nonequal
148 enum class _LIBCPP_ENUM_VIS _OrdResult : signed char {
153 enum class _LIBCPP_ENUM_VIS _NCmpResult : signed char {
157 struct _CmpUnspecifiedType;
158 using _CmpUnspecifiedParam = void (_CmpUnspecifiedType::*)();
160 class weak_equality {
161 _LIBCPP_INLINE_VISIBILITY
162 constexpr explicit weak_equality(_EqResult __val) noexcept : __value_(__val) {}
165 static const weak_equality equivalent;
166 static const weak_equality nonequivalent;
168 _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;
173 #ifndef _LIBCPP_HAS_NO_SPACESHIP_OPERATOR
174 _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;
182 _LIBCPP_INLINE_VAR constexpr weak_equality weak_equality::equivalent(_EqResult::__equiv);
183 _LIBCPP_INLINE_VAR constexpr weak_equality weak_equality::nonequivalent(_EqResult::__nonequiv);
185 _LIBCPP_INLINE_VISIBILITY
186 inline constexpr bool operator==(weak_equality __v, _CmpUnspecifiedParam) noexcept {
187 return __v.__value_ == _EqResult::__zero;
190 _LIBCPP_INLINE_VISIBILITY
191 inline constexpr bool operator==(_CmpUnspecifiedParam, weak_equality __v) noexcept {
192 return __v.__value_ == _EqResult::__zero;
195 _LIBCPP_INLINE_VISIBILITY
196 inline constexpr bool operator!=(weak_equality __v, _CmpUnspecifiedParam) noexcept {
197 return __v.__value_ != _EqResult::__zero;
200 _LIBCPP_INLINE_VISIBILITY
201 inline constexpr bool operator!=(_CmpUnspecifiedParam, weak_equality __v) noexcept {
202 return __v.__value_ != _EqResult::__zero;
205 #ifndef _LIBCPP_HAS_NO_SPACESHIP_OPERATOR
206 _LIBCPP_INLINE_VISIBILITY
207 inline constexpr weak_equality operator<=>(weak_equality __v, _CmpUnspecifiedParam) noexcept {
211 _LIBCPP_INLINE_VISIBILITY
212 inline constexpr weak_equality operator<=>(_CmpUnspecifiedParam, weak_equality __v) noexcept {
217 class strong_equality {
218 _LIBCPP_INLINE_VISIBILITY
219 explicit constexpr strong_equality(_EqResult __val) noexcept : __value_(__val) {}
222 static const strong_equality equal;
223 static const strong_equality nonequal;
224 static const strong_equality equivalent;
225 static const strong_equality nonequivalent;
228 _LIBCPP_INLINE_VISIBILITY constexpr operator weak_equality() const noexcept {
229 return __value_ == _EqResult::__zero ? weak_equality::equivalent
230 : weak_equality::nonequivalent;
234 _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;
239 #ifndef _LIBCPP_HAS_NO_SPACESHIP_OPERATOR
240 _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;
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);
252 _LIBCPP_INLINE_VISIBILITY
253 constexpr bool operator==(strong_equality __v, _CmpUnspecifiedParam) noexcept {
254 return __v.__value_ == _EqResult::__zero;
257 _LIBCPP_INLINE_VISIBILITY
258 constexpr bool operator==(_CmpUnspecifiedParam, strong_equality __v) noexcept {
259 return __v.__value_ == _EqResult::__zero;
262 _LIBCPP_INLINE_VISIBILITY
263 constexpr bool operator!=(strong_equality __v, _CmpUnspecifiedParam) noexcept {
264 return __v.__value_ != _EqResult::__zero;
267 _LIBCPP_INLINE_VISIBILITY
268 constexpr bool operator!=(_CmpUnspecifiedParam, strong_equality __v) noexcept {
269 return __v.__value_ != _EqResult::__zero;
272 #ifndef _LIBCPP_HAS_NO_SPACESHIP_OPERATOR
273 _LIBCPP_INLINE_VISIBILITY
274 constexpr strong_equality operator<=>(strong_equality __v, _CmpUnspecifiedParam) noexcept {
278 _LIBCPP_INLINE_VISIBILITY
279 constexpr strong_equality operator<=>(_CmpUnspecifiedParam, strong_equality __v) noexcept {
282 #endif // _LIBCPP_HAS_NO_SPACESHIP_OPERATOR
284 class partial_ordering {
285 using _ValueT = signed char;
287 _LIBCPP_INLINE_VISIBILITY
288 explicit constexpr partial_ordering(_EqResult __v) noexcept
289 : __value_(_ValueT(__v)) {}
291 _LIBCPP_INLINE_VISIBILITY
292 explicit constexpr partial_ordering(_OrdResult __v) noexcept
293 : __value_(_ValueT(__v)) {}
295 _LIBCPP_INLINE_VISIBILITY
296 explicit constexpr partial_ordering(_NCmpResult __v) noexcept
297 : __value_(_ValueT(__v)) {}
299 constexpr bool __is_ordered() const noexcept {
300 return __value_ != _ValueT(_NCmpResult::__unordered);
304 static const partial_ordering less;
305 static const partial_ordering equivalent;
306 static const partial_ordering greater;
307 static const partial_ordering unordered;
310 constexpr operator weak_equality() const noexcept {
311 return __value_ == 0 ? weak_equality::equivalent : weak_equality::nonequivalent;
315 _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;
328 #ifndef _LIBCPP_HAS_NO_SPACESHIP_OPERATOR
329 _LIBCPP_INLINE_VISIBILITY friend constexpr bool operator==(partial_ordering, partial_ordering) noexcept = default;
331 _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;
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);
344 _LIBCPP_INLINE_VISIBILITY
345 constexpr bool operator==(partial_ordering __v, _CmpUnspecifiedParam) noexcept {
346 return __v.__is_ordered() && __v.__value_ == 0;
348 _LIBCPP_INLINE_VISIBILITY
349 constexpr bool operator< (partial_ordering __v, _CmpUnspecifiedParam) noexcept {
350 return __v.__is_ordered() && __v.__value_ < 0;
352 _LIBCPP_INLINE_VISIBILITY
353 constexpr bool operator<=(partial_ordering __v, _CmpUnspecifiedParam) noexcept {
354 return __v.__is_ordered() && __v.__value_ <= 0;
356 _LIBCPP_INLINE_VISIBILITY
357 constexpr bool operator> (partial_ordering __v, _CmpUnspecifiedParam) noexcept {
358 return __v.__is_ordered() && __v.__value_ > 0;
360 _LIBCPP_INLINE_VISIBILITY
361 constexpr bool operator>=(partial_ordering __v, _CmpUnspecifiedParam) noexcept {
362 return __v.__is_ordered() && __v.__value_ >= 0;
365 _LIBCPP_INLINE_VISIBILITY
366 constexpr bool operator==(_CmpUnspecifiedParam, partial_ordering __v) noexcept {
367 return __v.__is_ordered() && 0 == __v.__value_;
369 _LIBCPP_INLINE_VISIBILITY
370 constexpr bool operator< (_CmpUnspecifiedParam, partial_ordering __v) noexcept {
371 return __v.__is_ordered() && 0 < __v.__value_;
373 _LIBCPP_INLINE_VISIBILITY
374 constexpr bool operator<=(_CmpUnspecifiedParam, partial_ordering __v) noexcept {
375 return __v.__is_ordered() && 0 <= __v.__value_;
377 _LIBCPP_INLINE_VISIBILITY
378 constexpr bool operator> (_CmpUnspecifiedParam, partial_ordering __v) noexcept {
379 return __v.__is_ordered() && 0 > __v.__value_;
381 _LIBCPP_INLINE_VISIBILITY
382 constexpr bool operator>=(_CmpUnspecifiedParam, partial_ordering __v) noexcept {
383 return __v.__is_ordered() && 0 >= __v.__value_;
386 _LIBCPP_INLINE_VISIBILITY
387 constexpr bool operator!=(partial_ordering __v, _CmpUnspecifiedParam) noexcept {
388 return !__v.__is_ordered() || __v.__value_ != 0;
390 _LIBCPP_INLINE_VISIBILITY
391 constexpr bool operator!=(_CmpUnspecifiedParam, partial_ordering __v) noexcept {
392 return !__v.__is_ordered() || __v.__value_ != 0;
395 #ifndef _LIBCPP_HAS_NO_SPACESHIP_OPERATOR
396 _LIBCPP_INLINE_VISIBILITY
397 constexpr partial_ordering operator<=>(partial_ordering __v, _CmpUnspecifiedParam) noexcept {
400 _LIBCPP_INLINE_VISIBILITY
401 constexpr partial_ordering operator<=>(_CmpUnspecifiedParam, partial_ordering __v) noexcept {
402 return __v < 0 ? partial_ordering::greater : (__v > 0 ? partial_ordering::less : __v);
404 #endif // _LIBCPP_HAS_NO_SPACESHIP_OPERATOR
406 class weak_ordering {
407 using _ValueT = signed char;
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)) {}
415 static const weak_ordering less;
416 static const weak_ordering equivalent;
417 static const weak_ordering greater;
420 _LIBCPP_INLINE_VISIBILITY
421 constexpr operator weak_equality() const noexcept {
422 return __value_ == 0 ? weak_equality::equivalent
423 : weak_equality::nonequivalent;
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);
433 _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;
446 #ifndef _LIBCPP_HAS_NO_SPACESHIP_OPERATOR
447 _LIBCPP_INLINE_VISIBILITY friend constexpr bool operator==(weak_ordering, weak_ordering) noexcept = default;
449 _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;
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);
461 _LIBCPP_INLINE_VISIBILITY
462 constexpr bool operator==(weak_ordering __v, _CmpUnspecifiedParam) noexcept {
463 return __v.__value_ == 0;
465 _LIBCPP_INLINE_VISIBILITY
466 constexpr bool operator!=(weak_ordering __v, _CmpUnspecifiedParam) noexcept {
467 return __v.__value_ != 0;
469 _LIBCPP_INLINE_VISIBILITY
470 constexpr bool operator< (weak_ordering __v, _CmpUnspecifiedParam) noexcept {
471 return __v.__value_ < 0;
473 _LIBCPP_INLINE_VISIBILITY
474 constexpr bool operator<=(weak_ordering __v, _CmpUnspecifiedParam) noexcept {
475 return __v.__value_ <= 0;
477 _LIBCPP_INLINE_VISIBILITY
478 constexpr bool operator> (weak_ordering __v, _CmpUnspecifiedParam) noexcept {
479 return __v.__value_ > 0;
481 _LIBCPP_INLINE_VISIBILITY
482 constexpr bool operator>=(weak_ordering __v, _CmpUnspecifiedParam) noexcept {
483 return __v.__value_ >= 0;
485 _LIBCPP_INLINE_VISIBILITY
486 constexpr bool operator==(_CmpUnspecifiedParam, weak_ordering __v) noexcept {
487 return 0 == __v.__value_;
489 _LIBCPP_INLINE_VISIBILITY
490 constexpr bool operator!=(_CmpUnspecifiedParam, weak_ordering __v) noexcept {
491 return 0 != __v.__value_;
493 _LIBCPP_INLINE_VISIBILITY
494 constexpr bool operator< (_CmpUnspecifiedParam, weak_ordering __v) noexcept {
495 return 0 < __v.__value_;
497 _LIBCPP_INLINE_VISIBILITY
498 constexpr bool operator<=(_CmpUnspecifiedParam, weak_ordering __v) noexcept {
499 return 0 <= __v.__value_;
501 _LIBCPP_INLINE_VISIBILITY
502 constexpr bool operator> (_CmpUnspecifiedParam, weak_ordering __v) noexcept {
503 return 0 > __v.__value_;
505 _LIBCPP_INLINE_VISIBILITY
506 constexpr bool operator>=(_CmpUnspecifiedParam, weak_ordering __v) noexcept {
507 return 0 >= __v.__value_;
510 #ifndef _LIBCPP_HAS_NO_SPACESHIP_OPERATOR
511 _LIBCPP_INLINE_VISIBILITY
512 constexpr weak_ordering operator<=>(weak_ordering __v, _CmpUnspecifiedParam) noexcept {
515 _LIBCPP_INLINE_VISIBILITY
516 constexpr weak_ordering operator<=>(_CmpUnspecifiedParam, weak_ordering __v) noexcept {
517 return __v < 0 ? weak_ordering::greater : (__v > 0 ? weak_ordering::less : __v);
519 #endif // _LIBCPP_HAS_NO_SPACESHIP_OPERATOR
521 class strong_ordering {
522 using _ValueT = signed char;
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)) {}
530 static const strong_ordering less;
531 static const strong_ordering equal;
532 static const strong_ordering equivalent;
533 static const strong_ordering greater;
536 _LIBCPP_INLINE_VISIBILITY
537 constexpr operator weak_equality() const noexcept {
538 return __value_ == 0 ? weak_equality::equivalent
539 : weak_equality::nonequivalent;
542 _LIBCPP_INLINE_VISIBILITY
543 constexpr operator strong_equality() const noexcept {
544 return __value_ == 0 ? strong_equality::equal
545 : strong_equality::nonequal;
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);
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);
561 _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;
574 #ifndef _LIBCPP_HAS_NO_SPACESHIP_OPERATOR
575 _LIBCPP_INLINE_VISIBILITY friend constexpr bool operator==(strong_ordering, strong_ordering) noexcept = default;
577 _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;
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);
590 _LIBCPP_INLINE_VISIBILITY
591 constexpr bool operator==(strong_ordering __v, _CmpUnspecifiedParam) noexcept {
592 return __v.__value_ == 0;
594 _LIBCPP_INLINE_VISIBILITY
595 constexpr bool operator!=(strong_ordering __v, _CmpUnspecifiedParam) noexcept {
596 return __v.__value_ != 0;
598 _LIBCPP_INLINE_VISIBILITY
599 constexpr bool operator< (strong_ordering __v, _CmpUnspecifiedParam) noexcept {
600 return __v.__value_ < 0;
602 _LIBCPP_INLINE_VISIBILITY
603 constexpr bool operator<=(strong_ordering __v, _CmpUnspecifiedParam) noexcept {
604 return __v.__value_ <= 0;
606 _LIBCPP_INLINE_VISIBILITY
607 constexpr bool operator> (strong_ordering __v, _CmpUnspecifiedParam) noexcept {
608 return __v.__value_ > 0;
610 _LIBCPP_INLINE_VISIBILITY
611 constexpr bool operator>=(strong_ordering __v, _CmpUnspecifiedParam) noexcept {
612 return __v.__value_ >= 0;
614 _LIBCPP_INLINE_VISIBILITY
615 constexpr bool operator==(_CmpUnspecifiedParam, strong_ordering __v) noexcept {
616 return 0 == __v.__value_;
618 _LIBCPP_INLINE_VISIBILITY
619 constexpr bool operator!=(_CmpUnspecifiedParam, strong_ordering __v) noexcept {
620 return 0 != __v.__value_;
622 _LIBCPP_INLINE_VISIBILITY
623 constexpr bool operator< (_CmpUnspecifiedParam, strong_ordering __v) noexcept {
624 return 0 < __v.__value_;
626 _LIBCPP_INLINE_VISIBILITY
627 constexpr bool operator<=(_CmpUnspecifiedParam, strong_ordering __v) noexcept {
628 return 0 <= __v.__value_;
630 _LIBCPP_INLINE_VISIBILITY
631 constexpr bool operator> (_CmpUnspecifiedParam, strong_ordering __v) noexcept {
632 return 0 > __v.__value_;
634 _LIBCPP_INLINE_VISIBILITY
635 constexpr bool operator>=(_CmpUnspecifiedParam, strong_ordering __v) noexcept {
636 return 0 >= __v.__value_;
639 #ifndef _LIBCPP_HAS_NO_SPACESHIP_OPERATOR
640 _LIBCPP_INLINE_VISIBILITY
641 constexpr strong_ordering operator<=>(strong_ordering __v, _CmpUnspecifiedParam) noexcept {
644 _LIBCPP_INLINE_VISIBILITY
645 constexpr strong_ordering operator<=>(_CmpUnspecifiedParam, strong_ordering __v) noexcept {
646 return __v < 0 ? strong_ordering::greater : (__v > 0 ? strong_ordering::less : __v);
648 #endif // _LIBCPP_HAS_NO_SPACESHIP_OPERATOR
650 // named comparison functions
651 _LIBCPP_INLINE_VISIBILITY
652 constexpr bool is_eq(weak_equality __cmp) noexcept { return __cmp == 0; }
654 _LIBCPP_INLINE_VISIBILITY
655 constexpr bool is_neq(weak_equality __cmp) noexcept { return __cmp != 0; }
657 _LIBCPP_INLINE_VISIBILITY
658 constexpr bool is_lt(partial_ordering __cmp) noexcept { return __cmp < 0; }
660 _LIBCPP_INLINE_VISIBILITY
661 constexpr bool is_lteq(partial_ordering __cmp) noexcept { return __cmp <= 0; }
663 _LIBCPP_INLINE_VISIBILITY
664 constexpr bool is_gt(partial_ordering __cmp) noexcept { return __cmp > 0; }
666 _LIBCPP_INLINE_VISIBILITY
667 constexpr bool is_gteq(partial_ordering __cmp) noexcept { return __cmp >= 0; }
669 namespace __comp_detail {
671 enum _ClassifyCompCategory : unsigned{
682 _LIBCPP_INLINE_VISIBILITY
683 constexpr _ClassifyCompCategory __type_to_enum() noexcept {
684 if (is_same_v<_Tp, weak_equality>)
686 if (is_same_v<_Tp, strong_equality>)
688 if (is_same_v<_Tp, partial_ordering>)
690 if (is_same_v<_Tp, weak_ordering>)
692 if (is_same_v<_Tp, strong_ordering>)
697 template <size_t _Size>
698 constexpr _ClassifyCompCategory
699 __compute_comp_type(std::array<_ClassifyCompCategory, _Size> __types) {
700 std::array<int, _CCC_Size> __seen = {};
701 for (auto __type : __types)
707 if (__seen[_StrongEq] && (__seen[_PartialOrd] || __seen[_WeakOrd]))
709 if (__seen[_StrongEq])
711 if (__seen[_PartialOrd])
713 if (__seen[_WeakOrd])
718 template <class ..._Ts>
719 constexpr auto __get_comp_type() {
720 using _CCC = _ClassifyCompCategory;
721 constexpr array<_CCC, sizeof...(_Ts)> __type_kinds{{__comp_detail::__type_to_enum<_Ts>()...}};
722 constexpr _CCC _Cat = sizeof...(_Ts) == 0 ? _StrongOrd
723 : __compute_comp_type(__type_kinds);
724 if constexpr (_Cat == _None)
726 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;
737 static_assert(_Cat != _Cat, "unhandled case");
739 } // namespace __comp_detail
741 // [cmp.common], common comparison category type
742 template<class... _Ts>
743 struct _LIBCPP_TEMPLATE_VIS common_comparison_category {
744 using type = decltype(__comp_detail::__get_comp_type<_Ts...>());
747 template<class... _Ts>
748 using common_comparison_category_t = typename common_comparison_category<_Ts...>::type;
750 // [cmp.alg], comparison algorithms
751 // TODO: unimplemented
752 template<class _Tp> constexpr strong_ordering strong_order(const _Tp& __lhs, const _Tp& __rhs);
753 template<class _Tp> constexpr weak_ordering weak_order(const _Tp& __lhs, const _Tp& __rhs);
754 template<class _Tp> constexpr partial_ordering partial_order(const _Tp& __lhs, const _Tp& __rhs);
755 template<class _Tp> constexpr strong_equality strong_equal(const _Tp& __lhs, const _Tp& __rhs);
756 template<class _Tp> constexpr weak_equality weak_equal(const _Tp& __lhs, const _Tp& __rhs);
758 #endif // _LIBCPP_STD_VER > 17
760 _LIBCPP_END_NAMESPACE_STD
762 #endif // _LIBCPP_COMPARE