summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorLars Knoll <lars.knoll@nokia.com>2012-01-10 11:58:31 +0100
committerLars Knoll <lars.knoll@nokia.com>2012-01-11 14:58:09 +0100
commit2e20b0abf92b2ee81a4328ae5d1ae4aaff46e189 (patch)
treef1e50437c320730da89b358731ddd7635f38329e /src
parent1fca88779c35a9adc848e482be2ddaca5e54a3db (diff)
Added an iterator interface to QJsonObject
Added both iterator and const_iterator and the required typedefs and methods for STL compatibility. Change-Id: Icee9a4bea45ce5499882bc83b8b62c3431b8c976 Sanity-Review: Qt Sanity Bot <qt_sanity_bot@ovi.com> Reviewed-by: Denis Dzyubenko <denis.dzyubenko@nokia.com>
Diffstat (limited to 'src')
-rw-r--r--src/qjsonobject.cpp46
-rw-r--r--src/qjsonobject.h125
2 files changed, 162 insertions, 9 deletions
diff --git a/src/qjsonobject.cpp b/src/qjsonobject.cpp
index 613d382..8c09fbe 100644
--- a/src/qjsonobject.cpp
+++ b/src/qjsonobject.cpp
@@ -170,11 +170,11 @@ QJsonValueRef QJsonObject::operator [](const QString &key)
return QJsonValueRef(this, index);
}
-void QJsonObject::insert(const QString &key, const QJsonValue &value)
+QJsonObject::iterator QJsonObject::insert(const QString &key, const QJsonValue &value)
{
if (value.t == QJsonValue::Undefined) {
remove(key);
- return;
+ return end();
}
bool latinOrIntValue;
@@ -208,6 +208,8 @@ void QJsonObject::insert(const QString &key, const QJsonValue &value)
Private::copyString((char *)(e + 1), key, latinKey);
if (valueSize)
value.copyData((char *)e + valueOffset, latinOrIntValue);
+
+ return iterator(this, pos);
}
void QJsonObject::remove(const QString &key)
@@ -279,6 +281,39 @@ bool QJsonObject::operator!=(const QJsonObject &other) const
return !(*this == other);
}
+QJsonObject::iterator QJsonObject::erase(QJsonObject::iterator it)
+{
+ Q_ASSERT(d && d->ref.load() == 1);
+ if (it.o != this || it.i < 0 || it.i >= (int)o->length)
+ return iterator(this, o->length);
+
+ int index = it.i;
+
+ o->removeItems(index, 1);
+ ++d->compactionCounter;
+ if (d->compactionCounter > 32 && d->compactionCounter >= (int)o->length/2)
+ compact();
+
+ // iterator hasn't changed
+ return it;
+}
+
+QJsonObject::iterator QJsonObject::find(const QString &key)
+{
+ int index = o ? o->indexOf(key) : 0;
+ if (index < 0)
+ index = o->length;
+ return iterator(this, index);
+}
+
+QJsonObject::const_iterator QJsonObject::constFind(const QString &key) const
+{
+ int index = o ? o->indexOf(key) : 0;
+ if (index < 0)
+ index = o->length;
+ return const_iterator(this, index);
+}
+
void QJsonObject::detach(uint reserve)
{
if (!d) {
@@ -308,7 +343,7 @@ void QJsonObject::compact() const
const_cast<QJsonObject *>(this)->o = static_cast<Private::Object *>(d->header->root());
}
-QString QJsonObject::keyAt(int i)
+QString QJsonObject::keyAt(int i) const
{
Q_ASSERT(o && i >= 0 && i < (int)o->length);
@@ -316,9 +351,10 @@ QString QJsonObject::keyAt(int i)
return e->key();
}
-QJsonValue QJsonObject::valueAt(int i)
+QJsonValue QJsonObject::valueAt(int i) const
{
- Q_ASSERT(o && i >= 0 && i < (int)o->length);
+ if (!o || i < 0 || i >= (int)o->length)
+ return QJsonValue(QJsonValue::Undefined);
Private::Entry *e = o->entryAt(i);
return QJsonValue(d, o, e->value);
diff --git a/src/qjsonobject.h b/src/qjsonobject.h
index dff0e9e..8bbbdd1 100644
--- a/src/qjsonobject.h
+++ b/src/qjsonobject.h
@@ -42,7 +42,7 @@
#ifndef QJSONOBJECT_H
#define QJSONOBJECT_H
-#include <qjsonglobal.h>
+#include <qjsonvalue.h>
#include <qvariant.h>
#include <qdebug.h>
@@ -73,7 +73,6 @@ public:
QJsonValue operator[] (const QString &key) const;
QJsonValueRef operator[] (const QString &key);
- void insert(const QString &key, const QJsonValue &value);
void remove(const QString &key);
QJsonValue take(const QString &key);
bool contains(const QString &key) const;
@@ -81,6 +80,124 @@ public:
bool operator==(const QJsonObject &other) const;
bool operator!=(const QJsonObject &other) const;
+ class const_iterator;
+
+ class iterator
+ {
+ friend class const_iterator;
+ friend class QJsonObject;
+ QJsonObject *o;
+ int i;
+
+ public:
+ typedef std::bidirectional_iterator_tag iterator_category;
+ typedef int difference_type;
+ typedef QJsonValue value_type;
+// typedef T *pointer;
+ typedef QJsonValueRef reference;
+
+ inline iterator() : o(0), i(0) {}
+ explicit inline iterator(QJsonObject *obj, int index) : o(obj), i(index) {}
+
+ inline QString key() const { return o->keyAt(i); }
+ inline QJsonValueRef value() const { return QJsonValueRef(o, i); }
+ inline QJsonValueRef operator*() const { return QJsonValueRef(o, i); }
+ //inline T *operator->() const { return &concrete(i)->value; }
+ inline bool operator==(const iterator &other) const { return i == other.i; }
+ inline bool operator!=(const iterator &other) const { return i != other.i; }
+
+ inline iterator &operator++() { ++i; return *this; }
+ inline iterator operator++(int) { iterator r = *this; ++i; return r; }
+ inline iterator &operator--() { --i; return *this; }
+ inline iterator operator--(int) { iterator r = *this; --i; return r; }
+ inline iterator operator+(int j) const
+ { iterator r = *this; r.i += j; return r; }
+ inline iterator operator-(int j) const { return operator+(-j); }
+ inline iterator &operator+=(int j) { i += j; return *this; }
+ inline iterator &operator-=(int j) { i -= j; return *this; }
+
+#ifdef QT_STRICT_ITERATORS
+ private:
+#else
+ public:
+#endif
+ inline bool operator==(const const_iterator &other) const { return i == other.i; }
+ inline bool operator!=(const const_iterator &other) const { return i != other.i; }
+ };
+ friend class iterator;
+
+ class const_iterator
+ {
+ friend class iterator;
+ const QJsonObject *o;
+ int i;
+
+ public:
+ typedef std::bidirectional_iterator_tag iterator_category;
+ typedef int difference_type;
+ typedef QJsonValue value_type;
+ //typedef const T *pointer;
+ typedef QJsonValue reference;
+
+ inline const_iterator() : o(0), i(0) {}
+ explicit inline const_iterator(const QJsonObject *obj, int index)
+ : o(obj), i(index) {}
+#ifdef QT_STRICT_ITERATORS
+ explicit inline const_iterator(const iterator &other)
+#else
+ inline const_iterator(const iterator &other)
+#endif
+ : o(other.o), i(other.i) {}
+
+ inline QString key() const { return o->keyAt(i); }
+ inline QJsonValue value() const { return o->valueAt(i); }
+ inline QJsonValue operator*() const { return o->valueAt(i); }
+ //inline const T *operator->() const { return &concrete(i)->value; }
+ inline bool operator==(const const_iterator &other) const { return i == other.i; }
+ inline bool operator!=(const const_iterator &other) const { return i != other.i; }
+
+ inline const_iterator &operator++() { ++i; return *this; }
+ inline const_iterator operator++(int) { const_iterator r = *this; ++i; return r; }
+ inline const_iterator &operator--() { --i; return *this; }
+ inline const_iterator operator--(int) { const_iterator r = *this; --i; return r; }
+ inline const_iterator operator+(int j) const
+ { const_iterator r = *this; r.i += j; return r; }
+ inline const_iterator operator-(int j) const { return operator+(-j); }
+ inline const_iterator &operator+=(int j) { i += j; return *this; }
+ inline const_iterator &operator-=(int j) { i -= j; return *this; }
+
+#ifdef QT_STRICT_ITERATORS
+ private:
+ inline bool operator==(const iterator &o) const { return i == o.i; }
+ inline bool operator!=(const iterator &o) const { return i != o.i; }
+#endif
+ };
+ friend class const_iterator;
+
+ // STL style
+ inline iterator begin() { detach(); return iterator(this, 0); }
+ inline const_iterator begin() const { return const_iterator(this, 0); }
+ inline const_iterator constBegin() const { return const_iterator(this, 0); }
+ inline iterator end() { detach(); return iterator(this, size()); }
+ inline const_iterator end() const { return const_iterator(this, size()); }
+ inline const_iterator constEnd() const { return const_iterator(this, size()); }
+ iterator erase(iterator it);
+
+ // more Qt
+ typedef iterator Iterator;
+ typedef const_iterator ConstIterator;
+ iterator find(const QString &key);
+ const_iterator find(const QString &key) const { return constFind(key); }
+ const_iterator constFind(const QString &key) const;
+ iterator insert(const QString &key, const QJsonValue &value);
+
+ // STL compatibility
+ typedef QJsonValue mapped_type;
+ typedef QString key_type;
+ typedef int size_type;
+
+ inline bool empty() const { return isEmpty(); }
+
private:
friend class Private::Data;
friend class QJsonValue;
@@ -94,8 +211,8 @@ private:
void detach(uint reserve = 0);
void compact() const;
- QString keyAt(int i);
- QJsonValue valueAt(int i);
+ QString keyAt(int i) const;
+ QJsonValue valueAt(int i) const;
void setValueAt(int i, const QJsonValue &val);
Private::Data *d;