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