diff options
author | Lars Knoll <lars.knoll@nokia.com> | 2012-01-10 11:58:31 +0100 |
---|---|---|
committer | Lars Knoll <lars.knoll@nokia.com> | 2012-01-11 14:58:09 +0100 |
commit | 2e20b0abf92b2ee81a4328ae5d1ae4aaff46e189 (patch) | |
tree | f1e50437c320730da89b358731ddd7635f38329e /src | |
parent | 1fca88779c35a9adc848e482be2ddaca5e54a3db (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.cpp | 46 | ||||
-rw-r--r-- | src/qjsonobject.h | 125 |
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; |