diff options
author | Thiago Macieira <thiago.macieira@intel.com> | 2018-05-31 20:13:05 -0700 |
---|---|---|
committer | Thiago Macieira <thiago.macieira@intel.com> | 2018-07-05 14:56:15 +0000 |
commit | 514972544a34aca0fd679b3a78521a0a1558d4e0 (patch) | |
tree | 8dbec4023d90d4022256071fadad39d67723c3c4 /src/corelib/serialization/qcborvalue.cpp | |
parent | fddf09363e1bbc6f6549eaf28def7699b2d87341 (diff) |
QCborArray & Map: implement move semantics
There isn't a lot of efficiency gain, since QCborValue was already
refcounted. This saves two atomic operations and an out-of-line call. In
the case of QCborValueRef (which includes QCborMap), because we reset
the container pointer in inline code, the call to QCborValue::dispose()
is also suppressed.
Change-Id: Icc2c231dc2c44abdb087fffd1533eaba7a9c70fa
Reviewed-by: Simon Hausmann <simon.hausmann@qt.io>
Diffstat (limited to 'src/corelib/serialization/qcborvalue.cpp')
-rw-r--r-- | src/corelib/serialization/qcborvalue.cpp | 36 |
1 files changed, 29 insertions, 7 deletions
diff --git a/src/corelib/serialization/qcborvalue.cpp b/src/corelib/serialization/qcborvalue.cpp index 0631e8d7a2..7409bed4e9 100644 --- a/src/corelib/serialization/qcborvalue.cpp +++ b/src/corelib/serialization/qcborvalue.cpp @@ -1053,7 +1053,12 @@ QCborContainerPrivate *QCborContainerPrivate::detach(QCborContainerPrivate *d, q return d; } -void QCborContainerPrivate::replaceAt_complex(Element &e, const QCborValue &value) +// Copies or moves \a value into element at position \a e. If \a disp is +// CopyContainer, then this function increases the reference count of the +// container, but otherwise leaves it unmodified. If \a disp is MoveContainer, +// then it transfers ownership (move semantics) and the caller must set +// value.container back to nullptr. +void QCborContainerPrivate::replaceAt_complex(Element &e, const QCborValue &value, ContainerDisposition disp) { if (value.n < 0) { // This QCborValue is an array, map, or tagged value (container points @@ -1062,14 +1067,18 @@ void QCborContainerPrivate::replaceAt_complex(Element &e, const QCborValue &valu // detect self-assignment if (Q_UNLIKELY(this == value.container)) { Q_ASSERT(ref.load() >= 2); + if (disp == MoveContainer) + ref.deref(); // not deref() because it can't drop to 0 QCborContainerPrivate *d = QCborContainerPrivate::clone(this); d->elements.detach(); + d->ref.store(1); e.container = d; } else { e.container = value.container; + if (disp == CopyContainer) + e.container->ref.ref(); } - e.container->ref.ref(); e.type = value.type(); e.flags = Element::IsContainer; } else { @@ -1079,6 +1088,9 @@ void QCborContainerPrivate::replaceAt_complex(Element &e, const QCborValue &valu // Copy string data, if any if (const ByteData *b = value.container->byteData(value.n)) e.value = addByteData(b->byte(), b->len); + + if (disp == MoveContainer) + value.container->deref(); } } @@ -1847,6 +1859,9 @@ QCborValue::QCborValue(QLatin1String s) } /*! + \fn QCborValue::QCborValue(const QCborArray &a) + \fn QCborValue::QCborValue(QCborArray &&a) + Creates a QCborValue with the array \a a. The array can later be retrieved using toArray(). @@ -1860,6 +1875,9 @@ QCborValue::QCborValue(const QCborArray &a) } /*! + \fn QCborValue::QCborValue(const QCborMap &m) + \fn QCborValue::QCborValue(QCborMap &&m) + Creates a QCborValue with the map \a m. The map can later be retrieved using toMap(). @@ -2526,16 +2544,20 @@ void QCborValueRef::toCbor(QCborStreamWriter &writer, QCborValue::EncodingOption concrete().toCbor(writer, opt); } -QCborValueRef &QCborValueRef::operator=(const QCborValue &other) +void QCborValueRef::assign(QCborValueRef that, const QCborValue &other) { - d->replaceAt(i, other); - return *this; + that.d->replaceAt(that.i, other); +} + +void QCborValueRef::assign(QCborValueRef that, QCborValue &&other) +{ + that.d->replaceAt(that.i, other, QCborContainerPrivate::MoveContainer); } -QCborValueRef &QCborValueRef::operator=(const QCborValueRef &other) +void QCborValueRef::assign(QCborValueRef that, const QCborValueRef other) { // ### optimize? - return *this = other.concrete(); + assign(that, other.concrete()); } QCborValue QCborValueRef::concrete(QCborValueRef self) Q_DECL_NOTHROW |