diff --git a/src/corelib/global/qcompare.cpp b/src/corelib/global/qcompare.cpp index 81abf01984f..d32f4ca251f 100644 --- a/src/corelib/global/qcompare.cpp +++ b/src/corelib/global/qcompare.cpp @@ -1308,6 +1308,77 @@ CHECK(strong, equivalent); between \a lhs and \a rhs. */ +/*! + \fn template Qt::compareThreeWay(Qt::totally_ordered_wrapper lhs, Qt::totally_ordered_wrapper rhs) + \since 6.8 + \relates + \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 Qt::compareThreeWay(Qt::totally_ordered_wrapper lhs, T *rhs) + \since 6.8 + \relates + \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 Qt::compareThreeWay(T *lhs, Qt::totally_ordered_wrapper rhs) + \since 6.8 + \relates + \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 Qt::compareThreeWay(Qt::totally_ordered_wrapper lhs, std::nullptr_t rhs) + \since 6.8 + \relates + \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 Qt::compareThreeWay(std::nullptr_t lhs, Qt::totally_ordered_wrapper rhs) + \since 6.8 + \relates + \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 qCompareThreeWay(const LeftType &lhs, const RightType &rhs) \since 6.7 diff --git a/src/corelib/global/qcomparehelpers.h b/src/corelib/global/qcomparehelpers.h index 9a0f0f83a44..cfdd395d6d5 100644 --- a/src/corelib/global/qcomparehelpers.h +++ b/src/corelib/global/qcomparehelpers.h @@ -451,6 +451,26 @@ constexpr bool IsFloatType_v = true; } // namespace QtPrivate +namespace QtOrderingPrivate { + +template +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 @@ -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

) MAKE_RELOP(bool, !=, not_equal_to

) @@ -662,6 +680,41 @@ private: { return qHash(key.ptr, seed); } }; +template +constexpr Qt::strong_ordering +compareThreeWay(Qt::totally_ordered_wrapper lhs, Qt::totally_ordered_wrapper rhs) noexcept +{ + return QtOrderingPrivate::strongOrderingCompareDefaultImpl(lhs, rhs); +} + +template +constexpr Qt::strong_ordering +compareThreeWay(Qt::totally_ordered_wrapper lhs, T *rhs) noexcept +{ + return QtOrderingPrivate::strongOrderingCompareDefaultImpl(lhs, rhs); +} + +template +constexpr Qt::strong_ordering +compareThreeWay(T *lhs, Qt::totally_ordered_wrapper rhs) noexcept +{ + return QtOrderingPrivate::strongOrderingCompareDefaultImpl(lhs, rhs); +} + +template +constexpr Qt::strong_ordering +compareThreeWay(Qt::totally_ordered_wrapper lhs, std::nullptr_t rhs) noexcept +{ + return QtOrderingPrivate::strongOrderingCompareDefaultImpl(lhs, rhs); +} + +template +constexpr Qt::strong_ordering +compareThreeWay(std::nullptr_t lhs, Qt::totally_ordered_wrapper rhs) noexcept +{ + return QtOrderingPrivate::strongOrderingCompareDefaultImpl(lhs, rhs); +} + } //Qt template diff --git a/tests/auto/corelib/global/qcomparehelpers/tst_qcomparehelpers.cpp b/tests/auto/corelib/global/qcomparehelpers/tst_qcomparehelpers.cpp index cb114bc90b5..c570151cb65 100644 --- a/tests/auto/corelib/global/qcomparehelpers/tst_qcomparehelpers.cpp +++ b/tests/auto/corelib/global/qcomparehelpers/tst_qcomparehelpers.cpp @@ -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(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 }