diff options
author | Lars Knoll <lars.knoll@qt.io> | 2020-10-16 12:38:00 +0200 |
---|---|---|
committer | Lars Knoll <lars.knoll@qt.io> | 2020-10-23 09:49:32 +0200 |
commit | f2df8033f0ab1f27cf2310e32c4c13631bbaca63 (patch) | |
tree | 8241fbeaf811c170ecfe45c59c9a24ca05832048 /src | |
parent | ee3adcc64227e1a27b36c8ca69ead415cf2fd644 (diff) |
Support Java style iterators for QMultiHash
Take the opportunity to clean up the implementation for QHash and
use the standard macro there instead of an inlined copy.
Fixes: QTBUG-86986
Change-Id: Iea846ca97bd8b9be5d6534b31d4c7707fd1a53e1
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
Diffstat (limited to 'src')
-rw-r--r-- | src/corelib/tools/qhash.h | 138 | ||||
-rw-r--r-- | src/corelib/tools/qiterator.h | 61 |
2 files changed, 65 insertions, 134 deletions
diff --git a/src/corelib/tools/qhash.h b/src/corelib/tools/qhash.h index ced64233b7..2ac6920cc3 100644 --- a/src/corelib/tools/qhash.h +++ b/src/corelib/tools/qhash.h @@ -1839,140 +1839,10 @@ private: } }; -#if !defined(QT_NO_JAVA_STYLE_ITERATORS) -template<class Key, class T> -class QHashIterator -{ - typedef typename QHash<Key, T>::const_iterator const_iterator; - typedef const_iterator Item; - QHash<Key, T> c; - const_iterator i, n; - inline bool item_exists() const noexcept { return n != c.constEnd(); } - -public: - inline QHashIterator(const QHash<Key, T> &container) noexcept - : c(container), i(c.constBegin()), n(c.constEnd()) - { } - inline QHashIterator &operator=(const QHash<Key, T> &container) noexcept - { - c = container; - i = c.constBegin(); - n = c.constEnd(); - return *this; - } - inline void toFront() noexcept - { - i = c.constBegin(); - n = c.constEnd(); - } - inline void toBack() noexcept - { - i = c.constEnd(); - n = c.constEnd(); - } - inline bool hasNext() const noexcept { return i != c.constEnd(); } - inline Item next() noexcept - { - n = i++; - return n; - } - inline Item peekNext() const noexcept { return i; } - inline const T &value() const noexcept - { - Q_ASSERT(item_exists()); - return *n; - } - inline const Key &key() const noexcept - { - Q_ASSERT(item_exists()); - return n.key(); - } - inline bool findNext(const T &t) noexcept - { - while ((n = i) != c.constEnd()) - if (*i++ == t) - return true; - return false; - } -}; - -template<class Key, class T> -class QMutableHashIterator -{ - typedef typename QHash<Key, T>::iterator iterator; - typedef typename QHash<Key, T>::const_iterator const_iterator; - typedef iterator Item; - QHash<Key, T> *c; - iterator i, n; - inline bool item_exists() const noexcept { return const_iterator(n) != c->constEnd(); } - -public: - inline QMutableHashIterator(QHash<Key, T> &container) - : c(&container) - { - i = c->begin(); - n = c->end(); - } - inline QMutableHashIterator &operator=(QHash<Key, T> &container) - { - c = &container; - i = c->begin(); - n = c->end(); - return *this; - } - inline void toFront() - { - i = c->begin(); - n = c->end(); - } - inline void toBack() noexcept - { - i = c->end(); - n = c->end(); - } - inline bool hasNext() const noexcept { return const_iterator(i) != c->constEnd(); } - inline Item next() noexcept - { - n = i++; - return n; - } - inline Item peekNext() const noexcept { return i; } - inline void remove() - { - if (const_iterator(n) != c->constEnd()) { - i = c->erase(n); - n = c->end(); - } - } - inline void setValue(const T &t) - { - if (const_iterator(n) != c->constEnd()) - *n = t; - } - inline T &value() noexcept - { - Q_ASSERT(item_exists()); - return *n; - } - inline const T &value() const noexcept - { - Q_ASSERT(item_exists()); - return *n; - } - inline const Key &key() const noexcept - { - Q_ASSERT(item_exists()); - return n.key(); - } - inline bool findNext(const T &t) noexcept - { - while (const_iterator(n = i) != c->constEnd()) - if (*i++ == t) - return true; - return false; - } -}; -#endif // !QT_NO_JAVA_STYLE_ITERATORS +Q_DECLARE_ASSOCIATIVE_FORWARD_ITERATOR(Hash) +Q_DECLARE_MUTABLE_ASSOCIATIVE_FORWARD_ITERATOR(Hash) +Q_DECLARE_ASSOCIATIVE_FORWARD_ITERATOR(MultiHash) +Q_DECLARE_MUTABLE_ASSOCIATIVE_FORWARD_ITERATOR(MultiHash) template <class Key, class T> size_t qHash(const QHash<Key, T> &key, size_t seed = 0) diff --git a/src/corelib/tools/qiterator.h b/src/corelib/tools/qiterator.h index 16c2d7f07c..8922f34758 100644 --- a/src/corelib/tools/qiterator.h +++ b/src/corelib/tools/qiterator.h @@ -181,11 +181,72 @@ public: \ n = c->end(); return false; } \ }; +#define Q_DECLARE_ASSOCIATIVE_FORWARD_ITERATOR(C) \ +\ +template <class Key, class T> \ +class Q##C##Iterator \ +{ \ + typedef typename Q##C<Key,T>::const_iterator const_iterator; \ + Q##C<Key,T> c; \ + const_iterator i, n; \ + inline bool item_exists() const { return n != c.constEnd(); } \ +public: \ + typedef const_iterator Item; \ + inline Q##C##Iterator(const Q##C<Key,T> &container) \ + : c(container), i(c.constBegin()), n(c.constEnd()) {} \ + inline Q##C##Iterator &operator=(const Q##C<Key,T> &container) \ + { c = container; i = c.constBegin(); n = c.constEnd(); return *this; } \ + inline void toFront() { i = c.constBegin(); n = c.constEnd(); } \ + inline void toBack() { i = c.constEnd(); n = c.constEnd(); } \ + inline bool hasNext() const { return i != c.constEnd(); } \ + inline Item next() { n = i++; return n; } \ + inline Item peekNext() const { return i; } \ + inline const T &value() const { Q_ASSERT(item_exists()); return *n; } \ + inline const Key &key() const { Q_ASSERT(item_exists()); return n.key(); } \ + inline bool findNext(const T &t) \ + { while ((n = i) != c.constEnd()) if (*i++ == t) return true; return false; } \ +}; + +#define Q_DECLARE_MUTABLE_ASSOCIATIVE_FORWARD_ITERATOR(C) \ +\ +template <class Key, class T> \ +class QMutable##C##Iterator \ +{ \ + typedef typename Q##C<Key,T>::iterator iterator; \ + typedef typename Q##C<Key,T>::const_iterator const_iterator; \ + Q##C<Key,T> *c; \ + iterator i, n; \ + inline bool item_exists() const { return const_iterator(n) != c->constEnd(); } \ +public: \ + typedef iterator Item; \ + inline QMutable##C##Iterator(Q##C<Key,T> &container) \ + : c(&container) \ + { i = c->begin(); n = c->end(); } \ + inline QMutable##C##Iterator &operator=(Q##C<Key,T> &container) \ + { c = &container; i = c->begin(); n = c->end(); return *this; } \ + inline void toFront() { i = c->begin(); n = c->end(); } \ + inline void toBack() { i = c->end(); n = c->end(); } \ + inline bool hasNext() const { return const_iterator(i) != c->constEnd(); } \ + inline Item next() { n = i++; return n; } \ + inline Item peekNext() const { return i; } \ + inline void remove() \ + { if (const_iterator(n) != c->constEnd()) { i = c->erase(n); n = c->end(); } } \ + inline void setValue(const T &t) { if (const_iterator(n) != c->constEnd()) *n = t; } \ + inline T &value() { Q_ASSERT(item_exists()); return *n; } \ + inline const T &value() const { Q_ASSERT(item_exists()); return *n; } \ + inline const Key &key() const { Q_ASSERT(item_exists()); return n.key(); } \ + inline bool findNext(const T &t) \ + { while (const_iterator(n = i) != c->constEnd()) if (*i++ == t) return true; return false; } \ +}; + + #else // QT_NO_JAVA_STYLE_ITERATORS #define Q_DECLARE_SEQUENTIAL_ITERATOR(C) #define Q_DECLARE_MUTABLE_SEQUENTIAL_ITERATOR(C) #define Q_DECLARE_ASSOCIATIVE_ITERATOR(C) #define Q_DECLARE_MUTABLE_ASSOCIATIVE_ITERATOR(C) +#define Q_DECLARE_ASSOCIATIVE_FORWARD_ITERATOR(C) +#define Q_DECLARE_MUTABLE_ASSOCIATIVE_FORWARD_ITERATOR(C) #endif // QT_NO_JAVA_STYLE_ITERATORS template<typename Key, typename T, class Iterator> |