1/****************************************************************************
2**
3** Copyright (C) 2016 The Qt Company Ltd.
4** Contact: https://www.qt.io/licensing/
5**
6** This file is part of the QtCore module of the Qt Toolkit.
7**
8** $QT_BEGIN_LICENSE:LGPL$
9** Commercial License Usage
10** Licensees holding valid commercial Qt licenses may use this file in
11** accordance with the commercial license agreement provided with the
12** Software or, alternatively, in accordance with the terms contained in
13** a written agreement between you and The Qt Company. For licensing terms
14** and conditions see https://www.qt.io/terms-conditions. For further
15** information use the contact form at https://www.qt.io/contact-us.
16**
17** GNU Lesser General Public License Usage
18** Alternatively, this file may be used under the terms of the GNU Lesser
19** General Public License version 3 as published by the Free Software
20** Foundation and appearing in the file LICENSE.LGPL3 included in the
21** packaging of this file. Please review the following information to
22** ensure the GNU Lesser General Public License version 3 requirements
23** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
24**
25** GNU General Public License Usage
26** Alternatively, this file may be used under the terms of the GNU
27** General Public License version 2.0 or (at your option) the GNU General
28** Public license version 3 or any later version approved by the KDE Free
29** Qt Foundation. The licenses are as published by the Free Software
30** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
31** included in the packaging of this file. Please review the following
32** information to ensure the GNU General Public License requirements will
33** be met: https://www.gnu.org/licenses/gpl-2.0.html and
34** https://www.gnu.org/licenses/gpl-3.0.html.
35**
36** $QT_END_LICENSE$
37**
38****************************************************************************/
39
40#ifndef QITERATOR_H
41#define QITERATOR_H
42
43#include <QtCore/qglobal.h>
44
45QT_BEGIN_NAMESPACE
46
47#define Q_DECLARE_SEQUENTIAL_ITERATOR(C) \
48\
49template <class T> \
50class Q##C##Iterator \
51{ \
52 typedef typename Q##C<T>::const_iterator const_iterator; \
53 Q##C<T> c; \
54 const_iterator i; \
55public: \
56 inline Q##C##Iterator(const Q##C<T> &container) \
57 : c(container), i(c.constBegin()) {} \
58 inline Q##C##Iterator &operator=(const Q##C<T> &container) \
59 { c = container; i = c.constBegin(); return *this; } \
60 inline void toFront() { i = c.constBegin(); } \
61 inline void toBack() { i = c.constEnd(); } \
62 inline bool hasNext() const { return i != c.constEnd(); } \
63 inline const T &next() { return *i++; } \
64 inline const T &peekNext() const { return *i; } \
65 inline bool hasPrevious() const { return i != c.constBegin(); } \
66 inline const T &previous() { return *--i; } \
67 inline const T &peekPrevious() const { const_iterator p = i; return *--p; } \
68 inline bool findNext(const T &t) \
69 { while (i != c.constEnd()) if (*i++ == t) return true; return false; } \
70 inline bool findPrevious(const T &t) \
71 { while (i != c.constBegin()) if (*(--i) == t) return true; \
72 return false; } \
73};
74
75#define Q_DECLARE_MUTABLE_SEQUENTIAL_ITERATOR(C) \
76\
77template <class T> \
78class QMutable##C##Iterator \
79{ \
80 typedef typename Q##C<T>::iterator iterator; \
81 typedef typename Q##C<T>::const_iterator const_iterator; \
82 Q##C<T> *c; \
83 iterator i, n; \
84 inline bool item_exists() const { return const_iterator(n) != c->constEnd(); } \
85public: \
86 inline QMutable##C##Iterator(Q##C<T> &container) \
87 : c(&container) \
88 { i = c->begin(); n = c->end(); } \
89 inline QMutable##C##Iterator &operator=(Q##C<T> &container) \
90 { c = &container; i = c->begin(); n = c->end(); return *this; } \
91 inline void toFront() { i = c->begin(); n = c->end(); } \
92 inline void toBack() { i = c->end(); n = i; } \
93 inline bool hasNext() const { return c->constEnd() != const_iterator(i); } \
94 inline T &next() { n = i++; return *n; } \
95 inline T &peekNext() const { return *i; } \
96 inline bool hasPrevious() const { return c->constBegin() != const_iterator(i); } \
97 inline T &previous() { n = --i; return *n; } \
98 inline T &peekPrevious() const { iterator p = i; return *--p; } \
99 inline void remove() \
100 { if (c->constEnd() != const_iterator(n)) { i = c->erase(n); n = c->end(); } } \
101 inline void setValue(const T &t) const { if (c->constEnd() != const_iterator(n)) *n = t; } \
102 inline T &value() { Q_ASSERT(item_exists()); return *n; } \
103 inline const T &value() const { Q_ASSERT(item_exists()); return *n; } \
104 inline void insert(const T &t) { n = i = c->insert(i, t); ++i; } \
105 inline bool findNext(const T &t) \
106 { while (c->constEnd() != const_iterator(n = i)) if (*i++ == t) return true; return false; } \
107 inline bool findPrevious(const T &t) \
108 { while (c->constBegin() != const_iterator(i)) if (*(n = --i) == t) return true; \
109 n = c->end(); return false; } \
110};
111
112#define Q_DECLARE_ASSOCIATIVE_ITERATOR(C) \
113\
114template <class Key, class T> \
115class Q##C##Iterator \
116{ \
117 typedef typename Q##C<Key,T>::const_iterator const_iterator; \
118 typedef const_iterator Item; \
119 Q##C<Key,T> c; \
120 const_iterator i, n; \
121 inline bool item_exists() const { return n != c.constEnd(); } \
122public: \
123 inline Q##C##Iterator(const Q##C<Key,T> &container) \
124 : c(container), i(c.constBegin()), n(c.constEnd()) {} \
125 inline Q##C##Iterator &operator=(const Q##C<Key,T> &container) \
126 { c = container; i = c.constBegin(); n = c.constEnd(); return *this; } \
127 inline void toFront() { i = c.constBegin(); n = c.constEnd(); } \
128 inline void toBack() { i = c.constEnd(); n = c.constEnd(); } \
129 inline bool hasNext() const { return i != c.constEnd(); } \
130 inline Item next() { n = i++; return n; } \
131 inline Item peekNext() const { return i; } \
132 inline bool hasPrevious() const { return i != c.constBegin(); } \
133 inline Item previous() { n = --i; return n; } \
134 inline Item peekPrevious() const { const_iterator p = i; return --p; } \
135 inline const T &value() const { Q_ASSERT(item_exists()); return *n; } \
136 inline const Key &key() const { Q_ASSERT(item_exists()); return n.key(); } \
137 inline bool findNext(const T &t) \
138 { while ((n = i) != c.constEnd()) if (*i++ == t) return true; return false; } \
139 inline bool findPrevious(const T &t) \
140 { while (i != c.constBegin()) if (*(n = --i) == t) return true; \
141 n = c.constEnd(); return false; } \
142};
143
144#define Q_DECLARE_MUTABLE_ASSOCIATIVE_ITERATOR(C) \
145\
146template <class Key, class T> \
147class QMutable##C##Iterator \
148{ \
149 typedef typename Q##C<Key,T>::iterator iterator; \
150 typedef typename Q##C<Key,T>::const_iterator const_iterator; \
151 typedef iterator Item; \
152 Q##C<Key,T> *c; \
153 iterator i, n; \
154 inline bool item_exists() const { return const_iterator(n) != c->constEnd(); } \
155public: \
156 inline QMutable##C##Iterator(Q##C<Key,T> &container) \
157 : c(&container) \
158 { i = c->begin(); n = c->end(); } \
159 inline QMutable##C##Iterator &operator=(Q##C<Key,T> &container) \
160 { c = &container; i = c->begin(); n = c->end(); return *this; } \
161 inline void toFront() { i = c->begin(); n = c->end(); } \
162 inline void toBack() { i = c->end(); n = c->end(); } \
163 inline bool hasNext() const { return const_iterator(i) != c->constEnd(); } \
164 inline Item next() { n = i++; return n; } \
165 inline Item peekNext() const { return i; } \
166 inline bool hasPrevious() const { return const_iterator(i) != c->constBegin(); } \
167 inline Item previous() { n = --i; return n; } \
168 inline Item peekPrevious() const { iterator p = i; return --p; } \
169 inline void remove() \
170 { if (const_iterator(n) != c->constEnd()) { i = c->erase(n); n = c->end(); } } \
171 inline void setValue(const T &t) { if (const_iterator(n) != c->constEnd()) *n = t; } \
172 inline T &value() { Q_ASSERT(item_exists()); return *n; } \
173 inline const T &value() const { Q_ASSERT(item_exists()); return *n; } \
174 inline const Key &key() const { Q_ASSERT(item_exists()); return n.key(); } \
175 inline bool findNext(const T &t) \
176 { while (const_iterator(n = i) != c->constEnd()) if (*i++ == t) return true; return false; } \
177 inline bool findPrevious(const T &t) \
178 { while (const_iterator(i) != c->constBegin()) if (*(n = --i) == t) return true; \
179 n = c->end(); return false; } \
180};
181
182template<typename Key, typename T, class Iterator>
183class QKeyValueIterator
184{
185public:
186 typedef typename Iterator::iterator_category iterator_category;
187 typedef typename Iterator::difference_type difference_type;
188 typedef std::pair<Key, T> value_type;
189 typedef const value_type *pointer;
190 typedef const value_type &reference;
191
192 QKeyValueIterator() = default;
193 Q_DECL_CONSTEXPR explicit QKeyValueIterator(Iterator o) Q_DECL_NOEXCEPT_EXPR(std::is_nothrow_move_constructible<Iterator>::value)
194 : i(std::move(o)) {}
195
196 std::pair<Key, T> operator*() const {
197 return std::pair<Key, T>(i.key(), i.value());
198 }
199
200 friend bool operator==(QKeyValueIterator lhs, QKeyValueIterator rhs) Q_DECL_NOEXCEPT { return lhs.i == rhs.i; }
201 friend bool operator!=(QKeyValueIterator lhs, QKeyValueIterator rhs) Q_DECL_NOEXCEPT { return lhs.i != rhs.i; }
202
203 inline QKeyValueIterator &operator++() { ++i; return *this; }
204 inline QKeyValueIterator operator++(int) { return QKeyValueIterator(i++);}
205 inline QKeyValueIterator &operator--() { --i; return *this; }
206 inline QKeyValueIterator operator--(int) { return QKeyValueIterator(i--); }
207 Iterator base() const { return i; }
208
209private:
210 Iterator i;
211};
212
213QT_END_NAMESPACE
214
215#endif // QITERATOR_H
216