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