diff options
Diffstat (limited to 'tests/auto/corelib/global/qcomparehelpers/tst_qcomparehelpers.cpp')
-rw-r--r-- | tests/auto/corelib/global/qcomparehelpers/tst_qcomparehelpers.cpp | 270 |
1 files changed, 243 insertions, 27 deletions
diff --git a/tests/auto/corelib/global/qcomparehelpers/tst_qcomparehelpers.cpp b/tests/auto/corelib/global/qcomparehelpers/tst_qcomparehelpers.cpp index e3810f8605..995418780a 100644 --- a/tests/auto/corelib/global/qcomparehelpers/tst_qcomparehelpers.cpp +++ b/tests/auto/corelib/global/qcomparehelpers/tst_qcomparehelpers.cpp @@ -5,6 +5,10 @@ #include <QtTest/qtest.h> #include <QtTest/private/qcomparisontesthelper_p.h> +#if defined(__STDCPP_FLOAT16_T__) && __has_include(<stdfloat>) +#include <stdfloat> +#endif + class IntWrapper { public: @@ -21,13 +25,7 @@ private: friend Qt::strong_ordering compareThreeWay(const IntWrapper &lhs, const IntWrapper &rhs) noexcept { - // ### Qt::compareThreeWay - if (lhs.m_val < rhs.m_val) - return Qt::strong_ordering::less; - else if (lhs.m_val > rhs.m_val) - return Qt::strong_ordering::greater; - else - return Qt::strong_ordering::equal; + return Qt::compareThreeWay(lhs.m_val, rhs.m_val); } friend bool comparesEqual(const IntWrapper &lhs, int rhs) noexcept { return lhs.m_val == rhs; } @@ -52,16 +50,7 @@ private: friend Qt::partial_ordering compareThreeWay(const DoubleWrapper &lhs, const DoubleWrapper &rhs) noexcept { - // ### Qt::compareThreeWay - if (qIsNaN(lhs.m_val) || qIsNaN(rhs.m_val)) - return Qt::partial_ordering::unordered; - - if (lhs.m_val < rhs.m_val) - return Qt::partial_ordering::less; - else if (lhs.m_val > rhs.m_val) - return Qt::partial_ordering::greater; - else - return Qt::partial_ordering::equivalent; + return Qt::compareThreeWay(lhs.m_val, rhs.m_val); } friend bool comparesEqual(const DoubleWrapper &lhs, const IntWrapper &rhs) noexcept { return comparesEqual(lhs, DoubleWrapper(rhs.value())); } @@ -72,16 +61,7 @@ private: { return lhs.m_val == rhs; } friend Qt::partial_ordering compareThreeWay(const DoubleWrapper &lhs, double rhs) noexcept { - // ### Qt::compareThreeWay - if (qIsNaN(lhs.m_val) || qIsNaN(rhs)) - return Qt::partial_ordering::unordered; - - if (lhs.m_val < rhs) - return Qt::partial_ordering::less; - else if (lhs.m_val > rhs) - return Qt::partial_ordering::greater; - else - return Qt::partial_ordering::equivalent; + return Qt::compareThreeWay(lhs.m_val, rhs); } Q_DECLARE_PARTIALLY_ORDERED(DoubleWrapper) @@ -210,6 +190,8 @@ private slots: { compareImpl<StringWrapper<QString>, QAnyStringView, Qt::weak_ordering>(); } void generatedClasses(); + + void builtinOrder(); }; template<typename LeftType, typename RightType, typename OrderingType> @@ -487,5 +469,239 @@ void tst_QCompareHelpers::generatedClasses() QTestPrivate::testEqualityOperatorsCompile<DummyNone, int>(); } +template <typename LeftType, typename RightType, + Qt::if_integral<LeftType, RightType> = true> +void testOrderForTypes() +{ + LeftType l0{0}; + LeftType l1{1}; + RightType r0{0}; + RightType r1{1}; + QCOMPARE_EQ(Qt::compareThreeWay(l0, r1), Qt::strong_ordering::less); + QCOMPARE_EQ(Qt::compareThreeWay(l1, r0), Qt::strong_ordering::greater); + QCOMPARE_EQ(Qt::compareThreeWay(l1, r1), Qt::strong_ordering::equivalent); + // also swap types + QCOMPARE_EQ(Qt::compareThreeWay(r1, l0), Qt::strong_ordering::greater); + QCOMPARE_EQ(Qt::compareThreeWay(r0, l1), Qt::strong_ordering::less); + QCOMPARE_EQ(Qt::compareThreeWay(r1, l1), Qt::strong_ordering::equivalent); + +#ifdef __cpp_lib_three_way_comparison + QCOMPARE_EQ(Qt::compareThreeWay(l0, r1), std::strong_ordering::less); + QCOMPARE_EQ(Qt::compareThreeWay(l1, r0), std::strong_ordering::greater); + QCOMPARE_EQ(Qt::compareThreeWay(l1, r1), std::strong_ordering::equivalent); + + QCOMPARE_EQ(Qt::compareThreeWay(r1, l0), std::strong_ordering::greater); + QCOMPARE_EQ(Qt::compareThreeWay(r0, l1), std::strong_ordering::less); + QCOMPARE_EQ(Qt::compareThreeWay(r1, l1), std::strong_ordering::equivalent); +#endif // __cpp_lib_three_way_comparison + + if constexpr (std::is_signed_v<LeftType>) { + LeftType lm1{-1}; + QCOMPARE_EQ(Qt::compareThreeWay(lm1, r1), Qt::strong_ordering::less); + QCOMPARE_EQ(Qt::compareThreeWay(r1, lm1), Qt::strong_ordering::greater); +#ifdef __cpp_lib_three_way_comparison + QCOMPARE_EQ(Qt::compareThreeWay(lm1, r1), std::strong_ordering::less); + QCOMPARE_EQ(Qt::compareThreeWay(r1, lm1), std::strong_ordering::greater); +#endif // __cpp_lib_three_way_comparison + } + if constexpr (std::is_signed_v<RightType>) { + RightType rm1{-1}; + QCOMPARE_EQ(Qt::compareThreeWay(rm1, l1), Qt::strong_ordering::less); + QCOMPARE_EQ(Qt::compareThreeWay(l1, rm1), Qt::strong_ordering::greater); +#ifdef __cpp_lib_three_way_comparison + QCOMPARE_EQ(Qt::compareThreeWay(rm1, l1), std::strong_ordering::less); + QCOMPARE_EQ(Qt::compareThreeWay(l1, rm1), std::strong_ordering::greater); +#endif // __cpp_lib_three_way_comparison + } +} + +template <typename LeftType, typename RightType, + Qt::if_floating_point<LeftType, RightType> = true> +void testOrderForTypes() +{ + LeftType lNeg{-1.0}; + LeftType lPos{1.0}; + + RightType rNeg{-1.0}; + RightType rPos{1.0}; + + QCOMPARE_EQ(Qt::compareThreeWay(lNeg, rPos), Qt::partial_ordering::less); + QCOMPARE_EQ(Qt::compareThreeWay(lPos, rNeg), Qt::partial_ordering::greater); + QCOMPARE_EQ(Qt::compareThreeWay(rNeg, lPos), Qt::partial_ordering::less); + QCOMPARE_EQ(Qt::compareThreeWay(rPos, lNeg), Qt::partial_ordering::greater); + QCOMPARE_EQ(Qt::compareThreeWay(lNeg, rNeg), Qt::partial_ordering::equivalent); + QCOMPARE_EQ(Qt::compareThreeWay(rNeg, lNeg), Qt::partial_ordering::equivalent); + + LeftType lNaN{std::numeric_limits<LeftType>::quiet_NaN()}; + LeftType lInf{std::numeric_limits<LeftType>::infinity()}; + + RightType rNaN{std::numeric_limits<RightType>::quiet_NaN()}; + RightType rInf{std::numeric_limits<RightType>::infinity()}; + + QCOMPARE_EQ(Qt::compareThreeWay(lNaN, rPos), Qt::partial_ordering::unordered); + QCOMPARE_EQ(Qt::compareThreeWay(rNeg, lNaN), Qt::partial_ordering::unordered); + QCOMPARE_EQ(Qt::compareThreeWay(lNeg, rNaN), Qt::partial_ordering::unordered); + QCOMPARE_EQ(Qt::compareThreeWay(rNaN, lPos), Qt::partial_ordering::unordered); + QCOMPARE_EQ(Qt::compareThreeWay(rNaN, lNaN), Qt::partial_ordering::unordered); + QCOMPARE_EQ(Qt::compareThreeWay(lNaN, rNaN), Qt::partial_ordering::unordered); + QCOMPARE_EQ(Qt::compareThreeWay(lNaN, rInf), Qt::partial_ordering::unordered); + QCOMPARE_EQ(Qt::compareThreeWay(rNaN, -lInf), Qt::partial_ordering::unordered); + + QCOMPARE_EQ(Qt::compareThreeWay(lInf, rPos), Qt::partial_ordering::greater); + QCOMPARE_EQ(Qt::compareThreeWay(rPos, lInf), Qt::partial_ordering::less); + QCOMPARE_EQ(Qt::compareThreeWay(rInf, lNeg), Qt::partial_ordering::greater); + QCOMPARE_EQ(Qt::compareThreeWay(lNeg, rInf), Qt::partial_ordering::less); + QCOMPARE_EQ(Qt::compareThreeWay(lInf, -rInf), Qt::partial_ordering::greater); + QCOMPARE_EQ(Qt::compareThreeWay(-lInf, rInf), Qt::partial_ordering::less); + QCOMPARE_EQ(Qt::compareThreeWay(-rInf, lInf), Qt::partial_ordering::less); + QCOMPARE_EQ(Qt::compareThreeWay(rInf, -lInf), Qt::partial_ordering::greater); + +#ifdef __cpp_lib_three_way_comparison + QCOMPARE_EQ(Qt::compareThreeWay(lNeg, rPos), std::partial_ordering::less); + QCOMPARE_EQ(Qt::compareThreeWay(lPos, rNeg), std::partial_ordering::greater); + QCOMPARE_EQ(Qt::compareThreeWay(rNeg, lPos), std::partial_ordering::less); + QCOMPARE_EQ(Qt::compareThreeWay(rPos, lNeg), std::partial_ordering::greater); + QCOMPARE_EQ(Qt::compareThreeWay(lNeg, rNeg), std::partial_ordering::equivalent); + QCOMPARE_EQ(Qt::compareThreeWay(rNeg, lNeg), std::partial_ordering::equivalent); + + QCOMPARE_EQ(Qt::compareThreeWay(lNaN, rPos), std::partial_ordering::unordered); + QCOMPARE_EQ(Qt::compareThreeWay(rNeg, lNaN), std::partial_ordering::unordered); + QCOMPARE_EQ(Qt::compareThreeWay(lNeg, rNaN), std::partial_ordering::unordered); + QCOMPARE_EQ(Qt::compareThreeWay(rNaN, lPos), std::partial_ordering::unordered); + QCOMPARE_EQ(Qt::compareThreeWay(rNaN, lNaN), std::partial_ordering::unordered); + QCOMPARE_EQ(Qt::compareThreeWay(lNaN, rNaN), std::partial_ordering::unordered); + QCOMPARE_EQ(Qt::compareThreeWay(lNaN, rInf), std::partial_ordering::unordered); + QCOMPARE_EQ(Qt::compareThreeWay(rNaN, -lInf), std::partial_ordering::unordered); + + QCOMPARE_EQ(Qt::compareThreeWay(lInf, rPos), std::partial_ordering::greater); + QCOMPARE_EQ(Qt::compareThreeWay(rPos, lInf), std::partial_ordering::less); + QCOMPARE_EQ(Qt::compareThreeWay(rInf, lNeg), std::partial_ordering::greater); + QCOMPARE_EQ(Qt::compareThreeWay(lNeg, rInf), std::partial_ordering::less); + QCOMPARE_EQ(Qt::compareThreeWay(lInf, -rInf), std::partial_ordering::greater); + QCOMPARE_EQ(Qt::compareThreeWay(-lInf, rInf), std::partial_ordering::less); + QCOMPARE_EQ(Qt::compareThreeWay(-rInf, lInf), std::partial_ordering::less); + QCOMPARE_EQ(Qt::compareThreeWay(rInf, -lInf), std::partial_ordering::greater); +#endif // __cpp_lib_three_way_comparison +} + +template <typename IntType, typename FloatType, + Qt::if_integral_and_floating_point<IntType, FloatType> = true> +void testOrderForTypes() +{ + IntType l0{0}; + IntType l1{1}; + + FloatType r0{0.0}; + FloatType r1{1.0}; + FloatType rNaN{std::numeric_limits<FloatType>::quiet_NaN()}; + + QCOMPARE_EQ(Qt::compareThreeWay(l0, r1), Qt::partial_ordering::less); + QCOMPARE_EQ(Qt::compareThreeWay(l1, r0), Qt::partial_ordering::greater); + QCOMPARE_EQ(Qt::compareThreeWay(r1, l0), Qt::partial_ordering::greater); + QCOMPARE_EQ(Qt::compareThreeWay(r0, l1), Qt::partial_ordering::less); + QCOMPARE_EQ(Qt::compareThreeWay(l0, r0), Qt::partial_ordering::equivalent); + QCOMPARE_EQ(Qt::compareThreeWay(r0, l0), Qt::partial_ordering::equivalent); + QCOMPARE_EQ(Qt::compareThreeWay(l0, rNaN), Qt::partial_ordering::unordered); + QCOMPARE_EQ(Qt::compareThreeWay(rNaN, l1), Qt::partial_ordering::unordered); +#ifdef __cpp_lib_three_way_comparison + QCOMPARE_EQ(Qt::compareThreeWay(l0, r1), std::partial_ordering::less); + QCOMPARE_EQ(Qt::compareThreeWay(l1, r0), std::partial_ordering::greater); + QCOMPARE_EQ(Qt::compareThreeWay(r1, l0), std::partial_ordering::greater); + QCOMPARE_EQ(Qt::compareThreeWay(r0, l1), std::partial_ordering::less); + QCOMPARE_EQ(Qt::compareThreeWay(l0, r0), std::partial_ordering::equivalent); + QCOMPARE_EQ(Qt::compareThreeWay(r0, l0), std::partial_ordering::equivalent); + QCOMPARE_EQ(Qt::compareThreeWay(l0, rNaN), std::partial_ordering::unordered); + QCOMPARE_EQ(Qt::compareThreeWay(rNaN, l1), std::partial_ordering::unordered); +#endif // __cpp_lib_three_way_comparison +} + +enum class TestEnum : quint8 { + Smaller, + Bigger +}; + +void tst_QCompareHelpers::builtinOrder() +{ +#define TEST_BUILTIN(Left, Right) \ + testOrderForTypes<Left, Right>(); \ + if (QTest::currentTestFailed()) { \ + qDebug("Failed Qt::compareThreeWay() test for builtin types " #Left " and " #Right); \ + return; \ + } + + // some combinations + TEST_BUILTIN(char, char) +#if CHAR_MIN < 0 + TEST_BUILTIN(char, short) + TEST_BUILTIN(qint8, char) +#else + TEST_BUILTIN(char, ushort) + TEST_BUILTIN(quint8, char) +#endif + TEST_BUILTIN(qint8, qint8) + TEST_BUILTIN(qint8, int) + TEST_BUILTIN(ulong, quint8) + TEST_BUILTIN(ushort, uchar) + TEST_BUILTIN(int, int) + TEST_BUILTIN(uint, ulong) + TEST_BUILTIN(long, int) + TEST_BUILTIN(uint, quint64) + TEST_BUILTIN(qint64, short) + TEST_BUILTIN(wchar_t, wchar_t) + TEST_BUILTIN(uint, char16_t) + TEST_BUILTIN(char32_t, char32_t) + TEST_BUILTIN(char32_t, ushort) +#ifdef __cpp_char8_t + TEST_BUILTIN(char8_t, char8_t) + TEST_BUILTIN(char8_t, ushort) + TEST_BUILTIN(char8_t, uint) + TEST_BUILTIN(char8_t, quint64) +#endif // __cpp_char8_t +#ifdef QT_SUPPORTS_INT128 + TEST_BUILTIN(qint128, qint128) + TEST_BUILTIN(quint128, quint128) + TEST_BUILTIN(qint128, int) + TEST_BUILTIN(ushort, quint128) +#endif + TEST_BUILTIN(float, double) + TEST_BUILTIN(double, float) + TEST_BUILTIN(quint64, float) + TEST_BUILTIN(qint64, double) +#ifdef __STDCPP_FLOAT16_T__ + TEST_BUILTIN(std::float16_t, std::float16_t) + TEST_BUILTIN(std::float16_t, double) + TEST_BUILTIN(qint64, std::float16_t) + TEST_BUILTIN(uint, std::float16_t) +#endif + + TEST_BUILTIN(long double, long double) + TEST_BUILTIN(float, long double) + TEST_BUILTIN(double, long double) + TEST_BUILTIN(quint64, long double) + TEST_BUILTIN(ushort, long double) + + QCOMPARE_EQ(Qt::compareThreeWay(TestEnum::Smaller, TestEnum::Bigger), + Qt::strong_ordering::less); + QCOMPARE_EQ(Qt::compareThreeWay(TestEnum::Bigger, TestEnum::Smaller), + Qt::strong_ordering::greater); + QCOMPARE_EQ(Qt::compareThreeWay(TestEnum::Smaller, TestEnum::Smaller), + Qt::strong_ordering::equivalent); + + std::array<int, 2> arr{1, 0}; + QCOMPARE_EQ(Qt::compareThreeWay(&arr[0], &arr[1]), Qt::strong_ordering::less); + QCOMPARE_EQ(Qt::compareThreeWay(arr.data(), &arr[0]), Qt::strong_ordering::equivalent); + + class Base {}; + class Derived : public Base {}; + + auto b = std::make_unique<Base>(); + auto d = std::make_unique<Derived>(); + 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(nullptr, d.get()), Qt::strong_ordering::less); + +#undef TEST_BUILTIN +} + QTEST_MAIN(tst_QCompareHelpers) #include "tst_qcomparehelpers.moc" |