QArgumentType: store a QMetaType instead of an id

This would avoid an indirection through the QMetaType constructor. But
I'm also making it so effectively we either have valid QMetaTypes or we
don't. If it can be looked up in the constructor, then string
comparisons aren't necessary at all.

Change-Id: I9a3b2a1a781c27c7271afffd3e5acbca06632476
Reviewed-by: Ulf Hermann <ulf.hermann@qt.io>
This commit is contained in:
Thiago Macieira 2024-08-27 10:11:06 -07:00
parent da4a6cf78f
commit 268006ee2f
3 changed files with 22 additions and 20 deletions

View File

@ -646,10 +646,11 @@ bool QMetaObjectPrivate::methodMatch(const QMetaObject *m, const QMetaMethod &me
int paramsIndex = data.parameters() + 1;
for (int i = 0; i < argc; ++i) {
uint typeInfo = m->d.data[paramsIndex + i];
if (int id = types[i].type()) {
if (id == QMetaType(ifaces[i]).id())
QMetaType mt = types[i].metaType();
if (mt.isValid()) {
if (mt == QMetaType(ifaces[i]))
continue;
if (id != typeFromTypeInfo(m, typeInfo))
if (mt.id() != typeFromTypeInfo(m, typeInfo))
return false;
} else {
if (types[i].name() == QMetaType(ifaces[i]).name())
@ -3994,7 +3995,7 @@ int QMetaProperty::notifySignalIndex() const
if (idx >= 0)
return idx + m->methodOffset();
// try 1-arg signal
QArgumentType argType(typeId());
QArgumentType argType(metaType());
idx = QMetaObjectPrivate::indexOfMethodRelative<MethodSignal>(&m, signalName, 1, &argType);
if (idx >= 0)
return idx + m->methodOffset();

View File

@ -41,21 +41,19 @@ Q_CORE_EXPORT int qMetaTypeTypeInternal(const char *);
class QArgumentType
{
public:
QArgumentType(int type)
: _type(type)
QArgumentType() = default;
QArgumentType(QMetaType metaType)
: _metaType(metaType)
{}
QArgumentType(const QByteArray &name)
: _type(qMetaTypeTypeInternal(name.constData())), _name(name)
: _metaType(QMetaType(qMetaTypeTypeInternal(name.constData()))), _name(name)
{}
QArgumentType()
: _type(0)
{}
int type() const
{ return _type; }
QByteArray name() const
QMetaType metaType() const noexcept
{ return _metaType; }
QByteArrayView name() const noexcept
{
if (_type && _name.isEmpty())
const_cast<QArgumentType *>(this)->_name = QMetaType(_type).name();
if (_name.isEmpty())
return metaType().name();
return _name;
}
@ -63,14 +61,14 @@ private:
friend bool comparesEqual(const QArgumentType &lhs,
const QArgumentType &rhs)
{
if (lhs._type && rhs._type)
return lhs._type == rhs._type;
if (lhs.metaType().isValid() && rhs.metaType().isValid())
return lhs.metaType() == rhs.metaType();
else
return lhs.name() == rhs.name();
}
Q_DECLARE_EQUALITY_COMPARABLE_NON_NOEXCEPT(QArgumentType)
int _type;
QMetaType _metaType;
QByteArray _name;
};
Q_DECLARE_TYPEINFO(QArgumentType, Q_RELOCATABLE_TYPE);

View File

@ -101,13 +101,14 @@ static int *queuedConnectionTypes(const QMetaMethod &method)
return typeIds;
}
// ### Future work: replace with an array of QMetaType or QtPrivate::QMetaTypeInterface *
static int *queuedConnectionTypes(const QArgumentType *argumentTypes, int argc)
{
auto types = std::make_unique<int[]>(argc + 1);
for (int i = 0; i < argc; ++i) {
const QArgumentType &type = argumentTypes[i];
if (type.type())
types[i] = type.type();
if (type.metaType().isValid())
types[i] = type.metaType().id();
else if (type.name().endsWith('*'))
types[i] = QMetaType::VoidStar;
else
@ -3059,6 +3060,8 @@ QMetaObject::Connection QObject::connect(const QObject *sender, const char *sign
return QMetaObject::Connection(nullptr);
}
// ### Future work: attempt get the metatypes from the meta object first
// because it's possible they're all registered.
int *types = nullptr;
if ((type == Qt::QueuedConnection)
&& !(types = queuedConnectionTypes(signalTypes.constData(), signalTypes.size()))) {