1*4d6fc14bSjoerg// -*- C++ -*- 2*4d6fc14bSjoerg//===-------------------------- compare -----------------------------------===// 3*4d6fc14bSjoerg// 4*4d6fc14bSjoerg// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 5*4d6fc14bSjoerg// See https://llvm.org/LICENSE.txt for license information. 6*4d6fc14bSjoerg// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 7*4d6fc14bSjoerg// 8*4d6fc14bSjoerg//===----------------------------------------------------------------------===// 9*4d6fc14bSjoerg 10*4d6fc14bSjoerg#ifndef _LIBCPP_COMPARE 11*4d6fc14bSjoerg#define _LIBCPP_COMPARE 12*4d6fc14bSjoerg 13*4d6fc14bSjoerg/* 14*4d6fc14bSjoerg compare synopsis 15*4d6fc14bSjoerg 16*4d6fc14bSjoergnamespace std { 17*4d6fc14bSjoerg // [cmp.categories], comparison category types 18*4d6fc14bSjoerg class partial_ordering; 19*4d6fc14bSjoerg class weak_ordering; 20*4d6fc14bSjoerg class strong_ordering; 21*4d6fc14bSjoerg 22*4d6fc14bSjoerg // named comparison functions 23*4d6fc14bSjoerg constexpr bool is_eq (partial_ordering cmp) noexcept { return cmp == 0; } 24*4d6fc14bSjoerg constexpr bool is_neq (partial_ordering cmp) noexcept { return cmp != 0; } 25*4d6fc14bSjoerg constexpr bool is_lt (partial_ordering cmp) noexcept { return cmp < 0; } 26*4d6fc14bSjoerg constexpr bool is_lteq(partial_ordering cmp) noexcept { return cmp <= 0; } 27*4d6fc14bSjoerg constexpr bool is_gt (partial_ordering cmp) noexcept { return cmp > 0; } 28*4d6fc14bSjoerg constexpr bool is_gteq(partial_ordering cmp) noexcept { return cmp >= 0; } 29*4d6fc14bSjoerg 30*4d6fc14bSjoerg // [cmp.common], common comparison category type 31*4d6fc14bSjoerg template<class... Ts> 32*4d6fc14bSjoerg struct common_comparison_category { 33*4d6fc14bSjoerg using type = see below; 34*4d6fc14bSjoerg }; 35*4d6fc14bSjoerg template<class... Ts> 36*4d6fc14bSjoerg using common_comparison_category_t = typename common_comparison_category<Ts...>::type; 37*4d6fc14bSjoerg 38*4d6fc14bSjoerg // [cmp.alg], comparison algorithms 39*4d6fc14bSjoerg template<class T> constexpr strong_ordering strong_order(const T& a, const T& b); 40*4d6fc14bSjoerg template<class T> constexpr weak_ordering weak_order(const T& a, const T& b); 41*4d6fc14bSjoerg template<class T> constexpr partial_ordering partial_order(const T& a, const T& b); 42*4d6fc14bSjoerg 43*4d6fc14bSjoerg // [cmp.partialord], Class partial_ordering 44*4d6fc14bSjoerg class partial_ordering { 45*4d6fc14bSjoerg public: 46*4d6fc14bSjoerg // valid values 47*4d6fc14bSjoerg static const partial_ordering less; 48*4d6fc14bSjoerg static const partial_ordering equivalent; 49*4d6fc14bSjoerg static const partial_ordering greater; 50*4d6fc14bSjoerg static const partial_ordering unordered; 51*4d6fc14bSjoerg 52*4d6fc14bSjoerg // comparisons 53*4d6fc14bSjoerg friend constexpr bool operator==(partial_ordering v, unspecified) noexcept; 54*4d6fc14bSjoerg friend constexpr bool operator==(partial_ordering v, partial_ordering w) noexcept = default; 55*4d6fc14bSjoerg friend constexpr bool operator< (partial_ordering v, unspecified) noexcept; 56*4d6fc14bSjoerg friend constexpr bool operator> (partial_ordering v, unspecified) noexcept; 57*4d6fc14bSjoerg friend constexpr bool operator<=(partial_ordering v, unspecified) noexcept; 58*4d6fc14bSjoerg friend constexpr bool operator>=(partial_ordering v, unspecified) noexcept; 59*4d6fc14bSjoerg friend constexpr bool operator< (unspecified, partial_ordering v) noexcept; 60*4d6fc14bSjoerg friend constexpr bool operator> (unspecified, partial_ordering v) noexcept; 61*4d6fc14bSjoerg friend constexpr bool operator<=(unspecified, partial_ordering v) noexcept; 62*4d6fc14bSjoerg friend constexpr bool operator>=(unspecified, partial_ordering v) noexcept; 63*4d6fc14bSjoerg friend constexpr partial_ordering operator<=>(partial_ordering v, unspecified) noexcept; 64*4d6fc14bSjoerg friend constexpr partial_ordering operator<=>(unspecified, partial_ordering v) noexcept; 65*4d6fc14bSjoerg }; 66*4d6fc14bSjoerg 67*4d6fc14bSjoerg // [cmp.weakord], Class weak_ordering 68*4d6fc14bSjoerg class weak_ordering { 69*4d6fc14bSjoerg public: 70*4d6fc14bSjoerg // valid values 71*4d6fc14bSjoerg static const weak_ordering less; 72*4d6fc14bSjoerg static const weak_ordering equivalent; 73*4d6fc14bSjoerg static const weak_ordering greater; 74*4d6fc14bSjoerg 75*4d6fc14bSjoerg // conversions 76*4d6fc14bSjoerg constexpr operator partial_ordering() const noexcept; 77*4d6fc14bSjoerg 78*4d6fc14bSjoerg // comparisons 79*4d6fc14bSjoerg friend constexpr bool operator==(weak_ordering v, unspecified) noexcept; 80*4d6fc14bSjoerg friend constexpr bool operator==(weak_ordering v, weak_ordering w) noexcept = default; 81*4d6fc14bSjoerg friend constexpr bool operator< (weak_ordering v, unspecified) noexcept; 82*4d6fc14bSjoerg friend constexpr bool operator> (weak_ordering v, unspecified) noexcept; 83*4d6fc14bSjoerg friend constexpr bool operator<=(weak_ordering v, unspecified) noexcept; 84*4d6fc14bSjoerg friend constexpr bool operator>=(weak_ordering v, unspecified) noexcept; 85*4d6fc14bSjoerg friend constexpr bool operator< (unspecified, weak_ordering v) noexcept; 86*4d6fc14bSjoerg friend constexpr bool operator> (unspecified, weak_ordering v) noexcept; 87*4d6fc14bSjoerg friend constexpr bool operator<=(unspecified, weak_ordering v) noexcept; 88*4d6fc14bSjoerg friend constexpr bool operator>=(unspecified, weak_ordering v) noexcept; 89*4d6fc14bSjoerg friend constexpr weak_ordering operator<=>(weak_ordering v, unspecified) noexcept; 90*4d6fc14bSjoerg friend constexpr weak_ordering operator<=>(unspecified, weak_ordering v) noexcept; 91*4d6fc14bSjoerg }; 92*4d6fc14bSjoerg 93*4d6fc14bSjoerg // [cmp.strongord], Class strong_ordering 94*4d6fc14bSjoerg class strong_ordering { 95*4d6fc14bSjoerg public: 96*4d6fc14bSjoerg // valid values 97*4d6fc14bSjoerg static const strong_ordering less; 98*4d6fc14bSjoerg static const strong_ordering equal; 99*4d6fc14bSjoerg static const strong_ordering equivalent; 100*4d6fc14bSjoerg static const strong_ordering greater; 101*4d6fc14bSjoerg 102*4d6fc14bSjoerg // conversions 103*4d6fc14bSjoerg constexpr operator partial_ordering() const noexcept; 104*4d6fc14bSjoerg constexpr operator weak_ordering() const noexcept; 105*4d6fc14bSjoerg 106*4d6fc14bSjoerg // comparisons 107*4d6fc14bSjoerg friend constexpr bool operator==(strong_ordering v, unspecified) noexcept; 108*4d6fc14bSjoerg friend constexpr bool operator==(strong_ordering v, strong_ordering w) noexcept = default; 109*4d6fc14bSjoerg friend constexpr bool operator< (strong_ordering v, unspecified) noexcept; 110*4d6fc14bSjoerg friend constexpr bool operator> (strong_ordering v, unspecified) noexcept; 111*4d6fc14bSjoerg friend constexpr bool operator<=(strong_ordering v, unspecified) noexcept; 112*4d6fc14bSjoerg friend constexpr bool operator>=(strong_ordering v, unspecified) noexcept; 113*4d6fc14bSjoerg friend constexpr bool operator< (unspecified, strong_ordering v) noexcept; 114*4d6fc14bSjoerg friend constexpr bool operator> (unspecified, strong_ordering v) noexcept; 115*4d6fc14bSjoerg friend constexpr bool operator<=(unspecified, strong_ordering v) noexcept; 116*4d6fc14bSjoerg friend constexpr bool operator>=(unspecified, strong_ordering v) noexcept; 117*4d6fc14bSjoerg friend constexpr strong_ordering operator<=>(strong_ordering v, unspecified) noexcept; 118*4d6fc14bSjoerg friend constexpr strong_ordering operator<=>(unspecified, strong_ordering v) noexcept; 119*4d6fc14bSjoerg }; 120*4d6fc14bSjoerg} 121*4d6fc14bSjoerg*/ 122*4d6fc14bSjoerg 123*4d6fc14bSjoerg#include <__config> 124*4d6fc14bSjoerg#include <type_traits> 125*4d6fc14bSjoerg 126*4d6fc14bSjoerg#ifndef _LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER 127*4d6fc14bSjoerg#pragma GCC system_header 128*4d6fc14bSjoerg#endif 129*4d6fc14bSjoerg 130*4d6fc14bSjoerg_LIBCPP_BEGIN_NAMESPACE_STD 131*4d6fc14bSjoerg 132*4d6fc14bSjoerg#if _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_SPACESHIP_OPERATOR) 133*4d6fc14bSjoerg// exposition only 134*4d6fc14bSjoergenum class _LIBCPP_ENUM_VIS _EqResult : unsigned char { 135*4d6fc14bSjoerg __zero = 0, 136*4d6fc14bSjoerg __equal = __zero, 137*4d6fc14bSjoerg __equiv = __equal, 138*4d6fc14bSjoerg __nonequal = 1, 139*4d6fc14bSjoerg __nonequiv = __nonequal 140*4d6fc14bSjoerg}; 141*4d6fc14bSjoerg 142*4d6fc14bSjoergenum class _LIBCPP_ENUM_VIS _OrdResult : signed char { 143*4d6fc14bSjoerg __less = -1, 144*4d6fc14bSjoerg __greater = 1 145*4d6fc14bSjoerg}; 146*4d6fc14bSjoerg 147*4d6fc14bSjoergenum class _LIBCPP_ENUM_VIS _NCmpResult : signed char { 148*4d6fc14bSjoerg __unordered = -127 149*4d6fc14bSjoerg}; 150*4d6fc14bSjoerg 151*4d6fc14bSjoergclass partial_ordering; 152*4d6fc14bSjoergclass weak_ordering; 153*4d6fc14bSjoergclass strong_ordering; 154*4d6fc14bSjoerg 155*4d6fc14bSjoergtemplate<class _Tp, class... _Args> 156*4d6fc14bSjoerginline constexpr bool __one_of_v = (is_same_v<_Tp, _Args> || ...); 157*4d6fc14bSjoerg 158*4d6fc14bSjoergstruct _CmpUnspecifiedParam { 159*4d6fc14bSjoerg _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEVAL 160*4d6fc14bSjoerg _CmpUnspecifiedParam(int _CmpUnspecifiedParam::*) noexcept {} 161*4d6fc14bSjoerg 162*4d6fc14bSjoerg template<class _Tp, class = enable_if_t<!__one_of_v<_Tp, int, partial_ordering, weak_ordering, strong_ordering>>> 163*4d6fc14bSjoerg _CmpUnspecifiedParam(_Tp) = delete; 164*4d6fc14bSjoerg}; 165*4d6fc14bSjoerg 166*4d6fc14bSjoergclass partial_ordering { 167*4d6fc14bSjoerg using _ValueT = signed char; 168*4d6fc14bSjoerg 169*4d6fc14bSjoerg _LIBCPP_INLINE_VISIBILITY 170*4d6fc14bSjoerg explicit constexpr partial_ordering(_EqResult __v) noexcept 171*4d6fc14bSjoerg : __value_(_ValueT(__v)) {} 172*4d6fc14bSjoerg 173*4d6fc14bSjoerg _LIBCPP_INLINE_VISIBILITY 174*4d6fc14bSjoerg explicit constexpr partial_ordering(_OrdResult __v) noexcept 175*4d6fc14bSjoerg : __value_(_ValueT(__v)) {} 176*4d6fc14bSjoerg 177*4d6fc14bSjoerg _LIBCPP_INLINE_VISIBILITY 178*4d6fc14bSjoerg explicit constexpr partial_ordering(_NCmpResult __v) noexcept 179*4d6fc14bSjoerg : __value_(_ValueT(__v)) {} 180*4d6fc14bSjoerg 181*4d6fc14bSjoerg constexpr bool __is_ordered() const noexcept { 182*4d6fc14bSjoerg return __value_ != _ValueT(_NCmpResult::__unordered); 183*4d6fc14bSjoerg } 184*4d6fc14bSjoergpublic: 185*4d6fc14bSjoerg // valid values 186*4d6fc14bSjoerg static const partial_ordering less; 187*4d6fc14bSjoerg static const partial_ordering equivalent; 188*4d6fc14bSjoerg static const partial_ordering greater; 189*4d6fc14bSjoerg static const partial_ordering unordered; 190*4d6fc14bSjoerg 191*4d6fc14bSjoerg // comparisons 192*4d6fc14bSjoerg _LIBCPP_INLINE_VISIBILITY friend constexpr bool operator==(partial_ordering, partial_ordering) noexcept = default; 193*4d6fc14bSjoerg 194*4d6fc14bSjoerg _LIBCPP_INLINE_VISIBILITY friend constexpr bool operator==(partial_ordering __v, _CmpUnspecifiedParam) noexcept { 195*4d6fc14bSjoerg return __v.__is_ordered() && __v.__value_ == 0; 196*4d6fc14bSjoerg } 197*4d6fc14bSjoerg 198*4d6fc14bSjoerg _LIBCPP_INLINE_VISIBILITY friend constexpr bool operator< (partial_ordering __v, _CmpUnspecifiedParam) noexcept { 199*4d6fc14bSjoerg return __v.__is_ordered() && __v.__value_ < 0; 200*4d6fc14bSjoerg } 201*4d6fc14bSjoerg 202*4d6fc14bSjoerg _LIBCPP_INLINE_VISIBILITY friend constexpr bool operator<=(partial_ordering __v, _CmpUnspecifiedParam) noexcept { 203*4d6fc14bSjoerg return __v.__is_ordered() && __v.__value_ <= 0; 204*4d6fc14bSjoerg } 205*4d6fc14bSjoerg 206*4d6fc14bSjoerg _LIBCPP_INLINE_VISIBILITY friend constexpr bool operator> (partial_ordering __v, _CmpUnspecifiedParam) noexcept { 207*4d6fc14bSjoerg return __v.__is_ordered() && __v.__value_ > 0; 208*4d6fc14bSjoerg } 209*4d6fc14bSjoerg 210*4d6fc14bSjoerg _LIBCPP_INLINE_VISIBILITY friend constexpr bool operator>=(partial_ordering __v, _CmpUnspecifiedParam) noexcept { 211*4d6fc14bSjoerg return __v.__is_ordered() && __v.__value_ >= 0; 212*4d6fc14bSjoerg } 213*4d6fc14bSjoerg 214*4d6fc14bSjoerg _LIBCPP_INLINE_VISIBILITY friend constexpr bool operator< (_CmpUnspecifiedParam, partial_ordering __v) noexcept { 215*4d6fc14bSjoerg return __v.__is_ordered() && 0 < __v.__value_; 216*4d6fc14bSjoerg } 217*4d6fc14bSjoerg 218*4d6fc14bSjoerg _LIBCPP_INLINE_VISIBILITY friend constexpr bool operator<=(_CmpUnspecifiedParam, partial_ordering __v) noexcept { 219*4d6fc14bSjoerg return __v.__is_ordered() && 0 <= __v.__value_; 220*4d6fc14bSjoerg } 221*4d6fc14bSjoerg 222*4d6fc14bSjoerg _LIBCPP_INLINE_VISIBILITY friend constexpr bool operator> (_CmpUnspecifiedParam, partial_ordering __v) noexcept { 223*4d6fc14bSjoerg return __v.__is_ordered() && 0 > __v.__value_; 224*4d6fc14bSjoerg } 225*4d6fc14bSjoerg 226*4d6fc14bSjoerg _LIBCPP_INLINE_VISIBILITY friend constexpr bool operator>=(_CmpUnspecifiedParam, partial_ordering __v) noexcept { 227*4d6fc14bSjoerg return __v.__is_ordered() && 0 >= __v.__value_; 228*4d6fc14bSjoerg } 229*4d6fc14bSjoerg 230*4d6fc14bSjoerg _LIBCPP_INLINE_VISIBILITY friend constexpr partial_ordering operator<=>(partial_ordering __v, _CmpUnspecifiedParam) noexcept { 231*4d6fc14bSjoerg return __v; 232*4d6fc14bSjoerg } 233*4d6fc14bSjoerg 234*4d6fc14bSjoerg _LIBCPP_INLINE_VISIBILITY friend constexpr partial_ordering operator<=>(_CmpUnspecifiedParam, partial_ordering __v) noexcept { 235*4d6fc14bSjoerg return __v < 0 ? partial_ordering::greater : (__v > 0 ? partial_ordering::less : __v); 236*4d6fc14bSjoerg } 237*4d6fc14bSjoergprivate: 238*4d6fc14bSjoerg _ValueT __value_; 239*4d6fc14bSjoerg}; 240*4d6fc14bSjoerg 241*4d6fc14bSjoerg_LIBCPP_INLINE_VAR constexpr partial_ordering partial_ordering::less(_OrdResult::__less); 242*4d6fc14bSjoerg_LIBCPP_INLINE_VAR constexpr partial_ordering partial_ordering::equivalent(_EqResult::__equiv); 243*4d6fc14bSjoerg_LIBCPP_INLINE_VAR constexpr partial_ordering partial_ordering::greater(_OrdResult::__greater); 244*4d6fc14bSjoerg_LIBCPP_INLINE_VAR constexpr partial_ordering partial_ordering::unordered(_NCmpResult ::__unordered); 245*4d6fc14bSjoerg 246*4d6fc14bSjoergclass weak_ordering { 247*4d6fc14bSjoerg using _ValueT = signed char; 248*4d6fc14bSjoerg 249*4d6fc14bSjoerg _LIBCPP_INLINE_VISIBILITY 250*4d6fc14bSjoerg explicit constexpr weak_ordering(_EqResult __v) noexcept : __value_(_ValueT(__v)) {} 251*4d6fc14bSjoerg _LIBCPP_INLINE_VISIBILITY 252*4d6fc14bSjoerg explicit constexpr weak_ordering(_OrdResult __v) noexcept : __value_(_ValueT(__v)) {} 253*4d6fc14bSjoerg 254*4d6fc14bSjoergpublic: 255*4d6fc14bSjoerg static const weak_ordering less; 256*4d6fc14bSjoerg static const weak_ordering equivalent; 257*4d6fc14bSjoerg static const weak_ordering greater; 258*4d6fc14bSjoerg 259*4d6fc14bSjoerg _LIBCPP_INLINE_VISIBILITY 260*4d6fc14bSjoerg constexpr operator partial_ordering() const noexcept { 261*4d6fc14bSjoerg return __value_ == 0 ? partial_ordering::equivalent 262*4d6fc14bSjoerg : (__value_ < 0 ? partial_ordering::less : partial_ordering::greater); 263*4d6fc14bSjoerg } 264*4d6fc14bSjoerg 265*4d6fc14bSjoerg // comparisons 266*4d6fc14bSjoerg _LIBCPP_INLINE_VISIBILITY friend constexpr bool operator==(weak_ordering, weak_ordering) noexcept = default; 267*4d6fc14bSjoerg 268*4d6fc14bSjoerg _LIBCPP_INLINE_VISIBILITY friend constexpr bool operator==(weak_ordering __v, _CmpUnspecifiedParam) noexcept { 269*4d6fc14bSjoerg return __v.__value_ == 0; 270*4d6fc14bSjoerg } 271*4d6fc14bSjoerg 272*4d6fc14bSjoerg _LIBCPP_INLINE_VISIBILITY friend constexpr bool operator< (weak_ordering __v, _CmpUnspecifiedParam) noexcept { 273*4d6fc14bSjoerg return __v.__value_ < 0; 274*4d6fc14bSjoerg } 275*4d6fc14bSjoerg 276*4d6fc14bSjoerg _LIBCPP_INLINE_VISIBILITY friend constexpr bool operator<=(weak_ordering __v, _CmpUnspecifiedParam) noexcept { 277*4d6fc14bSjoerg return __v.__value_ <= 0; 278*4d6fc14bSjoerg } 279*4d6fc14bSjoerg 280*4d6fc14bSjoerg _LIBCPP_INLINE_VISIBILITY friend constexpr bool operator> (weak_ordering __v, _CmpUnspecifiedParam) noexcept { 281*4d6fc14bSjoerg return __v.__value_ > 0; 282*4d6fc14bSjoerg } 283*4d6fc14bSjoerg 284*4d6fc14bSjoerg _LIBCPP_INLINE_VISIBILITY friend constexpr bool operator>=(weak_ordering __v, _CmpUnspecifiedParam) noexcept { 285*4d6fc14bSjoerg return __v.__value_ >= 0; 286*4d6fc14bSjoerg } 287*4d6fc14bSjoerg 288*4d6fc14bSjoerg _LIBCPP_INLINE_VISIBILITY friend constexpr bool operator< (_CmpUnspecifiedParam, weak_ordering __v) noexcept { 289*4d6fc14bSjoerg return 0 < __v.__value_; 290*4d6fc14bSjoerg } 291*4d6fc14bSjoerg 292*4d6fc14bSjoerg _LIBCPP_INLINE_VISIBILITY friend constexpr bool operator<=(_CmpUnspecifiedParam, weak_ordering __v) noexcept { 293*4d6fc14bSjoerg return 0 <= __v.__value_; 294*4d6fc14bSjoerg } 295*4d6fc14bSjoerg 296*4d6fc14bSjoerg _LIBCPP_INLINE_VISIBILITY friend constexpr bool operator> (_CmpUnspecifiedParam, weak_ordering __v) noexcept { 297*4d6fc14bSjoerg return 0 > __v.__value_; 298*4d6fc14bSjoerg } 299*4d6fc14bSjoerg 300*4d6fc14bSjoerg _LIBCPP_INLINE_VISIBILITY friend constexpr bool operator>=(_CmpUnspecifiedParam, weak_ordering __v) noexcept { 301*4d6fc14bSjoerg return 0 >= __v.__value_; 302*4d6fc14bSjoerg } 303*4d6fc14bSjoerg 304*4d6fc14bSjoerg _LIBCPP_INLINE_VISIBILITY friend constexpr weak_ordering operator<=>(weak_ordering __v, _CmpUnspecifiedParam) noexcept { 305*4d6fc14bSjoerg return __v; 306*4d6fc14bSjoerg } 307*4d6fc14bSjoerg 308*4d6fc14bSjoerg _LIBCPP_INLINE_VISIBILITY friend constexpr weak_ordering operator<=>(_CmpUnspecifiedParam, weak_ordering __v) noexcept { 309*4d6fc14bSjoerg return __v < 0 ? weak_ordering::greater : (__v > 0 ? weak_ordering::less : __v); 310*4d6fc14bSjoerg } 311*4d6fc14bSjoerg 312*4d6fc14bSjoergprivate: 313*4d6fc14bSjoerg _ValueT __value_; 314*4d6fc14bSjoerg}; 315*4d6fc14bSjoerg 316*4d6fc14bSjoerg_LIBCPP_INLINE_VAR constexpr weak_ordering weak_ordering::less(_OrdResult::__less); 317*4d6fc14bSjoerg_LIBCPP_INLINE_VAR constexpr weak_ordering weak_ordering::equivalent(_EqResult::__equiv); 318*4d6fc14bSjoerg_LIBCPP_INLINE_VAR constexpr weak_ordering weak_ordering::greater(_OrdResult::__greater); 319*4d6fc14bSjoergclass strong_ordering { 320*4d6fc14bSjoerg using _ValueT = signed char; 321*4d6fc14bSjoerg 322*4d6fc14bSjoerg _LIBCPP_INLINE_VISIBILITY 323*4d6fc14bSjoerg explicit constexpr strong_ordering(_EqResult __v) noexcept : __value_(_ValueT(__v)) {} 324*4d6fc14bSjoerg _LIBCPP_INLINE_VISIBILITY 325*4d6fc14bSjoerg explicit constexpr strong_ordering(_OrdResult __v) noexcept : __value_(_ValueT(__v)) {} 326*4d6fc14bSjoerg 327*4d6fc14bSjoergpublic: 328*4d6fc14bSjoerg static const strong_ordering less; 329*4d6fc14bSjoerg static const strong_ordering equal; 330*4d6fc14bSjoerg static const strong_ordering equivalent; 331*4d6fc14bSjoerg static const strong_ordering greater; 332*4d6fc14bSjoerg 333*4d6fc14bSjoerg // conversions 334*4d6fc14bSjoerg _LIBCPP_INLINE_VISIBILITY 335*4d6fc14bSjoerg constexpr operator partial_ordering() const noexcept { 336*4d6fc14bSjoerg return __value_ == 0 ? partial_ordering::equivalent 337*4d6fc14bSjoerg : (__value_ < 0 ? partial_ordering::less : partial_ordering::greater); 338*4d6fc14bSjoerg } 339*4d6fc14bSjoerg 340*4d6fc14bSjoerg _LIBCPP_INLINE_VISIBILITY 341*4d6fc14bSjoerg constexpr operator weak_ordering() const noexcept { 342*4d6fc14bSjoerg return __value_ == 0 ? weak_ordering::equivalent 343*4d6fc14bSjoerg : (__value_ < 0 ? weak_ordering::less : weak_ordering::greater); 344*4d6fc14bSjoerg } 345*4d6fc14bSjoerg 346*4d6fc14bSjoerg // comparisons 347*4d6fc14bSjoerg _LIBCPP_INLINE_VISIBILITY friend constexpr bool operator==(strong_ordering, strong_ordering) noexcept = default; 348*4d6fc14bSjoerg 349*4d6fc14bSjoerg _LIBCPP_INLINE_VISIBILITY friend constexpr bool operator==(strong_ordering __v, _CmpUnspecifiedParam) noexcept { 350*4d6fc14bSjoerg return __v.__value_ == 0; 351*4d6fc14bSjoerg } 352*4d6fc14bSjoerg 353*4d6fc14bSjoerg _LIBCPP_INLINE_VISIBILITY friend constexpr bool operator< (strong_ordering __v, _CmpUnspecifiedParam) noexcept { 354*4d6fc14bSjoerg return __v.__value_ < 0; 355*4d6fc14bSjoerg } 356*4d6fc14bSjoerg 357*4d6fc14bSjoerg _LIBCPP_INLINE_VISIBILITY friend constexpr bool operator<=(strong_ordering __v, _CmpUnspecifiedParam) noexcept { 358*4d6fc14bSjoerg return __v.__value_ <= 0; 359*4d6fc14bSjoerg } 360*4d6fc14bSjoerg 361*4d6fc14bSjoerg _LIBCPP_INLINE_VISIBILITY friend constexpr bool operator> (strong_ordering __v, _CmpUnspecifiedParam) noexcept { 362*4d6fc14bSjoerg return __v.__value_ > 0; 363*4d6fc14bSjoerg } 364*4d6fc14bSjoerg 365*4d6fc14bSjoerg _LIBCPP_INLINE_VISIBILITY friend constexpr bool operator>=(strong_ordering __v, _CmpUnspecifiedParam) noexcept { 366*4d6fc14bSjoerg return __v.__value_ >= 0; 367*4d6fc14bSjoerg } 368*4d6fc14bSjoerg 369*4d6fc14bSjoerg _LIBCPP_INLINE_VISIBILITY friend constexpr bool operator< (_CmpUnspecifiedParam, strong_ordering __v) noexcept { 370*4d6fc14bSjoerg return 0 < __v.__value_; 371*4d6fc14bSjoerg } 372*4d6fc14bSjoerg 373*4d6fc14bSjoerg _LIBCPP_INLINE_VISIBILITY friend constexpr bool operator<=(_CmpUnspecifiedParam, strong_ordering __v) noexcept { 374*4d6fc14bSjoerg return 0 <= __v.__value_; 375*4d6fc14bSjoerg } 376*4d6fc14bSjoerg 377*4d6fc14bSjoerg _LIBCPP_INLINE_VISIBILITY friend constexpr bool operator> (_CmpUnspecifiedParam, strong_ordering __v) noexcept { 378*4d6fc14bSjoerg return 0 > __v.__value_; 379*4d6fc14bSjoerg } 380*4d6fc14bSjoerg 381*4d6fc14bSjoerg _LIBCPP_INLINE_VISIBILITY friend constexpr bool operator>=(_CmpUnspecifiedParam, strong_ordering __v) noexcept { 382*4d6fc14bSjoerg return 0 >= __v.__value_; 383*4d6fc14bSjoerg } 384*4d6fc14bSjoerg 385*4d6fc14bSjoerg _LIBCPP_INLINE_VISIBILITY friend constexpr strong_ordering operator<=>(strong_ordering __v, _CmpUnspecifiedParam) noexcept { 386*4d6fc14bSjoerg return __v; 387*4d6fc14bSjoerg } 388*4d6fc14bSjoerg 389*4d6fc14bSjoerg _LIBCPP_INLINE_VISIBILITY friend constexpr strong_ordering operator<=>(_CmpUnspecifiedParam, strong_ordering __v) noexcept { 390*4d6fc14bSjoerg return __v < 0 ? strong_ordering::greater : (__v > 0 ? strong_ordering::less : __v); 391*4d6fc14bSjoerg } 392*4d6fc14bSjoerg 393*4d6fc14bSjoergprivate: 394*4d6fc14bSjoerg _ValueT __value_; 395*4d6fc14bSjoerg}; 396*4d6fc14bSjoerg 397*4d6fc14bSjoerg_LIBCPP_INLINE_VAR constexpr strong_ordering strong_ordering::less(_OrdResult::__less); 398*4d6fc14bSjoerg_LIBCPP_INLINE_VAR constexpr strong_ordering strong_ordering::equal(_EqResult::__equal); 399*4d6fc14bSjoerg_LIBCPP_INLINE_VAR constexpr strong_ordering strong_ordering::equivalent(_EqResult::__equiv); 400*4d6fc14bSjoerg_LIBCPP_INLINE_VAR constexpr strong_ordering strong_ordering::greater(_OrdResult::__greater); 401*4d6fc14bSjoerg 402*4d6fc14bSjoerg// named comparison functions 403*4d6fc14bSjoerg_LIBCPP_INLINE_VISIBILITY 404*4d6fc14bSjoergconstexpr bool is_lt(partial_ordering __cmp) noexcept { return __cmp < 0; } 405*4d6fc14bSjoerg 406*4d6fc14bSjoerg_LIBCPP_INLINE_VISIBILITY 407*4d6fc14bSjoergconstexpr bool is_lteq(partial_ordering __cmp) noexcept { return __cmp <= 0; } 408*4d6fc14bSjoerg 409*4d6fc14bSjoerg_LIBCPP_INLINE_VISIBILITY 410*4d6fc14bSjoergconstexpr bool is_gt(partial_ordering __cmp) noexcept { return __cmp > 0; } 411*4d6fc14bSjoerg 412*4d6fc14bSjoerg_LIBCPP_INLINE_VISIBILITY 413*4d6fc14bSjoergconstexpr bool is_gteq(partial_ordering __cmp) noexcept { return __cmp >= 0; } 414*4d6fc14bSjoerg 415*4d6fc14bSjoergnamespace __comp_detail { 416*4d6fc14bSjoerg 417*4d6fc14bSjoergenum _ClassifyCompCategory : unsigned{ 418*4d6fc14bSjoerg _None, 419*4d6fc14bSjoerg _PartialOrd, 420*4d6fc14bSjoerg _WeakOrd, 421*4d6fc14bSjoerg _StrongOrd, 422*4d6fc14bSjoerg _CCC_Size 423*4d6fc14bSjoerg}; 424*4d6fc14bSjoerg 425*4d6fc14bSjoergtemplate <class _Tp> 426*4d6fc14bSjoerg_LIBCPP_INLINE_VISIBILITY 427*4d6fc14bSjoergconstexpr _ClassifyCompCategory __type_to_enum() noexcept { 428*4d6fc14bSjoerg if (is_same_v<_Tp, partial_ordering>) 429*4d6fc14bSjoerg return _PartialOrd; 430*4d6fc14bSjoerg if (is_same_v<_Tp, weak_ordering>) 431*4d6fc14bSjoerg return _WeakOrd; 432*4d6fc14bSjoerg if (is_same_v<_Tp, strong_ordering>) 433*4d6fc14bSjoerg return _StrongOrd; 434*4d6fc14bSjoerg return _None; 435*4d6fc14bSjoerg} 436*4d6fc14bSjoerg 437*4d6fc14bSjoergtemplate <size_t _Size> 438*4d6fc14bSjoergconstexpr _ClassifyCompCategory 439*4d6fc14bSjoerg__compute_comp_type(const _ClassifyCompCategory (&__types)[_Size]) { 440*4d6fc14bSjoerg int __seen[_CCC_Size] = {}; 441*4d6fc14bSjoerg for (auto __type : __types) 442*4d6fc14bSjoerg ++__seen[__type]; 443*4d6fc14bSjoerg if (__seen[_None]) 444*4d6fc14bSjoerg return _None; 445*4d6fc14bSjoerg if (__seen[_PartialOrd]) 446*4d6fc14bSjoerg return _PartialOrd; 447*4d6fc14bSjoerg if (__seen[_WeakOrd]) 448*4d6fc14bSjoerg return _WeakOrd; 449*4d6fc14bSjoerg return _StrongOrd; 450*4d6fc14bSjoerg} 451*4d6fc14bSjoerg 452*4d6fc14bSjoergtemplate <class ..._Ts> 453*4d6fc14bSjoergconstexpr auto __get_comp_type() { 454*4d6fc14bSjoerg using _CCC = _ClassifyCompCategory; 455*4d6fc14bSjoerg constexpr _CCC __type_kinds[] = {_StrongOrd, __type_to_enum<_Ts>()...}; 456*4d6fc14bSjoerg constexpr _CCC _Cat = __compute_comp_type(__type_kinds); 457*4d6fc14bSjoerg if constexpr (_Cat == _None) 458*4d6fc14bSjoerg return void(); 459*4d6fc14bSjoerg else if constexpr (_Cat == _PartialOrd) 460*4d6fc14bSjoerg return partial_ordering::equivalent; 461*4d6fc14bSjoerg else if constexpr (_Cat == _WeakOrd) 462*4d6fc14bSjoerg return weak_ordering::equivalent; 463*4d6fc14bSjoerg else if constexpr (_Cat == _StrongOrd) 464*4d6fc14bSjoerg return strong_ordering::equivalent; 465*4d6fc14bSjoerg else 466*4d6fc14bSjoerg static_assert(_Cat != _Cat, "unhandled case"); 467*4d6fc14bSjoerg} 468*4d6fc14bSjoerg} // namespace __comp_detail 469*4d6fc14bSjoerg 470*4d6fc14bSjoerg// [cmp.common], common comparison category type 471*4d6fc14bSjoergtemplate<class... _Ts> 472*4d6fc14bSjoergstruct _LIBCPP_TEMPLATE_VIS common_comparison_category { 473*4d6fc14bSjoerg using type = decltype(__comp_detail::__get_comp_type<_Ts...>()); 474*4d6fc14bSjoerg}; 475*4d6fc14bSjoerg 476*4d6fc14bSjoergtemplate<class... _Ts> 477*4d6fc14bSjoergusing common_comparison_category_t = typename common_comparison_category<_Ts...>::type; 478*4d6fc14bSjoerg 479*4d6fc14bSjoerg// [cmp.alg], comparison algorithms 480*4d6fc14bSjoerg// TODO: unimplemented 481*4d6fc14bSjoergtemplate<class _Tp> constexpr strong_ordering strong_order(const _Tp& __lhs, const _Tp& __rhs); 482*4d6fc14bSjoergtemplate<class _Tp> constexpr weak_ordering weak_order(const _Tp& __lhs, const _Tp& __rhs); 483*4d6fc14bSjoergtemplate<class _Tp> constexpr partial_ordering partial_order(const _Tp& __lhs, const _Tp& __rhs); 484*4d6fc14bSjoerg 485*4d6fc14bSjoerg#endif // _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_SPACESHIP_OPERATOR) 486*4d6fc14bSjoerg 487*4d6fc14bSjoerg_LIBCPP_END_NAMESPACE_STD 488*4d6fc14bSjoerg 489*4d6fc14bSjoerg#endif // _LIBCPP_COMPARE 490