2 //===-------------------------- compare -----------------------------------===//
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
8 //===----------------------------------------------------------------------===//
10 #ifndef _LIBCPP_COMPARE
11 #define _LIBCPP_COMPARE
17 // [cmp.categories], comparison category types
19 class strong_equality;
20 class partial_ordering;
22 class strong_ordering;
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; }
32 // [cmp.common], common comparison category type
34 struct common_comparison_category {
35 using type = see below;
38 using common_comparison_category_t = typename common_comparison_category<Ts...>::type;
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);
50 #include <type_traits>
53 #ifndef _LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER
54 #pragma GCC system_header
57 _LIBCPP_BEGIN_NAMESPACE_STD
59 #if _LIBCPP_STD_VER > 17
62 enum class _LIBCPP_ENUM_VIS _EqResult : unsigned char {
67 __nonequiv = __nonequal
70 enum class _LIBCPP_ENUM_VIS _OrdResult : signed char {
75 enum class _LIBCPP_ENUM_VIS _NCmpResult : signed char {
79 struct _CmpUnspecifiedType;
80 using _CmpUnspecifiedParam = void (_CmpUnspecifiedType::*)();
83 _LIBCPP_INLINE_VISIBILITY
84 constexpr explicit weak_equality(_EqResult __val) noexcept : __value_(__val) {}
87 static const weak_equality equivalent;
88 static const weak_equality nonequivalent;
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;
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;
104 _LIBCPP_INLINE_VAR constexpr weak_equality weak_equality::equivalent(_EqResult::__equiv);
105 _LIBCPP_INLINE_VAR constexpr weak_equality weak_equality::nonequivalent(_EqResult::__nonequiv);
107 _LIBCPP_INLINE_VISIBILITY
108 inline constexpr bool operator==(weak_equality __v, _CmpUnspecifiedParam) noexcept {
109 return __v.__value_ == _EqResult::__zero;
112 _LIBCPP_INLINE_VISIBILITY
113 inline constexpr bool operator==(_CmpUnspecifiedParam, weak_equality __v) noexcept {
114 return __v.__value_ == _EqResult::__zero;
117 _LIBCPP_INLINE_VISIBILITY
118 inline constexpr bool operator!=(weak_equality __v, _CmpUnspecifiedParam) noexcept {
119 return __v.__value_ != _EqResult::__zero;
122 _LIBCPP_INLINE_VISIBILITY
123 inline constexpr bool operator!=(_CmpUnspecifiedParam, weak_equality __v) noexcept {
124 return __v.__value_ != _EqResult::__zero;
127 #ifndef _LIBCPP_HAS_NO_SPACESHIP_OPERATOR
128 _LIBCPP_INLINE_VISIBILITY
129 inline constexpr weak_equality operator<=>(weak_equality __v, _CmpUnspecifiedParam) noexcept {
133 _LIBCPP_INLINE_VISIBILITY
134 inline constexpr weak_equality operator<=>(_CmpUnspecifiedParam, weak_equality __v) noexcept {
139 class strong_equality {
140 _LIBCPP_INLINE_VISIBILITY
141 explicit constexpr strong_equality(_EqResult __val) noexcept : __value_(__val) {}
144 static const strong_equality equal;
145 static const strong_equality nonequal;
146 static const strong_equality equivalent;
147 static const strong_equality nonequivalent;
150 _LIBCPP_INLINE_VISIBILITY constexpr operator weak_equality() const noexcept {
151 return __value_ == _EqResult::__zero ? weak_equality::equivalent
152 : weak_equality::nonequivalent;
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;
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;
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);
174 _LIBCPP_INLINE_VISIBILITY
175 constexpr bool operator==(strong_equality __v, _CmpUnspecifiedParam) noexcept {
176 return __v.__value_ == _EqResult::__zero;
179 _LIBCPP_INLINE_VISIBILITY
180 constexpr bool operator==(_CmpUnspecifiedParam, strong_equality __v) noexcept {
181 return __v.__value_ == _EqResult::__zero;
184 _LIBCPP_INLINE_VISIBILITY
185 constexpr bool operator!=(strong_equality __v, _CmpUnspecifiedParam) noexcept {
186 return __v.__value_ != _EqResult::__zero;
189 _LIBCPP_INLINE_VISIBILITY
190 constexpr bool operator!=(_CmpUnspecifiedParam, strong_equality __v) noexcept {
191 return __v.__value_ != _EqResult::__zero;
194 #ifndef _LIBCPP_HAS_NO_SPACESHIP_OPERATOR
195 _LIBCPP_INLINE_VISIBILITY
196 constexpr strong_equality operator<=>(strong_equality __v, _CmpUnspecifiedParam) noexcept {
200 _LIBCPP_INLINE_VISIBILITY
201 constexpr strong_equality operator<=>(_CmpUnspecifiedParam, strong_equality __v) noexcept {
204 #endif // _LIBCPP_HAS_NO_SPACESHIP_OPERATOR
206 class partial_ordering {
207 using _ValueT = signed char;
209 _LIBCPP_INLINE_VISIBILITY
210 explicit constexpr partial_ordering(_EqResult __v) noexcept
211 : __value_(_ValueT(__v)) {}
213 _LIBCPP_INLINE_VISIBILITY
214 explicit constexpr partial_ordering(_OrdResult __v) noexcept
215 : __value_(_ValueT(__v)) {}
217 _LIBCPP_INLINE_VISIBILITY
218 explicit constexpr partial_ordering(_NCmpResult __v) noexcept
219 : __value_(_ValueT(__v)) {}
221 constexpr bool __is_ordered() const noexcept {
222 return __value_ != _ValueT(_NCmpResult::__unordered);
226 static const partial_ordering less;
227 static const partial_ordering equivalent;
228 static const partial_ordering greater;
229 static const partial_ordering unordered;
232 constexpr operator weak_equality() const noexcept {
233 return __value_ == 0 ? weak_equality::equivalent : weak_equality::nonequivalent;
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;
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;
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);
264 _LIBCPP_INLINE_VISIBILITY
265 constexpr bool operator==(partial_ordering __v, _CmpUnspecifiedParam) noexcept {
266 return __v.__is_ordered() && __v.__value_ == 0;
268 _LIBCPP_INLINE_VISIBILITY
269 constexpr bool operator< (partial_ordering __v, _CmpUnspecifiedParam) noexcept {
270 return __v.__is_ordered() && __v.__value_ < 0;
272 _LIBCPP_INLINE_VISIBILITY
273 constexpr bool operator<=(partial_ordering __v, _CmpUnspecifiedParam) noexcept {
274 return __v.__is_ordered() && __v.__value_ <= 0;
276 _LIBCPP_INLINE_VISIBILITY
277 constexpr bool operator> (partial_ordering __v, _CmpUnspecifiedParam) noexcept {
278 return __v.__is_ordered() && __v.__value_ > 0;
280 _LIBCPP_INLINE_VISIBILITY
281 constexpr bool operator>=(partial_ordering __v, _CmpUnspecifiedParam) noexcept {
282 return __v.__is_ordered() && __v.__value_ >= 0;
285 _LIBCPP_INLINE_VISIBILITY
286 constexpr bool operator==(_CmpUnspecifiedParam, partial_ordering __v) noexcept {
287 return __v.__is_ordered() && 0 == __v.__value_;
289 _LIBCPP_INLINE_VISIBILITY
290 constexpr bool operator< (_CmpUnspecifiedParam, partial_ordering __v) noexcept {
291 return __v.__is_ordered() && 0 < __v.__value_;
293 _LIBCPP_INLINE_VISIBILITY
294 constexpr bool operator<=(_CmpUnspecifiedParam, partial_ordering __v) noexcept {
295 return __v.__is_ordered() && 0 <= __v.__value_;
297 _LIBCPP_INLINE_VISIBILITY
298 constexpr bool operator> (_CmpUnspecifiedParam, partial_ordering __v) noexcept {
299 return __v.__is_ordered() && 0 > __v.__value_;
301 _LIBCPP_INLINE_VISIBILITY
302 constexpr bool operator>=(_CmpUnspecifiedParam, partial_ordering __v) noexcept {
303 return __v.__is_ordered() && 0 >= __v.__value_;
306 _LIBCPP_INLINE_VISIBILITY
307 constexpr bool operator!=(partial_ordering __v, _CmpUnspecifiedParam) noexcept {
308 return !__v.__is_ordered() || __v.__value_ != 0;
310 _LIBCPP_INLINE_VISIBILITY
311 constexpr bool operator!=(_CmpUnspecifiedParam, partial_ordering __v) noexcept {
312 return !__v.__is_ordered() || __v.__value_ != 0;
315 #ifndef _LIBCPP_HAS_NO_SPACESHIP_OPERATOR
316 _LIBCPP_INLINE_VISIBILITY
317 constexpr partial_ordering operator<=>(partial_ordering __v, _CmpUnspecifiedParam) noexcept {
320 _LIBCPP_INLINE_VISIBILITY
321 constexpr partial_ordering operator<=>(_CmpUnspecifiedParam, partial_ordering __v) noexcept {
322 return __v < 0 ? partial_ordering::greater : (__v > 0 ? partial_ordering::less : __v);
324 #endif // _LIBCPP_HAS_NO_SPACESHIP_OPERATOR
326 class weak_ordering {
327 using _ValueT = signed char;
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)) {}
335 static const weak_ordering less;
336 static const weak_ordering equivalent;
337 static const weak_ordering greater;
340 _LIBCPP_INLINE_VISIBILITY
341 constexpr operator weak_equality() const noexcept {
342 return __value_ == 0 ? weak_equality::equivalent
343 : weak_equality::nonequivalent;
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);
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;
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;
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);
379 _LIBCPP_INLINE_VISIBILITY
380 constexpr bool operator==(weak_ordering __v, _CmpUnspecifiedParam) noexcept {
381 return __v.__value_ == 0;
383 _LIBCPP_INLINE_VISIBILITY
384 constexpr bool operator!=(weak_ordering __v, _CmpUnspecifiedParam) noexcept {
385 return __v.__value_ != 0;
387 _LIBCPP_INLINE_VISIBILITY
388 constexpr bool operator< (weak_ordering __v, _CmpUnspecifiedParam) noexcept {
389 return __v.__value_ < 0;
391 _LIBCPP_INLINE_VISIBILITY
392 constexpr bool operator<=(weak_ordering __v, _CmpUnspecifiedParam) noexcept {
393 return __v.__value_ <= 0;
395 _LIBCPP_INLINE_VISIBILITY
396 constexpr bool operator> (weak_ordering __v, _CmpUnspecifiedParam) noexcept {
397 return __v.__value_ > 0;
399 _LIBCPP_INLINE_VISIBILITY
400 constexpr bool operator>=(weak_ordering __v, _CmpUnspecifiedParam) noexcept {
401 return __v.__value_ >= 0;
403 _LIBCPP_INLINE_VISIBILITY
404 constexpr bool operator==(_CmpUnspecifiedParam, weak_ordering __v) noexcept {
405 return 0 == __v.__value_;
407 _LIBCPP_INLINE_VISIBILITY
408 constexpr bool operator!=(_CmpUnspecifiedParam, weak_ordering __v) noexcept {
409 return 0 != __v.__value_;
411 _LIBCPP_INLINE_VISIBILITY
412 constexpr bool operator< (_CmpUnspecifiedParam, weak_ordering __v) noexcept {
413 return 0 < __v.__value_;
415 _LIBCPP_INLINE_VISIBILITY
416 constexpr bool operator<=(_CmpUnspecifiedParam, weak_ordering __v) noexcept {
417 return 0 <= __v.__value_;
419 _LIBCPP_INLINE_VISIBILITY
420 constexpr bool operator> (_CmpUnspecifiedParam, weak_ordering __v) noexcept {
421 return 0 > __v.__value_;
423 _LIBCPP_INLINE_VISIBILITY
424 constexpr bool operator>=(_CmpUnspecifiedParam, weak_ordering __v) noexcept {
425 return 0 >= __v.__value_;
428 #ifndef _LIBCPP_HAS_NO_SPACESHIP_OPERATOR
429 _LIBCPP_INLINE_VISIBILITY
430 constexpr weak_ordering operator<=>(weak_ordering __v, _CmpUnspecifiedParam) noexcept {
433 _LIBCPP_INLINE_VISIBILITY
434 constexpr weak_ordering operator<=>(_CmpUnspecifiedParam, weak_ordering __v) noexcept {
435 return __v < 0 ? weak_ordering::greater : (__v > 0 ? weak_ordering::less : __v);
437 #endif // _LIBCPP_HAS_NO_SPACESHIP_OPERATOR
439 class strong_ordering {
440 using _ValueT = signed char;
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)) {}
448 static const strong_ordering less;
449 static const strong_ordering equal;
450 static const strong_ordering equivalent;
451 static const strong_ordering greater;
454 _LIBCPP_INLINE_VISIBILITY
455 constexpr operator weak_equality() const noexcept {
456 return __value_ == 0 ? weak_equality::equivalent
457 : weak_equality::nonequivalent;
460 _LIBCPP_INLINE_VISIBILITY
461 constexpr operator strong_equality() const noexcept {
462 return __value_ == 0 ? strong_equality::equal
463 : strong_equality::nonequal;
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);
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);
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;
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;
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);
506 _LIBCPP_INLINE_VISIBILITY
507 constexpr bool operator==(strong_ordering __v, _CmpUnspecifiedParam) noexcept {
508 return __v.__value_ == 0;
510 _LIBCPP_INLINE_VISIBILITY
511 constexpr bool operator!=(strong_ordering __v, _CmpUnspecifiedParam) noexcept {
512 return __v.__value_ != 0;
514 _LIBCPP_INLINE_VISIBILITY
515 constexpr bool operator< (strong_ordering __v, _CmpUnspecifiedParam) noexcept {
516 return __v.__value_ < 0;
518 _LIBCPP_INLINE_VISIBILITY
519 constexpr bool operator<=(strong_ordering __v, _CmpUnspecifiedParam) noexcept {
520 return __v.__value_ <= 0;
522 _LIBCPP_INLINE_VISIBILITY
523 constexpr bool operator> (strong_ordering __v, _CmpUnspecifiedParam) noexcept {
524 return __v.__value_ > 0;
526 _LIBCPP_INLINE_VISIBILITY
527 constexpr bool operator>=(strong_ordering __v, _CmpUnspecifiedParam) noexcept {
528 return __v.__value_ >= 0;
530 _LIBCPP_INLINE_VISIBILITY
531 constexpr bool operator==(_CmpUnspecifiedParam, strong_ordering __v) noexcept {
532 return 0 == __v.__value_;
534 _LIBCPP_INLINE_VISIBILITY
535 constexpr bool operator!=(_CmpUnspecifiedParam, strong_ordering __v) noexcept {
536 return 0 != __v.__value_;
538 _LIBCPP_INLINE_VISIBILITY
539 constexpr bool operator< (_CmpUnspecifiedParam, strong_ordering __v) noexcept {
540 return 0 < __v.__value_;
542 _LIBCPP_INLINE_VISIBILITY
543 constexpr bool operator<=(_CmpUnspecifiedParam, strong_ordering __v) noexcept {
544 return 0 <= __v.__value_;
546 _LIBCPP_INLINE_VISIBILITY
547 constexpr bool operator> (_CmpUnspecifiedParam, strong_ordering __v) noexcept {
548 return 0 > __v.__value_;
550 _LIBCPP_INLINE_VISIBILITY
551 constexpr bool operator>=(_CmpUnspecifiedParam, strong_ordering __v) noexcept {
552 return 0 >= __v.__value_;
555 #ifndef _LIBCPP_HAS_NO_SPACESHIP_OPERATOR
556 _LIBCPP_INLINE_VISIBILITY
557 constexpr strong_ordering operator<=>(strong_ordering __v, _CmpUnspecifiedParam) noexcept {
560 _LIBCPP_INLINE_VISIBILITY
561 constexpr strong_ordering operator<=>(_CmpUnspecifiedParam, strong_ordering __v) noexcept {
562 return __v < 0 ? strong_ordering::greater : (__v > 0 ? strong_ordering::less : __v);
564 #endif // _LIBCPP_HAS_NO_SPACESHIP_OPERATOR
566 // named comparison functions
567 _LIBCPP_INLINE_VISIBILITY
568 constexpr bool is_eq(weak_equality __cmp) noexcept { return __cmp == 0; }
570 _LIBCPP_INLINE_VISIBILITY
571 constexpr bool is_neq(weak_equality __cmp) noexcept { return __cmp != 0; }
573 _LIBCPP_INLINE_VISIBILITY
574 constexpr bool is_lt(partial_ordering __cmp) noexcept { return __cmp < 0; }
576 _LIBCPP_INLINE_VISIBILITY
577 constexpr bool is_lteq(partial_ordering __cmp) noexcept { return __cmp <= 0; }
579 _LIBCPP_INLINE_VISIBILITY
580 constexpr bool is_gt(partial_ordering __cmp) noexcept { return __cmp > 0; }
582 _LIBCPP_INLINE_VISIBILITY
583 constexpr bool is_gteq(partial_ordering __cmp) noexcept { return __cmp >= 0; }
585 namespace __comp_detail {
587 enum _ClassifyCompCategory : unsigned{
598 _LIBCPP_INLINE_VISIBILITY
599 constexpr _ClassifyCompCategory __type_to_enum() noexcept {
600 if (is_same_v<_Tp, weak_equality>)
602 if (is_same_v<_Tp, strong_equality>)
604 if (is_same_v<_Tp, partial_ordering>)
606 if (is_same_v<_Tp, weak_ordering>)
608 if (is_same_v<_Tp, strong_ordering>)
613 template <size_t _Size>
614 constexpr _ClassifyCompCategory
615 __compute_comp_type(std::array<_ClassifyCompCategory, _Size> __types) {
616 std::array<int, _CCC_Size> __seen = {};
617 for (auto __type : __types)
623 if (__seen[_StrongEq] && (__seen[_PartialOrd] || __seen[_WeakOrd]))
625 if (__seen[_StrongEq])
627 if (__seen[_PartialOrd])
629 if (__seen[_WeakOrd])
634 template <class ..._Ts>
635 constexpr 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)
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;
653 static_assert(_Cat != _Cat, "unhandled case");
655 } // namespace __comp_detail
657 // [cmp.common], common comparison category type
658 template<class... _Ts>
659 struct _LIBCPP_TEMPLATE_VIS common_comparison_category {
660 using type = decltype(__comp_detail::__get_comp_type<_Ts...>());
663 template<class... _Ts>
664 using common_comparison_category_t = typename common_comparison_category<_Ts...>::type;
666 // [cmp.alg], comparison algorithms
667 // TODO: unimplemented
668 template<class _Tp> constexpr strong_ordering strong_order(const _Tp& __lhs, const _Tp& __rhs);
669 template<class _Tp> constexpr weak_ordering weak_order(const _Tp& __lhs, const _Tp& __rhs);
670 template<class _Tp> constexpr partial_ordering partial_order(const _Tp& __lhs, const _Tp& __rhs);
671 template<class _Tp> constexpr strong_equality strong_equal(const _Tp& __lhs, const _Tp& __rhs);
672 template<class _Tp> constexpr weak_equality weak_equal(const _Tp& __lhs, const _Tp& __rhs);
674 #endif // _LIBCPP_STD_VER > 17
676 _LIBCPP_END_NAMESPACE_STD
678 #endif // _LIBCPP_COMPARE