QObject: add setProperty() overload taking rvalue QVariant

Instead of duplicating the long-ish implementation, simply pass the
variant as pointers to const and mutable, and implement a runtime
version of std::forward.

[ChangeLog][QtCore][QObject] Added setProperty() overload taking an
rvalue QVariant.

Fixes: QTBUG-113281
Task-number: QTBUG-112762
Change-Id: Ifdc8f626ad5db138073474c3bd95ec7308c4396b
Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
Reviewed-by: Giuseppe D'Angelo <giuseppe.dangelo@kdab.com>
Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org>
This commit is contained in:
Marc Mutz 2023-04-28 17:11:36 +02:00
parent b8b34544d0
commit 39cdf431f0
3 changed files with 37 additions and 4 deletions

View File

@ -509,6 +509,8 @@ QByteArray QMessageAuthenticationCode::hash(const QByteArray &msg, const QByteAr
qToByteArrayViewIgnoringNull(key), method); qToByteArrayViewIgnoringNull(key), method);
} }
#include "qobject.h" // inlined API
#include "qrunnable.h" #include "qrunnable.h"
QRunnable *QRunnable::create(std::function<void()> functionToRun) QRunnable *QRunnable::create(std::function<void()> functionToRun)

View File

@ -4094,6 +4094,8 @@ int QObjectPrivate::signalIndex(const char *signalName,
*****************************************************************************/ *****************************************************************************/
/*! /*!
\fn bool QObject::setProperty(const char *name, const QVariant &value)
Sets the value of the object's \a name property to \a value. Sets the value of the object's \a name property to \a value.
If the property is defined in the class using Q_PROPERTY then If the property is defined in the class using Q_PROPERTY then
@ -4114,9 +4116,17 @@ int QObjectPrivate::signalIndex(const char *signalName,
\sa property(), metaObject(), dynamicPropertyNames(), QMetaProperty::write() \sa property(), metaObject(), dynamicPropertyNames(), QMetaProperty::write()
*/ */
bool QObject::setProperty(const char *name, const QVariant &value)
/*!
\fn bool QObject::setProperty(const char *name, QVariant &&value)
\since 6.6
\overload setProperty
*/
bool QObject::doSetProperty(const char *name, const QVariant *lvalue, QVariant *rvalue)
{ {
Q_D(QObject); Q_D(QObject);
const auto &value =*lvalue;
const QMetaObject *meta = metaObject(); const QMetaObject *meta = metaObject();
if (!name || !meta) if (!name || !meta)
return false; return false;
@ -4135,12 +4145,18 @@ bool QObject::setProperty(const char *name, const QVariant &value)
} else { } else {
if (idx == -1) { if (idx == -1) {
d->extraData->propertyNames.append(name); d->extraData->propertyNames.append(name);
d->extraData->propertyValues.append(value); if (rvalue)
d->extraData->propertyValues.append(std::move(*rvalue));
else
d->extraData->propertyValues.append(*lvalue);
} else { } else {
if (value.userType() == d->extraData->propertyValues.at(idx).userType() if (value.userType() == d->extraData->propertyValues.at(idx).userType()
&& value == d->extraData->propertyValues.at(idx)) && value == d->extraData->propertyValues.at(idx))
return false; return false;
d->extraData->propertyValues[idx] = value; if (rvalue)
d->extraData->propertyValues[idx] = std::move(*rvalue);
else
d->extraData->propertyValues[idx] = *lvalue;
} }
} }
@ -4155,7 +4171,7 @@ bool QObject::setProperty(const char *name, const QVariant &value)
qWarning("%s::setProperty: Property \"%s\" invalid," qWarning("%s::setProperty: Property \"%s\" invalid,"
" read-only or does not exist", metaObject()->className(), name); " read-only or does not exist", metaObject()->className(), name);
#endif #endif
return p.write(this, value); return rvalue ? p.write(this, std::move(*rvalue)) : p.write(this, *lvalue);
} }
/*! /*!

View File

@ -292,7 +292,9 @@ public:
void dumpObjectTree() const; void dumpObjectTree() const;
void dumpObjectInfo() const; void dumpObjectInfo() const;
QT_CORE_INLINE_SINCE(6, 6)
bool setProperty(const char *name, const QVariant &value); bool setProperty(const char *name, const QVariant &value);
inline bool setProperty(const char *name, QVariant &&value);
QVariant property(const char *name) const; QVariant property(const char *name) const;
QList<QByteArray> dynamicPropertyNames() const; QList<QByteArray> dynamicPropertyNames() const;
QBindingStorage *bindingStorage() { return &d_ptr->bindingStorage; } QBindingStorage *bindingStorage() { return &d_ptr->bindingStorage; }
@ -345,6 +347,8 @@ protected:
private: private:
void doSetObjectName(const QString &name); void doSetObjectName(const QString &name);
bool doSetProperty(const char *name, const QVariant *lvalue, QVariant *rvalue);
Q_DISABLE_COPY(QObject) Q_DISABLE_COPY(QObject)
Q_PRIVATE_SLOT(d_func(), void _q_reregisterTimers(void *)) Q_PRIVATE_SLOT(d_func(), void _q_reregisterTimers(void *))
@ -363,6 +367,17 @@ inline QMetaObject::Connection QObject::connect(const QObject *asender, const ch
const char *amember, Qt::ConnectionType atype) const const char *amember, Qt::ConnectionType atype) const
{ return connect(asender, asignal, this, amember, atype); } { return connect(asender, asignal, this, amember, atype); }
#if QT_CORE_INLINE_IMPL_SINCE(6, 6)
bool QObject::setProperty(const char *name, const QVariant &value)
{
return doSetProperty(name, &value, nullptr);
}
#endif // inline since 6.6
bool QObject::setProperty(const char *name, QVariant &&value)
{
return doSetProperty(name, &value, &value);
}
template <class T> template <class T>
inline T qobject_cast(QObject *object) inline T qobject_cast(QObject *object)
{ {