]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/llvm-project/libcxx/include/compare
Merge upstream r948: fix race condition in openpam_ttyconv(3).
[FreeBSD/FreeBSD.git] / contrib / llvm-project / libcxx / include / compare
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
16 namespace 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
140 enum class _LIBCPP_ENUM_VIS _EqResult : unsigned char {
141   __zero = 0,
142   __equal = __zero,
143   __equiv = __equal,
144   __nonequal = 1,
145   __nonequiv = __nonequal
146 };
147
148 enum class _LIBCPP_ENUM_VIS _OrdResult : signed char {
149   __less = -1,
150   __greater = 1
151 };
152
153 enum class _LIBCPP_ENUM_VIS _NCmpResult : signed char {
154   __unordered = -127
155 };
156
157 struct _CmpUnspecifiedType;
158 using _CmpUnspecifiedParam = void (_CmpUnspecifiedType::*)();
159
160 class  weak_equality {
161   _LIBCPP_INLINE_VISIBILITY
162   constexpr explicit weak_equality(_EqResult __val) noexcept : __value_(__val) {}
163
164 public:
165   static const weak_equality equivalent;
166   static const weak_equality nonequivalent;
167
168   _LIBCPP_INLINE_VISIBILITY friend constexpr bool operator==(weak_equality __v, _CmpUnspecifiedParam) noexcept;
169   _LIBCPP_INLINE_VISIBILITY friend constexpr bool operator==(_CmpUnspecifiedParam, weak_equality __v) noexcept;
170   _LIBCPP_INLINE_VISIBILITY friend constexpr bool operator!=(weak_equality __v, _CmpUnspecifiedParam) noexcept;
171   _LIBCPP_INLINE_VISIBILITY friend constexpr bool operator!=(_CmpUnspecifiedParam, weak_equality __v) noexcept;
172
173 #ifndef _LIBCPP_HAS_NO_SPACESHIP_OPERATOR
174   _LIBCPP_INLINE_VISIBILITY friend constexpr weak_equality operator<=>(weak_equality __v, _CmpUnspecifiedParam) noexcept;
175   _LIBCPP_INLINE_VISIBILITY friend constexpr weak_equality operator<=>(_CmpUnspecifiedParam, weak_equality __v) noexcept;
176 #endif
177
178 private:
179   _EqResult __value_;
180 };
181
182 _LIBCPP_INLINE_VAR constexpr weak_equality weak_equality::equivalent(_EqResult::__equiv);
183 _LIBCPP_INLINE_VAR constexpr weak_equality weak_equality::nonequivalent(_EqResult::__nonequiv);
184
185 _LIBCPP_INLINE_VISIBILITY
186 inline constexpr bool operator==(weak_equality __v, _CmpUnspecifiedParam) noexcept {
187   return __v.__value_ == _EqResult::__zero;
188 }
189
190 _LIBCPP_INLINE_VISIBILITY
191 inline constexpr bool operator==(_CmpUnspecifiedParam, weak_equality __v) noexcept {
192   return __v.__value_ == _EqResult::__zero;
193 }
194
195 _LIBCPP_INLINE_VISIBILITY
196 inline constexpr bool operator!=(weak_equality __v, _CmpUnspecifiedParam) noexcept {
197   return __v.__value_ != _EqResult::__zero;
198 }
199
200 _LIBCPP_INLINE_VISIBILITY
201 inline constexpr bool operator!=(_CmpUnspecifiedParam, weak_equality __v) noexcept {
202   return __v.__value_ != _EqResult::__zero;
203 }
204
205 #ifndef _LIBCPP_HAS_NO_SPACESHIP_OPERATOR
206 _LIBCPP_INLINE_VISIBILITY
207 inline constexpr weak_equality operator<=>(weak_equality __v, _CmpUnspecifiedParam) noexcept {
208   return __v;
209 }
210
211 _LIBCPP_INLINE_VISIBILITY
212 inline constexpr weak_equality operator<=>(_CmpUnspecifiedParam, weak_equality __v) noexcept {
213   return __v;
214 }
215 #endif
216
217 class strong_equality {
218   _LIBCPP_INLINE_VISIBILITY
219   explicit constexpr strong_equality(_EqResult __val) noexcept : __value_(__val) {}
220
221 public:
222   static const strong_equality equal;
223   static const strong_equality nonequal;
224   static const strong_equality equivalent;
225   static const strong_equality nonequivalent;
226
227   // conversion
228   _LIBCPP_INLINE_VISIBILITY constexpr operator weak_equality() const noexcept {
229     return __value_ == _EqResult::__zero ? weak_equality::equivalent
230           : weak_equality::nonequivalent;
231   }
232
233   // comparisons
234   _LIBCPP_INLINE_VISIBILITY friend constexpr bool operator==(strong_equality __v, _CmpUnspecifiedParam) noexcept;
235   _LIBCPP_INLINE_VISIBILITY friend constexpr bool operator!=(strong_equality __v, _CmpUnspecifiedParam) noexcept;
236   _LIBCPP_INLINE_VISIBILITY friend constexpr bool operator==(_CmpUnspecifiedParam, strong_equality __v) noexcept;
237   _LIBCPP_INLINE_VISIBILITY friend constexpr bool operator!=(_CmpUnspecifiedParam, strong_equality __v) noexcept;
238
239 #ifndef _LIBCPP_HAS_NO_SPACESHIP_OPERATOR
240   _LIBCPP_INLINE_VISIBILITY friend constexpr strong_equality operator<=>(strong_equality __v, _CmpUnspecifiedParam) noexcept;
241   _LIBCPP_INLINE_VISIBILITY friend constexpr strong_equality operator<=>(_CmpUnspecifiedParam, strong_equality __v) noexcept;
242 #endif
243 private:
244   _EqResult __value_;
245 };
246
247 _LIBCPP_INLINE_VAR constexpr strong_equality strong_equality::equal(_EqResult::__equal);
248 _LIBCPP_INLINE_VAR constexpr strong_equality strong_equality::nonequal(_EqResult::__nonequal);
249 _LIBCPP_INLINE_VAR constexpr strong_equality strong_equality::equivalent(_EqResult::__equiv);
250 _LIBCPP_INLINE_VAR constexpr strong_equality strong_equality::nonequivalent(_EqResult::__nonequiv);
251
252 _LIBCPP_INLINE_VISIBILITY
253 constexpr bool operator==(strong_equality __v, _CmpUnspecifiedParam) noexcept {
254   return __v.__value_ == _EqResult::__zero;
255 }
256
257 _LIBCPP_INLINE_VISIBILITY
258 constexpr bool operator==(_CmpUnspecifiedParam, strong_equality __v) noexcept {
259   return __v.__value_ == _EqResult::__zero;
260 }
261
262 _LIBCPP_INLINE_VISIBILITY
263 constexpr bool operator!=(strong_equality __v, _CmpUnspecifiedParam) noexcept {
264   return __v.__value_ != _EqResult::__zero;
265 }
266
267 _LIBCPP_INLINE_VISIBILITY
268 constexpr bool operator!=(_CmpUnspecifiedParam, strong_equality __v) noexcept {
269   return __v.__value_ != _EqResult::__zero;
270 }
271
272 #ifndef _LIBCPP_HAS_NO_SPACESHIP_OPERATOR
273 _LIBCPP_INLINE_VISIBILITY
274 constexpr strong_equality operator<=>(strong_equality __v, _CmpUnspecifiedParam) noexcept {
275   return __v;
276 }
277
278 _LIBCPP_INLINE_VISIBILITY
279 constexpr strong_equality operator<=>(_CmpUnspecifiedParam, strong_equality __v) noexcept {
280   return __v;
281 }
282 #endif // _LIBCPP_HAS_NO_SPACESHIP_OPERATOR
283
284 class partial_ordering {
285   using _ValueT = signed char;
286
287   _LIBCPP_INLINE_VISIBILITY
288   explicit constexpr partial_ordering(_EqResult __v) noexcept
289       : __value_(_ValueT(__v)) {}
290
291   _LIBCPP_INLINE_VISIBILITY
292   explicit constexpr partial_ordering(_OrdResult __v) noexcept
293       : __value_(_ValueT(__v)) {}
294
295   _LIBCPP_INLINE_VISIBILITY
296   explicit constexpr partial_ordering(_NCmpResult __v) noexcept
297       : __value_(_ValueT(__v)) {}
298
299   constexpr bool __is_ordered() const noexcept {
300     return __value_ != _ValueT(_NCmpResult::__unordered);
301   }
302 public:
303   // valid values
304   static const partial_ordering less;
305   static const partial_ordering equivalent;
306   static const partial_ordering greater;
307   static const partial_ordering unordered;
308
309   // conversion
310   constexpr operator weak_equality() const noexcept {
311     return __value_ == 0 ? weak_equality::equivalent : weak_equality::nonequivalent;
312   }
313
314   // comparisons
315   _LIBCPP_INLINE_VISIBILITY friend constexpr bool operator==(partial_ordering __v, _CmpUnspecifiedParam) noexcept;
316   _LIBCPP_INLINE_VISIBILITY friend constexpr bool operator!=(partial_ordering __v, _CmpUnspecifiedParam) noexcept;
317   _LIBCPP_INLINE_VISIBILITY friend constexpr bool operator< (partial_ordering __v, _CmpUnspecifiedParam) noexcept;
318   _LIBCPP_INLINE_VISIBILITY friend constexpr bool operator<=(partial_ordering __v, _CmpUnspecifiedParam) noexcept;
319   _LIBCPP_INLINE_VISIBILITY friend constexpr bool operator> (partial_ordering __v, _CmpUnspecifiedParam) noexcept;
320   _LIBCPP_INLINE_VISIBILITY friend constexpr bool operator>=(partial_ordering __v, _CmpUnspecifiedParam) noexcept;
321   _LIBCPP_INLINE_VISIBILITY friend constexpr bool operator==(_CmpUnspecifiedParam, partial_ordering __v) noexcept;
322   _LIBCPP_INLINE_VISIBILITY friend constexpr bool operator!=(_CmpUnspecifiedParam, partial_ordering __v) noexcept;
323   _LIBCPP_INLINE_VISIBILITY friend constexpr bool operator< (_CmpUnspecifiedParam, partial_ordering __v) noexcept;
324   _LIBCPP_INLINE_VISIBILITY friend constexpr bool operator<=(_CmpUnspecifiedParam, partial_ordering __v) noexcept;
325   _LIBCPP_INLINE_VISIBILITY friend constexpr bool operator> (_CmpUnspecifiedParam, partial_ordering __v) noexcept;
326   _LIBCPP_INLINE_VISIBILITY friend constexpr bool operator>=(_CmpUnspecifiedParam, partial_ordering __v) noexcept;
327
328 #ifndef _LIBCPP_HAS_NO_SPACESHIP_OPERATOR
329   _LIBCPP_INLINE_VISIBILITY friend constexpr bool operator==(partial_ordering, partial_ordering) noexcept = default;
330
331   _LIBCPP_INLINE_VISIBILITY friend constexpr partial_ordering operator<=>(partial_ordering __v, _CmpUnspecifiedParam) noexcept;
332   _LIBCPP_INLINE_VISIBILITY friend constexpr partial_ordering operator<=>(_CmpUnspecifiedParam, partial_ordering __v) noexcept;
333 #endif
334
335 private:
336   _ValueT __value_;
337 };
338
339 _LIBCPP_INLINE_VAR constexpr partial_ordering partial_ordering::less(_OrdResult::__less);
340 _LIBCPP_INLINE_VAR constexpr partial_ordering partial_ordering::equivalent(_EqResult::__equiv);
341 _LIBCPP_INLINE_VAR constexpr partial_ordering partial_ordering::greater(_OrdResult::__greater);
342 _LIBCPP_INLINE_VAR constexpr partial_ordering partial_ordering::unordered(_NCmpResult ::__unordered);
343
344 _LIBCPP_INLINE_VISIBILITY
345 constexpr bool operator==(partial_ordering __v, _CmpUnspecifiedParam) noexcept {
346   return __v.__is_ordered() && __v.__value_ == 0;
347 }
348 _LIBCPP_INLINE_VISIBILITY
349 constexpr bool operator< (partial_ordering __v, _CmpUnspecifiedParam) noexcept {
350   return __v.__is_ordered() && __v.__value_ < 0;
351 }
352 _LIBCPP_INLINE_VISIBILITY
353 constexpr bool operator<=(partial_ordering __v, _CmpUnspecifiedParam) noexcept {
354   return __v.__is_ordered() && __v.__value_ <= 0;
355 }
356 _LIBCPP_INLINE_VISIBILITY
357 constexpr bool operator> (partial_ordering __v, _CmpUnspecifiedParam) noexcept {
358   return __v.__is_ordered() && __v.__value_ > 0;
359 }
360 _LIBCPP_INLINE_VISIBILITY
361 constexpr bool operator>=(partial_ordering __v, _CmpUnspecifiedParam) noexcept {
362   return __v.__is_ordered() && __v.__value_ >= 0;
363 }
364
365 _LIBCPP_INLINE_VISIBILITY
366 constexpr bool operator==(_CmpUnspecifiedParam, partial_ordering __v) noexcept {
367   return __v.__is_ordered() && 0 == __v.__value_;
368 }
369 _LIBCPP_INLINE_VISIBILITY
370 constexpr bool operator< (_CmpUnspecifiedParam, partial_ordering __v) noexcept {
371   return __v.__is_ordered() && 0 < __v.__value_;
372 }
373 _LIBCPP_INLINE_VISIBILITY
374 constexpr bool operator<=(_CmpUnspecifiedParam, partial_ordering __v) noexcept {
375   return __v.__is_ordered() && 0 <= __v.__value_;
376 }
377 _LIBCPP_INLINE_VISIBILITY
378 constexpr bool operator> (_CmpUnspecifiedParam, partial_ordering __v) noexcept {
379   return __v.__is_ordered() && 0 > __v.__value_;
380 }
381 _LIBCPP_INLINE_VISIBILITY
382 constexpr bool operator>=(_CmpUnspecifiedParam, partial_ordering __v) noexcept {
383   return __v.__is_ordered() && 0 >= __v.__value_;
384 }
385
386 _LIBCPP_INLINE_VISIBILITY
387 constexpr bool operator!=(partial_ordering __v, _CmpUnspecifiedParam) noexcept {
388   return !__v.__is_ordered() || __v.__value_ != 0;
389 }
390 _LIBCPP_INLINE_VISIBILITY
391 constexpr bool operator!=(_CmpUnspecifiedParam, partial_ordering __v) noexcept {
392   return !__v.__is_ordered() || __v.__value_ != 0;
393 }
394
395 #ifndef _LIBCPP_HAS_NO_SPACESHIP_OPERATOR
396 _LIBCPP_INLINE_VISIBILITY
397 constexpr partial_ordering operator<=>(partial_ordering __v, _CmpUnspecifiedParam) noexcept {
398   return __v;
399 }
400 _LIBCPP_INLINE_VISIBILITY
401 constexpr partial_ordering operator<=>(_CmpUnspecifiedParam, partial_ordering __v) noexcept {
402   return __v < 0 ? partial_ordering::greater : (__v > 0 ? partial_ordering::less : __v);
403 }
404 #endif // _LIBCPP_HAS_NO_SPACESHIP_OPERATOR
405
406 class weak_ordering {
407   using _ValueT = signed char;
408
409   _LIBCPP_INLINE_VISIBILITY
410   explicit constexpr weak_ordering(_EqResult __v) noexcept : __value_(_ValueT(__v)) {}
411   _LIBCPP_INLINE_VISIBILITY
412   explicit constexpr weak_ordering(_OrdResult __v) noexcept : __value_(_ValueT(__v)) {}
413
414 public:
415   static const weak_ordering less;
416   static const weak_ordering equivalent;
417   static const weak_ordering greater;
418
419   // conversions
420   _LIBCPP_INLINE_VISIBILITY
421   constexpr operator weak_equality() const noexcept {
422     return __value_ == 0 ? weak_equality::equivalent
423                          : weak_equality::nonequivalent;
424   }
425
426   _LIBCPP_INLINE_VISIBILITY
427   constexpr operator partial_ordering() const noexcept {
428     return __value_ == 0 ? partial_ordering::equivalent
429         : (__value_ < 0 ? partial_ordering::less : partial_ordering::greater);
430   }
431
432   // comparisons
433   _LIBCPP_INLINE_VISIBILITY friend constexpr bool operator==(weak_ordering __v, _CmpUnspecifiedParam) noexcept;
434   _LIBCPP_INLINE_VISIBILITY friend constexpr bool operator!=(weak_ordering __v, _CmpUnspecifiedParam) noexcept;
435   _LIBCPP_INLINE_VISIBILITY friend constexpr bool operator< (weak_ordering __v, _CmpUnspecifiedParam) noexcept;
436   _LIBCPP_INLINE_VISIBILITY friend constexpr bool operator<=(weak_ordering __v, _CmpUnspecifiedParam) noexcept;
437   _LIBCPP_INLINE_VISIBILITY friend constexpr bool operator> (weak_ordering __v, _CmpUnspecifiedParam) noexcept;
438   _LIBCPP_INLINE_VISIBILITY friend constexpr bool operator>=(weak_ordering __v, _CmpUnspecifiedParam) noexcept;
439   _LIBCPP_INLINE_VISIBILITY friend constexpr bool operator==(_CmpUnspecifiedParam, weak_ordering __v) noexcept;
440   _LIBCPP_INLINE_VISIBILITY friend constexpr bool operator!=(_CmpUnspecifiedParam, weak_ordering __v) noexcept;
441   _LIBCPP_INLINE_VISIBILITY friend constexpr bool operator< (_CmpUnspecifiedParam, weak_ordering __v) noexcept;
442   _LIBCPP_INLINE_VISIBILITY friend constexpr bool operator<=(_CmpUnspecifiedParam, weak_ordering __v) noexcept;
443   _LIBCPP_INLINE_VISIBILITY friend constexpr bool operator> (_CmpUnspecifiedParam, weak_ordering __v) noexcept;
444   _LIBCPP_INLINE_VISIBILITY friend constexpr bool operator>=(_CmpUnspecifiedParam, weak_ordering __v) noexcept;
445
446 #ifndef _LIBCPP_HAS_NO_SPACESHIP_OPERATOR
447   _LIBCPP_INLINE_VISIBILITY friend constexpr bool operator==(weak_ordering, weak_ordering) noexcept = default;
448
449   _LIBCPP_INLINE_VISIBILITY friend constexpr weak_ordering operator<=>(weak_ordering __v, _CmpUnspecifiedParam) noexcept;
450   _LIBCPP_INLINE_VISIBILITY friend constexpr weak_ordering operator<=>(_CmpUnspecifiedParam, weak_ordering __v) noexcept;
451 #endif
452
453 private:
454   _ValueT __value_;
455 };
456
457 _LIBCPP_INLINE_VAR constexpr weak_ordering weak_ordering::less(_OrdResult::__less);
458 _LIBCPP_INLINE_VAR constexpr weak_ordering weak_ordering::equivalent(_EqResult::__equiv);
459 _LIBCPP_INLINE_VAR constexpr weak_ordering weak_ordering::greater(_OrdResult::__greater);
460
461 _LIBCPP_INLINE_VISIBILITY
462 constexpr bool operator==(weak_ordering __v, _CmpUnspecifiedParam) noexcept {
463   return __v.__value_ == 0;
464 }
465 _LIBCPP_INLINE_VISIBILITY
466 constexpr bool operator!=(weak_ordering __v, _CmpUnspecifiedParam) noexcept {
467   return __v.__value_ != 0;
468 }
469 _LIBCPP_INLINE_VISIBILITY
470 constexpr bool operator< (weak_ordering __v, _CmpUnspecifiedParam) noexcept {
471   return __v.__value_ < 0;
472 }
473 _LIBCPP_INLINE_VISIBILITY
474 constexpr bool operator<=(weak_ordering __v, _CmpUnspecifiedParam) noexcept {
475   return __v.__value_ <= 0;
476 }
477 _LIBCPP_INLINE_VISIBILITY
478 constexpr bool operator> (weak_ordering __v, _CmpUnspecifiedParam) noexcept {
479   return __v.__value_ > 0;
480 }
481 _LIBCPP_INLINE_VISIBILITY
482 constexpr bool operator>=(weak_ordering __v, _CmpUnspecifiedParam) noexcept {
483   return __v.__value_ >= 0;
484 }
485 _LIBCPP_INLINE_VISIBILITY
486 constexpr bool operator==(_CmpUnspecifiedParam, weak_ordering __v) noexcept {
487   return 0 == __v.__value_;
488 }
489 _LIBCPP_INLINE_VISIBILITY
490 constexpr bool operator!=(_CmpUnspecifiedParam, weak_ordering __v) noexcept {
491   return 0 != __v.__value_;
492 }
493 _LIBCPP_INLINE_VISIBILITY
494 constexpr bool operator< (_CmpUnspecifiedParam, weak_ordering __v) noexcept {
495   return 0 < __v.__value_;
496 }
497 _LIBCPP_INLINE_VISIBILITY
498 constexpr bool operator<=(_CmpUnspecifiedParam, weak_ordering __v) noexcept {
499   return 0 <= __v.__value_;
500 }
501 _LIBCPP_INLINE_VISIBILITY
502 constexpr bool operator> (_CmpUnspecifiedParam, weak_ordering __v) noexcept {
503   return 0 > __v.__value_;
504 }
505 _LIBCPP_INLINE_VISIBILITY
506 constexpr bool operator>=(_CmpUnspecifiedParam, weak_ordering __v) noexcept {
507   return 0 >= __v.__value_;
508 }
509
510 #ifndef _LIBCPP_HAS_NO_SPACESHIP_OPERATOR
511 _LIBCPP_INLINE_VISIBILITY
512 constexpr weak_ordering operator<=>(weak_ordering __v, _CmpUnspecifiedParam) noexcept {
513   return __v;
514 }
515 _LIBCPP_INLINE_VISIBILITY
516 constexpr weak_ordering operator<=>(_CmpUnspecifiedParam, weak_ordering __v) noexcept {
517   return __v < 0 ? weak_ordering::greater : (__v > 0 ? weak_ordering::less : __v);
518 }
519 #endif // _LIBCPP_HAS_NO_SPACESHIP_OPERATOR
520
521 class strong_ordering {
522   using _ValueT = signed char;
523
524   _LIBCPP_INLINE_VISIBILITY
525   explicit constexpr strong_ordering(_EqResult __v) noexcept : __value_(_ValueT(__v)) {}
526   _LIBCPP_INLINE_VISIBILITY
527   explicit constexpr strong_ordering(_OrdResult __v) noexcept : __value_(_ValueT(__v)) {}
528
529 public:
530   static const strong_ordering less;
531   static const strong_ordering equal;
532   static const strong_ordering equivalent;
533   static const strong_ordering greater;
534
535   // conversions
536   _LIBCPP_INLINE_VISIBILITY
537   constexpr operator weak_equality() const noexcept {
538     return __value_ == 0 ? weak_equality::equivalent
539                          : weak_equality::nonequivalent;
540   }
541
542   _LIBCPP_INLINE_VISIBILITY
543   constexpr operator strong_equality() const noexcept {
544     return __value_ == 0 ? strong_equality::equal
545                          : strong_equality::nonequal;
546   }
547
548   _LIBCPP_INLINE_VISIBILITY
549   constexpr operator partial_ordering() const noexcept {
550     return __value_ == 0 ? partial_ordering::equivalent
551         : (__value_ < 0 ? partial_ordering::less : partial_ordering::greater);
552   }
553
554   _LIBCPP_INLINE_VISIBILITY
555   constexpr operator weak_ordering() const noexcept {
556     return __value_ == 0 ? weak_ordering::equivalent
557         : (__value_ < 0 ? weak_ordering::less : weak_ordering::greater);
558   }
559
560   // comparisons
561   _LIBCPP_INLINE_VISIBILITY friend constexpr bool operator==(strong_ordering __v, _CmpUnspecifiedParam) noexcept;
562   _LIBCPP_INLINE_VISIBILITY friend constexpr bool operator!=(strong_ordering __v, _CmpUnspecifiedParam) noexcept;
563   _LIBCPP_INLINE_VISIBILITY friend constexpr bool operator< (strong_ordering __v, _CmpUnspecifiedParam) noexcept;
564   _LIBCPP_INLINE_VISIBILITY friend constexpr bool operator<=(strong_ordering __v, _CmpUnspecifiedParam) noexcept;
565   _LIBCPP_INLINE_VISIBILITY friend constexpr bool operator> (strong_ordering __v, _CmpUnspecifiedParam) noexcept;
566   _LIBCPP_INLINE_VISIBILITY friend constexpr bool operator>=(strong_ordering __v, _CmpUnspecifiedParam) noexcept;
567   _LIBCPP_INLINE_VISIBILITY friend constexpr bool operator==(_CmpUnspecifiedParam, strong_ordering __v) noexcept;
568   _LIBCPP_INLINE_VISIBILITY friend constexpr bool operator!=(_CmpUnspecifiedParam, strong_ordering __v) noexcept;
569   _LIBCPP_INLINE_VISIBILITY friend constexpr bool operator< (_CmpUnspecifiedParam, strong_ordering __v) noexcept;
570   _LIBCPP_INLINE_VISIBILITY friend constexpr bool operator<=(_CmpUnspecifiedParam, strong_ordering __v) noexcept;
571   _LIBCPP_INLINE_VISIBILITY friend constexpr bool operator> (_CmpUnspecifiedParam, strong_ordering __v) noexcept;
572   _LIBCPP_INLINE_VISIBILITY friend constexpr bool operator>=(_CmpUnspecifiedParam, strong_ordering __v) noexcept;
573
574 #ifndef _LIBCPP_HAS_NO_SPACESHIP_OPERATOR
575   _LIBCPP_INLINE_VISIBILITY friend constexpr bool operator==(strong_ordering, strong_ordering) noexcept = default;
576
577   _LIBCPP_INLINE_VISIBILITY friend constexpr strong_ordering operator<=>(strong_ordering __v, _CmpUnspecifiedParam) noexcept;
578   _LIBCPP_INLINE_VISIBILITY friend constexpr strong_ordering operator<=>(_CmpUnspecifiedParam, strong_ordering __v) noexcept;
579 #endif
580
581 private:
582   _ValueT __value_;
583 };
584
585 _LIBCPP_INLINE_VAR constexpr strong_ordering strong_ordering::less(_OrdResult::__less);
586 _LIBCPP_INLINE_VAR constexpr strong_ordering strong_ordering::equal(_EqResult::__equal);
587 _LIBCPP_INLINE_VAR constexpr strong_ordering strong_ordering::equivalent(_EqResult::__equiv);
588 _LIBCPP_INLINE_VAR constexpr strong_ordering strong_ordering::greater(_OrdResult::__greater);
589
590 _LIBCPP_INLINE_VISIBILITY
591 constexpr bool operator==(strong_ordering __v, _CmpUnspecifiedParam) noexcept {
592   return __v.__value_ == 0;
593 }
594 _LIBCPP_INLINE_VISIBILITY
595 constexpr bool operator!=(strong_ordering __v, _CmpUnspecifiedParam) noexcept {
596   return __v.__value_ != 0;
597 }
598 _LIBCPP_INLINE_VISIBILITY
599 constexpr bool operator< (strong_ordering __v, _CmpUnspecifiedParam) noexcept {
600   return __v.__value_ < 0;
601 }
602 _LIBCPP_INLINE_VISIBILITY
603 constexpr bool operator<=(strong_ordering __v, _CmpUnspecifiedParam) noexcept {
604   return __v.__value_ <= 0;
605 }
606 _LIBCPP_INLINE_VISIBILITY
607 constexpr bool operator> (strong_ordering __v, _CmpUnspecifiedParam) noexcept {
608   return __v.__value_ > 0;
609 }
610 _LIBCPP_INLINE_VISIBILITY
611 constexpr bool operator>=(strong_ordering __v, _CmpUnspecifiedParam) noexcept {
612   return __v.__value_ >= 0;
613 }
614 _LIBCPP_INLINE_VISIBILITY
615 constexpr bool operator==(_CmpUnspecifiedParam, strong_ordering __v) noexcept {
616   return 0 == __v.__value_;
617 }
618 _LIBCPP_INLINE_VISIBILITY
619 constexpr bool operator!=(_CmpUnspecifiedParam, strong_ordering __v) noexcept {
620   return 0 != __v.__value_;
621 }
622 _LIBCPP_INLINE_VISIBILITY
623 constexpr bool operator< (_CmpUnspecifiedParam, strong_ordering __v) noexcept {
624   return 0 < __v.__value_;
625 }
626 _LIBCPP_INLINE_VISIBILITY
627 constexpr bool operator<=(_CmpUnspecifiedParam, strong_ordering __v) noexcept {
628   return 0 <= __v.__value_;
629 }
630 _LIBCPP_INLINE_VISIBILITY
631 constexpr bool operator> (_CmpUnspecifiedParam, strong_ordering __v) noexcept {
632   return 0 > __v.__value_;
633 }
634 _LIBCPP_INLINE_VISIBILITY
635 constexpr bool operator>=(_CmpUnspecifiedParam, strong_ordering __v) noexcept {
636   return 0 >= __v.__value_;
637 }
638
639 #ifndef _LIBCPP_HAS_NO_SPACESHIP_OPERATOR
640 _LIBCPP_INLINE_VISIBILITY
641 constexpr strong_ordering operator<=>(strong_ordering __v, _CmpUnspecifiedParam) noexcept {
642   return __v;
643 }
644 _LIBCPP_INLINE_VISIBILITY
645 constexpr strong_ordering operator<=>(_CmpUnspecifiedParam, strong_ordering __v) noexcept {
646   return __v < 0 ? strong_ordering::greater : (__v > 0 ? strong_ordering::less : __v);
647 }
648 #endif // _LIBCPP_HAS_NO_SPACESHIP_OPERATOR
649
650 // named comparison functions
651 _LIBCPP_INLINE_VISIBILITY
652 constexpr bool is_eq(weak_equality __cmp) noexcept    { return __cmp == 0; }
653
654 _LIBCPP_INLINE_VISIBILITY
655 constexpr bool is_neq(weak_equality __cmp) noexcept    { return __cmp != 0; }
656
657 _LIBCPP_INLINE_VISIBILITY
658 constexpr bool is_lt(partial_ordering __cmp) noexcept { return __cmp < 0; }
659
660 _LIBCPP_INLINE_VISIBILITY
661 constexpr bool is_lteq(partial_ordering __cmp) noexcept { return __cmp <= 0; }
662
663 _LIBCPP_INLINE_VISIBILITY
664 constexpr bool is_gt(partial_ordering __cmp) noexcept { return __cmp > 0; }
665
666 _LIBCPP_INLINE_VISIBILITY
667 constexpr bool is_gteq(partial_ordering __cmp) noexcept { return __cmp >= 0; }
668
669 namespace __comp_detail {
670
671 enum _ClassifyCompCategory : unsigned{
672   _None,
673   _WeakEq,
674   _StrongEq,
675   _PartialOrd,
676   _WeakOrd,
677   _StrongOrd,
678   _CCC_Size
679 };
680
681 template <class _Tp>
682 _LIBCPP_INLINE_VISIBILITY
683 constexpr _ClassifyCompCategory __type_to_enum() noexcept {
684   if (is_same_v<_Tp, weak_equality>)
685     return _WeakEq;
686   if (is_same_v<_Tp, strong_equality>)
687     return _StrongEq;
688   if (is_same_v<_Tp, partial_ordering>)
689     return _PartialOrd;
690   if (is_same_v<_Tp, weak_ordering>)
691     return _WeakOrd;
692   if (is_same_v<_Tp, strong_ordering>)
693     return _StrongOrd;
694   return _None;
695 }
696
697 template <size_t _Size>
698 constexpr _ClassifyCompCategory
699 __compute_comp_type(std::array<_ClassifyCompCategory, _Size> __types) {
700   std::array<int, _CCC_Size> __seen = {};
701   for (auto __type : __types)
702     ++__seen[__type];
703   if (__seen[_None])
704     return _None;
705   if (__seen[_WeakEq])
706     return _WeakEq;
707   if (__seen[_StrongEq] && (__seen[_PartialOrd] || __seen[_WeakOrd]))
708     return _WeakEq;
709   if (__seen[_StrongEq])
710     return _StrongEq;
711   if (__seen[_PartialOrd])
712     return _PartialOrd;
713   if (__seen[_WeakOrd])
714     return _WeakOrd;
715   return _StrongOrd;
716 }
717
718 template <class ..._Ts>
719 constexpr auto __get_comp_type() {
720   using _CCC = _ClassifyCompCategory;
721   constexpr array<_CCC, sizeof...(_Ts)> __type_kinds{{__comp_detail::__type_to_enum<_Ts>()...}};
722   constexpr _CCC _Cat = sizeof...(_Ts) == 0 ? _StrongOrd
723       : __compute_comp_type(__type_kinds);
724   if constexpr (_Cat == _None)
725     return void();
726   else if constexpr (_Cat == _WeakEq)
727     return weak_equality::equivalent;
728   else if constexpr (_Cat == _StrongEq)
729     return strong_equality::equivalent;
730   else if constexpr (_Cat == _PartialOrd)
731     return partial_ordering::equivalent;
732   else if constexpr (_Cat == _WeakOrd)
733     return weak_ordering::equivalent;
734   else if constexpr (_Cat == _StrongOrd)
735     return strong_ordering::equivalent;
736   else
737     static_assert(_Cat != _Cat, "unhandled case");
738 }
739 } // namespace __comp_detail
740
741 // [cmp.common], common comparison category type
742 template<class... _Ts>
743 struct _LIBCPP_TEMPLATE_VIS common_comparison_category {
744   using type = decltype(__comp_detail::__get_comp_type<_Ts...>());
745 };
746
747 template<class... _Ts>
748 using common_comparison_category_t = typename common_comparison_category<_Ts...>::type;
749
750 // [cmp.alg], comparison algorithms
751 // TODO: unimplemented
752 template<class _Tp> constexpr strong_ordering strong_order(const _Tp& __lhs, const _Tp& __rhs);
753 template<class _Tp> constexpr weak_ordering weak_order(const _Tp& __lhs, const _Tp& __rhs);
754 template<class _Tp> constexpr partial_ordering partial_order(const _Tp& __lhs, const _Tp& __rhs);
755 template<class _Tp> constexpr strong_equality strong_equal(const _Tp& __lhs, const _Tp& __rhs);
756 template<class _Tp> constexpr weak_equality weak_equal(const _Tp& __lhs, const _Tp& __rhs);
757
758 #endif // _LIBCPP_STD_VER > 17
759
760 _LIBCPP_END_NAMESPACE_STD
761
762 #endif // _LIBCPP_COMPARE