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 <fabian.kosmale@qt.io>
This commit is contained in:
parent
2da86477d0
commit
3378987e63
@ -2617,13 +2617,6 @@ struct QRemovePointerLike<Pointer<T>> \
|
|||||||
QT_FOR_EACH_AUTOMATIC_TEMPLATE_SMART_POINTER(Q_REMOVE_POINTER_LIKE_IMPL)
|
QT_FOR_EACH_AUTOMATIC_TEMPLATE_SMART_POINTER(Q_REMOVE_POINTER_LIKE_IMPL)
|
||||||
#undef 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>
|
template<typename T>
|
||||||
constexpr const QMetaTypeInterface *qMetaTypeInterfaceForType()
|
constexpr const QMetaTypeInterface *qMetaTypeInterfaceForType()
|
||||||
{
|
{
|
||||||
@ -2632,18 +2625,21 @@ constexpr const QMetaTypeInterface *qMetaTypeInterfaceForType()
|
|||||||
return &QMetaTypeInterfaceWrapper<Ty>::metaType;
|
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()
|
constexpr const QMetaTypeInterface *qTryMetaTypeInterfaceForType()
|
||||||
{
|
{
|
||||||
using T = typename TypeCompletePair::type;
|
|
||||||
using ForceComplete = typename TypeCompletePair::ForceComplete;
|
|
||||||
using Ty = typename MetatypeDecay<T>::type;
|
using Ty = typename MetatypeDecay<T>::type;
|
||||||
using Tz = typename QRemovePointerLike<Ty>::type;
|
using Tz = typename QRemovePointerLike<Ty>::type;
|
||||||
|
|
||||||
if constexpr (std::is_void_v<Tz>) {
|
if constexpr (std::is_void_v<Tz>) {
|
||||||
// early out to avoid expanding the rest of the templates
|
// early out to avoid expanding the rest of the templates
|
||||||
return &QMetaTypeInterfaceWrapper<Ty>::metaType;
|
return &QMetaTypeInterfaceWrapper<Ty>::metaType;
|
||||||
} else if constexpr (ForceComplete::value) {
|
} else if constexpr (std::is_void_v<Unique>) {
|
||||||
checkTypeIsSuitableForMetaType<Ty>();
|
checkTypeIsSuitableForMetaType<Ty>();
|
||||||
return &QMetaTypeInterfaceWrapper<Ty>::metaType;
|
return &QMetaTypeInterfaceWrapper<Ty>::metaType;
|
||||||
} else if constexpr (std::is_reference_v<Tz>) {
|
} else if constexpr (std::is_reference_v<Tz>) {
|
||||||
|
@ -127,7 +127,6 @@ template <typename Prop, typename Value> inline bool setProperty(Prop &property,
|
|||||||
}
|
}
|
||||||
|
|
||||||
struct NoType {};
|
struct NoType {};
|
||||||
template <typename T> struct ForceCompleteMetaTypes {};
|
|
||||||
|
|
||||||
namespace detail {
|
namespace detail {
|
||||||
template<typename Enum> constexpr int payloadSizeForEnum()
|
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
|
// 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
|
// 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
|
// void as the Unique type (used by moc if --require-complete-types is passed
|
||||||
// --require-complete-types is passed or some internal heuristic for QML
|
// or some internal heuristic for QML matches) or by using the enum below, for
|
||||||
// matches) or in the type itself, used below for properties and enums.
|
// properties and enums.
|
||||||
template <typename T> struct TypeMustBeComplete : std::false_type {};
|
enum TypeCompletenessForMetaType : bool {
|
||||||
template <typename T> struct TypeMustBeComplete<ForceCompleteMetaTypes<T>> : std::true_type {};
|
TypeMayBeIncomplete = false,
|
||||||
// template <> struct TypeMustBeComplete<void> : std::true_type {};
|
TypeMustBeComplete = true,
|
||||||
|
|
||||||
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>();
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
template <typename Unique, typename T, typename RequireComplete>
|
template <bool TypeMustBeComplete, typename... T> struct MetaTypeList
|
||||||
struct TryMetaTypeInterfaceForType<Unique, ForceCompleteMetaTypes<T>, RequireComplete> :
|
|
||||||
TryMetaTypeInterfaceForType<void, T, std::true_type>
|
|
||||||
{};
|
|
||||||
|
|
||||||
template <typename... T> struct MetaTypeList
|
|
||||||
{
|
{
|
||||||
static constexpr int count() { return sizeof...(T); }
|
static constexpr int count() { return sizeof...(T); }
|
||||||
template <typename Unique, typename Result> static constexpr void
|
template <typename Unique, typename Result> static constexpr void
|
||||||
@ -181,8 +165,9 @@ template <typename... T> struct MetaTypeList
|
|||||||
{
|
{
|
||||||
if constexpr (count()) {
|
if constexpr (count()) {
|
||||||
using namespace QtPrivate;
|
using namespace QtPrivate;
|
||||||
|
using U = std::conditional_t<TypeMustBeComplete, void, Unique>;
|
||||||
const QMetaTypeInterface *metaTypes[] = {
|
const QMetaTypeInterface *metaTypes[] = {
|
||||||
TryMetaTypeInterfaceForType<Unique, T>::type()...
|
qTryMetaTypeInterfaceForType<U, T>()...
|
||||||
};
|
};
|
||||||
for (const QMetaTypeInterface *mt : metaTypes)
|
for (const QMetaTypeInterface *mt : metaTypes)
|
||||||
result.relocatingData.metaTypes[metatypeoffset++] = mt;
|
result.relocatingData.metaTypes[metatypeoffset++] = mt;
|
||||||
@ -315,7 +300,7 @@ template <typename PropertyType> struct PropertyData : detail::UintDataBlock<5,
|
|||||||
}
|
}
|
||||||
|
|
||||||
static constexpr auto metaTypes()
|
static constexpr auto metaTypes()
|
||||||
{ return detail::MetaTypeList<ForceCompleteMetaTypes<PropertyType>>{}; }
|
{ return detail::MetaTypeList<detail::TypeMustBeComplete, PropertyType>{}; }
|
||||||
|
|
||||||
static constexpr void adjustOffsets(uint *, uint, uint, uint) noexcept {}
|
static constexpr void adjustOffsets(uint *, uint, uint, uint) noexcept {}
|
||||||
};
|
};
|
||||||
@ -371,7 +356,7 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
static constexpr auto metaTypes()
|
static constexpr auto metaTypes()
|
||||||
{ return detail::MetaTypeList<ForceCompleteMetaTypes<Enum>>{}; }
|
{ return detail::MetaTypeList<detail::TypeMustBeComplete, Enum>{}; }
|
||||||
|
|
||||||
static constexpr void
|
static constexpr void
|
||||||
adjustOffsets(uint *ptr, uint dataoffset, uint payloadoffset, uint metatypeoffset) noexcept
|
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");
|
"NoType return type used on a non-constructor");
|
||||||
static_assert((ExtraFlags & MethodIsConst) == 0,
|
static_assert((ExtraFlags & MethodIsConst) == 0,
|
||||||
"Constructors cannot be const");
|
"Constructors cannot be const");
|
||||||
return detail::MetaTypeList<Args...>{};
|
return detail::MetaTypeList<detail::TypeMayBeIncomplete, Args...>{};
|
||||||
} else {
|
} else {
|
||||||
static_assert((ExtraFlags & MethodConstructor) != MethodConstructor,
|
static_assert((ExtraFlags & MethodConstructor) != MethodConstructor,
|
||||||
"Constructors must use NoType as return type");
|
"Constructors must use NoType as return type");
|
||||||
return detail::MetaTypeList<Ret, Args...>{};
|
return detail::MetaTypeList<detail::TypeMayBeIncomplete, Ret, Args...>{};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -329,9 +329,9 @@ void Generator::generateCode()
|
|||||||
metaObjectFlags = "QMC::PropertyAccessInStaticMetaCall";
|
metaObjectFlags = "QMC::PropertyAccessInStaticMetaCall";
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
QByteArray tagType = "qt_meta_tag_" + qualifiedClassNameIdentifier + "_t";
|
QByteArray tagType = QByteArrayLiteral("void");
|
||||||
if (requireCompleteness)
|
if (!requireCompleteness)
|
||||||
tagType = "QtMocHelpers::ForceCompleteMetaTypes<" + tagType + '>';
|
tagType = "qt_meta_tag_" + qualifiedClassNameIdentifier + "_t";
|
||||||
fprintf(out, " return QtMocHelpers::metaObjectData<%s, %s>(%s, qt_stringData,\n"
|
fprintf(out, " return QtMocHelpers::metaObjectData<%s, %s>(%s, qt_stringData,\n"
|
||||||
" qt_methods, qt_properties, qt_enums%s);\n"
|
" qt_methods, qt_properties, qt_enums%s);\n"
|
||||||
"}\n",
|
"}\n",
|
||||||
|
@ -699,7 +699,7 @@ void tst_MocHelpers::uintArray()
|
|||||||
using Dummy = QString;
|
using Dummy = QString;
|
||||||
using QtMocHelpers::NoType;
|
using QtMocHelpers::NoType;
|
||||||
using namespace QtMocConstants;
|
using namespace QtMocConstants;
|
||||||
constexpr auto mo = QtMocHelpers::metaObjectData<void, void>(PropertyAccessInStaticMetaCall,
|
constexpr auto mo = QtMocHelpers::metaObjectData<tst_MocHelpers, tst_MocHelpers>(PropertyAccessInStaticMetaCall,
|
||||||
dummyStringData,
|
dummyStringData,
|
||||||
QtMocHelpers::UintData{
|
QtMocHelpers::UintData{
|
||||||
QtMocHelpers::RevisionedSignalData<void()>(1, 2, QtMocConstants::AccessPublic, 0x509,
|
QtMocHelpers::RevisionedSignalData<void()>(1, 2, QtMocConstants::AccessPublic, 0x509,
|
||||||
@ -747,7 +747,7 @@ void tst_MocHelpers::uintArray()
|
|||||||
checkMethods(data, metaTypes);
|
checkMethods(data, metaTypes);
|
||||||
checkConstructors(data, metaTypes);
|
checkConstructors(data, metaTypes);
|
||||||
QMetaType self(metaTypes[data[6] + data[8]]);
|
QMetaType self(metaTypes[data[6] + data[8]]);
|
||||||
QCOMPARE(self, QMetaType::fromType<void>());
|
QCOMPARE(self, QMetaType::fromType<tst_MocHelpers>());
|
||||||
}
|
}
|
||||||
|
|
||||||
QTEST_MAIN(tst_MocHelpers)
|
QTEST_MAIN(tst_MocHelpers)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user