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 <lars.knoll@qt.io>
This commit is contained in:
Fabian Kosmale 2020-03-31 08:48:56 +02:00
parent 649d834443
commit 47c6466d0a
3 changed files with 34 additions and 13 deletions

View File

@ -2758,7 +2758,6 @@ QMetaTypeInterface QMetaTypeForType<T>::metaType = {
}
})
};
#undef QT_METATYPE_CONSTEXPRLAMDA
template<typename T>
constexpr const decltype(typenameHelper<T>()) QMetaTypeForType<T>::name = typenameHelper<T>();
@ -2766,7 +2765,28 @@ constexpr const decltype(typenameHelper<T>()) QMetaTypeForType<T>::name = typena
template<>
class QMetaTypeForType<void>
{
static const decltype(typenameHelper<void>()) name;
public:
static inline QMetaTypeInterface metaType =
{
/*.revision=*/ 0,
/*.size=*/ 0,
/*.alignment=*/ 0,
/*.flags=*/ 0,
/*.metaObject=*/ nullptr,
/*.name=*/ "void",
/*.typeId=*/ BuiltinMetaType<void>::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<typename T>
constexpr QMetaTypeInterface *qMetaTypeInterfaceForType()
{
using Ty = std::remove_cv_t<std::remove_reference_t<T>>;
if constexpr (std::is_same_v<Ty, void>) {
return nullptr;
} else {
return &QMetaTypeForType<Ty>::metaType;
}
return &QMetaTypeForType<Ty>::metaType;
}
namespace detail {
@ -2818,8 +2834,6 @@ constexpr QMetaTypeInterface *qTryMetaTypeInterfaceForType()
using Tz = std::remove_pointer_t<Ty>;
if constexpr (!is_complete<Tz, Unique>::value) {
return nullptr;
} else if constexpr (std::is_same_v<Ty, void>) {
return nullptr;
} else {
return &QMetaTypeForType<Ty>::metaType;
}

View File

@ -192,9 +192,7 @@ template<> struct TypeDefinition<QIcon> { static const bool IsAvailable = false;
template<typename T>
static QT_PREPEND_NAMESPACE(QtPrivate::QMetaTypeInterface) *getInterfaceFromType()
{
if constexpr (std::is_same_v<T, void>) {
return nullptr;
} else if constexpr (QtMetaTypePrivate::TypeDefinition<T>::IsAvailable) {
if constexpr (QtMetaTypePrivate::TypeDefinition<T>::IsAvailable) {
return &QT_PREPEND_NAMESPACE(QtPrivate::QMetaTypeForType)<T>::metaType;
}
return nullptr;

View File

@ -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<bool>("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>("IsRegisteredDummyType");
@ -2548,7 +2549,7 @@ void tst_QMetaType::operatorEq_data()
QTest::newRow("String") << QMetaType(QMetaType::QString)
<< QMetaType::fromType<const QString &>() << true;
QTest::newRow("void1") << QMetaType(QMetaType::UnknownType) << QMetaType::fromType<void>()
<< true;
<< false;
QTest::newRow("void2") << QMetaType::fromType<const void>() << QMetaType::fromType<void>()
<< true;
QTest::newRow("vec1") << QMetaType::fromType<QVector<const int *>>()
@ -2590,6 +2591,14 @@ void tst_QMetaType::typesWithInaccessibleDTors()
Q_UNUSED(QMetaType::fromType<WithDeletedDtor>());
}
void tst_QMetaType::voidIsNotUnknown()
{
QMetaType voidType = QMetaType::fromType<void>();
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;