1 #ifndef STD_COMPARE_H 2 #define STD_COMPARE_H 3 4 namespace std { 5 inline namespace __1 { 6 7 // exposition only 8 enum class _EqResult : unsigned char { 9 __zero = 0, 10 __equal = __zero, 11 __equiv = __equal, 12 __nonequal = 1, 13 __nonequiv = __nonequal 14 }; 15 16 enum class _OrdResult : signed char { 17 __less = -1, 18 __greater = 1 19 }; 20 21 enum class _NCmpResult : signed char { 22 __unordered = -127 23 }; 24 25 struct _CmpUnspecifiedType; 26 using _CmpUnspecifiedParam = void (_CmpUnspecifiedType::*)(); 27 28 class weak_equality { 29 constexpr explicit weak_equality(_EqResult __val) noexcept : __value_(__val) {} 30 31 public: 32 static const weak_equality equivalent; 33 static const weak_equality nonequivalent; 34 35 friend constexpr bool operator==(weak_equality __v, _CmpUnspecifiedParam) noexcept; 36 friend constexpr bool operator==(_CmpUnspecifiedParam, weak_equality __v) noexcept; 37 friend constexpr bool operator!=(weak_equality __v, _CmpUnspecifiedParam) noexcept; 38 friend constexpr bool operator!=(_CmpUnspecifiedParam, weak_equality __v) noexcept; 39 friend constexpr weak_equality operator<=>(weak_equality __v, _CmpUnspecifiedParam) noexcept; 40 friend constexpr weak_equality operator<=>(_CmpUnspecifiedParam, weak_equality __v) noexcept; 41 42 // test helper 43 constexpr bool test_eq(weak_equality const &other) const noexcept { 44 return __value_ == other.__value_; 45 } 46 47 private: 48 _EqResult __value_; 49 }; 50 51 inline constexpr weak_equality weak_equality::equivalent(_EqResult::__equiv); 52 inline constexpr weak_equality weak_equality::nonequivalent(_EqResult::__nonequiv); 53 inline constexpr bool operator==(weak_equality __v, _CmpUnspecifiedParam) noexcept { 54 return __v.__value_ == _EqResult::__zero; 55 } 56 inline constexpr bool operator==(_CmpUnspecifiedParam, weak_equality __v) noexcept { 57 return __v.__value_ == _EqResult::__zero; 58 } 59 inline constexpr bool operator!=(weak_equality __v, _CmpUnspecifiedParam) noexcept { 60 return __v.__value_ != _EqResult::__zero; 61 } 62 inline constexpr bool operator!=(_CmpUnspecifiedParam, weak_equality __v) noexcept { 63 return __v.__value_ != _EqResult::__zero; 64 } 65 66 inline constexpr weak_equality operator<=>(weak_equality __v, _CmpUnspecifiedParam) noexcept { 67 return __v; 68 } 69 inline constexpr weak_equality operator<=>(_CmpUnspecifiedParam, weak_equality __v) noexcept { 70 return __v; 71 } 72 73 class strong_equality { 74 explicit constexpr strong_equality(_EqResult __val) noexcept : __value_(__val) {} 75 76 public: 77 static const strong_equality equal; 78 static const strong_equality nonequal; 79 static const strong_equality equivalent; 80 static const strong_equality nonequivalent; 81 82 // conversion 83 constexpr operator weak_equality() const noexcept { 84 return __value_ == _EqResult::__zero ? weak_equality::equivalent 85 : weak_equality::nonequivalent; 86 } 87 88 // comparisons 89 friend constexpr bool operator==(strong_equality __v, _CmpUnspecifiedParam) noexcept; 90 friend constexpr bool operator!=(strong_equality __v, _CmpUnspecifiedParam) noexcept; 91 friend constexpr bool operator==(_CmpUnspecifiedParam, strong_equality __v) noexcept; 92 friend constexpr bool operator!=(_CmpUnspecifiedParam, strong_equality __v) noexcept; 93 94 friend constexpr strong_equality operator<=>(strong_equality __v, _CmpUnspecifiedParam) noexcept; 95 friend constexpr strong_equality operator<=>(_CmpUnspecifiedParam, strong_equality __v) noexcept; 96 97 // test helper 98 constexpr bool test_eq(strong_equality const &other) const noexcept { 99 return __value_ == other.__value_; 100 } 101 102 private: 103 _EqResult __value_; 104 }; 105 106 inline constexpr strong_equality strong_equality::equal(_EqResult::__equal); 107 inline constexpr strong_equality strong_equality::nonequal(_EqResult::__nonequal); 108 inline constexpr strong_equality strong_equality::equivalent(_EqResult::__equiv); 109 inline constexpr strong_equality strong_equality::nonequivalent(_EqResult::__nonequiv); 110 constexpr bool operator==(strong_equality __v, _CmpUnspecifiedParam) noexcept { 111 return __v.__value_ == _EqResult::__zero; 112 } 113 constexpr bool operator==(_CmpUnspecifiedParam, strong_equality __v) noexcept { 114 return __v.__value_ == _EqResult::__zero; 115 } 116 constexpr bool operator!=(strong_equality __v, _CmpUnspecifiedParam) noexcept { 117 return __v.__value_ != _EqResult::__zero; 118 } 119 constexpr bool operator!=(_CmpUnspecifiedParam, strong_equality __v) noexcept { 120 return __v.__value_ != _EqResult::__zero; 121 } 122 123 constexpr strong_equality operator<=>(strong_equality __v, _CmpUnspecifiedParam) noexcept { 124 return __v; 125 } 126 constexpr strong_equality operator<=>(_CmpUnspecifiedParam, strong_equality __v) noexcept { 127 return __v; 128 } 129 130 class partial_ordering { 131 using _ValueT = signed char; 132 explicit constexpr partial_ordering(_EqResult __v) noexcept 133 : __value_(_ValueT(__v)) {} 134 explicit constexpr partial_ordering(_OrdResult __v) noexcept 135 : __value_(_ValueT(__v)) {} 136 explicit constexpr partial_ordering(_NCmpResult __v) noexcept 137 : __value_(_ValueT(__v)) {} 138 139 constexpr bool __is_ordered() const noexcept { 140 return __value_ != _ValueT(_NCmpResult::__unordered); 141 } 142 143 public: 144 // valid values 145 static const partial_ordering less; 146 static const partial_ordering equivalent; 147 static const partial_ordering greater; 148 static const partial_ordering unordered; 149 150 // conversion 151 constexpr operator weak_equality() const noexcept { 152 return __value_ == 0 ? weak_equality::equivalent : weak_equality::nonequivalent; 153 } 154 155 // comparisons 156 friend constexpr bool operator==(partial_ordering __v, _CmpUnspecifiedParam) noexcept; 157 friend constexpr bool operator!=(partial_ordering __v, _CmpUnspecifiedParam) noexcept; 158 friend constexpr bool operator<(partial_ordering __v, _CmpUnspecifiedParam) noexcept; 159 friend constexpr bool operator<=(partial_ordering __v, _CmpUnspecifiedParam) noexcept; 160 friend constexpr bool operator>(partial_ordering __v, _CmpUnspecifiedParam) noexcept; 161 friend constexpr bool operator>=(partial_ordering __v, _CmpUnspecifiedParam) noexcept; 162 friend constexpr bool operator==(_CmpUnspecifiedParam, partial_ordering __v) noexcept; 163 friend constexpr bool operator!=(_CmpUnspecifiedParam, partial_ordering __v) noexcept; 164 friend constexpr bool operator<(_CmpUnspecifiedParam, partial_ordering __v) noexcept; 165 friend constexpr bool operator<=(_CmpUnspecifiedParam, partial_ordering __v) noexcept; 166 friend constexpr bool operator>(_CmpUnspecifiedParam, partial_ordering __v) noexcept; 167 friend constexpr bool operator>=(_CmpUnspecifiedParam, partial_ordering __v) noexcept; 168 169 friend constexpr partial_ordering operator<=>(partial_ordering __v, _CmpUnspecifiedParam) noexcept; 170 friend constexpr partial_ordering operator<=>(_CmpUnspecifiedParam, partial_ordering __v) noexcept; 171 172 // test helper 173 constexpr bool test_eq(partial_ordering const &other) const noexcept { 174 return __value_ == other.__value_; 175 } 176 177 private: 178 _ValueT __value_; 179 }; 180 181 inline constexpr partial_ordering partial_ordering::less(_OrdResult::__less); 182 inline constexpr partial_ordering partial_ordering::equivalent(_EqResult::__equiv); 183 inline constexpr partial_ordering partial_ordering::greater(_OrdResult::__greater); 184 inline constexpr partial_ordering partial_ordering::unordered(_NCmpResult ::__unordered); 185 constexpr bool operator==(partial_ordering __v, _CmpUnspecifiedParam) noexcept { 186 return __v.__is_ordered() && __v.__value_ == 0; 187 } 188 constexpr bool operator<(partial_ordering __v, _CmpUnspecifiedParam) noexcept { 189 return __v.__is_ordered() && __v.__value_ < 0; 190 } 191 constexpr bool operator<=(partial_ordering __v, _CmpUnspecifiedParam) noexcept { 192 return __v.__is_ordered() && __v.__value_ <= 0; 193 } 194 constexpr bool operator>(partial_ordering __v, _CmpUnspecifiedParam) noexcept { 195 return __v.__is_ordered() && __v.__value_ > 0; 196 } 197 constexpr bool operator>=(partial_ordering __v, _CmpUnspecifiedParam) noexcept { 198 return __v.__is_ordered() && __v.__value_ >= 0; 199 } 200 constexpr bool operator==(_CmpUnspecifiedParam, partial_ordering __v) noexcept { 201 return __v.__is_ordered() && 0 == __v.__value_; 202 } 203 constexpr bool operator<(_CmpUnspecifiedParam, partial_ordering __v) noexcept { 204 return __v.__is_ordered() && 0 < __v.__value_; 205 } 206 constexpr bool operator<=(_CmpUnspecifiedParam, partial_ordering __v) noexcept { 207 return __v.__is_ordered() && 0 <= __v.__value_; 208 } 209 constexpr bool operator>(_CmpUnspecifiedParam, partial_ordering __v) noexcept { 210 return __v.__is_ordered() && 0 > __v.__value_; 211 } 212 constexpr bool operator>=(_CmpUnspecifiedParam, partial_ordering __v) noexcept { 213 return __v.__is_ordered() && 0 >= __v.__value_; 214 } 215 constexpr bool operator!=(partial_ordering __v, _CmpUnspecifiedParam) noexcept { 216 return !__v.__is_ordered() || __v.__value_ != 0; 217 } 218 constexpr bool operator!=(_CmpUnspecifiedParam, partial_ordering __v) noexcept { 219 return !__v.__is_ordered() || __v.__value_ != 0; 220 } 221 222 constexpr partial_ordering operator<=>(partial_ordering __v, _CmpUnspecifiedParam) noexcept { 223 return __v; 224 } 225 constexpr partial_ordering operator<=>(_CmpUnspecifiedParam, partial_ordering __v) noexcept { 226 return __v < 0 ? partial_ordering::greater : (__v > 0 ? partial_ordering::less : __v); 227 } 228 229 class weak_ordering { 230 using _ValueT = signed char; 231 explicit constexpr weak_ordering(_EqResult __v) noexcept : __value_(_ValueT(__v)) {} 232 explicit constexpr weak_ordering(_OrdResult __v) noexcept : __value_(_ValueT(__v)) {} 233 234 public: 235 static const weak_ordering less; 236 static const weak_ordering equivalent; 237 static const weak_ordering greater; 238 239 // conversions 240 constexpr operator weak_equality() const noexcept { 241 return __value_ == 0 ? weak_equality::equivalent 242 : weak_equality::nonequivalent; 243 } 244 constexpr operator partial_ordering() const noexcept { 245 return __value_ == 0 ? partial_ordering::equivalent 246 : (__value_ < 0 ? partial_ordering::less : partial_ordering::greater); 247 } 248 249 // comparisons 250 friend constexpr bool operator==(weak_ordering __v, _CmpUnspecifiedParam) noexcept; 251 friend constexpr bool operator!=(weak_ordering __v, _CmpUnspecifiedParam) noexcept; 252 friend constexpr bool operator<(weak_ordering __v, _CmpUnspecifiedParam) noexcept; 253 friend constexpr bool operator<=(weak_ordering __v, _CmpUnspecifiedParam) noexcept; 254 friend constexpr bool operator>(weak_ordering __v, _CmpUnspecifiedParam) noexcept; 255 friend constexpr bool operator>=(weak_ordering __v, _CmpUnspecifiedParam) noexcept; 256 friend constexpr bool operator==(_CmpUnspecifiedParam, weak_ordering __v) noexcept; 257 friend constexpr bool operator!=(_CmpUnspecifiedParam, weak_ordering __v) noexcept; 258 friend constexpr bool operator<(_CmpUnspecifiedParam, weak_ordering __v) noexcept; 259 friend constexpr bool operator<=(_CmpUnspecifiedParam, weak_ordering __v) noexcept; 260 friend constexpr bool operator>(_CmpUnspecifiedParam, weak_ordering __v) noexcept; 261 friend constexpr bool operator>=(_CmpUnspecifiedParam, weak_ordering __v) noexcept; 262 263 friend constexpr weak_ordering operator<=>(weak_ordering __v, _CmpUnspecifiedParam) noexcept; 264 friend constexpr weak_ordering operator<=>(_CmpUnspecifiedParam, weak_ordering __v) noexcept; 265 266 // test helper 267 constexpr bool test_eq(weak_ordering const &other) const noexcept { 268 return __value_ == other.__value_; 269 } 270 271 private: 272 _ValueT __value_; 273 }; 274 275 inline constexpr weak_ordering weak_ordering::less(_OrdResult::__less); 276 inline constexpr weak_ordering weak_ordering::equivalent(_EqResult::__equiv); 277 inline constexpr weak_ordering weak_ordering::greater(_OrdResult::__greater); 278 constexpr bool operator==(weak_ordering __v, _CmpUnspecifiedParam) noexcept { 279 return __v.__value_ == 0; 280 } 281 constexpr bool operator!=(weak_ordering __v, _CmpUnspecifiedParam) noexcept { 282 return __v.__value_ != 0; 283 } 284 constexpr bool operator<(weak_ordering __v, _CmpUnspecifiedParam) noexcept { 285 return __v.__value_ < 0; 286 } 287 constexpr bool operator<=(weak_ordering __v, _CmpUnspecifiedParam) noexcept { 288 return __v.__value_ <= 0; 289 } 290 constexpr bool operator>(weak_ordering __v, _CmpUnspecifiedParam) noexcept { 291 return __v.__value_ > 0; 292 } 293 constexpr bool operator>=(weak_ordering __v, _CmpUnspecifiedParam) noexcept { 294 return __v.__value_ >= 0; 295 } 296 constexpr bool operator==(_CmpUnspecifiedParam, weak_ordering __v) noexcept { 297 return 0 == __v.__value_; 298 } 299 constexpr bool operator!=(_CmpUnspecifiedParam, weak_ordering __v) noexcept { 300 return 0 != __v.__value_; 301 } 302 constexpr bool operator<(_CmpUnspecifiedParam, weak_ordering __v) noexcept { 303 return 0 < __v.__value_; 304 } 305 constexpr bool operator<=(_CmpUnspecifiedParam, weak_ordering __v) noexcept { 306 return 0 <= __v.__value_; 307 } 308 constexpr bool operator>(_CmpUnspecifiedParam, weak_ordering __v) noexcept { 309 return 0 > __v.__value_; 310 } 311 constexpr bool operator>=(_CmpUnspecifiedParam, weak_ordering __v) noexcept { 312 return 0 >= __v.__value_; 313 } 314 315 constexpr weak_ordering operator<=>(weak_ordering __v, _CmpUnspecifiedParam) noexcept { 316 return __v; 317 } 318 constexpr weak_ordering operator<=>(_CmpUnspecifiedParam, weak_ordering __v) noexcept { 319 return __v < 0 ? weak_ordering::greater : (__v > 0 ? weak_ordering::less : __v); 320 } 321 322 class strong_ordering { 323 using _ValueT = signed char; 324 explicit constexpr strong_ordering(_EqResult __v) noexcept : __value_(static_cast<signed char>(__v)) {} 325 explicit constexpr strong_ordering(_OrdResult __v) noexcept : __value_(static_cast<signed char>(__v)) {} 326 327 public: 328 static const strong_ordering less; 329 static const strong_ordering equal; 330 static const strong_ordering equivalent; 331 static const strong_ordering greater; 332 333 // conversions 334 constexpr operator weak_equality() const noexcept { 335 return __value_ == 0 ? weak_equality::equivalent 336 : weak_equality::nonequivalent; 337 } 338 constexpr operator strong_equality() const noexcept { 339 return __value_ == 0 ? strong_equality::equal 340 : strong_equality::nonequal; 341 } 342 constexpr operator partial_ordering() const noexcept { 343 return __value_ == 0 ? partial_ordering::equivalent 344 : (__value_ < 0 ? partial_ordering::less : partial_ordering::greater); 345 } 346 constexpr operator weak_ordering() const noexcept { 347 return __value_ == 0 ? weak_ordering::equivalent 348 : (__value_ < 0 ? weak_ordering::less : weak_ordering::greater); 349 } 350 351 // comparisons 352 friend constexpr bool operator==(strong_ordering __v, _CmpUnspecifiedParam) noexcept; 353 friend constexpr bool operator!=(strong_ordering __v, _CmpUnspecifiedParam) noexcept; 354 friend constexpr bool operator<(strong_ordering __v, _CmpUnspecifiedParam) noexcept; 355 friend constexpr bool operator<=(strong_ordering __v, _CmpUnspecifiedParam) noexcept; 356 friend constexpr bool operator>(strong_ordering __v, _CmpUnspecifiedParam) noexcept; 357 friend constexpr bool operator>=(strong_ordering __v, _CmpUnspecifiedParam) noexcept; 358 friend constexpr bool operator==(_CmpUnspecifiedParam, strong_ordering __v) noexcept; 359 friend constexpr bool operator!=(_CmpUnspecifiedParam, strong_ordering __v) noexcept; 360 friend constexpr bool operator<(_CmpUnspecifiedParam, strong_ordering __v) noexcept; 361 friend constexpr bool operator<=(_CmpUnspecifiedParam, strong_ordering __v) noexcept; 362 friend constexpr bool operator>(_CmpUnspecifiedParam, strong_ordering __v) noexcept; 363 friend constexpr bool operator>=(_CmpUnspecifiedParam, strong_ordering __v) noexcept; 364 365 friend constexpr strong_ordering operator<=>(strong_ordering __v, _CmpUnspecifiedParam) noexcept; 366 friend constexpr strong_ordering operator<=>(_CmpUnspecifiedParam, strong_ordering __v) noexcept; 367 368 // test helper 369 constexpr bool test_eq(strong_ordering const &other) const noexcept { 370 return __value_ == other.__value_; 371 } 372 373 private: 374 _ValueT __value_; 375 }; 376 377 inline constexpr strong_ordering strong_ordering::less(_OrdResult::__less); 378 inline constexpr strong_ordering strong_ordering::equal(_EqResult::__equal); 379 inline constexpr strong_ordering strong_ordering::equivalent(_EqResult::__equiv); 380 inline constexpr strong_ordering strong_ordering::greater(_OrdResult::__greater); 381 382 constexpr bool operator==(strong_ordering __v, _CmpUnspecifiedParam) noexcept { 383 return __v.__value_ == 0; 384 } 385 constexpr bool operator!=(strong_ordering __v, _CmpUnspecifiedParam) noexcept { 386 return __v.__value_ != 0; 387 } 388 constexpr bool operator<(strong_ordering __v, _CmpUnspecifiedParam) noexcept { 389 return __v.__value_ < 0; 390 } 391 constexpr bool operator<=(strong_ordering __v, _CmpUnspecifiedParam) noexcept { 392 return __v.__value_ <= 0; 393 } 394 constexpr bool operator>(strong_ordering __v, _CmpUnspecifiedParam) noexcept { 395 return __v.__value_ > 0; 396 } 397 constexpr bool operator>=(strong_ordering __v, _CmpUnspecifiedParam) noexcept { 398 return __v.__value_ >= 0; 399 } 400 constexpr bool operator==(_CmpUnspecifiedParam, strong_ordering __v) noexcept { 401 return 0 == __v.__value_; 402 } 403 constexpr bool operator!=(_CmpUnspecifiedParam, strong_ordering __v) noexcept { 404 return 0 != __v.__value_; 405 } 406 constexpr bool operator<(_CmpUnspecifiedParam, strong_ordering __v) noexcept { 407 return 0 < __v.__value_; 408 } 409 constexpr bool operator<=(_CmpUnspecifiedParam, strong_ordering __v) noexcept { 410 return 0 <= __v.__value_; 411 } 412 constexpr bool operator>(_CmpUnspecifiedParam, strong_ordering __v) noexcept { 413 return 0 > __v.__value_; 414 } 415 constexpr bool operator>=(_CmpUnspecifiedParam, strong_ordering __v) noexcept { 416 return 0 >= __v.__value_; 417 } 418 419 constexpr strong_ordering operator<=>(strong_ordering __v, _CmpUnspecifiedParam) noexcept { 420 return __v; 421 } 422 constexpr strong_ordering operator<=>(_CmpUnspecifiedParam, strong_ordering __v) noexcept { 423 return __v < 0 ? strong_ordering::greater : (__v > 0 ? strong_ordering::less : __v); 424 } 425 426 // named comparison functions 427 constexpr bool is_eq(weak_equality __cmp) noexcept { return __cmp == 0; } 428 constexpr bool is_neq(weak_equality __cmp) noexcept { return __cmp != 0; } 429 constexpr bool is_lt(partial_ordering __cmp) noexcept { return __cmp < 0; } 430 constexpr bool is_lteq(partial_ordering __cmp) noexcept { return __cmp <= 0; } 431 constexpr bool is_gt(partial_ordering __cmp) noexcept { return __cmp > 0; } 432 constexpr bool is_gteq(partial_ordering __cmp) noexcept { return __cmp >= 0; } 433 434 } // namespace __1 435 } // end namespace std 436 437 #endif // STD_COMPARE_H 438