diff options
author | Thiago Macieira <[email protected]> | 2024-11-18 23:12:19 -0800 |
---|---|---|
committer | Thiago Macieira <[email protected]> | 2024-11-28 12:24:10 -0800 |
commit | 3378987e63d3d4d56d554fd235d451b9c252f6d0 (patch) | |
tree | 1f90798e6e7de49b501af68e7b1610424b9a7c94 | |
parent | 2da86477d0973605bd598db7ff3ff219e2736b42 (diff) |
QMetaType & moc: remove the pair type from qTryMetaTypeInterfaceForType()
We can detect whether the intent is to require completeness by having
Unique = void. This simplifies QtMocHelpers as well, removing one more
class that needed to be instantiated for each metatype.
Change-Id: I3a256568bb6ce1754399fffd6f61144d0a3e8deb
Reviewed-by: Fabian Kosmale <[email protected]>
-rw-r--r-- | src/corelib/kernel/qmetatype.h | 18 | ||||
-rw-r--r-- | src/corelib/kernel/qtmochelpers.h | 41 | ||||
-rw-r--r-- | src/tools/moc/generator.cpp | 6 | ||||
-rw-r--r-- | tests/auto/tools/mochelpers/tst_mochelpers.cpp | 4 |
4 files changed, 25 insertions, 44 deletions
diff --git a/src/corelib/kernel/qmetatype.h b/src/corelib/kernel/qmetatype.h index f379803e4a4..97fdf8b4ef3 100644 --- a/src/corelib/kernel/qmetatype.h +++ b/src/corelib/kernel/qmetatype.h @@ -2617,13 +2617,6 @@ struct QRemovePointerLike<Pointer<T>> \ QT_FOR_EACH_AUTOMATIC_TEMPLATE_SMART_POINTER(Q_REMOVE_POINTER_LIKE_IMPL) #undef Q_REMOVE_POINTER_LIKE_IMPL -template<typename T, typename ForceComplete_> -struct TypeAndForceComplete -{ - using type = T; - using ForceComplete = ForceComplete_; -}; - template<typename T> constexpr const QMetaTypeInterface *qMetaTypeInterfaceForType() { @@ -2632,18 +2625,21 @@ constexpr const QMetaTypeInterface *qMetaTypeInterfaceForType() return &QMetaTypeInterfaceWrapper<Ty>::metaType; } -template<typename Unique, typename TypeCompletePair> +// Relaxed vesion of the above, used by moc-generated code to create the +// metatype array without requiring types to be complete and allowing +// references. Unique is passed to is_complete and must be a different unique +// type; if it is void, this function is equal to qMetaTypeInterfaceForType() +// above. +template<typename Unique, typename T> constexpr const QMetaTypeInterface *qTryMetaTypeInterfaceForType() { - using T = typename TypeCompletePair::type; - using ForceComplete = typename TypeCompletePair::ForceComplete; using Ty = typename MetatypeDecay<T>::type; using Tz = typename QRemovePointerLike<Ty>::type; if constexpr (std::is_void_v<Tz>) { // early out to avoid expanding the rest of the templates return &QMetaTypeInterfaceWrapper<Ty>::metaType; - } else if constexpr (ForceComplete::value) { + } else if constexpr (std::is_void_v<Unique>) { checkTypeIsSuitableForMetaType<Ty>(); return &QMetaTypeInterfaceWrapper<Ty>::metaType; } else if constexpr (std::is_reference_v<Tz>) { diff --git a/src/corelib/kernel/qtmochelpers.h b/src/corelib/kernel/qtmochelpers.h index 588ae86d663..3099389b872 100644 --- a/src/corelib/kernel/qtmochelpers.h +++ b/src/corelib/kernel/qtmochelpers.h @@ -127,7 +127,6 @@ template <typename Prop, typename Value> inline bool setProperty(Prop &property, } struct NoType {}; -template <typename T> struct ForceCompleteMetaTypes {}; namespace detail { template<typename Enum> constexpr int payloadSizeForEnum() @@ -150,30 +149,15 @@ template <uint H, uint P> struct UintDataBlock // By default, we allow metatypes for incomplete types to be stored in the // metatype array, but we provide a way to require them to be complete by using -// ForceCompleteMetaTypes in either the Unique type (used by moc if -// --require-complete-types is passed or some internal heuristic for QML -// matches) or in the type itself, used below for properties and enums. -template <typename T> struct TypeMustBeComplete : std::false_type {}; -template <typename T> struct TypeMustBeComplete<ForceCompleteMetaTypes<T>> : std::true_type {}; -// template <> struct TypeMustBeComplete<void> : std::true_type {}; - -template <typename Unique, typename T, typename RequireComplete = TypeMustBeComplete<Unique>> -struct TryMetaTypeInterfaceForType -{ - static constexpr const QtPrivate::QMetaTypeInterface *type() noexcept - { - using namespace QtPrivate; - using Query = TypeAndForceComplete<T, RequireComplete>; - return qTryMetaTypeInterfaceForType<Unique, Query>(); - } +// void as the Unique type (used by moc if --require-complete-types is passed +// or some internal heuristic for QML matches) or by using the enum below, for +// properties and enums. +enum TypeCompletenessForMetaType : bool { + TypeMayBeIncomplete = false, + TypeMustBeComplete = true, }; -template <typename Unique, typename T, typename RequireComplete> -struct TryMetaTypeInterfaceForType<Unique, ForceCompleteMetaTypes<T>, RequireComplete> : - TryMetaTypeInterfaceForType<void, T, std::true_type> -{}; - -template <typename... T> struct MetaTypeList +template <bool TypeMustBeComplete, typename... T> struct MetaTypeList { static constexpr int count() { return sizeof...(T); } template <typename Unique, typename Result> static constexpr void @@ -181,8 +165,9 @@ template <typename... T> struct MetaTypeList { if constexpr (count()) { using namespace QtPrivate; + using U = std::conditional_t<TypeMustBeComplete, void, Unique>; const QMetaTypeInterface *metaTypes[] = { - TryMetaTypeInterfaceForType<Unique, T>::type()... + qTryMetaTypeInterfaceForType<U, T>()... }; for (const QMetaTypeInterface *mt : metaTypes) result.relocatingData.metaTypes[metatypeoffset++] = mt; @@ -315,7 +300,7 @@ template <typename PropertyType> struct PropertyData : detail::UintDataBlock<5, } static constexpr auto metaTypes() - { return detail::MetaTypeList<ForceCompleteMetaTypes<PropertyType>>{}; } + { return detail::MetaTypeList<detail::TypeMustBeComplete, PropertyType>{}; } static constexpr void adjustOffsets(uint *, uint, uint, uint) noexcept {} }; @@ -371,7 +356,7 @@ public: } static constexpr auto metaTypes() - { return detail::MetaTypeList<ForceCompleteMetaTypes<Enum>>{}; } + { return detail::MetaTypeList<detail::TypeMustBeComplete, Enum>{}; } static constexpr void adjustOffsets(uint *ptr, uint dataoffset, uint payloadoffset, uint metatypeoffset) noexcept @@ -402,11 +387,11 @@ struct FunctionData<Ret (Args...), ExtraFlags> "NoType return type used on a non-constructor"); static_assert((ExtraFlags & MethodIsConst) == 0, "Constructors cannot be const"); - return detail::MetaTypeList<Args...>{}; + return detail::MetaTypeList<detail::TypeMayBeIncomplete, Args...>{}; } else { static_assert((ExtraFlags & MethodConstructor) != MethodConstructor, "Constructors must use NoType as return type"); - return detail::MetaTypeList<Ret, Args...>{}; + return detail::MetaTypeList<detail::TypeMayBeIncomplete, Ret, Args...>{}; } } diff --git a/src/tools/moc/generator.cpp b/src/tools/moc/generator.cpp index 43583b35528..cf4679b2156 100644 --- a/src/tools/moc/generator.cpp +++ b/src/tools/moc/generator.cpp @@ -329,9 +329,9 @@ void Generator::generateCode() metaObjectFlags = "QMC::PropertyAccessInStaticMetaCall"; } { - QByteArray tagType = "qt_meta_tag_" + qualifiedClassNameIdentifier + "_t"; - if (requireCompleteness) - tagType = "QtMocHelpers::ForceCompleteMetaTypes<" + tagType + '>'; + QByteArray tagType = QByteArrayLiteral("void"); + if (!requireCompleteness) + tagType = "qt_meta_tag_" + qualifiedClassNameIdentifier + "_t"; fprintf(out, " return QtMocHelpers::metaObjectData<%s, %s>(%s, qt_stringData,\n" " qt_methods, qt_properties, qt_enums%s);\n" "}\n", diff --git a/tests/auto/tools/mochelpers/tst_mochelpers.cpp b/tests/auto/tools/mochelpers/tst_mochelpers.cpp index 022263e7d81..7e5d18d160e 100644 --- a/tests/auto/tools/mochelpers/tst_mochelpers.cpp +++ b/tests/auto/tools/mochelpers/tst_mochelpers.cpp @@ -699,7 +699,7 @@ void tst_MocHelpers::uintArray() using Dummy = QString; using QtMocHelpers::NoType; using namespace QtMocConstants; - constexpr auto mo = QtMocHelpers::metaObjectData<void, void>(PropertyAccessInStaticMetaCall, + constexpr auto mo = QtMocHelpers::metaObjectData<tst_MocHelpers, tst_MocHelpers>(PropertyAccessInStaticMetaCall, dummyStringData, QtMocHelpers::UintData{ QtMocHelpers::RevisionedSignalData<void()>(1, 2, QtMocConstants::AccessPublic, 0x509, @@ -747,7 +747,7 @@ void tst_MocHelpers::uintArray() checkMethods(data, metaTypes); checkConstructors(data, metaTypes); QMetaType self(metaTypes[data[6] + data[8]]); - QCOMPARE(self, QMetaType::fromType<void>()); + QCOMPARE(self, QMetaType::fromType<tst_MocHelpers>()); } QTEST_MAIN(tst_MocHelpers) |