summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/corelib/kernel/qmetatype.h84
-rw-r--r--tests/auto/corelib/kernel/qmetatype/tst_qmetatype.cpp35
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;