diff options
-rw-r--r-- | src/corelib/kernel/qmetatype.h | 84 | ||||
-rw-r--r-- | tests/auto/corelib/kernel/qmetatype/tst_qmetatype.cpp | 35 |
2 files changed, 63 insertions, 56 deletions
diff --git a/src/corelib/kernel/qmetatype.h b/src/corelib/kernel/qmetatype.h index 86cd15def8..8ef1bb8faa 100644 --- a/src/corelib/kernel/qmetatype.h +++ b/src/corelib/kernel/qmetatype.h @@ -698,7 +698,7 @@ public: { } - QPairVariantInterfaceImpl() + constexpr QPairVariantInterfaceImpl() : _pair(nullptr) , _getFirst(nullptr) , _getSecond(nullptr) @@ -818,36 +818,44 @@ namespace QtPrivate template<typename T, typename Enable = void> struct MetaObjectForType { - static constexpr inline const QMetaObject *value() { return nullptr; } + static constexpr const QMetaObject *value() { return nullptr; } + using MetaObjectFn = const QMetaObject *(*)(const QMetaTypeInterface *); + static constexpr MetaObjectFn metaObjectFunction = nullptr; }; #ifndef QT_NO_QOBJECT template<> struct MetaObjectForType<void> { - static constexpr inline const QMetaObject *value() { return nullptr; } + static constexpr const QMetaObject *value() { return nullptr; } + using MetaObjectFn = const QMetaObject *(*)(const QMetaTypeInterface *); + static constexpr MetaObjectFn metaObjectFunction = nullptr; }; template<typename T> struct MetaObjectForType<T*, typename std::enable_if<IsPointerToTypeDerivedFromQObject<T*>::Value>::type> { - static constexpr inline const QMetaObject *value() { return &T::staticMetaObject; } + static constexpr const QMetaObject *value() { return &T::staticMetaObject; } + static constexpr const QMetaObject *metaObjectFunction(const QMetaTypeInterface *) { return &T::staticMetaObject; } }; template<typename T> struct MetaObjectForType<T, typename std::enable_if<IsGadgetHelper<T>::IsGadgetOrDerivedFrom>::type> { - static constexpr inline const QMetaObject *value() { return &T::staticMetaObject; } + static constexpr const QMetaObject *value() { return &T::staticMetaObject; } + static constexpr const QMetaObject *metaObjectFunction(const QMetaTypeInterface *) { return &T::staticMetaObject; } }; template<typename T> struct MetaObjectForType<T, typename std::enable_if<IsPointerToGadgetHelper<T>::IsGadgetOrDerivedFrom>::type> { - static constexpr inline const QMetaObject *value() + static constexpr const QMetaObject *value() { return &IsPointerToGadgetHelper<T>::BaseType::staticMetaObject; } + static constexpr const QMetaObject *metaObjectFunction(const QMetaTypeInterface *) { return value(); } }; template<typename T> struct MetaObjectForType<T, typename std::enable_if<IsQEnumHelper<T>::Value>::type > { - static constexpr inline const QMetaObject *value() { return qt_getEnumMetaObject(T()); } + static constexpr const QMetaObject *value() { return qt_getEnumMetaObject(T()); } + static constexpr const QMetaObject *metaObjectFunction(const QMetaTypeInterface *) { return value(); } }; #endif @@ -1590,7 +1598,10 @@ public: uint size; uint flags; mutable QBasicAtomicInt typeId; - const QMetaObject *metaObject; + + using MetaObjectFn = const QMetaObject *(*)(const QMetaTypeInterface *); + const MetaObjectFn metaObjectFn; + const char *name; using DefaultCtrFn = void (*)(const QMetaTypeInterface *, void *); @@ -2224,42 +2235,27 @@ public: template<typename T> struct QMetaTypeInterfaceWrapper { - static inline constexpr QMetaTypeInterface create() - { - return { - /*.revision=*/ 0, - /*.alignment=*/ alignof(T), - /*.size=*/ sizeof(T), - /*.flags=*/ QMetaTypeTypeFlags<T>::Flags, - /*.typeId=*/ BuiltinMetaType<T>::value, - /*.metaObject=*/ MetaObjectForType<T>::value(), - /*.name=*/ QMetaTypeForType<T>::getName(), - /*.defaultCtr=*/ QMetaTypeForType<T>::getDefaultCtr(), - /*.copyCtr=*/ QMetaTypeForType<T>::getCopyCtr(), - /*.moveCtr=*/ QMetaTypeForType<T>::getMoveCtr(), - /*.dtor=*/ QMetaTypeForType<T>::getDtor(), - /*.equals=*/ QEqualityOperatorForType<T>::equals, - /*.lessThan=*/ QLessThanOperatorForType<T>::lessThan, - /*.debugStream=*/ QDebugStreamOperatorForType<T>::debugStream, - /*.dataStreamOut=*/ QDataStreamOperatorForType<T>::dataStreamOut, - /*.dataStreamIn=*/ QDataStreamOperatorForType<T>::dataStreamIn, - /*.legacyRegisterOp=*/ QMetaTypeForType<T>::getLegacyRegister() - }; - } - -#ifdef Q_OS_WIN - // MSVC produces link errors when the metaType is constexpr - static const QMetaTypeInterface metaType; -#else - static constexpr const QMetaTypeInterface metaType = create(); -#endif + static inline constexpr const QMetaTypeInterface metaType = { + /*.revision=*/ 0, + /*.alignment=*/ alignof(T), + /*.size=*/ sizeof(T), + /*.flags=*/ QMetaTypeTypeFlags<T>::Flags, + /*.typeId=*/ BuiltinMetaType<T>::value, + /*.metaObjectFn=*/ MetaObjectForType<T>::metaObjectFunction, + /*.name=*/ QMetaTypeForType<T>::getName(), + /*.defaultCtr=*/ QMetaTypeForType<T>::getDefaultCtr(), + /*.copyCtr=*/ QMetaTypeForType<T>::getCopyCtr(), + /*.moveCtr=*/ QMetaTypeForType<T>::getMoveCtr(), + /*.dtor=*/ QMetaTypeForType<T>::getDtor(), + /*.equals=*/ QEqualityOperatorForType<T>::equals, + /*.lessThan=*/ QLessThanOperatorForType<T>::lessThan, + /*.debugStream=*/ QDebugStreamOperatorForType<T>::debugStream, + /*.dataStreamOut=*/ QDataStreamOperatorForType<T>::dataStreamOut, + /*.dataStreamIn=*/ QDataStreamOperatorForType<T>::dataStreamIn, + /*.legacyRegisterOp=*/ QMetaTypeForType<T>::getLegacyRegister() + }; }; -#ifdef Q_OS_WIN -template<typename T> -const QMetaTypeInterface QMetaTypeInterfaceWrapper<T>::metaType - = QMetaTypeInterfaceWrapper<T>::create(); -#endif template<> class QMetaTypeInterfaceWrapper<void> @@ -2272,7 +2268,7 @@ public: /*.size=*/ 0, /*.flags=*/ 0, /*.typeId=*/ BuiltinMetaType<void>::value, - /*.metaObject=*/ nullptr, + /*.metaObjectFn=*/ nullptr, /*.name=*/ "void", /*.defaultCtr=*/ nullptr, /*.copyCtr=*/ nullptr, @@ -2395,7 +2391,7 @@ constexpr QMetaType::TypeFlags QMetaType::flags() const constexpr const QMetaObject *QMetaType::metaObject() const { - return d_ptr ? d_ptr->metaObject : nullptr; + return d_ptr && d_ptr->metaObjectFn ? d_ptr->metaObjectFn(d_ptr) : nullptr; } template<typename... T> diff --git a/tests/auto/corelib/kernel/qmetatype/tst_qmetatype.cpp b/tests/auto/corelib/kernel/qmetatype/tst_qmetatype.cpp index f3d95285dc..503e9b0e33 100644 --- a/tests/auto/corelib/kernel/qmetatype/tst_qmetatype.cpp +++ b/tests/auto/corelib/kernel/qmetatype/tst_qmetatype.cpp @@ -413,19 +413,30 @@ void tst_QMetaType::registerGadget(const char *name, const QList<GadgetPropertyT meta->d.static_metacall = &GadgetsStaticMetacallFunction; meta->d.superdata = nullptr; const auto flags = QMetaType::IsGadget | QMetaType::NeedsConstruction | QMetaType::NeedsDestruction; - using TypeInfo = QtPrivate::QMetaTypeInterface; + struct TypeInfo : public QtPrivate::QMetaTypeInterface + { + QMetaObject *mo; + }; + auto typeInfo = new TypeInfo { - 0, alignof(GenericGadgetType), sizeof(GenericGadgetType), uint(flags), 0, meta, name, - [](const TypeInfo *self, void *where) { GadgetTypedConstructor(self->typeId, where, nullptr); }, - [](const TypeInfo *self, void *where, const void *copy) { GadgetTypedConstructor(self->typeId, where, copy); }, - [](const TypeInfo *self, void *where, void *copy) { GadgetTypedConstructor(self->typeId, where, copy); }, - [](const TypeInfo *self, void *ptr) { GadgetTypedDestructor(self->typeId, ptr); }, - nullptr, - nullptr, - nullptr, - GadgetSaveOperator, - GadgetLoadOperator, - nullptr + { + 0, alignof(GenericGadgetType), sizeof(GenericGadgetType), uint(flags), 0, + [](const QtPrivate::QMetaTypeInterface *self) -> const QMetaObject * { + return reinterpret_cast<const TypeInfo *>(self)->mo; + }, + name, + [](const QtPrivate::QMetaTypeInterface *self, void *where) { GadgetTypedConstructor(self->typeId, where, nullptr); }, + [](const QtPrivate::QMetaTypeInterface *self, void *where, const void *copy) { GadgetTypedConstructor(self->typeId, where, copy); }, + [](const QtPrivate::QMetaTypeInterface *self, void *where, void *copy) { GadgetTypedConstructor(self->typeId, where, copy); }, + [](const QtPrivate::QMetaTypeInterface *self, void *ptr) { GadgetTypedDestructor(self->typeId, ptr); }, + nullptr, + nullptr, + nullptr, + GadgetSaveOperator, + GadgetLoadOperator, + nullptr + }, + meta }; QMetaType gadgetMetaType(typeInfo); dynamicGadgetProperties->m_metatype = gadgetMetaType; |