diff options
Diffstat (limited to 'src/corelib/kernel/qmetatype_p.h')
-rw-r--r-- | src/corelib/kernel/qmetatype_p.h | 94 |
1 files changed, 91 insertions, 3 deletions
diff --git a/src/corelib/kernel/qmetatype_p.h b/src/corelib/kernel/qmetatype_p.h index 8af74ba6ad..7e0457771f 100644 --- a/src/corelib/kernel/qmetatype_p.h +++ b/src/corelib/kernel/qmetatype_p.h @@ -38,20 +38,21 @@ QT_BEGIN_NAMESPACE assign_and_return \ } -class QMetaTypeModuleHelper +class Q_CORE_EXPORT QMetaTypeModuleHelper { Q_DISABLE_COPY_MOVE(QMetaTypeModuleHelper) protected: QMetaTypeModuleHelper() = default; ~QMetaTypeModuleHelper() = default; public: + Q_WEAK_OVERLOAD // prevent it from entering the ABI and rendering constexpr useless static constexpr auto makePair(int from, int to) -> quint64 { return (quint64(from) << 32) + quint64(to); } virtual const QtPrivate::QMetaTypeInterface *interfaceForType(int) const = 0; - virtual bool convert(const void *, int, void *, int) const { return false; } + virtual bool convert(const void *, int, void *, int) const; }; extern Q_CORE_EXPORT const QMetaTypeModuleHelper *qMetaTypeGuiHelper; @@ -116,6 +117,94 @@ template<> struct TypeDefinition<QQuaternion> { static const bool IsAvailable = template<> struct TypeDefinition<QIcon> { static const bool IsAvailable = false; }; #endif +template <typename T> inline bool isInterfaceFor(const QtPrivate::QMetaTypeInterface *iface) +{ + // typeId for built-in types are fixed and require no registration + static_assert(QMetaTypeId2<T>::IsBuiltIn, "This function only works for built-in types"); + static constexpr int typeId = QtPrivate::BuiltinMetaType<T>::value; + return iface->typeId.loadRelaxed() == typeId; +} + +template <typename FPointer> +inline bool checkMetaTypeFlagOrPointer(const QtPrivate::QMetaTypeInterface *iface, FPointer ptr, QMetaType::TypeFlag Flag) +{ + // helper to the isXxxConstructible & isDestructible functions below: a + // meta type has the trait if the trait is trivial or we have the pointer + // to perform the operation + Q_ASSERT(!isInterfaceFor<void>(iface)); + Q_ASSERT(iface->size); + return ptr != nullptr || (iface->flags & Flag) == 0; +} + +inline bool isDefaultConstructible(const QtPrivate::QMetaTypeInterface *iface) noexcept +{ + return checkMetaTypeFlagOrPointer(iface, iface->defaultCtr, QMetaType::NeedsConstruction); +} + +inline bool isCopyConstructible(const QtPrivate::QMetaTypeInterface *iface) noexcept +{ + return checkMetaTypeFlagOrPointer(iface, iface->copyCtr, QMetaType::NeedsCopyConstruction); +} + +inline bool isMoveConstructible(const QtPrivate::QMetaTypeInterface *iface) noexcept +{ + return checkMetaTypeFlagOrPointer(iface, iface->moveCtr, QMetaType::NeedsMoveConstruction); +} + +inline bool isDestructible(const QtPrivate::QMetaTypeInterface *iface) noexcept +{ + /* For metatypes of revision 1, the NeedsDestruction was set even for trivially + destructible types, but their dtor pointer would be null. + For that reason, we need the additional check here. + */ + return iface->revision < 1 || + checkMetaTypeFlagOrPointer(iface, iface->dtor, QMetaType::NeedsDestruction); +} + +inline void defaultConstruct(const QtPrivate::QMetaTypeInterface *iface, void *where) +{ + Q_ASSERT(isDefaultConstructible(iface)); + if (iface->defaultCtr) + iface->defaultCtr(iface, where); + else + memset(where, 0, iface->size); +} + +inline void copyConstruct(const QtPrivate::QMetaTypeInterface *iface, void *where, const void *copy) +{ + Q_ASSERT(isCopyConstructible(iface)); + if (iface->copyCtr) + iface->copyCtr(iface, where, copy); + else + memcpy(where, copy, iface->size); +} + +inline void moveConstruct(const QtPrivate::QMetaTypeInterface *iface, void *where, void *copy) +{ + Q_ASSERT(isMoveConstructible(iface)); + if (iface->moveCtr) + iface->moveCtr(iface, where, copy); + else + memcpy(where, copy, iface->size); +} + +inline void construct(const QtPrivate::QMetaTypeInterface *iface, void *where, const void *copy) +{ + if (copy) + copyConstruct(iface, where, copy); + else + defaultConstruct(iface, where); +} + +inline void destruct(const QtPrivate::QMetaTypeInterface *iface, void *where) +{ + Q_ASSERT(isDestructible(iface)); + if (iface->dtor) + iface->dtor(iface, where); +} + +const char *typedefNameForType(const QtPrivate::QMetaTypeInterface *type_d); + template<typename T> static const QT_PREPEND_NAMESPACE(QtPrivate::QMetaTypeInterface) *getInterfaceFromType() { @@ -129,7 +218,6 @@ static const QT_PREPEND_NAMESPACE(QtPrivate::QMetaTypeInterface) *getInterfaceFr case QMetaType::MetaTypeName: \ return QtMetaTypePrivate::getInterfaceFromType<RealName>(); -const char *typedefNameForType(const QtPrivate::QMetaTypeInterface *type_d); } //namespace QtMetaTypePrivate QT_END_NAMESPACE |