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