From 0306247f5a5d057fedfa183da06a78cc41139d1d Mon Sep 17 00:00:00 2001 From: Volker Hilsheimer Date: Mon, 8 May 2023 16:08:57 +0200 Subject: [PATCH] Remove Java iterator APIs for moving back if operator-- is not available QSet's iterator doesn't have operator--, but the Q_DECLARE_SEQUENTIAL_ITERATOR macro declared and implemented functions hasPrevious/previous/peekPrevious/findPrevious for the QSetIterator anyway, depending on that operator. The resulting code couldn't compile. Use SFINAE to remove the various "previous" functions from Java-style iterators if operator--() is not present. This removes the hasPrevious() API as well, even though it could compile (as we only check whether the iterator points at constBegin). But since nothing useful can be done with that information, it's best to remove that member function as well. [ChangeLog][Potentially source-incompatible changes] QSetIterator no longer has a hasPrevious() member function. The underlying iterator doesn't implement operator--(), so couldn't be moved backwards anyway. Fixes: QTBUG-113379 Change-Id: I47b0ba384d8fcd127123d8fa509cd89e10ea8c99 Reviewed-by: Thiago Macieira --- src/corelib/tools/qcontainertools_impl.h | 9 +++++++++ src/corelib/tools/qiterator.h | 23 +++++++++++++++++++++++ src/corelib/tools/qiterator.qdoc | 4 ---- 3 files changed, 32 insertions(+), 4 deletions(-) diff --git a/src/corelib/tools/qcontainertools_impl.h b/src/corelib/tools/qcontainertools_impl.h index dec60aa076..40ed0a84e9 100644 --- a/src/corelib/tools/qcontainertools_impl.h +++ b/src/corelib/tools/qcontainertools_impl.h @@ -302,6 +302,15 @@ template using IfAssociativeIteratorHasFirstAndSecond = std::enable_if_t, bool>; +template +using MoveBackwardsTest = decltype( + std::declval().operator--() +); + +template +using IfIteratorCanMoveBackwards = + std::enable_if_t, bool>; + template using IfIsNotSame = typename std::enable_if::value, bool>::type; diff --git a/src/corelib/tools/qiterator.h b/src/corelib/tools/qiterator.h index cff535d030..ab3d71f760 100644 --- a/src/corelib/tools/qiterator.h +++ b/src/corelib/tools/qiterator.h @@ -10,6 +10,13 @@ QT_BEGIN_NAMESPACE #if !defined(QT_NO_JAVA_STYLE_ITERATORS) +#ifdef Q_QDOC +#define Q_DISABLE_BACKWARD_ITERATOR +#else +#define Q_DISABLE_BACKWARD_ITERATOR \ + template = true> +#endif + #define Q_DECLARE_SEQUENTIAL_ITERATOR(C) \ \ template \ @@ -28,11 +35,15 @@ public: \ inline bool hasNext() const { return i != c.constEnd(); } \ inline const T &next() { return *i++; } \ inline const T &peekNext() const { return *i; } \ + Q_DISABLE_BACKWARD_ITERATOR \ inline bool hasPrevious() const { return i != c.constBegin(); } \ + Q_DISABLE_BACKWARD_ITERATOR \ inline const T &previous() { return *--i; } \ + Q_DISABLE_BACKWARD_ITERATOR \ inline const T &peekPrevious() const { const_iterator p = i; return *--p; } \ inline bool findNext(const T &t) \ { while (i != c.constEnd()) if (*i++ == t) return true; return false; } \ + Q_DISABLE_BACKWARD_ITERATOR \ inline bool findPrevious(const T &t) \ { while (i != c.constBegin()) if (*(--i) == t) return true; \ return false; } \ @@ -59,8 +70,11 @@ public: \ inline bool hasNext() const { return c->constEnd() != const_iterator(i); } \ inline T &next() { n = i++; return *n; } \ inline T &peekNext() const { return *i; } \ + Q_DISABLE_BACKWARD_ITERATOR \ inline bool hasPrevious() const { return c->constBegin() != const_iterator(i); } \ + Q_DISABLE_BACKWARD_ITERATOR \ inline T &previous() { n = --i; return *n; } \ + Q_DISABLE_BACKWARD_ITERATOR \ inline T &peekPrevious() const { iterator p = i; return *--p; } \ inline void remove() \ { if (c->constEnd() != const_iterator(n)) { i = c->erase(n); n = c->end(); } } \ @@ -70,6 +84,7 @@ public: \ inline void insert(const T &t) { n = i = c->insert(i, t); ++i; } \ inline bool findNext(const T &t) \ { while (c->constEnd() != const_iterator(n = i)) if (*i++ == t) return true; return false; } \ + Q_DISABLE_BACKWARD_ITERATOR \ inline bool findPrevious(const T &t) \ { while (c->constBegin() != const_iterator(i)) if (*(n = --i) == t) return true; \ n = c->end(); return false; } \ @@ -95,13 +110,17 @@ public: \ inline bool hasNext() const { return i != c.constEnd(); } \ inline Item next() { n = i++; return n; } \ inline Item peekNext() const { return i; } \ + Q_DISABLE_BACKWARD_ITERATOR \ inline bool hasPrevious() const { return i != c.constBegin(); } \ + Q_DISABLE_BACKWARD_ITERATOR \ inline Item previous() { n = --i; return n; } \ + Q_DISABLE_BACKWARD_ITERATOR \ inline Item peekPrevious() const { const_iterator p = i; return --p; } \ 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; } \ + Q_DISABLE_BACKWARD_ITERATOR \ inline bool findPrevious(const T &t) \ { while (i != c.constBegin()) if (*(n = --i) == t) return true; \ n = c.constEnd(); return false; } \ @@ -129,8 +148,11 @@ public: \ inline bool hasNext() const { return const_iterator(i) != c->constEnd(); } \ inline Item next() { n = i++; return n; } \ inline Item peekNext() const { return i; } \ + Q_DISABLE_BACKWARD_ITERATOR \ inline bool hasPrevious() const { return const_iterator(i) != c->constBegin(); } \ + Q_DISABLE_BACKWARD_ITERATOR \ inline Item previous() { n = --i; return n; } \ + Q_DISABLE_BACKWARD_ITERATOR \ inline Item peekPrevious() const { iterator p = i; return --p; } \ inline void remove() \ { if (const_iterator(n) != c->constEnd()) { i = c->erase(n); n = c->end(); } } \ @@ -140,6 +162,7 @@ public: \ 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; } \ + Q_DISABLE_BACKWARD_ITERATOR \ inline bool findPrevious(const T &t) \ { while (const_iterator(i) != c->constBegin()) if (*(n = --i) == t) return true; \ n = c->end(); return false; } \ diff --git a/src/corelib/tools/qiterator.qdoc b/src/corelib/tools/qiterator.qdoc index 3fc68e0874..77336c1bd8 100644 --- a/src/corelib/tools/qiterator.qdoc +++ b/src/corelib/tools/qiterator.qdoc @@ -500,7 +500,6 @@ */ /*! \fn template bool QListIterator::hasPrevious() const - \fn template bool QSetIterator::hasPrevious() const \fn template bool QMutableListIterator::hasPrevious() const Returns \c true if there is at least one item behind the iterator, @@ -511,7 +510,6 @@ */ /*! \fn template const T &QListIterator::previous() - \fn template const T &QSetIterator::previous() Returns the previous item and moves the iterator back by one position. @@ -534,7 +532,6 @@ */ /*! \fn template const T &QListIterator::peekPrevious() const - \fn template const T &QSetIterator::peekPrevious() const Returns the previous item without moving the iterator. @@ -580,7 +577,6 @@ */ /*! \fn template bool QListIterator::findPrevious(const T &value) - \fn template bool QSetIterator::findPrevious(const T &value) \fn template bool QMutableListIterator::findPrevious(const T &value) Searches for \a value starting from the current iterator position