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. 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) \ #define QT_ADD_STATIC_METATYPE(MetaTypeName, MetaTypeId, RealName) \
{ #RealName, sizeof(#RealName) - 1, MetaTypeId }, { #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 pointer if no matching type was found. The returned pointer must not be
deleted. deleted.
\sa type(), isRegistered(), Type \sa type(), isRegistered(), Type, name()
*/ */
const char *QMetaType::typeName(int typeId) const char *QMetaType::typeName(int typeId)
{ {
@ -950,6 +975,20 @@ const char *QMetaType::typeName(int typeId)
#undef QT_METATYPE_TYPEID_TYPENAME_CONVERTER #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. 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 \since 5.0
Constructs a QMetaType object that contains all information about type \a typeId. 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) QMetaType::QMetaType(const int typeId)
: m_typeId(typeId) : m_typeId(typeId)

View File

@ -572,7 +572,7 @@ public:
static bool load(QDataStream &stream, int type, void *data); static bool load(QDataStream &stream, int type, void *data);
#endif #endif
explicit QMetaType(const int type); // ### Qt6: drop const explicit QMetaType(const int type = QMetaType::UnknownType); // ### Qt6: drop const
inline ~QMetaType(); inline ~QMetaType();
inline bool isValid() const; inline bool isValid() const;
@ -581,12 +581,24 @@ public:
inline int sizeOf() const; inline int sizeOf() const;
inline TypeFlags flags() const; inline TypeFlags flags() const;
inline const QMetaObject *metaObject() const; inline const QMetaObject *metaObject() const;
QT_PREPEND_NAMESPACE(QByteArray) name() const;
inline void *create(const void *copy = nullptr) const; inline void *create(const void *copy = nullptr) const;
inline void destroy(void *data) const; inline void destroy(void *data) const;
inline void *construct(void *where, const void *copy = nullptr) const; inline void *construct(void *where, const void *copy = nullptr) const;
inline void destruct(void *data) 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: public:
template<typename T> template<typename T>
static bool registerComparators() static bool registerComparators()

View File

@ -125,6 +125,7 @@ private slots:
void compareCustomEqualOnlyType(); void compareCustomEqualOnlyType();
void customDebugStream(); void customDebugStream();
void unknownType(); void unknownType();
void fromType();
}; };
struct BaseGenericType struct BaseGenericType
@ -482,6 +483,7 @@ void tst_QMetaType::id()
{ {
QCOMPARE(QMetaType(QMetaType::QString).id(), QMetaType::QString); QCOMPARE(QMetaType(QMetaType::QString).id(), QMetaType::QString);
QCOMPARE(QMetaType(::qMetaTypeId<TestSpace::Foo>()).id(), ::qMetaTypeId<TestSpace::Foo>()); QCOMPARE(QMetaType(::qMetaTypeId<TestSpace::Foo>()).id(), ::qMetaTypeId<TestSpace::Foo>());
QCOMPARE(QMetaType::fromType<TestSpace::Foo>().id(), ::qMetaTypeId<TestSpace::Foo>());
} }
void tst_QMetaType::qMetaTypeId() void tst_QMetaType::qMetaTypeId()
@ -600,6 +602,12 @@ void tst_QMetaType::typeName()
QCOMPARE(name, aTypeName); QCOMPARE(name, aTypeName);
QCOMPARE(name.toLatin1(), QMetaObject::normalizedType(name.toLatin1().constData())); QCOMPARE(name.toLatin1(), QMetaObject::normalizedType(name.toLatin1().constData()));
QCOMPARE(rawname == nullptr, aTypeName.isNull()); 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() void tst_QMetaType::type_data()
@ -1728,6 +1736,7 @@ void tst_QMetaType::automaticTemplateRegistration()
const int type = QMetaType::type(tn); \ const int type = QMetaType::type(tn); \
const int expectedType = ::qMetaTypeId<CONTAINER< __VA_ARGS__ > >(); \ const int expectedType = ::qMetaTypeId<CONTAINER< __VA_ARGS__ > >(); \
QCOMPARE(type, expectedType); \ QCOMPARE(type, expectedType); \
QCOMPARE((QMetaType::fromType<CONTAINER< __VA_ARGS__ >>().id()), expectedType); \
} }
#define FOR_EACH_1ARG_TEMPLATE_TYPE(F, TYPE) \ #define FOR_EACH_1ARG_TEMPLATE_TYPE(F, TYPE) \
@ -2572,6 +2581,26 @@ void tst_QMetaType::unknownType()
invalid.construct(&buffer); invalid.construct(&buffer);
QCOMPARE(buffer, 0xBAD); 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 // Compile-time test, it should be possible to register function pointer types
class Undefined; class Undefined;