QObject: port findChild/ren() to QAnyStringView
Change the object's name type in QObject::findChild/ren() to QAnyStringView, because they are only used for comparison against objectName property. qt_qFindChild{,ren}_helper() functions taking an objectname as QString have to stay in the ABI as they were exported in inline methods before Qt 6.7. Unlike QString, constructing a null QAnyStringView doesn't involve any code-size overhead. So, get rid of the split in qt_qFindChildren_helper that was introduced for QString. Remove unneeded qt_qFindChildren_with_name helper function and qt_qFindChildren_helper overload without a name. findChildren(options) method used to call qt_qFindChildren_helper overload. Instead, call findChildren overload with name argument and pass QAnyStringView{} as the object name. [ChangeLog][QtCore][QObject] Ported QObject::findChild/ren() and their helper functions to QAnyStringView. Task-number: QTBUG-103986 Change-Id: I68bda0e581f984ae48b7581ad86cc1b95008c1b0 Reviewed-by: Ivan Solovev <ivan.solovev@qt.io>
This commit is contained in:
parent
bdd41f491c
commit
e608bc0192
@ -773,6 +773,20 @@ QString QLocale::bcp47Name() const
|
|||||||
return bcp47Name(TagSeparator::Dash);
|
return bcp47Name(TagSeparator::Dash);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#include "qobject.h"
|
||||||
|
|
||||||
|
void qt_qFindChildren_helper(const QObject *parent, const QString &name, const QMetaObject &mo,
|
||||||
|
QList<void*> *list, Qt::FindChildOptions options)
|
||||||
|
{
|
||||||
|
qt_qFindChildren_helper(parent, QAnyStringView{name}, mo, list, options);
|
||||||
|
}
|
||||||
|
|
||||||
|
QObject *qt_qFindChild_helper(const QObject *parent, const QString &name, const QMetaObject &mo,
|
||||||
|
Qt::FindChildOptions options)
|
||||||
|
{
|
||||||
|
return qt_qFindChild_helper(parent, QAnyStringView{name}, mo, options);
|
||||||
|
}
|
||||||
|
|
||||||
#include "qobjectdefs.h"
|
#include "qobjectdefs.h"
|
||||||
|
|
||||||
int QMetaObject::indexOfEnumerator(const char *name) const
|
int QMetaObject::indexOfEnumerator(const char *name) const
|
||||||
|
@ -1982,7 +1982,7 @@ void QObject::killTimer(int id)
|
|||||||
|
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
\fn template<typename T> T *QObject::findChild(const QString &name, Qt::FindChildOptions options) const
|
\fn template<typename T> T *QObject::findChild(QAnyStringView name, Qt::FindChildOptions options) const
|
||||||
|
|
||||||
Returns the child of this object that can be cast into type T and
|
Returns the child of this object that can be cast into type T and
|
||||||
that is called \a name, or \nullptr if there is no such object.
|
that is called \a name, or \nullptr if there is no such object.
|
||||||
@ -2016,11 +2016,14 @@ void QObject::killTimer(int id)
|
|||||||
|
|
||||||
\snippet code/src_corelib_kernel_qobject.cpp 42
|
\snippet code/src_corelib_kernel_qobject.cpp 42
|
||||||
|
|
||||||
|
\note In Qt versions prior to 6.7, this function took \a name as
|
||||||
|
\c{QString}, not \c{QAnyStringView}.
|
||||||
|
|
||||||
\sa findChildren()
|
\sa findChildren()
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
\fn template<typename T> QList<T> QObject::findChildren(const QString &name, Qt::FindChildOptions options) const
|
\fn template<typename T> QList<T> QObject::findChildren(QAnyStringView name, Qt::FindChildOptions options) const
|
||||||
|
|
||||||
Returns all children of this object with the given \a name that can be
|
Returns all children of this object with the given \a name that can be
|
||||||
cast to type T, or an empty list if there are no such objects.
|
cast to type T, or an empty list if there are no such objects.
|
||||||
@ -2042,6 +2045,9 @@ void QObject::killTimer(int id)
|
|||||||
|
|
||||||
\snippet code/src_corelib_kernel_qobject.cpp 43
|
\snippet code/src_corelib_kernel_qobject.cpp 43
|
||||||
|
|
||||||
|
\note In Qt versions prior to 6.7, this function took \a name as
|
||||||
|
\c{QString}, not \c{QAnyStringView}.
|
||||||
|
|
||||||
\sa findChild()
|
\sa findChild()
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@ -2103,46 +2109,26 @@ void QObject::killTimer(int id)
|
|||||||
\sa QObject::findChildren()
|
\sa QObject::findChildren()
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static void qt_qFindChildren_with_name(const QObject *parent, const QString &name,
|
static bool matches_objectName_non_null(QObject *obj, QAnyStringView name)
|
||||||
const QMetaObject &mo, QList<void *> *list,
|
|
||||||
Qt::FindChildOptions options)
|
|
||||||
{
|
{
|
||||||
Q_ASSERT(parent);
|
if (auto ext = QObjectPrivate::get(obj)->extraData)
|
||||||
Q_ASSERT(list);
|
return ext ->objectName.valueBypassingBindings() == name;
|
||||||
Q_ASSERT(!name.isNull());
|
return name.isEmpty();
|
||||||
for (QObject *obj : parent->children()) {
|
|
||||||
if (mo.cast(obj) && obj->objectName() == name)
|
|
||||||
list->append(obj);
|
|
||||||
if (options & Qt::FindChildrenRecursively)
|
|
||||||
qt_qFindChildren_with_name(obj, name, mo, list, options);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
\internal
|
\internal
|
||||||
*/
|
*/
|
||||||
void qt_qFindChildren_helper(const QObject *parent, const QString &name,
|
void qt_qFindChildren_helper(const QObject *parent, QAnyStringView name,
|
||||||
const QMetaObject &mo, QList<void*> *list, Qt::FindChildOptions options)
|
const QMetaObject &mo, QList<void*> *list, Qt::FindChildOptions options)
|
||||||
{
|
|
||||||
if (name.isNull())
|
|
||||||
return qt_qFindChildren_helper(parent, mo, list, options);
|
|
||||||
else
|
|
||||||
return qt_qFindChildren_with_name(parent, name, mo, list, options);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*!
|
|
||||||
\internal
|
|
||||||
*/
|
|
||||||
void qt_qFindChildren_helper(const QObject *parent, const QMetaObject &mo,
|
|
||||||
QList<void*> *list, Qt::FindChildOptions options)
|
|
||||||
{
|
{
|
||||||
Q_ASSERT(parent);
|
Q_ASSERT(parent);
|
||||||
Q_ASSERT(list);
|
Q_ASSERT(list);
|
||||||
for (QObject *obj : parent->children()) {
|
for (QObject *obj : parent->children()) {
|
||||||
if (mo.cast(obj))
|
if (mo.cast(obj) && (name.isNull() || matches_objectName_non_null(obj, name)))
|
||||||
list->append(obj);
|
list->append(obj);
|
||||||
if (options & Qt::FindChildrenRecursively)
|
if (options & Qt::FindChildrenRecursively)
|
||||||
qt_qFindChildren_helper(obj, mo, list, options);
|
qt_qFindChildren_helper(obj, name, mo, list, options);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2169,13 +2155,13 @@ void qt_qFindChildren_helper(const QObject *parent, const QRegularExpression &re
|
|||||||
|
|
||||||
/*!
|
/*!
|
||||||
\internal
|
\internal
|
||||||
*/
|
*/
|
||||||
QObject *qt_qFindChild_helper(const QObject *parent, const QString &name, const QMetaObject &mo, Qt::FindChildOptions options)
|
QObject *qt_qFindChild_helper(const QObject *parent, QAnyStringView name, const QMetaObject &mo, Qt::FindChildOptions options)
|
||||||
{
|
{
|
||||||
Q_ASSERT(parent);
|
Q_ASSERT(parent);
|
||||||
for (QObject *obj : parent->children()) {
|
for (QObject *obj : parent->children()) {
|
||||||
if (mo.cast(obj) && (name.isNull() || obj->objectName() == name))
|
if (mo.cast(obj) && (name.isNull() || matches_objectName_non_null(obj, name)))
|
||||||
return obj;
|
return obj;
|
||||||
}
|
}
|
||||||
if (options & Qt::FindChildrenRecursively) {
|
if (options & Qt::FindChildrenRecursively) {
|
||||||
for (QObject *child : parent->children()) {
|
for (QObject *child : parent->children()) {
|
||||||
|
@ -43,13 +43,22 @@ struct QDynamicMetaObjectData;
|
|||||||
|
|
||||||
typedef QList<QObject*> QObjectList;
|
typedef QList<QObject*> QObjectList;
|
||||||
|
|
||||||
|
#if QT_CORE_REMOVED_SINCE(6, 7)
|
||||||
Q_CORE_EXPORT void qt_qFindChildren_helper(const QObject *parent, const QString &name,
|
Q_CORE_EXPORT void qt_qFindChildren_helper(const QObject *parent, const QString &name,
|
||||||
const QMetaObject &mo, QList<void *> *list, Qt::FindChildOptions options);
|
const QMetaObject &mo, QList<void *> *list, Qt::FindChildOptions options);
|
||||||
|
#endif
|
||||||
|
Q_CORE_EXPORT void qt_qFindChildren_helper(const QObject *parent, QAnyStringView name,
|
||||||
|
const QMetaObject &mo, QList<void *> *list,
|
||||||
|
Qt::FindChildOptions options);
|
||||||
Q_CORE_EXPORT void qt_qFindChildren_helper(const QObject *parent, const QMetaObject &mo,
|
Q_CORE_EXPORT void qt_qFindChildren_helper(const QObject *parent, const QMetaObject &mo,
|
||||||
QList<void *> *list, Qt::FindChildOptions options);
|
QList<void *> *list, Qt::FindChildOptions options);
|
||||||
Q_CORE_EXPORT void qt_qFindChildren_helper(const QObject *parent, const QRegularExpression &re,
|
Q_CORE_EXPORT void qt_qFindChildren_helper(const QObject *parent, const QRegularExpression &re,
|
||||||
const QMetaObject &mo, QList<void *> *list, Qt::FindChildOptions options);
|
const QMetaObject &mo, QList<void *> *list, Qt::FindChildOptions options);
|
||||||
|
#if QT_CORE_REMOVED_SINCE(6, 7)
|
||||||
Q_CORE_EXPORT QObject *qt_qFindChild_helper(const QObject *parent, const QString &name, const QMetaObject &mo, Qt::FindChildOptions options);
|
Q_CORE_EXPORT QObject *qt_qFindChild_helper(const QObject *parent, const QString &name, const QMetaObject &mo, Qt::FindChildOptions options);
|
||||||
|
#endif
|
||||||
|
Q_CORE_EXPORT QObject *qt_qFindChild_helper(const QObject *parent, QAnyStringView name,
|
||||||
|
const QMetaObject &mo, Qt::FindChildOptions options);
|
||||||
|
|
||||||
class Q_CORE_EXPORT QObjectData
|
class Q_CORE_EXPORT QObjectData
|
||||||
{
|
{
|
||||||
@ -131,14 +140,14 @@ public:
|
|||||||
void killTimer(int id);
|
void killTimer(int id);
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
inline T findChild(const QString &aName = QString(), Qt::FindChildOptions options = Qt::FindChildrenRecursively) const
|
T findChild(QAnyStringView aName = {}, Qt::FindChildOptions options = Qt::FindChildrenRecursively) const
|
||||||
{
|
{
|
||||||
typedef typename std::remove_cv<typename std::remove_pointer<T>::type>::type ObjType;
|
typedef typename std::remove_cv<typename std::remove_pointer<T>::type>::type ObjType;
|
||||||
return static_cast<T>(qt_qFindChild_helper(this, aName, ObjType::staticMetaObject, options));
|
return static_cast<T>(qt_qFindChild_helper(this, aName, ObjType::staticMetaObject, options));
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
inline QList<T> findChildren(const QString &aName, Qt::FindChildOptions options = Qt::FindChildrenRecursively) const
|
QList<T> findChildren(QAnyStringView aName, Qt::FindChildOptions options = Qt::FindChildrenRecursively) const
|
||||||
{
|
{
|
||||||
typedef typename std::remove_cv<typename std::remove_pointer<T>::type>::type ObjType;
|
typedef typename std::remove_cv<typename std::remove_pointer<T>::type>::type ObjType;
|
||||||
QList<T> list;
|
QList<T> list;
|
||||||
@ -150,11 +159,7 @@ public:
|
|||||||
template<typename T>
|
template<typename T>
|
||||||
QList<T> findChildren(Qt::FindChildOptions options = Qt::FindChildrenRecursively) const
|
QList<T> findChildren(Qt::FindChildOptions options = Qt::FindChildrenRecursively) const
|
||||||
{
|
{
|
||||||
typedef typename std::remove_cv<typename std::remove_pointer<T>::type>::type ObjType;
|
return findChildren<T>(QAnyStringView{}, options);
|
||||||
QList<T> list;
|
|
||||||
qt_qFindChildren_helper(this, ObjType::staticMetaObject,
|
|
||||||
reinterpret_cast<QList<void *> *>(&list), options);
|
|
||||||
return list;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#if QT_CONFIG(regularexpression)
|
#if QT_CONFIG(regularexpression)
|
||||||
|
@ -39,6 +39,8 @@
|
|||||||
|
|
||||||
#include <math.h>
|
#include <math.h>
|
||||||
|
|
||||||
|
using namespace Qt::StringLiterals;
|
||||||
|
|
||||||
class tst_QObject : public QObject
|
class tst_QObject : public QObject
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
@ -520,6 +522,10 @@ void tst_QObject::findChildren()
|
|||||||
QTimer t1(&o);
|
QTimer t1(&o);
|
||||||
QTimer t121(&o12);
|
QTimer t121(&o12);
|
||||||
QTimer emptyname(&o);
|
QTimer emptyname(&o);
|
||||||
|
QObject oo;
|
||||||
|
QObject o21(&oo);
|
||||||
|
QObject o22(&oo);
|
||||||
|
QObject o23(&oo);
|
||||||
|
|
||||||
Q_SET_OBJECT_NAME(o);
|
Q_SET_OBJECT_NAME(o);
|
||||||
Q_SET_OBJECT_NAME(o1);
|
Q_SET_OBJECT_NAME(o1);
|
||||||
@ -530,6 +536,13 @@ void tst_QObject::findChildren()
|
|||||||
Q_SET_OBJECT_NAME(t1);
|
Q_SET_OBJECT_NAME(t1);
|
||||||
Q_SET_OBJECT_NAME(t121);
|
Q_SET_OBJECT_NAME(t121);
|
||||||
emptyname.setObjectName("");
|
emptyname.setObjectName("");
|
||||||
|
Q_SET_OBJECT_NAME(oo);
|
||||||
|
const QUtf8StringView utf8_name = u8"utf8 ⁎ obj";
|
||||||
|
o21.setObjectName(utf8_name);
|
||||||
|
const QStringView utf16_name = u"utf16 ⁎ obj";
|
||||||
|
o22.setObjectName(utf16_name);
|
||||||
|
constexpr QLatin1StringView L1_name("L1 ⁎ obj");
|
||||||
|
o23.setObjectName(L1_name);
|
||||||
|
|
||||||
QObject *op = nullptr;
|
QObject *op = nullptr;
|
||||||
|
|
||||||
@ -560,6 +573,27 @@ void tst_QObject::findChildren()
|
|||||||
op = o.findChild<QObject*>("o1");
|
op = o.findChild<QObject*>("o1");
|
||||||
QCOMPARE(op, &o1);
|
QCOMPARE(op, &o1);
|
||||||
|
|
||||||
|
op = oo.findChild<QObject*>(utf8_name);
|
||||||
|
QCOMPARE(op, &o21);
|
||||||
|
op = oo.findChild<QObject*>(utf8_name.chopped(1));
|
||||||
|
QCOMPARE(op, nullptr);
|
||||||
|
const QUtf8StringView utf8_name_with_trailing_data = u8"utf8 ⁎ obj_data";
|
||||||
|
op = oo.findChild<QObject*>(utf8_name_with_trailing_data.chopped(5));
|
||||||
|
QCOMPARE(op, &o21);
|
||||||
|
op = oo.findChild<QObject*>(utf16_name);
|
||||||
|
QCOMPARE(op, &o22);
|
||||||
|
op = oo.findChild<QObject*>(utf16_name.chopped(1));
|
||||||
|
QCOMPARE(op, nullptr);
|
||||||
|
const QStringView utf16_name_with_trailing_data = u"utf16 ⁎ obj_data";
|
||||||
|
op = oo.findChild<QObject*>(utf16_name_with_trailing_data.chopped(5));
|
||||||
|
QCOMPARE(op, &o22);
|
||||||
|
op = oo.findChild<QObject*>(L1_name);
|
||||||
|
QCOMPARE(op, &o23);
|
||||||
|
op = oo.findChild<QObject*>(L1_name.chopped(1));
|
||||||
|
QCOMPARE(op, nullptr);
|
||||||
|
op = oo.findChild<QObject*>((L1_name + "_data"_L1).chopped(5));
|
||||||
|
QCOMPARE(op, &o23);
|
||||||
|
|
||||||
QList<QObject*> l;
|
QList<QObject*> l;
|
||||||
QList<QTimer*> tl;
|
QList<QTimer*> tl;
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user