From 39cdf431f034121353e51768b4d1fec8b0dd35dc Mon Sep 17 00:00:00 2001 From: Marc Mutz Date: Fri, 28 Apr 2023 17:11:36 +0200 Subject: [PATCH] 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 Reviewed-by: Giuseppe D'Angelo Reviewed-by: Qt CI Bot --- src/corelib/compat/removed_api.cpp | 2 ++ src/corelib/kernel/qobject.cpp | 24 ++++++++++++++++++++---- src/corelib/kernel/qobject.h | 15 +++++++++++++++ 3 files changed, 37 insertions(+), 4 deletions(-) diff --git a/src/corelib/compat/removed_api.cpp b/src/corelib/compat/removed_api.cpp index 13a162135a1..dde262e7797 100644 --- a/src/corelib/compat/removed_api.cpp +++ b/src/corelib/compat/removed_api.cpp @@ -509,6 +509,8 @@ QByteArray QMessageAuthenticationCode::hash(const QByteArray &msg, const QByteAr qToByteArrayViewIgnoringNull(key), method); } +#include "qobject.h" // inlined API + #include "qrunnable.h" QRunnable *QRunnable::create(std::function functionToRun) diff --git a/src/corelib/kernel/qobject.cpp b/src/corelib/kernel/qobject.cpp index 668c1592dd0..2fc3d768981 100644 --- a/src/corelib/kernel/qobject.cpp +++ b/src/corelib/kernel/qobject.cpp @@ -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. 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() */ -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); + const auto &value =*lvalue; const QMetaObject *meta = metaObject(); if (!name || !meta) return false; @@ -4135,12 +4145,18 @@ bool QObject::setProperty(const char *name, const QVariant &value) } else { if (idx == -1) { 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 { if (value.userType() == d->extraData->propertyValues.at(idx).userType() && value == d->extraData->propertyValues.at(idx)) 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," " read-only or does not exist", metaObject()->className(), name); #endif - return p.write(this, value); + return rvalue ? p.write(this, std::move(*rvalue)) : p.write(this, *lvalue); } /*! diff --git a/src/corelib/kernel/qobject.h b/src/corelib/kernel/qobject.h index 852f5c7053a..3c102a0a851 100644 --- a/src/corelib/kernel/qobject.h +++ b/src/corelib/kernel/qobject.h @@ -292,7 +292,9 @@ public: void dumpObjectTree() const; void dumpObjectInfo() const; + QT_CORE_INLINE_SINCE(6, 6) bool setProperty(const char *name, const QVariant &value); + inline bool setProperty(const char *name, QVariant &&value); QVariant property(const char *name) const; QList dynamicPropertyNames() const; QBindingStorage *bindingStorage() { return &d_ptr->bindingStorage; } @@ -345,6 +347,8 @@ protected: private: void doSetObjectName(const QString &name); + bool doSetProperty(const char *name, const QVariant *lvalue, QVariant *rvalue); + Q_DISABLE_COPY(QObject) 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 { 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 inline T qobject_cast(QObject *object) {