Qt
Internal/Contributor docs for the Qt SDK. Note: These are NOT official API docs; those are found at https://doc.qt.io/
Loading...
Searching...
No Matches
qcompare.h
Go to the documentation of this file.
1// Copyright (C) 2020 Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.com, author Giuseppe D'Angelo <giuseppe.dangelo@kdab.com>
2// Copyright (C) 2023 The Qt Company Ltd.
3// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
4
5#ifndef QCOMPARE_H
6#define QCOMPARE_H
7
8#if 0
9#pragma qt_class(QtCompare)
10#endif
11
12#include <QtCore/qglobal.h>
13#include <QtCore/qcompare_impl.h>
14#include <QtCore/qstdlibdetection.h>
15
16#ifdef __cpp_lib_bit_cast
17#include <bit>
18#endif
19#ifdef __cpp_lib_three_way_comparison
20#include <compare>
21#endif
22
23QT_BEGIN_NAMESPACE
24
25namespace QtPrivate {
27constexpr CompareUnderlyingType LegacyUncomparableValue = -127; // historic Qt value
28
29// [cmp.categories.pre] / 1
37
39{
41 #if defined(Q_STL_LIBCPP)
42 -127
43 #elif defined(Q_STL_LIBSTDCPP)
44 2
45 #elif defined(Q_STL_MSSTL)
46 -128
47 #elif defined(Q_STL_DINKUMWARE) ||
48 defined(Q_STL_ROGUEWAVE) ||
49 defined(Q_STL_STLPORT) ||
50 defined(Q_STL_SGI)
52 // We haven't seen C++20 of these libraries, so we don't promise BC there.
53 # ifdef __cpp_lib_three_way_comparison
54 # error Please report the numeric value of std::partial_ordering::unordered in your STL in a bug report.
55 # endif
56 #else
57 # error Please handle any newly-added Q_STL_ checks in the above ifdef-ery.
58 #endif
59};
60
61} // namespace QtPrivate
62
64
65template <typename O>
66constexpr O reversed(O o) noexcept
67{
68 // https://eel.is/c++draft/cmp.partialord#5
69 return is_lt(o) ? O::greater :
70 is_gt(o) ? O::less :
71 /*else*/ o ;
72}
73
74} // namespace QtOrderingPrivate
75
76namespace Qt {
77
78class weak_ordering;
79class strong_ordering;
80
82{
83public:
84 static const partial_ordering less;
88
89 friend constexpr bool operator==(partial_ordering lhs,
91 { return lhs.isOrdered() && lhs.m_order == 0; }
92
93 friend constexpr bool operator!=(partial_ordering lhs,
95 { return !lhs.isOrdered() || lhs.m_order != 0; }
96
97 friend constexpr bool operator< (partial_ordering lhs,
99 { return lhs.isOrdered() && lhs.m_order < 0; }
100
101 friend constexpr bool operator<=(partial_ordering lhs,
103 { return lhs.isOrdered() && lhs.m_order <= 0; }
104
105 friend constexpr bool operator> (partial_ordering lhs,
107 { return lhs.isOrdered() && lhs.m_order > 0; }
108
109 friend constexpr bool operator>=(partial_ordering lhs,
111 { return lhs.isOrdered() && lhs.m_order >= 0; }
112
113
115 partial_ordering rhs) noexcept
116 { return rhs.isOrdered() && 0 == rhs.m_order; }
117
119 partial_ordering rhs) noexcept
120 { return !rhs.isOrdered() || 0 != rhs.m_order; }
121
123 partial_ordering rhs) noexcept
124 { return rhs.isOrdered() && 0 < rhs.m_order; }
125
127 partial_ordering rhs) noexcept
128 { return rhs.isOrdered() && 0 <= rhs.m_order; }
129
131 partial_ordering rhs) noexcept
132 { return rhs.isOrdered() && 0 > rhs.m_order; }
133
135 partial_ordering rhs) noexcept
136 { return rhs.isOrdered() && 0 >= rhs.m_order; }
137
138
139#ifdef __cpp_lib_three_way_comparison
140 friend constexpr std::partial_ordering
142 { return lhs; } // https://eel.is/c++draft/cmp.partialord#4
143
144 friend constexpr std::partial_ordering
146 { return QtOrderingPrivate::reversed(rhs); }
147#endif // __cpp_lib_three_way_comparison
148
149
150 friend constexpr bool operator==(partial_ordering lhs, partial_ordering rhs) noexcept
151 { return lhs.m_order == rhs.m_order; }
152
153 friend constexpr bool operator!=(partial_ordering lhs, partial_ordering rhs) noexcept
154 { return lhs.m_order != rhs.m_order; }
155
156#ifdef __cpp_lib_three_way_comparison
158 : m_order{} // == equivalent
159 {
162 else if (stdorder == std::partial_ordering::greater)
166 }
167
168 constexpr Q_IMPLICIT operator std::partial_ordering() const noexcept
169 {
170 static_assert(sizeof(*this) == sizeof(std::partial_ordering));
171#ifdef __cpp_lib_bit_cast
172 return std::bit_cast<std::partial_ordering>(*this);
173#else
174 using O = QtPrivate::Ordering;
175 using U = QtPrivate::Uncomparable;
176 using R = std::partial_ordering;
177 switch (m_order) {
178 case qToUnderlying(O::Less): return R::less;
179 case qToUnderlying(O::Greater): return R::greater;
180 case qToUnderlying(O::Equivalent): return R::equivalent;
181 case qToUnderlying(U::Unordered): return R::unordered;
182 }
184#endif // __cpp_lib_bit_cast
185 }
186
187 friend constexpr bool operator==(partial_ordering lhs, std::partial_ordering rhs) noexcept
188 { return static_cast<std::partial_ordering>(lhs) == rhs; }
189
190 friend constexpr bool operator!=(partial_ordering lhs, std::partial_ordering rhs) noexcept
191 { return static_cast<std::partial_ordering>(lhs) != rhs; }
192
193 friend constexpr bool operator==(std::partial_ordering lhs, partial_ordering rhs) noexcept
194 { return lhs == static_cast<std::partial_ordering>(rhs); }
195
196 friend constexpr bool operator!=(std::partial_ordering lhs, partial_ordering rhs) noexcept
197 { return lhs != static_cast<std::partial_ordering>(rhs); }
198
199 friend constexpr bool operator==(partial_ordering lhs, std::strong_ordering rhs) noexcept
200 { return static_cast<std::partial_ordering>(lhs) == rhs; }
201
202 friend constexpr bool operator!=(partial_ordering lhs, std::strong_ordering rhs) noexcept
203 { return static_cast<std::partial_ordering>(lhs) != rhs; }
204
205 friend constexpr bool operator==(std::strong_ordering lhs, partial_ordering rhs) noexcept
206 { return lhs == static_cast<std::partial_ordering>(rhs); }
207
208 friend constexpr bool operator!=(std::strong_ordering lhs, partial_ordering rhs) noexcept
209 { return lhs != static_cast<std::partial_ordering>(rhs); }
210
211 friend constexpr bool operator==(partial_ordering lhs, std::weak_ordering rhs) noexcept
212 { return static_cast<std::partial_ordering>(lhs) == rhs; }
213
214 friend constexpr bool operator!=(partial_ordering lhs, std::weak_ordering rhs) noexcept
215 { return static_cast<std::partial_ordering>(lhs) != rhs; }
216
217 friend constexpr bool operator==(std::weak_ordering lhs, partial_ordering rhs) noexcept
218 { return lhs == static_cast<std::partial_ordering>(rhs); }
219
220 friend constexpr bool operator!=(std::weak_ordering lhs, partial_ordering rhs) noexcept
221 { return lhs != static_cast<std::partial_ordering>(rhs); }
222#endif // __cpp_lib_three_way_comparison
223
224private:
225 friend class weak_ordering;
226 friend class strong_ordering;
227
228 constexpr explicit partial_ordering(QtPrivate::Ordering order) noexcept
229 : m_order(static_cast<QtPrivate::CompareUnderlyingType>(order))
230 {}
231 constexpr explicit partial_ordering(QtPrivate::Uncomparable order) noexcept
232 : m_order(static_cast<QtPrivate::CompareUnderlyingType>(order))
233 {}
234
235 QT_WARNING_PUSH
236 // https://gcc.gnu.org/bugzilla/show_bug.cgi?id=100903
237 QT_WARNING_DISABLE_GCC("-Wzero-as-null-pointer-constant")
238 QT_WARNING_DISABLE_CLANG("-Wzero-as-null-pointer-constant")
239 friend constexpr bool is_eq (partial_ordering o) noexcept { return o == 0; }
240 friend constexpr bool is_neq (partial_ordering o) noexcept { return o != 0; }
241 friend constexpr bool is_lt (partial_ordering o) noexcept { return o < 0; }
242 friend constexpr bool is_lteq(partial_ordering o) noexcept { return o <= 0; }
243 friend constexpr bool is_gt (partial_ordering o) noexcept { return o > 0; }
244 friend constexpr bool is_gteq(partial_ordering o) noexcept { return o >= 0; }
246
247 // instead of the exposition only is_ordered member in [cmp.partialord],
248 // use a private function
249 constexpr bool isOrdered() const noexcept
251
253};
254
259
261{
262public:
263 static const weak_ordering less;
265 static const weak_ordering greater;
266
267 constexpr Q_IMPLICIT operator partial_ordering() const noexcept
268 { return partial_ordering(static_cast<QtPrivate::Ordering>(m_order)); }
269
270 friend constexpr bool operator==(weak_ordering lhs,
272 { return lhs.m_order == 0; }
273
274 friend constexpr bool operator!=(weak_ordering lhs,
276 { return lhs.m_order != 0; }
277
278 friend constexpr bool operator< (weak_ordering lhs,
280 { return lhs.m_order < 0; }
281
282 friend constexpr bool operator<=(weak_ordering lhs,
284 { return lhs.m_order <= 0; }
285
286 friend constexpr bool operator> (weak_ordering lhs,
288 { return lhs.m_order > 0; }
289
290 friend constexpr bool operator>=(weak_ordering lhs,
292 { return lhs.m_order >= 0; }
293
294
296 weak_ordering rhs) noexcept
297 { return 0 == rhs.m_order; }
298
300 weak_ordering rhs) noexcept
301 { return 0 != rhs.m_order; }
302
304 weak_ordering rhs) noexcept
305 { return 0 < rhs.m_order; }
306
308 weak_ordering rhs) noexcept
309 { return 0 <= rhs.m_order; }
310
312 weak_ordering rhs) noexcept
313 { return 0 > rhs.m_order; }
314
316 weak_ordering rhs) noexcept
317 { return 0 >= rhs.m_order; }
318
319
320#ifdef __cpp_lib_three_way_comparison
321 friend constexpr std::weak_ordering
323 { return lhs; } // https://eel.is/c++draft/cmp.weakord#5
324
325 friend constexpr std::weak_ordering
327 { return QtOrderingPrivate::reversed(rhs); }
328#endif // __cpp_lib_three_way_comparison
329
330
331 friend constexpr bool operator==(weak_ordering lhs, weak_ordering rhs) noexcept
332 { return lhs.m_order == rhs.m_order; }
333
334 friend constexpr bool operator!=(weak_ordering lhs, weak_ordering rhs) noexcept
335 { return lhs.m_order != rhs.m_order; }
336
337 friend constexpr bool operator==(weak_ordering lhs, partial_ordering rhs) noexcept
338 { return static_cast<partial_ordering>(lhs) == rhs; }
339
340 friend constexpr bool operator!=(weak_ordering lhs, partial_ordering rhs) noexcept
341 { return static_cast<partial_ordering>(lhs) != rhs; }
342
343 friend constexpr bool operator==(partial_ordering lhs, weak_ordering rhs) noexcept
344 { return lhs == static_cast<partial_ordering>(rhs); }
345
346 friend constexpr bool operator!=(partial_ordering lhs, weak_ordering rhs) noexcept
347 { return lhs != static_cast<partial_ordering>(rhs); }
348
349#ifdef __cpp_lib_three_way_comparison
351 : m_order{} // == equivalent
352 {
355 else if (stdorder == std::weak_ordering::greater)
357 }
358
359 constexpr Q_IMPLICIT operator std::weak_ordering() const noexcept
360 {
361 static_assert(sizeof(*this) == sizeof(std::weak_ordering));
362#ifdef __cpp_lib_bit_cast
363 return std::bit_cast<std::weak_ordering>(*this);
364#else
365 using O = QtPrivate::Ordering;
366 using R = std::weak_ordering;
367 switch (m_order) {
368 case qToUnderlying(O::Less): return R::less;
369 case qToUnderlying(O::Greater): return R::greater;
370 case qToUnderlying(O::Equivalent): return R::equivalent;
371 }
373#endif // __cpp_lib_bit_cast
374 }
375
376 friend constexpr bool operator==(weak_ordering lhs, std::weak_ordering rhs) noexcept
377 { return static_cast<std::weak_ordering>(lhs) == rhs; }
378
379 friend constexpr bool operator!=(weak_ordering lhs, std::weak_ordering rhs) noexcept
380 { return static_cast<std::weak_ordering>(lhs) != rhs; }
381
382 friend constexpr bool operator==(weak_ordering lhs, std::partial_ordering rhs) noexcept
383 { return static_cast<std::weak_ordering>(lhs) == rhs; }
384
385 friend constexpr bool operator!=(weak_ordering lhs, std::partial_ordering rhs) noexcept
386 { return static_cast<std::weak_ordering>(lhs) != rhs; }
387
388 friend constexpr bool operator==(weak_ordering lhs, std::strong_ordering rhs) noexcept
389 { return static_cast<std::weak_ordering>(lhs) == rhs; }
390
391 friend constexpr bool operator!=(weak_ordering lhs, std::strong_ordering rhs) noexcept
392 { return static_cast<std::weak_ordering>(lhs) != rhs; }
393
394 friend constexpr bool operator==(std::weak_ordering lhs, weak_ordering rhs) noexcept
395 { return lhs == static_cast<std::weak_ordering>(rhs); }
396
397 friend constexpr bool operator!=(std::weak_ordering lhs, weak_ordering rhs) noexcept
398 { return lhs != static_cast<std::weak_ordering>(rhs); }
399
400 friend constexpr bool operator==(std::partial_ordering lhs, weak_ordering rhs) noexcept
401 { return lhs == static_cast<std::weak_ordering>(rhs); }
402
403 friend constexpr bool operator!=(std::partial_ordering lhs, weak_ordering rhs) noexcept
404 { return lhs != static_cast<std::weak_ordering>(rhs); }
405
406 friend constexpr bool operator==(std::strong_ordering lhs, weak_ordering rhs) noexcept
407 { return lhs == static_cast<std::weak_ordering>(rhs); }
408
409 friend constexpr bool operator!=(std::strong_ordering lhs, weak_ordering rhs) noexcept
410 { return lhs != static_cast<std::weak_ordering>(rhs); }
411#endif // __cpp_lib_three_way_comparison
412
413private:
414 friend class strong_ordering;
415
416 constexpr explicit weak_ordering(QtPrivate::Ordering order) noexcept
417 : m_order(static_cast<QtPrivate::CompareUnderlyingType>(order))
418 {}
419
420 QT_WARNING_PUSH
421 // https://gcc.gnu.org/bugzilla/show_bug.cgi?id=100903
422 QT_WARNING_DISABLE_GCC("-Wzero-as-null-pointer-constant")
423 QT_WARNING_DISABLE_CLANG("-Wzero-as-null-pointer-constant")
424 friend constexpr bool is_eq (weak_ordering o) noexcept { return o == 0; }
425 friend constexpr bool is_neq (weak_ordering o) noexcept { return o != 0; }
426 friend constexpr bool is_lt (weak_ordering o) noexcept { return o < 0; }
427 friend constexpr bool is_lteq(weak_ordering o) noexcept { return o <= 0; }
428 friend constexpr bool is_gt (weak_ordering o) noexcept { return o > 0; }
429 friend constexpr bool is_gteq(weak_ordering o) noexcept { return o >= 0; }
431
433};
434
438
440{
441public:
442 static const strong_ordering less;
444 static const strong_ordering equal;
446
447 constexpr Q_IMPLICIT operator partial_ordering() const noexcept
448 { return partial_ordering(static_cast<QtPrivate::Ordering>(m_order)); }
449
450 constexpr Q_IMPLICIT operator weak_ordering() const noexcept
451 { return weak_ordering(static_cast<QtPrivate::Ordering>(m_order)); }
452
453 friend constexpr bool operator==(strong_ordering lhs,
455 { return lhs.m_order == 0; }
456
457 friend constexpr bool operator!=(strong_ordering lhs,
459 { return lhs.m_order != 0; }
460
461 friend constexpr bool operator< (strong_ordering lhs,
463 { return lhs.m_order < 0; }
464
465 friend constexpr bool operator<=(strong_ordering lhs,
467 { return lhs.m_order <= 0; }
468
469 friend constexpr bool operator> (strong_ordering lhs,
471 { return lhs.m_order > 0; }
472
473 friend constexpr bool operator>=(strong_ordering lhs,
475 { return lhs.m_order >= 0; }
476
477
479 strong_ordering rhs) noexcept
480 { return 0 == rhs.m_order; }
481
483 strong_ordering rhs) noexcept
484 { return 0 != rhs.m_order; }
485
487 strong_ordering rhs) noexcept
488 { return 0 < rhs.m_order; }
489
491 strong_ordering rhs) noexcept
492 { return 0 <= rhs.m_order; }
493
495 strong_ordering rhs) noexcept
496 { return 0 > rhs.m_order; }
497
499 strong_ordering rhs) noexcept
500 { return 0 >= rhs.m_order; }
501
502
503#ifdef __cpp_lib_three_way_comparison
504 friend constexpr std::strong_ordering
506 { return lhs; } // https://eel.is/c++draft/cmp.strongord#6
507
508 friend constexpr std::strong_ordering
510 { return QtOrderingPrivate::reversed(rhs); }
511#endif // __cpp_lib_three_way_comparison
512
513
514 friend constexpr bool operator==(strong_ordering lhs, strong_ordering rhs) noexcept
515 { return lhs.m_order == rhs.m_order; }
516
517 friend constexpr bool operator!=(strong_ordering lhs, strong_ordering rhs) noexcept
518 { return lhs.m_order != rhs.m_order; }
519
520 friend constexpr bool operator==(strong_ordering lhs, partial_ordering rhs) noexcept
521 { return static_cast<partial_ordering>(lhs) == rhs; }
522
523 friend constexpr bool operator!=(strong_ordering lhs, partial_ordering rhs) noexcept
524 { return static_cast<partial_ordering>(lhs) == rhs; }
525
526 friend constexpr bool operator==(partial_ordering lhs, strong_ordering rhs) noexcept
527 { return lhs == static_cast<partial_ordering>(rhs); }
528
529 friend constexpr bool operator!=(partial_ordering lhs, strong_ordering rhs) noexcept
530 { return lhs != static_cast<partial_ordering>(rhs); }
531
532 friend constexpr bool operator==(strong_ordering lhs, weak_ordering rhs) noexcept
533 { return static_cast<weak_ordering>(lhs) == rhs; }
534
535 friend constexpr bool operator!=(strong_ordering lhs, weak_ordering rhs) noexcept
536 { return static_cast<weak_ordering>(lhs) == rhs; }
537
538 friend constexpr bool operator==(weak_ordering lhs, strong_ordering rhs) noexcept
539 { return lhs == static_cast<weak_ordering>(rhs); }
540
541 friend constexpr bool operator!=(weak_ordering lhs, strong_ordering rhs) noexcept
542 { return lhs != static_cast<weak_ordering>(rhs); }
543
544#ifdef __cpp_lib_three_way_comparison
546 : m_order{} // == equivalent
547 {
550 else if (stdorder == std::strong_ordering::greater)
552 }
553
554 constexpr Q_IMPLICIT operator std::strong_ordering() const noexcept
555 {
556 static_assert(sizeof(*this) == sizeof(std::strong_ordering));
557#ifdef __cpp_lib_bit_cast
558 return std::bit_cast<std::strong_ordering>(*this);
559#else
560 using O = QtPrivate::Ordering;
561 using R = std::strong_ordering;
562 switch (m_order) {
563 case qToUnderlying(O::Less): return R::less;
564 case qToUnderlying(O::Greater): return R::greater;
565 case qToUnderlying(O::Equal): return R::equal;
566 }
568#endif // __cpp_lib_bit_cast
569 }
570
571 friend constexpr bool operator==(strong_ordering lhs, std::strong_ordering rhs) noexcept
572 { return static_cast<std::strong_ordering>(lhs) == rhs; }
573
574 friend constexpr bool operator!=(strong_ordering lhs, std::strong_ordering rhs) noexcept
575 { return static_cast<std::strong_ordering>(lhs) != rhs; }
576
577 friend constexpr bool operator==(strong_ordering lhs, std::partial_ordering rhs) noexcept
578 { return static_cast<std::strong_ordering>(lhs) == rhs; }
579
580 friend constexpr bool operator!=(strong_ordering lhs, std::partial_ordering rhs) noexcept
581 { return static_cast<std::strong_ordering>(lhs) != rhs; }
582
583 friend constexpr bool operator==(strong_ordering lhs, std::weak_ordering rhs) noexcept
584 { return static_cast<std::strong_ordering>(lhs) == rhs; }
585
586 friend constexpr bool operator!=(strong_ordering lhs, std::weak_ordering rhs) noexcept
587 { return static_cast<std::strong_ordering>(lhs) != rhs; }
588
589 friend constexpr bool operator==(std::strong_ordering lhs, strong_ordering rhs) noexcept
590 { return lhs == static_cast<std::strong_ordering>(rhs); }
591
592 friend constexpr bool operator!=(std::strong_ordering lhs, strong_ordering rhs) noexcept
593 { return lhs != static_cast<std::strong_ordering>(rhs); }
594
595 friend constexpr bool operator==(std::partial_ordering lhs, strong_ordering rhs) noexcept
596 { return lhs == static_cast<std::strong_ordering>(rhs); }
597
598 friend constexpr bool operator!=(std::partial_ordering lhs, strong_ordering rhs) noexcept
599 { return lhs != static_cast<std::strong_ordering>(rhs); }
600
601 friend constexpr bool operator==(std::weak_ordering lhs, strong_ordering rhs) noexcept
602 { return lhs == static_cast<std::strong_ordering>(rhs); }
603
604 friend constexpr bool operator!=(std::weak_ordering lhs, strong_ordering rhs) noexcept
605 { return lhs != static_cast<std::strong_ordering>(rhs); }
606#endif // __cpp_lib_three_way_comparison
607
608 private:
609 constexpr explicit strong_ordering(QtPrivate::Ordering order) noexcept
610 : m_order(static_cast<QtPrivate::CompareUnderlyingType>(order))
611 {}
612
613 QT_WARNING_PUSH
614 // https://gcc.gnu.org/bugzilla/show_bug.cgi?id=100903
615 QT_WARNING_DISABLE_GCC("-Wzero-as-null-pointer-constant")
616 QT_WARNING_DISABLE_CLANG("-Wzero-as-null-pointer-constant")
617 friend constexpr bool is_eq (strong_ordering o) noexcept { return o == 0; }
618 friend constexpr bool is_neq (strong_ordering o) noexcept { return o != 0; }
619 friend constexpr bool is_lt (strong_ordering o) noexcept { return o < 0; }
620 friend constexpr bool is_lteq(strong_ordering o) noexcept { return o <= 0; }
621 friend constexpr bool is_gt (strong_ordering o) noexcept { return o > 0; }
622 friend constexpr bool is_gteq(strong_ordering o) noexcept { return o >= 0; }
624
626};
627
632
633} // namespace Qt
634
635QT_BEGIN_INCLUDE_NAMESPACE
636
637// This is intentionally included after Qt::*_ordering types and before
638// qCompareThreeWay. Do not change!
639#include <QtCore/qcomparehelpers.h>
640
641QT_END_INCLUDE_NAMESPACE
642
643#if defined(Q_QDOC)
644
645template <typename LeftType, typename RightType>
646auto qCompareThreeWay(const LeftType &lhs, const RightType &rhs);
647
648#else
649
650template <typename LT, typename RT,
651 std::enable_if_t<
652 std::disjunction_v<
653 QtOrderingPrivate::CompareThreeWayTester::HasCompareThreeWay<LT, RT>,
654 QtOrderingPrivate::CompareThreeWayTester::HasCompareThreeWay<RT, LT>>,
655 bool> = true>
656auto qCompareThreeWay(const LT &lhs, const RT &rhs)
657 noexcept(QtOrderingPrivate::CompareThreeWayTester::compareThreeWayNoexcept<LT, RT>())
658{
659 using Qt::compareThreeWay;
660 if constexpr (QtOrderingPrivate::CompareThreeWayTester::hasCompareThreeWay_v<LT, RT>) {
661 return compareThreeWay(lhs, rhs);
662 } else {
663 const auto retval = compareThreeWay(rhs, lhs);
664 return QtOrderingPrivate::reversed(retval);
665 }
666}
667
668#endif // defined(Q_QDOC)
669
670//
671// Legacy QPartialOrdering
672//
673
674namespace QtPrivate {
676{
677 Unordered = QtPrivate::LegacyUncomparableValue
678};
679}
680
681// [cmp.partialord]
683{
684public:
685 static const QPartialOrdering Less;
689
690 static const QPartialOrdering less;
694
695 friend constexpr bool operator==(QPartialOrdering lhs,
697 { return lhs.isOrdered() && lhs.m_order == 0; }
698
699 friend constexpr bool operator!=(QPartialOrdering lhs,
701 { return !lhs.isOrdered() || lhs.m_order != 0; }
702
703 friend constexpr bool operator< (QPartialOrdering lhs,
705 { return lhs.isOrdered() && lhs.m_order < 0; }
706
707 friend constexpr bool operator<=(QPartialOrdering lhs,
709 { return lhs.isOrdered() && lhs.m_order <= 0; }
710
711 friend constexpr bool operator> (QPartialOrdering lhs,
713 { return lhs.isOrdered() && lhs.m_order > 0; }
714
715 friend constexpr bool operator>=(QPartialOrdering lhs,
717 { return lhs.isOrdered() && lhs.m_order >= 0; }
718
719
721 QPartialOrdering rhs) noexcept
722 { return rhs.isOrdered() && 0 == rhs.m_order; }
723
725 QPartialOrdering rhs) noexcept
726 { return !rhs.isOrdered() || 0 != rhs.m_order; }
727
729 QPartialOrdering rhs) noexcept
730 { return rhs.isOrdered() && 0 < rhs.m_order; }
731
733 QPartialOrdering rhs) noexcept
734 { return rhs.isOrdered() && 0 <= rhs.m_order; }
735
737 QPartialOrdering rhs) noexcept
738 { return rhs.isOrdered() && 0 > rhs.m_order; }
739
741 QPartialOrdering rhs) noexcept
742 { return rhs.isOrdered() && 0 >= rhs.m_order; }
743
744
745#ifdef __cpp_lib_three_way_comparison
746 friend constexpr std::partial_ordering
748 { return lhs; } // https://eel.is/c++draft/cmp.partialord#4
749
750 friend constexpr std::partial_ordering
752 { return QtOrderingPrivate::reversed(rhs); }
753#endif // __cpp_lib_three_way_comparison
754
755
756 friend constexpr bool operator==(QPartialOrdering lhs, QPartialOrdering rhs) noexcept
757 { return lhs.m_order == rhs.m_order; }
758
759 friend constexpr bool operator!=(QPartialOrdering lhs, QPartialOrdering rhs) noexcept
760 { return lhs.m_order != rhs.m_order; }
761
772
775
778
779 constexpr Q_IMPLICIT operator Qt::partial_ordering() const noexcept
780 {
781 using O = QtPrivate::Ordering;
783 using R = Qt::partial_ordering;
784 switch (m_order) {
785 case qToUnderlying(O::Less): return R::less;
786 case qToUnderlying(O::Greater): return R::greater;
787 case qToUnderlying(O::Equivalent): return R::equivalent;
788 case qToUnderlying(U::Unordered): return R::unordered;
789 }
790 // GCC 8.x does not treat __builtin_unreachable() as constexpr
791#if !defined(Q_CC_GNU_ONLY) || (Q_CC_GNU >= 900)
792 // NOLINTNEXTLINE(qt-use-unreachable-return): Triggers on Clang, breaking GCC 8
794#endif
795 return R::unordered;
796 }
797
798 friend constexpr bool operator==(QPartialOrdering lhs, Qt::partial_ordering rhs) noexcept
799 { Qt::partial_ordering qt = lhs; return qt == rhs; }
800
801 friend constexpr bool operator!=(QPartialOrdering lhs, Qt::partial_ordering rhs) noexcept
802 { Qt::partial_ordering qt = lhs; return qt != rhs; }
803
804 friend constexpr bool operator==(Qt::partial_ordering lhs, QPartialOrdering rhs) noexcept
805 { Qt::partial_ordering qt = rhs; return lhs == qt; }
806
807 friend constexpr bool operator!=(Qt::partial_ordering lhs, QPartialOrdering rhs) noexcept
808 { Qt::partial_ordering qt = rhs; return lhs != qt; }
809
810#ifdef __cpp_lib_three_way_comparison
812 : m_order{} // == equivalent
813 {
816 else if (stdorder == std::partial_ordering::greater)
820 }
821
824
827
828 constexpr Q_IMPLICIT operator std::partial_ordering() const noexcept
829 {
830 using O = QtPrivate::Ordering;
832 using R = std::partial_ordering;
833 switch (m_order) {
834 case qToUnderlying(O::Less): return R::less;
835 case qToUnderlying(O::Greater): return R::greater;
836 case qToUnderlying(O::Equivalent): return R::equivalent;
837 case qToUnderlying(U::Unordered): return R::unordered;
838 }
840 }
841
842 friend constexpr bool operator==(QPartialOrdering lhs, std::partial_ordering rhs) noexcept
843 { return static_cast<std::partial_ordering>(lhs) == rhs; }
844
845 friend constexpr bool operator!=(QPartialOrdering lhs, std::partial_ordering rhs) noexcept
846 { return static_cast<std::partial_ordering>(lhs) != rhs; }
847
848 friend constexpr bool operator==(std::partial_ordering lhs, QPartialOrdering rhs) noexcept
849 { return lhs == static_cast<std::partial_ordering>(rhs); }
850
851 friend constexpr bool operator!=(std::partial_ordering lhs, QPartialOrdering rhs) noexcept
852 { return lhs != static_cast<std::partial_ordering>(rhs); }
853#endif // __cpp_lib_three_way_comparison
854
855private:
856 constexpr explicit QPartialOrdering(QtPrivate::Ordering order) noexcept
857 : m_order(static_cast<QtPrivate::CompareUnderlyingType>(order))
858 {}
859 constexpr explicit QPartialOrdering(QtPrivate::LegacyUncomparable order) noexcept
860 : m_order(static_cast<QtPrivate::CompareUnderlyingType>(order))
861 {}
862
863 QT_WARNING_PUSH
864 // https://gcc.gnu.org/bugzilla/show_bug.cgi?id=100903
865 QT_WARNING_DISABLE_GCC("-Wzero-as-null-pointer-constant")
866 QT_WARNING_DISABLE_CLANG("-Wzero-as-null-pointer-constant")
867 friend constexpr bool is_eq (QPartialOrdering o) noexcept { return o == 0; }
868 friend constexpr bool is_neq (QPartialOrdering o) noexcept { return o != 0; }
869 friend constexpr bool is_lt (QPartialOrdering o) noexcept { return o < 0; }
870 friend constexpr bool is_lteq(QPartialOrdering o) noexcept { return o <= 0; }
871 friend constexpr bool is_gt (QPartialOrdering o) noexcept { return o > 0; }
872 friend constexpr bool is_gteq(QPartialOrdering o) noexcept { return o >= 0; }
874
875 // instead of the exposition only is_ordered member in [cmp.partialord],
876 // use a private function
877 constexpr bool isOrdered() const noexcept
879
881};
882
887
892
893QT_END_NAMESPACE
894
895#endif // QCOMPARE_H
\variable Qt::partial_ordering::less
Definition qcompare.h:683
friend constexpr bool operator==(QPartialOrdering lhs, QtPrivate::CompareAgainstLiteralZero) noexcept
Definition qcompare.h:695
static const QPartialOrdering unordered
Definition qcompare.h:693
friend constexpr bool operator==(QPartialOrdering lhs, Qt::partial_ordering rhs) noexcept
Definition qcompare.h:798
static const QPartialOrdering greater
Definition qcompare.h:692
friend constexpr bool operator<(QtPrivate::CompareAgainstLiteralZero, QPartialOrdering rhs) noexcept
Definition qcompare.h:728
friend constexpr bool operator<(QPartialOrdering lhs, QtPrivate::CompareAgainstLiteralZero) noexcept
Definition qcompare.h:703
static const QPartialOrdering less
Definition qcompare.h:690
friend constexpr bool operator!=(QPartialOrdering lhs, Qt::partial_ordering rhs) noexcept
Definition qcompare.h:801
friend constexpr bool operator==(QtPrivate::CompareAgainstLiteralZero, QPartialOrdering rhs) noexcept
Definition qcompare.h:720
friend constexpr bool operator==(Qt::partial_ordering lhs, QPartialOrdering rhs) noexcept
Definition qcompare.h:804
friend constexpr bool operator>(QPartialOrdering lhs, QtPrivate::CompareAgainstLiteralZero) noexcept
Definition qcompare.h:711
static const QPartialOrdering Less
Definition qcompare.h:685
friend constexpr bool operator>=(QtPrivate::CompareAgainstLiteralZero, QPartialOrdering rhs) noexcept
Definition qcompare.h:740
friend constexpr bool operator==(QPartialOrdering lhs, QPartialOrdering rhs) noexcept
Return true if lhs and rhs represent the same result; otherwise, returns false.
Definition qcompare.h:756
static const QPartialOrdering equivalent
Definition qcompare.h:691
friend constexpr bool operator!=(Qt::partial_ordering lhs, QPartialOrdering rhs) noexcept
Definition qcompare.h:807
friend constexpr bool operator!=(QtPrivate::CompareAgainstLiteralZero, QPartialOrdering rhs) noexcept
Definition qcompare.h:724
friend constexpr bool operator<=(QPartialOrdering lhs, QtPrivate::CompareAgainstLiteralZero) noexcept
Definition qcompare.h:707
friend constexpr bool operator!=(QPartialOrdering lhs, QtPrivate::CompareAgainstLiteralZero) noexcept
Definition qcompare.h:699
friend constexpr bool operator!=(QPartialOrdering lhs, QPartialOrdering rhs) noexcept
Return true if lhs and rhs represent different results; otherwise, returns true.
Definition qcompare.h:759
friend constexpr bool operator>(QtPrivate::CompareAgainstLiteralZero, QPartialOrdering rhs) noexcept
Definition qcompare.h:736
static const QPartialOrdering Greater
Definition qcompare.h:687
friend constexpr bool operator<=(QtPrivate::CompareAgainstLiteralZero, QPartialOrdering rhs) noexcept
Definition qcompare.h:732
static const QPartialOrdering Equivalent
Definition qcompare.h:686
static const QPartialOrdering Unordered
Definition qcompare.h:688
friend constexpr bool operator>=(QPartialOrdering lhs, QtPrivate::CompareAgainstLiteralZero) noexcept
Definition qcompare.h:715
\variable Qt::weak_ordering::less
Definition qcompare.h:82
friend constexpr bool operator>=(QtPrivate::CompareAgainstLiteralZero, partial_ordering rhs) noexcept
Definition qcompare.h:134
friend constexpr bool operator>(partial_ordering lhs, QtPrivate::CompareAgainstLiteralZero) noexcept
Definition qcompare.h:105
friend constexpr bool operator>(QtPrivate::CompareAgainstLiteralZero, partial_ordering rhs) noexcept
Definition qcompare.h:130
friend constexpr bool operator==(QtPrivate::CompareAgainstLiteralZero, partial_ordering rhs) noexcept
Definition qcompare.h:114
friend constexpr bool operator<=(partial_ordering lhs, QtPrivate::CompareAgainstLiteralZero) noexcept
Definition qcompare.h:101
static const partial_ordering equivalent
Definition qcompare.h:85
friend constexpr bool operator<=(QtPrivate::CompareAgainstLiteralZero, partial_ordering rhs) noexcept
Definition qcompare.h:126
friend constexpr bool operator==(partial_ordering lhs, QtPrivate::CompareAgainstLiteralZero) noexcept
Definition qcompare.h:89
friend constexpr bool operator!=(QtPrivate::CompareAgainstLiteralZero, partial_ordering rhs) noexcept
Definition qcompare.h:118
friend constexpr bool operator!=(partial_ordering lhs, QtPrivate::CompareAgainstLiteralZero) noexcept
Definition qcompare.h:93
friend constexpr bool operator<(partial_ordering lhs, QtPrivate::CompareAgainstLiteralZero) noexcept
Definition qcompare.h:97
friend constexpr bool operator<(QtPrivate::CompareAgainstLiteralZero, partial_ordering rhs) noexcept
Definition qcompare.h:122
static const partial_ordering unordered
Definition qcompare.h:87
friend constexpr bool operator>=(partial_ordering lhs, QtPrivate::CompareAgainstLiteralZero) noexcept
Definition qcompare.h:109
static const partial_ordering greater
Definition qcompare.h:86
friend constexpr bool operator!=(partial_ordering lhs, partial_ordering rhs) noexcept
Return true if lhs and rhs represent different results; otherwise, returns true.
Definition qcompare.h:153
static const partial_ordering less
Definition qcompare.h:84
friend constexpr bool operator==(partial_ordering lhs, partial_ordering rhs) noexcept
Return true if lhs and rhs represent the same result; otherwise, returns false.
Definition qcompare.h:150
\inmodule QtCore \title Classes and helpers for defining comparison operators \keyword qtcompare
Definition qcompare.h:440
friend constexpr bool operator<=(strong_ordering lhs, QtPrivate::CompareAgainstLiteralZero) noexcept
Definition qcompare.h:465
friend constexpr bool operator!=(strong_ordering lhs, QtPrivate::CompareAgainstLiteralZero) noexcept
Definition qcompare.h:457
friend constexpr bool operator<(strong_ordering lhs, QtPrivate::CompareAgainstLiteralZero) noexcept
Definition qcompare.h:461
friend constexpr bool operator<(QtPrivate::CompareAgainstLiteralZero, strong_ordering rhs) noexcept
Definition qcompare.h:486
static const strong_ordering greater
Definition qcompare.h:445
friend constexpr bool operator==(strong_ordering lhs, partial_ordering rhs) noexcept
Definition qcompare.h:520
friend constexpr bool operator>(strong_ordering lhs, QtPrivate::CompareAgainstLiteralZero) noexcept
Definition qcompare.h:469
friend constexpr bool operator!=(weak_ordering lhs, strong_ordering rhs) noexcept
Definition qcompare.h:541
friend constexpr bool operator!=(partial_ordering lhs, strong_ordering rhs) noexcept
Definition qcompare.h:529
static const strong_ordering equal
Definition qcompare.h:444
friend constexpr bool operator!=(QtPrivate::CompareAgainstLiteralZero, strong_ordering rhs) noexcept
Definition qcompare.h:482
friend constexpr bool operator==(QtPrivate::CompareAgainstLiteralZero, strong_ordering rhs) noexcept
Definition qcompare.h:478
friend constexpr bool operator==(strong_ordering lhs, weak_ordering rhs) noexcept
Definition qcompare.h:532
friend constexpr bool operator>=(QtPrivate::CompareAgainstLiteralZero, strong_ordering rhs) noexcept
Definition qcompare.h:498
static const strong_ordering less
Definition qcompare.h:442
friend constexpr bool operator!=(strong_ordering lhs, weak_ordering rhs) noexcept
Definition qcompare.h:535
friend constexpr bool operator!=(strong_ordering lhs, partial_ordering rhs) noexcept
Definition qcompare.h:523
friend constexpr bool operator==(strong_ordering lhs, QtPrivate::CompareAgainstLiteralZero) noexcept
Definition qcompare.h:453
static const strong_ordering equivalent
Definition qcompare.h:443
friend constexpr bool operator>(QtPrivate::CompareAgainstLiteralZero, strong_ordering rhs) noexcept
Definition qcompare.h:494
friend constexpr bool operator<=(QtPrivate::CompareAgainstLiteralZero, strong_ordering rhs) noexcept
Definition qcompare.h:490
friend constexpr bool operator==(strong_ordering lhs, strong_ordering rhs) noexcept
Returns true if lhs and rhs represent the same result; otherwise, returns false.
Definition qcompare.h:514
friend constexpr bool operator!=(strong_ordering lhs, strong_ordering rhs) noexcept
Returns true if lhs and rhs represent different results; otherwise, returns true.
Definition qcompare.h:517
friend constexpr bool operator==(weak_ordering lhs, strong_ordering rhs) noexcept
Definition qcompare.h:538
friend constexpr bool operator==(partial_ordering lhs, strong_ordering rhs) noexcept
Definition qcompare.h:526
friend constexpr bool operator>=(strong_ordering lhs, QtPrivate::CompareAgainstLiteralZero) noexcept
Definition qcompare.h:473
\variable Qt::strong_ordering::less
Definition qcompare.h:261
friend constexpr bool operator!=(weak_ordering lhs, QtPrivate::CompareAgainstLiteralZero) noexcept
Definition qcompare.h:274
static const weak_ordering less
Definition qcompare.h:263
friend constexpr bool operator<=(weak_ordering lhs, QtPrivate::CompareAgainstLiteralZero) noexcept
Definition qcompare.h:282
friend constexpr bool operator<(weak_ordering lhs, QtPrivate::CompareAgainstLiteralZero) noexcept
Definition qcompare.h:278
friend constexpr bool operator==(weak_ordering lhs, partial_ordering rhs) noexcept
Definition qcompare.h:337
friend constexpr bool operator<(QtPrivate::CompareAgainstLiteralZero, weak_ordering rhs) noexcept
Definition qcompare.h:303
friend constexpr bool operator>(QtPrivate::CompareAgainstLiteralZero, weak_ordering rhs) noexcept
Definition qcompare.h:311
friend constexpr bool operator==(weak_ordering lhs, QtPrivate::CompareAgainstLiteralZero) noexcept
Definition qcompare.h:270
friend constexpr bool operator!=(QtPrivate::CompareAgainstLiteralZero, weak_ordering rhs) noexcept
Definition qcompare.h:299
friend constexpr bool operator>=(weak_ordering lhs, QtPrivate::CompareAgainstLiteralZero) noexcept
Definition qcompare.h:290
friend constexpr bool operator==(weak_ordering lhs, weak_ordering rhs) noexcept
Return true if lhs and rhs represent the same result; otherwise, returns false.
Definition qcompare.h:331
friend constexpr bool operator>=(QtPrivate::CompareAgainstLiteralZero, weak_ordering rhs) noexcept
Definition qcompare.h:315
static const weak_ordering greater
Definition qcompare.h:265
friend constexpr bool operator>(weak_ordering lhs, QtPrivate::CompareAgainstLiteralZero) noexcept
Definition qcompare.h:286
friend constexpr bool operator!=(weak_ordering lhs, weak_ordering rhs) noexcept
Return true if lhs and rhs represent different results; otherwise, returns true.
Definition qcompare.h:334
friend constexpr bool operator!=(weak_ordering lhs, partial_ordering rhs) noexcept
Definition qcompare.h:340
friend constexpr bool operator<=(QtPrivate::CompareAgainstLiteralZero, weak_ordering rhs) noexcept
Definition qcompare.h:307
friend constexpr bool operator!=(partial_ordering lhs, weak_ordering rhs) noexcept
Definition qcompare.h:346
friend constexpr bool operator==(partial_ordering lhs, weak_ordering rhs) noexcept
Definition qcompare.h:343
static const weak_ordering equivalent
Definition qcompare.h:264
friend constexpr bool operator==(QtPrivate::CompareAgainstLiteralZero, weak_ordering rhs) noexcept
Definition qcompare.h:295
constexpr O reversed(O o) noexcept
Definition qcompare.h:66
constexpr CompareUnderlyingType LegacyUncomparableValue
Definition qcompare.h:27
LegacyUncomparable
Definition qcompare.h:676
Definition qcompare.h:76