Add operator-> to QJson iterators

The iterators for QJsonArray and QJsonObject are currently lacking an
operator-> definition. Unfortunately it is not possible to do in clean
way without redefining either the iterators or QJsonValueRef class.

This patch instead adds two fake pointer classes that are only used
to handle the operator-> return value.

Task-number: QTBUG-29573
Change-Id: Ief785a6afbbedc9e89cf3b6f3958c2c755997a66
Reviewed-by: Lars Knoll <lars.knoll@digia.com>
This commit is contained in:
Allan Sandfeld Jensen 2014-08-15 15:41:44 +02:00
parent f16de5c1fd
commit 7dce962200
6 changed files with 71 additions and 7 deletions

View File

@ -746,6 +746,11 @@ bool QJsonArray::operator!=(const QJsonArray &other) const
from which you got the reference.
*/
/*! \fn QJsonValueRef *QJsonArray::iterator::operator->() const
Returns a pointer to a modifiable reference to the current item.
*/
/*! \fn QJsonValueRef QJsonArray::iterator::operator[](int j) const
Returns a modifiable reference to the item at offset \a j from the
@ -971,6 +976,11 @@ bool QJsonArray::operator!=(const QJsonArray &other) const
Returns the current item.
*/
/*! \fn QJsonValue *QJsonArray::const_iterator::operator->() const
Returns a pointer to the current item.
*/
/*! \fn QJsonValue QJsonArray::const_iterator::operator[](int j) const
Returns the item at offset \a j from the item pointed to by this iterator (the item at

View File

@ -112,14 +112,17 @@ public:
typedef std::random_access_iterator_tag iterator_category;
typedef int difference_type;
typedef QJsonValue value_type;
//typedef T *pointer;
typedef QJsonValueRef reference;
inline iterator() : a(0), i(0) { }
explicit inline iterator(QJsonArray *array, int index) : a(array), i(index) { }
inline QJsonValueRef operator*() const { return QJsonValueRef(a, i); }
//inline T *operator->() const { return &concrete(i)->value; }
#ifdef Q_QDOC
inline QJsonValueRef* operator->() const;
#else
inline QJsonValueRefPtr operator->() const { return QJsonValueRefPtr(a, i); }
#endif
inline QJsonValueRef operator[](int j) const { return QJsonValueRef(a, i + j); }
inline bool operator==(const iterator &o) const { return i == o.i; }
@ -153,7 +156,6 @@ public:
typedef std::random_access_iterator_tag iterator_category;
typedef qptrdiff difference_type;
typedef QJsonValue value_type;
//typedef const T *pointer;
typedef QJsonValue reference;
inline const_iterator() : a(0), i(0) { }
@ -162,7 +164,11 @@ public:
inline const_iterator(const iterator &o) : a(o.a), i(o.i) {}
inline QJsonValue operator*() const { return a->at(i); }
//inline T *operator->() const { return &concrete(i)->value; }
#ifdef Q_QDOC
inline QJsonValue* operator->() const;
#else
inline QJsonValuePtr operator->() const { return QJsonValuePtr(a->at(i)); }
#endif
inline QJsonValue operator[](int j) const { return a->at(i+j); }
inline bool operator==(const const_iterator &o) const { return i == o.i; }
inline bool operator!=(const const_iterator &o) const { return i != o.i; }

View File

@ -710,6 +710,11 @@ QJsonObject::const_iterator QJsonObject::constFind(const QString &key) const
\sa key()
*/
/*! \fn QJsonValueRef *QJsonObject::iterator::operator->() const
Returns a pointer to a modifiable reference to the current item.
*/
/*!
\fn bool QJsonObject::iterator::operator==(const iterator &other) const
\fn bool QJsonObject::iterator::operator==(const const_iterator &other) const
@ -893,6 +898,11 @@ QJsonObject::const_iterator QJsonObject::constFind(const QString &key) const
\sa key()
*/
/*! \fn QJsonValue *QJsonObject::const_iterator::operator->() const
Returns a pointer to the current item.
*/
/*! \fn bool QJsonObject::const_iterator::operator==(const const_iterator &other) const
\fn bool QJsonObject::const_iterator::operator==(const iterator &other) const

View File

@ -107,7 +107,6 @@ public:
typedef std::bidirectional_iterator_tag iterator_category;
typedef int difference_type;
typedef QJsonValue value_type;
// typedef T *pointer;
typedef QJsonValueRef reference;
Q_DECL_CONSTEXPR inline iterator() : o(0), i(0) {}
@ -116,7 +115,11 @@ public:
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; }
#ifdef Q_QDOC
inline QJsonValueRef* operator->() const;
#else
inline QJsonValueRefPtr operator->() const { return QJsonValueRefPtr(o, i); }
#endif
inline bool operator==(const iterator &other) const { return i == other.i; }
inline bool operator!=(const iterator &other) const { return i != other.i; }
@ -157,7 +160,11 @@ public:
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; }
#ifdef Q_QDOC
inline QJsonValue* operator->() const;
#else
inline QJsonValuePtr operator->() const { return QJsonValuePtr(o->valueAt(i)); }
#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; }

View File

@ -192,6 +192,33 @@ private:
struct UnionHelper;
};
#ifndef Q_QDOC
// ### Qt 6: Get rid of these fake pointer classes
class QJsonValuePtr
{
QJsonValue value;
public:
explicit QJsonValuePtr(const QJsonValue& val)
: value(val) {}
QJsonValue& operator*() { return value; }
QJsonValue* operator->() { return &value; }
};
class QJsonValueRefPtr
{
QJsonValueRef valueRef;
public:
QJsonValueRefPtr(QJsonArray *array, int idx)
: valueRef(array, idx) {}
QJsonValueRefPtr(QJsonObject *object, int idx)
: valueRef(object, idx) {}
QJsonValueRef& operator*() { return valueRef; }
QJsonValueRef* operator->() { return &valueRef; }
};
#endif
#if !defined(QT_NO_DEBUG_STREAM) && !defined(QT_JSON_READONLY)
Q_CORE_EXPORT QDebug operator<<(QDebug, const QJsonValue &);
#endif

View File

@ -746,6 +746,8 @@ void tst_QtJson::testObjectIteration()
QCOMPARE(object.size(), 10);
QCOMPARE(object.begin()->toDouble(), object.constBegin()->toDouble());
for (QJsonObject::iterator it = object.begin(); it != object.end(); ++it) {
QJsonValue value = it.value();
QCOMPARE((double)it.key().toInt(), value.toDouble());
@ -822,6 +824,8 @@ void tst_QtJson::testArrayIteration()
QCOMPARE((double)i, value.toDouble());
}
QCOMPARE(array.begin()->toDouble(), array.constBegin()->toDouble());
{
QJsonArray array2 = array;
QVERIFY(array == array2);