QMetaType: add more static-less API

In prevision to Qt6 which is going to discourrage the use of the integer id,
add some missing API to the staticless QMetaType API:

 - Add a way to construct a QMetaType from a type without calling qMetaTypeId:
   QMetaType::fromType<T>()
 - Add equality operators
 - Add a QMetaType::name() function
 - Add a default constructor (by adding a default parameter to the existing ctor)

Change-Id: I95487c1c31bdf0d773717daa9d5452cbced30673
Reviewed-by: Lars Knoll <lars.knoll@qt.io>
This commit is contained in:
Olivier Goffart 2019-12-04 09:49:34 +01:00
parent ece0c0a5e7
commit 4c3c63d4cb
3 changed files with 84 additions and 2 deletions

View File

@ -506,6 +506,31 @@ struct DefinedTypesFilter {
Destructs this object.
*/
/*!
\fn template<typename T> QMetaType QMetaType::fromType()
\since 5.15
Returns the QMetaType corresponding to the type in the template parameter.
*/
/*! \fn bool operator==(const QMetaType &a, const QMetaType &b)
\since 5.15
\relates QMetaType
\overload
Returns \c true if the QMetaType \a a represents the same type
as the QMetaType \a b, otherwise returns \c false.
*/
/*! \fn bool operator!=(const QMetaType &a, const QMetaType &c)
\since 5.15
\relates QMetaType
\overload
Returns \c true if the QMetaType \a a represents a difference type
than the QMetaType \a b, otherwise returns \c false.
*/
#define QT_ADD_STATIC_METATYPE(MetaTypeName, MetaTypeId, RealName) \
{ #RealName, sizeof(#RealName) - 1, MetaTypeId },
@ -930,7 +955,7 @@ constexpr MetaTypeOffsets<QtPrivate::Indexes<QMetaType::HighestInternalId + 1>::
pointer if no matching type was found. The returned pointer must not be
deleted.
\sa type(), isRegistered(), Type
\sa type(), isRegistered(), Type, name()
*/
const char *QMetaType::typeName(int typeId)
{
@ -950,6 +975,20 @@ const char *QMetaType::typeName(int typeId)
#undef QT_METATYPE_TYPEID_TYPENAME_CONVERTER
}
/*!
\since 5.15
Returns the type name associated with this QMetaType, or a null
pointer if no matching type was found. The returned pointer must not be
deleted.
\sa typeName()
*/
QByteArray QMetaType::name() const
{
return QMetaType::typeName(m_typeId);
}
/*
Similar to QMetaType::type(), but only looks in the static set of types.
*/
@ -2214,6 +2253,8 @@ QMetaType QMetaType::typeInfo(const int type)
\since 5.0
Constructs a QMetaType object that contains all information about type \a typeId.
\note: The default parameter was added in Qt 5.15
*/
QMetaType::QMetaType(const int typeId)
: m_typeId(typeId)

View File

@ -572,7 +572,7 @@ public:
static bool load(QDataStream &stream, int type, void *data);
#endif
explicit QMetaType(const int type); // ### Qt6: drop const
explicit QMetaType(const int type = QMetaType::UnknownType); // ### Qt6: drop const
inline ~QMetaType();
inline bool isValid() const;
@ -581,12 +581,24 @@ public:
inline int sizeOf() const;
inline TypeFlags flags() const;
inline const QMetaObject *metaObject() const;
QT_PREPEND_NAMESPACE(QByteArray) name() const;
inline void *create(const void *copy = nullptr) const;
inline void destroy(void *data) const;
inline void *construct(void *where, const void *copy = nullptr) const;
inline void destruct(void *data) const;
template<typename T>
static QMetaType fromType()
{ return QMetaType(qMetaTypeId<T>()); }
friend bool operator==(const QMetaType &a, const QMetaType &b)
{ return a.m_typeId == b.m_typeId; }
friend bool operator!=(const QMetaType &a, const QMetaType &b)
{ return a.m_typeId != b.m_typeId; }
public:
template<typename T>
static bool registerComparators()

View File

@ -125,6 +125,7 @@ private slots:
void compareCustomEqualOnlyType();
void customDebugStream();
void unknownType();
void fromType();
};
struct BaseGenericType
@ -482,6 +483,7 @@ void tst_QMetaType::id()
{
QCOMPARE(QMetaType(QMetaType::QString).id(), QMetaType::QString);
QCOMPARE(QMetaType(::qMetaTypeId<TestSpace::Foo>()).id(), ::qMetaTypeId<TestSpace::Foo>());
QCOMPARE(QMetaType::fromType<TestSpace::Foo>().id(), ::qMetaTypeId<TestSpace::Foo>());
}
void tst_QMetaType::qMetaTypeId()
@ -600,6 +602,12 @@ void tst_QMetaType::typeName()
QCOMPARE(name, aTypeName);
QCOMPARE(name.toLatin1(), QMetaObject::normalizedType(name.toLatin1().constData()));
QCOMPARE(rawname == nullptr, aTypeName.isNull());
QMetaType mt(aType);
if (mt.isValid()) { // Gui type are not valid
QCOMPARE(QString::fromLatin1(QMetaType(aType).name()), aTypeName);
}
}
void tst_QMetaType::type_data()
@ -1728,6 +1736,7 @@ void tst_QMetaType::automaticTemplateRegistration()
const int type = QMetaType::type(tn); \
const int expectedType = ::qMetaTypeId<CONTAINER< __VA_ARGS__ > >(); \
QCOMPARE(type, expectedType); \
QCOMPARE((QMetaType::fromType<CONTAINER< __VA_ARGS__ >>().id()), expectedType); \
}
#define FOR_EACH_1ARG_TEMPLATE_TYPE(F, TYPE) \
@ -2572,6 +2581,26 @@ void tst_QMetaType::unknownType()
invalid.construct(&buffer);
QCOMPARE(buffer, 0xBAD);
}
void tst_QMetaType::fromType()
{
#define FROMTYPE_CHECK(MetaTypeName, MetaTypeId, RealType) \
QCOMPARE(QMetaType::fromType<RealType>(), QMetaType(MetaTypeId)); \
QVERIFY(QMetaType::fromType<RealType>() == QMetaType(MetaTypeId)); \
QVERIFY(!(QMetaType::fromType<RealType>() != QMetaType(MetaTypeId))); \
QCOMPARE(QMetaType::fromType<RealType>().id(), MetaTypeId);
FOR_EACH_CORE_METATYPE(FROMTYPE_CHECK)
QVERIFY(QMetaType::fromType<QString>() != QMetaType());
QCOMPARE(QMetaType(), QMetaType());
QCOMPARE(QMetaType(QMetaType::UnknownType), QMetaType());
FROMTYPE_CHECK(_, ::qMetaTypeId<Whity<int>>(), Whity<int>)
#undef FROMTYPE_CHECK
}
// Compile-time test, it should be possible to register function pointer types
class Undefined;