Qt
Internal/Contributor docs for the Qt SDK. Note: These are NOT official API docs; those are found at https://doc.qt.io/
Loading...
Searching...
No Matches
qcomparehelpers.h
Go to the documentation of this file.
1// Copyright (C) 2023 The Qt Company Ltd.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
3// Qt-Security score:significant reason:default
4
5#ifndef QCOMPARE_H
6#error "Do not include qcomparehelpers.h directly. Use qcompare.h instead."
7#endif
8
9#ifndef QCOMPAREHELPERS_H
10#define QCOMPAREHELPERS_H
11
12#if 0
13#pragma qt_no_master_include
14#pragma qt_sync_skip_header_check
15#pragma qt_sync_stop_processing
16#endif
17
18#include <QtCore/qflags.h>
19#include <QtCore/qoverload.h>
20#include <QtCore/qttypetraits.h>
21#include <QtCore/qtypeinfo.h>
22#include <QtCore/qtypes.h>
23
24#ifdef __cpp_lib_three_way_comparison
25#include <compare>
26#endif
27#include <QtCore/q20type_traits.h>
28
29#include <functional> // std::less, std::hash
30
31QT_BEGIN_NAMESPACE
32
33class QPartialOrdering;
34
35namespace QtOrderingPrivate {
36template <typename T> struct is_std_ordering_type : std::false_type {};
37template <typename T> struct is_qt_ordering_type : std::false_type {};
38
39template <typename T> constexpr bool is_std_ordering_type_v = is_std_ordering_type<T>::value;
40template <typename T> constexpr bool is_qt_ordering_type_v = is_qt_ordering_type<T>::value;
41
42enum class QtOrderingType {
43 QtOrder = 0x00,
44 StdOrder = 0x01,
45 Partial = 0x00,
46 Weak = 0x20,
47 Strong = 0x40,
49};
52
53template <typename QtOrdering> struct StdOrdering;
54template <typename StdOrdering> struct QtOrdering;
55
56#ifdef __cpp_lib_three_way_comparison
57#define QT_STD_MAP(x)
58 template <> struct StdOrdering< Qt::x##_ordering> : q20::type_identity<std::x##_ordering> {};
59 template <> struct StdOrdering<std::x##_ordering> : q20::type_identity<std::x##_ordering> {};
60 template <> struct QtOrdering<std::x##_ordering> : q20::type_identity< Qt::x##_ordering> {};
61 template <> struct QtOrdering< Qt::x##_ordering> : q20::type_identity< Qt::x##_ordering> {};
62 template <> struct is_std_ordering_type<std::x##_ordering> : std::true_type {};
63 template <> struct is_qt_ordering_type< Qt::x##_ordering> : std::true_type {};
64 /* end */
68#undef QT_STD_MAP
69
72#else
74template <> struct is_qt_ordering_type< Qt::weak_ordering> : std::true_type {};
76#endif // __cpp_lib_three_way_comparison
77
78template <typename In> constexpr auto to_std(In in) noexcept
80{ return in; }
81
82template <typename In> constexpr auto to_Qt(In in) noexcept
83 -> typename QtOrderingPrivate::QtOrdering<In>::type
84{ return in; }
85
86template <typename T>
87constexpr bool is_ordering_type_v
89
90template <typename T>
92orderingFlagsFor(T t) noexcept
93{
94 QtOrderingTypeFlag flags = QtOrderingType::QtOrder;
95 Qt::partial_ordering convertedOrder(t);
96 if constexpr (std::is_same_v<T, Qt::strong_ordering>)
97 flags = flags | QtOrderingType::Strong;
98 else if constexpr (std::is_same_v<T, Qt::partial_ordering>)
99 flags = flags | QtOrderingType::Partial;
100 else if constexpr (std::is_same_v<T, Qt::weak_ordering>)
101 flags = flags | QtOrderingType::Weak;
102 return flags;
103}
104
105template <typename T>
107orderingFlagsFor(T t) noexcept
108{
109 QtOrderingPrivate::QtOrderingTypeFlag flags = QtOrderingPrivate::QtOrderingType::StdOrder;
110 return QtOrderingTypeFlag(flags
111 | QtOrderingPrivate::orderingFlagsFor(QtOrderingPrivate::to_Qt(t)));
112}
113} // namespace QtOrderingPrivate
114
115/*
116 For all the macros these parameter names are used:
117 * LeftType - the type of the left operand of the comparison
118 * RightType - the type of the right operand of the comparison
119 * Constexpr - must be either constexpr or empty. Defines whether the
120 operator is constexpr or not
121 * Noexcept - a noexcept specifier. By default the relational operators are
122 expected to be noexcept. However, there are some cases when
123 this cannot be achieved (e.g. QDir). The public macros will
124 pass noexcept(true) or noexcept(false) in this parameter,
125 because conditional noexcept is known to cause some issues.
126 However, internally we might want to pass a predicate here
127 for some specific classes (e.g. QList, etc).
128 * Attributes... - an optional list of attributes. For example, pass
129 \c QT_ASCII_CAST_WARN when defining comparisons between
130 C-style string and an encoding-aware string type.
131 This is a variable argument, and can now include up to 7
132 comma-separated parameters.
133
134 The macros require two helper functions. For operators to be constexpr,
135 these must be constexpr, too. Additionally, other attributes (like
136 Q_<Module>_EXPORT, Q_DECL_CONST_FUNCTION, etc) can be applied to them.
137 Aside from that, their declaration should match:
138 bool comparesEqual(LeftType, RightType) noexcept;
139 ReturnType compareThreeWay(LeftType, RightType) noexcept;
140
141 The ReturnType can be one of Qt::{partial,weak,strong}_ordering. The actual
142 type depends on the macro being used.
143 It makes sense to define the helper functions as hidden friends of the
144 class, so that they could be found via ADL, and don't participate in
145 unintended implicit conversions.
146*/
147
148/*
149 Some systems (e.g. QNX and Integrity (GHS compiler)) have bugs in
150 handling conditional noexcept in lambdas.
151 This macro is needed to overcome such bugs and provide a noexcept check only
152 on platforms that behave normally.
153 It does nothing on the systems that have problems.
154
155 This hack is explicitly disabled for C++20 because we want the compilers
156 to fix the known issues before switching.
157*/
158#if defined(__cpp_lib_three_way_comparison) || !(defined(Q_OS_QNX) || defined(Q_CC_GHS))
159# define QT_COMPARISON_NOEXCEPT_CHECK(Noexcept, Func)
160 constexpr auto f = []() Noexcept {};
161 static_assert(!noexcept(f()) || noexcept(Func(lhs, rhs)),
162 "Use *_NON_NOEXCEPT version of the macro, "
163 "or make the helper function noexcept")
164#else
165# define QT_COMPARISON_NOEXCEPT_CHECK(Noexcept, Func) /* no check */
166#endif
167
168
169// Seems that qdoc uses C++20 even when Qt is compiled in C++17 mode.
170// Or at least it defines __cpp_lib_three_way_comparison.
171// Let qdoc see only the C++17 operators for now, because that's what our docs
172// currently describe.
173#if defined(__cpp_lib_three_way_comparison) && !defined(Q_QDOC)
174// C++20 - provide operator==() for equality, and operator<=>() for ordering
175
176#define QT_DECLARE_EQUALITY_OPERATORS_HELPER(LeftType, RightType, Constexpr,
177 Noexcept, ...)
178 __VA_ARGS__
179 friend Constexpr bool operator==(LeftType const &lhs, RightType const &rhs) Noexcept
180 {
181 QT_COMPARISON_NOEXCEPT_CHECK(Noexcept, comparesEqual);
182 return comparesEqual(lhs, rhs);
183 }
184
185#define QT_DECLARE_ORDERING_HELPER_STRONG(LeftType, RightType, Constexpr, Noexcept, ...)
186 __VA_ARGS__
187 friend Constexpr std::strong_ordering
188 operator<=>(LeftType const &lhs, RightType const &rhs) Noexcept
189 {
190 QT_COMPARISON_NOEXCEPT_CHECK(Noexcept, compareThreeWay);
191 return compareThreeWay(lhs, rhs);
192 }
193
194#define QT_DECLARE_ORDERING_HELPER_WEAK(LeftType, RightType, Constexpr, Noexcept, ...)
195 __VA_ARGS__
196 friend Constexpr std::weak_ordering
197 operator<=>(LeftType const &lhs, RightType const &rhs) Noexcept
198 {
199 QT_COMPARISON_NOEXCEPT_CHECK(Noexcept, compareThreeWay);
200 return compareThreeWay(lhs, rhs);
201 }
202
203#define QT_DECLARE_ORDERING_HELPER_PARTIAL(LeftType, RightType, Constexpr, Noexcept, ...)
204 __VA_ARGS__
205 friend Constexpr std::partial_ordering
206 operator<=>(LeftType const &lhs, RightType const &rhs) Noexcept
207 {
208 QT_COMPARISON_NOEXCEPT_CHECK(Noexcept, compareThreeWay);
209 return compareThreeWay(lhs, rhs);
210 }
211
212#define QT_DECLARE_ORDERING_HELPER_AUTO(LeftType, RightType, Constexpr, Noexcept, ...)
213 __VA_ARGS__
214 friend Constexpr auto
215 operator<=>(LeftType const &lhs, RightType const &rhs) Noexcept
216 {
217 QT_COMPARISON_NOEXCEPT_CHECK(Noexcept, compareThreeWay);
218 return QtOrderingPrivate::to_std(compareThreeWay(lhs, rhs));
219 }
220
221#define QT_DECLARE_ORDERING_OPERATORS_HELPER(OrderingType, LeftType, RightType, Constexpr,
222 Noexcept, ...)
223 QT_DECLARE_EQUALITY_OPERATORS_HELPER(LeftType, RightType, Constexpr, Noexcept, __VA_ARGS__)
224 QT_DECLARE_ORDERING_HELPER_ ## OrderingType (LeftType, RightType, Constexpr, Noexcept,
225 __VA_ARGS__)
226
227#ifdef Q_COMPILER_LACKS_THREE_WAY_COMPARE_SYMMETRY
228
229// define reversed versions of the operators manually, because buggy MSVC versions do not do it
230#define QT_DECLARE_EQUALITY_OPERATORS_REVERSED_HELPER(LeftType, RightType, Constexpr,
231 Noexcept, ...)
232 __VA_ARGS__
233 friend Constexpr bool operator==(RightType const &lhs, LeftType const &rhs) Noexcept
234 { return comparesEqual(rhs, lhs); }
235
236#define QT_DECLARE_REVERSED_ORDERING_HELPER_STRONG(LeftType, RightType, Constexpr,
237 Noexcept, ...)
238 __VA_ARGS__
239 friend Constexpr std::strong_ordering
240 operator<=>(RightType const &lhs, LeftType const &rhs) Noexcept
241 {
242 const auto r = compareThreeWay(rhs, lhs);
243 return QtOrderingPrivate::reversed(r);
244 }
245
246#define QT_DECLARE_REVERSED_ORDERING_HELPER_WEAK(LeftType, RightType, Constexpr,
247 Noexcept, ...)
248 __VA_ARGS__
249 friend Constexpr std::weak_ordering
250 operator<=>(RightType const &lhs, LeftType const &rhs) Noexcept
251 {
252 const auto r = compareThreeWay(rhs, lhs);
253 return QtOrderingPrivate::reversed(r);
254 }
255
256#define QT_DECLARE_REVERSED_ORDERING_HELPER_PARTIAL(LeftType, RightType, Constexpr,
257 Noexcept, ...)
258 __VA_ARGS__
259 friend Constexpr std::partial_ordering
260 operator<=>(RightType const &lhs, LeftType const &rhs) Noexcept
261 {
262 const auto r = compareThreeWay(rhs, lhs);
263 return QtOrderingPrivate::reversed(r);
264 }
265
266#define QT_DECLARE_REVERSED_ORDERING_HELPER_AUTO(LeftType, RightType, Constexpr, Noexcept, ...)
267 __VA_ARGS__
268 friend Constexpr auto
269 operator<=>(RightType const &lhs, LeftType const &rhs) Noexcept
270 {
271 const auto r = compareThreeWay(rhs, lhs);
272 return QtOrderingPrivate::to_std(QtOrderingPrivate::reversed(r));
273 }
274
275#define QT_DECLARE_ORDERING_OPERATORS_REVERSED_HELPER(OrderingString, LeftType, RightType,
276 Constexpr, Noexcept, ...)
277 QT_DECLARE_EQUALITY_OPERATORS_REVERSED_HELPER(LeftType, RightType, Constexpr,
278 Noexcept, __VA_ARGS__)
279 QT_DECLARE_REVERSED_ORDERING_HELPER_ ## OrderingString (LeftType, RightType, Constexpr,
280 Noexcept, __VA_ARGS__)
281
282#else
283
284// dummy macros for C++17 compatibility, reversed operators are generated by the compiler
285#define QT_DECLARE_EQUALITY_OPERATORS_REVERSED_HELPER(LeftType, RightType, Constexpr,
286 Noexcept, ...)
287#define QT_DECLARE_ORDERING_OPERATORS_REVERSED_HELPER(OrderingString, LeftType, RightType,
288 Constexpr, Noexcept, ...)
289
290#endif // Q_COMPILER_LACKS_THREE_WAY_COMPARE_SYMMETRY
291
292#else
293// C++17 - provide operator==() and operator!=() for equality,
294// and all 4 comparison operators for ordering
295
296#define QT_DECLARE_EQUALITY_OPERATORS_HELPER(LeftType, RightType, Constexpr,
297 Noexcept, ...)
298 __VA_ARGS__
299 friend Constexpr bool operator==(LeftType const &lhs, RightType const &rhs) Noexcept
300 {
301 QT_COMPARISON_NOEXCEPT_CHECK(Noexcept, comparesEqual);
302 return comparesEqual(lhs, rhs);
303 }
304 __VA_ARGS__
305 friend Constexpr bool operator!=(LeftType const &lhs, RightType const &rhs) Noexcept
306 { return !comparesEqual(lhs, rhs); }
307
308// Helpers for reversed comparison, using the existing comparesEqual() function.
309#define QT_DECLARE_EQUALITY_OPERATORS_REVERSED_HELPER(LeftType, RightType, Constexpr,
310 Noexcept, ...)
311 __VA_ARGS__
312 friend Constexpr bool operator==(RightType const &lhs, LeftType const &rhs) Noexcept
313 { return comparesEqual(rhs, lhs); }
314 __VA_ARGS__
315 friend Constexpr bool operator!=(RightType const &lhs, LeftType const &rhs) Noexcept
316 { return !comparesEqual(rhs, lhs); }
317
318#define QT_DECLARE_ORDERING_HELPER_TEMPLATE(OrderingType, LeftType, RightType, Constexpr,
319 Noexcept, ...)
320 __VA_ARGS__
321 friend Constexpr bool operator<(LeftType const &lhs, RightType const &rhs) Noexcept
322 {
323 QT_COMPARISON_NOEXCEPT_CHECK(Noexcept, compareThreeWay);
324 return is_lt(compareThreeWay(lhs, rhs));
325 }
326 __VA_ARGS__
327 friend Constexpr bool operator>(LeftType const &lhs, RightType const &rhs) Noexcept
328 { return is_gt(compareThreeWay(lhs, rhs)); }
329 __VA_ARGS__
330 friend Constexpr bool operator<=(LeftType const &lhs, RightType const &rhs) Noexcept
331 { return is_lteq(compareThreeWay(lhs, rhs)); }
332 __VA_ARGS__
333 friend Constexpr bool operator>=(LeftType const &lhs, RightType const &rhs) Noexcept
334 { return is_gteq(compareThreeWay(lhs, rhs)); }
335
336#define QT_DECLARE_ORDERING_HELPER_AUTO(LeftType, RightType, Constexpr, Noexcept, ...)
337 QT_DECLARE_ORDERING_HELPER_TEMPLATE(auto, LeftType, RightType, Constexpr, Noexcept,
338 __VA_ARGS__)
339
340#define QT_DECLARE_ORDERING_HELPER_PARTIAL(LeftType, RightType, Constexpr, Noexcept, ...)
341 QT_DECLARE_ORDERING_HELPER_TEMPLATE(Qt::partial_ordering, LeftType, RightType, Constexpr,
342 Noexcept, __VA_ARGS__)
343
344#define QT_DECLARE_ORDERING_HELPER_WEAK(LeftType, RightType, Constexpr, Noexcept, ...)
345 QT_DECLARE_ORDERING_HELPER_TEMPLATE(Qt::weak_ordering, LeftType, RightType, Constexpr,
346 Noexcept, __VA_ARGS__)
347
348#define QT_DECLARE_ORDERING_HELPER_STRONG(LeftType, RightType, Constexpr, Noexcept, ...)
349 QT_DECLARE_ORDERING_HELPER_TEMPLATE(Qt::strong_ordering, LeftType, RightType, Constexpr,
350 Noexcept, __VA_ARGS__)
351
352#define QT_DECLARE_ORDERING_OPERATORS_HELPER(OrderingString, LeftType, RightType, Constexpr,
353 Noexcept, ...)
354 QT_DECLARE_EQUALITY_OPERATORS_HELPER(LeftType, RightType, Constexpr, Noexcept, __VA_ARGS__)
355 QT_DECLARE_ORDERING_HELPER_ ## OrderingString (LeftType, RightType, Constexpr, Noexcept,
356 __VA_ARGS__)
357
358// Helpers for reversed ordering, using the existing compareThreeWay() function.
359#define QT_DECLARE_REVERSED_ORDERING_HELPER_TEMPLATE(OrderingType, LeftType, RightType, Constexpr,
360 Noexcept, ...)
361 __VA_ARGS__
362 friend Constexpr bool operator<(RightType const &lhs, LeftType const &rhs) Noexcept
363 { return is_gt(compareThreeWay(rhs, lhs)); }
364 __VA_ARGS__
365 friend Constexpr bool operator>(RightType const &lhs, LeftType const &rhs) Noexcept
366 { return is_lt(compareThreeWay(rhs, lhs)); }
367 __VA_ARGS__
368 friend Constexpr bool operator<=(RightType const &lhs, LeftType const &rhs) Noexcept
369 { return is_gteq(compareThreeWay(rhs, lhs)); }
370 __VA_ARGS__
371 friend Constexpr bool operator>=(RightType const &lhs, LeftType const &rhs) Noexcept
372 { return is_lteq(compareThreeWay(rhs, lhs)); }
373
374#define QT_DECLARE_REVERSED_ORDERING_HELPER_AUTO(LeftType, RightType, Constexpr, Noexcept, ...)
375 QT_DECLARE_REVERSED_ORDERING_HELPER_TEMPLATE(auto, LeftType, RightType, Constexpr, Noexcept,
376 __VA_ARGS__)
377
378#define QT_DECLARE_REVERSED_ORDERING_HELPER_PARTIAL(LeftType, RightType, Constexpr, Noexcept, ...)
379 QT_DECLARE_REVERSED_ORDERING_HELPER_TEMPLATE(Qt::partial_ordering, LeftType, RightType,
380 Constexpr, Noexcept, __VA_ARGS__)
381
382#define QT_DECLARE_REVERSED_ORDERING_HELPER_WEAK(LeftType, RightType, Constexpr, Noexcept, ...)
383 QT_DECLARE_REVERSED_ORDERING_HELPER_TEMPLATE(Qt::weak_ordering, LeftType, RightType,
384 Constexpr, Noexcept, __VA_ARGS__)
385
386#define QT_DECLARE_REVERSED_ORDERING_HELPER_STRONG(LeftType, RightType, Constexpr, Noexcept, ...)
387 QT_DECLARE_REVERSED_ORDERING_HELPER_TEMPLATE(Qt::strong_ordering, LeftType, RightType,
388 Constexpr, Noexcept, __VA_ARGS__)
389
390#define QT_DECLARE_ORDERING_OPERATORS_REVERSED_HELPER(OrderingString, LeftType, RightType,
391 Constexpr, Noexcept, ...)
392 QT_DECLARE_EQUALITY_OPERATORS_REVERSED_HELPER(LeftType, RightType, Constexpr, Noexcept,
393 __VA_ARGS__)
394 QT_DECLARE_REVERSED_ORDERING_HELPER_ ## OrderingString (LeftType, RightType, Constexpr,
395 Noexcept, __VA_ARGS__)
396
397#endif // __cpp_lib_three_way_comparison
398
399/* Public API starts here */
400
401// Equality operators
402#define QT_DECLARE_EQUALITY_COMPARABLE_1(Type)
403 QT_DECLARE_EQUALITY_OPERATORS_HELPER(Type, Type, /* non-constexpr */, noexcept(true),
404 /* no attributes */)
405
406#define QT_DECLARE_EQUALITY_COMPARABLE_2(LeftType, RightType)
407 QT_DECLARE_EQUALITY_OPERATORS_HELPER(LeftType, RightType, /* non-constexpr */,
408 noexcept(true), /* no attributes */)
409 QT_DECLARE_EQUALITY_OPERATORS_REVERSED_HELPER(LeftType, RightType, /* non-constexpr */,
410 noexcept(true), /* no attributes */)
411
412#define QT_DECLARE_EQUALITY_COMPARABLE_3(LeftType, RightType, ...)
413 QT_DECLARE_EQUALITY_OPERATORS_HELPER(LeftType, RightType, /* non-constexpr */,
414 noexcept(true), __VA_ARGS__)
415 QT_DECLARE_EQUALITY_OPERATORS_REVERSED_HELPER(LeftType, RightType, /* non-constexpr */,
416 noexcept(true), __VA_ARGS__)
417
418#define QT_DECLARE_EQUALITY_COMPARABLE_4(...)
419 QT_VA_ARGS_EXPAND(QT_DECLARE_EQUALITY_COMPARABLE_3(__VA_ARGS__))
420#define QT_DECLARE_EQUALITY_COMPARABLE_5(...)
421 QT_VA_ARGS_EXPAND(QT_DECLARE_EQUALITY_COMPARABLE_3(__VA_ARGS__))
422#define QT_DECLARE_EQUALITY_COMPARABLE_6(...)
423 QT_VA_ARGS_EXPAND(QT_DECLARE_EQUALITY_COMPARABLE_3(__VA_ARGS__))
424#define QT_DECLARE_EQUALITY_COMPARABLE_7(...)
425 QT_VA_ARGS_EXPAND(QT_DECLARE_EQUALITY_COMPARABLE_3(__VA_ARGS__))
426#define QT_DECLARE_EQUALITY_COMPARABLE_8(...)
427 QT_VA_ARGS_EXPAND(QT_DECLARE_EQUALITY_COMPARABLE_3(__VA_ARGS__))
428#define QT_DECLARE_EQUALITY_COMPARABLE_9(...)
429 QT_VA_ARGS_EXPAND(QT_DECLARE_EQUALITY_COMPARABLE_3(__VA_ARGS__))
430
431#define Q_DECLARE_EQUALITY_COMPARABLE(...)
432 QT_OVERLOADED_MACRO(QT_DECLARE_EQUALITY_COMPARABLE, __VA_ARGS__)
433
434#define QT_DECLARE_EQUALITY_COMPARABLE_LITERAL_TYPE_1(Type)
435 QT_DECLARE_EQUALITY_OPERATORS_HELPER(Type, Type, constexpr, noexcept(true),
436 /* no attributes */)
437
438#define QT_DECLARE_EQUALITY_COMPARABLE_LITERAL_TYPE_2(LeftType, RightType)
439 QT_DECLARE_EQUALITY_OPERATORS_HELPER(LeftType, RightType, constexpr, noexcept(true),
440 /* no attributes */)
441 QT_DECLARE_EQUALITY_OPERATORS_REVERSED_HELPER(LeftType, RightType, constexpr,
442 noexcept(true), /* no attributes */)
443
444#define QT_DECLARE_EQUALITY_COMPARABLE_LITERAL_TYPE_3(LeftType, RightType, ...)
445 QT_DECLARE_EQUALITY_OPERATORS_HELPER(LeftType, RightType, constexpr, noexcept(true),
446 __VA_ARGS__)
447 QT_DECLARE_EQUALITY_OPERATORS_REVERSED_HELPER(LeftType, RightType, constexpr, noexcept(true),
448 __VA_ARGS__)
449
450#define QT_DECLARE_EQUALITY_COMPARABLE_LITERAL_TYPE_4(...)
451 QT_VA_ARGS_EXPAND(QT_DECLARE_EQUALITY_COMPARABLE_LITERAL_TYPE_3(__VA_ARGS__))
452#define QT_DECLARE_EQUALITY_COMPARABLE_LITERAL_TYPE_5(...)
453 QT_VA_ARGS_EXPAND(QT_DECLARE_EQUALITY_COMPARABLE_LITERAL_TYPE_3(__VA_ARGS__))
454#define QT_DECLARE_EQUALITY_COMPARABLE_LITERAL_TYPE_6(...)
455 QT_VA_ARGS_EXPAND(QT_DECLARE_EQUALITY_COMPARABLE_LITERAL_TYPE_3(__VA_ARGS__))
456#define QT_DECLARE_EQUALITY_COMPARABLE_LITERAL_TYPE_7(...)
457 QT_VA_ARGS_EXPAND(QT_DECLARE_EQUALITY_COMPARABLE_LITERAL_TYPE_3(__VA_ARGS__))
458#define QT_DECLARE_EQUALITY_COMPARABLE_LITERAL_TYPE_8(...)
459 QT_VA_ARGS_EXPAND(QT_DECLARE_EQUALITY_COMPARABLE_LITERAL_TYPE_3(__VA_ARGS__))
460#define QT_DECLARE_EQUALITY_COMPARABLE_LITERAL_TYPE_9(...)
461 QT_VA_ARGS_EXPAND(QT_DECLARE_EQUALITY_COMPARABLE_LITERAL_TYPE_3(__VA_ARGS__))
462
463#define Q_DECLARE_EQUALITY_COMPARABLE_LITERAL_TYPE(...)
464 QT_OVERLOADED_MACRO(QT_DECLARE_EQUALITY_COMPARABLE_LITERAL_TYPE, __VA_ARGS__)
465
466#define QT_DECLARE_EQUALITY_COMPARABLE_NON_NOEXCEPT_1(Type)
467 QT_DECLARE_EQUALITY_OPERATORS_HELPER(Type, Type, /* non-constexpr */, noexcept(false),
468 /* no attributes */)
469
470#define QT_DECLARE_EQUALITY_COMPARABLE_NON_NOEXCEPT_2(LeftType, RightType)
471 QT_DECLARE_EQUALITY_OPERATORS_HELPER(LeftType, RightType, /* non-constexpr */,
472 noexcept(false), /* no attributes */)
473 QT_DECLARE_EQUALITY_OPERATORS_REVERSED_HELPER(LeftType, RightType, /* non-constexpr */,
474 noexcept(false), /* no attributes */)
475
476#define QT_DECLARE_EQUALITY_COMPARABLE_NON_NOEXCEPT_3(LeftType, RightType, ...)
477 QT_DECLARE_EQUALITY_OPERATORS_HELPER(LeftType, RightType, /* non-constexpr */,
478 noexcept(false), __VA_ARGS__)
479 QT_DECLARE_EQUALITY_OPERATORS_REVERSED_HELPER(LeftType, RightType, /* non-constexpr */,
480 noexcept(false), __VA_ARGS__)
481
482#define QT_DECLARE_EQUALITY_COMPARABLE_NON_NOEXCEPT_4(...)
483 QT_VA_ARGS_EXPAND(QT_DECLARE_EQUALITY_COMPARABLE_NON_NOEXCEPT_3(__VA_ARGS__))
484#define QT_DECLARE_EQUALITY_COMPARABLE_NON_NOEXCEPT_5(...)
485 QT_VA_ARGS_EXPAND(QT_DECLARE_EQUALITY_COMPARABLE_NON_NOEXCEPT_3(__VA_ARGS__))
486#define QT_DECLARE_EQUALITY_COMPARABLE_NON_NOEXCEPT_6(...)
487 QT_VA_ARGS_EXPAND(QT_DECLARE_EQUALITY_COMPARABLE_NON_NOEXCEPT_3(__VA_ARGS__))
488#define QT_DECLARE_EQUALITY_COMPARABLE_NON_NOEXCEPT_7(...)
489 QT_VA_ARGS_EXPAND(QT_DECLARE_EQUALITY_COMPARABLE_NON_NOEXCEPT_3(__VA_ARGS__))
490#define QT_DECLARE_EQUALITY_COMPARABLE_NON_NOEXCEPT_8(...)
491 QT_VA_ARGS_EXPAND(QT_DECLARE_EQUALITY_COMPARABLE_NON_NOEXCEPT_3(__VA_ARGS__))
492#define QT_DECLARE_EQUALITY_COMPARABLE_NON_NOEXCEPT_9(...)
493 QT_VA_ARGS_EXPAND(QT_DECLARE_EQUALITY_COMPARABLE_NON_NOEXCEPT_3(__VA_ARGS__))
494
495#define Q_DECLARE_EQUALITY_COMPARABLE_NON_NOEXCEPT(...)
496 QT_OVERLOADED_MACRO(QT_DECLARE_EQUALITY_COMPARABLE_NON_NOEXCEPT, __VA_ARGS__)
497
498// Ordering operators that automatically deduce the strength:
499#define QT_DECLARE_ORDERED_1(Type)
500 QT_DECLARE_ORDERING_OPERATORS_HELPER(AUTO, Type, Type, /* non-constexpr */, noexcept(true),
501 /* no attributes */)
502
503#define QT_DECLARE_ORDERED_2(LeftType, RightType)
504 QT_DECLARE_ORDERING_OPERATORS_HELPER(AUTO, LeftType, RightType, /* non-constexpr */,
505 noexcept(true), /* no attributes */)
506 QT_DECLARE_ORDERING_OPERATORS_REVERSED_HELPER(AUTO, LeftType, RightType, /* non-constexpr */,
507 noexcept(true), /* no attributes */)
508
509#define QT_DECLARE_ORDERED_3(LeftType, RightType, ...)
510 QT_DECLARE_ORDERING_OPERATORS_HELPER(AUTO, LeftType, RightType, /* non-constexpr */,
511 noexcept(true), __VA_ARGS__)
512 QT_DECLARE_ORDERING_OPERATORS_REVERSED_HELPER(AUTO, LeftType, RightType, /* non-constexpr */,
513 noexcept(true), __VA_ARGS__)
514
515#define QT_DECLARE_ORDERED_4(...) QT_VA_ARGS_EXPAND(QT_DECLARE_ORDERED_3(__VA_ARGS__))
516#define QT_DECLARE_ORDERED_5(...) QT_VA_ARGS_EXPAND(QT_DECLARE_ORDERED_3(__VA_ARGS__))
517#define QT_DECLARE_ORDERED_6(...) QT_VA_ARGS_EXPAND(QT_DECLARE_ORDERED_3(__VA_ARGS__))
518#define QT_DECLARE_ORDERED_7(...) QT_VA_ARGS_EXPAND(QT_DECLARE_ORDERED_3(__VA_ARGS__))
519#define QT_DECLARE_ORDERED_8(...) QT_VA_ARGS_EXPAND(QT_DECLARE_ORDERED_3(__VA_ARGS__))
520#define QT_DECLARE_ORDERED_9(...) QT_VA_ARGS_EXPAND(QT_DECLARE_ORDERED_3(__VA_ARGS__))
521
522#define Q_DECLARE_ORDERED(...) QT_OVERLOADED_MACRO(QT_DECLARE_ORDERED, __VA_ARGS__)
523
524#define QT_DECLARE_ORDERED_LITERAL_TYPE_1(Type)
525 QT_DECLARE_ORDERING_OPERATORS_HELPER(AUTO, Type, Type, constexpr, noexcept(true),
526 /* no attributes */)
527
528#define QT_DECLARE_ORDERED_LITERAL_TYPE_2(LeftType, RightType)
529 QT_DECLARE_ORDERING_OPERATORS_HELPER(AUTO, LeftType, RightType, constexpr,
530 noexcept(true), /* no attributes */)
531 QT_DECLARE_ORDERING_OPERATORS_REVERSED_HELPER(AUTO, LeftType, RightType, constexpr,
532 noexcept(true), /* no attributes */)
533
534#define QT_DECLARE_ORDERED_LITERAL_TYPE_3(LeftType, RightType, ...)
535 QT_DECLARE_ORDERING_OPERATORS_HELPER(AUTO, LeftType, RightType, constexpr,
536 noexcept(true), __VA_ARGS__)
537 QT_DECLARE_ORDERING_OPERATORS_REVERSED_HELPER(AUTO, LeftType, RightType, constexpr,
538 noexcept(true), __VA_ARGS__)
539
540#define QT_DECLARE_ORDERED_LITERAL_TYPE_4(...)
541 QT_VA_ARGS_EXPAND(QT_DECLARE_ORDERED_LITERAL_TYPE_3(__VA_ARGS__))
542#define QT_DECLARE_ORDERED_LITERAL_TYPE_5(...)
543 QT_VA_ARGS_EXPAND(QT_DECLARE_ORDERED_LITERAL_TYPE_3(__VA_ARGS__))
544#define QT_DECLARE_ORDERED_LITERAL_TYPE_6(...)
545 QT_VA_ARGS_EXPAND(QT_DECLARE_ORDERED_LITERAL_TYPE_3(__VA_ARGS__))
546#define QT_DECLARE_ORDERED_LITERAL_TYPE_7(...)
547 QT_VA_ARGS_EXPAND(QT_DECLARE_ORDERED_LITERAL_TYPE_3(__VA_ARGS__))
548#define QT_DECLARE_ORDERED_LITERAL_TYPE_8(...)
549 QT_VA_ARGS_EXPAND(QT_DECLARE_ORDERED_LITERAL_TYPE_3(__VA_ARGS__))
550#define QT_DECLARE_ORDERED_LITERAL_TYPE_9(...)
551 QT_VA_ARGS_EXPAND(QT_DECLARE_ORDERED_LITERAL_TYPE_3(__VA_ARGS__))
552
553#define Q_DECLARE_ORDERED_LITERAL_TYPE(...)
554 QT_OVERLOADED_MACRO(QT_DECLARE_ORDERED_LITERAL_TYPE, __VA_ARGS__)
555
556#define QT_DECLARE_ORDERED_NON_NOEXCEPT_1(Type)
557 QT_DECLARE_ORDERING_OPERATORS_HELPER(AUTO, Type, Type, /* non-constexpr */, noexcept(false),
558 /* no attributes */)
559
560#define QT_DECLARE_ORDERED_NON_NOEXCEPT_2(LeftType, RightType)
561 QT_DECLARE_ORDERING_OPERATORS_HELPER(AUTO, LeftType, RightType, /* non-constexpr */,
562 noexcept(false), /* no attributes */)
563 QT_DECLARE_ORDERING_OPERATORS_REVERSED_HELPER(AUTO, LeftType, RightType, /* non-constexpr */,
564 noexcept(false), /* no attributes */)
565
566#define QT_DECLARE_ORDERED_NON_NOEXCEPT_3(LeftType, RightType, ...)
567 QT_DECLARE_ORDERING_OPERATORS_HELPER(AUTO, LeftType, RightType, /* non-constexpr */,
568 noexcept(false), __VA_ARGS__)
569 QT_DECLARE_ORDERING_OPERATORS_REVERSED_HELPER(AUTO, LeftType, RightType, /* non-constexpr */,
570 noexcept(false), __VA_ARGS__)
571
572#define QT_DECLARE_ORDERED_NON_NOEXCEPT_4(...)
573 QT_VA_ARGS_EXPAND(QT_DECLARE_ORDERED_NON_NOEXCEPT_3(__VA_ARGS__))
574#define QT_DECLARE_ORDERED_NON_NOEXCEPT_5(...)
575 QT_VA_ARGS_EXPAND(QT_DECLARE_ORDERED_NON_NOEXCEPT_3(__VA_ARGS__))
576#define QT_DECLARE_ORDERED_NON_NOEXCEPT_6(...)
577 QT_VA_ARGS_EXPAND(QT_DECLARE_ORDERED_NON_NOEXCEPT_3(__VA_ARGS__))
578#define QT_DECLARE_ORDERED_NON_NOEXCEPT_7(...)
579 QT_VA_ARGS_EXPAND(QT_DECLARE_ORDERED_NON_NOEXCEPT_3(__VA_ARGS__))
580#define QT_DECLARE_ORDERED_NON_NOEXCEPT_8(...)
581 QT_VA_ARGS_EXPAND(QT_DECLARE_ORDERED_NON_NOEXCEPT_3(__VA_ARGS__))
582#define QT_DECLARE_ORDERED_NON_NOEXCEPT_9(...)
583 QT_VA_ARGS_EXPAND(QT_DECLARE_ORDERED_NON_NOEXCEPT_3(__VA_ARGS__))
584
585#define Q_DECLARE_ORDERED_NON_NOEXCEPT(...)
586 QT_OVERLOADED_MACRO(QT_DECLARE_ORDERED_NON_NOEXCEPT, __VA_ARGS__)
587
588// Partial ordering operators
589#define QT_DECLARE_PARTIALLY_ORDERED_1(Type)
590 QT_DECLARE_ORDERING_OPERATORS_HELPER(PARTIAL, Type, Type, /* non-constexpr */,
591 noexcept(true), /* no attributes */)
592
593#define QT_DECLARE_PARTIALLY_ORDERED_2(LeftType, RightType)
594 QT_DECLARE_ORDERING_OPERATORS_HELPER(PARTIAL, LeftType, RightType, /* non-constexpr */,
595 noexcept(true), /* no attributes */)
596 QT_DECLARE_ORDERING_OPERATORS_REVERSED_HELPER(PARTIAL, LeftType, RightType,
597 /* non-constexpr */, noexcept(true),
598 /* no attributes */)
599
600#define QT_DECLARE_PARTIALLY_ORDERED_3(LeftType, RightType, ...)
601 QT_DECLARE_ORDERING_OPERATORS_HELPER(PARTIAL, LeftType, RightType, /* non-constexpr */,
602 noexcept(true), __VA_ARGS__)
603 QT_DECLARE_ORDERING_OPERATORS_REVERSED_HELPER(PARTIAL, LeftType, RightType,
604 /* non-constexpr */, noexcept(true), __VA_ARGS__)
605
606#define QT_DECLARE_PARTIALLY_ORDERED_4(...)
607 QT_VA_ARGS_EXPAND(QT_DECLARE_PARTIALLY_ORDERED_3(__VA_ARGS__))
608#define QT_DECLARE_PARTIALLY_ORDERED_5(...)
609 QT_VA_ARGS_EXPAND(QT_DECLARE_PARTIALLY_ORDERED_3(__VA_ARGS__))
610#define QT_DECLARE_PARTIALLY_ORDERED_6(...)
611 QT_VA_ARGS_EXPAND(QT_DECLARE_PARTIALLY_ORDERED_3(__VA_ARGS__))
612#define QT_DECLARE_PARTIALLY_ORDERED_7(...)
613 QT_VA_ARGS_EXPAND(QT_DECLARE_PARTIALLY_ORDERED_3(__VA_ARGS__))
614#define QT_DECLARE_PARTIALLY_ORDERED_8(...)
615 QT_VA_ARGS_EXPAND(QT_DECLARE_PARTIALLY_ORDERED_3(__VA_ARGS__))
616#define QT_DECLARE_PARTIALLY_ORDERED_9(...)
617 QT_VA_ARGS_EXPAND(QT_DECLARE_PARTIALLY_ORDERED_3(__VA_ARGS__))
618
619#define Q_DECLARE_PARTIALLY_ORDERED(...)
620 QT_OVERLOADED_MACRO(QT_DECLARE_PARTIALLY_ORDERED, __VA_ARGS__)
621
622#define QT_DECLARE_PARTIALLY_ORDERED_LITERAL_TYPE_1(Type)
623 QT_DECLARE_ORDERING_OPERATORS_HELPER(PARTIAL, Type, Type, constexpr, noexcept(true),
624 /* no attributes */)
625
626#define QT_DECLARE_PARTIALLY_ORDERED_LITERAL_TYPE_2(LeftType, RightType)
627 QT_DECLARE_ORDERING_OPERATORS_HELPER(PARTIAL, LeftType, RightType, constexpr,
628 noexcept(true), /* no attributes */)
629 QT_DECLARE_ORDERING_OPERATORS_REVERSED_HELPER(PARTIAL, LeftType, RightType, constexpr,
630 noexcept(true), /* no attributes */)
631
632#define QT_DECLARE_PARTIALLY_ORDERED_LITERAL_TYPE_3(LeftType, RightType, ...)
633 QT_DECLARE_ORDERING_OPERATORS_HELPER(PARTIAL, LeftType, RightType, constexpr, noexcept(true),
634 __VA_ARGS__)
635 QT_DECLARE_ORDERING_OPERATORS_REVERSED_HELPER(PARTIAL, LeftType, RightType, constexpr,
636 noexcept(true), __VA_ARGS__)
637
638#define QT_DECLARE_PARTIALLY_ORDERED_LITERAL_TYPE_4(...)
639 QT_VA_ARGS_EXPAND(QT_DECLARE_PARTIALLY_ORDERED_LITERAL_TYPE_3(__VA_ARGS__))
640#define QT_DECLARE_PARTIALLY_ORDERED_LITERAL_TYPE_5(...)
641 QT_VA_ARGS_EXPAND(QT_DECLARE_PARTIALLY_ORDERED_LITERAL_TYPE_3(__VA_ARGS__))
642#define QT_DECLARE_PARTIALLY_ORDERED_LITERAL_TYPE_6(...)
643 QT_VA_ARGS_EXPAND(QT_DECLARE_PARTIALLY_ORDERED_LITERAL_TYPE_3(__VA_ARGS__))
644#define QT_DECLARE_PARTIALLY_ORDERED_LITERAL_TYPE_7(...)
645 QT_VA_ARGS_EXPAND(QT_DECLARE_PARTIALLY_ORDERED_LITERAL_TYPE_3(__VA_ARGS__))
646#define QT_DECLARE_PARTIALLY_ORDERED_LITERAL_TYPE_8(...)
647 QT_VA_ARGS_EXPAND(QT_DECLARE_PARTIALLY_ORDERED_LITERAL_TYPE_3(__VA_ARGS__))
648#define QT_DECLARE_PARTIALLY_ORDERED_LITERAL_TYPE_9(...)
649 QT_VA_ARGS_EXPAND(QT_DECLARE_PARTIALLY_ORDERED_LITERAL_TYPE_3(__VA_ARGS__))
650
651#define Q_DECLARE_PARTIALLY_ORDERED_LITERAL_TYPE(...)
652 QT_OVERLOADED_MACRO(QT_DECLARE_PARTIALLY_ORDERED_LITERAL_TYPE, __VA_ARGS__)
653
654#define QT_DECLARE_PARTIALLY_ORDERED_NON_NOEXCEPT_1(Type)
655 QT_DECLARE_ORDERING_OPERATORS_HELPER(PARTIAL, Type, Type, /* non-constexpr */,
656 noexcept(false), /* no attributes */)
657
658#define QT_DECLARE_PARTIALLY_ORDERED_NON_NOEXCEPT_2(LeftType, RightType)
659 QT_DECLARE_ORDERING_OPERATORS_HELPER(PARTIAL, LeftType, RightType, /* non-constexpr */,
660 noexcept(false), /* no attributes */)
661 QT_DECLARE_ORDERING_OPERATORS_REVERSED_HELPER(PARTIAL, LeftType, RightType,
662 /* non-constexpr */, noexcept(false),
663 /* no attributes */)
664
665#define QT_DECLARE_PARTIALLY_ORDERED_NON_NOEXCEPT_3(LeftType, RightType, ...)
666 QT_DECLARE_ORDERING_OPERATORS_HELPER(PARTIAL, LeftType, RightType, /* non-constexpr */,
667 noexcept(false), __VA_ARGS__)
668 QT_DECLARE_ORDERING_OPERATORS_REVERSED_HELPER(PARTIAL, LeftType, RightType,
669 /* non-constexpr */, noexcept(false), __VA_ARGS__)
670
671#define QT_DECLARE_PARTIALLY_ORDERED_NON_NOEXCEPT_4(...)
672 QT_VA_ARGS_EXPAND(QT_DECLARE_PARTIALLY_ORDERED_NON_NOEXCEPT_3(__VA_ARGS__))
673#define QT_DECLARE_PARTIALLY_ORDERED_NON_NOEXCEPT_5(...)
674 QT_VA_ARGS_EXPAND(QT_DECLARE_PARTIALLY_ORDERED_NON_NOEXCEPT_3(__VA_ARGS__))
675#define QT_DECLARE_PARTIALLY_ORDERED_NON_NOEXCEPT_6(...)
676 QT_VA_ARGS_EXPAND(QT_DECLARE_PARTIALLY_ORDERED_NON_NOEXCEPT_3(__VA_ARGS__))
677#define QT_DECLARE_PARTIALLY_ORDERED_NON_NOEXCEPT_7(...)
678 QT_VA_ARGS_EXPAND(QT_DECLARE_PARTIALLY_ORDERED_NON_NOEXCEPT_3(__VA_ARGS__))
679#define QT_DECLARE_PARTIALLY_ORDERED_NON_NOEXCEPT_8(...)
680 QT_VA_ARGS_EXPAND(QT_DECLARE_PARTIALLY_ORDERED_NON_NOEXCEPT_3(__VA_ARGS__))
681#define QT_DECLARE_PARTIALLY_ORDERED_NON_NOEXCEPT_9(...)
682 QT_VA_ARGS_EXPAND(QT_DECLARE_PARTIALLY_ORDERED_NON_NOEXCEPT_3(__VA_ARGS__))
683
684#define Q_DECLARE_PARTIALLY_ORDERED_NON_NOEXCEPT(...)
685 QT_OVERLOADED_MACRO(QT_DECLARE_PARTIALLY_ORDERED_NON_NOEXCEPT, __VA_ARGS__)
686
687// Weak ordering operators
688#define QT_DECLARE_WEAKLY_ORDERED_1(Type)
689 QT_DECLARE_ORDERING_OPERATORS_HELPER(WEAK, Type, Type, /* non-constexpr */, noexcept(true),
690 /* no attributes */)
691
692#define QT_DECLARE_WEAKLY_ORDERED_2(LeftType, RightType)
693 QT_DECLARE_ORDERING_OPERATORS_HELPER(WEAK, LeftType, RightType, /* non-constexpr */,
694 noexcept(true), /* no attributes */)
695 QT_DECLARE_ORDERING_OPERATORS_REVERSED_HELPER(WEAK, LeftType, RightType, /* non-constexpr */,
696 noexcept(true), /* no attributes */)
697
698#define QT_DECLARE_WEAKLY_ORDERED_3(LeftType, RightType, ...)
699 QT_DECLARE_ORDERING_OPERATORS_HELPER(WEAK, LeftType, RightType, /* non-constexpr */,
700 noexcept(true), __VA_ARGS__)
701 QT_DECLARE_ORDERING_OPERATORS_REVERSED_HELPER(WEAK, LeftType, RightType, /* non-constexpr */,
702 noexcept(true), __VA_ARGS__)
703
704#define QT_DECLARE_WEAKLY_ORDERED_4(...)
705 QT_VA_ARGS_EXPAND(QT_DECLARE_WEAKLY_ORDERED_3(__VA_ARGS__))
706#define QT_DECLARE_WEAKLY_ORDERED_5(...)
707 QT_VA_ARGS_EXPAND(QT_DECLARE_WEAKLY_ORDERED_3(__VA_ARGS__))
708#define QT_DECLARE_WEAKLY_ORDERED_6(...)
709 QT_VA_ARGS_EXPAND(QT_DECLARE_WEAKLY_ORDERED_3(__VA_ARGS__))
710#define QT_DECLARE_WEAKLY_ORDERED_7(...)
711 QT_VA_ARGS_EXPAND(QT_DECLARE_WEAKLY_ORDERED_3(__VA_ARGS__))
712#define QT_DECLARE_WEAKLY_ORDERED_8(...)
713 QT_VA_ARGS_EXPAND(QT_DECLARE_WEAKLY_ORDERED_3(__VA_ARGS__))
714#define QT_DECLARE_WEAKLY_ORDERED_9(...)
715 QT_VA_ARGS_EXPAND(QT_DECLARE_WEAKLY_ORDERED_3(__VA_ARGS__))
716
717#define Q_DECLARE_WEAKLY_ORDERED(...)
718 QT_OVERLOADED_MACRO(QT_DECLARE_WEAKLY_ORDERED, __VA_ARGS__)
719
720#define QT_DECLARE_WEAKLY_ORDERED_LITERAL_TYPE_1(Type)
721 QT_DECLARE_ORDERING_OPERATORS_HELPER(WEAK, Type, Type, constexpr, noexcept(true),
722 /* no attributes */)
723
724#define QT_DECLARE_WEAKLY_ORDERED_LITERAL_TYPE_2(LeftType, RightType)
725 QT_DECLARE_ORDERING_OPERATORS_HELPER(WEAK, LeftType, RightType, constexpr,
726 noexcept(true), /* no attributes */)
727 QT_DECLARE_ORDERING_OPERATORS_REVERSED_HELPER(WEAK, LeftType, RightType, constexpr,
728 noexcept(true), /* no attributes */)
729
730#define QT_DECLARE_WEAKLY_ORDERED_LITERAL_TYPE_3(LeftType, RightType, ...)
731 QT_DECLARE_ORDERING_OPERATORS_HELPER(WEAK, LeftType, RightType, constexpr, noexcept(true),
732 __VA_ARGS__)
733 QT_DECLARE_ORDERING_OPERATORS_REVERSED_HELPER(WEAK, LeftType, RightType, constexpr,
734 noexcept(true), __VA_ARGS__)
735
736#define QT_DECLARE_WEAKLY_ORDERED_LITERAL_TYPE_4(...)
737 QT_VA_ARGS_EXPAND(QT_DECLARE_WEAKLY_ORDERED_LITERAL_TYPE_3(__VA_ARGS__))
738#define QT_DECLARE_WEAKLY_ORDERED_LITERAL_TYPE_5(...)
739 QT_VA_ARGS_EXPAND(QT_DECLARE_WEAKLY_ORDERED_LITERAL_TYPE_3(__VA_ARGS__))
740#define QT_DECLARE_WEAKLY_ORDERED_LITERAL_TYPE_6(...)
741 QT_VA_ARGS_EXPAND(QT_DECLARE_WEAKLY_ORDERED_LITERAL_TYPE_3(__VA_ARGS__))
742#define QT_DECLARE_WEAKLY_ORDERED_LITERAL_TYPE_7(...)
743 QT_VA_ARGS_EXPAND(QT_DECLARE_WEAKLY_ORDERED_LITERAL_TYPE_3(__VA_ARGS__))
744#define QT_DECLARE_WEAKLY_ORDERED_LITERAL_TYPE_8(...)
745 QT_VA_ARGS_EXPAND(QT_DECLARE_WEAKLY_ORDERED_LITERAL_TYPE_3(__VA_ARGS__))
746#define QT_DECLARE_WEAKLY_ORDERED_LITERAL_TYPE_9(...)
747 QT_VA_ARGS_EXPAND(QT_DECLARE_WEAKLY_ORDERED_LITERAL_TYPE_3(__VA_ARGS__))
748
749#define Q_DECLARE_WEAKLY_ORDERED_LITERAL_TYPE(...)
750 QT_OVERLOADED_MACRO(QT_DECLARE_WEAKLY_ORDERED_LITERAL_TYPE, __VA_ARGS__)
751
752#define QT_DECLARE_WEAKLY_ORDERED_NON_NOEXCEPT_1(Type)
753 QT_DECLARE_ORDERING_OPERATORS_HELPER(WEAK, Type, Type, /* non-constexpr */, noexcept(false),
754 /* no attributes */)
755
756#define QT_DECLARE_WEAKLY_ORDERED_NON_NOEXCEPT_2(LeftType, RightType)
757 QT_DECLARE_ORDERING_OPERATORS_HELPER(WEAK, LeftType, RightType, /* non-constexpr */,
758 noexcept(false), /* no attributes */)
759 QT_DECLARE_ORDERING_OPERATORS_REVERSED_HELPER(WEAK, LeftType, RightType, /* non-constexpr */,
760 noexcept(false), /* no attributes */)
761
762#define QT_DECLARE_WEAKLY_ORDERED_NON_NOEXCEPT_3(LeftType, RightType, ...)
763 QT_DECLARE_ORDERING_OPERATORS_HELPER(WEAK, LeftType, RightType, /* non-constexpr */,
764 noexcept(false), __VA_ARGS__)
765 QT_DECLARE_ORDERING_OPERATORS_REVERSED_HELPER(WEAK, LeftType, RightType, /* non-constexpr */,
766 noexcept(false), __VA_ARGS__)
767
768#define QT_DECLARE_WEAKLY_ORDERED_NON_NOEXCEPT_4(...)
769 QT_VA_ARGS_EXPAND(QT_DECLARE_WEAKLY_ORDERED_NON_NOEXCEPT_3(__VA_ARGS__))
770#define QT_DECLARE_WEAKLY_ORDERED_NON_NOEXCEPT_5(...)
771 QT_VA_ARGS_EXPAND(QT_DECLARE_WEAKLY_ORDERED_NON_NOEXCEPT_3(__VA_ARGS__))
772#define QT_DECLARE_WEAKLY_ORDERED_NON_NOEXCEPT_6(...)
773 QT_VA_ARGS_EXPAND(QT_DECLARE_WEAKLY_ORDERED_NON_NOEXCEPT_3(__VA_ARGS__))
774#define QT_DECLARE_WEAKLY_ORDERED_NON_NOEXCEPT_7(...)
775 QT_VA_ARGS_EXPAND(QT_DECLARE_WEAKLY_ORDERED_NON_NOEXCEPT_3(__VA_ARGS__))
776#define QT_DECLARE_WEAKLY_ORDERED_NON_NOEXCEPT_8(...)
777 QT_VA_ARGS_EXPAND(QT_DECLARE_WEAKLY_ORDERED_NON_NOEXCEPT_3(__VA_ARGS__))
778#define QT_DECLARE_WEAKLY_ORDERED_NON_NOEXCEPT_9(...)
779 QT_VA_ARGS_EXPAND(QT_DECLARE_WEAKLY_ORDERED_NON_NOEXCEPT_3(__VA_ARGS__))
780
781#define Q_DECLARE_WEAKLY_ORDERED_NON_NOEXCEPT(...)
782 QT_OVERLOADED_MACRO(QT_DECLARE_WEAKLY_ORDERED_NON_NOEXCEPT, __VA_ARGS__)
783
784// Strong ordering operators
785#define QT_DECLARE_STRONGLY_ORDERED_1(Type)
786 QT_DECLARE_ORDERING_OPERATORS_HELPER(STRONG, Type, Type, /* non-constexpr */,
787 noexcept(true), /* no attributes */)
788
789#define QT_DECLARE_STRONGLY_ORDERED_2(LeftType, RightType)
790 QT_DECLARE_ORDERING_OPERATORS_HELPER(STRONG, LeftType, RightType, /* non-constexpr */,
791 noexcept(true), /* no attributes */)
792 QT_DECLARE_ORDERING_OPERATORS_REVERSED_HELPER(STRONG, LeftType, RightType,
793 /* non-constexpr */, noexcept(true),
794 /* no attributes */)
795
796#define QT_DECLARE_STRONGLY_ORDERED_3(LeftType, RightType, ...)
797 QT_DECLARE_ORDERING_OPERATORS_HELPER(STRONG, LeftType, RightType, /* non-constexpr */,
798 noexcept(true), __VA_ARGS__)
799 QT_DECLARE_ORDERING_OPERATORS_REVERSED_HELPER(STRONG, LeftType, RightType,
800 /* non-constexpr */, noexcept(true), __VA_ARGS__)
801
802#define QT_DECLARE_STRONGLY_ORDERED_4(...)
803 QT_VA_ARGS_EXPAND(QT_DECLARE_STRONGLY_ORDERED_3(__VA_ARGS__))
804#define QT_DECLARE_STRONGLY_ORDERED_5(...)
805 QT_VA_ARGS_EXPAND(QT_DECLARE_STRONGLY_ORDERED_3(__VA_ARGS__))
806#define QT_DECLARE_STRONGLY_ORDERED_6(...)
807 QT_VA_ARGS_EXPAND(QT_DECLARE_STRONGLY_ORDERED_3(__VA_ARGS__))
808#define QT_DECLARE_STRONGLY_ORDERED_7(...)
809 QT_VA_ARGS_EXPAND(QT_DECLARE_STRONGLY_ORDERED_3(__VA_ARGS__))
810#define QT_DECLARE_STRONGLY_ORDERED_8(...)
811 QT_VA_ARGS_EXPAND(QT_DECLARE_STRONGLY_ORDERED_3(__VA_ARGS__))
812#define QT_DECLARE_STRONGLY_ORDERED_9(...)
813 QT_VA_ARGS_EXPAND(QT_DECLARE_STRONGLY_ORDERED_3(__VA_ARGS__))
814
815#define Q_DECLARE_STRONGLY_ORDERED(...)
816 QT_OVERLOADED_MACRO(QT_DECLARE_STRONGLY_ORDERED, __VA_ARGS__)
817
818#define QT_DECLARE_STRONGLY_ORDERED_LITERAL_TYPE_1(Type)
819 QT_DECLARE_ORDERING_OPERATORS_HELPER(STRONG, Type, Type, constexpr, noexcept(true),
820 /* no attributes */)
821
822#define QT_DECLARE_STRONGLY_ORDERED_LITERAL_TYPE_2(LeftType, RightType)
823 QT_DECLARE_ORDERING_OPERATORS_HELPER(STRONG, LeftType, RightType, constexpr,
824 noexcept(true), /* no attributes */)
825 QT_DECLARE_ORDERING_OPERATORS_REVERSED_HELPER(STRONG, LeftType, RightType, constexpr,
826 noexcept(true), /* no attributes */)
827
828#define QT_DECLARE_STRONGLY_ORDERED_LITERAL_TYPE_3(LeftType, RightType, ...)
829 QT_DECLARE_ORDERING_OPERATORS_HELPER(STRONG, LeftType, RightType, constexpr, noexcept(true),
830 __VA_ARGS__)
831 QT_DECLARE_ORDERING_OPERATORS_REVERSED_HELPER(STRONG, LeftType, RightType, constexpr,
832 noexcept(true), __VA_ARGS__)
833
834#define QT_DECLARE_STRONGLY_ORDERED_LITERAL_TYPE_4(...)
835 QT_VA_ARGS_EXPAND(QT_DECLARE_STRONGLY_ORDERED_LITERAL_TYPE_3(__VA_ARGS__))
836#define QT_DECLARE_STRONGLY_ORDERED_LITERAL_TYPE_5(...)
837 QT_VA_ARGS_EXPAND(QT_DECLARE_STRONGLY_ORDERED_LITERAL_TYPE_3(__VA_ARGS__))
838#define QT_DECLARE_STRONGLY_ORDERED_LITERAL_TYPE_6(...)
839 QT_VA_ARGS_EXPAND(QT_DECLARE_STRONGLY_ORDERED_LITERAL_TYPE_3(__VA_ARGS__))
840#define QT_DECLARE_STRONGLY_ORDERED_LITERAL_TYPE_7(...)
841 QT_VA_ARGS_EXPAND(QT_DECLARE_STRONGLY_ORDERED_LITERAL_TYPE_3(__VA_ARGS__))
842#define QT_DECLARE_STRONGLY_ORDERED_LITERAL_TYPE_8(...)
843 QT_VA_ARGS_EXPAND(QT_DECLARE_STRONGLY_ORDERED_LITERAL_TYPE_3(__VA_ARGS__))
844#define QT_DECLARE_STRONGLY_ORDERED_LITERAL_TYPE_9(...)
845 QT_VA_ARGS_EXPAND(QT_DECLARE_STRONGLY_ORDERED_LITERAL_TYPE_3(__VA_ARGS__))
846
847#define Q_DECLARE_STRONGLY_ORDERED_LITERAL_TYPE(...)
848 QT_OVERLOADED_MACRO(QT_DECLARE_STRONGLY_ORDERED_LITERAL_TYPE, __VA_ARGS__)
849
850#define QT_DECLARE_STRONGLY_ORDERED_NON_NOEXCEPT_1(Type)
851 QT_DECLARE_ORDERING_OPERATORS_HELPER(STRONG, Type, Type, /* non-constexpr */,
852 noexcept(false), /* no attributes */)
853
854#define QT_DECLARE_STRONGLY_ORDERED_NON_NOEXCEPT_2(LeftType, RightType)
855 QT_DECLARE_ORDERING_OPERATORS_HELPER(STRONG, LeftType, RightType, /* non-constexpr */,
856 noexcept(false), /* no attributes */)
857 QT_DECLARE_ORDERING_OPERATORS_REVERSED_HELPER(STRONG, LeftType, RightType,
858 /* non-constexpr */, noexcept(false),
859 /* no attributes */)
860
861#define QT_DECLARE_STRONGLY_ORDERED_NON_NOEXCEPT_3(LeftType, RightType, ...)
862 QT_DECLARE_ORDERING_OPERATORS_HELPER(STRONG, LeftType, RightType, /* non-constexpr */,
863 noexcept(false), __VA_ARGS__)
864 QT_DECLARE_ORDERING_OPERATORS_REVERSED_HELPER(STRONG, LeftType, RightType,
865 /* non-constexpr */, noexcept(false), __VA_ARGS__)
866
867#define QT_DECLARE_STRONGLY_ORDERED_NON_NOEXCEPT_4(...)
868 QT_VA_ARGS_EXPAND(QT_DECLARE_STRONGLY_ORDERED_NON_NOEXCEPT_3(__VA_ARGS__))
869#define QT_DECLARE_STRONGLY_ORDERED_NON_NOEXCEPT_5(...)
870 QT_VA_ARGS_EXPAND(QT_DECLARE_STRONGLY_ORDERED_NON_NOEXCEPT_3(__VA_ARGS__))
871#define QT_DECLARE_STRONGLY_ORDERED_NON_NOEXCEPT_6(...)
872 QT_VA_ARGS_EXPAND(QT_DECLARE_STRONGLY_ORDERED_NON_NOEXCEPT_3(__VA_ARGS__))
873#define QT_DECLARE_STRONGLY_ORDERED_NON_NOEXCEPT_7(...)
874 QT_VA_ARGS_EXPAND(QT_DECLARE_STRONGLY_ORDERED_NON_NOEXCEPT_3(__VA_ARGS__))
875#define QT_DECLARE_STRONGLY_ORDERED_NON_NOEXCEPT_8(...)
876 QT_VA_ARGS_EXPAND(QT_DECLARE_STRONGLY_ORDERED_NON_NOEXCEPT_3(__VA_ARGS__))
877#define QT_DECLARE_STRONGLY_ORDERED_NON_NOEXCEPT_9(...)
878 QT_VA_ARGS_EXPAND(QT_DECLARE_STRONGLY_ORDERED_NON_NOEXCEPT_3(__VA_ARGS__))
879
880#define Q_DECLARE_STRONGLY_ORDERED_NON_NOEXCEPT(...)
881 QT_OVERLOADED_MACRO(QT_DECLARE_STRONGLY_ORDERED_NON_NOEXCEPT, __VA_ARGS__)
882
883namespace QtPrivate {
884
885template <typename T>
888
889template <typename T>
891
892#if QFLOAT16_IS_NATIVE
893template <>
894inline constexpr bool IsFloatType_v<QtPrivate::NativeFloat16Type> = true;
895#endif
896
897} // namespace QtPrivate
898
899namespace QtOrderingPrivate {
900
901template <typename T, typename U>
902constexpr Qt::strong_ordering
904{
905#ifdef __cpp_lib_three_way_comparison
906 return lhs <=> rhs;
907#else
908 if (lhs == rhs)
909 return Qt::strong_ordering::equivalent;
910 else if (lhs < rhs)
911 return Qt::strong_ordering::less;
912 else
913 return Qt::strong_ordering::greater;
914#endif // __cpp_lib_three_way_comparison
915}
916
917} // namespace QtOrderingPrivate
918
919namespace Qt {
920
921template <typename T>
923
924template <typename T>
926
927template <typename T, typename U>
930 std::is_base_of<T, U>,
931 std::is_base_of<U, T>>,
932 bool>;
933
934template <typename Enum>
936
937template <typename LeftInt, typename RightInt,
938 if_integral<LeftInt> = true,
939 if_integral<RightInt> = true>
940constexpr Qt::strong_ordering compareThreeWay(LeftInt lhs, RightInt rhs) noexcept
941{
942 static_assert(std::is_signed_v<LeftInt> == std::is_signed_v<RightInt>,
943 "Qt::compareThreeWay() does not allow mixed-sign comparison.");
944
945#ifdef __cpp_lib_three_way_comparison
946 return lhs <=> rhs;
947#else
948 if (lhs == rhs)
949 return Qt::strong_ordering::equivalent;
950 else if (lhs < rhs)
951 return Qt::strong_ordering::less;
952 else
953 return Qt::strong_ordering::greater;
954#endif // __cpp_lib_three_way_comparison
955}
956
957template <typename LeftFloat, typename RightFloat,
958 if_floating_point<LeftFloat> = true,
959 if_floating_point<RightFloat> = true>
960constexpr Qt::partial_ordering compareThreeWay(LeftFloat lhs, RightFloat rhs) noexcept
961{
962QT_WARNING_PUSH
963QT_WARNING_DISABLE_FLOAT_COMPARE
964#ifdef __cpp_lib_three_way_comparison
965 return lhs <=> rhs;
966#else
967 if (lhs < rhs)
968 return Qt::partial_ordering::less;
969 else if (lhs > rhs)
970 return Qt::partial_ordering::greater;
971 else if (lhs == rhs)
972 return Qt::partial_ordering::equivalent;
973 else
974 return Qt::partial_ordering::unordered;
975#endif // __cpp_lib_three_way_comparison
976QT_WARNING_POP
977}
978
979template <typename IntType, typename FloatType,
980 if_integral<IntType> = true,
981 if_floating_point<FloatType> = true>
982constexpr Qt::partial_ordering compareThreeWay(IntType lhs, FloatType rhs) noexcept
983{
984 return compareThreeWay(FloatType(lhs), rhs);
985}
986
987template <typename FloatType, typename IntType,
988 if_floating_point<FloatType> = true,
989 if_integral<IntType> = true>
990constexpr Qt::partial_ordering compareThreeWay(FloatType lhs, IntType rhs) noexcept
991{
992 return compareThreeWay(lhs, FloatType(rhs));
993}
994
995#if QT_DEPRECATED_SINCE(6, 8)
996
997template <typename LeftType, typename RightType,
999QT_DEPRECATED_VERSION_X_6_8("Wrap the pointers into Qt::totally_ordered_wrapper and use the respective overload instead.")
1000constexpr Qt::strong_ordering compareThreeWay(const LeftType *lhs, const RightType *rhs) noexcept
1001{
1002#ifdef __cpp_lib_three_way_comparison
1003 return std::compare_three_way{}(lhs, rhs);
1004#else
1005 if (lhs == rhs)
1006 return Qt::strong_ordering::equivalent;
1007 else if (std::less<>{}(lhs, rhs))
1008 return Qt::strong_ordering::less;
1009 else
1010 return Qt::strong_ordering::greater;
1011#endif // __cpp_lib_three_way_comparison
1012}
1013
1014template <typename T>
1015QT_DEPRECATED_VERSION_X_6_8("Wrap the pointer into Qt::totally_ordered_wrapper and use the respective overload instead.")
1016constexpr Qt::strong_ordering compareThreeWay(const T *lhs, std::nullptr_t rhs) noexcept
1017{
1018 return compareThreeWay(lhs, static_cast<const T *>(rhs));
1019}
1020
1021template <typename T>
1022QT_DEPRECATED_VERSION_X_6_8("Wrap the pointer into Qt::totally_ordered_wrapper and use the respective overload instead.")
1023constexpr Qt::strong_ordering compareThreeWay(std::nullptr_t lhs, const T *rhs) noexcept
1024{
1025 return compareThreeWay(static_cast<const T *>(lhs), rhs);
1026}
1027
1028#endif // QT_DEPRECATED_SINCE(6, 8)
1029
1030template <class Enum, if_enum<Enum> = true>
1031constexpr Qt::strong_ordering compareThreeWay(Enum lhs, Enum rhs) noexcept
1032{
1033 return compareThreeWay(qToUnderlying(lhs), qToUnderlying(rhs));
1034}
1035} // namespace Qt
1036
1037namespace QtOrderingPrivate {
1038
1039template <typename Head, typename...Tail, std::size_t...Is>
1040constexpr std::tuple<Tail...> qt_tuple_pop_front_impl(const std::tuple<Head, Tail...> &t,
1041 std::index_sequence<Is...>) noexcept
1042{
1043 return std::tuple<Tail...>(std::get<Is + 1>(t)...);
1044}
1045
1046template <typename Head, typename...Tail>
1047constexpr std::tuple<Tail...> qt_tuple_pop_front(const std::tuple<Head, Tail...> &t) noexcept
1048{
1049 return qt_tuple_pop_front_impl(t, std::index_sequence_for<Tail...>{});
1050}
1051
1052template <typename LhsHead, typename...LhsTail, typename RhsHead, typename...RhsTail>
1053constexpr auto compareThreeWayMulti(const std::tuple<LhsHead, LhsTail...> &lhs, // ie. not empty
1054 const std::tuple<RhsHead, RhsTail...> &rhs) noexcept
1055{
1056 static_assert(sizeof...(LhsTail) == sizeof...(RhsTail),
1057 // expanded together below, but provide a nicer error message:
1058 "The tuple arguments have to have the same size.");
1059
1060 using Qt::compareThreeWay;
1061 using R = std::common_type_t<
1062 decltype(compareThreeWay(std::declval<LhsHead>(), std::declval<RhsHead>())),
1063 decltype(compareThreeWay(std::declval<LhsTail>(), std::declval<RhsTail>()))...
1064 >;
1065
1066 const auto &l = std::get<0>(lhs);
1067 const auto &r = std::get<0>(rhs);
1068 static_assert(noexcept(compareThreeWay(l, r)),
1069 "This function requires all relational operators to be noexcept.");
1070 const auto res = compareThreeWay(l, r);
1071 if constexpr (sizeof...(LhsTail) > 0) {
1072 if (is_eq(res))
1073 return R{compareThreeWayMulti(qt_tuple_pop_front(lhs), qt_tuple_pop_front(rhs))};
1074 }
1075 return R{res};
1076}
1077
1078} //QtOrderingPrivate
1079
1080namespace Qt {
1081// A wrapper class that adapts the wrappee to use the strongly-ordered
1082// <functional> function objects for implementing the relational operators.
1083// Mostly useful to avoid UB on pointers (which it currently mandates P to be),
1084// because all the comparison helpers (incl. std::compare_three_way on
1085// std::tuple<T*>!) will use the language-level operators.
1086//
1087template <typename P>
1089{
1090 static_assert(std::is_pointer_v<P>);
1091 using T = std::remove_pointer_t<P>;
1092
1093 P ptr;
1094public:
1095 totally_ordered_wrapper() noexcept = default;
1097 // requires std::is_pointer_v<P>
1098 : totally_ordered_wrapper(P{nullptr}) {}
1099 explicit constexpr totally_ordered_wrapper(P p) noexcept : ptr(p) {}
1100
1101 constexpr P get() const noexcept { return ptr; }
1102 constexpr void reset(P p) noexcept { ptr = p; }
1103 constexpr P operator->() const noexcept { return get(); }
1104 template <typename U = T, std::enable_if_t<!std::is_void_v<U>, bool> = true>
1105 constexpr U &operator*() const noexcept { return *get(); }
1106
1107 explicit constexpr operator bool() const noexcept { return get(); }
1108
1109private:
1110 // TODO: Replace the constraints with std::common_type_t<P, U> when
1111 // a bug in VxWorks is fixed!
1112 template <typename T, typename U>
1113 using if_compatible_types =
1115 std::is_pointer<U>,
1117 std::is_convertible<U, T>>>,
1118 bool>;
1119
1120#define MAKE_RELOP(Ret, op, Op)
1121 template <typename U = P, if_compatible_types<P, U> = true>
1122 friend constexpr Ret operator op (const totally_ordered_wrapper<P> &lhs, const totally_ordered_wrapper<U> &rhs) noexcept
1123 { return std:: Op {}(lhs.ptr, rhs.get()); }
1124 template <typename U = P, if_compatible_types<P, U> = true>
1125 friend constexpr Ret operator op (const totally_ordered_wrapper<P> &lhs, const U &rhs) noexcept
1126 { return std:: Op {}(lhs.ptr, rhs ); }
1127 template <typename U = P, if_compatible_types<P, U> = true>
1128 friend constexpr Ret operator op (const U &lhs, const totally_ordered_wrapper<P> &rhs) noexcept
1129 { return std:: Op {}(lhs, rhs.ptr); }
1130 friend constexpr Ret operator op (const totally_ordered_wrapper &lhs, std::nullptr_t) noexcept
1131 { return std:: Op {}(lhs.ptr, P(nullptr)); }
1132 friend constexpr Ret operator op (std::nullptr_t, const totally_ordered_wrapper &rhs) noexcept
1133 { return std:: Op {}(P(nullptr), rhs.ptr); }
1134 /* end */
1135 MAKE_RELOP(bool, ==, equal_to<>)
1136 MAKE_RELOP(bool, !=, not_equal_to<>)
1137 MAKE_RELOP(bool, < , less<>)
1138 MAKE_RELOP(bool, <=, less_equal<>)
1139 MAKE_RELOP(bool, > , greater<>)
1140 MAKE_RELOP(bool, >=, greater_equal<>)
1141#ifdef __cpp_lib_three_way_comparison
1142 MAKE_RELOP(auto, <=>, compare_three_way)
1143#endif
1144#undef MAKE_RELOP
1146 { qt_ptr_swap(lhs.ptr, rhs.ptr); }
1148 { qt_ptr_swap(lhs, rhs); }
1149 friend size_t qHash(totally_ordered_wrapper key, size_t seed = 0) noexcept
1150 { return qHash(key.ptr, seed); }
1151};
1152
1153template <typename T, typename U, if_compatible_pointers<T, U> = true>
1154constexpr Qt::strong_ordering
1156{
1157 return QtOrderingPrivate::strongOrderingCompareDefaultImpl(lhs, rhs);
1158}
1159
1160template <typename T, typename U, if_compatible_pointers<T, U> = true>
1161constexpr Qt::strong_ordering
1163{
1164 return QtOrderingPrivate::strongOrderingCompareDefaultImpl(lhs, rhs);
1165}
1166
1167template <typename T, typename U, if_compatible_pointers<T, U> = true>
1168constexpr Qt::strong_ordering
1170{
1171 return QtOrderingPrivate::strongOrderingCompareDefaultImpl(lhs, rhs);
1172}
1173
1174template <typename T>
1175constexpr Qt::strong_ordering
1176compareThreeWay(Qt::totally_ordered_wrapper<T*> lhs, std::nullptr_t rhs) noexcept
1177{
1178 return QtOrderingPrivate::strongOrderingCompareDefaultImpl(lhs, rhs);
1179}
1180
1181template <typename T>
1182constexpr Qt::strong_ordering
1183compareThreeWay(std::nullptr_t lhs, Qt::totally_ordered_wrapper<T*> rhs) noexcept
1184{
1185 return QtOrderingPrivate::strongOrderingCompareDefaultImpl(lhs, rhs);
1186}
1187
1188} //Qt
1189
1190template <typename P>
1192
1193namespace QtOrderingPrivate {
1194
1195QT_WARNING_PUSH
1196QT_WARNING_DISABLE_DEPRECATED // don't warn _here_ in case we hit the deprecated ptr/ptr overloads
1197
1199
1200using Qt::compareThreeWay;
1201
1202template <typename T>
1204
1205// Check if compareThreeWay is implemented for the (LT, RT) argument
1206// pair.
1207template <typename LT, typename RT, typename = void>
1209
1210template <typename LT, typename RT>
1212 LT, RT, std::void_t<decltype(compareThreeWay(std::declval<LT>(), std::declval<RT>()))>
1213 > : std::true_type {};
1214
1215template <typename LT, typename RT>
1217 LT*, RT*,
1219 std::declval<WrappedType<RT>>()))>
1220 > : std::true_type {};
1221
1222template <typename LT, typename RT>
1224
1225// Check if the operation is noexcept. We have two different overloads,
1226// depending on the available compareThreeWay() implementation.
1227// Both are declared, but not implemented. To be used only in unevaluated
1228// context.
1229
1230template <typename LT, typename RT,
1231 std::enable_if_t<hasCompareThreeWay_v<LT, RT>, bool> = true>
1232constexpr bool compareThreeWayNoexcept() noexcept
1233{ return noexcept(compareThreeWay(std::declval<LT>(), std::declval<RT>())); }
1234
1235template <typename LT, typename RT,
1238 bool> = true>
1239constexpr bool compareThreeWayNoexcept() noexcept
1240{ return noexcept(compareThreeWay(std::declval<RT>(), std::declval<LT>())); }
1241
1242} // namespace CompareThreeWayTester
1243
1244QT_WARNING_POP // QT_WARNING_DISABLE_DEPRECATED
1245
1246#ifdef __cpp_lib_three_way_comparison
1247[[maybe_unused]] inline constexpr struct { /* Niebloid */
1248 template <typename LT, typename RT = LT>
1249 [[maybe_unused]] constexpr auto operator()(const LT &lhs, const RT &rhs) const
1250 {
1251 // like [expos.only.entity]/2
1253 return lhs <=> rhs;
1254 } else {
1255 if (lhs < rhs)
1256 return std::weak_ordering::less;
1257 if (rhs < lhs)
1258 return std::weak_ordering::greater;
1259 return std::weak_ordering::equivalent;
1260 }
1261 }
1263
1264template <typename Container, typename T>
1269 bool>;
1270#endif // __cpp_lib_three_way_comparison
1271
1272// These checks do not use Qt::compareThreeWay(), so only work for user-defined
1273// compareThreeWay() helper functions.
1274// We cannot use the same condition as in CompareThreeWayTester::hasCompareThreeWay,
1275// because GCC seems to cache and re-use the result.
1276// Created https://gcc.gnu.org/bugzilla/show_bug.cgi?id=117174
1277// For now, modify the condition a bit without changing its meaning.
1278template <typename LT, typename RT = LT, typename = void>
1280
1281template <typename LT, typename RT>
1283 LT, RT,
1284 std::void_t<decltype(is_eq(compareThreeWay(std::declval<LT>(), std::declval<RT>())))>
1285 > : std::true_type {};
1286
1287template <typename InputIt1, typename InputIt2, typename Compare>
1288auto lexicographicalCompareThreeWay(InputIt1 first1, InputIt1 last1,
1289 InputIt2 first2, InputIt2 last2,
1290 Compare cmp)
1291{
1292 using R = decltype(cmp(*first1, *first2));
1293
1294 while (first1 != last1) {
1295 if (first2 == last2)
1296 return R::greater;
1297 const auto r = cmp(*first1, *first2);
1298 if (is_neq(r))
1299 return r;
1300 ++first1;
1301 ++first2;
1302 }
1303 return first2 == last2 ? R::equivalent : R::less;
1304}
1305
1306template <typename InputIt1, typename InputIt2>
1307auto lexicographicalCompareThreeWay(InputIt1 first1, InputIt1 last1,
1308 InputIt2 first2, InputIt2 last2)
1309{
1310 using LT = typename std::iterator_traits<InputIt1>::value_type;
1311 using RT = typename std::iterator_traits<InputIt2>::value_type;
1312
1313 // if LT && RT are pointers, and there is no user-defined compareThreeWay()
1314 // operation for the pointers, we need to wrap them into
1315 // Qt::totally_ordered_wrapper.
1316 constexpr bool UseWrapper =
1317 std::conjunction_v<std::is_pointer<LT>, std::is_pointer<RT>,
1318 std::negation<HasCustomCompareThreeWay<LT, RT>>,
1319 std::negation<HasCustomCompareThreeWay<RT, LT>>>;
1320 using WrapLT = std::conditional_t<UseWrapper,
1321 Qt::totally_ordered_wrapper<LT>,
1322 const LT &>;
1323 using WrapRT = std::conditional_t<UseWrapper,
1324 Qt::totally_ordered_wrapper<RT>,
1325 const RT &>;
1326
1327 auto cmp = [](LT const &lhs, RT const &rhs) {
1328 using Qt::compareThreeWay;
1329 namespace Test = QtOrderingPrivate::CompareThreeWayTester;
1330 // Need this because the user might provide only
1331 // compareThreeWay(LT, RT), but not the reversed version.
1332 if constexpr (Test::hasCompareThreeWay_v<WrapLT, WrapRT>)
1333 return compareThreeWay(WrapLT(lhs), WrapRT(rhs));
1334 else
1335 return QtOrderingPrivate::reversed(compareThreeWay(WrapRT(rhs), WrapLT(lhs)));
1336 };
1337 return lexicographicalCompareThreeWay(first1, last1, first2, last2, cmp);
1338}
1339
1340} // namespace QtOrderingPrivate
1341
1342namespace Qt {
1343
1344template <typename T, typename U>
1349 bool>;
1350
1351} // namespace Qt
1352
1353QT_END_NAMESPACE
1354
1355namespace std {
1356 template <typename P>
1364}
1365
1366#endif // QCOMPAREHELPERS_H
\inmodule QtCore \inheaderfile QtCompare
constexpr void reset(P p) noexcept
totally_ordered_wrapper() noexcept=default
constexpr operator bool() const noexcept
friend void qt_ptr_swap(totally_ordered_wrapper &lhs, totally_ordered_wrapper &rhs) noexcept
friend void swap(totally_ordered_wrapper &lhs, totally_ordered_wrapper &rhs) noexcept
constexpr U & operator*() const noexcept
constexpr P get() const noexcept
constexpr P operator->() const noexcept
friend size_t qHash(totally_ordered_wrapper key, size_t seed=0) noexcept
constexpr totally_ordered_wrapper(P p) noexcept
constexpr bool compareThreeWayNoexcept() noexcept
auto lexicographicalCompareThreeWay(InputIt1 first1, InputIt1 last1, InputIt2 first2, InputIt2 last2)
constexpr std::tuple< Tail... > qt_tuple_pop_front(const std::tuple< Head, Tail... > &t) noexcept
auto lexicographicalCompareThreeWay(InputIt1 first1, InputIt1 last1, InputIt2 first2, InputIt2 last2, Compare cmp)
constexpr auto compareThreeWayMulti(const std::tuple< LhsHead, LhsTail... > &lhs, const std::tuple< RhsHead, RhsTail... > &rhs) noexcept
constexpr std::tuple< Tail... > qt_tuple_pop_front_impl(const std::tuple< Head, Tail... > &t, std::index_sequence< Is... >) noexcept
constexpr std::enable_if_t< is_qt_ordering_type_v< T >, QtOrderingTypeFlag > orderingFlagsFor(T t) noexcept
constexpr bool is_std_ordering_type_v
constexpr Qt::strong_ordering strongOrderingCompareDefaultImpl(T lhs, U rhs) noexcept
constexpr bool is_qt_ordering_type_v
constexpr bool IsFloatType_v
constexpr bool IsIntegralType_v
Definition qcompare.h:111
constexpr Qt::strong_ordering compareThreeWay(Enum lhs, Enum rhs) noexcept
constexpr Qt::strong_ordering compareThreeWay(Qt::totally_ordered_wrapper< T * > lhs, Qt::totally_ordered_wrapper< U * > rhs) noexcept
constexpr Qt::strong_ordering compareThreeWay(std::nullptr_t lhs, Qt::totally_ordered_wrapper< T * > rhs) noexcept
constexpr Qt::strong_ordering compareThreeWay(LeftInt lhs, RightInt rhs) noexcept
constexpr Qt::strong_ordering compareThreeWay(U *lhs, Qt::totally_ordered_wrapper< T * > rhs) noexcept
constexpr Qt::strong_ordering compareThreeWay(Qt::totally_ordered_wrapper< T * > lhs, std::nullptr_t rhs) noexcept
constexpr Qt::strong_ordering compareThreeWay(Qt::totally_ordered_wrapper< T * > lhs, U *rhs) noexcept
#define QT_DECLARE_PARTIALLY_ORDERED_LITERAL_TYPE_3(LeftType, RightType,...)
#define QT_DECLARE_ORDERING_OPERATORS_HELPER(OrderingString, LeftType, RightType, Constexpr, Noexcept,...)
#define QT_DECLARE_EQUALITY_OPERATORS_HELPER(LeftType, RightType, Constexpr, Noexcept,...)
#define QT_DECLARE_PARTIALLY_ORDERED_3(LeftType, RightType,...)
#define QT_DECLARE_PARTIALLY_ORDERED_NON_NOEXCEPT_3(LeftType, RightType,...)
#define QT_DECLARE_WEAKLY_ORDERED_LITERAL_TYPE_3(LeftType, RightType,...)
#define QT_DECLARE_WEAKLY_ORDERED_NON_NOEXCEPT_3(LeftType, RightType,...)
#define QT_DECLARE_ORDERED_NON_NOEXCEPT_3(LeftType, RightType,...)
#define QT_DECLARE_ORDERED_LITERAL_TYPE_3(LeftType, RightType,...)
#define QT_DECLARE_ORDERING_OPERATORS_REVERSED_HELPER(OrderingString, LeftType, RightType, Constexpr, Noexcept,...)
#define QT_DECLARE_EQUALITY_COMPARABLE_NON_NOEXCEPT_3(LeftType, RightType,...)
#define QT_DECLARE_EQUALITY_COMPARABLE_LITERAL_TYPE_3(LeftType, RightType,...)
#define QT_DECLARE_STRONGLY_ORDERED_LITERAL_TYPE_3(LeftType, RightType,...)
#define QT_COMPARISON_NOEXCEPT_CHECK(Noexcept, Func)
#define QT_DECLARE_EQUALITY_COMPARABLE_3(LeftType, RightType,...)
#define QT_DECLARE_ORDERING_HELPER_TEMPLATE(OrderingType, LeftType, RightType, Constexpr, Noexcept,...)
#define QT_DECLARE_ORDERED_3(LeftType, RightType,...)
#define QT_DECLARE_REVERSED_ORDERING_HELPER_TEMPLATE(OrderingType, LeftType, RightType, Constexpr, Noexcept,...)
#define QT_DECLARE_STRONGLY_ORDERED_3(LeftType, RightType,...)
#define QT_DECLARE_STRONGLY_ORDERED_NON_NOEXCEPT_3(LeftType, RightType,...)
#define QT_DECLARE_EQUALITY_OPERATORS_REVERSED_HELPER(LeftType, RightType, Constexpr, Noexcept,...)
#define MAKE_RELOP(Ret, op, Op)
#define QT_DECLARE_WEAKLY_ORDERED_3(LeftType, RightType,...)