From 6b4f8a68c8da1af7c5be7dc6075b688c9d6ca55f Mon Sep 17 00:00:00 2001 From: Stephen Kelly Date: Sat, 31 Dec 2011 07:25:07 +0100 Subject: [PATCH] Automated metatype definition for template types. MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit If T is defined as a metatype, then QList is too automatically. So for example, no need to use Q_DECLARE_METATYPE(QList) anymore. This is a source compatible change. Change-Id: I2ee8a7b9e28fe6d4775f6a05cce39aca8563e0c5 Reviewed-by: Jędrzej Nowacki Reviewed-by: João Abecasis --- src/corelib/kernel/qmetatype.h | 31 +++++++++++++++ .../corelib/kernel/qmetatype/tst_qmetatype.cpp | 46 ++++++++++++++++++++++ 2 files changed, 77 insertions(+) diff --git a/src/corelib/kernel/qmetatype.h b/src/corelib/kernel/qmetatype.h index bbe4824..03cde9d 100644 --- a/src/corelib/kernel/qmetatype.h +++ b/src/corelib/kernel/qmetatype.h @@ -44,6 +44,7 @@ #include #include +#include #include @@ -501,12 +502,42 @@ QT_FOR_EACH_STATIC_WIDGETS_CLASS(QT_FORWARD_DECLARE_STATIC_TYPES_ITER) #undef QT_FORWARD_DECLARE_STATIC_TYPES_ITER template class QList; +template class QLinkedList; +template class QVector; +template class QQueue; +template class QStack; +template class QSet; +template class QSharedPointer; template class QMap; template class QHash; typedef QList QVariantList; typedef QMap QVariantMap; typedef QHash QVariantHash; +#define Q_DECLARE_METATYPE_TEMPLATE_1ARG(SINGLE_ARG_TEMPLATE) \ +template \ +struct QMetaTypeId< SINGLE_ARG_TEMPLATE > \ +{ \ + enum { \ + Defined = QMetaTypeId2::Defined \ + }; \ + static int qt_metatype_id() \ + { \ + static QBasicAtomicInt metatype_id = Q_BASIC_ATOMIC_INITIALIZER(0); \ + if (!metatype_id.load()) \ + metatype_id.storeRelease(qRegisterMetaType< SINGLE_ARG_TEMPLATE >( QByteArray(QByteArray(#SINGLE_ARG_TEMPLATE "<") + QMetaType::typeName(qMetaTypeId()) + ">"), \ + reinterpret_cast< SINGLE_ARG_TEMPLATE *>(quintptr(-1)))); \ + return metatype_id.loadAcquire(); \ + } \ +}; + +Q_DECLARE_METATYPE_TEMPLATE_1ARG(QList) +Q_DECLARE_METATYPE_TEMPLATE_1ARG(QVector) +Q_DECLARE_METATYPE_TEMPLATE_1ARG(QQueue) +Q_DECLARE_METATYPE_TEMPLATE_1ARG(QStack) +Q_DECLARE_METATYPE_TEMPLATE_1ARG(QSet) +Q_DECLARE_METATYPE_TEMPLATE_1ARG(QSharedPointer) +Q_DECLARE_METATYPE_TEMPLATE_1ARG(QLinkedList) QT_END_NAMESPACE diff --git a/tests/auto/corelib/kernel/qmetatype/tst_qmetatype.cpp b/tests/auto/corelib/kernel/qmetatype/tst_qmetatype.cpp index de93c21..19aa687 100644 --- a/tests/auto/corelib/kernel/qmetatype/tst_qmetatype.cpp +++ b/tests/auto/corelib/kernel/qmetatype/tst_qmetatype.cpp @@ -89,6 +89,7 @@ private slots: void isRegistered(); void unregisterType(); void registerStreamBuiltin(); + void automaticTemplateRegistration(); }; struct Foo { int i; }; @@ -888,5 +889,50 @@ void tst_QMetaType::registerStreamBuiltin() qRegisterMetaTypeStreamOperators("QVariant"); } +Q_DECLARE_METATYPE(QSharedPointer) + +void tst_QMetaType::automaticTemplateRegistration() +{ + { + QList intList; + intList << 42; + QVERIFY(QVariant::fromValue(intList).value >().first() == 42); + QVector > vectorList; + vectorList << intList; + QVERIFY(QVariant::fromValue(vectorList).value > >().first().first() == 42); + } + + { + QList bytearrayList; + bytearrayList << QByteArray("foo"); + QVERIFY(QVariant::fromValue(bytearrayList).value >().first() == QByteArray("foo")); + QVector > vectorList; + vectorList << bytearrayList; + QVERIFY(QVariant::fromValue(vectorList).value > >().first().first() == QByteArray("foo")); + } + + QCOMPARE(::qMetaTypeId(), (int)QMetaType::QVariantList); + QCOMPARE(::qMetaTypeId >(), (int)QMetaType::QVariantList); + + { + QList variantList; + variantList << 42; + QVERIFY(QVariant::fromValue(variantList).value >().first() == 42); + QVector > vectorList; + vectorList << variantList; + QVERIFY(QVariant::fromValue(vectorList).value > >().first().first() == 42); + } + + { + QList > sharedPointerList; + QObject *testObject = new QObject; + sharedPointerList << QSharedPointer(testObject); + QVERIFY(QVariant::fromValue(sharedPointerList).value > >().first() == testObject); + QVector > > vectorList; + vectorList << sharedPointerList; + QVERIFY(QVariant::fromValue(vectorList).value > > >().first().first() == testObject); + } +} + QTEST_MAIN(tst_QMetaType) #include "tst_qmetatype.moc" -- 2.7.4