diff options
Diffstat (limited to 'src/corelib/kernel')
-rw-r--r-- | src/corelib/kernel/qmetatype.cpp | 191 | ||||
-rw-r--r-- | src/corelib/kernel/qmetatype.h | 33 | ||||
-rw-r--r-- | src/corelib/kernel/qmetatype_p.h | 12 |
3 files changed, 166 insertions, 70 deletions
diff --git a/src/corelib/kernel/qmetatype.cpp b/src/corelib/kernel/qmetatype.cpp index 76e3d0d014..82952919dd 100644 --- a/src/corelib/kernel/qmetatype.cpp +++ b/src/corelib/kernel/qmetatype.cpp @@ -1054,45 +1054,40 @@ int QMetaType::registerType(const char *typeName, Deleter deleter, return registerNormalizedType(normalizedTypeName, deleter, creator, destructor, constructor, size, flags, metaObject); } - /*! - \internal - \since 5.0 - \overload - Don't use, kept for binary compatibility + \internal + \since 5.12 - ### TODO Qt6: remove me -*/ -int QMetaType::registerNormalizedType(const NS(QByteArray) &normalizedTypeName, Deleter deleter, - Creator creator, - Destructor destructor, - Constructor constructor, - int size, TypeFlags flags, const QMetaObject *metaObject) + Registers a user type for marshalling, with \a typeName, a \a + \a destructor, a \a constructor, and a \a size. Returns the + type's handle, or -1 if the type could not be registered. + */ +int QMetaType::registerType(const char *typeName, + TypedDestructor destructor, + TypedConstructor constructor, + int size, + TypeFlags flags, + const QMetaObject *metaObject) { - Q_UNUSED(deleter); - Q_UNUSED(creator); +#ifdef QT_NO_QOBJECT + NS(QByteArray) normalizedTypeName = typeName; +#else + NS(QByteArray) normalizedTypeName = QMetaObject::normalizedType(typeName); +#endif + return registerNormalizedType(normalizedTypeName, destructor, constructor, size, flags, metaObject); } -/*! - \internal - \since 5.5 - - Registers a user type for marshalling, with \a normalizedTypeName, - a \a destructor, a \a constructor, and a \a size. Returns the type's - handle, or -1 if the type could not be registered. - - \note normalizedTypeName is not checked for conformance with - Qt's normalized format, so it must already conform. - */ -int QMetaType::registerNormalizedType(const NS(QByteArray) &normalizedTypeName, - Destructor destructor, - Constructor constructor, - int size, TypeFlags flags, const QMetaObject *metaObject) +static int registerNormalizedType(const NS(QByteArray) &normalizedTypeName, + QMetaType::Destructor destructor, + QMetaType::Constructor constructor, + QMetaType::TypedDestructor typedDestructor, + QMetaType::TypedConstructor typedConstructor, + int size, QMetaType::TypeFlags flags, const QMetaObject *metaObject) { QVector<QCustomTypeInfo> *ct = customTypes(); - if (!ct || normalizedTypeName.isEmpty() || !destructor || !constructor) + if (!ct || normalizedTypeName.isEmpty() || (!destructor && !typedDestructor) || (!constructor && !typedConstructor)) return -1; int idx = qMetaTypeStaticType(normalizedTypeName.constData(), @@ -1100,13 +1095,13 @@ int QMetaType::registerNormalizedType(const NS(QByteArray) &normalizedTypeName, int previousSize = 0; QMetaType::TypeFlags::Int previousFlags = 0; - if (idx == UnknownType) { + if (idx == QMetaType::UnknownType) { QWriteLocker locker(customTypesLock()); int posInVector = -1; idx = qMetaTypeCustomType_unlocked(normalizedTypeName.constData(), normalizedTypeName.size(), &posInVector); - if (idx == UnknownType) { + if (idx == QMetaType::UnknownType) { QCustomTypeInfo inf; inf.typeName = normalizedTypeName; #ifndef QT_NO_DATASTREAM @@ -1114,30 +1109,32 @@ int QMetaType::registerNormalizedType(const NS(QByteArray) &normalizedTypeName, inf.saveOp = 0; #endif inf.alias = -1; + inf.typedConstructor = typedConstructor; + inf.typedDestructor = typedDestructor; inf.constructor = constructor; inf.destructor = destructor; inf.size = size; inf.flags = flags; inf.metaObject = metaObject; if (posInVector == -1) { - idx = ct->size() + User; + idx = ct->size() + QMetaType::User; ct->append(inf); } else { - idx = posInVector + User; + idx = posInVector + QMetaType::User; ct->data()[posInVector] = inf; } return idx; } - if (idx >= User) { - previousSize = ct->at(idx - User).size; - previousFlags = ct->at(idx - User).flags; + if (idx >= QMetaType::User) { + previousSize = ct->at(idx - QMetaType::User).size; + previousFlags = ct->at(idx - QMetaType::User).flags; // Set new/additional flags in case of old library/app. // Ensures that older code works in conjunction with new Qt releases // requiring the new flags. if (flags != previousFlags) { - QCustomTypeInfo &inf = ct->data()[idx - User]; + QCustomTypeInfo &inf = ct->data()[idx - QMetaType::User]; inf.flags |= flags; if (metaObject) inf.metaObject = metaObject; @@ -1145,7 +1142,7 @@ int QMetaType::registerNormalizedType(const NS(QByteArray) &normalizedTypeName, } } - if (idx < User) { + if (idx < QMetaType::User) { previousSize = QMetaType::sizeOf(idx); previousFlags = QMetaType::typeFlags(idx); } @@ -1158,8 +1155,8 @@ int QMetaType::registerNormalizedType(const NS(QByteArray) &normalizedTypeName, } // these flags cannot change in a binary compatible way: - const int binaryCompatibilityFlag = PointerToQObject | IsEnumeration | SharedPointerToQObject - | WeakPointerToQObject | TrackingPointerToQObject; + const int binaryCompatibilityFlag = QMetaType::PointerToQObject | QMetaType::IsEnumeration | QMetaType::SharedPointerToQObject + | QMetaType::WeakPointerToQObject | QMetaType::TrackingPointerToQObject; if (Q_UNLIKELY((previousFlags ^ flags) & binaryCompatibilityFlag)) { const char *msg = "QMetaType::registerType: Binary compatibility break. " @@ -1173,6 +1170,66 @@ int QMetaType::registerNormalizedType(const NS(QByteArray) &normalizedTypeName, } /*! + \internal + \since 5.0 + \overload + Don't use, kept for binary compatibility + + ### TODO Qt6: remove me +*/ +int QMetaType::registerNormalizedType(const NS(QByteArray) &normalizedTypeName, Deleter deleter, + Creator creator, + Destructor destructor, + Constructor constructor, + int size, TypeFlags flags, const QMetaObject *metaObject) +{ + Q_UNUSED(deleter); + Q_UNUSED(creator); + return registerNormalizedType(normalizedTypeName, destructor, constructor, size, flags, metaObject); +} + + +/*! + \internal + \since 5.5 + + Registers a user type for marshalling, with \a normalizedTypeName, + a \a destructor, a \a constructor, and a \a size. Returns the type's + handle, or -1 if the type could not be registered. + + \note normalizedTypeName is not checked for conformance with + Qt's normalized format, so it must already conform. + + ### TODO Qt6: remove me + */ +int QMetaType::registerNormalizedType(const NS(QByteArray) &normalizedTypeName, + Destructor destructor, + Constructor constructor, + int size, TypeFlags flags, const QMetaObject *metaObject) +{ + return NS(registerNormalizedType)(normalizedTypeName, destructor, constructor, nullptr, nullptr, size, flags, metaObject); +} + +/*! + \internal + \since 5.12 + + Registers a user type for marshalling, with \a normalizedTypeName, + a \a destructor, a \a constructor, and a \a size. Returns the type's + handle, or -1 if the type could not be registered. + + \note normalizedTypeName is not checked for conformance with + Qt's normalized format, so it must already conform. + */ +int QMetaType::registerNormalizedType(const NS(QByteArray) &normalizedTypeName, + TypedDestructor destructor, + TypedConstructor constructor, + int size, TypeFlags flags, const QMetaObject *metaObject) +{ + return NS(registerNormalizedType)(normalizedTypeName, nullptr, nullptr, destructor, constructor, size, flags, metaObject); +} + +/*! \internal \since 4.7 @@ -1850,14 +1907,19 @@ private: static void *customTypeConstructor(const int type, void *where, const void *copy) { QMetaType::Constructor ctor; + QMetaType::TypedConstructor tctor; const QVector<QCustomTypeInfo> * const ct = customTypes(); { QReadLocker locker(customTypesLock()); if (Q_UNLIKELY(type < QMetaType::User || !ct || ct->count() <= type - QMetaType::User)) return 0; - ctor = ct->at(type - QMetaType::User).constructor; + const auto &typeInfo = ct->at(type - QMetaType::User); + ctor = typeInfo.constructor; + tctor = typeInfo.typedConstructor; } - Q_ASSERT_X(ctor, "void *QMetaType::construct(int type, void *where, const void *copy)", "The type was not properly registered"); + Q_ASSERT_X((ctor || tctor) , "void *QMetaType::construct(int type, void *where, const void *copy)", "The type was not properly registered"); + if (Q_UNLIKELY(tctor)) + return tctor(type, where, copy); return ctor(where, copy); } @@ -1943,14 +2005,19 @@ private: static void customTypeDestructor(const int type, void *where) { QMetaType::Destructor dtor; + QMetaType::TypedDestructor tdtor; const QVector<QCustomTypeInfo> * const ct = customTypes(); { QReadLocker locker(customTypesLock()); if (Q_UNLIKELY(type < QMetaType::User || !ct || ct->count() <= type - QMetaType::User)) return; - dtor = ct->at(type - QMetaType::User).destructor; + const auto &typeInfo = ct->at(type - QMetaType::User); + dtor = typeInfo.destructor; + tdtor = typeInfo.typedDestructor; } - Q_ASSERT_X(dtor, "void QMetaType::destruct(int type, void *where)", "The type was not properly registered"); + Q_ASSERT_X((dtor || tdtor), "void QMetaType::destruct(int type, void *where)", "The type was not properly registered"); + if (Q_UNLIKELY(tdtor)) + return tdtor(type, where); dtor(where); } @@ -2363,10 +2430,12 @@ QMetaType QMetaType::typeInfo(const int type) { TypeInfo typeInfo(type); QMetaTypeSwitcher::switcher<void>(typeInfo, type, 0); - return typeInfo.info.constructor ? QMetaType(static_cast<ExtensionFlag>(QMetaType::CreateEx | QMetaType::DestroyEx) - , static_cast<const QMetaTypeInterface *>(0) // typeInfo::info is a temporary variable, we can't return address of it. - , 0 // unused - , 0 // unused + return (typeInfo.info.constructor || typeInfo.info.typedConstructor) + ? QMetaType(static_cast<ExtensionFlag>(QMetaType::CreateEx | QMetaType::DestroyEx | + (typeInfo.info.typedConstructor ? QMetaType::ConstructEx | QMetaType::DestructEx : 0)) + , static_cast<const QMetaTypeInterface *>(nullptr) // typeInfo::info is a temporary variable, we can't return address of it. + , typeInfo.info.typedConstructor + , typeInfo.info.typedDestructor , typeInfo.info.saveOp , typeInfo.info.loadOp , typeInfo.info.constructor @@ -2408,8 +2477,8 @@ QMetaType::QMetaType(const int typeId) Copy constructs a QMetaType object. */ QMetaType::QMetaType(const QMetaType &other) - : m_creator_unused(other.m_creator_unused) - , m_deleter_unused(other.m_deleter_unused) + : m_typedConstructor(other.m_typedConstructor) + , m_typedDestructor(other.m_typedDestructor) , m_saveOp(other.m_saveOp) , m_loadOp(other.m_loadOp) , m_constructor(other.m_constructor) @@ -2424,8 +2493,8 @@ QMetaType::QMetaType(const QMetaType &other) QMetaType &QMetaType::operator =(const QMetaType &other) { - m_creator_unused = other.m_creator_unused; - m_deleter_unused = other.m_deleter_unused; + m_typedConstructor = other.m_typedConstructor; + m_typedDestructor = other.m_typedDestructor; m_saveOp = other.m_saveOp; m_loadOp = other.m_loadOp; m_constructor = other.m_constructor; @@ -2481,6 +2550,8 @@ void *QMetaType::createExtended(const void *copy) const { if (m_typeId == QMetaType::UnknownType) return 0; + if (Q_UNLIKELY(m_typedConstructor && !m_constructor)) + return m_typedConstructor(m_typeId, operator new(m_size), copy); return m_constructor(operator new(m_size), copy); } @@ -2495,7 +2566,10 @@ void *QMetaType::createExtended(const void *copy) const */ void QMetaType::destroyExtended(void *data) const { - m_destructor(data); + if (Q_UNLIKELY(m_typedDestructor && !m_destructor)) + m_typedDestructor(m_typeId, data); + else + m_destructor(data); operator delete(data); } @@ -2508,9 +2582,9 @@ void QMetaType::destroyExtended(void *data) const */ void *QMetaType::constructExtended(void *where, const void *copy) const { - Q_UNUSED(where); - Q_UNUSED(copy); - return 0; + if (m_typedConstructor && !m_constructor) + return m_typedConstructor(m_typeId, where, copy); + return nullptr; } /*! @@ -2522,7 +2596,8 @@ void *QMetaType::constructExtended(void *where, const void *copy) const */ void QMetaType::destructExtended(void *data) const { - Q_UNUSED(data); + if (m_typedDestructor && !m_destructor) + m_typedDestructor(m_typeId, data); } /*! diff --git a/src/corelib/kernel/qmetatype.h b/src/corelib/kernel/qmetatype.h index 48cbe7f00b..ed7feee775 100644 --- a/src/corelib/kernel/qmetatype.h +++ b/src/corelib/kernel/qmetatype.h @@ -493,8 +493,12 @@ public: typedef void (*Deleter)(void *); typedef void *(*Creator)(const void *); +#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0) typedef void (*Destructor)(void *); - typedef void *(*Constructor)(void *, const void *); + typedef void *(*Constructor)(void *, const void *); // TODO Qt6: remove me +#endif + typedef void (*TypedDestructor)(int, void *); + typedef void *(*TypedConstructor)(int, void *, const void *); typedef void (*SaveOperator)(QDataStream &, const void *); typedef void (*LoadOperator)(QDataStream &, void *); @@ -513,6 +517,12 @@ public: int size, QMetaType::TypeFlags flags, const QMetaObject *metaObject); + static int registerType(const char *typeName, + TypedDestructor destructor, + TypedConstructor constructor, + int size, + QMetaType::TypeFlags flags, + const QMetaObject *metaObject); static bool unregisterType(int type); static int registerNormalizedType(const QT_PREPEND_NAMESPACE(QByteArray) &normalizedTypeName, Deleter deleter, Creator creator, @@ -526,6 +536,11 @@ public: int size, QMetaType::TypeFlags flags, const QMetaObject *metaObject); + static int registerNormalizedType(const QT_PREPEND_NAMESPACE(QByteArray) &normalizedTypeName, TypedDestructor destructor, + TypedConstructor constructor, + int size, + QMetaType::TypeFlags flags, + const QMetaObject *metaObject); static int registerTypedef(const char *typeName, int aliasId); static int registerNormalizedTypedef(const QT_PREPEND_NAMESPACE(QByteArray) &normalizedTypeName, int aliasId); static int type(const char *typeName); @@ -683,8 +698,8 @@ public: private: static QMetaType typeInfo(const int type); inline QMetaType(const ExtensionFlag extensionFlags, const QMetaTypeInterface *info, - Creator creator, - Deleter deleter, + TypedConstructor creator, + TypedDestructor deleter, SaveOperator saveOp, LoadOperator loadOp, Constructor constructor, @@ -731,8 +746,8 @@ public: static void unregisterConverterFunction(int from, int to); private: - Creator m_creator_unused; - Deleter m_deleter_unused; + TypedConstructor m_typedConstructor; + TypedDestructor m_typedDestructor; SaveOperator m_saveOp; LoadOperator m_loadOp; Constructor m_constructor; @@ -2163,8 +2178,8 @@ QT_BEGIN_NAMESPACE #undef Q_DECLARE_METATYPE_TEMPLATE_SMART_POINTER_ITER inline QMetaType::QMetaType(const ExtensionFlag extensionFlags, const QMetaTypeInterface *info, - Creator creator, - Deleter deleter, + TypedConstructor creator, + TypedDestructor deleter, SaveOperator saveOp, LoadOperator loadOp, Constructor constructor, @@ -2173,8 +2188,8 @@ inline QMetaType::QMetaType(const ExtensionFlag extensionFlags, const QMetaTypeI uint theTypeFlags, int typeId, const QMetaObject *_metaObject) - : m_creator_unused(creator) - , m_deleter_unused(deleter) + : m_typedConstructor(creator) + , m_typedDestructor(deleter) , m_saveOp(saveOp) , m_loadOp(loadOp) , m_constructor(constructor) diff --git a/src/corelib/kernel/qmetatype_p.h b/src/corelib/kernel/qmetatype_p.h index 76f43db8d7..94e9228778 100644 --- a/src/corelib/kernel/qmetatype_p.h +++ b/src/corelib/kernel/qmetatype_p.h @@ -126,11 +126,13 @@ class QMetaTypeInterface public: QMetaType::SaveOperator saveOp; QMetaType::LoadOperator loadOp; - QMetaType::Constructor constructor; + QMetaType::Constructor constructor; // TODO Qt6: remove me QMetaType::Destructor destructor; int size; QMetaType::TypeFlags::Int flags; const QMetaObject *metaObject; + QMetaType::TypedConstructor typedConstructor; + QMetaType::TypedDestructor typedDestructor; }; #ifndef QT_NO_DATASTREAM @@ -161,7 +163,9 @@ public: /*destructor*/(QtMetaTypePrivate::QMetaTypeFunctionHelper<Type, QtMetaTypePrivate::TypeDefinition<Type>::IsAvailable>::Destruct), \ /*size*/(QTypeInfo<Type>::sizeOf), \ /*flags*/QtPrivate::QMetaTypeTypeFlags<Type>::Flags, \ - /*metaObject*/METAOBJECT_DELEGATE(Type) \ + /*metaObject*/METAOBJECT_DELEGATE(Type), \ + /*typedConstructor*/ nullptr, \ + /*typedDestructor*/ nullptr \ } @@ -184,7 +188,9 @@ public: /*destructor*/ 0, \ /*size*/ 0, \ /*flags*/ 0, \ - /*metaObject*/ 0 \ + /*metaObject*/ 0 , \ + /*typedConstructor*/ nullptr, \ + /*typedDestructor*/ nullptr \ } namespace QtMetaTypePrivate { |