QCborValueRef: merge the operator[] into a template
Change-Id: I5e52dc5b093c43a3b678fffd16b6e94ad9d3f39b Reviewed-by: Edward Welbourne <edward.welbourne@qt.io>
This commit is contained in:
parent
832fcbf37f
commit
afe2f80c6a
@ -275,6 +275,7 @@ public:
|
|||||||
private:
|
private:
|
||||||
void detach(qsizetype reserve = 0);
|
void detach(qsizetype reserve = 0);
|
||||||
|
|
||||||
|
friend QCborContainerPrivate;
|
||||||
friend QCborValue;
|
friend QCborValue;
|
||||||
friend QCborValueRef;
|
friend QCborValueRef;
|
||||||
friend class QJsonPrivate::Variant;
|
friend class QJsonPrivate::Variant;
|
||||||
|
@ -766,6 +766,16 @@ QT_BEGIN_NAMESPACE
|
|||||||
|
|
||||||
using namespace QtCbor;
|
using namespace QtCbor;
|
||||||
|
|
||||||
|
static QCborContainerPrivate *assignContainer(QCborContainerPrivate *&d, QCborContainerPrivate *x)
|
||||||
|
{
|
||||||
|
if (d == x)
|
||||||
|
return d;
|
||||||
|
if (d)
|
||||||
|
d->deref();
|
||||||
|
x->ref.ref();
|
||||||
|
return d = x;
|
||||||
|
}
|
||||||
|
|
||||||
static QCborValue::Type convertToExtendedType(QCborContainerPrivate *d)
|
static QCborValue::Type convertToExtendedType(QCborContainerPrivate *d)
|
||||||
{
|
{
|
||||||
qint64 tag = d->elements.at(0).value;
|
qint64 tag = d->elements.at(0).value;
|
||||||
@ -2242,22 +2252,6 @@ static Q_DECL_COLD_FUNCTION QCborMap arrayAsMap(const QCborArray &array)
|
|||||||
return map;
|
return map;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*!
|
|
||||||
\internal
|
|
||||||
*/
|
|
||||||
[[maybe_unused]]
|
|
||||||
static QCborContainerPrivate *maybeDetach(QCborContainerPrivate *container, qsizetype size)
|
|
||||||
{
|
|
||||||
auto replace = QCborContainerPrivate::detach(container, size);
|
|
||||||
Q_ASSERT(replace);
|
|
||||||
if (replace != container) {
|
|
||||||
if (container)
|
|
||||||
container->deref();
|
|
||||||
replace->ref.ref();
|
|
||||||
}
|
|
||||||
return replace;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
\internal
|
\internal
|
||||||
*/
|
*/
|
||||||
@ -2287,12 +2281,32 @@ QCborContainerPrivate::findOrAddMapKey(QCborValue &self, KeyType key)
|
|||||||
self = QCborValue(QCborValue::Map);
|
self = QCborValue(QCborValue::Map);
|
||||||
|
|
||||||
QCborValueRef result = findOrAddMapKey<KeyType>(self.container, key);
|
QCborValueRef result = findOrAddMapKey<KeyType>(self.container, key);
|
||||||
if (result.d != self.container) {
|
assignContainer(self.container, result.d);
|
||||||
if (self.container)
|
return result;
|
||||||
self.container->deref();
|
}
|
||||||
self.container = result.d;
|
|
||||||
self.container->ref.ref();
|
template<typename KeyType> QCborValueRef
|
||||||
|
QCborContainerPrivate::findOrAddMapKey(QCborValueRef self, KeyType key)
|
||||||
|
{
|
||||||
|
auto &e = self.d->elements[self.i];
|
||||||
|
|
||||||
|
// we need a map, so convert if necessary
|
||||||
|
if (e.flags & QtCbor::Element::IsContainer) {
|
||||||
|
if (e.type == QCborValue::Array) {
|
||||||
|
QCborValue repack = QCborValue(arrayAsMap(QCborArray(*e.container)));
|
||||||
|
qSwap(e.container, repack.container);
|
||||||
|
} else if (e.type != QCborValue::Map) {
|
||||||
|
e.container->deref();
|
||||||
|
e.container = nullptr;
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
e.container = nullptr;
|
||||||
|
}
|
||||||
|
e.flags = QtCbor::Element::IsContainer;
|
||||||
|
e.type = QCborValue::Map;
|
||||||
|
|
||||||
|
QCborValueRef result = findOrAddMapKey<KeyType>(e.container, key);
|
||||||
|
assignContainer(e.container, result.d);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2733,48 +2747,7 @@ const QCborValue QCborValueRef::operator[](qint64 key) const
|
|||||||
*/
|
*/
|
||||||
QCborValueRef QCborValueRef::operator[](const QString &key)
|
QCborValueRef QCborValueRef::operator[](const QString &key)
|
||||||
{
|
{
|
||||||
auto &e = d->elements[i];
|
return QCborContainerPrivate::findOrAddMapKey(*this, qToStringViewIgnoringNull(key));
|
||||||
qsizetype size = 0;
|
|
||||||
if (e.flags & QtCbor::Element::IsContainer) {
|
|
||||||
if (e.container) {
|
|
||||||
if (e.type == QCborValue::Array) {
|
|
||||||
QCborValue repack = QCborValue(arrayAsMap(QCborArray(*e.container)));
|
|
||||||
qSwap(e.container, repack.container);
|
|
||||||
} else if (e.type != QCborValue::Map) {
|
|
||||||
e.container->deref();
|
|
||||||
e.container = nullptr;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
e.type = QCborValue::Map;
|
|
||||||
if (e.container)
|
|
||||||
size = e.container->elements.size();
|
|
||||||
} else {
|
|
||||||
// Stomp any prior e.value, replace with a map (that we'll grow)
|
|
||||||
e.container = nullptr;
|
|
||||||
e.type = QCborValue::Map;
|
|
||||||
e.flags = QtCbor::Element::IsContainer;
|
|
||||||
}
|
|
||||||
|
|
||||||
qsizetype index = size + 1;
|
|
||||||
bool found = false;
|
|
||||||
if (e.container) {
|
|
||||||
QCborMap proxy(*e.container);
|
|
||||||
auto it = proxy.constFind(key);
|
|
||||||
if (it < proxy.constEnd()) {
|
|
||||||
found = true;
|
|
||||||
index = it.item.i;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
e.container = maybeDetach(e.container, size + (found ? 0 : 2));
|
|
||||||
Q_ASSERT(e.container);
|
|
||||||
if (!found) {
|
|
||||||
e.container->append(key);
|
|
||||||
e.container->append(QCborValue());
|
|
||||||
}
|
|
||||||
Q_ASSERT(index & 1 && !(e.container->elements.size() & 1));
|
|
||||||
Q_ASSERT(index < e.container->elements.size());
|
|
||||||
return { e.container, index };
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
@ -2794,48 +2767,7 @@ QCborValueRef QCborValueRef::operator[](const QString &key)
|
|||||||
*/
|
*/
|
||||||
QCborValueRef QCborValueRef::operator[](QLatin1String key)
|
QCborValueRef QCborValueRef::operator[](QLatin1String key)
|
||||||
{
|
{
|
||||||
auto &e = d->elements[i];
|
return QCborContainerPrivate::findOrAddMapKey(*this, key);
|
||||||
qsizetype size = 0;
|
|
||||||
if (e.flags & QtCbor::Element::IsContainer) {
|
|
||||||
if (e.container) {
|
|
||||||
if (e.type == QCborValue::Array) {
|
|
||||||
QCborValue repack = QCborValue(arrayAsMap(QCborArray(*e.container)));
|
|
||||||
qSwap(e.container, repack.container);
|
|
||||||
} else if (e.type != QCborValue::Map) {
|
|
||||||
e.container->deref();
|
|
||||||
e.container = nullptr;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
e.type = QCborValue::Map;
|
|
||||||
if (e.container)
|
|
||||||
size = e.container->elements.size();
|
|
||||||
} else {
|
|
||||||
// Stomp any prior e.value, replace with a map (that we'll grow)
|
|
||||||
e.container = nullptr;
|
|
||||||
e.type = QCborValue::Map;
|
|
||||||
e.flags = QtCbor::Element::IsContainer;
|
|
||||||
}
|
|
||||||
|
|
||||||
qsizetype index = size + 1;
|
|
||||||
bool found = false;
|
|
||||||
if (e.container) {
|
|
||||||
QCborMap proxy(*e.container);
|
|
||||||
auto it = proxy.constFind(key);
|
|
||||||
if (it < proxy.constEnd()) {
|
|
||||||
found = true;
|
|
||||||
index = it.item.i;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
e.container = maybeDetach(e.container, size + (found ? 0 : 2));
|
|
||||||
Q_ASSERT(e.container);
|
|
||||||
if (!found) {
|
|
||||||
e.container->append(key);
|
|
||||||
e.container->append(QCborValue());
|
|
||||||
}
|
|
||||||
Q_ASSERT(index & 1 && !(e.container->elements.size() & 1));
|
|
||||||
Q_ASSERT(index < e.container->elements.size());
|
|
||||||
return { e.container, index };
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
@ -2862,48 +2794,7 @@ QCborValueRef QCborValueRef::operator[](qint64 key)
|
|||||||
e.flags |= QtCbor::Element::IsContainer;
|
e.flags |= QtCbor::Element::IsContainer;
|
||||||
return { e.container, qsizetype(key) };
|
return { e.container, qsizetype(key) };
|
||||||
}
|
}
|
||||||
qsizetype size = 0;
|
return QCborContainerPrivate::findOrAddMapKey(*this, key);
|
||||||
if (e.flags & QtCbor::Element::IsContainer) {
|
|
||||||
if (e.container) {
|
|
||||||
if (e.type == QCborValue::Array) {
|
|
||||||
QCborValue repack = QCborValue(arrayAsMap(QCborArray(*e.container)));
|
|
||||||
qSwap(e.container, repack.container);
|
|
||||||
} else if (e.type != QCborValue::Map) {
|
|
||||||
e.container->deref();
|
|
||||||
e.container = nullptr;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
e.type = QCborValue::Map;
|
|
||||||
if (e.container)
|
|
||||||
size = e.container->elements.size();
|
|
||||||
} else {
|
|
||||||
// Stomp any prior e.value, replace with a map (that we'll grow)
|
|
||||||
e.container = nullptr;
|
|
||||||
e.type = QCborValue::Map;
|
|
||||||
e.flags = QtCbor::Element::IsContainer;
|
|
||||||
}
|
|
||||||
Q_ASSERT(!(size & 1));
|
|
||||||
|
|
||||||
qsizetype index = size + 1;
|
|
||||||
bool found = false;
|
|
||||||
if (e.container) {
|
|
||||||
QCborMap proxy(*e.container);
|
|
||||||
auto it = proxy.constFind(key);
|
|
||||||
if (it < proxy.constEnd()) {
|
|
||||||
found = true;
|
|
||||||
index = it.item.i;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
e.container = maybeDetach(e.container, size + (found ? 0 : 2));
|
|
||||||
Q_ASSERT(e.container);
|
|
||||||
if (!found) {
|
|
||||||
e.container->append(key);
|
|
||||||
e.container->append(QCborValue());
|
|
||||||
}
|
|
||||||
Q_ASSERT(index & 1 && !(e.container->elements.size() & 1));
|
|
||||||
Q_ASSERT(index < e.container->elements.size());
|
|
||||||
return { e.container, index };
|
|
||||||
}
|
}
|
||||||
#endif // < Qt 7
|
#endif // < Qt 7
|
||||||
|
|
||||||
|
@ -473,6 +473,7 @@ public:
|
|||||||
}
|
}
|
||||||
template <typename KeyType> static QCborValueRef findOrAddMapKey(QCborMap &map, KeyType key);
|
template <typename KeyType> static QCborValueRef findOrAddMapKey(QCborMap &map, KeyType key);
|
||||||
template <typename KeyType> static QCborValueRef findOrAddMapKey(QCborValue &self, KeyType key);
|
template <typename KeyType> static QCborValueRef findOrAddMapKey(QCborValue &self, KeyType key);
|
||||||
|
template <typename KeyType> static QCborValueRef findOrAddMapKey(QCborValueRef self, KeyType key);
|
||||||
|
|
||||||
#if QT_CONFIG(cborstreamreader)
|
#if QT_CONFIG(cborstreamreader)
|
||||||
void decodeValueFromCbor(QCborStreamReader &reader, int remainingStackDepth);
|
void decodeValueFromCbor(QCborStreamReader &reader, int remainingStackDepth);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user