Add QMetaType::type(QByteArray) function
QMetaType::type(const char *) requires that the string argument is 0-terminated. This new overload makes it possible to query the type of a string with an explicit length. In particular, QByteArrays constructed by QByteArray::fromRawData(), for example from a substring of a normalized method signature (the "int" part of "mySlot(int"), can now be queried without making a copy of the string. Also, Qt5 meta-objects represent type names as QByteArray literals, which can be fed directly to this new QMetaType::type() overload (no need to call strlen). Change-Id: I60d35aa6bdc0f77e0997f98b0e30e12fd3d5e100 Reviewed-by: Jędrzej Nowacki <jedrzej.nowacki@digia.com> Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
This commit is contained in:
parent
3de0f442b5
commit
0678d7c43c
@ -801,7 +801,7 @@ static inline int qMetaTypeStaticType(const char *typeName, int length)
|
||||
{
|
||||
int i = 0;
|
||||
while (types[i].typeName && ((length != types[i].typeNameLength)
|
||||
|| strcmp(typeName, types[i].typeName))) {
|
||||
|| memcmp(typeName, types[i].typeName, length))) {
|
||||
++i;
|
||||
}
|
||||
return types[i].type;
|
||||
@ -821,7 +821,7 @@ static int qMetaTypeCustomType_unlocked(const char *typeName, int length)
|
||||
for (int v = 0; v < ct->count(); ++v) {
|
||||
const QCustomTypeInfo &customInfo = ct->at(v);
|
||||
if ((length == customInfo.typeName.size())
|
||||
&& !strcmp(typeName, customInfo.typeName.constData())) {
|
||||
&& !memcmp(typeName, customInfo.typeName.constData(), length)) {
|
||||
if (customInfo.alias >= 0)
|
||||
return customInfo.alias;
|
||||
return v + QMetaType::User;
|
||||
@ -1048,9 +1048,8 @@ bool QMetaType::isRegistered(int type)
|
||||
Implementation of QMetaType::type().
|
||||
*/
|
||||
template <bool tryNormalizedType>
|
||||
static inline int qMetaTypeTypeImpl(const char *typeName)
|
||||
static inline int qMetaTypeTypeImpl(const char *typeName, int length)
|
||||
{
|
||||
int length = qstrlen(typeName);
|
||||
if (!length)
|
||||
return QMetaType::UnknownType;
|
||||
int type = qMetaTypeStaticType(typeName, length);
|
||||
@ -1080,7 +1079,7 @@ static inline int qMetaTypeTypeImpl(const char *typeName)
|
||||
*/
|
||||
int QMetaType::type(const char *typeName)
|
||||
{
|
||||
return qMetaTypeTypeImpl</*tryNormalizedType=*/true>(typeName);
|
||||
return qMetaTypeTypeImpl</*tryNormalizedType=*/true>(typeName, qstrlen(typeName));
|
||||
}
|
||||
|
||||
/*!
|
||||
@ -1092,7 +1091,21 @@ int QMetaType::type(const char *typeName)
|
||||
*/
|
||||
int qMetaTypeTypeInternal(const char *typeName)
|
||||
{
|
||||
return qMetaTypeTypeImpl</*tryNormalizedType=*/false>(typeName);
|
||||
return qMetaTypeTypeImpl</*tryNormalizedType=*/false>(typeName, qstrlen(typeName));
|
||||
}
|
||||
|
||||
/*!
|
||||
\since 5.5
|
||||
\overload
|
||||
|
||||
Returns a handle to the type called \a typeName, or 0 if there is
|
||||
no such type.
|
||||
|
||||
\sa isRegistered(), typeName()
|
||||
*/
|
||||
int QMetaType::type(const QT_PREPEND_NAMESPACE(QByteArray) &typeName)
|
||||
{
|
||||
return qMetaTypeTypeImpl</*tryNormalizedType=*/true>(typeName.constData(), typeName.size());
|
||||
}
|
||||
|
||||
#ifndef QT_NO_DATASTREAM
|
||||
|
@ -472,6 +472,11 @@ public:
|
||||
static int registerTypedef(const char *typeName, int aliasId);
|
||||
static int registerNormalizedTypedef(const QT_PREPEND_NAMESPACE(QByteArray) &normalizedTypeName, int aliasId);
|
||||
static int type(const char *typeName);
|
||||
#ifndef Q_QDOC
|
||||
static int type(const QT_PREPEND_NAMESPACE(QByteArray) &typeName);
|
||||
#else
|
||||
static int type(const QByteArray &typeName);
|
||||
#endif
|
||||
static const char *typeName(int type);
|
||||
static int sizeOf(int type);
|
||||
static TypeFlags typeFlags(int type);
|
||||
|
@ -79,6 +79,10 @@ private slots:
|
||||
void normalizedTypes();
|
||||
void typeName_data();
|
||||
void typeName();
|
||||
void type_data();
|
||||
void type();
|
||||
void type_fromSubString_data();
|
||||
void type_fromSubString();
|
||||
void create_data();
|
||||
void create();
|
||||
void createCopy_data();
|
||||
@ -385,6 +389,61 @@ void tst_QMetaType::typeName()
|
||||
QCOMPARE(name.toLatin1(), QMetaObject::normalizedType(name.toLatin1().constData()));
|
||||
}
|
||||
|
||||
void tst_QMetaType::type_data()
|
||||
{
|
||||
QTest::addColumn<QMetaType::Type>("aType");
|
||||
QTest::addColumn<QByteArray>("aTypeName");
|
||||
|
||||
#define TST_QMETATYPE_TYPE_DATA(MetaTypeName, MetaTypeId, RealType)\
|
||||
QTest::newRow(#RealType) << QMetaType::MetaTypeName << QByteArray( #RealType );
|
||||
#define TST_QMETATYPE_TYPE_DATA_ALIAS(MetaTypeName, MetaTypeId, AliasType, RealTypeString)\
|
||||
QTest::newRow(RealTypeString) << QMetaType::MetaTypeName << QByteArray( #AliasType );
|
||||
|
||||
QTest::newRow("empty") << QMetaType::UnknownType << QByteArray();
|
||||
|
||||
QT_FOR_EACH_STATIC_TYPE(TST_QMETATYPE_TYPE_DATA)
|
||||
QT_FOR_EACH_STATIC_ALIAS_TYPE(TST_QMETATYPE_TYPE_DATA_ALIAS)
|
||||
|
||||
#undef TST_QMETATYPE_TYPE_DATA
|
||||
#undef TST_METATYPE_TYPE_DATA_ALIAS
|
||||
}
|
||||
|
||||
void tst_QMetaType::type()
|
||||
{
|
||||
QFETCH(QMetaType::Type, aType);
|
||||
QFETCH(QByteArray, aTypeName);
|
||||
|
||||
// QMetaType::type(QByteArray)
|
||||
QCOMPARE(QMetaType::type(aTypeName), int(aType));
|
||||
// QMetaType::type(const char *)
|
||||
QCOMPARE(QMetaType::type(aTypeName.constData()), int(aType));
|
||||
}
|
||||
|
||||
void tst_QMetaType::type_fromSubString_data()
|
||||
{
|
||||
QTest::addColumn<int>("offset");
|
||||
QTest::addColumn<int>("size");
|
||||
QTest::addColumn<int>("expectedType");
|
||||
|
||||
// The test string is defined in the test function below
|
||||
QTest::newRow("int") << 0 << 3 << int(QMetaType::Int);
|
||||
QTest::newRow("boo") << 3 << 3 << 0;
|
||||
QTest::newRow("bool") << 3 << 4 << int(QMetaType::Bool);
|
||||
QTest::newRow("intbool") << 0 << 7 << 0;
|
||||
QTest::newRow("QMetaType::Type") << 7 << 15 << ::qMetaTypeId<QMetaType::Type>();
|
||||
QTest::newRow("double") << 22 << 6 << int(QMetaType::Double);
|
||||
}
|
||||
|
||||
void tst_QMetaType::type_fromSubString()
|
||||
{
|
||||
static const char *types = "intboolQMetaType::Typedoublexxx";
|
||||
QFETCH(int, offset);
|
||||
QFETCH(int, size);
|
||||
QFETCH(int, expectedType);
|
||||
QByteArray ba = QByteArray::fromRawData(types + offset, size);
|
||||
QCOMPARE(QMetaType::type(ba), expectedType);
|
||||
}
|
||||
|
||||
#define FOR_EACH_PRIMITIVE_METATYPE(F) \
|
||||
QT_FOR_EACH_STATIC_PRIMITIVE_TYPE(F) \
|
||||
QT_FOR_EACH_STATIC_CORE_POINTER(F) \
|
||||
|
@ -45,6 +45,8 @@ public:
|
||||
private slots:
|
||||
void typeBuiltin_data();
|
||||
void typeBuiltin();
|
||||
void typeBuiltin_QByteArray_data();
|
||||
void typeBuiltin_QByteArray();
|
||||
void typeBuiltinNotNormalized_data();
|
||||
void typeBuiltinNotNormalized();
|
||||
void typeCustom();
|
||||
@ -94,6 +96,7 @@ void tst_QMetaType::typeBuiltin_data()
|
||||
}
|
||||
}
|
||||
|
||||
// QMetaType::type(const char *)
|
||||
void tst_QMetaType::typeBuiltin()
|
||||
{
|
||||
QFETCH(QByteArray, typeName);
|
||||
@ -104,6 +107,21 @@ void tst_QMetaType::typeBuiltin()
|
||||
}
|
||||
}
|
||||
|
||||
void tst_QMetaType::typeBuiltin_QByteArray_data()
|
||||
{
|
||||
typeBuiltin_data();
|
||||
}
|
||||
|
||||
// QMetaType::type(QByteArray)
|
||||
void tst_QMetaType::typeBuiltin_QByteArray()
|
||||
{
|
||||
QFETCH(QByteArray, typeName);
|
||||
QBENCHMARK {
|
||||
for (int i = 0; i < 100000; ++i)
|
||||
QMetaType::type(typeName);
|
||||
}
|
||||
}
|
||||
|
||||
void tst_QMetaType::typeBuiltinNotNormalized_data()
|
||||
{
|
||||
QTest::addColumn<QByteArray>("typeName");
|
||||
|
Loading…
Reference in New Issue
Block a user