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