summaryrefslogtreecommitdiffstats
path: root/tests/auto/corelib/global/qcomparehelpers/tst_qcomparehelpers.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'tests/auto/corelib/global/qcomparehelpers/tst_qcomparehelpers.cpp')
-rw-r--r--tests/auto/corelib/global/qcomparehelpers/tst_qcomparehelpers.cpp270
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"