File indexing completed on 2025-09-13 09:05:59
0001
0002
0003
0004
0005 #ifndef QCOMPARE_H
0006 #define QCOMPARE_H
0007
0008 #if 0
0009 #pragma qt_class(QtCompare)
0010 #endif
0011
0012 #include <QtCore/qglobal.h>
0013 #include <QtCore/qcompare_impl.h>
0014 #include <QtCore/qstdlibdetection.h>
0015
0016 #ifdef __cpp_lib_bit_cast
0017 #include <bit>
0018 #endif
0019 #ifdef __cpp_lib_three_way_comparison
0020 #include <compare>
0021 #endif
0022
0023 QT_BEGIN_NAMESPACE
0024
0025 namespace QtPrivate {
0026 using CompareUnderlyingType = qint8;
0027 constexpr CompareUnderlyingType LegacyUncomparableValue = -127;
0028
0029
0030 enum class Ordering : CompareUnderlyingType
0031 {
0032 Equal = 0,
0033 Equivalent = Equal,
0034 Less = -1,
0035 Greater = 1
0036 };
0037
0038 enum class Uncomparable : CompareUnderlyingType
0039 {
0040 Unordered =
0041 #if defined(Q_STL_LIBCPP)
0042 -127
0043 #elif defined(Q_STL_LIBSTDCPP)
0044 2
0045 #elif defined(Q_STL_MSSTL)
0046 -128
0047 #elif defined(Q_STL_DINKUMWARE) || \
0048 defined(Q_STL_ROGUEWAVE) || \
0049 defined(Q_STL_STLPORT) || \
0050 defined(Q_STL_SGI)
0051 QtPrivate::LegacyUncomparableValue
0052
0053 # ifdef __cpp_lib_three_way_comparison
0054 # error Please report the numeric value of std::partial_ordering::unordered in your STL in a bug report.
0055 # endif
0056 #else
0057 # error Please handle any newly-added Q_STL_ checks in the above ifdef-ery.
0058 #endif
0059 };
0060
0061 }
0062
0063 namespace QtOrderingPrivate {
0064
0065 template <typename O>
0066 constexpr O reversed(O o) noexcept
0067 {
0068
0069 return is_lt(o) ? O::greater :
0070 is_gt(o) ? O::less :
0071 o ;
0072 }
0073
0074 }
0075
0076 namespace Qt {
0077
0078 class weak_ordering;
0079 class strong_ordering;
0080
0081 class partial_ordering
0082 {
0083 public:
0084 static const partial_ordering less;
0085 static const partial_ordering equivalent;
0086 static const partial_ordering greater;
0087 static const partial_ordering unordered;
0088
0089 friend constexpr bool operator==(partial_ordering lhs,
0090 QtPrivate::CompareAgainstLiteralZero) noexcept
0091 { return lhs.isOrdered() && lhs.m_order == 0; }
0092
0093 friend constexpr bool operator!=(partial_ordering lhs,
0094 QtPrivate::CompareAgainstLiteralZero) noexcept
0095 { return !lhs.isOrdered() || lhs.m_order != 0; }
0096
0097 friend constexpr bool operator< (partial_ordering lhs,
0098 QtPrivate::CompareAgainstLiteralZero) noexcept
0099 { return lhs.isOrdered() && lhs.m_order < 0; }
0100
0101 friend constexpr bool operator<=(partial_ordering lhs,
0102 QtPrivate::CompareAgainstLiteralZero) noexcept
0103 { return lhs.isOrdered() && lhs.m_order <= 0; }
0104
0105 friend constexpr bool operator> (partial_ordering lhs,
0106 QtPrivate::CompareAgainstLiteralZero) noexcept
0107 { return lhs.isOrdered() && lhs.m_order > 0; }
0108
0109 friend constexpr bool operator>=(partial_ordering lhs,
0110 QtPrivate::CompareAgainstLiteralZero) noexcept
0111 { return lhs.isOrdered() && lhs.m_order >= 0; }
0112
0113
0114 friend constexpr bool operator==(QtPrivate::CompareAgainstLiteralZero,
0115 partial_ordering rhs) noexcept
0116 { return rhs.isOrdered() && 0 == rhs.m_order; }
0117
0118 friend constexpr bool operator!=(QtPrivate::CompareAgainstLiteralZero,
0119 partial_ordering rhs) noexcept
0120 { return !rhs.isOrdered() || 0 != rhs.m_order; }
0121
0122 friend constexpr bool operator< (QtPrivate::CompareAgainstLiteralZero,
0123 partial_ordering rhs) noexcept
0124 { return rhs.isOrdered() && 0 < rhs.m_order; }
0125
0126 friend constexpr bool operator<=(QtPrivate::CompareAgainstLiteralZero,
0127 partial_ordering rhs) noexcept
0128 { return rhs.isOrdered() && 0 <= rhs.m_order; }
0129
0130 friend constexpr bool operator> (QtPrivate::CompareAgainstLiteralZero,
0131 partial_ordering rhs) noexcept
0132 { return rhs.isOrdered() && 0 > rhs.m_order; }
0133
0134 friend constexpr bool operator>=(QtPrivate::CompareAgainstLiteralZero,
0135 partial_ordering rhs) noexcept
0136 { return rhs.isOrdered() && 0 >= rhs.m_order; }
0137
0138
0139 #ifdef __cpp_lib_three_way_comparison
0140 friend constexpr std::partial_ordering
0141 operator<=>(partial_ordering lhs, QtPrivate::CompareAgainstLiteralZero) noexcept
0142 { return lhs; }
0143
0144 friend constexpr std::partial_ordering
0145 operator<=>(QtPrivate::CompareAgainstLiteralZero, partial_ordering rhs) noexcept
0146 { return QtOrderingPrivate::reversed(rhs); }
0147 #endif
0148
0149
0150 friend constexpr bool operator==(partial_ordering lhs, partial_ordering rhs) noexcept
0151 { return lhs.m_order == rhs.m_order; }
0152
0153 friend constexpr bool operator!=(partial_ordering lhs, partial_ordering rhs) noexcept
0154 { return lhs.m_order != rhs.m_order; }
0155
0156 #ifdef __cpp_lib_three_way_comparison
0157 constexpr Q_IMPLICIT partial_ordering(std::partial_ordering stdorder) noexcept
0158 : m_order{}
0159 {
0160 if (stdorder == std::partial_ordering::less)
0161 m_order = static_cast<QtPrivate::CompareUnderlyingType>(QtPrivate::Ordering::Less);
0162 else if (stdorder == std::partial_ordering::greater)
0163 m_order = static_cast<QtPrivate::CompareUnderlyingType>(QtPrivate::Ordering::Greater);
0164 else if (stdorder == std::partial_ordering::unordered)
0165 m_order = static_cast<QtPrivate::CompareUnderlyingType>(QtPrivate::Uncomparable::Unordered);
0166 }
0167
0168 constexpr Q_IMPLICIT operator std::partial_ordering() const noexcept
0169 {
0170 static_assert(sizeof(*this) == sizeof(std::partial_ordering));
0171 #ifdef __cpp_lib_bit_cast
0172 return std::bit_cast<std::partial_ordering>(*this);
0173 #else
0174 using O = QtPrivate::Ordering;
0175 using U = QtPrivate::Uncomparable;
0176 using R = std::partial_ordering;
0177 switch (m_order) {
0178 case qToUnderlying(O::Less): return R::less;
0179 case qToUnderlying(O::Greater): return R::greater;
0180 case qToUnderlying(O::Equivalent): return R::equivalent;
0181 case qToUnderlying(U::Unordered): return R::unordered;
0182 }
0183 Q_UNREACHABLE_RETURN(R::unordered);
0184 #endif
0185 }
0186
0187 friend constexpr bool operator==(partial_ordering lhs, std::partial_ordering rhs) noexcept
0188 { return static_cast<std::partial_ordering>(lhs) == rhs; }
0189
0190 friend constexpr bool operator!=(partial_ordering lhs, std::partial_ordering rhs) noexcept
0191 { return static_cast<std::partial_ordering>(lhs) != rhs; }
0192
0193 friend constexpr bool operator==(std::partial_ordering lhs, partial_ordering rhs) noexcept
0194 { return lhs == static_cast<std::partial_ordering>(rhs); }
0195
0196 friend constexpr bool operator!=(std::partial_ordering lhs, partial_ordering rhs) noexcept
0197 { return lhs != static_cast<std::partial_ordering>(rhs); }
0198
0199 friend constexpr bool operator==(partial_ordering lhs, std::strong_ordering rhs) noexcept
0200 { return static_cast<std::partial_ordering>(lhs) == rhs; }
0201
0202 friend constexpr bool operator!=(partial_ordering lhs, std::strong_ordering rhs) noexcept
0203 { return static_cast<std::partial_ordering>(lhs) != rhs; }
0204
0205 friend constexpr bool operator==(std::strong_ordering lhs, partial_ordering rhs) noexcept
0206 { return lhs == static_cast<std::partial_ordering>(rhs); }
0207
0208 friend constexpr bool operator!=(std::strong_ordering lhs, partial_ordering rhs) noexcept
0209 { return lhs != static_cast<std::partial_ordering>(rhs); }
0210
0211 friend constexpr bool operator==(partial_ordering lhs, std::weak_ordering rhs) noexcept
0212 { return static_cast<std::partial_ordering>(lhs) == rhs; }
0213
0214 friend constexpr bool operator!=(partial_ordering lhs, std::weak_ordering rhs) noexcept
0215 { return static_cast<std::partial_ordering>(lhs) != rhs; }
0216
0217 friend constexpr bool operator==(std::weak_ordering lhs, partial_ordering rhs) noexcept
0218 { return lhs == static_cast<std::partial_ordering>(rhs); }
0219
0220 friend constexpr bool operator!=(std::weak_ordering lhs, partial_ordering rhs) noexcept
0221 { return lhs != static_cast<std::partial_ordering>(rhs); }
0222 #endif
0223
0224 private:
0225 friend class weak_ordering;
0226 friend class strong_ordering;
0227
0228 constexpr explicit partial_ordering(QtPrivate::Ordering order) noexcept
0229 : m_order(static_cast<QtPrivate::CompareUnderlyingType>(order))
0230 {}
0231 constexpr explicit partial_ordering(QtPrivate::Uncomparable order) noexcept
0232 : m_order(static_cast<QtPrivate::CompareUnderlyingType>(order))
0233 {}
0234
0235 QT_WARNING_PUSH
0236
0237 QT_WARNING_DISABLE_GCC("-Wzero-as-null-pointer-constant")
0238 QT_WARNING_DISABLE_CLANG("-Wzero-as-null-pointer-constant")
0239 friend constexpr bool is_eq (partial_ordering o) noexcept { return o == 0; }
0240 friend constexpr bool is_neq (partial_ordering o) noexcept { return o != 0; }
0241 friend constexpr bool is_lt (partial_ordering o) noexcept { return o < 0; }
0242 friend constexpr bool is_lteq(partial_ordering o) noexcept { return o <= 0; }
0243 friend constexpr bool is_gt (partial_ordering o) noexcept { return o > 0; }
0244 friend constexpr bool is_gteq(partial_ordering o) noexcept { return o >= 0; }
0245 QT_WARNING_POP
0246
0247
0248
0249 constexpr bool isOrdered() const noexcept
0250 { return m_order != static_cast<QtPrivate::CompareUnderlyingType>(QtPrivate::Uncomparable::Unordered); }
0251
0252 QtPrivate::CompareUnderlyingType m_order;
0253 };
0254
0255 inline constexpr partial_ordering partial_ordering::less(QtPrivate::Ordering::Less);
0256 inline constexpr partial_ordering partial_ordering::equivalent(QtPrivate::Ordering::Equivalent);
0257 inline constexpr partial_ordering partial_ordering::greater(QtPrivate::Ordering::Greater);
0258 inline constexpr partial_ordering partial_ordering::unordered(QtPrivate::Uncomparable::Unordered);
0259
0260 class weak_ordering
0261 {
0262 public:
0263 static const weak_ordering less;
0264 static const weak_ordering equivalent;
0265 static const weak_ordering greater;
0266
0267 constexpr Q_IMPLICIT operator partial_ordering() const noexcept
0268 { return partial_ordering(static_cast<QtPrivate::Ordering>(m_order)); }
0269
0270 friend constexpr bool operator==(weak_ordering lhs,
0271 QtPrivate::CompareAgainstLiteralZero) noexcept
0272 { return lhs.m_order == 0; }
0273
0274 friend constexpr bool operator!=(weak_ordering lhs,
0275 QtPrivate::CompareAgainstLiteralZero) noexcept
0276 { return lhs.m_order != 0; }
0277
0278 friend constexpr bool operator< (weak_ordering lhs,
0279 QtPrivate::CompareAgainstLiteralZero) noexcept
0280 { return lhs.m_order < 0; }
0281
0282 friend constexpr bool operator<=(weak_ordering lhs,
0283 QtPrivate::CompareAgainstLiteralZero) noexcept
0284 { return lhs.m_order <= 0; }
0285
0286 friend constexpr bool operator> (weak_ordering lhs,
0287 QtPrivate::CompareAgainstLiteralZero) noexcept
0288 { return lhs.m_order > 0; }
0289
0290 friend constexpr bool operator>=(weak_ordering lhs,
0291 QtPrivate::CompareAgainstLiteralZero) noexcept
0292 { return lhs.m_order >= 0; }
0293
0294
0295 friend constexpr bool operator==(QtPrivate::CompareAgainstLiteralZero,
0296 weak_ordering rhs) noexcept
0297 { return 0 == rhs.m_order; }
0298
0299 friend constexpr bool operator!=(QtPrivate::CompareAgainstLiteralZero,
0300 weak_ordering rhs) noexcept
0301 { return 0 != rhs.m_order; }
0302
0303 friend constexpr bool operator< (QtPrivate::CompareAgainstLiteralZero,
0304 weak_ordering rhs) noexcept
0305 { return 0 < rhs.m_order; }
0306
0307 friend constexpr bool operator<=(QtPrivate::CompareAgainstLiteralZero,
0308 weak_ordering rhs) noexcept
0309 { return 0 <= rhs.m_order; }
0310
0311 friend constexpr bool operator> (QtPrivate::CompareAgainstLiteralZero,
0312 weak_ordering rhs) noexcept
0313 { return 0 > rhs.m_order; }
0314
0315 friend constexpr bool operator>=(QtPrivate::CompareAgainstLiteralZero,
0316 weak_ordering rhs) noexcept
0317 { return 0 >= rhs.m_order; }
0318
0319
0320 #ifdef __cpp_lib_three_way_comparison
0321 friend constexpr std::weak_ordering
0322 operator<=>(weak_ordering lhs, QtPrivate::CompareAgainstLiteralZero) noexcept
0323 { return lhs; }
0324
0325 friend constexpr std::weak_ordering
0326 operator<=>(QtPrivate::CompareAgainstLiteralZero, weak_ordering rhs) noexcept
0327 { return QtOrderingPrivate::reversed(rhs); }
0328 #endif
0329
0330
0331 friend constexpr bool operator==(weak_ordering lhs, weak_ordering rhs) noexcept
0332 { return lhs.m_order == rhs.m_order; }
0333
0334 friend constexpr bool operator!=(weak_ordering lhs, weak_ordering rhs) noexcept
0335 { return lhs.m_order != rhs.m_order; }
0336
0337 friend constexpr bool operator==(weak_ordering lhs, partial_ordering rhs) noexcept
0338 { return static_cast<partial_ordering>(lhs) == rhs; }
0339
0340 friend constexpr bool operator!=(weak_ordering lhs, partial_ordering rhs) noexcept
0341 { return static_cast<partial_ordering>(lhs) != rhs; }
0342
0343 friend constexpr bool operator==(partial_ordering lhs, weak_ordering rhs) noexcept
0344 { return lhs == static_cast<partial_ordering>(rhs); }
0345
0346 friend constexpr bool operator!=(partial_ordering lhs, weak_ordering rhs) noexcept
0347 { return lhs != static_cast<partial_ordering>(rhs); }
0348
0349 #ifdef __cpp_lib_three_way_comparison
0350 constexpr Q_IMPLICIT weak_ordering(std::weak_ordering stdorder) noexcept
0351 : m_order{}
0352 {
0353 if (stdorder == std::weak_ordering::less)
0354 m_order = static_cast<QtPrivate::CompareUnderlyingType>(QtPrivate::Ordering::Less);
0355 else if (stdorder == std::weak_ordering::greater)
0356 m_order = static_cast<QtPrivate::CompareUnderlyingType>(QtPrivate::Ordering::Greater);
0357 }
0358
0359 constexpr Q_IMPLICIT operator std::weak_ordering() const noexcept
0360 {
0361 static_assert(sizeof(*this) == sizeof(std::weak_ordering));
0362 #ifdef __cpp_lib_bit_cast
0363 return std::bit_cast<std::weak_ordering>(*this);
0364 #else
0365 using O = QtPrivate::Ordering;
0366 using R = std::weak_ordering;
0367 switch (m_order) {
0368 case qToUnderlying(O::Less): return R::less;
0369 case qToUnderlying(O::Greater): return R::greater;
0370 case qToUnderlying(O::Equivalent): return R::equivalent;
0371 }
0372 Q_UNREACHABLE_RETURN(R::equivalent);
0373 #endif
0374 }
0375
0376 friend constexpr bool operator==(weak_ordering lhs, std::weak_ordering rhs) noexcept
0377 { return static_cast<std::weak_ordering>(lhs) == rhs; }
0378
0379 friend constexpr bool operator!=(weak_ordering lhs, std::weak_ordering rhs) noexcept
0380 { return static_cast<std::weak_ordering>(lhs) != rhs; }
0381
0382 friend constexpr bool operator==(weak_ordering lhs, std::partial_ordering rhs) noexcept
0383 { return static_cast<std::weak_ordering>(lhs) == rhs; }
0384
0385 friend constexpr bool operator!=(weak_ordering lhs, std::partial_ordering rhs) noexcept
0386 { return static_cast<std::weak_ordering>(lhs) != rhs; }
0387
0388 friend constexpr bool operator==(weak_ordering lhs, std::strong_ordering rhs) noexcept
0389 { return static_cast<std::weak_ordering>(lhs) == rhs; }
0390
0391 friend constexpr bool operator!=(weak_ordering lhs, std::strong_ordering rhs) noexcept
0392 { return static_cast<std::weak_ordering>(lhs) != rhs; }
0393
0394 friend constexpr bool operator==(std::weak_ordering lhs, weak_ordering rhs) noexcept
0395 { return lhs == static_cast<std::weak_ordering>(rhs); }
0396
0397 friend constexpr bool operator!=(std::weak_ordering lhs, weak_ordering rhs) noexcept
0398 { return lhs != static_cast<std::weak_ordering>(rhs); }
0399
0400 friend constexpr bool operator==(std::partial_ordering lhs, weak_ordering rhs) noexcept
0401 { return lhs == static_cast<std::weak_ordering>(rhs); }
0402
0403 friend constexpr bool operator!=(std::partial_ordering lhs, weak_ordering rhs) noexcept
0404 { return lhs != static_cast<std::weak_ordering>(rhs); }
0405
0406 friend constexpr bool operator==(std::strong_ordering lhs, weak_ordering rhs) noexcept
0407 { return lhs == static_cast<std::weak_ordering>(rhs); }
0408
0409 friend constexpr bool operator!=(std::strong_ordering lhs, weak_ordering rhs) noexcept
0410 { return lhs != static_cast<std::weak_ordering>(rhs); }
0411 #endif
0412
0413 private:
0414 friend class strong_ordering;
0415
0416 constexpr explicit weak_ordering(QtPrivate::Ordering order) noexcept
0417 : m_order(static_cast<QtPrivate::CompareUnderlyingType>(order))
0418 {}
0419
0420 QT_WARNING_PUSH
0421
0422 QT_WARNING_DISABLE_GCC("-Wzero-as-null-pointer-constant")
0423 QT_WARNING_DISABLE_CLANG("-Wzero-as-null-pointer-constant")
0424 friend constexpr bool is_eq (weak_ordering o) noexcept { return o == 0; }
0425 friend constexpr bool is_neq (weak_ordering o) noexcept { return o != 0; }
0426 friend constexpr bool is_lt (weak_ordering o) noexcept { return o < 0; }
0427 friend constexpr bool is_lteq(weak_ordering o) noexcept { return o <= 0; }
0428 friend constexpr bool is_gt (weak_ordering o) noexcept { return o > 0; }
0429 friend constexpr bool is_gteq(weak_ordering o) noexcept { return o >= 0; }
0430 QT_WARNING_POP
0431
0432 QtPrivate::CompareUnderlyingType m_order;
0433 };
0434
0435 inline constexpr weak_ordering weak_ordering::less(QtPrivate::Ordering::Less);
0436 inline constexpr weak_ordering weak_ordering::equivalent(QtPrivate::Ordering::Equivalent);
0437 inline constexpr weak_ordering weak_ordering::greater(QtPrivate::Ordering::Greater);
0438
0439 class strong_ordering
0440 {
0441 public:
0442 static const strong_ordering less;
0443 static const strong_ordering equivalent;
0444 static const strong_ordering equal;
0445 static const strong_ordering greater;
0446
0447 constexpr Q_IMPLICIT operator partial_ordering() const noexcept
0448 { return partial_ordering(static_cast<QtPrivate::Ordering>(m_order)); }
0449
0450 constexpr Q_IMPLICIT operator weak_ordering() const noexcept
0451 { return weak_ordering(static_cast<QtPrivate::Ordering>(m_order)); }
0452
0453 friend constexpr bool operator==(strong_ordering lhs,
0454 QtPrivate::CompareAgainstLiteralZero) noexcept
0455 { return lhs.m_order == 0; }
0456
0457 friend constexpr bool operator!=(strong_ordering lhs,
0458 QtPrivate::CompareAgainstLiteralZero) noexcept
0459 { return lhs.m_order != 0; }
0460
0461 friend constexpr bool operator< (strong_ordering lhs,
0462 QtPrivate::CompareAgainstLiteralZero) noexcept
0463 { return lhs.m_order < 0; }
0464
0465 friend constexpr bool operator<=(strong_ordering lhs,
0466 QtPrivate::CompareAgainstLiteralZero) noexcept
0467 { return lhs.m_order <= 0; }
0468
0469 friend constexpr bool operator> (strong_ordering lhs,
0470 QtPrivate::CompareAgainstLiteralZero) noexcept
0471 { return lhs.m_order > 0; }
0472
0473 friend constexpr bool operator>=(strong_ordering lhs,
0474 QtPrivate::CompareAgainstLiteralZero) noexcept
0475 { return lhs.m_order >= 0; }
0476
0477
0478 friend constexpr bool operator==(QtPrivate::CompareAgainstLiteralZero,
0479 strong_ordering rhs) noexcept
0480 { return 0 == rhs.m_order; }
0481
0482 friend constexpr bool operator!=(QtPrivate::CompareAgainstLiteralZero,
0483 strong_ordering rhs) noexcept
0484 { return 0 != rhs.m_order; }
0485
0486 friend constexpr bool operator< (QtPrivate::CompareAgainstLiteralZero,
0487 strong_ordering rhs) noexcept
0488 { return 0 < rhs.m_order; }
0489
0490 friend constexpr bool operator<=(QtPrivate::CompareAgainstLiteralZero,
0491 strong_ordering rhs) noexcept
0492 { return 0 <= rhs.m_order; }
0493
0494 friend constexpr bool operator> (QtPrivate::CompareAgainstLiteralZero,
0495 strong_ordering rhs) noexcept
0496 { return 0 > rhs.m_order; }
0497
0498 friend constexpr bool operator>=(QtPrivate::CompareAgainstLiteralZero,
0499 strong_ordering rhs) noexcept
0500 { return 0 >= rhs.m_order; }
0501
0502
0503 #ifdef __cpp_lib_three_way_comparison
0504 friend constexpr std::strong_ordering
0505 operator<=>(strong_ordering lhs, QtPrivate::CompareAgainstLiteralZero) noexcept
0506 { return lhs; }
0507
0508 friend constexpr std::strong_ordering
0509 operator<=>(QtPrivate::CompareAgainstLiteralZero, strong_ordering rhs) noexcept
0510 { return QtOrderingPrivate::reversed(rhs); }
0511 #endif
0512
0513
0514 friend constexpr bool operator==(strong_ordering lhs, strong_ordering rhs) noexcept
0515 { return lhs.m_order == rhs.m_order; }
0516
0517 friend constexpr bool operator!=(strong_ordering lhs, strong_ordering rhs) noexcept
0518 { return lhs.m_order != rhs.m_order; }
0519
0520 friend constexpr bool operator==(strong_ordering lhs, partial_ordering rhs) noexcept
0521 { return static_cast<partial_ordering>(lhs) == rhs; }
0522
0523 friend constexpr bool operator!=(strong_ordering lhs, partial_ordering rhs) noexcept
0524 { return static_cast<partial_ordering>(lhs) == rhs; }
0525
0526 friend constexpr bool operator==(partial_ordering lhs, strong_ordering rhs) noexcept
0527 { return lhs == static_cast<partial_ordering>(rhs); }
0528
0529 friend constexpr bool operator!=(partial_ordering lhs, strong_ordering rhs) noexcept
0530 { return lhs != static_cast<partial_ordering>(rhs); }
0531
0532 friend constexpr bool operator==(strong_ordering lhs, weak_ordering rhs) noexcept
0533 { return static_cast<weak_ordering>(lhs) == rhs; }
0534
0535 friend constexpr bool operator!=(strong_ordering lhs, weak_ordering rhs) noexcept
0536 { return static_cast<weak_ordering>(lhs) == rhs; }
0537
0538 friend constexpr bool operator==(weak_ordering lhs, strong_ordering rhs) noexcept
0539 { return lhs == static_cast<weak_ordering>(rhs); }
0540
0541 friend constexpr bool operator!=(weak_ordering lhs, strong_ordering rhs) noexcept
0542 { return lhs != static_cast<weak_ordering>(rhs); }
0543
0544 #ifdef __cpp_lib_three_way_comparison
0545 constexpr Q_IMPLICIT strong_ordering(std::strong_ordering stdorder) noexcept
0546 : m_order{}
0547 {
0548 if (stdorder == std::strong_ordering::less)
0549 m_order = static_cast<QtPrivate::CompareUnderlyingType>(QtPrivate::Ordering::Less);
0550 else if (stdorder == std::strong_ordering::greater)
0551 m_order = static_cast<QtPrivate::CompareUnderlyingType>(QtPrivate::Ordering::Greater);
0552 }
0553
0554 constexpr Q_IMPLICIT operator std::strong_ordering() const noexcept
0555 {
0556 static_assert(sizeof(*this) == sizeof(std::strong_ordering));
0557 #ifdef __cpp_lib_bit_cast
0558 return std::bit_cast<std::strong_ordering>(*this);
0559 #else
0560 using O = QtPrivate::Ordering;
0561 using R = std::strong_ordering;
0562 switch (m_order) {
0563 case qToUnderlying(O::Less): return R::less;
0564 case qToUnderlying(O::Greater): return R::greater;
0565 case qToUnderlying(O::Equal): return R::equal;
0566 }
0567 Q_UNREACHABLE_RETURN(R::equal);
0568 #endif
0569 }
0570
0571 friend constexpr bool operator==(strong_ordering lhs, std::strong_ordering rhs) noexcept
0572 { return static_cast<std::strong_ordering>(lhs) == rhs; }
0573
0574 friend constexpr bool operator!=(strong_ordering lhs, std::strong_ordering rhs) noexcept
0575 { return static_cast<std::strong_ordering>(lhs) != rhs; }
0576
0577 friend constexpr bool operator==(strong_ordering lhs, std::partial_ordering rhs) noexcept
0578 { return static_cast<std::strong_ordering>(lhs) == rhs; }
0579
0580 friend constexpr bool operator!=(strong_ordering lhs, std::partial_ordering rhs) noexcept
0581 { return static_cast<std::strong_ordering>(lhs) != rhs; }
0582
0583 friend constexpr bool operator==(strong_ordering lhs, std::weak_ordering rhs) noexcept
0584 { return static_cast<std::strong_ordering>(lhs) == rhs; }
0585
0586 friend constexpr bool operator!=(strong_ordering lhs, std::weak_ordering rhs) noexcept
0587 { return static_cast<std::strong_ordering>(lhs) != rhs; }
0588
0589 friend constexpr bool operator==(std::strong_ordering lhs, strong_ordering rhs) noexcept
0590 { return lhs == static_cast<std::strong_ordering>(rhs); }
0591
0592 friend constexpr bool operator!=(std::strong_ordering lhs, strong_ordering rhs) noexcept
0593 { return lhs != static_cast<std::strong_ordering>(rhs); }
0594
0595 friend constexpr bool operator==(std::partial_ordering lhs, strong_ordering rhs) noexcept
0596 { return lhs == static_cast<std::strong_ordering>(rhs); }
0597
0598 friend constexpr bool operator!=(std::partial_ordering lhs, strong_ordering rhs) noexcept
0599 { return lhs != static_cast<std::strong_ordering>(rhs); }
0600
0601 friend constexpr bool operator==(std::weak_ordering lhs, strong_ordering rhs) noexcept
0602 { return lhs == static_cast<std::strong_ordering>(rhs); }
0603
0604 friend constexpr bool operator!=(std::weak_ordering lhs, strong_ordering rhs) noexcept
0605 { return lhs != static_cast<std::strong_ordering>(rhs); }
0606 #endif
0607
0608 private:
0609 constexpr explicit strong_ordering(QtPrivate::Ordering order) noexcept
0610 : m_order(static_cast<QtPrivate::CompareUnderlyingType>(order))
0611 {}
0612
0613 QT_WARNING_PUSH
0614
0615 QT_WARNING_DISABLE_GCC("-Wzero-as-null-pointer-constant")
0616 QT_WARNING_DISABLE_CLANG("-Wzero-as-null-pointer-constant")
0617 friend constexpr bool is_eq (strong_ordering o) noexcept { return o == 0; }
0618 friend constexpr bool is_neq (strong_ordering o) noexcept { return o != 0; }
0619 friend constexpr bool is_lt (strong_ordering o) noexcept { return o < 0; }
0620 friend constexpr bool is_lteq(strong_ordering o) noexcept { return o <= 0; }
0621 friend constexpr bool is_gt (strong_ordering o) noexcept { return o > 0; }
0622 friend constexpr bool is_gteq(strong_ordering o) noexcept { return o >= 0; }
0623 QT_WARNING_POP
0624
0625 QtPrivate::CompareUnderlyingType m_order;
0626 };
0627
0628 inline constexpr strong_ordering strong_ordering::less(QtPrivate::Ordering::Less);
0629 inline constexpr strong_ordering strong_ordering::equivalent(QtPrivate::Ordering::Equivalent);
0630 inline constexpr strong_ordering strong_ordering::equal(QtPrivate::Ordering::Equal);
0631 inline constexpr strong_ordering strong_ordering::greater(QtPrivate::Ordering::Greater);
0632
0633 }
0634
0635 QT_BEGIN_INCLUDE_NAMESPACE
0636
0637
0638
0639 #include <QtCore/qcomparehelpers.h>
0640
0641 QT_END_INCLUDE_NAMESPACE
0642
0643 #if defined(Q_QDOC)
0644
0645 template <typename LeftType, typename RightType>
0646 auto qCompareThreeWay(const LeftType &lhs, const RightType &rhs);
0647
0648 #else
0649
0650 template <typename LT, typename RT,
0651 std::enable_if_t<
0652 std::disjunction_v<
0653 QtOrderingPrivate::CompareThreeWayTester::HasCompareThreeWay<LT, RT>,
0654 QtOrderingPrivate::CompareThreeWayTester::HasCompareThreeWay<RT, LT>>,
0655 bool> = true>
0656 auto qCompareThreeWay(const LT &lhs, const RT &rhs)
0657 noexcept(QtOrderingPrivate::CompareThreeWayTester::compareThreeWayNoexcept<LT, RT>())
0658 {
0659 using Qt::compareThreeWay;
0660 if constexpr (QtOrderingPrivate::CompareThreeWayTester::hasCompareThreeWay_v<LT, RT>) {
0661 return compareThreeWay(lhs, rhs);
0662 } else {
0663 const auto retval = compareThreeWay(rhs, lhs);
0664 return QtOrderingPrivate::reversed(retval);
0665 }
0666 }
0667
0668 #endif
0669
0670
0671
0672
0673
0674 namespace QtPrivate {
0675 enum class LegacyUncomparable : CompareUnderlyingType
0676 {
0677 Unordered = QtPrivate::LegacyUncomparableValue
0678 };
0679 }
0680
0681
0682 class QPartialOrdering
0683 {
0684 public:
0685 static const QPartialOrdering Less;
0686 static const QPartialOrdering Equivalent;
0687 static const QPartialOrdering Greater;
0688 static const QPartialOrdering Unordered;
0689
0690 static const QPartialOrdering less;
0691 static const QPartialOrdering equivalent;
0692 static const QPartialOrdering greater;
0693 static const QPartialOrdering unordered;
0694
0695 friend constexpr bool operator==(QPartialOrdering lhs,
0696 QtPrivate::CompareAgainstLiteralZero) noexcept
0697 { return lhs.isOrdered() && lhs.m_order == 0; }
0698
0699 friend constexpr bool operator!=(QPartialOrdering lhs,
0700 QtPrivate::CompareAgainstLiteralZero) noexcept
0701 { return !lhs.isOrdered() || lhs.m_order != 0; }
0702
0703 friend constexpr bool operator< (QPartialOrdering lhs,
0704 QtPrivate::CompareAgainstLiteralZero) noexcept
0705 { return lhs.isOrdered() && lhs.m_order < 0; }
0706
0707 friend constexpr bool operator<=(QPartialOrdering lhs,
0708 QtPrivate::CompareAgainstLiteralZero) noexcept
0709 { return lhs.isOrdered() && lhs.m_order <= 0; }
0710
0711 friend constexpr bool operator> (QPartialOrdering lhs,
0712 QtPrivate::CompareAgainstLiteralZero) noexcept
0713 { return lhs.isOrdered() && lhs.m_order > 0; }
0714
0715 friend constexpr bool operator>=(QPartialOrdering lhs,
0716 QtPrivate::CompareAgainstLiteralZero) noexcept
0717 { return lhs.isOrdered() && lhs.m_order >= 0; }
0718
0719
0720 friend constexpr bool operator==(QtPrivate::CompareAgainstLiteralZero,
0721 QPartialOrdering rhs) noexcept
0722 { return rhs.isOrdered() && 0 == rhs.m_order; }
0723
0724 friend constexpr bool operator!=(QtPrivate::CompareAgainstLiteralZero,
0725 QPartialOrdering rhs) noexcept
0726 { return !rhs.isOrdered() || 0 != rhs.m_order; }
0727
0728 friend constexpr bool operator< (QtPrivate::CompareAgainstLiteralZero,
0729 QPartialOrdering rhs) noexcept
0730 { return rhs.isOrdered() && 0 < rhs.m_order; }
0731
0732 friend constexpr bool operator<=(QtPrivate::CompareAgainstLiteralZero,
0733 QPartialOrdering rhs) noexcept
0734 { return rhs.isOrdered() && 0 <= rhs.m_order; }
0735
0736 friend constexpr bool operator> (QtPrivate::CompareAgainstLiteralZero,
0737 QPartialOrdering rhs) noexcept
0738 { return rhs.isOrdered() && 0 > rhs.m_order; }
0739
0740 friend constexpr bool operator>=(QtPrivate::CompareAgainstLiteralZero,
0741 QPartialOrdering rhs) noexcept
0742 { return rhs.isOrdered() && 0 >= rhs.m_order; }
0743
0744
0745 #ifdef __cpp_lib_three_way_comparison
0746 friend constexpr std::partial_ordering
0747 operator<=>(QPartialOrdering lhs, QtPrivate::CompareAgainstLiteralZero) noexcept
0748 { return lhs; }
0749
0750 friend constexpr std::partial_ordering
0751 operator<=>(QtPrivate::CompareAgainstLiteralZero, QPartialOrdering rhs) noexcept
0752 { return QtOrderingPrivate::reversed(rhs); }
0753 #endif
0754
0755
0756 friend constexpr bool operator==(QPartialOrdering lhs, QPartialOrdering rhs) noexcept
0757 { return lhs.m_order == rhs.m_order; }
0758
0759 friend constexpr bool operator!=(QPartialOrdering lhs, QPartialOrdering rhs) noexcept
0760 { return lhs.m_order != rhs.m_order; }
0761
0762 constexpr Q_IMPLICIT QPartialOrdering(Qt::partial_ordering order) noexcept
0763 : m_order{}
0764 {
0765 if (order == Qt::partial_ordering::less)
0766 m_order = static_cast<QtPrivate::CompareUnderlyingType>(QtPrivate::Ordering::Less);
0767 else if (order == Qt::partial_ordering::greater)
0768 m_order = static_cast<QtPrivate::CompareUnderlyingType>(QtPrivate::Ordering::Greater);
0769 else if (order == Qt::partial_ordering::unordered)
0770 m_order = static_cast<QtPrivate::CompareUnderlyingType>(QtPrivate::LegacyUncomparable::Unordered);
0771 }
0772
0773 constexpr Q_IMPLICIT QPartialOrdering(Qt::weak_ordering stdorder) noexcept
0774 : QPartialOrdering(Qt::partial_ordering{stdorder}) {}
0775
0776 constexpr Q_IMPLICIT QPartialOrdering(Qt::strong_ordering stdorder) noexcept
0777 : QPartialOrdering(Qt::partial_ordering{stdorder}) {}
0778
0779 constexpr Q_IMPLICIT operator Qt::partial_ordering() const noexcept
0780 {
0781 using O = QtPrivate::Ordering;
0782 using U = QtPrivate::LegacyUncomparable;
0783 using R = Qt::partial_ordering;
0784 switch (m_order) {
0785 case qToUnderlying(O::Less): return R::less;
0786 case qToUnderlying(O::Greater): return R::greater;
0787 case qToUnderlying(O::Equivalent): return R::equivalent;
0788 case qToUnderlying(U::Unordered): return R::unordered;
0789 }
0790
0791 #if !defined(Q_CC_GNU_ONLY) || (Q_CC_GNU >= 900)
0792
0793 Q_UNREACHABLE();
0794 #endif
0795 return R::unordered;
0796 }
0797
0798 friend constexpr bool operator==(QPartialOrdering lhs, Qt::partial_ordering rhs) noexcept
0799 { Qt::partial_ordering qt = lhs; return qt == rhs; }
0800
0801 friend constexpr bool operator!=(QPartialOrdering lhs, Qt::partial_ordering rhs) noexcept
0802 { Qt::partial_ordering qt = lhs; return qt != rhs; }
0803
0804 friend constexpr bool operator==(Qt::partial_ordering lhs, QPartialOrdering rhs) noexcept
0805 { Qt::partial_ordering qt = rhs; return lhs == qt; }
0806
0807 friend constexpr bool operator!=(Qt::partial_ordering lhs, QPartialOrdering rhs) noexcept
0808 { Qt::partial_ordering qt = rhs; return lhs != qt; }
0809
0810 #ifdef __cpp_lib_three_way_comparison
0811 constexpr Q_IMPLICIT QPartialOrdering(std::partial_ordering stdorder) noexcept
0812 : m_order{}
0813 {
0814 if (stdorder == std::partial_ordering::less)
0815 m_order = static_cast<QtPrivate::CompareUnderlyingType>(QtPrivate::Ordering::Less);
0816 else if (stdorder == std::partial_ordering::greater)
0817 m_order = static_cast<QtPrivate::CompareUnderlyingType>(QtPrivate::Ordering::Greater);
0818 else if (stdorder == std::partial_ordering::unordered)
0819 m_order = static_cast<QtPrivate::CompareUnderlyingType>(QtPrivate::LegacyUncomparable::Unordered);
0820 }
0821
0822 constexpr Q_IMPLICIT QPartialOrdering(std::weak_ordering stdorder) noexcept
0823 : QPartialOrdering(std::partial_ordering(stdorder)) {}
0824
0825 constexpr Q_IMPLICIT QPartialOrdering(std::strong_ordering stdorder) noexcept
0826 : QPartialOrdering(std::partial_ordering(stdorder)) {}
0827
0828 constexpr Q_IMPLICIT operator std::partial_ordering() const noexcept
0829 {
0830 using O = QtPrivate::Ordering;
0831 using U = QtPrivate::LegacyUncomparable;
0832 using R = std::partial_ordering;
0833 switch (m_order) {
0834 case qToUnderlying(O::Less): return R::less;
0835 case qToUnderlying(O::Greater): return R::greater;
0836 case qToUnderlying(O::Equivalent): return R::equivalent;
0837 case qToUnderlying(U::Unordered): return R::unordered;
0838 }
0839 Q_UNREACHABLE_RETURN(R::unordered);
0840 }
0841
0842 friend constexpr bool operator==(QPartialOrdering lhs, std::partial_ordering rhs) noexcept
0843 { return static_cast<std::partial_ordering>(lhs) == rhs; }
0844
0845 friend constexpr bool operator!=(QPartialOrdering lhs, std::partial_ordering rhs) noexcept
0846 { return static_cast<std::partial_ordering>(lhs) != rhs; }
0847
0848 friend constexpr bool operator==(std::partial_ordering lhs, QPartialOrdering rhs) noexcept
0849 { return lhs == static_cast<std::partial_ordering>(rhs); }
0850
0851 friend constexpr bool operator!=(std::partial_ordering lhs, QPartialOrdering rhs) noexcept
0852 { return lhs != static_cast<std::partial_ordering>(rhs); }
0853 #endif
0854
0855 private:
0856 constexpr explicit QPartialOrdering(QtPrivate::Ordering order) noexcept
0857 : m_order(static_cast<QtPrivate::CompareUnderlyingType>(order))
0858 {}
0859 constexpr explicit QPartialOrdering(QtPrivate::LegacyUncomparable order) noexcept
0860 : m_order(static_cast<QtPrivate::CompareUnderlyingType>(order))
0861 {}
0862
0863 QT_WARNING_PUSH
0864
0865 QT_WARNING_DISABLE_GCC("-Wzero-as-null-pointer-constant")
0866 QT_WARNING_DISABLE_CLANG("-Wzero-as-null-pointer-constant")
0867 friend constexpr bool is_eq (QPartialOrdering o) noexcept { return o == 0; }
0868 friend constexpr bool is_neq (QPartialOrdering o) noexcept { return o != 0; }
0869 friend constexpr bool is_lt (QPartialOrdering o) noexcept { return o < 0; }
0870 friend constexpr bool is_lteq(QPartialOrdering o) noexcept { return o <= 0; }
0871 friend constexpr bool is_gt (QPartialOrdering o) noexcept { return o > 0; }
0872 friend constexpr bool is_gteq(QPartialOrdering o) noexcept { return o >= 0; }
0873 QT_WARNING_POP
0874
0875
0876
0877 constexpr bool isOrdered() const noexcept
0878 { return m_order != static_cast<QtPrivate::CompareUnderlyingType>(QtPrivate::LegacyUncomparable::Unordered); }
0879
0880 QtPrivate::CompareUnderlyingType m_order;
0881 };
0882
0883 inline constexpr QPartialOrdering QPartialOrdering::Less(QtPrivate::Ordering::Less);
0884 inline constexpr QPartialOrdering QPartialOrdering::Equivalent(QtPrivate::Ordering::Equivalent);
0885 inline constexpr QPartialOrdering QPartialOrdering::Greater(QtPrivate::Ordering::Greater);
0886 inline constexpr QPartialOrdering QPartialOrdering::Unordered(QtPrivate::LegacyUncomparable::Unordered);
0887
0888 inline constexpr QPartialOrdering QPartialOrdering::less(QtPrivate::Ordering::Less);
0889 inline constexpr QPartialOrdering QPartialOrdering::equivalent(QtPrivate::Ordering::Equivalent);
0890 inline constexpr QPartialOrdering QPartialOrdering::greater(QtPrivate::Ordering::Greater);
0891 inline constexpr QPartialOrdering QPartialOrdering::unordered(QtPrivate::LegacyUncomparable::Unordered);
0892
0893 QT_END_NAMESPACE
0894
0895 #endif