QMetaType: Automatic registration of Q_GADGET and Q_ENUM types

Change-Id: If43dcc2b77fea5ae3ec40cc847467fc21fbd2c83
Reviewed-by: Marc Mutz <marc.mutz@kdab.com>
Reviewed-by: Simon Hausmann <simon.hausmann@theqtcompany.com>
bb10
Olivier Goffart 2015-02-07 14:12:30 +01:00 committed by Olivier Goffart (Woboq GmbH)
parent 071716f2da
commit 3cf8e426f4
2 changed files with 67 additions and 3 deletions

View File

@ -1545,7 +1545,10 @@ namespace QtPrivate
Q_CORE_EXPORT bool isBuiltinType(const QByteArray &type);
} // namespace QtPrivate
template <typename T, bool = QtPrivate::IsPointerToTypeDerivedFromQObject<T>::Value>
template <typename T, int =
QtPrivate::IsPointerToTypeDerivedFromQObject<T>::Value ? QMetaType::PointerToQObject :
QtPrivate::IsGadgetHelper<T>::Value ? QMetaType::IsGadget :
QtPrivate::IsQEnumHelper<T>::Value ? QMetaType::IsEnumeration : 0>
struct QMetaTypeIdQObject
{
enum {
@ -1725,8 +1728,9 @@ QT_DEPRECATED inline Q_DECL_CONSTEXPR int qRegisterMetaType(T *)
#endif
#endif
#ifndef QT_NO_QOBJECT
template <typename T>
struct QMetaTypeIdQObject<T*, /* isPointerToTypeDerivedFromQObject */ true>
struct QMetaTypeIdQObject<T*, QMetaType::PointerToQObject>
{
enum {
Defined = 1
@ -1749,6 +1753,53 @@ struct QMetaTypeIdQObject<T*, /* isPointerToTypeDerivedFromQObject */ true>
}
};
template <typename T>
struct QMetaTypeIdQObject<T, QMetaType::IsGadget>
{
enum {
Defined = 1
};
static int qt_metatype_id()
{
static QBasicAtomicInt metatype_id = Q_BASIC_ATOMIC_INITIALIZER(0);
if (const int id = metatype_id.loadAcquire())
return id;
const char * const cName = T::staticMetaObject.className();
const int newId = qRegisterNormalizedMetaType<T>(
cName,
reinterpret_cast<T*>(quintptr(-1)));
metatype_id.storeRelease(newId);
return newId;
}
};
template <typename T>
struct QMetaTypeIdQObject<T, QMetaType::IsEnumeration>
{
enum {
Defined = 1
};
static int qt_metatype_id()
{
static QBasicAtomicInt metatype_id = Q_BASIC_ATOMIC_INITIALIZER(0);
if (const int id = metatype_id.loadAcquire())
return id;
const char *eName = qt_getEnumName(T());
const char *cName = qt_getEnumMetaObject(T())->className();
QByteArray typeName;
typeName.reserve(int(strlen(cName) + 2 + strlen(eName)));
typeName.append(cName).append("::").append(eName);
const int newId = qRegisterNormalizedMetaType<T>(
typeName,
reinterpret_cast<T*>(quintptr(-1)));
metatype_id.storeRelease(newId);
return newId;
}
};
#endif
#ifndef QT_NO_DATASTREAM
template <typename T>
inline int qRegisterMetaTypeStreamOperators()

View File

@ -136,6 +136,11 @@ public:
: QObject(parent)
{
}
enum CustomQEnum { Val1, Val2 };
Q_ENUM(CustomQEnum)
};
class CustomGadget {
Q_GADGET
};
class CustomNonQObject {};
@ -146,10 +151,13 @@ void tst_QMetaType::defined()
QCOMPARE(int(QMetaTypeId2<Foo>::Defined), 0);
QCOMPARE(int(QMetaTypeId2<void*>::Defined), 1);
QCOMPARE(int(QMetaTypeId2<int*>::Defined), 0);
QVERIFY(QMetaTypeId2<CustomQObject*>::Defined);
QCOMPARE(int(QMetaTypeId2<CustomQObject::CustomQEnum>::Defined), 1);
QCOMPARE(int(QMetaTypeId2<CustomGadget>::Defined), 1);
QVERIFY(int(QMetaTypeId2<CustomQObject*>::Defined));
QVERIFY(!QMetaTypeId2<CustomQObject>::Defined);
QVERIFY(!QMetaTypeId2<CustomNonQObject>::Defined);
QVERIFY(!QMetaTypeId2<CustomNonQObject*>::Defined);
QVERIFY(!QMetaTypeId2<CustomGadget*>::Defined);
}
struct Bar
@ -378,6 +386,11 @@ void tst_QMetaType::typeName_data()
QTest::newRow("QMap<int,int>") << static_cast<QMetaType::Type>(::qMetaTypeId<QMap<int, int> >()) << QString::fromLatin1("QMap<int,int>");
QTest::newRow("QVector<QList<int>>") << static_cast<QMetaType::Type>(::qMetaTypeId<QVector<QList<int> > >()) << QString::fromLatin1("QVector<QList<int> >");
QTest::newRow("QVector<QMap<int,int>>") << static_cast<QMetaType::Type>(::qMetaTypeId<QVector<QMap<int, int> > >()) << QString::fromLatin1("QVector<QMap<int,int> >");
QTest::newRow("CustomQObject*") << static_cast<QMetaType::Type>(::qMetaTypeId<CustomQObject*>()) << QString::fromLatin1("CustomQObject*");
QTest::newRow("CustomGadget") << static_cast<QMetaType::Type>(::qMetaTypeId<CustomGadget>()) << QString::fromLatin1("CustomGadget");
QTest::newRow("CustomQObject::CustomQEnum") << static_cast<QMetaType::Type>(::qMetaTypeId<CustomQObject::CustomQEnum>()) << QString::fromLatin1("CustomQObject::CustomQEnum");
QTest::newRow("Qt::ArrowType") << static_cast<QMetaType::Type>(::qMetaTypeId<Qt::ArrowType>()) << QString::fromLatin1("Qt::ArrowType");
}
void tst_QMetaType::typeName()