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