diff options
author | Stephen Kelly <stephen.kelly@kdab.com> | 2011-12-31 07:25:07 +0100 |
---|---|---|
committer | Qt by Nokia <qt-info@nokia.com> | 2012-01-26 13:15:38 +0100 |
commit | 6b4f8a68c8da1af7c5be7dc6075b688c9d6ca55f (patch) | |
tree | 408b925b542fbedcbdfe80175f7fb7260ef5b71a | |
parent | d39d8b49d5724659321b2ba42b8159da57f8adce (diff) |
Automated metatype definition for template types.
If T is defined as a metatype, then QList<T> is too automatically.
So for example, no need to use
Q_DECLARE_METATYPE(QList<int>)
anymore.
This is a source compatible change.
Change-Id: I2ee8a7b9e28fe6d4775f6a05cce39aca8563e0c5
Reviewed-by: Jędrzej Nowacki <jedrzej.nowacki@nokia.com>
Reviewed-by: João Abecasis <joao.abecasis@nokia.com>
-rw-r--r-- | src/corelib/kernel/qmetatype.h | 31 | ||||
-rw-r--r-- | tests/auto/corelib/kernel/qmetatype/tst_qmetatype.cpp | 46 |
2 files changed, 77 insertions, 0 deletions
diff --git a/src/corelib/kernel/qmetatype.h b/src/corelib/kernel/qmetatype.h index bbe482428f..03cde9d257 100644 --- a/src/corelib/kernel/qmetatype.h +++ b/src/corelib/kernel/qmetatype.h @@ -44,6 +44,7 @@ #include <QtCore/qglobal.h> #include <QtCore/qatomic.h> +#include <QtCore/qbytearray.h> #include <new> @@ -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 T> class QList; +template <class T> class QLinkedList; +template <class T> class QVector; +template <class T> class QQueue; +template <class T> class QStack; +template <class T> class QSet; +template <class T> class QSharedPointer; template <class T1, class T2> class QMap; template <class T1, class T2> class QHash; typedef QList<QVariant> QVariantList; typedef QMap<QString, QVariant> QVariantMap; typedef QHash<QString, QVariant> QVariantHash; +#define Q_DECLARE_METATYPE_TEMPLATE_1ARG(SINGLE_ARG_TEMPLATE) \ +template <typename T> \ +struct QMetaTypeId< SINGLE_ARG_TEMPLATE<T> > \ +{ \ + enum { \ + Defined = QMetaTypeId2<T>::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<T> >( QByteArray(QByteArray(#SINGLE_ARG_TEMPLATE "<") + QMetaType::typeName(qMetaTypeId<T>()) + ">"), \ + reinterpret_cast< SINGLE_ARG_TEMPLATE<T> *>(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 de93c21d43..19aa6877b2 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>("QVariant"); } +Q_DECLARE_METATYPE(QSharedPointer<QObject>) + +void tst_QMetaType::automaticTemplateRegistration() +{ + { + QList<int> intList; + intList << 42; + QVERIFY(QVariant::fromValue(intList).value<QList<int> >().first() == 42); + QVector<QList<int> > vectorList; + vectorList << intList; + QVERIFY(QVariant::fromValue(vectorList).value<QVector<QList<int> > >().first().first() == 42); + } + + { + QList<QByteArray> bytearrayList; + bytearrayList << QByteArray("foo"); + QVERIFY(QVariant::fromValue(bytearrayList).value<QList<QByteArray> >().first() == QByteArray("foo")); + QVector<QList<QByteArray> > vectorList; + vectorList << bytearrayList; + QVERIFY(QVariant::fromValue(vectorList).value<QVector<QList<QByteArray> > >().first().first() == QByteArray("foo")); + } + + QCOMPARE(::qMetaTypeId<QVariantList>(), (int)QMetaType::QVariantList); + QCOMPARE(::qMetaTypeId<QList<QVariant> >(), (int)QMetaType::QVariantList); + + { + QList<QVariant> variantList; + variantList << 42; + QVERIFY(QVariant::fromValue(variantList).value<QList<QVariant> >().first() == 42); + QVector<QList<QVariant> > vectorList; + vectorList << variantList; + QVERIFY(QVariant::fromValue(vectorList).value<QVector<QList<QVariant> > >().first().first() == 42); + } + + { + QList<QSharedPointer<QObject> > sharedPointerList; + QObject *testObject = new QObject; + sharedPointerList << QSharedPointer<QObject>(testObject); + QVERIFY(QVariant::fromValue(sharedPointerList).value<QList<QSharedPointer<QObject> > >().first() == testObject); + QVector<QList<QSharedPointer<QObject> > > vectorList; + vectorList << sharedPointerList; + QVERIFY(QVariant::fromValue(vectorList).value<QVector<QList<QSharedPointer<QObject> > > >().first().first() == testObject); + } +} + QTEST_MAIN(tst_QMetaType) #include "tst_qmetatype.moc" |