Qt
Internal/Contributor docs for the Qt SDK. <b>Note:</b> These are NOT official API docs; those are found <a href='https://doc.qt.io/'>here</a>.
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
15#ifdef __cpp_lib_bit_cast
16#include <bit>
17#endif
18#ifdef __cpp_lib_three_way_comparison
19#include <compare>
20#endif
21
23
24namespace QtPrivate {
26
27// [cmp.categories.pre] / 1
29{
30 Equal = 0,
32 Less = -1,
33 Greater = 1
34};
35
37{
38 Unordered =
39 #if defined(_LIBCPP_VERSION) // libc++
40 -127
41 #elif defined(__GLIBCXX__) // libstdc++
42 2
43 #else // assume MSSTL
44 -128
45 #endif
46};
47
48} // namespace QtPrivate
49
51
52template <typename O>
53constexpr O reversed(O o) noexcept
54{
55 // https://eel.is/c++draft/cmp.partialord#5
56 return is_lt(o) ? O::greater :
57 is_gt(o) ? O::less :
58 /*else*/ o ;
59}
60
61} // namespace QtOrderingPrivate
62
63namespace Qt {
64
65class weak_ordering;
66class strong_ordering;
67
69{
70public:
71 static const partial_ordering less;
75
76 friend constexpr bool operator==(partial_ordering lhs,
78 { return lhs.isOrdered() && lhs.m_order == 0; }
79
80 friend constexpr bool operator!=(partial_ordering lhs,
82 { return lhs.isOrdered() && lhs.m_order != 0; }
83
84 friend constexpr bool operator< (partial_ordering lhs,
86 { return lhs.isOrdered() && lhs.m_order < 0; }
87
88 friend constexpr bool operator<=(partial_ordering lhs,
90 { return lhs.isOrdered() && lhs.m_order <= 0; }
91
92 friend constexpr bool operator> (partial_ordering lhs,
94 { return lhs.isOrdered() && lhs.m_order > 0; }
95
96 friend constexpr bool operator>=(partial_ordering lhs,
98 { return lhs.isOrdered() && lhs.m_order >= 0; }
99
100
102 partial_ordering rhs) noexcept
103 { return rhs.isOrdered() && 0 == rhs.m_order; }
104
106 partial_ordering rhs) noexcept
107 { return rhs.isOrdered() && 0 != rhs.m_order; }
108
110 partial_ordering rhs) noexcept
111 { return rhs.isOrdered() && 0 < rhs.m_order; }
112
114 partial_ordering rhs) noexcept
115 { return rhs.isOrdered() && 0 <= rhs.m_order; }
116
118 partial_ordering rhs) noexcept
119 { return rhs.isOrdered() && 0 > rhs.m_order; }
120
122 partial_ordering rhs) noexcept
123 { return rhs.isOrdered() && 0 >= rhs.m_order; }
124
125
126#ifdef __cpp_lib_three_way_comparison
127 friend constexpr std::partial_ordering
129 { return lhs; } // https://eel.is/c++draft/cmp.partialord#4
130
131 friend constexpr std::partial_ordering
132 operator<=>(QtPrivate::CompareAgainstLiteralZero, partial_ordering rhs) noexcept
133 { return QtOrderingPrivate::reversed(rhs); }
134#endif // __cpp_lib_three_way_comparison
135
136
137 friend constexpr bool operator==(partial_ordering lhs, partial_ordering rhs) noexcept
138 { return lhs.m_order == rhs.m_order; }
139
140 friend constexpr bool operator!=(partial_ordering lhs, partial_ordering rhs) noexcept
141 { return lhs.m_order != rhs.m_order; }
142
143#ifdef __cpp_lib_three_way_comparison
144 constexpr Q_IMPLICIT partial_ordering(std::partial_ordering stdorder) noexcept
145 {
146 if (stdorder == std::partial_ordering::less)
148 else if (stdorder == std::partial_ordering::equivalent)
150 else if (stdorder == std::partial_ordering::greater)
152 else if (stdorder == std::partial_ordering::unordered)
154 }
155
156 constexpr Q_IMPLICIT operator std::partial_ordering() const noexcept
157 {
158 static_assert(sizeof(*this) == sizeof(std::partial_ordering));
159#ifdef __cpp_lib_bit_cast
160 return std::bit_cast<std::partial_ordering>(*this);
161#else
162 using O = QtPrivate::Ordering;
163 using U = QtPrivate::Uncomparable;
164 using R = std::partial_ordering;
165 switch (m_order) {
166 case qToUnderlying(O::Less): return R::less;
167 case qToUnderlying(O::Greater): return R::greater;
168 case qToUnderlying(O::Equivalent): return R::equivalent;
169 case qToUnderlying(U::Unordered): return R::unordered;
170 }
171 Q_UNREACHABLE_RETURN(R::unordered);
172#endif // __cpp_lib_bit_cast
173 }
174
175 friend constexpr bool operator==(partial_ordering lhs, std::partial_ordering rhs) noexcept
176 { return static_cast<std::partial_ordering>(lhs) == rhs; }
177
178 friend constexpr bool operator!=(partial_ordering lhs, std::partial_ordering rhs) noexcept
179 { return static_cast<std::partial_ordering>(lhs) != rhs; }
180
181 friend constexpr bool operator==(std::partial_ordering lhs, partial_ordering rhs) noexcept
182 { return lhs == static_cast<std::partial_ordering>(rhs); }
183
184 friend constexpr bool operator!=(std::partial_ordering lhs, partial_ordering rhs) noexcept
185 { return lhs != static_cast<std::partial_ordering>(rhs); }
186#endif // __cpp_lib_three_way_comparison
187
188private:
189 friend class weak_ordering;
190 friend class strong_ordering;
191
192 constexpr explicit partial_ordering(QtPrivate::Ordering order) noexcept
193 : m_order(static_cast<QtPrivate::CompareUnderlyingType>(order))
194 {}
195 constexpr explicit partial_ordering(QtPrivate::Uncomparable order) noexcept
196 : m_order(static_cast<QtPrivate::CompareUnderlyingType>(order))
197 {}
198
200 // https://gcc.gnu.org/bugzilla/show_bug.cgi?id=100903
201 QT_WARNING_DISABLE_GCC("-Wzero-as-null-pointer-constant")
202 friend constexpr bool is_eq (partial_ordering o) noexcept { return o == 0; }
203 friend constexpr bool is_neq (partial_ordering o) noexcept { return o != 0; }
204 friend constexpr bool is_lt (partial_ordering o) noexcept { return o < 0; }
205 friend constexpr bool is_lteq(partial_ordering o) noexcept { return o <= 0; }
206 friend constexpr bool is_gt (partial_ordering o) noexcept { return o > 0; }
207 friend constexpr bool is_gteq(partial_ordering o) noexcept { return o >= 0; }
209
210 // instead of the exposition only is_ordered member in [cmp.partialord],
211 // use a private function
212 constexpr bool isOrdered() const noexcept
214
216};
217
218inline constexpr partial_ordering partial_ordering::less(QtPrivate::Ordering::Less);
219inline constexpr partial_ordering partial_ordering::equivalent(QtPrivate::Ordering::Equivalent);
220inline constexpr partial_ordering partial_ordering::greater(QtPrivate::Ordering::Greater);
221inline constexpr partial_ordering partial_ordering::unordered(QtPrivate::Uncomparable::Unordered);
222
224{
225public:
226 static const weak_ordering less;
228 static const weak_ordering greater;
229
230 constexpr Q_IMPLICIT operator partial_ordering() const noexcept
231 { return partial_ordering(static_cast<QtPrivate::Ordering>(m_order)); }
232
233 friend constexpr bool operator==(weak_ordering lhs,
235 { return lhs.m_order == 0; }
236
237 friend constexpr bool operator!=(weak_ordering lhs,
239 { return lhs.m_order != 0; }
240
241 friend constexpr bool operator< (weak_ordering lhs,
243 { return lhs.m_order < 0; }
244
245 friend constexpr bool operator<=(weak_ordering lhs,
247 { return lhs.m_order <= 0; }
248
249 friend constexpr bool operator> (weak_ordering lhs,
251 { return lhs.m_order > 0; }
252
253 friend constexpr bool operator>=(weak_ordering lhs,
255 { return lhs.m_order >= 0; }
256
257
259 weak_ordering rhs) noexcept
260 { return 0 == rhs.m_order; }
261
263 weak_ordering rhs) noexcept
264 { return 0 != rhs.m_order; }
265
267 weak_ordering rhs) noexcept
268 { return 0 < rhs.m_order; }
269
271 weak_ordering rhs) noexcept
272 { return 0 <= rhs.m_order; }
273
275 weak_ordering rhs) noexcept
276 { return 0 > rhs.m_order; }
277
279 weak_ordering rhs) noexcept
280 { return 0 >= rhs.m_order; }
281
282
283#ifdef __cpp_lib_three_way_comparison
284 friend constexpr std::weak_ordering
285 operator<=>(weak_ordering lhs, QtPrivate::CompareAgainstLiteralZero) noexcept
286 { return lhs; } // https://eel.is/c++draft/cmp.weakord#5
287
288 friend constexpr std::weak_ordering
289 operator<=>(QtPrivate::CompareAgainstLiteralZero, weak_ordering rhs) noexcept
290 { return QtOrderingPrivate::reversed(rhs); }
291#endif // __cpp_lib_three_way_comparison
292
293
294 friend constexpr bool operator==(weak_ordering lhs, weak_ordering rhs) noexcept
295 { return lhs.m_order == rhs.m_order; }
296
297 friend constexpr bool operator!=(weak_ordering lhs, weak_ordering rhs) noexcept
298 { return lhs.m_order != rhs.m_order; }
299
300 friend constexpr bool operator==(weak_ordering lhs, partial_ordering rhs) noexcept
301 { return static_cast<partial_ordering>(lhs) == rhs; }
302
303 friend constexpr bool operator!=(weak_ordering lhs, partial_ordering rhs) noexcept
304 { return static_cast<partial_ordering>(lhs) != rhs; }
305
306 friend constexpr bool operator==(partial_ordering lhs, weak_ordering rhs) noexcept
307 { return lhs == static_cast<partial_ordering>(rhs); }
308
309 friend constexpr bool operator!=(partial_ordering lhs, weak_ordering rhs) noexcept
310 { return lhs != static_cast<partial_ordering>(rhs); }
311
312#ifdef __cpp_lib_three_way_comparison
313 constexpr Q_IMPLICIT weak_ordering(std::weak_ordering stdorder) noexcept
314 {
315 if (stdorder == std::weak_ordering::less)
317 else if (stdorder == std::weak_ordering::equivalent)
319 else if (stdorder == std::weak_ordering::greater)
321 }
322
323 constexpr Q_IMPLICIT operator std::weak_ordering() const noexcept
324 {
325 static_assert(sizeof(*this) == sizeof(std::weak_ordering));
326#ifdef __cpp_lib_bit_cast
327 return std::bit_cast<std::weak_ordering>(*this);
328#else
329 using O = QtPrivate::Ordering;
330 using R = std::weak_ordering;
331 switch (m_order) {
332 case qToUnderlying(O::Less): return R::less;
333 case qToUnderlying(O::Greater): return R::greater;
334 case qToUnderlying(O::Equivalent): return R::equivalent;
335 }
336 Q_UNREACHABLE_RETURN(R::equivalent);
337#endif // __cpp_lib_bit_cast
338 }
339
340 friend constexpr bool operator==(weak_ordering lhs, std::weak_ordering rhs) noexcept
341 { return static_cast<std::weak_ordering>(lhs) == rhs; }
342
343 friend constexpr bool operator!=(weak_ordering lhs, std::weak_ordering rhs) noexcept
344 { return static_cast<std::weak_ordering>(lhs) != rhs; }
345
346 friend constexpr bool operator==(weak_ordering lhs, std::partial_ordering rhs) noexcept
347 { return static_cast<std::weak_ordering>(lhs) == rhs; }
348
349 friend constexpr bool operator!=(weak_ordering lhs, std::partial_ordering rhs) noexcept
350 { return static_cast<std::weak_ordering>(lhs) != rhs; }
351
352 friend constexpr bool operator==(weak_ordering lhs, std::strong_ordering rhs) noexcept
353 { return static_cast<std::weak_ordering>(lhs) == rhs; }
354
355 friend constexpr bool operator!=(weak_ordering lhs, std::strong_ordering rhs) noexcept
356 { return static_cast<std::weak_ordering>(lhs) != rhs; }
357
358 friend constexpr bool operator==(std::weak_ordering lhs, weak_ordering rhs) noexcept
359 { return lhs == static_cast<std::weak_ordering>(rhs); }
360
361 friend constexpr bool operator!=(std::weak_ordering lhs, weak_ordering rhs) noexcept
362 { return lhs != static_cast<std::weak_ordering>(rhs); }
363
364 friend constexpr bool operator==(std::partial_ordering lhs, weak_ordering rhs) noexcept
365 { return lhs == static_cast<std::weak_ordering>(rhs); }
366
367 friend constexpr bool operator!=(std::partial_ordering lhs, weak_ordering rhs) noexcept
368 { return lhs != static_cast<std::weak_ordering>(rhs); }
369
370 friend constexpr bool operator==(std::strong_ordering lhs, weak_ordering rhs) noexcept
371 { return lhs == static_cast<std::weak_ordering>(rhs); }
372
373 friend constexpr bool operator!=(std::strong_ordering lhs, weak_ordering rhs) noexcept
374 { return lhs != static_cast<std::weak_ordering>(rhs); }
375#endif // __cpp_lib_three_way_comparison
376
377private:
378 friend class strong_ordering;
379
380 constexpr explicit weak_ordering(QtPrivate::Ordering order) noexcept
381 : m_order(static_cast<QtPrivate::CompareUnderlyingType>(order))
382 {}
383
385 // https://gcc.gnu.org/bugzilla/show_bug.cgi?id=100903
386 QT_WARNING_DISABLE_GCC("-Wzero-as-null-pointer-constant")
387 friend constexpr bool is_eq (weak_ordering o) noexcept { return o == 0; }
388 friend constexpr bool is_neq (weak_ordering o) noexcept { return o != 0; }
389 friend constexpr bool is_lt (weak_ordering o) noexcept { return o < 0; }
390 friend constexpr bool is_lteq(weak_ordering o) noexcept { return o <= 0; }
391 friend constexpr bool is_gt (weak_ordering o) noexcept { return o > 0; }
392 friend constexpr bool is_gteq(weak_ordering o) noexcept { return o >= 0; }
394
396};
397
398inline constexpr weak_ordering weak_ordering::less(QtPrivate::Ordering::Less);
399inline constexpr weak_ordering weak_ordering::equivalent(QtPrivate::Ordering::Equivalent);
400inline constexpr weak_ordering weak_ordering::greater(QtPrivate::Ordering::Greater);
401
403{
404public:
405 static const strong_ordering less;
407 static const strong_ordering equal;
409
410 constexpr Q_IMPLICIT operator partial_ordering() const noexcept
411 { return partial_ordering(static_cast<QtPrivate::Ordering>(m_order)); }
412
413 constexpr Q_IMPLICIT operator weak_ordering() const noexcept
414 { return weak_ordering(static_cast<QtPrivate::Ordering>(m_order)); }
415
416 friend constexpr bool operator==(strong_ordering lhs,
418 { return lhs.m_order == 0; }
419
420 friend constexpr bool operator!=(strong_ordering lhs,
422 { return lhs.m_order != 0; }
423
424 friend constexpr bool operator< (strong_ordering lhs,
426 { return lhs.m_order < 0; }
427
428 friend constexpr bool operator<=(strong_ordering lhs,
430 { return lhs.m_order <= 0; }
431
432 friend constexpr bool operator> (strong_ordering lhs,
434 { return lhs.m_order > 0; }
435
436 friend constexpr bool operator>=(strong_ordering lhs,
438 { return lhs.m_order >= 0; }
439
440
442 strong_ordering rhs) noexcept
443 { return 0 == rhs.m_order; }
444
446 strong_ordering rhs) noexcept
447 { return 0 != rhs.m_order; }
448
450 strong_ordering rhs) noexcept
451 { return 0 < rhs.m_order; }
452
454 strong_ordering rhs) noexcept
455 { return 0 <= rhs.m_order; }
456
458 strong_ordering rhs) noexcept
459 { return 0 > rhs.m_order; }
460
462 strong_ordering rhs) noexcept
463 { return 0 >= rhs.m_order; }
464
465
466#ifdef __cpp_lib_three_way_comparison
467 friend constexpr std::strong_ordering
469 { return lhs; } // https://eel.is/c++draft/cmp.strongord#6
470
471 friend constexpr std::strong_ordering
472 operator<=>(QtPrivate::CompareAgainstLiteralZero, strong_ordering rhs) noexcept
473 { return QtOrderingPrivate::reversed(rhs); }
474#endif // __cpp_lib_three_way_comparison
475
476
477 friend constexpr bool operator==(strong_ordering lhs, strong_ordering rhs) noexcept
478 { return lhs.m_order == rhs.m_order; }
479
480 friend constexpr bool operator!=(strong_ordering lhs, strong_ordering rhs) noexcept
481 { return lhs.m_order != rhs.m_order; }
482
483 friend constexpr bool operator==(strong_ordering lhs, partial_ordering rhs) noexcept
484 { return static_cast<partial_ordering>(lhs) == rhs; }
485
486 friend constexpr bool operator!=(strong_ordering lhs, partial_ordering rhs) noexcept
487 { return static_cast<partial_ordering>(lhs) == rhs; }
488
489 friend constexpr bool operator==(partial_ordering lhs, strong_ordering rhs) noexcept
490 { return lhs == static_cast<partial_ordering>(rhs); }
491
492 friend constexpr bool operator!=(partial_ordering lhs, strong_ordering rhs) noexcept
493 { return lhs != static_cast<partial_ordering>(rhs); }
494
495 friend constexpr bool operator==(strong_ordering lhs, weak_ordering rhs) noexcept
496 { return static_cast<weak_ordering>(lhs) == rhs; }
497
498 friend constexpr bool operator!=(strong_ordering lhs, weak_ordering rhs) noexcept
499 { return static_cast<weak_ordering>(lhs) == rhs; }
500
501 friend constexpr bool operator==(weak_ordering lhs, strong_ordering rhs) noexcept
502 { return lhs == static_cast<weak_ordering>(rhs); }
503
504 friend constexpr bool operator!=(weak_ordering lhs, strong_ordering rhs) noexcept
505 { return lhs != static_cast<weak_ordering>(rhs); }
506
507#ifdef __cpp_lib_three_way_comparison
508 constexpr Q_IMPLICIT strong_ordering(std::strong_ordering stdorder) noexcept
509 {
510 if (stdorder == std::strong_ordering::less)
512 else if (stdorder == std::strong_ordering::equivalent)
514 else if (stdorder == std::strong_ordering::equal)
516 else if (stdorder == std::strong_ordering::greater)
518 }
519
520 constexpr Q_IMPLICIT operator std::strong_ordering() const noexcept
521 {
522 static_assert(sizeof(*this) == sizeof(std::strong_ordering));
523#ifdef __cpp_lib_bit_cast
524 return std::bit_cast<std::strong_ordering>(*this);
525#else
526 using O = QtPrivate::Ordering;
527 using R = std::strong_ordering;
528 switch (m_order) {
529 case qToUnderlying(O::Less): return R::less;
530 case qToUnderlying(O::Greater): return R::greater;
531 case qToUnderlying(O::Equal): return R::equal;
532 }
533 Q_UNREACHABLE_RETURN(R::equal);
534#endif // __cpp_lib_bit_cast
535 }
536
537 friend constexpr bool operator==(strong_ordering lhs, std::strong_ordering rhs) noexcept
538 { return static_cast<std::strong_ordering>(lhs) == rhs; }
539
540 friend constexpr bool operator!=(strong_ordering lhs, std::strong_ordering rhs) noexcept
541 { return static_cast<std::strong_ordering>(lhs) != rhs; }
542
543 friend constexpr bool operator==(strong_ordering lhs, std::partial_ordering rhs) noexcept
544 { return static_cast<std::strong_ordering>(lhs) == rhs; }
545
546 friend constexpr bool operator!=(strong_ordering lhs, std::partial_ordering rhs) noexcept
547 { return static_cast<std::strong_ordering>(lhs) != rhs; }
548
549 friend constexpr bool operator==(strong_ordering lhs, std::weak_ordering rhs) noexcept
550 { return static_cast<std::strong_ordering>(lhs) == rhs; }
551
552 friend constexpr bool operator!=(strong_ordering lhs, std::weak_ordering rhs) noexcept
553 { return static_cast<std::strong_ordering>(lhs) != rhs; }
554
555 friend constexpr bool operator==(std::strong_ordering lhs, strong_ordering rhs) noexcept
556 { return lhs == static_cast<std::strong_ordering>(rhs); }
557
558 friend constexpr bool operator!=(std::strong_ordering lhs, strong_ordering rhs) noexcept
559 { return lhs != static_cast<std::strong_ordering>(rhs); }
560
561 friend constexpr bool operator==(std::partial_ordering lhs, strong_ordering rhs) noexcept
562 { return lhs == static_cast<std::strong_ordering>(rhs); }
563
564 friend constexpr bool operator!=(std::partial_ordering lhs, strong_ordering rhs) noexcept
565 { return lhs != static_cast<std::strong_ordering>(rhs); }
566
567 friend constexpr bool operator==(std::weak_ordering lhs, strong_ordering rhs) noexcept
568 { return lhs == static_cast<std::strong_ordering>(rhs); }
569
570 friend constexpr bool operator!=(std::weak_ordering lhs, strong_ordering rhs) noexcept
571 { return lhs != static_cast<std::strong_ordering>(rhs); }
572#endif // __cpp_lib_three_way_comparison
573
574 private:
575 constexpr explicit strong_ordering(QtPrivate::Ordering order) noexcept
576 : m_order(static_cast<QtPrivate::CompareUnderlyingType>(order))
577 {}
578
580 // https://gcc.gnu.org/bugzilla/show_bug.cgi?id=100903
581 QT_WARNING_DISABLE_GCC("-Wzero-as-null-pointer-constant")
582 friend constexpr bool is_eq (strong_ordering o) noexcept { return o == 0; }
583 friend constexpr bool is_neq (strong_ordering o) noexcept { return o != 0; }
584 friend constexpr bool is_lt (strong_ordering o) noexcept { return o < 0; }
585 friend constexpr bool is_lteq(strong_ordering o) noexcept { return o <= 0; }
586 friend constexpr bool is_gt (strong_ordering o) noexcept { return o > 0; }
587 friend constexpr bool is_gteq(strong_ordering o) noexcept { return o >= 0; }
589
591};
592
593inline constexpr strong_ordering strong_ordering::less(QtPrivate::Ordering::Less);
594inline constexpr strong_ordering strong_ordering::equivalent(QtPrivate::Ordering::Equivalent);
595inline constexpr strong_ordering strong_ordering::equal(QtPrivate::Ordering::Equal);
596inline constexpr strong_ordering strong_ordering::greater(QtPrivate::Ordering::Greater);
597
598} // namespace Qt
599
601
602// This is intentionally included after Qt::*_ordering types and before
603// qCompareThreeWay. Do not change!
604#include <QtCore/qcomparehelpers.h>
605
607
608namespace QtPrivate {
609
610namespace CompareThreeWayTester {
611
613
614 // Check if compareThreeWay is implemented for the (LT, RT) argument
615 // pair.
616 template <typename LT, typename RT, typename = void>
617 constexpr bool hasCompareThreeWay = false;
618
619 template <typename LT, typename RT>
620 constexpr bool hasCompareThreeWay<
621 LT, RT, std::void_t<decltype(compareThreeWay(std::declval<LT>(), std::declval<RT>()))>
622 > = true;
623
624 // Check if the operation is noexcept. We have two different overloads,
625 // depending on the available compareThreeWay() implementation.
626 // Both are declared, but not implemented. To be used only in unevaluated
627 // context.
628
629 template <typename LT, typename RT,
630 std::enable_if_t<hasCompareThreeWay<LT, RT>, bool> = true>
631 constexpr bool compareThreeWayNoexcept() noexcept
632 { return noexcept(compareThreeWay(std::declval<LT>(), std::declval<RT>())); }
633
634 template <typename LT, typename RT,
635 std::enable_if_t<!hasCompareThreeWay<LT, RT> && hasCompareThreeWay<RT, LT>,
636 bool> = true>
637 constexpr bool compareThreeWayNoexcept() noexcept
638 { return noexcept(compareThreeWay(std::declval<RT>(), std::declval<LT>())); }
639
640} // namespace CompareThreeWayTester
641
642} // namespace QtPrivate
643
644#if defined(Q_QDOC)
645
646template <typename LeftType, typename RightType>
647auto qCompareThreeWay(const LeftType &lhs, const RightType &rhs);
648
649#else
650
651template <typename LT, typename RT,
652 std::enable_if_t<QtPrivate::CompareThreeWayTester::hasCompareThreeWay<LT, RT>
653 || QtPrivate::CompareThreeWayTester::hasCompareThreeWay<RT, LT>,
654 bool> = true>
655auto qCompareThreeWay(const LT &lhs, const RT &rhs)
656 noexcept(QtPrivate::CompareThreeWayTester::compareThreeWayNoexcept<LT, RT>())
657{
659 if constexpr (QtPrivate::CompareThreeWayTester::hasCompareThreeWay<LT, RT>) {
660 return compareThreeWay(lhs, rhs);
661 } else {
662 const auto retval = compareThreeWay(rhs, lhs);
663 return QtOrderingPrivate::reversed(retval);
664 }
665}
666
667#endif // defined(Q_QDOC)
668
669//
670// Legacy QPartialOrdering
671//
672
673namespace QtPrivate {
675{
676 Unordered = -127
677};
678}
679
680// [cmp.partialord]
682{
683public:
684 static const QPartialOrdering Less;
688
689 static const QPartialOrdering less;
693
694 friend constexpr bool operator==(QPartialOrdering lhs,
696 { return lhs.isOrdered() && lhs.m_order == 0; }
697
698 friend constexpr bool operator!=(QPartialOrdering lhs,
700 { return lhs.isOrdered() && lhs.m_order != 0; }
701
702 friend constexpr bool operator< (QPartialOrdering lhs,
704 { return lhs.isOrdered() && lhs.m_order < 0; }
705
706 friend constexpr bool operator<=(QPartialOrdering lhs,
708 { return lhs.isOrdered() && lhs.m_order <= 0; }
709
710 friend constexpr bool operator> (QPartialOrdering lhs,
712 { return lhs.isOrdered() && lhs.m_order > 0; }
713
714 friend constexpr bool operator>=(QPartialOrdering lhs,
716 { return lhs.isOrdered() && lhs.m_order >= 0; }
717
718
720 QPartialOrdering rhs) noexcept
721 { return rhs.isOrdered() && 0 == rhs.m_order; }
722
724 QPartialOrdering rhs) noexcept
725 { return rhs.isOrdered() && 0 != rhs.m_order; }
726
728 QPartialOrdering rhs) noexcept
729 { return rhs.isOrdered() && 0 < rhs.m_order; }
730
732 QPartialOrdering rhs) noexcept
733 { return rhs.isOrdered() && 0 <= rhs.m_order; }
734
736 QPartialOrdering rhs) noexcept
737 { return rhs.isOrdered() && 0 > rhs.m_order; }
738
740 QPartialOrdering rhs) noexcept
741 { return rhs.isOrdered() && 0 >= rhs.m_order; }
742
743
744#ifdef __cpp_lib_three_way_comparison
745 friend constexpr std::partial_ordering
747 { return lhs; } // https://eel.is/c++draft/cmp.partialord#4
748
749 friend constexpr std::partial_ordering
751 { return QtOrderingPrivate::reversed(rhs); }
752#endif // __cpp_lib_three_way_comparison
753
754
755 friend constexpr bool operator==(QPartialOrdering lhs, QPartialOrdering rhs) noexcept
756 { return lhs.m_order == rhs.m_order; }
757
758 friend constexpr bool operator!=(QPartialOrdering lhs, QPartialOrdering rhs) noexcept
759 { return lhs.m_order != rhs.m_order; }
760
771
774
777
778 constexpr Q_IMPLICIT operator Qt::partial_ordering() const noexcept
779 {
780 using O = QtPrivate::Ordering;
782 using R = Qt::partial_ordering;
783 switch (m_order) {
784 case qToUnderlying(O::Less): return R::less;
785 case qToUnderlying(O::Greater): return R::greater;
786 case qToUnderlying(O::Equivalent): return R::equivalent;
787 case qToUnderlying(U::Unordered): return R::unordered;
788 }
789 // GCC 8.x does not treat __builtin_unreachable() as constexpr
790#if !defined(Q_CC_GNU_ONLY) || (Q_CC_GNU >= 900)
791 // NOLINTNEXTLINE(qt-use-unreachable-return): Triggers on Clang, breaking GCC 8
792 Q_UNREACHABLE();
793#endif
794 return R::unordered;
795 }
796
797 friend constexpr bool operator==(QPartialOrdering lhs, Qt::partial_ordering rhs) noexcept
798 { Qt::partial_ordering qt = lhs; return qt == rhs; }
799
800 friend constexpr bool operator!=(QPartialOrdering lhs, Qt::partial_ordering rhs) noexcept
801 { Qt::partial_ordering qt = lhs; return qt != rhs; }
802
803 friend constexpr bool operator==(Qt::partial_ordering lhs, QPartialOrdering rhs) noexcept
804 { Qt::partial_ordering qt = rhs; return lhs == qt; }
805
806 friend constexpr bool operator!=(Qt::partial_ordering lhs, QPartialOrdering rhs) noexcept
807 { Qt::partial_ordering qt = rhs; return lhs != qt; }
808
809#ifdef __cpp_lib_three_way_comparison
810 constexpr Q_IMPLICIT QPartialOrdering(std::partial_ordering stdorder) noexcept
811 {
812 if (stdorder == std::partial_ordering::less)
814 else if (stdorder == std::partial_ordering::equivalent)
816 else if (stdorder == std::partial_ordering::greater)
818 else if (stdorder == std::partial_ordering::unordered)
820 }
821
822 constexpr Q_IMPLICIT QPartialOrdering(std::weak_ordering stdorder) noexcept
823 : QPartialOrdering(std::partial_ordering(stdorder)) {}
824
825 constexpr Q_IMPLICIT QPartialOrdering(std::strong_ordering stdorder) noexcept
826 : QPartialOrdering(std::partial_ordering(stdorder)) {}
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 }
839 Q_UNREACHABLE_RETURN(R::unordered);
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
864 // https://gcc.gnu.org/bugzilla/show_bug.cgi?id=100903
865 QT_WARNING_DISABLE_GCC("-Wzero-as-null-pointer-constant")
866 friend constexpr bool is_eq (QPartialOrdering o) noexcept { return o == 0; }
867 friend constexpr bool is_neq (QPartialOrdering o) noexcept { return o != 0; }
868 friend constexpr bool is_lt (QPartialOrdering o) noexcept { return o < 0; }
869 friend constexpr bool is_lteq(QPartialOrdering o) noexcept { return o <= 0; }
870 friend constexpr bool is_gt (QPartialOrdering o) noexcept { return o > 0; }
871 friend constexpr bool is_gteq(QPartialOrdering o) noexcept { return o >= 0; }
873
874 // instead of the exposition only is_ordered member in [cmp.partialord],
875 // use a private function
876 constexpr bool isOrdered() const noexcept
878
880};
881
886
891
893
894#endif // QCOMPARE_H
\variable Qt::partial_ordering::less
Definition qcompare.h:682
friend constexpr bool is_gteq(QPartialOrdering o) noexcept
Definition qcompare.h:871
static const QPartialOrdering unordered
Definition qcompare.h:692
friend constexpr bool is_neq(QPartialOrdering o) noexcept
Definition qcompare.h:867
friend constexpr bool operator==(QPartialOrdering lhs, Qt::partial_ordering rhs) noexcept
Definition qcompare.h:797
constexpr Q_IMPLICIT QPartialOrdering(Qt::partial_ordering order) noexcept
Definition qcompare.h:761
static const QPartialOrdering greater
Definition qcompare.h:691
constexpr Q_IMPLICIT QPartialOrdering(Qt::weak_ordering stdorder) noexcept
Definition qcompare.h:772
friend constexpr bool operator<(QPartialOrdering lhs, QtPrivate::CompareAgainstLiteralZero) noexcept
Definition qcompare.h:702
static const QPartialOrdering less
Definition qcompare.h:689
friend constexpr bool is_lteq(QPartialOrdering o) noexcept
Definition qcompare.h:869
friend constexpr bool operator!=(QPartialOrdering lhs, Qt::partial_ordering rhs) noexcept
Definition qcompare.h:800
friend constexpr bool operator==(QtPrivate::CompareAgainstLiteralZero, QPartialOrdering rhs) noexcept
Definition qcompare.h:719
friend constexpr bool operator==(Qt::partial_ordering lhs, QPartialOrdering rhs) noexcept
Definition qcompare.h:803
friend constexpr bool operator>(QPartialOrdering lhs, QtPrivate::CompareAgainstLiteralZero) noexcept
Definition qcompare.h:710
constexpr Q_IMPLICIT QPartialOrdering(Qt::strong_ordering stdorder) noexcept
Definition qcompare.h:775
static const QPartialOrdering Less
Definition qcompare.h:684
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:755
friend constexpr bool is_lt(QPartialOrdering o) noexcept
Definition qcompare.h:868
friend constexpr bool operator>=(QtPrivate::CompareAgainstLiteralZero, QPartialOrdering rhs) noexcept
Definition qcompare.h:739
static const QPartialOrdering equivalent
Definition qcompare.h:690
friend constexpr bool operator!=(Qt::partial_ordering lhs, QPartialOrdering rhs) noexcept
Definition qcompare.h:806
friend constexpr bool operator!=(QtPrivate::CompareAgainstLiteralZero, QPartialOrdering rhs) noexcept
Definition qcompare.h:723
friend constexpr bool operator<=(QPartialOrdering lhs, QtPrivate::CompareAgainstLiteralZero) noexcept
Definition qcompare.h:706
friend constexpr bool operator!=(QPartialOrdering lhs, QtPrivate::CompareAgainstLiteralZero) noexcept
Definition qcompare.h:698
friend constexpr bool is_gt(QPartialOrdering o) noexcept
Definition qcompare.h:870
static const QPartialOrdering Greater
Definition qcompare.h:686
friend constexpr bool operator==(QPartialOrdering lhs, QtPrivate::CompareAgainstLiteralZero) noexcept
Definition qcompare.h:694
friend constexpr bool operator!=(QPartialOrdering lhs, QPartialOrdering rhs) noexcept
Return true if lhs and rhs represent different results; otherwise, returns true.
Definition qcompare.h:758
friend constexpr bool operator<=(QtPrivate::CompareAgainstLiteralZero, QPartialOrdering rhs) noexcept
Definition qcompare.h:731
static const QPartialOrdering Equivalent
Definition qcompare.h:685
QT_WARNING_PUSH friend constexpr bool is_eq(QPartialOrdering o) noexcept
Definition qcompare.h:866
static const QPartialOrdering Unordered
Definition qcompare.h:687
friend constexpr bool operator>=(QPartialOrdering lhs, QtPrivate::CompareAgainstLiteralZero) noexcept
Definition qcompare.h:714
\variable Qt::weak_ordering::less
Definition qcompare.h:69
friend constexpr bool is_neq(partial_ordering o) noexcept
Definition qcompare.h:203
friend constexpr bool is_lteq(partial_ordering o) noexcept
Definition qcompare.h:205
friend constexpr bool operator>=(QtPrivate::CompareAgainstLiteralZero, partial_ordering rhs) noexcept
Definition qcompare.h:121
friend constexpr bool operator>(partial_ordering lhs, QtPrivate::CompareAgainstLiteralZero) noexcept
Definition qcompare.h:92
friend constexpr bool is_gt(partial_ordering o) noexcept
Definition qcompare.h:206
friend constexpr bool operator==(QtPrivate::CompareAgainstLiteralZero, partial_ordering rhs) noexcept
Definition qcompare.h:101
friend constexpr bool operator<=(partial_ordering lhs, QtPrivate::CompareAgainstLiteralZero) noexcept
Definition qcompare.h:88
friend constexpr bool is_gteq(partial_ordering o) noexcept
Definition qcompare.h:207
static const partial_ordering equivalent
Definition qcompare.h:72
friend constexpr bool operator<=(QtPrivate::CompareAgainstLiteralZero, partial_ordering rhs) noexcept
Definition qcompare.h:113
friend constexpr bool operator==(partial_ordering lhs, QtPrivate::CompareAgainstLiteralZero) noexcept
Definition qcompare.h:76
friend constexpr bool operator!=(QtPrivate::CompareAgainstLiteralZero, partial_ordering rhs) noexcept
Definition qcompare.h:105
friend constexpr bool operator!=(partial_ordering lhs, QtPrivate::CompareAgainstLiteralZero) noexcept
Definition qcompare.h:80
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:140
friend constexpr bool operator<(partial_ordering lhs, QtPrivate::CompareAgainstLiteralZero) noexcept
Definition qcompare.h:84
friend constexpr bool is_lt(partial_ordering o) noexcept
Definition qcompare.h:204
static const partial_ordering unordered
Definition qcompare.h:74
friend constexpr bool operator>=(partial_ordering lhs, QtPrivate::CompareAgainstLiteralZero) noexcept
Definition qcompare.h:96
QT_WARNING_PUSH friend constexpr bool is_eq(partial_ordering o) noexcept
Definition qcompare.h:202
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:137
static const partial_ordering greater
Definition qcompare.h:73
static const partial_ordering less
Definition qcompare.h:71
\inmodule QtCore \title Classes and helpers for defining comparison operators \keyword qtcompare
Definition qcompare.h:403
friend constexpr bool operator<=(strong_ordering lhs, QtPrivate::CompareAgainstLiteralZero) noexcept
Definition qcompare.h:428
friend constexpr bool is_gt(strong_ordering o) noexcept
Definition qcompare.h:586
QT_WARNING_PUSH friend constexpr bool is_eq(strong_ordering o) noexcept
Definition qcompare.h:582
friend constexpr bool operator!=(strong_ordering lhs, QtPrivate::CompareAgainstLiteralZero) noexcept
Definition qcompare.h:420
friend constexpr bool operator<(strong_ordering lhs, QtPrivate::CompareAgainstLiteralZero) noexcept
Definition qcompare.h:424
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:477
static const strong_ordering greater
Definition qcompare.h:408
friend constexpr bool operator==(strong_ordering lhs, partial_ordering rhs) noexcept
Definition qcompare.h:483
friend constexpr bool operator>(strong_ordering lhs, QtPrivate::CompareAgainstLiteralZero) noexcept
Definition qcompare.h:432
friend constexpr bool operator!=(weak_ordering lhs, strong_ordering rhs) noexcept
Definition qcompare.h:504
friend constexpr bool operator!=(partial_ordering lhs, strong_ordering rhs) noexcept
Definition qcompare.h:492
static const strong_ordering equal
Definition qcompare.h:407
friend constexpr bool operator!=(QtPrivate::CompareAgainstLiteralZero, strong_ordering rhs) noexcept
Definition qcompare.h:445
friend constexpr bool operator==(QtPrivate::CompareAgainstLiteralZero, strong_ordering rhs) noexcept
Definition qcompare.h:441
friend constexpr bool operator==(strong_ordering lhs, weak_ordering rhs) noexcept
Definition qcompare.h:495
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:480
friend constexpr bool operator>=(QtPrivate::CompareAgainstLiteralZero, strong_ordering rhs) noexcept
Definition qcompare.h:461
static const strong_ordering less
Definition qcompare.h:405
friend constexpr bool operator!=(strong_ordering lhs, weak_ordering rhs) noexcept
Definition qcompare.h:498
friend constexpr bool is_neq(strong_ordering o) noexcept
Definition qcompare.h:583
friend constexpr bool operator!=(strong_ordering lhs, partial_ordering rhs) noexcept
Definition qcompare.h:486
friend constexpr bool is_lteq(strong_ordering o) noexcept
Definition qcompare.h:585
friend constexpr bool operator==(strong_ordering lhs, QtPrivate::CompareAgainstLiteralZero) noexcept
Definition qcompare.h:416
static const strong_ordering equivalent
Definition qcompare.h:406
friend constexpr bool is_lt(strong_ordering o) noexcept
Definition qcompare.h:584
friend constexpr bool operator<=(QtPrivate::CompareAgainstLiteralZero, strong_ordering rhs) noexcept
Definition qcompare.h:453
friend constexpr bool operator==(weak_ordering lhs, strong_ordering rhs) noexcept
Definition qcompare.h:501
friend constexpr bool operator==(partial_ordering lhs, strong_ordering rhs) noexcept
Definition qcompare.h:489
friend constexpr bool is_gteq(strong_ordering o) noexcept
Definition qcompare.h:587
friend constexpr bool operator>=(strong_ordering lhs, QtPrivate::CompareAgainstLiteralZero) noexcept
Definition qcompare.h:436
\variable Qt::strong_ordering::less
Definition qcompare.h:224
friend constexpr bool is_lteq(weak_ordering o) noexcept
Definition qcompare.h:390
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:294
friend constexpr bool operator!=(weak_ordering lhs, QtPrivate::CompareAgainstLiteralZero) noexcept
Definition qcompare.h:237
QT_WARNING_PUSH friend constexpr bool is_eq(weak_ordering o) noexcept
Definition qcompare.h:387
static const weak_ordering less
Definition qcompare.h:226
friend constexpr bool operator<=(weak_ordering lhs, QtPrivate::CompareAgainstLiteralZero) noexcept
Definition qcompare.h:245
friend constexpr bool operator<(weak_ordering lhs, QtPrivate::CompareAgainstLiteralZero) noexcept
Definition qcompare.h:241
friend constexpr bool operator==(weak_ordering lhs, partial_ordering rhs) noexcept
Definition qcompare.h:300
friend constexpr bool is_gteq(weak_ordering o) noexcept
Definition qcompare.h:392
friend constexpr bool is_lt(weak_ordering o) noexcept
Definition qcompare.h:389
friend constexpr bool operator==(weak_ordering lhs, QtPrivate::CompareAgainstLiteralZero) noexcept
Definition qcompare.h:233
friend constexpr bool operator!=(QtPrivate::CompareAgainstLiteralZero, weak_ordering rhs) noexcept
Definition qcompare.h:262
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:297
friend constexpr bool is_gt(weak_ordering o) noexcept
Definition qcompare.h:391
friend constexpr bool operator>=(weak_ordering lhs, QtPrivate::CompareAgainstLiteralZero) noexcept
Definition qcompare.h:253
friend constexpr bool operator>=(QtPrivate::CompareAgainstLiteralZero, weak_ordering rhs) noexcept
Definition qcompare.h:278
friend constexpr bool is_neq(weak_ordering o) noexcept
Definition qcompare.h:388
static const weak_ordering greater
Definition qcompare.h:228
friend constexpr bool operator>(weak_ordering lhs, QtPrivate::CompareAgainstLiteralZero) noexcept
Definition qcompare.h:249
friend constexpr bool operator!=(weak_ordering lhs, partial_ordering rhs) noexcept
Definition qcompare.h:303
friend constexpr bool operator<=(QtPrivate::CompareAgainstLiteralZero, weak_ordering rhs) noexcept
Definition qcompare.h:270
friend constexpr bool operator!=(partial_ordering lhs, weak_ordering rhs) noexcept
Definition qcompare.h:309
friend constexpr bool operator==(partial_ordering lhs, weak_ordering rhs) noexcept
Definition qcompare.h:306
static const weak_ordering equivalent
Definition qcompare.h:227
friend constexpr bool operator==(QtPrivate::CompareAgainstLiteralZero, weak_ordering rhs) noexcept
Definition qcompare.h:258
Combined button and popup list for selecting options.
constexpr O reversed(O o) noexcept
Definition qcompare.h:53
constexpr bool compareThreeWayNoexcept() noexcept
Definition qcompare.h:631
constexpr bool hasCompareThreeWay
Definition qcompare.h:617
\macro QT_NO_KEYWORDS >
LegacyUncomparable
Definition qcompare.h:675
qint8 CompareUnderlyingType
Definition qcompare.h:25
Definition qcompare.h:63
constexpr Qt::strong_ordering compareThreeWay(LeftInt lhs, RightInt rhs) noexcept
auto qCompareThreeWay(const LT &lhs, const RT &rhs) noexcept(QtPrivate::CompareThreeWayTester::compareThreeWayNoexcept< LT, RT >())
Definition qcompare.h:655
#define QT_WARNING_POP
#define QT_WARNING_DISABLE_GCC(text)
#define QT_WARNING_PUSH
#define Q_IMPLICIT
GLfixed GLfixed GLint GLint order
#define QT_BEGIN_INCLUDE_NAMESPACE
#define QT_END_INCLUDE_NAMESPACE
QT_BEGIN_NAMESPACE constexpr std::underlying_type_t< Enum > qToUnderlying(Enum e) noexcept
QT_BEGIN_NAMESPACE typedef signed char qint8
Definition qtypes.h:45
Qt::weak_ordering compareThreeWay(const QUrl &lhs, const QUrl &rhs)
Definition qurl.cpp:3079