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
11QT_BEGIN_NAMESPACE
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 \include qcompare.cpp noexcept-requirement-desc
1173*/
1174
1175/*!
1176 \internal
1177 \macro Q_DECLARE_EQUALITY_COMPARABLE_NON_NOEXCEPT(Type)
1178 \macro Q_DECLARE_EQUALITY_COMPARABLE_NON_NOEXCEPT(LeftType, RightType)
1179 \macro Q_DECLARE_EQUALITY_COMPARABLE_NON_NOEXCEPT(LeftType, RightType, Attributes)
1180 \macro Q_DECLARE_PARTIALLY_ORDERED_NON_NOEXCEPT(Type)
1181 \macro Q_DECLARE_PARTIALLY_ORDERED_NON_NOEXCEPT(LeftType, RightType)
1182 \macro Q_DECLARE_PARTIALLY_ORDERED_NON_NOEXCEPT(LeftType, RightType, Attributes)
1183 \macro Q_DECLARE_WEAKLY_ORDERED_NON_NOEXCEPT(Type)
1184 \macro Q_DECLARE_WEAKLY_ORDERED_NON_NOEXCEPT(LeftType, RightType)
1185 \macro Q_DECLARE_WEAKLY_ORDERED_NON_NOEXCEPT(LeftType, RightType, Attributes)
1186 \macro Q_DECLARE_STRONGLY_ORDERED_NON_NOEXCEPT(Type)
1187 \macro Q_DECLARE_STRONGLY_ORDERED_NON_NOEXCEPT(LeftType, RightType)
1188 \macro Q_DECLARE_STRONGLY_ORDERED_NON_NOEXCEPT(LeftType, RightType, Attributes)
1189 \since 6.8
1190 \relates <QtCompare>
1191
1192 These macros behave like their versions without the \c {_NON_NOEXCEPT}
1193 suffix, but should be used when the relational operators cannot be
1194 \c {noexcept}.
1195*/
1196
1197/*!
1198 \fn template <typename LeftInt, typename RightInt, Qt::if_integral<LeftInt> = true, Qt::if_integral<RightInt> = true> auto Qt::compareThreeWay(LeftInt lhs, RightInt rhs)
1199 \since 6.7
1200 \relates <QtCompare>
1201 \overload
1202
1203 Implements three-way comparison of integral types.
1204
1205 \note This function participates in overload resolution only if both
1206 \c LeftInt and \c RightInt are built-in integral types.
1207
1208 Returns \c {lhs <=> rhs}, provided \c LeftInt and \c RightInt are built-in
1209 integral types. Unlike \c {operator<=>()}, this function template is also
1210 available in C++17. See
1211 \l {https://en.cppreference.com/w/cpp/language/operator_comparison#Three-way_comparison}
1212 {cppreference} for more details.
1213
1214 This function can also be used in custom \c {compareThreeWay()} functions,
1215 when ordering members of a custom class represented by built-in types:
1216
1217 \code
1218 class MyClass {
1219 public:
1220 ...
1221 private:
1222 int value;
1223 ...
1224 friend Qt::strong_ordering
1225 compareThreeWay(const MyClass &lhs, const MyClass &rhs) noexcept
1226 { return Qt::compareThreeWay(lhs.value, rhs.value); }
1227 Q_DECLARE_STRONGLY_ORDERED(MyClass)
1228 };
1229 \endcode
1230
1231 Returns an instance of \l Qt::strong_ordering that represents the relation
1232 between \a lhs and \a rhs.
1233*/
1234
1235/*!
1236 \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)
1237 \since 6.7
1238 \relates <QtCompare>
1239 \overload
1240
1241 Implements three-way comparison of floating point types.
1242
1243 \note This function participates in overload resolution only if both
1244 \c LeftFloat and \c RightFloat are built-in floating-point types.
1245
1246 Returns \c {lhs <=> rhs}, provided \c LeftFloat and \c RightFloat are
1247 built-in floating-point types. Unlike \c {operator<=>()}, this function
1248 template is also available in C++17. See
1249 \l {https://en.cppreference.com/w/cpp/language/operator_comparison#Three-way_comparison}
1250 {cppreference} for more details.
1251
1252 This function can also be used in custom \c {compareThreeWay()} functions,
1253 when ordering members of a custom class represented by built-in types:
1254
1255 \code
1256 class MyClass {
1257 public:
1258 ...
1259 private:
1260 double value;
1261 ...
1262 friend Qt::partial_ordering
1263 compareThreeWay(const MyClass &lhs, const MyClass &rhs) noexcept
1264 { return Qt::compareThreeWay(lhs.value, rhs.value); }
1265 Q_DECLARE_PARTIALLY_ORDERED(MyClass)
1266 };
1267 \endcode
1268
1269 Returns an instance of \l Qt::partial_ordering that represents the relation
1270 between \a lhs and \a rhs. If \a lhs or \a rhs is not a number (NaN),
1271 \l Qt::partial_ordering::unordered is returned.
1272*/
1273
1274/*!
1275 \fn template <typename IntType, typename FloatType, Qt::if_integral<IntType> = true, Qt::if_floating_point<FloatType> = true> auto Qt::compareThreeWay(IntType lhs, FloatType rhs)
1276 \since 6.7
1277 \relates <QtCompare>
1278 \overload
1279
1280 Implements three-way comparison of integral and floating point types.
1281
1282 \note This function participates in overload resolution only if \c IntType
1283 is a built-in integral type and \c FloatType is a built-in floating-point
1284 type.
1285
1286 This function converts \a lhs to \c FloatType and calls the overload for
1287 floating-point types.
1288
1289 Returns an instance of \l Qt::partial_ordering that represents the relation
1290 between \a lhs and \a rhs. If \a rhs is not a number (NaN),
1291 \l Qt::partial_ordering::unordered is returned.
1292*/
1293
1294/*!
1295 \fn template <typename FloatType, typename IntType, Qt::if_floating_point<FloatType> = true, Qt::if_integral<IntType> = true> auto Qt::compareThreeWay(FloatType lhs, IntType rhs)
1296 \since 6.7
1297 \relates <QtCompare>
1298 \overload
1299
1300 Implements three-way comparison of floating point and integral types.
1301
1302 \note This function participates in overload resolution only if \c FloatType
1303 is a built-in floating-point type and \c IntType is a built-in integral
1304 type.
1305
1306 This function converts \a rhs to \c FloatType and calls the overload for
1307 floating-point types.
1308
1309 Returns an instance of \l Qt::partial_ordering that represents the relation
1310 between \a lhs and \a rhs. If \a lhs is not a number (NaN),
1311 \l Qt::partial_ordering::unordered is returned.
1312*/
1313
1314#if QT_DEPRECATED_SINCE(6, 8)
1315/*!
1316 \fn template <typename LeftType, typename RightType, Qt::if_compatible_pointers<LeftType, RightType> = true> Qt::compareThreeWay(const LeftType *lhs, const RightType *rhs)
1317 \since 6.7
1318 \deprecated [6.8] Wrap the pointers into Qt::totally_ordered_wrapper and
1319 use the respective Qt::compareThreeWay() overload instead.
1320 \relates <QtCompare>
1321 \overload
1322
1323 Implements three-way comparison of pointers.
1324
1325 \note This function participates in overload resolution if \c LeftType and
1326 \c RightType are the same type, or base and derived types. It is also used
1327 to compare any pointer to \c {std::nullptr_t}.
1328
1329 Returns an instance of \l Qt::strong_ordering that represents the relation
1330 between \a lhs and \a rhs.
1331*/
1332#endif // QT_DEPRECATED_SINCE(6, 8)
1333
1334/*!
1335 \fn template <class Enum, Qt::if_enum<Enum> = true> Qt::compareThreeWay(Enum lhs, Enum rhs)
1336 \since 6.7
1337 \relates <QtCompare>
1338 \overload
1339
1340 Implements three-way comparison of enum types.
1341
1342 \note This function participates in overload resolution only if \c Enum
1343 is an enum type.
1344
1345 This function converts \c Enum to its underlying type and calls the
1346 overload for integral types.
1347
1348 Returns an instance of \l Qt::strong_ordering that represents the relation
1349 between \a lhs and \a rhs.
1350*/
1351
1352/*!
1353 \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)
1354 \since 6.8
1355 \relates <QtCompare>
1356 \overload
1357
1358 Implements three-way comparison of pointers that are wrapped into
1359 \l Qt::totally_ordered_wrapper. Uses
1360 \l {https://en.cppreference.com/w/cpp/language/operator_comparison#Pointer_total_order}
1361 {strict total order over pointers} when doing the comparison.
1362
1363 \note This function participates in overload resolution if \c T and \c U
1364 are the same type, or base and derived types.
1365
1366 Returns an instance of \l Qt::strong_ordering that represents the relation
1367 between \a lhs and \a rhs.
1368*/
1369
1370/*!
1371 \fn template <typename T, typename U, Qt::if_compatible_pointers<T, U> = true> Qt::compareThreeWay(Qt::totally_ordered_wrapper<T*> lhs, U *rhs)
1372 \since 6.8
1373 \relates <QtCompare>
1374 \overload
1375
1376 Implements three-way comparison of a pointer wrapped into
1377 \l Qt::totally_ordered_wrapper with a normal pointer. Uses
1378 \l {https://en.cppreference.com/w/cpp/language/operator_comparison#Pointer_total_order}
1379 {strict total order over pointers} when doing the comparison.
1380
1381 \note This function participates in overload resolution if \c T and \c U
1382 are the same type, or base and derived types.
1383
1384 Returns an instance of \l Qt::strong_ordering that represents the relation
1385 between \a lhs and \a rhs.
1386*/
1387
1388/*!
1389 \fn template <typename T, typename U, Qt::if_compatible_pointers<T, U> = true> Qt::compareThreeWay(U *lhs, Qt::totally_ordered_wrapper<T*> rhs)
1390 \since 6.8
1391 \relates <QtCompare>
1392 \overload
1393
1394 Implements three-way comparison of a normal pointer with a pointer wrapped
1395 into \l Qt::totally_ordered_wrapper. Uses
1396 \l {https://en.cppreference.com/w/cpp/language/operator_comparison#Pointer_total_order}
1397 {strict total order over pointers} when doing the comparison.
1398
1399 \note This function participates in overload resolution if \c T and \c U
1400 are the same type, or base and derived types.
1401
1402 Returns an instance of \l Qt::strong_ordering that represents the relation
1403 between \a lhs and \a rhs.
1404*/
1405
1406/*!
1407 \fn template <typename T> Qt::compareThreeWay(Qt::totally_ordered_wrapper<T*> lhs, std::nullptr_t rhs)
1408 \since 6.8
1409 \relates <QtCompare>
1410 \overload
1411
1412 Implements three-way comparison of a pointer wrapped into
1413 \l Qt::totally_ordered_wrapper with \c {std::nullptr_t}.
1414
1415 Returns an instance of \l Qt::strong_ordering that represents the relation
1416 between \a lhs and \a rhs.
1417*/
1418
1419/*!
1420 \fn template <typename T> Qt::compareThreeWay(std::nullptr_t lhs, Qt::totally_ordered_wrapper<T*> rhs)
1421 \since 6.8
1422 \relates <QtCompare>
1423 \overload
1424
1425 Implements three-way comparison of \c {std::nullptr_t} with a pointer
1426 wrapped into \l Qt::totally_ordered_wrapper.
1427
1428 Returns an instance of \l Qt::strong_ordering that represents the relation
1429 between \a lhs and \a rhs.
1430*/
1431
1432/*!
1433 \fn template <typename LeftType, typename RightType> qCompareThreeWay(const LeftType &lhs, const RightType &rhs)
1434 \since 6.7
1435 \relates <QtCompare>
1436
1437 Performs the three-way comparison on \a lhs and \a rhs and returns one of
1438 the Qt ordering types as a result. This function is available for both
1439 C++17 and C++20.
1440
1441 The actual returned type depends on \c LeftType and \c RightType.
1442
1443 \note This function template is only available when \c {compareThreeWay()}
1444 is implemented for the \c {(LeftType, RightType)} pair or the reversed
1445 \c {(RightType, LeftType)} pair.
1446
1447 This method is equivalent to
1448
1449 \code
1450 using Qt::compareThreeWay;
1451 return compareThreeWay(lhs, rhs);
1452 \endcode
1453
1454 where \c {Qt::compareThreeWay} is the Qt implementation of three-way
1455 comparison for built-in types.
1456
1457 The free \c {compareThreeWay} functions should provide three-way comparison
1458 for custom types. The functions should return one of the Qt ordering types.
1459
1460 Qt provides \c {compareThreeWay} implementation for some of its types.
1461
1462 \note \b {Do not} re-implement \c {compareThreeWay()} for Qt types, as more
1463 Qt types will get support for it in future Qt releases.
1464
1465 Use this function primarly in generic code, when you know nothing about
1466 \c LeftType and \c RightType.
1467
1468 If you know the types, use
1469
1470 \list
1471 \li \c {Qt::compareThreeWay} for built-in types
1472 \li \c {compareThreeWay} for custom types
1473 \endlist
1474
1475 Use \c {operator<=>()} directly in code that will only be compiled with
1476 C++20 or later.
1477
1478 \sa Qt::partial_ordering, Qt::weak_ordering, Qt::strong_ordering
1479*/
1480
1481/*!
1482 \class Qt::totally_ordered_wrapper
1483 \inmodule QtCore
1484 \inheaderfile QtCompare
1485 \brief Qt::totally_ordered_wrapper is a wrapper type that provides strict
1486 total order for the wrapped types.
1487 \since 6.8
1488
1489 One of its primary usecases is to prevent \e {Undefined Behavior} (UB) when
1490 comparing pointers.
1491
1492 Consider the following simple class:
1493
1494 \code
1495 template <typename T>
1496 struct PointerWrapperBad {
1497 int val;
1498 T *ptr;
1499 };
1500 \endcode
1501
1502 Lexicographical comparison of the two instances of the \c PointerWrapperBad
1503 type would result in UB, because it will call \c {operator<()} or
1504 \c {operator<=>()} on the \c {ptr} members.
1505
1506 To fix it, use the new wrapper type:
1507
1508 \code
1509 template <typename T>
1510 struct PointerWrapperGood {
1511 int val;
1512 Qt::totally_ordered_wrapper<T *> ptr;
1513
1514 friend bool
1515 operator==(PointerWrapperGood lhs, PointerWrapperGood rhs) noexcept = default;
1516 friend auto
1517 operator<=>(PointerWrapperGood lhs, PointerWrapperGood rhs) noexecpt = default;
1518 };
1519 \endcode
1520
1521 The \c {operator<()} and (if available) \c {operator<=>()} operators for
1522 the \c {Qt::totally_ordered_wrapper} type use the
1523 \l {https://en.cppreference.com/w/cpp/utility/functional/less}{std::less}
1524 and \l {https://en.cppreference.com/w/cpp/utility/compare/compare_three_way}
1525 {std::compare_three_way} function objects respectively, providing
1526 \l {https://en.cppreference.com/w/cpp/language/operator_comparison#Pointer_total_order}
1527 {strict total order over pointers} when doing the comparison.
1528
1529 As a result, the relational operators for \c {PointerWrapperGood::ptr}
1530 member will be well-defined, and we can even \c {=default} the relational
1531 operators for the \c {PointerWrapperGood} class, like it's shown above.
1532*/
1533
1534QT_END_NAMESPACE
1535

Provided by KDAB

Privacy Policy
Learn Advanced QML with KDAB
Find out more

source code of qtbase/src/corelib/global/qcompare.cpp