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.cpp
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#include "qcompare.h"
6
7#ifdef __cpp_lib_bit_cast
8#include <bit>
9#endif
10
12
13#ifdef __cpp_lib_three_way_comparison
14#ifdef __cpp_lib_bit_cast
15#define CHECK(type, flag)
16 static_assert(std::bit_cast<Qt:: type ## _ordering>(std:: type ## _ordering:: flag)
17 == Qt:: type ## _ordering :: flag);
18 static_assert(std::bit_cast<std:: type ## _ordering>(Qt:: type ## _ordering:: flag)
19 == std:: type ## _ordering :: flag)
20 /* end */
21#if !defined(Q_STL_LIBSTDCPP) || QT_VERSION >= QT_VERSION_CHECK(7, 0, 0)
22CHECK(partial, unordered);
23#endif
24CHECK(partial, less);
25CHECK(partial, greater);
26CHECK(partial, equivalent);
27CHECK(weak, less);
28CHECK(weak, greater);
29CHECK(weak, equivalent);
30CHECK(strong, less);
31CHECK(strong, greater);
32CHECK(strong, equal);
33CHECK(strong, equivalent);
34#undef CHECK
35#endif // __cpp_lib_bit_cast
36#endif //__cpp_lib_three_way_comparison
37
38
39/*!
40 \page comparison-types.html overview
41 \title Comparison types overview
42 \keyword three-way comparison
43 \inmodule QtCore
44 \sa Qt::strong_ordering, Qt::weak_ordering, Qt::partial_ordering
45
46 \note Qt's comparison types provide functionality equivalent to their C++20
47 standard counterparts. The only reason why they exist is to make the
48 functionality available in C++17 builds, too. In a C++20 build, they
49 implicitly convert to and from the \c std types, making them fully
50 interchangeable. We therefore recommended that you prefer to use the C++
51 standard types in your code, if you can use C++20 in your projects already.
52 The Qt comparison types will be removed in Qt 7.
53
54 Qt provides several comparison types for a \l
55 {https://en.cppreference.com/w/cpp/language/operator_comparison#Three-way_comparison}
56 {three-way comparison}, which are comparable against a \e {zero literal}.
57 To use these comparison types, you need to include the \c <QtCompare>
58 header. These comparison types are categorized based on their \e order,
59 which is a mathematical concept used to describe the arrangement or ranking
60 of elements. The following categories are provided:
61
62 \table 100 %
63 \header
64 \li C++ type
65 \li Qt type
66 \li strict
67 \li total
68 \li Example
69 \row
70 \li \l {https://en.cppreference.com/w/cpp/utility/compare/strong_ordering}
71 {std::strong_ordering}
72 \li Qt::strong_ordering
73 \li yes
74 \li yes
75 \li integral types, case-sensitive strings, QDate, QTime
76 \row
77 \li \l {https://en.cppreference.com/w/cpp/utility/compare/weak_ordering}
78 {std::weak_ordering}
79 \li Qt::weak_ordering
80 \li no
81 \li yes
82 \li case-insensitive strings, unordered associative containers, QDateTime
83 \row
84 \li \l {https://en.cppreference.com/w/cpp/utility/compare/partial_ordering}
85 {std::partial_ordering}
86 \li Qt::partial_ordering
87 \li no
88 \li no
89 \li floating-point types, QOperatingSystemVersion, QVariant
90 \endtable
91
92 The strongest comparison type, Qt::strong_ordering, represents a strict total
93 order. It requires that any two elements be comparable in a way where
94 equality implies substitutability. In other words, equivalent values
95 cannot be distinguished from each other. A practical example would be the
96 case-sensitive comparison of two strings. For instance, when comparing the
97 values \c "Qt" and \c "Qt" the result would be \l Qt::strong_ordering::equal.
98 Both values are indistinguishable and all deterministic operations performed
99 on these values would yield identical results.
100
101 Qt::weak_ordering represents a total order. While any two values still need to
102 be comparable, equivalent values may be distinguishable. The canonical
103 example here would be the case-insensitive comparison of two strings. For
104 instance, when comparing the values \c "Qt" and \c "qt" both hold the same
105 letters but with different representations. This comparison would
106 result in \l Qt::weak_ordering::equivalent, but not actually \c Equal.
107 Another example would be QDateTime, which can represent a given instant in
108 time in terms of local time or any other time-zone, including UTC. The
109 different representations are equivalent, even though their \c time() and
110 sometimes \c date() may differ.
111
112 Qt::partial_ordering represents, as the name implies, a partial ordering. It
113 allows for the possibility that two values may not be comparable, resulting
114 in an \l {Qt::partial_ordering::}{unordered} state. Additionally, equivalent
115 values may still be distinguishable. A practical example would be the
116 comparison of two floating-point values, comparing with NaN (Not-a-Number)
117 would yield an unordered result. Another example is the comparison of two
118 QOperatingSystemVersion objects. Comparing versions of two different
119 operating systems, such as Android and Windows, would produce an unordered
120 result.
121
122 Utilizing these comparison types enhances the expressiveness of defining
123 relations. Furthermore, they serve as a fundamental component for
124 implementing three-way comparison with C++17.
125*/
126
127/*!
128 \headerfile <QtCompare>
129 \inmodule QtCore
130 \title Classes and helpers for defining comparison operators
131 \keyword qtcompare
132
133 \brief The <QtCompare> header file defines \c {Qt::*_ordering} types and helper
134 macros for defining comparison operators.
135
136 This header introduces the \l Qt::partial_ordering, \l Qt::weak_ordering, and
137 \l Qt::strong_ordering types, which are Qt's C++17 backports of
138 \c {std::*_ordering} types.
139
140 This header also contains functions for implementing three-way comparison
141 in C++17.
142
143 The \c {Qt::compareThreeWay()} function overloads provide three-way
144 comparison for built-in C++ types.
145
146 The \l qCompareThreeWay() template serves as a generic three-way comparison
147 implementation. It relies on \c {Qt::compareThreeWay()} and free
148 \c {compareThreeWay()} functions in its implementation.
149*/
150
151/*!
152 \class Qt::strong_ordering
153 \inmodule QtCore
154 \inheaderfile QtCompare
155 \brief Qt::strong_ordering represents a comparison where equivalent values are
156 indistinguishable.
157 \sa Qt::weak_ordering, Qt::partial_ordering, {Comparison types overview}
158 \since 6.7
159
160 A value of type Qt::strong_ordering is typically returned from a three-way
161 comparison function. Such a function compares two objects and establishes
162 how they are ordered. It uses this return type to indicate that the ordering
163 is strict; that is, the function establishes a well-defined total order.
164
165 Qt::strong_ordering has four values, represented by the following symbolic
166 constants:
167
168 \list
169 \li \l less represents that the left operand is less than the right;
170 \li \l equal represents that the left operand is equivalent to the right;
171 \li \l equivalent is an alias for \c equal;
172 \li \l greater represents that the left operand is greater than the right.
173 \endlist
174
175 Qt::strong_ordering is idiomatically used by comparing an instance against a
176 literal zero, for instance like this:
177
178 \code
179
180 // given a, b, c, d as objects of some type that allows for a 3-way compare,
181 // and a compare function declared as follows:
182
183 Qt::strong_ordering compare(T lhs, T rhs); // defined out-of-line
184 ~~~
185
186 Qt::strong_ordering result = compare(a, b);
187 if (result < 0) {
188 // a is less than b
189 }
190
191 if (compare(c, d) >= 0) {
192 // c is greater than or equal to d
193 }
194
195 \endcode
196*/
197
198/*!
199 \fn Qt::strong_ordering::operator Qt::partial_ordering() const
200
201 Converts this Qt::strong_ordering value to a Qt::partial_ordering object using the
202 following rules:
203
204 \list
205 \li \l less converts to \l {Qt::partial_ordering::less}.
206 \li \l equivalent converts to \l {Qt::partial_ordering::equivalent}.
207 \li \l equal converts to \l {Qt::partial_ordering::equivalent}.
208 \li \l greater converts to \l {Qt::partial_ordering::greater}.
209 \endlist
210*/
211
212/*!
213 \fn Qt::strong_ordering::operator Qt::weak_ordering() const
214
215 Converts this Qt::strong_ordering value to a Qt::weak_ordering object using the
216 following rules:
217
218 \list
219 \li \l less converts to \l {Qt::weak_ordering::less}.
220 \li \l equivalent converts to \l {Qt::weak_ordering::equivalent}.
221 \li \l equal converts to \l {Qt::weak_ordering::equivalent}.
222 \li \l greater converts to \l {Qt::weak_ordering::greater}.
223 \endlist
224*/
225
226/*!
227 \fn Qt::strong_ordering::strong_ordering(std::strong_ordering stdorder)
228
229 Constructs a Qt::strong_ordering object from \a stdorder using the following rules:
230
231 \list
232 \li std::strong_ordering::less converts to \l less.
233 \li std::strong_ordering::equivalent converts to \l equivalent.
234 \li std::strong_ordering::equal converts to \l equal.
235 \li std::strong_ordering::greater converts to \l greater.
236 \endlist
237*/
238
239/*!
240 \fn Qt::strong_ordering::operator std::strong_ordering() const
241
242 Converts this Qt::strong_ordering value to a std::strong_ordering object using
243 the following rules:
244
245 \list
246 \li \l less converts to std::strong_ordering::less.
247 \li \l equivalent converts to std::strong_ordering::equivalent.
248 \li \l equal converts to std::strong_ordering::equal.
249 \li \l greater converts to std::strong_ordering::greater.
250 \endlist
251*/
252
253/*!
254 \fn bool Qt::strong_ordering::operator==(Qt::strong_ordering lhs, Qt::strong_ordering rhs)
255
256 Returns true if \a lhs and \a rhs represent the same result;
257 otherwise, returns false.
258*/
259
260/*!
261 \fn bool Qt::strong_ordering::operator!=(Qt::strong_ordering lhs, Qt::strong_ordering rhs)
262
263 Returns true if \a lhs and \a rhs represent different results;
264 otherwise, returns true.
265*/
266
267/*!
268 \internal
269 \relates Qt::strong_ordering
270 \fn bool operator==(Qt::strong_ordering lhs, QtPrivate::CompareAgainstLiteralZero)
271 \fn bool operator!=(Qt::strong_ordering lhs, QtPrivate::CompareAgainstLiteralZero)
272 \fn bool operator< (Qt::strong_ordering lhs, QtPrivate::CompareAgainstLiteralZero)
273 \fn bool operator<=(Qt::strong_ordering lhs, QtPrivate::CompareAgainstLiteralZero)
274 \fn bool operator> (Qt::strong_ordering lhs, QtPrivate::CompareAgainstLiteralZero)
275 \fn bool operator>=(Qt::strong_ordering lhs, QtPrivate::CompareAgainstLiteralZero)
276
277 \fn bool operator==(QtPrivate::CompareAgainstLiteralZero, Qt::strong_ordering rhs)
278 \fn bool operator!=(QtPrivate::CompareAgainstLiteralZero, Qt::strong_ordering rhs)
279 \fn bool operator< (QtPrivate::CompareAgainstLiteralZero, Qt::strong_ordering rhs)
280 \fn bool operator<=(QtPrivate::CompareAgainstLiteralZero, Qt::strong_ordering rhs)
281 \fn bool operator> (QtPrivate::CompareAgainstLiteralZero, Qt::strong_ordering rhs)
282 \fn bool operator>=(QtPrivate::CompareAgainstLiteralZero, Qt::strong_ordering rhs)
283*/
284
285/*!
286 \fn Qt::strong_ordering::is_eq (Qt::strong_ordering o)
287 \fn Qt::strong_ordering::is_neq (Qt::strong_ordering o)
288 \fn Qt::strong_ordering::is_lt (Qt::strong_ordering o)
289 \fn Qt::strong_ordering::is_lteq(Qt::strong_ordering o)
290 \fn Qt::strong_ordering::is_gt (Qt::strong_ordering o)
291 \fn Qt::strong_ordering::is_gteq(Qt::strong_ordering o)
292
293//! [is_eq_table]
294 Converts \a o into the result of one of the six relational operators:
295 \table
296 \header \li Function \li Operation
297 \row \li \c{is_eq} \li \a o \c{== 0}
298 \row \li \c{is_neq} \li \a o \c{!= 0}
299 \row \li \c{is_lt} \li \a o \c{< 0}
300 \row \li \c{is_lteq} \li \a o \c{<= 0}
301 \row \li \c{is_gt} \li \a o \c{> 0}
302 \row \li \c{is_gteq} \li \a o \c{>= 0}
303 \endtable
304//! [is_eq_table]
305
306 These functions are provided for compatibility with \c{std::strong_ordering}.
307*/
308
309/*!
310 \variable Qt::strong_ordering::less
311
312 Represents the result of a comparison where the left operand is less
313 than the right operand.
314*/
315
316/*!
317 \variable Qt::strong_ordering::equivalent
318
319 Represents the result of a comparison where the left operand is equal
320 to the right operand. Same as \l {Qt::strong_ordering::equal}.
321*/
322
323/*!
324 \variable Qt::strong_ordering::equal
325
326 Represents the result of a comparison where the left operand is equal
327 to the right operand. Same as \l {Qt::strong_ordering::equivalent}.
328*/
329
330/*!
331 \variable Qt::strong_ordering::greater
332
333 Represents the result of a comparison where the left operand is greater
334 than the right operand.
335*/
336
337/*!
338 \class Qt::weak_ordering
339 \inmodule QtCore
340 \inheaderfile QtCompare
341 \brief Qt::weak_ordering represents a comparison where equivalent values are
342 still distinguishable.
343 \sa Qt::strong_ordering, Qt::partial_ordering, {Comparison types overview}
344 \since 6.7
345
346 A value of type Qt::weak_ordering is typically returned from a three-way
347 comparison function. Such a function compares two objects and establishes
348 how they are ordered. It uses this return type to indicate that the ordering
349 is weak; that is, equivalent values may be distinguishable.
350
351 Qt::weak_ordering has three values, represented by the following symbolic
352 constants:
353
354 \list
355 \li \l less represents that the left operand is less than the right;
356 \li \l equivalent represents that the left operand is equivalent to the
357 right;
358 \li \l greater represents that the left operand is greater than the right,
359 \endlist
360
361 Qt::weak_ordering is idiomatically used by comparing an instance against a
362 literal zero, for instance like this:
363
364 \code
365
366 // given a, b, c, d as objects of some type that allows for a 3-way compare,
367 // and a compare function declared as follows:
368
369 Qt::weak_ordering compare(T lhs, T rhs); // defined out-of-line
370 ~~~
371
372 Qt::weak_ordering result = compare(a, b);
373 if (result < 0) {
374 // a is less than b
375 }
376
377 if (compare(c, d) >= 0) {
378 // c is greater than or equivalent to d
379 }
380
381 \endcode
382*/
383
384/*!
385 \fn Qt::weak_ordering::operator Qt::partial_ordering() const
386
387 Converts this Qt::weak_ordering value to a Qt::partial_ordering object using the
388 following rules:
389
390 \list
391 \li \l less converts to \l {Qt::partial_ordering::less}.
392 \li \l equivalent converts to \l {Qt::partial_ordering::equivalent}.
393 \li \l greater converts to \l {Qt::partial_ordering::greater}.
394 \endlist
395*/
396
397/*!
398 \fn Qt::weak_ordering::weak_ordering(std::weak_ordering stdorder)
399
400 Constructs a Qt::weak_ordering object from \a stdorder using the following rules:
401
402 \list
403 \li std::weak_ordering::less converts to \l less.
404 \li std::weak_ordering::equivalent converts to \l equivalent.
405 \li std::weak_ordering::greater converts to \l greater.
406 \endlist
407*/
408
409/*!
410 \fn Qt::weak_ordering::operator std::weak_ordering() const
411
412 Converts this Qt::weak_ordering value to a std::weak_ordering object using
413 the following rules:
414
415 \list
416 \li \l less converts to std::weak_ordering::less.
417 \li \l equivalent converts to std::weak_ordering::equivalent.
418 \li \l greater converts to std::weak_ordering::greater.
419 \endlist
420*/
421
422/*!
423 \fn bool Qt::weak_ordering::operator==(Qt::weak_ordering lhs, Qt::weak_ordering rhs)
424
425 Return true if \a lhs and \a rhs represent the same result;
426 otherwise, returns false.
427*/
428
429/*!
430 \fn bool Qt::weak_ordering::operator!=(Qt::weak_ordering lhs, Qt::weak_ordering rhs)
431
432 Return true if \a lhs and \a rhs represent different results;
433 otherwise, returns true.
434*/
435
436/*!
437 \internal
438 \relates Qt::weak_ordering
439 \fn bool operator==(Qt::weak_ordering lhs, QtPrivate::CompareAgainstLiteralZero)
440 \fn bool operator!=(Qt::weak_ordering lhs, QtPrivate::CompareAgainstLiteralZero)
441 \fn bool operator< (Qt::weak_ordering lhs, QtPrivate::CompareAgainstLiteralZero)
442 \fn bool operator<=(Qt::weak_ordering lhs, QtPrivate::CompareAgainstLiteralZero)
443 \fn bool operator> (Qt::weak_ordering lhs, QtPrivate::CompareAgainstLiteralZero)
444 \fn bool operator>=(Qt::weak_ordering lhs, QtPrivate::CompareAgainstLiteralZero)
445
446 \fn bool operator==(QtPrivate::CompareAgainstLiteralZero, Qt::weak_ordering rhs)
447 \fn bool operator!=(QtPrivate::CompareAgainstLiteralZero, Qt::weak_ordering rhs)
448 \fn bool operator< (QtPrivate::CompareAgainstLiteralZero, Qt::weak_ordering rhs)
449 \fn bool operator<=(QtPrivate::CompareAgainstLiteralZero, Qt::weak_ordering rhs)
450 \fn bool operator> (QtPrivate::CompareAgainstLiteralZero, Qt::weak_ordering rhs)
451 \fn bool operator>=(QtPrivate::CompareAgainstLiteralZero, Qt::weak_ordering rhs)
452*/
453
454/*!
455 \fn Qt::weak_ordering::is_eq (Qt::weak_ordering o)
456 \fn Qt::weak_ordering::is_neq (Qt::weak_ordering o)
457 \fn Qt::weak_ordering::is_lt (Qt::weak_ordering o)
458 \fn Qt::weak_ordering::is_lteq(Qt::weak_ordering o)
459 \fn Qt::weak_ordering::is_gt (Qt::weak_ordering o)
460 \fn Qt::weak_ordering::is_gteq(Qt::weak_ordering o)
461
462 \include qcompare.cpp is_eq_table
463
464 These functions are provided for compatibility with \c{std::weak_ordering}.
465*/
466
467/*!
468 \variable Qt::weak_ordering::less
469
470 Represents the result of a comparison where the left operand is less than
471 the right operand.
472*/
473
474/*!
475 \variable Qt::weak_ordering::equivalent
476
477 Represents the result of a comparison where the left operand is equivalent
478 to the right operand.
479*/
480
481/*!
482 \variable Qt::weak_ordering::greater
483
484 Represents the result of a comparison where the left operand is greater
485 than the right operand.
486*/
487
488/*!
489 \class Qt::partial_ordering
490 \inmodule QtCore
491 \inheaderfile QtCompare
492 \brief Qt::partial_ordering represents the result of a comparison that allows
493 for unordered results.
494 \sa Qt::strong_ordering, Qt::weak_ordering, {Comparison types overview}
495 \since 6.7
496
497 A value of type Qt::partial_ordering is typically returned from a
498 three-way comparison function. Such a function compares two objects,
499 establishing whether they are ordered and, if so, their ordering. It uses
500 this return type to indicate that the ordering is partial; that is, not all
501 pairs of values are ordered.
502
503 Qt::partial_ordering has four values, represented by the following symbolic
504 constants:
505
506 \list
507 \li \l less represents that the left operand is less than the right;
508 \li \l equivalent represents that the two operands are equivalent;
509 \li \l greater represents that the left operand is greater than the right;
510 \li \l unordered represents that the two operands are \e {not ordered}.
511 \endlist
512
513 Qt::partial_ordering is idiomatically used by comparing an instance
514 against a literal zero, for instance like this:
515
516 \code
517
518 // given a, b, c, d as objects of some type that allows for a 3-way compare,
519 // and a compare function declared as follows:
520
521 Qt::partial_ordering compare(T lhs, T rhs); // defined out-of-line
522 ~~~
523
524 Qt::partial_ordering result = compare(a, b);
525 if (result < 0) {
526 // a is less than b
527 }
528
529 if (compare(c, d) >= 0) {
530 // c is greater than or equal to d
531 }
532
533 \endcode
534
535 Comparing Qt::partial_ordering::unordered against literal 0 always returns
536 a \c false result.
537*/
538
539/*!
540 \fn Qt::partial_ordering::partial_ordering(std::partial_ordering stdorder)
541
542 Constructs a Qt::partial_ordering object from \a stdorder using the following
543 rules:
544
545 \list
546 \li std::partial_ordering::less converts to \l less.
547 \li std::partial_ordering::equivalent converts to \l equivalent.
548 \li std::partial_ordering::greater converts to \l greater.
549 \li std::partial_ordering::unordered converts to \l unordered
550 \endlist
551*/
552
553/*!
554 \fn Qt::partial_ordering::operator std::partial_ordering() const
555
556 Converts this Qt::partial_ordering value to a std::partial_ordering object using
557 the following rules:
558
559 \list
560 \li \l less converts to std::partial_ordering::less.
561 \li \l equivalent converts to std::partial_ordering::equivalent.
562 \li \l greater converts to std::partial_ordering::greater.
563 \li \l unordered converts to std::partial_ordering::unordered.
564 \endlist
565*/
566
567/*!
568 \fn bool Qt::partial_ordering::operator==(Qt::partial_ordering lhs, Qt::partial_ordering rhs)
569
570 Return true if \a lhs and \a rhs represent the same result;
571 otherwise, returns false.
572*/
573
574/*!
575 \fn bool Qt::partial_ordering::operator!=(Qt::partial_ordering lhs, Qt::partial_ordering rhs)
576
577 Return true if \a lhs and \a rhs represent different results;
578 otherwise, returns true.
579*/
580
581/*!
582 \internal
583 \relates Qt::partial_ordering
584 \fn bool operator==(Qt::partial_ordering lhs, QtPrivate::CompareAgainstLiteralZero)
585 \fn bool operator!=(Qt::partial_ordering lhs, QtPrivate::CompareAgainstLiteralZero)
586 \fn bool operator< (Qt::partial_ordering lhs, QtPrivate::CompareAgainstLiteralZero)
587 \fn bool operator<=(Qt::partial_ordering lhs, QtPrivate::CompareAgainstLiteralZero)
588 \fn bool operator> (Qt::partial_ordering lhs, QtPrivate::CompareAgainstLiteralZero)
589 \fn bool operator>=(Qt::partial_ordering lhs, QtPrivate::CompareAgainstLiteralZero)
590
591 \fn bool operator==(QtPrivate::CompareAgainstLiteralZero, Qt::partial_ordering rhs)
592 \fn bool operator!=(QtPrivate::CompareAgainstLiteralZero, Qt::partial_ordering rhs)
593 \fn bool operator< (QtPrivate::CompareAgainstLiteralZero, Qt::partial_ordering rhs)
594 \fn bool operator<=(QtPrivate::CompareAgainstLiteralZero, Qt::partial_ordering rhs)
595 \fn bool operator> (QtPrivate::CompareAgainstLiteralZero, Qt::partial_ordering rhs)
596 \fn bool operator>=(QtPrivate::CompareAgainstLiteralZero, Qt::partial_ordering rhs)
597*/
598
599/*!
600 \fn Qt::partial_ordering::is_eq (Qt::partial_ordering o)
601 \fn Qt::partial_ordering::is_neq (Qt::partial_ordering o)
602 \fn Qt::partial_ordering::is_lt (Qt::partial_ordering o)
603 \fn Qt::partial_ordering::is_lteq(Qt::partial_ordering o)
604 \fn Qt::partial_ordering::is_gt (Qt::partial_ordering o)
605 \fn Qt::partial_ordering::is_gteq(Qt::partial_ordering o)
606
607 \include qcompare.cpp is_eq_table
608
609 These functions are provided for compatibility with \c{std::partial_ordering}.
610*/
611
612/*!
613 \variable Qt::partial_ordering::less
614
615 Represents the result of a comparison where the left operand is less than
616 the right operand.
617*/
618
619/*!
620 \variable Qt::partial_ordering::equivalent
621
622 Represents the result of a comparison where the two operands are equivalent.
623*/
624
625/*!
626 \variable Qt::partial_ordering::greater
627
628 Represents the result of a comparison where the left operand is greater
629 than the right operand.
630*/
631
632/*!
633 \variable Qt::partial_ordering::unordered
634
635 Represents the result of a comparison where there is no ordering
636 relationship between the two operands.
637*/
638
639/*!
640 \class QPartialOrdering
641 \inmodule QtCore
642 \brief QPartialOrdering represents the result of a comparison that allows
643 for unordered results.
644 \sa Qt::strong_ordering, Qt::weak_ordering, {Comparison types overview}
645 \since 6.0
646
647 A value of type QPartialOrdering is typically returned from a
648 three-way comparison function. Such a function compares two objects,
649 establishing whether they are ordered and, if so, their ordering. It uses
650 this return type to indicate that the ordering is partial; that is, not all
651 pairs of values are ordered.
652
653 QPartialOrdering has four values, represented by the following symbolic
654 constants:
655
656 \list
657 \li \l less represents that the left operand is less than the right;
658 \li \l equivalent represents that the two operands are equivalent;
659 \li \l greater represents that the left operand is greater than the right;
660 \li \l unordered represents that the two operands are \e {not ordered}.
661 \endlist
662
663 QPartialOrdering is idiomatically used by comparing an instance
664 against a literal zero, for instance like this:
665
666 \code
667
668 // given a, b, c, d as objects of some type that allows for a 3-way compare,
669 // and a compare function declared as follows:
670
671 QPartialOrdering compare(T lhs, T rhs); // defined out-of-line
672 ~~~
673
674 QPartialOrdering result = compare(a, b);
675 if (result < 0) {
676 // a is less than b
677 }
678
679 if (compare(c, d) >= 0) {
680 // c is greater than or equal to d
681 }
682
683 \endcode
684
685 Comparing QPartialOrdering::unordered against literal 0 always returns
686 a \c false result.
687*/
688
689/*!
690 \fn QPartialOrdering::QPartialOrdering(std::partial_ordering stdorder)
691
692 Constructs a QPartialOrdering object from \a stdorder using the following
693 rules:
694
695 \list
696 \li std::partial_ordering::less converts to \l less.
697 \li std::partial_ordering::equivalent converts to \l equivalent.
698 \li std::partial_ordering::greater converts to \l greater.
699 \li std::partial_ordering::unordered converts to \l unordered
700 \endlist
701*/
702
703/*!
704 \fn QPartialOrdering::operator std::partial_ordering() const
705
706 Converts this QPartialOrdering value to a std::partial_ordering object using
707 the following rules:
708
709 \list
710 \li \l less converts to std::partial_ordering::less.
711 \li \l equivalent converts to std::partial_ordering::equivalent.
712 \li \l greater converts to std::partial_ordering::greater.
713 \li \l unordered converts to std::partial_ordering::unordered.
714 \endlist
715*/
716
717/*!
718 \fn bool QPartialOrdering::operator==(QPartialOrdering lhs, QPartialOrdering rhs)
719
720 Return true if \a lhs and \a rhs represent the same result;
721 otherwise, returns false.
722*/
723
724/*!
725 \fn bool QPartialOrdering::operator!=(QPartialOrdering lhs, QPartialOrdering rhs)
726
727 Return true if \a lhs and \a rhs represent different results;
728 otherwise, returns true.
729*/
730
731/*!
732 \internal
733 \relates QPartialOrdering
734 \fn bool operator==(QPartialOrdering lhs, QtPrivate::CompareAgainstLiteralZero)
735 \fn bool operator!=(QPartialOrdering lhs, QtPrivate::CompareAgainstLiteralZero)
736 \fn bool operator< (QPartialOrdering lhs, QtPrivate::CompareAgainstLiteralZero)
737 \fn bool operator<=(QPartialOrdering lhs, QtPrivate::CompareAgainstLiteralZero)
738 \fn bool operator> (QPartialOrdering lhs, QtPrivate::CompareAgainstLiteralZero)
739 \fn bool operator>=(QPartialOrdering lhs, QtPrivate::CompareAgainstLiteralZero)
740
741 \fn bool operator==(QtPrivate::CompareAgainstLiteralZero, QPartialOrdering rhs)
742 \fn bool operator!=(QtPrivate::CompareAgainstLiteralZero, QPartialOrdering rhs)
743 \fn bool operator< (QtPrivate::CompareAgainstLiteralZero, QPartialOrdering rhs)
744 \fn bool operator<=(QtPrivate::CompareAgainstLiteralZero, QPartialOrdering rhs)
745 \fn bool operator> (QtPrivate::CompareAgainstLiteralZero, QPartialOrdering rhs)
746 \fn bool operator>=(QtPrivate::CompareAgainstLiteralZero, QPartialOrdering rhs)
747*/
748
749/*!
750 \fn QPartialOrdering::is_eq (QPartialOrdering o)
751 \fn QPartialOrdering::is_neq (QPartialOrdering o)
752 \fn QPartialOrdering::is_lt (QPartialOrdering o)
753 \fn QPartialOrdering::is_lteq(QPartialOrdering o)
754 \fn QPartialOrdering::is_gt (QPartialOrdering o)
755 \fn QPartialOrdering::is_gteq(QPartialOrdering o)
756
757 \since 6.7
758 \include qcompare.cpp is_eq_table
759
760 These functions are provided for compatibility with \c{std::partial_ordering}.
761*/
762
763/*!
764 \variable QPartialOrdering::less
765
766 Represents the result of a comparison where the left operand is less than
767 the right operand.
768*/
769
770/*!
771 \variable QPartialOrdering::equivalent
772
773 Represents the result of a comparison where the two operands are equivalent.
774*/
775
776/*!
777 \variable QPartialOrdering::greater
778
779 Represents the result of a comparison where the left operand is greater
780 than the right operand.
781*/
782
783/*!
784 \variable QPartialOrdering::unordered
785
786 Represents the result of a comparison where there is no ordering
787 relationship between the two operands.
788*/
789
790/*!
791 \variable QPartialOrdering::Less
792
793 Represents the result of a comparison where the left operand is less than
794 the right operand.
795*/
796
797/*!
798 \variable QPartialOrdering::Equivalent
799
800 Represents the result of a comparison where the two operands are equivalent.
801*/
802
803/*!
804 \variable QPartialOrdering::Greater
805
806 Represents the result of a comparison where the left operand is greater
807 than the right operand.
808*/
809
810/*!
811 \variable QPartialOrdering::Unordered
812
813 Represents the result of a comparison where there is no ordering
814 relationship between the two operands.
815*/
816
817/*!
818 \internal
819 \macro Q_DECLARE_EQUALITY_COMPARABLE(Type)
820 \macro Q_DECLARE_EQUALITY_COMPARABLE(LeftType, RightType)
821 \macro Q_DECLARE_EQUALITY_COMPARABLE_LITERAL_TYPE(Type)
822 \macro Q_DECLARE_EQUALITY_COMPARABLE_LITERAL_TYPE(LeftType, RightType)
823 \since 6.7
824 \relates <QtCompare>
825
826 These macros are used to generate \c {operator==()} and \c {operator!=()}.
827
828 In C++17 mode, the mixed-type overloads also generate the reversed
829 operators.
830
831 In C++20 mode, only \c {operator==()} is defined. \c {operator!=()},
832 as well as the reversed operators for mixed-type comparison, are synthesized
833 by the compiler.
834
835 The operators are implemented in terms of a helper function
836 \c {comparesEqual()}.
837 It's the user's responsibility to declare and define this function.
838
839 Consider the following example of a comparison operators declaration:
840
841 \code
842 class MyClass {
843 ...
844 private:
845 friend bool comparesEqual(const MyClass &, const MyClass &) noexcept;
846 Q_DECLARE_EQUALITY_COMPARABLE(MyClass)
847 };
848 \endcode
849
850 When compiled with C++17, the macro will expand into the following code:
851
852 \code
853 friend bool operator==(const MyClass &lhs, const MyClass &rhs) noexcept
854 {
855 // inline implementation which uses comparesEqual()
856 }
857 friend bool operator!=(const MyClass &lhs, const MyClass &rhs) noexcept
858 {
859 // inline implementation which uses comparesEqual()
860 }
861 \endcode
862
863 When compiled with C++20, the macro will expand only into \c {operator==()}:
864
865 \code
866 friend bool operator==(const MyClass &lhs, const MyClass &rhs) noexcept
867 {
868 // inline implementation which uses comparesEqual()
869 }
870 \endcode
871
872 The \c {*_LITERAL_TYPE} versions of the macros are used to generate
873 \c constexpr operators. This means that the helper \c {comparesEqual()}
874 function must also be \c constexpr.
875
876 Consider the following example of a mixed-type \c constexpr comparison
877 operators declaration:
878
879 \code
880 class MyClass {
881 ...
882 private:
883 friend constexpr bool comparesEqual(const MyClass &, int) noexcept;
884 Q_DECLARE_EQUALITY_COMPARABLE_LITERAL_TYPE(MyClass, int)
885 };
886 \endcode
887
888 When compiled with C++17, the macro will expand into the following code:
889
890 \code
891 friend constexpr bool operator==(const MyClass &lhs, int rhs) noexcept
892 {
893 // inline implementation which uses comparesEqual()
894 }
895 friend constexpr bool operator!=(const MyClass &lhs, int rhs) noexcept
896 {
897 // inline implementation which uses comparesEqual()
898 }
899 friend constexpr bool operator==(int lhs, const MyClass &rhs) noexcept
900 {
901 // inline implementation which uses comparesEqual()
902 }
903 friend constexpr bool operator!=(int lhs, const MyClass &rhs) noexcept
904 {
905 // inline implementation which uses comparesEqual()
906 }
907 \endcode
908
909 When compiled with C++20, the macro expands only into \c {operator==()}:
910
911 \code
912 friend constexpr bool operator==(const MyClass &lhs, int rhs) noexcept
913 {
914 // inline implementation which uses comparesEqual()
915 }
916 \endcode
917
918//! [noexcept-requirement-desc]
919 These macros generate \c {noexcept} relational operators, and so they check
920 that the helper functions are \c {noexcept}.
921 Use the \c {_NON_NOEXCEPT} versions of the macros if the relational
922 operators of your class cannot be \c {noexcept}.
923//! [noexcept-requirement-desc]
924*/
925
926/*!
927 \internal
928 \macro Q_DECLARE_PARTIALLY_ORDERED(Type)
929 \macro Q_DECLARE_PARTIALLY_ORDERED(LeftType, RightType)
930 \macro Q_DECLARE_PARTIALLY_ORDERED_LITERAL_TYPE(Type)
931 \macro Q_DECLARE_PARTIALLY_ORDERED_LITERAL_TYPE(LeftType, RightType)
932 \since 6.7
933 \relates <QtCompare>
934
935 These macros are used to generate all six relational operators.
936 The operators represent
937 \l {https://en.cppreference.com/w/cpp/utility/compare/partial_ordering}
938 {partial ordering}.
939
940 These macros use respective overloads of the
941 \l {Q_DECLARE_EQUALITY_COMPARABLE} macro to generate \c {operator==()} and
942 \c {operator!=()}, and also generate the four relational operators:
943 \c {operator<()}, \c {operator>()}, \c {operator<=()}, and \c {operator>()}.
944
945 In C++17 mode, the mixed-type overloads also generate the reversed
946 operators.
947
948 In C++20 mode, only \c {operator==()} and \c {operator<=>()} are defined.
949 Other operators, as well as the reversed operators for mixed-type
950 comparison, are synthesized by the compiler.
951
952 The (in)equality operators are implemented in terms of a helper function
953 \c {comparesEqual()}. The other relational operators are implemented in
954 terms of a helper function \c {compareThreeWay()}.
955 The \c {compareThreeWay()} function \e must return an object of type
956 \l Qt::partial_ordering. It's the user's responsibility to declare and define
957 both helper functions.
958
959 Consider the following example of a comparison operators declaration:
960
961 \code
962 class MyClass {
963 ...
964 private:
965 friend bool comparesEqual(const MyClass &, const MyClass &) noexcept;
966 friend Qt::partial_ordering compareThreeWay(const MyClass &, const MyClass &) noexcept;
967 Q_DECLARE_PARTIALLY_ORDERED(MyClass)
968 };
969 \endcode
970
971 When compiled with C++17, the macro will expand into the following code:
972
973 \code
974 // operator==() and operator!=() are generated from
975 // Q_DECLARE_EQUALITY_COMPARABLE
976 friend bool operator<(const MyClass &lhs, const MyClass &rhs) noexcept
977 {
978 // inline implementation which uses compareThreeWay()
979 }
980 friend bool operator>(const MyClass &lhs, const MyClass &rhs) noexcept
981 {
982 // inline implementation which uses compareThreeWay()
983 }
984 friend bool operator<=(const MyClass &lhs, const MyClass &rhs) noexcept
985 {
986 // inline implementation which uses compareThreeWay()
987 }
988 friend bool operator>=(const MyClass &lhs, const MyClass &rhs) noexcept
989 {
990 // inline implementation which uses compareThreeWay()
991 }
992 \endcode
993
994 When compiled with C++20, the macro will expand into \c {operator==()} and
995 \c {operator<=>()}:
996
997 \code
998 friend bool operator==(const MyClass &lhs, const MyClass &rhs) noexcept
999 {
1000 // inline implementation which uses comparesEqual()
1001 }
1002 friend std::partial_ordering
1003 operator<=>(const MyClass &lhs, const MyClass &rhs) noexcept
1004 {
1005 // inline implementation which uses compareThreeWay()
1006 }
1007 \endcode
1008
1009 The \c {*_LITERAL_TYPE} versions of the macros are used to generate
1010 \c constexpr operators. This means that the helper \c {comparesEqual()} and
1011 \c {compareThreeWay()} functions must also be \c constexpr.
1012
1013 Consider the following example of a mixed-type \c constexpr comparison
1014 operators declaration:
1015
1016 \code
1017 class MyClass {
1018 ...
1019 private:
1020 friend constexpr bool comparesEqual(const MyClass &, int) noexcept;
1021 friend constexpr Qt::partial_ordering compareThreeWay(const MyClass &, int) noexcept;
1022 Q_DECLARE_PARTIALLY_ORDERED_LITERAL_TYPE(MyClass, int)
1023 };
1024 \endcode
1025
1026 When compiled with C++17, the macro will expand into the following code:
1027
1028 \code
1029 // operator==(), operator!=(), and their reversed versions are generated
1030 // from Q_DECLARE_EQUALITY_COMPARABLE_LITERAL_TYPE
1031 friend constexpr bool operator<(const MyClass &lhs, int rhs) noexcept
1032 {
1033 // inline implementation which uses compareThreeWay()
1034 }
1035 friend constexpr bool operator>(const MyClass &lhs, int rhs) noexcept
1036 {
1037 // inline implementation which uses compareThreeWay()
1038 }
1039 friend constexpr bool operator<=(const MyClass &lhs, int rhs) noexcept
1040 {
1041 // inline implementation which uses compareThreeWay()
1042 }
1043 friend constexpr bool operator>=(const MyClass &lhs, int rhs) noexcept
1044 {
1045 // inline implementation which uses compareThreeWay()
1046 }
1047 friend constexpr bool operator<(int lhs, const MyClass &rhs) noexcept
1048 {
1049 // inline implementation which uses compareThreeWay()
1050 }
1051 friend constexpr bool operator>(int lhs, const MyClass &rhs) noexcept
1052 {
1053 // inline implementation which uses compareThreeWay()
1054 }
1055 friend constexpr bool operator<=(int lhs, const MyClass &rhs) noexcept
1056 {
1057 // inline implementation which uses compareThreeWay()
1058 }
1059 friend constexpr bool operator>=(int lhs, const MyClass &rhs) noexcept
1060 {
1061 // inline implementation which uses compareThreeWay()
1062 }
1063 \endcode
1064
1065 When compiled with C++20, the macro will expand into \c {operator==()} and
1066 \c {operator<=>()}:
1067
1068 \code
1069 friend constexpr bool operator==(const MyClass &lhs, int rhs) noexcept
1070 {
1071 // inline implementation which uses comparesEqual()
1072 }
1073 friend constexpr std::partial_ordering
1074 operator<=>(const MyClass &lhs, int rhs) noexcept
1075 {
1076 // inline implementation which uses compareThreeWay()
1077 }
1078 \endcode
1079
1080 \include qcompare.cpp noexcept-requirement-desc
1081
1082 \sa Q_DECLARE_EQUALITY_COMPARABLE, Q_DECLARE_WEAKLY_ORDERED,
1083 Q_DECLARE_STRONGLY_ORDERED
1084*/
1085
1086/*!
1087 \internal
1088 \macro Q_DECLARE_WEAKLY_ORDERED(Type)
1089 \macro Q_DECLARE_WEAKLY_ORDERED(LeftType, RightType)
1090 \macro Q_DECLARE_WEAKLY_ORDERED_LITERAL_TYPE(Type)
1091 \macro Q_DECLARE_WEAKLY_ORDERED_LITERAL_TYPE(LeftType, RightType)
1092 \since 6.7
1093 \relates <QtCompare>
1094
1095 These macros behave similarly to the
1096 \l {Q_DECLARE_PARTIALLY_ORDERED} overloads, but represent
1097 \l {https://en.cppreference.com/w/cpp/utility/compare/weak_ordering}
1098 {weak ordering}.
1099
1100 The (in)equality operators are implemented in terms of a helper function
1101 \c {comparesEqual()}. The other relational operators are implemented in
1102 terms of a helper function \c {compareThreeWay()}.
1103 The \c {compareThreeWay()} function \e must return an object of type
1104 \l Qt::weak_ordering. It's the user's responsibility to declare and define both
1105 helper functions.
1106
1107 The \c {*_LITERAL_TYPE} overloads are used to generate \c constexpr
1108 operators. This means that the helper \c {comparesEqual()} and
1109 \c {compareThreeWay()} functions must also be \c constexpr.
1110
1111 \include qcompare.cpp noexcept-requirement-desc
1112
1113 See \l {Q_DECLARE_PARTIALLY_ORDERED} for usage examples.
1114
1115 \sa Q_DECLARE_PARTIALLY_ORDERED, Q_DECLARE_STRONGLY_ORDERED,
1116 Q_DECLARE_EQUALITY_COMPARABLE
1117*/
1118
1119/*!
1120 \internal
1121 \macro Q_DECLARE_STRONGLY_ORDERED(Type)
1122 \macro Q_DECLARE_STRONGLY_ORDERED(LeftType, RightType)
1123 \macro Q_DECLARE_STRONGLY_ORDERED_LITERAL_TYPE(Type)
1124 \macro Q_DECLARE_STRONGLY_ORDERED_LITERAL_TYPE(LeftType, RightType)
1125 \since 6.7
1126 \relates <QtCompare>
1127
1128 These macros behave similarly to the
1129 \l {Q_DECLARE_PARTIALLY_ORDERED} overloads, but represent
1130 \l {https://en.cppreference.com/w/cpp/utility/compare/strong_ordering}
1131 {strong ordering}.
1132
1133 The (in)equality operators are implemented in terms of a helper function
1134 \c {comparesEqual()}. The other relational operators are implemented in
1135 terms of a helper function \c {compareThreeWay()}.
1136 The \c {compareThreeWay()} function \e must return an object of type
1137 \l Qt::strong_ordering. It's the user's responsibility to declare and define
1138 both helper functions.
1139
1140 The \c {*_LITERAL_TYPE} overloads are used to generate \c constexpr
1141 operators. This means that the helper \c {comparesEqual()} and
1142 \c {compareThreeWay()} functions must also be \c constexpr.
1143
1144 \include qcompare.cpp noexcept-requirement-desc
1145
1146 See \l {Q_DECLARE_PARTIALLY_ORDERED} for usage examples.
1147
1148 \sa Q_DECLARE_PARTIALLY_ORDERED, Q_DECLARE_WEAKLY_ORDERED,
1149 Q_DECLARE_EQUALITY_COMPARABLE
1150*/
1151
1152/*!
1153 \internal
1154 \macro Q_DECLARE_EQUALITY_COMPARABLE(LeftType, RightType, Attributes...)
1155 \macro Q_DECLARE_EQUALITY_COMPARABLE_LITERAL_TYPE(LeftType, RightType, Attributes...)
1156 \macro Q_DECLARE_PARTIALLY_ORDERED(LeftType, RightType, Attributes...)
1157 \macro Q_DECLARE_PARTIALLY_ORDERED_LITERAL_TYPE(LeftType, RightType, Attributes...)
1158 \macro Q_DECLARE_WEAKLY_ORDERED(LeftType, RightType, Attributes...)
1159 \macro Q_DECLARE_WEAKLY_ORDERED_LITERAL_TYPE(LeftType, RightType, Attributes...)
1160 \macro Q_DECLARE_STRONGLY_ORDERED(LeftType, RightType, Attributes...)
1161 \macro Q_DECLARE_STRONGLY_ORDERED_LITERAL_TYPE(LeftType, RightType, Attributes...)
1162 \since 6.8
1163 \relates <QtCompare>
1164
1165 These macros behave like their two-argument versions, but allow
1166 specification of C++ attributes to add before every generated relational
1167 operator.
1168
1169 As an example, the \c Attributes parameter can be used in Qt to pass
1170 the \c QT_ASCII_CAST_WARN marco (whose expansion can mark the function as
1171 deprecated) when implementing comparison of encoding-aware string types
1172 with C-style strings or byte arrays.
1173
1174 Starting from Qt 6.9, \c Attributes becomes a variable argument, meaning
1175 that you can now specify more complex templates and constraints using
1176 these macros.
1177
1178 For example, equality-comparison of a custom type with any integral type
1179 can be implemented in the following way:
1180
1181 \code
1182 class MyClass {
1183 public:
1184 ...
1185 private:
1186 template <typename T, std::enable_if_t<std::is_integral_v<T>, bool> = true>
1187 friend constexpr bool comparesEqual(const MyClass &lhs, T rhs) noexcept
1188 { ... }
1189 Q_DECLARE_EQUALITY_COMPARABLE(MyClass, T,
1190 template <typename T,
1191 std::enable_if_t<std::is_integral_v<T>,
1192 bool> = true>)
1193 };
1194 \endcode
1195
1196 \note Bear in mind that a macro treats each comma (unless within
1197 parentheses) as starting a new argument; for example, the invocation above
1198 has five arguments. Due to implementation details, the macros cannot have
1199 more than nine arguments. If the constraint is too complicated, use an alias
1200 template to give it a self-explanatory name, and use this alias as an
1201 argument of the macro.
1202
1203 \include qcompare.cpp noexcept-requirement-desc
1204*/
1205
1206/*!
1207 \internal
1208 \macro Q_DECLARE_EQUALITY_COMPARABLE_NON_NOEXCEPT(Type)
1209 \macro Q_DECLARE_EQUALITY_COMPARABLE_NON_NOEXCEPT(LeftType, RightType)
1210 \macro Q_DECLARE_EQUALITY_COMPARABLE_NON_NOEXCEPT(LeftType, RightType, Attributes...)
1211 \macro Q_DECLARE_PARTIALLY_ORDERED_NON_NOEXCEPT(Type)
1212 \macro Q_DECLARE_PARTIALLY_ORDERED_NON_NOEXCEPT(LeftType, RightType)
1213 \macro Q_DECLARE_PARTIALLY_ORDERED_NON_NOEXCEPT(LeftType, RightType, Attributes...)
1214 \macro Q_DECLARE_WEAKLY_ORDERED_NON_NOEXCEPT(Type)
1215 \macro Q_DECLARE_WEAKLY_ORDERED_NON_NOEXCEPT(LeftType, RightType)
1216 \macro Q_DECLARE_WEAKLY_ORDERED_NON_NOEXCEPT(LeftType, RightType, Attributes...)
1217 \macro Q_DECLARE_STRONGLY_ORDERED_NON_NOEXCEPT(Type)
1218 \macro Q_DECLARE_STRONGLY_ORDERED_NON_NOEXCEPT(LeftType, RightType)
1219 \macro Q_DECLARE_STRONGLY_ORDERED_NON_NOEXCEPT(LeftType, RightType, Attributes...)
1220 \since 6.8
1221 \relates <QtCompare>
1222
1223 These macros behave like their versions without the \c {_NON_NOEXCEPT}
1224 suffix, but should be used when the relational operators cannot be
1225 \c {noexcept}.
1226
1227 Starting from Qt 6.9, \c Attributes becomes a variable argument.
1228*/
1229
1230/*!
1231 \internal
1232 \macro Q_DECLARE_ORDERED(Type)
1233 \macro Q_DECLARE_ORDERED(LeftType, RightType)
1234 \macro Q_DECLARE_ORDERED(LeftType, RightType, Attributes...)
1235 \macro Q_DECLARE_ORDERED_LITERAL_TYPE(Type)
1236 \macro Q_DECLARE_ORDERED_LITERAL_TYPE(LeftType, RightType)
1237 \macro Q_DECLARE_ORDERED_LITERAL_TYPE(LeftType, RightType, Attributes...)
1238 \macro Q_DECLARE_ORDERED_NON_NOEXCEPT(Type)
1239 \macro Q_DECLARE_ORDERED_NON_NOEXCEPT(LeftType, RightType)
1240 \macro Q_DECLARE_ORDERED_NON_NOEXCEPT(LeftType, RightType, Attributes...)
1241 \since 6.9
1242 \relates <QtCompare>
1243
1244 These macros behave similarly to the
1245 \c {Q_DECLARE_(PARTIALLY,WEAKLY,STRONGLY)_ORDERED} overloads, but represent
1246 any one of those three, using \c auto return type.
1247
1248 This is what you typically would use for template classes where
1249 the strength of the ordering depends on the template arguments.
1250 For example, if one of the template arguments is a floating-point
1251 type, the ordering would be \l {Qt::partial_ordering}, if they all
1252 are integral - \l {Qt::strong_ordering}.
1253
1254 \note It is better to use one of the explicit-strength macros in general, to
1255 communicate intent. Use these macros only when the stength actually does vary
1256 with template arguments.
1257
1258 The (in)equality operators are implemented in terms of a helper function
1259 \c {comparesEqual()}. The other relational operators are implemented in
1260 terms of a helper function \c {compareThreeWay()}.
1261 The \c {compareThreeWay()} function \e must return an object of an ordering
1262 type. It's the user's responsibility to declare and define both helper
1263 functions.
1264
1265 The \c {*_LITERAL_TYPE} overloads are used to generate \c constexpr
1266 operators. This means that the helper \c {comparesEqual()} and
1267 \c {compareThreeWay()} functions must also be \c constexpr.
1268
1269 See \l {Q_DECLARE_PARTIALLY_ORDERED} for usage examples.
1270
1271 By default, the generated operators are \c {noexcept}.
1272 Use the \c {*_NON_NOEXCEPT} overloads if the relational operators cannot be
1273 \c {noexcept}.
1274
1275 The three-argument versions of the macros allow specification of C++
1276 attributes to add before every generated relational operator.
1277 See \l {Q_DECLARE_EQUALITY_COMPARABLE(LeftType, RightType, Attributes...)}
1278 for more details and usage examples.
1279
1280 \sa Q_DECLARE_PARTIALLY_ORDERED, Q_DECLARE_WEAKLY_ORDERED,
1281 Q_DECLARE_STRONGLY_ORDERED, Q_DECLARE_EQUALITY_COMPARABLE
1282*/
1283
1284/*!
1285 \fn template <typename LeftInt, typename RightInt, Qt::if_integral<LeftInt> = true, Qt::if_integral<RightInt> = true> auto Qt::compareThreeWay(LeftInt lhs, RightInt rhs)
1286 \since 6.7
1287 \relates <QtCompare>
1288 \overload
1289
1290 Implements three-way comparison of integral types.
1291
1292 Returns \c {lhs <=> rhs}, provided \c LeftInt and \c RightInt are built-in
1293 integral types. Unlike \c {operator<=>()}, this function template is also
1294 available in C++17. See
1295 \l {https://en.cppreference.com/w/cpp/language/operator_comparison#Three-way_comparison}
1296 {cppreference} for more details.
1297
1298 This function can also be used in custom \c {compareThreeWay()} functions,
1299 when ordering members of a custom class represented by built-in types:
1300
1301 \code
1302 class MyClass {
1303 public:
1304 ...
1305 private:
1306 int value;
1307 ...
1308 friend Qt::strong_ordering
1309 compareThreeWay(const MyClass &lhs, const MyClass &rhs) noexcept
1310 { return Qt::compareThreeWay(lhs.value, rhs.value); }
1311 Q_DECLARE_STRONGLY_ORDERED(MyClass)
1312 };
1313 \endcode
1314
1315 Returns an instance of \l Qt::strong_ordering that represents the relation
1316 between \a lhs and \a rhs.
1317
1318 \constraints both
1319 \c LeftInt and \c RightInt are built-in integral types.
1320*/
1321
1322/*!
1323 \fn template <typename LeftFloat, typename RightFloat, Qt::if_floating_point<LeftFloat> = true, Qt::if_floating_point<RightFloat> = true> auto Qt::compareThreeWay(LeftFloat lhs, RightFloat rhs)
1324 \since 6.7
1325 \relates <QtCompare>
1326 \overload
1327
1328 Implements three-way comparison of floating point types.
1329
1330 Returns \c {lhs <=> rhs}, provided \c LeftFloat and \c RightFloat are
1331 built-in floating-point types. Unlike \c {operator<=>()}, this function
1332 template is also available in C++17. See
1333 \l {https://en.cppreference.com/w/cpp/language/operator_comparison#Three-way_comparison}
1334 {cppreference} for more details.
1335
1336 This function can also be used in custom \c {compareThreeWay()} functions,
1337 when ordering members of a custom class represented by built-in types:
1338
1339 \code
1340 class MyClass {
1341 public:
1342 ...
1343 private:
1344 double value;
1345 ...
1346 friend Qt::partial_ordering
1347 compareThreeWay(const MyClass &lhs, const MyClass &rhs) noexcept
1348 { return Qt::compareThreeWay(lhs.value, rhs.value); }
1349 Q_DECLARE_PARTIALLY_ORDERED(MyClass)
1350 };
1351 \endcode
1352
1353 Returns an instance of \l Qt::partial_ordering that represents the relation
1354 between \a lhs and \a rhs. If \a lhs or \a rhs is not a number (NaN),
1355 \l Qt::partial_ordering::unordered is returned.
1356
1357 \constraints both
1358 \c LeftFloat and \c RightFloat are built-in floating-point types.
1359*/
1360
1361/*!
1362 \fn template <typename IntType, typename FloatType, Qt::if_integral<IntType> = true, Qt::if_floating_point<FloatType> = true> auto Qt::compareThreeWay(IntType lhs, FloatType rhs)
1363 \since 6.7
1364 \relates <QtCompare>
1365 \overload
1366
1367 Implements three-way comparison of integral and floating point types.
1368
1369 This function converts \a lhs to \c FloatType and calls the overload for
1370 floating-point types.
1371
1372 Returns an instance of \l Qt::partial_ordering that represents the relation
1373 between \a lhs and \a rhs. If \a rhs is not a number (NaN),
1374 \l Qt::partial_ordering::unordered is returned.
1375
1376 \constraints \c IntType
1377 is a built-in integral type and \c FloatType is a built-in floating-point
1378 type.
1379*/
1380
1381/*!
1382 \fn template <typename FloatType, typename IntType, Qt::if_floating_point<FloatType> = true, Qt::if_integral<IntType> = true> auto Qt::compareThreeWay(FloatType lhs, IntType rhs)
1383 \since 6.7
1384 \relates <QtCompare>
1385 \overload
1386
1387 Implements three-way comparison of floating point and integral types.
1388
1389 This function converts \a rhs to \c FloatType and calls the overload for
1390 floating-point types.
1391
1392 Returns an instance of \l Qt::partial_ordering that represents the relation
1393 between \a lhs and \a rhs. If \a lhs is not a number (NaN),
1394 \l Qt::partial_ordering::unordered is returned.
1395
1396 \constraints \c FloatType
1397 is a built-in floating-point type and \c IntType is a built-in integral
1398 type.
1399*/
1400
1401#if QT_DEPRECATED_SINCE(6, 8)
1402/*!
1403 \fn template <typename LeftType, typename RightType, Qt::if_compatible_pointers<LeftType, RightType> = true> Qt::compareThreeWay(const LeftType *lhs, const RightType *rhs)
1404 \since 6.7
1405 \deprecated [6.8] Wrap the pointers into Qt::totally_ordered_wrapper and
1406 use the respective Qt::compareThreeWay() overload instead.
1407 \relates <QtCompare>
1408 \overload
1409
1410 Implements three-way comparison of pointers.
1411
1412 Returns an instance of \l Qt::strong_ordering that represents the relation
1413 between \a lhs and \a rhs.
1414
1415 \constraints \c LeftType and
1416 \c RightType are the same type, or base and derived types. It is also used
1417 to compare any pointer to \c {std::nullptr_t}.
1418*/
1419#endif // QT_DEPRECATED_SINCE(6, 8)
1420
1421/*!
1422 \fn template <class Enum, Qt::if_enum<Enum> = true> Qt::compareThreeWay(Enum lhs, Enum rhs)
1423 \since 6.7
1424 \relates <QtCompare>
1425 \overload
1426
1427 Implements three-way comparison of enum types.
1428
1429 This function converts \c Enum to its underlying type and calls the
1430 overload for integral types.
1431
1432 Returns an instance of \l Qt::strong_ordering that represents the relation
1433 between \a lhs and \a rhs.
1434
1435 \constraints \c Enum is an enum type.
1436*/
1437
1438/*!
1439 \fn template <typename T, typename U, Qt::if_compatible_pointers<T, U> = true> Qt::compareThreeWay(Qt::totally_ordered_wrapper<T*> lhs, Qt::totally_ordered_wrapper<U*> rhs)
1440 \since 6.8
1441 \relates <QtCompare>
1442 \overload
1443
1444 Implements three-way comparison of pointers that are wrapped into
1445 \l Qt::totally_ordered_wrapper. Uses
1446 \l {https://en.cppreference.com/w/cpp/language/operator_comparison#Pointer_total_order}
1447 {strict total order over pointers} when doing the comparison.
1448
1449 Returns an instance of \l Qt::strong_ordering that represents the relation
1450 between \a lhs and \a rhs.
1451
1452 \constraints \c T and \c U are the same type, or base and derived types.
1453*/
1454
1455/*!
1456 \fn template <typename T, typename U, Qt::if_compatible_pointers<T, U> = true> Qt::compareThreeWay(Qt::totally_ordered_wrapper<T*> lhs, U *rhs)
1457 \since 6.8
1458 \relates <QtCompare>
1459 \overload
1460
1461 Implements three-way comparison of a pointer wrapped into
1462 \l Qt::totally_ordered_wrapper with a normal pointer. Uses
1463 \l {https://en.cppreference.com/w/cpp/language/operator_comparison#Pointer_total_order}
1464 {strict total order over pointers} when doing the comparison.
1465
1466 Returns an instance of \l Qt::strong_ordering that represents the relation
1467 between \a lhs and \a rhs.
1468
1469 \constraints \c T and \c U are the same type, or base and derived types.
1470*/
1471
1472/*!
1473 \fn template <typename T, typename U, Qt::if_compatible_pointers<T, U> = true> Qt::compareThreeWay(U *lhs, Qt::totally_ordered_wrapper<T*> rhs)
1474 \since 6.8
1475 \relates <QtCompare>
1476 \overload
1477
1478 Implements three-way comparison of a normal pointer with a pointer wrapped
1479 into \l Qt::totally_ordered_wrapper. Uses
1480 \l {https://en.cppreference.com/w/cpp/language/operator_comparison#Pointer_total_order}
1481 {strict total order over pointers} when doing the comparison.
1482
1483 Returns an instance of \l Qt::strong_ordering that represents the relation
1484 between \a lhs and \a rhs.
1485
1486 \constraints \c T and \c U are the same type, or base and derived types.
1487*/
1488
1489/*!
1490 \fn template <typename T> Qt::compareThreeWay(Qt::totally_ordered_wrapper<T*> lhs, std::nullptr_t rhs)
1491 \since 6.8
1492 \relates <QtCompare>
1493 \overload
1494
1495 Implements three-way comparison of a pointer wrapped into
1496 \l Qt::totally_ordered_wrapper with \c {std::nullptr_t}.
1497
1498 Returns an instance of \l Qt::strong_ordering that represents the relation
1499 between \a lhs and \a rhs.
1500*/
1501
1502/*!
1503 \fn template <typename T> Qt::compareThreeWay(std::nullptr_t lhs, Qt::totally_ordered_wrapper<T*> rhs)
1504 \since 6.8
1505 \relates <QtCompare>
1506 \overload
1507
1508 Implements three-way comparison of \c {std::nullptr_t} with a pointer
1509 wrapped into \l Qt::totally_ordered_wrapper.
1510
1511 Returns an instance of \l Qt::strong_ordering that represents the relation
1512 between \a lhs and \a rhs.
1513*/
1514
1515/*!
1516 \fn template <typename LeftType, typename RightType> qCompareThreeWay(const LeftType &lhs, const RightType &rhs)
1517 \since 6.7
1518 \relates <QtCompare>
1519
1520 Performs the three-way comparison on \a lhs and \a rhs and returns one of
1521 the Qt ordering types as a result. This function is available for both
1522 C++17 and C++20.
1523
1524 The actual returned type depends on \c LeftType and \c RightType.
1525
1526 \note This function template is only available when \c {compareThreeWay()}
1527 is implemented for the \c {(LeftType, RightType)} pair or the reversed
1528 \c {(RightType, LeftType)} pair.
1529
1530 This method is equivalent to
1531
1532 \code
1533 using Qt::compareThreeWay;
1534 return compareThreeWay(lhs, rhs);
1535 \endcode
1536
1537 where \c {Qt::compareThreeWay} is the Qt implementation of three-way
1538 comparison for built-in types.
1539
1540 The free \c {compareThreeWay} functions should provide three-way comparison
1541 for custom types. The functions should return one of the Qt ordering types.
1542
1543 Qt provides \c {compareThreeWay} implementation for some of its types.
1544
1545 \note \b {Do not} re-implement \c {compareThreeWay()} for Qt types, as more
1546 Qt types will get support for it in future Qt releases.
1547
1548 Use this function primarly in generic code, when you know nothing about
1549 \c LeftType and \c RightType.
1550
1551 If you know the types, use
1552
1553 \list
1554 \li \c {Qt::compareThreeWay} for built-in types
1555 \li \c {compareThreeWay} for custom types
1556 \endlist
1557
1558 Use \c {operator<=>()} directly in code that will only be compiled with
1559 C++20 or later.
1560
1561 \sa Qt::partial_ordering, Qt::weak_ordering, Qt::strong_ordering
1562*/
1563
1564/*!
1565 \fn template <typename InputIt1, typename InputIt2> QtOrderingPrivate::lexicographicalCompareThreeWay(InputIt1 first1, InputIt1 last1, InputIt2 first2, InputIt2 last2)
1566 \internal
1567 \relates <QtCompare>
1568
1569 \brief Three-way lexicographic comparison of ranges.
1570
1571 Checks how the range [ \a first1, \a last1 ) compares to the second range
1572 [ \a first2, \a last2 ) and produces a result of the strongest applicable
1573 category type.
1574
1575 This function can only be used if \c InputIt1::value_type and
1576 \c InputIt2::value_type types provide a \c {compareThreeWay()} helper method
1577 that returns one of the Qt ordering types.
1578
1579 \sa {Comparison types overview}
1580*/
1581
1582/*!
1583 \fn template <typename InputIt1, typename InputIt2, typename Comparator> QtOrderingPrivate::lexicographicalCompareThreeWay(InputIt1 first1, InputIt1 last1, InputIt2 first2, InputIt2 last2, Comparator cmp)
1584 \internal
1585 \relates <QtCompare>
1586 \overload
1587
1588 This overload takes a custom \c Comparator that is used to do the comparison.
1589 The comparator should have the following signature:
1590
1591 \badcode
1592 OrderingType cmp(const InputIt1::value_type &lhs, const InputIt2::value_type &rhs);
1593 \endcode
1594
1595 where \c OrderingType is one of the Qt ordering types.
1596
1597 \sa {Comparison types overview}
1598*/
1599
1600/*!
1601 \class Qt::totally_ordered_wrapper
1602 \inmodule QtCore
1603 \inheaderfile QtCompare
1604 \brief Qt::totally_ordered_wrapper is a wrapper type that provides strict
1605 total order for the wrapped types.
1606 \since 6.8
1607
1608 Qt::totally_ordered_wrapper<P> is a template class where \a P specifies
1609 the type to wrap.
1610
1611 One of its primary usecases is to prevent \e {Undefined Behavior} (UB) when
1612 comparing pointers.
1613
1614 Consider the following simple class:
1615
1616 \code
1617 template <typename T>
1618 struct PointerWrapperBad {
1619 int val;
1620 T *ptr;
1621 };
1622 \endcode
1623
1624 Lexicographical comparison of the two instances of the \c PointerWrapperBad
1625 type would result in UB, because it will call \c {operator<()} or
1626 \c {operator<=>()} on the \c {ptr} members.
1627
1628 To fix it, use the new wrapper type:
1629
1630 \code
1631 template <typename T>
1632 struct PointerWrapperGood {
1633 int val;
1634 Qt::totally_ordered_wrapper<T *> ptr;
1635
1636 friend bool
1637 operator==(PointerWrapperGood lhs, PointerWrapperGood rhs) noexcept = default;
1638 friend auto
1639 operator<=>(PointerWrapperGood lhs, PointerWrapperGood rhs) noexecpt = default;
1640 };
1641 \endcode
1642
1643 The \c {operator<()} and (if available) \c {operator<=>()} operators for
1644 the \c {Qt::totally_ordered_wrapper} type use the
1645 \l {https://en.cppreference.com/w/cpp/utility/functional/less}{std::less}
1646 and \l {https://en.cppreference.com/w/cpp/utility/compare/compare_three_way}
1647 {std::compare_three_way} function objects respectively, providing
1648 \l {https://en.cppreference.com/w/cpp/language/operator_comparison#Pointer_total_order}
1649 {strict total order over pointers} when doing the comparison.
1650
1651 As a result, the relational operators for \c {PointerWrapperGood::ptr}
1652 member will be well-defined, and we can even \c {=default} the relational
1653 operators for the \c {PointerWrapperGood} class, like it's shown above.
1654*/
1655
1656QT_END_NAMESPACE
Combined button and popup list for selecting options.