Q_DECLARE_METATYPE: Do not re-register types
When Q_DECLARE_METATYPE is used, we often end up re-registering types as typedefs of themselves. This is because with Q_DECLARE_METATYPE, we set a legacy register operation which calls (after some indirection) QMetaType::registerNormalizedType. We still need to support this to preserve compatibility in the presence of typedefs and namespaced types. However, there is no reason to do the wasteful work of normalizing the typename at runtime and adding memory overhead to have a type registered as a typedef of itself. We can skip the type normalization work by checking whether the name in the metatype interface equals that of the typename. We still need to make sure that the converter and view functions are registered, though. Moreover, we can fix the check in qRegisterNormalizedMetaType to only call registerNormalizedTypedef if the new name doesn't match the name stored in the metatype. Fixes: QTBUG-93841 Change-Id: Icfe42c349b23add630fe3c761362b60e9e9aaa2b Reviewed-by: Ulf Hermann <ulf.hermann@qt.io> Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org> Reviewed-by: Andrei Golubev <andrei.golubev@qt.io> Reviewed-by: Lars Knoll <lars.knoll@qt.io>
This commit is contained in:
parent
bf0b2b24a7
commit
33a2bd9ca9
@ -1209,14 +1209,15 @@ int qRegisterNormalizedMetaType(const QT_PREPEND_NAMESPACE(QByteArray) &normaliz
|
||||
const QMetaType metaType = QMetaType::fromType<T>();
|
||||
const int id = metaType.id();
|
||||
|
||||
if (id > 0) {
|
||||
QtPrivate::SequentialContainerTransformationHelper<T>::registerConverter();
|
||||
QtPrivate::SequentialContainerTransformationHelper<T>::registerMutableView();
|
||||
QtPrivate::AssociativeContainerTransformationHelper<T>::registerConverter();
|
||||
QtPrivate::AssociativeContainerTransformationHelper<T>::registerMutableView();
|
||||
QtPrivate::MetaTypePairHelper<T>::registerConverter();
|
||||
QtPrivate::MetaTypeSmartPointerHelper<T>::registerConverter();
|
||||
|
||||
if (normalizedTypeName != metaType.name()) {
|
||||
QMetaType::registerNormalizedTypedef(normalizedTypeName, metaType);
|
||||
QtPrivate::SequentialContainerTransformationHelper<T>::registerConverter();
|
||||
QtPrivate::SequentialContainerTransformationHelper<T>::registerMutableView();
|
||||
QtPrivate::AssociativeContainerTransformationHelper<T>::registerConverter();
|
||||
QtPrivate::AssociativeContainerTransformationHelper<T>::registerMutableView();
|
||||
QtPrivate::MetaTypePairHelper<T>::registerConverter();
|
||||
QtPrivate::MetaTypeSmartPointerHelper<T>::registerConverter();
|
||||
}
|
||||
|
||||
return id;
|
||||
@ -1348,6 +1349,12 @@ struct QMetaTypeIdQObject<T, QMetaType::IsEnumeration>
|
||||
} QT_END_NAMESPACE \
|
||||
/**/
|
||||
|
||||
template <typename T>
|
||||
int qRegisterMetatypeIndirection()
|
||||
{
|
||||
return qRegisterNormalizedMetaType<T>(QMetaType::fromType<T>().name());
|
||||
}
|
||||
|
||||
#ifndef Q_MOC_RUN
|
||||
#define Q_DECLARE_METATYPE(TYPE) Q_DECLARE_METATYPE_IMPL(TYPE)
|
||||
#define Q_DECLARE_METATYPE_IMPL(TYPE) \
|
||||
@ -1361,6 +1368,12 @@ struct QMetaTypeIdQObject<T, QMetaType::IsEnumeration>
|
||||
static QBasicAtomicInt metatype_id = Q_BASIC_ATOMIC_INITIALIZER(0); \
|
||||
if (const int id = metatype_id.loadAcquire()) \
|
||||
return id; \
|
||||
const auto mt = QMetaType::fromType<TYPE>(); \
|
||||
if (QByteArrayView(mt.name()) == (#TYPE)) { \
|
||||
qRegisterMetatypeIndirection<TYPE>(); \
|
||||
metatype_id.storeRelease(mt.id()); \
|
||||
return mt.id(); \
|
||||
} \
|
||||
const int newId = qRegisterMetaType< TYPE >(#TYPE); \
|
||||
metatype_id.storeRelease(newId); \
|
||||
return newId; \
|
||||
|
Loading…
x
Reference in New Issue
Block a user