Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-05-03 08:13:16

0001 //===----------------------------------------------------------------------===//
0002 //
0003 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
0004 // See https://llvm.org/LICENSE.txt for license information.
0005 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
0006 //
0007 //===----------------------------------------------------------------------===//
0008 
0009 #ifndef _LIBCPP___COMPARE_ORDERING_H
0010 #define _LIBCPP___COMPARE_ORDERING_H
0011 
0012 #include <__config>
0013 #include <__type_traits/enable_if.h>
0014 #include <__type_traits/is_same.h>
0015 
0016 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
0017 #  pragma GCC system_header
0018 #endif
0019 
0020 _LIBCPP_BEGIN_NAMESPACE_STD
0021 
0022 #if _LIBCPP_STD_VER >= 20
0023 
0024 // exposition only
0025 enum class _OrdResult : signed char { __less = -1, __equiv = 0, __greater = 1 };
0026 
0027 enum class _PartialOrdResult : signed char {
0028   __less      = static_cast<signed char>(_OrdResult::__less),
0029   __equiv     = static_cast<signed char>(_OrdResult::__equiv),
0030   __greater   = static_cast<signed char>(_OrdResult::__greater),
0031   __unordered = -127,
0032 };
0033 
0034 class partial_ordering;
0035 class weak_ordering;
0036 class strong_ordering;
0037 
0038 struct _CmpUnspecifiedParam {
0039   // If anything other than a literal 0 is provided, the behavior is undefined by the Standard.
0040   //
0041   // The alternative to the `__enable_if__` attribute would be to use the fact that a pointer
0042   // can be constructed from literal 0, but this conflicts with `-Wzero-as-null-pointer-constant`.
0043   template <class _Tp, class = __enable_if_t<is_same_v<_Tp, int> > >
0044   _LIBCPP_HIDE_FROM_ABI consteval _CmpUnspecifiedParam(_Tp __zero) noexcept
0045 #  if __has_attribute(__enable_if__)
0046       __attribute__((__enable_if__(
0047           __zero == 0, "Only literal 0 is allowed as the operand of a comparison with one of the ordering types")))
0048 #  endif
0049   {
0050     (void)__zero;
0051   }
0052 };
0053 
0054 class partial_ordering {
0055   _LIBCPP_HIDE_FROM_ABI explicit constexpr partial_ordering(_PartialOrdResult __v) noexcept : __value_(__v) {}
0056 
0057 public:
0058   // valid values
0059   static const partial_ordering less;
0060   static const partial_ordering equivalent;
0061   static const partial_ordering greater;
0062   static const partial_ordering unordered;
0063 
0064   // comparisons
0065   _LIBCPP_HIDE_FROM_ABI friend constexpr bool operator==(partial_ordering, partial_ordering) noexcept = default;
0066 
0067   _LIBCPP_HIDE_FROM_ABI friend constexpr bool operator==(partial_ordering __v, _CmpUnspecifiedParam) noexcept {
0068     return __v.__value_ == _PartialOrdResult::__equiv;
0069   }
0070 
0071   _LIBCPP_HIDE_FROM_ABI friend constexpr bool operator<(partial_ordering __v, _CmpUnspecifiedParam) noexcept {
0072     return __v.__value_ == _PartialOrdResult::__less;
0073   }
0074 
0075   _LIBCPP_HIDE_FROM_ABI friend constexpr bool operator<=(partial_ordering __v, _CmpUnspecifiedParam) noexcept {
0076     return __v.__value_ == _PartialOrdResult::__equiv || __v.__value_ == _PartialOrdResult::__less;
0077   }
0078 
0079   _LIBCPP_HIDE_FROM_ABI friend constexpr bool operator>(partial_ordering __v, _CmpUnspecifiedParam) noexcept {
0080     return __v.__value_ == _PartialOrdResult::__greater;
0081   }
0082 
0083   _LIBCPP_HIDE_FROM_ABI friend constexpr bool operator>=(partial_ordering __v, _CmpUnspecifiedParam) noexcept {
0084     return __v.__value_ == _PartialOrdResult::__equiv || __v.__value_ == _PartialOrdResult::__greater;
0085   }
0086 
0087   _LIBCPP_HIDE_FROM_ABI friend constexpr bool operator<(_CmpUnspecifiedParam, partial_ordering __v) noexcept {
0088     return __v.__value_ == _PartialOrdResult::__greater;
0089   }
0090 
0091   _LIBCPP_HIDE_FROM_ABI friend constexpr bool operator<=(_CmpUnspecifiedParam, partial_ordering __v) noexcept {
0092     return __v.__value_ == _PartialOrdResult::__equiv || __v.__value_ == _PartialOrdResult::__greater;
0093   }
0094 
0095   _LIBCPP_HIDE_FROM_ABI friend constexpr bool operator>(_CmpUnspecifiedParam, partial_ordering __v) noexcept {
0096     return __v.__value_ == _PartialOrdResult::__less;
0097   }
0098 
0099   _LIBCPP_HIDE_FROM_ABI friend constexpr bool operator>=(_CmpUnspecifiedParam, partial_ordering __v) noexcept {
0100     return __v.__value_ == _PartialOrdResult::__equiv || __v.__value_ == _PartialOrdResult::__less;
0101   }
0102 
0103   _LIBCPP_HIDE_FROM_ABI friend constexpr partial_ordering
0104   operator<=>(partial_ordering __v, _CmpUnspecifiedParam) noexcept {
0105     return __v;
0106   }
0107 
0108   _LIBCPP_HIDE_FROM_ABI friend constexpr partial_ordering
0109   operator<=>(_CmpUnspecifiedParam, partial_ordering __v) noexcept {
0110     return __v < 0 ? partial_ordering::greater : (__v > 0 ? partial_ordering::less : __v);
0111   }
0112 
0113 private:
0114   _PartialOrdResult __value_;
0115 };
0116 
0117 inline constexpr partial_ordering partial_ordering::less(_PartialOrdResult::__less);
0118 inline constexpr partial_ordering partial_ordering::equivalent(_PartialOrdResult::__equiv);
0119 inline constexpr partial_ordering partial_ordering::greater(_PartialOrdResult::__greater);
0120 inline constexpr partial_ordering partial_ordering::unordered(_PartialOrdResult::__unordered);
0121 
0122 class weak_ordering {
0123   using _ValueT _LIBCPP_NODEBUG = signed char;
0124 
0125   _LIBCPP_HIDE_FROM_ABI explicit constexpr weak_ordering(_OrdResult __v) noexcept : __value_(_ValueT(__v)) {}
0126 
0127 public:
0128   static const weak_ordering less;
0129   static const weak_ordering equivalent;
0130   static const weak_ordering greater;
0131 
0132   _LIBCPP_HIDE_FROM_ABI constexpr operator partial_ordering() const noexcept {
0133     return __value_ == 0 ? partial_ordering::equivalent
0134                          : (__value_ < 0 ? partial_ordering::less : partial_ordering::greater);
0135   }
0136 
0137   // comparisons
0138   _LIBCPP_HIDE_FROM_ABI friend constexpr bool operator==(weak_ordering, weak_ordering) noexcept = default;
0139 
0140   _LIBCPP_HIDE_FROM_ABI friend constexpr bool operator==(weak_ordering __v, _CmpUnspecifiedParam) noexcept {
0141     return __v.__value_ == 0;
0142   }
0143 
0144   _LIBCPP_HIDE_FROM_ABI friend constexpr bool operator<(weak_ordering __v, _CmpUnspecifiedParam) noexcept {
0145     return __v.__value_ < 0;
0146   }
0147 
0148   _LIBCPP_HIDE_FROM_ABI friend constexpr bool operator<=(weak_ordering __v, _CmpUnspecifiedParam) noexcept {
0149     return __v.__value_ <= 0;
0150   }
0151 
0152   _LIBCPP_HIDE_FROM_ABI friend constexpr bool operator>(weak_ordering __v, _CmpUnspecifiedParam) noexcept {
0153     return __v.__value_ > 0;
0154   }
0155 
0156   _LIBCPP_HIDE_FROM_ABI friend constexpr bool operator>=(weak_ordering __v, _CmpUnspecifiedParam) noexcept {
0157     return __v.__value_ >= 0;
0158   }
0159 
0160   _LIBCPP_HIDE_FROM_ABI friend constexpr bool operator<(_CmpUnspecifiedParam, weak_ordering __v) noexcept {
0161     return 0 < __v.__value_;
0162   }
0163 
0164   _LIBCPP_HIDE_FROM_ABI friend constexpr bool operator<=(_CmpUnspecifiedParam, weak_ordering __v) noexcept {
0165     return 0 <= __v.__value_;
0166   }
0167 
0168   _LIBCPP_HIDE_FROM_ABI friend constexpr bool operator>(_CmpUnspecifiedParam, weak_ordering __v) noexcept {
0169     return 0 > __v.__value_;
0170   }
0171 
0172   _LIBCPP_HIDE_FROM_ABI friend constexpr bool operator>=(_CmpUnspecifiedParam, weak_ordering __v) noexcept {
0173     return 0 >= __v.__value_;
0174   }
0175 
0176   _LIBCPP_HIDE_FROM_ABI friend constexpr weak_ordering operator<=>(weak_ordering __v, _CmpUnspecifiedParam) noexcept {
0177     return __v;
0178   }
0179 
0180   _LIBCPP_HIDE_FROM_ABI friend constexpr weak_ordering operator<=>(_CmpUnspecifiedParam, weak_ordering __v) noexcept {
0181     return __v < 0 ? weak_ordering::greater : (__v > 0 ? weak_ordering::less : __v);
0182   }
0183 
0184 private:
0185   _ValueT __value_;
0186 };
0187 
0188 inline constexpr weak_ordering weak_ordering::less(_OrdResult::__less);
0189 inline constexpr weak_ordering weak_ordering::equivalent(_OrdResult::__equiv);
0190 inline constexpr weak_ordering weak_ordering::greater(_OrdResult::__greater);
0191 
0192 class strong_ordering {
0193   using _ValueT _LIBCPP_NODEBUG = signed char;
0194 
0195   _LIBCPP_HIDE_FROM_ABI explicit constexpr strong_ordering(_OrdResult __v) noexcept : __value_(_ValueT(__v)) {}
0196 
0197 public:
0198   static const strong_ordering less;
0199   static const strong_ordering equal;
0200   static const strong_ordering equivalent;
0201   static const strong_ordering greater;
0202 
0203   // conversions
0204   _LIBCPP_HIDE_FROM_ABI constexpr operator partial_ordering() const noexcept {
0205     return __value_ == 0 ? partial_ordering::equivalent
0206                          : (__value_ < 0 ? partial_ordering::less : partial_ordering::greater);
0207   }
0208 
0209   _LIBCPP_HIDE_FROM_ABI constexpr operator weak_ordering() const noexcept {
0210     return __value_ == 0 ? weak_ordering::equivalent : (__value_ < 0 ? weak_ordering::less : weak_ordering::greater);
0211   }
0212 
0213   // comparisons
0214   _LIBCPP_HIDE_FROM_ABI friend constexpr bool operator==(strong_ordering, strong_ordering) noexcept = default;
0215 
0216   _LIBCPP_HIDE_FROM_ABI friend constexpr bool operator==(strong_ordering __v, _CmpUnspecifiedParam) noexcept {
0217     return __v.__value_ == 0;
0218   }
0219 
0220   _LIBCPP_HIDE_FROM_ABI friend constexpr bool operator<(strong_ordering __v, _CmpUnspecifiedParam) noexcept {
0221     return __v.__value_ < 0;
0222   }
0223 
0224   _LIBCPP_HIDE_FROM_ABI friend constexpr bool operator<=(strong_ordering __v, _CmpUnspecifiedParam) noexcept {
0225     return __v.__value_ <= 0;
0226   }
0227 
0228   _LIBCPP_HIDE_FROM_ABI friend constexpr bool operator>(strong_ordering __v, _CmpUnspecifiedParam) noexcept {
0229     return __v.__value_ > 0;
0230   }
0231 
0232   _LIBCPP_HIDE_FROM_ABI friend constexpr bool operator>=(strong_ordering __v, _CmpUnspecifiedParam) noexcept {
0233     return __v.__value_ >= 0;
0234   }
0235 
0236   _LIBCPP_HIDE_FROM_ABI friend constexpr bool operator<(_CmpUnspecifiedParam, strong_ordering __v) noexcept {
0237     return 0 < __v.__value_;
0238   }
0239 
0240   _LIBCPP_HIDE_FROM_ABI friend constexpr bool operator<=(_CmpUnspecifiedParam, strong_ordering __v) noexcept {
0241     return 0 <= __v.__value_;
0242   }
0243 
0244   _LIBCPP_HIDE_FROM_ABI friend constexpr bool operator>(_CmpUnspecifiedParam, strong_ordering __v) noexcept {
0245     return 0 > __v.__value_;
0246   }
0247 
0248   _LIBCPP_HIDE_FROM_ABI friend constexpr bool operator>=(_CmpUnspecifiedParam, strong_ordering __v) noexcept {
0249     return 0 >= __v.__value_;
0250   }
0251 
0252   _LIBCPP_HIDE_FROM_ABI friend constexpr strong_ordering
0253   operator<=>(strong_ordering __v, _CmpUnspecifiedParam) noexcept {
0254     return __v;
0255   }
0256 
0257   _LIBCPP_HIDE_FROM_ABI friend constexpr strong_ordering
0258   operator<=>(_CmpUnspecifiedParam, strong_ordering __v) noexcept {
0259     return __v < 0 ? strong_ordering::greater : (__v > 0 ? strong_ordering::less : __v);
0260   }
0261 
0262 private:
0263   _ValueT __value_;
0264 };
0265 
0266 inline constexpr strong_ordering strong_ordering::less(_OrdResult::__less);
0267 inline constexpr strong_ordering strong_ordering::equal(_OrdResult::__equiv);
0268 inline constexpr strong_ordering strong_ordering::equivalent(_OrdResult::__equiv);
0269 inline constexpr strong_ordering strong_ordering::greater(_OrdResult::__greater);
0270 
0271 /// [cmp.categories.pre]/1
0272 /// The types partial_ordering, weak_ordering, and strong_ordering are
0273 /// collectively termed the comparison category types.
0274 template <class _Tp>
0275 concept __comparison_category =
0276     is_same_v<_Tp, partial_ordering> || is_same_v<_Tp, weak_ordering> || is_same_v<_Tp, strong_ordering>;
0277 
0278 #endif // _LIBCPP_STD_VER >= 20
0279 
0280 _LIBCPP_END_NAMESPACE_STD
0281 
0282 #endif // _LIBCPP___COMPARE_ORDERING_H