diff options
Diffstat (limited to 'src/corelib/kernel/qmetatype.h')
-rw-r--r-- | src/corelib/kernel/qmetatype.h | 117 |
1 files changed, 78 insertions, 39 deletions
diff --git a/src/corelib/kernel/qmetatype.h b/src/corelib/kernel/qmetatype.h index ec9a256c4d..1e944660c6 100644 --- a/src/corelib/kernel/qmetatype.h +++ b/src/corelib/kernel/qmetatype.h @@ -18,6 +18,7 @@ #include <QtCore/qobjectdefs.h> #endif #include <QtCore/qscopeguard.h> +#include <QtCore/qttypetraits.h> #include <array> #include <new> @@ -26,7 +27,7 @@ #include <map> #include <functional> #include <optional> -#include <type_traits> +#include <QtCore/q20type_traits.h> #ifdef Bool #error qmetatype.h must be included before any header file that defines Bool @@ -92,6 +93,12 @@ inline constexpr int qMetaTypeId(); #else # define QT_FOR_EACH_STATIC_REGULAR_EXPRESSION(F) #endif +#ifndef QT_NO_VARIANT +# define QT_FOR_EACH_STATIC_QVARIANT(F) \ + F(QVariant, 41, QVariant) +#else +# define QT_FOR_EACH_STATIC_QVARIANT(F) +#endif #define QT_FOR_EACH_STATIC_CORE_CLASS(F)\ F(QChar, 7, QChar) \ @@ -113,7 +120,7 @@ inline constexpr int qMetaTypeId(); F(QPointF, 26, QPointF) \ QT_FOR_EACH_STATIC_EASINGCURVE(F) \ F(QUuid, 30, QUuid) \ - F(QVariant, 41, QVariant) \ + QT_FOR_EACH_STATIC_QVARIANT(F) \ QT_FOR_EACH_STATIC_REGULAR_EXPRESSION(F) \ F(QJsonValue, 45, QJsonValue) \ F(QJsonObject, 46, QJsonObject) \ @@ -128,13 +135,20 @@ inline constexpr int qMetaTypeId(); #define QT_FOR_EACH_STATIC_CORE_POINTER(F)\ F(QObjectStar, 39, QObject*) -#define QT_FOR_EACH_STATIC_CORE_TEMPLATE(F)\ +#ifndef QT_NO_VARIANT +# define QT_FOR_EACH_STATIC_CORE_TEMPLATE(F)\ F(QVariantMap, 8, QVariantMap) \ F(QVariantList, 9, QVariantList) \ F(QVariantHash, 28, QVariantHash) \ F(QVariantPair, 58, QVariantPair) \ F(QByteArrayList, 49, QByteArrayList) \ F(QStringList, 11, QStringList) \ + /**/ +#else +# define QT_FOR_EACH_STATIC_CORE_TEMPLATE(F)\ + F(QByteArrayList, 49, QByteArrayList) \ + F(QStringList, 11, QStringList) +#endif #if QT_CONFIG(shortcut) #define QT_FOR_EACH_STATIC_KEYSEQUENCE_CLASS(F)\ @@ -188,12 +202,20 @@ inline constexpr int qMetaTypeId(); F(UInt, -1, uint, "quint32") \ F(LongLong, -1, qlonglong, "qint64") \ F(ULongLong, -1, qulonglong, "quint64") \ + F(QByteArrayList, -1, QByteArrayList, "QList<QByteArray>") \ + F(QStringList, -1, QStringList, "QList<QString>") \ + QT_FOR_EACH_STATIC_VARIANT_ALIAS_TYPE(F) + +#ifndef QT_NO_VARIANT +#define QT_FOR_EACH_STATIC_VARIANT_ALIAS_TYPE(F) \ F(QVariantList, -1, QVariantList, "QList<QVariant>") \ F(QVariantMap, -1, QVariantMap, "QMap<QString,QVariant>") \ F(QVariantHash, -1, QVariantHash, "QHash<QString,QVariant>") \ F(QVariantPair, -1, QVariantPair, "QPair<QVariant,QVariant>") \ - F(QByteArrayList, -1, QByteArrayList, "QList<QByteArray>") \ - F(QStringList, -1, QStringList, "QList<QString>") \ + /**/ +#else +#define QT_FOR_EACH_STATIC_VARIANT_ALIAS_TYPE(F) +#endif #define QT_FOR_EACH_STATIC_TYPE(F)\ QT_FOR_EACH_STATIC_PRIMITIVE_TYPE(F)\ @@ -246,7 +268,14 @@ using NonConstMetaTypeInterface = const QMetaTypeInterface; class QMetaTypeInterface { public: - ushort revision; // 0 in Qt 6.0. Can increase if new field are added + + /* Revision: Can increase if new field are added, or if semantics changes + 0: Initial Revision + 1: the meaning of the NeedsDestruction flag changed + */ + static inline constexpr ushort CurrentRevision = 1; + + ushort revision; ushort alignment; uint size; uint flags; @@ -485,23 +514,25 @@ public: #endif #endif + QMetaType underlyingType() const; + template<typename T> constexpr static QMetaType fromType(); static QMetaType fromName(QByteArrayView name); - - friend bool operator==(QMetaType a, QMetaType b) +private: + friend bool comparesEqual(const QMetaType &lhs, + const QMetaType &rhs) noexcept { - if (a.d_ptr == b.d_ptr) + if (lhs.d_ptr == rhs.d_ptr) return true; - if (!a.d_ptr || !b.d_ptr) + if (!lhs.d_ptr || !rhs.d_ptr) return false; // one type is undefined, the other is defined // avoid id call if we already have the id - const int aId = a.id(); - const int bId = b.id(); + const int aId = lhs.id(); + const int bId = rhs.id(); return aId == bId; } - friend bool operator!=(QMetaType a, QMetaType b) { return !(a == b); } - + Q_DECLARE_EQUALITY_COMPARABLE(QMetaType) #ifndef QT_NO_DEBUG_STREAM private: friend Q_CORE_EXPORT QDebug operator<<(QDebug d, QMetaType m); @@ -606,8 +637,7 @@ public: const From *f = static_cast<const From *>(from); To *t = static_cast<To *>(to); auto &&r = function(*f); - if constexpr (std::is_same_v<std::remove_cv_t<std::remove_reference_t<decltype(r)>>, - std::optional<To>>) { + if constexpr (std::is_same_v<q20::remove_cvref_t<decltype(r)>, std::optional<To>>) { if (!r) return false; *t = *std::forward<decltype(r)>(r); @@ -1721,11 +1751,19 @@ QT_FOR_EACH_STATIC_TYPE(Q_DECLARE_BUILTIN_METATYPE) QT_BEGIN_NAMESPACE +namespace QtPrivate { +// out-of-line helpers to reduce template code bloat ("SCARY") and improve compile times: +Q_CORE_EXPORT bool hasRegisteredConverterFunctionToPairVariantInterface(QMetaType m); +Q_CORE_EXPORT bool hasRegisteredConverterFunctionToIterableMetaSequence(QMetaType m); +Q_CORE_EXPORT bool hasRegisteredMutableViewFunctionToIterableMetaSequence(QMetaType m); +Q_CORE_EXPORT bool hasRegisteredConverterFunctionToIterableMetaAssociation(QMetaType m); +Q_CORE_EXPORT bool hasRegisteredMutableViewFunctionToIterableMetaAssociation(QMetaType m); +} + template <typename T> inline bool QtPrivate::IsMetaTypePair<T, true>::registerConverter() { - const QMetaType to = QMetaType::fromType<QtMetaTypePrivate::QPairVariantInterfaceImpl>(); - if (!QMetaType::hasRegisteredConverterFunction(QMetaType::fromType<T>(), to)) { + if (!QtPrivate::hasRegisteredConverterFunctionToPairVariantInterface(QMetaType::fromType<T>())) { QtMetaTypePrivate::QPairVariantInterfaceConvertFunctor<T> o; return QMetaType::registerConverter<T, QtMetaTypePrivate::QPairVariantInterfaceImpl>(o); } @@ -1757,8 +1795,7 @@ struct SequentialValueTypeIsMetaType<T, true> { static bool registerConverter() { - const QMetaType to = QMetaType::fromType<QIterable<QMetaSequence>>(); - if (!QMetaType::hasRegisteredConverterFunction(QMetaType::fromType<T>(), to)) { + if (!QtPrivate::hasRegisteredConverterFunctionToIterableMetaSequence(QMetaType::fromType<T>())) { QSequentialIterableConvertFunctor<T> o; return QMetaType::registerConverter<T, QIterable<QMetaSequence>>(o); } @@ -1767,8 +1804,7 @@ struct SequentialValueTypeIsMetaType<T, true> static bool registerMutableView() { - const QMetaType to = QMetaType::fromType<QIterable<QMetaSequence>>(); - if (!QMetaType::hasRegisteredMutableViewFunction(QMetaType::fromType<T>(), to)) { + if (!QtPrivate::hasRegisteredMutableViewFunctionToIterableMetaSequence(QMetaType::fromType<T>())) { QSequentialIterableMutableViewFunctor<T> o; return QMetaType::registerMutableView<T, QIterable<QMetaSequence>>(o); } @@ -1801,8 +1837,7 @@ struct AssociativeKeyTypeIsMetaType<T, true> : AssociativeMappedTypeIsMetaType<T { static bool registerConverter() { - const QMetaType to = QMetaType::fromType<QIterable<QMetaAssociation>>(); - if (!QMetaType::hasRegisteredConverterFunction(QMetaType::fromType<T>(), to)) { + if (!QtPrivate::hasRegisteredConverterFunctionToIterableMetaAssociation(QMetaType::fromType<T>())) { QAssociativeIterableConvertFunctor<T> o; return QMetaType::registerConverter<T, QIterable<QMetaAssociation>>(o); } @@ -1811,8 +1846,7 @@ struct AssociativeKeyTypeIsMetaType<T, true> : AssociativeMappedTypeIsMetaType<T static bool registerMutableView() { - const QMetaType to = QMetaType::fromType<QIterable<QMetaAssociation>>(); - if (!QMetaType::hasRegisteredMutableViewFunction(QMetaType::fromType<T>(), to)) { + if (!QtPrivate::hasRegisteredMutableViewFunctionToIterableMetaAssociation(QMetaType::fromType<T>())) { QAssociativeIterableMutableViewFunctor<T> o; return QMetaType::registerMutableView<T, QIterable<QMetaAssociation>>(o); } @@ -2227,6 +2261,7 @@ struct is_std_pair<std::pair<T1_, T2_>> : std::true_type { using T2 = T2_; }; +namespace TypeNameHelper { template<typename T> constexpr auto typenameHelper() { @@ -2268,15 +2303,15 @@ constexpr auto typenameHelper() QT_STRINGIFY(QT_NAMESPACE) "::" #endif #if defined(Q_CC_MSVC) && defined(Q_CC_CLANG) - "auto __cdecl QtPrivate::typenameHelper(void) [T = " + "auto __cdecl QtPrivate::TypeNameHelper::typenameHelper(void) [T = " #elif defined(Q_CC_MSVC) - "auto __cdecl QtPrivate::typenameHelper<" + "auto __cdecl QtPrivate::TypeNameHelper::typenameHelper<" #elif defined(Q_CC_CLANG) - "auto QtPrivate::typenameHelper() [T = " + "auto QtPrivate::TypeNameHelper::typenameHelper() [T = " #elif defined(Q_CC_GHS) - "auto QtPrivate::typenameHelper<T>()[with T=" + "auto QtPrivate::TypeNameHelper::typenameHelper<T>()[with T=" #else - "constexpr auto QtPrivate::typenameHelper() [with T = " + "constexpr auto QtPrivate::TypeNameHelper::typenameHelper() [with T = " #endif ) - 1; #if defined(Q_CC_MSVC) && !defined(Q_CC_CLANG) @@ -2302,6 +2337,8 @@ constexpr auto typenameHelper() return result; } } +} // namespace TypeNameHelper +using TypeNameHelper::typenameHelper; template<typename T, typename = void> struct BuiltinMetaType : std::integral_constant<int, 0> @@ -2358,18 +2395,20 @@ struct QDebugStreamOperatorForType <T, false> template<typename T, bool = QTypeTraits::has_stream_operator_v<QDataStream, T>> struct QDataStreamOperatorForType { - static void dataStreamOut(const QMetaTypeInterface *, QDataStream &ds, const void *a) - { ds << *reinterpret_cast<const T *>(a); } - static void dataStreamIn(const QMetaTypeInterface *, QDataStream &ds, void *a) - { ds >> *reinterpret_cast<T *>(a); } + static constexpr QMetaTypeInterface::DataStreamOutFn dataStreamOut = nullptr; + static constexpr QMetaTypeInterface::DataStreamInFn dataStreamIn = nullptr; }; +#ifndef QT_NO_DATASTREAM template<typename T> -struct QDataStreamOperatorForType <T, false> +struct QDataStreamOperatorForType <T, true> { - static constexpr QMetaTypeInterface::DataStreamOutFn dataStreamOut = nullptr; - static constexpr QMetaTypeInterface::DataStreamInFn dataStreamIn = nullptr; + static void dataStreamOut(const QMetaTypeInterface *, QDataStream &ds, const void *a) + { ds << *reinterpret_cast<const T *>(a); } + static void dataStreamIn(const QMetaTypeInterface *, QDataStream &ds, void *a) + { ds >> *reinterpret_cast<T *>(a); } }; +#endif // Performance optimization: // @@ -2462,7 +2501,7 @@ struct QMetaTypeInterfaceWrapper using InterfaceType = std::conditional_t<IsConstMetaTypeInterface, const QMetaTypeInterface, NonConstMetaTypeInterface>; static inline InterfaceType metaType = { - /*.revision=*/ 0, + /*.revision=*/ QMetaTypeInterface::CurrentRevision, /*.alignment=*/ alignof(T), /*.size=*/ sizeof(T), /*.flags=*/ QMetaTypeForType<T>::Flags, |