Deprecate Qt::compareThreeWay() overload for pointers
compareThreeWay() was supposed to be an operator<=>(), but for C++17. The idea was that at some point when we unconditionally demand C++20, people could just replace all the usages of compareThreeWay() with operator<=>(). However, the Qt::compareThreeWay() overload for pointers is different from the operator<=>() for pointers, because it is actually using std::less{} or std::compare_three_way{} to do the comparison, thus avoiding an UB. This is not bad as such, but can potentially lead to UB when mass-replacing all compareThreeWay() calls with operator<=>(). To avoid this problem, deprecate the overload, and suggest to use the Qt::totally_ordered_wrapper together with the respective overload instead. Found in API Review. [ChangeLog][QtCore][QtCompare] Deprecate Qt::compareThreeWay() overload for pointers. Change-Id: I9c57871145dc3cb9656d6006db88b48a1553bef4 Reviewed-by: Marc Mutz <marc.mutz@qt.io> (cherry picked from commit b1ae4334ea11f6942c7ce37a80a3aa98a3447809) Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
This commit is contained in:
parent
e24f931b9f
commit
e37c0a33a4
@ -1274,9 +1274,12 @@ CHECK(strong, equivalent);
|
|||||||
\l Qt::partial_ordering::unordered is returned.
|
\l Qt::partial_ordering::unordered is returned.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#if QT_DEPRECATED_SINCE(6, 8)
|
||||||
/*!
|
/*!
|
||||||
\fn template <typename LeftType, typename RightType, Qt::if_compatible_pointers<LeftType, RightType> = true> Qt::compareThreeWay(const LeftType *lhs, const RightType *rhs)
|
\fn template <typename LeftType, typename RightType, Qt::if_compatible_pointers<LeftType, RightType> = true> Qt::compareThreeWay(const LeftType *lhs, const RightType *rhs)
|
||||||
\since 6.7
|
\since 6.7
|
||||||
|
\deprecated [6.8] Wrap the pointers into Qt::totally_ordered_wrapper and
|
||||||
|
use the respective Qt::compareThreeWay() overload instead.
|
||||||
\relates <QtCompare>
|
\relates <QtCompare>
|
||||||
\overload
|
\overload
|
||||||
|
|
||||||
@ -1289,6 +1292,7 @@ CHECK(strong, equivalent);
|
|||||||
Returns an instance of \l Qt::strong_ordering that represents the relation
|
Returns an instance of \l Qt::strong_ordering that represents the relation
|
||||||
between \a lhs and \a rhs.
|
between \a lhs and \a rhs.
|
||||||
*/
|
*/
|
||||||
|
#endif // QT_DEPRECATED_SINCE(6, 8)
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
\fn template <class Enum, Qt::if_enum<Enum> = true> Qt::compareThreeWay(Enum lhs, Enum rhs)
|
\fn template <class Enum, Qt::if_enum<Enum> = true> Qt::compareThreeWay(Enum lhs, Enum rhs)
|
||||||
|
@ -547,8 +547,11 @@ constexpr Qt::partial_ordering compareThreeWay(FloatType lhs, IntType rhs) noexc
|
|||||||
return compareThreeWay(lhs, FloatType(rhs));
|
return compareThreeWay(lhs, FloatType(rhs));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if QT_DEPRECATED_SINCE(6, 8)
|
||||||
|
|
||||||
template <typename LeftType, typename RightType,
|
template <typename LeftType, typename RightType,
|
||||||
if_compatible_pointers<LeftType, RightType> = true>
|
if_compatible_pointers<LeftType, RightType> = true>
|
||||||
|
QT_DEPRECATED_VERSION_X_6_8("Wrap the pointers into Qt::totally_ordered_wrapper and use the respective overload instead.")
|
||||||
constexpr Qt::strong_ordering compareThreeWay(const LeftType *lhs, const RightType *rhs) noexcept
|
constexpr Qt::strong_ordering compareThreeWay(const LeftType *lhs, const RightType *rhs) noexcept
|
||||||
{
|
{
|
||||||
#ifdef __cpp_lib_three_way_comparison
|
#ifdef __cpp_lib_three_way_comparison
|
||||||
@ -564,17 +567,21 @@ constexpr Qt::strong_ordering compareThreeWay(const LeftType *lhs, const RightTy
|
|||||||
}
|
}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
|
QT_DEPRECATED_VERSION_X_6_8("Wrap the pointer into Qt::totally_ordered_wrapper and use the respective overload instead.")
|
||||||
constexpr Qt::strong_ordering compareThreeWay(const T *lhs, std::nullptr_t rhs) noexcept
|
constexpr Qt::strong_ordering compareThreeWay(const T *lhs, std::nullptr_t rhs) noexcept
|
||||||
{
|
{
|
||||||
return compareThreeWay(lhs, static_cast<const T *>(rhs));
|
return compareThreeWay(lhs, static_cast<const T *>(rhs));
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
|
QT_DEPRECATED_VERSION_X_6_8("Wrap the pointer into Qt::totally_ordered_wrapper and use the respective overload instead.")
|
||||||
constexpr Qt::strong_ordering compareThreeWay(std::nullptr_t lhs, const T *rhs) noexcept
|
constexpr Qt::strong_ordering compareThreeWay(std::nullptr_t lhs, const T *rhs) noexcept
|
||||||
{
|
{
|
||||||
return compareThreeWay(static_cast<const T *>(lhs), rhs);
|
return compareThreeWay(static_cast<const T *>(lhs), rhs);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#endif // QT_DEPRECATED_SINCE(6, 8)
|
||||||
|
|
||||||
template <class Enum, if_enum<Enum> = true>
|
template <class Enum, if_enum<Enum> = true>
|
||||||
constexpr Qt::strong_ordering compareThreeWay(Enum lhs, Enum rhs) noexcept
|
constexpr Qt::strong_ordering compareThreeWay(Enum lhs, Enum rhs) noexcept
|
||||||
{
|
{
|
||||||
|
@ -785,9 +785,10 @@ void tst_QCompare::compareThreeWay()
|
|||||||
static_assert(noexcept(qCompareThreeWay(std::declval<TestEnum>(), std::declval<TestEnum>())));
|
static_assert(noexcept(qCompareThreeWay(std::declval<TestEnum>(), std::declval<TestEnum>())));
|
||||||
|
|
||||||
// pointers
|
// pointers
|
||||||
static_assert(noexcept(qCompareThreeWay(std::declval<StringWrapper *>(),
|
using StringWrapperPtr = Qt::totally_ordered_wrapper<StringWrapper *>;
|
||||||
std::declval<StringWrapper *>())));
|
static_assert(noexcept(qCompareThreeWay(std::declval<StringWrapperPtr>(),
|
||||||
static_assert(noexcept(qCompareThreeWay(std::declval<StringWrapper *>(), nullptr)));
|
std::declval<StringWrapperPtr>())));
|
||||||
|
static_assert(noexcept(qCompareThreeWay(std::declval<StringWrapperPtr>(), nullptr)));
|
||||||
|
|
||||||
// Test some actual comparison results
|
// Test some actual comparison results
|
||||||
|
|
||||||
@ -832,8 +833,17 @@ void tst_QCompare::compareThreeWay()
|
|||||||
|
|
||||||
// pointers
|
// pointers
|
||||||
std::array<int, 2> arr{1, 0};
|
std::array<int, 2> arr{1, 0};
|
||||||
|
#if QT_DEPRECATED_SINCE(6, 8)
|
||||||
|
QT_WARNING_PUSH
|
||||||
|
QT_WARNING_DISABLE_DEPRECATED
|
||||||
QCOMPARE_EQ(qCompareThreeWay(&arr[1], &arr[0]), Qt::strong_ordering::greater);
|
QCOMPARE_EQ(qCompareThreeWay(&arr[1], &arr[0]), Qt::strong_ordering::greater);
|
||||||
QCOMPARE_EQ(qCompareThreeWay(arr.data(), &arr[0]), Qt::strong_ordering::equivalent);
|
QCOMPARE_EQ(qCompareThreeWay(arr.data(), &arr[0]), Qt::strong_ordering::equivalent);
|
||||||
|
QT_WARNING_POP
|
||||||
|
#endif // QT_DEPRECATED_SINCE(6, 8)
|
||||||
|
const auto a0 = Qt::totally_ordered_wrapper(&arr[0]);
|
||||||
|
const auto a1 = Qt::totally_ordered_wrapper(&arr[1]);
|
||||||
|
QCOMPARE_EQ(qCompareThreeWay(a1, a0), Qt::strong_ordering::greater);
|
||||||
|
QCOMPARE_EQ(qCompareThreeWay(arr.data(), a0), Qt::strong_ordering::equivalent);
|
||||||
}
|
}
|
||||||
|
|
||||||
QTEST_MAIN(tst_QCompare)
|
QTEST_MAIN(tst_QCompare)
|
||||||
|
@ -581,17 +581,27 @@ void tst_QCompareHelpers::builtinOrder()
|
|||||||
Qt::strong_ordering::equivalent);
|
Qt::strong_ordering::equivalent);
|
||||||
|
|
||||||
std::array<int, 2> arr{1, 0};
|
std::array<int, 2> arr{1, 0};
|
||||||
|
#if QT_DEPRECATED_SINCE(6, 8)
|
||||||
|
QT_WARNING_PUSH
|
||||||
|
QT_WARNING_DISABLE_DEPRECATED
|
||||||
QCOMPARE_EQ(Qt::compareThreeWay(&arr[0], &arr[1]), Qt::strong_ordering::less);
|
QCOMPARE_EQ(Qt::compareThreeWay(&arr[0], &arr[1]), Qt::strong_ordering::less);
|
||||||
QCOMPARE_EQ(Qt::compareThreeWay(arr.data(), &arr[0]), Qt::strong_ordering::equivalent);
|
QCOMPARE_EQ(Qt::compareThreeWay(arr.data(), &arr[0]), Qt::strong_ordering::equivalent);
|
||||||
|
QT_WARNING_POP
|
||||||
|
#endif // QT_DEPRECATED_SINCE(6, 8)
|
||||||
|
|
||||||
class Base {};
|
class Base {};
|
||||||
class Derived : public Base {};
|
class Derived : public Base {};
|
||||||
|
|
||||||
auto b = std::make_unique<Base>();
|
auto b = std::make_unique<Base>();
|
||||||
auto d = std::make_unique<Derived>();
|
auto d = std::make_unique<Derived>();
|
||||||
|
#if QT_DEPRECATED_SINCE(6, 8)
|
||||||
|
QT_WARNING_PUSH
|
||||||
|
QT_WARNING_DISABLE_DEPRECATED
|
||||||
QCOMPARE_NE(Qt::compareThreeWay(b.get(), d.get()), Qt::strong_ordering::equivalent);
|
QCOMPARE_NE(Qt::compareThreeWay(b.get(), d.get()), Qt::strong_ordering::equivalent);
|
||||||
QCOMPARE_EQ(Qt::compareThreeWay(b.get(), nullptr), Qt::strong_ordering::greater);
|
QCOMPARE_EQ(Qt::compareThreeWay(b.get(), nullptr), Qt::strong_ordering::greater);
|
||||||
QCOMPARE_EQ(Qt::compareThreeWay(nullptr, d.get()), Qt::strong_ordering::less);
|
QCOMPARE_EQ(Qt::compareThreeWay(nullptr, d.get()), Qt::strong_ordering::less);
|
||||||
|
QT_WARNING_POP
|
||||||
|
#endif // QT_DEPRECATED_SINCE(6, 8)
|
||||||
|
|
||||||
// Check Qt::totally_ordered_wrapper
|
// Check Qt::totally_ordered_wrapper
|
||||||
auto a0 = Qt::totally_ordered_wrapper(&arr[0]);
|
auto a0 = Qt::totally_ordered_wrapper(&arr[0]);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user