File indexing completed on 2026-08-16 09:17:13
0001
0002
0003
0004
0005 #ifndef QITERATOR_H
0006 #define QITERATOR_H
0007
0008 #include <QtCore/qglobal.h>
0009 #include <QtCore/qcontainertools_impl.h>
0010
0011 #ifdef __cpp_lib_ranges
0012 #include <ranges>
0013 #endif
0014
0015 QT_BEGIN_NAMESPACE
0016
0017 #if !defined(QT_NO_JAVA_STYLE_ITERATORS)
0018
0019 #ifdef Q_QDOC
0020 #define Q_DISABLE_BACKWARD_ITERATOR
0021 #else
0022 #define Q_DISABLE_BACKWARD_ITERATOR \
0023 template<typename It = decltype(i), QtPrivate::IfIteratorCanMoveBackwards<It> = true>
0024 #endif
0025
0026 #define Q_DECLARE_SEQUENTIAL_ITERATOR(C) \
0027 \
0028 template <class T> \
0029 class Q##C##Iterator \
0030 { \
0031 typedef typename Q##C<T>::const_iterator const_iterator; \
0032 Q##C<T> c; \
0033 const_iterator i; \
0034 public: \
0035 inline Q##C##Iterator(const Q##C<T> &container) \
0036 : c(container), i(c.constBegin()) {} \
0037 inline Q##C##Iterator &operator=(const Q##C<T> &container) \
0038 { c = container; i = c.constBegin(); return *this; } \
0039 inline void toFront() { i = c.constBegin(); } \
0040 inline void toBack() { i = c.constEnd(); } \
0041 inline bool hasNext() const { return i != c.constEnd(); } \
0042 inline const T &next() { return *i++; } \
0043 inline const T &peekNext() const { return *i; } \
0044 Q_DISABLE_BACKWARD_ITERATOR \
0045 inline bool hasPrevious() const { return i != c.constBegin(); } \
0046 Q_DISABLE_BACKWARD_ITERATOR \
0047 inline const T &previous() { return *--i; } \
0048 Q_DISABLE_BACKWARD_ITERATOR \
0049 inline const T &peekPrevious() const { const_iterator p = i; return *--p; } \
0050 inline bool findNext(const T &t) \
0051 { while (i != c.constEnd()) if (*i++ == t) return true; return false; } \
0052 Q_DISABLE_BACKWARD_ITERATOR \
0053 inline bool findPrevious(const T &t) \
0054 { while (i != c.constBegin()) if (*(--i) == t) return true; \
0055 return false; } \
0056 };
0057
0058 #define Q_DECLARE_MUTABLE_SEQUENTIAL_ITERATOR(C) \
0059 \
0060 template <class T> \
0061 class QMutable##C##Iterator \
0062 { \
0063 typedef typename Q##C<T>::iterator iterator; \
0064 typedef typename Q##C<T>::const_iterator const_iterator; \
0065 Q##C<T> *c; \
0066 iterator i, n; \
0067 inline bool item_exists() const { return const_iterator(n) != c->constEnd(); } \
0068 public: \
0069 inline QMutable##C##Iterator(Q##C<T> &container) \
0070 : c(&container) \
0071 { i = c->begin(); n = c->end(); } \
0072 inline QMutable##C##Iterator &operator=(Q##C<T> &container) \
0073 { c = &container; i = c->begin(); n = c->end(); return *this; } \
0074 inline void toFront() { i = c->begin(); n = c->end(); } \
0075 inline void toBack() { i = c->end(); n = i; } \
0076 inline bool hasNext() const { return c->constEnd() != const_iterator(i); } \
0077 inline T &next() { n = i++; return *n; } \
0078 inline T &peekNext() const { return *i; } \
0079 Q_DISABLE_BACKWARD_ITERATOR \
0080 inline bool hasPrevious() const { return c->constBegin() != const_iterator(i); } \
0081 Q_DISABLE_BACKWARD_ITERATOR \
0082 inline T &previous() { n = --i; return *n; } \
0083 Q_DISABLE_BACKWARD_ITERATOR \
0084 inline T &peekPrevious() const { iterator p = i; return *--p; } \
0085 inline void remove() \
0086 { if (c->constEnd() != const_iterator(n)) { i = c->erase(n); n = c->end(); } } \
0087 inline void setValue(const T &t) const { if (c->constEnd() != const_iterator(n)) *n = t; } \
0088 inline T &value() { Q_ASSERT(item_exists()); return *n; } \
0089 inline const T &value() const { Q_ASSERT(item_exists()); return *n; } \
0090 inline void insert(const T &t) { n = i = c->insert(i, t); ++i; } \
0091 inline bool findNext(const T &t) \
0092 { while (c->constEnd() != const_iterator(n = i)) if (*i++ == t) return true; return false; } \
0093 Q_DISABLE_BACKWARD_ITERATOR \
0094 inline bool findPrevious(const T &t) \
0095 { while (c->constBegin() != const_iterator(i)) if (*(n = --i) == t) return true; \
0096 n = c->end(); return false; } \
0097 };
0098
0099 #define Q_DECLARE_ASSOCIATIVE_ITERATOR(C) \
0100 \
0101 template <class Key, class T> \
0102 class Q##C##Iterator \
0103 { \
0104 typedef typename Q##C<Key,T>::const_iterator const_iterator; \
0105 Q##C<Key,T> c; \
0106 const_iterator i, n; \
0107 inline bool item_exists() const { return n != c.constEnd(); } \
0108 public: \
0109 typedef const_iterator Item; \
0110 inline Q##C##Iterator(const Q##C<Key,T> &container) \
0111 : c(container), i(c.constBegin()), n(c.constEnd()) {} \
0112 inline Q##C##Iterator &operator=(const Q##C<Key,T> &container) \
0113 { c = container; i = c.constBegin(); n = c.constEnd(); return *this; } \
0114 inline void toFront() { i = c.constBegin(); n = c.constEnd(); } \
0115 inline void toBack() { i = c.constEnd(); n = c.constEnd(); } \
0116 inline bool hasNext() const { return i != c.constEnd(); } \
0117 inline Item next() { n = i++; return n; } \
0118 inline Item peekNext() const { return i; } \
0119 Q_DISABLE_BACKWARD_ITERATOR \
0120 inline bool hasPrevious() const { return i != c.constBegin(); } \
0121 Q_DISABLE_BACKWARD_ITERATOR \
0122 inline Item previous() { n = --i; return n; } \
0123 Q_DISABLE_BACKWARD_ITERATOR \
0124 inline Item peekPrevious() const { const_iterator p = i; return --p; } \
0125 inline const T &value() const { Q_ASSERT(item_exists()); return *n; } \
0126 inline const Key &key() const { Q_ASSERT(item_exists()); return n.key(); } \
0127 inline bool findNext(const T &t) \
0128 { while ((n = i) != c.constEnd()) if (*i++ == t) return true; return false; } \
0129 Q_DISABLE_BACKWARD_ITERATOR \
0130 inline bool findPrevious(const T &t) \
0131 { while (i != c.constBegin()) if (*(n = --i) == t) return true; \
0132 n = c.constEnd(); return false; } \
0133 };
0134
0135 #define Q_DECLARE_MUTABLE_ASSOCIATIVE_ITERATOR(C) \
0136 \
0137 template <class Key, class T> \
0138 class QMutable##C##Iterator \
0139 { \
0140 typedef typename Q##C<Key,T>::iterator iterator; \
0141 typedef typename Q##C<Key,T>::const_iterator const_iterator; \
0142 Q##C<Key,T> *c; \
0143 iterator i, n; \
0144 inline bool item_exists() const { return const_iterator(n) != c->constEnd(); } \
0145 public: \
0146 typedef iterator Item; \
0147 inline QMutable##C##Iterator(Q##C<Key,T> &container) \
0148 : c(&container) \
0149 { i = c->begin(); n = c->end(); } \
0150 inline QMutable##C##Iterator &operator=(Q##C<Key,T> &container) \
0151 { c = &container; i = c->begin(); n = c->end(); return *this; } \
0152 inline void toFront() { i = c->begin(); n = c->end(); } \
0153 inline void toBack() { i = c->end(); n = c->end(); } \
0154 inline bool hasNext() const { return const_iterator(i) != c->constEnd(); } \
0155 inline Item next() { n = i++; return n; } \
0156 inline Item peekNext() const { return i; } \
0157 Q_DISABLE_BACKWARD_ITERATOR \
0158 inline bool hasPrevious() const { return const_iterator(i) != c->constBegin(); } \
0159 Q_DISABLE_BACKWARD_ITERATOR \
0160 inline Item previous() { n = --i; return n; } \
0161 Q_DISABLE_BACKWARD_ITERATOR \
0162 inline Item peekPrevious() const { iterator p = i; return --p; } \
0163 inline void remove() \
0164 { if (const_iterator(n) != c->constEnd()) { i = c->erase(n); n = c->end(); } } \
0165 inline void setValue(const T &t) { if (const_iterator(n) != c->constEnd()) *n = t; } \
0166 inline T &value() { Q_ASSERT(item_exists()); return *n; } \
0167 inline const T &value() const { Q_ASSERT(item_exists()); return *n; } \
0168 inline const Key &key() const { Q_ASSERT(item_exists()); return n.key(); } \
0169 inline bool findNext(const T &t) \
0170 { while (const_iterator(n = i) != c->constEnd()) if (*i++ == t) return true; return false; } \
0171 Q_DISABLE_BACKWARD_ITERATOR \
0172 inline bool findPrevious(const T &t) \
0173 { while (const_iterator(i) != c->constBegin()) if (*(n = --i) == t) return true; \
0174 n = c->end(); return false; } \
0175 };
0176
0177 #define Q_DECLARE_ASSOCIATIVE_FORWARD_ITERATOR(C) \
0178 \
0179 template <class Key, class T> \
0180 class Q##C##Iterator \
0181 { \
0182 typedef typename Q##C<Key,T>::const_iterator const_iterator; \
0183 Q##C<Key,T> c; \
0184 const_iterator i, n; \
0185 inline bool item_exists() const { return n != c.constEnd(); } \
0186 public: \
0187 typedef const_iterator Item; \
0188 inline Q##C##Iterator(const Q##C<Key,T> &container) \
0189 : c(container), i(c.constBegin()), n(c.constEnd()) {} \
0190 inline Q##C##Iterator &operator=(const Q##C<Key,T> &container) \
0191 { c = container; i = c.constBegin(); n = c.constEnd(); return *this; } \
0192 inline void toFront() { i = c.constBegin(); n = c.constEnd(); } \
0193 inline void toBack() { i = c.constEnd(); n = c.constEnd(); } \
0194 inline bool hasNext() const { return i != c.constEnd(); } \
0195 inline Item next() { n = i++; return n; } \
0196 inline Item peekNext() const { return i; } \
0197 inline const T &value() const { Q_ASSERT(item_exists()); return *n; } \
0198 inline const Key &key() const { Q_ASSERT(item_exists()); return n.key(); } \
0199 inline bool findNext(const T &t) \
0200 { while ((n = i) != c.constEnd()) if (*i++ == t) return true; return false; } \
0201 };
0202
0203 #define Q_DECLARE_MUTABLE_ASSOCIATIVE_FORWARD_ITERATOR(C) \
0204 \
0205 template <class Key, class T> \
0206 class QMutable##C##Iterator \
0207 { \
0208 typedef typename Q##C<Key,T>::iterator iterator; \
0209 typedef typename Q##C<Key,T>::const_iterator const_iterator; \
0210 Q##C<Key,T> *c; \
0211 iterator i, n; \
0212 inline bool item_exists() const { return const_iterator(n) != c->constEnd(); } \
0213 public: \
0214 typedef iterator Item; \
0215 inline QMutable##C##Iterator(Q##C<Key,T> &container) \
0216 : c(&container) \
0217 { i = c->begin(); n = c->end(); } \
0218 inline QMutable##C##Iterator &operator=(Q##C<Key,T> &container) \
0219 { c = &container; i = c->begin(); n = c->end(); return *this; } \
0220 inline void toFront() { i = c->begin(); n = c->end(); } \
0221 inline void toBack() { i = c->end(); n = c->end(); } \
0222 inline bool hasNext() const { return const_iterator(i) != c->constEnd(); } \
0223 inline Item next() { n = i++; return n; } \
0224 inline Item peekNext() const { return i; } \
0225 inline void remove() \
0226 { if (const_iterator(n) != c->constEnd()) { i = c->erase(n); n = c->end(); } } \
0227 inline void setValue(const T &t) { if (const_iterator(n) != c->constEnd()) *n = t; } \
0228 inline T &value() { Q_ASSERT(item_exists()); return *n; } \
0229 inline const T &value() const { Q_ASSERT(item_exists()); return *n; } \
0230 inline const Key &key() const { Q_ASSERT(item_exists()); return n.key(); } \
0231 inline bool findNext(const T &t) \
0232 { while (const_iterator(n = i) != c->constEnd()) if (*i++ == t) return true; return false; } \
0233 };
0234
0235
0236 #else
0237 #define Q_DECLARE_SEQUENTIAL_ITERATOR(C)
0238 #define Q_DECLARE_MUTABLE_SEQUENTIAL_ITERATOR(C)
0239 #define Q_DECLARE_ASSOCIATIVE_ITERATOR(C)
0240 #define Q_DECLARE_MUTABLE_ASSOCIATIVE_ITERATOR(C)
0241 #define Q_DECLARE_ASSOCIATIVE_FORWARD_ITERATOR(C)
0242 #define Q_DECLARE_MUTABLE_ASSOCIATIVE_FORWARD_ITERATOR(C)
0243 #endif
0244
0245 namespace QtPrivate {
0246
0247 template <typename Key, typename T, typename Iterator>
0248 struct QDefaultKeyValues
0249 {
0250 static Key key(const Iterator &it) { return it.key(); }
0251 static Key key(Iterator &it) { return it.key(); }
0252 static T value(const Iterator &it) { return it.value(); }
0253 static T value(Iterator &it) { return it.value(); }
0254 };
0255
0256 }
0257
0258 template <typename Key, typename T, class Iterator,
0259 class Traits = QtPrivate::QDefaultKeyValues<Key, T, Iterator>>
0260 class QKeyValueIterator
0261 {
0262 public:
0263 typedef typename Iterator::iterator_category iterator_category;
0264 typedef typename Iterator::difference_type difference_type;
0265 typedef std::pair<Key, T> value_type;
0266 typedef const value_type &reference;
0267
0268 QKeyValueIterator() = default;
0269 constexpr explicit QKeyValueIterator(Iterator o) noexcept(std::is_nothrow_move_constructible<Iterator>::value)
0270 : i(std::move(o)) {}
0271
0272 std::pair<Key, T> operator*() const {
0273 return std::pair<Key, T>(Traits::key(i), Traits::value(i));
0274 }
0275
0276 using pointer = QtPrivate::ArrowProxy<value_type>;
0277
0278 pointer operator->() const {
0279 return pointer{ std::pair<Key, T>(Traits::key(i), Traits::value(i)) };
0280 }
0281
0282 friend bool operator==(QKeyValueIterator lhs, QKeyValueIterator rhs) noexcept { return lhs.i == rhs.i; }
0283 friend bool operator!=(QKeyValueIterator lhs, QKeyValueIterator rhs) noexcept { return lhs.i != rhs.i; }
0284
0285 inline QKeyValueIterator &operator++() { ++i; return *this; }
0286 inline QKeyValueIterator operator++(int) { return QKeyValueIterator(i++);}
0287 inline QKeyValueIterator &operator--() { --i; return *this; }
0288 inline QKeyValueIterator operator--(int) { return QKeyValueIterator(i--); }
0289 Iterator base() const { return i; }
0290
0291 private:
0292 Iterator i;
0293 };
0294
0295 namespace QtPrivate {
0296
0297 template <typename Map>
0298 class QKeyValueRangeStorage
0299 {
0300 protected:
0301 Map m_map;
0302 Map &map() { return m_map; }
0303 const Map &map() const { return m_map; }
0304 public:
0305 explicit QKeyValueRangeStorage(const Map &map) : m_map(map) {}
0306 explicit QKeyValueRangeStorage(Map &&map) : m_map(std::move(map)) {}
0307 };
0308
0309 template <typename Map>
0310 class QKeyValueRangeStorage<Map &>
0311 #ifdef __cpp_lib_ranges
0312 : public std::ranges::view_base
0313 #endif
0314 {
0315 protected:
0316 Map *m_map;
0317 Map &map() { return *m_map; }
0318 const Map &map() const { return *m_map; }
0319 public:
0320 explicit QKeyValueRangeStorage(Map &map) : m_map(&map) {}
0321 };
0322
0323 template <typename Map>
0324 class QKeyValueRange : public QKeyValueRangeStorage<Map>
0325 {
0326 public:
0327 using QKeyValueRangeStorage<Map>::QKeyValueRangeStorage;
0328 auto begin() { return this->map().keyValueBegin(); }
0329 auto begin() const { return this->map().keyValueBegin(); }
0330 auto end() { return this->map().keyValueEnd(); }
0331 auto end() const { return this->map().keyValueEnd(); }
0332 };
0333
0334 }
0335
0336
0337 QT_END_NAMESPACE
0338
0339 #endif