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