summaryrefslogtreecommitdiffstats
path: root/tests/auto
diff options
context:
space:
mode:
authorVolker Hilsheimer <volker.hilsheimer@qt.io>2021-02-07 11:45:06 +0100
committerVolker Hilsheimer <volker.hilsheimer@qt.io>2021-02-09 14:27:20 +0100
commit85416ae6fd9da00540e471e5b0864a3e1678f423 (patch)
tree6d637033fac75defdc83a44de93f3d2f8b14a45f /tests/auto
parent2861cfb6f851d7cee503b19f0e800a33374db66c (diff)
Split up the QMetaType unit test
gcc 9 consumed enourmous amounts of memory building the test, regularly dying on a VM with 4GB RAM. Splitting it up helps. As a drive-by, use inline static variables, and rename the header used by other tests to tst_qmetatype_common.h. Change-Id: Ib716d8e3506aac6c87845e57b04cb1a4f6c68387 Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
Diffstat (limited to 'tests/auto')
-rw-r--r--tests/auto/corelib/io/qsettings/tst_qsettings.cpp2
-rw-r--r--tests/auto/corelib/kernel/qmetatype/CMakeLists.txt2
-rw-r--r--tests/auto/corelib/kernel/qmetatype/tst_qmetatype.cpp663
-rw-r--r--tests/auto/corelib/kernel/qmetatype/tst_qmetatype.h430
-rw-r--r--tests/auto/corelib/kernel/qmetatype/tst_qmetatype2.cpp483
-rw-r--r--tests/auto/corelib/kernel/qmetatype/tst_qmetatype_common.h298
-rw-r--r--tests/auto/other/qvariant_common/tst_qvariant_common.h6
7 files changed, 969 insertions, 915 deletions
diff --git a/tests/auto/corelib/io/qsettings/tst_qsettings.cpp b/tests/auto/corelib/io/qsettings/tst_qsettings.cpp
index 9fd7b255d7..732d81d84a 100644
--- a/tests/auto/corelib/io/qsettings/tst_qsettings.cpp
+++ b/tests/auto/corelib/io/qsettings/tst_qsettings.cpp
@@ -45,7 +45,7 @@
#include <QtCore>
#include <QtGui>
-#include "tst_qmetatype.h"
+#include "tst_qmetatype_common.h"
#include <cctype>
#include <stdlib.h>
diff --git a/tests/auto/corelib/kernel/qmetatype/CMakeLists.txt b/tests/auto/corelib/kernel/qmetatype/CMakeLists.txt
index d3e576127f..49fcecebc3 100644
--- a/tests/auto/corelib/kernel/qmetatype/CMakeLists.txt
+++ b/tests/auto/corelib/kernel/qmetatype/CMakeLists.txt
@@ -9,7 +9,7 @@ list(APPEND test_data "./typeFlags.bin")
qt_internal_add_test(tst_qmetatype
SOURCES
- tst_qmetatype.cpp
+ tst_qmetatype.h tst_qmetatype.cpp tst_qmetatype2.cpp
DEFINES
QT_DISABLE_DEPRECATED_BEFORE=0
INCLUDE_DIRECTORIES
diff --git a/tests/auto/corelib/kernel/qmetatype/tst_qmetatype.cpp b/tests/auto/corelib/kernel/qmetatype/tst_qmetatype.cpp
index 1978e9e1b7..81a67f1b78 100644
--- a/tests/auto/corelib/kernel/qmetatype/tst_qmetatype.cpp
+++ b/tests/auto/corelib/kernel/qmetatype/tst_qmetatype.cpp
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2016 The Qt Company Ltd.
+** Copyright (C) 2021 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the test suite of the Qt Toolkit.
@@ -26,14 +26,10 @@
**
****************************************************************************/
+#include "tst_qmetatype.h"
-#include <QtCore>
-#include <QTest>
#include <QtCore/private/qmetaobjectbuilder_p.h>
-#include "tst_qmetatype.h"
-#include "tst_qvariant_common.h"
-
#ifdef Q_OS_LINUX
# include <pthread.h>
#endif
@@ -153,91 +149,6 @@ static_assert(!QTypeTraits::has_operator_less_than_v<std::tuple<int, Nested2>>);
}
-
-class tst_QMetaType: public QObject
-{
- Q_OBJECT
- Q_PROPERTY(QList<QVariant> prop READ prop WRITE setProp)
-
-public:
- struct GadgetPropertyType {
- QByteArray type;
- QByteArray name;
- QVariant testData;
- };
-
- tst_QMetaType() { propList << 42 << "Hello"; }
-
- QList<QVariant> prop() const { return propList; }
- void setProp(const QList<QVariant> &list) { propList = list; }
-
-private:
- void registerGadget(const char * name, const QList<GadgetPropertyType> &gadgetProperties);
- QList<QVariant> propList;
-
-private slots:
- void defined();
- void threadSafety();
- void namespaces();
- void id();
- void qMetaTypeId();
- void properties();
- void normalizedTypes();
- void typeName_data();
- void typeName();
- void type_data();
- void type();
- void type_fromSubString_data();
- void type_fromSubString();
- void create_data();
- void create();
- void createCopy_data();
- void createCopy();
- void sizeOf_data();
- void sizeOf();
- void sizeOfStaticLess_data();
- void sizeOfStaticLess();
- void alignOf_data();
- void alignOf();
- void flags_data();
- void flags();
- void flagsStaticLess_data();
- void flagsStaticLess();
- void flagsBinaryCompatibility6_0_data();
- void flagsBinaryCompatibility6_0();
- void construct_data();
- void construct();
- void typedConstruct();
- void constructCopy_data();
- void constructCopy();
- void typedefs();
- void registerType();
- void isRegistered_data();
- void isRegistered();
- void isRegisteredStaticLess_data();
- void isRegisteredStaticLess();
- void isEnum();
- void automaticTemplateRegistration();
- void saveAndLoadBuiltin_data();
- void saveAndLoadBuiltin();
- void saveAndLoadCustom();
- void metaObject_data();
- void metaObject();
- void constexprMetaTypeIds();
- void constRefs();
- void convertCustomType_data();
- void convertCustomType();
- void compareCustomEqualOnlyType();
- void customDebugStream();
- void unknownType();
- void fromType();
- void operatorEq_data();
- void operatorEq();
- void typesWithInaccessibleDTors();
- void voidIsNotUnknown();
- void typeNameNormalization();
-};
-
struct BaseGenericType
{
int m_typeId = -1;
@@ -647,18 +558,6 @@ void tst_QMetaType::properties()
QCOMPARE(v.toList().count(), 4);
}
-template <typename T>
-struct Whity { T t; Whity() {} };
-
-Q_DECLARE_METATYPE( Whity < int > )
-Q_DECLARE_METATYPE(Whity<double>)
-
-#if !defined(Q_CC_CLANG) && defined(Q_CC_GNU) && Q_CC_GNU < 501
-QT_BEGIN_NAMESPACE
-Q_DECLARE_TYPEINFO(Whity<double>, Q_RELOCATABLE_TYPE);
-QT_END_NAMESPACE
-#endif
-
void tst_QMetaType::normalizedTypes()
{
int WhityIntId = ::qMetaTypeId<Whity<int> >();
@@ -1011,20 +910,6 @@ void tst_QMetaType::alignOf()
QCOMPARE(size_t(QMetaType(type).alignOf()), size);
}
-struct CustomMovable { CustomMovable() {} };
-
-// needed for QSet<CustomMovable>. We actually check that it makes sense.
-bool operator==(const CustomMovable &, const CustomMovable &) { return true; }
-qsizetype qHash(const CustomMovable &, qsizetype seed = 0) { return seed; }
-
-#if !defined(Q_CC_CLANG) && defined(Q_CC_GNU) && Q_CC_GNU < 501
-QT_BEGIN_NAMESPACE
-Q_DECLARE_TYPEINFO(CustomMovable, Q_RELOCATABLE_TYPE);
-QT_END_NAMESPACE
-#endif
-
-Q_DECLARE_METATYPE(CustomMovable);
-
class CustomObject : public QObject
{
Q_OBJECT
@@ -2234,549 +2119,5 @@ void tst_QMetaType::constexprMetaTypeIds()
Q_UNUSED(metaType);
}
-void tst_QMetaType::constRefs()
-{
- QCOMPARE(::qMetaTypeId<const int &>(), ::qMetaTypeId<int>());
- QCOMPARE(::qMetaTypeId<const QString &>(), ::qMetaTypeId<QString>());
- QCOMPARE(::qMetaTypeId<const CustomMovable &>(), ::qMetaTypeId<CustomMovable>());
- QCOMPARE(::qMetaTypeId<const QList<CustomMovable> &>(), ::qMetaTypeId<QList<CustomMovable> >());
- static_assert(::qMetaTypeId<const int &>() == ::qMetaTypeId<int>());
-}
-
-struct CustomConvertibleType
-{
- explicit CustomConvertibleType(const QVariant &foo = QVariant()) : m_foo(foo) {}
- virtual ~CustomConvertibleType() {}
- QString toString() const { return m_foo.toString(); }
- operator QPoint() const { return QPoint(12, 34); }
- template<typename To>
- To convert() const { return s_value.value<To>();}
- template<typename To>
- To convertOk(bool *ok) const { *ok = s_ok; return s_value.value<To>();}
-
- QVariant m_foo;
- static QVariant s_value;
- static bool s_ok;
-};
-
-bool operator<(const CustomConvertibleType &lhs, const CustomConvertibleType &rhs)
-{ return lhs.m_foo.toString() < rhs.m_foo.toString(); }
-bool operator==(const CustomConvertibleType &lhs, const CustomConvertibleType &rhs)
-{ return lhs.m_foo == rhs.m_foo; }
-bool operator!=(const CustomConvertibleType &lhs, const CustomConvertibleType &rhs)
-{ return !operator==(lhs, rhs); }
-
-QVariant CustomConvertibleType::s_value;
-bool CustomConvertibleType::s_ok = true;
-
-struct CustomConvertibleType2
-{
- // implicit
- CustomConvertibleType2(const CustomConvertibleType &t = CustomConvertibleType())
- : m_foo(t.m_foo) {}
- virtual ~CustomConvertibleType2() {}
-
- QVariant m_foo;
-};
-
-struct CustomDebugStreamableType
-{
- QString toString() const { return "test"; }
-};
-
-struct CustomDebugStreamableType2
-{
- QString toString() const { return "test"; }
-};
-
-QDebug operator<<(QDebug dbg, const CustomDebugStreamableType&)
-{
- return dbg << "string-content";
-}
-
-bool operator==(const CustomConvertibleType2 &lhs, const CustomConvertibleType2 &rhs)
-{ return lhs.m_foo == rhs.m_foo; }
-bool operator!=(const CustomConvertibleType2 &lhs, const CustomConvertibleType2 &rhs)
-{ return !operator==(lhs, rhs); }
-
-
-struct CustomEqualsOnlyType
-{
- explicit CustomEqualsOnlyType(int value = 0) : val(value) {}
- virtual ~CustomEqualsOnlyType() {}
-
- int val;
-};
-bool operator==(const CustomEqualsOnlyType &lhs, const CustomEqualsOnlyType &rhs)
-{ return lhs.val == rhs.val;}
-bool operator!=(const CustomEqualsOnlyType &lhs, const CustomEqualsOnlyType &rhs)
-{ return !operator==(lhs, rhs); }
-
-static_assert(QTypeTraits::has_operator_equal_v<CustomEqualsOnlyType>);
-static_assert(!QTypeTraits::has_operator_less_than_v<CustomEqualsOnlyType>);
-
-Q_DECLARE_METATYPE(CustomConvertibleType);
-Q_DECLARE_METATYPE(CustomConvertibleType2);
-Q_DECLARE_METATYPE(CustomDebugStreamableType);
-Q_DECLARE_METATYPE(CustomEqualsOnlyType);
-
-template<typename T, typename U>
-U convert(const T &t)
-{
- return t;
-}
-
-template<typename From>
-struct ConvertFunctor
-{
- CustomConvertibleType operator()(const From& f) const
- {
- return CustomConvertibleType(QVariant::fromValue(f));
- }
-};
-
-template<typename From, typename To>
-bool hasRegisteredConverterFunction()
-{
- return QMetaType::hasRegisteredConverterFunction<From, To>();
-}
-
-template<typename From, typename To>
-void testCustomTypeNotYetConvertible()
-{
- QVERIFY((!hasRegisteredConverterFunction<From, To>()));
- QVERIFY((!QVariant::fromValue<From>(From()).template canConvert<To>()));
-}
-
-template<typename From, typename To>
-void testCustomTypeConvertible()
-{
- QVERIFY((hasRegisteredConverterFunction<From, To>()));
- QVERIFY((QVariant::fromValue<From>(From()).template canConvert<To>()));
-}
-
-void customTypeNotYetConvertible()
-{
- testCustomTypeNotYetConvertible<CustomConvertibleType, QString>();
- testCustomTypeNotYetConvertible<CustomConvertibleType, bool>();
- testCustomTypeNotYetConvertible<CustomConvertibleType, int>();
- testCustomTypeNotYetConvertible<CustomConvertibleType, double>();
- testCustomTypeNotYetConvertible<CustomConvertibleType, float>();
- testCustomTypeNotYetConvertible<CustomConvertibleType, QRect>();
- testCustomTypeNotYetConvertible<CustomConvertibleType, QRectF>();
- testCustomTypeNotYetConvertible<CustomConvertibleType, QPoint>();
- testCustomTypeNotYetConvertible<CustomConvertibleType, QPointF>();
- testCustomTypeNotYetConvertible<CustomConvertibleType, QSize>();
- testCustomTypeNotYetConvertible<CustomConvertibleType, QSizeF>();
- testCustomTypeNotYetConvertible<CustomConvertibleType, QLine>();
- testCustomTypeNotYetConvertible<CustomConvertibleType, QLineF>();
- testCustomTypeNotYetConvertible<CustomConvertibleType, QChar>();
- testCustomTypeNotYetConvertible<QString, CustomConvertibleType>();
- testCustomTypeNotYetConvertible<bool, CustomConvertibleType>();
- testCustomTypeNotYetConvertible<int, CustomConvertibleType>();
- testCustomTypeNotYetConvertible<double, CustomConvertibleType>();
- testCustomTypeNotYetConvertible<float, CustomConvertibleType>();
- testCustomTypeNotYetConvertible<QRect, CustomConvertibleType>();
- testCustomTypeNotYetConvertible<QRectF, CustomConvertibleType>();
- testCustomTypeNotYetConvertible<QPoint, CustomConvertibleType>();
- testCustomTypeNotYetConvertible<QPointF, CustomConvertibleType>();
- testCustomTypeNotYetConvertible<QSize, CustomConvertibleType>();
- testCustomTypeNotYetConvertible<QSizeF, CustomConvertibleType>();
- testCustomTypeNotYetConvertible<QLine, CustomConvertibleType>();
- testCustomTypeNotYetConvertible<QLineF, CustomConvertibleType>();
- testCustomTypeNotYetConvertible<QChar, CustomConvertibleType>();
- testCustomTypeNotYetConvertible<CustomConvertibleType, CustomConvertibleType2>();
-}
-
-void registerCustomTypeConversions()
-{
- QVERIFY((QMetaType::registerConverter<CustomConvertibleType, QString>(&CustomConvertibleType::convertOk<QString>)));
- QVERIFY((QMetaType::registerConverter<CustomConvertibleType, bool>(&CustomConvertibleType::convert<bool>)));
- QVERIFY((QMetaType::registerConverter<CustomConvertibleType, int>(&CustomConvertibleType::convertOk<int>)));
- QVERIFY((QMetaType::registerConverter<CustomConvertibleType, double>(&CustomConvertibleType::convert<double>)));
- QVERIFY((QMetaType::registerConverter<CustomConvertibleType, float>(&CustomConvertibleType::convertOk<float>)));
- QVERIFY((QMetaType::registerConverter<CustomConvertibleType, QRect>(&CustomConvertibleType::convert<QRect>)));
- QVERIFY((QMetaType::registerConverter<CustomConvertibleType, QRectF>(&CustomConvertibleType::convertOk<QRectF>)));
- QVERIFY((QMetaType::registerConverter<CustomConvertibleType, QPoint>(convert<CustomConvertibleType,QPoint>)));
- QVERIFY((QMetaType::registerConverter<CustomConvertibleType, QPointF>(&CustomConvertibleType::convertOk<QPointF>)));
- QVERIFY((QMetaType::registerConverter<CustomConvertibleType, QSize>(&CustomConvertibleType::convert<QSize>)));
- QVERIFY((QMetaType::registerConverter<CustomConvertibleType, QSizeF>(&CustomConvertibleType::convertOk<QSizeF>)));
- QVERIFY((QMetaType::registerConverter<CustomConvertibleType, QLine>(&CustomConvertibleType::convert<QLine>)));
- QVERIFY((QMetaType::registerConverter<CustomConvertibleType, QLineF>(&CustomConvertibleType::convertOk<QLineF>)));
- QVERIFY((QMetaType::registerConverter<CustomConvertibleType, QChar>(&CustomConvertibleType::convert<QChar>)));
- QVERIFY((QMetaType::registerConverter<QString, CustomConvertibleType>(ConvertFunctor<QString>())));
- QVERIFY((QMetaType::registerConverter<bool, CustomConvertibleType>(ConvertFunctor<bool>())));
- QVERIFY((QMetaType::registerConverter<int, CustomConvertibleType>(ConvertFunctor<int>())));
- QVERIFY((QMetaType::registerConverter<double, CustomConvertibleType>(ConvertFunctor<double>())));
- QVERIFY((QMetaType::registerConverter<float, CustomConvertibleType>(ConvertFunctor<float>())));
- QVERIFY((QMetaType::registerConverter<QRect, CustomConvertibleType>(ConvertFunctor<QRect>())));
- QVERIFY((QMetaType::registerConverter<QRectF, CustomConvertibleType>(ConvertFunctor<QRectF>())));
- QVERIFY((QMetaType::registerConverter<QPoint, CustomConvertibleType>(ConvertFunctor<QPoint>())));
- QVERIFY((QMetaType::registerConverter<QPointF, CustomConvertibleType>(ConvertFunctor<QPointF>())));
- QVERIFY((QMetaType::registerConverter<QSize, CustomConvertibleType>(ConvertFunctor<QSize>())));
- QVERIFY((QMetaType::registerConverter<QSizeF, CustomConvertibleType>(ConvertFunctor<QSizeF>())));
- QVERIFY((QMetaType::registerConverter<QLine, CustomConvertibleType>(ConvertFunctor<QLine>())));
- QVERIFY((QMetaType::registerConverter<QLineF, CustomConvertibleType>(ConvertFunctor<QLineF>())));
- QVERIFY((QMetaType::registerConverter<QChar, CustomConvertibleType>(ConvertFunctor<QChar>())));
- QVERIFY((QMetaType::registerConverter<CustomConvertibleType, CustomConvertibleType2>()));
- QTest::ignoreMessage(QtWarningMsg, "Type conversion already registered from type CustomConvertibleType to type CustomConvertibleType2");
- QVERIFY((!QMetaType::registerConverter<CustomConvertibleType, CustomConvertibleType2>()));
-}
-
-void tst_QMetaType::convertCustomType_data()
-{
- customTypeNotYetConvertible();
- registerCustomTypeConversions();
-
- QTest::addColumn<bool>("ok");
- QTest::addColumn<QString>("testQString");
- QTest::addColumn<bool>("testBool");
- QTest::addColumn<int>("testInt");
- QTest::addColumn<double>("testDouble");
- QTest::addColumn<float>("testFloat");
- QTest::addColumn<QRect>("testQRect");
- QTest::addColumn<QRectF>("testQRectF");
- QTest::addColumn<QPoint>("testQPoint");
- QTest::addColumn<QPointF>("testQPointF");
- QTest::addColumn<QSize>("testQSize");
- QTest::addColumn<QSizeF>("testQSizeF");
- QTest::addColumn<QLine>("testQLine");
- QTest::addColumn<QLineF>("testQLineF");
- QTest::addColumn<QChar>("testQChar");
- QTest::addColumn<CustomConvertibleType>("testCustom");
-
- QTest::newRow("default") << true
- << QString::fromLatin1("string") << true << 15
- << double(3.14) << float(3.6) << QRect(1, 2, 3, 4)
- << QRectF(1.4, 1.9, 10.9, 40.2) << QPoint(12, 34)
- << QPointF(9.2, 2.7) << QSize(4, 9) << QSizeF(3.3, 9.8)
- << QLine(3, 9, 29, 4) << QLineF(38.9, 28.9, 102.3, 0.0)
- << QChar('Q') << CustomConvertibleType(QString::fromLatin1("test"));
- QTest::newRow("not ok") << false
- << QString::fromLatin1("string") << true << 15
- << double(3.14) << float(3.6) << QRect(1, 2, 3, 4)
- << QRectF(1.4, 1.9, 10.9, 40.2) << QPoint(12, 34)
- << QPointF(9.2, 2.7) << QSize(4, 9) << QSizeF(3.3, 9.8)
- << QLine(3, 9, 29, 4) << QLineF()
- << QChar('Q') << CustomConvertibleType(42);
-}
-
-void tst_QMetaType::convertCustomType()
-{
- QFETCH(bool, ok);
- CustomConvertibleType::s_ok = ok;
-
- CustomConvertibleType t;
- QVariant v = QVariant::fromValue(t);
- QFETCH(QString, testQString);
- CustomConvertibleType::s_value = testQString;
- QCOMPARE(v.toString(), ok ? testQString : QString());
- QCOMPARE(v.value<QString>(), ok ? testQString : QString());
- QVERIFY(CustomConvertibleType::s_value.canConvert<CustomConvertibleType>());
- QCOMPARE((CustomConvertibleType::s_value.value<CustomConvertibleType>().m_foo.toString()), testQString);
-
- QFETCH(bool, testBool);
- CustomConvertibleType::s_value = testBool;
- QCOMPARE(v.toBool(), testBool);
- QCOMPARE(v.value<bool>(), testBool);
- QCOMPARE((CustomConvertibleType::s_value.value<CustomConvertibleType>().m_foo.toBool()), testBool);
-
- QFETCH(int, testInt);
- CustomConvertibleType::s_value = testInt;
- QCOMPARE(v.toInt(), ok ? testInt : 0);
- QCOMPARE(v.value<int>(), ok ? testInt : 0);
- QCOMPARE((CustomConvertibleType::s_value.value<CustomConvertibleType>().m_foo.toInt()), testInt);
-
- QFETCH(double, testDouble);
- CustomConvertibleType::s_value = testDouble;
- QCOMPARE(v.toDouble(), testDouble);
- QCOMPARE(v.value<double>(), testDouble);
- QCOMPARE((CustomConvertibleType::s_value.value<CustomConvertibleType>().m_foo.toDouble()), testDouble);
-
- QFETCH(float, testFloat);
- CustomConvertibleType::s_value = testFloat;
- QCOMPARE(v.toFloat(), ok ? testFloat : 0.0);
- QCOMPARE(v.value<float>(), ok ? testFloat : 0.0);
- QCOMPARE((CustomConvertibleType::s_value.value<CustomConvertibleType>().m_foo.toFloat()), testFloat);
-
- QFETCH(QRect, testQRect);
- CustomConvertibleType::s_value = testQRect;
- QCOMPARE(v.toRect(), testQRect);
- QCOMPARE(v.value<QRect>(), testQRect);
- QCOMPARE((CustomConvertibleType::s_value.value<CustomConvertibleType>().m_foo.toRect()), testQRect);
-
- QFETCH(QRectF, testQRectF);
- CustomConvertibleType::s_value = testQRectF;
- QCOMPARE(v.toRectF(), ok ? testQRectF : QRectF());
- QCOMPARE(v.value<QRectF>(), ok ? testQRectF : QRectF());
- QCOMPARE((CustomConvertibleType::s_value.value<CustomConvertibleType>().m_foo.toRectF()), testQRectF);
-
- QFETCH(QPoint, testQPoint);
- CustomConvertibleType::s_value = testQPoint;
- QCOMPARE(v.toPoint(), testQPoint);
- QCOMPARE(v.value<QPoint>(), testQPoint);
- QCOMPARE((CustomConvertibleType::s_value.value<CustomConvertibleType>().m_foo.toPoint()), testQPoint);
-
- QFETCH(QPointF, testQPointF);
- CustomConvertibleType::s_value = testQPointF;
- QCOMPARE(v.toPointF(), ok ? testQPointF : QPointF());
- QCOMPARE(v.value<QPointF>(), ok ? testQPointF : QPointF());
- QCOMPARE((CustomConvertibleType::s_value.value<CustomConvertibleType>().m_foo.toPointF()), testQPointF);
-
- QFETCH(QSize, testQSize);
- CustomConvertibleType::s_value = testQSize;
- QCOMPARE(v.toSize(), testQSize);
- QCOMPARE(v.value<QSize>(), testQSize);
- QCOMPARE((CustomConvertibleType::s_value.value<CustomConvertibleType>().m_foo.toSize()), testQSize);
-
- QFETCH(QSizeF, testQSizeF);
- CustomConvertibleType::s_value = testQSizeF;
- QCOMPARE(v.toSizeF(), ok ? testQSizeF : QSizeF());
- QCOMPARE(v.value<QSizeF>(), ok ? testQSizeF : QSizeF());
- QCOMPARE((CustomConvertibleType::s_value.value<CustomConvertibleType>().m_foo.toSizeF()), testQSizeF);
-
- QFETCH(QLine, testQLine);
- CustomConvertibleType::s_value = testQLine;
- QCOMPARE(v.toLine(), testQLine);
- QCOMPARE(v.value<QLine>(), testQLine);
- QCOMPARE((CustomConvertibleType::s_value.value<CustomConvertibleType>().m_foo.toLine()), testQLine);
-
- QFETCH(QLineF, testQLineF);
- CustomConvertibleType::s_value = testQLineF;
- QCOMPARE(v.toLineF(), ok ? testQLineF : QLineF());
- QCOMPARE(v.value<QLineF>(), ok ? testQLineF : QLineF());
- QCOMPARE((CustomConvertibleType::s_value.value<CustomConvertibleType>().m_foo.toLineF()), testQLineF);
-
- QFETCH(QChar, testQChar);
- CustomConvertibleType::s_value = testQChar;
- QCOMPARE(v.toChar(), testQChar);
- QCOMPARE((CustomConvertibleType::s_value.value<CustomConvertibleType>().m_foo.toChar()), testQChar);
-
- QFETCH(CustomConvertibleType, testCustom);
- v = QVariant::fromValue(testCustom);
- QVERIFY(v.canConvert(::qMetaTypeId<CustomConvertibleType2>()));
- QCOMPARE(v.value<CustomConvertibleType2>().m_foo, testCustom.m_foo);
-}
-
-void tst_QMetaType::compareCustomEqualOnlyType()
-{
- QMetaType type = QMetaType::fromType<CustomEqualsOnlyType>();
-
- CustomEqualsOnlyType val50(50);
- CustomEqualsOnlyType val100(100);
- CustomEqualsOnlyType val100x(100);
-
- QVariant variant50 = QVariant::fromValue(val50);
- QVariant variant100 = QVariant::fromValue(val100);
- QVariant variant100x = QVariant::fromValue(val100x);
-
- QVERIFY(variant50 != variant100);
- QVERIFY(variant50 != variant100x);
- QVERIFY(variant100 != variant50);
- QVERIFY(variant100x != variant50);
- QCOMPARE(variant100, variant100x);
- QCOMPARE(variant100, variant100);
-
- // check QMetaType::compare works/doesn't crash for equals only comparators
- auto cmp = type.compare(variant50.constData(), variant50.constData());
- QCOMPARE(cmp, QPartialOrdering::Unordered);
- bool equals = type.equals(variant50.constData(), variant50.constData());
- QVERIFY(equals);
-
- cmp = type.compare(variant100.constData(), variant100x.constData());
- QCOMPARE(cmp, QPartialOrdering::Unordered);
- equals = type.equals(variant100.constData(), variant100x.constData());
- QVERIFY(equals);
-
- cmp = type.compare(variant50.constData(), variant100.constData());
- QCOMPARE(cmp, QPartialOrdering::Unordered);
- equals = type.equals(variant50.constData(), variant100.constData());
- QVERIFY(!equals);
-
- //check QMetaType::equals for type w/o equals comparator being registered
- CustomMovable movable1;
- CustomMovable movable2;
- type = QMetaType::fromType<CustomMovable>();
- equals = type.equals(&movable1, &movable2);
-}
-
-struct MessageHandlerCustom : public MessageHandler
-{
- MessageHandlerCustom(const int typeId)
- : MessageHandler(typeId, handler)
- {}
- static void handler(QtMsgType, const QMessageLogContext &, const QString &msg)
- {
- QCOMPARE(msg.trimmed(), expectedMessage.trimmed());
- }
- static QString expectedMessage;
-};
-
-QString MessageHandlerCustom::expectedMessage;
-
-void tst_QMetaType::customDebugStream()
-{
- MessageHandlerCustom handler(::qMetaTypeId<CustomDebugStreamableType>());
- QVariant v1 = QVariant::fromValue(CustomDebugStreamableType());
- handler.expectedMessage = "QVariant(CustomDebugStreamableType, string-content)";
- qDebug() << v1;
-
- MessageHandlerCustom handler2(::qMetaTypeId<CustomDebugStreamableType2>());
- QMetaType::registerConverter<CustomDebugStreamableType2, QString>(&CustomDebugStreamableType2::toString);
- handler2.expectedMessage = "QVariant(CustomDebugStreamableType2, \"test\")";
- QVariant v2 = QVariant::fromValue(CustomDebugStreamableType2());
- qDebug() << v2;
-}
-
-void tst_QMetaType::unknownType()
-{
- QMetaType invalid(QMetaType::UnknownType);
- QVERIFY(!invalid.create());
- QVERIFY(!invalid.sizeOf());
- QVERIFY(!invalid.metaObject());
- int buffer = 0xBAD;
- invalid.construct(&buffer);
- QCOMPARE(buffer, 0xBAD);
-}
-
-void tst_QMetaType::fromType()
-{
- #define FROMTYPE_CHECK(MetaTypeName, MetaTypeId, RealType) \
- QCOMPARE(QMetaType::fromType<RealType>(), QMetaType(MetaTypeId)); \
- QVERIFY(QMetaType::fromType<RealType>() == QMetaType(MetaTypeId)); \
- QVERIFY(!(QMetaType::fromType<RealType>() != QMetaType(MetaTypeId))); \
- if (MetaTypeId != QMetaType::Void) \
- QCOMPARE(QMetaType::fromType<RealType>().id(), MetaTypeId);
-
- FOR_EACH_CORE_METATYPE(FROMTYPE_CHECK)
-
- QVERIFY(QMetaType::fromType<QString>() != QMetaType());
- QCOMPARE(QMetaType(), QMetaType());
- QCOMPARE(QMetaType(QMetaType::UnknownType), QMetaType());
-
- FROMTYPE_CHECK(_, ::qMetaTypeId<Whity<int>>(), Whity<int>)
- #undef FROMTYPE_CHECK
-}
-
-template<char X, typename T = void>
-struct CharTemplate
-{
- struct
- {
- int a;
- } x;
-};
-
-void tst_QMetaType::operatorEq_data()
-{
- QTest::addColumn<QMetaType>("typeA");
- QTest::addColumn<QMetaType>("typeB");
- QTest::addColumn<bool>("eq");
-
- QTest::newRow("String") << QMetaType(QMetaType::QString)
- << QMetaType::fromType<const QString &>() << true;
- QTest::newRow("void1") << QMetaType(QMetaType::UnknownType) << QMetaType::fromType<void>()
- << false;
- QTest::newRow("void2") << QMetaType::fromType<const void>() << QMetaType::fromType<void>()
- << true;
- QTest::newRow("list1") << QMetaType::fromType<QList<const int *>>()
- << QMetaType::fromType<QList<const int *>>() << true;
- QTest::newRow("list2") << QMetaType::fromType<QList<const int *>>()
- << QMetaType::fromType<QList<int *>>() << false;
- QTest::newRow("char1") << QMetaType::fromType<CharTemplate<'>'>>()
- << QMetaType::fromType<CharTemplate<'>', void>>() << true;
- QTest::newRow("annon1") << QMetaType::fromType<decltype(CharTemplate<'>'>::x)>()
- << QMetaType::fromType<decltype(CharTemplate<'>'>::x)>() << true;
- QTest::newRow("annon2") << QMetaType::fromType<decltype(CharTemplate<'>'>::x)>()
- << QMetaType::fromType<decltype(CharTemplate<'<'>::x)>() << false;
-}
-
-void tst_QMetaType::operatorEq()
-{
- QFETCH(QMetaType, typeA);
- QFETCH(QMetaType, typeB);
- QFETCH(bool, eq);
-
- QCOMPARE(typeA == typeB, eq);
- QCOMPARE(typeB == typeA, eq);
- QCOMPARE(typeA != typeB, !eq);
- QCOMPARE(typeB != typeA, !eq);
-}
-
-class WithPrivateDTor {
- ~WithPrivateDTor(){};
-};
-
-struct WithDeletedDtor {
- ~WithDeletedDtor() = delete;
-};
-
-void tst_QMetaType::typesWithInaccessibleDTors()
-{
- // should compile
- Q_UNUSED(QMetaType::fromType<WithPrivateDTor>());
- Q_UNUSED(QMetaType::fromType<WithDeletedDtor>());
-}
-
-void tst_QMetaType::voidIsNotUnknown()
-{
- QMetaType voidType = QMetaType::fromType<void>();
- QMetaType voidType2 = QMetaType(QMetaType::Void);
- QCOMPARE(voidType, voidType2);
- QVERIFY(voidType != QMetaType(QMetaType::UnknownType));
-}
-
-void tst_QMetaType::typeNameNormalization()
-{
- // check the we normalize types the right way
-
-#define CHECK_TYPE_NORMALIZATION(Normalized, ...) \
- do { \
- /*QCOMPARE(QtPrivate::typenameHelper<Type>(), Normalized);*/ \
- QByteArray typeName = QMetaObject::normalizedType(#__VA_ARGS__); \
- QCOMPARE(typeName, Normalized); \
- typeName = QMetaType::fromType<__VA_ARGS__>().name(); \
- QCOMPARE(typeName, Normalized); \
- } while (0)
-
- CHECK_TYPE_NORMALIZATION("QList<QString*const>", QList<QString * const>);
- CHECK_TYPE_NORMALIZATION("QList<const QString*>", QList<const QString * >);
- CHECK_TYPE_NORMALIZATION("QList<const QString*const>", QList<const QString * const>);
- CHECK_TYPE_NORMALIZATION("QList<const QString*>", QList<QString const *>);
- CHECK_TYPE_NORMALIZATION("QList<signed char>", QList<signed char>);
- CHECK_TYPE_NORMALIZATION("QList<uint>", QList<unsigned>);
- CHECK_TYPE_NORMALIZATION("uint", uint);
- CHECK_TYPE_NORMALIZATION("QList<QHash<uint,QString*>>", QList<QHash<unsigned, QString *>>);
- CHECK_TYPE_NORMALIZATION("QList<qlonglong>", QList<qlonglong>);
- CHECK_TYPE_NORMALIZATION("QList<qulonglong>", QList<qulonglong>);
- CHECK_TYPE_NORMALIZATION("QList<qlonglong>", QList<long long>);
- CHECK_TYPE_NORMALIZATION("QList<qulonglong>", QList<unsigned long long>);
- CHECK_TYPE_NORMALIZATION("QList<qulonglong*>", QList<unsigned long long *>);
- CHECK_TYPE_NORMALIZATION("QList<ulong>", QList<long unsigned >);
-#ifdef Q_CC_MSVC
- CHECK_TYPE_NORMALIZATION("qulonglong", __int64 unsigned);
-#endif
- CHECK_TYPE_NORMALIZATION("std::pair<const QString&&,short>", QPair<const QString &&, signed short>);
-
- // The string based normalization doesn't handle aliases, QMetaType::fromType() does
-// CHECK_TYPE_NORMALIZATION("qulonglong", quint64);
- QCOMPARE(QMetaType::fromType<quint64>().name(), "qulonglong");
-}
-
-// Compile-time test, it should be possible to register function pointer types
-class Undefined;
-
-typedef Undefined (*UndefinedFunction0)();
-typedef Undefined (*UndefinedFunction1)(Undefined);
-typedef Undefined (*UndefinedFunction2)(Undefined, Undefined);
-typedef Undefined (*UndefinedFunction3)(Undefined, Undefined, Undefined);
-typedef Undefined (*UndefinedFunction4)(Undefined, Undefined, Undefined, Undefined, Undefined, Undefined, Undefined, Undefined);
-
-Q_DECLARE_METATYPE(UndefinedFunction0);
-Q_DECLARE_METATYPE(UndefinedFunction1);
-Q_DECLARE_METATYPE(UndefinedFunction2);
-Q_DECLARE_METATYPE(UndefinedFunction3);
-Q_DECLARE_METATYPE(UndefinedFunction4);
-
QTEST_MAIN(tst_QMetaType)
#include "tst_qmetatype.moc"
diff --git a/tests/auto/corelib/kernel/qmetatype/tst_qmetatype.h b/tests/auto/corelib/kernel/qmetatype/tst_qmetatype.h
index 43a099de17..2a0e177be1 100644
--- a/tests/auto/corelib/kernel/qmetatype/tst_qmetatype.h
+++ b/tests/auto/corelib/kernel/qmetatype/tst_qmetatype.h
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2016 The Qt Company Ltd.
+** Copyright (C) 2021 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the test suite of the Qt Toolkit.
@@ -26,273 +26,207 @@
**
****************************************************************************/
-// Used by both tst_qmetatype and tst_qsettings
+#include <QtCore>
+#include <QTest>
+#include "tst_qmetatype_common.h"
+#include "tst_qvariant_common.h"
-#ifndef TST_QMETATYPE_H
-#define TST_QMETATYPE_H
-
-#include <qmetatype.h>
-#include <float.h>
-
-#define FOR_EACH_PRIMITIVE_METATYPE(F) \
- QT_FOR_EACH_STATIC_PRIMITIVE_TYPE(F) \
- QT_FOR_EACH_STATIC_CORE_POINTER(F) \
+struct MessageHandlerCustom : public MessageHandler
+{
+ MessageHandlerCustom(const int typeId)
+ : MessageHandler(typeId, handler)
+ {}
+ static void handler(QtMsgType, const QMessageLogContext &, const QString &msg)
+ {
+ QCOMPARE(msg.trimmed(), expectedMessage.trimmed());
+ }
+ inline static QString expectedMessage;
+};
-#define FOR_EACH_COMPLEX_CORE_METATYPE(F) \
- QT_FOR_EACH_STATIC_CORE_CLASS(F) \
- QT_FOR_EACH_STATIC_CORE_TEMPLATE(F)
+class tst_QMetaType: public QObject
+{
+ Q_OBJECT
+ Q_PROPERTY(QList<QVariant> prop READ prop WRITE setProp)
+
+public:
+ struct GadgetPropertyType {
+ QByteArray type;
+ QByteArray name;
+ QVariant testData;
+ };
+
+ tst_QMetaType() { propList << 42 << "Hello"; }
+
+ QList<QVariant> prop() const { return propList; }
+ void setProp(const QList<QVariant> &list) { propList = list; }
+
+private:
+ void registerGadget(const char * name, const QList<GadgetPropertyType> &gadgetProperties);
+ QList<QVariant> propList;
+
+private slots:
+ void defined();
+ void threadSafety();
+ void namespaces();
+ void id();
+ void qMetaTypeId();
+ void properties();
+ void normalizedTypes();
+ void typeName_data();
+ void typeName();
+ void type_data();
+ void type();
+ void type_fromSubString_data();
+ void type_fromSubString();
+ void create_data();
+ void create();
+ void createCopy_data();
+ void createCopy();
+ void sizeOf_data();
+ void sizeOf();
+ void sizeOfStaticLess_data();
+ void sizeOfStaticLess();
+ void alignOf_data();
+ void alignOf();
+ void flags_data();
+ void flags();
+ void flagsStaticLess_data();
+ void flagsStaticLess();
+ void flagsBinaryCompatibility6_0_data();
+ void flagsBinaryCompatibility6_0();
+ void construct_data();
+ void construct();
+ void typedConstruct();
+ void constructCopy_data();
+ void constructCopy();
+ void typedefs();
+ void registerType();
+ void isRegistered_data();
+ void isRegistered();
+ void isRegisteredStaticLess_data();
+ void isRegisteredStaticLess();
+ void isEnum();
+ void automaticTemplateRegistration();
+ void saveAndLoadBuiltin_data();
+ void saveAndLoadBuiltin();
+ void saveAndLoadCustom();
+ void metaObject_data();
+ void metaObject();
+ void constexprMetaTypeIds();
+
+ // tst_qmetatype2.cpp
+ void constRefs();
+ void convertCustomType_data();
+ void convertCustomType();
+ void compareCustomEqualOnlyType();
+ void customDebugStream();
+ void unknownType();
+ void fromType();
+ void operatorEq_data();
+ void operatorEq();
+ void typesWithInaccessibleDTors();
+ void voidIsNotUnknown();
+ void typeNameNormalization();
+};
+
+template <typename T>
+struct Whity { T t; Whity() {} };
+
+Q_DECLARE_METATYPE(Whity<int>)
+Q_DECLARE_METATYPE(Whity<double>)
+
+#if !defined(Q_CC_CLANG) && defined(Q_CC_GNU) && Q_CC_GNU < 501
+QT_BEGIN_NAMESPACE
+Q_DECLARE_TYPEINFO(Whity<double>, Q_RELOCATABLE_TYPE);
+QT_END_NAMESPACE
+#endif
-#define FOR_EACH_CORE_METATYPE(F) \
- FOR_EACH_PRIMITIVE_METATYPE(F) \
- FOR_EACH_COMPLEX_CORE_METATYPE(F) \
+struct CustomConvertibleType
+{
+ explicit CustomConvertibleType(const QVariant &foo = QVariant()) : m_foo(foo) {}
+ virtual ~CustomConvertibleType() {}
+ QString toString() const { return m_foo.toString(); }
+ operator QPoint() const { return QPoint(12, 34); }
+ template<typename To>
+ To convert() const { return s_value.value<To>();}
+ template<typename To>
+ To convertOk(bool *ok) const { *ok = s_ok; return s_value.value<To>();}
+
+ QVariant m_foo;
+ inline static QVariant s_value;
+ inline static bool s_ok = true;
+
+ friend bool operator<(const CustomConvertibleType &lhs, const CustomConvertibleType &rhs)
+ { return lhs.m_foo.toString() < rhs.m_foo.toString(); }
+ friend bool operator==(const CustomConvertibleType &lhs, const CustomConvertibleType &rhs)
+ { return lhs.m_foo == rhs.m_foo; }
+ friend bool operator!=(const CustomConvertibleType &lhs, const CustomConvertibleType &rhs)
+ { return !operator==(lhs, rhs); }
+};
+
+struct CustomConvertibleType2
+{
+ // implicit
+ CustomConvertibleType2(const CustomConvertibleType &t = CustomConvertibleType())
+ : m_foo(t.m_foo) {}
+ virtual ~CustomConvertibleType2() {}
-template <int ID>
-struct MetaEnumToType {};
+ QVariant m_foo;
-#define DEFINE_META_ENUM_TO_TYPE(MetaTypeName, MetaTypeId, RealType) \
-template<> \
-struct MetaEnumToType<QMetaType::MetaTypeName> { \
- typedef RealType Type; \
+ friend bool operator==(const CustomConvertibleType2 &lhs, const CustomConvertibleType2 &rhs)
+ { return lhs.m_foo == rhs.m_foo; }
+ friend bool operator!=(const CustomConvertibleType2 &lhs, const CustomConvertibleType2 &rhs)
+ { return !operator==(lhs, rhs); }
};
-FOR_EACH_CORE_METATYPE(DEFINE_META_ENUM_TO_TYPE)
-#undef DEFINE_META_ENUM_TO_TYPE
-template <int ID>
-struct DefaultValueFactory
+struct CustomDebugStreamableType
{
- typedef typename MetaEnumToType<ID>::Type Type;
- static Type *create() { return new Type; }
-};
+ QString toString() const { return "test"; }
-template <>
-struct DefaultValueFactory<QMetaType::Void>
-{
- typedef MetaEnumToType<QMetaType::Void>::Type Type;
- static Type *create() { return 0; }
+ friend QDebug operator<<(QDebug dbg, const CustomDebugStreamableType&)
+ {
+ return dbg << "string-content";
+ }
};
-template <int ID>
-struct DefaultValueTraits
+struct CustomDebugStreamableType2
{
- // By default we assume that a default-constructed value (new T) is
- // initialized; e.g. QCOMPARE(*(new T), *(new T)) should succeed
- enum { IsInitialized = true };
+ QString toString() const { return "test"; }
};
-#define DEFINE_NON_INITIALIZED_DEFAULT_VALUE_TRAITS(MetaTypeName, MetaTypeId, RealType) \
-template<> struct DefaultValueTraits<QMetaType::MetaTypeName> { \
- enum { IsInitialized = false }; \
-};
-// Primitive types (int et al) aren't initialized
-FOR_EACH_PRIMITIVE_METATYPE(DEFINE_NON_INITIALIZED_DEFAULT_VALUE_TRAITS)
-#undef DEFINE_NON_INITIALIZED_DEFAULT_VALUE_TRAITS
+struct CustomEqualsOnlyType
+{
+ explicit CustomEqualsOnlyType(int value = 0) : val(value) {}
+ virtual ~CustomEqualsOnlyType() {}
-template <int ID>
-struct TestValueFactory {};
+ int val;
-template<> struct TestValueFactory<QMetaType::Void> {
- static void *create() { return 0; }
+ friend bool operator==(const CustomEqualsOnlyType &lhs, const CustomEqualsOnlyType &rhs)
+ { return lhs.val == rhs.val;}
+ friend bool operator!=(const CustomEqualsOnlyType &lhs, const CustomEqualsOnlyType &rhs)
+ { return !operator==(lhs, rhs); }
};
-template<> struct TestValueFactory<QMetaType::QString> {
- static QString *create() { return new QString(QString::fromLatin1("QString")); }
-};
-template<> struct TestValueFactory<QMetaType::Int> {
- static int *create() { return new int(INT_MIN); }
-};
-template<> struct TestValueFactory<QMetaType::UInt> {
- static uint *create() { return new uint(UINT_MAX); }
-};
-template<> struct TestValueFactory<QMetaType::Bool> {
- static bool *create() { return new bool(true); }
-};
-template<> struct TestValueFactory<QMetaType::Double> {
- static double *create() { return new double(DBL_MIN); }
-};
-template<> struct TestValueFactory<QMetaType::QByteArray> {
- static QByteArray *create() { return new QByteArray(QByteArray("QByteArray")); }
-};
-template<> struct TestValueFactory<QMetaType::QByteArrayList> {
- static QByteArrayList *create() { return new QByteArrayList(QByteArrayList() << "Q" << "Byte" << "Array" << "List"); }
-};
-template<> struct TestValueFactory<QMetaType::QVariantMap> {
- static QVariantMap *create() { return new QVariantMap(); }
-};
-template<> struct TestValueFactory<QMetaType::QVariantHash> {
- static QVariantHash *create() { return new QVariantHash(); }
-};
-template<> struct TestValueFactory<QMetaType::QVariantPair> {
- static QVariantPair *create() { return new QVariantPair(); }
-};
+static_assert(QTypeTraits::has_operator_equal_v<CustomEqualsOnlyType>);
+static_assert(!QTypeTraits::has_operator_less_than_v<CustomEqualsOnlyType>);
-template<> struct TestValueFactory<QMetaType::QVariantList> {
- static QVariantList *create() { return new QVariantList(QVariantList() << 123 << "Q" << "Variant" << "List"); }
-};
-template<> struct TestValueFactory<QMetaType::QChar> {
- static QChar *create() { return new QChar(QChar('q')); }
-};
-template<> struct TestValueFactory<QMetaType::Long> {
- static long *create() { return new long(LONG_MIN); }
-};
-template<> struct TestValueFactory<QMetaType::Short> {
- static short *create() { return new short(SHRT_MIN); }
-};
-template<> struct TestValueFactory<QMetaType::Char> {
- static char *create() { return new char('c'); }
-};
-template<> struct TestValueFactory<QMetaType::Char16> {
- static char16_t *create() { return new char16_t('c'); }
-};
-template<> struct TestValueFactory<QMetaType::Char32> {
- static char32_t *create() { return new char32_t('c'); }
-};
-template<> struct TestValueFactory<QMetaType::ULong> {
- static ulong *create() { return new ulong(ULONG_MAX); }
-};
-template<> struct TestValueFactory<QMetaType::UShort> {
- static ushort *create() { return new ushort(USHRT_MAX); }
-};
-template<> struct TestValueFactory<QMetaType::SChar> {
- static signed char *create() { return new signed char(CHAR_MIN); }
-};
-template<> struct TestValueFactory<QMetaType::UChar> {
- static uchar *create() { return new uchar(UCHAR_MAX); }
-};
-template<> struct TestValueFactory<QMetaType::Float> {
- static float *create() { return new float(FLT_MIN); }
-};
-template<> struct TestValueFactory<QMetaType::QObjectStar> {
- static QObject * *create() { return new QObject *(0); }
-};
-template<> struct TestValueFactory<QMetaType::VoidStar> {
- static void * *create() { return new void *(0); }
-};
-template<> struct TestValueFactory<QMetaType::LongLong> {
- static qlonglong *create() { return new qlonglong(LLONG_MIN); }
-};
-template<> struct TestValueFactory<QMetaType::ULongLong> {
- static qulonglong *create() { return new qulonglong(ULLONG_MAX); }
-};
-template<> struct TestValueFactory<QMetaType::QStringList> {
- static QStringList *create() { return new QStringList(QStringList() << "Q" << "t"); }
-};
-template<> struct TestValueFactory<QMetaType::QBitArray> {
- static QBitArray *create() { return new QBitArray(QBitArray(256, true)); }
-};
-template<> struct TestValueFactory<QMetaType::QDate> {
- static QDate *create() { return new QDate(QDate::currentDate()); }
-};
-template<> struct TestValueFactory<QMetaType::QTime> {
- static QTime *create() { return new QTime(QTime::currentTime()); }
-};
-template<> struct TestValueFactory<QMetaType::QDateTime> {
- static QDateTime *create() { return new QDateTime(QDateTime::currentDateTime()); }
-};
-template<> struct TestValueFactory<QMetaType::QUrl> {
- static QUrl *create() { return new QUrl("http://www.example.org"); }
-};
-template<> struct TestValueFactory<QMetaType::QLocale> {
- static QLocale *create() { return new QLocale(QLocale::c()); }
-};
-template<> struct TestValueFactory<QMetaType::QRect> {
- static QRect *create() { return new QRect(10, 20, 30, 40); }
-};
-template<> struct TestValueFactory<QMetaType::QRectF> {
- static QRectF *create() { return new QRectF(10, 20, 30, 40); }
-};
-template<> struct TestValueFactory<QMetaType::QSize> {
- static QSize *create() { return new QSize(10, 20); }
-};
-template<> struct TestValueFactory<QMetaType::QSizeF> {
- static QSizeF *create() { return new QSizeF(10, 20); }
-};
-template<> struct TestValueFactory<QMetaType::QLine> {
- static QLine *create() { return new QLine(10, 20, 30, 40); }
-};
-template<> struct TestValueFactory<QMetaType::QLineF> {
- static QLineF *create() { return new QLineF(10, 20, 30, 40); }
-};
-template<> struct TestValueFactory<QMetaType::QPoint> {
- static QPoint *create() { return new QPoint(10, 20); }
-};
-template<> struct TestValueFactory<QMetaType::QPointF> {
- static QPointF *create() { return new QPointF(10, 20); }
-};
-template<> struct TestValueFactory<QMetaType::QEasingCurve> {
- static QEasingCurve *create() { return new QEasingCurve(QEasingCurve::InOutElastic); }
-};
-template<> struct TestValueFactory<QMetaType::QUuid> {
- static QUuid *create() { return new QUuid(); }
-};
-template<> struct TestValueFactory<QMetaType::QModelIndex> {
- static QModelIndex *create() { return new QModelIndex(); }
-};
-template<> struct TestValueFactory<QMetaType::QPersistentModelIndex> {
- static QPersistentModelIndex *create() { return new QPersistentModelIndex(); }
-};
-template<> struct TestValueFactory<QMetaType::Nullptr> {
- static std::nullptr_t *create() { return new std::nullptr_t; }
-};
-template<> struct TestValueFactory<QMetaType::QRegularExpression> {
- static QRegularExpression *create()
- {
-#if QT_CONFIG(regularexpression)
- return new QRegularExpression("abc.*def");
-#else
- return 0;
-#endif
- }
-};
-template<> struct TestValueFactory<QMetaType::QJsonValue> {
- static QJsonValue *create() { return new QJsonValue(123.); }
-};
-template<> struct TestValueFactory<QMetaType::QJsonObject> {
- static QJsonObject *create() {
- QJsonObject *o = new QJsonObject();
- o->insert("a", 123.);
- o->insert("b", true);
- o->insert("c", QJsonValue::Null);
- o->insert("d", QLatin1String("ciao"));
- return o;
- }
-};
-template<> struct TestValueFactory<QMetaType::QJsonArray> {
- static QJsonArray *create() {
- QJsonArray *a = new QJsonArray();
- a->append(123.);
- a->append(true);
- a->append(QJsonValue::Null);
- a->append(QLatin1String("ciao"));
- return a;
- }
-};
-template<> struct TestValueFactory<QMetaType::QJsonDocument> {
- static QJsonDocument *create() {
- return new QJsonDocument(
- QJsonDocument::fromJson("{ 'foo': 123, 'bar': [true, null, 'ciao'] }")
- );
- }
-};
+Q_DECLARE_METATYPE(CustomConvertibleType);
+Q_DECLARE_METATYPE(CustomConvertibleType2);
+Q_DECLARE_METATYPE(CustomDebugStreamableType);
+Q_DECLARE_METATYPE(CustomEqualsOnlyType);
-template<> struct TestValueFactory<QMetaType::QCborSimpleType> {
- static QCborSimpleType *create() { return new QCborSimpleType(QCborSimpleType::True); }
-};
-template<> struct TestValueFactory<QMetaType::QCborValue> {
- static QCborValue *create() { return new QCborValue(123.); }
-};
-template<> struct TestValueFactory<QMetaType::QCborMap> {
- static QCborMap *create() {
- return new QCborMap{{0, 0}, {"Hello", 1}, {1, nullptr}};
- }
-};
-template<> struct TestValueFactory<QMetaType::QCborArray> {
- static QCborArray *create() {
- return new QCborArray{0, 1, -2, 2.5, false, nullptr, "Hello", QByteArray("World") };
- }
-};
+struct CustomMovable {
+ CustomMovable() {}
-template<> struct TestValueFactory<QMetaType::QVariant> {
- static QVariant *create() { return new QVariant(QStringList(QStringList() << "Q" << "t")); }
+ friend bool operator==(const CustomMovable &, const CustomMovable &) { return true; }
+ // needed for QSet<CustomMovable>. We actually check that it makes sense.
+ friend qsizetype qHash(const CustomMovable &, qsizetype seed = 0) { return seed; }
};
-#endif // TST_QMETATYPE_H
+#if !defined(Q_CC_CLANG) && defined(Q_CC_GNU) && Q_CC_GNU < 501
+QT_BEGIN_NAMESPACE
+Q_DECLARE_TYPEINFO(CustomMovable, Q_RELOCATABLE_TYPE);
+QT_END_NAMESPACE
+#endif
+
+Q_DECLARE_METATYPE(CustomMovable);
diff --git a/tests/auto/corelib/kernel/qmetatype/tst_qmetatype2.cpp b/tests/auto/corelib/kernel/qmetatype/tst_qmetatype2.cpp
new file mode 100644
index 0000000000..3c097ad0d8
--- /dev/null
+++ b/tests/auto/corelib/kernel/qmetatype/tst_qmetatype2.cpp
@@ -0,0 +1,483 @@
+/****************************************************************************
+**
+** Copyright (C) 2021 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:GPL-EXCEPT$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "tst_qmetatype.h"
+#include "tst_qvariant_common.h"
+
+#include <QtCore/private/qmetaobjectbuilder_p.h>
+
+void tst_QMetaType::constRefs()
+{
+ QCOMPARE(::qMetaTypeId<const int &>(), ::qMetaTypeId<int>());
+ QCOMPARE(::qMetaTypeId<const QString &>(), ::qMetaTypeId<QString>());
+ QCOMPARE(::qMetaTypeId<const CustomMovable &>(), ::qMetaTypeId<CustomMovable>());
+ QCOMPARE(::qMetaTypeId<const QList<CustomMovable> &>(), ::qMetaTypeId<QList<CustomMovable> >());
+ static_assert(::qMetaTypeId<const int &>() == ::qMetaTypeId<int>());
+}
+
+template<typename T, typename U>
+U convert(const T &t)
+{
+ return t;
+}
+
+template<typename From>
+struct ConvertFunctor
+{
+ CustomConvertibleType operator()(const From& f) const
+ {
+ return CustomConvertibleType(QVariant::fromValue(f));
+ }
+};
+
+template<typename From, typename To>
+bool hasRegisteredConverterFunction()
+{
+ return QMetaType::hasRegisteredConverterFunction<From, To>();
+}
+
+template<typename From, typename To>
+void testCustomTypeNotYetConvertible()
+{
+ QVERIFY((!hasRegisteredConverterFunction<From, To>()));
+ QVERIFY((!QVariant::fromValue<From>(From()).template canConvert<To>()));
+}
+
+template<typename From, typename To>
+void testCustomTypeConvertible()
+{
+ QVERIFY((hasRegisteredConverterFunction<From, To>()));
+ QVERIFY((QVariant::fromValue<From>(From()).template canConvert<To>()));
+}
+
+void customTypeNotYetConvertible()
+{
+ testCustomTypeNotYetConvertible<CustomConvertibleType, QString>();
+ testCustomTypeNotYetConvertible<CustomConvertibleType, bool>();
+ testCustomTypeNotYetConvertible<CustomConvertibleType, int>();
+ testCustomTypeNotYetConvertible<CustomConvertibleType, double>();
+ testCustomTypeNotYetConvertible<CustomConvertibleType, float>();
+ testCustomTypeNotYetConvertible<CustomConvertibleType, QRect>();
+ testCustomTypeNotYetConvertible<CustomConvertibleType, QRectF>();
+ testCustomTypeNotYetConvertible<CustomConvertibleType, QPoint>();
+ testCustomTypeNotYetConvertible<CustomConvertibleType, QPointF>();
+ testCustomTypeNotYetConvertible<CustomConvertibleType, QSize>();
+ testCustomTypeNotYetConvertible<CustomConvertibleType, QSizeF>();
+ testCustomTypeNotYetConvertible<CustomConvertibleType, QLine>();
+ testCustomTypeNotYetConvertible<CustomConvertibleType, QLineF>();
+ testCustomTypeNotYetConvertible<CustomConvertibleType, QChar>();
+ testCustomTypeNotYetConvertible<QString, CustomConvertibleType>();
+ testCustomTypeNotYetConvertible<bool, CustomConvertibleType>();
+ testCustomTypeNotYetConvertible<int, CustomConvertibleType>();
+ testCustomTypeNotYetConvertible<double, CustomConvertibleType>();
+ testCustomTypeNotYetConvertible<float, CustomConvertibleType>();
+ testCustomTypeNotYetConvertible<QRect, CustomConvertibleType>();
+ testCustomTypeNotYetConvertible<QRectF, CustomConvertibleType>();
+ testCustomTypeNotYetConvertible<QPoint, CustomConvertibleType>();
+ testCustomTypeNotYetConvertible<QPointF, CustomConvertibleType>();
+ testCustomTypeNotYetConvertible<QSize, CustomConvertibleType>();
+ testCustomTypeNotYetConvertible<QSizeF, CustomConvertibleType>();
+ testCustomTypeNotYetConvertible<QLine, CustomConvertibleType>();
+ testCustomTypeNotYetConvertible<QLineF, CustomConvertibleType>();
+ testCustomTypeNotYetConvertible<QChar, CustomConvertibleType>();
+ testCustomTypeNotYetConvertible<CustomConvertibleType, CustomConvertibleType2>();
+}
+
+void registerCustomTypeConversions()
+{
+ QVERIFY((QMetaType::registerConverter<CustomConvertibleType, QString>(&CustomConvertibleType::convertOk<QString>)));
+ QVERIFY((QMetaType::registerConverter<CustomConvertibleType, bool>(&CustomConvertibleType::convert<bool>)));
+ QVERIFY((QMetaType::registerConverter<CustomConvertibleType, int>(&CustomConvertibleType::convertOk<int>)));
+ QVERIFY((QMetaType::registerConverter<CustomConvertibleType, double>(&CustomConvertibleType::convert<double>)));
+ QVERIFY((QMetaType::registerConverter<CustomConvertibleType, float>(&CustomConvertibleType::convertOk<float>)));
+ QVERIFY((QMetaType::registerConverter<CustomConvertibleType, QRect>(&CustomConvertibleType::convert<QRect>)));
+ QVERIFY((QMetaType::registerConverter<CustomConvertibleType, QRectF>(&CustomConvertibleType::convertOk<QRectF>)));
+ QVERIFY((QMetaType::registerConverter<CustomConvertibleType, QPoint>(convert<CustomConvertibleType,QPoint>)));
+ QVERIFY((QMetaType::registerConverter<CustomConvertibleType, QPointF>(&CustomConvertibleType::convertOk<QPointF>)));
+ QVERIFY((QMetaType::registerConverter<CustomConvertibleType, QSize>(&CustomConvertibleType::convert<QSize>)));
+ QVERIFY((QMetaType::registerConverter<CustomConvertibleType, QSizeF>(&CustomConvertibleType::convertOk<QSizeF>)));
+ QVERIFY((QMetaType::registerConverter<CustomConvertibleType, QLine>(&CustomConvertibleType::convert<QLine>)));
+ QVERIFY((QMetaType::registerConverter<CustomConvertibleType, QLineF>(&CustomConvertibleType::convertOk<QLineF>)));
+ QVERIFY((QMetaType::registerConverter<CustomConvertibleType, QChar>(&CustomConvertibleType::convert<QChar>)));
+ QVERIFY((QMetaType::registerConverter<QString, CustomConvertibleType>(ConvertFunctor<QString>())));
+ QVERIFY((QMetaType::registerConverter<bool, CustomConvertibleType>(ConvertFunctor<bool>())));
+ QVERIFY((QMetaType::registerConverter<int, CustomConvertibleType>(ConvertFunctor<int>())));
+ QVERIFY((QMetaType::registerConverter<double, CustomConvertibleType>(ConvertFunctor<double>())));
+ QVERIFY((QMetaType::registerConverter<float, CustomConvertibleType>(ConvertFunctor<float>())));
+ QVERIFY((QMetaType::registerConverter<QRect, CustomConvertibleType>(ConvertFunctor<QRect>())));
+ QVERIFY((QMetaType::registerConverter<QRectF, CustomConvertibleType>(ConvertFunctor<QRectF>())));
+ QVERIFY((QMetaType::registerConverter<QPoint, CustomConvertibleType>(ConvertFunctor<QPoint>())));
+ QVERIFY((QMetaType::registerConverter<QPointF, CustomConvertibleType>(ConvertFunctor<QPointF>())));
+ QVERIFY((QMetaType::registerConverter<QSize, CustomConvertibleType>(ConvertFunctor<QSize>())));
+ QVERIFY((QMetaType::registerConverter<QSizeF, CustomConvertibleType>(ConvertFunctor<QSizeF>())));
+ QVERIFY((QMetaType::registerConverter<QLine, CustomConvertibleType>(ConvertFunctor<QLine>())));
+ QVERIFY((QMetaType::registerConverter<QLineF, CustomConvertibleType>(ConvertFunctor<QLineF>())));
+ QVERIFY((QMetaType::registerConverter<QChar, CustomConvertibleType>(ConvertFunctor<QChar>())));
+ QVERIFY((QMetaType::registerConverter<CustomConvertibleType, CustomConvertibleType2>()));
+ QTest::ignoreMessage(QtWarningMsg, "Type conversion already registered from type CustomConvertibleType to type CustomConvertibleType2");
+ QVERIFY((!QMetaType::registerConverter<CustomConvertibleType, CustomConvertibleType2>()));
+}
+
+void tst_QMetaType::convertCustomType_data()
+{
+ customTypeNotYetConvertible();
+ registerCustomTypeConversions();
+
+ QTest::addColumn<bool>("ok");
+ QTest::addColumn<QString>("testQString");
+ QTest::addColumn<bool>("testBool");
+ QTest::addColumn<int>("testInt");
+ QTest::addColumn<double>("testDouble");
+ QTest::addColumn<float>("testFloat");
+ QTest::addColumn<QRect>("testQRect");
+ QTest::addColumn<QRectF>("testQRectF");
+ QTest::addColumn<QPoint>("testQPoint");
+ QTest::addColumn<QPointF>("testQPointF");
+ QTest::addColumn<QSize>("testQSize");
+ QTest::addColumn<QSizeF>("testQSizeF");
+ QTest::addColumn<QLine>("testQLine");
+ QTest::addColumn<QLineF>("testQLineF");
+ QTest::addColumn<QChar>("testQChar");
+ QTest::addColumn<CustomConvertibleType>("testCustom");
+
+ QTest::newRow("default") << true
+ << QString::fromLatin1("string") << true << 15
+ << double(3.14) << float(3.6) << QRect(1, 2, 3, 4)
+ << QRectF(1.4, 1.9, 10.9, 40.2) << QPoint(12, 34)
+ << QPointF(9.2, 2.7) << QSize(4, 9) << QSizeF(3.3, 9.8)
+ << QLine(3, 9, 29, 4) << QLineF(38.9, 28.9, 102.3, 0.0)
+ << QChar('Q') << CustomConvertibleType(QString::fromLatin1("test"));
+ QTest::newRow("not ok") << false
+ << QString::fromLatin1("string") << true << 15
+ << double(3.14) << float(3.6) << QRect(1, 2, 3, 4)
+ << QRectF(1.4, 1.9, 10.9, 40.2) << QPoint(12, 34)
+ << QPointF(9.2, 2.7) << QSize(4, 9) << QSizeF(3.3, 9.8)
+ << QLine(3, 9, 29, 4) << QLineF()
+ << QChar('Q') << CustomConvertibleType(42);
+}
+
+void tst_QMetaType::convertCustomType()
+{
+ QFETCH(bool, ok);
+ CustomConvertibleType::s_ok = ok;
+
+ CustomConvertibleType t;
+ QVariant v = QVariant::fromValue(t);
+ QFETCH(QString, testQString);
+ CustomConvertibleType::s_value = testQString;
+ QCOMPARE(v.toString(), ok ? testQString : QString());
+ QCOMPARE(v.value<QString>(), ok ? testQString : QString());
+ QVERIFY(CustomConvertibleType::s_value.canConvert<CustomConvertibleType>());
+ QCOMPARE((CustomConvertibleType::s_value.value<CustomConvertibleType>().m_foo.toString()), testQString);
+
+ QFETCH(bool, testBool);
+ CustomConvertibleType::s_value = testBool;
+ QCOMPARE(v.toBool(), testBool);
+ QCOMPARE(v.value<bool>(), testBool);
+ QCOMPARE((CustomConvertibleType::s_value.value<CustomConvertibleType>().m_foo.toBool()), testBool);
+
+ QFETCH(int, testInt);
+ CustomConvertibleType::s_value = testInt;
+ QCOMPARE(v.toInt(), ok ? testInt : 0);
+ QCOMPARE(v.value<int>(), ok ? testInt : 0);
+ QCOMPARE((CustomConvertibleType::s_value.value<CustomConvertibleType>().m_foo.toInt()), testInt);
+
+ QFETCH(double, testDouble);
+ CustomConvertibleType::s_value = testDouble;
+ QCOMPARE(v.toDouble(), testDouble);
+ QCOMPARE(v.value<double>(), testDouble);
+ QCOMPARE((CustomConvertibleType::s_value.value<CustomConvertibleType>().m_foo.toDouble()), testDouble);
+
+ QFETCH(float, testFloat);
+ CustomConvertibleType::s_value = testFloat;
+ QCOMPARE(v.toFloat(), ok ? testFloat : 0.0);
+ QCOMPARE(v.value<float>(), ok ? testFloat : 0.0);
+ QCOMPARE((CustomConvertibleType::s_value.value<CustomConvertibleType>().m_foo.toFloat()), testFloat);
+
+ QFETCH(QRect, testQRect);
+ CustomConvertibleType::s_value = testQRect;
+ QCOMPARE(v.toRect(), testQRect);
+ QCOMPARE(v.value<QRect>(), testQRect);
+ QCOMPARE((CustomConvertibleType::s_value.value<CustomConvertibleType>().m_foo.toRect()), testQRect);
+
+ QFETCH(QRectF, testQRectF);
+ CustomConvertibleType::s_value = testQRectF;
+ QCOMPARE(v.toRectF(), ok ? testQRectF : QRectF());
+ QCOMPARE(v.value<QRectF>(), ok ? testQRectF : QRectF());
+ QCOMPARE((CustomConvertibleType::s_value.value<CustomConvertibleType>().m_foo.toRectF()), testQRectF);
+
+ QFETCH(QPoint, testQPoint);
+ CustomConvertibleType::s_value = testQPoint;
+ QCOMPARE(v.toPoint(), testQPoint);
+ QCOMPARE(v.value<QPoint>(), testQPoint);
+ QCOMPARE((CustomConvertibleType::s_value.value<CustomConvertibleType>().m_foo.toPoint()), testQPoint);
+
+ QFETCH(QPointF, testQPointF);
+ CustomConvertibleType::s_value = testQPointF;
+ QCOMPARE(v.toPointF(), ok ? testQPointF : QPointF());
+ QCOMPARE(v.value<QPointF>(), ok ? testQPointF : QPointF());
+ QCOMPARE((CustomConvertibleType::s_value.value<CustomConvertibleType>().m_foo.toPointF()), testQPointF);
+
+ QFETCH(QSize, testQSize);
+ CustomConvertibleType::s_value = testQSize;
+ QCOMPARE(v.toSize(), testQSize);
+ QCOMPARE(v.value<QSize>(), testQSize);
+ QCOMPARE((CustomConvertibleType::s_value.value<CustomConvertibleType>().m_foo.toSize()), testQSize);
+
+ QFETCH(QSizeF, testQSizeF);
+ CustomConvertibleType::s_value = testQSizeF;
+ QCOMPARE(v.toSizeF(), ok ? testQSizeF : QSizeF());
+ QCOMPARE(v.value<QSizeF>(), ok ? testQSizeF : QSizeF());
+ QCOMPARE((CustomConvertibleType::s_value.value<CustomConvertibleType>().m_foo.toSizeF()), testQSizeF);
+
+ QFETCH(QLine, testQLine);
+ CustomConvertibleType::s_value = testQLine;
+ QCOMPARE(v.toLine(), testQLine);
+ QCOMPARE(v.value<QLine>(), testQLine);
+ QCOMPARE((CustomConvertibleType::s_value.value<CustomConvertibleType>().m_foo.toLine()), testQLine);
+
+ QFETCH(QLineF, testQLineF);
+ CustomConvertibleType::s_value = testQLineF;
+ QCOMPARE(v.toLineF(), ok ? testQLineF : QLineF());
+ QCOMPARE(v.value<QLineF>(), ok ? testQLineF : QLineF());
+ QCOMPARE((CustomConvertibleType::s_value.value<CustomConvertibleType>().m_foo.toLineF()), testQLineF);
+
+ QFETCH(QChar, testQChar);
+ CustomConvertibleType::s_value = testQChar;
+ QCOMPARE(v.toChar(), testQChar);
+ QCOMPARE((CustomConvertibleType::s_value.value<CustomConvertibleType>().m_foo.toChar()), testQChar);
+
+ QFETCH(CustomConvertibleType, testCustom);
+ v = QVariant::fromValue(testCustom);
+ QVERIFY(v.canConvert(::qMetaTypeId<CustomConvertibleType2>()));
+ QCOMPARE(v.value<CustomConvertibleType2>().m_foo, testCustom.m_foo);
+}
+
+void tst_QMetaType::compareCustomEqualOnlyType()
+{
+ QMetaType type = QMetaType::fromType<CustomEqualsOnlyType>();
+
+ CustomEqualsOnlyType val50(50);
+ CustomEqualsOnlyType val100(100);
+ CustomEqualsOnlyType val100x(100);
+
+ QVariant variant50 = QVariant::fromValue(val50);
+ QVariant variant100 = QVariant::fromValue(val100);
+ QVariant variant100x = QVariant::fromValue(val100x);
+
+ QVERIFY(variant50 != variant100);
+ QVERIFY(variant50 != variant100x);
+ QVERIFY(variant100 != variant50);
+ QVERIFY(variant100x != variant50);
+ QCOMPARE(variant100, variant100x);
+ QCOMPARE(variant100, variant100);
+
+ // check QMetaType::compare works/doesn't crash for equals only comparators
+ auto cmp = type.compare(variant50.constData(), variant50.constData());
+ QCOMPARE(cmp, QPartialOrdering::Unordered);
+ bool equals = type.equals(variant50.constData(), variant50.constData());
+ QVERIFY(equals);
+
+ cmp = type.compare(variant100.constData(), variant100x.constData());
+ QCOMPARE(cmp, QPartialOrdering::Unordered);
+ equals = type.equals(variant100.constData(), variant100x.constData());
+ QVERIFY(equals);
+
+ cmp = type.compare(variant50.constData(), variant100.constData());
+ QCOMPARE(cmp, QPartialOrdering::Unordered);
+ equals = type.equals(variant50.constData(), variant100.constData());
+ QVERIFY(!equals);
+
+ //check QMetaType::equals for type w/o equals comparator being registered
+ CustomMovable movable1;
+ CustomMovable movable2;
+ type = QMetaType::fromType<CustomMovable>();
+ equals = type.equals(&movable1, &movable2);
+}
+
+void tst_QMetaType::customDebugStream()
+{
+ MessageHandlerCustom handler(::qMetaTypeId<CustomDebugStreamableType>());
+ QVariant v1 = QVariant::fromValue(CustomDebugStreamableType());
+ handler.expectedMessage = "QVariant(CustomDebugStreamableType, string-content)";
+ qDebug() << v1;
+
+ MessageHandlerCustom handler2(::qMetaTypeId<CustomDebugStreamableType2>());
+ QMetaType::registerConverter<CustomDebugStreamableType2, QString>(&CustomDebugStreamableType2::toString);
+ handler2.expectedMessage = "QVariant(CustomDebugStreamableType2, \"test\")";
+ QVariant v2 = QVariant::fromValue(CustomDebugStreamableType2());
+ qDebug() << v2;
+}
+
+void tst_QMetaType::unknownType()
+{
+ QMetaType invalid(QMetaType::UnknownType);
+ QVERIFY(!invalid.create());
+ QVERIFY(!invalid.sizeOf());
+ QVERIFY(!invalid.metaObject());
+ int buffer = 0xBAD;
+ invalid.construct(&buffer);
+ QCOMPARE(buffer, 0xBAD);
+}
+
+void tst_QMetaType::fromType()
+{
+ #define FROMTYPE_CHECK(MetaTypeName, MetaTypeId, RealType) \
+ QCOMPARE(QMetaType::fromType<RealType>(), QMetaType(MetaTypeId)); \
+ QVERIFY(QMetaType::fromType<RealType>() == QMetaType(MetaTypeId)); \
+ QVERIFY(!(QMetaType::fromType<RealType>() != QMetaType(MetaTypeId))); \
+ if (MetaTypeId != QMetaType::Void) \
+ QCOMPARE(QMetaType::fromType<RealType>().id(), MetaTypeId);
+
+ FOR_EACH_CORE_METATYPE(FROMTYPE_CHECK)
+
+ QVERIFY(QMetaType::fromType<QString>() != QMetaType());
+ QCOMPARE(QMetaType(), QMetaType());
+ QCOMPARE(QMetaType(QMetaType::UnknownType), QMetaType());
+
+ FROMTYPE_CHECK(_, ::qMetaTypeId<Whity<int>>(), Whity<int>)
+ #undef FROMTYPE_CHECK
+}
+
+template<char X, typename T = void>
+struct CharTemplate
+{
+ struct
+ {
+ int a;
+ } x;
+};
+
+void tst_QMetaType::operatorEq_data()
+{
+ QTest::addColumn<QMetaType>("typeA");
+ QTest::addColumn<QMetaType>("typeB");
+ QTest::addColumn<bool>("eq");
+ QTest::newRow("String") << QMetaType(QMetaType::QString)
+ << QMetaType::fromType<const QString &>() << true;
+ QTest::newRow("void1") << QMetaType(QMetaType::UnknownType) << QMetaType::fromType<void>()
+ << false;
+ QTest::newRow("void2") << QMetaType::fromType<const void>() << QMetaType::fromType<void>()
+ << true;
+ QTest::newRow("list1") << QMetaType::fromType<QList<const int *>>()
+ << QMetaType::fromType<QList<const int *>>() << true;
+ QTest::newRow("list2") << QMetaType::fromType<QList<const int *>>()
+ << QMetaType::fromType<QList<int *>>() << false;
+ QTest::newRow("char1") << QMetaType::fromType<CharTemplate<'>'>>()
+ << QMetaType::fromType<CharTemplate<'>', void>>() << true;
+ QTest::newRow("annon1") << QMetaType::fromType<decltype(CharTemplate<'>'>::x)>()
+ << QMetaType::fromType<decltype(CharTemplate<'>'>::x)>() << true;
+ QTest::newRow("annon2") << QMetaType::fromType<decltype(CharTemplate<'>'>::x)>()
+ << QMetaType::fromType<decltype(CharTemplate<'<'>::x)>() << false;
+}
+
+void tst_QMetaType::operatorEq()
+{
+ QFETCH(QMetaType, typeA);
+ QFETCH(QMetaType, typeB);
+ QFETCH(bool, eq);
+
+ QCOMPARE(typeA == typeB, eq);
+ QCOMPARE(typeB == typeA, eq);
+ QCOMPARE(typeA != typeB, !eq);
+ QCOMPARE(typeB != typeA, !eq);
+}
+
+class WithPrivateDTor {
+ ~WithPrivateDTor(){};
+};
+
+struct WithDeletedDtor {
+ ~WithDeletedDtor() = delete;
+};
+
+void tst_QMetaType::typesWithInaccessibleDTors()
+{
+ // should compile
+ Q_UNUSED(QMetaType::fromType<WithPrivateDTor>());
+ Q_UNUSED(QMetaType::fromType<WithDeletedDtor>());
+}
+
+void tst_QMetaType::voidIsNotUnknown()
+{
+ QMetaType voidType = QMetaType::fromType<void>();
+ QMetaType voidType2 = QMetaType(QMetaType::Void);
+ QCOMPARE(voidType, voidType2);
+ QVERIFY(voidType != QMetaType(QMetaType::UnknownType));
+}
+
+void tst_QMetaType::typeNameNormalization()
+{
+ // check the we normalize types the right way
+#define CHECK_TYPE_NORMALIZATION(Normalized, ...) \
+ do { \
+ /*QCOMPARE(QtPrivate::typenameHelper<Type>(), Normalized);*/ \
+ QByteArray typeName = QMetaObject::normalizedType(#__VA_ARGS__); \
+ QCOMPARE(typeName, Normalized); \
+ typeName = QMetaType::fromType<__VA_ARGS__>().name(); \
+ QCOMPARE(typeName, Normalized); \
+ } while (0)
+
+ CHECK_TYPE_NORMALIZATION("QList<QString*const>", QList<QString * const>);
+ CHECK_TYPE_NORMALIZATION("QList<const QString*>", QList<const QString * >);
+ CHECK_TYPE_NORMALIZATION("QList<const QString*const>", QList<const QString * const>);
+ CHECK_TYPE_NORMALIZATION("QList<const QString*>", QList<QString const *>);
+ CHECK_TYPE_NORMALIZATION("QList<signed char>", QList<signed char>);
+ CHECK_TYPE_NORMALIZATION("QList<uint>", QList<unsigned>);
+ CHECK_TYPE_NORMALIZATION("uint", uint);
+ CHECK_TYPE_NORMALIZATION("QList<QHash<uint,QString*>>", QList<QHash<unsigned, QString *>>);
+ CHECK_TYPE_NORMALIZATION("QList<qlonglong>", QList<qlonglong>);
+ CHECK_TYPE_NORMALIZATION("QList<qulonglong>", QList<qulonglong>);
+ CHECK_TYPE_NORMALIZATION("QList<qlonglong>", QList<long long>);
+ CHECK_TYPE_NORMALIZATION("QList<qulonglong>", QList<unsigned long long>);
+ CHECK_TYPE_NORMALIZATION("QList<qulonglong*>", QList<unsigned long long *>);
+ CHECK_TYPE_NORMALIZATION("QList<ulong>", QList<long unsigned >);
+#ifdef Q_CC_MSVC
+ CHECK_TYPE_NORMALIZATION("qulonglong", __int64 unsigned);
+#endif
+ CHECK_TYPE_NORMALIZATION("std::pair<const QString&&,short>", QPair<const QString &&, signed short>);
+
+ // The string based normalization doesn't handle aliases, QMetaType::fromType() does
+// CHECK_TYPE_NORMALIZATION("qulonglong", quint64);
+ QCOMPARE(QMetaType::fromType<quint64>().name(), "qulonglong");
+}
+
+// Compile-time test, it should be possible to register function pointer types
+class Undefined;
+
+typedef Undefined (*UndefinedFunction0)();
+typedef Undefined (*UndefinedFunction1)(Undefined);
+typedef Undefined (*UndefinedFunction2)(Undefined, Undefined);
+typedef Undefined (*UndefinedFunction3)(Undefined, Undefined, Undefined);
+typedef Undefined (*UndefinedFunction4)(Undefined, Undefined, Undefined, Undefined, Undefined, Undefined, Undefined, Undefined);
+
+Q_DECLARE_METATYPE(UndefinedFunction0);
+Q_DECLARE_METATYPE(UndefinedFunction1);
+Q_DECLARE_METATYPE(UndefinedFunction2);
+Q_DECLARE_METATYPE(UndefinedFunction3);
+Q_DECLARE_METATYPE(UndefinedFunction4);
diff --git a/tests/auto/corelib/kernel/qmetatype/tst_qmetatype_common.h b/tests/auto/corelib/kernel/qmetatype/tst_qmetatype_common.h
new file mode 100644
index 0000000000..6193ca93b8
--- /dev/null
+++ b/tests/auto/corelib/kernel/qmetatype/tst_qmetatype_common.h
@@ -0,0 +1,298 @@
+/****************************************************************************
+**
+** Copyright (C) 2021 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:GPL-EXCEPT$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+// Used by both tst_qmetatype and tst_qsettings
+
+#ifndef TST_QMETATYPE_H
+#define TST_QMETATYPE_H
+
+#include <qmetatype.h>
+#include <float.h>
+
+#define FOR_EACH_PRIMITIVE_METATYPE(F) \
+ QT_FOR_EACH_STATIC_PRIMITIVE_TYPE(F) \
+ QT_FOR_EACH_STATIC_CORE_POINTER(F) \
+
+#define FOR_EACH_COMPLEX_CORE_METATYPE(F) \
+ QT_FOR_EACH_STATIC_CORE_CLASS(F) \
+ QT_FOR_EACH_STATIC_CORE_TEMPLATE(F)
+
+#define FOR_EACH_CORE_METATYPE(F) \
+ FOR_EACH_PRIMITIVE_METATYPE(F) \
+ FOR_EACH_COMPLEX_CORE_METATYPE(F) \
+
+template <int ID>
+struct MetaEnumToType {};
+
+#define DEFINE_META_ENUM_TO_TYPE(MetaTypeName, MetaTypeId, RealType) \
+template<> \
+struct MetaEnumToType<QMetaType::MetaTypeName> { \
+ typedef RealType Type; \
+};
+FOR_EACH_CORE_METATYPE(DEFINE_META_ENUM_TO_TYPE)
+#undef DEFINE_META_ENUM_TO_TYPE
+
+template <int ID>
+struct DefaultValueFactory
+{
+ typedef typename MetaEnumToType<ID>::Type Type;
+ static Type *create() { return new Type; }
+};
+
+template <>
+struct DefaultValueFactory<QMetaType::Void>
+{
+ typedef MetaEnumToType<QMetaType::Void>::Type Type;
+ static Type *create() { return 0; }
+};
+
+template <int ID>
+struct DefaultValueTraits
+{
+ // By default we assume that a default-constructed value (new T) is
+ // initialized; e.g. QCOMPARE(*(new T), *(new T)) should succeed
+ enum { IsInitialized = true };
+};
+
+#define DEFINE_NON_INITIALIZED_DEFAULT_VALUE_TRAITS(MetaTypeName, MetaTypeId, RealType) \
+template<> struct DefaultValueTraits<QMetaType::MetaTypeName> { \
+ enum { IsInitialized = false }; \
+};
+// Primitive types (int et al) aren't initialized
+FOR_EACH_PRIMITIVE_METATYPE(DEFINE_NON_INITIALIZED_DEFAULT_VALUE_TRAITS)
+#undef DEFINE_NON_INITIALIZED_DEFAULT_VALUE_TRAITS
+
+template <int ID>
+struct TestValueFactory {};
+
+template<> struct TestValueFactory<QMetaType::Void> {
+ static void *create() { return 0; }
+};
+
+template<> struct TestValueFactory<QMetaType::QString> {
+ static QString *create() { return new QString(QString::fromLatin1("QString")); }
+};
+template<> struct TestValueFactory<QMetaType::Int> {
+ static int *create() { return new int(INT_MIN); }
+};
+template<> struct TestValueFactory<QMetaType::UInt> {
+ static uint *create() { return new uint(UINT_MAX); }
+};
+template<> struct TestValueFactory<QMetaType::Bool> {
+ static bool *create() { return new bool(true); }
+};
+template<> struct TestValueFactory<QMetaType::Double> {
+ static double *create() { return new double(DBL_MIN); }
+};
+template<> struct TestValueFactory<QMetaType::QByteArray> {
+ static QByteArray *create() { return new QByteArray(QByteArray("QByteArray")); }
+};
+template<> struct TestValueFactory<QMetaType::QByteArrayList> {
+ static QByteArrayList *create() { return new QByteArrayList(QByteArrayList() << "Q" << "Byte" << "Array" << "List"); }
+};
+template<> struct TestValueFactory<QMetaType::QVariantMap> {
+ static QVariantMap *create() { return new QVariantMap(); }
+};
+template<> struct TestValueFactory<QMetaType::QVariantHash> {
+ static QVariantHash *create() { return new QVariantHash(); }
+};
+template<> struct TestValueFactory<QMetaType::QVariantPair> {
+ static QVariantPair *create() { return new QVariantPair(); }
+};
+
+template<> struct TestValueFactory<QMetaType::QVariantList> {
+ static QVariantList *create() { return new QVariantList(QVariantList() << 123 << "Q" << "Variant" << "List"); }
+};
+template<> struct TestValueFactory<QMetaType::QChar> {
+ static QChar *create() { return new QChar(QChar('q')); }
+};
+template<> struct TestValueFactory<QMetaType::Long> {
+ static long *create() { return new long(LONG_MIN); }
+};
+template<> struct TestValueFactory<QMetaType::Short> {
+ static short *create() { return new short(SHRT_MIN); }
+};
+template<> struct TestValueFactory<QMetaType::Char> {
+ static char *create() { return new char('c'); }
+};
+template<> struct TestValueFactory<QMetaType::Char16> {
+ static char16_t *create() { return new char16_t('c'); }
+};
+template<> struct TestValueFactory<QMetaType::Char32> {
+ static char32_t *create() { return new char32_t('c'); }
+};
+template<> struct TestValueFactory<QMetaType::ULong> {
+ static ulong *create() { return new ulong(ULONG_MAX); }
+};
+template<> struct TestValueFactory<QMetaType::UShort> {
+ static ushort *create() { return new ushort(USHRT_MAX); }
+};
+template<> struct TestValueFactory<QMetaType::SChar> {
+ static signed char *create() { return new signed char(CHAR_MIN); }
+};
+template<> struct TestValueFactory<QMetaType::UChar> {
+ static uchar *create() { return new uchar(UCHAR_MAX); }
+};
+template<> struct TestValueFactory<QMetaType::Float> {
+ static float *create() { return new float(FLT_MIN); }
+};
+template<> struct TestValueFactory<QMetaType::QObjectStar> {
+ static QObject * *create() { return new QObject *(0); }
+};
+template<> struct TestValueFactory<QMetaType::VoidStar> {
+ static void * *create() { return new void *(0); }
+};
+template<> struct TestValueFactory<QMetaType::LongLong> {
+ static qlonglong *create() { return new qlonglong(LLONG_MIN); }
+};
+template<> struct TestValueFactory<QMetaType::ULongLong> {
+ static qulonglong *create() { return new qulonglong(ULLONG_MAX); }
+};
+template<> struct TestValueFactory<QMetaType::QStringList> {
+ static QStringList *create() { return new QStringList(QStringList() << "Q" << "t"); }
+};
+template<> struct TestValueFactory<QMetaType::QBitArray> {
+ static QBitArray *create() { return new QBitArray(QBitArray(256, true)); }
+};
+template<> struct TestValueFactory<QMetaType::QDate> {
+ static QDate *create() { return new QDate(QDate::currentDate()); }
+};
+template<> struct TestValueFactory<QMetaType::QTime> {
+ static QTime *create() { return new QTime(QTime::currentTime()); }
+};
+template<> struct TestValueFactory<QMetaType::QDateTime> {
+ static QDateTime *create() { return new QDateTime(QDateTime::currentDateTime()); }
+};
+template<> struct TestValueFactory<QMetaType::QUrl> {
+ static QUrl *create() { return new QUrl("http://www.example.org"); }
+};
+template<> struct TestValueFactory<QMetaType::QLocale> {
+ static QLocale *create() { return new QLocale(QLocale::c()); }
+};
+template<> struct TestValueFactory<QMetaType::QRect> {
+ static QRect *create() { return new QRect(10, 20, 30, 40); }
+};
+template<> struct TestValueFactory<QMetaType::QRectF> {
+ static QRectF *create() { return new QRectF(10, 20, 30, 40); }
+};
+template<> struct TestValueFactory<QMetaType::QSize> {
+ static QSize *create() { return new QSize(10, 20); }
+};
+template<> struct TestValueFactory<QMetaType::QSizeF> {
+ static QSizeF *create() { return new QSizeF(10, 20); }
+};
+template<> struct TestValueFactory<QMetaType::QLine> {
+ static QLine *create() { return new QLine(10, 20, 30, 40); }
+};
+template<> struct TestValueFactory<QMetaType::QLineF> {
+ static QLineF *create() { return new QLineF(10, 20, 30, 40); }
+};
+template<> struct TestValueFactory<QMetaType::QPoint> {
+ static QPoint *create() { return new QPoint(10, 20); }
+};
+template<> struct TestValueFactory<QMetaType::QPointF> {
+ static QPointF *create() { return new QPointF(10, 20); }
+};
+template<> struct TestValueFactory<QMetaType::QEasingCurve> {
+ static QEasingCurve *create() { return new QEasingCurve(QEasingCurve::InOutElastic); }
+};
+template<> struct TestValueFactory<QMetaType::QUuid> {
+ static QUuid *create() { return new QUuid(); }
+};
+template<> struct TestValueFactory<QMetaType::QModelIndex> {
+ static QModelIndex *create() { return new QModelIndex(); }
+};
+template<> struct TestValueFactory<QMetaType::QPersistentModelIndex> {
+ static QPersistentModelIndex *create() { return new QPersistentModelIndex(); }
+};
+template<> struct TestValueFactory<QMetaType::Nullptr> {
+ static std::nullptr_t *create() { return new std::nullptr_t; }
+};
+template<> struct TestValueFactory<QMetaType::QRegularExpression> {
+ static QRegularExpression *create()
+ {
+#if QT_CONFIG(regularexpression)
+ return new QRegularExpression("abc.*def");
+#else
+ return 0;
+#endif
+ }
+};
+template<> struct TestValueFactory<QMetaType::QJsonValue> {
+ static QJsonValue *create() { return new QJsonValue(123.); }
+};
+template<> struct TestValueFactory<QMetaType::QJsonObject> {
+ static QJsonObject *create() {
+ QJsonObject *o = new QJsonObject();
+ o->insert("a", 123.);
+ o->insert("b", true);
+ o->insert("c", QJsonValue::Null);
+ o->insert("d", QLatin1String("ciao"));
+ return o;
+ }
+};
+template<> struct TestValueFactory<QMetaType::QJsonArray> {
+ static QJsonArray *create() {
+ QJsonArray *a = new QJsonArray();
+ a->append(123.);
+ a->append(true);
+ a->append(QJsonValue::Null);
+ a->append(QLatin1String("ciao"));
+ return a;
+ }
+};
+template<> struct TestValueFactory<QMetaType::QJsonDocument> {
+ static QJsonDocument *create() {
+ return new QJsonDocument(
+ QJsonDocument::fromJson("{ 'foo': 123, 'bar': [true, null, 'ciao'] }")
+ );
+ }
+};
+
+template<> struct TestValueFactory<QMetaType::QCborSimpleType> {
+ static QCborSimpleType *create() { return new QCborSimpleType(QCborSimpleType::True); }
+};
+template<> struct TestValueFactory<QMetaType::QCborValue> {
+ static QCborValue *create() { return new QCborValue(123.); }
+};
+template<> struct TestValueFactory<QMetaType::QCborMap> {
+ static QCborMap *create() {
+ return new QCborMap{{0, 0}, {"Hello", 1}, {1, nullptr}};
+ }
+};
+template<> struct TestValueFactory<QMetaType::QCborArray> {
+ static QCborArray *create() {
+ return new QCborArray{0, 1, -2, 2.5, false, nullptr, "Hello", QByteArray("World") };
+ }
+};
+
+template<> struct TestValueFactory<QMetaType::QVariant> {
+ static QVariant *create() { return new QVariant(QStringList(QStringList() << "Q" << "t")); }
+};
+
+#endif // TST_QMETATYPE_H
diff --git a/tests/auto/other/qvariant_common/tst_qvariant_common.h b/tests/auto/other/qvariant_common/tst_qvariant_common.h
index 7851bf8dcc..70a44ad10f 100644
--- a/tests/auto/other/qvariant_common/tst_qvariant_common.h
+++ b/tests/auto/other/qvariant_common/tst_qvariant_common.h
@@ -72,11 +72,9 @@ protected:
}
QtMessageHandler oldMsgHandler;
- static int currentId;
- static bool ok;
+ inline static int currentId = {};
+ inline static bool ok = {};
};
-bool MessageHandler::ok;
-int MessageHandler::currentId;
#define TST_QVARIANT_CANCONVERT_DATATABLE_HEADERS \
QTest::addColumn<QVariant>("val"); \