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