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