Qt
Internal/Contributor docs for the Qt SDK. Note: These are NOT official API docs; those are found at https://doc.qt.io/
Loading...
Searching...
No Matches
qiterator.h
Go to the documentation of this file.
1// Copyright (C) 2016 The Qt Company Ltd.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
3
4#ifndef QITERATOR_H
5#define QITERATOR_H
6
7#include <QtCore/qglobal.h>
8#include <QtCore/qcontainertools_impl.h>
9
10#ifdef __cpp_lib_ranges
11#include <ranges>
12#endif
13
14QT_BEGIN_NAMESPACE
15
16#if !defined(QT_NO_JAVA_STYLE_ITERATORS)
17
18#ifdef Q_QDOC
19#define Q_DISABLE_BACKWARD_ITERATOR
20#else
21#define Q_DISABLE_BACKWARD_ITERATOR
22 template<typename It = decltype(i), QtPrivate::IfIteratorCanMoveBackwards<It> = true>
23#endif
24
25#define Q_DECLARE_SEQUENTIAL_ITERATOR(C) template
26
27 <class T> class
28 Q##C##Iterator \
29{
30 typedef typename Q##C<T>::const_iterator const_iterator;
31 Q##C<T> c;
32 const_iterator i; public
33 :
34 inline Q##C##Iterator(const Q##C<T> &container)
35 : c(container), i(c.constBegin()) {}
36 inline Q##C##Iterator &operator=(const Q##C<T> &container)
37 { c = container; i = c.constBegin(); return *this; }
38 inline void toFront() { i = c.constBegin(); }
39 inline void toBack() { i = c.constEnd(); }
40 inline bool hasNext() const { return i != c.constEnd(); }
41 inline const T &next() { return *i++; }
42 inline const T &peekNext() const { return *i; }
44 inline bool hasPrevious() const { return i != c.constBegin(); }
46 inline const T &previous() { return *--i; }
48 inline const T &peekPrevious() const { const_iterator p = i; return *--p; }
49 inline bool findNext(const T &t)
50 { while (i != c.constEnd()) if (*i++ == t) return true; return false; }
52 inline bool findPrevious(const T &t)
53 { while (i != c.constBegin()) if (*(--i) == t) return true;
54 return false; } \
55};
56
57#define Q_DECLARE_MUTABLE_SEQUENTIAL_ITERATOR(C) template
58
59 <class T> class
60 QMutable##C##Iterator \
61{
62 typedef typename Q##C<T>::iterator iterator;
63 typedef typename Q##C<T>::const_iterator const_iterator;
64 Q##C<T> *c;
65 iterator i, n;
66 inline bool item_exists() const { return const_iterator(n) != c->constEnd(); } public
67 :
68 inline QMutable##C##Iterator(Q##C<T> &container)
69 : c(&container)
70 { i = c->begin(); n = c->end(); }
71 inline QMutable##C##Iterator &operator=(Q##C<T> &container)
72 { c = &container; i = c->begin(); n = c->end(); return *this; }
73 inline void toFront() { i = c->begin(); n = c->end(); }
74 inline void toBack() { i = c->end(); n = i; }
75 inline bool hasNext() const { return c->constEnd() != const_iterator(i); }
76 inline T &next() { n = i++; return *n; }
77 inline T &peekNext() const { return *i; }
79 inline bool hasPrevious() const { return c->constBegin() != const_iterator(i); }
81 inline T &previous() { n = --i; return *n; }
83 inline T &peekPrevious() const { iterator p = i; return *--p; }
84 inline void remove()
85 { if (c->constEnd() != const_iterator(n)) { i = c->erase(n); n = c->end(); } }
86 inline void setValue(const T &t) const { if (c->constEnd() != const_iterator(n)) *n = t; }
87 inline T &value() { Q_ASSERT(item_exists()); return *n; }
88 inline const T &value() const { Q_ASSERT(item_exists()); return *n; }
89 inline void insert(const T &t) { n = i = c->insert(i, t); ++i; }
90 inline bool findNext(const T &t)
91 { while (c->constEnd() != const_iterator(n = i)) if (*i++ == t) return true; return false; }
93 inline bool findPrevious(const T &t)
94 { while (c->constBegin() != const_iterator(i)) if (*(n = --i) == t) return true;
95 n = c->end(); return false; } \
96};
97
98#define Q_DECLARE_ASSOCIATIVE_ITERATOR(C) template
99
100 <class Key, class T> class
101 Q##C##Iterator \
102{
103 typedef typename Q##C<Key,T>::const_iterator const_iterator;
104 Q##C<Key,T> c;
105 const_iterator i, n;
106 inline bool item_exists() const { return n != c.constEnd(); } public
107 :
108 typedef const_iterator Item;
109 inline Q##C##Iterator(const Q##C<Key,T> &container)
110 : c(container), i(c.constBegin()), n(c.constEnd()) {}
111 inline Q##C##Iterator &operator=(const Q##C<Key,T> &container)
112 { c = container; i = c.constBegin(); n = c.constEnd(); return *this; }
113 inline void toFront() { i = c.constBegin(); n = c.constEnd(); }
114 inline void toBack() { i = c.constEnd(); n = c.constEnd(); }
115 inline bool hasNext() const { return i != c.constEnd(); }
116 inline Item next() { n = i++; return n; }
117 inline Item peekNext() const { return i; }
119 inline bool hasPrevious() const { return i != c.constBegin(); }
121 inline Item previous() { n = --i; return n; }
123 inline Item peekPrevious() const { const_iterator p = i; return --p; }
124 inline const T &value() const { Q_ASSERT(item_exists()); return *n; }
125 inline const Key &key() const { Q_ASSERT(item_exists()); return n.key(); }
126 inline bool findNext(const T &t)
127 { while ((n = i) != c.constEnd()) if (*i++ == t) return true; return false; }
129 inline bool findPrevious(const T &t)
130 { while (i != c.constBegin()) if (*(n = --i) == t) return true;
131 n = c.constEnd(); return false; } \
132};
133
134#define Q_DECLARE_MUTABLE_ASSOCIATIVE_ITERATOR(C) template
135
136 <class Key, class T> class
137 QMutable##C##Iterator \
138{
139 typedef typename Q##C<Key,T>::iterator iterator;
140 typedef typename Q##C<Key,T>::const_iterator const_iterator;
141 Q##C<Key,T> *c;
142 iterator i, n;
143 inline bool item_exists() const { return const_iterator(n) != c->constEnd(); } public
144 :
145 typedef iterator Item;
146 inline QMutable##C##Iterator(Q##C<Key,T> &container)
147 : c(&container)
148 { i = c->begin(); n = c->end(); }
149 inline QMutable##C##Iterator &operator=(Q##C<Key,T> &container)
150 { c = &container; i = c->begin(); n = c->end(); return *this; }
151 inline void toFront() { i = c->begin(); n = c->end(); }
152 inline void toBack() { i = c->end(); n = c->end(); }
153 inline bool hasNext() const { return const_iterator(i) != c->constEnd(); }
154 inline Item next() { n = i++; return n; }
155 inline Item peekNext() const { return i; }
157 inline bool hasPrevious() const { return const_iterator(i) != c->constBegin(); }
159 inline Item previous() { n = --i; return n; }
161 inline Item peekPrevious() const { iterator p = i; return --p; }
162 inline void remove()
163 { if (const_iterator(n) != c->constEnd()) { i = c->erase(n); n = c->end(); } }
164 inline void setValue(const T &t) { if (const_iterator(n) != c->constEnd()) *n = t; }
165 inline T &value() { Q_ASSERT(item_exists()); return *n; }
166 inline const T &value() const { Q_ASSERT(item_exists()); return *n; }
167 inline const Key &key() const { Q_ASSERT(item_exists()); return n.key(); }
168 inline bool findNext(const T &t)
169 { while (const_iterator(n = i) != c->constEnd()) if (*i++ == t) return true; return false; }
171 inline bool findPrevious(const T &t)
172 { while (const_iterator(i) != c->constBegin()) if (*(n = --i) == t) return true;
173 n = c->end(); return false; } \
174};
175
176#define Q_DECLARE_ASSOCIATIVE_FORWARD_ITERATOR(C) template
177
178 <class Key, class T> class
179 Q##C##Iterator \
180{
181 typedef typename Q##C<Key,T>::const_iterator const_iterator;
182 Q##C<Key,T> c;
183 const_iterator i, n;
184 inline bool item_exists() const { return n != c.constEnd(); } public
185 :
186 typedef const_iterator Item;
187 inline Q##C##Iterator(const Q##C<Key,T> &container)
188 : c(container), i(c.constBegin()), n(c.constEnd()) {}
189 inline Q##C##Iterator &operator=(const Q##C<Key,T> &container)
190 { c = container; i = c.constBegin(); n = c.constEnd(); return *this; }
191 inline void toFront() { i = c.constBegin(); n = c.constEnd(); }
192 inline void toBack() { i = c.constEnd(); n = c.constEnd(); }
193 inline bool hasNext() const { return i != c.constEnd(); }
194 inline Item next() { n = i++; return n; }
195 inline Item peekNext() const { return i; }
196 inline const T &value() const { Q_ASSERT(item_exists()); return *n; }
197 inline const Key &key() const { Q_ASSERT(item_exists()); return n.key(); }
198 inline bool findNext(const T &t)
199 { while ((n = i) != c.constEnd()) if (*i++ == t) return true; return false; } \
200};
201
202#define Q_DECLARE_MUTABLE_ASSOCIATIVE_FORWARD_ITERATOR(C) template
203
204 <class Key, class T> class
205 QMutable##C##Iterator \
206{
207 typedef typename Q##C<Key,T>::iterator iterator;
208 typedef typename Q##C<Key,T>::const_iterator const_iterator;
209 Q##C<Key,T> *c;
210 iterator i, n;
211 inline bool item_exists() const { return const_iterator(n) != c->constEnd(); } public
212 :
213 typedef iterator Item;
214 inline QMutable##C##Iterator(Q##C<Key,T> &container)
215 : c(&container)
216 { i = c->begin(); n = c->end(); }
217 inline QMutable##C##Iterator &operator=(Q##C<Key,T> &container)
218 { c = &container; i = c->begin(); n = c->end(); return *this; }
219 inline void toFront() { i = c->begin(); n = c->end(); }
220 inline void toBack() { i = c->end(); n = c->end(); }
221 inline bool hasNext() const { return const_iterator(i) != c->constEnd(); }
222 inline Item next() { n = i++; return n; }
223 inline Item peekNext() const { return i; }
224 inline void remove()
225 { if (const_iterator(n) != c->constEnd()) { i = c->erase(n); n = c->end(); } }
226 inline void setValue(const T &t) { if (const_iterator(n) != c->constEnd()) *n = t; }
227 inline T &value() { Q_ASSERT(item_exists()); return *n; }
228 inline const T &value() const { Q_ASSERT(item_exists()); return *n; }
229 inline const Key &key() const { Q_ASSERT(item_exists()); return n.key(); }
230 inline bool findNext(const T &t)
231 { while (const_iterator(n = i) != c->constEnd()) if (*i++ == t) return true; return false; } \
232};
233
234
235#else // QT_NO_JAVA_STYLE_ITERATORS
236#define Q_DECLARE_SEQUENTIAL_ITERATOR(C)
237#define Q_DECLARE_MUTABLE_SEQUENTIAL_ITERATOR(C)
238#define Q_DECLARE_ASSOCIATIVE_ITERATOR(C)
239#define Q_DECLARE_MUTABLE_ASSOCIATIVE_ITERATOR(C)
240#define Q_DECLARE_ASSOCIATIVE_FORWARD_ITERATOR(C)
241#define Q_DECLARE_MUTABLE_ASSOCIATIVE_FORWARD_ITERATOR(C)
242#endif // QT_NO_JAVA_STYLE_ITERATORS
243
244namespace QtPrivate {
245
246template <typename Key, typename T, typename Iterator>
248{
249 static Key key(const Iterator &it) { return it.key(); }
250 static Key key(Iterator &it) { return it.key(); }
251 static T value(const Iterator &it) { return it.value(); }
252 static T value(Iterator &it) { return it.value(); }
253};
254
255} // namespace QtPrivate
256
257template <typename Key, typename T, class Iterator,
258 class Traits = QtPrivate::QDefaultKeyValues<Key, T, Iterator>>
260{
261public:
262 typedef typename Iterator::iterator_category iterator_category;
263 typedef typename Iterator::difference_type difference_type;
264 typedef std::pair<Key, T> value_type;
265 typedef const value_type &reference;
266
267 QKeyValueIterator() = default;
268 constexpr explicit QKeyValueIterator(Iterator o) noexcept(std::is_nothrow_move_constructible<Iterator>::value)
269 : i(std::move(o)) {}
270
271 std::pair<Key, T> operator*() const {
272 return std::pair<Key, T>(Traits::key(i), Traits::value(i));
273 }
274
276
277 pointer operator->() const {
278 return pointer{ std::pair<Key, T>(Traits::key(i), Traits::value(i)) };
279 }
280
281 friend bool operator==(QKeyValueIterator lhs, QKeyValueIterator rhs) noexcept { return lhs.i == rhs.i; }
282 friend bool operator!=(QKeyValueIterator lhs, QKeyValueIterator rhs) noexcept { return lhs.i != rhs.i; }
283
284 inline QKeyValueIterator &operator++() { ++i; return *this; }
285 inline QKeyValueIterator operator++(int) { return QKeyValueIterator(i++);}
286 inline QKeyValueIterator &operator--() { --i; return *this; }
287 inline QKeyValueIterator operator--(int) { return QKeyValueIterator(i--); }
288 Iterator base() const { return i; }
289
290private:
291 Iterator i;
292};
293
294namespace QtPrivate {
295
296template <typename Map>
298{
299protected:
300 Map m_map;
301 Map &map() { return m_map; }
302 const Map &map() const { return m_map; }
303public:
304 explicit QKeyValueRangeStorage(const Map &map) : m_map(map) {}
305 explicit QKeyValueRangeStorage(Map &&map) : m_map(std::move(map)) {}
306};
307
308template <typename Map>
310#ifdef __cpp_lib_ranges
311 : public std::ranges::view_base
312#endif
313{
314protected:
315 Map *m_map;
316 Map &map() { return *m_map; }
317 const Map &map() const { return *m_map; }
318public:
319 explicit QKeyValueRangeStorage(Map &map) : m_map(&map) {}
320};
321
322template <typename Map>
324{
325public:
327 auto begin() { return this->map().keyValueBegin(); }
328 auto begin() const { return this->map().keyValueBegin(); }
329 auto end() { return this->map().keyValueEnd(); }
330 auto end() const { return this->map().keyValueEnd(); }
331};
332
333} // namespace QtPrivate
334
335
336QT_END_NAMESPACE
337
338#endif // QITERATOR_H
Iterator::difference_type difference_type
Definition qiterator.h:263
constexpr QKeyValueIterator(Iterator o) noexcept(std::is_nothrow_move_constructible< Iterator >::value)
Definition qiterator.h:268
std::pair< Key, T > operator*() const
Definition qiterator.h:271
std::pair< Key, T > value_type
Definition qiterator.h:264
friend bool operator==(QKeyValueIterator lhs, QKeyValueIterator rhs) noexcept
Definition qiterator.h:281
QKeyValueIterator()=default
pointer operator->() const
Definition qiterator.h:277
QKeyValueIterator operator++(int)
Definition qiterator.h:285
Iterator::iterator_category iterator_category
Definition qiterator.h:262
QKeyValueIterator & operator--()
Definition qiterator.h:286
const value_type & reference
Definition qiterator.h:265
QKeyValueIterator operator--(int)
Definition qiterator.h:287
Iterator base() const
Definition qiterator.h:288
friend bool operator!=(QKeyValueIterator lhs, QKeyValueIterator rhs) noexcept
Definition qiterator.h:282
QKeyValueIterator & operator++()
Definition qiterator.h:284
QKeyValueRangeStorage(const Map &map)
Definition qiterator.h:304
#define Q_DISABLE_BACKWARD_ITERATOR
Definition qiterator.h:21
static T value(Iterator &it)
Definition qiterator.h:252
static Key key(const Iterator &it)
Definition qiterator.h:249
static T value(const Iterator &it)
Definition qiterator.h:251
static Key key(Iterator &it)
Definition qiterator.h:250