Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 10:07:20

0001 // Copyright (C) 2020 Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.com, author Giuseppe D'Angelo <giuseppe.dangelo@kdab.com>
0002 // Copyright (C) 2023 The Qt Company Ltd.
0003 // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
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 
0015 #ifdef __cpp_lib_bit_cast
0016 #include <bit>
0017 #endif
0018 #ifdef __cpp_lib_three_way_comparison
0019 #include <compare>
0020 #endif
0021 
0022 QT_BEGIN_NAMESPACE
0023 
0024 namespace QtPrivate {
0025 using CompareUnderlyingType = qint8;
0026 
0027 // [cmp.categories.pre] / 1
0028 enum class Ordering : CompareUnderlyingType
0029 {
0030     Equal = 0,
0031     Equivalent = Equal,
0032     Less = -1,
0033     Greater = 1
0034 };
0035 
0036 enum class Uncomparable : CompareUnderlyingType
0037 {
0038     Unordered =
0039         #if defined(_LIBCPP_VERSION) // libc++
0040                 -127
0041         #elif defined(__GLIBCXX__)   // libstdc++
0042                    2
0043         #else                        // assume MSSTL
0044                 -128
0045         #endif
0046 };
0047 
0048 } // namespace QtPrivate
0049 
0050 namespace QtOrderingPrivate {
0051 
0052 template <typename O>
0053 constexpr O reversed(O o) noexcept
0054 {
0055     // https://eel.is/c++draft/cmp.partialord#5
0056     return is_lt(o) ? O::greater :
0057            is_gt(o) ? O::less :
0058            /*else*/ o ;
0059 }
0060 
0061 } // namespace QtOrderingPrivate
0062 
0063 namespace Qt {
0064 
0065 class partial_ordering
0066 {
0067 public:
0068     static const partial_ordering less;
0069     static const partial_ordering equivalent;
0070     static const partial_ordering greater;
0071     static const partial_ordering unordered;
0072 
0073     friend constexpr bool operator==(partial_ordering lhs,
0074                                      QtPrivate::CompareAgainstLiteralZero) noexcept
0075     { return lhs.isOrdered() && lhs.m_order == 0; }
0076 
0077     friend constexpr bool operator!=(partial_ordering lhs,
0078                                      QtPrivate::CompareAgainstLiteralZero) noexcept
0079     { return lhs.isOrdered() && lhs.m_order != 0; }
0080 
0081     friend constexpr bool operator< (partial_ordering lhs,
0082                                      QtPrivate::CompareAgainstLiteralZero) noexcept
0083     { return lhs.isOrdered() && lhs.m_order <  0; }
0084 
0085     friend constexpr bool operator<=(partial_ordering lhs,
0086                                      QtPrivate::CompareAgainstLiteralZero) noexcept
0087     { return lhs.isOrdered() && lhs.m_order <= 0; }
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 
0098     friend constexpr bool operator==(QtPrivate::CompareAgainstLiteralZero,
0099                                      partial_ordering rhs) noexcept
0100     { return rhs.isOrdered() && 0 == rhs.m_order; }
0101 
0102     friend constexpr bool operator!=(QtPrivate::CompareAgainstLiteralZero,
0103                                      partial_ordering rhs) noexcept
0104     { return rhs.isOrdered() && 0 != rhs.m_order; }
0105 
0106     friend constexpr bool operator< (QtPrivate::CompareAgainstLiteralZero,
0107                                      partial_ordering rhs) noexcept
0108     { return rhs.isOrdered() && 0 <  rhs.m_order; }
0109 
0110     friend constexpr bool operator<=(QtPrivate::CompareAgainstLiteralZero,
0111                                      partial_ordering rhs) noexcept
0112     { return rhs.isOrdered() && 0 <= rhs.m_order; }
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 
0123 #ifdef __cpp_lib_three_way_comparison
0124     friend constexpr std::partial_ordering
0125     operator<=>(partial_ordering lhs, QtPrivate::CompareAgainstLiteralZero) noexcept
0126     { return lhs; } // https://eel.is/c++draft/cmp.partialord#4
0127 
0128     friend constexpr std::partial_ordering
0129     operator<=>(QtPrivate::CompareAgainstLiteralZero, partial_ordering rhs) noexcept
0130     { return QtOrderingPrivate::reversed(rhs); }
0131 #endif // __cpp_lib_three_way_comparison
0132 
0133 
0134     friend constexpr bool operator==(partial_ordering lhs, partial_ordering rhs) noexcept
0135     { return lhs.m_order == rhs.m_order; }
0136 
0137     friend constexpr bool operator!=(partial_ordering lhs, partial_ordering rhs) noexcept
0138     { return lhs.m_order != rhs.m_order; }
0139 
0140 #ifdef __cpp_lib_three_way_comparison
0141     constexpr Q_IMPLICIT partial_ordering(std::partial_ordering stdorder) noexcept
0142     {
0143         if (stdorder == std::partial_ordering::less)
0144             m_order = static_cast<QtPrivate::CompareUnderlyingType>(QtPrivate::Ordering::Less);
0145         else if (stdorder == std::partial_ordering::equivalent)
0146             m_order = static_cast<QtPrivate::CompareUnderlyingType>(QtPrivate::Ordering::Equivalent);
0147         else if (stdorder == std::partial_ordering::greater)
0148             m_order = static_cast<QtPrivate::CompareUnderlyingType>(QtPrivate::Ordering::Greater);
0149         else if (stdorder == std::partial_ordering::unordered)
0150             m_order = static_cast<QtPrivate::CompareUnderlyingType>(QtPrivate::Uncomparable::Unordered);
0151     }
0152 
0153     constexpr Q_IMPLICIT operator std::partial_ordering() const noexcept
0154     {
0155         static_assert(sizeof(*this) == sizeof(std::partial_ordering));
0156 #ifdef __cpp_lib_bit_cast
0157         return std::bit_cast<std::partial_ordering>(*this);
0158 #else
0159         using O = QtPrivate::Ordering;
0160         using U = QtPrivate::Uncomparable;
0161         using R = std::partial_ordering;
0162         switch (m_order) {
0163         case qToUnderlying(O::Less):        return R::less;
0164         case qToUnderlying(O::Greater):     return R::greater;
0165         case qToUnderlying(O::Equivalent):  return R::equivalent;
0166         case qToUnderlying(U::Unordered):   return R::unordered;
0167         }
0168         Q_UNREACHABLE_RETURN(R::unordered);
0169 #endif // __cpp_lib_bit_cast
0170     }
0171 
0172     friend constexpr bool operator==(partial_ordering lhs, std::partial_ordering rhs) noexcept
0173     { return static_cast<std::partial_ordering>(lhs) == rhs; }
0174 
0175     friend constexpr bool operator!=(partial_ordering lhs, std::partial_ordering rhs) noexcept
0176     { return static_cast<std::partial_ordering>(lhs) != rhs; }
0177 
0178     friend constexpr bool operator==(std::partial_ordering lhs, partial_ordering rhs) noexcept
0179     { return lhs == static_cast<std::partial_ordering>(rhs); }
0180 
0181     friend constexpr bool operator!=(std::partial_ordering lhs, partial_ordering rhs) noexcept
0182     { return lhs != static_cast<std::partial_ordering>(rhs); }
0183 #endif // __cpp_lib_three_way_comparison
0184 
0185 private:
0186     friend class weak_ordering;
0187     friend class strong_ordering;
0188 
0189     constexpr explicit partial_ordering(QtPrivate::Ordering order) noexcept
0190         : m_order(static_cast<QtPrivate::CompareUnderlyingType>(order))
0191     {}
0192     constexpr explicit partial_ordering(QtPrivate::Uncomparable order) noexcept
0193         : m_order(static_cast<QtPrivate::CompareUnderlyingType>(order))
0194     {}
0195 
0196     QT_WARNING_PUSH
0197     // https://gcc.gnu.org/bugzilla/show_bug.cgi?id=100903
0198     QT_WARNING_DISABLE_GCC("-Wzero-as-null-pointer-constant")
0199     friend constexpr bool is_eq  (partial_ordering o) noexcept { return o == 0; }
0200     friend constexpr bool is_neq (partial_ordering o) noexcept { return o != 0; }
0201     friend constexpr bool is_lt  (partial_ordering o) noexcept { return o <  0; }
0202     friend constexpr bool is_lteq(partial_ordering o) noexcept { return o <= 0; }
0203     friend constexpr bool is_gt  (partial_ordering o) noexcept { return o >  0; }
0204     friend constexpr bool is_gteq(partial_ordering o) noexcept { return o >= 0; }
0205     QT_WARNING_POP
0206 
0207     // instead of the exposition only is_ordered member in [cmp.partialord],
0208     // use a private function
0209     constexpr bool isOrdered() const noexcept
0210     { return m_order != static_cast<QtPrivate::CompareUnderlyingType>(QtPrivate::Uncomparable::Unordered); }
0211 
0212     QtPrivate::CompareUnderlyingType m_order;
0213 };
0214 
0215 inline constexpr partial_ordering partial_ordering::less(QtPrivate::Ordering::Less);
0216 inline constexpr partial_ordering partial_ordering::equivalent(QtPrivate::Ordering::Equivalent);
0217 inline constexpr partial_ordering partial_ordering::greater(QtPrivate::Ordering::Greater);
0218 inline constexpr partial_ordering partial_ordering::unordered(QtPrivate::Uncomparable::Unordered);
0219 
0220 class weak_ordering
0221 {
0222 public:
0223     static const weak_ordering less;
0224     static const weak_ordering equivalent;
0225     static const weak_ordering greater;
0226 
0227     constexpr Q_IMPLICIT operator partial_ordering() const noexcept
0228     { return partial_ordering(static_cast<QtPrivate::Ordering>(m_order)); }
0229 
0230     friend constexpr bool operator==(weak_ordering lhs,
0231                                      QtPrivate::CompareAgainstLiteralZero) noexcept
0232     { return lhs.m_order == 0; }
0233 
0234     friend constexpr bool operator!=(weak_ordering lhs,
0235                                      QtPrivate::CompareAgainstLiteralZero) noexcept
0236     { return lhs.m_order != 0; }
0237 
0238     friend constexpr bool operator< (weak_ordering lhs,
0239                                      QtPrivate::CompareAgainstLiteralZero) noexcept
0240     { return lhs.m_order <  0; }
0241 
0242     friend constexpr bool operator<=(weak_ordering lhs,
0243                                      QtPrivate::CompareAgainstLiteralZero) noexcept
0244     { return lhs.m_order <= 0; }
0245 
0246     friend constexpr bool operator> (weak_ordering lhs,
0247                                      QtPrivate::CompareAgainstLiteralZero) noexcept
0248     { return lhs.m_order >  0; }
0249 
0250     friend constexpr bool operator>=(weak_ordering lhs,
0251                                      QtPrivate::CompareAgainstLiteralZero) noexcept
0252     { return lhs.m_order >= 0; }
0253 
0254 
0255     friend constexpr bool operator==(QtPrivate::CompareAgainstLiteralZero,
0256                                      weak_ordering rhs) noexcept
0257     { return 0 == rhs.m_order; }
0258 
0259     friend constexpr bool operator!=(QtPrivate::CompareAgainstLiteralZero,
0260                                      weak_ordering rhs) noexcept
0261     { return 0 != rhs.m_order; }
0262 
0263     friend constexpr bool operator< (QtPrivate::CompareAgainstLiteralZero,
0264                                      weak_ordering rhs) noexcept
0265     { return 0 <  rhs.m_order; }
0266 
0267     friend constexpr bool operator<=(QtPrivate::CompareAgainstLiteralZero,
0268                                      weak_ordering rhs) noexcept
0269     { return 0 <= rhs.m_order; }
0270 
0271     friend constexpr bool operator> (QtPrivate::CompareAgainstLiteralZero,
0272                                      weak_ordering rhs) noexcept
0273     { return 0 > rhs.m_order; }
0274 
0275     friend constexpr bool operator>=(QtPrivate::CompareAgainstLiteralZero,
0276                                      weak_ordering rhs) noexcept
0277     { return 0 >= rhs.m_order; }
0278 
0279 
0280 #ifdef __cpp_lib_three_way_comparison
0281     friend constexpr std::weak_ordering
0282     operator<=>(weak_ordering lhs, QtPrivate::CompareAgainstLiteralZero) noexcept
0283     { return lhs; } // https://eel.is/c++draft/cmp.weakord#5
0284 
0285     friend constexpr std::weak_ordering
0286     operator<=>(QtPrivate::CompareAgainstLiteralZero, weak_ordering rhs) noexcept
0287     { return QtOrderingPrivate::reversed(rhs); }
0288 #endif // __cpp_lib_three_way_comparison
0289 
0290 
0291     friend constexpr bool operator==(weak_ordering lhs, weak_ordering rhs) noexcept
0292     { return lhs.m_order == rhs.m_order; }
0293 
0294     friend constexpr bool operator!=(weak_ordering lhs, weak_ordering rhs) noexcept
0295     { return lhs.m_order != rhs.m_order; }
0296 
0297     friend constexpr bool operator==(weak_ordering lhs, partial_ordering rhs) noexcept
0298     { return static_cast<partial_ordering>(lhs) == rhs; }
0299 
0300     friend constexpr bool operator!=(weak_ordering lhs, partial_ordering rhs) noexcept
0301     { return static_cast<partial_ordering>(lhs) != rhs; }
0302 
0303     friend constexpr bool operator==(partial_ordering lhs, weak_ordering rhs) noexcept
0304     { return lhs == static_cast<partial_ordering>(rhs); }
0305 
0306     friend constexpr bool operator!=(partial_ordering lhs, weak_ordering rhs) noexcept
0307     { return lhs != static_cast<partial_ordering>(rhs); }
0308 
0309 #ifdef __cpp_lib_three_way_comparison
0310     constexpr Q_IMPLICIT weak_ordering(std::weak_ordering stdorder) noexcept
0311     {
0312         if (stdorder == std::weak_ordering::less)
0313             m_order = static_cast<QtPrivate::CompareUnderlyingType>(QtPrivate::Ordering::Less);
0314         else if (stdorder == std::weak_ordering::equivalent)
0315             m_order = static_cast<QtPrivate::CompareUnderlyingType>(QtPrivate::Ordering::Equivalent);
0316         else if (stdorder == std::weak_ordering::greater)
0317             m_order = static_cast<QtPrivate::CompareUnderlyingType>(QtPrivate::Ordering::Greater);
0318     }
0319 
0320     constexpr Q_IMPLICIT operator std::weak_ordering() const noexcept
0321     {
0322         static_assert(sizeof(*this) == sizeof(std::weak_ordering));
0323 #ifdef __cpp_lib_bit_cast
0324         return std::bit_cast<std::weak_ordering>(*this);
0325 #else
0326         using O = QtPrivate::Ordering;
0327         using R = std::weak_ordering;
0328         switch (m_order) {
0329         case qToUnderlying(O::Less):          return R::less;
0330         case qToUnderlying(O::Greater):       return R::greater;
0331         case qToUnderlying(O::Equivalent):    return R::equivalent;
0332         }
0333         Q_UNREACHABLE_RETURN(R::equivalent);
0334 #endif // __cpp_lib_bit_cast
0335     }
0336 
0337     friend constexpr bool operator==(weak_ordering lhs, std::weak_ordering rhs) noexcept
0338     { return static_cast<std::weak_ordering>(lhs) == rhs; }
0339 
0340     friend constexpr bool operator!=(weak_ordering lhs, std::weak_ordering rhs) noexcept
0341     { return static_cast<std::weak_ordering>(lhs) != rhs; }
0342 
0343     friend constexpr bool operator==(weak_ordering lhs, std::partial_ordering rhs) noexcept
0344     { return static_cast<std::weak_ordering>(lhs) == rhs; }
0345 
0346     friend constexpr bool operator!=(weak_ordering lhs, std::partial_ordering rhs) noexcept
0347     { return static_cast<std::weak_ordering>(lhs) != rhs; }
0348 
0349     friend constexpr bool operator==(weak_ordering lhs, std::strong_ordering rhs) noexcept
0350     { return static_cast<std::weak_ordering>(lhs) == rhs; }
0351 
0352     friend constexpr bool operator!=(weak_ordering lhs, std::strong_ordering rhs) noexcept
0353     { return static_cast<std::weak_ordering>(lhs) != rhs; }
0354 
0355     friend constexpr bool operator==(std::weak_ordering lhs, weak_ordering rhs) noexcept
0356     { return lhs == static_cast<std::weak_ordering>(rhs); }
0357 
0358     friend constexpr bool operator!=(std::weak_ordering lhs, weak_ordering rhs) noexcept
0359     { return lhs != static_cast<std::weak_ordering>(rhs); }
0360 
0361     friend constexpr bool operator==(std::partial_ordering lhs, weak_ordering rhs) noexcept
0362     { return lhs == static_cast<std::weak_ordering>(rhs); }
0363 
0364     friend constexpr bool operator!=(std::partial_ordering lhs, weak_ordering rhs) noexcept
0365     { return lhs != static_cast<std::weak_ordering>(rhs); }
0366 
0367     friend constexpr bool operator==(std::strong_ordering lhs, weak_ordering rhs) noexcept
0368     { return lhs == static_cast<std::weak_ordering>(rhs); }
0369 
0370     friend constexpr bool operator!=(std::strong_ordering lhs, weak_ordering rhs) noexcept
0371     { return lhs != static_cast<std::weak_ordering>(rhs); }
0372 #endif // __cpp_lib_three_way_comparison
0373 
0374 private:
0375     friend class strong_ordering;
0376 
0377     constexpr explicit weak_ordering(QtPrivate::Ordering order) noexcept
0378         : m_order(static_cast<QtPrivate::CompareUnderlyingType>(order))
0379     {}
0380 
0381     QT_WARNING_PUSH
0382     // https://gcc.gnu.org/bugzilla/show_bug.cgi?id=100903
0383     QT_WARNING_DISABLE_GCC("-Wzero-as-null-pointer-constant")
0384     friend constexpr bool is_eq  (weak_ordering o) noexcept { return o == 0; }
0385     friend constexpr bool is_neq (weak_ordering o) noexcept { return o != 0; }
0386     friend constexpr bool is_lt  (weak_ordering o) noexcept { return o <  0; }
0387     friend constexpr bool is_lteq(weak_ordering o) noexcept { return o <= 0; }
0388     friend constexpr bool is_gt  (weak_ordering o) noexcept { return o >  0; }
0389     friend constexpr bool is_gteq(weak_ordering o) noexcept { return o >= 0; }
0390     QT_WARNING_POP
0391 
0392     QtPrivate::CompareUnderlyingType m_order;
0393 };
0394 
0395 inline constexpr weak_ordering weak_ordering::less(QtPrivate::Ordering::Less);
0396 inline constexpr weak_ordering weak_ordering::equivalent(QtPrivate::Ordering::Equivalent);
0397 inline constexpr weak_ordering weak_ordering::greater(QtPrivate::Ordering::Greater);
0398 
0399 class strong_ordering
0400 {
0401 public:
0402     static const strong_ordering less;
0403     static const strong_ordering equivalent;
0404     static const strong_ordering equal;
0405     static const strong_ordering greater;
0406 
0407     constexpr Q_IMPLICIT operator partial_ordering() const noexcept
0408     { return partial_ordering(static_cast<QtPrivate::Ordering>(m_order)); }
0409 
0410     constexpr Q_IMPLICIT operator weak_ordering() const noexcept
0411     { return weak_ordering(static_cast<QtPrivate::Ordering>(m_order)); }
0412 
0413     friend constexpr bool operator==(strong_ordering lhs,
0414                                      QtPrivate::CompareAgainstLiteralZero) noexcept
0415     { return lhs.m_order == 0; }
0416 
0417     friend constexpr bool operator!=(strong_ordering lhs,
0418                                      QtPrivate::CompareAgainstLiteralZero) noexcept
0419     { return lhs.m_order != 0; }
0420 
0421     friend constexpr bool operator< (strong_ordering lhs,
0422                                      QtPrivate::CompareAgainstLiteralZero) noexcept
0423     { return lhs.m_order <  0; }
0424 
0425     friend constexpr bool operator<=(strong_ordering lhs,
0426                                      QtPrivate::CompareAgainstLiteralZero) noexcept
0427     { return lhs.m_order <= 0; }
0428 
0429     friend constexpr bool operator> (strong_ordering lhs,
0430                                      QtPrivate::CompareAgainstLiteralZero) noexcept
0431     { return lhs.m_order >  0; }
0432 
0433     friend constexpr bool operator>=(strong_ordering lhs,
0434                                      QtPrivate::CompareAgainstLiteralZero) noexcept
0435     { return lhs.m_order >= 0; }
0436 
0437 
0438     friend constexpr bool operator==(QtPrivate::CompareAgainstLiteralZero,
0439                                      strong_ordering rhs) noexcept
0440     { return 0 == rhs.m_order; }
0441 
0442     friend constexpr bool operator!=(QtPrivate::CompareAgainstLiteralZero,
0443                                      strong_ordering rhs) noexcept
0444     { return 0 != rhs.m_order; }
0445 
0446     friend constexpr bool operator< (QtPrivate::CompareAgainstLiteralZero,
0447                                     strong_ordering rhs) noexcept
0448     { return 0 <  rhs.m_order; }
0449 
0450     friend constexpr bool operator<=(QtPrivate::CompareAgainstLiteralZero,
0451                                      strong_ordering rhs) noexcept
0452     { return 0 <= rhs.m_order; }
0453 
0454     friend constexpr bool operator> (QtPrivate::CompareAgainstLiteralZero,
0455                                     strong_ordering rhs) noexcept
0456     { return 0 >  rhs.m_order; }
0457 
0458     friend constexpr bool operator>=(QtPrivate::CompareAgainstLiteralZero,
0459                                      strong_ordering rhs) noexcept
0460     { return 0 >= rhs.m_order; }
0461 
0462 
0463 #ifdef __cpp_lib_three_way_comparison
0464     friend constexpr std::strong_ordering
0465     operator<=>(strong_ordering lhs, QtPrivate::CompareAgainstLiteralZero) noexcept
0466     { return lhs; } // https://eel.is/c++draft/cmp.strongord#6
0467 
0468     friend constexpr std::strong_ordering
0469     operator<=>(QtPrivate::CompareAgainstLiteralZero, strong_ordering rhs) noexcept
0470     { return QtOrderingPrivate::reversed(rhs); }
0471 #endif // __cpp_lib_three_way_comparison
0472 
0473 
0474     friend constexpr bool operator==(strong_ordering lhs, strong_ordering rhs) noexcept
0475     { return lhs.m_order == rhs.m_order; }
0476 
0477     friend constexpr bool operator!=(strong_ordering lhs, strong_ordering rhs) noexcept
0478     { return lhs.m_order != rhs.m_order; }
0479 
0480     friend constexpr bool operator==(strong_ordering lhs, partial_ordering rhs) noexcept
0481     { return static_cast<partial_ordering>(lhs) == rhs; }
0482 
0483     friend constexpr bool operator!=(strong_ordering lhs, partial_ordering rhs) noexcept
0484     { return static_cast<partial_ordering>(lhs) == rhs; }
0485 
0486     friend constexpr bool operator==(partial_ordering lhs, strong_ordering rhs) noexcept
0487     { return lhs == static_cast<partial_ordering>(rhs); }
0488 
0489     friend constexpr bool operator!=(partial_ordering lhs, strong_ordering rhs) noexcept
0490     { return lhs != static_cast<partial_ordering>(rhs); }
0491 
0492     friend constexpr bool operator==(strong_ordering lhs, weak_ordering rhs) noexcept
0493     { return static_cast<weak_ordering>(lhs) == rhs; }
0494 
0495     friend constexpr bool operator!=(strong_ordering lhs, weak_ordering rhs) noexcept
0496     { return static_cast<weak_ordering>(lhs) == rhs; }
0497 
0498     friend constexpr bool operator==(weak_ordering lhs, strong_ordering rhs) noexcept
0499     { return lhs == static_cast<weak_ordering>(rhs); }
0500 
0501     friend constexpr bool operator!=(weak_ordering lhs, strong_ordering rhs) noexcept
0502     { return lhs != static_cast<weak_ordering>(rhs); }
0503 
0504 #ifdef __cpp_lib_three_way_comparison
0505     constexpr Q_IMPLICIT strong_ordering(std::strong_ordering stdorder) noexcept
0506     {
0507         if (stdorder == std::strong_ordering::less)
0508             m_order = static_cast<QtPrivate::CompareUnderlyingType>(QtPrivate::Ordering::Less);
0509         else if (stdorder == std::strong_ordering::equivalent)
0510             m_order = static_cast<QtPrivate::CompareUnderlyingType>(QtPrivate::Ordering::Equivalent);
0511         else if (stdorder == std::strong_ordering::equal)
0512             m_order = static_cast<QtPrivate::CompareUnderlyingType>(QtPrivate::Ordering::Equal);
0513         else if (stdorder == std::strong_ordering::greater)
0514             m_order = static_cast<QtPrivate::CompareUnderlyingType>(QtPrivate::Ordering::Greater);
0515     }
0516 
0517     constexpr Q_IMPLICIT operator std::strong_ordering() const noexcept
0518     {
0519         static_assert(sizeof(*this) == sizeof(std::strong_ordering));
0520 #ifdef __cpp_lib_bit_cast
0521         return std::bit_cast<std::strong_ordering>(*this);
0522 #else
0523         using O = QtPrivate::Ordering;
0524         using R = std::strong_ordering;
0525         switch (m_order) {
0526         case qToUnderlying(O::Less):    return R::less;
0527         case qToUnderlying(O::Greater): return R::greater;
0528         case qToUnderlying(O::Equal):   return R::equal;
0529         }
0530         Q_UNREACHABLE_RETURN(R::equal);
0531 #endif // __cpp_lib_bit_cast
0532     }
0533 
0534     friend constexpr bool operator==(strong_ordering lhs, std::strong_ordering rhs) noexcept
0535     { return static_cast<std::strong_ordering>(lhs) == rhs; }
0536 
0537     friend constexpr bool operator!=(strong_ordering lhs, std::strong_ordering rhs) noexcept
0538     { return static_cast<std::strong_ordering>(lhs) != rhs; }
0539 
0540     friend constexpr bool operator==(strong_ordering lhs, std::partial_ordering rhs) noexcept
0541     { return static_cast<std::strong_ordering>(lhs) == rhs; }
0542 
0543     friend constexpr bool operator!=(strong_ordering lhs, std::partial_ordering rhs) noexcept
0544     { return static_cast<std::strong_ordering>(lhs) != rhs; }
0545 
0546     friend constexpr bool operator==(strong_ordering lhs, std::weak_ordering rhs) noexcept
0547     { return static_cast<std::strong_ordering>(lhs) == rhs; }
0548 
0549     friend constexpr bool operator!=(strong_ordering lhs, std::weak_ordering rhs) noexcept
0550     { return static_cast<std::strong_ordering>(lhs) != rhs; }
0551 
0552     friend constexpr bool operator==(std::strong_ordering lhs, strong_ordering rhs) noexcept
0553     { return lhs == static_cast<std::strong_ordering>(rhs); }
0554 
0555     friend constexpr bool operator!=(std::strong_ordering lhs, strong_ordering rhs) noexcept
0556     { return lhs != static_cast<std::strong_ordering>(rhs); }
0557 
0558     friend constexpr bool operator==(std::partial_ordering lhs, strong_ordering rhs) noexcept
0559     { return lhs == static_cast<std::strong_ordering>(rhs); }
0560 
0561     friend constexpr bool operator!=(std::partial_ordering lhs, strong_ordering rhs) noexcept
0562     { return lhs != static_cast<std::strong_ordering>(rhs); }
0563 
0564     friend constexpr bool operator==(std::weak_ordering lhs, strong_ordering rhs) noexcept
0565     { return lhs == static_cast<std::strong_ordering>(rhs); }
0566 
0567     friend constexpr bool operator!=(std::weak_ordering lhs, strong_ordering rhs) noexcept
0568     { return lhs != static_cast<std::strong_ordering>(rhs); }
0569 #endif // __cpp_lib_three_way_comparison
0570 
0571     private:
0572     constexpr explicit strong_ordering(QtPrivate::Ordering order) noexcept
0573         : m_order(static_cast<QtPrivate::CompareUnderlyingType>(order))
0574     {}
0575 
0576     QT_WARNING_PUSH
0577     // https://gcc.gnu.org/bugzilla/show_bug.cgi?id=100903
0578     QT_WARNING_DISABLE_GCC("-Wzero-as-null-pointer-constant")
0579     friend constexpr bool is_eq  (strong_ordering o) noexcept { return o == 0; }
0580     friend constexpr bool is_neq (strong_ordering o) noexcept { return o != 0; }
0581     friend constexpr bool is_lt  (strong_ordering o) noexcept { return o <  0; }
0582     friend constexpr bool is_lteq(strong_ordering o) noexcept { return o <= 0; }
0583     friend constexpr bool is_gt  (strong_ordering o) noexcept { return o >  0; }
0584     friend constexpr bool is_gteq(strong_ordering o) noexcept { return o >= 0; }
0585     QT_WARNING_POP
0586 
0587     QtPrivate::CompareUnderlyingType m_order;
0588 };
0589 
0590 inline constexpr strong_ordering strong_ordering::less(QtPrivate::Ordering::Less);
0591 inline constexpr strong_ordering strong_ordering::equivalent(QtPrivate::Ordering::Equivalent);
0592 inline constexpr strong_ordering strong_ordering::equal(QtPrivate::Ordering::Equal);
0593 inline constexpr strong_ordering strong_ordering::greater(QtPrivate::Ordering::Greater);
0594 
0595 } // namespace Qt
0596 
0597 QT_BEGIN_INCLUDE_NAMESPACE
0598 
0599 // This is intentionally included after Qt::*_ordering types and before
0600 // qCompareThreeWay. Do not change!
0601 #include <QtCore/qcomparehelpers.h>
0602 
0603 QT_END_INCLUDE_NAMESPACE
0604 
0605 namespace QtPrivate {
0606 
0607 namespace CompareThreeWayTester {
0608 
0609     using Qt::compareThreeWay;
0610 
0611     // Check if compareThreeWay is implemented for the (LT, RT) argument
0612     // pair.
0613     template <typename LT, typename RT, typename = void>
0614     constexpr bool hasCompareThreeWay = false;
0615 
0616     template <typename LT, typename RT>
0617     constexpr bool hasCompareThreeWay<
0618             LT, RT, std::void_t<decltype(compareThreeWay(std::declval<LT>(), std::declval<RT>()))>
0619     > = true;
0620 
0621     // Check if the operation is noexcept. We have two different overloads,
0622     // depending on the available compareThreeWay() implementation.
0623     // Both are declared, but not implemented. To be used only in unevaluated
0624     // context.
0625 
0626     template <typename LT, typename RT,
0627              std::enable_if_t<hasCompareThreeWay<LT, RT>, bool> = true>
0628     constexpr bool compareThreeWayNoexcept() noexcept
0629     { return noexcept(compareThreeWay(std::declval<LT>(), std::declval<RT>())); }
0630 
0631     template <typename LT, typename RT,
0632              std::enable_if_t<!hasCompareThreeWay<LT, RT> && hasCompareThreeWay<RT, LT>,
0633                               bool> = true>
0634     constexpr bool compareThreeWayNoexcept() noexcept
0635     { return noexcept(compareThreeWay(std::declval<RT>(), std::declval<LT>())); }
0636 
0637 } // namespace CompareThreeWayTester
0638 
0639 } // namespace QtPrivate
0640 
0641 #if defined(Q_QDOC)
0642 
0643 template <typename LeftType, typename RightType>
0644 auto qCompareThreeWay(const LeftType &lhs, const RightType &rhs);
0645 
0646 #else
0647 
0648 template <typename LT, typename RT,
0649           std::enable_if_t<QtPrivate::CompareThreeWayTester::hasCompareThreeWay<LT, RT>
0650                             || QtPrivate::CompareThreeWayTester::hasCompareThreeWay<RT, LT>,
0651                            bool> = true>
0652 auto qCompareThreeWay(const LT &lhs, const RT &rhs)
0653         noexcept(QtPrivate::CompareThreeWayTester::compareThreeWayNoexcept<LT, RT>())
0654 {
0655     using Qt::compareThreeWay;
0656     if constexpr (QtPrivate::CompareThreeWayTester::hasCompareThreeWay<LT, RT>) {
0657         return compareThreeWay(lhs, rhs);
0658     } else {
0659         const auto retval = compareThreeWay(rhs, lhs);
0660         return QtOrderingPrivate::reversed(retval);
0661     }
0662 }
0663 
0664 #endif // defined(Q_QDOC)
0665 
0666 //
0667 // Legacy QPartialOrdering
0668 //
0669 
0670 namespace QtPrivate {
0671 enum class LegacyUncomparable : CompareUnderlyingType
0672 {
0673     Unordered = -127
0674 };
0675 }
0676 
0677 // [cmp.partialord]
0678 class QPartialOrdering
0679 {
0680 public:
0681     static const QPartialOrdering Less;
0682     static const QPartialOrdering Equivalent;
0683     static const QPartialOrdering Greater;
0684     static const QPartialOrdering Unordered;
0685 
0686     static const QPartialOrdering less;
0687     static const QPartialOrdering equivalent;
0688     static const QPartialOrdering greater;
0689     static const QPartialOrdering unordered;
0690 
0691     friend constexpr bool operator==(QPartialOrdering lhs,
0692                                      QtPrivate::CompareAgainstLiteralZero) noexcept
0693     { return lhs.isOrdered() && lhs.m_order == 0; }
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 
0716     friend constexpr bool operator==(QtPrivate::CompareAgainstLiteralZero,
0717                                      QPartialOrdering rhs) noexcept
0718     { return rhs.isOrdered() && 0 == rhs.m_order; }
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 
0741 #ifdef __cpp_lib_three_way_comparison
0742     friend constexpr std::partial_ordering
0743     operator<=>(QPartialOrdering lhs, QtPrivate::CompareAgainstLiteralZero) noexcept
0744     { return lhs; } // https://eel.is/c++draft/cmp.partialord#4
0745 
0746     friend constexpr std::partial_ordering
0747     operator<=>(QtPrivate::CompareAgainstLiteralZero, QPartialOrdering rhs) noexcept
0748     { return QtOrderingPrivate::reversed(rhs); }
0749 #endif // __cpp_lib_three_way_comparison
0750 
0751 
0752     friend constexpr bool operator==(QPartialOrdering lhs, QPartialOrdering rhs) noexcept
0753     { return lhs.m_order == rhs.m_order; }
0754 
0755     friend constexpr bool operator!=(QPartialOrdering lhs, QPartialOrdering rhs) noexcept
0756     { return lhs.m_order != rhs.m_order; }
0757 
0758     constexpr Q_IMPLICIT QPartialOrdering(Qt::partial_ordering order) noexcept
0759         : m_order{} // == equivalent
0760     {
0761         if (order == Qt::partial_ordering::less)
0762             m_order = static_cast<QtPrivate::CompareUnderlyingType>(QtPrivate::Ordering::Less);
0763         else if (order == Qt::partial_ordering::greater)
0764             m_order = static_cast<QtPrivate::CompareUnderlyingType>(QtPrivate::Ordering::Greater);
0765         else if (order == Qt::partial_ordering::unordered)
0766             m_order = static_cast<QtPrivate::CompareUnderlyingType>(QtPrivate::LegacyUncomparable::Unordered);
0767     }
0768 
0769     constexpr Q_IMPLICIT QPartialOrdering(Qt::weak_ordering stdorder) noexcept
0770         : QPartialOrdering(Qt::partial_ordering{stdorder}) {}
0771 
0772     constexpr Q_IMPLICIT QPartialOrdering(Qt::strong_ordering stdorder) noexcept
0773         : QPartialOrdering(Qt::partial_ordering{stdorder}) {}
0774 
0775     constexpr Q_IMPLICIT operator Qt::partial_ordering() const noexcept
0776     {
0777         using O = QtPrivate::Ordering;
0778         using U = QtPrivate::LegacyUncomparable;
0779         using R = Qt::partial_ordering;
0780         switch (m_order) {
0781         case qToUnderlying(O::Less):       return R::less;
0782         case qToUnderlying(O::Greater):    return R::greater;
0783         case qToUnderlying(O::Equivalent): return R::equivalent;
0784         case qToUnderlying(U::Unordered):  return R::unordered;
0785         }
0786         // GCC 8.x does not treat __builtin_unreachable() as constexpr
0787 #if !defined(Q_CC_GNU_ONLY) || (Q_CC_GNU >= 900)
0788         // NOLINTNEXTLINE(qt-use-unreachable-return): Triggers on Clang, breaking GCC 8
0789         Q_UNREACHABLE();
0790 #endif
0791         return R::unordered;
0792     }
0793 
0794     friend constexpr bool operator==(QPartialOrdering lhs, Qt::partial_ordering rhs) noexcept
0795     { Qt::partial_ordering qt = lhs; return qt == rhs; }
0796 
0797     friend constexpr bool operator!=(QPartialOrdering lhs, Qt::partial_ordering rhs) noexcept
0798     { Qt::partial_ordering qt = lhs; return qt != rhs; }
0799 
0800     friend constexpr bool operator==(Qt::partial_ordering lhs, QPartialOrdering rhs) noexcept
0801     { Qt::partial_ordering qt = rhs; return lhs == qt; }
0802 
0803     friend constexpr bool operator!=(Qt::partial_ordering lhs, QPartialOrdering rhs) noexcept
0804     { Qt::partial_ordering qt = rhs; return lhs != qt; }
0805 
0806 #ifdef __cpp_lib_three_way_comparison
0807     constexpr Q_IMPLICIT QPartialOrdering(std::partial_ordering stdorder) noexcept
0808     {
0809         if (stdorder == std::partial_ordering::less)
0810             m_order = static_cast<QtPrivate::CompareUnderlyingType>(QtPrivate::Ordering::Less);
0811         else if (stdorder == std::partial_ordering::equivalent)
0812             m_order = static_cast<QtPrivate::CompareUnderlyingType>(QtPrivate::Ordering::Equivalent);
0813         else if (stdorder == std::partial_ordering::greater)
0814             m_order = static_cast<QtPrivate::CompareUnderlyingType>(QtPrivate::Ordering::Greater);
0815         else if (stdorder == std::partial_ordering::unordered)
0816             m_order = static_cast<QtPrivate::CompareUnderlyingType>(QtPrivate::LegacyUncomparable::Unordered);
0817     }
0818 
0819     constexpr Q_IMPLICIT QPartialOrdering(std::weak_ordering stdorder) noexcept
0820         : QPartialOrdering(std::partial_ordering(stdorder)) {}
0821 
0822     constexpr Q_IMPLICIT QPartialOrdering(std::strong_ordering stdorder) noexcept
0823         : QPartialOrdering(std::partial_ordering(stdorder)) {}
0824 
0825     constexpr Q_IMPLICIT operator std::partial_ordering() const noexcept
0826     {
0827         using O = QtPrivate::Ordering;
0828         using U = QtPrivate::LegacyUncomparable;
0829         using R = std::partial_ordering;
0830         switch (m_order) {
0831         case qToUnderlying(O::Less):       return R::less;
0832         case qToUnderlying(O::Greater):    return R::greater;
0833         case qToUnderlying(O::Equivalent): return R::equivalent;
0834         case qToUnderlying(U::Unordered):  return R::unordered;
0835         }
0836         Q_UNREACHABLE_RETURN(R::unordered);
0837     }
0838 
0839     friend constexpr bool operator==(QPartialOrdering lhs, std::partial_ordering rhs) noexcept
0840     { return static_cast<std::partial_ordering>(lhs) == rhs; }
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==(std::partial_ordering lhs, QPartialOrdering rhs) noexcept
0846     { return lhs == static_cast<std::partial_ordering>(rhs); }
0847 
0848     friend constexpr bool operator!=(std::partial_ordering lhs, QPartialOrdering rhs) noexcept
0849     { return lhs != static_cast<std::partial_ordering>(rhs); }
0850 #endif // __cpp_lib_three_way_comparison
0851 
0852 private:
0853     constexpr explicit QPartialOrdering(QtPrivate::Ordering order) noexcept
0854         : m_order(static_cast<QtPrivate::CompareUnderlyingType>(order))
0855     {}
0856     constexpr explicit QPartialOrdering(QtPrivate::LegacyUncomparable order) noexcept
0857         : m_order(static_cast<QtPrivate::CompareUnderlyingType>(order))
0858     {}
0859 
0860     QT_WARNING_PUSH
0861     // https://gcc.gnu.org/bugzilla/show_bug.cgi?id=100903
0862     QT_WARNING_DISABLE_GCC("-Wzero-as-null-pointer-constant")
0863     friend constexpr bool is_eq  (QPartialOrdering o) noexcept { return o == 0; }
0864     friend constexpr bool is_neq (QPartialOrdering o) noexcept { return o != 0; }
0865     friend constexpr bool is_lt  (QPartialOrdering o) noexcept { return o <  0; }
0866     friend constexpr bool is_lteq(QPartialOrdering o) noexcept { return o <= 0; }
0867     friend constexpr bool is_gt  (QPartialOrdering o) noexcept { return o >  0; }
0868     friend constexpr bool is_gteq(QPartialOrdering o) noexcept { return o >= 0; }
0869     QT_WARNING_POP
0870 
0871     // instead of the exposition only is_ordered member in [cmp.partialord],
0872     // use a private function
0873     constexpr bool isOrdered() const noexcept
0874     { return m_order != static_cast<QtPrivate::CompareUnderlyingType>(QtPrivate::LegacyUncomparable::Unordered); }
0875 
0876     QtPrivate::CompareUnderlyingType m_order;
0877 };
0878 
0879 inline constexpr QPartialOrdering QPartialOrdering::Less(QtPrivate::Ordering::Less);
0880 inline constexpr QPartialOrdering QPartialOrdering::Equivalent(QtPrivate::Ordering::Equivalent);
0881 inline constexpr QPartialOrdering QPartialOrdering::Greater(QtPrivate::Ordering::Greater);
0882 inline constexpr QPartialOrdering QPartialOrdering::Unordered(QtPrivate::LegacyUncomparable::Unordered);
0883 
0884 inline constexpr QPartialOrdering QPartialOrdering::less(QtPrivate::Ordering::Less);
0885 inline constexpr QPartialOrdering QPartialOrdering::equivalent(QtPrivate::Ordering::Equivalent);
0886 inline constexpr QPartialOrdering QPartialOrdering::greater(QtPrivate::Ordering::Greater);
0887 inline constexpr QPartialOrdering QPartialOrdering::unordered(QtPrivate::LegacyUncomparable::Unordered);
0888 
0889 QT_END_NAMESPACE
0890 
0891 #endif // QCOMPARE_H