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 130#ifndef _LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER 131#pragma GCC system_header 132#endif 133 134_LIBCPP_BEGIN_NAMESPACE_STD 135 136#if _LIBCPP_STD_VER > 17 137 138// exposition only 139enum class _LIBCPP_ENUM_VIS _EqResult : unsigned char { 140 __zero = 0, 141 __equal = __zero, 142 __equiv = __equal, 143 __nonequal = 1, 144 __nonequiv = __nonequal 145}; 146 147enum class _LIBCPP_ENUM_VIS _OrdResult : signed char { 148 __less = -1, 149 __greater = 1 150}; 151 152enum class _LIBCPP_ENUM_VIS _NCmpResult : signed char { 153 __unordered = -127 154}; 155 156struct _CmpUnspecifiedParam { 157 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEVAL 158 _CmpUnspecifiedParam(int _CmpUnspecifiedParam::*) noexcept {} 159 160 template<typename _Tp, typename = _VSTD::enable_if_t<!_VSTD::is_same_v<_Tp, int>>> 161 _CmpUnspecifiedParam(_Tp) = delete; 162}; 163 164class weak_equality { 165 _LIBCPP_INLINE_VISIBILITY 166 constexpr explicit weak_equality(_EqResult __val) noexcept : __value_(__val) {} 167 168public: 169 static const weak_equality equivalent; 170 static const weak_equality nonequivalent; 171 172 _LIBCPP_INLINE_VISIBILITY friend constexpr bool operator==(weak_equality __v, _CmpUnspecifiedParam) noexcept; 173 _LIBCPP_INLINE_VISIBILITY friend constexpr bool operator==(_CmpUnspecifiedParam, weak_equality __v) noexcept; 174 _LIBCPP_INLINE_VISIBILITY friend constexpr bool operator!=(weak_equality __v, _CmpUnspecifiedParam) noexcept; 175 _LIBCPP_INLINE_VISIBILITY friend constexpr bool operator!=(_CmpUnspecifiedParam, weak_equality __v) noexcept; 176 177#ifndef _LIBCPP_HAS_NO_SPACESHIP_OPERATOR 178 _LIBCPP_INLINE_VISIBILITY friend constexpr weak_equality operator<=>(weak_equality __v, _CmpUnspecifiedParam) noexcept; 179 _LIBCPP_INLINE_VISIBILITY friend constexpr weak_equality operator<=>(_CmpUnspecifiedParam, weak_equality __v) noexcept; 180#endif 181 182private: 183 _EqResult __value_; 184}; 185 186_LIBCPP_INLINE_VAR constexpr weak_equality weak_equality::equivalent(_EqResult::__equiv); 187_LIBCPP_INLINE_VAR constexpr weak_equality weak_equality::nonequivalent(_EqResult::__nonequiv); 188 189_LIBCPP_INLINE_VISIBILITY 190inline constexpr bool operator==(weak_equality __v, _CmpUnspecifiedParam) noexcept { 191 return __v.__value_ == _EqResult::__zero; 192} 193 194_LIBCPP_INLINE_VISIBILITY 195inline constexpr bool operator==(_CmpUnspecifiedParam, weak_equality __v) noexcept { 196 return __v.__value_ == _EqResult::__zero; 197} 198 199_LIBCPP_INLINE_VISIBILITY 200inline constexpr bool operator!=(weak_equality __v, _CmpUnspecifiedParam) noexcept { 201 return __v.__value_ != _EqResult::__zero; 202} 203 204_LIBCPP_INLINE_VISIBILITY 205inline constexpr bool operator!=(_CmpUnspecifiedParam, weak_equality __v) noexcept { 206 return __v.__value_ != _EqResult::__zero; 207} 208 209#ifndef _LIBCPP_HAS_NO_SPACESHIP_OPERATOR 210_LIBCPP_INLINE_VISIBILITY 211inline constexpr weak_equality operator<=>(weak_equality __v, _CmpUnspecifiedParam) noexcept { 212 return __v; 213} 214 215_LIBCPP_INLINE_VISIBILITY 216inline constexpr weak_equality operator<=>(_CmpUnspecifiedParam, weak_equality __v) noexcept { 217 return __v; 218} 219#endif 220 221class strong_equality { 222 _LIBCPP_INLINE_VISIBILITY 223 explicit constexpr strong_equality(_EqResult __val) noexcept : __value_(__val) {} 224 225public: 226 static const strong_equality equal; 227 static const strong_equality nonequal; 228 static const strong_equality equivalent; 229 static const strong_equality nonequivalent; 230 231 // conversion 232 _LIBCPP_INLINE_VISIBILITY constexpr operator weak_equality() const noexcept { 233 return __value_ == _EqResult::__zero ? weak_equality::equivalent 234 : weak_equality::nonequivalent; 235 } 236 237 // comparisons 238 _LIBCPP_INLINE_VISIBILITY friend constexpr bool operator==(strong_equality __v, _CmpUnspecifiedParam) noexcept; 239 _LIBCPP_INLINE_VISIBILITY friend constexpr bool operator!=(strong_equality __v, _CmpUnspecifiedParam) noexcept; 240 _LIBCPP_INLINE_VISIBILITY friend constexpr bool operator==(_CmpUnspecifiedParam, strong_equality __v) noexcept; 241 _LIBCPP_INLINE_VISIBILITY friend constexpr bool operator!=(_CmpUnspecifiedParam, strong_equality __v) noexcept; 242 243#ifndef _LIBCPP_HAS_NO_SPACESHIP_OPERATOR 244 _LIBCPP_INLINE_VISIBILITY friend constexpr strong_equality operator<=>(strong_equality __v, _CmpUnspecifiedParam) noexcept; 245 _LIBCPP_INLINE_VISIBILITY friend constexpr strong_equality operator<=>(_CmpUnspecifiedParam, strong_equality __v) noexcept; 246#endif 247private: 248 _EqResult __value_; 249}; 250 251_LIBCPP_INLINE_VAR constexpr strong_equality strong_equality::equal(_EqResult::__equal); 252_LIBCPP_INLINE_VAR constexpr strong_equality strong_equality::nonequal(_EqResult::__nonequal); 253_LIBCPP_INLINE_VAR constexpr strong_equality strong_equality::equivalent(_EqResult::__equiv); 254_LIBCPP_INLINE_VAR constexpr strong_equality strong_equality::nonequivalent(_EqResult::__nonequiv); 255 256_LIBCPP_INLINE_VISIBILITY 257constexpr bool operator==(strong_equality __v, _CmpUnspecifiedParam) noexcept { 258 return __v.__value_ == _EqResult::__zero; 259} 260 261_LIBCPP_INLINE_VISIBILITY 262constexpr bool operator==(_CmpUnspecifiedParam, strong_equality __v) noexcept { 263 return __v.__value_ == _EqResult::__zero; 264} 265 266_LIBCPP_INLINE_VISIBILITY 267constexpr bool operator!=(strong_equality __v, _CmpUnspecifiedParam) noexcept { 268 return __v.__value_ != _EqResult::__zero; 269} 270 271_LIBCPP_INLINE_VISIBILITY 272constexpr bool operator!=(_CmpUnspecifiedParam, strong_equality __v) noexcept { 273 return __v.__value_ != _EqResult::__zero; 274} 275 276#ifndef _LIBCPP_HAS_NO_SPACESHIP_OPERATOR 277_LIBCPP_INLINE_VISIBILITY 278constexpr strong_equality operator<=>(strong_equality __v, _CmpUnspecifiedParam) noexcept { 279 return __v; 280} 281 282_LIBCPP_INLINE_VISIBILITY 283constexpr strong_equality operator<=>(_CmpUnspecifiedParam, strong_equality __v) noexcept { 284 return __v; 285} 286#endif // _LIBCPP_HAS_NO_SPACESHIP_OPERATOR 287 288class partial_ordering { 289 using _ValueT = signed char; 290 291 _LIBCPP_INLINE_VISIBILITY 292 explicit constexpr partial_ordering(_EqResult __v) noexcept 293 : __value_(_ValueT(__v)) {} 294 295 _LIBCPP_INLINE_VISIBILITY 296 explicit constexpr partial_ordering(_OrdResult __v) noexcept 297 : __value_(_ValueT(__v)) {} 298 299 _LIBCPP_INLINE_VISIBILITY 300 explicit constexpr partial_ordering(_NCmpResult __v) noexcept 301 : __value_(_ValueT(__v)) {} 302 303 constexpr bool __is_ordered() const noexcept { 304 return __value_ != _ValueT(_NCmpResult::__unordered); 305 } 306public: 307 // valid values 308 static const partial_ordering less; 309 static const partial_ordering equivalent; 310 static const partial_ordering greater; 311 static const partial_ordering unordered; 312 313 // conversion 314 constexpr operator weak_equality() const noexcept { 315 return __value_ == 0 ? weak_equality::equivalent : weak_equality::nonequivalent; 316 } 317 318 // comparisons 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< (partial_ordering __v, _CmpUnspecifiedParam) noexcept; 322 _LIBCPP_INLINE_VISIBILITY friend constexpr bool operator<=(partial_ordering __v, _CmpUnspecifiedParam) noexcept; 323 _LIBCPP_INLINE_VISIBILITY friend constexpr bool operator> (partial_ordering __v, _CmpUnspecifiedParam) noexcept; 324 _LIBCPP_INLINE_VISIBILITY friend constexpr bool operator>=(partial_ordering __v, _CmpUnspecifiedParam) 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 _LIBCPP_INLINE_VISIBILITY friend constexpr bool operator< (_CmpUnspecifiedParam, partial_ordering __v) noexcept; 328 _LIBCPP_INLINE_VISIBILITY friend constexpr bool operator<=(_CmpUnspecifiedParam, partial_ordering __v) noexcept; 329 _LIBCPP_INLINE_VISIBILITY friend constexpr bool operator> (_CmpUnspecifiedParam, partial_ordering __v) noexcept; 330 _LIBCPP_INLINE_VISIBILITY friend constexpr bool operator>=(_CmpUnspecifiedParam, partial_ordering __v) noexcept; 331 332#ifndef _LIBCPP_HAS_NO_SPACESHIP_OPERATOR 333 _LIBCPP_INLINE_VISIBILITY friend constexpr bool operator==(partial_ordering, partial_ordering) noexcept = default; 334 335 _LIBCPP_INLINE_VISIBILITY friend constexpr partial_ordering operator<=>(partial_ordering __v, _CmpUnspecifiedParam) noexcept; 336 _LIBCPP_INLINE_VISIBILITY friend constexpr partial_ordering operator<=>(_CmpUnspecifiedParam, partial_ordering __v) noexcept; 337#endif 338 339private: 340 _ValueT __value_; 341}; 342 343_LIBCPP_INLINE_VAR constexpr partial_ordering partial_ordering::less(_OrdResult::__less); 344_LIBCPP_INLINE_VAR constexpr partial_ordering partial_ordering::equivalent(_EqResult::__equiv); 345_LIBCPP_INLINE_VAR constexpr partial_ordering partial_ordering::greater(_OrdResult::__greater); 346_LIBCPP_INLINE_VAR constexpr partial_ordering partial_ordering::unordered(_NCmpResult ::__unordered); 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_LIBCPP_INLINE_VISIBILITY 365constexpr bool operator>=(partial_ordering __v, _CmpUnspecifiedParam) noexcept { 366 return __v.__is_ordered() && __v.__value_ >= 0; 367} 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_LIBCPP_INLINE_VISIBILITY 386constexpr bool operator>=(_CmpUnspecifiedParam, partial_ordering __v) noexcept { 387 return __v.__is_ordered() && 0 >= __v.__value_; 388} 389 390_LIBCPP_INLINE_VISIBILITY 391constexpr bool operator!=(partial_ordering __v, _CmpUnspecifiedParam) noexcept { 392 return !__v.__is_ordered() || __v.__value_ != 0; 393} 394_LIBCPP_INLINE_VISIBILITY 395constexpr bool operator!=(_CmpUnspecifiedParam, partial_ordering __v) noexcept { 396 return !__v.__is_ordered() || __v.__value_ != 0; 397} 398 399#ifndef _LIBCPP_HAS_NO_SPACESHIP_OPERATOR 400_LIBCPP_INLINE_VISIBILITY 401constexpr partial_ordering operator<=>(partial_ordering __v, _CmpUnspecifiedParam) noexcept { 402 return __v; 403} 404_LIBCPP_INLINE_VISIBILITY 405constexpr partial_ordering operator<=>(_CmpUnspecifiedParam, partial_ordering __v) noexcept { 406 return __v < 0 ? partial_ordering::greater : (__v > 0 ? partial_ordering::less : __v); 407} 408#endif // _LIBCPP_HAS_NO_SPACESHIP_OPERATOR 409 410class weak_ordering { 411 using _ValueT = signed char; 412 413 _LIBCPP_INLINE_VISIBILITY 414 explicit constexpr weak_ordering(_EqResult __v) noexcept : __value_(_ValueT(__v)) {} 415 _LIBCPP_INLINE_VISIBILITY 416 explicit constexpr weak_ordering(_OrdResult __v) noexcept : __value_(_ValueT(__v)) {} 417 418public: 419 static const weak_ordering less; 420 static const weak_ordering equivalent; 421 static const weak_ordering greater; 422 423 // conversions 424 _LIBCPP_INLINE_VISIBILITY 425 constexpr operator weak_equality() const noexcept { 426 return __value_ == 0 ? weak_equality::equivalent 427 : weak_equality::nonequivalent; 428 } 429 430 _LIBCPP_INLINE_VISIBILITY 431 constexpr operator partial_ordering() const noexcept { 432 return __value_ == 0 ? partial_ordering::equivalent 433 : (__value_ < 0 ? partial_ordering::less : partial_ordering::greater); 434 } 435 436 // comparisons 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< (weak_ordering __v, _CmpUnspecifiedParam) noexcept; 440 _LIBCPP_INLINE_VISIBILITY friend constexpr bool operator<=(weak_ordering __v, _CmpUnspecifiedParam) noexcept; 441 _LIBCPP_INLINE_VISIBILITY friend constexpr bool operator> (weak_ordering __v, _CmpUnspecifiedParam) noexcept; 442 _LIBCPP_INLINE_VISIBILITY friend constexpr bool operator>=(weak_ordering __v, _CmpUnspecifiedParam) 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 _LIBCPP_INLINE_VISIBILITY friend constexpr bool operator< (_CmpUnspecifiedParam, weak_ordering __v) noexcept; 446 _LIBCPP_INLINE_VISIBILITY friend constexpr bool operator<=(_CmpUnspecifiedParam, weak_ordering __v) noexcept; 447 _LIBCPP_INLINE_VISIBILITY friend constexpr bool operator> (_CmpUnspecifiedParam, weak_ordering __v) noexcept; 448 _LIBCPP_INLINE_VISIBILITY friend constexpr bool operator>=(_CmpUnspecifiedParam, weak_ordering __v) noexcept; 449 450#ifndef _LIBCPP_HAS_NO_SPACESHIP_OPERATOR 451 _LIBCPP_INLINE_VISIBILITY friend constexpr bool operator==(weak_ordering, weak_ordering) noexcept = default; 452 453 _LIBCPP_INLINE_VISIBILITY friend constexpr weak_ordering operator<=>(weak_ordering __v, _CmpUnspecifiedParam) noexcept; 454 _LIBCPP_INLINE_VISIBILITY friend constexpr weak_ordering operator<=>(_CmpUnspecifiedParam, weak_ordering __v) noexcept; 455#endif 456 457private: 458 _ValueT __value_; 459}; 460 461_LIBCPP_INLINE_VAR constexpr weak_ordering weak_ordering::less(_OrdResult::__less); 462_LIBCPP_INLINE_VAR constexpr weak_ordering weak_ordering::equivalent(_EqResult::__equiv); 463_LIBCPP_INLINE_VAR constexpr weak_ordering weak_ordering::greater(_OrdResult::__greater); 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>=(weak_ordering __v, _CmpUnspecifiedParam) noexcept { 487 return __v.__value_ >= 0; 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_LIBCPP_INLINE_VISIBILITY 510constexpr bool operator>=(_CmpUnspecifiedParam, weak_ordering __v) noexcept { 511 return 0 >= __v.__value_; 512} 513 514#ifndef _LIBCPP_HAS_NO_SPACESHIP_OPERATOR 515_LIBCPP_INLINE_VISIBILITY 516constexpr weak_ordering operator<=>(weak_ordering __v, _CmpUnspecifiedParam) noexcept { 517 return __v; 518} 519_LIBCPP_INLINE_VISIBILITY 520constexpr weak_ordering operator<=>(_CmpUnspecifiedParam, weak_ordering __v) noexcept { 521 return __v < 0 ? weak_ordering::greater : (__v > 0 ? weak_ordering::less : __v); 522} 523#endif // _LIBCPP_HAS_NO_SPACESHIP_OPERATOR 524 525class strong_ordering { 526 using _ValueT = signed char; 527 528 _LIBCPP_INLINE_VISIBILITY 529 explicit constexpr strong_ordering(_EqResult __v) noexcept : __value_(_ValueT(__v)) {} 530 _LIBCPP_INLINE_VISIBILITY 531 explicit constexpr strong_ordering(_OrdResult __v) noexcept : __value_(_ValueT(__v)) {} 532 533public: 534 static const strong_ordering less; 535 static const strong_ordering equal; 536 static const strong_ordering equivalent; 537 static const strong_ordering greater; 538 539 // conversions 540 _LIBCPP_INLINE_VISIBILITY 541 constexpr operator weak_equality() const noexcept { 542 return __value_ == 0 ? weak_equality::equivalent 543 : weak_equality::nonequivalent; 544 } 545 546 _LIBCPP_INLINE_VISIBILITY 547 constexpr operator strong_equality() const noexcept { 548 return __value_ == 0 ? strong_equality::equal 549 : strong_equality::nonequal; 550 } 551 552 _LIBCPP_INLINE_VISIBILITY 553 constexpr operator partial_ordering() const noexcept { 554 return __value_ == 0 ? partial_ordering::equivalent 555 : (__value_ < 0 ? partial_ordering::less : partial_ordering::greater); 556 } 557 558 _LIBCPP_INLINE_VISIBILITY 559 constexpr operator weak_ordering() const noexcept { 560 return __value_ == 0 ? weak_ordering::equivalent 561 : (__value_ < 0 ? weak_ordering::less : weak_ordering::greater); 562 } 563 564 // comparisons 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< (strong_ordering __v, _CmpUnspecifiedParam) noexcept; 568 _LIBCPP_INLINE_VISIBILITY friend constexpr bool operator<=(strong_ordering __v, _CmpUnspecifiedParam) noexcept; 569 _LIBCPP_INLINE_VISIBILITY friend constexpr bool operator> (strong_ordering __v, _CmpUnspecifiedParam) noexcept; 570 _LIBCPP_INLINE_VISIBILITY friend constexpr bool operator>=(strong_ordering __v, _CmpUnspecifiedParam) 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 _LIBCPP_INLINE_VISIBILITY friend constexpr bool operator< (_CmpUnspecifiedParam, strong_ordering __v) noexcept; 574 _LIBCPP_INLINE_VISIBILITY friend constexpr bool operator<=(_CmpUnspecifiedParam, strong_ordering __v) noexcept; 575 _LIBCPP_INLINE_VISIBILITY friend constexpr bool operator> (_CmpUnspecifiedParam, strong_ordering __v) noexcept; 576 _LIBCPP_INLINE_VISIBILITY friend constexpr bool operator>=(_CmpUnspecifiedParam, strong_ordering __v) noexcept; 577 578#ifndef _LIBCPP_HAS_NO_SPACESHIP_OPERATOR 579 _LIBCPP_INLINE_VISIBILITY friend constexpr bool operator==(strong_ordering, strong_ordering) noexcept = default; 580 581 _LIBCPP_INLINE_VISIBILITY friend constexpr strong_ordering operator<=>(strong_ordering __v, _CmpUnspecifiedParam) noexcept; 582 _LIBCPP_INLINE_VISIBILITY friend constexpr strong_ordering operator<=>(_CmpUnspecifiedParam, strong_ordering __v) noexcept; 583#endif 584 585private: 586 _ValueT __value_; 587}; 588 589_LIBCPP_INLINE_VAR constexpr strong_ordering strong_ordering::less(_OrdResult::__less); 590_LIBCPP_INLINE_VAR constexpr strong_ordering strong_ordering::equal(_EqResult::__equal); 591_LIBCPP_INLINE_VAR constexpr strong_ordering strong_ordering::equivalent(_EqResult::__equiv); 592_LIBCPP_INLINE_VAR constexpr strong_ordering strong_ordering::greater(_OrdResult::__greater); 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>=(strong_ordering __v, _CmpUnspecifiedParam) noexcept { 616 return __v.__value_ >= 0; 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_LIBCPP_INLINE_VISIBILITY 639constexpr bool operator>=(_CmpUnspecifiedParam, strong_ordering __v) noexcept { 640 return 0 >= __v.__value_; 641} 642 643#ifndef _LIBCPP_HAS_NO_SPACESHIP_OPERATOR 644_LIBCPP_INLINE_VISIBILITY 645constexpr strong_ordering operator<=>(strong_ordering __v, _CmpUnspecifiedParam) noexcept { 646 return __v; 647} 648_LIBCPP_INLINE_VISIBILITY 649constexpr strong_ordering operator<=>(_CmpUnspecifiedParam, strong_ordering __v) noexcept { 650 return __v < 0 ? strong_ordering::greater : (__v > 0 ? strong_ordering::less : __v); 651} 652#endif // _LIBCPP_HAS_NO_SPACESHIP_OPERATOR 653 654// named comparison functions 655_LIBCPP_INLINE_VISIBILITY 656constexpr bool is_eq(weak_equality __cmp) noexcept { return __cmp == 0; } 657 658_LIBCPP_INLINE_VISIBILITY 659constexpr bool is_neq(weak_equality __cmp) noexcept { return __cmp != 0; } 660 661_LIBCPP_INLINE_VISIBILITY 662constexpr bool is_lt(partial_ordering __cmp) noexcept { return __cmp < 0; } 663 664_LIBCPP_INLINE_VISIBILITY 665constexpr bool is_lteq(partial_ordering __cmp) noexcept { return __cmp <= 0; } 666 667_LIBCPP_INLINE_VISIBILITY 668constexpr bool is_gt(partial_ordering __cmp) noexcept { return __cmp > 0; } 669 670_LIBCPP_INLINE_VISIBILITY 671constexpr bool is_gteq(partial_ordering __cmp) noexcept { return __cmp >= 0; } 672 673namespace __comp_detail { 674 675enum _ClassifyCompCategory : unsigned{ 676 _None, 677 _WeakEq, 678 _StrongEq, 679 _PartialOrd, 680 _WeakOrd, 681 _StrongOrd, 682 _CCC_Size 683}; 684 685template <class _Tp> 686_LIBCPP_INLINE_VISIBILITY 687constexpr _ClassifyCompCategory __type_to_enum() noexcept { 688 if (is_same_v<_Tp, weak_equality>) 689 return _WeakEq; 690 if (is_same_v<_Tp, strong_equality>) 691 return _StrongEq; 692 if (is_same_v<_Tp, partial_ordering>) 693 return _PartialOrd; 694 if (is_same_v<_Tp, weak_ordering>) 695 return _WeakOrd; 696 if (is_same_v<_Tp, strong_ordering>) 697 return _StrongOrd; 698 return _None; 699} 700 701template <size_t _Size> 702constexpr _ClassifyCompCategory 703__compute_comp_type(const _ClassifyCompCategory (&__types)[_Size]) { 704 int __seen[_CCC_Size] = {}; 705 for (auto __type : __types) 706 ++__seen[__type]; 707 if (__seen[_None]) 708 return _None; 709 if (__seen[_WeakEq]) 710 return _WeakEq; 711 if (__seen[_StrongEq] && (__seen[_PartialOrd] || __seen[_WeakOrd])) 712 return _WeakEq; 713 if (__seen[_StrongEq]) 714 return _StrongEq; 715 if (__seen[_PartialOrd]) 716 return _PartialOrd; 717 if (__seen[_WeakOrd]) 718 return _WeakOrd; 719 return _StrongOrd; 720} 721 722template <class ..._Ts> 723constexpr auto __get_comp_type() { 724 using _CCC = _ClassifyCompCategory; 725 constexpr _CCC __type_kinds[] = {_StrongOrd, __type_to_enum<_Ts>()...}; 726 constexpr _CCC _Cat = __compute_comp_type(__type_kinds); 727 if constexpr (_Cat == _None) 728 return void(); 729 else if constexpr (_Cat == _WeakEq) 730 return weak_equality::equivalent; 731 else if constexpr (_Cat == _StrongEq) 732 return strong_equality::equivalent; 733 else if constexpr (_Cat == _PartialOrd) 734 return partial_ordering::equivalent; 735 else if constexpr (_Cat == _WeakOrd) 736 return weak_ordering::equivalent; 737 else if constexpr (_Cat == _StrongOrd) 738 return strong_ordering::equivalent; 739 else 740 static_assert(_Cat != _Cat, "unhandled case"); 741} 742} // namespace __comp_detail 743 744// [cmp.common], common comparison category type 745template<class... _Ts> 746struct _LIBCPP_TEMPLATE_VIS common_comparison_category { 747 using type = decltype(__comp_detail::__get_comp_type<_Ts...>()); 748}; 749 750template<class... _Ts> 751using common_comparison_category_t = typename common_comparison_category<_Ts...>::type; 752 753// [cmp.alg], comparison algorithms 754// TODO: unimplemented 755template<class _Tp> constexpr strong_ordering strong_order(const _Tp& __lhs, const _Tp& __rhs); 756template<class _Tp> constexpr weak_ordering weak_order(const _Tp& __lhs, const _Tp& __rhs); 757template<class _Tp> constexpr partial_ordering partial_order(const _Tp& __lhs, const _Tp& __rhs); 758template<class _Tp> constexpr strong_equality strong_equal(const _Tp& __lhs, const _Tp& __rhs); 759template<class _Tp> constexpr weak_equality weak_equal(const _Tp& __lhs, const _Tp& __rhs); 760 761#endif // _LIBCPP_STD_VER > 17 762 763_LIBCPP_END_NAMESPACE_STD 764 765#endif // _LIBCPP_COMPARE 766