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