diff options
author | Marc Mutz <marc.mutz@qt.io> | 2023-04-27 13:50:08 +0200 |
---|---|---|
committer | Marc Mutz <marc.mutz@qt.io> | 2023-04-28 17:37:30 +0000 |
commit | 968250ee1444d3eabf3d805053f46015bc7185c5 (patch) | |
tree | 422d9ecd404ad2fa30964d92798c50a758937942 | |
parent | 5fc53f58e9b87a1d50780e0788990b3d41d124c9 (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.cpp | 20 | ||||
-rw-r--r-- | src/corelib/kernel/qmetaobject.h | 1 |
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; |