summaryrefslogtreecommitdiffstats
path: root/src/corelib/serialization/qcborvalue.cpp
diff options
context:
space:
mode:
authorThiago Macieira <thiago.macieira@intel.com>2018-05-31 20:13:05 -0700
committerThiago Macieira <thiago.macieira@intel.com>2018-07-05 14:56:15 +0000
commit514972544a34aca0fd679b3a78521a0a1558d4e0 (patch)
tree8dbec4023d90d4022256071fadad39d67723c3c4 /src/corelib/serialization/qcborvalue.cpp
parentfddf09363e1bbc6f6549eaf28def7699b2d87341 (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.cpp36
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