1*4ba319b5SDimitry Andric// -*- C++ -*- 2*4ba319b5SDimitry Andric//===-------------------------- compare -----------------------------------===// 3*4ba319b5SDimitry Andric// 4*4ba319b5SDimitry Andric// The LLVM Compiler Infrastructure 5*4ba319b5SDimitry Andric// 6*4ba319b5SDimitry Andric// This file is dual licensed under the MIT and the University of Illinois Open 7*4ba319b5SDimitry Andric// Source Licenses. See LICENSE.TXT for details. 8*4ba319b5SDimitry Andric// 9*4ba319b5SDimitry Andric//===----------------------------------------------------------------------===// 10*4ba319b5SDimitry Andric 11*4ba319b5SDimitry Andric#ifndef _LIBCPP_COMPARE 12*4ba319b5SDimitry Andric#define _LIBCPP_COMPARE 13*4ba319b5SDimitry Andric 14*4ba319b5SDimitry Andric/* 15*4ba319b5SDimitry Andric compare synopsis 16*4ba319b5SDimitry Andric 17*4ba319b5SDimitry Andricnamespace std { 18*4ba319b5SDimitry Andric // [cmp.categories], comparison category types 19*4ba319b5SDimitry Andric class weak_equality; 20*4ba319b5SDimitry Andric class strong_equality; 21*4ba319b5SDimitry Andric class partial_ordering; 22*4ba319b5SDimitry Andric class weak_ordering; 23*4ba319b5SDimitry Andric class strong_ordering; 24*4ba319b5SDimitry Andric 25*4ba319b5SDimitry Andric // named comparison functions 26*4ba319b5SDimitry Andric constexpr bool is_eq (weak_equality cmp) noexcept { return cmp == 0; } 27*4ba319b5SDimitry Andric constexpr bool is_neq (weak_equality cmp) noexcept { return cmp != 0; } 28*4ba319b5SDimitry Andric constexpr bool is_lt (partial_ordering cmp) noexcept { return cmp < 0; } 29*4ba319b5SDimitry Andric constexpr bool is_lteq(partial_ordering cmp) noexcept { return cmp <= 0; } 30*4ba319b5SDimitry Andric constexpr bool is_gt (partial_ordering cmp) noexcept { return cmp > 0; } 31*4ba319b5SDimitry Andric constexpr bool is_gteq(partial_ordering cmp) noexcept { return cmp >= 0; } 32*4ba319b5SDimitry Andric 33*4ba319b5SDimitry Andric // [cmp.common], common comparison category type 34*4ba319b5SDimitry Andric template<class... Ts> 35*4ba319b5SDimitry Andric struct common_comparison_category { 36*4ba319b5SDimitry Andric using type = see below; 37*4ba319b5SDimitry Andric }; 38*4ba319b5SDimitry Andric template<class... Ts> 39*4ba319b5SDimitry Andric using common_comparison_category_t = typename common_comparison_category<Ts...>::type; 40*4ba319b5SDimitry Andric 41*4ba319b5SDimitry Andric // [cmp.alg], comparison algorithms 42*4ba319b5SDimitry Andric template<class T> constexpr strong_ordering strong_order(const T& a, const T& b); 43*4ba319b5SDimitry Andric template<class T> constexpr weak_ordering weak_order(const T& a, const T& b); 44*4ba319b5SDimitry Andric template<class T> constexpr partial_ordering partial_order(const T& a, const T& b); 45*4ba319b5SDimitry Andric template<class T> constexpr strong_equality strong_equal(const T& a, const T& b); 46*4ba319b5SDimitry Andric template<class T> constexpr weak_equality weak_equal(const T& a, const T& b); 47*4ba319b5SDimitry Andric} 48*4ba319b5SDimitry Andric*/ 49*4ba319b5SDimitry Andric 50*4ba319b5SDimitry Andric#include <__config> 51*4ba319b5SDimitry Andric#include <type_traits> 52*4ba319b5SDimitry Andric#include <array> 53*4ba319b5SDimitry Andric 54*4ba319b5SDimitry Andric#ifndef _LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER 55*4ba319b5SDimitry Andric#pragma GCC system_header 56*4ba319b5SDimitry Andric#endif 57*4ba319b5SDimitry Andric 58*4ba319b5SDimitry Andric_LIBCPP_BEGIN_NAMESPACE_STD 59*4ba319b5SDimitry Andric 60*4ba319b5SDimitry Andric#if _LIBCPP_STD_VER > 17 61*4ba319b5SDimitry Andric 62*4ba319b5SDimitry Andric// exposition only 63*4ba319b5SDimitry Andricenum class _LIBCPP_ENUM_VIS _EqResult : unsigned char { 64*4ba319b5SDimitry Andric __zero = 0, 65*4ba319b5SDimitry Andric __equal = __zero, 66*4ba319b5SDimitry Andric __equiv = __equal, 67*4ba319b5SDimitry Andric __nonequal = 1, 68*4ba319b5SDimitry Andric __nonequiv = __nonequal 69*4ba319b5SDimitry Andric}; 70*4ba319b5SDimitry Andric 71*4ba319b5SDimitry Andricenum class _LIBCPP_ENUM_VIS _OrdResult : signed char { 72*4ba319b5SDimitry Andric __less = -1, 73*4ba319b5SDimitry Andric __greater = 1 74*4ba319b5SDimitry Andric}; 75*4ba319b5SDimitry Andric 76*4ba319b5SDimitry Andricenum class _LIBCPP_ENUM_VIS _NCmpResult : signed char { 77*4ba319b5SDimitry Andric __unordered = -127 78*4ba319b5SDimitry Andric}; 79*4ba319b5SDimitry Andric 80*4ba319b5SDimitry Andricstruct _CmpUnspecifiedType; 81*4ba319b5SDimitry Andricusing _CmpUnspecifiedParam = void (_CmpUnspecifiedType::*)(); 82*4ba319b5SDimitry Andric 83*4ba319b5SDimitry Andricclass weak_equality { 84*4ba319b5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 85*4ba319b5SDimitry Andric constexpr explicit weak_equality(_EqResult __val) noexcept : __value_(__val) {} 86*4ba319b5SDimitry Andric 87*4ba319b5SDimitry Andricpublic: 88*4ba319b5SDimitry Andric static const weak_equality equivalent; 89*4ba319b5SDimitry Andric static const weak_equality nonequivalent; 90*4ba319b5SDimitry Andric 91*4ba319b5SDimitry Andric _LIBCPP_INLINE_VISIBILITY friend constexpr bool operator==(weak_equality __v, _CmpUnspecifiedParam) noexcept; 92*4ba319b5SDimitry Andric _LIBCPP_INLINE_VISIBILITY friend constexpr bool operator==(_CmpUnspecifiedParam, weak_equality __v) noexcept; 93*4ba319b5SDimitry Andric _LIBCPP_INLINE_VISIBILITY friend constexpr bool operator!=(weak_equality __v, _CmpUnspecifiedParam) noexcept; 94*4ba319b5SDimitry Andric _LIBCPP_INLINE_VISIBILITY friend constexpr bool operator!=(_CmpUnspecifiedParam, weak_equality __v) noexcept; 95*4ba319b5SDimitry Andric 96*4ba319b5SDimitry Andric#ifndef _LIBCPP_HAS_NO_SPACESHIP_OPERATOR 97*4ba319b5SDimitry Andric _LIBCPP_INLINE_VISIBILITY friend constexpr weak_equality operator<=>(weak_equality __v, _CmpUnspecifiedParam) noexcept; 98*4ba319b5SDimitry Andric _LIBCPP_INLINE_VISIBILITY friend constexpr weak_equality operator<=>(_CmpUnspecifiedParam, weak_equality __v) noexcept; 99*4ba319b5SDimitry Andric#endif 100*4ba319b5SDimitry Andric 101*4ba319b5SDimitry Andricprivate: 102*4ba319b5SDimitry Andric _EqResult __value_; 103*4ba319b5SDimitry Andric}; 104*4ba319b5SDimitry Andric 105*4ba319b5SDimitry Andric_LIBCPP_INLINE_VAR constexpr weak_equality weak_equality::equivalent(_EqResult::__equiv); 106*4ba319b5SDimitry Andric_LIBCPP_INLINE_VAR constexpr weak_equality weak_equality::nonequivalent(_EqResult::__nonequiv); 107*4ba319b5SDimitry Andric 108*4ba319b5SDimitry Andric_LIBCPP_INLINE_VISIBILITY 109*4ba319b5SDimitry Andricinline constexpr bool operator==(weak_equality __v, _CmpUnspecifiedParam) noexcept { 110*4ba319b5SDimitry Andric return __v.__value_ == _EqResult::__zero; 111*4ba319b5SDimitry Andric} 112*4ba319b5SDimitry Andric 113*4ba319b5SDimitry Andric_LIBCPP_INLINE_VISIBILITY 114*4ba319b5SDimitry Andricinline constexpr bool operator==(_CmpUnspecifiedParam, weak_equality __v) noexcept { 115*4ba319b5SDimitry Andric return __v.__value_ == _EqResult::__zero; 116*4ba319b5SDimitry Andric} 117*4ba319b5SDimitry Andric 118*4ba319b5SDimitry Andric_LIBCPP_INLINE_VISIBILITY 119*4ba319b5SDimitry Andricinline constexpr bool operator!=(weak_equality __v, _CmpUnspecifiedParam) noexcept { 120*4ba319b5SDimitry Andric return __v.__value_ != _EqResult::__zero; 121*4ba319b5SDimitry Andric} 122*4ba319b5SDimitry Andric 123*4ba319b5SDimitry Andric_LIBCPP_INLINE_VISIBILITY 124*4ba319b5SDimitry Andricinline constexpr bool operator!=(_CmpUnspecifiedParam, weak_equality __v) noexcept { 125*4ba319b5SDimitry Andric return __v.__value_ != _EqResult::__zero; 126*4ba319b5SDimitry Andric} 127*4ba319b5SDimitry Andric 128*4ba319b5SDimitry Andric#ifndef _LIBCPP_HAS_NO_SPACESHIP_OPERATOR 129*4ba319b5SDimitry Andric_LIBCPP_INLINE_VISIBILITY 130*4ba319b5SDimitry Andricinline constexpr weak_equality operator<=>(weak_equality __v, _CmpUnspecifiedParam) noexcept { 131*4ba319b5SDimitry Andric return __v; 132*4ba319b5SDimitry Andric} 133*4ba319b5SDimitry Andric 134*4ba319b5SDimitry Andric_LIBCPP_INLINE_VISIBILITY 135*4ba319b5SDimitry Andricinline constexpr weak_equality operator<=>(_CmpUnspecifiedParam, weak_equality __v) noexcept { 136*4ba319b5SDimitry Andric return __v; 137*4ba319b5SDimitry Andric} 138*4ba319b5SDimitry Andric#endif 139*4ba319b5SDimitry Andric 140*4ba319b5SDimitry Andricclass strong_equality { 141*4ba319b5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 142*4ba319b5SDimitry Andric explicit constexpr strong_equality(_EqResult __val) noexcept : __value_(__val) {} 143*4ba319b5SDimitry Andric 144*4ba319b5SDimitry Andricpublic: 145*4ba319b5SDimitry Andric static const strong_equality equal; 146*4ba319b5SDimitry Andric static const strong_equality nonequal; 147*4ba319b5SDimitry Andric static const strong_equality equivalent; 148*4ba319b5SDimitry Andric static const strong_equality nonequivalent; 149*4ba319b5SDimitry Andric 150*4ba319b5SDimitry Andric // conversion 151*4ba319b5SDimitry Andric _LIBCPP_INLINE_VISIBILITY constexpr operator weak_equality() const noexcept { 152*4ba319b5SDimitry Andric return __value_ == _EqResult::__zero ? weak_equality::equivalent 153*4ba319b5SDimitry Andric : weak_equality::nonequivalent; 154*4ba319b5SDimitry Andric } 155*4ba319b5SDimitry Andric 156*4ba319b5SDimitry Andric // comparisons 157*4ba319b5SDimitry Andric _LIBCPP_INLINE_VISIBILITY friend constexpr bool operator==(strong_equality __v, _CmpUnspecifiedParam) noexcept; 158*4ba319b5SDimitry Andric _LIBCPP_INLINE_VISIBILITY friend constexpr bool operator!=(strong_equality __v, _CmpUnspecifiedParam) noexcept; 159*4ba319b5SDimitry Andric _LIBCPP_INLINE_VISIBILITY friend constexpr bool operator==(_CmpUnspecifiedParam, strong_equality __v) noexcept; 160*4ba319b5SDimitry Andric _LIBCPP_INLINE_VISIBILITY friend constexpr bool operator!=(_CmpUnspecifiedParam, strong_equality __v) noexcept; 161*4ba319b5SDimitry Andric 162*4ba319b5SDimitry Andric#ifndef _LIBCPP_HAS_NO_SPACESHIP_OPERATOR 163*4ba319b5SDimitry Andric _LIBCPP_INLINE_VISIBILITY friend constexpr strong_equality operator<=>(strong_equality __v, _CmpUnspecifiedParam) noexcept; 164*4ba319b5SDimitry Andric _LIBCPP_INLINE_VISIBILITY friend constexpr strong_equality operator<=>(_CmpUnspecifiedParam, strong_equality __v) noexcept; 165*4ba319b5SDimitry Andric#endif 166*4ba319b5SDimitry Andricprivate: 167*4ba319b5SDimitry Andric _EqResult __value_; 168*4ba319b5SDimitry Andric}; 169*4ba319b5SDimitry Andric 170*4ba319b5SDimitry Andric_LIBCPP_INLINE_VAR constexpr strong_equality strong_equality::equal(_EqResult::__equal); 171*4ba319b5SDimitry Andric_LIBCPP_INLINE_VAR constexpr strong_equality strong_equality::nonequal(_EqResult::__nonequal); 172*4ba319b5SDimitry Andric_LIBCPP_INLINE_VAR constexpr strong_equality strong_equality::equivalent(_EqResult::__equiv); 173*4ba319b5SDimitry Andric_LIBCPP_INLINE_VAR constexpr strong_equality strong_equality::nonequivalent(_EqResult::__nonequiv); 174*4ba319b5SDimitry Andric 175*4ba319b5SDimitry Andric_LIBCPP_INLINE_VISIBILITY 176*4ba319b5SDimitry Andricconstexpr bool operator==(strong_equality __v, _CmpUnspecifiedParam) noexcept { 177*4ba319b5SDimitry Andric return __v.__value_ == _EqResult::__zero; 178*4ba319b5SDimitry Andric} 179*4ba319b5SDimitry Andric 180*4ba319b5SDimitry Andric_LIBCPP_INLINE_VISIBILITY 181*4ba319b5SDimitry Andricconstexpr bool operator==(_CmpUnspecifiedParam, strong_equality __v) noexcept { 182*4ba319b5SDimitry Andric return __v.__value_ == _EqResult::__zero; 183*4ba319b5SDimitry Andric} 184*4ba319b5SDimitry Andric 185*4ba319b5SDimitry Andric_LIBCPP_INLINE_VISIBILITY 186*4ba319b5SDimitry Andricconstexpr bool operator!=(strong_equality __v, _CmpUnspecifiedParam) noexcept { 187*4ba319b5SDimitry Andric return __v.__value_ != _EqResult::__zero; 188*4ba319b5SDimitry Andric} 189*4ba319b5SDimitry Andric 190*4ba319b5SDimitry Andric_LIBCPP_INLINE_VISIBILITY 191*4ba319b5SDimitry Andricconstexpr bool operator!=(_CmpUnspecifiedParam, strong_equality __v) noexcept { 192*4ba319b5SDimitry Andric return __v.__value_ != _EqResult::__zero; 193*4ba319b5SDimitry Andric} 194*4ba319b5SDimitry Andric 195*4ba319b5SDimitry Andric#ifndef _LIBCPP_HAS_NO_SPACESHIP_OPERATOR 196*4ba319b5SDimitry Andric_LIBCPP_INLINE_VISIBILITY 197*4ba319b5SDimitry Andricconstexpr strong_equality operator<=>(strong_equality __v, _CmpUnspecifiedParam) noexcept { 198*4ba319b5SDimitry Andric return __v; 199*4ba319b5SDimitry Andric} 200*4ba319b5SDimitry Andric 201*4ba319b5SDimitry Andric_LIBCPP_INLINE_VISIBILITY 202*4ba319b5SDimitry Andricconstexpr strong_equality operator<=>(_CmpUnspecifiedParam, strong_equality __v) noexcept { 203*4ba319b5SDimitry Andric return __v; 204*4ba319b5SDimitry Andric} 205*4ba319b5SDimitry Andric#endif // _LIBCPP_HAS_NO_SPACESHIP_OPERATOR 206*4ba319b5SDimitry Andric 207*4ba319b5SDimitry Andricclass partial_ordering { 208*4ba319b5SDimitry Andric using _ValueT = signed char; 209*4ba319b5SDimitry Andric 210*4ba319b5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 211*4ba319b5SDimitry Andric explicit constexpr partial_ordering(_EqResult __v) noexcept 212*4ba319b5SDimitry Andric : __value_(_ValueT(__v)) {} 213*4ba319b5SDimitry Andric 214*4ba319b5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 215*4ba319b5SDimitry Andric explicit constexpr partial_ordering(_OrdResult __v) noexcept 216*4ba319b5SDimitry Andric : __value_(_ValueT(__v)) {} 217*4ba319b5SDimitry Andric 218*4ba319b5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 219*4ba319b5SDimitry Andric explicit constexpr partial_ordering(_NCmpResult __v) noexcept 220*4ba319b5SDimitry Andric : __value_(_ValueT(__v)) {} 221*4ba319b5SDimitry Andric 222*4ba319b5SDimitry Andric constexpr bool __is_ordered() const noexcept { 223*4ba319b5SDimitry Andric return __value_ != _ValueT(_NCmpResult::__unordered); 224*4ba319b5SDimitry Andric } 225*4ba319b5SDimitry Andricpublic: 226*4ba319b5SDimitry Andric // valid values 227*4ba319b5SDimitry Andric static const partial_ordering less; 228*4ba319b5SDimitry Andric static const partial_ordering equivalent; 229*4ba319b5SDimitry Andric static const partial_ordering greater; 230*4ba319b5SDimitry Andric static const partial_ordering unordered; 231*4ba319b5SDimitry Andric 232*4ba319b5SDimitry Andric // conversion 233*4ba319b5SDimitry Andric constexpr operator weak_equality() const noexcept { 234*4ba319b5SDimitry Andric return __value_ == 0 ? weak_equality::equivalent : weak_equality::nonequivalent; 235*4ba319b5SDimitry Andric } 236*4ba319b5SDimitry Andric 237*4ba319b5SDimitry Andric // comparisons 238*4ba319b5SDimitry Andric _LIBCPP_INLINE_VISIBILITY friend constexpr bool operator==(partial_ordering __v, _CmpUnspecifiedParam) noexcept; 239*4ba319b5SDimitry Andric _LIBCPP_INLINE_VISIBILITY friend constexpr bool operator!=(partial_ordering __v, _CmpUnspecifiedParam) noexcept; 240*4ba319b5SDimitry Andric _LIBCPP_INLINE_VISIBILITY friend constexpr bool operator< (partial_ordering __v, _CmpUnspecifiedParam) noexcept; 241*4ba319b5SDimitry Andric _LIBCPP_INLINE_VISIBILITY friend constexpr bool operator<=(partial_ordering __v, _CmpUnspecifiedParam) noexcept; 242*4ba319b5SDimitry Andric _LIBCPP_INLINE_VISIBILITY friend constexpr bool operator> (partial_ordering __v, _CmpUnspecifiedParam) noexcept; 243*4ba319b5SDimitry Andric _LIBCPP_INLINE_VISIBILITY friend constexpr bool operator>=(partial_ordering __v, _CmpUnspecifiedParam) noexcept; 244*4ba319b5SDimitry Andric _LIBCPP_INLINE_VISIBILITY friend constexpr bool operator==(_CmpUnspecifiedParam, partial_ordering __v) noexcept; 245*4ba319b5SDimitry Andric _LIBCPP_INLINE_VISIBILITY friend constexpr bool operator!=(_CmpUnspecifiedParam, partial_ordering __v) noexcept; 246*4ba319b5SDimitry Andric _LIBCPP_INLINE_VISIBILITY friend constexpr bool operator< (_CmpUnspecifiedParam, partial_ordering __v) noexcept; 247*4ba319b5SDimitry Andric _LIBCPP_INLINE_VISIBILITY friend constexpr bool operator<=(_CmpUnspecifiedParam, partial_ordering __v) noexcept; 248*4ba319b5SDimitry Andric _LIBCPP_INLINE_VISIBILITY friend constexpr bool operator> (_CmpUnspecifiedParam, partial_ordering __v) noexcept; 249*4ba319b5SDimitry Andric _LIBCPP_INLINE_VISIBILITY friend constexpr bool operator>=(_CmpUnspecifiedParam, partial_ordering __v) noexcept; 250*4ba319b5SDimitry Andric 251*4ba319b5SDimitry Andric#ifndef _LIBCPP_HAS_NO_SPACESHIP_OPERATOR 252*4ba319b5SDimitry Andric _LIBCPP_INLINE_VISIBILITY friend constexpr partial_ordering operator<=>(partial_ordering __v, _CmpUnspecifiedParam) noexcept; 253*4ba319b5SDimitry Andric _LIBCPP_INLINE_VISIBILITY friend constexpr partial_ordering operator<=>(_CmpUnspecifiedParam, partial_ordering __v) noexcept; 254*4ba319b5SDimitry Andric#endif 255*4ba319b5SDimitry Andric 256*4ba319b5SDimitry Andricprivate: 257*4ba319b5SDimitry Andric _ValueT __value_; 258*4ba319b5SDimitry Andric}; 259*4ba319b5SDimitry Andric 260*4ba319b5SDimitry Andric_LIBCPP_INLINE_VAR constexpr partial_ordering partial_ordering::less(_OrdResult::__less); 261*4ba319b5SDimitry Andric_LIBCPP_INLINE_VAR constexpr partial_ordering partial_ordering::equivalent(_EqResult::__equiv); 262*4ba319b5SDimitry Andric_LIBCPP_INLINE_VAR constexpr partial_ordering partial_ordering::greater(_OrdResult::__greater); 263*4ba319b5SDimitry Andric_LIBCPP_INLINE_VAR constexpr partial_ordering partial_ordering::unordered(_NCmpResult ::__unordered); 264*4ba319b5SDimitry Andric 265*4ba319b5SDimitry Andric_LIBCPP_INLINE_VISIBILITY 266*4ba319b5SDimitry Andricconstexpr bool operator==(partial_ordering __v, _CmpUnspecifiedParam) noexcept { 267*4ba319b5SDimitry Andric return __v.__is_ordered() && __v.__value_ == 0; 268*4ba319b5SDimitry Andric} 269*4ba319b5SDimitry Andric_LIBCPP_INLINE_VISIBILITY 270*4ba319b5SDimitry Andricconstexpr bool operator< (partial_ordering __v, _CmpUnspecifiedParam) noexcept { 271*4ba319b5SDimitry Andric return __v.__is_ordered() && __v.__value_ < 0; 272*4ba319b5SDimitry Andric} 273*4ba319b5SDimitry Andric_LIBCPP_INLINE_VISIBILITY 274*4ba319b5SDimitry Andricconstexpr bool operator<=(partial_ordering __v, _CmpUnspecifiedParam) noexcept { 275*4ba319b5SDimitry Andric return __v.__is_ordered() && __v.__value_ <= 0; 276*4ba319b5SDimitry Andric} 277*4ba319b5SDimitry Andric_LIBCPP_INLINE_VISIBILITY 278*4ba319b5SDimitry Andricconstexpr bool operator> (partial_ordering __v, _CmpUnspecifiedParam) noexcept { 279*4ba319b5SDimitry Andric return __v.__is_ordered() && __v.__value_ > 0; 280*4ba319b5SDimitry Andric} 281*4ba319b5SDimitry Andric_LIBCPP_INLINE_VISIBILITY 282*4ba319b5SDimitry Andricconstexpr bool operator>=(partial_ordering __v, _CmpUnspecifiedParam) noexcept { 283*4ba319b5SDimitry Andric return __v.__is_ordered() && __v.__value_ >= 0; 284*4ba319b5SDimitry Andric} 285*4ba319b5SDimitry Andric 286*4ba319b5SDimitry Andric_LIBCPP_INLINE_VISIBILITY 287*4ba319b5SDimitry Andricconstexpr bool operator==(_CmpUnspecifiedParam, partial_ordering __v) noexcept { 288*4ba319b5SDimitry Andric return __v.__is_ordered() && 0 == __v.__value_; 289*4ba319b5SDimitry Andric} 290*4ba319b5SDimitry Andric_LIBCPP_INLINE_VISIBILITY 291*4ba319b5SDimitry Andricconstexpr bool operator< (_CmpUnspecifiedParam, partial_ordering __v) noexcept { 292*4ba319b5SDimitry Andric return __v.__is_ordered() && 0 < __v.__value_; 293*4ba319b5SDimitry Andric} 294*4ba319b5SDimitry Andric_LIBCPP_INLINE_VISIBILITY 295*4ba319b5SDimitry Andricconstexpr bool operator<=(_CmpUnspecifiedParam, partial_ordering __v) noexcept { 296*4ba319b5SDimitry Andric return __v.__is_ordered() && 0 <= __v.__value_; 297*4ba319b5SDimitry Andric} 298*4ba319b5SDimitry Andric_LIBCPP_INLINE_VISIBILITY 299*4ba319b5SDimitry Andricconstexpr bool operator> (_CmpUnspecifiedParam, partial_ordering __v) noexcept { 300*4ba319b5SDimitry Andric return __v.__is_ordered() && 0 > __v.__value_; 301*4ba319b5SDimitry Andric} 302*4ba319b5SDimitry Andric_LIBCPP_INLINE_VISIBILITY 303*4ba319b5SDimitry Andricconstexpr bool operator>=(_CmpUnspecifiedParam, partial_ordering __v) noexcept { 304*4ba319b5SDimitry Andric return __v.__is_ordered() && 0 >= __v.__value_; 305*4ba319b5SDimitry Andric} 306*4ba319b5SDimitry Andric 307*4ba319b5SDimitry Andric_LIBCPP_INLINE_VISIBILITY 308*4ba319b5SDimitry Andricconstexpr bool operator!=(partial_ordering __v, _CmpUnspecifiedParam) noexcept { 309*4ba319b5SDimitry Andric return !__v.__is_ordered() || __v.__value_ != 0; 310*4ba319b5SDimitry Andric} 311*4ba319b5SDimitry Andric_LIBCPP_INLINE_VISIBILITY 312*4ba319b5SDimitry Andricconstexpr bool operator!=(_CmpUnspecifiedParam, partial_ordering __v) noexcept { 313*4ba319b5SDimitry Andric return !__v.__is_ordered() || __v.__value_ != 0; 314*4ba319b5SDimitry Andric} 315*4ba319b5SDimitry Andric 316*4ba319b5SDimitry Andric#ifndef _LIBCPP_HAS_NO_SPACESHIP_OPERATOR 317*4ba319b5SDimitry Andric_LIBCPP_INLINE_VISIBILITY 318*4ba319b5SDimitry Andricconstexpr partial_ordering operator<=>(partial_ordering __v, _CmpUnspecifiedParam) noexcept { 319*4ba319b5SDimitry Andric return __v; 320*4ba319b5SDimitry Andric} 321*4ba319b5SDimitry Andric_LIBCPP_INLINE_VISIBILITY 322*4ba319b5SDimitry Andricconstexpr partial_ordering operator<=>(_CmpUnspecifiedParam, partial_ordering __v) noexcept { 323*4ba319b5SDimitry Andric return __v < 0 ? partial_ordering::greater : (__v > 0 ? partial_ordering::less : __v); 324*4ba319b5SDimitry Andric} 325*4ba319b5SDimitry Andric#endif // _LIBCPP_HAS_NO_SPACESHIP_OPERATOR 326*4ba319b5SDimitry Andric 327*4ba319b5SDimitry Andricclass weak_ordering { 328*4ba319b5SDimitry Andric using _ValueT = signed char; 329*4ba319b5SDimitry Andric 330*4ba319b5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 331*4ba319b5SDimitry Andric explicit constexpr weak_ordering(_EqResult __v) noexcept : __value_(_ValueT(__v)) {} 332*4ba319b5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 333*4ba319b5SDimitry Andric explicit constexpr weak_ordering(_OrdResult __v) noexcept : __value_(_ValueT(__v)) {} 334*4ba319b5SDimitry Andric 335*4ba319b5SDimitry Andricpublic: 336*4ba319b5SDimitry Andric static const weak_ordering less; 337*4ba319b5SDimitry Andric static const weak_ordering equivalent; 338*4ba319b5SDimitry Andric static const weak_ordering greater; 339*4ba319b5SDimitry Andric 340*4ba319b5SDimitry Andric // conversions 341*4ba319b5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 342*4ba319b5SDimitry Andric constexpr operator weak_equality() const noexcept { 343*4ba319b5SDimitry Andric return __value_ == 0 ? weak_equality::equivalent 344*4ba319b5SDimitry Andric : weak_equality::nonequivalent; 345*4ba319b5SDimitry Andric } 346*4ba319b5SDimitry Andric 347*4ba319b5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 348*4ba319b5SDimitry Andric constexpr operator partial_ordering() const noexcept { 349*4ba319b5SDimitry Andric return __value_ == 0 ? partial_ordering::equivalent 350*4ba319b5SDimitry Andric : (__value_ < 0 ? partial_ordering::less : partial_ordering::greater); 351*4ba319b5SDimitry Andric } 352*4ba319b5SDimitry Andric 353*4ba319b5SDimitry Andric // comparisons 354*4ba319b5SDimitry Andric _LIBCPP_INLINE_VISIBILITY friend constexpr bool operator==(weak_ordering __v, _CmpUnspecifiedParam) noexcept; 355*4ba319b5SDimitry Andric _LIBCPP_INLINE_VISIBILITY friend constexpr bool operator!=(weak_ordering __v, _CmpUnspecifiedParam) noexcept; 356*4ba319b5SDimitry Andric _LIBCPP_INLINE_VISIBILITY friend constexpr bool operator< (weak_ordering __v, _CmpUnspecifiedParam) noexcept; 357*4ba319b5SDimitry Andric _LIBCPP_INLINE_VISIBILITY friend constexpr bool operator<=(weak_ordering __v, _CmpUnspecifiedParam) noexcept; 358*4ba319b5SDimitry Andric _LIBCPP_INLINE_VISIBILITY friend constexpr bool operator> (weak_ordering __v, _CmpUnspecifiedParam) noexcept; 359*4ba319b5SDimitry Andric _LIBCPP_INLINE_VISIBILITY friend constexpr bool operator>=(weak_ordering __v, _CmpUnspecifiedParam) noexcept; 360*4ba319b5SDimitry Andric _LIBCPP_INLINE_VISIBILITY friend constexpr bool operator==(_CmpUnspecifiedParam, weak_ordering __v) noexcept; 361*4ba319b5SDimitry Andric _LIBCPP_INLINE_VISIBILITY friend constexpr bool operator!=(_CmpUnspecifiedParam, weak_ordering __v) noexcept; 362*4ba319b5SDimitry Andric _LIBCPP_INLINE_VISIBILITY friend constexpr bool operator< (_CmpUnspecifiedParam, weak_ordering __v) noexcept; 363*4ba319b5SDimitry Andric _LIBCPP_INLINE_VISIBILITY friend constexpr bool operator<=(_CmpUnspecifiedParam, weak_ordering __v) noexcept; 364*4ba319b5SDimitry Andric _LIBCPP_INLINE_VISIBILITY friend constexpr bool operator> (_CmpUnspecifiedParam, weak_ordering __v) noexcept; 365*4ba319b5SDimitry Andric _LIBCPP_INLINE_VISIBILITY friend constexpr bool operator>=(_CmpUnspecifiedParam, weak_ordering __v) noexcept; 366*4ba319b5SDimitry Andric 367*4ba319b5SDimitry Andric#ifndef _LIBCPP_HAS_NO_SPACESHIP_OPERATOR 368*4ba319b5SDimitry Andric _LIBCPP_INLINE_VISIBILITY friend constexpr weak_ordering operator<=>(weak_ordering __v, _CmpUnspecifiedParam) noexcept; 369*4ba319b5SDimitry Andric _LIBCPP_INLINE_VISIBILITY friend constexpr weak_ordering operator<=>(_CmpUnspecifiedParam, weak_ordering __v) noexcept; 370*4ba319b5SDimitry Andric#endif 371*4ba319b5SDimitry Andric 372*4ba319b5SDimitry Andricprivate: 373*4ba319b5SDimitry Andric _ValueT __value_; 374*4ba319b5SDimitry Andric}; 375*4ba319b5SDimitry Andric 376*4ba319b5SDimitry Andric_LIBCPP_INLINE_VAR constexpr weak_ordering weak_ordering::less(_OrdResult::__less); 377*4ba319b5SDimitry Andric_LIBCPP_INLINE_VAR constexpr weak_ordering weak_ordering::equivalent(_EqResult::__equiv); 378*4ba319b5SDimitry Andric_LIBCPP_INLINE_VAR constexpr weak_ordering weak_ordering::greater(_OrdResult::__greater); 379*4ba319b5SDimitry Andric 380*4ba319b5SDimitry Andric_LIBCPP_INLINE_VISIBILITY 381*4ba319b5SDimitry Andricconstexpr bool operator==(weak_ordering __v, _CmpUnspecifiedParam) noexcept { 382*4ba319b5SDimitry Andric return __v.__value_ == 0; 383*4ba319b5SDimitry Andric} 384*4ba319b5SDimitry Andric_LIBCPP_INLINE_VISIBILITY 385*4ba319b5SDimitry Andricconstexpr bool operator!=(weak_ordering __v, _CmpUnspecifiedParam) noexcept { 386*4ba319b5SDimitry Andric return __v.__value_ != 0; 387*4ba319b5SDimitry Andric} 388*4ba319b5SDimitry Andric_LIBCPP_INLINE_VISIBILITY 389*4ba319b5SDimitry Andricconstexpr bool operator< (weak_ordering __v, _CmpUnspecifiedParam) noexcept { 390*4ba319b5SDimitry Andric return __v.__value_ < 0; 391*4ba319b5SDimitry Andric} 392*4ba319b5SDimitry Andric_LIBCPP_INLINE_VISIBILITY 393*4ba319b5SDimitry Andricconstexpr bool operator<=(weak_ordering __v, _CmpUnspecifiedParam) noexcept { 394*4ba319b5SDimitry Andric return __v.__value_ <= 0; 395*4ba319b5SDimitry Andric} 396*4ba319b5SDimitry Andric_LIBCPP_INLINE_VISIBILITY 397*4ba319b5SDimitry Andricconstexpr bool operator> (weak_ordering __v, _CmpUnspecifiedParam) noexcept { 398*4ba319b5SDimitry Andric return __v.__value_ > 0; 399*4ba319b5SDimitry Andric} 400*4ba319b5SDimitry Andric_LIBCPP_INLINE_VISIBILITY 401*4ba319b5SDimitry Andricconstexpr bool operator>=(weak_ordering __v, _CmpUnspecifiedParam) noexcept { 402*4ba319b5SDimitry Andric return __v.__value_ >= 0; 403*4ba319b5SDimitry Andric} 404*4ba319b5SDimitry Andric_LIBCPP_INLINE_VISIBILITY 405*4ba319b5SDimitry Andricconstexpr bool operator==(_CmpUnspecifiedParam, weak_ordering __v) noexcept { 406*4ba319b5SDimitry Andric return 0 == __v.__value_; 407*4ba319b5SDimitry Andric} 408*4ba319b5SDimitry Andric_LIBCPP_INLINE_VISIBILITY 409*4ba319b5SDimitry Andricconstexpr bool operator!=(_CmpUnspecifiedParam, weak_ordering __v) noexcept { 410*4ba319b5SDimitry Andric return 0 != __v.__value_; 411*4ba319b5SDimitry Andric} 412*4ba319b5SDimitry Andric_LIBCPP_INLINE_VISIBILITY 413*4ba319b5SDimitry Andricconstexpr bool operator< (_CmpUnspecifiedParam, weak_ordering __v) noexcept { 414*4ba319b5SDimitry Andric return 0 < __v.__value_; 415*4ba319b5SDimitry Andric} 416*4ba319b5SDimitry Andric_LIBCPP_INLINE_VISIBILITY 417*4ba319b5SDimitry Andricconstexpr bool operator<=(_CmpUnspecifiedParam, weak_ordering __v) noexcept { 418*4ba319b5SDimitry Andric return 0 <= __v.__value_; 419*4ba319b5SDimitry Andric} 420*4ba319b5SDimitry Andric_LIBCPP_INLINE_VISIBILITY 421*4ba319b5SDimitry Andricconstexpr bool operator> (_CmpUnspecifiedParam, weak_ordering __v) noexcept { 422*4ba319b5SDimitry Andric return 0 > __v.__value_; 423*4ba319b5SDimitry Andric} 424*4ba319b5SDimitry Andric_LIBCPP_INLINE_VISIBILITY 425*4ba319b5SDimitry Andricconstexpr bool operator>=(_CmpUnspecifiedParam, weak_ordering __v) noexcept { 426*4ba319b5SDimitry Andric return 0 >= __v.__value_; 427*4ba319b5SDimitry Andric} 428*4ba319b5SDimitry Andric 429*4ba319b5SDimitry Andric#ifndef _LIBCPP_HAS_NO_SPACESHIP_OPERATOR 430*4ba319b5SDimitry Andric_LIBCPP_INLINE_VISIBILITY 431*4ba319b5SDimitry Andricconstexpr weak_ordering operator<=>(weak_ordering __v, _CmpUnspecifiedParam) noexcept { 432*4ba319b5SDimitry Andric return __v; 433*4ba319b5SDimitry Andric} 434*4ba319b5SDimitry Andric_LIBCPP_INLINE_VISIBILITY 435*4ba319b5SDimitry Andricconstexpr weak_ordering operator<=>(_CmpUnspecifiedParam, weak_ordering __v) noexcept { 436*4ba319b5SDimitry Andric return __v < 0 ? weak_ordering::greater : (__v > 0 ? weak_ordering::less : __v); 437*4ba319b5SDimitry Andric} 438*4ba319b5SDimitry Andric#endif // _LIBCPP_HAS_NO_SPACESHIP_OPERATOR 439*4ba319b5SDimitry Andric 440*4ba319b5SDimitry Andricclass strong_ordering { 441*4ba319b5SDimitry Andric using _ValueT = signed char; 442*4ba319b5SDimitry Andric 443*4ba319b5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 444*4ba319b5SDimitry Andric explicit constexpr strong_ordering(_EqResult __v) noexcept : __value_(_ValueT(__v)) {} 445*4ba319b5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 446*4ba319b5SDimitry Andric explicit constexpr strong_ordering(_OrdResult __v) noexcept : __value_(_ValueT(__v)) {} 447*4ba319b5SDimitry Andric 448*4ba319b5SDimitry Andricpublic: 449*4ba319b5SDimitry Andric static const strong_ordering less; 450*4ba319b5SDimitry Andric static const strong_ordering equal; 451*4ba319b5SDimitry Andric static const strong_ordering equivalent; 452*4ba319b5SDimitry Andric static const strong_ordering greater; 453*4ba319b5SDimitry Andric 454*4ba319b5SDimitry Andric // conversions 455*4ba319b5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 456*4ba319b5SDimitry Andric constexpr operator weak_equality() const noexcept { 457*4ba319b5SDimitry Andric return __value_ == 0 ? weak_equality::equivalent 458*4ba319b5SDimitry Andric : weak_equality::nonequivalent; 459*4ba319b5SDimitry Andric } 460*4ba319b5SDimitry Andric 461*4ba319b5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 462*4ba319b5SDimitry Andric constexpr operator strong_equality() const noexcept { 463*4ba319b5SDimitry Andric return __value_ == 0 ? strong_equality::equal 464*4ba319b5SDimitry Andric : strong_equality::nonequal; 465*4ba319b5SDimitry Andric } 466*4ba319b5SDimitry Andric 467*4ba319b5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 468*4ba319b5SDimitry Andric constexpr operator partial_ordering() const noexcept { 469*4ba319b5SDimitry Andric return __value_ == 0 ? partial_ordering::equivalent 470*4ba319b5SDimitry Andric : (__value_ < 0 ? partial_ordering::less : partial_ordering::greater); 471*4ba319b5SDimitry Andric } 472*4ba319b5SDimitry Andric 473*4ba319b5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 474*4ba319b5SDimitry Andric constexpr operator weak_ordering() const noexcept { 475*4ba319b5SDimitry Andric return __value_ == 0 ? weak_ordering::equivalent 476*4ba319b5SDimitry Andric : (__value_ < 0 ? weak_ordering::less : weak_ordering::greater); 477*4ba319b5SDimitry Andric } 478*4ba319b5SDimitry Andric 479*4ba319b5SDimitry Andric // comparisons 480*4ba319b5SDimitry Andric _LIBCPP_INLINE_VISIBILITY friend constexpr bool operator==(strong_ordering __v, _CmpUnspecifiedParam) noexcept; 481*4ba319b5SDimitry Andric _LIBCPP_INLINE_VISIBILITY friend constexpr bool operator!=(strong_ordering __v, _CmpUnspecifiedParam) noexcept; 482*4ba319b5SDimitry Andric _LIBCPP_INLINE_VISIBILITY friend constexpr bool operator< (strong_ordering __v, _CmpUnspecifiedParam) noexcept; 483*4ba319b5SDimitry Andric _LIBCPP_INLINE_VISIBILITY friend constexpr bool operator<=(strong_ordering __v, _CmpUnspecifiedParam) noexcept; 484*4ba319b5SDimitry Andric _LIBCPP_INLINE_VISIBILITY friend constexpr bool operator> (strong_ordering __v, _CmpUnspecifiedParam) noexcept; 485*4ba319b5SDimitry Andric _LIBCPP_INLINE_VISIBILITY friend constexpr bool operator>=(strong_ordering __v, _CmpUnspecifiedParam) noexcept; 486*4ba319b5SDimitry Andric _LIBCPP_INLINE_VISIBILITY friend constexpr bool operator==(_CmpUnspecifiedParam, strong_ordering __v) noexcept; 487*4ba319b5SDimitry Andric _LIBCPP_INLINE_VISIBILITY friend constexpr bool operator!=(_CmpUnspecifiedParam, strong_ordering __v) noexcept; 488*4ba319b5SDimitry Andric _LIBCPP_INLINE_VISIBILITY friend constexpr bool operator< (_CmpUnspecifiedParam, strong_ordering __v) noexcept; 489*4ba319b5SDimitry Andric _LIBCPP_INLINE_VISIBILITY friend constexpr bool operator<=(_CmpUnspecifiedParam, strong_ordering __v) noexcept; 490*4ba319b5SDimitry Andric _LIBCPP_INLINE_VISIBILITY friend constexpr bool operator> (_CmpUnspecifiedParam, strong_ordering __v) noexcept; 491*4ba319b5SDimitry Andric _LIBCPP_INLINE_VISIBILITY friend constexpr bool operator>=(_CmpUnspecifiedParam, strong_ordering __v) noexcept; 492*4ba319b5SDimitry Andric 493*4ba319b5SDimitry Andric#ifndef _LIBCPP_HAS_NO_SPACESHIP_OPERATOR 494*4ba319b5SDimitry Andric _LIBCPP_INLINE_VISIBILITY friend constexpr strong_ordering operator<=>(strong_ordering __v, _CmpUnspecifiedParam) noexcept; 495*4ba319b5SDimitry Andric _LIBCPP_INLINE_VISIBILITY friend constexpr strong_ordering operator<=>(_CmpUnspecifiedParam, strong_ordering __v) noexcept; 496*4ba319b5SDimitry Andric#endif 497*4ba319b5SDimitry Andric 498*4ba319b5SDimitry Andricprivate: 499*4ba319b5SDimitry Andric _ValueT __value_; 500*4ba319b5SDimitry Andric}; 501*4ba319b5SDimitry Andric 502*4ba319b5SDimitry Andric_LIBCPP_INLINE_VAR constexpr strong_ordering strong_ordering::less(_OrdResult::__less); 503*4ba319b5SDimitry Andric_LIBCPP_INLINE_VAR constexpr strong_ordering strong_ordering::equal(_EqResult::__equal); 504*4ba319b5SDimitry Andric_LIBCPP_INLINE_VAR constexpr strong_ordering strong_ordering::equivalent(_EqResult::__equiv); 505*4ba319b5SDimitry Andric_LIBCPP_INLINE_VAR constexpr strong_ordering strong_ordering::greater(_OrdResult::__greater); 506*4ba319b5SDimitry Andric 507*4ba319b5SDimitry Andric_LIBCPP_INLINE_VISIBILITY 508*4ba319b5SDimitry Andricconstexpr bool operator==(strong_ordering __v, _CmpUnspecifiedParam) noexcept { 509*4ba319b5SDimitry Andric return __v.__value_ == 0; 510*4ba319b5SDimitry Andric} 511*4ba319b5SDimitry Andric_LIBCPP_INLINE_VISIBILITY 512*4ba319b5SDimitry Andricconstexpr bool operator!=(strong_ordering __v, _CmpUnspecifiedParam) noexcept { 513*4ba319b5SDimitry Andric return __v.__value_ != 0; 514*4ba319b5SDimitry Andric} 515*4ba319b5SDimitry Andric_LIBCPP_INLINE_VISIBILITY 516*4ba319b5SDimitry Andricconstexpr bool operator< (strong_ordering __v, _CmpUnspecifiedParam) noexcept { 517*4ba319b5SDimitry Andric return __v.__value_ < 0; 518*4ba319b5SDimitry Andric} 519*4ba319b5SDimitry Andric_LIBCPP_INLINE_VISIBILITY 520*4ba319b5SDimitry Andricconstexpr bool operator<=(strong_ordering __v, _CmpUnspecifiedParam) noexcept { 521*4ba319b5SDimitry Andric return __v.__value_ <= 0; 522*4ba319b5SDimitry Andric} 523*4ba319b5SDimitry Andric_LIBCPP_INLINE_VISIBILITY 524*4ba319b5SDimitry Andricconstexpr bool operator> (strong_ordering __v, _CmpUnspecifiedParam) noexcept { 525*4ba319b5SDimitry Andric return __v.__value_ > 0; 526*4ba319b5SDimitry Andric} 527*4ba319b5SDimitry Andric_LIBCPP_INLINE_VISIBILITY 528*4ba319b5SDimitry Andricconstexpr bool operator>=(strong_ordering __v, _CmpUnspecifiedParam) noexcept { 529*4ba319b5SDimitry Andric return __v.__value_ >= 0; 530*4ba319b5SDimitry Andric} 531*4ba319b5SDimitry Andric_LIBCPP_INLINE_VISIBILITY 532*4ba319b5SDimitry Andricconstexpr bool operator==(_CmpUnspecifiedParam, strong_ordering __v) noexcept { 533*4ba319b5SDimitry Andric return 0 == __v.__value_; 534*4ba319b5SDimitry Andric} 535*4ba319b5SDimitry Andric_LIBCPP_INLINE_VISIBILITY 536*4ba319b5SDimitry Andricconstexpr bool operator!=(_CmpUnspecifiedParam, strong_ordering __v) noexcept { 537*4ba319b5SDimitry Andric return 0 != __v.__value_; 538*4ba319b5SDimitry Andric} 539*4ba319b5SDimitry Andric_LIBCPP_INLINE_VISIBILITY 540*4ba319b5SDimitry Andricconstexpr bool operator< (_CmpUnspecifiedParam, strong_ordering __v) noexcept { 541*4ba319b5SDimitry Andric return 0 < __v.__value_; 542*4ba319b5SDimitry Andric} 543*4ba319b5SDimitry Andric_LIBCPP_INLINE_VISIBILITY 544*4ba319b5SDimitry Andricconstexpr bool operator<=(_CmpUnspecifiedParam, strong_ordering __v) noexcept { 545*4ba319b5SDimitry Andric return 0 <= __v.__value_; 546*4ba319b5SDimitry Andric} 547*4ba319b5SDimitry Andric_LIBCPP_INLINE_VISIBILITY 548*4ba319b5SDimitry Andricconstexpr bool operator> (_CmpUnspecifiedParam, strong_ordering __v) noexcept { 549*4ba319b5SDimitry Andric return 0 > __v.__value_; 550*4ba319b5SDimitry Andric} 551*4ba319b5SDimitry Andric_LIBCPP_INLINE_VISIBILITY 552*4ba319b5SDimitry Andricconstexpr bool operator>=(_CmpUnspecifiedParam, strong_ordering __v) noexcept { 553*4ba319b5SDimitry Andric return 0 >= __v.__value_; 554*4ba319b5SDimitry Andric} 555*4ba319b5SDimitry Andric 556*4ba319b5SDimitry Andric#ifndef _LIBCPP_HAS_NO_SPACESHIP_OPERATOR 557*4ba319b5SDimitry Andric_LIBCPP_INLINE_VISIBILITY 558*4ba319b5SDimitry Andricconstexpr strong_ordering operator<=>(strong_ordering __v, _CmpUnspecifiedParam) noexcept { 559*4ba319b5SDimitry Andric return __v; 560*4ba319b5SDimitry Andric} 561*4ba319b5SDimitry Andric_LIBCPP_INLINE_VISIBILITY 562*4ba319b5SDimitry Andricconstexpr strong_ordering operator<=>(_CmpUnspecifiedParam, strong_ordering __v) noexcept { 563*4ba319b5SDimitry Andric return __v < 0 ? strong_ordering::greater : (__v > 0 ? strong_ordering::less : __v); 564*4ba319b5SDimitry Andric} 565*4ba319b5SDimitry Andric#endif // _LIBCPP_HAS_NO_SPACESHIP_OPERATOR 566*4ba319b5SDimitry Andric 567*4ba319b5SDimitry Andric// named comparison functions 568*4ba319b5SDimitry Andric_LIBCPP_INLINE_VISIBILITY 569*4ba319b5SDimitry Andricconstexpr bool is_eq(weak_equality __cmp) noexcept { return __cmp == 0; } 570*4ba319b5SDimitry Andric 571*4ba319b5SDimitry Andric_LIBCPP_INLINE_VISIBILITY 572*4ba319b5SDimitry Andricconstexpr bool is_neq(weak_equality __cmp) noexcept { return __cmp != 0; } 573*4ba319b5SDimitry Andric 574*4ba319b5SDimitry Andric_LIBCPP_INLINE_VISIBILITY 575*4ba319b5SDimitry Andricconstexpr bool is_lt(partial_ordering __cmp) noexcept { return __cmp < 0; } 576*4ba319b5SDimitry Andric 577*4ba319b5SDimitry Andric_LIBCPP_INLINE_VISIBILITY 578*4ba319b5SDimitry Andricconstexpr bool is_lteq(partial_ordering __cmp) noexcept { return __cmp <= 0; } 579*4ba319b5SDimitry Andric 580*4ba319b5SDimitry Andric_LIBCPP_INLINE_VISIBILITY 581*4ba319b5SDimitry Andricconstexpr bool is_gt(partial_ordering __cmp) noexcept { return __cmp > 0; } 582*4ba319b5SDimitry Andric 583*4ba319b5SDimitry Andric_LIBCPP_INLINE_VISIBILITY 584*4ba319b5SDimitry Andricconstexpr bool is_gteq(partial_ordering __cmp) noexcept { return __cmp >= 0; } 585*4ba319b5SDimitry Andric 586*4ba319b5SDimitry Andricnamespace __comp_detail { 587*4ba319b5SDimitry Andric 588*4ba319b5SDimitry Andricenum _ClassifyCompCategory : unsigned{ 589*4ba319b5SDimitry Andric _None, 590*4ba319b5SDimitry Andric _WeakEq, 591*4ba319b5SDimitry Andric _StrongEq, 592*4ba319b5SDimitry Andric _PartialOrd, 593*4ba319b5SDimitry Andric _WeakOrd, 594*4ba319b5SDimitry Andric _StrongOrd, 595*4ba319b5SDimitry Andric _CCC_Size 596*4ba319b5SDimitry Andric}; 597*4ba319b5SDimitry Andric 598*4ba319b5SDimitry Andrictemplate <class _Tp> 599*4ba319b5SDimitry Andric_LIBCPP_INLINE_VISIBILITY 600*4ba319b5SDimitry Andricconstexpr _ClassifyCompCategory __type_to_enum() noexcept { 601*4ba319b5SDimitry Andric if (is_same_v<_Tp, weak_equality>) 602*4ba319b5SDimitry Andric return _WeakEq; 603*4ba319b5SDimitry Andric if (is_same_v<_Tp, strong_equality>) 604*4ba319b5SDimitry Andric return _StrongEq; 605*4ba319b5SDimitry Andric if (is_same_v<_Tp, partial_ordering>) 606*4ba319b5SDimitry Andric return _PartialOrd; 607*4ba319b5SDimitry Andric if (is_same_v<_Tp, weak_ordering>) 608*4ba319b5SDimitry Andric return _WeakOrd; 609*4ba319b5SDimitry Andric if (is_same_v<_Tp, strong_ordering>) 610*4ba319b5SDimitry Andric return _StrongOrd; 611*4ba319b5SDimitry Andric return _None; 612*4ba319b5SDimitry Andric} 613*4ba319b5SDimitry Andric 614*4ba319b5SDimitry Andrictemplate <size_t _Size> 615*4ba319b5SDimitry Andricconstexpr _ClassifyCompCategory 616*4ba319b5SDimitry Andric__compute_comp_type(std::array<_ClassifyCompCategory, _Size> __types) { 617*4ba319b5SDimitry Andric std::array<int, _CCC_Size> __seen = {}; 618*4ba319b5SDimitry Andric for (auto __type : __types) 619*4ba319b5SDimitry Andric ++__seen[__type]; 620*4ba319b5SDimitry Andric if (__seen[_None]) 621*4ba319b5SDimitry Andric return _None; 622*4ba319b5SDimitry Andric if (__seen[_WeakEq]) 623*4ba319b5SDimitry Andric return _WeakEq; 624*4ba319b5SDimitry Andric if (__seen[_StrongEq] && (__seen[_PartialOrd] || __seen[_WeakOrd])) 625*4ba319b5SDimitry Andric return _WeakEq; 626*4ba319b5SDimitry Andric if (__seen[_StrongEq]) 627*4ba319b5SDimitry Andric return _StrongEq; 628*4ba319b5SDimitry Andric if (__seen[_PartialOrd]) 629*4ba319b5SDimitry Andric return _PartialOrd; 630*4ba319b5SDimitry Andric if (__seen[_WeakOrd]) 631*4ba319b5SDimitry Andric return _WeakOrd; 632*4ba319b5SDimitry Andric return _StrongOrd; 633*4ba319b5SDimitry Andric} 634*4ba319b5SDimitry Andric 635*4ba319b5SDimitry Andrictemplate <class ..._Ts> 636*4ba319b5SDimitry Andricconstexpr auto __get_comp_type() { 637*4ba319b5SDimitry Andric using _CCC = _ClassifyCompCategory; 638*4ba319b5SDimitry Andric constexpr array<_CCC, sizeof...(_Ts)> __type_kinds{{__comp_detail::__type_to_enum<_Ts>()...}}; 639*4ba319b5SDimitry Andric constexpr _CCC _Cat = sizeof...(_Ts) == 0 ? _StrongOrd 640*4ba319b5SDimitry Andric : __compute_comp_type(__type_kinds); 641*4ba319b5SDimitry Andric if constexpr (_Cat == _None) 642*4ba319b5SDimitry Andric return void(); 643*4ba319b5SDimitry Andric else if constexpr (_Cat == _WeakEq) 644*4ba319b5SDimitry Andric return weak_equality::equivalent; 645*4ba319b5SDimitry Andric else if constexpr (_Cat == _StrongEq) 646*4ba319b5SDimitry Andric return strong_equality::equivalent; 647*4ba319b5SDimitry Andric else if constexpr (_Cat == _PartialOrd) 648*4ba319b5SDimitry Andric return partial_ordering::equivalent; 649*4ba319b5SDimitry Andric else if constexpr (_Cat == _WeakOrd) 650*4ba319b5SDimitry Andric return weak_ordering::equivalent; 651*4ba319b5SDimitry Andric else if constexpr (_Cat == _StrongOrd) 652*4ba319b5SDimitry Andric return strong_ordering::equivalent; 653*4ba319b5SDimitry Andric else 654*4ba319b5SDimitry Andric static_assert(_Cat != _Cat, "unhandled case"); 655*4ba319b5SDimitry Andric} 656*4ba319b5SDimitry Andric} // namespace __comp_detail 657*4ba319b5SDimitry Andric 658*4ba319b5SDimitry Andric// [cmp.common], common comparison category type 659*4ba319b5SDimitry Andrictemplate<class... _Ts> 660*4ba319b5SDimitry Andricstruct _LIBCPP_TEMPLATE_VIS common_comparison_category { 661*4ba319b5SDimitry Andric using type = decltype(__comp_detail::__get_comp_type<_Ts...>()); 662*4ba319b5SDimitry Andric}; 663*4ba319b5SDimitry Andric 664*4ba319b5SDimitry Andrictemplate<class... _Ts> 665*4ba319b5SDimitry Andricusing common_comparison_category_t = typename common_comparison_category<_Ts...>::type; 666*4ba319b5SDimitry Andric 667*4ba319b5SDimitry Andric// [cmp.alg], comparison algorithms 668*4ba319b5SDimitry Andric// TODO: unimplemented 669*4ba319b5SDimitry Andrictemplate<class _Tp> constexpr strong_ordering strong_order(const _Tp& __lhs, const _Tp& __rhs); 670*4ba319b5SDimitry Andrictemplate<class _Tp> constexpr weak_ordering weak_order(const _Tp& __lhs, const _Tp& __rhs); 671*4ba319b5SDimitry Andrictemplate<class _Tp> constexpr partial_ordering partial_order(const _Tp& __lhs, const _Tp& __rhs); 672*4ba319b5SDimitry Andrictemplate<class _Tp> constexpr strong_equality strong_equal(const _Tp& __lhs, const _Tp& __rhs); 673*4ba319b5SDimitry Andrictemplate<class _Tp> constexpr weak_equality weak_equal(const _Tp& __lhs, const _Tp& __rhs); 674*4ba319b5SDimitry Andric 675*4ba319b5SDimitry Andric#endif // _LIBCPP_STD_VER > 17 676*4ba319b5SDimitry Andric 677*4ba319b5SDimitry Andric_LIBCPP_END_NAMESPACE_STD 678*4ba319b5SDimitry Andric 679*4ba319b5SDimitry Andric#endif // _LIBCPP_COMPARE 680