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
66{
67public:
68 static const partial_ordering less;
72
73 friend constexpr bool operator==(partial_ordering lhs,
75 { return lhs.isOrdered() && lhs.m_order == 0; }
76
77 friend constexpr bool operator!=(partial_ordering lhs,
79 { return lhs.isOrdered() && lhs.m_order != 0; }
80
81 friend constexpr bool operator< (partial_ordering lhs,
83 { return lhs.isOrdered() && lhs.m_order < 0; }
84
85 friend constexpr bool operator<=(partial_ordering lhs,
87 { return lhs.isOrdered() && lhs.m_order <= 0; }
88
89 friend constexpr bool operator> (partial_ordering lhs,
91 { return lhs.isOrdered() && lhs.m_order > 0; }
92
93 friend constexpr bool operator>=(partial_ordering lhs,
95 { return lhs.isOrdered() && lhs.m_order >= 0; }
96
97
99 partial_ordering rhs) noexcept
100 { return rhs.isOrdered() && 0 == rhs.m_order; }
101
103 partial_ordering rhs) noexcept
104 { return rhs.isOrdered() && 0 != rhs.m_order; }
105
107 partial_ordering rhs) noexcept
108 { return rhs.isOrdered() && 0 < rhs.m_order; }
109
111 partial_ordering rhs) noexcept
112 { return rhs.isOrdered() && 0 <= rhs.m_order; }
113
115 partial_ordering rhs) noexcept
116 { return rhs.isOrdered() && 0 > rhs.m_order; }
117
119 partial_ordering rhs) noexcept
120 { return rhs.isOrdered() && 0 >= rhs.m_order; }
121
122
123#ifdef __cpp_lib_three_way_comparison
124 friend constexpr std::partial_ordering
126 { return lhs; } // https://eel.is/c++draft/cmp.partialord#4
127
128 friend constexpr std::partial_ordering
129 operator<=>(QtPrivate::CompareAgainstLiteralZero, partial_ordering rhs) noexcept
130 { return QtOrderingPrivate::reversed(rhs); }
131#endif // __cpp_lib_three_way_comparison
132
133
134 friend constexpr bool operator==(partial_ordering lhs, partial_ordering rhs) noexcept
135 { return lhs.m_order == rhs.m_order; }
136
137 friend constexpr bool operator!=(partial_ordering lhs, partial_ordering rhs) noexcept
138 { return lhs.m_order != rhs.m_order; }
139
140#ifdef __cpp_lib_three_way_comparison
141 constexpr Q_IMPLICIT partial_ordering(std::partial_ordering stdorder) noexcept
142 {
143 if (stdorder == std::partial_ordering::less)
145 else if (stdorder == std::partial_ordering::equivalent)
147 else if (stdorder == std::partial_ordering::greater)
149 else if (stdorder == std::partial_ordering::unordered)
151 }
152
153 constexpr Q_IMPLICIT operator std::partial_ordering() const noexcept
154 {
155 static_assert(sizeof(*this) == sizeof(std::partial_ordering));
156#ifdef __cpp_lib_bit_cast
157 return std::bit_cast<std::partial_ordering>(*this);
158#else
159 using O = QtPrivate::Ordering;
160 using U = QtPrivate::Uncomparable;
161 using R = std::partial_ordering;
162 switch (m_order) {
163 case qToUnderlying(O::Less): return R::less;
164 case qToUnderlying(O::Greater): return R::greater;
165 case qToUnderlying(O::Equivalent): return R::equivalent;
166 case qToUnderlying(U::Unordered): return R::unordered;
167 }
168 Q_UNREACHABLE_RETURN(R::unordered);
169#endif // __cpp_lib_bit_cast
170 }
171
172 friend constexpr bool operator==(partial_ordering lhs, std::partial_ordering rhs) noexcept
173 { return static_cast<std::partial_ordering>(lhs) == rhs; }
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==(std::partial_ordering lhs, partial_ordering rhs) noexcept
179 { return lhs == static_cast<std::partial_ordering>(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#endif // __cpp_lib_three_way_comparison
184
185private:
186 friend class weak_ordering;
187 friend class strong_ordering;
188
189 constexpr explicit partial_ordering(QtPrivate::Ordering order) noexcept
190 : m_order(static_cast<QtPrivate::CompareUnderlyingType>(order))
191 {}
192 constexpr explicit partial_ordering(QtPrivate::Uncomparable order) noexcept
193 : m_order(static_cast<QtPrivate::CompareUnderlyingType>(order))
194 {}
195
197 // https://gcc.gnu.org/bugzilla/show_bug.cgi?id=100903
198 QT_WARNING_DISABLE_GCC("-Wzero-as-null-pointer-constant")
199 friend constexpr bool is_eq (partial_ordering o) noexcept { return o == 0; }
200 friend constexpr bool is_neq (partial_ordering o) noexcept { return o != 0; }
201 friend constexpr bool is_lt (partial_ordering o) noexcept { return o < 0; }
202 friend constexpr bool is_lteq(partial_ordering o) noexcept { return o <= 0; }
203 friend constexpr bool is_gt (partial_ordering o) noexcept { return o > 0; }
204 friend constexpr bool is_gteq(partial_ordering o) noexcept { return o >= 0; }
206
207 // instead of the exposition only is_ordered member in [cmp.partialord],
208 // use a private function
209 constexpr bool isOrdered() const noexcept
211
213};
214
215inline constexpr partial_ordering partial_ordering::less(QtPrivate::Ordering::Less);
216inline constexpr partial_ordering partial_ordering::equivalent(QtPrivate::Ordering::Equivalent);
217inline constexpr partial_ordering partial_ordering::greater(QtPrivate::Ordering::Greater);
218inline constexpr partial_ordering partial_ordering::unordered(QtPrivate::Uncomparable::Unordered);
219
221{
222public:
223 static const weak_ordering less;
225 static const weak_ordering greater;
226
227 constexpr Q_IMPLICIT operator partial_ordering() const noexcept
228 { return partial_ordering(static_cast<QtPrivate::Ordering>(m_order)); }
229
230 friend constexpr bool operator==(weak_ordering lhs,
232 { return lhs.m_order == 0; }
233
234 friend constexpr bool operator!=(weak_ordering lhs,
236 { return lhs.m_order != 0; }
237
238 friend constexpr bool operator< (weak_ordering lhs,
240 { return lhs.m_order < 0; }
241
242 friend constexpr bool operator<=(weak_ordering lhs,
244 { return lhs.m_order <= 0; }
245
246 friend constexpr bool operator> (weak_ordering lhs,
248 { return lhs.m_order > 0; }
249
250 friend constexpr bool operator>=(weak_ordering lhs,
252 { return lhs.m_order >= 0; }
253
254
256 weak_ordering rhs) noexcept
257 { return 0 == rhs.m_order; }
258
260 weak_ordering rhs) noexcept
261 { return 0 != rhs.m_order; }
262
264 weak_ordering rhs) noexcept
265 { return 0 < rhs.m_order; }
266
268 weak_ordering rhs) noexcept
269 { return 0 <= rhs.m_order; }
270
272 weak_ordering rhs) noexcept
273 { return 0 > rhs.m_order; }
274
276 weak_ordering rhs) noexcept
277 { return 0 >= rhs.m_order; }
278
279
280#ifdef __cpp_lib_three_way_comparison
281 friend constexpr std::weak_ordering
282 operator<=>(weak_ordering lhs, QtPrivate::CompareAgainstLiteralZero) noexcept
283 { return lhs; } // https://eel.is/c++draft/cmp.weakord#5
284
285 friend constexpr std::weak_ordering
286 operator<=>(QtPrivate::CompareAgainstLiteralZero, weak_ordering rhs) noexcept
287 { return QtOrderingPrivate::reversed(rhs); }
288#endif // __cpp_lib_three_way_comparison
289
290
291 friend constexpr bool operator==(weak_ordering lhs, weak_ordering rhs) noexcept
292 { return lhs.m_order == rhs.m_order; }
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, partial_ordering rhs) noexcept
298 { return static_cast<partial_ordering>(lhs) == rhs; }
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==(partial_ordering lhs, weak_ordering rhs) noexcept
304 { return lhs == static_cast<partial_ordering>(rhs); }
305
306 friend constexpr bool operator!=(partial_ordering lhs, weak_ordering rhs) noexcept
307 { return lhs != static_cast<partial_ordering>(rhs); }
308
309#ifdef __cpp_lib_three_way_comparison
310 constexpr Q_IMPLICIT weak_ordering(std::weak_ordering stdorder) noexcept
311 {
312 if (stdorder == std::weak_ordering::less)
314 else if (stdorder == std::weak_ordering::equivalent)
316 else if (stdorder == std::weak_ordering::greater)
318 }
319
320 constexpr Q_IMPLICIT operator std::weak_ordering() const noexcept
321 {
322 static_assert(sizeof(*this) == sizeof(std::weak_ordering));
323#ifdef __cpp_lib_bit_cast
324 return std::bit_cast<std::weak_ordering>(*this);
325#else
326 using O = QtPrivate::Ordering;
327 using R = std::weak_ordering;
328 switch (m_order) {
329 case qToUnderlying(O::Less): return R::less;
330 case qToUnderlying(O::Greater): return R::greater;
331 case qToUnderlying(O::Equivalent): return R::equivalent;
332 }
333 Q_UNREACHABLE_RETURN(R::equivalent);
334#endif // __cpp_lib_bit_cast
335 }
336
337 friend constexpr bool operator==(weak_ordering lhs, std::weak_ordering rhs) noexcept
338 { return static_cast<std::weak_ordering>(lhs) == rhs; }
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::partial_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::strong_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==(std::weak_ordering lhs, weak_ordering rhs) noexcept
356 { return lhs == static_cast<std::weak_ordering>(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::partial_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::strong_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#endif // __cpp_lib_three_way_comparison
373
374private:
375 friend class strong_ordering;
376
377 constexpr explicit weak_ordering(QtPrivate::Ordering order) noexcept
378 : m_order(static_cast<QtPrivate::CompareUnderlyingType>(order))
379 {}
380
382 // https://gcc.gnu.org/bugzilla/show_bug.cgi?id=100903
383 QT_WARNING_DISABLE_GCC("-Wzero-as-null-pointer-constant")
384 friend constexpr bool is_eq (weak_ordering o) noexcept { return o == 0; }
385 friend constexpr bool is_neq (weak_ordering o) noexcept { return o != 0; }
386 friend constexpr bool is_lt (weak_ordering o) noexcept { return o < 0; }
387 friend constexpr bool is_lteq(weak_ordering o) noexcept { return o <= 0; }
388 friend constexpr bool is_gt (weak_ordering o) noexcept { return o > 0; }
389 friend constexpr bool is_gteq(weak_ordering o) noexcept { return o >= 0; }
391
393};
394
395inline constexpr weak_ordering weak_ordering::less(QtPrivate::Ordering::Less);
396inline constexpr weak_ordering weak_ordering::equivalent(QtPrivate::Ordering::Equivalent);
397inline constexpr weak_ordering weak_ordering::greater(QtPrivate::Ordering::Greater);
398
400{
401public:
402 static const strong_ordering less;
404 static const strong_ordering equal;
406
407 constexpr Q_IMPLICIT operator partial_ordering() const noexcept
408 { return partial_ordering(static_cast<QtPrivate::Ordering>(m_order)); }
409
410 constexpr Q_IMPLICIT operator weak_ordering() const noexcept
411 { return weak_ordering(static_cast<QtPrivate::Ordering>(m_order)); }
412
413 friend constexpr bool operator==(strong_ordering lhs,
415 { return lhs.m_order == 0; }
416
417 friend constexpr bool operator!=(strong_ordering lhs,
419 { return lhs.m_order != 0; }
420
421 friend constexpr bool operator< (strong_ordering lhs,
423 { return lhs.m_order < 0; }
424
425 friend constexpr bool operator<=(strong_ordering lhs,
427 { return lhs.m_order <= 0; }
428
429 friend constexpr bool operator> (strong_ordering lhs,
431 { return lhs.m_order > 0; }
432
433 friend constexpr bool operator>=(strong_ordering lhs,
435 { return lhs.m_order >= 0; }
436
437
439 strong_ordering rhs) noexcept
440 { return 0 == rhs.m_order; }
441
443 strong_ordering rhs) noexcept
444 { return 0 != rhs.m_order; }
445
447 strong_ordering rhs) noexcept
448 { return 0 < rhs.m_order; }
449
451 strong_ordering rhs) noexcept
452 { return 0 <= rhs.m_order; }
453
455 strong_ordering rhs) noexcept
456 { return 0 > rhs.m_order; }
457
459 strong_ordering rhs) noexcept
460 { return 0 >= rhs.m_order; }
461
462
463#ifdef __cpp_lib_three_way_comparison
464 friend constexpr std::strong_ordering
466 { return lhs; } // https://eel.is/c++draft/cmp.strongord#6
467
468 friend constexpr std::strong_ordering
469 operator<=>(QtPrivate::CompareAgainstLiteralZero, strong_ordering rhs) noexcept
470 { return QtOrderingPrivate::reversed(rhs); }
471#endif // __cpp_lib_three_way_comparison
472
473
474 friend constexpr bool operator==(strong_ordering lhs, strong_ordering rhs) noexcept
475 { return lhs.m_order == rhs.m_order; }
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, partial_ordering rhs) noexcept
481 { return static_cast<partial_ordering>(lhs) == rhs; }
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==(partial_ordering lhs, strong_ordering rhs) noexcept
487 { return lhs == static_cast<partial_ordering>(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==(strong_ordering lhs, weak_ordering rhs) noexcept
493 { return static_cast<weak_ordering>(lhs) == 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==(weak_ordering lhs, strong_ordering rhs) noexcept
499 { return lhs == static_cast<weak_ordering>(rhs); }
500
501 friend constexpr bool operator!=(weak_ordering lhs, strong_ordering rhs) noexcept
502 { return lhs != static_cast<weak_ordering>(rhs); }
503
504#ifdef __cpp_lib_three_way_comparison
505 constexpr Q_IMPLICIT strong_ordering(std::strong_ordering stdorder) noexcept
506 {
507 if (stdorder == std::strong_ordering::less)
509 else if (stdorder == std::strong_ordering::equivalent)
511 else if (stdorder == std::strong_ordering::equal)
513 else if (stdorder == std::strong_ordering::greater)
515 }
516
517 constexpr Q_IMPLICIT operator std::strong_ordering() const noexcept
518 {
519 static_assert(sizeof(*this) == sizeof(std::strong_ordering));
520#ifdef __cpp_lib_bit_cast
521 return std::bit_cast<std::strong_ordering>(*this);
522#else
523 using O = QtPrivate::Ordering;
524 using R = std::strong_ordering;
525 switch (m_order) {
526 case qToUnderlying(O::Less): return R::less;
527 case qToUnderlying(O::Greater): return R::greater;
528 case qToUnderlying(O::Equal): return R::equal;
529 }
530 Q_UNREACHABLE_RETURN(R::equal);
531#endif // __cpp_lib_bit_cast
532 }
533
534 friend constexpr bool operator==(strong_ordering lhs, std::strong_ordering rhs) noexcept
535 { return static_cast<std::strong_ordering>(lhs) == rhs; }
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::partial_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::weak_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==(std::strong_ordering lhs, strong_ordering rhs) noexcept
553 { return lhs == static_cast<std::strong_ordering>(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::partial_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::weak_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#endif // __cpp_lib_three_way_comparison
570
571 private:
572 constexpr explicit strong_ordering(QtPrivate::Ordering order) noexcept
573 : m_order(static_cast<QtPrivate::CompareUnderlyingType>(order))
574 {}
575
577 // https://gcc.gnu.org/bugzilla/show_bug.cgi?id=100903
578 QT_WARNING_DISABLE_GCC("-Wzero-as-null-pointer-constant")
579 friend constexpr bool is_eq (strong_ordering o) noexcept { return o == 0; }
580 friend constexpr bool is_neq (strong_ordering o) noexcept { return o != 0; }
581 friend constexpr bool is_lt (strong_ordering o) noexcept { return o < 0; }
582 friend constexpr bool is_lteq(strong_ordering o) noexcept { return o <= 0; }
583 friend constexpr bool is_gt (strong_ordering o) noexcept { return o > 0; }
584 friend constexpr bool is_gteq(strong_ordering o) noexcept { return o >= 0; }
586
588};
589
590inline constexpr strong_ordering strong_ordering::less(QtPrivate::Ordering::Less);
591inline constexpr strong_ordering strong_ordering::equivalent(QtPrivate::Ordering::Equivalent);
592inline constexpr strong_ordering strong_ordering::equal(QtPrivate::Ordering::Equal);
593inline constexpr strong_ordering strong_ordering::greater(QtPrivate::Ordering::Greater);
594
595} // namespace Qt
596
598
599// This is intentionally included after Qt::*_ordering types and before
600// qCompareThreeWay. Do not change!
601#include <QtCore/qcomparehelpers.h>
602
604
605namespace QtPrivate {
606
607namespace CompareThreeWayTester {
608
610
611 // Check if compareThreeWay is implemented for the (LT, RT) argument
612 // pair.
613 template <typename LT, typename RT, typename = void>
614 constexpr bool hasCompareThreeWay = false;
615
616 template <typename LT, typename RT>
617 constexpr bool hasCompareThreeWay<
618 LT, RT, std::void_t<decltype(compareThreeWay(std::declval<LT>(), std::declval<RT>()))>
619 > = true;
620
621 // Check if the operation is noexcept. We have two different overloads,
622 // depending on the available compareThreeWay() implementation.
623 // Both are declared, but not implemented. To be used only in unevaluated
624 // context.
625
626 template <typename LT, typename RT,
627 std::enable_if_t<hasCompareThreeWay<LT, RT>, bool> = true>
628 constexpr bool compareThreeWayNoexcept() noexcept
629 { return noexcept(compareThreeWay(std::declval<LT>(), std::declval<RT>())); }
630
631 template <typename LT, typename RT,
632 std::enable_if_t<!hasCompareThreeWay<LT, RT> && hasCompareThreeWay<RT, LT>,
633 bool> = true>
634 constexpr bool compareThreeWayNoexcept() noexcept
635 { return noexcept(compareThreeWay(std::declval<RT>(), std::declval<LT>())); }
636
637} // namespace CompareThreeWayTester
638
639} // namespace QtPrivate
640
641#if defined(Q_QDOC)
642
643template <typename LeftType, typename RightType>
644auto qCompareThreeWay(const LeftType &lhs, const RightType &rhs);
645
646#else
647
648template <typename LT, typename RT,
649 std::enable_if_t<QtPrivate::CompareThreeWayTester::hasCompareThreeWay<LT, RT>
650 || QtPrivate::CompareThreeWayTester::hasCompareThreeWay<RT, LT>,
651 bool> = true>
652auto qCompareThreeWay(const LT &lhs, const RT &rhs)
653 noexcept(QtPrivate::CompareThreeWayTester::compareThreeWayNoexcept<LT, RT>())
654{
656 if constexpr (QtPrivate::CompareThreeWayTester::hasCompareThreeWay<LT, RT>) {
657 return compareThreeWay(lhs, rhs);
658 } else {
659 const auto retval = compareThreeWay(rhs, lhs);
660 return QtOrderingPrivate::reversed(retval);
661 }
662}
663
664#endif // defined(Q_QDOC)
665
666//
667// Legacy QPartialOrdering
668//
669
670namespace QtPrivate {
672{
673 Unordered = -127
674};
675}
676
677// [cmp.partialord]
679{
680public:
681 static const QPartialOrdering Less;
685
686 static const QPartialOrdering less;
690
691 friend constexpr bool operator==(QPartialOrdering lhs,
693 { return lhs.isOrdered() && lhs.m_order == 0; }
694
695 friend constexpr bool operator!=(QPartialOrdering lhs,
697 { return lhs.isOrdered() && lhs.m_order != 0; }
698
699 friend constexpr bool operator< (QPartialOrdering lhs,
701 { return lhs.isOrdered() && lhs.m_order < 0; }
702
703 friend constexpr bool operator<=(QPartialOrdering lhs,
705 { return lhs.isOrdered() && lhs.m_order <= 0; }
706
707 friend constexpr bool operator> (QPartialOrdering lhs,
709 { return lhs.isOrdered() && lhs.m_order > 0; }
710
711 friend constexpr bool operator>=(QPartialOrdering lhs,
713 { return lhs.isOrdered() && lhs.m_order >= 0; }
714
715
717 QPartialOrdering rhs) noexcept
718 { return rhs.isOrdered() && 0 == rhs.m_order; }
719
721 QPartialOrdering rhs) noexcept
722 { return rhs.isOrdered() && 0 != rhs.m_order; }
723
725 QPartialOrdering rhs) noexcept
726 { return rhs.isOrdered() && 0 < rhs.m_order; }
727
729 QPartialOrdering rhs) noexcept
730 { return rhs.isOrdered() && 0 <= rhs.m_order; }
731
733 QPartialOrdering rhs) noexcept
734 { return rhs.isOrdered() && 0 > rhs.m_order; }
735
737 QPartialOrdering rhs) noexcept
738 { return rhs.isOrdered() && 0 >= rhs.m_order; }
739
740
741#ifdef __cpp_lib_three_way_comparison
742 friend constexpr std::partial_ordering
744 { return lhs; } // https://eel.is/c++draft/cmp.partialord#4
745
746 friend constexpr std::partial_ordering
748 { return QtOrderingPrivate::reversed(rhs); }
749#endif // __cpp_lib_three_way_comparison
750
751
752 friend constexpr bool operator==(QPartialOrdering lhs, QPartialOrdering rhs) noexcept
753 { return lhs.m_order == rhs.m_order; }
754
755 friend constexpr bool operator!=(QPartialOrdering lhs, QPartialOrdering rhs) noexcept
756 { return lhs.m_order != rhs.m_order; }
757
768
771
774
775 constexpr Q_IMPLICIT operator Qt::partial_ordering() const noexcept
776 {
777 using O = QtPrivate::Ordering;
779 using R = Qt::partial_ordering;
780 switch (m_order) {
781 case qToUnderlying(O::Less): return R::less;
782 case qToUnderlying(O::Greater): return R::greater;
783 case qToUnderlying(O::Equivalent): return R::equivalent;
784 case qToUnderlying(U::Unordered): return R::unordered;
785 }
786 // GCC 8.x does not treat __builtin_unreachable() as constexpr
787#if !defined(Q_CC_GNU_ONLY) || (Q_CC_GNU >= 900)
788 // NOLINTNEXTLINE(qt-use-unreachable-return): Triggers on Clang, breaking GCC 8
789 Q_UNREACHABLE();
790#endif
791 return R::unordered;
792 }
793
794 friend constexpr bool operator==(QPartialOrdering lhs, Qt::partial_ordering rhs) noexcept
795 { Qt::partial_ordering qt = lhs; return qt == rhs; }
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==(Qt::partial_ordering lhs, QPartialOrdering rhs) noexcept
801 { Qt::partial_ordering qt = rhs; return lhs == qt; }
802
803 friend constexpr bool operator!=(Qt::partial_ordering lhs, QPartialOrdering rhs) noexcept
804 { Qt::partial_ordering qt = rhs; return lhs != qt; }
805
806#ifdef __cpp_lib_three_way_comparison
807 constexpr Q_IMPLICIT QPartialOrdering(std::partial_ordering stdorder) noexcept
808 {
809 if (stdorder == std::partial_ordering::less)
811 else if (stdorder == std::partial_ordering::equivalent)
813 else if (stdorder == std::partial_ordering::greater)
815 else if (stdorder == std::partial_ordering::unordered)
817 }
818
819 constexpr Q_IMPLICIT QPartialOrdering(std::weak_ordering stdorder) noexcept
820 : QPartialOrdering(std::partial_ordering(stdorder)) {}
821
822 constexpr Q_IMPLICIT QPartialOrdering(std::strong_ordering stdorder) noexcept
823 : QPartialOrdering(std::partial_ordering(stdorder)) {}
824
825 constexpr Q_IMPLICIT operator std::partial_ordering() const noexcept
826 {
827 using O = QtPrivate::Ordering;
829 using R = std::partial_ordering;
830 switch (m_order) {
831 case qToUnderlying(O::Less): return R::less;
832 case qToUnderlying(O::Greater): return R::greater;
833 case qToUnderlying(O::Equivalent): return R::equivalent;
834 case qToUnderlying(U::Unordered): return R::unordered;
835 }
836 Q_UNREACHABLE_RETURN(R::unordered);
837 }
838
839 friend constexpr bool operator==(QPartialOrdering lhs, std::partial_ordering rhs) noexcept
840 { return static_cast<std::partial_ordering>(lhs) == rhs; }
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==(std::partial_ordering lhs, QPartialOrdering rhs) noexcept
846 { return lhs == static_cast<std::partial_ordering>(rhs); }
847
848 friend constexpr bool operator!=(std::partial_ordering lhs, QPartialOrdering rhs) noexcept
849 { return lhs != static_cast<std::partial_ordering>(rhs); }
850#endif // __cpp_lib_three_way_comparison
851
852private:
853 constexpr explicit QPartialOrdering(QtPrivate::Ordering order) noexcept
854 : m_order(static_cast<QtPrivate::CompareUnderlyingType>(order))
855 {}
856 constexpr explicit QPartialOrdering(QtPrivate::LegacyUncomparable order) noexcept
857 : m_order(static_cast<QtPrivate::CompareUnderlyingType>(order))
858 {}
859
861 // https://gcc.gnu.org/bugzilla/show_bug.cgi?id=100903
862 QT_WARNING_DISABLE_GCC("-Wzero-as-null-pointer-constant")
863 friend constexpr bool is_eq (QPartialOrdering o) noexcept { return o == 0; }
864 friend constexpr bool is_neq (QPartialOrdering o) noexcept { return o != 0; }
865 friend constexpr bool is_lt (QPartialOrdering o) noexcept { return o < 0; }
866 friend constexpr bool is_lteq(QPartialOrdering o) noexcept { return o <= 0; }
867 friend constexpr bool is_gt (QPartialOrdering o) noexcept { return o > 0; }
868 friend constexpr bool is_gteq(QPartialOrdering o) noexcept { return o >= 0; }
870
871 // instead of the exposition only is_ordered member in [cmp.partialord],
872 // use a private function
873 constexpr bool isOrdered() const noexcept
875
877};
878
883
888
890
891#endif // QCOMPARE_H
\variable Qt::partial_ordering::less
Definition qcompare.h:679
friend constexpr bool is_gteq(QPartialOrdering o) noexcept
Definition qcompare.h:868
static const QPartialOrdering unordered
Definition qcompare.h:689
friend constexpr bool is_neq(QPartialOrdering o) noexcept
Definition qcompare.h:864
friend constexpr bool operator==(QPartialOrdering lhs, Qt::partial_ordering rhs) noexcept
Definition qcompare.h:794
constexpr Q_IMPLICIT QPartialOrdering(Qt::partial_ordering order) noexcept
Definition qcompare.h:758
static const QPartialOrdering greater
Definition qcompare.h:688
constexpr Q_IMPLICIT QPartialOrdering(Qt::weak_ordering stdorder) noexcept
Definition qcompare.h:769
friend constexpr bool operator<(QPartialOrdering lhs, QtPrivate::CompareAgainstLiteralZero) noexcept
Definition qcompare.h:699
static const QPartialOrdering less
Definition qcompare.h:686
friend constexpr bool is_lteq(QPartialOrdering o) noexcept
Definition qcompare.h:866
friend constexpr bool operator!=(QPartialOrdering lhs, Qt::partial_ordering rhs) noexcept
Definition qcompare.h:797
friend constexpr bool operator==(QtPrivate::CompareAgainstLiteralZero, QPartialOrdering rhs) noexcept
Definition qcompare.h:716
friend constexpr bool operator==(Qt::partial_ordering lhs, QPartialOrdering rhs) noexcept
Definition qcompare.h:800
friend constexpr bool operator>(QPartialOrdering lhs, QtPrivate::CompareAgainstLiteralZero) noexcept
Definition qcompare.h:707
constexpr Q_IMPLICIT QPartialOrdering(Qt::strong_ordering stdorder) noexcept
Definition qcompare.h:772
static const QPartialOrdering Less
Definition qcompare.h:681
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:752
friend constexpr bool is_lt(QPartialOrdering o) noexcept
Definition qcompare.h:865
friend constexpr bool operator>=(QtPrivate::CompareAgainstLiteralZero, QPartialOrdering rhs) noexcept
Definition qcompare.h:736
static const QPartialOrdering equivalent
Definition qcompare.h:687
friend constexpr bool operator!=(Qt::partial_ordering lhs, QPartialOrdering rhs) noexcept
Definition qcompare.h:803
friend constexpr bool operator!=(QtPrivate::CompareAgainstLiteralZero, QPartialOrdering rhs) noexcept
Definition qcompare.h:720
friend constexpr bool operator<=(QPartialOrdering lhs, QtPrivate::CompareAgainstLiteralZero) noexcept
Definition qcompare.h:703
friend constexpr bool operator!=(QPartialOrdering lhs, QtPrivate::CompareAgainstLiteralZero) noexcept
Definition qcompare.h:695
friend constexpr bool is_gt(QPartialOrdering o) noexcept
Definition qcompare.h:867
static const QPartialOrdering Greater
Definition qcompare.h:683
friend constexpr bool operator==(QPartialOrdering lhs, QtPrivate::CompareAgainstLiteralZero) noexcept
Definition qcompare.h:691
friend constexpr bool operator!=(QPartialOrdering lhs, QPartialOrdering rhs) noexcept
Return true if lhs and rhs represent different results; otherwise, returns true.
Definition qcompare.h:755
friend constexpr bool operator<=(QtPrivate::CompareAgainstLiteralZero, QPartialOrdering rhs) noexcept
Definition qcompare.h:728
static const QPartialOrdering Equivalent
Definition qcompare.h:682
QT_WARNING_PUSH friend constexpr bool is_eq(QPartialOrdering o) noexcept
Definition qcompare.h:863
static const QPartialOrdering Unordered
Definition qcompare.h:684
friend constexpr bool operator>=(QPartialOrdering lhs, QtPrivate::CompareAgainstLiteralZero) noexcept
Definition qcompare.h:711
\variable Qt::weak_ordering::less
Definition qcompare.h:66
friend constexpr bool is_neq(partial_ordering o) noexcept
Definition qcompare.h:200
friend constexpr bool is_lteq(partial_ordering o) noexcept
Definition qcompare.h:202
friend constexpr bool operator>=(QtPrivate::CompareAgainstLiteralZero, partial_ordering rhs) noexcept
Definition qcompare.h:118
friend constexpr bool operator>(partial_ordering lhs, QtPrivate::CompareAgainstLiteralZero) noexcept
Definition qcompare.h:89
friend constexpr bool is_gt(partial_ordering o) noexcept
Definition qcompare.h:203
friend constexpr bool operator==(QtPrivate::CompareAgainstLiteralZero, partial_ordering rhs) noexcept
Definition qcompare.h:98
friend constexpr bool operator<=(partial_ordering lhs, QtPrivate::CompareAgainstLiteralZero) noexcept
Definition qcompare.h:85
friend constexpr bool is_gteq(partial_ordering o) noexcept
Definition qcompare.h:204
static const partial_ordering equivalent
Definition qcompare.h:69
friend constexpr bool operator<=(QtPrivate::CompareAgainstLiteralZero, partial_ordering rhs) noexcept
Definition qcompare.h:110
friend constexpr bool operator==(partial_ordering lhs, QtPrivate::CompareAgainstLiteralZero) noexcept
Definition qcompare.h:73
friend constexpr bool operator!=(QtPrivate::CompareAgainstLiteralZero, partial_ordering rhs) noexcept
Definition qcompare.h:102
friend constexpr bool operator!=(partial_ordering lhs, QtPrivate::CompareAgainstLiteralZero) noexcept
Definition qcompare.h:77
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:137
friend constexpr bool operator<(partial_ordering lhs, QtPrivate::CompareAgainstLiteralZero) noexcept
Definition qcompare.h:81
friend constexpr bool is_lt(partial_ordering o) noexcept
Definition qcompare.h:201
static const partial_ordering unordered
Definition qcompare.h:71
friend constexpr bool operator>=(partial_ordering lhs, QtPrivate::CompareAgainstLiteralZero) noexcept
Definition qcompare.h:93
QT_WARNING_PUSH friend constexpr bool is_eq(partial_ordering o) noexcept
Definition qcompare.h:199
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:134
static const partial_ordering greater
Definition qcompare.h:70
static const partial_ordering less
Definition qcompare.h:68
\inmodule QtCore \title Classes and helpers for defining comparison operators \keyword qtcompare
Definition qcompare.h:400
friend constexpr bool operator<=(strong_ordering lhs, QtPrivate::CompareAgainstLiteralZero) noexcept
Definition qcompare.h:425
friend constexpr bool is_gt(strong_ordering o) noexcept
Definition qcompare.h:583
QT_WARNING_PUSH friend constexpr bool is_eq(strong_ordering o) noexcept
Definition qcompare.h:579
friend constexpr bool operator!=(strong_ordering lhs, QtPrivate::CompareAgainstLiteralZero) noexcept
Definition qcompare.h:417
friend constexpr bool operator<(strong_ordering lhs, QtPrivate::CompareAgainstLiteralZero) noexcept
Definition qcompare.h:421
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:474
static const strong_ordering greater
Definition qcompare.h:405
friend constexpr bool operator==(strong_ordering lhs, partial_ordering rhs) noexcept
Definition qcompare.h:480
friend constexpr bool operator>(strong_ordering lhs, QtPrivate::CompareAgainstLiteralZero) noexcept
Definition qcompare.h:429
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
static const strong_ordering equal
Definition qcompare.h:404
friend constexpr bool operator!=(QtPrivate::CompareAgainstLiteralZero, strong_ordering rhs) noexcept
Definition qcompare.h:442
friend constexpr bool operator==(QtPrivate::CompareAgainstLiteralZero, strong_ordering rhs) noexcept
Definition qcompare.h:438
friend constexpr bool operator==(strong_ordering lhs, weak_ordering rhs) noexcept
Definition qcompare.h:492
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:477
friend constexpr bool operator>=(QtPrivate::CompareAgainstLiteralZero, strong_ordering rhs) noexcept
Definition qcompare.h:458
static const strong_ordering less
Definition qcompare.h:402
friend constexpr bool operator!=(strong_ordering lhs, weak_ordering rhs) noexcept
Definition qcompare.h:495
friend constexpr bool is_neq(strong_ordering o) noexcept
Definition qcompare.h:580
friend constexpr bool operator!=(strong_ordering lhs, partial_ordering rhs) noexcept
Definition qcompare.h:483
friend constexpr bool is_lteq(strong_ordering o) noexcept
Definition qcompare.h:582
friend constexpr bool operator==(strong_ordering lhs, QtPrivate::CompareAgainstLiteralZero) noexcept
Definition qcompare.h:413
static const strong_ordering equivalent
Definition qcompare.h:403
friend constexpr bool is_lt(strong_ordering o) noexcept
Definition qcompare.h:581
friend constexpr bool operator<=(QtPrivate::CompareAgainstLiteralZero, strong_ordering rhs) noexcept
Definition qcompare.h:450
friend constexpr bool operator==(weak_ordering lhs, strong_ordering rhs) noexcept
Definition qcompare.h:498
friend constexpr bool operator==(partial_ordering lhs, strong_ordering rhs) noexcept
Definition qcompare.h:486
friend constexpr bool is_gteq(strong_ordering o) noexcept
Definition qcompare.h:584
friend constexpr bool operator>=(strong_ordering lhs, QtPrivate::CompareAgainstLiteralZero) noexcept
Definition qcompare.h:433
\variable Qt::strong_ordering::less
Definition qcompare.h:221
friend constexpr bool is_lteq(weak_ordering o) noexcept
Definition qcompare.h:387
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:291
friend constexpr bool operator!=(weak_ordering lhs, QtPrivate::CompareAgainstLiteralZero) noexcept
Definition qcompare.h:234
QT_WARNING_PUSH friend constexpr bool is_eq(weak_ordering o) noexcept
Definition qcompare.h:384
static const weak_ordering less
Definition qcompare.h:223
friend constexpr bool operator<=(weak_ordering lhs, QtPrivate::CompareAgainstLiteralZero) noexcept
Definition qcompare.h:242
friend constexpr bool operator<(weak_ordering lhs, QtPrivate::CompareAgainstLiteralZero) noexcept
Definition qcompare.h:238
friend constexpr bool operator==(weak_ordering lhs, partial_ordering rhs) noexcept
Definition qcompare.h:297
friend constexpr bool is_gteq(weak_ordering o) noexcept
Definition qcompare.h:389
friend constexpr bool is_lt(weak_ordering o) noexcept
Definition qcompare.h:386
friend constexpr bool operator==(weak_ordering lhs, QtPrivate::CompareAgainstLiteralZero) noexcept
Definition qcompare.h:230
friend constexpr bool operator!=(QtPrivate::CompareAgainstLiteralZero, weak_ordering rhs) noexcept
Definition qcompare.h:259
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:294
friend constexpr bool is_gt(weak_ordering o) noexcept
Definition qcompare.h:388
friend constexpr bool operator>=(weak_ordering lhs, QtPrivate::CompareAgainstLiteralZero) noexcept
Definition qcompare.h:250
friend constexpr bool operator>=(QtPrivate::CompareAgainstLiteralZero, weak_ordering rhs) noexcept
Definition qcompare.h:275
friend constexpr bool is_neq(weak_ordering o) noexcept
Definition qcompare.h:385
static const weak_ordering greater
Definition qcompare.h:225
friend constexpr bool operator>(weak_ordering lhs, QtPrivate::CompareAgainstLiteralZero) noexcept
Definition qcompare.h:246
friend constexpr bool operator!=(weak_ordering lhs, partial_ordering rhs) noexcept
Definition qcompare.h:300
friend constexpr bool operator<=(QtPrivate::CompareAgainstLiteralZero, weak_ordering rhs) noexcept
Definition qcompare.h:267
friend constexpr bool operator!=(partial_ordering lhs, weak_ordering rhs) noexcept
Definition qcompare.h:306
friend constexpr bool operator==(partial_ordering lhs, weak_ordering rhs) noexcept
Definition qcompare.h:303
static const weak_ordering equivalent
Definition qcompare.h:224
friend constexpr bool operator==(QtPrivate::CompareAgainstLiteralZero, weak_ordering rhs) noexcept
Definition qcompare.h:255
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:628
constexpr bool hasCompareThreeWay
Definition qcompare.h:614
\macro QT_NO_KEYWORDS >
LegacyUncomparable
Definition qcompare.h:672
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:652
#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