Add Qt::compareThreeWay() overloads for Qt::totally_ordered_wrapper
Provide the overloads as free functions in Qt namespace instead of making them hidden friends of the Qt::totally_ordered_wrapper class, because they should replace the to-be-deprecated overloads of Qt::compareThreeWay() for raw pointers, so they should be easily discoverable. Also, we treat Qt::compareThreeWay() as a C++17 equivalent of operator<=>(), so we need to have an overload for pointers (even if it takes only the wrapped pointers). Found in API Review. [ChangeLog][QtCore][QtCompare] Added Qt::compareThreeWay() overloads for Qt::totally_ordered_wrapper. These overloads do the comparison using strict total ordering. Change-Id: I2b5bc542c546330ca78c6284188c8167136a849e Reviewed-by: Marc Mutz <marc.mutz@qt.io> (cherry picked from commit d6e1df3513c7d5b6e93d68583fc4c1febb7bcd85) Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
This commit is contained in:
parent
8e61693bea
commit
e24f931b9f
@ -1308,6 +1308,77 @@ CHECK(strong, equivalent);
|
||||
between \a lhs and \a rhs.
|
||||
*/
|
||||
|
||||
/*!
|
||||
\fn template <typename T> Qt::compareThreeWay(Qt::totally_ordered_wrapper<T*> lhs, Qt::totally_ordered_wrapper<T*> rhs)
|
||||
\since 6.8
|
||||
\relates <QtCompare>
|
||||
\overload
|
||||
|
||||
Implements three-way comparison of pointers that are wrapped into
|
||||
\l Qt::totally_ordered_wrapper. Uses
|
||||
\l {https://en.cppreference.com/w/cpp/language/operator_comparison#Pointer_total_order}
|
||||
{strict total order over pointers} when doing the comparison.
|
||||
|
||||
Returns an instance of \l Qt::strong_ordering that represents the relation
|
||||
between \a lhs and \a rhs.
|
||||
*/
|
||||
|
||||
/*!
|
||||
\fn template <typename T> Qt::compareThreeWay(Qt::totally_ordered_wrapper<T*> lhs, T *rhs)
|
||||
\since 6.8
|
||||
\relates <QtCompare>
|
||||
\overload
|
||||
|
||||
Implements three-way comparison of a pointer wrapped into
|
||||
\l Qt::totally_ordered_wrapper with a normal pointer. Uses
|
||||
\l {https://en.cppreference.com/w/cpp/language/operator_comparison#Pointer_total_order}
|
||||
{strict total order over pointers} when doing the comparison.
|
||||
|
||||
Returns an instance of \l Qt::strong_ordering that represents the relation
|
||||
between \a lhs and \a rhs.
|
||||
*/
|
||||
|
||||
/*!
|
||||
\fn template <typename T> Qt::compareThreeWay(T *lhs, Qt::totally_ordered_wrapper<T*> rhs)
|
||||
\since 6.8
|
||||
\relates <QtCompare>
|
||||
\overload
|
||||
|
||||
Implements three-way comparison of a normal pointer with a pointer wrapped
|
||||
into \l Qt::totally_ordered_wrapper. Uses
|
||||
\l {https://en.cppreference.com/w/cpp/language/operator_comparison#Pointer_total_order}
|
||||
{strict total order over pointers} when doing the comparison.
|
||||
|
||||
Returns an instance of \l Qt::strong_ordering that represents the relation
|
||||
between \a lhs and \a rhs.
|
||||
*/
|
||||
|
||||
/*!
|
||||
\fn template <typename T> Qt::compareThreeWay(Qt::totally_ordered_wrapper<T*> lhs, std::nullptr_t rhs)
|
||||
\since 6.8
|
||||
\relates <QtCompare>
|
||||
\overload
|
||||
|
||||
Implements three-way comparison of a pointer wrapped into
|
||||
\l Qt::totally_ordered_wrapper with \c {std::nullptr_t}.
|
||||
|
||||
Returns an instance of \l Qt::strong_ordering that represents the relation
|
||||
between \a lhs and \a rhs.
|
||||
*/
|
||||
|
||||
/*!
|
||||
\fn template <typename T> Qt::compareThreeWay(std::nullptr_t lhs, Qt::totally_ordered_wrapper<T*> rhs)
|
||||
\since 6.8
|
||||
\relates <QtCompare>
|
||||
\overload
|
||||
|
||||
Implements three-way comparison of \c {std::nullptr_t} with a pointer
|
||||
wrapped into \l Qt::totally_ordered_wrapper.
|
||||
|
||||
Returns an instance of \l Qt::strong_ordering that represents the relation
|
||||
between \a lhs and \a rhs.
|
||||
*/
|
||||
|
||||
/*!
|
||||
\fn template <typename LeftType, typename RightType> qCompareThreeWay(const LeftType &lhs, const RightType &rhs)
|
||||
\since 6.7
|
||||
|
@ -451,6 +451,26 @@ constexpr bool IsFloatType_v<QtPrivate::NativeFloat16Type> = true;
|
||||
|
||||
} // namespace QtPrivate
|
||||
|
||||
namespace QtOrderingPrivate {
|
||||
|
||||
template <typename T, typename U>
|
||||
constexpr Qt::strong_ordering
|
||||
strongOrderingCompareDefaultImpl(T lhs, U rhs) noexcept
|
||||
{
|
||||
#ifdef __cpp_lib_three_way_comparison
|
||||
return lhs <=> rhs;
|
||||
#else
|
||||
if (lhs == rhs)
|
||||
return Qt::strong_ordering::equivalent;
|
||||
else if (lhs < rhs)
|
||||
return Qt::strong_ordering::less;
|
||||
else
|
||||
return Qt::strong_ordering::greater;
|
||||
#endif // __cpp_lib_three_way_comparison
|
||||
}
|
||||
|
||||
} // namespace QtOrderingPrivate
|
||||
|
||||
namespace Qt {
|
||||
|
||||
template <typename T>
|
||||
@ -630,8 +650,6 @@ public:
|
||||
explicit constexpr operator bool() const noexcept { return get(); }
|
||||
|
||||
private:
|
||||
friend constexpr auto compareThreeWay(const totally_ordered_wrapper &lhs, const totally_ordered_wrapper &rhs) noexcept
|
||||
{ return Qt::compareThreeWay(lhs.ptr, rhs.ptr); }
|
||||
#define MAKE_RELOP(Ret, op, Op) \
|
||||
friend constexpr Ret operator op (const totally_ordered_wrapper &lhs, const totally_ordered_wrapper &rhs) noexcept \
|
||||
{ return std:: Op {}(lhs.ptr, rhs.ptr); } \
|
||||
@ -640,9 +658,9 @@ private:
|
||||
friend constexpr Ret operator op (const P &lhs, const totally_ordered_wrapper &rhs) noexcept \
|
||||
{ return std:: Op {}(lhs, rhs.ptr); } \
|
||||
friend constexpr Ret operator op (const totally_ordered_wrapper &lhs, std::nullptr_t) noexcept \
|
||||
{ return std:: Op {}(lhs.ptr, nullptr); } \
|
||||
{ return std:: Op {}(lhs.ptr, P(nullptr)); } \
|
||||
friend constexpr Ret operator op (std::nullptr_t, const totally_ordered_wrapper &rhs) noexcept \
|
||||
{ return std:: Op {}(nullptr, rhs.ptr); } \
|
||||
{ return std:: Op {}(P(nullptr), rhs.ptr); } \
|
||||
/* end */
|
||||
MAKE_RELOP(bool, ==, equal_to<P>)
|
||||
MAKE_RELOP(bool, !=, not_equal_to<P>)
|
||||
@ -662,6 +680,41 @@ private:
|
||||
{ return qHash(key.ptr, seed); }
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
constexpr Qt::strong_ordering
|
||||
compareThreeWay(Qt::totally_ordered_wrapper<T*> lhs, Qt::totally_ordered_wrapper<T*> rhs) noexcept
|
||||
{
|
||||
return QtOrderingPrivate::strongOrderingCompareDefaultImpl(lhs, rhs);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
constexpr Qt::strong_ordering
|
||||
compareThreeWay(Qt::totally_ordered_wrapper<T*> lhs, T *rhs) noexcept
|
||||
{
|
||||
return QtOrderingPrivate::strongOrderingCompareDefaultImpl(lhs, rhs);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
constexpr Qt::strong_ordering
|
||||
compareThreeWay(T *lhs, Qt::totally_ordered_wrapper<T*> rhs) noexcept
|
||||
{
|
||||
return QtOrderingPrivate::strongOrderingCompareDefaultImpl(lhs, rhs);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
constexpr Qt::strong_ordering
|
||||
compareThreeWay(Qt::totally_ordered_wrapper<T*> lhs, std::nullptr_t rhs) noexcept
|
||||
{
|
||||
return QtOrderingPrivate::strongOrderingCompareDefaultImpl(lhs, rhs);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
constexpr Qt::strong_ordering
|
||||
compareThreeWay(std::nullptr_t lhs, Qt::totally_ordered_wrapper<T*> rhs) noexcept
|
||||
{
|
||||
return QtOrderingPrivate::strongOrderingCompareDefaultImpl(lhs, rhs);
|
||||
}
|
||||
|
||||
} //Qt
|
||||
|
||||
template <typename P>
|
||||
|
@ -593,6 +593,18 @@ void tst_QCompareHelpers::builtinOrder()
|
||||
QCOMPARE_EQ(Qt::compareThreeWay(b.get(), nullptr), Qt::strong_ordering::greater);
|
||||
QCOMPARE_EQ(Qt::compareThreeWay(nullptr, d.get()), Qt::strong_ordering::less);
|
||||
|
||||
// Check Qt::totally_ordered_wrapper
|
||||
auto a0 = Qt::totally_ordered_wrapper(&arr[0]);
|
||||
auto a1 = Qt::totally_ordered_wrapper(&arr[1]);
|
||||
QCOMPARE_EQ(Qt::compareThreeWay(a0, a1), Qt::strong_ordering::less);
|
||||
QCOMPARE_EQ(Qt::compareThreeWay(arr.data(), a0), Qt::strong_ordering::equivalent);
|
||||
|
||||
auto bWrapper = Qt::totally_ordered_wrapper(b.get());
|
||||
auto dWrapper = Qt::totally_ordered_wrapper<Base*>(d.get());
|
||||
QCOMPARE_NE(Qt::compareThreeWay(bWrapper, dWrapper), Qt::strong_ordering::equivalent);
|
||||
QCOMPARE_EQ(Qt::compareThreeWay(bWrapper, nullptr), Qt::strong_ordering::greater);
|
||||
QCOMPARE_EQ(Qt::compareThreeWay(nullptr, dWrapper), Qt::strong_ordering::less);
|
||||
|
||||
#undef TEST_BUILTIN
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user