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>
This commit is contained in:
Lars Knoll 2020-10-16 12:38:00 +02:00
parent ee3adcc642
commit f2df8033f0
2 changed files with 65 additions and 134 deletions

View File

@ -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)

View File

@ -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>