Qt
Internal/Contributor docs for the Qt SDK. <b>Note:</b> These are NOT official API docs; those are found <a href='https://doc.qt.io/'>here</a>.
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
4#ifndef QCOMPARE_H
5#error "Do not include qcomparehelpers.h directly. Use qcompare.h instead."
6#endif
7
8#ifndef QCOMPAREHELPERS_H
9#define QCOMPAREHELPERS_H
10
11#if 0
12#pragma qt_no_master_include
13#pragma qt_sync_skip_header_check
14#pragma qt_sync_stop_processing
15#endif
16
17#include <QtCore/qoverload.h>
18#include <QtCore/qttypetraits.h>
19#include <QtCore/qtypes.h>
20
21#ifdef __cpp_lib_three_way_comparison
22#include <compare>
23#endif
24#include <QtCore/q20type_traits.h>
25
26#include <functional> // std::less
27
29
31
32namespace QtOrderingPrivate {
33#ifdef __cpp_lib_three_way_comparison
34
35template <typename QtOrdering> struct StdOrdering;
36template <typename StdOrdering> struct QtOrdering;
37
38#define QT_STD_MAP(x) \
39 template <> struct StdOrdering< Qt::x##_ordering> : q20::type_identity<std::x##_ordering> {};\
40 template <> struct StdOrdering<std::x##_ordering> : q20::type_identity<std::x##_ordering> {};\
41 template <> struct QtOrdering<std::x##_ordering> : q20::type_identity< Qt::x##_ordering> {};\
42 template <> struct QtOrdering< Qt::x##_ordering> : q20::type_identity< Qt::x##_ordering> {};\
43 /* end */
44QT_STD_MAP(partial)
45QT_STD_MAP(weak)
46QT_STD_MAP(strong)
47#undef QT_STD_MAP
48
49template <> struct StdOrdering<QPartialOrdering> : q20::type_identity<std::partial_ordering> {};
50template <> struct QtOrdering<QPartialOrdering> : q20::type_identity< Qt::partial_ordering> {};
51
52template <typename In> constexpr auto to_std(In in) noexcept
53 -> typename QtOrderingPrivate::StdOrdering<In>::type
54{ return in; }
55
56template <typename In> constexpr auto to_Qt(In in) noexcept
57 -> typename QtOrderingPrivate::QtOrdering<In>::type
58{ return in; }
59
60#endif // __cpp_lib_three_way_comparison
61} // namespace QtOrderingPrivate
62
63/*
64 For all the macros these parameter names are used:
65 * LeftType - the type of the left operand of the comparison
66 * RightType - the type of the right operand of the comparison
67 * Constexpr - must be either constexpr or empty. Defines whether the
68 operator is constexpr or not
69 * Attributes - an optional list of attributes. For example, pass
70 \c QT_ASCII_CAST_WARN when defining comparisons between
71 C-style string and an encoding-aware string type.
72
73 The macros require two helper functions. For operators to be constexpr,
74 these must be constexpr, too. Additionally, other attributes (like
75 Q_<Module>_EXPORT, Q_DECL_CONST_FUNCTION, etc) can be applied to them.
76 Aside from that, their declaration should match:
77 bool comparesEqual(LeftType, RightType) noexcept;
78 ReturnType compareThreeWay(LeftType, RightType) noexcept;
79
80 The ReturnType can be one of Qt::{partial,weak,strong}_ordering. The actual
81 type depends on the macro being used.
82 It makes sense to define the helper functions as hidden friends of the
83 class, so that they could be found via ADL, and don't participate in
84 unintended implicit conversions.
85*/
86
87// Seems that qdoc uses C++20 even when Qt is compiled in C++17 mode.
88// Or at least it defines __cpp_lib_three_way_comparison.
89// Let qdoc see only the C++17 operators for now, because that's what our docs
90// currently describe.
91#if defined(__cpp_lib_three_way_comparison) && !defined(Q_QDOC)
92// C++20 - provide operator==() for equality, and operator<=>() for ordering
93
94#define QT_DECLARE_EQUALITY_OPERATORS_HELPER(LeftType, RightType, Constexpr, Attributes) \
95 Attributes \
96 friend Constexpr bool operator==(LeftType const &lhs, RightType const &rhs) \
97 noexcept(noexcept(comparesEqual(lhs, rhs))) \
98 { return comparesEqual(lhs, rhs); }
99
100#define QT_DECLARE_3WAY_HELPER_STRONG(LeftType, RightType, Constexpr, Attributes) \
101 Attributes \
102 friend Constexpr std::strong_ordering \
103 operator<=>(LeftType const &lhs, RightType const &rhs) \
104 noexcept(noexcept(compareThreeWay(lhs, rhs))) \
105 { \
106 return compareThreeWay(lhs, rhs); \
107 }
108
109#define QT_DECLARE_3WAY_HELPER_WEAK(LeftType, RightType, Constexpr, Attributes) \
110 Attributes \
111 friend Constexpr std::weak_ordering \
112 operator<=>(LeftType const &lhs, RightType const &rhs) \
113 noexcept(noexcept(compareThreeWay(lhs, rhs))) \
114 { \
115 return compareThreeWay(lhs, rhs); \
116 }
117
118#define QT_DECLARE_3WAY_HELPER_PARTIAL(LeftType, RightType, Constexpr, Attributes) \
119 Attributes \
120 friend Constexpr std::partial_ordering \
121 operator<=>(LeftType const &lhs, RightType const &rhs) \
122 noexcept(noexcept(compareThreeWay(lhs, rhs))) \
123 { \
124 return compareThreeWay(lhs, rhs); \
125 }
126
127#define QT_DECLARE_ORDERING_OPERATORS_HELPER(OrderingType, LeftType, RightType, Constexpr, \
128 Attributes) \
129 QT_DECLARE_EQUALITY_OPERATORS_HELPER(LeftType, RightType, Constexpr, Attributes) \
130 QT_DECLARE_3WAY_HELPER_ ## OrderingType (LeftType, RightType, Constexpr, Attributes)
131
132#ifdef Q_COMPILER_LACKS_THREE_WAY_COMPARE_SYMMETRY
133
134// define reversed versions of the operators manually, because buggy MSVC versions do not do it
135#define QT_DECLARE_EQUALITY_OPERATORS_REVERSED_HELPER(LeftType, RightType, Constexpr, Attributes) \
136 Attributes \
137 friend Constexpr bool operator==(RightType const &lhs, LeftType const &rhs) \
138 noexcept(noexcept(comparesEqual(rhs, lhs))) \
139 { return comparesEqual(rhs, lhs); }
140
141#define QT_DECLARE_REVERSED_3WAY_HELPER_STRONG(LeftType, RightType, Constexpr, Attributes) \
142 Attributes \
143 friend Constexpr std::strong_ordering \
144 operator<=>(RightType const &lhs, LeftType const &rhs) \
145 noexcept(noexcept(compareThreeWay(rhs, lhs))) \
146 { \
147 const auto r = compareThreeWay(rhs, lhs); \
148 if (is_gt(r)) return std::strong_ordering::less; \
149 if (is_lt(r)) return std::strong_ordering::greater; \
150 return r; \
151 }
152
153#define QT_DECLARE_REVERSED_3WAY_HELPER_WEAK(LeftType, RightType, Constexpr, Attributes) \
154 Attributes \
155 friend Constexpr std::weak_ordering \
156 operator<=>(RightType const &lhs, LeftType const &rhs) \
157 noexcept(noexcept(compareThreeWay(rhs, lhs))) \
158 { \
159 const auto r = compareThreeWay(rhs, lhs); \
160 if (is_gt(r)) return std::weak_ordering::less; \
161 if (is_lt(r)) return std::weak_ordering::greater; \
162 return r; \
163 }
164
165#define QT_DECLARE_REVERSED_3WAY_HELPER_PARTIAL(LeftType, RightType, Constexpr, Attributes) \
166 Attributes \
167 friend Constexpr std::partial_ordering \
168 operator<=>(RightType const &lhs, LeftType const &rhs) \
169 noexcept(noexcept(compareThreeWay(rhs, lhs))) \
170 { \
171 const auto r = compareThreeWay(rhs, lhs); \
172 if (is_gt(r)) return std::partial_ordering::less; \
173 if (is_lt(r)) return std::partial_ordering::greater; \
174 return r; \
175 }
176
177#define QT_DECLARE_ORDERING_OPERATORS_REVERSED_HELPER(OrderingString, LeftType, RightType, \
178 Constexpr, Attributes) \
179 QT_DECLARE_EQUALITY_OPERATORS_REVERSED_HELPER(LeftType, RightType, Constexpr, Attributes) \
180 QT_DECLARE_REVERSED_3WAY_HELPER_ ## OrderingString (LeftType, RightType, Constexpr, Attributes)
181
182#else
183
184// dummy macros for C++17 compatibility, reversed operators are generated by the compiler
185#define QT_DECLARE_EQUALITY_OPERATORS_REVERSED_HELPER(LeftType, RightType, Constexpr, Attributes)
186#define QT_DECLARE_ORDERING_OPERATORS_REVERSED_HELPER(OrderingString, LeftType, RightType, \
187 Constexpr, Attributes)
188
189#endif // Q_COMPILER_LACKS_THREE_WAY_COMPARE_SYMMETRY
190
191#else
192// C++17 - provide operator==() and operator!=() for equality,
193// and all 4 comparison operators for ordering
194
195#define QT_DECLARE_EQUALITY_OPERATORS_HELPER(LeftType, RightType, Constexpr, Attributes) \
196 Attributes \
197 friend Constexpr bool operator==(LeftType const &lhs, RightType const &rhs) \
198 noexcept(noexcept(comparesEqual(lhs, rhs))) \
199 { return comparesEqual(lhs, rhs); } \
200 Attributes \
201 friend Constexpr bool operator!=(LeftType const &lhs, RightType const &rhs) \
202 noexcept(noexcept(comparesEqual(lhs, rhs))) \
203 { return !comparesEqual(lhs, rhs); }
204
205// Helpers for reversed comparison, using the existing comparesEqual() function.
206#define QT_DECLARE_EQUALITY_OPERATORS_REVERSED_HELPER(LeftType, RightType, Constexpr, Attributes) \
207 Attributes \
208 friend Constexpr bool operator==(RightType const &lhs, LeftType const &rhs) \
209 noexcept(noexcept(comparesEqual(rhs, lhs))) \
210 { return comparesEqual(rhs, lhs); } \
211 Attributes \
212 friend Constexpr bool operator!=(RightType const &lhs, LeftType const &rhs) \
213 noexcept(noexcept(comparesEqual(rhs, lhs))) \
214 { return !comparesEqual(rhs, lhs); }
215
216#define QT_DECLARE_ORDERING_HELPER_TEMPLATE(OrderingType, LeftType, RightType, Constexpr, \
217 Attributes) \
218 Attributes \
219 friend Constexpr bool operator<(LeftType const &lhs, RightType const &rhs) \
220 noexcept(noexcept(compareThreeWay(lhs, rhs))) \
221 { return is_lt(compareThreeWay(lhs, rhs)); } \
222 Attributes \
223 friend Constexpr bool operator>(LeftType const &lhs, RightType const &rhs) \
224 noexcept(noexcept(compareThreeWay(lhs, rhs))) \
225 { return is_gt(compareThreeWay(lhs, rhs)); } \
226 Attributes \
227 friend Constexpr bool operator<=(LeftType const &lhs, RightType const &rhs) \
228 noexcept(noexcept(compareThreeWay(lhs, rhs))) \
229 { return is_lteq(compareThreeWay(lhs, rhs)); } \
230 Attributes \
231 friend Constexpr bool operator>=(LeftType const &lhs, RightType const &rhs) \
232 noexcept(noexcept(compareThreeWay(lhs, rhs))) \
233 { return is_gteq(compareThreeWay(lhs, rhs)); }
234
235#define QT_DECLARE_ORDERING_HELPER_PARTIAL(LeftType, RightType, Constexpr, Attributes) \
236 QT_DECLARE_ORDERING_HELPER_TEMPLATE(Qt::partial_ordering, LeftType, RightType, Constexpr, \
237 Attributes)
238
239#define QT_DECLARE_ORDERING_HELPER_WEAK(LeftType, RightType, Constexpr, Attributes) \
240 QT_DECLARE_ORDERING_HELPER_TEMPLATE(Qt::weak_ordering, LeftType, RightType, Constexpr, \
241 Attributes)
242
243#define QT_DECLARE_ORDERING_HELPER_STRONG(LeftType, RightType, Constexpr, Attributes) \
244 QT_DECLARE_ORDERING_HELPER_TEMPLATE(Qt::strong_ordering, LeftType, RightType, Constexpr, \
245 Attributes)
246
247#define QT_DECLARE_ORDERING_OPERATORS_HELPER(OrderingString, LeftType, RightType, Constexpr, \
248 Attributes) \
249 QT_DECLARE_EQUALITY_OPERATORS_HELPER(LeftType, RightType, Constexpr, Attributes) \
250 QT_DECLARE_ORDERING_HELPER_ ## OrderingString (LeftType, RightType, Constexpr, Attributes)
251
252// Helpers for reversed ordering, using the existing compareThreeWay() function.
253#define QT_DECLARE_REVERSED_ORDERING_HELPER_TEMPLATE(OrderingType, LeftType, RightType, Constexpr, \
254 Attributes) \
255 Attributes \
256 friend Constexpr bool operator<(RightType const &lhs, LeftType const &rhs) \
257 noexcept(noexcept(compareThreeWay(rhs, lhs))) \
258 { return is_gt(compareThreeWay(rhs, lhs)); } \
259 Attributes \
260 friend Constexpr bool operator>(RightType const &lhs, LeftType const &rhs) \
261 noexcept(noexcept(compareThreeWay(rhs, lhs))) \
262 { return is_lt(compareThreeWay(rhs, lhs)); } \
263 Attributes \
264 friend Constexpr bool operator<=(RightType const &lhs, LeftType const &rhs) \
265 noexcept(noexcept(compareThreeWay(rhs, lhs))) \
266 { return is_gteq(compareThreeWay(rhs, lhs)); } \
267 Attributes \
268 friend Constexpr bool operator>=(RightType const &lhs, LeftType const &rhs) \
269 noexcept(noexcept(compareThreeWay(rhs, lhs))) \
270 { return is_lteq(compareThreeWay(rhs, lhs)); }
271
272#define QT_DECLARE_REVERSED_ORDERING_HELPER_PARTIAL(LeftType, RightType, Constexpr, Attributes) \
273 QT_DECLARE_REVERSED_ORDERING_HELPER_TEMPLATE(Qt::partial_ordering, LeftType, RightType, \
274 Constexpr, Attributes)
275
276#define QT_DECLARE_REVERSED_ORDERING_HELPER_WEAK(LeftType, RightType, Constexpr, Attributes) \
277 QT_DECLARE_REVERSED_ORDERING_HELPER_TEMPLATE(Qt::weak_ordering, LeftType, RightType, \
278 Constexpr, Attributes)
279
280#define QT_DECLARE_REVERSED_ORDERING_HELPER_STRONG(LeftType, RightType, Constexpr, Attributes) \
281 QT_DECLARE_REVERSED_ORDERING_HELPER_TEMPLATE(Qt::strong_ordering, LeftType, RightType, \
282 Constexpr, Attributes)
283
284#define QT_DECLARE_ORDERING_OPERATORS_REVERSED_HELPER(OrderingString, LeftType, RightType, \
285 Constexpr, Attributes) \
286 QT_DECLARE_EQUALITY_OPERATORS_REVERSED_HELPER(LeftType, RightType, Constexpr, Attributes) \
287 QT_DECLARE_REVERSED_ORDERING_HELPER_ ## OrderingString (LeftType, RightType, Constexpr, \
288 Attributes)
289
290#endif // __cpp_lib_three_way_comparison
291
292/* Public API starts here */
293
294// Equality operators
295#define QT_DECLARE_EQUALITY_COMPARABLE_1(Type) \
296 QT_DECLARE_EQUALITY_OPERATORS_HELPER(Type, Type, /* non-constexpr */, /* no attributes */)
297
298#define QT_DECLARE_EQUALITY_COMPARABLE_2(LeftType, RightType) \
299 QT_DECLARE_EQUALITY_OPERATORS_HELPER(LeftType, RightType, /* non-constexpr */, \
300 /* no attributes */) \
301 QT_DECLARE_EQUALITY_OPERATORS_REVERSED_HELPER(LeftType, RightType, /* non-constexpr */, \
302 /* no attributes */)
303
304#define QT_DECLARE_EQUALITY_COMPARABLE_3(LeftType, RightType, Attributes) \
305 QT_DECLARE_EQUALITY_OPERATORS_HELPER(LeftType, RightType, /* non-constexpr */, Attributes) \
306 QT_DECLARE_EQUALITY_OPERATORS_REVERSED_HELPER(LeftType, RightType, /* non-constexpr */, \
307 Attributes)
308
309#define Q_DECLARE_EQUALITY_COMPARABLE(...) \
310 QT_OVERLOADED_MACRO(QT_DECLARE_EQUALITY_COMPARABLE, __VA_ARGS__)
311
312#define QT_DECLARE_EQUALITY_COMPARABLE_LITERAL_TYPE_1(Type) \
313 QT_DECLARE_EQUALITY_OPERATORS_HELPER(Type, Type, constexpr, /* no attributes */)
314
315#define QT_DECLARE_EQUALITY_COMPARABLE_LITERAL_TYPE_2(LeftType, RightType) \
316 QT_DECLARE_EQUALITY_OPERATORS_HELPER(LeftType, RightType, constexpr, /* no attributes */) \
317 QT_DECLARE_EQUALITY_OPERATORS_REVERSED_HELPER(LeftType, RightType, constexpr, \
318 /* no attributes */)
319
320#define QT_DECLARE_EQUALITY_COMPARABLE_LITERAL_TYPE_3(LeftType, RightType, Attributes) \
321 QT_DECLARE_EQUALITY_OPERATORS_HELPER(LeftType, RightType, constexpr, Attributes) \
322 QT_DECLARE_EQUALITY_OPERATORS_REVERSED_HELPER(LeftType, RightType, constexpr, Attributes)
323
324#define Q_DECLARE_EQUALITY_COMPARABLE_LITERAL_TYPE(...) \
325 QT_OVERLOADED_MACRO(QT_DECLARE_EQUALITY_COMPARABLE_LITERAL_TYPE, __VA_ARGS__)
326
327// Partial ordering operators
328#define QT_DECLARE_PARTIALLY_ORDERED_1(Type) \
329 QT_DECLARE_ORDERING_OPERATORS_HELPER(PARTIAL, Type, Type, /* non-constexpr */, \
330 /* no attributes */)
331
332#define QT_DECLARE_PARTIALLY_ORDERED_2(LeftType, RightType) \
333 QT_DECLARE_ORDERING_OPERATORS_HELPER(PARTIAL, LeftType, RightType, /* non-constexpr */, \
334 /* no attributes */) \
335 QT_DECLARE_ORDERING_OPERATORS_REVERSED_HELPER(PARTIAL, LeftType, RightType, \
336 /* non-constexpr */, /* no attributes */)
337
338#define QT_DECLARE_PARTIALLY_ORDERED_3(LeftType, RightType, Attributes) \
339 QT_DECLARE_ORDERING_OPERATORS_HELPER(PARTIAL, LeftType, RightType, /* non-constexpr */, \
340 Attributes) \
341 QT_DECLARE_ORDERING_OPERATORS_REVERSED_HELPER(PARTIAL, LeftType, RightType, \
342 /* non-constexpr */, Attributes)
343
344#define Q_DECLARE_PARTIALLY_ORDERED(...) \
345 QT_OVERLOADED_MACRO(QT_DECLARE_PARTIALLY_ORDERED, __VA_ARGS__)
346
347#define QT_DECLARE_PARTIALLY_ORDERED_LITERAL_TYPE_1(Type) \
348 QT_DECLARE_ORDERING_OPERATORS_HELPER(PARTIAL, Type, Type, constexpr, /* no attributes */)
349
350#define QT_DECLARE_PARTIALLY_ORDERED_LITERAL_TYPE_2(LeftType, RightType) \
351 QT_DECLARE_ORDERING_OPERATORS_HELPER(PARTIAL, LeftType, RightType, constexpr, \
352 /* no attributes */) \
353 QT_DECLARE_ORDERING_OPERATORS_REVERSED_HELPER(PARTIAL, LeftType, RightType, constexpr, \
354 /* no attributes */)
355
356#define QT_DECLARE_PARTIALLY_ORDERED_LITERAL_TYPE_3(LeftType, RightType, Attributes) \
357 QT_DECLARE_ORDERING_OPERATORS_HELPER(PARTIAL, LeftType, RightType, constexpr, Attributes) \
358 QT_DECLARE_ORDERING_OPERATORS_REVERSED_HELPER(PARTIAL, LeftType, RightType, constexpr, \
359 Attributes)
360
361#define Q_DECLARE_PARTIALLY_ORDERED_LITERAL_TYPE(...) \
362 QT_OVERLOADED_MACRO(QT_DECLARE_PARTIALLY_ORDERED_LITERAL_TYPE, __VA_ARGS__)
363
364// Weak ordering operators
365#define QT_DECLARE_WEAKLY_ORDERED_1(Type) \
366 QT_DECLARE_ORDERING_OPERATORS_HELPER(WEAK, Type, Type, /* non-constexpr */, /* no attributes */)
367
368#define QT_DECLARE_WEAKLY_ORDERED_2(LeftType, RightType) \
369 QT_DECLARE_ORDERING_OPERATORS_HELPER(WEAK, LeftType, RightType, /* non-constexpr */, \
370 /* no attributes */) \
371 QT_DECLARE_ORDERING_OPERATORS_REVERSED_HELPER(WEAK, LeftType, RightType, /* non-constexpr */, \
372 /* no attributes */)
373
374#define QT_DECLARE_WEAKLY_ORDERED_3(LeftType, RightType, Attributes) \
375 QT_DECLARE_ORDERING_OPERATORS_HELPER(WEAK, LeftType, RightType, /* non-constexpr */, \
376 Attributes) \
377 QT_DECLARE_ORDERING_OPERATORS_REVERSED_HELPER(WEAK, LeftType, RightType, /* non-constexpr */, \
378 Attributes)
379
380#define Q_DECLARE_WEAKLY_ORDERED(...) \
381 QT_OVERLOADED_MACRO(QT_DECLARE_WEAKLY_ORDERED, __VA_ARGS__)
382
383#define QT_DECLARE_WEAKLY_ORDERED_LITERAL_TYPE_1(Type) \
384 QT_DECLARE_ORDERING_OPERATORS_HELPER(WEAK, Type, Type, constexpr, /* no attributes */)
385
386#define QT_DECLARE_WEAKLY_ORDERED_LITERAL_TYPE_2(LeftType, RightType) \
387 QT_DECLARE_ORDERING_OPERATORS_HELPER(WEAK, LeftType, RightType, constexpr, \
388 /* no attributes */) \
389 QT_DECLARE_ORDERING_OPERATORS_REVERSED_HELPER(WEAK, LeftType, RightType, constexpr, \
390 /* no attributes */)
391
392#define QT_DECLARE_WEAKLY_ORDERED_LITERAL_TYPE_3(LeftType, RightType, Attributes) \
393QT_DECLARE_ORDERING_OPERATORS_HELPER(WEAK, LeftType, RightType, constexpr, Attributes) \
394 QT_DECLARE_ORDERING_OPERATORS_REVERSED_HELPER(WEAK, LeftType, RightType, constexpr, \
395 Attributes)
396
397#define Q_DECLARE_WEAKLY_ORDERED_LITERAL_TYPE(...) \
398 QT_OVERLOADED_MACRO(QT_DECLARE_WEAKLY_ORDERED_LITERAL_TYPE, __VA_ARGS__)
399
400// Strong ordering operators
401#define QT_DECLARE_STRONGLY_ORDERED_1(Type) \
402 QT_DECLARE_ORDERING_OPERATORS_HELPER(STRONG, Type, Type, /* non-constexpr */, \
403 /* no attributes */)
404
405#define QT_DECLARE_STRONGLY_ORDERED_2(LeftType, RightType) \
406 QT_DECLARE_ORDERING_OPERATORS_HELPER(STRONG, LeftType, RightType, /* non-constexpr */, \
407 /* no attributes */) \
408 QT_DECLARE_ORDERING_OPERATORS_REVERSED_HELPER(STRONG, LeftType, RightType, \
409 /* non-constexpr */, /* no attributes */)
410
411#define QT_DECLARE_STRONGLY_ORDERED_3(LeftType, RightType, Attributes) \
412 QT_DECLARE_ORDERING_OPERATORS_HELPER(STRONG, LeftType, RightType, /* non-constexpr */, \
413 Attributes) \
414 QT_DECLARE_ORDERING_OPERATORS_REVERSED_HELPER(STRONG, LeftType, RightType, \
415 /* non-constexpr */, Attributes)
416
417#define Q_DECLARE_STRONGLY_ORDERED(...) \
418 QT_OVERLOADED_MACRO(QT_DECLARE_STRONGLY_ORDERED, __VA_ARGS__)
419
420#define QT_DECLARE_STRONGLY_ORDERED_LITERAL_TYPE_1(Type) \
421 QT_DECLARE_ORDERING_OPERATORS_HELPER(STRONG, Type, Type, constexpr, /* no attributes */)
422
423#define QT_DECLARE_STRONGLY_ORDERED_LITERAL_TYPE_2(LeftType, RightType) \
424 QT_DECLARE_ORDERING_OPERATORS_HELPER(STRONG, LeftType, RightType, constexpr, \
425 /* no attributes */) \
426 QT_DECLARE_ORDERING_OPERATORS_REVERSED_HELPER(STRONG, LeftType, RightType, constexpr, \
427 /* no attributes */)
428
429#define QT_DECLARE_STRONGLY_ORDERED_LITERAL_TYPE_3(LeftType, RightType, Attributes) \
430 QT_DECLARE_ORDERING_OPERATORS_HELPER(STRONG, LeftType, RightType, constexpr, Attributes) \
431 QT_DECLARE_ORDERING_OPERATORS_REVERSED_HELPER(STRONG, LeftType, RightType, constexpr, \
432 Attributes)
433
434#define Q_DECLARE_STRONGLY_ORDERED_LITERAL_TYPE(...) \
435 QT_OVERLOADED_MACRO(QT_DECLARE_STRONGLY_ORDERED_LITERAL_TYPE, __VA_ARGS__)
436
437namespace QtPrivate {
438
439template <typename T>
440constexpr bool IsIntegralType_v = std::numeric_limits<std::remove_const_t<T>>::is_specialized
441 && std::numeric_limits<std::remove_const_t<T>>::is_integer;
442
443template <typename T>
444constexpr bool IsFloatType_v = std::is_floating_point_v<T>;
445
446#if QFLOAT16_IS_NATIVE
447template <>
448constexpr bool IsFloatType_v<QtPrivate::NativeFloat16Type> = true;
449#endif
450
451} // namespace QtPrivate
452
453namespace Qt {
454
455template <typename T>
456using if_integral = std::enable_if_t<QtPrivate::IsIntegralType_v<T>, bool>;
457
458template <typename T>
459using if_floating_point = std::enable_if_t<QtPrivate::IsFloatType_v<T>, bool>;
460
461template <typename T, typename U>
463 std::enable_if_t<std::disjunction_v<std::is_same<T, U>,
464 std::is_base_of<T, U>,
465 std::is_base_of<U, T>>,
466 bool>;
467
468template <typename Enum>
469using if_enum = std::enable_if_t<std::is_enum_v<Enum>, bool>;
470
471template <typename LeftInt, typename RightInt,
472 if_integral<LeftInt> = true,
473 if_integral<RightInt> = true>
474constexpr Qt::strong_ordering compareThreeWay(LeftInt lhs, RightInt rhs) noexcept
475{
476 static_assert(std::is_signed_v<LeftInt> == std::is_signed_v<RightInt>,
477 "Qt::compareThreeWay() does not allow mixed-sign comparison.");
478
479#ifdef __cpp_lib_three_way_comparison
480 return lhs <=> rhs;
481#else
482 if (lhs == rhs)
484 else if (lhs < rhs)
486 else
488#endif // __cpp_lib_three_way_comparison
489}
490
491template <typename LeftFloat, typename RightFloat,
492 if_floating_point<LeftFloat> = true,
493 if_floating_point<RightFloat> = true>
494constexpr Qt::partial_ordering compareThreeWay(LeftFloat lhs, RightFloat rhs) noexcept
495{
498#ifdef __cpp_lib_three_way_comparison
499 return lhs <=> rhs;
500#else
501 if (lhs < rhs)
503 else if (lhs > rhs)
505 else if (lhs == rhs)
507 else
509#endif // __cpp_lib_three_way_comparison
511}
512
513template <typename IntType, typename FloatType,
514 if_integral<IntType> = true,
515 if_floating_point<FloatType> = true>
516constexpr Qt::partial_ordering compareThreeWay(IntType lhs, FloatType rhs) noexcept
517{
518 return compareThreeWay(FloatType(lhs), rhs);
519}
520
521template <typename FloatType, typename IntType,
522 if_floating_point<FloatType> = true,
523 if_integral<IntType> = true>
524constexpr Qt::partial_ordering compareThreeWay(FloatType lhs, IntType rhs) noexcept
525{
526 return compareThreeWay(lhs, FloatType(rhs));
527}
528
529template <typename LeftType, typename RightType,
530 if_compatible_pointers<LeftType, RightType> = true>
531constexpr Qt::strong_ordering compareThreeWay(const LeftType *lhs, const RightType *rhs) noexcept
532{
533#ifdef __cpp_lib_three_way_comparison
534 return std::compare_three_way{}(lhs, rhs);
535#else
536 if (lhs == rhs)
538 else if (std::less<>{}(lhs, rhs))
540 else
542#endif // __cpp_lib_three_way_comparison
543}
544
545template <typename T>
546constexpr Qt::strong_ordering compareThreeWay(const T *lhs, std::nullptr_t rhs) noexcept
547{
548 return compareThreeWay(lhs, static_cast<const T *>(rhs));
549}
550
551template <typename T>
552constexpr Qt::strong_ordering compareThreeWay(std::nullptr_t lhs, const T *rhs) noexcept
553{
554 return compareThreeWay(static_cast<const T *>(lhs), rhs);
555}
556
557template <class Enum, if_enum<Enum> = true>
558constexpr Qt::strong_ordering compareThreeWay(Enum lhs, Enum rhs) noexcept
559{
561}
562
563} // namespace Qt
564
566
567#endif // QCOMPAREHELPERS_H
\variable Qt::partial_ordering::less
Definition qcompare.h:679
\variable Qt::weak_ordering::less
Definition qcompare.h:66
static const partial_ordering equivalent
Definition qcompare.h:69
static const partial_ordering unordered
Definition qcompare.h:71
static const partial_ordering greater
Definition qcompare.h:70
static const partial_ordering less
Definition qcompare.h:68
\inmodule QtCore \title Classes and helpers for defining comparison operators \keyword qtcompare
Definition qcompare.h:400
static const strong_ordering greater
Definition qcompare.h:405
static const strong_ordering less
Definition qcompare.h:402
static const strong_ordering equivalent
Definition qcompare.h:403
Combined button and popup list for selecting options.
\macro QT_NO_KEYWORDS >
constexpr bool IsFloatType_v
constexpr bool IsIntegralType_v
Definition qcompare.h:63
std::enable_if_t< std::disjunction_v< std::is_same< T, U >, std::is_base_of< T, U >, std::is_base_of< U, T > >, bool > if_compatible_pointers
std::enable_if_t< QtPrivate::IsIntegralType_v< T >, bool > if_integral
std::enable_if_t< std::is_enum_v< Enum >, bool > if_enum
constexpr Qt::strong_ordering compareThreeWay(LeftInt lhs, RightInt rhs) noexcept
std::enable_if_t< QtPrivate::IsFloatType_v< T >, bool > if_floating_point
#define QT_WARNING_POP
#define QT_WARNING_DISABLE_FLOAT_COMPARE
#define QT_WARNING_PUSH
GLuint in
QT_BEGIN_NAMESPACE constexpr std::underlying_type_t< Enum > qToUnderlying(Enum e) noexcept
QSharedPointer< int > strong