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.
|
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)
|
\fn template <typename LeftType, typename RightType> qCompareThreeWay(const LeftType &lhs, const RightType &rhs)
|
||||||
\since 6.7
|
\since 6.7
|
||||||
|
@ -451,6 +451,26 @@ constexpr bool IsFloatType_v<QtPrivate::NativeFloat16Type> = true;
|
|||||||
|
|
||||||
} // namespace QtPrivate
|
} // 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 {
|
namespace Qt {
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
@ -630,8 +650,6 @@ public:
|
|||||||
explicit constexpr operator bool() const noexcept { return get(); }
|
explicit constexpr operator bool() const noexcept { return get(); }
|
||||||
|
|
||||||
private:
|
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) \
|
#define MAKE_RELOP(Ret, op, Op) \
|
||||||
friend constexpr Ret operator op (const totally_ordered_wrapper &lhs, const totally_ordered_wrapper &rhs) noexcept \
|
friend constexpr Ret operator op (const totally_ordered_wrapper &lhs, const totally_ordered_wrapper &rhs) noexcept \
|
||||||
{ return std:: Op {}(lhs.ptr, rhs.ptr); } \
|
{ 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 \
|
friend constexpr Ret operator op (const P &lhs, const totally_ordered_wrapper &rhs) noexcept \
|
||||||
{ return std:: Op {}(lhs, rhs.ptr); } \
|
{ return std:: Op {}(lhs, rhs.ptr); } \
|
||||||
friend constexpr Ret operator op (const totally_ordered_wrapper &lhs, std::nullptr_t) noexcept \
|
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 \
|
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 */
|
/* end */
|
||||||
MAKE_RELOP(bool, ==, equal_to<P>)
|
MAKE_RELOP(bool, ==, equal_to<P>)
|
||||||
MAKE_RELOP(bool, !=, not_equal_to<P>)
|
MAKE_RELOP(bool, !=, not_equal_to<P>)
|
||||||
@ -662,6 +680,41 @@ private:
|
|||||||
{ return qHash(key.ptr, seed); }
|
{ 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
|
} //Qt
|
||||||
|
|
||||||
template <typename P>
|
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(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);
|
||||||
|
|
||||||
|
// 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
|
#undef TEST_BUILTIN
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user