diff options
author | Thiago Macieira <thiago.macieira@intel.com> | 2022-07-19 12:53:38 -0700 |
---|---|---|
committer | Thiago Macieira <thiago.macieira@intel.com> | 2022-07-26 20:12:45 -0700 |
commit | 764d82ceb541f5b0ca812fa451707311b6e6ccc0 (patch) | |
tree | 3c6e8e8e92ecf467f5dec973d37d9e77439394c0 | |
parent | 74fac865cf7c55d3afba1043072ba6cc932d161d (diff) |
QMetaType: add is{Default,Copy,Move}Constructible and isDestructible
Unit tests will come after I've fixed the flags themselves. At this point,
they are wrong.
[ChangeLog][QtCore][QMetaType] Added isDefaultConstructible(),
isCopyConstructible(), isMoveConstructible() and isDestructible().
Change-Id: I3859764fed084846bcb0fffd170353109378e34c
Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
-rw-r--r-- | src/corelib/kernel/qmetatype.cpp | 72 | ||||
-rw-r--r-- | src/corelib/kernel/qmetatype.h | 9 | ||||
-rw-r--r-- | src/corelib/kernel/qmetatype_p.h | 43 |
3 files changed, 121 insertions, 3 deletions
diff --git a/src/corelib/kernel/qmetatype.cpp b/src/corelib/kernel/qmetatype.cpp index ea7cd4a0c9..f2676fa48f 100644 --- a/src/corelib/kernel/qmetatype.cpp +++ b/src/corelib/kernel/qmetatype.cpp @@ -65,6 +65,8 @@ QT_BEGIN_NAMESPACE QT_IMPL_METATYPE_EXTERN_TAGGED(QtMetaTypePrivate::QPairVariantInterfaceImpl, QPairVariantInterfaceImpl) +using QtMetaTypePrivate::isVoid; + namespace { struct QMetaTypeCustomRegistry @@ -554,9 +556,13 @@ int QMetaType::registerHelper(const QtPrivate::QMetaTypeInterface *iface) \fn constexpr TypeFlags QMetaType::flags() const \since 5.0 - Returns flags of the type for which this QMetaType instance was constructed. + Returns flags of the type for which this QMetaType instance was + constructed. To inspect specific type traits, prefer using one of the "is-" + functions rather than the flags directly. - \sa QMetaType::TypeFlags, QMetaType::flags() + \sa QMetaType::TypeFlags, QMetaType::flags(), isDefaultConstructible(), + isCopyConstructible(), isMoveConstructible(), isDestructible(), + isEqualityComparable(), isOrdered() */ /*! @@ -778,6 +784,68 @@ bool QMetaType::equals(const void *lhs, const void *rhs) const } /*! + \fn bool QMetaType::isDefaultConstructible() const noexcept + \since 6.5 + + Returns true if this type can be default-constructed. If it can be, then + construct() and create() can be used with a \c{copy} parameter that is + null. + + \sa flags(), isCopyConstructible(), isMoveConstructible(), isDestructible() + */ + +/*! + \fn bool QMetaType::isCopyConstructible() const noexcept + \since 6.5 + + Returns true if this type can be copy-constructed. If it can be, then + construct() and create() can be used with a \c{copy} parameter that is + not null. + + \sa flags(), isDefaultConstructible(), isMoveConstructible(), isDestructible() + */ + +/*! + \fn bool QMetaType::isMoveConstructible() const noexcept + \since 6.5 + + Returns true if this type can be move-constructed. QMetaType currently does + not have an API to make use of this trait. + + \sa flags(), isDefaultConstructible(), isCopyConstructible(), isDestructible() + */ + +/*! + \fn bool QMetaType::isDestructible() const noexcept + \since 6.5 + + Returns true if this type can be destroyed. If it can be, then destroy() + and destruct() can be called. + + \sa flags(), isDefaultConstructible(), isCopyConstructible(), isMoveConstructible() + */ + +bool QMetaType::isDefaultConstructible(const QtPrivate::QMetaTypeInterface *iface) noexcept +{ + return !isVoid(iface) && QtMetaTypePrivate::isDefaultConstructible(iface); +} + +bool QMetaType::isCopyConstructible(const QtPrivate::QMetaTypeInterface *iface) noexcept +{ + return !isVoid(iface) && QtMetaTypePrivate::isCopyConstructible(iface); +} + +bool QMetaType::isMoveConstructible(const QtPrivate::QMetaTypeInterface *iface) noexcept +{ + return !isVoid(iface) && QtMetaTypePrivate::isMoveConstructible(iface); +} + +bool QMetaType::isDestructible(const QtPrivate::QMetaTypeInterface *iface) noexcept +{ + return !isVoid(iface) && QtMetaTypePrivate::isDestructible(iface); +} + +/*! Returns \c true if a less than or equality operator for the type described by this metatype was visible to the metatype declaration, otherwise \c false. diff --git a/src/corelib/kernel/qmetatype.h b/src/corelib/kernel/qmetatype.h index e9599af5bb..28d246d2cf 100644 --- a/src/corelib/kernel/qmetatype.h +++ b/src/corelib/kernel/qmetatype.h @@ -455,6 +455,10 @@ public: QPartialOrdering compare(const void *lhs, const void *rhs) const; bool equals(const void *lhs, const void *rhs) const; + bool isDefaultConstructible() const noexcept { return d_ptr && isDefaultConstructible(d_ptr); } + bool isCopyConstructible() const noexcept { return d_ptr && isCopyConstructible(d_ptr); } + bool isMoveConstructible() const noexcept { return d_ptr && isMoveConstructible(d_ptr); } + bool isDestructible() const noexcept { return d_ptr && isDestructible(d_ptr); } bool isEqualityComparable() const; bool isOrdered() const; @@ -722,6 +726,11 @@ public: const QtPrivate::QMetaTypeInterface *iface() const { return d_ptr; } private: + static bool isDefaultConstructible(const QtPrivate::QMetaTypeInterface *) noexcept Q_DECL_PURE_FUNCTION; + static bool isCopyConstructible(const QtPrivate::QMetaTypeInterface *) noexcept Q_DECL_PURE_FUNCTION; + static bool isMoveConstructible(const QtPrivate::QMetaTypeInterface *) noexcept Q_DECL_PURE_FUNCTION; + static bool isDestructible(const QtPrivate::QMetaTypeInterface *) noexcept Q_DECL_PURE_FUNCTION; + #if QT_CORE_REMOVED_SINCE(6, 5) int idHelper() const; #endif diff --git a/src/corelib/kernel/qmetatype_p.h b/src/corelib/kernel/qmetatype_p.h index 8af74ba6ad..89f1854bf6 100644 --- a/src/corelib/kernel/qmetatype_p.h +++ b/src/corelib/kernel/qmetatype_p.h @@ -116,6 +116,48 @@ template<> struct TypeDefinition<QQuaternion> { static const bool IsAvailable = template<> struct TypeDefinition<QIcon> { static const bool IsAvailable = false; }; #endif +inline bool isVoid(const QtPrivate::QMetaTypeInterface *iface) +{ + // void is special because it can't be constructed, copied or destroyed, + // but iface->flags doesn't set Needs{Construction,Destruction}. + return iface->typeId.loadRelaxed() == QMetaType::Void; +} + +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(!isVoid(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 +{ + // ### broken + return checkMetaTypeFlagOrPointer(iface, iface->copyCtr, QMetaType::NeedsConstruction); +} + +inline bool isMoveConstructible(const QtPrivate::QMetaTypeInterface *iface) noexcept +{ + return iface->moveCtr; +} + +inline bool isDestructible(const QtPrivate::QMetaTypeInterface *iface) noexcept +{ + // ### broken + return checkMetaTypeFlagOrPointer(iface, iface->dtor, QMetaType::NeedsDestruction); +} + +const char *typedefNameForType(const QtPrivate::QMetaTypeInterface *type_d); + template<typename T> static const QT_PREPEND_NAMESPACE(QtPrivate::QMetaTypeInterface) *getInterfaceFromType() { @@ -129,7 +171,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 |