From 47c6466d0acc6d8d733b4fdbaf980a60bbfc93ef Mon Sep 17 00:00:00 2001 From: Fabian Kosmale Date: Tue, 31 Mar 2020 08:48:56 +0200 Subject: [PATCH] QMetaType: create metatype for void Create a QMetaTypeInterface for void. This allows us differentiate QMetaType::Unknown from QMetaType::Void. In addition, this will enable the usage of QMetaMethod::metaReturnType in QMetaMethod::returnType, and will facilitate using metaReturnType in declarative, which needs to distinguish between Unknown and Void. Change-Id: I83296b49587f3deb7ec73e25a33f0d8c98cf8da0 Reviewed-by: Lars Knoll --- src/corelib/kernel/qmetatype.h | 30 ++++++++++++++----- src/corelib/kernel/qmetatype_p.h | 4 +-- .../kernel/qmetatype/tst_qmetatype.cpp | 13 ++++++-- 3 files changed, 34 insertions(+), 13 deletions(-) diff --git a/src/corelib/kernel/qmetatype.h b/src/corelib/kernel/qmetatype.h index 60192e4131c..3c7781c8509 100644 --- a/src/corelib/kernel/qmetatype.h +++ b/src/corelib/kernel/qmetatype.h @@ -2758,7 +2758,6 @@ QMetaTypeInterface QMetaTypeForType::metaType = { } }) }; -#undef QT_METATYPE_CONSTEXPRLAMDA template constexpr const decltype(typenameHelper()) QMetaTypeForType::name = typenameHelper(); @@ -2766,7 +2765,28 @@ constexpr const decltype(typenameHelper()) QMetaTypeForType::name = typena template<> class QMetaTypeForType { + static const decltype(typenameHelper()) name; + +public: + static inline QMetaTypeInterface metaType = + { + /*.revision=*/ 0, + /*.size=*/ 0, + /*.alignment=*/ 0, + /*.flags=*/ 0, + /*.metaObject=*/ nullptr, + /*.name=*/ "void", + /*.typeId=*/ BuiltinMetaType::value, + /*.ref=*/ Q_REFCOUNT_INITIALIZE_STATIC, + /*.deleteSelf=*/ nullptr, + /*.defaultCtr=*/ nullptr, + /*.copyCtr=*/ nullptr, + /*.moveCtr=*/ nullptr, + /*.dtor=*/ nullptr, + /*.legacyRegisterOp=*/ nullptr + }; }; +#undef QT_METATYPE_CONSTEXPRLAMDA #ifndef QT_BOOTSTRAPPED #define QT_METATYPE_DECLARE_EXTERN_TEMPLATE_ITER(TypeName, Id, Name) \ @@ -2789,11 +2809,7 @@ template constexpr QMetaTypeInterface *qMetaTypeInterfaceForType() { using Ty = std::remove_cv_t>; - if constexpr (std::is_same_v) { - return nullptr; - } else { - return &QMetaTypeForType::metaType; - } + return &QMetaTypeForType::metaType; } namespace detail { @@ -2818,8 +2834,6 @@ constexpr QMetaTypeInterface *qTryMetaTypeInterfaceForType() using Tz = std::remove_pointer_t; if constexpr (!is_complete::value) { return nullptr; - } else if constexpr (std::is_same_v) { - return nullptr; } else { return &QMetaTypeForType::metaType; } diff --git a/src/corelib/kernel/qmetatype_p.h b/src/corelib/kernel/qmetatype_p.h index 8e08d84ffdf..2f4d69488ff 100644 --- a/src/corelib/kernel/qmetatype_p.h +++ b/src/corelib/kernel/qmetatype_p.h @@ -192,9 +192,7 @@ template<> struct TypeDefinition { static const bool IsAvailable = false; template static QT_PREPEND_NAMESPACE(QtPrivate::QMetaTypeInterface) *getInterfaceFromType() { - if constexpr (std::is_same_v) { - return nullptr; - } else if constexpr (QtMetaTypePrivate::TypeDefinition::IsAvailable) { + if constexpr (QtMetaTypePrivate::TypeDefinition::IsAvailable) { return &QT_PREPEND_NAMESPACE(QtPrivate::QMetaTypeForType)::metaType; } return nullptr; diff --git a/tests/auto/corelib/kernel/qmetatype/tst_qmetatype.cpp b/tests/auto/corelib/kernel/qmetatype/tst_qmetatype.cpp index f144aad7e40..d036be55c69 100644 --- a/tests/auto/corelib/kernel/qmetatype/tst_qmetatype.cpp +++ b/tests/auto/corelib/kernel/qmetatype/tst_qmetatype.cpp @@ -127,6 +127,7 @@ private slots: void operatorEq_data(); void operatorEq(); void typesWithInaccessibleDTors(); + void voidIsNotUnknown(); }; struct BaseGenericType @@ -1339,7 +1340,7 @@ void tst_QMetaType::isRegistered_data() QTest::addColumn("registered"); // predefined/custom types - QTest::newRow("QMetaType::Void") << int(QMetaType::Void) << false; + QTest::newRow("QMetaType::Void") << int(QMetaType::Void) << true; QTest::newRow("QMetaType::Int") << int(QMetaType::Int) << true; int dummyTypeId = qRegisterMetaType("IsRegisteredDummyType"); @@ -2548,7 +2549,7 @@ void tst_QMetaType::operatorEq_data() QTest::newRow("String") << QMetaType(QMetaType::QString) << QMetaType::fromType() << true; QTest::newRow("void1") << QMetaType(QMetaType::UnknownType) << QMetaType::fromType() - << true; + << false; QTest::newRow("void2") << QMetaType::fromType() << QMetaType::fromType() << true; QTest::newRow("vec1") << QMetaType::fromType>() @@ -2590,6 +2591,14 @@ void tst_QMetaType::typesWithInaccessibleDTors() Q_UNUSED(QMetaType::fromType()); } +void tst_QMetaType::voidIsNotUnknown() +{ + QMetaType voidType = QMetaType::fromType(); + QMetaType voidType2 = QMetaType(QMetaType::Void); + QCOMPARE(voidType, voidType2); + QVERIFY(voidType != QMetaType(QMetaType::UnknownType)); +} + // Compile-time test, it should be possible to register function pointer types class Undefined;