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