summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorThiago Macieira <[email protected]>2024-11-18 23:12:19 -0800
committerThiago Macieira <[email protected]>2024-11-28 12:24:10 -0800
commit3378987e63d3d4d56d554fd235d451b9c252f6d0 (patch)
tree1f90798e6e7de49b501af68e7b1610424b9a7c94
parent2da86477d0973605bd598db7ff3ff219e2736b42 (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.h18
-rw-r--r--src/corelib/kernel/qtmochelpers.h41
-rw-r--r--src/tools/moc/generator.cpp6
-rw-r--r--tests/auto/tools/mochelpers/tst_mochelpers.cpp4
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)