33#pragma GCC system_header
35#if __cplusplus > 201703L && __cpp_impl_three_way_comparison >= 201907L
37#pragma GCC visibility push(default)
42# define __cpp_lib_three_way_comparison 201711L
51 using type =
signed char;
53 enum class _Ord : type { equivalent = 0, less = -1, greater = 1 };
55 enum class _Ncmp : type { _Unordered = 2 };
59 constexpr __unspec(__unspec*) { }
63 class partial_ordering
66 __cmp_cat::type _M_value;
69 partial_ordering(__cmp_cat::_Ord __v) noexcept
70 : _M_value(__cmp_cat::type(__v))
74 partial_ordering(__cmp_cat::_Ncmp __v) noexcept
75 : _M_value(__cmp_cat::type(__v))
78 friend class weak_ordering;
79 friend class strong_ordering;
83 static const partial_ordering less;
84 static const partial_ordering equivalent;
85 static const partial_ordering greater;
86 static const partial_ordering unordered;
90 operator==(partial_ordering __v, __cmp_cat::__unspec)
noexcept
91 {
return __v._M_value == 0; }
94 operator==(partial_ordering, partial_ordering)
noexcept =
default;
97 operator< (partial_ordering __v, __cmp_cat::__unspec)
noexcept
98 {
return __v._M_value == -1; }
100 friend constexpr bool
101 operator> (partial_ordering __v, __cmp_cat::__unspec)
noexcept
102 {
return __v._M_value == 1; }
104 friend constexpr bool
105 operator<=(partial_ordering __v, __cmp_cat::__unspec)
noexcept
106 {
return __v._M_value <= 0; }
108 friend constexpr bool
109 operator>=(partial_ordering __v, __cmp_cat::__unspec)
noexcept
110 {
return __cmp_cat::type(__v._M_value & 1) == __v._M_value; }
112 friend constexpr bool
113 operator< (__cmp_cat::__unspec, partial_ordering __v)
noexcept
114 {
return __v._M_value == 1; }
116 friend constexpr bool
117 operator> (__cmp_cat::__unspec, partial_ordering __v)
noexcept
118 {
return __v._M_value == -1; }
120 friend constexpr bool
121 operator<=(__cmp_cat::__unspec, partial_ordering __v)
noexcept
122 {
return __cmp_cat::type(__v._M_value & 1) == __v._M_value; }
124 friend constexpr bool
125 operator>=(__cmp_cat::__unspec, partial_ordering __v)
noexcept
126 {
return 0 >= __v._M_value; }
128 friend constexpr partial_ordering
129 operator<=>(partial_ordering __v, __cmp_cat::__unspec)
noexcept
132 friend constexpr partial_ordering
133 operator<=>(__cmp_cat::__unspec, partial_ordering __v)
noexcept
135 if (__v._M_value & 1)
136 return partial_ordering(__cmp_cat::_Ord(-__v._M_value));
143 inline constexpr partial_ordering
144 partial_ordering::less(__cmp_cat::_Ord::less);
146 inline constexpr partial_ordering
147 partial_ordering::equivalent(__cmp_cat::_Ord::equivalent);
149 inline constexpr partial_ordering
150 partial_ordering::greater(__cmp_cat::_Ord::greater);
152 inline constexpr partial_ordering
153 partial_ordering::unordered(__cmp_cat::_Ncmp::_Unordered);
157 __cmp_cat::type _M_value;
160 weak_ordering(__cmp_cat::_Ord __v) noexcept : _M_value(__cmp_cat::type(__v))
163 friend class strong_ordering;
167 static const weak_ordering less;
168 static const weak_ordering equivalent;
169 static const weak_ordering greater;
171 constexpr operator partial_ordering() const noexcept
172 {
return partial_ordering(__cmp_cat::_Ord(_M_value)); }
175 friend constexpr bool
176 operator==(weak_ordering __v, __cmp_cat::__unspec)
noexcept
177 {
return __v._M_value == 0; }
179 friend constexpr bool
180 operator==(weak_ordering, weak_ordering)
noexcept =
default;
182 friend constexpr bool
183 operator< (weak_ordering __v, __cmp_cat::__unspec)
noexcept
184 {
return __v._M_value < 0; }
186 friend constexpr bool
187 operator> (weak_ordering __v, __cmp_cat::__unspec)
noexcept
188 {
return __v._M_value > 0; }
190 friend constexpr bool
191 operator<=(weak_ordering __v, __cmp_cat::__unspec)
noexcept
192 {
return __v._M_value <= 0; }
194 friend constexpr bool
195 operator>=(weak_ordering __v, __cmp_cat::__unspec)
noexcept
196 {
return __v._M_value >= 0; }
198 friend constexpr bool
199 operator< (__cmp_cat::__unspec, weak_ordering __v)
noexcept
200 {
return 0 < __v._M_value; }
202 friend constexpr bool
203 operator> (__cmp_cat::__unspec, weak_ordering __v)
noexcept
204 {
return 0 > __v._M_value; }
206 friend constexpr bool
207 operator<=(__cmp_cat::__unspec, weak_ordering __v)
noexcept
208 {
return 0 <= __v._M_value; }
210 friend constexpr bool
211 operator>=(__cmp_cat::__unspec, weak_ordering __v)
noexcept
212 {
return 0 >= __v._M_value; }
214 friend constexpr weak_ordering
215 operator<=>(weak_ordering __v, __cmp_cat::__unspec)
noexcept
218 friend constexpr weak_ordering
219 operator<=>(__cmp_cat::__unspec, weak_ordering __v)
noexcept
220 {
return weak_ordering(__cmp_cat::_Ord(-__v._M_value)); }
224 inline constexpr weak_ordering
225 weak_ordering::less(__cmp_cat::_Ord::less);
227 inline constexpr weak_ordering
228 weak_ordering::equivalent(__cmp_cat::_Ord::equivalent);
230 inline constexpr weak_ordering
231 weak_ordering::greater(__cmp_cat::_Ord::greater);
233 class strong_ordering
235 __cmp_cat::type _M_value;
238 strong_ordering(__cmp_cat::_Ord __v) noexcept
239 : _M_value(__cmp_cat::type(__v))
244 static const strong_ordering less;
245 static const strong_ordering equal;
246 static const strong_ordering equivalent;
247 static const strong_ordering greater;
249 constexpr operator partial_ordering() const noexcept
250 {
return partial_ordering(__cmp_cat::_Ord(_M_value)); }
252 constexpr operator weak_ordering() const noexcept
253 {
return weak_ordering(__cmp_cat::_Ord(_M_value)); }
256 friend constexpr bool
257 operator==(strong_ordering __v, __cmp_cat::__unspec)
noexcept
258 {
return __v._M_value == 0; }
260 friend constexpr bool
261 operator==(strong_ordering, strong_ordering)
noexcept =
default;
263 friend constexpr bool
264 operator< (strong_ordering __v, __cmp_cat::__unspec)
noexcept
265 {
return __v._M_value < 0; }
267 friend constexpr bool
268 operator> (strong_ordering __v, __cmp_cat::__unspec)
noexcept
269 {
return __v._M_value > 0; }
271 friend constexpr bool
272 operator<=(strong_ordering __v, __cmp_cat::__unspec)
noexcept
273 {
return __v._M_value <= 0; }
275 friend constexpr bool
276 operator>=(strong_ordering __v, __cmp_cat::__unspec)
noexcept
277 {
return __v._M_value >= 0; }
279 friend constexpr bool
280 operator< (__cmp_cat::__unspec, strong_ordering __v)
noexcept
281 {
return 0 < __v._M_value; }
283 friend constexpr bool
284 operator> (__cmp_cat::__unspec, strong_ordering __v)
noexcept
285 {
return 0 > __v._M_value; }
287 friend constexpr bool
288 operator<=(__cmp_cat::__unspec, strong_ordering __v)
noexcept
289 {
return 0 <= __v._M_value; }
291 friend constexpr bool
292 operator>=(__cmp_cat::__unspec, strong_ordering __v)
noexcept
293 {
return 0 >= __v._M_value; }
295 friend constexpr strong_ordering
296 operator<=>(strong_ordering __v, __cmp_cat::__unspec)
noexcept
299 friend constexpr strong_ordering
300 operator<=>(__cmp_cat::__unspec, strong_ordering __v)
noexcept
301 {
return strong_ordering(__cmp_cat::_Ord(-__v._M_value)); }
305 inline constexpr strong_ordering
306 strong_ordering::less(__cmp_cat::_Ord::less);
308 inline constexpr strong_ordering
309 strong_ordering::equal(__cmp_cat::_Ord::equivalent);
311 inline constexpr strong_ordering
312 strong_ordering::equivalent(__cmp_cat::_Ord::equivalent);
314 inline constexpr strong_ordering
315 strong_ordering::greater(__cmp_cat::_Ord::greater);
320 is_eq(partial_ordering __cmp)
noexcept
321 {
return __cmp == 0; }
324 is_neq(partial_ordering __cmp)
noexcept
325 {
return __cmp != 0; }
328 is_lt (partial_ordering __cmp)
noexcept
329 {
return __cmp < 0; }
332 is_lteq(partial_ordering __cmp)
noexcept
333 {
return __cmp <= 0; }
336 is_gt (partial_ordering __cmp)
noexcept
337 {
return __cmp > 0; }
340 is_gteq(partial_ordering __cmp)
noexcept
341 {
return __cmp >= 0; }
345 template<
typename _Tp>
346 inline constexpr unsigned __cmp_cat_id = 1;
348 inline constexpr unsigned __cmp_cat_id<partial_ordering> = 2;
350 inline constexpr unsigned __cmp_cat_id<weak_ordering> = 4;
352 inline constexpr unsigned __cmp_cat_id<strong_ordering> = 8;
354 template<
typename... _Ts>
355 constexpr auto __common_cmp_cat()
357 constexpr unsigned __cats = (__cmp_cat_id<_Ts> | ...);
359 if constexpr (__cats & 1)
363 else if constexpr (bool(__cats & __cmp_cat_id<partial_ordering>))
364 return partial_ordering::equivalent;
367 else if constexpr (bool(__cats & __cmp_cat_id<weak_ordering>))
368 return weak_ordering::equivalent;
371 return strong_ordering::equivalent;
376 template<
typename... _Ts>
377 struct common_comparison_category
379 using type =
decltype(__detail::__common_cmp_cat<_Ts...>());
384 template<
typename _Tp>
385 struct common_comparison_category<_Tp>
386 {
using type = void; };
389 struct common_comparison_category<partial_ordering>
390 {
using type = partial_ordering; };
393 struct common_comparison_category<weak_ordering>
394 {
using type = weak_ordering; };
397 struct common_comparison_category<strong_ordering>
398 {
using type = strong_ordering; };
401 struct common_comparison_category<>
402 {
using type = strong_ordering; };
404 template<
typename... _Ts>
405 using common_comparison_category_t
406 =
typename common_comparison_category<_Ts...>::type;
408#if __cpp_lib_concepts
411 template<
typename _Tp,
typename _Cat>
412 concept __compares_as
413 = same_as<common_comparison_category_t<_Tp, _Cat>, _Cat>;
417 template<
typename _Tp,
typename _Cat = partial_ordering>
418 concept three_way_comparable
419 = __detail::__weakly_eq_cmp_with<_Tp, _Tp>
420 && __detail::__partially_ordered_with<_Tp, _Tp>
421 &&
requires(
const remove_reference_t<_Tp>& __a,
422 const remove_reference_t<_Tp>& __b)
424 { __a <=> __b } -> __detail::__compares_as<_Cat>;
427 template<
typename _Tp,
typename _Up,
typename _Cat = partial_ordering>
428 concept three_way_comparable_with
429 = three_way_comparable<_Tp, _Cat>
430 && three_way_comparable<_Up, _Cat>
431 && common_reference_with<const remove_reference_t<_Tp>&,
432 const remove_reference_t<_Up>&>
433 && three_way_comparable<
434 common_reference_t<const remove_reference_t<_Tp>&,
435 const remove_reference_t<_Up>&>, _Cat>
436 && __detail::__weakly_eq_cmp_with<_Tp, _Up>
437 && __detail::__partially_ordered_with<_Tp, _Up>
438 &&
requires(
const remove_reference_t<_Tp>& __t,
439 const remove_reference_t<_Up>& __u)
441 { __t <=> __u } -> __detail::__compares_as<_Cat>;
442 { __u <=> __t } -> __detail::__compares_as<_Cat>;
447 template<
typename _Tp,
typename _Up>
448 using __cmp3way_res_t
449 =
decltype(std::declval<_Tp>() <=> std::declval<_Up>());
456 template<
typename _Tp,
typename _Up>
457 struct __cmp3way_res_impl
460 template<
typename _Tp,
typename _Up>
461 requires requires {
typename __cmp3way_res_t<__cref<_Tp>, __cref<_Up>>; }
462 struct __cmp3way_res_impl<_Tp, _Up>
464 using type = __cmp3way_res_t<__cref<_Tp>, __cref<_Up>>;
469 template<
typename _Tp,
typename _Up = _Tp>
470 struct compare_three_way_result
471 : __detail::__cmp3way_res_impl<_Tp, _Up>
475 template<
typename _Tp,
typename _Up = _Tp>
476 using compare_three_way_result_t
477 =
typename __detail::__cmp3way_res_impl<_Tp, _Up>::type;
482 template<
typename _Tp,
typename _Up>
483 concept __3way_builtin_ptr_cmp
484 = three_way_comparable_with<_Tp, _Up>
485 && convertible_to<_Tp, const volatile void*>
486 && convertible_to<_Up, const volatile void*>
487 && !
requires(_Tp&& __t, _Up&& __u)
488 { operator<=>(
static_cast<_Tp&&
>(__t),
static_cast<_Up&&
>(__u)); }
489 && !
requires(_Tp&& __t, _Up&& __u)
490 {
static_cast<_Tp&&
>(__t).operator<=>(
static_cast<_Up&&
>(__u)); };
494 struct compare_three_way
496 template<
typename _Tp,
typename _Up>
497 requires three_way_comparable_with<_Tp, _Up>
499 operator()(_Tp&& __t, _Up&& __u)
const
500 noexcept(
noexcept(std::declval<_Tp>() <=> std::declval<_Up>()))
502 if constexpr (__detail::__3way_builtin_ptr_cmp<_Tp, _Up>)
504 auto __pt =
static_cast<const volatile void*
>(__t);
505 auto __pu =
static_cast<const volatile void*
>(__u);
506 if (__builtin_is_constant_evaluated())
507 return __pt <=> __pu;
508 auto __it =
reinterpret_cast<__UINTPTR_TYPE__
>(__pt);
509 auto __iu =
reinterpret_cast<__UINTPTR_TYPE__
>(__pu);
510 return __it <=> __iu;
513 return static_cast<_Tp&&
>(__t) <=>
static_cast<_Up&&
>(__u);
516 using is_transparent = void;
521 template<
floating_po
int _Tp>
522 constexpr weak_ordering
523 __fp_weak_ordering(_Tp __e, _Tp __f)
527 auto __cat = [](_Tp __fp) ->
int {
528 const int __sign = __builtin_signbit(__fp) ? -1 : 1;
529 if (__builtin_isnormal(__fp))
530 return (__fp == 0 ? 1 : 3) * __sign;
531 if (__builtin_isnan(__fp))
533 if (
int __inf = __builtin_isinf_sign(__fp))
538 auto __po = __e <=> __f;
540 return weak_ordering::less;
541 else if (is_gt(__po))
542 return weak_ordering::greater;
543 else if (__po == partial_ordering::equivalent)
544 return weak_ordering::equivalent;
548 auto __isnan_sign = [](_Tp __fp) ->
int {
549 return __builtin_isnan(__fp)
550 ? __builtin_signbit(__fp) ? -1 : 1
553 auto __ord = __isnan_sign(__e) <=> __isnan_sign(__f);
555 return weak_ordering::equivalent;
556 else if (is_lt(__ord))
557 return weak_ordering::less;
559 return weak_ordering::greater;
563 template<
typename _Tp,
typename _Up>
564 concept __adl_strong =
requires(_Tp&& __t, _Up&& __u)
566 strong_ordering(strong_order(
static_cast<_Tp&&
>(__t),
567 static_cast<_Up&&
>(__u)));
570 template<
typename _Tp,
typename _Up>
571 concept __adl_weak =
requires(_Tp&& __t, _Up&& __u)
573 weak_ordering(weak_order(
static_cast<_Tp&&
>(__t),
574 static_cast<_Up&&
>(__u)));
577 template<
typename _Tp,
typename _Up>
578 concept __adl_partial =
requires(_Tp&& __t, _Up&& __u)
580 partial_ordering(partial_order(
static_cast<_Tp&&
>(__t),
581 static_cast<_Up&&
>(__u)));
584 template<
typename _Ord,
typename _Tp,
typename _Up>
585 concept __cmp3way =
requires(_Tp&& __t, _Up&& __u, compare_three_way __c)
587 _Ord(__c(
static_cast<_Tp&&
>(__t),
static_cast<_Up&&
>(__u)));
590 template<
typename _Tp,
typename _Up>
591 concept __strongly_ordered
592 = __adl_strong<_Tp, _Up>
594 || __cmp3way<strong_ordering, _Tp, _Up>;
598 template<
typename _Tp,
typename _Up>
599 static constexpr bool
602 if constexpr (floating_point<decay_t<_Tp>>)
604 else if constexpr (__adl_strong<_Tp, _Up>)
605 return noexcept(strong_ordering(strong_order(std::declval<_Tp>(),
606 std::declval<_Up>())));
607 else if constexpr (__cmp3way<strong_ordering, _Tp, _Up>)
608 return noexcept(compare_three_way()(std::declval<_Tp>(),
609 std::declval<_Up>()));
612 friend class _Weak_order;
613 friend class _Strong_fallback;
616 template<
typename _Tp,
typename _Up>
617 requires __strongly_ordered<_Tp, _Up>
618 constexpr strong_ordering
619 operator()(_Tp&& __e, _Up&& __f)
const
620 noexcept(_S_noexcept<_Tp, _Up>())
622 static_assert(same_as<decay_t<_Tp>, decay_t<_Up>>);
627 if constexpr (__adl_strong<_Tp, _Up>)
628 return strong_ordering(strong_order(
static_cast<_Tp&&
>(__e),
629 static_cast<_Up&&
>(__f)));
630 else if constexpr (__cmp3way<strong_ordering, _Tp, _Up>)
631 return compare_three_way()(
static_cast<_Tp&&
>(__e),
632 static_cast<_Up&&
>(__f));
636 template<
typename _Tp,
typename _Up>
637 concept __weakly_ordered
638 = floating_point<remove_reference_t<_Tp>>
639 || __adl_weak<_Tp, _Up>
640 || __cmp3way<weak_ordering, _Tp, _Up>
641 || __strongly_ordered<_Tp, _Up>;
645 template<
typename _Tp,
typename _Up>
646 static constexpr bool
649 if constexpr (floating_point<decay_t<_Tp>>)
651 else if constexpr (__adl_weak<_Tp, _Up>)
652 return noexcept(weak_ordering(weak_order(std::declval<_Tp>(),
653 std::declval<_Up>())));
654 else if constexpr (__cmp3way<weak_ordering, _Tp, _Up>)
655 return noexcept(compare_three_way()(std::declval<_Tp>(),
656 std::declval<_Up>()));
657 else if constexpr (__strongly_ordered<_Tp, _Up>)
658 return _Strong_order::_S_noexcept<_Tp, _Up>();
661 friend class _Partial_order;
662 friend class _Weak_fallback;
665 template<
typename _Tp,
typename _Up>
666 requires __weakly_ordered<_Tp, _Up>
667 constexpr weak_ordering
668 operator()(_Tp&& __e, _Up&& __f)
const
669 noexcept(_S_noexcept<_Tp, _Up>())
671 static_assert(same_as<decay_t<_Tp>, decay_t<_Up>>);
673 if constexpr (floating_point<decay_t<_Tp>>)
674 return __cmp_cust::__fp_weak_ordering(__e, __f);
675 else if constexpr (__adl_weak<_Tp, _Up>)
676 return weak_ordering(weak_order(
static_cast<_Tp&&
>(__e),
677 static_cast<_Up&&
>(__f)));
678 else if constexpr (__cmp3way<weak_ordering, _Tp, _Up>)
679 return compare_three_way()(
static_cast<_Tp&&
>(__e),
680 static_cast<_Up&&
>(__f));
681 else if constexpr (__strongly_ordered<_Tp, _Up>)
682 return _Strong_order{}(
static_cast<_Tp&&
>(__e),
683 static_cast<_Up&&
>(__f));
687 template<
typename _Tp,
typename _Up>
688 concept __partially_ordered
689 = __adl_partial<_Tp, _Up>
690 || __cmp3way<partial_ordering, _Tp, _Up>
691 || __weakly_ordered<_Tp, _Up>;
695 template<
typename _Tp,
typename _Up>
696 static constexpr bool
699 if constexpr (__adl_partial<_Tp, _Up>)
700 return noexcept(partial_ordering(partial_order(std::declval<_Tp>(),
701 std::declval<_Up>())));
702 else if constexpr (__cmp3way<partial_ordering, _Tp, _Up>)
703 return noexcept(compare_three_way()(std::declval<_Tp>(),
704 std::declval<_Up>()));
705 else if constexpr (__weakly_ordered<_Tp, _Up>)
706 return _Weak_order::_S_noexcept<_Tp, _Up>();
709 friend class _Partial_fallback;
712 template<
typename _Tp,
typename _Up>
713 requires __partially_ordered<_Tp, _Up>
714 constexpr partial_ordering
715 operator()(_Tp&& __e, _Up&& __f)
const
716 noexcept(_S_noexcept<_Tp, _Up>())
718 static_assert(same_as<decay_t<_Tp>, decay_t<_Up>>);
720 if constexpr (__adl_partial<_Tp, _Up>)
721 return partial_ordering(partial_order(
static_cast<_Tp&&
>(__e),
722 static_cast<_Up&&
>(__f)));
723 else if constexpr (__cmp3way<partial_ordering, _Tp, _Up>)
724 return compare_three_way()(
static_cast<_Tp&&
>(__e),
725 static_cast<_Up&&
>(__f));
726 else if constexpr (__weakly_ordered<_Tp, _Up>)
727 return _Weak_order{}(
static_cast<_Tp&&
>(__e),
728 static_cast<_Up&&
>(__f));
732 template<
typename _Tp,
typename _Up>
733 concept __op_eq_lt =
requires(_Tp&& __t, _Up&& __u)
735 {
static_cast<_Tp&&
>(__t) ==
static_cast<_Up&&
>(__u) }
736 -> convertible_to<bool>;
737 {
static_cast<_Tp&&
>(__t) <
static_cast<_Up&&
>(__u) }
738 -> convertible_to<bool>;
741 class _Strong_fallback
743 template<
typename _Tp,
typename _Up>
744 static constexpr bool
747 if constexpr (__strongly_ordered<_Tp, _Up>)
748 return _Strong_order::_S_noexcept<_Tp, _Up>();
750 return noexcept(bool(std::declval<_Tp>() == std::declval<_Up>()))
751 &&
noexcept(
bool(std::declval<_Tp>() < std::declval<_Up>()));
755 template<
typename _Tp,
typename _Up>
756 requires __strongly_ordered<_Tp, _Up> || __op_eq_lt<_Tp, _Up>
757 constexpr decltype(
auto)
758 operator()(_Tp&& __e, _Up&& __f)
const
759 noexcept(_S_noexcept<_Tp, _Up>())
761 static_assert(same_as<decay_t<_Tp>, decay_t<_Up>>);
763 if constexpr (__strongly_ordered<_Tp, _Up>)
764 return _Strong_order{}(
static_cast<_Tp&&
>(__e),
765 static_cast<_Up&&
>(__f));
766 else if constexpr (__op_eq_lt<_Tp, _Up>)
767 return static_cast<_Tp&&
>(__e) ==
static_cast<_Up&&
>(__f)
768 ? strong_ordering::equal
769 :
static_cast<_Tp&&
>(__e) <
static_cast<_Up&&
>(__f)
770 ? strong_ordering::less
771 : strong_ordering::greater;
777 template<
typename _Tp,
typename _Up>
778 static constexpr bool
781 if constexpr (__weakly_ordered<_Tp, _Up>)
782 return _Weak_order::_S_noexcept<_Tp, _Up>();
784 return noexcept(bool(std::declval<_Tp>() == std::declval<_Up>()))
785 &&
noexcept(
bool(std::declval<_Tp>() < std::declval<_Up>()));
789 template<
typename _Tp,
typename _Up>
790 requires __weakly_ordered<_Tp, _Up> || __op_eq_lt<_Tp, _Up>
791 constexpr decltype(
auto)
792 operator()(_Tp&& __e, _Up&& __f)
const
793 noexcept(_S_noexcept<_Tp, _Up>())
795 static_assert(same_as<decay_t<_Tp>, decay_t<_Up>>);
797 if constexpr (__weakly_ordered<_Tp, _Up>)
798 return _Weak_order{}(
static_cast<_Tp&&
>(__e),
799 static_cast<_Up&&
>(__f));
800 else if constexpr (__op_eq_lt<_Tp, _Up>)
801 return static_cast<_Tp&&
>(__e) ==
static_cast<_Up&&
>(__f)
802 ? weak_ordering::equivalent
803 :
static_cast<_Tp&&
>(__e) <
static_cast<_Up&&
>(__f)
804 ? weak_ordering::less
805 : weak_ordering::greater;
809 class _Partial_fallback
811 template<
typename _Tp,
typename _Up>
812 static constexpr bool
815 if constexpr (__partially_ordered<_Tp, _Up>)
816 return _Partial_order::_S_noexcept<_Tp, _Up>();
818 return noexcept(bool(std::declval<_Tp>() == std::declval<_Up>()))
819 &&
noexcept(
bool(std::declval<_Tp>() < std::declval<_Up>()));
823 template<
typename _Tp,
typename _Up>
824 requires __partially_ordered<_Tp, _Up> || __op_eq_lt<_Tp, _Up>
825 constexpr decltype(
auto)
826 operator()(_Tp&& __e, _Up&& __f)
const
827 noexcept(_S_noexcept<_Tp, _Up>())
829 static_assert(same_as<decay_t<_Tp>, decay_t<_Up>>);
831 if constexpr (__partially_ordered<_Tp, _Up>)
832 return _Partial_order{}(
static_cast<_Tp&&
>(__e),
833 static_cast<_Up&&
>(__f));
834 else if constexpr (__op_eq_lt<_Tp, _Up>)
835 return static_cast<_Tp&&
>(__e) ==
static_cast<_Up&&
>(__f)
836 ? partial_ordering::equivalent
837 :
static_cast<_Tp&&
>(__e) <
static_cast<_Up&&
>(__f)
838 ? partial_ordering::less
839 :
static_cast<_Up&&
>(__f) <
static_cast<_Tp&&
>(__e)
840 ? partial_ordering::greater
841 : partial_ordering::unordered;
847 inline namespace __cmp_alg
849 inline constexpr __cmp_cust::_Strong_order strong_order{};
851 inline constexpr __cmp_cust::_Weak_order weak_order{};
853 inline constexpr __cmp_cust::_Partial_order partial_order{};
855 inline constexpr __cmp_cust::_Strong_fallback
856 compare_strong_order_fallback{};
858 inline constexpr __cmp_cust::_Weak_fallback
859 compare_weak_order_fallback{};
861 inline constexpr __cmp_cust::_Partial_fallback
862 compare_partial_order_fallback{};
868 inline constexpr struct _Synth3way
870 template<
typename _Tp,
typename _Up>
872 operator()(
const _Tp& __t,
const _Up& __u)
const
875 { __t < __u } -> __boolean_testable;
876 { __u < __t } -> __boolean_testable;
879 if constexpr (three_way_comparable_with<_Tp, _Up>)
884 return weak_ordering::less;
886 return weak_ordering::greater;
888 return weak_ordering::equivalent;
893 template<
typename _Tp,
typename _Up = _Tp>
895 =
decltype(__detail::__synth3way(std::declval<_Tp&>(),
896 std::declval<_Up&>()));
901#pragma GCC visibility pop
ISO C++ entities toplevel namespace is std.