blob: 12c7aa0a740efe322680e773c26184453f7f99fe [file] [log] [blame]
Eric Fiseliere0074fc2018-04-06 21:37:23 +00001// -*- C++ -*-
2//===-------------------------- compare -----------------------------------===//
3//
Chandler Carruthd2012102019-01-19 10:56:40 +00004// 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
Eric Fiseliere0074fc2018-04-06 21:37:23 +00007//
8//===----------------------------------------------------------------------===//
9
10#ifndef _LIBCPP_COMPARE
11#define _LIBCPP_COMPARE
12
13/*
14 compare synopsis
15
16namespace std {
17 // [cmp.categories], comparison category types
18 class 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);
Christopher Di Bella3f33a1e2020-06-18 10:17:57 -040046
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 };
Eric Fiseliere0074fc2018-04-06 21:37:23 +0000124}
125*/
126
127#include <__config>
128#include <type_traits>
Eric Fiseliere0074fc2018-04-06 21:37:23 +0000129
130#ifndef _LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER
131#pragma GCC system_header
132#endif
133
134_LIBCPP_BEGIN_NAMESPACE_STD
135
136#if _LIBCPP_STD_VER > 17
137
138// exposition only
139enum class _LIBCPP_ENUM_VIS _EqResult : unsigned char {
140 __zero = 0,
141 __equal = __zero,
142 __equiv = __equal,
143 __nonequal = 1,
144 __nonequiv = __nonequal
145};
146
147enum class _LIBCPP_ENUM_VIS _OrdResult : signed char {
148 __less = -1,
149 __greater = 1
150};
151
152enum class _LIBCPP_ENUM_VIS _NCmpResult : signed char {
153 __unordered = -127
154};
155
Richard Smith55a75c82020-07-31 15:03:21 -0700156struct _CmpUnspecifiedParam {
157 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEVAL
Richard Smith758569c2020-09-29 17:08:42 -0700158 _CmpUnspecifiedParam(int _CmpUnspecifiedParam::*) noexcept {}
Richard Smith55a75c82020-07-31 15:03:21 -0700159
160 template<typename _Tp, typename = _VSTD::enable_if_t<!_VSTD::is_same_v<_Tp, int>>>
161 _CmpUnspecifiedParam(_Tp) = delete;
162};
Eric Fiseliere0074fc2018-04-06 21:37:23 +0000163
164class weak_equality {
165 _LIBCPP_INLINE_VISIBILITY
166 constexpr explicit weak_equality(_EqResult __val) noexcept : __value_(__val) {}
167
168public:
169 static const weak_equality equivalent;
170 static const weak_equality nonequivalent;
171
Louis Dionne05aca382018-07-10 13:21:03 +0000172 _LIBCPP_INLINE_VISIBILITY friend constexpr bool operator==(weak_equality __v, _CmpUnspecifiedParam) noexcept;
173 _LIBCPP_INLINE_VISIBILITY friend constexpr bool operator==(_CmpUnspecifiedParam, weak_equality __v) noexcept;
174 _LIBCPP_INLINE_VISIBILITY friend constexpr bool operator!=(weak_equality __v, _CmpUnspecifiedParam) noexcept;
175 _LIBCPP_INLINE_VISIBILITY friend constexpr bool operator!=(_CmpUnspecifiedParam, weak_equality __v) noexcept;
Eric Fiseliere0074fc2018-04-06 21:37:23 +0000176
177#ifndef _LIBCPP_HAS_NO_SPACESHIP_OPERATOR
Louis Dionne05aca382018-07-10 13:21:03 +0000178 _LIBCPP_INLINE_VISIBILITY friend constexpr weak_equality operator<=>(weak_equality __v, _CmpUnspecifiedParam) noexcept;
179 _LIBCPP_INLINE_VISIBILITY friend constexpr weak_equality operator<=>(_CmpUnspecifiedParam, weak_equality __v) noexcept;
Eric Fiseliere0074fc2018-04-06 21:37:23 +0000180#endif
181
182private:
183 _EqResult __value_;
184};
185
186_LIBCPP_INLINE_VAR constexpr weak_equality weak_equality::equivalent(_EqResult::__equiv);
187_LIBCPP_INLINE_VAR constexpr weak_equality weak_equality::nonequivalent(_EqResult::__nonequiv);
188
189_LIBCPP_INLINE_VISIBILITY
190inline constexpr bool operator==(weak_equality __v, _CmpUnspecifiedParam) noexcept {
191 return __v.__value_ == _EqResult::__zero;
192}
193
194_LIBCPP_INLINE_VISIBILITY
195inline constexpr bool operator==(_CmpUnspecifiedParam, weak_equality __v) noexcept {
196 return __v.__value_ == _EqResult::__zero;
197}
198
199_LIBCPP_INLINE_VISIBILITY
200inline constexpr bool operator!=(weak_equality __v, _CmpUnspecifiedParam) noexcept {
201 return __v.__value_ != _EqResult::__zero;
202}
203
204_LIBCPP_INLINE_VISIBILITY
205inline constexpr bool operator!=(_CmpUnspecifiedParam, weak_equality __v) noexcept {
206 return __v.__value_ != _EqResult::__zero;
207}
208
209#ifndef _LIBCPP_HAS_NO_SPACESHIP_OPERATOR
210_LIBCPP_INLINE_VISIBILITY
211inline constexpr weak_equality operator<=>(weak_equality __v, _CmpUnspecifiedParam) noexcept {
212 return __v;
213}
214
215_LIBCPP_INLINE_VISIBILITY
216inline constexpr weak_equality operator<=>(_CmpUnspecifiedParam, weak_equality __v) noexcept {
217 return __v;
218}
219#endif
220
221class strong_equality {
222 _LIBCPP_INLINE_VISIBILITY
223 explicit constexpr strong_equality(_EqResult __val) noexcept : __value_(__val) {}
224
225public:
226 static const strong_equality equal;
227 static const strong_equality nonequal;
228 static const strong_equality equivalent;
229 static const strong_equality nonequivalent;
230
231 // conversion
Louis Dionne05aca382018-07-10 13:21:03 +0000232 _LIBCPP_INLINE_VISIBILITY constexpr operator weak_equality() const noexcept {
Eric Fiseliere0074fc2018-04-06 21:37:23 +0000233 return __value_ == _EqResult::__zero ? weak_equality::equivalent
234 : weak_equality::nonequivalent;
235 }
236
237 // comparisons
Louis Dionne05aca382018-07-10 13:21:03 +0000238 _LIBCPP_INLINE_VISIBILITY friend constexpr bool operator==(strong_equality __v, _CmpUnspecifiedParam) noexcept;
239 _LIBCPP_INLINE_VISIBILITY friend constexpr bool operator!=(strong_equality __v, _CmpUnspecifiedParam) noexcept;
240 _LIBCPP_INLINE_VISIBILITY friend constexpr bool operator==(_CmpUnspecifiedParam, strong_equality __v) noexcept;
241 _LIBCPP_INLINE_VISIBILITY friend constexpr bool operator!=(_CmpUnspecifiedParam, strong_equality __v) noexcept;
Eric Fiseliere0074fc2018-04-06 21:37:23 +0000242
243#ifndef _LIBCPP_HAS_NO_SPACESHIP_OPERATOR
Louis Dionne05aca382018-07-10 13:21:03 +0000244 _LIBCPP_INLINE_VISIBILITY friend constexpr strong_equality operator<=>(strong_equality __v, _CmpUnspecifiedParam) noexcept;
245 _LIBCPP_INLINE_VISIBILITY friend constexpr strong_equality operator<=>(_CmpUnspecifiedParam, strong_equality __v) noexcept;
Eric Fiseliere0074fc2018-04-06 21:37:23 +0000246#endif
247private:
248 _EqResult __value_;
249};
250
251_LIBCPP_INLINE_VAR constexpr strong_equality strong_equality::equal(_EqResult::__equal);
252_LIBCPP_INLINE_VAR constexpr strong_equality strong_equality::nonequal(_EqResult::__nonequal);
253_LIBCPP_INLINE_VAR constexpr strong_equality strong_equality::equivalent(_EqResult::__equiv);
254_LIBCPP_INLINE_VAR constexpr strong_equality strong_equality::nonequivalent(_EqResult::__nonequiv);
255
256_LIBCPP_INLINE_VISIBILITY
257constexpr bool operator==(strong_equality __v, _CmpUnspecifiedParam) noexcept {
258 return __v.__value_ == _EqResult::__zero;
259}
260
261_LIBCPP_INLINE_VISIBILITY
262constexpr bool operator==(_CmpUnspecifiedParam, strong_equality __v) noexcept {
263 return __v.__value_ == _EqResult::__zero;
264}
265
266_LIBCPP_INLINE_VISIBILITY
267constexpr bool operator!=(strong_equality __v, _CmpUnspecifiedParam) noexcept {
268 return __v.__value_ != _EqResult::__zero;
269}
270
271_LIBCPP_INLINE_VISIBILITY
272constexpr bool operator!=(_CmpUnspecifiedParam, strong_equality __v) noexcept {
273 return __v.__value_ != _EqResult::__zero;
274}
275
276#ifndef _LIBCPP_HAS_NO_SPACESHIP_OPERATOR
277_LIBCPP_INLINE_VISIBILITY
278constexpr strong_equality operator<=>(strong_equality __v, _CmpUnspecifiedParam) noexcept {
279 return __v;
280}
281
282_LIBCPP_INLINE_VISIBILITY
283constexpr strong_equality operator<=>(_CmpUnspecifiedParam, strong_equality __v) noexcept {
284 return __v;
285}
286#endif // _LIBCPP_HAS_NO_SPACESHIP_OPERATOR
287
288class partial_ordering {
289 using _ValueT = signed char;
290
291 _LIBCPP_INLINE_VISIBILITY
292 explicit constexpr partial_ordering(_EqResult __v) noexcept
293 : __value_(_ValueT(__v)) {}
294
295 _LIBCPP_INLINE_VISIBILITY
296 explicit constexpr partial_ordering(_OrdResult __v) noexcept
297 : __value_(_ValueT(__v)) {}
298
299 _LIBCPP_INLINE_VISIBILITY
300 explicit constexpr partial_ordering(_NCmpResult __v) noexcept
301 : __value_(_ValueT(__v)) {}
302
303 constexpr bool __is_ordered() const noexcept {
304 return __value_ != _ValueT(_NCmpResult::__unordered);
305 }
306public:
307 // valid values
308 static const partial_ordering less;
309 static const partial_ordering equivalent;
310 static const partial_ordering greater;
311 static const partial_ordering unordered;
312
313 // conversion
314 constexpr operator weak_equality() const noexcept {
315 return __value_ == 0 ? weak_equality::equivalent : weak_equality::nonequivalent;
316 }
317
318 // comparisons
Louis Dionne05aca382018-07-10 13:21:03 +0000319 _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< (partial_ordering __v, _CmpUnspecifiedParam) noexcept;
322 _LIBCPP_INLINE_VISIBILITY friend constexpr bool operator<=(partial_ordering __v, _CmpUnspecifiedParam) noexcept;
323 _LIBCPP_INLINE_VISIBILITY friend constexpr bool operator> (partial_ordering __v, _CmpUnspecifiedParam) noexcept;
324 _LIBCPP_INLINE_VISIBILITY friend constexpr bool operator>=(partial_ordering __v, _CmpUnspecifiedParam) 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 _LIBCPP_INLINE_VISIBILITY friend constexpr bool operator< (_CmpUnspecifiedParam, partial_ordering __v) noexcept;
328 _LIBCPP_INLINE_VISIBILITY friend constexpr bool operator<=(_CmpUnspecifiedParam, partial_ordering __v) noexcept;
329 _LIBCPP_INLINE_VISIBILITY friend constexpr bool operator> (_CmpUnspecifiedParam, partial_ordering __v) noexcept;
330 _LIBCPP_INLINE_VISIBILITY friend constexpr bool operator>=(_CmpUnspecifiedParam, partial_ordering __v) noexcept;
Eric Fiseliere0074fc2018-04-06 21:37:23 +0000331
332#ifndef _LIBCPP_HAS_NO_SPACESHIP_OPERATOR
Christopher Di Bella3f33a1e2020-06-18 10:17:57 -0400333 _LIBCPP_INLINE_VISIBILITY friend constexpr bool operator==(partial_ordering, partial_ordering) noexcept = default;
334
Louis Dionne05aca382018-07-10 13:21:03 +0000335 _LIBCPP_INLINE_VISIBILITY friend constexpr partial_ordering operator<=>(partial_ordering __v, _CmpUnspecifiedParam) noexcept;
336 _LIBCPP_INLINE_VISIBILITY friend constexpr partial_ordering operator<=>(_CmpUnspecifiedParam, partial_ordering __v) noexcept;
Eric Fiseliere0074fc2018-04-06 21:37:23 +0000337#endif
338
339private:
340 _ValueT __value_;
341};
342
343_LIBCPP_INLINE_VAR constexpr partial_ordering partial_ordering::less(_OrdResult::__less);
344_LIBCPP_INLINE_VAR constexpr partial_ordering partial_ordering::equivalent(_EqResult::__equiv);
345_LIBCPP_INLINE_VAR constexpr partial_ordering partial_ordering::greater(_OrdResult::__greater);
346_LIBCPP_INLINE_VAR constexpr partial_ordering partial_ordering::unordered(_NCmpResult ::__unordered);
347
348_LIBCPP_INLINE_VISIBILITY
349constexpr bool operator==(partial_ordering __v, _CmpUnspecifiedParam) noexcept {
350 return __v.__is_ordered() && __v.__value_ == 0;
351}
352_LIBCPP_INLINE_VISIBILITY
353constexpr bool operator< (partial_ordering __v, _CmpUnspecifiedParam) noexcept {
354 return __v.__is_ordered() && __v.__value_ < 0;
355}
356_LIBCPP_INLINE_VISIBILITY
357constexpr bool operator<=(partial_ordering __v, _CmpUnspecifiedParam) noexcept {
358 return __v.__is_ordered() && __v.__value_ <= 0;
359}
360_LIBCPP_INLINE_VISIBILITY
361constexpr bool operator> (partial_ordering __v, _CmpUnspecifiedParam) noexcept {
362 return __v.__is_ordered() && __v.__value_ > 0;
363}
364_LIBCPP_INLINE_VISIBILITY
365constexpr bool operator>=(partial_ordering __v, _CmpUnspecifiedParam) noexcept {
366 return __v.__is_ordered() && __v.__value_ >= 0;
367}
368
369_LIBCPP_INLINE_VISIBILITY
370constexpr bool operator==(_CmpUnspecifiedParam, partial_ordering __v) noexcept {
371 return __v.__is_ordered() && 0 == __v.__value_;
372}
373_LIBCPP_INLINE_VISIBILITY
374constexpr bool operator< (_CmpUnspecifiedParam, partial_ordering __v) noexcept {
375 return __v.__is_ordered() && 0 < __v.__value_;
376}
377_LIBCPP_INLINE_VISIBILITY
378constexpr bool operator<=(_CmpUnspecifiedParam, partial_ordering __v) noexcept {
379 return __v.__is_ordered() && 0 <= __v.__value_;
380}
381_LIBCPP_INLINE_VISIBILITY
382constexpr bool operator> (_CmpUnspecifiedParam, partial_ordering __v) noexcept {
383 return __v.__is_ordered() && 0 > __v.__value_;
384}
385_LIBCPP_INLINE_VISIBILITY
386constexpr bool operator>=(_CmpUnspecifiedParam, partial_ordering __v) noexcept {
387 return __v.__is_ordered() && 0 >= __v.__value_;
388}
389
390_LIBCPP_INLINE_VISIBILITY
391constexpr bool operator!=(partial_ordering __v, _CmpUnspecifiedParam) noexcept {
392 return !__v.__is_ordered() || __v.__value_ != 0;
393}
394_LIBCPP_INLINE_VISIBILITY
395constexpr bool operator!=(_CmpUnspecifiedParam, partial_ordering __v) noexcept {
396 return !__v.__is_ordered() || __v.__value_ != 0;
397}
398
399#ifndef _LIBCPP_HAS_NO_SPACESHIP_OPERATOR
400_LIBCPP_INLINE_VISIBILITY
401constexpr partial_ordering operator<=>(partial_ordering __v, _CmpUnspecifiedParam) noexcept {
402 return __v;
403}
404_LIBCPP_INLINE_VISIBILITY
405constexpr partial_ordering operator<=>(_CmpUnspecifiedParam, partial_ordering __v) noexcept {
406 return __v < 0 ? partial_ordering::greater : (__v > 0 ? partial_ordering::less : __v);
407}
408#endif // _LIBCPP_HAS_NO_SPACESHIP_OPERATOR
409
410class weak_ordering {
411 using _ValueT = signed char;
412
413 _LIBCPP_INLINE_VISIBILITY
414 explicit constexpr weak_ordering(_EqResult __v) noexcept : __value_(_ValueT(__v)) {}
415 _LIBCPP_INLINE_VISIBILITY
416 explicit constexpr weak_ordering(_OrdResult __v) noexcept : __value_(_ValueT(__v)) {}
417
418public:
419 static const weak_ordering less;
420 static const weak_ordering equivalent;
421 static const weak_ordering greater;
422
423 // conversions
424 _LIBCPP_INLINE_VISIBILITY
425 constexpr operator weak_equality() const noexcept {
426 return __value_ == 0 ? weak_equality::equivalent
427 : weak_equality::nonequivalent;
428 }
429
430 _LIBCPP_INLINE_VISIBILITY
431 constexpr operator partial_ordering() const noexcept {
432 return __value_ == 0 ? partial_ordering::equivalent
433 : (__value_ < 0 ? partial_ordering::less : partial_ordering::greater);
434 }
435
436 // comparisons
Louis Dionne05aca382018-07-10 13:21:03 +0000437 _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< (weak_ordering __v, _CmpUnspecifiedParam) noexcept;
440 _LIBCPP_INLINE_VISIBILITY friend constexpr bool operator<=(weak_ordering __v, _CmpUnspecifiedParam) noexcept;
441 _LIBCPP_INLINE_VISIBILITY friend constexpr bool operator> (weak_ordering __v, _CmpUnspecifiedParam) noexcept;
442 _LIBCPP_INLINE_VISIBILITY friend constexpr bool operator>=(weak_ordering __v, _CmpUnspecifiedParam) 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 _LIBCPP_INLINE_VISIBILITY friend constexpr bool operator< (_CmpUnspecifiedParam, weak_ordering __v) noexcept;
446 _LIBCPP_INLINE_VISIBILITY friend constexpr bool operator<=(_CmpUnspecifiedParam, weak_ordering __v) noexcept;
447 _LIBCPP_INLINE_VISIBILITY friend constexpr bool operator> (_CmpUnspecifiedParam, weak_ordering __v) noexcept;
448 _LIBCPP_INLINE_VISIBILITY friend constexpr bool operator>=(_CmpUnspecifiedParam, weak_ordering __v) noexcept;
Eric Fiseliere0074fc2018-04-06 21:37:23 +0000449
450#ifndef _LIBCPP_HAS_NO_SPACESHIP_OPERATOR
Christopher Di Bella3f33a1e2020-06-18 10:17:57 -0400451 _LIBCPP_INLINE_VISIBILITY friend constexpr bool operator==(weak_ordering, weak_ordering) noexcept = default;
452
Louis Dionne05aca382018-07-10 13:21:03 +0000453 _LIBCPP_INLINE_VISIBILITY friend constexpr weak_ordering operator<=>(weak_ordering __v, _CmpUnspecifiedParam) noexcept;
454 _LIBCPP_INLINE_VISIBILITY friend constexpr weak_ordering operator<=>(_CmpUnspecifiedParam, weak_ordering __v) noexcept;
Eric Fiseliere0074fc2018-04-06 21:37:23 +0000455#endif
456
457private:
458 _ValueT __value_;
459};
460
461_LIBCPP_INLINE_VAR constexpr weak_ordering weak_ordering::less(_OrdResult::__less);
462_LIBCPP_INLINE_VAR constexpr weak_ordering weak_ordering::equivalent(_EqResult::__equiv);
463_LIBCPP_INLINE_VAR constexpr weak_ordering weak_ordering::greater(_OrdResult::__greater);
464
465_LIBCPP_INLINE_VISIBILITY
466constexpr bool operator==(weak_ordering __v, _CmpUnspecifiedParam) noexcept {
467 return __v.__value_ == 0;
468}
469_LIBCPP_INLINE_VISIBILITY
470constexpr bool operator!=(weak_ordering __v, _CmpUnspecifiedParam) noexcept {
471 return __v.__value_ != 0;
472}
473_LIBCPP_INLINE_VISIBILITY
474constexpr bool operator< (weak_ordering __v, _CmpUnspecifiedParam) noexcept {
475 return __v.__value_ < 0;
476}
477_LIBCPP_INLINE_VISIBILITY
478constexpr bool operator<=(weak_ordering __v, _CmpUnspecifiedParam) noexcept {
479 return __v.__value_ <= 0;
480}
481_LIBCPP_INLINE_VISIBILITY
482constexpr bool operator> (weak_ordering __v, _CmpUnspecifiedParam) noexcept {
483 return __v.__value_ > 0;
484}
485_LIBCPP_INLINE_VISIBILITY
486constexpr bool operator>=(weak_ordering __v, _CmpUnspecifiedParam) noexcept {
487 return __v.__value_ >= 0;
488}
489_LIBCPP_INLINE_VISIBILITY
490constexpr bool operator==(_CmpUnspecifiedParam, weak_ordering __v) noexcept {
491 return 0 == __v.__value_;
492}
493_LIBCPP_INLINE_VISIBILITY
494constexpr bool operator!=(_CmpUnspecifiedParam, weak_ordering __v) noexcept {
495 return 0 != __v.__value_;
496}
497_LIBCPP_INLINE_VISIBILITY
498constexpr bool operator< (_CmpUnspecifiedParam, weak_ordering __v) noexcept {
499 return 0 < __v.__value_;
500}
501_LIBCPP_INLINE_VISIBILITY
502constexpr bool operator<=(_CmpUnspecifiedParam, weak_ordering __v) noexcept {
503 return 0 <= __v.__value_;
504}
505_LIBCPP_INLINE_VISIBILITY
506constexpr bool operator> (_CmpUnspecifiedParam, weak_ordering __v) noexcept {
507 return 0 > __v.__value_;
508}
509_LIBCPP_INLINE_VISIBILITY
510constexpr bool operator>=(_CmpUnspecifiedParam, weak_ordering __v) noexcept {
511 return 0 >= __v.__value_;
512}
513
514#ifndef _LIBCPP_HAS_NO_SPACESHIP_OPERATOR
515_LIBCPP_INLINE_VISIBILITY
516constexpr weak_ordering operator<=>(weak_ordering __v, _CmpUnspecifiedParam) noexcept {
517 return __v;
518}
519_LIBCPP_INLINE_VISIBILITY
520constexpr weak_ordering operator<=>(_CmpUnspecifiedParam, weak_ordering __v) noexcept {
521 return __v < 0 ? weak_ordering::greater : (__v > 0 ? weak_ordering::less : __v);
522}
523#endif // _LIBCPP_HAS_NO_SPACESHIP_OPERATOR
524
525class strong_ordering {
526 using _ValueT = signed char;
527
528 _LIBCPP_INLINE_VISIBILITY
529 explicit constexpr strong_ordering(_EqResult __v) noexcept : __value_(_ValueT(__v)) {}
530 _LIBCPP_INLINE_VISIBILITY
531 explicit constexpr strong_ordering(_OrdResult __v) noexcept : __value_(_ValueT(__v)) {}
532
533public:
534 static const strong_ordering less;
535 static const strong_ordering equal;
536 static const strong_ordering equivalent;
537 static const strong_ordering greater;
538
539 // conversions
540 _LIBCPP_INLINE_VISIBILITY
541 constexpr operator weak_equality() const noexcept {
542 return __value_ == 0 ? weak_equality::equivalent
543 : weak_equality::nonequivalent;
544 }
545
546 _LIBCPP_INLINE_VISIBILITY
547 constexpr operator strong_equality() const noexcept {
548 return __value_ == 0 ? strong_equality::equal
549 : strong_equality::nonequal;
550 }
551
552 _LIBCPP_INLINE_VISIBILITY
553 constexpr operator partial_ordering() const noexcept {
554 return __value_ == 0 ? partial_ordering::equivalent
555 : (__value_ < 0 ? partial_ordering::less : partial_ordering::greater);
556 }
557
558 _LIBCPP_INLINE_VISIBILITY
559 constexpr operator weak_ordering() const noexcept {
560 return __value_ == 0 ? weak_ordering::equivalent
561 : (__value_ < 0 ? weak_ordering::less : weak_ordering::greater);
562 }
563
564 // comparisons
Louis Dionne05aca382018-07-10 13:21:03 +0000565 _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< (strong_ordering __v, _CmpUnspecifiedParam) noexcept;
568 _LIBCPP_INLINE_VISIBILITY friend constexpr bool operator<=(strong_ordering __v, _CmpUnspecifiedParam) noexcept;
569 _LIBCPP_INLINE_VISIBILITY friend constexpr bool operator> (strong_ordering __v, _CmpUnspecifiedParam) noexcept;
570 _LIBCPP_INLINE_VISIBILITY friend constexpr bool operator>=(strong_ordering __v, _CmpUnspecifiedParam) 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 _LIBCPP_INLINE_VISIBILITY friend constexpr bool operator< (_CmpUnspecifiedParam, strong_ordering __v) noexcept;
574 _LIBCPP_INLINE_VISIBILITY friend constexpr bool operator<=(_CmpUnspecifiedParam, strong_ordering __v) noexcept;
575 _LIBCPP_INLINE_VISIBILITY friend constexpr bool operator> (_CmpUnspecifiedParam, strong_ordering __v) noexcept;
576 _LIBCPP_INLINE_VISIBILITY friend constexpr bool operator>=(_CmpUnspecifiedParam, strong_ordering __v) noexcept;
Eric Fiseliere0074fc2018-04-06 21:37:23 +0000577
578#ifndef _LIBCPP_HAS_NO_SPACESHIP_OPERATOR
Christopher Di Bella3f33a1e2020-06-18 10:17:57 -0400579 _LIBCPP_INLINE_VISIBILITY friend constexpr bool operator==(strong_ordering, strong_ordering) noexcept = default;
580
Louis Dionne05aca382018-07-10 13:21:03 +0000581 _LIBCPP_INLINE_VISIBILITY friend constexpr strong_ordering operator<=>(strong_ordering __v, _CmpUnspecifiedParam) noexcept;
582 _LIBCPP_INLINE_VISIBILITY friend constexpr strong_ordering operator<=>(_CmpUnspecifiedParam, strong_ordering __v) noexcept;
Eric Fiseliere0074fc2018-04-06 21:37:23 +0000583#endif
584
585private:
586 _ValueT __value_;
587};
588
589_LIBCPP_INLINE_VAR constexpr strong_ordering strong_ordering::less(_OrdResult::__less);
590_LIBCPP_INLINE_VAR constexpr strong_ordering strong_ordering::equal(_EqResult::__equal);
591_LIBCPP_INLINE_VAR constexpr strong_ordering strong_ordering::equivalent(_EqResult::__equiv);
592_LIBCPP_INLINE_VAR constexpr strong_ordering strong_ordering::greater(_OrdResult::__greater);
593
594_LIBCPP_INLINE_VISIBILITY
595constexpr bool operator==(strong_ordering __v, _CmpUnspecifiedParam) noexcept {
596 return __v.__value_ == 0;
597}
598_LIBCPP_INLINE_VISIBILITY
599constexpr bool operator!=(strong_ordering __v, _CmpUnspecifiedParam) noexcept {
600 return __v.__value_ != 0;
601}
602_LIBCPP_INLINE_VISIBILITY
603constexpr bool operator< (strong_ordering __v, _CmpUnspecifiedParam) noexcept {
604 return __v.__value_ < 0;
605}
606_LIBCPP_INLINE_VISIBILITY
607constexpr bool operator<=(strong_ordering __v, _CmpUnspecifiedParam) noexcept {
608 return __v.__value_ <= 0;
609}
610_LIBCPP_INLINE_VISIBILITY
611constexpr bool operator> (strong_ordering __v, _CmpUnspecifiedParam) noexcept {
612 return __v.__value_ > 0;
613}
614_LIBCPP_INLINE_VISIBILITY
615constexpr bool operator>=(strong_ordering __v, _CmpUnspecifiedParam) noexcept {
616 return __v.__value_ >= 0;
617}
618_LIBCPP_INLINE_VISIBILITY
619constexpr bool operator==(_CmpUnspecifiedParam, strong_ordering __v) noexcept {
620 return 0 == __v.__value_;
621}
622_LIBCPP_INLINE_VISIBILITY
623constexpr bool operator!=(_CmpUnspecifiedParam, strong_ordering __v) noexcept {
624 return 0 != __v.__value_;
625}
626_LIBCPP_INLINE_VISIBILITY
627constexpr bool operator< (_CmpUnspecifiedParam, strong_ordering __v) noexcept {
628 return 0 < __v.__value_;
629}
630_LIBCPP_INLINE_VISIBILITY
631constexpr bool operator<=(_CmpUnspecifiedParam, strong_ordering __v) noexcept {
632 return 0 <= __v.__value_;
633}
634_LIBCPP_INLINE_VISIBILITY
635constexpr bool operator> (_CmpUnspecifiedParam, strong_ordering __v) noexcept {
636 return 0 > __v.__value_;
637}
638_LIBCPP_INLINE_VISIBILITY
639constexpr bool operator>=(_CmpUnspecifiedParam, strong_ordering __v) noexcept {
640 return 0 >= __v.__value_;
641}
642
643#ifndef _LIBCPP_HAS_NO_SPACESHIP_OPERATOR
644_LIBCPP_INLINE_VISIBILITY
645constexpr strong_ordering operator<=>(strong_ordering __v, _CmpUnspecifiedParam) noexcept {
646 return __v;
647}
648_LIBCPP_INLINE_VISIBILITY
649constexpr strong_ordering operator<=>(_CmpUnspecifiedParam, strong_ordering __v) noexcept {
650 return __v < 0 ? strong_ordering::greater : (__v > 0 ? strong_ordering::less : __v);
651}
652#endif // _LIBCPP_HAS_NO_SPACESHIP_OPERATOR
653
654// named comparison functions
655_LIBCPP_INLINE_VISIBILITY
656constexpr bool is_eq(weak_equality __cmp) noexcept { return __cmp == 0; }
657
658_LIBCPP_INLINE_VISIBILITY
659constexpr bool is_neq(weak_equality __cmp) noexcept { return __cmp != 0; }
660
661_LIBCPP_INLINE_VISIBILITY
662constexpr bool is_lt(partial_ordering __cmp) noexcept { return __cmp < 0; }
663
664_LIBCPP_INLINE_VISIBILITY
665constexpr bool is_lteq(partial_ordering __cmp) noexcept { return __cmp <= 0; }
666
667_LIBCPP_INLINE_VISIBILITY
668constexpr bool is_gt(partial_ordering __cmp) noexcept { return __cmp > 0; }
669
670_LIBCPP_INLINE_VISIBILITY
671constexpr bool is_gteq(partial_ordering __cmp) noexcept { return __cmp >= 0; }
672
673namespace __comp_detail {
674
675enum _ClassifyCompCategory : unsigned{
676 _None,
677 _WeakEq,
678 _StrongEq,
679 _PartialOrd,
680 _WeakOrd,
681 _StrongOrd,
682 _CCC_Size
683};
684
685template <class _Tp>
686_LIBCPP_INLINE_VISIBILITY
687constexpr _ClassifyCompCategory __type_to_enum() noexcept {
688 if (is_same_v<_Tp, weak_equality>)
689 return _WeakEq;
690 if (is_same_v<_Tp, strong_equality>)
691 return _StrongEq;
692 if (is_same_v<_Tp, partial_ordering>)
693 return _PartialOrd;
694 if (is_same_v<_Tp, weak_ordering>)
695 return _WeakOrd;
696 if (is_same_v<_Tp, strong_ordering>)
697 return _StrongOrd;
698 return _None;
699}
700
701template <size_t _Size>
702constexpr _ClassifyCompCategory
Arthur O'Dwyer6bee3232021-03-24 19:14:51 -0400703__compute_comp_type(const _ClassifyCompCategory (&__types)[_Size]) {
704 int __seen[_CCC_Size] = {};
Eric Fiseliere0074fc2018-04-06 21:37:23 +0000705 for (auto __type : __types)
706 ++__seen[__type];
707 if (__seen[_None])
708 return _None;
709 if (__seen[_WeakEq])
710 return _WeakEq;
711 if (__seen[_StrongEq] && (__seen[_PartialOrd] || __seen[_WeakOrd]))
712 return _WeakEq;
713 if (__seen[_StrongEq])
714 return _StrongEq;
715 if (__seen[_PartialOrd])
716 return _PartialOrd;
717 if (__seen[_WeakOrd])
718 return _WeakOrd;
719 return _StrongOrd;
720}
721
722template <class ..._Ts>
723constexpr auto __get_comp_type() {
724 using _CCC = _ClassifyCompCategory;
Arthur O'Dwyer6bee3232021-03-24 19:14:51 -0400725 constexpr _CCC __type_kinds[] = {_StrongOrd, __type_to_enum<_Ts>()...};
726 constexpr _CCC _Cat = __compute_comp_type(__type_kinds);
Eric Fiseliere0074fc2018-04-06 21:37:23 +0000727 if constexpr (_Cat == _None)
Eric Fiselierafcb4b82018-04-07 04:28:11 +0000728 return void();
Eric Fiseliere0074fc2018-04-06 21:37:23 +0000729 else if constexpr (_Cat == _WeakEq)
730 return weak_equality::equivalent;
731 else if constexpr (_Cat == _StrongEq)
732 return strong_equality::equivalent;
733 else if constexpr (_Cat == _PartialOrd)
734 return partial_ordering::equivalent;
735 else if constexpr (_Cat == _WeakOrd)
736 return weak_ordering::equivalent;
737 else if constexpr (_Cat == _StrongOrd)
738 return strong_ordering::equivalent;
739 else
740 static_assert(_Cat != _Cat, "unhandled case");
741}
742} // namespace __comp_detail
743
744// [cmp.common], common comparison category type
745template<class... _Ts>
746struct _LIBCPP_TEMPLATE_VIS common_comparison_category {
747 using type = decltype(__comp_detail::__get_comp_type<_Ts...>());
748};
749
750template<class... _Ts>
751using common_comparison_category_t = typename common_comparison_category<_Ts...>::type;
752
753// [cmp.alg], comparison algorithms
754// TODO: unimplemented
755template<class _Tp> constexpr strong_ordering strong_order(const _Tp& __lhs, const _Tp& __rhs);
756template<class _Tp> constexpr weak_ordering weak_order(const _Tp& __lhs, const _Tp& __rhs);
757template<class _Tp> constexpr partial_ordering partial_order(const _Tp& __lhs, const _Tp& __rhs);
758template<class _Tp> constexpr strong_equality strong_equal(const _Tp& __lhs, const _Tp& __rhs);
759template<class _Tp> constexpr weak_equality weak_equal(const _Tp& __lhs, const _Tp& __rhs);
760
761#endif // _LIBCPP_STD_VER > 17
762
763_LIBCPP_END_NAMESPACE_STD
764
765#endif // _LIBCPP_COMPARE