summaryrefslogtreecommitdiffstats
path: root/src/corelib/kernel/qmetatype.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/corelib/kernel/qmetatype.cpp')
-rw-r--r--src/corelib/kernel/qmetatype.cpp191
1 files changed, 133 insertions, 58 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);
}
/*!