From 4ecbe42ff44ace881ed4962744e9cd6c8fa65dab Mon Sep 17 00:00:00 2001 From: Ahmad Samir Date: Thu, 27 Jul 2023 21:46:34 +0300 Subject: [PATCH] QMetaObject: add indexOfEnumerator(QBAV) overload And remove the indexOfEnumerator(const char *) overload. Taking by view so that it works with string data that isn't necessarily null-terminated (e.g. a sliced() or chopped() view). QMetaObjectPrivate::indexOfEnumerator needs to be a member function because it usess a private QMetaEnum constructor (QMetaObjectPrivate is a friend of QMetaEnum). [ChangeLog][QtCore][QMetaObject] Added indexOfEnumerator(QByteArrayView) overload. And deprecated indexOfEnumerator(const char *) overload. Change-Id: Ie2f4f1a9af69373c19a5d7bd92499544e95e9289 Reviewed-by: Thiago Macieira --- src/corelib/compat/removed_api.cpp | 6 ++++++ src/corelib/kernel/qmetaobject.cpp | 34 +++++++++++++++--------------- src/corelib/kernel/qmetaobject_p.h | 4 ++++ src/corelib/kernel/qobjectdefs.h | 6 ++++++ 4 files changed, 33 insertions(+), 17 deletions(-) diff --git a/src/corelib/compat/removed_api.cpp b/src/corelib/compat/removed_api.cpp index 6f0bb2bf106..964597a2da7 100644 --- a/src/corelib/compat/removed_api.cpp +++ b/src/corelib/compat/removed_api.cpp @@ -775,6 +775,11 @@ QString QLocale::bcp47Name() const #include "qobjectdefs.h" +int QMetaObject::indexOfEnumerator(const char *name) const +{ + return indexOfEnumerator(QByteArrayView(name)); +} + bool QMetaObject::invokeMethodImpl(QObject *object, QtPrivate::QSlotObjectBase *slot, Qt::ConnectionType type, void *ret) { return invokeMethodImpl(object, slot, type, 1, &ret, nullptr, nullptr); @@ -835,6 +840,7 @@ QUrl QUrl::fromEncoded(const QByteArray &input, ParsingMode mode) return QUrl::fromEncoded(QByteArrayView(input), mode); } + // #include "qotherheader.h" // // implement removed functions from qotherheader.h // order sections alphabetically to reduce chances of merge conflicts diff --git a/src/corelib/kernel/qmetaobject.cpp b/src/corelib/kernel/qmetaobject.cpp index be7bd7c6c1e..e91385143e8 100644 --- a/src/corelib/kernel/qmetaobject.cpp +++ b/src/corelib/kernel/qmetaobject.cpp @@ -1058,30 +1058,30 @@ static const QMetaObject *QMetaObject_findMetaObject(const QMetaObject *self, QB -1. \sa enumerator(), enumeratorCount(), enumeratorOffset() + + \note Starting from Qt 6.7 this method takes a \c QByteArrayView, before + that it took a \c {const char *}. This change is source compatible i.e. + calling this method on a \c {const char *} should still work. */ -int QMetaObject::indexOfEnumerator(const char *name) const +int QMetaObject::indexOfEnumerator(QByteArrayView name) const { - const QMetaObject *m = this; - while (m) { - const QMetaObjectPrivate *d = priv(m->d.data); - for (int i = 0; i < d->enumeratorCount; ++i) { - const QMetaEnum e(m, i); - const char *prop = rawStringData(m, e.data.name()); - if (strcmp(name, prop) == 0) { - i += m->enumeratorOffset(); - return i; - } - } - m = m->d.superdata; + using W = QMetaObjectPrivate::Which; + for (auto which : { W::Name, W::Alias }) { + if (int index = QMetaObjectPrivate::indexOfEnumerator(this, name, which); index != -1) + return index; } - // Check alias names: - m = this; + return -1; +} + +int QMetaObjectPrivate::indexOfEnumerator(const QMetaObject *m, QByteArrayView name, Which which) +{ while (m) { const QMetaObjectPrivate *d = priv(m->d.data); for (int i = 0; i < d->enumeratorCount; ++i) { const QMetaEnum e(m, i); - const char *prop = rawStringData(m, e.data.alias()); - if (strcmp(name, prop) == 0) { + const quint32 id = which == Which::Name ? e.data.name() : e.data.alias(); + QLatin1StringView prop = stringDataView(m, id); + if (name == prop) { i += m->enumeratorOffset(); return i; } diff --git a/src/corelib/kernel/qmetaobject_p.h b/src/corelib/kernel/qmetaobject_p.h index 224c9d53541..c3b61212414 100644 --- a/src/corelib/kernel/qmetaobject_p.h +++ b/src/corelib/kernel/qmetaobject_p.h @@ -212,6 +212,10 @@ struct QMetaObjectPrivate int argc, const QArgumentType *types); static int indexOfConstructor(const QMetaObject *m, const QByteArray &name, int argc, const QArgumentType *types); + + enum class Which { Name, Alias }; + static int indexOfEnumerator(const QMetaObject *m, QByteArrayView name, Which which); + Q_CORE_EXPORT static QMetaMethod signal(const QMetaObject *m, int signal_index); static inline int signalOffset(const QMetaObject *m) { diff --git a/src/corelib/kernel/qobjectdefs.h b/src/corelib/kernel/qobjectdefs.h index 71e7f006970..1ff4ee80b67 100644 --- a/src/corelib/kernel/qobjectdefs.h +++ b/src/corelib/kernel/qobjectdefs.h @@ -11,6 +11,7 @@ #include #include +#include #include QT_BEGIN_NAMESPACE @@ -261,7 +262,12 @@ struct Q_CORE_EXPORT QMetaObject int indexOfMethod(const char *method) const; int indexOfSignal(const char *signal) const; int indexOfSlot(const char *slot) const; + +#if QT_CORE_REMOVED_SINCE(6, 7) int indexOfEnumerator(const char *name) const; +#endif + int indexOfEnumerator(QByteArrayView name) const; + int indexOfProperty(const char *name) const; int indexOfClassInfo(const char *name) const;