diff options
-rw-r--r-- | src/corelib/kernel/qmetatype.h | 47 | ||||
-rw-r--r-- | tests/auto/corelib/kernel/qmetatype/tst_qmetatype.cpp | 24 |
2 files changed, 62 insertions, 9 deletions
diff --git a/src/corelib/kernel/qmetatype.h b/src/corelib/kernel/qmetatype.h index 3674ebc1a1..5e2e746bbc 100644 --- a/src/corelib/kernel/qmetatype.h +++ b/src/corelib/kernel/qmetatype.h @@ -462,7 +462,8 @@ public: WeakPointerToQObject = 0x40, TrackingPointerToQObject = 0x80, WasDeclaredAsMetaType = 0x100, - IsGadget = 0x200 + IsGadget = 0x200, + PointerToGadget = 0x400 }; Q_DECLARE_FLAGS(TypeFlags, TypeFlag) @@ -1388,6 +1389,19 @@ namespace QtPrivate enum { Value = sizeof(checkType(&T::qt_check_for_QGADGET_macro)) == sizeof(void *) }; }; + template<typename T, typename Enable = void> + struct IsPointerToGadgetHelper { enum { Value = false }; }; + + template<typename T> + struct IsPointerToGadgetHelper<T*, typename T::QtGadgetHelper> + { + using BaseType = T; + template <typename X> + static char checkType(void (X::*)()); + static void *checkType(void (T::*)()); + enum { Value = sizeof(checkType(&T::qt_check_for_QGADGET_macro)) == sizeof(void *) }; + }; + template<typename T> char qt_getEnumMetaObject(const T&); @@ -1423,6 +1437,11 @@ namespace QtPrivate static inline const QMetaObject *value() { return &T::staticMetaObject; } }; template<typename T> + struct MetaObjectForType<T, typename QEnableIf<IsPointerToGadgetHelper<T>::Value>::Type> + { + static inline const QMetaObject *value() { return &IsPointerToGadgetHelper<T>::BaseType::staticMetaObject; } + }; + template<typename T> struct MetaObjectForType<T, typename std::enable_if<IsQEnumHelper<T>::Value>::type > { static inline const QMetaObject *value() { return qt_getEnumMetaObject(T()); } @@ -1578,6 +1597,7 @@ namespace QtPrivate template <typename T, int = QtPrivate::IsPointerToTypeDerivedFromQObject<T>::Value ? QMetaType::PointerToQObject : QtPrivate::IsGadgetHelper<T>::Value ? QMetaType::IsGadget : + QtPrivate::IsPointerToGadgetHelper<T>::Value ? QMetaType::PointerToGadget : QtPrivate::IsQEnumHelper<T>::Value ? QMetaType::IsEnumeration : 0> struct QMetaTypeIdQObject { @@ -1631,6 +1651,7 @@ namespace QtPrivate { | (IsTrackingPointerToTypeDerivedFromQObject<T>::Value ? QMetaType::TrackingPointerToQObject : 0) | (std::is_enum<T>::value ? QMetaType::IsEnumeration : 0) | (IsGadgetHelper<T>::Value ? QMetaType::IsGadget : 0) + | (IsPointerToGadgetHelper<T>::Value ? QMetaType::PointerToGadget : 0) }; }; @@ -1798,6 +1819,30 @@ struct QMetaTypeIdQObject<T, QMetaType::IsGadget> }; template <typename T> +struct QMetaTypeIdQObject<T*, QMetaType::PointerToGadget> +{ + 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(); + QByteArray typeName; + typeName.reserve(int(strlen(cName)) + 1); + typeName.append(cName).append('*'); + const int newId = qRegisterNormalizedMetaType<T*>( + typeName, + reinterpret_cast<T**>(quintptr(-1))); + metatype_id.storeRelease(newId); + return newId; + } +}; + +template <typename T> struct QMetaTypeIdQObject<T, QMetaType::IsEnumeration> { enum { diff --git a/tests/auto/corelib/kernel/qmetatype/tst_qmetatype.cpp b/tests/auto/corelib/kernel/qmetatype/tst_qmetatype.cpp index 7d9f56ef38..450bd1cf3f 100644 --- a/tests/auto/corelib/kernel/qmetatype/tst_qmetatype.cpp +++ b/tests/auto/corelib/kernel/qmetatype/tst_qmetatype.cpp @@ -155,7 +155,9 @@ void tst_QMetaType::defined() QCOMPARE(int(QMetaTypeId2<int*>::Defined), 0); QCOMPARE(int(QMetaTypeId2<CustomQObject::CustomQEnum>::Defined), 1); QCOMPARE(int(QMetaTypeId2<CustomGadget>::Defined), 1); + QCOMPARE(int(QMetaTypeId2<CustomGadget*>::Defined), 1); QVERIFY(!QMetaTypeId2<GadgetDerived>::Defined); + QVERIFY(!QMetaTypeId2<GadgetDerived*>::Defined); QVERIFY(int(QMetaTypeId2<CustomQObject*>::Defined)); QVERIFY(!QMetaTypeId2<CustomQObject>::Defined); QVERIFY(!QMetaTypeId2<CustomNonQObject>::Defined); @@ -395,6 +397,7 @@ void tst_QMetaType::typeName_data() QTest::newRow("CustomQObject*") << ::qMetaTypeId<CustomQObject*>() << QString::fromLatin1("CustomQObject*"); QTest::newRow("CustomGadget") << ::qMetaTypeId<CustomGadget>() << QString::fromLatin1("CustomGadget"); + QTest::newRow("CustomGadget*") << ::qMetaTypeId<CustomGadget*>() << QString::fromLatin1("CustomGadget*"); QTest::newRow("CustomQObject::CustomQEnum") << ::qMetaTypeId<CustomQObject::CustomQEnum>() << QString::fromLatin1("CustomQObject::CustomQEnum"); QTest::newRow("Qt::ArrowType") << ::qMetaTypeId<Qt::ArrowType>() << QString::fromLatin1("Qt::ArrowType"); } @@ -1675,6 +1678,7 @@ public: }; Q_DECLARE_METATYPE(MyGadget); +Q_DECLARE_METATYPE(MyGadget*); Q_DECLARE_METATYPE(const QMetaObject *); Q_DECLARE_METATYPE(Qt::ScrollBarPolicy); Q_DECLARE_METATYPE(MyGadget::MyEnum); @@ -1684,16 +1688,18 @@ void tst_QMetaType::metaObject_data() QTest::addColumn<int>("type"); QTest::addColumn<const QMetaObject*>("result"); QTest::addColumn<bool>("isGadget"); + QTest::addColumn<bool>("isGadgetPtr"); QTest::addColumn<bool>("isQObjectPtr"); - QTest::newRow("QObject") << int(QMetaType::QObjectStar) << &QObject::staticMetaObject << false << true; - QTest::newRow("QFile*") << ::qMetaTypeId<QFile*>() << &QFile::staticMetaObject << false << true; - QTest::newRow("MyObject*") << ::qMetaTypeId<MyObject*>() << &MyObject::staticMetaObject << false << true; - QTest::newRow("int") << int(QMetaType::Int) << static_cast<const QMetaObject *>(0) << false << false; - QTest::newRow("QEasingCurve") << ::qMetaTypeId<QEasingCurve>() << &QEasingCurve::staticMetaObject << true << false; - QTest::newRow("MyGadget") << ::qMetaTypeId<MyGadget>() << &MyGadget::staticMetaObject << true << false; - QTest::newRow("MyEnum") << ::qMetaTypeId<MyGadget::MyEnum>() << &MyGadget::staticMetaObject << false << false; - QTest::newRow("Qt::ScrollBarPolicy") << ::qMetaTypeId<Qt::ScrollBarPolicy>() << &QObject::staticQtMetaObject << false << false; + QTest::newRow("QObject") << int(QMetaType::QObjectStar) << &QObject::staticMetaObject << false << false << true; + QTest::newRow("QFile*") << ::qMetaTypeId<QFile*>() << &QFile::staticMetaObject << false << false << true; + QTest::newRow("MyObject*") << ::qMetaTypeId<MyObject*>() << &MyObject::staticMetaObject << false << false << true; + QTest::newRow("int") << int(QMetaType::Int) << static_cast<const QMetaObject *>(0) << false << false << false; + QTest::newRow("QEasingCurve") << ::qMetaTypeId<QEasingCurve>() << &QEasingCurve::staticMetaObject << true << false << false; + QTest::newRow("MyGadget") << ::qMetaTypeId<MyGadget>() << &MyGadget::staticMetaObject << true << false << false; + QTest::newRow("MyGadget*") << ::qMetaTypeId<MyGadget*>() << &MyGadget::staticMetaObject << false << true << false; + QTest::newRow("MyEnum") << ::qMetaTypeId<MyGadget::MyEnum>() << &MyGadget::staticMetaObject << false << false << false; + QTest::newRow("Qt::ScrollBarPolicy") << ::qMetaTypeId<Qt::ScrollBarPolicy>() << &QObject::staticQtMetaObject << false << false << false; } @@ -1702,12 +1708,14 @@ void tst_QMetaType::metaObject() QFETCH(int, type); QFETCH(const QMetaObject *, result); QFETCH(bool, isGadget); + QFETCH(bool, isGadgetPtr); QFETCH(bool, isQObjectPtr); QCOMPARE(QMetaType::metaObjectForType(type), result); QMetaType mt(type); QCOMPARE(mt.metaObject(), result); QCOMPARE(!!(mt.flags() & QMetaType::IsGadget), isGadget); + QCOMPARE(!!(mt.flags() & QMetaType::PointerToGadget), isGadgetPtr); QCOMPARE(!!(mt.flags() & QMetaType::PointerToQObject), isQObjectPtr); } |