]> gcc.gnu.org Git - gcc.git/blame - libstdc++-v3/libsupc++/compare
libstdc++: remove redundant equality operators
[gcc.git] / libstdc++-v3 / libsupc++ / compare
CommitLineData
b7689b96
JM
1// -*- C++ -*- operator<=> three-way comparison support.
2
3// Copyright (C) 2019 Free Software Foundation, Inc.
4//
5// This file is part of GCC.
6//
7// GCC is free software; you can redistribute it and/or modify
8// it under the terms of the GNU General Public License as published by
9// the Free Software Foundation; either version 3, or (at your option)
10// any later version.
11//
12// GCC is distributed in the hope that it will be useful,
13// but WITHOUT ANY WARRANTY; without even the implied warranty of
14// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15// GNU General Public License for more details.
16//
17// Under Section 7 of GPL version 3, you are granted additional
18// permissions described in the GCC Runtime Library Exception, version
19// 3.1, as published by the Free Software Foundation.
20
21// You should have received a copy of the GNU General Public License and
22// a copy of the GCC Runtime Library Exception along with this program;
23// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
24// <http://www.gnu.org/licenses/>.
25
26/** @file compare
27 * This is a Standard C++ Library header.
28 */
29
30#ifndef _COMPARE
31#define _COMPARE
32
33#pragma GCC system_header
34
35#if __cplusplus > 201703L && __cpp_impl_three_way_comparison >= 201907L
36
37#pragma GCC visibility push(default)
38
39#include <concepts>
40
41namespace std
42{
43#define __cpp_lib_three_way_comparison 201711L
44
45 // [cmp.categories], comparison category types
46
47 namespace __cmp_cat
48 {
49 enum class _Eq
50 { equal = 0, equivalent = equal, nonequal = 1, nonequivalent = nonequal };
51
52 enum class _Ord { _Less = -1, _Greater = 1 };
53
54 enum class _Ncmp { _Unordered = -127 };
55
56 struct __unspec
57 {
58 constexpr __unspec(__unspec*) { }
59 };
60 }
61
62 class weak_equality
63 {
64 int _M_value;
65
66 constexpr explicit
67 weak_equality(__cmp_cat::_Eq __val) noexcept
68 : _M_value(int(__val))
69 { }
70
71 public:
72 // valid values
73
74 static const weak_equality equivalent;
75 static const weak_equality nonequivalent;
76
77 // comparisons
78
79 friend constexpr bool
80 operator==(weak_equality __v, __cmp_cat::__unspec) noexcept
81 { return __v._M_value == 0; }
82
83 friend constexpr bool
84 operator==(weak_equality, weak_equality) noexcept = default;
85
86 friend constexpr weak_equality
87 operator<=>(weak_equality __v, __cmp_cat::__unspec) noexcept
88 { return __v; }
89
90 friend constexpr weak_equality
91 operator<=>(__cmp_cat::__unspec, weak_equality __v) noexcept
92 { return __v; }
93 };
94
95 // valid values' definitions
96 inline constexpr weak_equality
97 weak_equality::equivalent(__cmp_cat::_Eq::equivalent);
98
99 inline constexpr weak_equality
100 weak_equality::nonequivalent(__cmp_cat::_Eq::nonequivalent);
101
102 class strong_equality
103 {
104 int _M_value;
105
106 constexpr explicit
107 strong_equality(__cmp_cat::_Eq __val) noexcept
108 : _M_value(int(__val))
109 { }
110
111 public:
112 // valid values
113
114 static const strong_equality equal;
115 static const strong_equality nonequal;
116 static const strong_equality equivalent;
117 static const strong_equality nonequivalent;
118
119 // conversion
120 constexpr operator weak_equality() const noexcept
121 {
122 if (_M_value == 0)
123 return weak_equality::equivalent;
124 else
125 return weak_equality::nonequivalent;
126 }
127
128 // comparisons
129
130 friend constexpr bool
131 operator==(strong_equality __v, __cmp_cat::__unspec) noexcept
132 { return __v._M_value == 0; }
133
134 friend constexpr bool
135 operator==(strong_equality, strong_equality) noexcept = default;
136
137 friend constexpr strong_equality
138 operator<=>(strong_equality __v, __cmp_cat::__unspec) noexcept
139 { return __v; }
140
141 friend constexpr strong_equality
142 operator<=>(__cmp_cat::__unspec, strong_equality __v) noexcept
143 { return __v; }
144 };
145
146 // valid values' definitions
147 inline constexpr strong_equality
148 strong_equality::equal(__cmp_cat::_Eq::equal);
149
150 inline constexpr strong_equality
151 strong_equality::nonequal(__cmp_cat::_Eq::nonequal);
152
153 inline constexpr strong_equality
154 strong_equality::equivalent(__cmp_cat::_Eq::equivalent);
155
156 inline constexpr strong_equality
157 strong_equality::nonequivalent(__cmp_cat::_Eq::nonequivalent);
158
159 class partial_ordering
160 {
161 int _M_value;
162 bool _M_is_ordered;
163
164 constexpr explicit
165 partial_ordering(__cmp_cat::_Eq __v) noexcept
166 : _M_value(int(__v)), _M_is_ordered(true)
167 { }
168
169 constexpr explicit
170 partial_ordering(__cmp_cat::_Ord __v) noexcept
171 : _M_value(int(__v)), _M_is_ordered(true)
172 { }
173
174 constexpr explicit
175 partial_ordering(__cmp_cat::_Ncmp __v) noexcept
176 : _M_value(int(__v)), _M_is_ordered(false)
177 { }
178
179 public:
180 // valid values
181 static const partial_ordering less;
182 static const partial_ordering equivalent;
183 static const partial_ordering greater;
184 static const partial_ordering unordered;
185
186 // conversion
187 constexpr operator weak_equality() const noexcept
188 {
189 if (_M_value == 0)
190 return weak_equality::equivalent;
191 else
192 return weak_equality::nonequivalent;
193 }
194
195 // comparisons
196 friend constexpr bool
197 operator==(partial_ordering __v, __cmp_cat::__unspec) noexcept
198 { return __v._M_is_ordered && __v._M_value == 0; }
199
200 friend constexpr bool
201 operator==(partial_ordering, partial_ordering) noexcept = default;
202
203 friend constexpr bool
204 operator< (partial_ordering __v, __cmp_cat::__unspec) noexcept
205 { return __v._M_is_ordered && __v._M_value < 0; }
206
207 friend constexpr bool
208 operator> (partial_ordering __v, __cmp_cat::__unspec) noexcept
209 { return __v._M_is_ordered && __v._M_value > 0; }
210
211 friend constexpr bool
212 operator<=(partial_ordering __v, __cmp_cat::__unspec) noexcept
213 { return __v._M_is_ordered && __v._M_value <= 0; }
214
215 friend constexpr bool
216 operator>=(partial_ordering __v, __cmp_cat::__unspec) noexcept
217 { return __v._M_is_ordered && __v._M_value >= 0; }
218
219 friend constexpr bool
220 operator< (__cmp_cat::__unspec, partial_ordering __v) noexcept
221 { return __v._M_is_ordered && 0 < __v._M_value; }
222
223 friend constexpr bool
224 operator> (__cmp_cat::__unspec, partial_ordering __v) noexcept
225 { return __v._M_is_ordered && 0 > __v._M_value; }
226
227 friend constexpr bool
228 operator<=(__cmp_cat::__unspec, partial_ordering __v) noexcept
229 { return __v._M_is_ordered && 0 <= __v._M_value; }
230
231 friend constexpr bool
232 operator>=(__cmp_cat::__unspec, partial_ordering __v) noexcept
233 { return __v._M_is_ordered && 0 >= __v._M_value; }
234
235 friend constexpr partial_ordering
236 operator<=>(partial_ordering __v, __cmp_cat::__unspec) noexcept
237 { return __v; }
238
239 friend constexpr partial_ordering
240 operator<=>(__cmp_cat::__unspec, partial_ordering __v) noexcept
241 {
242 if (__v < 0)
243 return partial_ordering::greater;
244 else if (__v > 0)
245 return partial_ordering::less;
246 else
247 return __v;
248 }
249 };
250
251 // valid values' definitions
252 inline constexpr partial_ordering
253 partial_ordering::less(__cmp_cat::_Ord::_Less);
254
255 inline constexpr partial_ordering
256 partial_ordering::equivalent(__cmp_cat::_Eq::equivalent);
257
258 inline constexpr partial_ordering
259 partial_ordering::greater(__cmp_cat::_Ord::_Greater);
260
261 inline constexpr partial_ordering
262 partial_ordering::unordered(__cmp_cat::_Ncmp::_Unordered);
263
264 class weak_ordering
265 {
266 int _M_value;
267
268 constexpr explicit
269 weak_ordering(__cmp_cat::_Eq __v) noexcept : _M_value(int(__v))
270 { }
271
272 constexpr explicit
273 weak_ordering(__cmp_cat::_Ord __v) noexcept : _M_value(int(__v))
274 { }
275
276 public:
277 // valid values
278 static const weak_ordering less;
279 static const weak_ordering equivalent;
280 static const weak_ordering greater;
281
282 // conversions
283 constexpr operator weak_equality() const noexcept
284 {
285 if (_M_value == 0)
286 return weak_equality::equivalent;
287 else
288 return weak_equality::nonequivalent;
289 }
290
291 constexpr operator partial_ordering() const noexcept
292 {
293 if (_M_value == 0)
294 return partial_ordering::equivalent;
295 else if (_M_value < 0)
296 return partial_ordering::less;
297 else
298 return partial_ordering::greater;
299 }
300
301 // comparisons
302 friend constexpr bool
303 operator==(weak_ordering __v, __cmp_cat::__unspec) noexcept
304 { return __v._M_value == 0; }
305
306 friend constexpr bool
307 operator==(weak_ordering, weak_ordering) noexcept = default;
308
309 friend constexpr bool
310 operator< (weak_ordering __v, __cmp_cat::__unspec) noexcept
311 { return __v._M_value < 0; }
312
313 friend constexpr bool
314 operator> (weak_ordering __v, __cmp_cat::__unspec) noexcept
315 { return __v._M_value > 0; }
316
317 friend constexpr bool
318 operator<=(weak_ordering __v, __cmp_cat::__unspec) noexcept
319 { return __v._M_value <= 0; }
320
321 friend constexpr bool
322 operator>=(weak_ordering __v, __cmp_cat::__unspec) noexcept
323 { return __v._M_value >= 0; }
324
325 friend constexpr bool
326 operator< (__cmp_cat::__unspec, weak_ordering __v) noexcept
327 { return 0 < __v._M_value; }
328
329 friend constexpr bool
330 operator> (__cmp_cat::__unspec, weak_ordering __v) noexcept
331 { return 0 > __v._M_value; }
332
333 friend constexpr bool
334 operator<=(__cmp_cat::__unspec, weak_ordering __v) noexcept
335 { return 0 <= __v._M_value; }
336
337 friend constexpr bool
338 operator>=(__cmp_cat::__unspec, weak_ordering __v) noexcept
339 { return 0 >= __v._M_value; }
340
341 friend constexpr weak_ordering
342 operator<=>(weak_ordering __v, __cmp_cat::__unspec) noexcept
343 { return __v; }
344
345 friend constexpr weak_ordering
346 operator<=>(__cmp_cat::__unspec, weak_ordering __v) noexcept
347 {
348 if (__v < 0)
349 return weak_ordering::greater;
350 else if (__v > 0)
351 return weak_ordering::less;
352 else
353 return __v;
354 }
355 };
356
357 // valid values' definitions
358 inline constexpr weak_ordering
359 weak_ordering::less(__cmp_cat::_Ord::_Less);
360
361 inline constexpr weak_ordering
362 weak_ordering::equivalent(__cmp_cat::_Eq::equivalent);
363
364 inline constexpr weak_ordering
365 weak_ordering::greater(__cmp_cat::_Ord::_Greater);
366
367 class strong_ordering
368 {
369 int _M_value;
370
371 constexpr explicit
372 strong_ordering(__cmp_cat::_Eq __v) noexcept
373 : _M_value(int(__v))
374 { }
375
376 constexpr explicit
377 strong_ordering(__cmp_cat::_Ord __v) noexcept
378 : _M_value(int(__v))
379 { }
380
381 public:
382 // valid values
383 static const strong_ordering less;
384 static const strong_ordering equal;
385 static const strong_ordering equivalent;
386 static const strong_ordering greater;
387
388 // conversions
389 constexpr operator weak_equality() const noexcept
390 {
391 if (_M_value == 0)
392 return weak_equality::equivalent;
393 else
394 return weak_equality::nonequivalent;
395 }
396
397 constexpr operator strong_equality() const noexcept
398 {
399 if (_M_value == 0)
400 return strong_equality::equal;
401 else
402 return strong_equality::nonequal;
403 }
404
405 constexpr operator partial_ordering() const noexcept
406 {
407 if (_M_value == 0)
408 return partial_ordering::equivalent;
409 else if (_M_value < 0)
410 return partial_ordering::less;
411 else
412 return partial_ordering::greater;
413 }
414
415 constexpr operator weak_ordering() const noexcept
416 {
417 if (_M_value == 0)
418 return weak_ordering::equivalent;
419 else if (_M_value < 0)
420 return weak_ordering::less;
421 else
422 return weak_ordering::greater;
423 }
424
425 // comparisons
426 friend constexpr bool
427 operator==(strong_ordering __v, __cmp_cat::__unspec) noexcept
428 { return __v._M_value == 0; }
429
430 friend constexpr bool
431 operator==(strong_ordering, strong_ordering) noexcept = default;
432
433 friend constexpr bool
434 operator< (strong_ordering __v, __cmp_cat::__unspec) noexcept
435 { return __v._M_value < 0; }
436
437 friend constexpr bool
438 operator> (strong_ordering __v, __cmp_cat::__unspec) noexcept
439 { return __v._M_value > 0; }
440
441 friend constexpr bool
442 operator<=(strong_ordering __v, __cmp_cat::__unspec) noexcept
443 { return __v._M_value <= 0; }
444
445 friend constexpr bool
446 operator>=(strong_ordering __v, __cmp_cat::__unspec) noexcept
447 { return __v._M_value >= 0; }
448
449 friend constexpr bool
450 operator< (__cmp_cat::__unspec, strong_ordering __v) noexcept
451 { return 0 < __v._M_value; }
452
453 friend constexpr bool
454 operator> (__cmp_cat::__unspec, strong_ordering __v) noexcept
455 { return 0 > __v._M_value; }
456
457 friend constexpr bool
458 operator<=(__cmp_cat::__unspec, strong_ordering __v) noexcept
459 { return 0 <= __v._M_value; }
460
461 friend constexpr bool
462 operator>=(__cmp_cat::__unspec, strong_ordering __v) noexcept
463 { return 0 >= __v._M_value; }
464
465 friend constexpr strong_ordering
466 operator<=>(strong_ordering __v, __cmp_cat::__unspec) noexcept
467 { return __v; }
468
469 friend constexpr strong_ordering
470 operator<=>(__cmp_cat::__unspec, strong_ordering __v) noexcept
471 {
472 if (__v < 0)
473 return strong_ordering::greater;
474 else if (__v > 0)
475 return strong_ordering::less;
476 else
477 return __v;
478 }
479 };
480
481 // valid values' definitions
482 inline constexpr strong_ordering
483 strong_ordering::less(__cmp_cat::_Ord::_Less);
484
485 inline constexpr strong_ordering
486 strong_ordering::equal(__cmp_cat::_Eq::equal);
487
488 inline constexpr strong_ordering
489 strong_ordering::equivalent(__cmp_cat::_Eq::equivalent);
490
491 inline constexpr strong_ordering
492 strong_ordering::greater(__cmp_cat::_Ord::_Greater);
493
494
495 // named comparison functions
496 constexpr bool
497 is_eq(weak_equality __cmp) noexcept
498 { return __cmp == 0; }
499
500 constexpr bool
501 is_neq(weak_equality __cmp) noexcept
502 { return __cmp != 0; }
503
504 constexpr bool
505 is_lt (partial_ordering __cmp) noexcept
506 { return __cmp < 0; }
507
508 constexpr bool
509 is_lteq(partial_ordering __cmp) noexcept
510 { return __cmp <= 0; }
511
512 constexpr bool
513 is_gt (partial_ordering __cmp) noexcept
514 { return __cmp > 0; }
515
516 constexpr bool
517 is_gteq(partial_ordering __cmp) noexcept
518 { return __cmp >= 0; }
519
520 // [cmp.common], common comparison category type
521 template<typename... _Ts>
522 struct common_comparison_category {
523 // using type = TODO
524 };
525
526 template<typename... _Ts>
527 using common_comparison_category_t
528 = typename common_comparison_category<_Ts...>::type;
529
530#if __cpp_concepts
531 namespace __detail
532 {
533 template<typename _Tp, typename _Cat>
534 concept __compares_as
535 = same_as<common_comparison_category_t<_Tp, _Cat>, _Cat>;
536
537 template<typename _Tp, typename _Up>
538 concept __partially_ordered_with
539 = requires(const remove_reference_t<_Tp>& __t,
540 const remove_reference_t<_Up>& __u) {
541 { __t < __u } -> boolean;
542 { __t > __u } -> boolean;
543 { __t <= __u } -> boolean;
544 { __t >= __u } -> boolean;
545 { __u < __t } -> boolean;
546 { __u > __t } -> boolean;
547 { __u <= __t } -> boolean;
548 { __u >= __t } -> boolean;
549 };
550 } // namespace __detail
551
552 // [cmp.concept], concept three_way_comparable
553 template<typename _Tp, typename _Cat = partial_ordering>
554 concept three_way_comparable
555 = __detail::__weakly_eq_cmp_with<_Tp, _Tp>
556 && (!convertible_to<_Cat, partial_ordering>
557 || __detail::__partially_ordered_with<_Tp, _Tp>)
558 && requires(const remove_reference_t<_Tp>& __a,
559 const remove_reference_t<_Tp>& __b) {
560 { __a <=> __b } -> __detail::__compares_as<_Cat>;
561 };
562
563 template<typename _Tp, typename _Up, typename _Cat = partial_ordering>
564 concept three_way_comparable_with
565 = __detail::__weakly_eq_cmp_with<_Tp, _Up>
566 && (!convertible_to<_Cat, partial_ordering>
567 || __detail::__partially_ordered_with<_Tp, _Up>)
568 && three_way_comparable<_Tp, _Cat>
569 && three_way_comparable<_Up, _Cat>
570 && common_reference_with<const remove_reference_t<_Tp>&,
571 const remove_reference_t<_Up>&>
572 && three_way_comparable<
573 common_reference_t<const remove_reference_t<_Tp>&,
574 const remove_reference_t<_Up>&>, _Cat>
575 && requires(const remove_reference_t<_Tp>& __t,
576 const remove_reference_t<_Up>& __u) {
577 { __t <=> __u } -> __detail::__compares_as<_Cat>;
578 { __u <=> __t } -> __detail::__compares_as<_Cat>;
579 };
580#endif
581
582 template<typename _Tp, typename _Up>
583 using __cmp2way_res_t
584 = decltype(std::declval<_Tp&>() <=> std::declval<_Up&>());
585
586 template<typename _Tp, typename _Up = _Tp, typename = void>
587 struct __cmp3way_helper
588 { };
589
590 template<typename _Tp, typename _Up>
591 struct __cmp3way_helper<_Tp, _Up, void_t<__cmp2way_res_t<_Tp, _Up>>>
592 {
593 using type = __cmp2way_res_t<_Tp, _Up>;
594 using __type = type;
595 };
596
597 /// [cmp.result], result of three-way comparison
598 template<typename _Tp, typename _Up = _Tp>
599 struct compare_three_way_result
600 : __cmp3way_helper<_Tp, _Up>
601 { };
602
603 template<typename _Tp, typename _Up = _Tp>
604 using compare_three_way_result_t
605 = typename compare_three_way_result<_Tp, _Up>::__type;
606
607 // [cmp.object], typename compare_three_way
608 struct compare_three_way
609 {
610 // TODO
611#if 0
612 template<typename _Tp, typename _Up>
613 requires (three_way_comparable_with<_Tp, _Up>
614 || BUILTIN-PTR-THREE-WAY(_Tp, _Up))
615 constexpr auto
616 operator()(_Tp&& __t, _Up&& __u) const noexcept
617 {
618 // TODO
619 }
620#endif
621
622 using is_transparent = void;
623 };
624
625 // [cmp.alg], comparison algorithms
626 inline namespace __cmp_alg
627 {
628 // TODO
629#if 0
630 inline constexpr unspecified strong_order = unspecified;
631 inline constexpr unspecified weak_order = unspecified;
632 inline constexpr unspecified partial_order = unspecified;
633 inline constexpr unspecified compare_strong_order_fallback = unspecified;
634 inline constexpr unspecified compare_weak_order_fallback = unspecified;
635 inline constexpr unspecified compare_partial_order_fallback = unspecified;
636#endif
637 }
638}
639
640#pragma GCC visibility pop
641
642#endif // C++20
643
644#endif // _COMPARE
This page took 0.116731 seconds and 5 git commands to generate.