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 17 namespace 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 63 enum class _LIBCPP_ENUM_VIS _EqResult : unsigned char { 64 __zero = 0, 65 __equal = __zero, 66 __equiv = __equal, 67 __nonequal = 1, 68 __nonequiv = __nonequal 69 }; 70 71 enum class _LIBCPP_ENUM_VIS _OrdResult : signed char { 72 __less = -1, 73 __greater = 1 74 }; 75 76 enum class _LIBCPP_ENUM_VIS _NCmpResult : signed char { 77 __unordered = -127 78 }; 79 80 struct _CmpUnspecifiedType; 81 using _CmpUnspecifiedParam = void (_CmpUnspecifiedType::*)(); 82 83 class weak_equality { 84 _LIBCPP_INLINE_VISIBILITY 85 constexpr explicit weak_equality(_EqResult __val) noexcept : __value_(__val) {} 86 87 public: 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 101 private: 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 109 inline constexpr bool operator==(weak_equality __v, _CmpUnspecifiedParam) noexcept { 110 return __v.__value_ == _EqResult::__zero; 111 } 112 113 _LIBCPP_INLINE_VISIBILITY 114 inline constexpr bool operator==(_CmpUnspecifiedParam, weak_equality __v) noexcept { 115 return __v.__value_ == _EqResult::__zero; 116 } 117 118 _LIBCPP_INLINE_VISIBILITY 119 inline constexpr bool operator!=(weak_equality __v, _CmpUnspecifiedParam) noexcept { 120 return __v.__value_ != _EqResult::__zero; 121 } 122 123 _LIBCPP_INLINE_VISIBILITY 124 inline 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 130 inline constexpr weak_equality operator<=>(weak_equality __v, _CmpUnspecifiedParam) noexcept { 131 return __v; 132 } 133 134 _LIBCPP_INLINE_VISIBILITY 135 inline constexpr weak_equality operator<=>(_CmpUnspecifiedParam, weak_equality __v) noexcept { 136 return __v; 137 } 138 #endif 139 140 class strong_equality { 141 _LIBCPP_INLINE_VISIBILITY 142 explicit constexpr strong_equality(_EqResult __val) noexcept : __value_(__val) {} 143 144 public: 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 166 private: 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 176 constexpr bool operator==(strong_equality __v, _CmpUnspecifiedParam) noexcept { 177 return __v.__value_ == _EqResult::__zero; 178 } 179 180 _LIBCPP_INLINE_VISIBILITY 181 constexpr bool operator==(_CmpUnspecifiedParam, strong_equality __v) noexcept { 182 return __v.__value_ == _EqResult::__zero; 183 } 184 185 _LIBCPP_INLINE_VISIBILITY 186 constexpr bool operator!=(strong_equality __v, _CmpUnspecifiedParam) noexcept { 187 return __v.__value_ != _EqResult::__zero; 188 } 189 190 _LIBCPP_INLINE_VISIBILITY 191 constexpr 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 197 constexpr strong_equality operator<=>(strong_equality __v, _CmpUnspecifiedParam) noexcept { 198 return __v; 199 } 200 201 _LIBCPP_INLINE_VISIBILITY 202 constexpr strong_equality operator<=>(_CmpUnspecifiedParam, strong_equality __v) noexcept { 203 return __v; 204 } 205 #endif // _LIBCPP_HAS_NO_SPACESHIP_OPERATOR 206 207 class 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 } 225 public: 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 256 private: 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 266 constexpr bool operator==(partial_ordering __v, _CmpUnspecifiedParam) noexcept { 267 return __v.__is_ordered() && __v.__value_ == 0; 268 } 269 _LIBCPP_INLINE_VISIBILITY 270 constexpr bool operator< (partial_ordering __v, _CmpUnspecifiedParam) noexcept { 271 return __v.__is_ordered() && __v.__value_ < 0; 272 } 273 _LIBCPP_INLINE_VISIBILITY 274 constexpr bool operator<=(partial_ordering __v, _CmpUnspecifiedParam) noexcept { 275 return __v.__is_ordered() && __v.__value_ <= 0; 276 } 277 _LIBCPP_INLINE_VISIBILITY 278 constexpr bool operator> (partial_ordering __v, _CmpUnspecifiedParam) noexcept { 279 return __v.__is_ordered() && __v.__value_ > 0; 280 } 281 _LIBCPP_INLINE_VISIBILITY 282 constexpr bool operator>=(partial_ordering __v, _CmpUnspecifiedParam) noexcept { 283 return __v.__is_ordered() && __v.__value_ >= 0; 284 } 285 286 _LIBCPP_INLINE_VISIBILITY 287 constexpr bool operator==(_CmpUnspecifiedParam, partial_ordering __v) noexcept { 288 return __v.__is_ordered() && 0 == __v.__value_; 289 } 290 _LIBCPP_INLINE_VISIBILITY 291 constexpr bool operator< (_CmpUnspecifiedParam, partial_ordering __v) noexcept { 292 return __v.__is_ordered() && 0 < __v.__value_; 293 } 294 _LIBCPP_INLINE_VISIBILITY 295 constexpr bool operator<=(_CmpUnspecifiedParam, partial_ordering __v) noexcept { 296 return __v.__is_ordered() && 0 <= __v.__value_; 297 } 298 _LIBCPP_INLINE_VISIBILITY 299 constexpr bool operator> (_CmpUnspecifiedParam, partial_ordering __v) noexcept { 300 return __v.__is_ordered() && 0 > __v.__value_; 301 } 302 _LIBCPP_INLINE_VISIBILITY 303 constexpr bool operator>=(_CmpUnspecifiedParam, partial_ordering __v) noexcept { 304 return __v.__is_ordered() && 0 >= __v.__value_; 305 } 306 307 _LIBCPP_INLINE_VISIBILITY 308 constexpr bool operator!=(partial_ordering __v, _CmpUnspecifiedParam) noexcept { 309 return !__v.__is_ordered() || __v.__value_ != 0; 310 } 311 _LIBCPP_INLINE_VISIBILITY 312 constexpr 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 318 constexpr partial_ordering operator<=>(partial_ordering __v, _CmpUnspecifiedParam) noexcept { 319 return __v; 320 } 321 _LIBCPP_INLINE_VISIBILITY 322 constexpr 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 327 class 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 335 public: 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 372 private: 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 381 constexpr bool operator==(weak_ordering __v, _CmpUnspecifiedParam) noexcept { 382 return __v.__value_ == 0; 383 } 384 _LIBCPP_INLINE_VISIBILITY 385 constexpr bool operator!=(weak_ordering __v, _CmpUnspecifiedParam) noexcept { 386 return __v.__value_ != 0; 387 } 388 _LIBCPP_INLINE_VISIBILITY 389 constexpr bool operator< (weak_ordering __v, _CmpUnspecifiedParam) noexcept { 390 return __v.__value_ < 0; 391 } 392 _LIBCPP_INLINE_VISIBILITY 393 constexpr bool operator<=(weak_ordering __v, _CmpUnspecifiedParam) noexcept { 394 return __v.__value_ <= 0; 395 } 396 _LIBCPP_INLINE_VISIBILITY 397 constexpr bool operator> (weak_ordering __v, _CmpUnspecifiedParam) noexcept { 398 return __v.__value_ > 0; 399 } 400 _LIBCPP_INLINE_VISIBILITY 401 constexpr bool operator>=(weak_ordering __v, _CmpUnspecifiedParam) noexcept { 402 return __v.__value_ >= 0; 403 } 404 _LIBCPP_INLINE_VISIBILITY 405 constexpr bool operator==(_CmpUnspecifiedParam, weak_ordering __v) noexcept { 406 return 0 == __v.__value_; 407 } 408 _LIBCPP_INLINE_VISIBILITY 409 constexpr bool operator!=(_CmpUnspecifiedParam, weak_ordering __v) noexcept { 410 return 0 != __v.__value_; 411 } 412 _LIBCPP_INLINE_VISIBILITY 413 constexpr bool operator< (_CmpUnspecifiedParam, weak_ordering __v) noexcept { 414 return 0 < __v.__value_; 415 } 416 _LIBCPP_INLINE_VISIBILITY 417 constexpr bool operator<=(_CmpUnspecifiedParam, weak_ordering __v) noexcept { 418 return 0 <= __v.__value_; 419 } 420 _LIBCPP_INLINE_VISIBILITY 421 constexpr bool operator> (_CmpUnspecifiedParam, weak_ordering __v) noexcept { 422 return 0 > __v.__value_; 423 } 424 _LIBCPP_INLINE_VISIBILITY 425 constexpr 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 431 constexpr weak_ordering operator<=>(weak_ordering __v, _CmpUnspecifiedParam) noexcept { 432 return __v; 433 } 434 _LIBCPP_INLINE_VISIBILITY 435 constexpr 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 440 class 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 448 public: 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 498 private: 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 508 constexpr bool operator==(strong_ordering __v, _CmpUnspecifiedParam) noexcept { 509 return __v.__value_ == 0; 510 } 511 _LIBCPP_INLINE_VISIBILITY 512 constexpr bool operator!=(strong_ordering __v, _CmpUnspecifiedParam) noexcept { 513 return __v.__value_ != 0; 514 } 515 _LIBCPP_INLINE_VISIBILITY 516 constexpr bool operator< (strong_ordering __v, _CmpUnspecifiedParam) noexcept { 517 return __v.__value_ < 0; 518 } 519 _LIBCPP_INLINE_VISIBILITY 520 constexpr bool operator<=(strong_ordering __v, _CmpUnspecifiedParam) noexcept { 521 return __v.__value_ <= 0; 522 } 523 _LIBCPP_INLINE_VISIBILITY 524 constexpr bool operator> (strong_ordering __v, _CmpUnspecifiedParam) noexcept { 525 return __v.__value_ > 0; 526 } 527 _LIBCPP_INLINE_VISIBILITY 528 constexpr bool operator>=(strong_ordering __v, _CmpUnspecifiedParam) noexcept { 529 return __v.__value_ >= 0; 530 } 531 _LIBCPP_INLINE_VISIBILITY 532 constexpr bool operator==(_CmpUnspecifiedParam, strong_ordering __v) noexcept { 533 return 0 == __v.__value_; 534 } 535 _LIBCPP_INLINE_VISIBILITY 536 constexpr bool operator!=(_CmpUnspecifiedParam, strong_ordering __v) noexcept { 537 return 0 != __v.__value_; 538 } 539 _LIBCPP_INLINE_VISIBILITY 540 constexpr bool operator< (_CmpUnspecifiedParam, strong_ordering __v) noexcept { 541 return 0 < __v.__value_; 542 } 543 _LIBCPP_INLINE_VISIBILITY 544 constexpr bool operator<=(_CmpUnspecifiedParam, strong_ordering __v) noexcept { 545 return 0 <= __v.__value_; 546 } 547 _LIBCPP_INLINE_VISIBILITY 548 constexpr bool operator> (_CmpUnspecifiedParam, strong_ordering __v) noexcept { 549 return 0 > __v.__value_; 550 } 551 _LIBCPP_INLINE_VISIBILITY 552 constexpr 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 558 constexpr strong_ordering operator<=>(strong_ordering __v, _CmpUnspecifiedParam) noexcept { 559 return __v; 560 } 561 _LIBCPP_INLINE_VISIBILITY 562 constexpr 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 569 constexpr bool is_eq(weak_equality __cmp) noexcept { return __cmp == 0; } 570 571 _LIBCPP_INLINE_VISIBILITY 572 constexpr bool is_neq(weak_equality __cmp) noexcept { return __cmp != 0; } 573 574 _LIBCPP_INLINE_VISIBILITY 575 constexpr bool is_lt(partial_ordering __cmp) noexcept { return __cmp < 0; } 576 577 _LIBCPP_INLINE_VISIBILITY 578 constexpr bool is_lteq(partial_ordering __cmp) noexcept { return __cmp <= 0; } 579 580 _LIBCPP_INLINE_VISIBILITY 581 constexpr bool is_gt(partial_ordering __cmp) noexcept { return __cmp > 0; } 582 583 _LIBCPP_INLINE_VISIBILITY 584 constexpr bool is_gteq(partial_ordering __cmp) noexcept { return __cmp >= 0; } 585 586 namespace __comp_detail { 587 588 enum _ClassifyCompCategory : unsigned{ 589 _None, 590 _WeakEq, 591 _StrongEq, 592 _PartialOrd, 593 _WeakOrd, 594 _StrongOrd, 595 _CCC_Size 596 }; 597 598 template <class _Tp> 599 _LIBCPP_INLINE_VISIBILITY 600 constexpr _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 614 template <size_t _Size> 615 constexpr _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 635 template <class ..._Ts> 636 constexpr 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 659 template<class... _Ts> 660 struct _LIBCPP_TEMPLATE_VIS common_comparison_category { 661 using type = decltype(__comp_detail::__get_comp_type<_Ts...>()); 662 }; 663 664 template<class... _Ts> 665 using common_comparison_category_t = typename common_comparison_category<_Ts...>::type; 666 667 // [cmp.alg], comparison algorithms 668 // TODO: unimplemented 669 template<class _Tp> constexpr strong_ordering strong_order(const _Tp& __lhs, const _Tp& __rhs); 670 template<class _Tp> constexpr weak_ordering weak_order(const _Tp& __lhs, const _Tp& __rhs); 671 template<class _Tp> constexpr partial_ordering partial_order(const _Tp& __lhs, const _Tp& __rhs); 672 template<class _Tp> constexpr strong_equality strong_equal(const _Tp& __lhs, const _Tp& __rhs); 673 template<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