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