1*4bdff4beSrobert //===----------------------------------------------------------------------===// 2*4bdff4beSrobert // 3*4bdff4beSrobert // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4*4bdff4beSrobert // See https://llvm.org/LICENSE.txt for license information. 5*4bdff4beSrobert // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6*4bdff4beSrobert // 7*4bdff4beSrobert //===----------------------------------------------------------------------===// 8*4bdff4beSrobert 9*4bdff4beSrobert #ifndef _LIBCPP___COMPARE_ORDERING_H 10*4bdff4beSrobert #define _LIBCPP___COMPARE_ORDERING_H 11*4bdff4beSrobert 12*4bdff4beSrobert #include <__config> 13*4bdff4beSrobert #include <__type_traits/enable_if.h> 14*4bdff4beSrobert #include <__type_traits/is_same.h> 15*4bdff4beSrobert 16*4bdff4beSrobert #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) 17*4bdff4beSrobert # pragma GCC system_header 18*4bdff4beSrobert #endif 19*4bdff4beSrobert 20*4bdff4beSrobert _LIBCPP_BEGIN_NAMESPACE_STD 21*4bdff4beSrobert 22*4bdff4beSrobert #if _LIBCPP_STD_VER > 17 23*4bdff4beSrobert 24*4bdff4beSrobert // exposition only 25*4bdff4beSrobert enum class _LIBCPP_ENUM_VIS _OrdResult : signed char { 26*4bdff4beSrobert __less = -1, 27*4bdff4beSrobert __equiv = 0, 28*4bdff4beSrobert __greater = 1 29*4bdff4beSrobert }; 30*4bdff4beSrobert 31*4bdff4beSrobert enum class _LIBCPP_ENUM_VIS _NCmpResult : signed char { 32*4bdff4beSrobert __unordered = -127 33*4bdff4beSrobert }; 34*4bdff4beSrobert 35*4bdff4beSrobert class partial_ordering; 36*4bdff4beSrobert class weak_ordering; 37*4bdff4beSrobert class strong_ordering; 38*4bdff4beSrobert 39*4bdff4beSrobert template<class _Tp, class... _Args> 40*4bdff4beSrobert inline constexpr bool __one_of_v = (is_same_v<_Tp, _Args> || ...); 41*4bdff4beSrobert 42*4bdff4beSrobert struct _CmpUnspecifiedParam { 43*4bdff4beSrobert _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEVAL _CmpUnspecifiedParam_CmpUnspecifiedParam44*4bdff4beSrobert _CmpUnspecifiedParam(int _CmpUnspecifiedParam::*) noexcept {} 45*4bdff4beSrobert 46*4bdff4beSrobert template<class _Tp, class = enable_if_t<!__one_of_v<_Tp, int, partial_ordering, weak_ordering, strong_ordering>>> 47*4bdff4beSrobert _CmpUnspecifiedParam(_Tp) = delete; 48*4bdff4beSrobert }; 49*4bdff4beSrobert 50*4bdff4beSrobert class partial_ordering { 51*4bdff4beSrobert using _ValueT = signed char; 52*4bdff4beSrobert 53*4bdff4beSrobert _LIBCPP_HIDE_FROM_ABI partial_ordering(_OrdResult __v)54*4bdff4beSrobert explicit constexpr partial_ordering(_OrdResult __v) noexcept 55*4bdff4beSrobert : __value_(_ValueT(__v)) {} 56*4bdff4beSrobert 57*4bdff4beSrobert _LIBCPP_HIDE_FROM_ABI partial_ordering(_NCmpResult __v)58*4bdff4beSrobert explicit constexpr partial_ordering(_NCmpResult __v) noexcept 59*4bdff4beSrobert : __value_(_ValueT(__v)) {} 60*4bdff4beSrobert 61*4bdff4beSrobert _LIBCPP_HIDE_FROM_ABI __is_ordered()62*4bdff4beSrobert constexpr bool __is_ordered() const noexcept { 63*4bdff4beSrobert return __value_ != _ValueT(_NCmpResult::__unordered); 64*4bdff4beSrobert } 65*4bdff4beSrobert public: 66*4bdff4beSrobert // valid values 67*4bdff4beSrobert static const partial_ordering less; 68*4bdff4beSrobert static const partial_ordering equivalent; 69*4bdff4beSrobert static const partial_ordering greater; 70*4bdff4beSrobert static const partial_ordering unordered; 71*4bdff4beSrobert 72*4bdff4beSrobert // comparisons 73*4bdff4beSrobert _LIBCPP_HIDE_FROM_ABI 74*4bdff4beSrobert friend constexpr bool operator==(partial_ordering, partial_ordering) noexcept = default; 75*4bdff4beSrobert 76*4bdff4beSrobert _LIBCPP_HIDE_FROM_ABI 77*4bdff4beSrobert friend constexpr bool operator==(partial_ordering __v, _CmpUnspecifiedParam) noexcept { 78*4bdff4beSrobert return __v.__is_ordered() && __v.__value_ == 0; 79*4bdff4beSrobert } 80*4bdff4beSrobert 81*4bdff4beSrobert _LIBCPP_HIDE_FROM_ABI 82*4bdff4beSrobert friend constexpr bool operator< (partial_ordering __v, _CmpUnspecifiedParam) noexcept { 83*4bdff4beSrobert return __v.__is_ordered() && __v.__value_ < 0; 84*4bdff4beSrobert } 85*4bdff4beSrobert 86*4bdff4beSrobert _LIBCPP_HIDE_FROM_ABI 87*4bdff4beSrobert friend constexpr bool operator<=(partial_ordering __v, _CmpUnspecifiedParam) noexcept { 88*4bdff4beSrobert return __v.__is_ordered() && __v.__value_ <= 0; 89*4bdff4beSrobert } 90*4bdff4beSrobert 91*4bdff4beSrobert _LIBCPP_HIDE_FROM_ABI 92*4bdff4beSrobert friend constexpr bool operator> (partial_ordering __v, _CmpUnspecifiedParam) noexcept { 93*4bdff4beSrobert return __v.__is_ordered() && __v.__value_ > 0; 94*4bdff4beSrobert } 95*4bdff4beSrobert 96*4bdff4beSrobert _LIBCPP_HIDE_FROM_ABI 97*4bdff4beSrobert friend constexpr bool operator>=(partial_ordering __v, _CmpUnspecifiedParam) noexcept { 98*4bdff4beSrobert return __v.__is_ordered() && __v.__value_ >= 0; 99*4bdff4beSrobert } 100*4bdff4beSrobert 101*4bdff4beSrobert _LIBCPP_HIDE_FROM_ABI 102*4bdff4beSrobert friend constexpr bool operator< (_CmpUnspecifiedParam, partial_ordering __v) noexcept { 103*4bdff4beSrobert return __v.__is_ordered() && 0 < __v.__value_; 104*4bdff4beSrobert } 105*4bdff4beSrobert 106*4bdff4beSrobert _LIBCPP_HIDE_FROM_ABI 107*4bdff4beSrobert friend constexpr bool operator<=(_CmpUnspecifiedParam, partial_ordering __v) noexcept { 108*4bdff4beSrobert return __v.__is_ordered() && 0 <= __v.__value_; 109*4bdff4beSrobert } 110*4bdff4beSrobert 111*4bdff4beSrobert _LIBCPP_HIDE_FROM_ABI 112*4bdff4beSrobert friend constexpr bool operator> (_CmpUnspecifiedParam, partial_ordering __v) noexcept { 113*4bdff4beSrobert return __v.__is_ordered() && 0 > __v.__value_; 114*4bdff4beSrobert } 115*4bdff4beSrobert 116*4bdff4beSrobert _LIBCPP_HIDE_FROM_ABI 117*4bdff4beSrobert friend constexpr bool operator>=(_CmpUnspecifiedParam, partial_ordering __v) noexcept { 118*4bdff4beSrobert return __v.__is_ordered() && 0 >= __v.__value_; 119*4bdff4beSrobert } 120*4bdff4beSrobert 121*4bdff4beSrobert _LIBCPP_HIDE_FROM_ABI 122*4bdff4beSrobert friend constexpr partial_ordering operator<=>(partial_ordering __v, _CmpUnspecifiedParam) noexcept { 123*4bdff4beSrobert return __v; 124*4bdff4beSrobert } 125*4bdff4beSrobert 126*4bdff4beSrobert _LIBCPP_HIDE_FROM_ABI 127*4bdff4beSrobert friend constexpr partial_ordering operator<=>(_CmpUnspecifiedParam, partial_ordering __v) noexcept { 128*4bdff4beSrobert return __v < 0 ? partial_ordering::greater : (__v > 0 ? partial_ordering::less : __v); 129*4bdff4beSrobert } 130*4bdff4beSrobert private: 131*4bdff4beSrobert _ValueT __value_; 132*4bdff4beSrobert }; 133*4bdff4beSrobert 134*4bdff4beSrobert inline constexpr partial_ordering partial_ordering::less(_OrdResult::__less); 135*4bdff4beSrobert inline constexpr partial_ordering partial_ordering::equivalent(_OrdResult::__equiv); 136*4bdff4beSrobert inline constexpr partial_ordering partial_ordering::greater(_OrdResult::__greater); 137*4bdff4beSrobert inline constexpr partial_ordering partial_ordering::unordered(_NCmpResult ::__unordered); 138*4bdff4beSrobert 139*4bdff4beSrobert class weak_ordering { 140*4bdff4beSrobert using _ValueT = signed char; 141*4bdff4beSrobert 142*4bdff4beSrobert _LIBCPP_HIDE_FROM_ABI weak_ordering(_OrdResult __v)143*4bdff4beSrobert explicit constexpr weak_ordering(_OrdResult __v) noexcept : __value_(_ValueT(__v)) {} 144*4bdff4beSrobert 145*4bdff4beSrobert public: 146*4bdff4beSrobert static const weak_ordering less; 147*4bdff4beSrobert static const weak_ordering equivalent; 148*4bdff4beSrobert static const weak_ordering greater; 149*4bdff4beSrobert 150*4bdff4beSrobert _LIBCPP_HIDE_FROM_ABI partial_ordering()151*4bdff4beSrobert constexpr operator partial_ordering() const noexcept { 152*4bdff4beSrobert return __value_ == 0 ? partial_ordering::equivalent 153*4bdff4beSrobert : (__value_ < 0 ? partial_ordering::less : partial_ordering::greater); 154*4bdff4beSrobert } 155*4bdff4beSrobert 156*4bdff4beSrobert // comparisons 157*4bdff4beSrobert _LIBCPP_HIDE_FROM_ABI 158*4bdff4beSrobert friend constexpr bool operator==(weak_ordering, weak_ordering) noexcept = default; 159*4bdff4beSrobert 160*4bdff4beSrobert _LIBCPP_HIDE_FROM_ABI 161*4bdff4beSrobert friend constexpr bool operator==(weak_ordering __v, _CmpUnspecifiedParam) noexcept { 162*4bdff4beSrobert return __v.__value_ == 0; 163*4bdff4beSrobert } 164*4bdff4beSrobert 165*4bdff4beSrobert _LIBCPP_HIDE_FROM_ABI 166*4bdff4beSrobert friend constexpr bool operator< (weak_ordering __v, _CmpUnspecifiedParam) noexcept { 167*4bdff4beSrobert return __v.__value_ < 0; 168*4bdff4beSrobert } 169*4bdff4beSrobert 170*4bdff4beSrobert _LIBCPP_HIDE_FROM_ABI 171*4bdff4beSrobert friend constexpr bool operator<=(weak_ordering __v, _CmpUnspecifiedParam) noexcept { 172*4bdff4beSrobert return __v.__value_ <= 0; 173*4bdff4beSrobert } 174*4bdff4beSrobert 175*4bdff4beSrobert _LIBCPP_HIDE_FROM_ABI 176*4bdff4beSrobert friend constexpr bool operator> (weak_ordering __v, _CmpUnspecifiedParam) noexcept { 177*4bdff4beSrobert return __v.__value_ > 0; 178*4bdff4beSrobert } 179*4bdff4beSrobert 180*4bdff4beSrobert _LIBCPP_HIDE_FROM_ABI 181*4bdff4beSrobert friend constexpr bool operator>=(weak_ordering __v, _CmpUnspecifiedParam) noexcept { 182*4bdff4beSrobert return __v.__value_ >= 0; 183*4bdff4beSrobert } 184*4bdff4beSrobert 185*4bdff4beSrobert _LIBCPP_HIDE_FROM_ABI 186*4bdff4beSrobert friend constexpr bool operator< (_CmpUnspecifiedParam, weak_ordering __v) noexcept { 187*4bdff4beSrobert return 0 < __v.__value_; 188*4bdff4beSrobert } 189*4bdff4beSrobert 190*4bdff4beSrobert _LIBCPP_HIDE_FROM_ABI 191*4bdff4beSrobert friend constexpr bool operator<=(_CmpUnspecifiedParam, weak_ordering __v) noexcept { 192*4bdff4beSrobert return 0 <= __v.__value_; 193*4bdff4beSrobert } 194*4bdff4beSrobert 195*4bdff4beSrobert _LIBCPP_HIDE_FROM_ABI 196*4bdff4beSrobert friend constexpr bool operator> (_CmpUnspecifiedParam, weak_ordering __v) noexcept { 197*4bdff4beSrobert return 0 > __v.__value_; 198*4bdff4beSrobert } 199*4bdff4beSrobert 200*4bdff4beSrobert _LIBCPP_HIDE_FROM_ABI 201*4bdff4beSrobert friend constexpr bool operator>=(_CmpUnspecifiedParam, weak_ordering __v) noexcept { 202*4bdff4beSrobert return 0 >= __v.__value_; 203*4bdff4beSrobert } 204*4bdff4beSrobert 205*4bdff4beSrobert _LIBCPP_HIDE_FROM_ABI 206*4bdff4beSrobert friend constexpr weak_ordering operator<=>(weak_ordering __v, _CmpUnspecifiedParam) noexcept { 207*4bdff4beSrobert return __v; 208*4bdff4beSrobert } 209*4bdff4beSrobert 210*4bdff4beSrobert _LIBCPP_HIDE_FROM_ABI 211*4bdff4beSrobert friend constexpr weak_ordering operator<=>(_CmpUnspecifiedParam, weak_ordering __v) noexcept { 212*4bdff4beSrobert return __v < 0 ? weak_ordering::greater : (__v > 0 ? weak_ordering::less : __v); 213*4bdff4beSrobert } 214*4bdff4beSrobert 215*4bdff4beSrobert private: 216*4bdff4beSrobert _ValueT __value_; 217*4bdff4beSrobert }; 218*4bdff4beSrobert 219*4bdff4beSrobert inline constexpr weak_ordering weak_ordering::less(_OrdResult::__less); 220*4bdff4beSrobert inline constexpr weak_ordering weak_ordering::equivalent(_OrdResult::__equiv); 221*4bdff4beSrobert inline constexpr weak_ordering weak_ordering::greater(_OrdResult::__greater); 222*4bdff4beSrobert 223*4bdff4beSrobert class strong_ordering { 224*4bdff4beSrobert using _ValueT = signed char; 225*4bdff4beSrobert 226*4bdff4beSrobert _LIBCPP_HIDE_FROM_ABI strong_ordering(_OrdResult __v)227*4bdff4beSrobert explicit constexpr strong_ordering(_OrdResult __v) noexcept : __value_(_ValueT(__v)) {} 228*4bdff4beSrobert 229*4bdff4beSrobert public: 230*4bdff4beSrobert static const strong_ordering less; 231*4bdff4beSrobert static const strong_ordering equal; 232*4bdff4beSrobert static const strong_ordering equivalent; 233*4bdff4beSrobert static const strong_ordering greater; 234*4bdff4beSrobert 235*4bdff4beSrobert // conversions 236*4bdff4beSrobert _LIBCPP_HIDE_FROM_ABI partial_ordering()237*4bdff4beSrobert constexpr operator partial_ordering() const noexcept { 238*4bdff4beSrobert return __value_ == 0 ? partial_ordering::equivalent 239*4bdff4beSrobert : (__value_ < 0 ? partial_ordering::less : partial_ordering::greater); 240*4bdff4beSrobert } 241*4bdff4beSrobert 242*4bdff4beSrobert _LIBCPP_HIDE_FROM_ABI weak_ordering()243*4bdff4beSrobert constexpr operator weak_ordering() const noexcept { 244*4bdff4beSrobert return __value_ == 0 ? weak_ordering::equivalent 245*4bdff4beSrobert : (__value_ < 0 ? weak_ordering::less : weak_ordering::greater); 246*4bdff4beSrobert } 247*4bdff4beSrobert 248*4bdff4beSrobert // comparisons 249*4bdff4beSrobert _LIBCPP_HIDE_FROM_ABI 250*4bdff4beSrobert friend constexpr bool operator==(strong_ordering, strong_ordering) noexcept = default; 251*4bdff4beSrobert 252*4bdff4beSrobert _LIBCPP_HIDE_FROM_ABI 253*4bdff4beSrobert friend constexpr bool operator==(strong_ordering __v, _CmpUnspecifiedParam) noexcept { 254*4bdff4beSrobert return __v.__value_ == 0; 255*4bdff4beSrobert } 256*4bdff4beSrobert 257*4bdff4beSrobert _LIBCPP_HIDE_FROM_ABI 258*4bdff4beSrobert friend constexpr bool operator< (strong_ordering __v, _CmpUnspecifiedParam) noexcept { 259*4bdff4beSrobert return __v.__value_ < 0; 260*4bdff4beSrobert } 261*4bdff4beSrobert 262*4bdff4beSrobert _LIBCPP_HIDE_FROM_ABI 263*4bdff4beSrobert friend constexpr bool operator<=(strong_ordering __v, _CmpUnspecifiedParam) noexcept { 264*4bdff4beSrobert return __v.__value_ <= 0; 265*4bdff4beSrobert } 266*4bdff4beSrobert 267*4bdff4beSrobert _LIBCPP_HIDE_FROM_ABI 268*4bdff4beSrobert friend constexpr bool operator> (strong_ordering __v, _CmpUnspecifiedParam) noexcept { 269*4bdff4beSrobert return __v.__value_ > 0; 270*4bdff4beSrobert } 271*4bdff4beSrobert 272*4bdff4beSrobert _LIBCPP_HIDE_FROM_ABI 273*4bdff4beSrobert friend constexpr bool operator>=(strong_ordering __v, _CmpUnspecifiedParam) noexcept { 274*4bdff4beSrobert return __v.__value_ >= 0; 275*4bdff4beSrobert } 276*4bdff4beSrobert 277*4bdff4beSrobert _LIBCPP_HIDE_FROM_ABI 278*4bdff4beSrobert friend constexpr bool operator< (_CmpUnspecifiedParam, strong_ordering __v) noexcept { 279*4bdff4beSrobert return 0 < __v.__value_; 280*4bdff4beSrobert } 281*4bdff4beSrobert 282*4bdff4beSrobert _LIBCPP_HIDE_FROM_ABI 283*4bdff4beSrobert friend constexpr bool operator<=(_CmpUnspecifiedParam, strong_ordering __v) noexcept { 284*4bdff4beSrobert return 0 <= __v.__value_; 285*4bdff4beSrobert } 286*4bdff4beSrobert 287*4bdff4beSrobert _LIBCPP_HIDE_FROM_ABI 288*4bdff4beSrobert friend constexpr bool operator> (_CmpUnspecifiedParam, strong_ordering __v) noexcept { 289*4bdff4beSrobert return 0 > __v.__value_; 290*4bdff4beSrobert } 291*4bdff4beSrobert 292*4bdff4beSrobert _LIBCPP_HIDE_FROM_ABI 293*4bdff4beSrobert friend constexpr bool operator>=(_CmpUnspecifiedParam, strong_ordering __v) noexcept { 294*4bdff4beSrobert return 0 >= __v.__value_; 295*4bdff4beSrobert } 296*4bdff4beSrobert 297*4bdff4beSrobert _LIBCPP_HIDE_FROM_ABI 298*4bdff4beSrobert friend constexpr strong_ordering operator<=>(strong_ordering __v, _CmpUnspecifiedParam) noexcept { 299*4bdff4beSrobert return __v; 300*4bdff4beSrobert } 301*4bdff4beSrobert 302*4bdff4beSrobert _LIBCPP_HIDE_FROM_ABI 303*4bdff4beSrobert friend constexpr strong_ordering operator<=>(_CmpUnspecifiedParam, strong_ordering __v) noexcept { 304*4bdff4beSrobert return __v < 0 ? strong_ordering::greater : (__v > 0 ? strong_ordering::less : __v); 305*4bdff4beSrobert } 306*4bdff4beSrobert 307*4bdff4beSrobert private: 308*4bdff4beSrobert _ValueT __value_; 309*4bdff4beSrobert }; 310*4bdff4beSrobert 311*4bdff4beSrobert inline constexpr strong_ordering strong_ordering::less(_OrdResult::__less); 312*4bdff4beSrobert inline constexpr strong_ordering strong_ordering::equal(_OrdResult::__equiv); 313*4bdff4beSrobert inline constexpr strong_ordering strong_ordering::equivalent(_OrdResult::__equiv); 314*4bdff4beSrobert inline constexpr strong_ordering strong_ordering::greater(_OrdResult::__greater); 315*4bdff4beSrobert 316*4bdff4beSrobert /// [cmp.categories.pre]/1 317*4bdff4beSrobert /// The types partial_ordering, weak_ordering, and strong_ordering are 318*4bdff4beSrobert /// collectively termed the comparison category types. 319*4bdff4beSrobert template <class _Tp> 320*4bdff4beSrobert concept __comparison_category = __one_of_v<_Tp, partial_ordering, weak_ordering, strong_ordering>; 321*4bdff4beSrobert 322*4bdff4beSrobert #endif // _LIBCPP_STD_VER > 17 323*4bdff4beSrobert 324*4bdff4beSrobert _LIBCPP_END_NAMESPACE_STD 325*4bdff4beSrobert 326*4bdff4beSrobert #endif // _LIBCPP___COMPARE_ORDERING_H 327