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;
|
int i = 0;
|
||||||
while (types[i].typeName && ((length != types[i].typeNameLength)
|
while (types[i].typeName && ((length != types[i].typeNameLength)
|
||||||
|| strcmp(typeName, types[i].typeName))) {
|
|| memcmp(typeName, types[i].typeName, length))) {
|
||||||
++i;
|
++i;
|
||||||
}
|
}
|
||||||
return types[i].type;
|
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) {
|
for (int v = 0; v < ct->count(); ++v) {
|
||||||
const QCustomTypeInfo &customInfo = ct->at(v);
|
const QCustomTypeInfo &customInfo = ct->at(v);
|
||||||
if ((length == customInfo.typeName.size())
|
if ((length == customInfo.typeName.size())
|
||||||
&& !strcmp(typeName, customInfo.typeName.constData())) {
|
&& !memcmp(typeName, customInfo.typeName.constData(), length)) {
|
||||||
if (customInfo.alias >= 0)
|
if (customInfo.alias >= 0)
|
||||||
return customInfo.alias;
|
return customInfo.alias;
|
||||||
return v + QMetaType::User;
|
return v + QMetaType::User;
|
||||||
@ -1048,9 +1048,8 @@ bool QMetaType::isRegistered(int type)
|
|||||||
Implementation of QMetaType::type().
|
Implementation of QMetaType::type().
|
||||||
*/
|
*/
|
||||||
template <bool tryNormalizedType>
|
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)
|
if (!length)
|
||||||
return QMetaType::UnknownType;
|
return QMetaType::UnknownType;
|
||||||
int type = qMetaTypeStaticType(typeName, length);
|
int type = qMetaTypeStaticType(typeName, length);
|
||||||
@ -1080,7 +1079,7 @@ static inline int qMetaTypeTypeImpl(const char *typeName)
|
|||||||
*/
|
*/
|
||||||
int QMetaType::type(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)
|
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
|
#ifndef QT_NO_DATASTREAM
|
||||||
|
@ -472,6 +472,11 @@ public:
|
|||||||
static int registerTypedef(const char *typeName, int aliasId);
|
static int registerTypedef(const char *typeName, int aliasId);
|
||||||
static int registerNormalizedTypedef(const QT_PREPEND_NAMESPACE(QByteArray) &normalizedTypeName, int aliasId);
|
static int registerNormalizedTypedef(const QT_PREPEND_NAMESPACE(QByteArray) &normalizedTypeName, int aliasId);
|
||||||
static int type(const char *typeName);
|
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 const char *typeName(int type);
|
||||||
static int sizeOf(int type);
|
static int sizeOf(int type);
|
||||||
static TypeFlags typeFlags(int type);
|
static TypeFlags typeFlags(int type);
|
||||||
|
@ -79,6 +79,10 @@ private slots:
|
|||||||
void normalizedTypes();
|
void normalizedTypes();
|
||||||
void typeName_data();
|
void typeName_data();
|
||||||
void typeName();
|
void typeName();
|
||||||
|
void type_data();
|
||||||
|
void type();
|
||||||
|
void type_fromSubString_data();
|
||||||
|
void type_fromSubString();
|
||||||
void create_data();
|
void create_data();
|
||||||
void create();
|
void create();
|
||||||
void createCopy_data();
|
void createCopy_data();
|
||||||
@ -385,6 +389,61 @@ void tst_QMetaType::typeName()
|
|||||||
QCOMPARE(name.toLatin1(), QMetaObject::normalizedType(name.toLatin1().constData()));
|
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) \
|
#define FOR_EACH_PRIMITIVE_METATYPE(F) \
|
||||||
QT_FOR_EACH_STATIC_PRIMITIVE_TYPE(F) \
|
QT_FOR_EACH_STATIC_PRIMITIVE_TYPE(F) \
|
||||||
QT_FOR_EACH_STATIC_CORE_POINTER(F) \
|
QT_FOR_EACH_STATIC_CORE_POINTER(F) \
|
||||||
|
@ -45,6 +45,8 @@ public:
|
|||||||
private slots:
|
private slots:
|
||||||
void typeBuiltin_data();
|
void typeBuiltin_data();
|
||||||
void typeBuiltin();
|
void typeBuiltin();
|
||||||
|
void typeBuiltin_QByteArray_data();
|
||||||
|
void typeBuiltin_QByteArray();
|
||||||
void typeBuiltinNotNormalized_data();
|
void typeBuiltinNotNormalized_data();
|
||||||
void typeBuiltinNotNormalized();
|
void typeBuiltinNotNormalized();
|
||||||
void typeCustom();
|
void typeCustom();
|
||||||
@ -94,6 +96,7 @@ void tst_QMetaType::typeBuiltin_data()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// QMetaType::type(const char *)
|
||||||
void tst_QMetaType::typeBuiltin()
|
void tst_QMetaType::typeBuiltin()
|
||||||
{
|
{
|
||||||
QFETCH(QByteArray, typeName);
|
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()
|
void tst_QMetaType::typeBuiltinNotNormalized_data()
|
||||||
{
|
{
|
||||||
QTest::addColumn<QByteArray>("typeName");
|
QTest::addColumn<QByteArray>("typeName");
|
||||||
|
Loading…
x
Reference in New Issue
Block a user