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