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);
|
||||
}
|
||||
|
||||
#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"
|
||||
|
||||
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
|
||||
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
|
||||
|
||||
\note In Qt versions prior to 6.7, this function took \a name as
|
||||
\c{QString}, not \c{QAnyStringView}.
|
||||
|
||||
\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
|
||||
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
|
||||
|
||||
\note In Qt versions prior to 6.7, this function took \a name as
|
||||
\c{QString}, not \c{QAnyStringView}.
|
||||
|
||||
\sa findChild()
|
||||
*/
|
||||
|
||||
@ -2103,46 +2109,26 @@ void QObject::killTimer(int id)
|
||||
\sa QObject::findChildren()
|
||||
*/
|
||||
|
||||
static void qt_qFindChildren_with_name(const QObject *parent, const QString &name,
|
||||
const QMetaObject &mo, QList<void *> *list,
|
||||
Qt::FindChildOptions options)
|
||||
static bool matches_objectName_non_null(QObject *obj, QAnyStringView name)
|
||||
{
|
||||
Q_ASSERT(parent);
|
||||
Q_ASSERT(list);
|
||||
Q_ASSERT(!name.isNull());
|
||||
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);
|
||||
}
|
||||
if (auto ext = QObjectPrivate::get(obj)->extraData)
|
||||
return ext ->objectName.valueBypassingBindings() == name;
|
||||
return name.isEmpty();
|
||||
}
|
||||
|
||||
/*!
|
||||
\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)
|
||||
{
|
||||
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(list);
|
||||
for (QObject *obj : parent->children()) {
|
||||
if (mo.cast(obj))
|
||||
if (mo.cast(obj) && (name.isNull() || matches_objectName_non_null(obj, name)))
|
||||
list->append(obj);
|
||||
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
|
||||
*/
|
||||
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);
|
||||
for (QObject *obj : parent->children()) {
|
||||
if (mo.cast(obj) && (name.isNull() || obj->objectName() == name))
|
||||
return obj;
|
||||
if (mo.cast(obj) && (name.isNull() || matches_objectName_non_null(obj, name)))
|
||||
return obj;
|
||||
}
|
||||
if (options & Qt::FindChildrenRecursively) {
|
||||
for (QObject *child : parent->children()) {
|
||||
|
@ -43,13 +43,22 @@ struct QDynamicMetaObjectData;
|
||||
|
||||
typedef QList<QObject*> QObjectList;
|
||||
|
||||
#if QT_CORE_REMOVED_SINCE(6, 7)
|
||||
Q_CORE_EXPORT void qt_qFindChildren_helper(const QObject *parent, const QString &name,
|
||||
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,
|
||||
QList<void *> *list, Qt::FindChildOptions options);
|
||||
Q_CORE_EXPORT void qt_qFindChildren_helper(const QObject *parent, const QRegularExpression &re,
|
||||
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);
|
||||
#endif
|
||||
Q_CORE_EXPORT QObject *qt_qFindChild_helper(const QObject *parent, QAnyStringView name,
|
||||
const QMetaObject &mo, Qt::FindChildOptions options);
|
||||
|
||||
class Q_CORE_EXPORT QObjectData
|
||||
{
|
||||
@ -131,14 +140,14 @@ public:
|
||||
void killTimer(int id);
|
||||
|
||||
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;
|
||||
return static_cast<T>(qt_qFindChild_helper(this, aName, ObjType::staticMetaObject, options));
|
||||
}
|
||||
|
||||
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;
|
||||
QList<T> list;
|
||||
@ -150,11 +159,7 @@ public:
|
||||
template<typename T>
|
||||
QList<T> findChildren(Qt::FindChildOptions options = Qt::FindChildrenRecursively) const
|
||||
{
|
||||
typedef typename std::remove_cv<typename std::remove_pointer<T>::type>::type ObjType;
|
||||
QList<T> list;
|
||||
qt_qFindChildren_helper(this, ObjType::staticMetaObject,
|
||||
reinterpret_cast<QList<void *> *>(&list), options);
|
||||
return list;
|
||||
return findChildren<T>(QAnyStringView{}, options);
|
||||
}
|
||||
|
||||
#if QT_CONFIG(regularexpression)
|
||||
|
@ -39,6 +39,8 @@
|
||||
|
||||
#include <math.h>
|
||||
|
||||
using namespace Qt::StringLiterals;
|
||||
|
||||
class tst_QObject : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
@ -520,6 +522,10 @@ void tst_QObject::findChildren()
|
||||
QTimer t1(&o);
|
||||
QTimer t121(&o12);
|
||||
QTimer emptyname(&o);
|
||||
QObject oo;
|
||||
QObject o21(&oo);
|
||||
QObject o22(&oo);
|
||||
QObject o23(&oo);
|
||||
|
||||
Q_SET_OBJECT_NAME(o);
|
||||
Q_SET_OBJECT_NAME(o1);
|
||||
@ -530,6 +536,13 @@ void tst_QObject::findChildren()
|
||||
Q_SET_OBJECT_NAME(t1);
|
||||
Q_SET_OBJECT_NAME(t121);
|
||||
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;
|
||||
|
||||
@ -560,6 +573,27 @@ void tst_QObject::findChildren()
|
||||
op = o.findChild<QObject*>("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<QTimer*> tl;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user