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.cpp1300
1 files changed, 303 insertions, 997 deletions
diff --git a/src/corelib/kernel/qmetatype.cpp b/src/corelib/kernel/qmetatype.cpp
index 21254108e3..c34e442cdb 100644
--- a/src/corelib/kernel/qmetatype.cpp
+++ b/src/corelib/kernel/qmetatype.cpp
@@ -85,6 +85,9 @@
# include "qline.h"
#endif
+#include <bitset>
+#include <new>
+
QT_BEGIN_NAMESPACE
#define NS(x) QT_PREPEND_NAMESPACE(x)
@@ -97,6 +100,88 @@ struct DefinedTypesFilter {
static const bool IsAccepted = QtMetaTypePrivate::TypeDefinition<T>::IsAvailable && QModulesPrivate::QTypeModuleInfo<T>::IsCore;
};
};
+
+struct QMetaTypeCustomRegistry
+{
+ QReadWriteLock lock;
+ QVector<QtPrivate::QMetaTypeInterface *> registry;
+ QHash<QByteArray, QtPrivate::QMetaTypeInterface *> aliases;
+#ifndef QT_NO_DATASTREAM
+ struct DataStreamOps
+ {
+ QMetaType::SaveOperator saveOp;
+ QMetaType::LoadOperator loadOp;
+ };
+ QHash<int, DataStreamOps> dataStreamOp;
+#endif
+ // index of first empty (unregistered) type in registry, if any.
+ int firstEmpty = 0;
+
+ int registerCustomType(QtPrivate::QMetaTypeInterface *ti)
+ {
+ {
+ QWriteLocker l(&lock);
+ if (ti->typeId)
+ return ti->typeId;
+ QByteArray name =
+#ifndef QT_NO_QOBJECT
+ QMetaObject::normalizedType
+#endif
+ (ti->name);
+ if (auto ti2 = aliases.value(name)) {
+ ti->typeId.storeRelaxed(ti2->typeId.loadRelaxed());
+ return ti2->typeId;
+ }
+ aliases[name] = ti;
+ int size = registry.size();
+ while (firstEmpty < size && registry[firstEmpty])
+ ++firstEmpty;
+ if (firstEmpty < size) {
+ registry[firstEmpty] = ti;
+ ++firstEmpty;
+ } else {
+ registry.append(ti);
+ firstEmpty = registry.size();
+ }
+ ti->typeId = firstEmpty + QMetaType::User;
+ }
+ if (ti->legacyRegisterOp)
+ ti->legacyRegisterOp();
+ return ti->typeId;
+ };
+
+ void unregisterDynamicType(int id)
+ {
+ if (!id)
+ return;
+ Q_ASSERT(id > QMetaType::User);
+ QWriteLocker l(&lock);
+ int idx = id - QMetaType::User - 1;
+ auto &ti = registry[idx];
+
+ // We must unregister all names.
+ auto it = aliases.begin();
+ while (it != aliases.end()) {
+ if (it.value() == ti)
+ it = aliases.erase(it);
+ else
+ ++it;
+ }
+
+ ti = nullptr;
+
+ firstEmpty = std::min(firstEmpty, idx);
+ }
+
+ QtPrivate::QMetaTypeInterface *getCustomType(int id)
+ {
+ QReadLocker l(&lock);
+ return registry.value(id - QMetaType::User - 1);
+ }
+};
+
+Q_GLOBAL_STATIC(QMetaTypeCustomRegistry, customTypeRegistry)
+
} // namespace
/*!
@@ -153,7 +238,7 @@ struct DefinedTypesFilter {
\list
\li Pointers to classes derived from QObject
- \li QList<T>, QVector<T>, QQueue<T>, QStack<T>, QSet<T> or QLinkedList<T>
+ \li QList<T>, QVector<T>, QQueue<T>, QStack<T> or QSet<T>
where T is a registered meta type
\li QHash<T1, T2>, QMap<T1, T2> or QPair<T1, T2> where T1 and T2 are
registered meta types
@@ -282,7 +367,6 @@ struct DefinedTypesFilter {
\value QPixmap QPixmap
\value QLocale QLocale
\value QBitmap QBitmap
- \value QMatrix QMatrix
\value QTransform QTransform
\value QMatrix4x4 QMatrix4x4
\value QVector2D QVector2D
@@ -371,6 +455,10 @@ struct DefinedTypesFilter {
Returns \c true if this QMetaType object contains valid
information about a type, false otherwise.
*/
+bool QMetaType::isValid() const
+{
+ return d_ptr;
+}
/*!
\fn bool QMetaType::isRegistered() const
@@ -379,6 +467,10 @@ struct DefinedTypesFilter {
Returns \c true if this QMetaType object contains valid
information about a type, false otherwise.
*/
+bool QMetaType::isRegistered() const
+{
+ return d_ptr;
+}
/*!
\fn int QMetaType::id() const
@@ -386,6 +478,18 @@ struct DefinedTypesFilter {
Returns id type hold by this QMetatype instance.
*/
+int QMetaType::id() const
+{
+ if (d_ptr) {
+ if (d_ptr->typeId)
+ return d_ptr->typeId;
+ auto reg = customTypeRegistry();
+ if (reg) {
+ return reg->registerCustomType(d_ptr);
+ }
+ }
+ return 0;
+}
/*!
\fn bool QMetaType::sizeOf() const
@@ -400,6 +504,12 @@ struct DefinedTypesFilter {
\sa QMetaType::construct(), QMetaType::sizeOf()
*/
+int QMetaType::sizeOf() const
+{
+ if (d_ptr)
+ return d_ptr->size;
+ return 0;
+}
/*!
\fn TypeFlags QMetaType::flags() const
@@ -409,6 +519,12 @@ struct DefinedTypesFilter {
\sa QMetaType::TypeFlags, QMetaType::typeFlags()
*/
+QMetaType::TypeFlags QMetaType::flags() const
+{
+ if (d_ptr)
+ return TypeFlags(d_ptr->flags);
+ return {};
+}
/*!
\fn const QMetaObject *QMetaType::metaObject() const
@@ -430,6 +546,10 @@ struct DefinedTypesFilter {
\sa QMetaType::metaObjectForType(), QMetaType::flags()
*/
+const QMetaObject *QMetaType::metaObject() const
+{
+ return d_ptr ? d_ptr->metaObject : nullptr;
+}
/*!
\fn void *QMetaType::create(const void *copy = 0) const
@@ -441,6 +561,19 @@ struct DefinedTypesFilter {
\sa QMetaType::destroy()
*/
+void *QMetaType::create(const void *copy) const
+{
+ if (d_ptr) {
+ void *where =
+#ifdef __STDCPP_DEFAULT_NEW_ALIGNMENT__
+ d_ptr->alignment > __STDCPP_DEFAULT_NEW_ALIGNMENT__ ?
+ operator new(d_ptr->size, std::align_val_t(d_ptr->alignment)) :
+#endif
+ operator new(d_ptr->size);
+ return construct(where, copy);
+ }
+ return nullptr;
+}
/*!
\fn void QMetaType::destroy(void *data) const
@@ -451,18 +584,19 @@ struct DefinedTypesFilter {
\sa QMetaType::create()
*/
+void QMetaType::destroy(void *data) const
+{
+ if (d_ptr && d_ptr->dtor) {
+ d_ptr->dtor(d_ptr, data);
+ if (d_ptr->alignment > __STDCPP_DEFAULT_NEW_ALIGNMENT__) {
+ operator delete(data, std::align_val_t(d_ptr->alignment));
+ } else {
+ operator delete(data);
+ }
+ }
+}
/*!
- \fn void *QMetaType::construct(int type, const void *copy)
- \deprecated
-
- Constructs a value of the given type which is a copy of \a copy.
- The default value for \a copy is \nullptr.
-
- Deprecated, use the static function QMetaType::create(int type,
- const void *copy) instead.
-*/
-/*!
\fn void *QMetaType::construct(void *where, const void *copy = 0) const
\since 5.0
@@ -488,6 +622,21 @@ struct DefinedTypesFilter {
special hardware instructions (e.g., aligned SSE loads and stores
on x86).
*/
+void *QMetaType::construct(void *where, const void *copy) const
+{
+ if (!where)
+ return nullptr;
+ if (d_ptr) {
+ if (copy && d_ptr->copyCtr) {
+ d_ptr->copyCtr(d_ptr, where, copy);
+ return where;
+ } else if (!copy && d_ptr->defaultCtr) {
+ d_ptr->defaultCtr(d_ptr, where);
+ return where;
+ }
+ }
+ return nullptr;
+}
/*!
\fn void QMetaType::destruct(void *data) const
@@ -500,12 +649,53 @@ struct DefinedTypesFilter {
destructor, it doesn't invoke the delete operator.
\sa QMetaType::construct()
*/
+void QMetaType::destruct(void *data) const
+{
+ if (!data)
+ return;
+ if (d_ptr && d_ptr->dtor) {
+ d_ptr->dtor(d_ptr, data);
+ return;
+ }
+}
+
+void QtMetaTypePrivate::derefAndDestroy(NS(QtPrivate::QMetaTypeInterface) *d_ptr)
+{
+ if (d_ptr && !d_ptr->ref.deref()) {
+ if (auto reg = customTypeRegistry())
+ reg->unregisterDynamicType(d_ptr->typeId.loadRelaxed());
+ Q_ASSERT(d_ptr->deleteSelf);
+ d_ptr->deleteSelf(d_ptr);
+ }
+}
/*!
\fn QMetaType::~QMetaType()
Destructs this object.
*/
+QMetaType::~QMetaType()
+{
+ QtMetaTypePrivate::derefAndDestroy(d_ptr);
+}
+
+QMetaType::QMetaType(QtPrivate::QMetaTypeInterface *d) : d_ptr(d)
+{
+ if (d_ptr)
+ d_ptr->ref.ref();
+}
+
+QMetaType::QMetaType() : d_ptr(nullptr) {}
+
+QMetaType::QMetaType(const QMetaType &other) : QMetaType(other.d_ptr) {}
+QMetaType &QMetaType::operator=(const QMetaType &other)
+{
+ if (d_ptr != other.d_ptr) {
+ this->~QMetaType();
+ new (this) QMetaType(other.d_ptr);
+ }
+ return *this;
+}
/*!
\fn template<typename T> QMetaType QMetaType::fromType()
@@ -538,32 +728,26 @@ struct DefinedTypesFilter {
#define QT_ADD_STATIC_METATYPE_ALIASES_ITER(MetaTypeName, MetaTypeId, AliasingName, RealNameStr) \
{ RealNameStr, sizeof(RealNameStr) - 1, QMetaType::MetaTypeName },
-#define QT_ADD_STATIC_METATYPE_HACKS_ITER(MetaTypeName, TypeId, Name) \
- QT_ADD_STATIC_METATYPE(MetaTypeName, MetaTypeName, Name)
+
static const struct { const char * typeName; int typeNameLength; int type; } types[] = {
QT_FOR_EACH_STATIC_TYPE(QT_ADD_STATIC_METATYPE)
QT_FOR_EACH_STATIC_ALIAS_TYPE(QT_ADD_STATIC_METATYPE_ALIASES_ITER)
- QT_FOR_EACH_STATIC_HACKS_TYPE(QT_ADD_STATIC_METATYPE_HACKS_ITER)
+ QT_ADD_STATIC_METATYPE(_, QMetaTypeId2<qreal>::MetaType, qreal)
{nullptr, 0, QMetaType::UnknownType}
};
-Q_CORE_EXPORT const QMetaTypeInterface *qMetaTypeGuiHelper = nullptr;
-Q_CORE_EXPORT const QMetaTypeInterface *qMetaTypeWidgetsHelper = nullptr;
-Q_CORE_EXPORT const QMetaObject *qMetaObjectWidgetsHelper = nullptr;
+Q_CORE_EXPORT const QMetaTypeModuleHelper *qMetaTypeGuiHelper = nullptr;
+Q_CORE_EXPORT const QMetaTypeModuleHelper *qMetaTypeWidgetsHelper = nullptr;
-class QCustomTypeInfo : public QMetaTypeInterface
+static const QMetaTypeModuleHelper *qModuleHelperForType(int type)
{
-public:
- QCustomTypeInfo()
- : alias(-1)
- {
- QMetaTypeInterface empty = QT_METATYPE_INTERFACE_INIT(void);
- *static_cast<QMetaTypeInterface*>(this) = empty;
- }
- QByteArray typeName;
- int alias;
-};
+ if (type >= QMetaType::FirstGuiType && type <= QMetaType::LastGuiType)
+ return qMetaTypeGuiHelper;
+ else if (type >= QMetaType::FirstWidgetsType && type <= QMetaType::LastWidgetsType)
+ return qMetaTypeWidgetsHelper;
+ return nullptr;
+}
template<typename T, typename Key>
class QMetaTypeFunctionRegistry
@@ -615,12 +799,6 @@ QMetaTypeComparatorRegistry;
typedef QMetaTypeFunctionRegistry<QtPrivate::AbstractDebugStreamFunction,int>
QMetaTypeDebugStreamRegistry;
-Q_STATIC_ASSERT(std::is_trivial<QMetaTypeInterface>::value);
-Q_STATIC_ASSERT(std::is_standard_layout<QMetaTypeInterface>::value);
-
-Q_DECLARE_TYPEINFO(QCustomTypeInfo, Q_MOVABLE_TYPE);
-Q_GLOBAL_STATIC(QVector<QCustomTypeInfo>, customTypes)
-Q_GLOBAL_STATIC(QReadWriteLock, customTypesLock)
Q_GLOBAL_STATIC(QMetaTypeConverterRegistry, customTypesConversionRegistry)
Q_GLOBAL_STATIC(QMetaTypeComparatorRegistry, customTypesComparatorRegistry)
Q_GLOBAL_STATIC(QMetaTypeDebugStreamRegistry, customTypesDebugStreamRegistry)
@@ -863,13 +1041,11 @@ void QMetaType::registerStreamOperators(int idx, SaveOperator saveOp,
{
if (idx < User)
return; //builtin types should not be registered;
- QVector<QCustomTypeInfo> *ct = customTypes();
- if (!ct)
- return;
- QWriteLocker locker(customTypesLock());
- QCustomTypeInfo &inf = (*ct)[idx - User];
- inf.saveOp = saveOp;
- inf.loadOp = loadOp;
+
+ if (auto reg = customTypeRegistry()) {
+ QWriteLocker locker(&reg->lock);
+ reg->dataStreamOp[idx] = { saveOp, loadOp };
+ }
}
#endif // QT_NO_DATASTREAM
@@ -968,13 +1144,11 @@ const char *QMetaType::typeName(int typeId)
return nullptr; // It can happen when someone cast int to QVariant::Type, we should not crash...
}
- const QVector<QCustomTypeInfo> * const ct = customTypes();
- QReadLocker locker(customTypesLock());
- return ct && uint(ct->count()) > type - QMetaType::User && !ct->at(type - QMetaType::User).typeName.isEmpty()
- ? ct->at(type - QMetaType::User).typeName.constData()
- : nullptr;
-
-#undef QT_METATYPE_TYPEID_TYPENAME_CONVERTER
+ if (auto reg = customTypeRegistry()) {
+ if (auto ti = reg->getCustomType(typeId))
+ return ti->name;
+ }
+ return nullptr;
}
/*!
@@ -988,7 +1162,7 @@ const char *QMetaType::typeName(int typeId)
*/
QByteArray QMetaType::name() const
{
- return QMetaType::typeName(m_typeId);
+ return d_ptr ? d_ptr->name : nullptr;
}
/*
@@ -1007,338 +1181,40 @@ static inline int qMetaTypeStaticType(const char *typeName, int length)
/*
Similar to QMetaType::type(), but only looks in the custom set of
types, and doesn't lock the mutex.
- The extra \a firstInvalidIndex parameter is an easy way to avoid
- iterating over customTypes() a second time in registerNormalizedType().
-*/
-static int qMetaTypeCustomType_unlocked(const char *typeName, int length, int *firstInvalidIndex = nullptr)
-{
- const QVector<QCustomTypeInfo> * const ct = customTypes();
- if (!ct)
- return QMetaType::UnknownType;
-
- if (firstInvalidIndex)
- *firstInvalidIndex = -1;
- for (int v = 0; v < ct->count(); ++v) {
- const QCustomTypeInfo &customInfo = ct->at(v);
- if ((length == customInfo.typeName.size())
- && !memcmp(typeName, customInfo.typeName.constData(), length)) {
- if (customInfo.alias >= 0)
- return customInfo.alias;
- return v + QMetaType::User;
- }
- if (firstInvalidIndex && (*firstInvalidIndex < 0) && customInfo.typeName.isEmpty())
- *firstInvalidIndex = v;
- }
- return QMetaType::UnknownType;
-}
-
-/*!
- \internal
-
- This function is needed until existing code outside of qtbase
- has been changed to call the new version of registerType().
- */
-int QMetaType::registerType(const char *typeName, Deleter deleter,
- Creator creator)
-{
- return registerType(typeName, deleter, creator,
- QtMetaTypePrivate::QMetaTypeFunctionHelper<void>::Destruct,
- QtMetaTypePrivate::QMetaTypeFunctionHelper<void>::Construct, 0, TypeFlags(), nullptr);
-}
-
-/*!
- \internal
- \since 5.5
-
- Unregisters the user type with the given \a typeId and all its aliases.
- Returns \c true if the type was unregistered or \c false otherwise.
-
- This function was added for QML to be able to deregister types after
- they are unloaded to prevent an infinite increase in custom types for
- applications that are unloading/reloading components often.
- */
-bool QMetaType::unregisterType(int type)
-{
- QWriteLocker locker(customTypesLock());
- QVector<QCustomTypeInfo> *ct = customTypes();
-
- // check if user type
- if ((type < User) || ((type - User) >= ct->size()))
- return false;
-
- // only types without Q_DECLARE_METATYPE can be unregistered
- if (ct->data()[type - User].flags & WasDeclaredAsMetaType)
- return false;
-
- // invalidate type and all its alias entries
- for (int v = 0; v < ct->count(); ++v) {
- if (((v + User) == type) || (ct->at(v).alias == type))
- ct->data()[v].typeName.clear();
- }
- return true;
-}
-
-
-/*!
- \internal
- \since 5.0
-
- Registers a user type for marshalling, with \a typeName, a \a
- deleter, a \a creator, 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, Deleter deleter,
- Creator creator,
- Destructor destructor,
- Constructor constructor,
- int size, TypeFlags flags, const QMetaObject *metaObject)
-{
-#ifdef QT_NO_QOBJECT
- NS(QByteArray) normalizedTypeName = typeName;
-#else
- NS(QByteArray) normalizedTypeName = QMetaObject::normalizedType(typeName);
-#endif
-
- return registerNormalizedType(normalizedTypeName, deleter, creator, destructor, constructor, size, flags, metaObject);
-}
-
-/*!
- \internal
- \since 5.12
-
- Registers a user type for marshalling, with \a typeName, 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)
-{
-#ifdef QT_NO_QOBJECT
- NS(QByteArray) normalizedTypeName = typeName;
-#else
- NS(QByteArray) normalizedTypeName = QMetaObject::normalizedType(typeName);
-#endif
-
- return registerNormalizedType(normalizedTypeName, destructor, constructor, size, flags, 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)
+*/
+static int qMetaTypeCustomType_unlocked(const char *typeName, int length)
{
- QVector<QCustomTypeInfo> *ct = customTypes();
- if (!ct || normalizedTypeName.isEmpty() || (!destructor && !typedDestructor) || (!constructor && !typedConstructor))
- return -1;
-
- int idx = qMetaTypeStaticType(normalizedTypeName.constData(),
- normalizedTypeName.size());
-
- int previousSize = 0;
- QMetaType::TypeFlags::Int previousFlags = 0;
- if (idx == QMetaType::UnknownType) {
- QWriteLocker locker(customTypesLock());
- int posInVector = -1;
- idx = qMetaTypeCustomType_unlocked(normalizedTypeName.constData(),
- normalizedTypeName.size(),
- &posInVector);
- if (idx == QMetaType::UnknownType) {
- QCustomTypeInfo inf;
- inf.typeName = normalizedTypeName;
-#ifndef QT_NO_DATASTREAM
- inf.loadOp = nullptr;
- inf.saveOp = nullptr;
+ if (auto reg = customTypeRegistry()) {
+#if QT_CONFIG(thread)
+ Q_ASSERT(!reg->lock.tryLockForWrite());
#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() + QMetaType::User;
- ct->append(inf);
- } else {
- idx = posInVector + QMetaType::User;
- ct->data()[posInVector] = inf;
- }
- return idx;
+ if (auto ti = reg->aliases.value(QByteArray(typeName, length), nullptr)) {
+ return ti->typeId;
}
-
- 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 - QMetaType::User];
- inf.flags |= flags;
- if (metaObject)
- inf.metaObject = metaObject;
- }
- }
- }
-
- if (idx < QMetaType::User) {
- previousSize = QMetaType::sizeOf(idx);
- previousFlags = QMetaType::typeFlags(idx);
- }
-
- if (Q_UNLIKELY(previousSize != size)) {
- qFatal("QMetaType::registerType: Binary compatibility break "
- "-- Size mismatch for type '%s' [%i]. Previously registered "
- "size %i, now registering size %i.",
- normalizedTypeName.constData(), idx, previousSize, size);
}
-
- // these flags cannot change in a binary compatible way:
- 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. "
- "\nType flags for type '%s' [%i] don't match. Previously "
- "registered TypeFlags(0x%x), now registering TypeFlags(0x%x). ";
-
- qFatal(msg, normalizedTypeName.constData(), idx, previousFlags, int(flags));
- }
-
- return idx;
-}
-
-/*!
- \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
-
- Registers a user type for marshalling, as an alias of another type (typedef)
-*/
-int QMetaType::registerTypedef(const char* typeName, int aliasId)
-{
-#ifdef QT_NO_QOBJECT
- NS(QByteArray) normalizedTypeName = typeName;
-#else
- NS(QByteArray) normalizedTypeName = QMetaObject::normalizedType(typeName);
-#endif
-
- return registerNormalizedTypedef(normalizedTypeName, aliasId);
+ return QMetaType::UnknownType;
}
/*!
\internal
- \since 5.0
Registers a user type for marshalling, as an alias of another type (typedef).
Note that normalizedTypeName is not checked for conformance with Qt's normalized format,
so it must already conform.
*/
-int QMetaType::registerNormalizedTypedef(const NS(QByteArray) &normalizedTypeName, int aliasId)
+void QMetaType::registerNormalizedTypedef(const NS(QByteArray) & normalizedTypeName,
+ QMetaType metaType)
{
- QVector<QCustomTypeInfo> *ct = customTypes();
- if (!ct || normalizedTypeName.isEmpty())
- return -1;
-
- int idx = qMetaTypeStaticType(normalizedTypeName.constData(),
- normalizedTypeName.size());
-
- if (idx == UnknownType) {
- QWriteLocker locker(customTypesLock());
- int posInVector = -1;
- idx = qMetaTypeCustomType_unlocked(normalizedTypeName.constData(),
- normalizedTypeName.size(),
- &posInVector);
-
- if (idx == UnknownType) {
- QCustomTypeInfo inf;
- inf.typeName = normalizedTypeName;
- inf.alias = aliasId;
- if (posInVector == -1)
- ct->append(inf);
- else
- ct->data()[posInVector] = inf;
- return aliasId;
- }
- }
-
- if (idx != aliasId) {
- qWarning("QMetaType::registerTypedef: "
- "-- Type name '%s' previously registered as typedef of '%s' [%i], "
- "now registering as typedef of '%s' [%i].",
- normalizedTypeName.constData(), QMetaType::typeName(idx), idx,
- QMetaType::typeName(aliasId), aliasId);
+ if (!metaType.isValid())
+ return;
+ if (auto reg = customTypeRegistry()) {
+ QWriteLocker lock(&reg->lock);
+ auto &al = reg->aliases[normalizedTypeName];
+ if (al)
+ return;
+ al = metaType.d_ptr;
}
- return idx;
}
/*!
@@ -1349,16 +1225,7 @@ int QMetaType::registerNormalizedTypedef(const NS(QByteArray) &normalizedTypeNam
*/
bool QMetaType::isRegistered(int type)
{
- // predefined type
- if ((type >= FirstCoreType && type <= LastCoreType)
- || (type >= FirstGuiType && type <= LastGuiType)
- || (type >= FirstWidgetsType && type <= LastWidgetsType)) {
- return true;
- }
-
- QReadLocker locker(customTypesLock());
- const QVector<QCustomTypeInfo> * const ct = customTypes();
- return ((type >= User) && (ct && ct->count() > type - User) && !ct->at(type - User).typeName.isEmpty());
+ return QMetaType(type).isRegistered();
}
template <bool tryNormalizedType>
@@ -1368,7 +1235,7 @@ static inline int qMetaTypeTypeImpl(const char *typeName, int length)
return QMetaType::UnknownType;
int type = qMetaTypeStaticType(typeName, length);
if (type == QMetaType::UnknownType) {
- QReadLocker locker(customTypesLock());
+ QReadLocker locker(&customTypeRegistry()->lock);
type = qMetaTypeCustomType_unlocked(typeName, length);
#ifndef QT_NO_QOBJECT
if ((type == QMetaType::UnknownType) && tryNormalizedType) {
@@ -1423,7 +1290,6 @@ int QMetaType::type(const QT_PREPEND_NAMESPACE(QByteArray) &typeName)
}
#ifndef QT_NO_DATASTREAM
-
namespace
{
@@ -1467,30 +1333,29 @@ struct FilteredOperatorSwitch
return true;
}
};
+
template<typename T>
struct FilteredOperatorSwitch<T, /* IsAcceptedType = */ false>
{
- static const QMetaTypeInterface* getMetaTypeInterface(int type)
+ static const QMetaTypeModuleHelper *getMetaTypeInterface()
{
- if (QModulesPrivate::QTypeModuleInfo<T>::IsGui && qMetaTypeGuiHelper)
- return &qMetaTypeGuiHelper[type - QMetaType::FirstGuiType];
- else if (QModulesPrivate::QTypeModuleInfo<T>::IsWidget && qMetaTypeWidgetsHelper)
- return &qMetaTypeWidgetsHelper[type - QMetaType::FirstWidgetsType];
+ if (QModulesPrivate::QTypeModuleInfo<T>::IsGui)
+ return qMetaTypeGuiHelper;
+ else if (QModulesPrivate::QTypeModuleInfo<T>::IsWidget)
+ return qMetaTypeWidgetsHelper;
return nullptr;
}
static bool save(QDataStream &stream, const T *data, int type)
{
- if (auto interface = getMetaTypeInterface(type)) {
- interface->saveOp(stream, data);
- return true;
+ if (auto interface = getMetaTypeInterface()) {
+ return interface->save(stream, type, data);
}
return false;
}
static bool load(QDataStream &stream, T *data, int type)
{
- if (auto interface = getMetaTypeInterface(type)) {
- interface->loadOp(stream, data);
- return true;
+ if (auto interface = getMetaTypeInterface()) {
+ return interface->load(stream, type, data);
}
return false;
}
@@ -1525,17 +1390,17 @@ public:
}
bool delegate(const QMetaTypeSwitcher::NotBuiltinType *data)
{
- const QVector<QCustomTypeInfo> * const ct = customTypes();
+ auto ct = customTypeRegistry();
if (!ct)
return false;
- QMetaType::SaveOperator saveOp = nullptr;
+ QMetaType::SaveOperator op = nullptr;
{
- QReadLocker locker(customTypesLock());
- saveOp = ct->at(m_type - QMetaType::User).saveOp;
+ QReadLocker lock(&ct->lock);
+ op = ct->dataStreamOp.value(m_type).saveOp;
}
- if (!saveOp)
+ if (!op)
return false;
- saveOp(stream, data);
+ op(stream, data);
return true;
}
bool delegate(const void*) { return false; }
@@ -1576,17 +1441,17 @@ public:
}
bool delegate(const QMetaTypeSwitcher::NotBuiltinType *data)
{
- const QVector<QCustomTypeInfo> * const ct = customTypes();
+ auto ct = customTypeRegistry();
if (!ct)
return false;
- QMetaType::LoadOperator loadOp = nullptr;
+ QMetaType::LoadOperator op = nullptr;
{
- QReadLocker locker(customTypesLock());
- loadOp = ct->at(m_type - QMetaType::User).loadOp;
+ QReadLocker lock(&ct->lock);
+ op = ct->dataStreamOp.value(m_type).loadOp;
}
- if (!loadOp)
+ if (!op)
return false;
- loadOp(stream, const_cast<QMetaTypeSwitcher::NotBuiltinType*>(data));
+ op(stream, const_cast<QMetaTypeSwitcher::NotBuiltinType *>(data));
return true;
}
bool delegate(const void*) { return false; }
@@ -1647,10 +1512,7 @@ bool QMetaType::load(QDataStream &stream, int type, void *data)
*/
void *QMetaType::create(int type, const void *copy)
{
- QMetaType info(type);
- if (int size = info.sizeOf())
- return info.construct(operator new(size), copy);
- return nullptr;
+ return QMetaType(type).create(copy);
}
/*!
@@ -1660,73 +1522,9 @@ void *QMetaType::create(int type, const void *copy)
*/
void QMetaType::destroy(int type, void *data)
{
- QMetaType info(type);
- info.destruct(data);
- operator delete(data);
+ QMetaType(type).destroy(data);
}
-namespace {
-class TypeConstructor {
- template<typename T, bool IsAcceptedType = DefinedTypesFilter::Acceptor<T>::IsAccepted>
- struct ConstructorImpl {
- static void *Construct(const int /*type*/, void *where, const void *copy) { return QtMetaTypePrivate::QMetaTypeFunctionHelper<T>::Construct(where, copy); }
- };
- template<typename T>
- struct ConstructorImpl<T, /* IsAcceptedType = */ false> {
- static void *Construct(const int type, void *where, const void *copy)
- {
- if (QModulesPrivate::QTypeModuleInfo<T>::IsGui)
- return Q_LIKELY(qMetaTypeGuiHelper)
- ? qMetaTypeGuiHelper[type - QMetaType::FirstGuiType].constructor(where, copy)
- : nullptr;
-
- if (QModulesPrivate::QTypeModuleInfo<T>::IsWidget)
- return Q_LIKELY(qMetaTypeWidgetsHelper)
- ? qMetaTypeWidgetsHelper[type - QMetaType::FirstWidgetsType].constructor(where, copy)
- : nullptr;
-
- // This point can be reached only for known types that definition is not available, for example
- // in bootstrap mode. We have no other choice then ignore it.
- return nullptr;
- }
- };
-public:
- TypeConstructor(const int type, void *where)
- : m_type(type)
- , m_where(where)
- {}
-
- template<typename T>
- void *delegate(const T *copy) { return ConstructorImpl<T>::Construct(m_type, m_where, copy); }
- void *delegate(const void *) { return m_where; }
- void *delegate(const QMetaTypeSwitcher::UnknownType*) { return m_where; }
- void *delegate(const QMetaTypeSwitcher::NotBuiltinType *copy) { return customTypeConstructor(m_type, m_where, copy); }
-
-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 nullptr;
- const auto &typeInfo = ct->at(type - QMetaType::User);
- ctor = typeInfo.constructor;
- tctor = typeInfo.typedConstructor;
- }
- 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);
- }
-
- const int m_type;
- void *m_where;
-};
-} // namespace
-
/*!
\since 5.0
@@ -1755,75 +1553,10 @@ private:
*/
void *QMetaType::construct(int type, void *where, const void *copy)
{
- if (!where)
- return nullptr;
- TypeConstructor constructor(type, where);
- return QMetaTypeSwitcher::switcher<void*>(constructor, type, copy);
+ return QMetaType(type).construct(where, copy);
}
-namespace {
-class TypeDestructor {
- template<typename T, bool IsAcceptedType = DefinedTypesFilter::Acceptor<T>::IsAccepted>
- struct DestructorImpl {
- static void Destruct(const int /* type */, void *where) { QtMetaTypePrivate::QMetaTypeFunctionHelper<T>::Destruct(where); }
- };
- template<typename T>
- struct DestructorImpl<T, /* IsAcceptedType = */ false> {
- static void Destruct(const int type, void *where)
- {
- if (QModulesPrivate::QTypeModuleInfo<T>::IsGui) {
- if (Q_LIKELY(qMetaTypeGuiHelper))
- qMetaTypeGuiHelper[type - QMetaType::FirstGuiType].destructor(where);
- return;
- }
- if (QModulesPrivate::QTypeModuleInfo<T>::IsWidget) {
- if (Q_LIKELY(qMetaTypeWidgetsHelper))
- qMetaTypeWidgetsHelper[type - QMetaType::FirstWidgetsType].destructor(where);
- return;
- }
- // This point can be reached only for known types that definition is not available, for example
- // in bootstrap mode. We have no other choice then ignore it.
- }
- };
-public:
- TypeDestructor(const int type)
- : m_type(type)
- {}
-
- template<typename T>
- void delegate(const T *where) { DestructorImpl<T>::Destruct(m_type, const_cast<T*>(where)); }
- // MSVC2013 and earlier can not const_cast a std::nullptr_t pointer.
- void delegate(const std::nullptr_t *) {}
- void delegate(const void *) {}
- void delegate(const QMetaTypeSwitcher::UnknownType*) {}
- void delegate(const QMetaTypeSwitcher::NotBuiltinType *where)
- { customTypeDestructor(m_type, const_cast<void *>(static_cast<const void *>(where))); }
-
-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;
- const auto &typeInfo = ct->at(type - QMetaType::User);
- dtor = typeInfo.destructor;
- tdtor = typeInfo.typedDestructor;
- }
- 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);
- }
-
- const int m_type;
-};
-} // namespace
-
/*!
\since 5.0
@@ -1836,58 +1569,9 @@ private:
*/
void QMetaType::destruct(int type, void *where)
{
- if (!where)
- return;
- TypeDestructor destructor(type);
- QMetaTypeSwitcher::switcher<void>(destructor, type, where);
+ return QMetaType(type).destruct(where);
}
-
-namespace {
-class SizeOf {
- template<typename T, bool IsAcceptedType = DefinedTypesFilter::Acceptor<T>::IsAccepted>
- struct SizeOfImpl {
- static int Size(const int) { return QTypeInfo<T>::sizeOf; }
- };
- template<typename T>
- struct SizeOfImpl<T, /* IsAcceptedType = */ false> {
- static int Size(const int type)
- {
- if (QModulesPrivate::QTypeModuleInfo<T>::IsGui)
- return Q_LIKELY(qMetaTypeGuiHelper) ? qMetaTypeGuiHelper[type - QMetaType::FirstGuiType].size : 0;
-
- if (QModulesPrivate::QTypeModuleInfo<T>::IsWidget)
- return Q_LIKELY(qMetaTypeWidgetsHelper) ? qMetaTypeWidgetsHelper[type - QMetaType::FirstWidgetsType].size : 0;
-
- // This point can be reached only for known types that definition is not available, for example
- // in bootstrap mode. We have no other choice then ignore it.
- return 0;
- }
- };
-
-public:
- SizeOf(int type)
- : m_type(type)
- {}
-
- template<typename T>
- int delegate(const T*) { return SizeOfImpl<T>::Size(m_type); }
- int delegate(const QMetaTypeSwitcher::UnknownType*) { return 0; }
- int delegate(const QMetaTypeSwitcher::NotBuiltinType*) { return customTypeSizeOf(m_type); }
-private:
- static int customTypeSizeOf(const int type)
- {
- const QVector<QCustomTypeInfo> * const ct = customTypes();
- QReadLocker locker(customTypesLock());
- if (Q_UNLIKELY(type < QMetaType::User || !ct || ct->count() <= type - QMetaType::User))
- return 0;
- return ct->at(type - QMetaType::User).size;
- }
-
- const int m_type;
-};
-} // namespace
-
/*!
\since 5.0
@@ -1901,61 +1585,9 @@ private:
*/
int QMetaType::sizeOf(int type)
{
- SizeOf sizeOf(type);
- return QMetaTypeSwitcher::switcher<int>(sizeOf, type);
+ return QMetaType(type).sizeOf();
}
-namespace {
-class Flags
-{
- template<typename T, bool IsAcceptedType = DefinedTypesFilter::Acceptor<T>::IsAccepted>
- struct FlagsImpl
- {
- static quint32 Flags(const int /* type */)
- {
- return QtPrivate::QMetaTypeTypeFlags<T>::Flags;
- }
- };
- template<typename T>
- struct FlagsImpl<T, /* IsAcceptedType = */ false>
- {
- static quint32 Flags(const int type)
- {
- if (QModulesPrivate::QTypeModuleInfo<T>::IsGui)
- return Q_LIKELY(qMetaTypeGuiHelper) ? qMetaTypeGuiHelper[type - QMetaType::FirstGuiType].flags : 0;
-
- if (QModulesPrivate::QTypeModuleInfo<T>::IsWidget)
- return Q_LIKELY(qMetaTypeWidgetsHelper) ? qMetaTypeWidgetsHelper[type - QMetaType::FirstWidgetsType].flags : 0;
-
- // This point can be reached only for known types that definition is not available, for example
- // in bootstrap mode. We have no other choice then ignore it.
- return 0;
- }
- };
-public:
- Flags(const int type)
- : m_type(type)
- {}
- template<typename T>
- quint32 delegate(const T*) { return FlagsImpl<T>::Flags(m_type); }
- quint32 delegate(const void*) { return 0; }
- quint32 delegate(const QMetaTypeSwitcher::UnknownType*) { return 0; }
- quint32 delegate(const QMetaTypeSwitcher::NotBuiltinType*) { return customTypeFlags(m_type); }
-private:
- const int m_type;
- static quint32 customTypeFlags(const int type)
- {
- const QVector<QCustomTypeInfo> * const ct = customTypes();
- if (Q_UNLIKELY(!ct || type < QMetaType::User))
- return 0;
- QReadLocker locker(customTypesLock());
- if (Q_UNLIKELY(ct->count() <= type - QMetaType::User))
- return 0;
- return ct->at(type - QMetaType::User).flags;
- }
-};
-} // namespace
-
/*!
\since 5.0
@@ -1965,61 +1597,9 @@ private:
*/
QMetaType::TypeFlags QMetaType::typeFlags(int type)
{
- Flags flags(type);
- return static_cast<QMetaType::TypeFlags>(QMetaTypeSwitcher::switcher<quint32>(flags, type));
+ return QMetaType(type).flags();
}
-#ifndef QT_BOOTSTRAPPED
-namespace {
-class MetaObject
-{
-public:
- MetaObject(const int type)
- : m_type(type)
- {}
-
- template<typename T, bool IsAcceptedType = DefinedTypesFilter::Acceptor<T>::IsAccepted>
- struct MetaObjectImpl
- {
- static const QMetaObject *MetaObject(int /*type*/)
- { return QtPrivate::MetaObjectForType<T>::value(); }
- };
- template<typename T>
- struct MetaObjectImpl<T, /* IsAcceptedType = */ false>
- {
- static const QMetaObject *MetaObject(int type) {
- if (QModulesPrivate::QTypeModuleInfo<T>::IsGui)
- return Q_LIKELY(qMetaTypeGuiHelper)
- ? qMetaTypeGuiHelper[type - QMetaType::FirstGuiType].metaObject
- : nullptr;
- if (QModulesPrivate::QTypeModuleInfo<T>::IsWidget)
- return Q_LIKELY(qMetaTypeWidgetsHelper)
- ? qMetaTypeWidgetsHelper[type - QMetaType::FirstWidgetsType].metaObject
- : nullptr;
- return nullptr;
- }
- };
-
- template <typename T>
- const QMetaObject *delegate(const T *) { return MetaObjectImpl<T>::MetaObject(m_type); }
- const QMetaObject *delegate(const void*) { return nullptr; }
- const QMetaObject *delegate(const QMetaTypeSwitcher::UnknownType*) { return nullptr; }
- const QMetaObject *delegate(const QMetaTypeSwitcher::NotBuiltinType*) { return customMetaObject(m_type); }
-private:
- const int m_type;
- static const QMetaObject *customMetaObject(const int type)
- {
- const QVector<QCustomTypeInfo> * const ct = customTypes();
- if (Q_UNLIKELY(!ct || type < QMetaType::User))
- return nullptr;
- QReadLocker locker(customTypesLock());
- if (Q_UNLIKELY(ct->count() <= type - QMetaType::User))
- return nullptr;
- return ct->at(type - QMetaType::User).metaObject;
- }
-};
-} // namespace
-#endif
/*!
\since 5.0
@@ -2030,13 +1610,7 @@ private:
*/
const QMetaObject *QMetaType::metaObjectForType(int type)
{
-#ifndef QT_BOOTSTRAPPED
- MetaObject mo(type);
- return QMetaTypeSwitcher::switcher<const QMetaObject*>(mo, type);
-#else
- Q_UNUSED(type);
- return nullptr;
-#endif
+ return QMetaType(type).metaObject();
}
/*!
@@ -2094,25 +1668,6 @@ const QMetaObject *QMetaType::metaObjectForType(int type)
\sa qRegisterMetaType(), QMetaType::isRegistered(), Q_DECLARE_METATYPE()
*/
-/*! \typedef QMetaType::Deleter
- \internal
-*/
-/*! \typedef QMetaType::Creator
- \internal
-*/
-/*! \typedef QMetaType::SaveOperator
- \internal
-*/
-/*! \typedef QMetaType::LoadOperator
- \internal
-*/
-/*! \typedef QMetaType::Destructor
- \internal
-*/
-/*! \typedef QMetaType::Constructor
- \internal
-*/
-
/*!
\fn int qRegisterMetaType()
\relates QMetaType
@@ -2169,85 +1724,24 @@ const QMetaObject *QMetaType::metaObjectForType(int type)
\sa Q_DECLARE_METATYPE(), QMetaType::type()
*/
-namespace {
-class TypeInfo {
- template<typename T, bool IsAcceptedType = DefinedTypesFilter::Acceptor<T>::IsAccepted>
- struct TypeInfoImpl
- {
- TypeInfoImpl(const uint /* type */, QMetaTypeInterface &info)
- {
- QMetaTypeInterface tmp = QT_METATYPE_INTERFACE_INIT_NO_DATASTREAM(T);
- info = tmp;
- }
- };
-
- template<typename T>
- struct TypeInfoImpl<T, /* IsAcceptedType = */ false>
- {
- TypeInfoImpl(const uint type, QMetaTypeInterface &info)
- {
- if (QModulesPrivate::QTypeModuleInfo<T>::IsGui) {
- if (Q_LIKELY(qMetaTypeGuiHelper))
- info = qMetaTypeGuiHelper[type - QMetaType::FirstGuiType];
- return;
- }
- if (QModulesPrivate::QTypeModuleInfo<T>::IsWidget) {
- if (Q_LIKELY(qMetaTypeWidgetsHelper))
- info = qMetaTypeWidgetsHelper[type - QMetaType::FirstWidgetsType];
- return;
- }
- }
- };
-public:
- QMetaTypeInterface info;
- TypeInfo(const uint type)
- : m_type(type)
- {
- QMetaTypeInterface tmp = QT_METATYPE_INTERFACE_INIT_EMPTY();
- info = tmp;
+static QtPrivate::QMetaTypeInterface *interfaceForType(int typeId)
+{
+ if (typeId >= QMetaType::User) {
+ if (auto reg = customTypeRegistry())
+ return reg->getCustomType(typeId);
}
- template<typename T>
- void delegate(const T*) { TypeInfoImpl<T>(m_type, info); }
- void delegate(const QMetaTypeSwitcher::UnknownType*) {}
- void delegate(const QMetaTypeSwitcher::NotBuiltinType*) { customTypeInfo(m_type); }
-private:
- void customTypeInfo(const uint type)
- {
- const QVector<QCustomTypeInfo> * const ct = customTypes();
- if (Q_UNLIKELY(!ct))
- return;
- QReadLocker locker(customTypesLock());
- if (Q_LIKELY(uint(ct->count()) > type - QMetaType::User))
- info = ct->at(type - QMetaType::User);
+ if (auto moduleHelper = qModuleHelperForType(typeId))
+ return moduleHelper->interfaceForType(typeId);
+
+ switch (typeId) {
+ QT_FOR_EACH_STATIC_PRIMITIVE_TYPE(QT_METATYPE_CONVERT_ID_TO_TYPE)
+ QT_FOR_EACH_STATIC_PRIMITIVE_POINTER(QT_METATYPE_CONVERT_ID_TO_TYPE)
+ QT_FOR_EACH_STATIC_CORE_CLASS(QT_METATYPE_CONVERT_ID_TO_TYPE)
+ QT_FOR_EACH_STATIC_CORE_POINTER(QT_METATYPE_CONVERT_ID_TO_TYPE)
+ QT_FOR_EACH_STATIC_CORE_TEMPLATE(QT_METATYPE_CONVERT_ID_TO_TYPE)
+ default:
+ return nullptr;
}
-
- const uint m_type;
-};
-} // namespace
-
-/*!
- \fn QMetaType QMetaType::typeInfo(const int type)
- \internal
-*/
-QMetaType QMetaType::typeInfo(const int type)
-{
- TypeInfo typeInfo(type);
- QMetaTypeSwitcher::switcher<void>(typeInfo, type);
- 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
- , typeInfo.info.destructor
- , typeInfo.info.size
- , typeInfo.info.flags
- , type
- , typeInfo.info.metaObject)
- : QMetaType(UnknownType);
}
/*!
@@ -2258,212 +1752,24 @@ QMetaType QMetaType::typeInfo(const int type)
\note The default parameter was added in Qt 5.15.
*/
-QMetaType::QMetaType(const int typeId)
- : m_typeId(typeId)
-{
- if (Q_UNLIKELY(typeId == UnknownType)) {
- // Constructs invalid QMetaType instance.
- m_extensionFlags = 0xffffffff;
- Q_ASSERT(!isValid());
- } else {
- // TODO it can be better.
- *this = QMetaType::typeInfo(typeId);
- if (m_typeId == UnknownType)
- m_extensionFlags = 0xffffffff;
- else if (m_typeId == QMetaType::Void)
- m_extensionFlags = CreateEx | DestroyEx | ConstructEx | DestructEx;
- }
-}
-
-/*!
- \fn QMetaType::QMetaType(const QMetaType &other)
- \since 5.0
-
- Copy constructs a QMetaType object.
-*/
-QMetaType::QMetaType(const QMetaType &other)
- : 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)
- , m_destructor(other.m_destructor)
- , m_extension(other.m_extension) // space reserved for future use
- , m_size(other.m_size)
- , m_typeFlags(other.m_typeFlags)
- , m_extensionFlags(other.m_extensionFlags)
- , m_typeId(other.m_typeId)
- , m_metaObject(other.m_metaObject)
-{}
-
-QMetaType &QMetaType::operator =(const QMetaType &other)
-{
- 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;
- m_destructor = other.m_destructor;
- m_size = other.m_size;
- m_typeFlags = other.m_typeFlags;
- m_extensionFlags = other.m_extensionFlags;
- m_extension = other.m_extension; // space reserved for future use
- m_typeId = other.m_typeId;
- m_metaObject = other.m_metaObject;
- return *this;
-}
-
-/*!
- \fn void QMetaType::ctor(const QMetaTypeInterface *info)
- \internal
-
- Method used for future binary compatible extensions. The function may be
- called from within QMetaType's constructor to force a library call from
- inlined code.
-*/
-void QMetaType::ctor(const QMetaTypeInterface *info)
-{
- // Special case for Void type, the type is valid but not constructible.
- // In future we may consider to remove this assert and extend this function to initialize
- // differently m_extensionFlags for different types. Currently it is not needed.
- Q_ASSERT(m_typeId == QMetaType::Void);
- Q_UNUSED(info);
- m_extensionFlags = CreateEx | DestroyEx | ConstructEx | DestructEx;
-}
-
-/*!
- \fn void QMetaType::dtor()
- \internal
-
- Method used for future binary compatible extensions. The function may be
- called from within QMetaType's destructor to force a library call from
- inlined code.
-*/
-void QMetaType::dtor()
-{}
-
-/*!
- \fn void *QMetaType::createExtended(const void *copy) const
- \internal
-
- Method used for future binary compatible extensions. The function may be called
- during QMetaType::create to force library call from inlined code.
-
- ### TODO Qt6 remove the extension
-*/
-void *QMetaType::createExtended(const void *copy) const
-{
- if (m_typeId == QMetaType::UnknownType)
- return nullptr;
- 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);
-}
-
-/*!
- \fn void QMetaType::destroyExtended(void *data) const
- \internal
-
- Method used for future binary compatible extensions. The function may be called
- during QMetaType::destroy to force library call from inlined code.
-
- ### TODO Qt6 remove the extension
-*/
-void QMetaType::destroyExtended(void *data) const
-{
- if (m_typeId == QMetaType::UnknownType)
- return;
- if (Q_UNLIKELY(m_typedDestructor && !m_destructor))
- m_typedDestructor(m_typeId, data);
- else
- m_destructor(data);
- operator delete(data);
-}
-
-/*!
- \fn void *QMetaType::constructExtended(void *where, const void *copy) const
- \internal
-
- Method used for future binary compatible extensions. The function may be called
- during QMetaType::construct to force library call from inlined code.
-*/
-void *QMetaType::constructExtended(void *where, const void *copy) const
-{
- if (m_typeId == QMetaType::UnknownType)
- return nullptr;
- if (m_typedConstructor && !m_constructor)
- return m_typedConstructor(m_typeId, where, copy);
- return nullptr;
-}
-
-/*!
- \fn void QMetaType::destructExtended(void *data) const
- \internal
-
- Method used for future binary compatible extensions. The function may be called
- during QMetaType::destruct to force library call from inlined code.
-*/
-void QMetaType::destructExtended(void *data) const
-{
- if (m_typeId == QMetaType::UnknownType)
- return;
- if (m_typedDestructor && !m_destructor)
- m_typedDestructor(m_typeId, data);
-}
-
-/*!
- \fn uint QMetaType::sizeExtended() const
- \internal
-
- Method used for future binary compatible extensions. The function may be
- called from within QMetaType::size to force a library call from
- inlined code.
-*/
-uint QMetaType::sizeExtended() const
-{
- return 0;
-}
-
-/*!
- \fn QMetaType::TypeFlags QMetaType::flagsExtended() const
- \internal
-
- Method used for future binary compatible extensions. The function may be
- called from within QMetaType::flags to force a library call from
- inlined code.
-*/
-QMetaType::TypeFlags QMetaType::flagsExtended() const
-{
- return { };
-}
-
-/*!
- \brief QMetaType::metaObjectExtended
- \internal
-
- Method used for future binary compatible extensions. The function may be
- called from within QMetaType::metaObject to force a library call from
- inlined code.
-*/
-const QMetaObject *QMetaType::metaObjectExtended() const
-{
- return nullptr;
-}
-
-
-namespace QtPrivate
-{
-const QMetaObject *metaObjectForQWidget()
-{
- if (!qMetaTypeWidgetsHelper)
- return nullptr;
- return qMetaObjectWidgetsHelper;
-}
-}
+QMetaType::QMetaType(int typeId) : QMetaType(interfaceForType(typeId)) {}
namespace QtMetaTypePrivate {
const bool VectorBoolElements::true_element = true;
const bool VectorBoolElements::false_element = false;
}
+namespace QtPrivate {
+#ifndef QT_BOOTSTRAPPED
+// Explicit instantiation definition
+#define QT_METATYPE_DECLARE_TEMPLATE_ITER(TypeName, Id, Name) template class QMetaTypeForType<Name>;
+QT_FOR_EACH_STATIC_PRIMITIVE_TYPE(QT_METATYPE_DECLARE_TEMPLATE_ITER)
+QT_FOR_EACH_STATIC_PRIMITIVE_POINTER(QT_METATYPE_DECLARE_TEMPLATE_ITER)
+QT_FOR_EACH_STATIC_CORE_CLASS(QT_METATYPE_DECLARE_TEMPLATE_ITER)
+QT_FOR_EACH_STATIC_CORE_POINTER(QT_METATYPE_DECLARE_TEMPLATE_ITER)
+QT_FOR_EACH_STATIC_CORE_TEMPLATE(QT_METATYPE_DECLARE_TEMPLATE_ITER)
+#undef QT_METATYPE_DECLARE_TEMPLATE_ITER
+#endif
+}
+
QT_END_NAMESPACE