summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMarc Mutz <marc.mutz@qt.io>2023-04-27 13:50:08 +0200
committerMarc Mutz <marc.mutz@qt.io>2023-04-28 17:37:30 +0000
commit968250ee1444d3eabf3d805053f46015bc7185c5 (patch)
tree422d9ecd404ad2fa30964d92798c50a758937942
parent5fc53f58e9b87a1d50780e0788990b3d41d124c9 (diff)
QMetaProperty: add write() overload taking rvalue QVariant
The existing overload unconditionally copies the QVariant, causing it to unconditional detach in most cases (when calling data() later). The rvalue overload need not preserve the source object, so doesn't need to copy. Implement the lvalue overload in terms of the rvalue one, but keep the sanity check in both to avoid copying the QVariant just to find that there's nothing to do. Following the copy, there were some references to the source object, but they can all be replaced by references to the target object instead, which hasn't been touched by then, yet. [ChangeLog][QtCore][QMetaProperty] Added write() overload taking an rvalue QVariant. Fixes: QTBUG-112762 Change-Id: I0a8a91aa32143f071ebc8dae8f1f64b07fad9764 Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
-rw-r--r--src/corelib/kernel/qmetaobject.cpp20
-rw-r--r--src/corelib/kernel/qmetaobject.h1
2 files changed, 17 insertions, 4 deletions
diff --git a/src/corelib/kernel/qmetaobject.cpp b/src/corelib/kernel/qmetaobject.cpp
index 6a775d13ac..5a75993ca3 100644
--- a/src/corelib/kernel/qmetaobject.cpp
+++ b/src/corelib/kernel/qmetaobject.cpp
@@ -3681,26 +3681,38 @@ QVariant QMetaProperty::read(const QObject *object) const
if this property is resettable, or setting a default-constructed object
otherwise.
+ \note This function internally makes a copy of \a value. Prefer to use the
+ rvalue overload when possible.
+
\sa read(), reset(), isWritable()
*/
bool QMetaProperty::write(QObject *object, const QVariant &value) const
{
if (!object || !isWritable())
return false;
+ return write(object, QVariant(value));
+}
- QVariant v = value;
+/*!
+ \overload
+ \since 6.6
+*/
+bool QMetaProperty::write(QObject *object, QVariant &&v) const
+{
+ if (!object || !isWritable())
+ return false;
QMetaType t(mobj->d.metaTypes[data.index(mobj)]);
if (t != QMetaType::fromType<QVariant>() && t != v.metaType()) {
if (isEnumType() && !t.metaObject() && v.metaType().id() == QMetaType::QString) {
// Assigning a string to a property of type Q_ENUMS (instead of Q_ENUM)
bool ok;
if (isFlagType())
- v = QVariant(menum.keysToValue(value.toByteArray(), &ok));
+ v = QVariant(menum.keysToValue(v.toByteArray(), &ok));
else
- v = QVariant(menum.keyToValue(value.toByteArray(), &ok));
+ v = QVariant(menum.keyToValue(v.toByteArray(), &ok));
if (!ok)
return false;
- } else if (!value.isValid()) {
+ } else if (!v.isValid()) {
if (isResettable())
return reset(object);
v = QVariant(t, nullptr);
diff --git a/src/corelib/kernel/qmetaobject.h b/src/corelib/kernel/qmetaobject.h
index b27a8636eb..d9c0d78831 100644
--- a/src/corelib/kernel/qmetaobject.h
+++ b/src/corelib/kernel/qmetaobject.h
@@ -363,6 +363,7 @@ public:
QVariant read(const QObject *obj) const;
bool write(QObject *obj, const QVariant &value) const;
+ bool write(QObject *obj, QVariant &&value) const;
bool reset(QObject *obj) const;
QUntypedBindable bindable(QObject *object) const;