summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorStephen Kelly <stephen.kelly@kdab.com>2011-12-31 07:25:07 +0100
committerQt by Nokia <qt-info@nokia.com>2012-01-26 13:15:38 +0100
commit6b4f8a68c8da1af7c5be7dc6075b688c9d6ca55f (patch)
tree408b925b542fbedcbdfe80175f7fb7260ef5b71a
parentd39d8b49d5724659321b2ba42b8159da57f8adce (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.h31
-rw-r--r--tests/auto/corelib/kernel/qmetatype/tst_qmetatype.cpp46
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"