diff --git a/src/corelib/global/qcompare.h b/src/corelib/global/qcompare.h index fd9fb84c6b9..ba6b5afcd0e 100644 --- a/src/corelib/global/qcompare.h +++ b/src/corelib/global/qcompare.h @@ -21,6 +21,12 @@ QT_BEGIN_NAMESPACE +#if defined(Q_CC_MSVC) +#define Q_COMPARE_CAST_IMPLICIT explicit +#else +#define Q_COMPARE_CAST_IMPLICIT Q_IMPLICIT +#endif // Q_CC_MSVC + namespace QtPrivate { using CompareUnderlyingType = qint8; @@ -361,6 +367,23 @@ public: #endif // __cpp_lib_bit_cast } + constexpr Q_COMPARE_CAST_IMPLICIT operator std::partial_ordering() const noexcept + { + static_assert(sizeof(*this) == sizeof(std::partial_ordering)); +#ifdef __cpp_lib_bit_cast + return std::bit_cast(*this); +#else + using O = QtPrivate::Ordering; + using R = std::partial_ordering; + switch (m_order) { + case qToUnderlying(O::Less): return R::less; + case qToUnderlying(O::Greater): return R::greater; + case qToUnderlying(O::Equivalent): return R::equivalent; + } + Q_UNREACHABLE_RETURN(R::unordered); +#endif // __cpp_lib_bit_cast + } + friend constexpr bool operator==(weak_ordering lhs, std::weak_ordering rhs) noexcept { return static_cast(lhs) == rhs; } @@ -558,6 +581,40 @@ public: #endif // __cpp_lib_bit_cast } + constexpr Q_COMPARE_CAST_IMPLICIT operator std::weak_ordering() const noexcept + { + static_assert(sizeof(*this) == sizeof(std::weak_ordering)); +#ifdef __cpp_lib_bit_cast + return std::bit_cast(*this); +#else + using O = QtPrivate::Ordering; + using R = std::weak_ordering; + switch (m_order) { + case qToUnderlying(O::Less): return R::less; + case qToUnderlying(O::Greater): return R::greater; + case qToUnderlying(O::Equal): return R::equivalent; + } + Q_UNREACHABLE_RETURN(R::equivalent); +#endif // __cpp_lib_bit_cast + } + + constexpr Q_COMPARE_CAST_IMPLICIT operator std::partial_ordering() const noexcept + { + static_assert(sizeof(*this) == sizeof(std::partial_ordering)); +#ifdef __cpp_lib_bit_cast + return std::bit_cast(*this); +#else + using O = QtPrivate::Ordering; + using R = std::partial_ordering; + switch (m_order) { + case qToUnderlying(O::Less): return R::less; + case qToUnderlying(O::Greater): return R::greater; + case qToUnderlying(O::Equal): return R::equivalent; + } + Q_UNREACHABLE_RETURN(R::unordered); +#endif // __cpp_lib_bit_cast + } + friend constexpr bool operator==(strong_ordering lhs, std::strong_ordering rhs) noexcept { return static_cast(lhs) == rhs; } @@ -913,6 +970,8 @@ inline constexpr QPartialOrdering QPartialOrdering::equivalent(QtPrivate::Orderi inline constexpr QPartialOrdering QPartialOrdering::greater(QtPrivate::Ordering::Greater); inline constexpr QPartialOrdering QPartialOrdering::unordered(QtPrivate::LegacyUncomparable::Unordered); +#undef Q_COMPARE_CAST_IMPLICIT + QT_END_NAMESPACE #endif // QCOMPARE_H diff --git a/tests/auto/corelib/global/qcompare/tst_qcompare.cpp b/tests/auto/corelib/global/qcompare/tst_qcompare.cpp index 8d764ad5257..30edd5f7345 100644 --- a/tests/auto/corelib/global/qcompare/tst_qcompare.cpp +++ b/tests/auto/corelib/global/qcompare/tst_qcompare.cpp @@ -693,6 +693,20 @@ void tst_QCompare::conversions() static_assert(Qt::partial_ordering::less == std::weak_ordering::less); static_assert(Qt::partial_ordering::equivalent == std::strong_ordering::equivalent); static_assert(Qt::partial_ordering::equivalent != std::strong_ordering::less); + + // convert Qt::strong to std::partial + constexpr Qt::strong_ordering qtS = Qt::strong_ordering::less; + constexpr std::partial_ordering stdP1 = qtS; + static_assert(stdP1 == qtS); + + // convert Qt::strong to std::weak + constexpr std::weak_ordering stdW = qtS; + static_assert(stdW == qtS); + + // convert Qt::weak to std::partial + constexpr Qt::weak_ordering qtW = Qt::weak_ordering::greater; + constexpr std::partial_ordering stdP2 = qtW; + static_assert(stdP2 == qtW); } #endif