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