File indexing completed on 2025-09-17 09:09:12
0001
0002
0003
0004 #ifndef QCOMPARE_H
0005 #error "Do not include qcomparehelpers.h directly. Use qcompare.h instead."
0006 #endif
0007
0008 #ifndef QCOMPAREHELPERS_H
0009 #define QCOMPAREHELPERS_H
0010
0011 #if 0
0012 #pragma qt_no_master_include
0013 #pragma qt_sync_skip_header_check
0014 #pragma qt_sync_stop_processing
0015 #endif
0016
0017 #include <QtCore/qflags.h>
0018 #include <QtCore/qoverload.h>
0019 #include <QtCore/qttypetraits.h>
0020 #include <QtCore/qtypeinfo.h>
0021 #include <QtCore/qtypes.h>
0022
0023 #ifdef __cpp_lib_three_way_comparison
0024 #include <compare>
0025 #endif
0026 #include <QtCore/q20type_traits.h>
0027
0028 #include <functional> // std::less, std::hash
0029
0030 QT_BEGIN_NAMESPACE
0031
0032 class QPartialOrdering;
0033
0034 namespace QtOrderingPrivate {
0035 template <typename T> struct is_std_ordering_type : std::false_type {};
0036 template <typename T> struct is_qt_ordering_type : std::false_type {};
0037
0038 template <typename T> constexpr bool is_std_ordering_type_v = is_std_ordering_type<T>::value;
0039 template <typename T> constexpr bool is_qt_ordering_type_v = is_qt_ordering_type<T>::value;
0040
0041 enum class QtOrderingType {
0042 QtOrder = 0x00,
0043 StdOrder = 0x01,
0044 Partial = 0x00,
0045 Weak = 0x20,
0046 Strong = 0x40,
0047 StrengthMask = Weak|Strong,
0048 };
0049 Q_DECLARE_FLAGS(QtOrderingTypeFlag, QtOrderingType)
0050 Q_DECLARE_OPERATORS_FOR_FLAGS(QtOrderingPrivate::QtOrderingTypeFlag)
0051
0052 template <typename QtOrdering> struct StdOrdering;
0053 template <typename StdOrdering> struct QtOrdering;
0054
0055 #ifdef __cpp_lib_three_way_comparison
0056 #define QT_STD_MAP(x) \
0057 template <> struct StdOrdering< Qt::x##_ordering> : q20::type_identity<std::x##_ordering> {};\
0058 template <> struct StdOrdering<std::x##_ordering> : q20::type_identity<std::x##_ordering> {};\
0059 template <> struct QtOrdering<std::x##_ordering> : q20::type_identity< Qt::x##_ordering> {};\
0060 template <> struct QtOrdering< Qt::x##_ordering> : q20::type_identity< Qt::x##_ordering> {};\
0061 template <> struct is_std_ordering_type<std::x##_ordering> : std::true_type {};\
0062 template <> struct is_qt_ordering_type< Qt::x##_ordering> : std::true_type {};\
0063
0064 QT_STD_MAP(partial)
0065 QT_STD_MAP(weak)
0066 QT_STD_MAP(strong)
0067 #undef QT_STD_MAP
0068
0069 template <> struct StdOrdering<QPartialOrdering> : q20::type_identity<std::partial_ordering> {};
0070 template <> struct QtOrdering<QPartialOrdering> : q20::type_identity< Qt::partial_ordering> {};
0071 #else
0072 template <> struct is_qt_ordering_type< Qt::partial_ordering> : std::true_type {};
0073 template <> struct is_qt_ordering_type< Qt::weak_ordering> : std::true_type {};
0074 template <> struct is_qt_ordering_type< Qt::strong_ordering> : std::true_type {};
0075 #endif
0076
0077 template <typename In> constexpr auto to_std(In in) noexcept
0078 -> typename QtOrderingPrivate::StdOrdering<In>::type
0079 { return in; }
0080
0081 template <typename In> constexpr auto to_Qt(In in) noexcept
0082 -> typename QtOrderingPrivate::QtOrdering<In>::type
0083 { return in; }
0084
0085 template <typename T>
0086 constexpr bool is_ordering_type_v
0087 = std::disjunction_v<is_qt_ordering_type<T>, is_std_ordering_type<T>>;
0088
0089 template <typename T>
0090 constexpr std::enable_if_t<is_qt_ordering_type_v<T>, QtOrderingTypeFlag>
0091 orderingFlagsFor(T t) noexcept
0092 {
0093 QtOrderingTypeFlag flags = QtOrderingType::QtOrder;
0094 Qt::partial_ordering convertedOrder(t);
0095 if constexpr (std::is_same_v<T, Qt::strong_ordering>)
0096 flags = flags | QtOrderingType::Strong;
0097 else if constexpr (std::is_same_v<T, Qt::partial_ordering>)
0098 flags = flags | QtOrderingType::Partial;
0099 else if constexpr (std::is_same_v<T, Qt::weak_ordering>)
0100 flags = flags | QtOrderingType::Weak;
0101 return flags;
0102 }
0103
0104 template <typename T>
0105 constexpr std::enable_if_t<is_std_ordering_type_v<T>, QtOrderingTypeFlag>
0106 orderingFlagsFor(T t) noexcept
0107 {
0108 QtOrderingPrivate::QtOrderingTypeFlag flags = QtOrderingPrivate::QtOrderingType::StdOrder;
0109 return QtOrderingTypeFlag(flags
0110 | QtOrderingPrivate::orderingFlagsFor(QtOrderingPrivate::to_Qt(t)));
0111 }
0112 }
0113
0114
0115
0116
0117
0118
0119
0120
0121
0122
0123
0124
0125
0126
0127
0128
0129
0130
0131
0132
0133
0134
0135
0136
0137
0138
0139
0140
0141
0142
0143
0144
0145
0146
0147
0148
0149
0150
0151
0152
0153
0154
0155
0156
0157 #if defined(__cpp_lib_three_way_comparison) || !(defined(Q_OS_QNX) || defined(Q_CC_GHS))
0158 # define QT_COMPARISON_NOEXCEPT_CHECK(Noexcept, Func) \
0159 constexpr auto f = []() Noexcept {}; \
0160 static_assert(!noexcept(f()) || noexcept(Func(lhs, rhs)), \
0161 "Use *_NON_NOEXCEPT version of the macro, " \
0162 "or make the helper function noexcept")
0163 #else
0164 # define QT_COMPARISON_NOEXCEPT_CHECK(Noexcept, Func)
0165 #endif
0166
0167
0168
0169
0170
0171
0172 #if defined(__cpp_lib_three_way_comparison) && !defined(Q_QDOC)
0173
0174
0175 #define QT_DECLARE_EQUALITY_OPERATORS_HELPER(LeftType, RightType, Constexpr, \
0176 Noexcept, ...) \
0177 __VA_ARGS__ \
0178 friend Constexpr bool operator==(LeftType const &lhs, RightType const &rhs) Noexcept \
0179 { \
0180 QT_COMPARISON_NOEXCEPT_CHECK(Noexcept, comparesEqual); \
0181 return comparesEqual(lhs, rhs); \
0182 }
0183
0184 #define QT_DECLARE_ORDERING_HELPER_STRONG(LeftType, RightType, Constexpr, Noexcept, ...) \
0185 __VA_ARGS__ \
0186 friend Constexpr std::strong_ordering \
0187 operator<=>(LeftType const &lhs, RightType const &rhs) Noexcept \
0188 { \
0189 QT_COMPARISON_NOEXCEPT_CHECK(Noexcept, compareThreeWay); \
0190 return compareThreeWay(lhs, rhs); \
0191 }
0192
0193 #define QT_DECLARE_ORDERING_HELPER_WEAK(LeftType, RightType, Constexpr, Noexcept, ...) \
0194 __VA_ARGS__ \
0195 friend Constexpr std::weak_ordering \
0196 operator<=>(LeftType const &lhs, RightType const &rhs) Noexcept \
0197 { \
0198 QT_COMPARISON_NOEXCEPT_CHECK(Noexcept, compareThreeWay); \
0199 return compareThreeWay(lhs, rhs); \
0200 }
0201
0202 #define QT_DECLARE_ORDERING_HELPER_PARTIAL(LeftType, RightType, Constexpr, Noexcept, ...) \
0203 __VA_ARGS__ \
0204 friend Constexpr std::partial_ordering \
0205 operator<=>(LeftType const &lhs, RightType const &rhs) Noexcept \
0206 { \
0207 QT_COMPARISON_NOEXCEPT_CHECK(Noexcept, compareThreeWay); \
0208 return compareThreeWay(lhs, rhs); \
0209 }
0210
0211 #define QT_DECLARE_ORDERING_HELPER_AUTO(LeftType, RightType, Constexpr, Noexcept, ...) \
0212 __VA_ARGS__ \
0213 friend Constexpr auto \
0214 operator<=>(LeftType const &lhs, RightType const &rhs) Noexcept \
0215 { \
0216 QT_COMPARISON_NOEXCEPT_CHECK(Noexcept, compareThreeWay);\
0217 return QtOrderingPrivate::to_std(compareThreeWay(lhs, rhs)); \
0218 }
0219
0220 #define QT_DECLARE_ORDERING_OPERATORS_HELPER(OrderingType, LeftType, RightType, Constexpr, \
0221 Noexcept, ...) \
0222 QT_DECLARE_EQUALITY_OPERATORS_HELPER(LeftType, RightType, Constexpr, Noexcept, __VA_ARGS__) \
0223 QT_DECLARE_ORDERING_HELPER_ ## OrderingType (LeftType, RightType, Constexpr, Noexcept, \
0224 __VA_ARGS__)
0225
0226 #ifdef Q_COMPILER_LACKS_THREE_WAY_COMPARE_SYMMETRY
0227
0228
0229 #define QT_DECLARE_EQUALITY_OPERATORS_REVERSED_HELPER(LeftType, RightType, Constexpr, \
0230 Noexcept, ...) \
0231 __VA_ARGS__ \
0232 friend Constexpr bool operator==(RightType const &lhs, LeftType const &rhs) Noexcept \
0233 { return comparesEqual(rhs, lhs); }
0234
0235 #define QT_DECLARE_REVERSED_ORDERING_HELPER_STRONG(LeftType, RightType, Constexpr, \
0236 Noexcept, ...) \
0237 __VA_ARGS__ \
0238 friend Constexpr std::strong_ordering \
0239 operator<=>(RightType const &lhs, LeftType const &rhs) Noexcept \
0240 { \
0241 const auto r = compareThreeWay(rhs, lhs); \
0242 return QtOrderingPrivate::reversed(r); \
0243 }
0244
0245 #define QT_DECLARE_REVERSED_ORDERING_HELPER_WEAK(LeftType, RightType, Constexpr, \
0246 Noexcept, ...) \
0247 __VA_ARGS__ \
0248 friend Constexpr std::weak_ordering \
0249 operator<=>(RightType const &lhs, LeftType const &rhs) Noexcept \
0250 { \
0251 const auto r = compareThreeWay(rhs, lhs); \
0252 return QtOrderingPrivate::reversed(r); \
0253 }
0254
0255 #define QT_DECLARE_REVERSED_ORDERING_HELPER_PARTIAL(LeftType, RightType, Constexpr, \
0256 Noexcept, ...) \
0257 __VA_ARGS__ \
0258 friend Constexpr std::partial_ordering \
0259 operator<=>(RightType const &lhs, LeftType const &rhs) Noexcept \
0260 { \
0261 const auto r = compareThreeWay(rhs, lhs); \
0262 return QtOrderingPrivate::reversed(r); \
0263 }
0264
0265 #define QT_DECLARE_REVERSED_ORDERING_HELPER_AUTO(LeftType, RightType, Constexpr, Noexcept, ...) \
0266 __VA_ARGS__ \
0267 friend Constexpr auto \
0268 operator<=>(RightType const &lhs, LeftType const &rhs) Noexcept \
0269 { \
0270 const auto r = compareThreeWay(rhs, lhs); \
0271 return QtOrderingPrivate::to_std(QtOrderingPrivate::reversed(r)); \
0272 }
0273
0274 #define QT_DECLARE_ORDERING_OPERATORS_REVERSED_HELPER(OrderingString, LeftType, RightType, \
0275 Constexpr, Noexcept, ...) \
0276 QT_DECLARE_EQUALITY_OPERATORS_REVERSED_HELPER(LeftType, RightType, Constexpr, \
0277 Noexcept, __VA_ARGS__) \
0278 QT_DECLARE_REVERSED_ORDERING_HELPER_ ## OrderingString (LeftType, RightType, Constexpr, \
0279 Noexcept, __VA_ARGS__)
0280
0281 #else
0282
0283
0284 #define QT_DECLARE_EQUALITY_OPERATORS_REVERSED_HELPER(LeftType, RightType, Constexpr, \
0285 Noexcept, ...)
0286 #define QT_DECLARE_ORDERING_OPERATORS_REVERSED_HELPER(OrderingString, LeftType, RightType, \
0287 Constexpr, Noexcept, ...)
0288
0289 #endif
0290
0291 #else
0292
0293
0294
0295 #define QT_DECLARE_EQUALITY_OPERATORS_HELPER(LeftType, RightType, Constexpr, \
0296 Noexcept, ...) \
0297 __VA_ARGS__ \
0298 friend Constexpr bool operator==(LeftType const &lhs, RightType const &rhs) Noexcept \
0299 { \
0300 QT_COMPARISON_NOEXCEPT_CHECK(Noexcept, comparesEqual); \
0301 return comparesEqual(lhs, rhs); \
0302 } \
0303 __VA_ARGS__ \
0304 friend Constexpr bool operator!=(LeftType const &lhs, RightType const &rhs) Noexcept \
0305 { return !comparesEqual(lhs, rhs); }
0306
0307
0308 #define QT_DECLARE_EQUALITY_OPERATORS_REVERSED_HELPER(LeftType, RightType, Constexpr, \
0309 Noexcept, ...) \
0310 __VA_ARGS__ \
0311 friend Constexpr bool operator==(RightType const &lhs, LeftType const &rhs) Noexcept \
0312 { return comparesEqual(rhs, lhs); } \
0313 __VA_ARGS__ \
0314 friend Constexpr bool operator!=(RightType const &lhs, LeftType const &rhs) Noexcept \
0315 { return !comparesEqual(rhs, lhs); }
0316
0317 #define QT_DECLARE_ORDERING_HELPER_TEMPLATE(OrderingType, LeftType, RightType, Constexpr, \
0318 Noexcept, ...) \
0319 __VA_ARGS__ \
0320 friend Constexpr bool operator<(LeftType const &lhs, RightType const &rhs) Noexcept \
0321 { \
0322 QT_COMPARISON_NOEXCEPT_CHECK(Noexcept, compareThreeWay); \
0323 return is_lt(compareThreeWay(lhs, rhs)); \
0324 } \
0325 __VA_ARGS__ \
0326 friend Constexpr bool operator>(LeftType const &lhs, RightType const &rhs) Noexcept \
0327 { return is_gt(compareThreeWay(lhs, rhs)); } \
0328 __VA_ARGS__ \
0329 friend Constexpr bool operator<=(LeftType const &lhs, RightType const &rhs) Noexcept \
0330 { return is_lteq(compareThreeWay(lhs, rhs)); } \
0331 __VA_ARGS__ \
0332 friend Constexpr bool operator>=(LeftType const &lhs, RightType const &rhs) Noexcept \
0333 { return is_gteq(compareThreeWay(lhs, rhs)); }
0334
0335 #define QT_DECLARE_ORDERING_HELPER_AUTO(LeftType, RightType, Constexpr, Noexcept, ...) \
0336 QT_DECLARE_ORDERING_HELPER_TEMPLATE(auto, LeftType, RightType, Constexpr, Noexcept, \
0337 __VA_ARGS__)
0338
0339 #define QT_DECLARE_ORDERING_HELPER_PARTIAL(LeftType, RightType, Constexpr, Noexcept, ...) \
0340 QT_DECLARE_ORDERING_HELPER_TEMPLATE(Qt::partial_ordering, LeftType, RightType, Constexpr, \
0341 Noexcept, __VA_ARGS__)
0342
0343 #define QT_DECLARE_ORDERING_HELPER_WEAK(LeftType, RightType, Constexpr, Noexcept, ...) \
0344 QT_DECLARE_ORDERING_HELPER_TEMPLATE(Qt::weak_ordering, LeftType, RightType, Constexpr, \
0345 Noexcept, __VA_ARGS__)
0346
0347 #define QT_DECLARE_ORDERING_HELPER_STRONG(LeftType, RightType, Constexpr, Noexcept, ...) \
0348 QT_DECLARE_ORDERING_HELPER_TEMPLATE(Qt::strong_ordering, LeftType, RightType, Constexpr, \
0349 Noexcept, __VA_ARGS__)
0350
0351 #define QT_DECLARE_ORDERING_OPERATORS_HELPER(OrderingString, LeftType, RightType, Constexpr, \
0352 Noexcept, ...) \
0353 QT_DECLARE_EQUALITY_OPERATORS_HELPER(LeftType, RightType, Constexpr, Noexcept, __VA_ARGS__) \
0354 QT_DECLARE_ORDERING_HELPER_ ## OrderingString (LeftType, RightType, Constexpr, Noexcept, \
0355 __VA_ARGS__)
0356
0357
0358 #define QT_DECLARE_REVERSED_ORDERING_HELPER_TEMPLATE(OrderingType, LeftType, RightType, Constexpr, \
0359 Noexcept, ...) \
0360 __VA_ARGS__ \
0361 friend Constexpr bool operator<(RightType const &lhs, LeftType const &rhs) Noexcept \
0362 { return is_gt(compareThreeWay(rhs, lhs)); } \
0363 __VA_ARGS__ \
0364 friend Constexpr bool operator>(RightType const &lhs, LeftType const &rhs) Noexcept \
0365 { return is_lt(compareThreeWay(rhs, lhs)); } \
0366 __VA_ARGS__ \
0367 friend Constexpr bool operator<=(RightType const &lhs, LeftType const &rhs) Noexcept \
0368 { return is_gteq(compareThreeWay(rhs, lhs)); } \
0369 __VA_ARGS__ \
0370 friend Constexpr bool operator>=(RightType const &lhs, LeftType const &rhs) Noexcept \
0371 { return is_lteq(compareThreeWay(rhs, lhs)); }
0372
0373 #define QT_DECLARE_REVERSED_ORDERING_HELPER_AUTO(LeftType, RightType, Constexpr, Noexcept, ...) \
0374 QT_DECLARE_REVERSED_ORDERING_HELPER_TEMPLATE(auto, LeftType, RightType, Constexpr, Noexcept, \
0375 __VA_ARGS__)
0376
0377 #define QT_DECLARE_REVERSED_ORDERING_HELPER_PARTIAL(LeftType, RightType, Constexpr, Noexcept, ...) \
0378 QT_DECLARE_REVERSED_ORDERING_HELPER_TEMPLATE(Qt::partial_ordering, LeftType, RightType, \
0379 Constexpr, Noexcept, __VA_ARGS__)
0380
0381 #define QT_DECLARE_REVERSED_ORDERING_HELPER_WEAK(LeftType, RightType, Constexpr, Noexcept, ...) \
0382 QT_DECLARE_REVERSED_ORDERING_HELPER_TEMPLATE(Qt::weak_ordering, LeftType, RightType, \
0383 Constexpr, Noexcept, __VA_ARGS__)
0384
0385 #define QT_DECLARE_REVERSED_ORDERING_HELPER_STRONG(LeftType, RightType, Constexpr, Noexcept, ...) \
0386 QT_DECLARE_REVERSED_ORDERING_HELPER_TEMPLATE(Qt::strong_ordering, LeftType, RightType, \
0387 Constexpr, Noexcept, __VA_ARGS__)
0388
0389 #define QT_DECLARE_ORDERING_OPERATORS_REVERSED_HELPER(OrderingString, LeftType, RightType, \
0390 Constexpr, Noexcept, ...) \
0391 QT_DECLARE_EQUALITY_OPERATORS_REVERSED_HELPER(LeftType, RightType, Constexpr, Noexcept, \
0392 __VA_ARGS__) \
0393 QT_DECLARE_REVERSED_ORDERING_HELPER_ ## OrderingString (LeftType, RightType, Constexpr, \
0394 Noexcept, __VA_ARGS__)
0395
0396 #endif
0397
0398
0399
0400
0401 #define QT_DECLARE_EQUALITY_COMPARABLE_1(Type) \
0402 QT_DECLARE_EQUALITY_OPERATORS_HELPER(Type, Type, , noexcept(true), \
0403 )
0404
0405 #define QT_DECLARE_EQUALITY_COMPARABLE_2(LeftType, RightType) \
0406 QT_DECLARE_EQUALITY_OPERATORS_HELPER(LeftType, RightType, , \
0407 noexcept(true), ) \
0408 QT_DECLARE_EQUALITY_OPERATORS_REVERSED_HELPER(LeftType, RightType, , \
0409 noexcept(true), )
0410
0411 #define QT_DECLARE_EQUALITY_COMPARABLE_3(LeftType, RightType, ...) \
0412 QT_DECLARE_EQUALITY_OPERATORS_HELPER(LeftType, RightType, , \
0413 noexcept(true), __VA_ARGS__) \
0414 QT_DECLARE_EQUALITY_OPERATORS_REVERSED_HELPER(LeftType, RightType, , \
0415 noexcept(true), __VA_ARGS__)
0416
0417 #define QT_DECLARE_EQUALITY_COMPARABLE_4(...) \
0418 QT_VA_ARGS_EXPAND(QT_DECLARE_EQUALITY_COMPARABLE_3(__VA_ARGS__))
0419 #define QT_DECLARE_EQUALITY_COMPARABLE_5(...) \
0420 QT_VA_ARGS_EXPAND(QT_DECLARE_EQUALITY_COMPARABLE_3(__VA_ARGS__))
0421 #define QT_DECLARE_EQUALITY_COMPARABLE_6(...) \
0422 QT_VA_ARGS_EXPAND(QT_DECLARE_EQUALITY_COMPARABLE_3(__VA_ARGS__))
0423 #define QT_DECLARE_EQUALITY_COMPARABLE_7(...) \
0424 QT_VA_ARGS_EXPAND(QT_DECLARE_EQUALITY_COMPARABLE_3(__VA_ARGS__))
0425 #define QT_DECLARE_EQUALITY_COMPARABLE_8(...) \
0426 QT_VA_ARGS_EXPAND(QT_DECLARE_EQUALITY_COMPARABLE_3(__VA_ARGS__))
0427 #define QT_DECLARE_EQUALITY_COMPARABLE_9(...) \
0428 QT_VA_ARGS_EXPAND(QT_DECLARE_EQUALITY_COMPARABLE_3(__VA_ARGS__))
0429
0430 #define Q_DECLARE_EQUALITY_COMPARABLE(...) \
0431 QT_OVERLOADED_MACRO(QT_DECLARE_EQUALITY_COMPARABLE, __VA_ARGS__)
0432
0433 #define QT_DECLARE_EQUALITY_COMPARABLE_LITERAL_TYPE_1(Type) \
0434 QT_DECLARE_EQUALITY_OPERATORS_HELPER(Type, Type, constexpr, noexcept(true), \
0435 )
0436
0437 #define QT_DECLARE_EQUALITY_COMPARABLE_LITERAL_TYPE_2(LeftType, RightType) \
0438 QT_DECLARE_EQUALITY_OPERATORS_HELPER(LeftType, RightType, constexpr, noexcept(true), \
0439 ) \
0440 QT_DECLARE_EQUALITY_OPERATORS_REVERSED_HELPER(LeftType, RightType, constexpr, \
0441 noexcept(true), )
0442
0443 #define QT_DECLARE_EQUALITY_COMPARABLE_LITERAL_TYPE_3(LeftType, RightType, ...) \
0444 QT_DECLARE_EQUALITY_OPERATORS_HELPER(LeftType, RightType, constexpr, noexcept(true), \
0445 __VA_ARGS__) \
0446 QT_DECLARE_EQUALITY_OPERATORS_REVERSED_HELPER(LeftType, RightType, constexpr, noexcept(true), \
0447 __VA_ARGS__)
0448
0449 #define QT_DECLARE_EQUALITY_COMPARABLE_LITERAL_TYPE_4(...) \
0450 QT_VA_ARGS_EXPAND(QT_DECLARE_EQUALITY_COMPARABLE_LITERAL_TYPE_3(__VA_ARGS__))
0451 #define QT_DECLARE_EQUALITY_COMPARABLE_LITERAL_TYPE_5(...) \
0452 QT_VA_ARGS_EXPAND(QT_DECLARE_EQUALITY_COMPARABLE_LITERAL_TYPE_3(__VA_ARGS__))
0453 #define QT_DECLARE_EQUALITY_COMPARABLE_LITERAL_TYPE_6(...) \
0454 QT_VA_ARGS_EXPAND(QT_DECLARE_EQUALITY_COMPARABLE_LITERAL_TYPE_3(__VA_ARGS__))
0455 #define QT_DECLARE_EQUALITY_COMPARABLE_LITERAL_TYPE_7(...) \
0456 QT_VA_ARGS_EXPAND(QT_DECLARE_EQUALITY_COMPARABLE_LITERAL_TYPE_3(__VA_ARGS__))
0457 #define QT_DECLARE_EQUALITY_COMPARABLE_LITERAL_TYPE_8(...) \
0458 QT_VA_ARGS_EXPAND(QT_DECLARE_EQUALITY_COMPARABLE_LITERAL_TYPE_3(__VA_ARGS__))
0459 #define QT_DECLARE_EQUALITY_COMPARABLE_LITERAL_TYPE_9(...) \
0460 QT_VA_ARGS_EXPAND(QT_DECLARE_EQUALITY_COMPARABLE_LITERAL_TYPE_3(__VA_ARGS__))
0461
0462 #define Q_DECLARE_EQUALITY_COMPARABLE_LITERAL_TYPE(...) \
0463 QT_OVERLOADED_MACRO(QT_DECLARE_EQUALITY_COMPARABLE_LITERAL_TYPE, __VA_ARGS__)
0464
0465 #define QT_DECLARE_EQUALITY_COMPARABLE_NON_NOEXCEPT_1(Type) \
0466 QT_DECLARE_EQUALITY_OPERATORS_HELPER(Type, Type, , noexcept(false), \
0467 )
0468
0469 #define QT_DECLARE_EQUALITY_COMPARABLE_NON_NOEXCEPT_2(LeftType, RightType) \
0470 QT_DECLARE_EQUALITY_OPERATORS_HELPER(LeftType, RightType, , \
0471 noexcept(false), ) \
0472 QT_DECLARE_EQUALITY_OPERATORS_REVERSED_HELPER(LeftType, RightType, , \
0473 noexcept(false), )
0474
0475 #define QT_DECLARE_EQUALITY_COMPARABLE_NON_NOEXCEPT_3(LeftType, RightType, ...) \
0476 QT_DECLARE_EQUALITY_OPERATORS_HELPER(LeftType, RightType, , \
0477 noexcept(false), __VA_ARGS__) \
0478 QT_DECLARE_EQUALITY_OPERATORS_REVERSED_HELPER(LeftType, RightType, , \
0479 noexcept(false), __VA_ARGS__)
0480
0481 #define QT_DECLARE_EQUALITY_COMPARABLE_NON_NOEXCEPT_4(...) \
0482 QT_VA_ARGS_EXPAND(QT_DECLARE_EQUALITY_COMPARABLE_NON_NOEXCEPT_3(__VA_ARGS__))
0483 #define QT_DECLARE_EQUALITY_COMPARABLE_NON_NOEXCEPT_5(...) \
0484 QT_VA_ARGS_EXPAND(QT_DECLARE_EQUALITY_COMPARABLE_NON_NOEXCEPT_3(__VA_ARGS__))
0485 #define QT_DECLARE_EQUALITY_COMPARABLE_NON_NOEXCEPT_6(...) \
0486 QT_VA_ARGS_EXPAND(QT_DECLARE_EQUALITY_COMPARABLE_NON_NOEXCEPT_3(__VA_ARGS__))
0487 #define QT_DECLARE_EQUALITY_COMPARABLE_NON_NOEXCEPT_7(...) \
0488 QT_VA_ARGS_EXPAND(QT_DECLARE_EQUALITY_COMPARABLE_NON_NOEXCEPT_3(__VA_ARGS__))
0489 #define QT_DECLARE_EQUALITY_COMPARABLE_NON_NOEXCEPT_8(...) \
0490 QT_VA_ARGS_EXPAND(QT_DECLARE_EQUALITY_COMPARABLE_NON_NOEXCEPT_3(__VA_ARGS__))
0491 #define QT_DECLARE_EQUALITY_COMPARABLE_NON_NOEXCEPT_9(...) \
0492 QT_VA_ARGS_EXPAND(QT_DECLARE_EQUALITY_COMPARABLE_NON_NOEXCEPT_3(__VA_ARGS__))
0493
0494 #define Q_DECLARE_EQUALITY_COMPARABLE_NON_NOEXCEPT(...) \
0495 QT_OVERLOADED_MACRO(QT_DECLARE_EQUALITY_COMPARABLE_NON_NOEXCEPT, __VA_ARGS__)
0496
0497
0498 #define QT_DECLARE_ORDERED_1(Type) \
0499 QT_DECLARE_ORDERING_OPERATORS_HELPER(AUTO, Type, Type, , noexcept(true), \
0500 )
0501
0502 #define QT_DECLARE_ORDERED_2(LeftType, RightType) \
0503 QT_DECLARE_ORDERING_OPERATORS_HELPER(AUTO, LeftType, RightType, , \
0504 noexcept(true), ) \
0505 QT_DECLARE_ORDERING_OPERATORS_REVERSED_HELPER(AUTO, LeftType, RightType, , \
0506 noexcept(true), )
0507
0508 #define QT_DECLARE_ORDERED_3(LeftType, RightType, ...) \
0509 QT_DECLARE_ORDERING_OPERATORS_HELPER(AUTO, LeftType, RightType, , \
0510 noexcept(true), __VA_ARGS__) \
0511 QT_DECLARE_ORDERING_OPERATORS_REVERSED_HELPER(AUTO, LeftType, RightType, , \
0512 noexcept(true), __VA_ARGS__)
0513
0514 #define QT_DECLARE_ORDERED_4(...) QT_VA_ARGS_EXPAND(QT_DECLARE_ORDERED_3(__VA_ARGS__))
0515 #define QT_DECLARE_ORDERED_5(...) QT_VA_ARGS_EXPAND(QT_DECLARE_ORDERED_3(__VA_ARGS__))
0516 #define QT_DECLARE_ORDERED_6(...) QT_VA_ARGS_EXPAND(QT_DECLARE_ORDERED_3(__VA_ARGS__))
0517 #define QT_DECLARE_ORDERED_7(...) QT_VA_ARGS_EXPAND(QT_DECLARE_ORDERED_3(__VA_ARGS__))
0518 #define QT_DECLARE_ORDERED_8(...) QT_VA_ARGS_EXPAND(QT_DECLARE_ORDERED_3(__VA_ARGS__))
0519 #define QT_DECLARE_ORDERED_9(...) QT_VA_ARGS_EXPAND(QT_DECLARE_ORDERED_3(__VA_ARGS__))
0520
0521 #define Q_DECLARE_ORDERED(...) QT_OVERLOADED_MACRO(QT_DECLARE_ORDERED, __VA_ARGS__)
0522
0523 #define QT_DECLARE_ORDERED_LITERAL_TYPE_1(Type) \
0524 QT_DECLARE_ORDERING_OPERATORS_HELPER(AUTO, Type, Type, constexpr, noexcept(true), \
0525 )
0526
0527 #define QT_DECLARE_ORDERED_LITERAL_TYPE_2(LeftType, RightType) \
0528 QT_DECLARE_ORDERING_OPERATORS_HELPER(AUTO, LeftType, RightType, constexpr, \
0529 noexcept(true), ) \
0530 QT_DECLARE_ORDERING_OPERATORS_REVERSED_HELPER(AUTO, LeftType, RightType, constexpr, \
0531 noexcept(true), )
0532
0533 #define QT_DECLARE_ORDERED_LITERAL_TYPE_3(LeftType, RightType, ...) \
0534 QT_DECLARE_ORDERING_OPERATORS_HELPER(AUTO, LeftType, RightType, constexpr, \
0535 noexcept(true), __VA_ARGS__) \
0536 QT_DECLARE_ORDERING_OPERATORS_REVERSED_HELPER(AUTO, LeftType, RightType, constexpr, \
0537 noexcept(true), __VA_ARGS__)
0538
0539 #define QT_DECLARE_ORDERED_LITERAL_TYPE_4(...) \
0540 QT_VA_ARGS_EXPAND(QT_DECLARE_ORDERED_LITERAL_TYPE_3(__VA_ARGS__))
0541 #define QT_DECLARE_ORDERED_LITERAL_TYPE_5(...) \
0542 QT_VA_ARGS_EXPAND(QT_DECLARE_ORDERED_LITERAL_TYPE_3(__VA_ARGS__))
0543 #define QT_DECLARE_ORDERED_LITERAL_TYPE_6(...) \
0544 QT_VA_ARGS_EXPAND(QT_DECLARE_ORDERED_LITERAL_TYPE_3(__VA_ARGS__))
0545 #define QT_DECLARE_ORDERED_LITERAL_TYPE_7(...) \
0546 QT_VA_ARGS_EXPAND(QT_DECLARE_ORDERED_LITERAL_TYPE_3(__VA_ARGS__))
0547 #define QT_DECLARE_ORDERED_LITERAL_TYPE_8(...) \
0548 QT_VA_ARGS_EXPAND(QT_DECLARE_ORDERED_LITERAL_TYPE_3(__VA_ARGS__))
0549 #define QT_DECLARE_ORDERED_LITERAL_TYPE_9(...) \
0550 QT_VA_ARGS_EXPAND(QT_DECLARE_ORDERED_LITERAL_TYPE_3(__VA_ARGS__))
0551
0552 #define Q_DECLARE_ORDERED_LITERAL_TYPE(...) \
0553 QT_OVERLOADED_MACRO(QT_DECLARE_ORDERED_LITERAL_TYPE, __VA_ARGS__)
0554
0555 #define QT_DECLARE_ORDERED_NON_NOEXCEPT_1(Type) \
0556 QT_DECLARE_ORDERING_OPERATORS_HELPER(AUTO, Type, Type, , noexcept(false), \
0557 )
0558
0559 #define QT_DECLARE_ORDERED_NON_NOEXCEPT_2(LeftType, RightType) \
0560 QT_DECLARE_ORDERING_OPERATORS_HELPER(AUTO, LeftType, RightType, , \
0561 noexcept(false), ) \
0562 QT_DECLARE_ORDERING_OPERATORS_REVERSED_HELPER(AUTO, LeftType, RightType, , \
0563 noexcept(false), )
0564
0565 #define QT_DECLARE_ORDERED_NON_NOEXCEPT_3(LeftType, RightType, ...) \
0566 QT_DECLARE_ORDERING_OPERATORS_HELPER(AUTO, LeftType, RightType, , \
0567 noexcept(false), __VA_ARGS__) \
0568 QT_DECLARE_ORDERING_OPERATORS_REVERSED_HELPER(AUTO, LeftType, RightType, , \
0569 noexcept(false), __VA_ARGS__)
0570
0571 #define QT_DECLARE_ORDERED_NON_NOEXCEPT_4(...) \
0572 QT_VA_ARGS_EXPAND(QT_DECLARE_ORDERED_NON_NOEXCEPT_3(__VA_ARGS__))
0573 #define QT_DECLARE_ORDERED_NON_NOEXCEPT_5(...) \
0574 QT_VA_ARGS_EXPAND(QT_DECLARE_ORDERED_NON_NOEXCEPT_3(__VA_ARGS__))
0575 #define QT_DECLARE_ORDERED_NON_NOEXCEPT_6(...) \
0576 QT_VA_ARGS_EXPAND(QT_DECLARE_ORDERED_NON_NOEXCEPT_3(__VA_ARGS__))
0577 #define QT_DECLARE_ORDERED_NON_NOEXCEPT_7(...) \
0578 QT_VA_ARGS_EXPAND(QT_DECLARE_ORDERED_NON_NOEXCEPT_3(__VA_ARGS__))
0579 #define QT_DECLARE_ORDERED_NON_NOEXCEPT_8(...) \
0580 QT_VA_ARGS_EXPAND(QT_DECLARE_ORDERED_NON_NOEXCEPT_3(__VA_ARGS__))
0581 #define QT_DECLARE_ORDERED_NON_NOEXCEPT_9(...) \
0582 QT_VA_ARGS_EXPAND(QT_DECLARE_ORDERED_NON_NOEXCEPT_3(__VA_ARGS__))
0583
0584 #define Q_DECLARE_ORDERED_NON_NOEXCEPT(...) \
0585 QT_OVERLOADED_MACRO(QT_DECLARE_ORDERED_NON_NOEXCEPT, __VA_ARGS__)
0586
0587
0588 #define QT_DECLARE_PARTIALLY_ORDERED_1(Type) \
0589 QT_DECLARE_ORDERING_OPERATORS_HELPER(PARTIAL, Type, Type, , \
0590 noexcept(true), )
0591
0592 #define QT_DECLARE_PARTIALLY_ORDERED_2(LeftType, RightType) \
0593 QT_DECLARE_ORDERING_OPERATORS_HELPER(PARTIAL, LeftType, RightType, , \
0594 noexcept(true), ) \
0595 QT_DECLARE_ORDERING_OPERATORS_REVERSED_HELPER(PARTIAL, LeftType, RightType, \
0596 , noexcept(true), \
0597 )
0598
0599 #define QT_DECLARE_PARTIALLY_ORDERED_3(LeftType, RightType, ...) \
0600 QT_DECLARE_ORDERING_OPERATORS_HELPER(PARTIAL, LeftType, RightType, , \
0601 noexcept(true), __VA_ARGS__) \
0602 QT_DECLARE_ORDERING_OPERATORS_REVERSED_HELPER(PARTIAL, LeftType, RightType, \
0603 , noexcept(true), __VA_ARGS__)
0604
0605 #define QT_DECLARE_PARTIALLY_ORDERED_4(...) \
0606 QT_VA_ARGS_EXPAND(QT_DECLARE_PARTIALLY_ORDERED_3(__VA_ARGS__))
0607 #define QT_DECLARE_PARTIALLY_ORDERED_5(...) \
0608 QT_VA_ARGS_EXPAND(QT_DECLARE_PARTIALLY_ORDERED_3(__VA_ARGS__))
0609 #define QT_DECLARE_PARTIALLY_ORDERED_6(...) \
0610 QT_VA_ARGS_EXPAND(QT_DECLARE_PARTIALLY_ORDERED_3(__VA_ARGS__))
0611 #define QT_DECLARE_PARTIALLY_ORDERED_7(...) \
0612 QT_VA_ARGS_EXPAND(QT_DECLARE_PARTIALLY_ORDERED_3(__VA_ARGS__))
0613 #define QT_DECLARE_PARTIALLY_ORDERED_8(...) \
0614 QT_VA_ARGS_EXPAND(QT_DECLARE_PARTIALLY_ORDERED_3(__VA_ARGS__))
0615 #define QT_DECLARE_PARTIALLY_ORDERED_9(...) \
0616 QT_VA_ARGS_EXPAND(QT_DECLARE_PARTIALLY_ORDERED_3(__VA_ARGS__))
0617
0618 #define Q_DECLARE_PARTIALLY_ORDERED(...) \
0619 QT_OVERLOADED_MACRO(QT_DECLARE_PARTIALLY_ORDERED, __VA_ARGS__)
0620
0621 #define QT_DECLARE_PARTIALLY_ORDERED_LITERAL_TYPE_1(Type) \
0622 QT_DECLARE_ORDERING_OPERATORS_HELPER(PARTIAL, Type, Type, constexpr, noexcept(true), \
0623 )
0624
0625 #define QT_DECLARE_PARTIALLY_ORDERED_LITERAL_TYPE_2(LeftType, RightType) \
0626 QT_DECLARE_ORDERING_OPERATORS_HELPER(PARTIAL, LeftType, RightType, constexpr, \
0627 noexcept(true), ) \
0628 QT_DECLARE_ORDERING_OPERATORS_REVERSED_HELPER(PARTIAL, LeftType, RightType, constexpr, \
0629 noexcept(true), )
0630
0631 #define QT_DECLARE_PARTIALLY_ORDERED_LITERAL_TYPE_3(LeftType, RightType, ...) \
0632 QT_DECLARE_ORDERING_OPERATORS_HELPER(PARTIAL, LeftType, RightType, constexpr, noexcept(true), \
0633 __VA_ARGS__) \
0634 QT_DECLARE_ORDERING_OPERATORS_REVERSED_HELPER(PARTIAL, LeftType, RightType, constexpr, \
0635 noexcept(true), __VA_ARGS__)
0636
0637 #define QT_DECLARE_PARTIALLY_ORDERED_LITERAL_TYPE_4(...) \
0638 QT_VA_ARGS_EXPAND(QT_DECLARE_PARTIALLY_ORDERED_LITERAL_TYPE_3(__VA_ARGS__))
0639 #define QT_DECLARE_PARTIALLY_ORDERED_LITERAL_TYPE_5(...) \
0640 QT_VA_ARGS_EXPAND(QT_DECLARE_PARTIALLY_ORDERED_LITERAL_TYPE_3(__VA_ARGS__))
0641 #define QT_DECLARE_PARTIALLY_ORDERED_LITERAL_TYPE_6(...) \
0642 QT_VA_ARGS_EXPAND(QT_DECLARE_PARTIALLY_ORDERED_LITERAL_TYPE_3(__VA_ARGS__))
0643 #define QT_DECLARE_PARTIALLY_ORDERED_LITERAL_TYPE_7(...) \
0644 QT_VA_ARGS_EXPAND(QT_DECLARE_PARTIALLY_ORDERED_LITERAL_TYPE_3(__VA_ARGS__))
0645 #define QT_DECLARE_PARTIALLY_ORDERED_LITERAL_TYPE_8(...) \
0646 QT_VA_ARGS_EXPAND(QT_DECLARE_PARTIALLY_ORDERED_LITERAL_TYPE_3(__VA_ARGS__))
0647 #define QT_DECLARE_PARTIALLY_ORDERED_LITERAL_TYPE_9(...) \
0648 QT_VA_ARGS_EXPAND(QT_DECLARE_PARTIALLY_ORDERED_LITERAL_TYPE_3(__VA_ARGS__))
0649
0650 #define Q_DECLARE_PARTIALLY_ORDERED_LITERAL_TYPE(...) \
0651 QT_OVERLOADED_MACRO(QT_DECLARE_PARTIALLY_ORDERED_LITERAL_TYPE, __VA_ARGS__)
0652
0653 #define QT_DECLARE_PARTIALLY_ORDERED_NON_NOEXCEPT_1(Type) \
0654 QT_DECLARE_ORDERING_OPERATORS_HELPER(PARTIAL, Type, Type, , \
0655 noexcept(false), )
0656
0657 #define QT_DECLARE_PARTIALLY_ORDERED_NON_NOEXCEPT_2(LeftType, RightType) \
0658 QT_DECLARE_ORDERING_OPERATORS_HELPER(PARTIAL, LeftType, RightType, , \
0659 noexcept(false), ) \
0660 QT_DECLARE_ORDERING_OPERATORS_REVERSED_HELPER(PARTIAL, LeftType, RightType, \
0661 , noexcept(false), \
0662 )
0663
0664 #define QT_DECLARE_PARTIALLY_ORDERED_NON_NOEXCEPT_3(LeftType, RightType, ...) \
0665 QT_DECLARE_ORDERING_OPERATORS_HELPER(PARTIAL, LeftType, RightType, , \
0666 noexcept(false), __VA_ARGS__) \
0667 QT_DECLARE_ORDERING_OPERATORS_REVERSED_HELPER(PARTIAL, LeftType, RightType, \
0668 , noexcept(false), __VA_ARGS__)
0669
0670 #define QT_DECLARE_PARTIALLY_ORDERED_NON_NOEXCEPT_4(...) \
0671 QT_VA_ARGS_EXPAND(QT_DECLARE_PARTIALLY_ORDERED_NON_NOEXCEPT_3(__VA_ARGS__))
0672 #define QT_DECLARE_PARTIALLY_ORDERED_NON_NOEXCEPT_5(...) \
0673 QT_VA_ARGS_EXPAND(QT_DECLARE_PARTIALLY_ORDERED_NON_NOEXCEPT_3(__VA_ARGS__))
0674 #define QT_DECLARE_PARTIALLY_ORDERED_NON_NOEXCEPT_6(...) \
0675 QT_VA_ARGS_EXPAND(QT_DECLARE_PARTIALLY_ORDERED_NON_NOEXCEPT_3(__VA_ARGS__))
0676 #define QT_DECLARE_PARTIALLY_ORDERED_NON_NOEXCEPT_7(...) \
0677 QT_VA_ARGS_EXPAND(QT_DECLARE_PARTIALLY_ORDERED_NON_NOEXCEPT_3(__VA_ARGS__))
0678 #define QT_DECLARE_PARTIALLY_ORDERED_NON_NOEXCEPT_8(...) \
0679 QT_VA_ARGS_EXPAND(QT_DECLARE_PARTIALLY_ORDERED_NON_NOEXCEPT_3(__VA_ARGS__))
0680 #define QT_DECLARE_PARTIALLY_ORDERED_NON_NOEXCEPT_9(...) \
0681 QT_VA_ARGS_EXPAND(QT_DECLARE_PARTIALLY_ORDERED_NON_NOEXCEPT_3(__VA_ARGS__))
0682
0683 #define Q_DECLARE_PARTIALLY_ORDERED_NON_NOEXCEPT(...) \
0684 QT_OVERLOADED_MACRO(QT_DECLARE_PARTIALLY_ORDERED_NON_NOEXCEPT, __VA_ARGS__)
0685
0686
0687 #define QT_DECLARE_WEAKLY_ORDERED_1(Type) \
0688 QT_DECLARE_ORDERING_OPERATORS_HELPER(WEAK, Type, Type, , noexcept(true), \
0689 )
0690
0691 #define QT_DECLARE_WEAKLY_ORDERED_2(LeftType, RightType) \
0692 QT_DECLARE_ORDERING_OPERATORS_HELPER(WEAK, LeftType, RightType, , \
0693 noexcept(true), ) \
0694 QT_DECLARE_ORDERING_OPERATORS_REVERSED_HELPER(WEAK, LeftType, RightType, , \
0695 noexcept(true), )
0696
0697 #define QT_DECLARE_WEAKLY_ORDERED_3(LeftType, RightType, ...) \
0698 QT_DECLARE_ORDERING_OPERATORS_HELPER(WEAK, LeftType, RightType, , \
0699 noexcept(true), __VA_ARGS__) \
0700 QT_DECLARE_ORDERING_OPERATORS_REVERSED_HELPER(WEAK, LeftType, RightType, , \
0701 noexcept(true), __VA_ARGS__)
0702
0703 #define QT_DECLARE_WEAKLY_ORDERED_4(...) \
0704 QT_VA_ARGS_EXPAND(QT_DECLARE_WEAKLY_ORDERED_3(__VA_ARGS__))
0705 #define QT_DECLARE_WEAKLY_ORDERED_5(...) \
0706 QT_VA_ARGS_EXPAND(QT_DECLARE_WEAKLY_ORDERED_3(__VA_ARGS__))
0707 #define QT_DECLARE_WEAKLY_ORDERED_6(...) \
0708 QT_VA_ARGS_EXPAND(QT_DECLARE_WEAKLY_ORDERED_3(__VA_ARGS__))
0709 #define QT_DECLARE_WEAKLY_ORDERED_7(...) \
0710 QT_VA_ARGS_EXPAND(QT_DECLARE_WEAKLY_ORDERED_3(__VA_ARGS__))
0711 #define QT_DECLARE_WEAKLY_ORDERED_8(...) \
0712 QT_VA_ARGS_EXPAND(QT_DECLARE_WEAKLY_ORDERED_3(__VA_ARGS__))
0713 #define QT_DECLARE_WEAKLY_ORDERED_9(...) \
0714 QT_VA_ARGS_EXPAND(QT_DECLARE_WEAKLY_ORDERED_3(__VA_ARGS__))
0715
0716 #define Q_DECLARE_WEAKLY_ORDERED(...) \
0717 QT_OVERLOADED_MACRO(QT_DECLARE_WEAKLY_ORDERED, __VA_ARGS__)
0718
0719 #define QT_DECLARE_WEAKLY_ORDERED_LITERAL_TYPE_1(Type) \
0720 QT_DECLARE_ORDERING_OPERATORS_HELPER(WEAK, Type, Type, constexpr, noexcept(true), \
0721 )
0722
0723 #define QT_DECLARE_WEAKLY_ORDERED_LITERAL_TYPE_2(LeftType, RightType) \
0724 QT_DECLARE_ORDERING_OPERATORS_HELPER(WEAK, LeftType, RightType, constexpr, \
0725 noexcept(true), ) \
0726 QT_DECLARE_ORDERING_OPERATORS_REVERSED_HELPER(WEAK, LeftType, RightType, constexpr, \
0727 noexcept(true), )
0728
0729 #define QT_DECLARE_WEAKLY_ORDERED_LITERAL_TYPE_3(LeftType, RightType, ...) \
0730 QT_DECLARE_ORDERING_OPERATORS_HELPER(WEAK, LeftType, RightType, constexpr, noexcept(true), \
0731 __VA_ARGS__) \
0732 QT_DECLARE_ORDERING_OPERATORS_REVERSED_HELPER(WEAK, LeftType, RightType, constexpr, \
0733 noexcept(true), __VA_ARGS__)
0734
0735 #define QT_DECLARE_WEAKLY_ORDERED_LITERAL_TYPE_4(...) \
0736 QT_VA_ARGS_EXPAND(QT_DECLARE_WEAKLY_ORDERED_LITERAL_TYPE_3(__VA_ARGS__))
0737 #define QT_DECLARE_WEAKLY_ORDERED_LITERAL_TYPE_5(...) \
0738 QT_VA_ARGS_EXPAND(QT_DECLARE_WEAKLY_ORDERED_LITERAL_TYPE_3(__VA_ARGS__))
0739 #define QT_DECLARE_WEAKLY_ORDERED_LITERAL_TYPE_6(...) \
0740 QT_VA_ARGS_EXPAND(QT_DECLARE_WEAKLY_ORDERED_LITERAL_TYPE_3(__VA_ARGS__))
0741 #define QT_DECLARE_WEAKLY_ORDERED_LITERAL_TYPE_7(...) \
0742 QT_VA_ARGS_EXPAND(QT_DECLARE_WEAKLY_ORDERED_LITERAL_TYPE_3(__VA_ARGS__))
0743 #define QT_DECLARE_WEAKLY_ORDERED_LITERAL_TYPE_8(...) \
0744 QT_VA_ARGS_EXPAND(QT_DECLARE_WEAKLY_ORDERED_LITERAL_TYPE_3(__VA_ARGS__))
0745 #define QT_DECLARE_WEAKLY_ORDERED_LITERAL_TYPE_9(...) \
0746 QT_VA_ARGS_EXPAND(QT_DECLARE_WEAKLY_ORDERED_LITERAL_TYPE_3(__VA_ARGS__))
0747
0748 #define Q_DECLARE_WEAKLY_ORDERED_LITERAL_TYPE(...) \
0749 QT_OVERLOADED_MACRO(QT_DECLARE_WEAKLY_ORDERED_LITERAL_TYPE, __VA_ARGS__)
0750
0751 #define QT_DECLARE_WEAKLY_ORDERED_NON_NOEXCEPT_1(Type) \
0752 QT_DECLARE_ORDERING_OPERATORS_HELPER(WEAK, Type, Type, , noexcept(false), \
0753 )
0754
0755 #define QT_DECLARE_WEAKLY_ORDERED_NON_NOEXCEPT_2(LeftType, RightType) \
0756 QT_DECLARE_ORDERING_OPERATORS_HELPER(WEAK, LeftType, RightType, , \
0757 noexcept(false), ) \
0758 QT_DECLARE_ORDERING_OPERATORS_REVERSED_HELPER(WEAK, LeftType, RightType, , \
0759 noexcept(false), )
0760
0761 #define QT_DECLARE_WEAKLY_ORDERED_NON_NOEXCEPT_3(LeftType, RightType, ...) \
0762 QT_DECLARE_ORDERING_OPERATORS_HELPER(WEAK, LeftType, RightType, , \
0763 noexcept(false), __VA_ARGS__) \
0764 QT_DECLARE_ORDERING_OPERATORS_REVERSED_HELPER(WEAK, LeftType, RightType, , \
0765 noexcept(false), __VA_ARGS__)
0766
0767 #define QT_DECLARE_WEAKLY_ORDERED_NON_NOEXCEPT_4(...) \
0768 QT_VA_ARGS_EXPAND(QT_DECLARE_WEAKLY_ORDERED_NON_NOEXCEPT_3(__VA_ARGS__))
0769 #define QT_DECLARE_WEAKLY_ORDERED_NON_NOEXCEPT_5(...) \
0770 QT_VA_ARGS_EXPAND(QT_DECLARE_WEAKLY_ORDERED_NON_NOEXCEPT_3(__VA_ARGS__))
0771 #define QT_DECLARE_WEAKLY_ORDERED_NON_NOEXCEPT_6(...) \
0772 QT_VA_ARGS_EXPAND(QT_DECLARE_WEAKLY_ORDERED_NON_NOEXCEPT_3(__VA_ARGS__))
0773 #define QT_DECLARE_WEAKLY_ORDERED_NON_NOEXCEPT_7(...) \
0774 QT_VA_ARGS_EXPAND(QT_DECLARE_WEAKLY_ORDERED_NON_NOEXCEPT_3(__VA_ARGS__))
0775 #define QT_DECLARE_WEAKLY_ORDERED_NON_NOEXCEPT_8(...) \
0776 QT_VA_ARGS_EXPAND(QT_DECLARE_WEAKLY_ORDERED_NON_NOEXCEPT_3(__VA_ARGS__))
0777 #define QT_DECLARE_WEAKLY_ORDERED_NON_NOEXCEPT_9(...) \
0778 QT_VA_ARGS_EXPAND(QT_DECLARE_WEAKLY_ORDERED_NON_NOEXCEPT_3(__VA_ARGS__))
0779
0780 #define Q_DECLARE_WEAKLY_ORDERED_NON_NOEXCEPT(...) \
0781 QT_OVERLOADED_MACRO(QT_DECLARE_WEAKLY_ORDERED_NON_NOEXCEPT, __VA_ARGS__)
0782
0783
0784 #define QT_DECLARE_STRONGLY_ORDERED_1(Type) \
0785 QT_DECLARE_ORDERING_OPERATORS_HELPER(STRONG, Type, Type, , \
0786 noexcept(true), )
0787
0788 #define QT_DECLARE_STRONGLY_ORDERED_2(LeftType, RightType) \
0789 QT_DECLARE_ORDERING_OPERATORS_HELPER(STRONG, LeftType, RightType, , \
0790 noexcept(true), ) \
0791 QT_DECLARE_ORDERING_OPERATORS_REVERSED_HELPER(STRONG, LeftType, RightType, \
0792 , noexcept(true), \
0793 )
0794
0795 #define QT_DECLARE_STRONGLY_ORDERED_3(LeftType, RightType, ...) \
0796 QT_DECLARE_ORDERING_OPERATORS_HELPER(STRONG, LeftType, RightType, , \
0797 noexcept(true), __VA_ARGS__) \
0798 QT_DECLARE_ORDERING_OPERATORS_REVERSED_HELPER(STRONG, LeftType, RightType, \
0799 , noexcept(true), __VA_ARGS__)
0800
0801 #define QT_DECLARE_STRONGLY_ORDERED_4(...) \
0802 QT_VA_ARGS_EXPAND(QT_DECLARE_STRONGLY_ORDERED_3(__VA_ARGS__))
0803 #define QT_DECLARE_STRONGLY_ORDERED_5(...) \
0804 QT_VA_ARGS_EXPAND(QT_DECLARE_STRONGLY_ORDERED_3(__VA_ARGS__))
0805 #define QT_DECLARE_STRONGLY_ORDERED_6(...) \
0806 QT_VA_ARGS_EXPAND(QT_DECLARE_STRONGLY_ORDERED_3(__VA_ARGS__))
0807 #define QT_DECLARE_STRONGLY_ORDERED_7(...) \
0808 QT_VA_ARGS_EXPAND(QT_DECLARE_STRONGLY_ORDERED_3(__VA_ARGS__))
0809 #define QT_DECLARE_STRONGLY_ORDERED_8(...) \
0810 QT_VA_ARGS_EXPAND(QT_DECLARE_STRONGLY_ORDERED_3(__VA_ARGS__))
0811 #define QT_DECLARE_STRONGLY_ORDERED_9(...) \
0812 QT_VA_ARGS_EXPAND(QT_DECLARE_STRONGLY_ORDERED_3(__VA_ARGS__))
0813
0814 #define Q_DECLARE_STRONGLY_ORDERED(...) \
0815 QT_OVERLOADED_MACRO(QT_DECLARE_STRONGLY_ORDERED, __VA_ARGS__)
0816
0817 #define QT_DECLARE_STRONGLY_ORDERED_LITERAL_TYPE_1(Type) \
0818 QT_DECLARE_ORDERING_OPERATORS_HELPER(STRONG, Type, Type, constexpr, noexcept(true), \
0819 )
0820
0821 #define QT_DECLARE_STRONGLY_ORDERED_LITERAL_TYPE_2(LeftType, RightType) \
0822 QT_DECLARE_ORDERING_OPERATORS_HELPER(STRONG, LeftType, RightType, constexpr, \
0823 noexcept(true), ) \
0824 QT_DECLARE_ORDERING_OPERATORS_REVERSED_HELPER(STRONG, LeftType, RightType, constexpr, \
0825 noexcept(true), )
0826
0827 #define QT_DECLARE_STRONGLY_ORDERED_LITERAL_TYPE_3(LeftType, RightType, ...) \
0828 QT_DECLARE_ORDERING_OPERATORS_HELPER(STRONG, LeftType, RightType, constexpr, noexcept(true), \
0829 __VA_ARGS__) \
0830 QT_DECLARE_ORDERING_OPERATORS_REVERSED_HELPER(STRONG, LeftType, RightType, constexpr, \
0831 noexcept(true), __VA_ARGS__)
0832
0833 #define QT_DECLARE_STRONGLY_ORDERED_LITERAL_TYPE_4(...) \
0834 QT_VA_ARGS_EXPAND(QT_DECLARE_STRONGLY_ORDERED_LITERAL_TYPE_3(__VA_ARGS__))
0835 #define QT_DECLARE_STRONGLY_ORDERED_LITERAL_TYPE_5(...) \
0836 QT_VA_ARGS_EXPAND(QT_DECLARE_STRONGLY_ORDERED_LITERAL_TYPE_3(__VA_ARGS__))
0837 #define QT_DECLARE_STRONGLY_ORDERED_LITERAL_TYPE_6(...) \
0838 QT_VA_ARGS_EXPAND(QT_DECLARE_STRONGLY_ORDERED_LITERAL_TYPE_3(__VA_ARGS__))
0839 #define QT_DECLARE_STRONGLY_ORDERED_LITERAL_TYPE_7(...) \
0840 QT_VA_ARGS_EXPAND(QT_DECLARE_STRONGLY_ORDERED_LITERAL_TYPE_3(__VA_ARGS__))
0841 #define QT_DECLARE_STRONGLY_ORDERED_LITERAL_TYPE_8(...) \
0842 QT_VA_ARGS_EXPAND(QT_DECLARE_STRONGLY_ORDERED_LITERAL_TYPE_3(__VA_ARGS__))
0843 #define QT_DECLARE_STRONGLY_ORDERED_LITERAL_TYPE_9(...) \
0844 QT_VA_ARGS_EXPAND(QT_DECLARE_STRONGLY_ORDERED_LITERAL_TYPE_3(__VA_ARGS__))
0845
0846 #define Q_DECLARE_STRONGLY_ORDERED_LITERAL_TYPE(...) \
0847 QT_OVERLOADED_MACRO(QT_DECLARE_STRONGLY_ORDERED_LITERAL_TYPE, __VA_ARGS__)
0848
0849 #define QT_DECLARE_STRONGLY_ORDERED_NON_NOEXCEPT_1(Type) \
0850 QT_DECLARE_ORDERING_OPERATORS_HELPER(STRONG, Type, Type, , \
0851 noexcept(false), )
0852
0853 #define QT_DECLARE_STRONGLY_ORDERED_NON_NOEXCEPT_2(LeftType, RightType) \
0854 QT_DECLARE_ORDERING_OPERATORS_HELPER(STRONG, LeftType, RightType, , \
0855 noexcept(false), ) \
0856 QT_DECLARE_ORDERING_OPERATORS_REVERSED_HELPER(STRONG, LeftType, RightType, \
0857 , noexcept(false), \
0858 )
0859
0860 #define QT_DECLARE_STRONGLY_ORDERED_NON_NOEXCEPT_3(LeftType, RightType, ...) \
0861 QT_DECLARE_ORDERING_OPERATORS_HELPER(STRONG, LeftType, RightType, , \
0862 noexcept(false), __VA_ARGS__) \
0863 QT_DECLARE_ORDERING_OPERATORS_REVERSED_HELPER(STRONG, LeftType, RightType, \
0864 , noexcept(false), __VA_ARGS__)
0865
0866 #define QT_DECLARE_STRONGLY_ORDERED_NON_NOEXCEPT_4(...) \
0867 QT_VA_ARGS_EXPAND(QT_DECLARE_STRONGLY_ORDERED_NON_NOEXCEPT_3(__VA_ARGS__))
0868 #define QT_DECLARE_STRONGLY_ORDERED_NON_NOEXCEPT_5(...) \
0869 QT_VA_ARGS_EXPAND(QT_DECLARE_STRONGLY_ORDERED_NON_NOEXCEPT_3(__VA_ARGS__))
0870 #define QT_DECLARE_STRONGLY_ORDERED_NON_NOEXCEPT_6(...) \
0871 QT_VA_ARGS_EXPAND(QT_DECLARE_STRONGLY_ORDERED_NON_NOEXCEPT_3(__VA_ARGS__))
0872 #define QT_DECLARE_STRONGLY_ORDERED_NON_NOEXCEPT_7(...) \
0873 QT_VA_ARGS_EXPAND(QT_DECLARE_STRONGLY_ORDERED_NON_NOEXCEPT_3(__VA_ARGS__))
0874 #define QT_DECLARE_STRONGLY_ORDERED_NON_NOEXCEPT_8(...) \
0875 QT_VA_ARGS_EXPAND(QT_DECLARE_STRONGLY_ORDERED_NON_NOEXCEPT_3(__VA_ARGS__))
0876 #define QT_DECLARE_STRONGLY_ORDERED_NON_NOEXCEPT_9(...) \
0877 QT_VA_ARGS_EXPAND(QT_DECLARE_STRONGLY_ORDERED_NON_NOEXCEPT_3(__VA_ARGS__))
0878
0879 #define Q_DECLARE_STRONGLY_ORDERED_NON_NOEXCEPT(...) \
0880 QT_OVERLOADED_MACRO(QT_DECLARE_STRONGLY_ORDERED_NON_NOEXCEPT, __VA_ARGS__)
0881
0882 namespace QtPrivate {
0883
0884 template <typename T>
0885 constexpr bool IsIntegralType_v = std::numeric_limits<std::remove_const_t<T>>::is_specialized
0886 && std::numeric_limits<std::remove_const_t<T>>::is_integer;
0887
0888 template <typename T>
0889 constexpr bool IsFloatType_v = std::is_floating_point_v<T>;
0890
0891 #if QFLOAT16_IS_NATIVE
0892 template <>
0893 inline constexpr bool IsFloatType_v<QtPrivate::NativeFloat16Type> = true;
0894 #endif
0895
0896 }
0897
0898 namespace QtOrderingPrivate {
0899
0900 template <typename T, typename U>
0901 constexpr Qt::strong_ordering
0902 strongOrderingCompareDefaultImpl(T lhs, U rhs) noexcept
0903 {
0904 #ifdef __cpp_lib_three_way_comparison
0905 return lhs <=> rhs;
0906 #else
0907 if (lhs == rhs)
0908 return Qt::strong_ordering::equivalent;
0909 else if (lhs < rhs)
0910 return Qt::strong_ordering::less;
0911 else
0912 return Qt::strong_ordering::greater;
0913 #endif
0914 }
0915
0916 }
0917
0918 namespace Qt {
0919
0920 template <typename T>
0921 using if_integral = std::enable_if_t<QtPrivate::IsIntegralType_v<T>, bool>;
0922
0923 template <typename T>
0924 using if_floating_point = std::enable_if_t<QtPrivate::IsFloatType_v<T>, bool>;
0925
0926 template <typename T, typename U>
0927 using if_compatible_pointers =
0928 std::enable_if_t<std::disjunction_v<std::is_same<T, U>,
0929 std::is_base_of<T, U>,
0930 std::is_base_of<U, T>>,
0931 bool>;
0932
0933 template <typename Enum>
0934 using if_enum = std::enable_if_t<std::is_enum_v<Enum>, bool>;
0935
0936 template <typename LeftInt, typename RightInt,
0937 if_integral<LeftInt> = true,
0938 if_integral<RightInt> = true>
0939 constexpr Qt::strong_ordering compareThreeWay(LeftInt lhs, RightInt rhs) noexcept
0940 {
0941 static_assert(std::is_signed_v<LeftInt> == std::is_signed_v<RightInt>,
0942 "Qt::compareThreeWay() does not allow mixed-sign comparison.");
0943
0944 #ifdef __cpp_lib_three_way_comparison
0945 return lhs <=> rhs;
0946 #else
0947 if (lhs == rhs)
0948 return Qt::strong_ordering::equivalent;
0949 else if (lhs < rhs)
0950 return Qt::strong_ordering::less;
0951 else
0952 return Qt::strong_ordering::greater;
0953 #endif
0954 }
0955
0956 template <typename LeftFloat, typename RightFloat,
0957 if_floating_point<LeftFloat> = true,
0958 if_floating_point<RightFloat> = true>
0959 constexpr Qt::partial_ordering compareThreeWay(LeftFloat lhs, RightFloat rhs) noexcept
0960 {
0961 QT_WARNING_PUSH
0962 QT_WARNING_DISABLE_FLOAT_COMPARE
0963 #ifdef __cpp_lib_three_way_comparison
0964 return lhs <=> rhs;
0965 #else
0966 if (lhs < rhs)
0967 return Qt::partial_ordering::less;
0968 else if (lhs > rhs)
0969 return Qt::partial_ordering::greater;
0970 else if (lhs == rhs)
0971 return Qt::partial_ordering::equivalent;
0972 else
0973 return Qt::partial_ordering::unordered;
0974 #endif
0975 QT_WARNING_POP
0976 }
0977
0978 template <typename IntType, typename FloatType,
0979 if_integral<IntType> = true,
0980 if_floating_point<FloatType> = true>
0981 constexpr Qt::partial_ordering compareThreeWay(IntType lhs, FloatType rhs) noexcept
0982 {
0983 return compareThreeWay(FloatType(lhs), rhs);
0984 }
0985
0986 template <typename FloatType, typename IntType,
0987 if_floating_point<FloatType> = true,
0988 if_integral<IntType> = true>
0989 constexpr Qt::partial_ordering compareThreeWay(FloatType lhs, IntType rhs) noexcept
0990 {
0991 return compareThreeWay(lhs, FloatType(rhs));
0992 }
0993
0994 #if QT_DEPRECATED_SINCE(6, 8)
0995
0996 template <typename LeftType, typename RightType,
0997 if_compatible_pointers<LeftType, RightType> = true>
0998 QT_DEPRECATED_VERSION_X_6_8("Wrap the pointers into Qt::totally_ordered_wrapper and use the respective overload instead.")
0999 constexpr Qt::strong_ordering compareThreeWay(const LeftType *lhs, const RightType *rhs) noexcept
1000 {
1001 #ifdef __cpp_lib_three_way_comparison
1002 return std::compare_three_way{}(lhs, rhs);
1003 #else
1004 if (lhs == rhs)
1005 return Qt::strong_ordering::equivalent;
1006 else if (std::less<>{}(lhs, rhs))
1007 return Qt::strong_ordering::less;
1008 else
1009 return Qt::strong_ordering::greater;
1010 #endif
1011 }
1012
1013 template <typename T>
1014 QT_DEPRECATED_VERSION_X_6_8("Wrap the pointer into Qt::totally_ordered_wrapper and use the respective overload instead.")
1015 constexpr Qt::strong_ordering compareThreeWay(const T *lhs, std::nullptr_t rhs) noexcept
1016 {
1017 return compareThreeWay(lhs, static_cast<const T *>(rhs));
1018 }
1019
1020 template <typename T>
1021 QT_DEPRECATED_VERSION_X_6_8("Wrap the pointer into Qt::totally_ordered_wrapper and use the respective overload instead.")
1022 constexpr Qt::strong_ordering compareThreeWay(std::nullptr_t lhs, const T *rhs) noexcept
1023 {
1024 return compareThreeWay(static_cast<const T *>(lhs), rhs);
1025 }
1026
1027 #endif
1028
1029 template <class Enum, if_enum<Enum> = true>
1030 constexpr Qt::strong_ordering compareThreeWay(Enum lhs, Enum rhs) noexcept
1031 {
1032 return compareThreeWay(qToUnderlying(lhs), qToUnderlying(rhs));
1033 }
1034 }
1035
1036 namespace QtOrderingPrivate {
1037
1038 template <typename Head, typename...Tail, std::size_t...Is>
1039 constexpr std::tuple<Tail...> qt_tuple_pop_front_impl(const std::tuple<Head, Tail...> &t,
1040 std::index_sequence<Is...>) noexcept
1041 {
1042 return std::tuple<Tail...>(std::get<Is + 1>(t)...);
1043 }
1044
1045 template <typename Head, typename...Tail>
1046 constexpr std::tuple<Tail...> qt_tuple_pop_front(const std::tuple<Head, Tail...> &t) noexcept
1047 {
1048 return qt_tuple_pop_front_impl(t, std::index_sequence_for<Tail...>{});
1049 }
1050
1051 template <typename LhsHead, typename...LhsTail, typename RhsHead, typename...RhsTail>
1052 constexpr auto compareThreeWayMulti(const std::tuple<LhsHead, LhsTail...> &lhs,
1053 const std::tuple<RhsHead, RhsTail...> &rhs) noexcept
1054 {
1055 static_assert(sizeof...(LhsTail) == sizeof...(RhsTail),
1056
1057 "The tuple arguments have to have the same size.");
1058
1059 using Qt::compareThreeWay;
1060 using R = std::common_type_t<
1061 decltype(compareThreeWay(std::declval<LhsHead>(), std::declval<RhsHead>())),
1062 decltype(compareThreeWay(std::declval<LhsTail>(), std::declval<RhsTail>()))...
1063 >;
1064
1065 const auto &l = std::get<0>(lhs);
1066 const auto &r = std::get<0>(rhs);
1067 static_assert(noexcept(compareThreeWay(l, r)),
1068 "This function requires all relational operators to be noexcept.");
1069 const auto res = compareThreeWay(l, r);
1070 if constexpr (sizeof...(LhsTail) > 0) {
1071 if (is_eq(res))
1072 return R{compareThreeWayMulti(qt_tuple_pop_front(lhs), qt_tuple_pop_front(rhs))};
1073 }
1074 return R{res};
1075 }
1076
1077 }
1078
1079 namespace Qt {
1080
1081
1082
1083
1084
1085
1086 template <typename P>
1087 class totally_ordered_wrapper
1088 {
1089 static_assert(std::is_pointer_v<P>);
1090 using T = std::remove_pointer_t<P>;
1091
1092 P ptr;
1093 public:
1094 totally_ordered_wrapper() noexcept = default;
1095 Q_IMPLICIT constexpr totally_ordered_wrapper(std::nullptr_t)
1096
1097 : totally_ordered_wrapper(P{nullptr}) {}
1098 explicit constexpr totally_ordered_wrapper(P p) noexcept : ptr(p) {}
1099
1100 constexpr P get() const noexcept { return ptr; }
1101 constexpr void reset(P p) noexcept { ptr = p; }
1102 constexpr P operator->() const noexcept { return get(); }
1103 template <typename U = T, std::enable_if_t<!std::is_void_v<U>, bool> = true>
1104 constexpr U &operator*() const noexcept { return *get(); }
1105
1106 explicit constexpr operator bool() const noexcept { return get(); }
1107
1108 private:
1109
1110
1111 template <typename T, typename U>
1112 using if_compatible_types =
1113 std::enable_if_t<std::conjunction_v<std::is_pointer<T>,
1114 std::is_pointer<U>,
1115 std::disjunction<std::is_convertible<T, U>,
1116 std::is_convertible<U, T>>>,
1117 bool>;
1118
1119 #define MAKE_RELOP(Ret, op, Op) \
1120 template <typename U = P, if_compatible_types<P, U> = true> \
1121 friend constexpr Ret operator op (const totally_ordered_wrapper<P> &lhs, const totally_ordered_wrapper<U> &rhs) noexcept \
1122 { return std:: Op {}(lhs.ptr, rhs.get()); } \
1123 template <typename U = P, if_compatible_types<P, U> = true> \
1124 friend constexpr Ret operator op (const totally_ordered_wrapper<P> &lhs, const U &rhs) noexcept \
1125 { return std:: Op {}(lhs.ptr, rhs ); } \
1126 template <typename U = P, if_compatible_types<P, U> = true> \
1127 friend constexpr Ret operator op (const U &lhs, const totally_ordered_wrapper<P> &rhs) noexcept \
1128 { return std:: Op {}(lhs, rhs.ptr); } \
1129 friend constexpr Ret operator op (const totally_ordered_wrapper &lhs, std::nullptr_t) noexcept \
1130 { return std:: Op {}(lhs.ptr, P(nullptr)); } \
1131 friend constexpr Ret operator op (std::nullptr_t, const totally_ordered_wrapper &rhs) noexcept \
1132 { return std:: Op {}(P(nullptr), rhs.ptr); } \
1133
1134 MAKE_RELOP(bool, ==, equal_to<>)
1135 MAKE_RELOP(bool, !=, not_equal_to<>)
1136 MAKE_RELOP(bool, < , less<>)
1137 MAKE_RELOP(bool, <=, less_equal<>)
1138 MAKE_RELOP(bool, > , greater<>)
1139 MAKE_RELOP(bool, >=, greater_equal<>)
1140 #ifdef __cpp_lib_three_way_comparison
1141 MAKE_RELOP(auto, <=>, compare_three_way)
1142 #endif
1143 #undef MAKE_RELOP
1144 friend void qt_ptr_swap(totally_ordered_wrapper &lhs, totally_ordered_wrapper &rhs) noexcept
1145 { qt_ptr_swap(lhs.ptr, rhs.ptr); }
1146 friend void swap(totally_ordered_wrapper &lhs, totally_ordered_wrapper &rhs) noexcept
1147 { qt_ptr_swap(lhs, rhs); }
1148 friend size_t qHash(totally_ordered_wrapper key, size_t seed = 0) noexcept
1149 { return qHash(key.ptr, seed); }
1150 };
1151
1152 template <typename T, typename U, if_compatible_pointers<T, U> = true>
1153 constexpr Qt::strong_ordering
1154 compareThreeWay(Qt::totally_ordered_wrapper<T*> lhs, Qt::totally_ordered_wrapper<U*> rhs) noexcept
1155 {
1156 return QtOrderingPrivate::strongOrderingCompareDefaultImpl(lhs, rhs);
1157 }
1158
1159 template <typename T, typename U, if_compatible_pointers<T, U> = true>
1160 constexpr Qt::strong_ordering
1161 compareThreeWay(Qt::totally_ordered_wrapper<T*> lhs, U *rhs) noexcept
1162 {
1163 return QtOrderingPrivate::strongOrderingCompareDefaultImpl(lhs, rhs);
1164 }
1165
1166 template <typename T, typename U, if_compatible_pointers<T, U> = true>
1167 constexpr Qt::strong_ordering
1168 compareThreeWay(U *lhs, Qt::totally_ordered_wrapper<T*> rhs) noexcept
1169 {
1170 return QtOrderingPrivate::strongOrderingCompareDefaultImpl(lhs, rhs);
1171 }
1172
1173 template <typename T>
1174 constexpr Qt::strong_ordering
1175 compareThreeWay(Qt::totally_ordered_wrapper<T*> lhs, std::nullptr_t rhs) noexcept
1176 {
1177 return QtOrderingPrivate::strongOrderingCompareDefaultImpl(lhs, rhs);
1178 }
1179
1180 template <typename T>
1181 constexpr Qt::strong_ordering
1182 compareThreeWay(std::nullptr_t lhs, Qt::totally_ordered_wrapper<T*> rhs) noexcept
1183 {
1184 return QtOrderingPrivate::strongOrderingCompareDefaultImpl(lhs, rhs);
1185 }
1186
1187 }
1188
1189 template <typename P>
1190 class QTypeInfo<Qt::totally_ordered_wrapper<P>> : public QTypeInfo<P> {};
1191
1192 namespace QtOrderingPrivate {
1193
1194 QT_WARNING_PUSH
1195 QT_WARNING_DISABLE_DEPRECATED
1196
1197 namespace CompareThreeWayTester {
1198
1199 using Qt::compareThreeWay;
1200
1201 template <typename T>
1202 using WrappedType = std::conditional_t<std::is_pointer_v<T>, Qt::totally_ordered_wrapper<T>, T>;
1203
1204
1205
1206 template <typename LT, typename RT, typename = void>
1207 struct HasCompareThreeWay : std::false_type {};
1208
1209 template <typename LT, typename RT>
1210 struct HasCompareThreeWay<
1211 LT, RT, std::void_t<decltype(compareThreeWay(std::declval<LT>(), std::declval<RT>()))>
1212 > : std::true_type {};
1213
1214 template <typename LT, typename RT>
1215 struct HasCompareThreeWay<
1216 LT*, RT*,
1217 std::void_t<decltype(compareThreeWay(std::declval<WrappedType<LT>>(),
1218 std::declval<WrappedType<RT>>()))>
1219 > : std::true_type {};
1220
1221 template <typename LT, typename RT>
1222 constexpr inline bool hasCompareThreeWay_v = HasCompareThreeWay<LT, RT>::value;
1223
1224
1225
1226
1227
1228
1229 template <typename LT, typename RT,
1230 std::enable_if_t<hasCompareThreeWay_v<LT, RT>, bool> = true>
1231 constexpr bool compareThreeWayNoexcept() noexcept
1232 { return noexcept(compareThreeWay(std::declval<LT>(), std::declval<RT>())); }
1233
1234 template <typename LT, typename RT,
1235 std::enable_if_t<std::conjunction_v<std::negation<HasCompareThreeWay<LT, RT>>,
1236 HasCompareThreeWay<RT, LT>>,
1237 bool> = true>
1238 constexpr bool compareThreeWayNoexcept() noexcept
1239 { return noexcept(compareThreeWay(std::declval<RT>(), std::declval<LT>())); }
1240
1241 }
1242
1243 QT_WARNING_POP
1244
1245 #ifdef __cpp_lib_three_way_comparison
1246 [[maybe_unused]] inline constexpr struct {
1247 template <typename LT, typename RT = LT>
1248 [[maybe_unused]] constexpr auto operator()(const LT &lhs, const RT &rhs) const
1249 {
1250
1251 if constexpr (QTypeTraits::has_operator_compare_three_way_with_v<LT, RT>) {
1252 return lhs <=> rhs;
1253 } else {
1254 if (lhs < rhs)
1255 return std::weak_ordering::less;
1256 if (rhs < lhs)
1257 return std::weak_ordering::greater;
1258 return std::weak_ordering::equivalent;
1259 }
1260 }
1261 } synthThreeWay;
1262
1263 template <typename Container, typename T>
1264 using if_has_op_less_or_op_compare_three_way =
1265 std::enable_if_t<
1266 std::disjunction_v<QTypeTraits::has_operator_less_than_container<Container, T>,
1267 QTypeTraits::has_operator_compare_three_way<T>>,
1268 bool>;
1269 #endif
1270
1271
1272
1273
1274
1275
1276
1277 template <typename LT, typename RT = LT, typename = void>
1278 struct HasCustomCompareThreeWay : std::false_type {};
1279
1280 template <typename LT, typename RT>
1281 struct HasCustomCompareThreeWay<
1282 LT, RT,
1283 std::void_t<decltype(is_eq(compareThreeWay(std::declval<LT>(), std::declval<RT>())))>
1284 > : std::true_type {};
1285
1286 template <typename InputIt1, typename InputIt2, typename Compare>
1287 auto lexicographicalCompareThreeWay(InputIt1 first1, InputIt1 last1,
1288 InputIt2 first2, InputIt2 last2,
1289 Compare cmp)
1290 {
1291 using R = decltype(cmp(*first1, *first2));
1292
1293 while (first1 != last1) {
1294 if (first2 == last2)
1295 return R::greater;
1296 const auto r = cmp(*first1, *first2);
1297 if (is_neq(r))
1298 return r;
1299 ++first1;
1300 ++first2;
1301 }
1302 return first2 == last2 ? R::equivalent : R::less;
1303 }
1304
1305 template <typename InputIt1, typename InputIt2>
1306 auto lexicographicalCompareThreeWay(InputIt1 first1, InputIt1 last1,
1307 InputIt2 first2, InputIt2 last2)
1308 {
1309 using LT = typename std::iterator_traits<InputIt1>::value_type;
1310 using RT = typename std::iterator_traits<InputIt2>::value_type;
1311
1312
1313
1314
1315 constexpr bool UseWrapper =
1316 std::conjunction_v<std::is_pointer<LT>, std::is_pointer<RT>,
1317 std::negation<HasCustomCompareThreeWay<LT, RT>>,
1318 std::negation<HasCustomCompareThreeWay<RT, LT>>>;
1319 using WrapLT = std::conditional_t<UseWrapper,
1320 Qt::totally_ordered_wrapper<LT>,
1321 const LT &>;
1322 using WrapRT = std::conditional_t<UseWrapper,
1323 Qt::totally_ordered_wrapper<RT>,
1324 const RT &>;
1325
1326 auto cmp = [](LT const &lhs, RT const &rhs) {
1327 using Qt::compareThreeWay;
1328 namespace Test = QtOrderingPrivate::CompareThreeWayTester;
1329
1330
1331 if constexpr (Test::hasCompareThreeWay_v<WrapLT, WrapRT>)
1332 return compareThreeWay(WrapLT(lhs), WrapRT(rhs));
1333 else
1334 return QtOrderingPrivate::reversed(compareThreeWay(WrapRT(rhs), WrapLT(lhs)));
1335 };
1336 return lexicographicalCompareThreeWay(first1, last1, first2, last2, cmp);
1337 }
1338
1339 }
1340
1341 namespace Qt {
1342
1343 template <typename T, typename U>
1344 using if_has_qt_compare_three_way =
1345 std::enable_if_t<
1346 std::disjunction_v<QtOrderingPrivate::CompareThreeWayTester::HasCompareThreeWay<T, U>,
1347 QtOrderingPrivate::CompareThreeWayTester::HasCompareThreeWay<U, T>>,
1348 bool>;
1349
1350 }
1351
1352 QT_END_NAMESPACE
1353
1354 namespace std {
1355 template <typename P>
1356 struct hash<QT_PREPEND_NAMESPACE(Qt::totally_ordered_wrapper)<P>>
1357 {
1358 using argument_type = QT_PREPEND_NAMESPACE(Qt::totally_ordered_wrapper)<P>;
1359 using result_type = size_t;
1360 constexpr result_type operator()(argument_type w) const noexcept
1361 { return std::hash<P>{}(w.get()); }
1362 };
1363 }
1364
1365 #endif