New QMetaType representation
the QMetaType is represented as a pointer to a "vtable" in the form of a QtPrivate::QMetaTypeInterface* The recomanded use of QMetaType is to construct an object with QMetaType::fromType. This does not require any registration. There is still an id() function which will do some registration for compatibility with Qt5. Also the patch does not really touch the other extra things that can be registered (data stream operator, comparison operator, iteratable, ...) and this still uses the previous system. This is only the change in QMetaType, other changes to use it in QVariant and QMetaObject will follow Change-Id: Iffad20085cf33f33447f58a68236013a8b60fdbf Reviewed-by: Simon Hausmann <simon.hausmann@qt.io>
This commit is contained in:
parent
14f1ec186f
commit
33cd680ddb
File diff suppressed because it is too large
Load Diff
@ -46,6 +46,7 @@
|
||||
#include <QtCore/qatomic.h>
|
||||
#include <QtCore/qbytearray.h>
|
||||
#include <QtCore/qvarlengtharray.h>
|
||||
#include <QtCore/qrefcount.h>
|
||||
#ifndef QT_NO_QOBJECT
|
||||
#include <QtCore/qobjectdefs.h>
|
||||
#endif
|
||||
@ -245,6 +246,9 @@ struct QMetaObject;
|
||||
|
||||
namespace QtPrivate
|
||||
{
|
||||
|
||||
class QMetaTypeInterface;
|
||||
|
||||
/*!
|
||||
This template is used for implicit conversion from type From to type To.
|
||||
\internal
|
||||
@ -424,13 +428,6 @@ struct ConverterFunctor : public AbstractConverterFunction
|
||||
}
|
||||
|
||||
class Q_CORE_EXPORT QMetaType {
|
||||
enum ExtensionFlag { NoExtensionFlags,
|
||||
CreateEx = 0x1, DestroyEx = 0x2,
|
||||
ConstructEx = 0x4, DestructEx = 0x8,
|
||||
NameEx = 0x10, SizeEx = 0x20,
|
||||
CtorEx = 0x40, DtorEx = 0x80,
|
||||
FlagsEx = 0x100, MetaObjectEx = 0x200
|
||||
};
|
||||
public:
|
||||
#ifndef Q_CLANG_QDOC
|
||||
// The code that actually gets compiled.
|
||||
@ -501,16 +498,6 @@ public:
|
||||
};
|
||||
Q_DECLARE_FLAGS(TypeFlags, TypeFlag)
|
||||
|
||||
typedef void (*Deleter)(void *);
|
||||
typedef void *(*Creator)(const void *);
|
||||
|
||||
#if 1 || QT_VERSION < QT_VERSION_CHECK(6, 0, 0) // ### Qt6: fix this
|
||||
typedef void (*Destructor)(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 *);
|
||||
#ifndef QT_NO_DATASTREAM
|
||||
@ -519,41 +506,8 @@ public:
|
||||
static void registerStreamOperators(int type, SaveOperator saveOp,
|
||||
LoadOperator loadOp);
|
||||
#endif
|
||||
static int registerType(const char *typeName, Deleter deleter,
|
||||
Creator creator);
|
||||
static int registerType(const char *typeName, Deleter deleter,
|
||||
Creator creator,
|
||||
Destructor destructor,
|
||||
Constructor constructor,
|
||||
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,
|
||||
Destructor destructor,
|
||||
Constructor constructor,
|
||||
int size,
|
||||
QMetaType::TypeFlags flags,
|
||||
const QMetaObject *metaObject);
|
||||
static int registerNormalizedType(const QT_PREPEND_NAMESPACE(QByteArray) &normalizedTypeName, Destructor destructor,
|
||||
Constructor constructor,
|
||||
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 void registerNormalizedTypedef(const QT_PREPEND_NAMESPACE(QByteArray) &normalizedTypeName, QMetaType type);
|
||||
|
||||
static int type(const char *typeName);
|
||||
|
||||
static int type(const QT_PREPEND_NAMESPACE(QByteArray) &typeName);
|
||||
@ -563,10 +517,6 @@ public:
|
||||
static const QMetaObject *metaObjectForType(int type);
|
||||
static bool isRegistered(int type);
|
||||
static void *create(int type, const void *copy = nullptr);
|
||||
#if QT_DEPRECATED_SINCE(5, 0)
|
||||
QT_DEPRECATED static void *construct(int type, const void *copy = nullptr)
|
||||
{ return create(type, copy); }
|
||||
#endif
|
||||
static void destroy(int type, void *data);
|
||||
static void *construct(int type, void *where, const void *copy);
|
||||
static void destruct(int type, void *where);
|
||||
@ -576,32 +526,37 @@ public:
|
||||
static bool load(QDataStream &stream, int type, void *data);
|
||||
#endif
|
||||
|
||||
explicit QMetaType(const int type = QMetaType::UnknownType); // ### Qt6: drop const
|
||||
inline ~QMetaType();
|
||||
explicit QMetaType(int type);
|
||||
explicit QMetaType(QtPrivate::QMetaTypeInterface *d);
|
||||
QMetaType();
|
||||
~QMetaType();
|
||||
QMetaType(const QMetaType &other);
|
||||
QMetaType &operator=(const QMetaType &);
|
||||
QMetaType(QMetaType &&other) : d_ptr(other.d_ptr) { other.d_ptr = nullptr; }
|
||||
QMetaType &operator=(QMetaType &&other)
|
||||
{
|
||||
qSwap(d_ptr, other.d_ptr);
|
||||
return *this;
|
||||
}
|
||||
|
||||
inline bool isValid() const;
|
||||
inline bool isRegistered() const;
|
||||
inline int id() const;
|
||||
inline int sizeOf() const;
|
||||
inline TypeFlags flags() const;
|
||||
inline const QMetaObject *metaObject() const;
|
||||
bool isValid() const;
|
||||
bool isRegistered() const;
|
||||
int id() const;
|
||||
int sizeOf() const;
|
||||
TypeFlags flags() const;
|
||||
const QMetaObject *metaObject() const;
|
||||
QT_PREPEND_NAMESPACE(QByteArray) name() const;
|
||||
|
||||
inline void *create(const void *copy = nullptr) const;
|
||||
inline void destroy(void *data) const;
|
||||
inline void *construct(void *where, const void *copy = nullptr) const;
|
||||
inline void destruct(void *data) const;
|
||||
void *create(const void *copy = nullptr) const;
|
||||
void destroy(void *data) const;
|
||||
void *construct(void *where, const void *copy = nullptr) const;
|
||||
void destruct(void *data) const;
|
||||
|
||||
template<typename T>
|
||||
static QMetaType fromType()
|
||||
{ return QMetaType(qMetaTypeId<T>()); }
|
||||
|
||||
friend bool operator==(const QMetaType &a, const QMetaType &b)
|
||||
{ return a.m_typeId == b.m_typeId; }
|
||||
|
||||
friend bool operator!=(const QMetaType &a, const QMetaType &b)
|
||||
{ return a.m_typeId != b.m_typeId; }
|
||||
static QMetaType fromType();
|
||||
|
||||
friend bool operator==(const QMetaType &a, const QMetaType &b) { return a.id() == b.id(); }
|
||||
friend bool operator!=(const QMetaType &a, const QMetaType &b) { return !(a == b); }
|
||||
|
||||
public:
|
||||
template<typename T>
|
||||
@ -719,34 +674,6 @@ public:
|
||||
|
||||
static bool hasRegisteredConverterFunction(int fromTypeId, int toTypeId);
|
||||
|
||||
private:
|
||||
static QMetaType typeInfo(const int type);
|
||||
inline QMetaType(const ExtensionFlag extensionFlags, const QMetaTypeInterface *info,
|
||||
TypedConstructor creator,
|
||||
TypedDestructor deleter,
|
||||
SaveOperator saveOp,
|
||||
LoadOperator loadOp,
|
||||
Constructor constructor,
|
||||
Destructor destructor,
|
||||
uint sizeOf,
|
||||
uint theTypeFlags,
|
||||
int typeId,
|
||||
const QMetaObject *metaObject);
|
||||
QMetaType(const QMetaType &other);
|
||||
QMetaType &operator =(const QMetaType &);
|
||||
inline bool isExtended(const ExtensionFlag flag) const { return m_extensionFlags & flag; }
|
||||
|
||||
// Methods used for future binary compatible extensions
|
||||
void ctor(const QMetaTypeInterface *info);
|
||||
void dtor();
|
||||
uint sizeExtended() const;
|
||||
QMetaType::TypeFlags flagsExtended() const;
|
||||
const QMetaObject *metaObjectExtended() const;
|
||||
void *createExtended(const void *copy = nullptr) const;
|
||||
void destroyExtended(void *data) const;
|
||||
void *constructExtended(void *where, const void *copy = nullptr) const;
|
||||
void destructExtended(void *data) const;
|
||||
|
||||
static bool registerComparatorFunction(const QtPrivate::AbstractComparatorFunction *f, int type);
|
||||
#ifndef QT_NO_DEBUG_STREAM
|
||||
static bool registerDebugStreamOperatorFunction(const QtPrivate::AbstractDebugStreamFunction *f, int type);
|
||||
@ -764,19 +691,7 @@ private:
|
||||
static bool registerConverterFunction(const QtPrivate::AbstractConverterFunction *f, int from, int to);
|
||||
static void unregisterConverterFunction(int from, int to);
|
||||
private:
|
||||
|
||||
TypedConstructor m_typedConstructor;
|
||||
TypedDestructor m_typedDestructor;
|
||||
SaveOperator m_saveOp;
|
||||
LoadOperator m_loadOp;
|
||||
Constructor m_constructor;
|
||||
Destructor m_destructor;
|
||||
void *m_extension; // space reserved for future use
|
||||
uint m_size;
|
||||
uint m_typeFlags;
|
||||
uint m_extensionFlags;
|
||||
int m_typeId;
|
||||
const QMetaObject *m_metaObject;
|
||||
QtPrivate::QMetaTypeInterface *d_ptr = nullptr;
|
||||
};
|
||||
|
||||
#undef QT_DEFINE_METATYPE_ID
|
||||
@ -1553,33 +1468,38 @@ namespace QtPrivate
|
||||
template<typename T, typename Enable = void>
|
||||
struct MetaObjectForType
|
||||
{
|
||||
static inline const QMetaObject *value() { return nullptr; }
|
||||
static constexpr inline const QMetaObject *value() { return nullptr; }
|
||||
};
|
||||
#ifndef QT_NO_QOBJECT
|
||||
template<>
|
||||
struct MetaObjectForType<void>
|
||||
{
|
||||
static inline const QMetaObject *value() { return nullptr; }
|
||||
static constexpr inline const QMetaObject *value() { return nullptr; }
|
||||
};
|
||||
template<typename T>
|
||||
struct MetaObjectForType<T*, typename std::enable_if<IsPointerToTypeDerivedFromQObject<T*>::Value>::type>
|
||||
{
|
||||
static inline const QMetaObject *value() { return &T::staticMetaObject; }
|
||||
static constexpr inline const QMetaObject *value() { return &T::staticMetaObject; }
|
||||
};
|
||||
template<typename T>
|
||||
struct MetaObjectForType<T, typename std::enable_if<IsGadgetHelper<T>::IsGadgetOrDerivedFrom>::type>
|
||||
{
|
||||
static inline const QMetaObject *value() { return &T::staticMetaObject; }
|
||||
static constexpr inline const QMetaObject *value() { return &T::staticMetaObject; }
|
||||
};
|
||||
template<typename T>
|
||||
struct MetaObjectForType<T, typename std::enable_if<IsPointerToGadgetHelper<T>::IsGadgetOrDerivedFrom>::type>
|
||||
{
|
||||
static inline const QMetaObject *value() { return &IsPointerToGadgetHelper<T>::BaseType::staticMetaObject; }
|
||||
static constexpr inline const QMetaObject *value()
|
||||
{
|
||||
return &IsPointerToGadgetHelper<T>::BaseType::staticMetaObject;
|
||||
}
|
||||
};
|
||||
template<typename T>
|
||||
struct MetaObjectForType<T, typename std::enable_if<IsQEnumHelper<T>::Value>::type >
|
||||
{
|
||||
static inline const QMetaObject *value() { return qt_getEnumMetaObject(T()); }
|
||||
static constexpr inline const QMetaObject *value() { return qt_getEnumMetaObject(T()); }
|
||||
};
|
||||
#endif
|
||||
|
||||
template<typename T>
|
||||
struct IsSharedPointerToTypeDerivedFromQObject
|
||||
@ -1726,22 +1646,6 @@ namespace QtPrivate
|
||||
};
|
||||
|
||||
template<class T>
|
||||
struct Qt5CompatibilityHook
|
||||
{
|
||||
static inline void postRegister(int, const QByteArray &) {};
|
||||
};
|
||||
|
||||
Q_CORE_EXPORT void qt5CompatibilityHookPostRegister(int id, const QByteArray &normalizedTypeName);
|
||||
|
||||
template<class T>
|
||||
struct Qt5CompatibilityHook<QVector<T>>
|
||||
{
|
||||
static inline void postRegister(int id, const QByteArray &normalizedTypeName)
|
||||
{
|
||||
qt5CompatibilityHookPostRegister(id, normalizedTypeName);
|
||||
}
|
||||
};
|
||||
|
||||
Q_CORE_EXPORT bool isBuiltinType(const QByteArray &type);
|
||||
} // namespace QtPrivate
|
||||
|
||||
@ -1837,38 +1741,29 @@ namespace QtPrivate {
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
int qRegisterNormalizedMetaType(const QT_PREPEND_NAMESPACE(QByteArray) &normalizedTypeName
|
||||
int qRegisterNormalizedMetaType(const QT_PREPEND_NAMESPACE(QByteArray) &_normalizedTypeName
|
||||
#ifndef Q_CLANG_QDOC
|
||||
, T * dummy = 0
|
||||
, typename QtPrivate::MetaTypeDefinedHelper<T, QMetaTypeId2<T>::Defined && !QMetaTypeId2<T>::IsBuiltIn>::DefinedType defined = QtPrivate::MetaTypeDefinedHelper<T, QMetaTypeId2<T>::Defined && !QMetaTypeId2<T>::IsBuiltIn>::Defined
|
||||
, T * = 0
|
||||
, typename QtPrivate::MetaTypeDefinedHelper<T, QMetaTypeId2<T>::Defined && !QMetaTypeId2<T>::IsBuiltIn>::DefinedType = QtPrivate::MetaTypeDefinedHelper<T, QMetaTypeId2<T>::Defined && !QMetaTypeId2<T>::IsBuiltIn>::Defined
|
||||
#endif
|
||||
)
|
||||
{
|
||||
auto normalizedTypeName = _normalizedTypeName;
|
||||
#ifndef QT_NO_QOBJECT
|
||||
// FIXME currently not normalized because we don't do compile time normalization
|
||||
normalizedTypeName = QMetaObject::normalizedType(_normalizedTypeName.constData());
|
||||
Q_ASSERT_X(normalizedTypeName == QMetaObject::normalizedType(normalizedTypeName.constData()), "qRegisterNormalizedMetaType", "qRegisterNormalizedMetaType was called with a not normalized type name, please call qRegisterMetaType instead.");
|
||||
#endif
|
||||
const int typedefOf = dummy ? -1 : QtPrivate::QMetaTypeIdHelper<T>::qt_metatype_id();
|
||||
if (typedefOf != -1)
|
||||
return QMetaType::registerNormalizedTypedef(normalizedTypeName, typedefOf);
|
||||
|
||||
QMetaType::TypeFlags flags(QtPrivate::QMetaTypeTypeFlags<T>::Flags);
|
||||
|
||||
if (defined)
|
||||
flags |= QMetaType::WasDeclaredAsMetaType;
|
||||
|
||||
const int id = QMetaType::registerNormalizedType(normalizedTypeName,
|
||||
QtMetaTypePrivate::QMetaTypeFunctionHelper<T>::Destruct,
|
||||
QtMetaTypePrivate::QMetaTypeFunctionHelper<T>::Construct,
|
||||
int(sizeof(T)),
|
||||
flags,
|
||||
QtPrivate::MetaObjectForType<T>::value());
|
||||
const QMetaType metaType = QMetaType::fromType<T>();
|
||||
const int id = metaType.id();
|
||||
|
||||
if (id > 0) {
|
||||
QMetaType::registerNormalizedTypedef(normalizedTypeName, metaType);
|
||||
QtPrivate::SequentialContainerConverterHelper<T>::registerConverter(id);
|
||||
QtPrivate::AssociativeContainerConverterHelper<T>::registerConverter(id);
|
||||
QtPrivate::MetaTypePairHelper<T>::registerConverter(id);
|
||||
QtPrivate::MetaTypeSmartPointerHelper<T>::registerConverter(id);
|
||||
QtPrivate::Qt5CompatibilityHook<T>::postRegister(id, normalizedTypeName);
|
||||
}
|
||||
|
||||
return id;
|
||||
@ -1907,8 +1802,11 @@ void qRegisterMetaTypeStreamOperators(const char *typeName
|
||||
template <typename T>
|
||||
inline Q_DECL_CONSTEXPR int qMetaTypeId()
|
||||
{
|
||||
Q_STATIC_ASSERT_X(QMetaTypeId2<T>::Defined, "Type is not registered, please use the Q_DECLARE_METATYPE macro to make it known to Qt's meta-object system");
|
||||
return QMetaTypeId2<T>::qt_metatype_id();
|
||||
if constexpr (bool(QMetaTypeId2<T>::IsBuiltIn)) {
|
||||
return QMetaTypeId2<T>::MetaType;
|
||||
} else {
|
||||
return QMetaType::fromType<T>().id();
|
||||
}
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
@ -2074,6 +1972,7 @@ inline int qRegisterMetaTypeStreamOperators()
|
||||
{ \
|
||||
enum { Defined = 1, IsBuiltIn = true, MetaType = METATYPEID }; \
|
||||
static inline Q_DECL_CONSTEXPR int qt_metatype_id() { return METATYPEID; } \
|
||||
static constexpr const char * const name = #NAME; \
|
||||
}; \
|
||||
QT_END_NAMESPACE
|
||||
|
||||
@ -2292,104 +2191,6 @@ QT_BEGIN_NAMESPACE
|
||||
|
||||
#undef Q_DECLARE_METATYPE_TEMPLATE_SMART_POINTER_ITER
|
||||
|
||||
inline QMetaType::QMetaType(const ExtensionFlag extensionFlags, const QMetaTypeInterface *info,
|
||||
TypedConstructor creator,
|
||||
TypedDestructor deleter,
|
||||
SaveOperator saveOp,
|
||||
LoadOperator loadOp,
|
||||
Constructor constructor,
|
||||
Destructor destructor,
|
||||
uint size,
|
||||
uint theTypeFlags,
|
||||
int typeId,
|
||||
const QMetaObject *_metaObject)
|
||||
: m_typedConstructor(creator)
|
||||
, m_typedDestructor(deleter)
|
||||
, m_saveOp(saveOp)
|
||||
, m_loadOp(loadOp)
|
||||
, m_constructor(constructor)
|
||||
, m_destructor(destructor)
|
||||
, m_extension(nullptr)
|
||||
, m_size(size)
|
||||
, m_typeFlags(theTypeFlags)
|
||||
, m_extensionFlags(extensionFlags)
|
||||
, m_typeId(typeId)
|
||||
, m_metaObject(_metaObject)
|
||||
{
|
||||
if (Q_UNLIKELY(isExtended(CtorEx) || typeId == QMetaType::Void))
|
||||
ctor(info);
|
||||
}
|
||||
|
||||
inline QMetaType::~QMetaType()
|
||||
{
|
||||
if (Q_UNLIKELY(isExtended(DtorEx)))
|
||||
dtor();
|
||||
}
|
||||
|
||||
inline bool QMetaType::isValid() const
|
||||
{
|
||||
return m_typeId != UnknownType;
|
||||
}
|
||||
|
||||
inline bool QMetaType::isRegistered() const
|
||||
{
|
||||
return isValid();
|
||||
}
|
||||
|
||||
inline int QMetaType::id() const
|
||||
{
|
||||
return m_typeId;
|
||||
}
|
||||
|
||||
inline void *QMetaType::create(const void *copy) const
|
||||
{
|
||||
// ### TODO Qt6 remove the extension
|
||||
return createExtended(copy);
|
||||
}
|
||||
|
||||
inline void QMetaType::destroy(void *data) const
|
||||
{
|
||||
// ### TODO Qt6 remove the extension
|
||||
destroyExtended(data);
|
||||
}
|
||||
|
||||
inline void *QMetaType::construct(void *where, const void *copy) const
|
||||
{
|
||||
if (Q_UNLIKELY(isExtended(ConstructEx)))
|
||||
return constructExtended(where, copy);
|
||||
return m_constructor(where, copy);
|
||||
}
|
||||
|
||||
inline void QMetaType::destruct(void *data) const
|
||||
{
|
||||
if (Q_UNLIKELY(isExtended(DestructEx)))
|
||||
return destructExtended(data);
|
||||
if (Q_UNLIKELY(!data))
|
||||
return;
|
||||
m_destructor(data);
|
||||
}
|
||||
|
||||
inline int QMetaType::sizeOf() const
|
||||
{
|
||||
if (Q_UNLIKELY(isExtended(SizeEx)))
|
||||
return sizeExtended();
|
||||
return m_size;
|
||||
}
|
||||
|
||||
inline QMetaType::TypeFlags QMetaType::flags() const
|
||||
{
|
||||
if (Q_UNLIKELY(isExtended(FlagsEx)))
|
||||
return flagsExtended();
|
||||
return QMetaType::TypeFlags(m_typeFlags);
|
||||
}
|
||||
|
||||
inline const QMetaObject *QMetaType::metaObject() const
|
||||
{
|
||||
if (Q_UNLIKELY(isExtended(MetaObjectEx)))
|
||||
return metaObjectExtended();
|
||||
return m_metaObject;
|
||||
}
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
||||
|
||||
@ -2451,6 +2252,163 @@ namespace QtPrivate {
|
||||
};
|
||||
}
|
||||
|
||||
namespace QtPrivate {
|
||||
|
||||
class QMetaTypeInterface
|
||||
{
|
||||
public:
|
||||
uint revision; // 0 in Qt 6.0. Can increase if new field are added
|
||||
uint size;
|
||||
uint alignment;
|
||||
uint flags;
|
||||
const QMetaObject *metaObject;
|
||||
const char *name;
|
||||
|
||||
QBasicAtomicInt typeId;
|
||||
QtPrivate::RefCount ref;
|
||||
|
||||
// Called when the type is unregistered, to delete this
|
||||
using DeleteSelf = void (*)(QMetaTypeInterface *);
|
||||
DeleteSelf deleteSelf;
|
||||
|
||||
using DefaultCtrFn = void (*)(const QMetaTypeInterface *, void *);
|
||||
DefaultCtrFn defaultCtr;
|
||||
using CopyCtrFn = void (*)(const QMetaTypeInterface *, void *, const void *);
|
||||
CopyCtrFn copyCtr;
|
||||
using MoveCtrFn = void (*)(const QMetaTypeInterface *, void *, void *);
|
||||
MoveCtrFn moveCtr;
|
||||
using DtorFn = void (*)(const QMetaTypeInterface *, void *);
|
||||
DtorFn dtor;
|
||||
|
||||
using LegacyRegisterOp = void (*)();
|
||||
LegacyRegisterOp legacyRegisterOp;
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
constexpr auto typenameHelper()
|
||||
{
|
||||
constexpr auto prefix = sizeof(
|
||||
#ifdef Q_CC_CLANG
|
||||
"auto QtPrivate::typenameHelper() [T = ") - 1;
|
||||
#else
|
||||
"constexpr auto QtPrivate::typenameHelper() [with T = ") - 1;
|
||||
#endif
|
||||
constexpr int suffix = sizeof("]");
|
||||
constexpr int len = sizeof(__PRETTY_FUNCTION__) - prefix - suffix;
|
||||
std::array<char, len + 1> result {};
|
||||
for (int i = 0; i < len; ++i)
|
||||
result[i] = __PRETTY_FUNCTION__[prefix + i];
|
||||
return result;
|
||||
}
|
||||
|
||||
template<typename T, typename = void>
|
||||
struct BuiltinMetaType : std::integral_constant<int, 0>
|
||||
{
|
||||
};
|
||||
template<typename T>
|
||||
struct BuiltinMetaType<T, std::enable_if_t<QMetaTypeId2<T>::IsBuiltIn>>
|
||||
: std::integral_constant<int, QMetaTypeId2<T>::MetaType>
|
||||
{
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
class QMetaTypeForType
|
||||
{
|
||||
static const decltype(typenameHelper<T>()) name;
|
||||
|
||||
public:
|
||||
static QMetaTypeInterface metaType;
|
||||
};
|
||||
|
||||
#ifdef Q_CC_CLANG
|
||||
// Workaround for https://bugs.llvm.org/show_bug.cgi?id=44554 : Every lambda used for initializing
|
||||
// static members need a different signature for explicit instentiation
|
||||
#define QT_METATYPE_CONSTEXPRLAMDA(...) [](std::integral_constant<int, __COUNTER__> = {}) constexpr __VA_ARGS__ ()
|
||||
#elif defined(Q_CC_MSVC) && Q_CC_MSVC < 1920
|
||||
// Workaround a bug with 'if constexpr' not working in lambda that are not generic in MSVC 2017
|
||||
#define QT_METATYPE_CONSTEXPRLAMDA(...) [](auto) constexpr __VA_ARGS__ (0)
|
||||
#else
|
||||
#define QT_METATYPE_CONSTEXPRLAMDA(...) []() constexpr __VA_ARGS__ ()
|
||||
#endif
|
||||
|
||||
template<typename T>
|
||||
QMetaTypeInterface QMetaTypeForType<T>::metaType = {
|
||||
/*.revision=*/ 0,
|
||||
/*.size=*/ sizeof(T),
|
||||
/*.alignment=*/ alignof(T),
|
||||
/*.flags=*/ QMetaTypeTypeFlags<T>::Flags,
|
||||
/*.metaObject=*/ MetaObjectForType<T>::value(),
|
||||
/*.name=*/ QT_METATYPE_CONSTEXPRLAMDA( -> const char * {
|
||||
if constexpr (bool(QMetaTypeId2<T>::IsBuiltIn)) {
|
||||
return QMetaTypeId2<T>::name;
|
||||
} else {
|
||||
return name.data();
|
||||
}
|
||||
}),
|
||||
/*.typeId=*/ BuiltinMetaType<T>::value,
|
||||
/*.ref=*/ Q_REFCOUNT_INITIALIZE_STATIC,
|
||||
/*.deleteSelf=*/ nullptr,
|
||||
/*.defaultCtr=*/ QT_METATYPE_CONSTEXPRLAMDA( -> QMetaTypeInterface::DefaultCtrFn {
|
||||
if constexpr (std::is_default_constructible_v<T>) {
|
||||
return [](const QMetaTypeInterface *, void *addr) { new (addr) T(); };
|
||||
} else {
|
||||
return nullptr;
|
||||
}
|
||||
}),
|
||||
/*.copyCtr=*/ QT_METATYPE_CONSTEXPRLAMDA( -> QMetaTypeInterface::CopyCtrFn {
|
||||
if (std::is_copy_constructible_v<T>) {
|
||||
return [](const QMetaTypeInterface *, void *addr, const void *other) {
|
||||
new (addr) T(*reinterpret_cast<const T *>(other));
|
||||
};
|
||||
} else {
|
||||
return nullptr;
|
||||
}
|
||||
}),
|
||||
/*.moveCtr=*/ QT_METATYPE_CONSTEXPRLAMDA( -> QMetaTypeInterface::MoveCtrFn {
|
||||
if constexpr (std::is_move_constructible_v<T>) {
|
||||
return [](const QMetaTypeInterface *, void *addr, void *other) {
|
||||
new (addr) T(std::move(*reinterpret_cast<T *>(other)));
|
||||
};
|
||||
} else {
|
||||
return nullptr;
|
||||
}
|
||||
}),
|
||||
/*.dtor=*/ QT_METATYPE_CONSTEXPRLAMDA( -> QMetaTypeInterface::DtorFn {
|
||||
return [](const QMetaTypeInterface *, void *addr) { reinterpret_cast<T *>(addr)->~T(); };
|
||||
}),
|
||||
/*.legacyRegisterOp=*/ QT_METATYPE_CONSTEXPRLAMDA( -> QMetaTypeInterface::LegacyRegisterOp {
|
||||
if constexpr (QMetaTypeId2<T>::Defined && !QMetaTypeId2<T>::IsBuiltIn) {
|
||||
return []() { QMetaTypeId2<T>::qt_metatype_id(); };
|
||||
} else {
|
||||
return nullptr;
|
||||
}
|
||||
})
|
||||
};
|
||||
#undef QT_METATYPE_CONSTEXPRLAMDA
|
||||
|
||||
template<typename T>
|
||||
constexpr const decltype(typenameHelper<T>()) QMetaTypeForType<T>::name = typenameHelper<T>();
|
||||
|
||||
|
||||
template<typename T>
|
||||
constexpr QMetaTypeInterface *qMetaTypeIntefaceForType()
|
||||
{
|
||||
using Ty = std::remove_cv_t<std::remove_reference_t<T>>;
|
||||
if constexpr (std::is_same_v<Ty, void>) {
|
||||
return nullptr;
|
||||
} else {
|
||||
return &QMetaTypeForType<Ty>::metaType;
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace QtPrivate
|
||||
|
||||
template<typename T>
|
||||
QMetaType QMetaType::fromType()
|
||||
{
|
||||
return QMetaType(QtPrivate::qMetaTypeIntefaceForType<T>());
|
||||
}
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
||||
#endif // QMETATYPE_H
|
||||
|
@ -121,77 +121,15 @@ QT_FOR_EACH_STATIC_WIDGETS_CLASS(QT_DECLARE_WIDGETS_MODULE_TYPES_ITER)
|
||||
#undef QT_DECLARE_GUI_MODULE_TYPES_ITER
|
||||
#undef QT_DECLARE_WIDGETS_MODULE_TYPES_ITER
|
||||
|
||||
class QMetaTypeInterface
|
||||
class QMetaTypeModuleHelper
|
||||
{
|
||||
public:
|
||||
QMetaType::SaveOperator saveOp;
|
||||
QMetaType::LoadOperator loadOp;
|
||||
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;
|
||||
};
|
||||
|
||||
virtual QtPrivate::QMetaTypeInterface *interfaceForType(int) const = 0;
|
||||
#ifndef QT_NO_DATASTREAM
|
||||
# define QT_METATYPE_INTERFACE_INIT_DATASTREAM_IMPL(Type) \
|
||||
/*saveOp*/(QtMetaTypePrivate::QMetaTypeFunctionHelper<Type, QtMetaTypePrivate::TypeDefinition<Type>::IsAvailable>::Save), \
|
||||
/*loadOp*/(QtMetaTypePrivate::QMetaTypeFunctionHelper<Type, QtMetaTypePrivate::TypeDefinition<Type>::IsAvailable>::Load),
|
||||
# define QT_METATYPE_INTERFACE_INIT_EMPTY_DATASTREAM_IMPL(Type) \
|
||||
/*saveOp*/ nullptr, \
|
||||
/*loadOp*/ nullptr,
|
||||
#else
|
||||
# define QT_METATYPE_INTERFACE_INIT_EMPTY_DATASTREAM_IMPL(Type) \
|
||||
/*saveOp*/ nullptr, \
|
||||
/*loadOp*/ nullptr,
|
||||
# define QT_METATYPE_INTERFACE_INIT_DATASTREAM_IMPL(Type) \
|
||||
QT_METATYPE_INTERFACE_INIT_EMPTY_DATASTREAM_IMPL(Type)
|
||||
virtual bool save(QDataStream &stream, int type, const void *data) const = 0;
|
||||
virtual bool load(QDataStream &stream, int type, void *data) const = 0;
|
||||
#endif
|
||||
|
||||
#ifndef QT_BOOTSTRAPPED
|
||||
#define METAOBJECT_DELEGATE(Type) (QtPrivate::MetaObjectForType<Type>::value())
|
||||
#else
|
||||
#define METAOBJECT_DELEGATE(Type) nullptr
|
||||
#endif
|
||||
|
||||
#define QT_METATYPE_INTERFACE_INIT_IMPL(Type, DATASTREAM_DELEGATE) \
|
||||
{ \
|
||||
DATASTREAM_DELEGATE(Type) \
|
||||
/*constructor*/(QtMetaTypePrivate::QMetaTypeFunctionHelper<Type, QtMetaTypePrivate::TypeDefinition<Type>::IsAvailable>::Construct), \
|
||||
/*destructor*/(QtMetaTypePrivate::QMetaTypeFunctionHelper<Type, QtMetaTypePrivate::TypeDefinition<Type>::IsAvailable>::Destruct), \
|
||||
/*size*/(QTypeInfo<Type>::sizeOf), \
|
||||
/*flags*/QtPrivate::QMetaTypeTypeFlags<Type>::Flags, \
|
||||
/*metaObject*/METAOBJECT_DELEGATE(Type), \
|
||||
/*typedConstructor*/ nullptr, \
|
||||
/*typedDestructor*/ nullptr \
|
||||
}
|
||||
|
||||
|
||||
/* These QT_METATYPE_INTERFACE_INIT* macros are used to initialize QMetaTypeInterface instance.
|
||||
|
||||
- QT_METATYPE_INTERFACE_INIT(Type) -> It takes Type argument and creates all necessary wrapper functions for the Type,
|
||||
it detects if QT_NO_DATASTREAM was defined. Probably it is the macro that you want to use.
|
||||
|
||||
- QT_METATYPE_INTERFACE_INIT_EMPTY() -> It initializes an empty QMetaTypeInterface instance.
|
||||
|
||||
- QT_METATYPE_INTERFACE_INIT_NO_DATASTREAM(Type) -> Temporary workaround for missing auto-detection of data stream
|
||||
operators. It creates same instance as QT_METATYPE_INTERFACE_INIT(Type) but with null stream operators callbacks.
|
||||
*/
|
||||
#define QT_METATYPE_INTERFACE_INIT(Type) QT_METATYPE_INTERFACE_INIT_IMPL(Type, QT_METATYPE_INTERFACE_INIT_DATASTREAM_IMPL)
|
||||
#define QT_METATYPE_INTERFACE_INIT_NO_DATASTREAM(Type) QT_METATYPE_INTERFACE_INIT_IMPL(Type, QT_METATYPE_INTERFACE_INIT_EMPTY_DATASTREAM_IMPL)
|
||||
#define QT_METATYPE_INTERFACE_INIT_EMPTY() \
|
||||
{ \
|
||||
QT_METATYPE_INTERFACE_INIT_EMPTY_DATASTREAM_IMPL(void) \
|
||||
/*constructor*/ nullptr, \
|
||||
/*destructor*/ nullptr, \
|
||||
/*size*/ 0, \
|
||||
/*flags*/ 0, \
|
||||
/*metaObject*/ nullptr , \
|
||||
/*typedConstructor*/ nullptr, \
|
||||
/*typedDestructor*/ nullptr \
|
||||
}
|
||||
};
|
||||
|
||||
namespace QtMetaTypePrivate {
|
||||
template<typename T>
|
||||
@ -253,6 +191,32 @@ template<> struct TypeDefinition<QQuaternion> { static const bool IsAvailable =
|
||||
#ifdef QT_NO_ICON
|
||||
template<> struct TypeDefinition<QIcon> { static const bool IsAvailable = false; };
|
||||
#endif
|
||||
|
||||
template<typename T>
|
||||
static QtPrivate::QMetaTypeInterface *getInterfaceFromType()
|
||||
{
|
||||
if constexpr (std::is_same_v<T, void>) {
|
||||
return nullptr;
|
||||
} else if constexpr (QtMetaTypePrivate::TypeDefinition<T>::IsAvailable) {
|
||||
return &QtPrivate::QMetaTypeForType<T>::metaType;
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
#define QT_METATYPE_CONVERT_ID_TO_TYPE(MetaTypeName, MetaTypeId, RealName) \
|
||||
case QMetaType::MetaTypeName: \
|
||||
return QtMetaTypePrivate::getInterfaceFromType<RealName>();
|
||||
|
||||
#define QT_METATYPE_DATASTREAM_SAVE(MetaTypeName, MetaTypeId, RealName) \
|
||||
case QMetaType::MetaTypeName: \
|
||||
QtMetaTypePrivate::QMetaTypeFunctionHelper<RealName, QtMetaTypePrivate::TypeDefinition<RealName>::IsAvailable>::Save(stream, data); \
|
||||
return true;
|
||||
|
||||
#define QT_METATYPE_DATASTREAM_LOAD(MetaTypeName, MetaTypeId, RealName) \
|
||||
case QMetaType::MetaTypeName: \
|
||||
QtMetaTypePrivate::QMetaTypeFunctionHelper<RealName, QtMetaTypePrivate::TypeDefinition<RealName>::IsAvailable>::Load(stream, data); \
|
||||
return true;
|
||||
|
||||
} //namespace QtMetaTypePrivate
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
@ -127,27 +127,31 @@ QDBusMetaObjectGenerator::QDBusMetaObjectGenerator(const QString &interfaceName,
|
||||
}
|
||||
}
|
||||
|
||||
static int registerComplexDBusType(const char *typeName)
|
||||
static int registerComplexDBusType(const QByteArray &typeName)
|
||||
{
|
||||
struct QDBusRawTypeHandler {
|
||||
static void destruct(void *)
|
||||
{
|
||||
qFatal("Cannot destruct placeholder type QDBusRawType");
|
||||
}
|
||||
|
||||
static void *construct(void *, const void *)
|
||||
{
|
||||
qFatal("Cannot construct placeholder type QDBusRawType");
|
||||
return nullptr;
|
||||
}
|
||||
struct QDBusRawTypeHandler : QtPrivate::QMetaTypeInterface
|
||||
{
|
||||
const QByteArray name;
|
||||
QDBusRawTypeHandler(const QByteArray &name)
|
||||
: QtPrivate::QMetaTypeInterface {
|
||||
0, sizeof(void *), sizeof(void *), QMetaType::MovableType, nullptr,
|
||||
name.constData(), 0, QtPrivate::RefCount{0},
|
||||
[](QtPrivate::QMetaTypeInterface *self) {
|
||||
delete static_cast<QDBusRawTypeHandler *>(self);
|
||||
},
|
||||
nullptr, nullptr, nullptr, nullptr, nullptr
|
||||
},
|
||||
name(name)
|
||||
{}
|
||||
};
|
||||
|
||||
return QMetaType::registerNormalizedType(typeName,
|
||||
QDBusRawTypeHandler::destruct,
|
||||
QDBusRawTypeHandler::construct,
|
||||
sizeof(void *),
|
||||
QMetaType::MovableType,
|
||||
nullptr);
|
||||
static QBasicMutex mutex;
|
||||
static QHash<QByteArray, QMetaType> hash;
|
||||
QMutexLocker lock(&mutex);
|
||||
QMetaType &metatype = hash[typeName];
|
||||
if (!metatype.isValid())
|
||||
metatype = QMetaType(new QDBusRawTypeHandler(typeName));
|
||||
return metatype.id();
|
||||
}
|
||||
|
||||
Q_DBUS_EXPORT bool qt_dbus_metaobject_skip_annotations = false;
|
||||
|
@ -338,19 +338,41 @@ const QVariant::Handler qt_gui_variant_handler = {
|
||||
#define QT_IMPL_METATYPEINTERFACE_GUI_TYPES(MetaTypeName, MetaTypeId, RealName) \
|
||||
QT_METATYPE_INTERFACE_INIT(RealName),
|
||||
|
||||
static const QMetaTypeInterface qVariantGuiHelper[] = {
|
||||
QT_FOR_EACH_STATIC_GUI_CLASS(QT_IMPL_METATYPEINTERFACE_GUI_TYPES)
|
||||
};
|
||||
static const struct : QMetaTypeModuleHelper
|
||||
{
|
||||
QtPrivate::QMetaTypeInterface *interfaceForType(int type) const override {
|
||||
switch (type) {
|
||||
QT_FOR_EACH_STATIC_GUI_CLASS(QT_METATYPE_CONVERT_ID_TO_TYPE)
|
||||
default: return nullptr;
|
||||
}
|
||||
}
|
||||
#ifndef QT_NO_DATASTREAM
|
||||
bool save(QDataStream &stream, int type, const void *data) const override {
|
||||
switch (type) {
|
||||
QT_FOR_EACH_STATIC_GUI_CLASS(QT_METATYPE_DATASTREAM_SAVE)
|
||||
default: return false;
|
||||
}
|
||||
}
|
||||
bool load(QDataStream &stream, int type, void *data) const override {
|
||||
switch (type) {
|
||||
QT_FOR_EACH_STATIC_GUI_CLASS(QT_METATYPE_DATASTREAM_LOAD)
|
||||
default: return false;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
} qVariantGuiHelper;
|
||||
|
||||
|
||||
#undef QT_IMPL_METATYPEINTERFACE_GUI_TYPES
|
||||
} // namespace used to hide QVariant handler
|
||||
|
||||
extern Q_CORE_EXPORT const QMetaTypeInterface *qMetaTypeGuiHelper;
|
||||
extern Q_CORE_EXPORT const QMetaTypeModuleHelper *qMetaTypeGuiHelper;
|
||||
|
||||
void qRegisterGuiVariant()
|
||||
{
|
||||
QVariantPrivate::registerHandler(QModulesPrivate::Gui, &qt_gui_variant_handler);
|
||||
qMetaTypeGuiHelper = qVariantGuiHelper;
|
||||
qMetaTypeGuiHelper = &qVariantGuiHelper;
|
||||
}
|
||||
Q_CONSTRUCTOR_FUNCTION(qRegisterGuiVariant)
|
||||
|
||||
|
@ -138,23 +138,42 @@ static const QVariant::Handler widgets_handler = {
|
||||
#endif
|
||||
};
|
||||
|
||||
#define QT_IMPL_METATYPEINTERFACE_WIDGETS_TYPES(MetaTypeName, MetaTypeId, RealName) \
|
||||
QT_METATYPE_INTERFACE_INIT(RealName),
|
||||
static const struct : QMetaTypeModuleHelper
|
||||
{
|
||||
QtPrivate::QMetaTypeInterface *interfaceForType(int type) const override {
|
||||
switch (type) {
|
||||
QT_FOR_EACH_STATIC_WIDGETS_CLASS(QT_METATYPE_CONVERT_ID_TO_TYPE)
|
||||
default: return nullptr;
|
||||
}
|
||||
}
|
||||
#ifndef QT_NO_DATASTREAM
|
||||
bool save(QDataStream &stream, int type, const void *data) const override {
|
||||
switch (type) {
|
||||
QT_FOR_EACH_STATIC_WIDGETS_CLASS(QT_METATYPE_DATASTREAM_SAVE)
|
||||
default: return false;
|
||||
}
|
||||
}
|
||||
bool load(QDataStream &stream, int type, void *data) const override {
|
||||
switch (type) {
|
||||
QT_FOR_EACH_STATIC_WIDGETS_CLASS(QT_METATYPE_DATASTREAM_LOAD)
|
||||
default: return false;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
} qVariantWidgetsHelper;
|
||||
|
||||
static const QMetaTypeInterface qVariantWidgetsHelper[] = {
|
||||
QT_FOR_EACH_STATIC_WIDGETS_CLASS(QT_IMPL_METATYPEINTERFACE_WIDGETS_TYPES)
|
||||
};
|
||||
|
||||
#undef QT_IMPL_METATYPEINTERFACE_WIDGETS_TYPES
|
||||
|
||||
} // namespace
|
||||
|
||||
extern Q_CORE_EXPORT const QMetaTypeInterface *qMetaTypeWidgetsHelper;
|
||||
extern Q_CORE_EXPORT const QMetaTypeModuleHelper *qMetaTypeWidgetsHelper;
|
||||
|
||||
void qRegisterWidgetsVariant()
|
||||
{
|
||||
qRegisterMetaType<QWidget*>();
|
||||
qMetaTypeWidgetsHelper = qVariantWidgetsHelper;
|
||||
qMetaTypeWidgetsHelper = &qVariantWidgetsHelper;
|
||||
QVariantPrivate::registerHandler(QModulesPrivate::Widgets, &widgets_handler);
|
||||
}
|
||||
Q_CONSTRUCTOR_FUNCTION(qRegisterWidgetsVariant)
|
||||
|
@ -129,6 +129,7 @@ private slots:
|
||||
struct BaseGenericType
|
||||
{
|
||||
int m_typeId = -1;
|
||||
QMetaType m_metatype;
|
||||
virtual void *constructor(int typeId, void *where, const void *copy) = 0;
|
||||
virtual void staticMetacallFunction(QMetaObject::Call _c, int _id, void **_a) = 0;
|
||||
virtual void saveOperator(QDataStream & out) const = 0;
|
||||
@ -300,11 +301,19 @@ void tst_QMetaType::registerGadget(const char *name, const QVector<GadgetPropert
|
||||
meta->d.static_metacall = &GadgetsStaticMetacallFunction;
|
||||
meta->d.superdata = nullptr;
|
||||
const auto flags = QMetaType::WasDeclaredAsMetaType | QMetaType::IsGadget | QMetaType::NeedsConstruction | QMetaType::NeedsDestruction;
|
||||
int gadgetTypeId = QMetaType::registerType(name,
|
||||
&GadgetTypedDestructor,
|
||||
&GadgetTypedConstructor,
|
||||
sizeof(GenericGadgetType),
|
||||
flags, meta);
|
||||
using TypeInfo = QtPrivate::QMetaTypeInterface;
|
||||
auto typeInfo = new TypeInfo {
|
||||
0, sizeof(GenericGadgetType), alignof(GenericGadgetType), uint(flags), meta, name, 0,
|
||||
QtPrivate::RefCount{ 0 },
|
||||
[](TypeInfo *self) { delete self; },
|
||||
[](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 };
|
||||
QMetaType gadgetMetaType(typeInfo);
|
||||
dynamicGadgetProperties->m_metatype = gadgetMetaType;
|
||||
int gadgetTypeId = QMetaType(typeInfo).id();
|
||||
QVERIFY(gadgetTypeId > 0);
|
||||
QMetaType::registerStreamOperators(gadgetTypeId, &GadgetSaveOperator, &GadgetLoadOperator);
|
||||
s_managedTypes[gadgetTypeId] = qMakePair(dynamicGadgetProperties, std::shared_ptr<QMetaObject>{meta, [](QMetaObject *ptr){ ::free(ptr); }});
|
||||
@ -390,10 +399,6 @@ protected:
|
||||
++failureCount;
|
||||
qWarning() << "Wrong metatype returned for" << name;
|
||||
}
|
||||
if (QMetaType::typeName(tp) != name) {
|
||||
++failureCount;
|
||||
qWarning() << "Wrong typeName returned for" << tp;
|
||||
}
|
||||
void *buf1 = QMetaType::create(tp, 0);
|
||||
void *buf2 = QMetaType::create(tp, buf1);
|
||||
void *buf3 = info.create(tp, 0);
|
||||
@ -1006,6 +1011,10 @@ void tst_QMetaType::flagsBinaryCompatibility5_0_data()
|
||||
for (int i = 0; i < buffer.size(); i+=2) {
|
||||
const quint32 id = buffer.at(i);
|
||||
const quint32 flags = buffer.at(i + 1);
|
||||
if (id > QMetaType::LastCoreType)
|
||||
continue; // We do not link against QtGui, so we do longer consider such type as registered
|
||||
if (id == QMetaType::Void)
|
||||
continue; // The meaning of QMetaType::Void has changed in Qt6
|
||||
QVERIFY2(QMetaType::isRegistered(id), "A type could not be removed in BC way");
|
||||
QTest::newRow(QMetaType::typeName(id)) << id << flags;
|
||||
}
|
||||
@ -1158,11 +1167,19 @@ void tst_QMetaType::typedConstruct()
|
||||
auto dynamicGadgetProperties = std::make_shared<GenericPODType>();
|
||||
dynamicGadgetProperties->podData = myPodTesData;
|
||||
const auto flags = QMetaType::NeedsConstruction | QMetaType::NeedsDestruction;
|
||||
int podTypeId = QMetaType::registerType(podTypeName,
|
||||
&GadgetTypedDestructor,
|
||||
&GadgetTypedConstructor,
|
||||
sizeof(GenericGadgetType),
|
||||
flags, nullptr);
|
||||
using TypeInfo = QtPrivate::QMetaTypeInterface;
|
||||
auto typeInfo = new TypeInfo {
|
||||
0, sizeof(GenericGadgetType), alignof(GenericGadgetType), uint(flags), nullptr, podTypeName,
|
||||
0, QtPrivate::RefCount{0},
|
||||
[](TypeInfo *self) { delete self; },
|
||||
[](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 };
|
||||
QMetaType metatype(typeInfo);
|
||||
dynamicGadgetProperties->m_metatype = metatype;
|
||||
int podTypeId = metatype.id();
|
||||
QVERIFY(podTypeId > 0);
|
||||
QMetaType::registerStreamOperators(podTypeId, &GadgetSaveOperator, &GadgetLoadOperator);
|
||||
s_managedTypes[podTypeId] = qMakePair(dynamicGadgetProperties, std::shared_ptr<QMetaObject>{});
|
||||
@ -1309,54 +1326,6 @@ void tst_QMetaType::registerType()
|
||||
QCOMPARE(qRegisterMetaType<MyFoo>("MyFoo"), fooId);
|
||||
|
||||
QCOMPARE(QMetaType::type("MyFoo"), fooId);
|
||||
|
||||
// cannot unregister built-in types
|
||||
QVERIFY(!QMetaType::unregisterType(QMetaType::QString));
|
||||
QCOMPARE(QMetaType::type("QString"), int(QMetaType::QString));
|
||||
QCOMPARE(QMetaType::type("MyString"), int(QMetaType::QString));
|
||||
|
||||
// cannot unregister declared types
|
||||
QVERIFY(!QMetaType::unregisterType(fooId));
|
||||
QCOMPARE(QMetaType::type("TestSpace::Foo"), fooId);
|
||||
QCOMPARE(QMetaType::type("MyFoo"), fooId);
|
||||
|
||||
// test unregistration of dynamic types (used by Qml)
|
||||
int unregId = QMetaType::registerType("UnregisterMe",
|
||||
0,
|
||||
0,
|
||||
QtMetaTypePrivate::QMetaTypeFunctionHelper<void>::Destruct,
|
||||
QtMetaTypePrivate::QMetaTypeFunctionHelper<void>::Construct,
|
||||
0, QMetaType::TypeFlags(), 0);
|
||||
QCOMPARE(QMetaType::registerTypedef("UnregisterMeTypedef", unregId), unregId);
|
||||
int unregId2 = QMetaType::registerType("UnregisterMe2",
|
||||
0,
|
||||
0,
|
||||
QtMetaTypePrivate::QMetaTypeFunctionHelper<void>::Destruct,
|
||||
QtMetaTypePrivate::QMetaTypeFunctionHelper<void>::Construct,
|
||||
0, QMetaType::TypeFlags(), 0);
|
||||
QVERIFY(unregId >= int(QMetaType::User));
|
||||
QCOMPARE(unregId2, unregId + 2);
|
||||
|
||||
QVERIFY(QMetaType::unregisterType(unregId));
|
||||
QCOMPARE(QMetaType::type("UnregisterMe"), 0);
|
||||
QCOMPARE(QMetaType::type("UnregisterMeTypedef"), 0);
|
||||
QCOMPARE(QMetaType::type("UnregisterMe2"), unregId2);
|
||||
QVERIFY(QMetaType::unregisterType(unregId2));
|
||||
QCOMPARE(QMetaType::type("UnregisterMe2"), 0);
|
||||
|
||||
// re-registering should always return the lowest free index
|
||||
QCOMPARE(QMetaType::registerType("UnregisterMe2",
|
||||
0,
|
||||
0,
|
||||
QtMetaTypePrivate::QMetaTypeFunctionHelper<void>::Destruct,
|
||||
QtMetaTypePrivate::QMetaTypeFunctionHelper<void>::Construct,
|
||||
0, QMetaType::TypeFlags(), 0), unregId);
|
||||
QCOMPARE(QMetaType::registerType("UnregisterMe",
|
||||
0,
|
||||
0,
|
||||
QtMetaTypePrivate::QMetaTypeFunctionHelper<void>::Destruct,
|
||||
QtMetaTypePrivate::QMetaTypeFunctionHelper<void>::Construct,
|
||||
0, QMetaType::TypeFlags(), 0), unregId + 1);
|
||||
}
|
||||
|
||||
class IsRegisteredDummyType { };
|
||||
@ -1367,7 +1336,7 @@ void tst_QMetaType::isRegistered_data()
|
||||
QTest::addColumn<bool>("registered");
|
||||
|
||||
// predefined/custom types
|
||||
QTest::newRow("QMetaType::Void") << int(QMetaType::Void) << true;
|
||||
QTest::newRow("QMetaType::Void") << int(QMetaType::Void) << false;
|
||||
QTest::newRow("QMetaType::Int") << int(QMetaType::Int) << true;
|
||||
|
||||
int dummyTypeId = qRegisterMetaType<IsRegisteredDummyType>("IsRegisteredDummyType");
|
||||
@ -1733,8 +1702,8 @@ void tst_QMetaType::automaticTemplateRegistration()
|
||||
CONTAINER< __VA_ARGS__ > t; \
|
||||
const QVariant v = QVariant::fromValue(t); \
|
||||
QByteArray tn = createTypeName(#CONTAINER "<", #__VA_ARGS__); \
|
||||
const int type = QMetaType::type(tn); \
|
||||
const int expectedType = ::qMetaTypeId<CONTAINER< __VA_ARGS__ > >(); \
|
||||
const int type = QMetaType::type(tn); \
|
||||
QCOMPARE(type, expectedType); \
|
||||
QCOMPARE((QMetaType::fromType<CONTAINER< __VA_ARGS__ >>().id()), expectedType); \
|
||||
}
|
||||
@ -2545,7 +2514,8 @@ void tst_QMetaType::fromType()
|
||||
QCOMPARE(QMetaType::fromType<RealType>(), QMetaType(MetaTypeId)); \
|
||||
QVERIFY(QMetaType::fromType<RealType>() == QMetaType(MetaTypeId)); \
|
||||
QVERIFY(!(QMetaType::fromType<RealType>() != QMetaType(MetaTypeId))); \
|
||||
QCOMPARE(QMetaType::fromType<RealType>().id(), MetaTypeId);
|
||||
if (MetaTypeId != QMetaType::Void) \
|
||||
QCOMPARE(QMetaType::fromType<RealType>().id(), MetaTypeId);
|
||||
|
||||
FOR_EACH_CORE_METATYPE(FROMTYPE_CHECK)
|
||||
|
||||
|
@ -394,7 +394,6 @@ void tst_QDBusMetaObject::types()
|
||||
QCOMPARE(constructed.name(), expected.name());
|
||||
QCOMPARE(constructed.parameterCount(), expected.parameterCount());
|
||||
QCOMPARE(constructed.parameterNames(), expected.parameterNames());
|
||||
QCOMPARE(constructed.parameterTypes(), expected.parameterTypes());
|
||||
for (int j = 0; j < constructed.parameterCount(); ++j)
|
||||
QCOMPARE(constructed.parameterType(j), expected.parameterType(j));
|
||||
QCOMPARE(constructed.tag(), expected.tag());
|
||||
|
Loading…
x
Reference in New Issue
Block a user