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{
40 // We choose the value of our Uncomparable to be the same that the C++
41 // Standard Library chooses for its own std::partial_ordering::unordered,
42 // so we can convert from their type to ours via simple std::bit_cast.
43#if 0
44 // GCC 16 broke ABI, so we cannot use the std::*_ordering types
45 // in our ABI until we drop support for GCC 15 and earlier. When that
46 // happens and std::bit_cast is guaranteed, this can be simplified to:
48#else
50 #if defined(Q_STL_LIBCPP)
51 -127
52 #elif defined(Q_STL_LIBSTDCPP) && QT_VERSION < QT_VERSION_CHECK(7, 0, 0)
53 // GCC 10 to 15 ABI
54 2
55 #elif defined(Q_STL_LIBSTDCPP)
56 -128
57 #elif defined(Q_STL_MSSTL)
58 -128
59 #elif defined(Q_STL_DINKUMWARE) ||
60 defined(Q_STL_ROGUEWAVE) ||
61 defined(Q_STL_STLPORT) ||
62 defined(Q_STL_SGI)
64 // We haven't seen C++20 of these libraries, so we haven't chosen a value yet.
65 # ifdef __cpp_lib_three_way_comparison
66 # error Please report the numeric value of std::partial_ordering::unordered in your STL in a bug report.
67 # endif
68 #else
69 # error Please handle any newly-added Q_STL_ checks in the above ifdef-ery.
70 #endif
71#endif // future Qt
72};
73} // namespace QtPrivate
74
76
77using QtPrivate::Ordering;
78using QtPrivate::Uncomparable;
79
80#if defined(__cpp_lib_bit_cast) && defined(__cpp_lib_three_way_comparison)
81inline constexpr bool OrderingValuesAreEqual =
86inline constexpr bool UnorderedValueIsEqual =
88#endif
89
90template <typename O>
91constexpr O reversed(O o) noexcept
92{
93 // https://eel.is/c++draft/cmp.partialord#5
94 return is_lt(o) ? O::greater :
95 is_gt(o) ? O::less :
96 /*else*/ o ;
97}
98
99template <typename O> constexpr auto toUnderlying(O o) noexcept;
100
101} // namespace QtOrderingPrivate
102
103QT_WARNING_PUSH
104QT_WARNING_DISABLE_MSVC(4702) // unreachable code
105
106// https://gcc.gnu.org/bugzilla/show_bug.cgi?id=100903
107QT_WARNING_DISABLE_GCC("-Wzero-as-null-pointer-constant")
108QT_WARNING_DISABLE_CLANG("-Wzero-as-null-pointer-constant")
109
110namespace Qt {
111
112class weak_ordering;
113class strong_ordering;
114
116{
117public:
118 static const partial_ordering less;
122
123 friend constexpr bool operator==(partial_ordering lhs,
125 { return lhs.isOrdered() && lhs.m_order == 0; }
126
127 friend constexpr bool operator!=(partial_ordering lhs,
129 { return !lhs.isOrdered() || lhs.m_order != 0; }
130
131 friend constexpr bool operator< (partial_ordering lhs,
133 { return lhs.isOrdered() && lhs.m_order < 0; }
134
135 friend constexpr bool operator<=(partial_ordering lhs,
137 { return lhs.isOrdered() && lhs.m_order <= 0; }
138
139 friend constexpr bool operator> (partial_ordering lhs,
141 { return lhs.isOrdered() && lhs.m_order > 0; }
142
143 friend constexpr bool operator>=(partial_ordering lhs,
145 { return lhs.isOrdered() && lhs.m_order >= 0; }
146
147
149 partial_ordering rhs) noexcept
150 { return rhs.isOrdered() && 0 == rhs.m_order; }
151
153 partial_ordering rhs) noexcept
154 { return !rhs.isOrdered() || 0 != rhs.m_order; }
155
157 partial_ordering rhs) noexcept
158 { return rhs.isOrdered() && 0 < rhs.m_order; }
159
161 partial_ordering rhs) noexcept
162 { return rhs.isOrdered() && 0 <= rhs.m_order; }
163
165 partial_ordering rhs) noexcept
166 { return rhs.isOrdered() && 0 > rhs.m_order; }
167
169 partial_ordering rhs) noexcept
170 { return rhs.isOrdered() && 0 >= rhs.m_order; }
171
172
173#ifdef __cpp_lib_three_way_comparison
174 friend constexpr std::partial_ordering
176 { return lhs; } // https://eel.is/c++draft/cmp.partialord#4
177
178 friend constexpr std::partial_ordering
180 { return QtOrderingPrivate::reversed(rhs); }
181#endif // __cpp_lib_three_way_comparison
182
183
184 friend constexpr bool operator==(partial_ordering lhs, partial_ordering rhs) noexcept
185 { return lhs.m_order == rhs.m_order; }
186
187 friend constexpr bool operator!=(partial_ordering lhs, partial_ordering rhs) noexcept
188 { return lhs.m_order != rhs.m_order; }
189
190#ifdef __cpp_lib_three_way_comparison
192 : m_order{} // == equivalent
193 {
194#ifdef __cpp_lib_bit_cast
200 }
201 return;
202 }
203#endif // __cpp_lib_bit_cast
204 if (stdorder < 0)
206 else if (stdorder > 0)
208 else if (stdorder != 0)
210 }
211
212 constexpr Q_IMPLICIT operator std::partial_ordering() const noexcept
213 {
214 static_assert(sizeof(*this) == sizeof(std::partial_ordering));
215 using O = QtPrivate::Ordering;
216 using U = QtPrivate::Uncomparable;
217 using R = std::partial_ordering;
218#ifdef __cpp_lib_bit_cast
222 return R::unordered;
223 }
224 return std::bit_cast<R>(*this);
225 }
226#endif // __cpp_lib_bit_cast
227 switch (m_order) {
228 case qToUnderlying(O::Less): return R::less;
229 case qToUnderlying(O::Greater): return R::greater;
230 case qToUnderlying(O::Equivalent): return R::equivalent;
231 case qToUnderlying(U::Unordered): return R::unordered;
232 }
234 }
235
236 friend constexpr bool operator==(partial_ordering lhs, std::partial_ordering rhs) noexcept
237 { return static_cast<std::partial_ordering>(lhs) == rhs; }
238
239 friend constexpr bool operator!=(partial_ordering lhs, std::partial_ordering rhs) noexcept
240 { return static_cast<std::partial_ordering>(lhs) != rhs; }
241
242 friend constexpr bool operator==(std::partial_ordering lhs, partial_ordering rhs) noexcept
243 { return lhs == static_cast<std::partial_ordering>(rhs); }
244
245 friend constexpr bool operator!=(std::partial_ordering lhs, partial_ordering rhs) noexcept
246 { return lhs != static_cast<std::partial_ordering>(rhs); }
247
248 friend constexpr bool operator==(partial_ordering lhs, std::strong_ordering rhs) noexcept
249 { return static_cast<std::partial_ordering>(lhs) == rhs; }
250
251 friend constexpr bool operator!=(partial_ordering lhs, std::strong_ordering rhs) noexcept
252 { return static_cast<std::partial_ordering>(lhs) != rhs; }
253
254 friend constexpr bool operator==(std::strong_ordering lhs, partial_ordering rhs) noexcept
255 { return lhs == static_cast<std::partial_ordering>(rhs); }
256
257 friend constexpr bool operator!=(std::strong_ordering lhs, partial_ordering rhs) noexcept
258 { return lhs != static_cast<std::partial_ordering>(rhs); }
259
260 friend constexpr bool operator==(partial_ordering lhs, std::weak_ordering rhs) noexcept
261 { return static_cast<std::partial_ordering>(lhs) == rhs; }
262
263 friend constexpr bool operator!=(partial_ordering lhs, std::weak_ordering rhs) noexcept
264 { return static_cast<std::partial_ordering>(lhs) != rhs; }
265
266 friend constexpr bool operator==(std::weak_ordering lhs, partial_ordering rhs) noexcept
267 { return lhs == static_cast<std::partial_ordering>(rhs); }
268
269 friend constexpr bool operator!=(std::weak_ordering lhs, partial_ordering rhs) noexcept
270 { return lhs != static_cast<std::partial_ordering>(rhs); }
271#endif // __cpp_lib_three_way_comparison
272
273private:
274 friend class weak_ordering;
275 friend class strong_ordering;
276 template <typename O> friend constexpr auto QtOrderingPrivate::toUnderlying(O o) noexcept;
277
278 constexpr explicit partial_ordering(QtPrivate::Ordering order) noexcept
279 : m_order(static_cast<QtPrivate::CompareUnderlyingType>(order))
280 {}
281 constexpr explicit partial_ordering(QtPrivate::Uncomparable order) noexcept
282 : m_order(static_cast<QtPrivate::CompareUnderlyingType>(order))
283 {}
284
285 friend constexpr bool is_eq (partial_ordering o) noexcept { return o == 0; }
286 friend constexpr bool is_neq (partial_ordering o) noexcept { return o != 0; }
287 friend constexpr bool is_lt (partial_ordering o) noexcept { return o < 0; }
288 friend constexpr bool is_lteq(partial_ordering o) noexcept { return o <= 0; }
289 friend constexpr bool is_gt (partial_ordering o) noexcept { return o > 0; }
290 friend constexpr bool is_gteq(partial_ordering o) noexcept { return o >= 0; }
291
292 // instead of the exposition only is_ordered member in [cmp.partialord],
293 // use a private function
294 constexpr bool isOrdered() const noexcept
295 { return m_order != static_cast<QtPrivate::CompareUnderlyingType>(QtPrivate::Uncomparable::Unordered); }
296
297 QtPrivate::CompareUnderlyingType m_order;
298};
299
304
306{
307public:
308 static const weak_ordering less;
310 static const weak_ordering greater;
311
312 constexpr Q_IMPLICIT operator partial_ordering() const noexcept
313 { return partial_ordering(static_cast<QtPrivate::Ordering>(m_order)); }
314
315 friend constexpr bool operator==(weak_ordering lhs,
317 { return lhs.m_order == 0; }
318
319 friend constexpr bool operator!=(weak_ordering lhs,
321 { return lhs.m_order != 0; }
322
323 friend constexpr bool operator< (weak_ordering lhs,
325 { return lhs.m_order < 0; }
326
327 friend constexpr bool operator<=(weak_ordering lhs,
329 { return lhs.m_order <= 0; }
330
331 friend constexpr bool operator> (weak_ordering lhs,
333 { return lhs.m_order > 0; }
334
335 friend constexpr bool operator>=(weak_ordering lhs,
337 { return lhs.m_order >= 0; }
338
339
341 weak_ordering rhs) noexcept
342 { return 0 == rhs.m_order; }
343
345 weak_ordering rhs) noexcept
346 { return 0 != rhs.m_order; }
347
349 weak_ordering rhs) noexcept
350 { return 0 < rhs.m_order; }
351
353 weak_ordering rhs) noexcept
354 { return 0 <= rhs.m_order; }
355
357 weak_ordering rhs) noexcept
358 { return 0 > rhs.m_order; }
359
361 weak_ordering rhs) noexcept
362 { return 0 >= rhs.m_order; }
363
364
365#ifdef __cpp_lib_three_way_comparison
366 friend constexpr std::weak_ordering
368 { return lhs; } // https://eel.is/c++draft/cmp.weakord#5
369
370 friend constexpr std::weak_ordering
372 { return QtOrderingPrivate::reversed(rhs); }
373#endif // __cpp_lib_three_way_comparison
374
375
376 friend constexpr bool operator==(weak_ordering lhs, weak_ordering rhs) noexcept
377 { return lhs.m_order == rhs.m_order; }
378
379 friend constexpr bool operator!=(weak_ordering lhs, weak_ordering rhs) noexcept
380 { return lhs.m_order != rhs.m_order; }
381
382 friend constexpr bool operator==(weak_ordering lhs, partial_ordering rhs) noexcept
383 { return static_cast<partial_ordering>(lhs) == rhs; }
384
385 friend constexpr bool operator!=(weak_ordering lhs, partial_ordering rhs) noexcept
386 { return static_cast<partial_ordering>(lhs) != rhs; }
387
388 friend constexpr bool operator==(partial_ordering lhs, weak_ordering rhs) noexcept
389 { return lhs == static_cast<partial_ordering>(rhs); }
390
391 friend constexpr bool operator!=(partial_ordering lhs, weak_ordering rhs) noexcept
392 { return lhs != static_cast<partial_ordering>(rhs); }
393
394#ifdef __cpp_lib_three_way_comparison
396 : m_order{} // == equivalent
397 {
398#ifdef __cpp_lib_bit_cast
401 return;
402 }
403#endif // __cpp_lib_bit_cast
404 if (stdorder < 0)
406 else if (stdorder > 0)
408 }
409
410 constexpr Q_IMPLICIT operator std::weak_ordering() const noexcept
411 {
412 static_assert(sizeof(*this) == sizeof(std::weak_ordering));
413 using O = QtPrivate::Ordering;
414 using R = std::weak_ordering;
415#ifdef __cpp_lib_bit_cast
417 return std::bit_cast<R>(*this);
418#endif // __cpp_lib_bit_cast
419 switch (m_order) {
420 case qToUnderlying(O::Less): return R::less;
421 case qToUnderlying(O::Greater): return R::greater;
422 case qToUnderlying(O::Equivalent): return R::equivalent;
423 }
425 }
426
427 friend constexpr bool operator==(weak_ordering lhs, std::weak_ordering rhs) noexcept
428 { return static_cast<std::weak_ordering>(lhs) == rhs; }
429
430 friend constexpr bool operator!=(weak_ordering lhs, std::weak_ordering rhs) noexcept
431 { return static_cast<std::weak_ordering>(lhs) != rhs; }
432
433 friend constexpr bool operator==(weak_ordering lhs, std::partial_ordering rhs) noexcept
434 { return static_cast<std::weak_ordering>(lhs) == rhs; }
435
436 friend constexpr bool operator!=(weak_ordering lhs, std::partial_ordering rhs) noexcept
437 { return static_cast<std::weak_ordering>(lhs) != rhs; }
438
439 friend constexpr bool operator==(weak_ordering lhs, std::strong_ordering rhs) noexcept
440 { return static_cast<std::weak_ordering>(lhs) == rhs; }
441
442 friend constexpr bool operator!=(weak_ordering lhs, std::strong_ordering rhs) noexcept
443 { return static_cast<std::weak_ordering>(lhs) != rhs; }
444
445 friend constexpr bool operator==(std::weak_ordering lhs, weak_ordering rhs) noexcept
446 { return lhs == static_cast<std::weak_ordering>(rhs); }
447
448 friend constexpr bool operator!=(std::weak_ordering lhs, weak_ordering rhs) noexcept
449 { return lhs != static_cast<std::weak_ordering>(rhs); }
450
451 friend constexpr bool operator==(std::partial_ordering lhs, weak_ordering rhs) noexcept
452 { return lhs == static_cast<std::weak_ordering>(rhs); }
453
454 friend constexpr bool operator!=(std::partial_ordering lhs, weak_ordering rhs) noexcept
455 { return lhs != static_cast<std::weak_ordering>(rhs); }
456
457 friend constexpr bool operator==(std::strong_ordering lhs, weak_ordering rhs) noexcept
458 { return lhs == static_cast<std::weak_ordering>(rhs); }
459
460 friend constexpr bool operator!=(std::strong_ordering lhs, weak_ordering rhs) noexcept
461 { return lhs != static_cast<std::weak_ordering>(rhs); }
462#endif // __cpp_lib_three_way_comparison
463
464private:
465 friend class strong_ordering;
466 template <typename O> friend constexpr auto QtOrderingPrivate::toUnderlying(O o) noexcept;
467
468 constexpr explicit weak_ordering(QtPrivate::Ordering order) noexcept
469 : m_order(static_cast<QtPrivate::CompareUnderlyingType>(order))
470 {}
471
472 friend constexpr bool is_eq (weak_ordering o) noexcept { return o == 0; }
473 friend constexpr bool is_neq (weak_ordering o) noexcept { return o != 0; }
474 friend constexpr bool is_lt (weak_ordering o) noexcept { return o < 0; }
475 friend constexpr bool is_lteq(weak_ordering o) noexcept { return o <= 0; }
476 friend constexpr bool is_gt (weak_ordering o) noexcept { return o > 0; }
477 friend constexpr bool is_gteq(weak_ordering o) noexcept { return o >= 0; }
478
479 QtPrivate::CompareUnderlyingType m_order;
480};
481
485
487{
488public:
489 static const strong_ordering less;
491 static const strong_ordering equal;
493
494 constexpr Q_IMPLICIT operator partial_ordering() const noexcept
495 { return partial_ordering(static_cast<QtPrivate::Ordering>(m_order)); }
496
497 constexpr Q_IMPLICIT operator weak_ordering() const noexcept
498 { return weak_ordering(static_cast<QtPrivate::Ordering>(m_order)); }
499
500 friend constexpr bool operator==(strong_ordering lhs,
502 { return lhs.m_order == 0; }
503
504 friend constexpr bool operator!=(strong_ordering lhs,
506 { return lhs.m_order != 0; }
507
508 friend constexpr bool operator< (strong_ordering lhs,
510 { return lhs.m_order < 0; }
511
512 friend constexpr bool operator<=(strong_ordering lhs,
514 { return lhs.m_order <= 0; }
515
516 friend constexpr bool operator> (strong_ordering lhs,
518 { return lhs.m_order > 0; }
519
520 friend constexpr bool operator>=(strong_ordering lhs,
522 { return lhs.m_order >= 0; }
523
524
526 strong_ordering rhs) noexcept
527 { return 0 == rhs.m_order; }
528
530 strong_ordering rhs) noexcept
531 { return 0 != rhs.m_order; }
532
534 strong_ordering rhs) noexcept
535 { return 0 < rhs.m_order; }
536
538 strong_ordering rhs) noexcept
539 { return 0 <= rhs.m_order; }
540
542 strong_ordering rhs) noexcept
543 { return 0 > rhs.m_order; }
544
546 strong_ordering rhs) noexcept
547 { return 0 >= rhs.m_order; }
548
549
550#ifdef __cpp_lib_three_way_comparison
551 friend constexpr std::strong_ordering
553 { return lhs; } // https://eel.is/c++draft/cmp.strongord#6
554
555 friend constexpr std::strong_ordering
557 { return QtOrderingPrivate::reversed(rhs); }
558#endif // __cpp_lib_three_way_comparison
559
560
561 friend constexpr bool operator==(strong_ordering lhs, strong_ordering rhs) noexcept
562 { return lhs.m_order == rhs.m_order; }
563
564 friend constexpr bool operator!=(strong_ordering lhs, strong_ordering rhs) noexcept
565 { return lhs.m_order != rhs.m_order; }
566
567 friend constexpr bool operator==(strong_ordering lhs, partial_ordering rhs) noexcept
568 { return static_cast<partial_ordering>(lhs) == rhs; }
569
570 friend constexpr bool operator!=(strong_ordering lhs, partial_ordering rhs) noexcept
571 { return static_cast<partial_ordering>(lhs) == rhs; }
572
573 friend constexpr bool operator==(partial_ordering lhs, strong_ordering rhs) noexcept
574 { return lhs == static_cast<partial_ordering>(rhs); }
575
576 friend constexpr bool operator!=(partial_ordering lhs, strong_ordering rhs) noexcept
577 { return lhs != static_cast<partial_ordering>(rhs); }
578
579 friend constexpr bool operator==(strong_ordering lhs, weak_ordering rhs) noexcept
580 { return static_cast<weak_ordering>(lhs) == rhs; }
581
582 friend constexpr bool operator!=(strong_ordering lhs, weak_ordering rhs) noexcept
583 { return static_cast<weak_ordering>(lhs) == rhs; }
584
585 friend constexpr bool operator==(weak_ordering lhs, strong_ordering rhs) noexcept
586 { return lhs == static_cast<weak_ordering>(rhs); }
587
588 friend constexpr bool operator!=(weak_ordering lhs, strong_ordering rhs) noexcept
589 { return lhs != static_cast<weak_ordering>(rhs); }
590
591#ifdef __cpp_lib_three_way_comparison
593 : m_order{} // == equivalent
594 {
595#ifdef __cpp_lib_bit_cast
598 return;
599 }
600#endif // __cpp_lib_bit_cast
601 if (stdorder < 0)
603 else if (stdorder > 0)
605 }
606
607 constexpr Q_IMPLICIT operator std::strong_ordering() const noexcept
608 {
609 static_assert(sizeof(*this) == sizeof(std::strong_ordering));
610 using O = QtPrivate::Ordering;
611 using R = std::strong_ordering;
612#ifdef __cpp_lib_bit_cast
614 return std::bit_cast<R>(*this);
615#endif // __cpp_lib_bit_cast
616 switch (m_order) {
617 case qToUnderlying(O::Less): return R::less;
618 case qToUnderlying(O::Greater): return R::greater;
619 case qToUnderlying(O::Equal): return R::equal;
620 }
622 }
623
624 friend constexpr bool operator==(strong_ordering lhs, std::strong_ordering rhs) noexcept
625 { return static_cast<std::strong_ordering>(lhs) == rhs; }
626
627 friend constexpr bool operator!=(strong_ordering lhs, std::strong_ordering rhs) noexcept
628 { return static_cast<std::strong_ordering>(lhs) != rhs; }
629
630 friend constexpr bool operator==(strong_ordering lhs, std::partial_ordering rhs) noexcept
631 { return static_cast<std::strong_ordering>(lhs) == rhs; }
632
633 friend constexpr bool operator!=(strong_ordering lhs, std::partial_ordering rhs) noexcept
634 { return static_cast<std::strong_ordering>(lhs) != rhs; }
635
636 friend constexpr bool operator==(strong_ordering lhs, std::weak_ordering rhs) noexcept
637 { return static_cast<std::strong_ordering>(lhs) == rhs; }
638
639 friend constexpr bool operator!=(strong_ordering lhs, std::weak_ordering rhs) noexcept
640 { return static_cast<std::strong_ordering>(lhs) != rhs; }
641
642 friend constexpr bool operator==(std::strong_ordering lhs, strong_ordering rhs) noexcept
643 { return lhs == static_cast<std::strong_ordering>(rhs); }
644
645 friend constexpr bool operator!=(std::strong_ordering lhs, strong_ordering rhs) noexcept
646 { return lhs != static_cast<std::strong_ordering>(rhs); }
647
648 friend constexpr bool operator==(std::partial_ordering lhs, strong_ordering rhs) noexcept
649 { return lhs == static_cast<std::strong_ordering>(rhs); }
650
651 friend constexpr bool operator!=(std::partial_ordering lhs, strong_ordering rhs) noexcept
652 { return lhs != static_cast<std::strong_ordering>(rhs); }
653
654 friend constexpr bool operator==(std::weak_ordering lhs, strong_ordering rhs) noexcept
655 { return lhs == static_cast<std::strong_ordering>(rhs); }
656
657 friend constexpr bool operator!=(std::weak_ordering lhs, strong_ordering rhs) noexcept
658 { return lhs != static_cast<std::strong_ordering>(rhs); }
659#endif // __cpp_lib_three_way_comparison
660
661private:
662 template <typename O> friend constexpr auto QtOrderingPrivate::toUnderlying(O o) noexcept;
663
664 constexpr explicit strong_ordering(QtPrivate::Ordering order) noexcept
665 : m_order(static_cast<QtPrivate::CompareUnderlyingType>(order))
666 {}
667
668 friend constexpr bool is_eq (strong_ordering o) noexcept { return o == 0; }
669 friend constexpr bool is_neq (strong_ordering o) noexcept { return o != 0; }
670 friend constexpr bool is_lt (strong_ordering o) noexcept { return o < 0; }
671 friend constexpr bool is_lteq(strong_ordering o) noexcept { return o <= 0; }
672 friend constexpr bool is_gt (strong_ordering o) noexcept { return o > 0; }
673 friend constexpr bool is_gteq(strong_ordering o) noexcept { return o >= 0; }
674
675 QtPrivate::CompareUnderlyingType m_order;
676};
677
682
683} // namespace Qt
684
685QT_WARNING_POP
686
687namespace QtOrderingPrivate {
688template<> constexpr auto toUnderlying<Qt::partial_ordering>(Qt::partial_ordering o) noexcept
689{ return o.m_order; }
690
691template<> constexpr auto toUnderlying<Qt::weak_ordering>(Qt::weak_ordering o) noexcept
692{ return o.m_order; }
693
694template<> constexpr auto toUnderlying<Qt::strong_ordering>(Qt::strong_ordering o) noexcept
695{ return o.m_order; }
696}
697
698QT_BEGIN_INCLUDE_NAMESPACE
699
700// This is intentionally included after Qt::*_ordering types and before
701// qCompareThreeWay. Do not change!
702#include <QtCore/qcomparehelpers.h>
703
704QT_END_INCLUDE_NAMESPACE
705
706#if defined(Q_QDOC)
707
708template <typename LeftType, typename RightType>
709auto qCompareThreeWay(const LeftType &lhs, const RightType &rhs);
710
711#else
712
713template <typename LT, typename RT,
714 std::enable_if_t<
715 std::disjunction_v<
716 QtOrderingPrivate::CompareThreeWayTester::HasCompareThreeWay<LT, RT>,
717 QtOrderingPrivate::CompareThreeWayTester::HasCompareThreeWay<RT, LT>>,
718 bool> = true>
719auto qCompareThreeWay(const LT &lhs, const RT &rhs)
720 noexcept(QtOrderingPrivate::CompareThreeWayTester::compareThreeWayNoexcept<LT, RT>())
721{
722 using Qt::compareThreeWay;
723 if constexpr (QtOrderingPrivate::CompareThreeWayTester::hasCompareThreeWay_v<LT, RT>) {
724 return compareThreeWay(lhs, rhs);
725 } else {
726 const auto retval = compareThreeWay(rhs, lhs);
727 return QtOrderingPrivate::reversed(retval);
728 }
729}
730
731#endif // defined(Q_QDOC)
732
733//
734// Legacy QPartialOrdering
735//
736
737namespace QtPrivate {
739{
740 Unordered = QtPrivate::LegacyUncomparableValue
741};
742}
743
744// [cmp.partialord]
746{
747public:
748 static const QPartialOrdering Less;
752
753 static const QPartialOrdering less;
757
758 friend constexpr bool operator==(QPartialOrdering lhs,
760 { return lhs.isOrdered() && lhs.m_order == 0; }
761
762 friend constexpr bool operator!=(QPartialOrdering lhs,
764 { return !lhs.isOrdered() || lhs.m_order != 0; }
765
766 friend constexpr bool operator< (QPartialOrdering lhs,
768 { return lhs.isOrdered() && lhs.m_order < 0; }
769
770 friend constexpr bool operator<=(QPartialOrdering lhs,
772 { return lhs.isOrdered() && lhs.m_order <= 0; }
773
774 friend constexpr bool operator> (QPartialOrdering lhs,
776 { return lhs.isOrdered() && lhs.m_order > 0; }
777
778 friend constexpr bool operator>=(QPartialOrdering lhs,
780 { return lhs.isOrdered() && lhs.m_order >= 0; }
781
782
784 QPartialOrdering rhs) noexcept
785 { return rhs.isOrdered() && 0 == rhs.m_order; }
786
788 QPartialOrdering rhs) noexcept
789 { return !rhs.isOrdered() || 0 != rhs.m_order; }
790
792 QPartialOrdering rhs) noexcept
793 { return rhs.isOrdered() && 0 < rhs.m_order; }
794
796 QPartialOrdering rhs) noexcept
797 { return rhs.isOrdered() && 0 <= rhs.m_order; }
798
800 QPartialOrdering rhs) noexcept
801 { return rhs.isOrdered() && 0 > rhs.m_order; }
802
804 QPartialOrdering rhs) noexcept
805 { return rhs.isOrdered() && 0 >= rhs.m_order; }
806
807
808#ifdef __cpp_lib_three_way_comparison
809 friend constexpr std::partial_ordering
811 { return lhs; } // https://eel.is/c++draft/cmp.partialord#4
812
813 friend constexpr std::partial_ordering
815 { return QtOrderingPrivate::reversed(rhs); }
816#endif // __cpp_lib_three_way_comparison
817
818
819 friend constexpr bool operator==(QPartialOrdering lhs, QPartialOrdering rhs) noexcept
820 { return lhs.m_order == rhs.m_order; }
821
822 friend constexpr bool operator!=(QPartialOrdering lhs, QPartialOrdering rhs) noexcept
823 { return lhs.m_order != rhs.m_order; }
824
835
838
841
842 constexpr Q_IMPLICIT operator Qt::partial_ordering() const noexcept
843 {
844 using O = QtPrivate::Ordering;
846 using R = Qt::partial_ordering;
847 switch (m_order) {
848 case qToUnderlying(O::Less): return R::less;
849 case qToUnderlying(O::Greater): return R::greater;
850 case qToUnderlying(O::Equivalent): return R::equivalent;
851 case qToUnderlying(U::Unordered): return R::unordered;
852 }
853 // GCC 8.x does not treat __builtin_unreachable() as constexpr
854#if !defined(Q_CC_GNU_ONLY) || (Q_CC_GNU >= 900)
855 // NOLINTNEXTLINE(qt-use-unreachable-return): Triggers on Clang, breaking GCC 8
857#endif
858 return R::unordered;
859 }
860
861 friend constexpr bool operator==(QPartialOrdering lhs, Qt::partial_ordering rhs) noexcept
862 { Qt::partial_ordering qt = lhs; return qt == rhs; }
863
864 friend constexpr bool operator!=(QPartialOrdering lhs, Qt::partial_ordering rhs) noexcept
865 { Qt::partial_ordering qt = lhs; return qt != rhs; }
866
867 friend constexpr bool operator==(Qt::partial_ordering lhs, QPartialOrdering rhs) noexcept
868 { Qt::partial_ordering qt = rhs; return lhs == qt; }
869
870 friend constexpr bool operator!=(Qt::partial_ordering lhs, QPartialOrdering rhs) noexcept
871 { Qt::partial_ordering qt = rhs; return lhs != qt; }
872
873#ifdef __cpp_lib_three_way_comparison
876
879
882
883 constexpr Q_IMPLICIT operator std::partial_ordering() const noexcept
884 {
885 using O = QtPrivate::Ordering;
887 using R = std::partial_ordering;
888 switch (m_order) {
889 case qToUnderlying(O::Less): return R::less;
890 case qToUnderlying(O::Greater): return R::greater;
891 case qToUnderlying(O::Equivalent): return R::equivalent;
892 case qToUnderlying(U::Unordered): return R::unordered;
893 }
895 }
896
897 friend constexpr bool operator==(QPartialOrdering lhs, std::partial_ordering rhs) noexcept
898 { return static_cast<std::partial_ordering>(lhs) == rhs; }
899
900 friend constexpr bool operator!=(QPartialOrdering lhs, std::partial_ordering rhs) noexcept
901 { return static_cast<std::partial_ordering>(lhs) != rhs; }
902
903 friend constexpr bool operator==(std::partial_ordering lhs, QPartialOrdering rhs) noexcept
904 { return lhs == static_cast<std::partial_ordering>(rhs); }
905
906 friend constexpr bool operator!=(std::partial_ordering lhs, QPartialOrdering rhs) noexcept
907 { return lhs != static_cast<std::partial_ordering>(rhs); }
908#endif // __cpp_lib_three_way_comparison
909
910private:
911 constexpr explicit QPartialOrdering(QtPrivate::Ordering order) noexcept
912 : m_order(static_cast<QtPrivate::CompareUnderlyingType>(order))
913 {}
914 constexpr explicit QPartialOrdering(QtPrivate::LegacyUncomparable order) noexcept
915 : m_order(static_cast<QtPrivate::CompareUnderlyingType>(order))
916 {}
917
918 QT_WARNING_PUSH
919 // https://gcc.gnu.org/bugzilla/show_bug.cgi?id=100903
920 QT_WARNING_DISABLE_GCC("-Wzero-as-null-pointer-constant")
921 QT_WARNING_DISABLE_CLANG("-Wzero-as-null-pointer-constant")
922 friend constexpr bool is_eq (QPartialOrdering o) noexcept { return o == 0; }
923 friend constexpr bool is_neq (QPartialOrdering o) noexcept { return o != 0; }
924 friend constexpr bool is_lt (QPartialOrdering o) noexcept { return o < 0; }
925 friend constexpr bool is_lteq(QPartialOrdering o) noexcept { return o <= 0; }
926 friend constexpr bool is_gt (QPartialOrdering o) noexcept { return o > 0; }
927 friend constexpr bool is_gteq(QPartialOrdering o) noexcept { return o >= 0; }
929
930 // instead of the exposition only is_ordered member in [cmp.partialord],
931 // use a private function
932 constexpr bool isOrdered() const noexcept
934
936};
937
942
947
948QT_END_NAMESPACE
949
950#endif // QCOMPARE_H
\variable Qt::partial_ordering::less
Definition qcompare.h:746
friend constexpr bool operator==(QPartialOrdering lhs, QtPrivate::CompareAgainstLiteralZero) noexcept
Definition qcompare.h:758
static const QPartialOrdering unordered
Definition qcompare.h:756
friend constexpr bool operator==(QPartialOrdering lhs, Qt::partial_ordering rhs) noexcept
Definition qcompare.h:861
static const QPartialOrdering greater
Definition qcompare.h:755
friend constexpr bool operator<(QtPrivate::CompareAgainstLiteralZero, QPartialOrdering rhs) noexcept
Definition qcompare.h:791
friend constexpr bool operator<(QPartialOrdering lhs, QtPrivate::CompareAgainstLiteralZero) noexcept
Definition qcompare.h:766
static const QPartialOrdering less
Definition qcompare.h:753
friend constexpr bool operator!=(QPartialOrdering lhs, Qt::partial_ordering rhs) noexcept
Definition qcompare.h:864
friend constexpr bool operator==(QtPrivate::CompareAgainstLiteralZero, QPartialOrdering rhs) noexcept
Definition qcompare.h:783
friend constexpr bool operator==(Qt::partial_ordering lhs, QPartialOrdering rhs) noexcept
Definition qcompare.h:867
friend constexpr bool operator>(QPartialOrdering lhs, QtPrivate::CompareAgainstLiteralZero) noexcept
Definition qcompare.h:774
static const QPartialOrdering Less
Definition qcompare.h:748
friend constexpr bool operator>=(QtPrivate::CompareAgainstLiteralZero, QPartialOrdering rhs) noexcept
Definition qcompare.h:803
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:819
static const QPartialOrdering equivalent
Definition qcompare.h:754
friend constexpr bool operator!=(Qt::partial_ordering lhs, QPartialOrdering rhs) noexcept
Definition qcompare.h:870
friend constexpr bool operator!=(QtPrivate::CompareAgainstLiteralZero, QPartialOrdering rhs) noexcept
Definition qcompare.h:787
friend constexpr bool operator<=(QPartialOrdering lhs, QtPrivate::CompareAgainstLiteralZero) noexcept
Definition qcompare.h:770
friend constexpr bool operator!=(QPartialOrdering lhs, QtPrivate::CompareAgainstLiteralZero) noexcept
Definition qcompare.h:762
friend constexpr bool operator!=(QPartialOrdering lhs, QPartialOrdering rhs) noexcept
Return true if lhs and rhs represent different results; otherwise, returns true.
Definition qcompare.h:822
friend constexpr bool operator>(QtPrivate::CompareAgainstLiteralZero, QPartialOrdering rhs) noexcept
Definition qcompare.h:799
static const QPartialOrdering Greater
Definition qcompare.h:750
friend constexpr bool operator<=(QtPrivate::CompareAgainstLiteralZero, QPartialOrdering rhs) noexcept
Definition qcompare.h:795
static const QPartialOrdering Equivalent
Definition qcompare.h:749
static const QPartialOrdering Unordered
Definition qcompare.h:751
friend constexpr bool operator>=(QPartialOrdering lhs, QtPrivate::CompareAgainstLiteralZero) noexcept
Definition qcompare.h:778
\variable Qt::weak_ordering::less
Definition qcompare.h:116
friend constexpr bool is_eq(partial_ordering o) noexcept
Definition qcompare.h:285
friend constexpr bool operator>=(QtPrivate::CompareAgainstLiteralZero, partial_ordering rhs) noexcept
Definition qcompare.h:168
friend constexpr bool operator>(partial_ordering lhs, QtPrivate::CompareAgainstLiteralZero) noexcept
Definition qcompare.h:139
friend constexpr bool operator>(QtPrivate::CompareAgainstLiteralZero, partial_ordering rhs) noexcept
Definition qcompare.h:164
friend constexpr bool is_lt(partial_ordering o) noexcept
Definition qcompare.h:287
friend constexpr bool operator==(QtPrivate::CompareAgainstLiteralZero, partial_ordering rhs) noexcept
Definition qcompare.h:148
friend constexpr bool operator<=(partial_ordering lhs, QtPrivate::CompareAgainstLiteralZero) noexcept
Definition qcompare.h:135
static const partial_ordering equivalent
Definition qcompare.h:119
friend constexpr bool operator<=(QtPrivate::CompareAgainstLiteralZero, partial_ordering rhs) noexcept
Definition qcompare.h:160
friend constexpr bool operator==(partial_ordering lhs, QtPrivate::CompareAgainstLiteralZero) noexcept
Definition qcompare.h:123
friend constexpr bool operator!=(QtPrivate::CompareAgainstLiteralZero, partial_ordering rhs) noexcept
Definition qcompare.h:152
friend constexpr bool is_lteq(partial_ordering o) noexcept
Definition qcompare.h:288
friend constexpr bool operator!=(partial_ordering lhs, QtPrivate::CompareAgainstLiteralZero) noexcept
Definition qcompare.h:127
friend constexpr bool operator<(partial_ordering lhs, QtPrivate::CompareAgainstLiteralZero) noexcept
Definition qcompare.h:131
friend constexpr bool operator<(QtPrivate::CompareAgainstLiteralZero, partial_ordering rhs) noexcept
Definition qcompare.h:156
static const partial_ordering unordered
Definition qcompare.h:121
friend constexpr bool operator>=(partial_ordering lhs, QtPrivate::CompareAgainstLiteralZero) noexcept
Definition qcompare.h:143
friend constexpr bool is_gt(partial_ordering o) noexcept
Definition qcompare.h:289
friend constexpr bool is_gteq(partial_ordering o) noexcept
Definition qcompare.h:290
static const partial_ordering greater
Definition qcompare.h:120
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:187
static const partial_ordering less
Definition qcompare.h:118
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:184
friend constexpr bool is_neq(partial_ordering o) noexcept
Definition qcompare.h:286
\inmodule QtCore \title Classes and helpers for defining comparison operators \keyword qtcompare
Definition qcompare.h:487
friend constexpr bool operator<=(strong_ordering lhs, QtPrivate::CompareAgainstLiteralZero) noexcept
Definition qcompare.h:512
friend constexpr bool is_gt(strong_ordering o) noexcept
Definition qcompare.h:672
friend constexpr bool operator!=(strong_ordering lhs, QtPrivate::CompareAgainstLiteralZero) noexcept
Definition qcompare.h:504
friend constexpr bool operator<(strong_ordering lhs, QtPrivate::CompareAgainstLiteralZero) noexcept
Definition qcompare.h:508
friend constexpr bool operator<(QtPrivate::CompareAgainstLiteralZero, strong_ordering rhs) noexcept
Definition qcompare.h:533
static const strong_ordering greater
Definition qcompare.h:492
friend constexpr bool operator==(strong_ordering lhs, partial_ordering rhs) noexcept
Definition qcompare.h:567
friend constexpr bool operator>(strong_ordering lhs, QtPrivate::CompareAgainstLiteralZero) noexcept
Definition qcompare.h:516
friend constexpr bool operator!=(weak_ordering lhs, strong_ordering rhs) noexcept
Definition qcompare.h:588
friend constexpr bool operator!=(partial_ordering lhs, strong_ordering rhs) noexcept
Definition qcompare.h:576
static const strong_ordering equal
Definition qcompare.h:491
friend constexpr bool is_eq(strong_ordering o) noexcept
Definition qcompare.h:668
friend constexpr bool operator!=(QtPrivate::CompareAgainstLiteralZero, strong_ordering rhs) noexcept
Definition qcompare.h:529
friend constexpr bool operator==(QtPrivate::CompareAgainstLiteralZero, strong_ordering rhs) noexcept
Definition qcompare.h:525
friend constexpr bool operator==(strong_ordering lhs, weak_ordering rhs) noexcept
Definition qcompare.h:579
friend constexpr bool operator>=(QtPrivate::CompareAgainstLiteralZero, strong_ordering rhs) noexcept
Definition qcompare.h:545
static const strong_ordering less
Definition qcompare.h:489
friend constexpr bool operator!=(strong_ordering lhs, weak_ordering rhs) noexcept
Definition qcompare.h:582
friend constexpr bool is_neq(strong_ordering o) noexcept
Definition qcompare.h:669
friend constexpr bool operator!=(strong_ordering lhs, partial_ordering rhs) noexcept
Definition qcompare.h:570
friend constexpr bool is_lteq(strong_ordering o) noexcept
Definition qcompare.h:671
friend constexpr bool operator==(strong_ordering lhs, QtPrivate::CompareAgainstLiteralZero) noexcept
Definition qcompare.h:500
static const strong_ordering equivalent
Definition qcompare.h:490
friend constexpr bool operator>(QtPrivate::CompareAgainstLiteralZero, strong_ordering rhs) noexcept
Definition qcompare.h:541
friend constexpr bool is_lt(strong_ordering o) noexcept
Definition qcompare.h:670
friend constexpr bool operator<=(QtPrivate::CompareAgainstLiteralZero, strong_ordering rhs) noexcept
Definition qcompare.h:537
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:561
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:564
friend constexpr bool operator==(weak_ordering lhs, strong_ordering rhs) noexcept
Definition qcompare.h:585
friend constexpr bool operator==(partial_ordering lhs, strong_ordering rhs) noexcept
Definition qcompare.h:573
friend constexpr bool is_gteq(strong_ordering o) noexcept
Definition qcompare.h:673
friend constexpr bool operator>=(strong_ordering lhs, QtPrivate::CompareAgainstLiteralZero) noexcept
Definition qcompare.h:520
\variable Qt::strong_ordering::less
Definition qcompare.h:306
friend constexpr bool operator!=(weak_ordering lhs, QtPrivate::CompareAgainstLiteralZero) noexcept
Definition qcompare.h:319
static const weak_ordering less
Definition qcompare.h:308
friend constexpr bool operator<=(weak_ordering lhs, QtPrivate::CompareAgainstLiteralZero) noexcept
Definition qcompare.h:327
friend constexpr bool is_neq(weak_ordering o) noexcept
Definition qcompare.h:473
friend constexpr bool operator<(weak_ordering lhs, QtPrivate::CompareAgainstLiteralZero) noexcept
Definition qcompare.h:323
friend constexpr bool is_gteq(weak_ordering o) noexcept
Definition qcompare.h:477
friend constexpr bool is_gt(weak_ordering o) noexcept
Definition qcompare.h:476
friend constexpr bool operator==(weak_ordering lhs, partial_ordering rhs) noexcept
Definition qcompare.h:382
friend constexpr bool operator<(QtPrivate::CompareAgainstLiteralZero, weak_ordering rhs) noexcept
Definition qcompare.h:348
friend constexpr bool is_lteq(weak_ordering o) noexcept
Definition qcompare.h:475
friend constexpr bool operator>(QtPrivate::CompareAgainstLiteralZero, weak_ordering rhs) noexcept
Definition qcompare.h:356
friend constexpr bool operator==(weak_ordering lhs, QtPrivate::CompareAgainstLiteralZero) noexcept
Definition qcompare.h:315
friend constexpr bool is_lt(weak_ordering o) noexcept
Definition qcompare.h:474
friend constexpr bool operator!=(QtPrivate::CompareAgainstLiteralZero, weak_ordering rhs) noexcept
Definition qcompare.h:344
friend constexpr bool is_eq(weak_ordering o) noexcept
Definition qcompare.h:472
friend constexpr bool operator>=(weak_ordering lhs, QtPrivate::CompareAgainstLiteralZero) noexcept
Definition qcompare.h:335
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:376
friend constexpr bool operator>=(QtPrivate::CompareAgainstLiteralZero, weak_ordering rhs) noexcept
Definition qcompare.h:360
static const weak_ordering greater
Definition qcompare.h:310
friend constexpr bool operator>(weak_ordering lhs, QtPrivate::CompareAgainstLiteralZero) noexcept
Definition qcompare.h:331
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:379
friend constexpr bool operator!=(weak_ordering lhs, partial_ordering rhs) noexcept
Definition qcompare.h:385
friend constexpr bool operator<=(QtPrivate::CompareAgainstLiteralZero, weak_ordering rhs) noexcept
Definition qcompare.h:352
friend constexpr bool operator!=(partial_ordering lhs, weak_ordering rhs) noexcept
Definition qcompare.h:391
friend constexpr bool operator==(partial_ordering lhs, weak_ordering rhs) noexcept
Definition qcompare.h:388
static const weak_ordering equivalent
Definition qcompare.h:309
friend constexpr bool operator==(QtPrivate::CompareAgainstLiteralZero, weak_ordering rhs) noexcept
Definition qcompare.h:340
Combined button and popup list for selecting options.
constexpr O reversed(O o) noexcept
Definition qcompare.h:91
constexpr auto toUnderlying(O o) noexcept
constexpr auto toUnderlying< Qt::weak_ordering >(Qt::weak_ordering o) noexcept
Definition qcompare.h:691
constexpr auto toUnderlying< Qt::strong_ordering >(Qt::strong_ordering o) noexcept
Definition qcompare.h:694
constexpr auto toUnderlying< Qt::partial_ordering >(Qt::partial_ordering o) noexcept
Definition qcompare.h:688
constexpr CompareUnderlyingType LegacyUncomparableValue
Definition qcompare.h:27
LegacyUncomparable
Definition qcompare.h:739
Definition qcompare.h:110