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