diff options
Diffstat (limited to 'src/corelib/kernel/qmetatype.h')
-rw-r--r-- | src/corelib/kernel/qmetatype.h | 123 |
1 files changed, 91 insertions, 32 deletions
diff --git a/src/corelib/kernel/qmetatype.h b/src/corelib/kernel/qmetatype.h index b119c20d2b..e3ef1474da 100644 --- a/src/corelib/kernel/qmetatype.h +++ b/src/corelib/kernel/qmetatype.h @@ -10,13 +10,14 @@ #include <QtCore/qatomic.h> #include <QtCore/qbytearray.h> #include <QtCore/qcompare.h> -#include <QtCore/qscopeguard.h> #include <QtCore/qdatastream.h> +#include <QtCore/qfloat16.h> +#include <QtCore/qhashfunctions.h> #include <QtCore/qiterable.h> #ifndef QT_NO_QOBJECT #include <QtCore/qobjectdefs.h> #endif -#include <QtCore/qhashfunctions.h> +#include <QtCore/qscopeguard.h> #include <array> #include <new> @@ -24,6 +25,8 @@ #include <list> #include <map> #include <functional> +#include <optional> +#include <QtCore/q20type_traits.h> #ifdef Bool #error qmetatype.h must be included before any header file that defines Bool @@ -89,6 +92,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) \ @@ -110,7 +119,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) \ @@ -119,18 +128,26 @@ inline constexpr int qMetaTypeId(); F(QCborValue, 53, QCborValue) \ F(QCborArray, 54, QCborArray) \ F(QCborMap, 55, QCborMap) \ + F(Float16, 63, qfloat16) \ QT_FOR_EACH_STATIC_ITEMMODEL_CLASS(F) #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)\ @@ -184,12 +201,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)\ @@ -242,7 +267,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; @@ -308,14 +340,14 @@ To convertImplicit(const From& from) class Q_CORE_EXPORT QMetaType { public: -#ifndef Q_CLANG_QDOC +#ifndef Q_QDOC // The code that actually gets compiled. enum Type { // these are merged with QVariant QT_FOR_EACH_STATIC_TYPE(QT_DEFINE_METATYPE_ID) FirstCoreType = Bool, - LastCoreType = QVariantPair, + LastCoreType = Float16, FirstGuiType = QFont, LastGuiType = QColorSpace, FirstWidgetsType = QSizePolicy, @@ -344,9 +376,10 @@ public: QByteArrayList = 49, QObjectStar = 39, SChar = 40, Void = 43, Nullptr = 51, - QVariantMap = 8, QVariantList = 9, QVariantHash = 28, + QVariantMap = 8, QVariantList = 9, QVariantHash = 28, QVariantPair = 58, QCborSimpleType = 52, QCborValue = 53, QCborArray = 54, QCborMap = 55, Char16 = 56, Char32 = 57, + Int128 = 59, UInt128 = 60, Float128 = 61, BFloat16 = 62, Float16 = 63, // Gui types QFont = 0x1000, QPixmap = 0x1001, QBrush = 0x1002, QColor = 0x1003, QPalette = 0x1004, @@ -357,8 +390,8 @@ public: // Widget types QSizePolicy = 0x2000, - LastCoreType = Char32, - LastGuiType = QColorSpace, + + // Start-point for client-code types: User = 65536 }; #endif @@ -480,6 +513,8 @@ public: #endif #endif + QMetaType underlyingType() const; + template<typename T> constexpr static QMetaType fromType(); static QMetaType fromName(QByteArrayView name); @@ -600,7 +635,14 @@ public: auto converter = [function = std::move(function)](const void *from, void *to) -> bool { const From *f = static_cast<const From *>(from); To *t = static_cast<To *>(to); - *t = function(*f); + auto &&r = function(*f); + 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); + } else { + *t = std::forward<decltype(r)>(r); + } return true; }; return registerConverterImpl<From, To>(std::move(converter), fromType, toType); @@ -709,7 +751,7 @@ public: static bool hasRegisteredMutableViewFunction(QMetaType fromType, QMetaType toType); -#ifndef Q_CLANG_QDOC +#ifndef Q_QDOC template<typename, bool> friend struct QtPrivate::SequentialValueTypeIsMetaType; template<typename, bool> friend struct QtPrivate::AssociativeValueTypeIsMetaType; template<typename, bool> friend struct QtPrivate::IsMetaTypePair; @@ -1204,7 +1246,12 @@ template <typename T> struct QMetaTypeId2<const T&> : QMetaTypeId2<T> {}; template <typename T> -struct QMetaTypeId2<T&> { enum {Defined = false }; }; +struct QMetaTypeId2<T&> +{ + using NameAsArrayType = void; + enum { Defined = false, IsBuiltIn = false }; + static inline constexpr int qt_metatype_id() { return 0; } +}; namespace QtPrivate { template <typename T, bool Defined = QMetaTypeId2<T>::Defined> @@ -1233,7 +1280,7 @@ namespace QtPrivate { struct QMetaTypeTypeFlags { enum { Flags = (QTypeInfo<T>::isRelocatable ? QMetaType::RelocatableType : 0) - | (!std::is_trivially_default_constructible_v<T> ? QMetaType::NeedsConstruction : 0) + | ((!std::is_default_constructible_v<T> || !QTypeInfo<T>::isValueInitializationBitwiseZero) ? QMetaType::NeedsConstruction : 0) | (!std::is_trivially_destructible_v<T> ? QMetaType::NeedsDestruction : 0) | (!std::is_trivially_copy_constructible_v<T> ? QMetaType::NeedsCopyConstruction : 0) | (!std::is_trivially_move_constructible_v<T> ? QMetaType::NeedsMoveConstruction : 0) @@ -1244,7 +1291,7 @@ namespace QtPrivate { | (IsEnumOrFlags<T>::value ? QMetaType::IsEnumeration : 0) | (IsGadgetHelper<T>::IsGadgetOrDerivedFrom ? QMetaType::IsGadget : 0) | (IsPointerToGadgetHelper<T>::IsGadgetOrDerivedFrom ? QMetaType::PointerToGadget : 0) - | (QTypeInfo<T>::isPointer ? QMetaType::IsPointer : 0) + | (std::is_pointer_v<T> ? QMetaType::IsPointer : 0) | (IsUnsignedEnum<T> ? QMetaType::IsUnsignedEnumeration : 0) | (IsQmlListType<T> ? QMetaType::IsQmlList : 0) | (std::is_const_v<std::remove_pointer_t<T>> ? QMetaType::IsConst : 0) @@ -2209,6 +2256,7 @@ struct is_std_pair<std::pair<T1_, T2_>> : std::true_type { using T2 = T2_; }; +namespace TypeNameHelper { template<typename T> constexpr auto typenameHelper() { @@ -2250,15 +2298,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) @@ -2284,6 +2332,8 @@ constexpr auto typenameHelper() return result; } } +} // namespace TypeNameHelper +using TypeNameHelper::typenameHelper; template<typename T, typename = void> struct BuiltinMetaType : std::integral_constant<int, 0> @@ -2340,18 +2390,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: // @@ -2376,7 +2428,7 @@ public: static constexpr QMetaTypeInterface::DefaultCtrFn getDefaultCtr() { - if constexpr (std::is_default_constructible_v<S> && !std::is_trivially_default_constructible_v<S>) { + if constexpr (std::is_default_constructible_v<S> && !QTypeInfo<S>::isValueInitializationBitwiseZero) { return [](const QMetaTypeInterface *, void *addr) { new (addr) S(); }; } else { return nullptr; @@ -2444,7 +2496,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, @@ -2611,7 +2663,14 @@ constexpr const QMetaObject *QMetaType::metaObject() const template<typename... T> constexpr const QtPrivate::QMetaTypeInterface *const qt_metaTypeArray[] = { - QtPrivate::qMetaTypeInterfaceForType<T>()... + /* + Unique in qTryMetaTypeInterfaceForType does not have to be unique here + as we require _all_ types here to be actually complete. + We just want to have the additional type processing that exist in + QtPrivate::qTryMetaTypeInterfaceForType as opposed to the normal + QtPrivate::qMetaTypeInterfaceForType used in QMetaType::fromType + */ + QtPrivate::qTryMetaTypeInterfaceForType<void, QtPrivate::TypeAndForceComplete<T, std::true_type>>()... }; constexpr const char *QMetaType::name() const |