1/****************************************************************************
2**
3** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
4** Contact: http://www.qt-project.org/
5**
6** This file is part of the QtCore module of the Qt Toolkit.
7**
8** $QT_BEGIN_LICENSE:LGPL$
9** GNU Lesser General Public License Usage
10** This file may be used under the terms of the GNU Lesser General Public
11** License version 2.1 as published by the Free Software Foundation and
12** appearing in the file LICENSE.LGPL included in the packaging of this
13** file. Please review the following information to ensure the GNU Lesser
14** General Public License version 2.1 requirements will be met:
15** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
16**
17** In addition, as a special exception, Nokia gives you certain additional
18** rights. These rights are described in the Nokia Qt LGPL Exception
19** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
20**
21** GNU General Public License Usage
22** Alternatively, this file may be used under the terms of the GNU General
23** Public License version 3.0 as published by the Free Software Foundation
24** and appearing in the file LICENSE.GPL included in the packaging of this
25** file. Please review the following information to ensure the GNU General
26** Public License version 3.0 requirements will be met:
27** http://www.gnu.org/copyleft/gpl.html.
28**
29** Other Usage
30** Alternatively, this file may be used in accordance with the terms and
31** conditions contained in a signed written agreement between you and Nokia.
32**
33**
34**
35**
36**
37**
38** $QT_END_LICENSE$
39**
40****************************************************************************/
41
42#ifndef QITERATOR_H
43#define QITERATOR_H
44
45#include <QtCore/qglobal.h>
46
47QT_BEGIN_HEADER
48
49#ifdef QT_NO_STL
50namespace std {
51 struct bidirectional_iterator_tag;
52 struct random_access_iterator_tag;
53}
54#endif
55
56QT_BEGIN_NAMESPACE
57
58QT_MODULE(Core)
59
60#define Q_DECLARE_SEQUENTIAL_ITERATOR(C) \
61\
62template <class T> \
63class Q##C##Iterator \
64{ \
65 typedef typename Q##C<T>::const_iterator const_iterator; \
66 Q##C<T> c; \
67 const_iterator i; \
68public: \
69 inline Q##C##Iterator(const Q##C<T> &container) \
70 : c(container), i(c.constBegin()) {} \
71 inline Q##C##Iterator &operator=(const Q##C<T> &container) \
72 { c = container; i = c.constBegin(); return *this; } \
73 inline void toFront() { i = c.constBegin(); } \
74 inline void toBack() { i = c.constEnd(); } \
75 inline bool hasNext() const { return i != c.constEnd(); } \
76 inline const T &next() { return *i++; } \
77 inline const T &peekNext() const { return *i; } \
78 inline bool hasPrevious() const { return i != c.constBegin(); } \
79 inline const T &previous() { return *--i; } \
80 inline const T &peekPrevious() const { const_iterator p = i; return *--p; } \
81 inline bool findNext(const T &t) \
82 { while (i != c.constEnd()) if (*i++ == t) return true; return false; } \
83 inline bool findPrevious(const T &t) \
84 { while (i != c.constBegin()) if (*(--i) == t) return true; \
85 return false; } \
86};
87
88#define Q_DECLARE_MUTABLE_SEQUENTIAL_ITERATOR(C) \
89\
90template <class T> \
91class QMutable##C##Iterator \
92{ \
93 typedef typename Q##C<T>::iterator iterator; \
94 typedef typename Q##C<T>::const_iterator const_iterator; \
95 Q##C<T> *c; \
96 iterator i, n; \
97 inline bool item_exists() const { return const_iterator(n) != c->constEnd(); } \
98public: \
99 inline QMutable##C##Iterator(Q##C<T> &container) \
100 : c(&container) \
101 { c->setSharable(false); i = c->begin(); n = c->end(); } \
102 inline ~QMutable##C##Iterator() \
103 { c->setSharable(true); } \
104 inline QMutable##C##Iterator &operator=(Q##C<T> &container) \
105 { c->setSharable(true); c = &container; c->setSharable(false); \
106 i = c->begin(); n = c->end(); return *this; } \
107 inline void toFront() { i = c->begin(); n = c->end(); } \
108 inline void toBack() { i = c->end(); n = i; } \
109 inline bool hasNext() const { return c->constEnd() != const_iterator(i); } \
110 inline T &next() { n = i++; return *n; } \
111 inline T &peekNext() const { return *i; } \
112 inline bool hasPrevious() const { return c->constBegin() != const_iterator(i); } \
113 inline T &previous() { n = --i; return *n; } \
114 inline T &peekPrevious() const { iterator p = i; return *--p; } \
115 inline void remove() \
116 { if (c->constEnd() != const_iterator(n)) { i = c->erase(n); n = c->end(); } } \
117 inline void setValue(const T &t) const { if (c->constEnd() != const_iterator(n)) *n = t; } \
118 inline T &value() { Q_ASSERT(item_exists()); return *n; } \
119 inline const T &value() const { Q_ASSERT(item_exists()); return *n; } \
120 inline void insert(const T &t) { n = i = c->insert(i, t); ++i; } \
121 inline bool findNext(const T &t) \
122 { while (c->constEnd() != const_iterator(n = i)) if (*i++ == t) return true; return false; } \
123 inline bool findPrevious(const T &t) \
124 { while (c->constBegin() != const_iterator(i)) if (*(n = --i) == t) return true; \
125 n = c->end(); return false; } \
126};
127
128#define Q_DECLARE_ASSOCIATIVE_ITERATOR(C) \
129\
130template <class Key, class T> \
131class Q##C##Iterator \
132{ \
133 typedef typename Q##C<Key,T>::const_iterator const_iterator; \
134 typedef const_iterator Item; \
135 Q##C<Key,T> c; \
136 const_iterator i, n; \
137 inline bool item_exists() const { return n != c.constEnd(); } \
138public: \
139 inline Q##C##Iterator(const Q##C<Key,T> &container) \
140 : c(container), i(c.constBegin()), n(c.constEnd()) {} \
141 inline Q##C##Iterator &operator=(const Q##C<Key,T> &container) \
142 { c = container; i = c.constBegin(); n = c.constEnd(); return *this; } \
143 inline void toFront() { i = c.constBegin(); n = c.constEnd(); } \
144 inline void toBack() { i = c.constEnd(); n = c.constEnd(); } \
145 inline bool hasNext() const { return i != c.constEnd(); } \
146 inline Item next() { n = i++; return n; } \
147 inline Item peekNext() const { return i; } \
148 inline bool hasPrevious() const { return i != c.constBegin(); } \
149 inline Item previous() { n = --i; return n; } \
150 inline Item peekPrevious() const { const_iterator p = i; return --p; } \
151 inline const T &value() const { Q_ASSERT(item_exists()); return *n; } \
152 inline const Key &key() const { Q_ASSERT(item_exists()); return n.key(); } \
153 inline bool findNext(const T &t) \
154 { while ((n = i) != c.constEnd()) if (*i++ == t) return true; return false; } \
155 inline bool findPrevious(const T &t) \
156 { while (i != c.constBegin()) if (*(n = --i) == t) return true; \
157 n = c.constEnd(); return false; } \
158};
159
160#define Q_DECLARE_MUTABLE_ASSOCIATIVE_ITERATOR(C) \
161\
162template <class Key, class T> \
163class QMutable##C##Iterator \
164{ \
165 typedef typename Q##C<Key,T>::iterator iterator; \
166 typedef typename Q##C<Key,T>::const_iterator const_iterator; \
167 typedef iterator Item; \
168 Q##C<Key,T> *c; \
169 iterator i, n; \
170 inline bool item_exists() const { return const_iterator(n) != c->constEnd(); } \
171public: \
172 inline QMutable##C##Iterator(Q##C<Key,T> &container) \
173 : c(&container) \
174 { c->setSharable(false); i = c->begin(); n = c->end(); } \
175 inline ~QMutable##C##Iterator() \
176 { c->setSharable(true); } \
177 inline QMutable##C##Iterator &operator=(Q##C<Key,T> &container) \
178 { c->setSharable(true); c = &container; c->setSharable(false); i = c->begin(); n = c->end(); return *this; } \
179 inline void toFront() { i = c->begin(); n = c->end(); } \
180 inline void toBack() { i = c->end(); n = c->end(); } \
181 inline bool hasNext() const { return const_iterator(i) != c->constEnd(); } \
182 inline Item next() { n = i++; return n; } \
183 inline Item peekNext() const { return i; } \
184 inline bool hasPrevious() const { return const_iterator(i) != c->constBegin(); } \
185 inline Item previous() { n = --i; return n; } \
186 inline Item peekPrevious() const { iterator p = i; return --p; } \
187 inline void remove() \
188 { if (const_iterator(n) != c->constEnd()) { i = c->erase(n); n = c->end(); } } \
189 inline void setValue(const T &t) { if (const_iterator(n) != c->constEnd()) *n = t; } \
190 inline T &value() { Q_ASSERT(item_exists()); return *n; } \
191 inline const T &value() const { Q_ASSERT(item_exists()); return *n; } \
192 inline const Key &key() const { Q_ASSERT(item_exists()); return n.key(); } \
193 inline bool findNext(const T &t) \
194 { while (const_iterator(n = i) != c->constEnd()) if (*i++ == t) return true; return false; } \
195 inline bool findPrevious(const T &t) \
196 { while (const_iterator(i) != c->constBegin()) if (*(n = --i) == t) return true; \
197 n = c->end(); return false; } \
198};
199
200QT_END_NAMESPACE
201
202QT_END_HEADER
203
204#endif // QITERATOR_H
205