summaryrefslogtreecommitdiffstats
path: root/src/corelib/kernel/qmetatype_p.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/corelib/kernel/qmetatype_p.h')
-rw-r--r--src/corelib/kernel/qmetatype_p.h94
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