summaryrefslogtreecommitdiffstats
path: root/tests/auto/corelib/kernel/qvariant/tst_qvariant.cpp
diff options
context:
space:
mode:
authorThiago Macieira <thiago.macieira@intel.com>2022-11-04 15:15:26 -0700
committerThiago Macieira <thiago.macieira@intel.com>2022-11-09 04:05:50 -0700
commit393d5efda30aac8f20c35dc22b7d22c350f6f096 (patch)
treeb82007f3b82deeece3475ef597495bd226efe69e /tests/auto/corelib/kernel/qvariant/tst_qvariant.cpp
parent250ca8d5f8bb3771695ae8eccb8d9b469003d840 (diff)
QVariant: make a major simplification in the numeric comparison
The code implementing the C++ rules of type promotion and conversion was too pedantic. There's no need to follow the letter of the standard, not when we can now assume that everything is two's complement (this was true for all architectures we supported when I wrote this code in 2014, but wasn't required by the standard). So we can reduce this to fewer comparisons and fewer rules, using the size of the type, not just the type ID. Change-Id: I3d74c753055744deb8acfffd172446b02444c0c0 Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
Diffstat (limited to 'tests/auto/corelib/kernel/qvariant/tst_qvariant.cpp')
-rw-r--r--tests/auto/corelib/kernel/qvariant/tst_qvariant.cpp190
1 files changed, 190 insertions, 0 deletions
diff --git a/tests/auto/corelib/kernel/qvariant/tst_qvariant.cpp b/tests/auto/corelib/kernel/qvariant/tst_qvariant.cpp
index 5f8f965973..e7579a7927 100644
--- a/tests/auto/corelib/kernel/qvariant/tst_qvariant.cpp
+++ b/tests/auto/corelib/kernel/qvariant/tst_qvariant.cpp
@@ -209,6 +209,8 @@ private slots:
void variantHash();
void convertToQUint8() const;
+ void compareNumerics_data() const;
+ void compareNumerics() const;
void comparePointers() const;
void voidStar() const;
void dataStar() const;
@@ -2714,6 +2716,194 @@ void tst_QVariant::convertToQUint8() const
}
}
+void tst_QVariant::compareNumerics_data() const
+{
+ QTest::addColumn<QVariant>("v1");
+ QTest::addColumn<QVariant>("v2");
+ QTest::addColumn<QPartialOrdering>("result");
+
+ QTest::addRow("invalid-invalid")
+ << QVariant() << QVariant() << QPartialOrdering::Unordered;
+
+ static const auto asString = [](const QVariant &v) {
+ if (v.isNull())
+ return QStringLiteral("null");
+ switch (v.typeId()) {
+ case QMetaType::Char:
+ case QMetaType::Char16:
+ case QMetaType::Char32:
+ case QMetaType::UChar:
+ return QString::number(v.toUInt());
+ case QMetaType::SChar:
+ return QString::number(v.toInt());
+ }
+ return v.toString();
+ };
+
+ auto addCompareToInvalid = [](auto value) {
+ QVariant v = QVariant::fromValue(value);
+ QTest::addRow("invalid-%s(%s)", v.typeName(), qPrintable(asString(v)))
+ << QVariant() << v << QPartialOrdering::Unordered;
+ QTest::addRow("%s(%s)-invalid", v.typeName(), qPrintable(asString(v)))
+ << v << QVariant() << QPartialOrdering::Unordered;
+ };
+ addCompareToInvalid(false);
+ addCompareToInvalid(true);
+ addCompareToInvalid(char(0));
+ addCompareToInvalid(qint8(0));
+ addCompareToInvalid(quint8(0));
+ addCompareToInvalid(short(0));
+ addCompareToInvalid(ushort(0));
+ addCompareToInvalid(int(0));
+ addCompareToInvalid(uint(0));
+ addCompareToInvalid(long(0));
+ addCompareToInvalid(ulong(0));
+ addCompareToInvalid(qint64(0));
+ addCompareToInvalid(quint64(0));
+ addCompareToInvalid(0.f);
+ addCompareToInvalid(0.0);
+ addCompareToInvalid(QCborSimpleType{});
+
+QT_WARNING_PUSH
+QT_WARNING_DISABLE_CLANG("-Wsign-compare")
+QT_WARNING_DISABLE_GCC("-Wsign-compare")
+QT_WARNING_DISABLE_MSVC(4018) // '<': signed/unsigned mismatch
+ static const auto addComparePair = [](auto value1, auto value2) {
+ QVariant v1 = QVariant::fromValue(value1);
+ QVariant v2 = QVariant::fromValue(value2);
+ QPartialOrdering order = QPartialOrdering::Unordered;
+ if (value1 == value2)
+ order = QPartialOrdering::Equivalent;
+ else if (value1 < value2)
+ order = QPartialOrdering::Less;
+ else if (value1 > value2)
+ order = QPartialOrdering::Greater;
+ QTest::addRow("%s(%s)-%s(%s)", v1.typeName(), qPrintable(asString(v1)),
+ v2.typeName(), qPrintable(asString(v2)))
+ << v1 << v2 << order;
+ };
+QT_WARNING_POP
+
+ // homogeneous first
+ static const auto addList = [](auto list) {
+ for (auto v1 : list)
+ for (auto v2 : list)
+ addComparePair(v1, v2);
+ };
+
+ auto addSingleType = [](auto zero) {
+ using T = decltype(zero);
+ T one = T(zero + 1);
+ T min = std::numeric_limits<T>::min();
+ T max = std::numeric_limits<T>::max();
+ T mid = max / 2 + 1;
+ if (min != zero)
+ addList(std::array{zero, one, min, mid, max});
+ else
+ addList(std::array{zero, one, mid, max});
+ };
+ addList(std::array{ false, true });
+ addList(std::array{ QCborSimpleType{}, QCborSimpleType::False, QCborSimpleType(0xff) });
+ addSingleType(char(0));
+ addSingleType(qint8(0));
+ addSingleType(quint8(0));
+ addSingleType(qint16(0));
+ addSingleType(quint16(0));
+ addSingleType(qint32(0));
+ addSingleType(quint32(0));
+ addSingleType(qint64(0));
+ addSingleType(quint64(0));
+ addSingleType(0.f);
+ addSingleType(0.0);
+
+ // heterogeneous
+ addComparePair(char(0), qint8(-127));
+ addComparePair(char(127), qint8(127));
+ addComparePair(char(127), quint8(127));
+ addComparePair(qint8(-1), quint8(255));
+ addComparePair(0U, -1);
+ addComparePair(~0U, -1);
+ addComparePair(Q_UINT64_C(0), -1);
+ addComparePair(~Q_UINT64_C(0), -1);
+ addComparePair(Q_UINT64_C(0), Q_INT64_C(-1));
+ addComparePair(~Q_UINT64_C(0), Q_INT64_C(-1));
+ addComparePair(INT_MAX, uint(INT_MAX));
+ addComparePair(INT_MAX, qint64(INT_MAX) + 1);
+ addComparePair(INT_MAX, UINT_MAX);
+ addComparePair(INT_MAX, qint64(UINT_MAX));
+ addComparePair(INT_MAX, qint64(UINT_MAX) + 1);
+ addComparePair(INT_MAX, quint64(UINT_MAX));
+ addComparePair(INT_MAX, quint64(UINT_MAX) + 1);
+ addComparePair(INT_MAX, LONG_MIN);
+ addComparePair(INT_MAX, LONG_MAX);
+ addComparePair(INT_MAX, LLONG_MIN);
+ addComparePair(INT_MAX, LLONG_MAX);
+ addComparePair(INT_MIN, uint(INT_MIN));
+ addComparePair(INT_MIN, uint(INT_MIN) + 1);
+ addComparePair(INT_MIN + 1, uint(INT_MIN));
+ addComparePair(INT_MIN + 1, uint(INT_MIN) + 1);
+ addComparePair(INT_MIN, qint64(INT_MIN) - 1);
+ addComparePair(INT_MIN + 1, qint64(INT_MIN) + 1);
+ addComparePair(INT_MIN + 1, qint64(INT_MIN) - 1);
+ addComparePair(INT_MIN, UINT_MAX);
+ addComparePair(INT_MIN, qint64(UINT_MAX));
+ addComparePair(INT_MIN, qint64(UINT_MAX) + 1);
+ addComparePair(INT_MIN, quint64(UINT_MAX));
+ addComparePair(INT_MIN, quint64(UINT_MAX) + 1);
+ addComparePair(UINT_MAX, qint64(UINT_MAX) + 1);
+ addComparePair(UINT_MAX, quint64(UINT_MAX) + 1);
+ addComparePair(UINT_MAX, qint64(INT_MIN) - 1);
+ addComparePair(UINT_MAX, quint64(INT_MIN) + 1);
+ addComparePair(LLONG_MAX, quint64(LLONG_MAX));
+ addComparePair(LLONG_MAX, quint64(LLONG_MAX) + 1);
+ addComparePair(LLONG_MIN, quint64(LLONG_MAX));
+ addComparePair(LLONG_MIN, quint64(LLONG_MAX) + 1);
+ addComparePair(LLONG_MIN, quint64(LLONG_MIN) + 1);
+ addComparePair(LLONG_MIN + 1, quint64(LLONG_MIN) + 1);
+ addComparePair(LLONG_MIN, LLONG_MAX - 1);
+ addComparePair(LLONG_MIN, LLONG_MAX);
+
+ // floating point
+ addComparePair(0.f, 0);
+ addComparePair(0.f, 0U);
+ addComparePair(0.f, Q_INT64_C(0));
+ addComparePair(0.f, Q_UINT64_C(0));
+ addComparePair(0.f, 0.);
+ addComparePair(0.f, 1.);
+ addComparePair(0.f, 1.);
+ addComparePair(float(1 << 24), 1 << 24);
+ addComparePair(float(1 << 24) - 1, (1 << 24) - 1);
+ addComparePair(-float(1 << 24), 1 << 24);
+ addComparePair(-float(1 << 24) + 1, -(1 << 24) + 1);
+ addComparePair(HUGE_VALF, qInf());
+ addComparePair(HUGE_VALF, -qInf());
+ addComparePair(qQNaN(), std::numeric_limits<float>::quiet_NaN());
+ if (sizeof(qreal) == sizeof(double)) {
+ addComparePair(std::numeric_limits<float>::min(), std::numeric_limits<double>::min());
+ addComparePair(std::numeric_limits<float>::min(), std::numeric_limits<double>::min());
+ addComparePair(std::numeric_limits<float>::max(), std::numeric_limits<double>::min());
+ addComparePair(std::numeric_limits<float>::max(), std::numeric_limits<double>::max());
+ addComparePair(double(Q_INT64_C(1) << 53), Q_INT64_C(1) << 53);
+ addComparePair(double(Q_INT64_C(1) << 53) - 1, (Q_INT64_C(1) << 53) - 1);
+ addComparePair(-double(Q_INT64_C(1) << 53), Q_INT64_C(1) << 53);
+ addComparePair(-double(Q_INT64_C(1) << 53) + 1, (Q_INT64_C(1) << 53) + 1);
+ }
+}
+
+void tst_QVariant::compareNumerics() const
+{
+ QFETCH(QVariant, v1);
+ QFETCH(QVariant, v2);
+ QFETCH(QPartialOrdering, result);
+ QCOMPARE(QVariant::compare(v1, v2), result);
+
+ QEXPECT_FAIL("invalid-invalid", "needs fixing", Continue);
+ if (result == QPartialOrdering::Equivalent)
+ QCOMPARE_EQ(v1, v2);
+ else
+ QCOMPARE_NE(v1, v2);
+}
+
void tst_QVariant::comparePointers() const
{
class MyClass