5#error "Do not include qcomparehelpers.h directly. Use qcompare.h instead."
8#ifndef QCOMPAREHELPERS_H
9#define QCOMPAREHELPERS_H
12#pragma qt_no_master_include
13#pragma qt_sync_skip_header_check
14#pragma qt_sync_stop_processing
17#include <QtCore/qoverload.h>
18#include <QtCore/qttypetraits.h>
19#include <QtCore/qtypes.h>
21#ifdef __cpp_lib_three_way_comparison
24#include <QtCore/q20type_traits.h>
33#ifdef __cpp_lib_three_way_comparison
35template <
typename QtOrdering>
struct StdOrdering;
36template <
typename StdOrdering>
struct QtOrdering;
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> {};\
52template <
typename In>
constexpr auto to_std(In
in)
noexcept
53 ->
typename QtOrderingPrivate::StdOrdering<In>::type
56template <
typename In>
constexpr auto to_Qt(In
in)
noexcept
57 ->
typename QtOrderingPrivate::QtOrdering<In>::type
91#if defined(__cpp_lib_three_way_comparison) && !defined(Q_QDOC)
94#define QT_DECLARE_EQUALITY_OPERATORS_HELPER(LeftType, RightType, Constexpr, Attributes) \
96 friend Constexpr bool operator==(LeftType const &lhs, RightType const &rhs) \
97 noexcept(noexcept(comparesEqual(lhs, rhs))) \
98 { return comparesEqual(lhs, rhs); }
100#define QT_DECLARE_3WAY_HELPER_STRONG(LeftType, RightType, Constexpr, Attributes) \
102 friend Constexpr std::strong_ordering \
103 operator<=>(LeftType const &lhs, RightType const &rhs) \
104 noexcept(noexcept(compareThreeWay(lhs, rhs))) \
106 return compareThreeWay(lhs, rhs); \
109#define QT_DECLARE_3WAY_HELPER_WEAK(LeftType, RightType, Constexpr, Attributes) \
111 friend Constexpr std::weak_ordering \
112 operator<=>(LeftType const &lhs, RightType const &rhs) \
113 noexcept(noexcept(compareThreeWay(lhs, rhs))) \
115 return compareThreeWay(lhs, rhs); \
118#define QT_DECLARE_3WAY_HELPER_PARTIAL(LeftType, RightType, Constexpr, Attributes) \
120 friend Constexpr std::partial_ordering \
121 operator<=>(LeftType const &lhs, RightType const &rhs) \
122 noexcept(noexcept(compareThreeWay(lhs, rhs))) \
124 return compareThreeWay(lhs, rhs); \
127#define QT_DECLARE_ORDERING_OPERATORS_HELPER(OrderingType, LeftType, RightType, Constexpr, \
129 QT_DECLARE_EQUALITY_OPERATORS_HELPER(LeftType, RightType, Constexpr, Attributes) \
130 QT_DECLARE_3WAY_HELPER_ ## OrderingType (LeftType, RightType, Constexpr, Attributes)
132#ifdef Q_COMPILER_LACKS_THREE_WAY_COMPARE_SYMMETRY
135#define QT_DECLARE_EQUALITY_OPERATORS_REVERSED_HELPER(LeftType, RightType, Constexpr, Attributes) \
137 friend Constexpr bool operator==(RightType const &lhs, LeftType const &rhs) \
138 noexcept(noexcept(comparesEqual(rhs, lhs))) \
139 { return comparesEqual(rhs, lhs); }
141#define QT_DECLARE_REVERSED_3WAY_HELPER_STRONG(LeftType, RightType, Constexpr, Attributes) \
143 friend Constexpr std::strong_ordering \
144 operator<=>(RightType const &lhs, LeftType const &rhs) \
145 noexcept(noexcept(compareThreeWay(rhs, lhs))) \
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; \
153#define QT_DECLARE_REVERSED_3WAY_HELPER_WEAK(LeftType, RightType, Constexpr, Attributes) \
155 friend Constexpr std::weak_ordering \
156 operator<=>(RightType const &lhs, LeftType const &rhs) \
157 noexcept(noexcept(compareThreeWay(rhs, lhs))) \
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; \
165#define QT_DECLARE_REVERSED_3WAY_HELPER_PARTIAL(LeftType, RightType, Constexpr, Attributes) \
167 friend Constexpr std::partial_ordering \
168 operator<=>(RightType const &lhs, LeftType const &rhs) \
169 noexcept(noexcept(compareThreeWay(rhs, lhs))) \
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; \
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)
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)
195#define QT_DECLARE_EQUALITY_OPERATORS_HELPER(LeftType, RightType, Constexpr, Attributes) \
197 friend Constexpr bool operator==(LeftType const &lhs, RightType const &rhs) \
198 noexcept(noexcept(comparesEqual(lhs, rhs))) \
199 { return comparesEqual(lhs, rhs); } \
201 friend Constexpr bool operator!=(LeftType const &lhs, RightType const &rhs) \
202 noexcept(noexcept(comparesEqual(lhs, rhs))) \
203 { return !comparesEqual(lhs, rhs); }
206#define QT_DECLARE_EQUALITY_OPERATORS_REVERSED_HELPER(LeftType, RightType, Constexpr, Attributes) \
208 friend Constexpr bool operator==(RightType const &lhs, LeftType const &rhs) \
209 noexcept(noexcept(comparesEqual(rhs, lhs))) \
210 { return comparesEqual(rhs, lhs); } \
212 friend Constexpr bool operator!=(RightType const &lhs, LeftType const &rhs) \
213 noexcept(noexcept(comparesEqual(rhs, lhs))) \
214 { return !comparesEqual(rhs, lhs); }
216#define QT_DECLARE_ORDERING_HELPER_TEMPLATE(OrderingType, LeftType, RightType, Constexpr, \
219 friend Constexpr bool operator<(LeftType const &lhs, RightType const &rhs) \
220 noexcept(noexcept(compareThreeWay(lhs, rhs))) \
221 { return is_lt(compareThreeWay(lhs, rhs)); } \
223 friend Constexpr bool operator>(LeftType const &lhs, RightType const &rhs) \
224 noexcept(noexcept(compareThreeWay(lhs, rhs))) \
225 { return is_gt(compareThreeWay(lhs, rhs)); } \
227 friend Constexpr bool operator<=(LeftType const &lhs, RightType const &rhs) \
228 noexcept(noexcept(compareThreeWay(lhs, rhs))) \
229 { return is_lteq(compareThreeWay(lhs, rhs)); } \
231 friend Constexpr bool operator>=(LeftType const &lhs, RightType const &rhs) \
232 noexcept(noexcept(compareThreeWay(lhs, rhs))) \
233 { return is_gteq(compareThreeWay(lhs, rhs)); }
235#define QT_DECLARE_ORDERING_HELPER_PARTIAL(LeftType, RightType, Constexpr, Attributes) \
236 QT_DECLARE_ORDERING_HELPER_TEMPLATE(Qt::partial_ordering, LeftType, RightType, Constexpr, \
239#define QT_DECLARE_ORDERING_HELPER_WEAK(LeftType, RightType, Constexpr, Attributes) \
240 QT_DECLARE_ORDERING_HELPER_TEMPLATE(Qt::weak_ordering, LeftType, RightType, Constexpr, \
243#define QT_DECLARE_ORDERING_HELPER_STRONG(LeftType, RightType, Constexpr, Attributes) \
244 QT_DECLARE_ORDERING_HELPER_TEMPLATE(Qt::strong_ordering, LeftType, RightType, Constexpr, \
247#define QT_DECLARE_ORDERING_OPERATORS_HELPER(OrderingString, LeftType, RightType, Constexpr, \
249 QT_DECLARE_EQUALITY_OPERATORS_HELPER(LeftType, RightType, Constexpr, Attributes) \
250 QT_DECLARE_ORDERING_HELPER_ ## OrderingString (LeftType, RightType, Constexpr, Attributes)
253#define QT_DECLARE_REVERSED_ORDERING_HELPER_TEMPLATE(OrderingType, LeftType, RightType, Constexpr, \
256 friend Constexpr bool operator<(RightType const &lhs, LeftType const &rhs) \
257 noexcept(noexcept(compareThreeWay(rhs, lhs))) \
258 { return is_gt(compareThreeWay(rhs, lhs)); } \
260 friend Constexpr bool operator>(RightType const &lhs, LeftType const &rhs) \
261 noexcept(noexcept(compareThreeWay(rhs, lhs))) \
262 { return is_lt(compareThreeWay(rhs, lhs)); } \
264 friend Constexpr bool operator<=(RightType const &lhs, LeftType const &rhs) \
265 noexcept(noexcept(compareThreeWay(rhs, lhs))) \
266 { return is_gteq(compareThreeWay(rhs, lhs)); } \
268 friend Constexpr bool operator>=(RightType const &lhs, LeftType const &rhs) \
269 noexcept(noexcept(compareThreeWay(rhs, lhs))) \
270 { return is_lteq(compareThreeWay(rhs, lhs)); }
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)
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)
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)
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, \
295#define QT_DECLARE_EQUALITY_COMPARABLE_1(Type) \
296 QT_DECLARE_EQUALITY_OPERATORS_HELPER(Type, Type, , )
298#define QT_DECLARE_EQUALITY_COMPARABLE_2(LeftType, RightType) \
299 QT_DECLARE_EQUALITY_OPERATORS_HELPER(LeftType, RightType, , \
301 QT_DECLARE_EQUALITY_OPERATORS_REVERSED_HELPER(LeftType, RightType, , \
304#define QT_DECLARE_EQUALITY_COMPARABLE_3(LeftType, RightType, Attributes) \
305 QT_DECLARE_EQUALITY_OPERATORS_HELPER(LeftType, RightType, , Attributes) \
306 QT_DECLARE_EQUALITY_OPERATORS_REVERSED_HELPER(LeftType, RightType, , \
309#define Q_DECLARE_EQUALITY_COMPARABLE(...) \
310 QT_OVERLOADED_MACRO(QT_DECLARE_EQUALITY_COMPARABLE, __VA_ARGS__)
312#define QT_DECLARE_EQUALITY_COMPARABLE_LITERAL_TYPE_1(Type) \
313 QT_DECLARE_EQUALITY_OPERATORS_HELPER(Type, Type, constexpr, )
315#define QT_DECLARE_EQUALITY_COMPARABLE_LITERAL_TYPE_2(LeftType, RightType) \
316 QT_DECLARE_EQUALITY_OPERATORS_HELPER(LeftType, RightType, constexpr, ) \
317 QT_DECLARE_EQUALITY_OPERATORS_REVERSED_HELPER(LeftType, RightType, constexpr, \
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)
324#define Q_DECLARE_EQUALITY_COMPARABLE_LITERAL_TYPE(...) \
325 QT_OVERLOADED_MACRO(QT_DECLARE_EQUALITY_COMPARABLE_LITERAL_TYPE, __VA_ARGS__)
328#define QT_DECLARE_PARTIALLY_ORDERED_1(Type) \
329 QT_DECLARE_ORDERING_OPERATORS_HELPER(PARTIAL, Type, Type, , \
332#define QT_DECLARE_PARTIALLY_ORDERED_2(LeftType, RightType) \
333 QT_DECLARE_ORDERING_OPERATORS_HELPER(PARTIAL, LeftType, RightType, , \
335 QT_DECLARE_ORDERING_OPERATORS_REVERSED_HELPER(PARTIAL, LeftType, RightType, \
338#define QT_DECLARE_PARTIALLY_ORDERED_3(LeftType, RightType, Attributes) \
339 QT_DECLARE_ORDERING_OPERATORS_HELPER(PARTIAL, LeftType, RightType, , \
341 QT_DECLARE_ORDERING_OPERATORS_REVERSED_HELPER(PARTIAL, LeftType, RightType, \
344#define Q_DECLARE_PARTIALLY_ORDERED(...) \
345 QT_OVERLOADED_MACRO(QT_DECLARE_PARTIALLY_ORDERED, __VA_ARGS__)
347#define QT_DECLARE_PARTIALLY_ORDERED_LITERAL_TYPE_1(Type) \
348 QT_DECLARE_ORDERING_OPERATORS_HELPER(PARTIAL, Type, Type, constexpr, )
350#define QT_DECLARE_PARTIALLY_ORDERED_LITERAL_TYPE_2(LeftType, RightType) \
351 QT_DECLARE_ORDERING_OPERATORS_HELPER(PARTIAL, LeftType, RightType, constexpr, \
353 QT_DECLARE_ORDERING_OPERATORS_REVERSED_HELPER(PARTIAL, LeftType, RightType, constexpr, \
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, \
361#define Q_DECLARE_PARTIALLY_ORDERED_LITERAL_TYPE(...) \
362 QT_OVERLOADED_MACRO(QT_DECLARE_PARTIALLY_ORDERED_LITERAL_TYPE, __VA_ARGS__)
365#define QT_DECLARE_WEAKLY_ORDERED_1(Type) \
366 QT_DECLARE_ORDERING_OPERATORS_HELPER(WEAK, Type, Type, , )
368#define QT_DECLARE_WEAKLY_ORDERED_2(LeftType, RightType) \
369 QT_DECLARE_ORDERING_OPERATORS_HELPER(WEAK, LeftType, RightType, , \
371 QT_DECLARE_ORDERING_OPERATORS_REVERSED_HELPER(WEAK, LeftType, RightType, , \
374#define QT_DECLARE_WEAKLY_ORDERED_3(LeftType, RightType, Attributes) \
375 QT_DECLARE_ORDERING_OPERATORS_HELPER(WEAK, LeftType, RightType, , \
377 QT_DECLARE_ORDERING_OPERATORS_REVERSED_HELPER(WEAK, LeftType, RightType, , \
380#define Q_DECLARE_WEAKLY_ORDERED(...) \
381 QT_OVERLOADED_MACRO(QT_DECLARE_WEAKLY_ORDERED, __VA_ARGS__)
383#define QT_DECLARE_WEAKLY_ORDERED_LITERAL_TYPE_1(Type) \
384 QT_DECLARE_ORDERING_OPERATORS_HELPER(WEAK, Type, Type, constexpr, )
386#define QT_DECLARE_WEAKLY_ORDERED_LITERAL_TYPE_2(LeftType, RightType) \
387 QT_DECLARE_ORDERING_OPERATORS_HELPER(WEAK, LeftType, RightType, constexpr, \
389 QT_DECLARE_ORDERING_OPERATORS_REVERSED_HELPER(WEAK, LeftType, RightType, constexpr, \
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, \
397#define Q_DECLARE_WEAKLY_ORDERED_LITERAL_TYPE(...) \
398 QT_OVERLOADED_MACRO(QT_DECLARE_WEAKLY_ORDERED_LITERAL_TYPE, __VA_ARGS__)
401#define QT_DECLARE_STRONGLY_ORDERED_1(Type) \
402 QT_DECLARE_ORDERING_OPERATORS_HELPER(STRONG, Type, Type, , \
405#define QT_DECLARE_STRONGLY_ORDERED_2(LeftType, RightType) \
406 QT_DECLARE_ORDERING_OPERATORS_HELPER(STRONG, LeftType, RightType, , \
408 QT_DECLARE_ORDERING_OPERATORS_REVERSED_HELPER(STRONG, LeftType, RightType, \
411#define QT_DECLARE_STRONGLY_ORDERED_3(LeftType, RightType, Attributes) \
412 QT_DECLARE_ORDERING_OPERATORS_HELPER(STRONG, LeftType, RightType, , \
414 QT_DECLARE_ORDERING_OPERATORS_REVERSED_HELPER(STRONG, LeftType, RightType, \
417#define Q_DECLARE_STRONGLY_ORDERED(...) \
418 QT_OVERLOADED_MACRO(QT_DECLARE_STRONGLY_ORDERED, __VA_ARGS__)
420#define QT_DECLARE_STRONGLY_ORDERED_LITERAL_TYPE_1(Type) \
421 QT_DECLARE_ORDERING_OPERATORS_HELPER(STRONG, Type, Type, constexpr, )
423#define QT_DECLARE_STRONGLY_ORDERED_LITERAL_TYPE_2(LeftType, RightType) \
424 QT_DECLARE_ORDERING_OPERATORS_HELPER(STRONG, LeftType, RightType, constexpr, \
426 QT_DECLARE_ORDERING_OPERATORS_REVERSED_HELPER(STRONG, LeftType, RightType, constexpr, \
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, \
434#define Q_DECLARE_STRONGLY_ORDERED_LITERAL_TYPE(...) \
435 QT_OVERLOADED_MACRO(QT_DECLARE_STRONGLY_ORDERED_LITERAL_TYPE, __VA_ARGS__)
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;
446#if QFLOAT16_IS_NATIVE
448constexpr bool IsFloatType_v<QtPrivate::NativeFloat16Type> =
true;
456using if_integral = std::enable_if_t<QtPrivate::IsIntegralType_v<T>,
bool>;
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>>,
468template <
typename Enum>
469using if_enum = std::enable_if_t<std::is_enum_v<Enum>,
bool>;
471template <
typename LeftInt,
typename RightInt,
472 if_integral<LeftInt> =
true,
473 if_integral<RightInt> =
true>
476 static_assert(std::is_signed_v<LeftInt> == std::is_signed_v<RightInt>,
477 "Qt::compareThreeWay() does not allow mixed-sign comparison.");
479#ifdef __cpp_lib_three_way_comparison
491template <
typename LeftFloat,
typename RightFloat,
492 if_floating_point<LeftFloat> =
true,
493 if_floating_point<RightFloat> =
true>
498#ifdef __cpp_lib_three_way_comparison
513template <
typename IntType,
typename FloatType,
514 if_integral<IntType> =
true,
515 if_floating_point<FloatType> =
true>
521template <
typename FloatType,
typename IntType,
522 if_floating_point<FloatType> =
true,
523 if_integral<IntType> =
true>
529template <
typename LeftType,
typename RightType,
530 if_compatible_pointers<LeftType, RightType> =
true>
533#ifdef __cpp_lib_three_way_comparison
534 return std::compare_three_way{}(lhs, rhs);
538 else if (std::less<>{}(lhs, rhs))
557template <
class Enum, if_enum<Enum> = true>
\variable Qt::partial_ordering::less
\variable Qt::weak_ordering::less
static const partial_ordering equivalent
static const partial_ordering unordered
static const partial_ordering greater
static const partial_ordering less
\inmodule QtCore \title Classes and helpers for defining comparison operators \keyword qtcompare
static const strong_ordering greater
static const strong_ordering less
static const strong_ordering equivalent
Combined button and popup list for selecting options.
constexpr bool IsFloatType_v
constexpr bool IsIntegralType_v
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_DISABLE_FLOAT_COMPARE
QT_BEGIN_NAMESPACE constexpr std::underlying_type_t< Enum > qToUnderlying(Enum e) noexcept