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