Convert a Qt ordering type to the weaker std ordering type

- Added missing conversion from Qt::strong_ordering to
std::weak_ordering, std::partial_ordering.
- Added missing conversion from Qt::weak_ordering to
std::partial_ordering.

Usage of Q_IMPLICIT specifier in new std::*_ordering conversion functions leads to following ambiguity errors on WIN + MSVC configuration:
C:/Users/qt/work/qt/qtbase/src/corelib/global/qcompare.h(334): error C2440:
'static_cast': cannot convert from 'Qt::weak_ordering' to 'Qt::partial_ordering'
qcompare.h(334): note: 'Qt::partial_ordering::partial_ordering': ambiguous call to overloaded function
qcompare.h(249): note: could be 'Qt::partial_ordering::partial_ordering(Qt::partial_ordering &&)'
qcompare.h(153): note: or 'Qt::partial_ordering::partial_ordering(std::partial_ordering) noexcept'
qcompare.h(334): note: while trying to match the argument list '(Qt::weak_ordering)'

For solving the problem we can exclude the conversion function from the argument list(make it explicit in case of MSVC).
Q_COMPARE_CAST_IMPLICIT is used for setting explicit or implicit specifier depending on the compiler type

[ChangeLog][QtCore][QtCompare] Added missing conversions
from Qt ordering types to std ordering types.

Fixes: QTBUG-127670
Pick-to: 6.7
Change-Id: I32a9a33fa8921c75b0e5a40bd413572f1bd6765a
Reviewed-by: Ivan Solovev <ivan.solovev@qt.io>
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
(cherry picked from commit 521e091bca1764d53ac06bb60707475d1032f5d5)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
This commit is contained in:
Tatiana Borisova 2024-08-05 19:01:34 +02:00 committed by Qt Cherry-pick Bot
parent fdd8924dce
commit eae3d0807a
2 changed files with 73 additions and 0 deletions

View File

@ -21,6 +21,12 @@
QT_BEGIN_NAMESPACE 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 { namespace QtPrivate {
using CompareUnderlyingType = qint8; using CompareUnderlyingType = qint8;
@ -361,6 +367,23 @@ public:
#endif // __cpp_lib_bit_cast #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<std::partial_ordering>(*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 friend constexpr bool operator==(weak_ordering lhs, std::weak_ordering rhs) noexcept
{ return static_cast<std::weak_ordering>(lhs) == rhs; } { return static_cast<std::weak_ordering>(lhs) == rhs; }
@ -558,6 +581,40 @@ public:
#endif // __cpp_lib_bit_cast #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<std::weak_ordering>(*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<std::partial_ordering>(*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 friend constexpr bool operator==(strong_ordering lhs, std::strong_ordering rhs) noexcept
{ return static_cast<std::strong_ordering>(lhs) == rhs; } { return static_cast<std::strong_ordering>(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::greater(QtPrivate::Ordering::Greater);
inline constexpr QPartialOrdering QPartialOrdering::unordered(QtPrivate::LegacyUncomparable::Unordered); inline constexpr QPartialOrdering QPartialOrdering::unordered(QtPrivate::LegacyUncomparable::Unordered);
#undef Q_COMPARE_CAST_IMPLICIT
QT_END_NAMESPACE QT_END_NAMESPACE
#endif // QCOMPARE_H #endif // QCOMPARE_H

View File

@ -693,6 +693,20 @@ void tst_QCompare::conversions()
static_assert(Qt::partial_ordering::less == std::weak_ordering::less); 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::equivalent);
static_assert(Qt::partial_ordering::equivalent != std::strong_ordering::less); 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 #endif