Chris@16
|
1 //
|
Chris@16
|
2 // Copyright (c) 2000-2002
|
Chris@16
|
3 // Joerg Walter, Mathias Koch
|
Chris@16
|
4 //
|
Chris@16
|
5 // Distributed under the Boost Software License, Version 1.0. (See
|
Chris@16
|
6 // accompanying file LICENSE_1_0.txt or copy at
|
Chris@16
|
7 // http://www.boost.org/LICENSE_1_0.txt)
|
Chris@16
|
8 //
|
Chris@16
|
9 // The authors gratefully acknowledge the support of
|
Chris@16
|
10 // GeNeSys mbH & Co. KG in producing this work.
|
Chris@16
|
11 //
|
Chris@16
|
12
|
Chris@16
|
13 #ifndef _BOOST_UBLAS_ITERATOR_
|
Chris@16
|
14 #define _BOOST_UBLAS_ITERATOR_
|
Chris@16
|
15
|
Chris@16
|
16 #include <boost/numeric/ublas/exception.hpp>
|
Chris@16
|
17 #include <iterator>
|
Chris@16
|
18
|
Chris@16
|
19
|
Chris@16
|
20 namespace boost { namespace numeric { namespace ublas {
|
Chris@16
|
21
|
Chris@16
|
22 /** \brief Base class of all proxy classes that contain
|
Chris@16
|
23 * a (redirectable) reference to an immutable object.
|
Chris@16
|
24 *
|
Chris@16
|
25 * \param C the type of the container referred to
|
Chris@16
|
26 */
|
Chris@16
|
27 template<class C>
|
Chris@16
|
28 class container_const_reference:
|
Chris@16
|
29 private nonassignable {
|
Chris@16
|
30 public:
|
Chris@16
|
31 typedef C container_type;
|
Chris@16
|
32
|
Chris@16
|
33 BOOST_UBLAS_INLINE
|
Chris@16
|
34 container_const_reference ():
|
Chris@16
|
35 c_ (0) {}
|
Chris@16
|
36 BOOST_UBLAS_INLINE
|
Chris@16
|
37 container_const_reference (const container_type &c):
|
Chris@16
|
38 c_ (&c) {}
|
Chris@16
|
39
|
Chris@16
|
40 BOOST_UBLAS_INLINE
|
Chris@16
|
41 const container_type &operator () () const {
|
Chris@16
|
42 return *c_;
|
Chris@16
|
43 }
|
Chris@16
|
44
|
Chris@16
|
45 BOOST_UBLAS_INLINE
|
Chris@16
|
46 container_const_reference &assign (const container_type *c) {
|
Chris@16
|
47 c_ = c;
|
Chris@16
|
48 return *this;
|
Chris@16
|
49 }
|
Chris@16
|
50
|
Chris@16
|
51 // Closure comparison
|
Chris@16
|
52 BOOST_UBLAS_INLINE
|
Chris@16
|
53 bool same_closure (const container_const_reference &cr) const {
|
Chris@16
|
54 return c_ == cr.c_;
|
Chris@16
|
55 }
|
Chris@16
|
56
|
Chris@16
|
57 private:
|
Chris@16
|
58 const container_type *c_;
|
Chris@16
|
59 };
|
Chris@16
|
60
|
Chris@16
|
61 /** \brief Base class of all proxy classes that contain
|
Chris@16
|
62 * a (redirectable) reference to a mutable object.
|
Chris@16
|
63 *
|
Chris@16
|
64 * \param C the type of the container referred to
|
Chris@16
|
65 */
|
Chris@16
|
66 template<class C>
|
Chris@16
|
67 class container_reference:
|
Chris@16
|
68 private nonassignable {
|
Chris@16
|
69 public:
|
Chris@16
|
70 typedef C container_type;
|
Chris@16
|
71
|
Chris@16
|
72 BOOST_UBLAS_INLINE
|
Chris@16
|
73 container_reference ():
|
Chris@16
|
74 c_ (0) {}
|
Chris@16
|
75 BOOST_UBLAS_INLINE
|
Chris@16
|
76 container_reference (container_type &c):
|
Chris@16
|
77 c_ (&c) {}
|
Chris@16
|
78
|
Chris@16
|
79 BOOST_UBLAS_INLINE
|
Chris@16
|
80 container_type &operator () () const {
|
Chris@16
|
81 return *c_;
|
Chris@16
|
82 }
|
Chris@16
|
83
|
Chris@16
|
84 BOOST_UBLAS_INLINE
|
Chris@16
|
85 container_reference &assign (container_type *c) {
|
Chris@16
|
86 c_ = c;
|
Chris@16
|
87 return *this;
|
Chris@16
|
88 }
|
Chris@16
|
89
|
Chris@16
|
90 // Closure comparison
|
Chris@16
|
91 BOOST_UBLAS_INLINE
|
Chris@16
|
92 bool same_closure (const container_reference &cr) const {
|
Chris@16
|
93 return c_ == cr.c_;
|
Chris@16
|
94 }
|
Chris@16
|
95
|
Chris@16
|
96 private:
|
Chris@16
|
97 container_type *c_;
|
Chris@16
|
98 };
|
Chris@16
|
99
|
Chris@16
|
100 /** \brief Base class of all forward iterators.
|
Chris@16
|
101 *
|
Chris@16
|
102 * \param IC the iterator category
|
Chris@16
|
103 * \param I the derived iterator type
|
Chris@16
|
104 * \param T the value type
|
Chris@16
|
105 *
|
Chris@16
|
106 * The forward iterator can only proceed in one direction
|
Chris@16
|
107 * via the post increment operator.
|
Chris@16
|
108 */
|
Chris@16
|
109 template<class IC, class I, class T>
|
Chris@16
|
110 struct forward_iterator_base:
|
Chris@16
|
111 public std::iterator<IC, T> {
|
Chris@16
|
112 typedef I derived_iterator_type;
|
Chris@16
|
113 typedef T derived_value_type;
|
Chris@16
|
114
|
Chris@16
|
115 // Arithmetic
|
Chris@16
|
116 BOOST_UBLAS_INLINE
|
Chris@16
|
117 derived_iterator_type operator ++ (int) {
|
Chris@16
|
118 derived_iterator_type &d (*static_cast<const derived_iterator_type *> (this));
|
Chris@16
|
119 derived_iterator_type tmp (d);
|
Chris@16
|
120 ++ d;
|
Chris@16
|
121 return tmp;
|
Chris@16
|
122 }
|
Chris@16
|
123 BOOST_UBLAS_INLINE
|
Chris@16
|
124 friend derived_iterator_type operator ++ (derived_iterator_type &d, int) {
|
Chris@16
|
125 derived_iterator_type tmp (d);
|
Chris@16
|
126 ++ d;
|
Chris@16
|
127 return tmp;
|
Chris@16
|
128 }
|
Chris@16
|
129
|
Chris@16
|
130 // Comparison
|
Chris@16
|
131 BOOST_UBLAS_INLINE
|
Chris@16
|
132 bool operator != (const derived_iterator_type &it) const {
|
Chris@16
|
133 const derived_iterator_type *d = static_cast<const derived_iterator_type *> (this);
|
Chris@16
|
134 return ! (*d == it);
|
Chris@16
|
135 }
|
Chris@16
|
136 };
|
Chris@16
|
137
|
Chris@16
|
138 /** \brief Base class of all bidirectional iterators.
|
Chris@16
|
139 *
|
Chris@16
|
140 * \param IC the iterator category
|
Chris@16
|
141 * \param I the derived iterator type
|
Chris@16
|
142 * \param T the value type
|
Chris@16
|
143 *
|
Chris@16
|
144 * The bidirectional iterator can proceed in both directions
|
Chris@16
|
145 * via the post increment and post decrement operator.
|
Chris@16
|
146 */
|
Chris@16
|
147 template<class IC, class I, class T>
|
Chris@16
|
148 struct bidirectional_iterator_base:
|
Chris@16
|
149 public std::iterator<IC, T> {
|
Chris@16
|
150 typedef I derived_iterator_type;
|
Chris@16
|
151 typedef T derived_value_type;
|
Chris@16
|
152
|
Chris@16
|
153 // Arithmetic
|
Chris@16
|
154 BOOST_UBLAS_INLINE
|
Chris@16
|
155 derived_iterator_type operator ++ (int) {
|
Chris@16
|
156 derived_iterator_type &d (*static_cast<const derived_iterator_type *> (this));
|
Chris@16
|
157 derived_iterator_type tmp (d);
|
Chris@16
|
158 ++ d;
|
Chris@16
|
159 return tmp;
|
Chris@16
|
160 }
|
Chris@16
|
161 BOOST_UBLAS_INLINE
|
Chris@16
|
162 friend derived_iterator_type operator ++ (derived_iterator_type &d, int) {
|
Chris@16
|
163 derived_iterator_type tmp (d);
|
Chris@16
|
164 ++ d;
|
Chris@16
|
165 return tmp;
|
Chris@16
|
166 }
|
Chris@16
|
167 BOOST_UBLAS_INLINE
|
Chris@16
|
168 derived_iterator_type operator -- (int) {
|
Chris@16
|
169 derived_iterator_type &d (*static_cast<const derived_iterator_type *> (this));
|
Chris@16
|
170 derived_iterator_type tmp (d);
|
Chris@16
|
171 -- d;
|
Chris@16
|
172 return tmp;
|
Chris@16
|
173 }
|
Chris@16
|
174 BOOST_UBLAS_INLINE
|
Chris@16
|
175 friend derived_iterator_type operator -- (derived_iterator_type &d, int) {
|
Chris@16
|
176 derived_iterator_type tmp (d);
|
Chris@16
|
177 -- d;
|
Chris@16
|
178 return tmp;
|
Chris@16
|
179 }
|
Chris@16
|
180
|
Chris@16
|
181 // Comparison
|
Chris@16
|
182 BOOST_UBLAS_INLINE
|
Chris@16
|
183 bool operator != (const derived_iterator_type &it) const {
|
Chris@16
|
184 const derived_iterator_type *d = static_cast<const derived_iterator_type *> (this);
|
Chris@16
|
185 return ! (*d == it);
|
Chris@16
|
186 }
|
Chris@16
|
187 };
|
Chris@16
|
188
|
Chris@16
|
189 /** \brief Base class of all random access iterators.
|
Chris@16
|
190 *
|
Chris@16
|
191 * \param IC the iterator category
|
Chris@16
|
192 * \param I the derived iterator type
|
Chris@16
|
193 * \param T the value type
|
Chris@16
|
194 * \param D the difference type, default: std::ptrdiff_t
|
Chris@16
|
195 *
|
Chris@16
|
196 * The random access iterator can proceed in both directions
|
Chris@16
|
197 * via the post increment/decrement operator or in larger steps
|
Chris@16
|
198 * via the +, - and +=, -= operators. The random access iterator
|
Chris@16
|
199 * is LessThan Comparable.
|
Chris@16
|
200 */
|
Chris@16
|
201 template<class IC, class I, class T, class D = std::ptrdiff_t>
|
Chris@16
|
202 // ISSUE the default for D seems rather dangerous as it can easily be (silently) incorrect
|
Chris@16
|
203 struct random_access_iterator_base:
|
Chris@16
|
204 public std::iterator<IC, T> {
|
Chris@16
|
205 typedef I derived_iterator_type;
|
Chris@16
|
206 typedef T derived_value_type;
|
Chris@16
|
207 typedef D derived_difference_type;
|
Chris@16
|
208
|
Chris@16
|
209 /* FIXME Need to explicitly pass derived_reference_type as otherwise I undefined type or forward declared
|
Chris@16
|
210 typedef typename derived_iterator_type::reference derived_reference_type;
|
Chris@16
|
211 // Indexed element
|
Chris@16
|
212 BOOST_UBLAS_INLINE
|
Chris@16
|
213 derived_reference_type operator [] (derived_difference_type n) {
|
Chris@16
|
214 return *(*this + n);
|
Chris@16
|
215 }
|
Chris@16
|
216 */
|
Chris@16
|
217
|
Chris@16
|
218 // Arithmetic
|
Chris@16
|
219 BOOST_UBLAS_INLINE
|
Chris@16
|
220 derived_iterator_type operator ++ (int) {
|
Chris@16
|
221 derived_iterator_type &d (*static_cast<derived_iterator_type *> (this));
|
Chris@16
|
222 derived_iterator_type tmp (d);
|
Chris@16
|
223 ++ d;
|
Chris@16
|
224 return tmp;
|
Chris@16
|
225 }
|
Chris@16
|
226 BOOST_UBLAS_INLINE
|
Chris@16
|
227 friend derived_iterator_type operator ++ (derived_iterator_type &d, int) {
|
Chris@16
|
228 derived_iterator_type tmp (d);
|
Chris@16
|
229 ++ d;
|
Chris@16
|
230 return tmp;
|
Chris@16
|
231 }
|
Chris@16
|
232 BOOST_UBLAS_INLINE
|
Chris@16
|
233 derived_iterator_type operator -- (int) {
|
Chris@16
|
234 derived_iterator_type &d (*static_cast<derived_iterator_type *> (this));
|
Chris@16
|
235 derived_iterator_type tmp (d);
|
Chris@16
|
236 -- d;
|
Chris@16
|
237 return tmp;
|
Chris@16
|
238 }
|
Chris@16
|
239 BOOST_UBLAS_INLINE
|
Chris@16
|
240 friend derived_iterator_type operator -- (derived_iterator_type &d, int) {
|
Chris@16
|
241 derived_iterator_type tmp (d);
|
Chris@16
|
242 -- d;
|
Chris@16
|
243 return tmp;
|
Chris@16
|
244 }
|
Chris@16
|
245 BOOST_UBLAS_INLINE
|
Chris@16
|
246 derived_iterator_type operator + (derived_difference_type n) const {
|
Chris@16
|
247 derived_iterator_type tmp (*static_cast<const derived_iterator_type *> (this));
|
Chris@16
|
248 return tmp += n;
|
Chris@16
|
249 }
|
Chris@16
|
250 BOOST_UBLAS_INLINE
|
Chris@16
|
251 friend derived_iterator_type operator + (const derived_iterator_type &d, derived_difference_type n) {
|
Chris@16
|
252 derived_iterator_type tmp (d);
|
Chris@16
|
253 return tmp += n;
|
Chris@16
|
254 }
|
Chris@16
|
255 BOOST_UBLAS_INLINE
|
Chris@16
|
256 friend derived_iterator_type operator + (derived_difference_type n, const derived_iterator_type &d) {
|
Chris@16
|
257 derived_iterator_type tmp (d);
|
Chris@16
|
258 return tmp += n;
|
Chris@16
|
259 }
|
Chris@16
|
260 BOOST_UBLAS_INLINE
|
Chris@16
|
261 derived_iterator_type operator - (derived_difference_type n) const {
|
Chris@16
|
262 derived_iterator_type tmp (*static_cast<const derived_iterator_type *> (this));
|
Chris@16
|
263 return tmp -= n;
|
Chris@16
|
264 }
|
Chris@16
|
265 BOOST_UBLAS_INLINE
|
Chris@16
|
266 friend derived_iterator_type operator - (const derived_iterator_type &d, derived_difference_type n) {
|
Chris@16
|
267 derived_iterator_type tmp (d);
|
Chris@16
|
268 return tmp -= n;
|
Chris@16
|
269 }
|
Chris@16
|
270
|
Chris@16
|
271 // Comparison
|
Chris@16
|
272 BOOST_UBLAS_INLINE
|
Chris@16
|
273 bool operator != (const derived_iterator_type &it) const {
|
Chris@16
|
274 const derived_iterator_type *d = static_cast<const derived_iterator_type *> (this);
|
Chris@16
|
275 return ! (*d == it);
|
Chris@16
|
276 }
|
Chris@16
|
277 BOOST_UBLAS_INLINE
|
Chris@16
|
278 bool operator <= (const derived_iterator_type &it) const {
|
Chris@16
|
279 const derived_iterator_type *d = static_cast<const derived_iterator_type *> (this);
|
Chris@16
|
280 return ! (it < *d);
|
Chris@16
|
281 }
|
Chris@16
|
282 BOOST_UBLAS_INLINE
|
Chris@16
|
283 bool operator >= (const derived_iterator_type &it) const {
|
Chris@16
|
284 const derived_iterator_type *d = static_cast<const derived_iterator_type *> (this);
|
Chris@16
|
285 return ! (*d < it);
|
Chris@16
|
286 }
|
Chris@16
|
287 BOOST_UBLAS_INLINE
|
Chris@16
|
288 bool operator > (const derived_iterator_type &it) const {
|
Chris@16
|
289 const derived_iterator_type *d = static_cast<const derived_iterator_type *> (this);
|
Chris@16
|
290 return it < *d;
|
Chris@16
|
291 }
|
Chris@16
|
292 };
|
Chris@16
|
293
|
Chris@16
|
294 /** \brief Base class of all reverse iterators. (non-MSVC version)
|
Chris@16
|
295 *
|
Chris@16
|
296 * \param I the derived iterator type
|
Chris@16
|
297 * \param T the value type
|
Chris@16
|
298 * \param R the reference type
|
Chris@16
|
299 *
|
Chris@16
|
300 * The reverse iterator implements a bidirectional iterator
|
Chris@16
|
301 * reversing the elements of the underlying iterator. It
|
Chris@16
|
302 * implements most operators of a random access iterator.
|
Chris@16
|
303 *
|
Chris@16
|
304 * uBLAS extension: it.index()
|
Chris@16
|
305 */
|
Chris@16
|
306
|
Chris@16
|
307 // Renamed this class from reverse_iterator to get
|
Chris@16
|
308 // typedef reverse_iterator<...> reverse_iterator
|
Chris@16
|
309 // working. Thanks to Gabriel Dos Reis for explaining this.
|
Chris@16
|
310 template <class I>
|
Chris@16
|
311 class reverse_iterator_base:
|
Chris@16
|
312 public std::reverse_iterator<I> {
|
Chris@16
|
313 public:
|
Chris@16
|
314 typedef typename I::container_type container_type;
|
Chris@16
|
315 typedef typename container_type::size_type size_type;
|
Chris@16
|
316 typedef typename I::difference_type difference_type;
|
Chris@16
|
317 typedef I iterator_type;
|
Chris@16
|
318
|
Chris@16
|
319 // Construction and destruction
|
Chris@16
|
320 BOOST_UBLAS_INLINE
|
Chris@16
|
321 reverse_iterator_base ():
|
Chris@16
|
322 std::reverse_iterator<iterator_type> () {}
|
Chris@16
|
323 BOOST_UBLAS_INLINE
|
Chris@16
|
324 reverse_iterator_base (const iterator_type &it):
|
Chris@16
|
325 std::reverse_iterator<iterator_type> (it) {}
|
Chris@16
|
326
|
Chris@16
|
327 // Arithmetic
|
Chris@16
|
328 BOOST_UBLAS_INLINE
|
Chris@16
|
329 reverse_iterator_base &operator ++ () {
|
Chris@16
|
330 return *this = -- this->base ();
|
Chris@16
|
331 }
|
Chris@16
|
332 BOOST_UBLAS_INLINE
|
Chris@16
|
333 reverse_iterator_base operator ++ (int) {
|
Chris@16
|
334 reverse_iterator_base tmp (*this);
|
Chris@16
|
335 *this = -- this->base ();
|
Chris@16
|
336 return tmp;
|
Chris@16
|
337 }
|
Chris@16
|
338 BOOST_UBLAS_INLINE
|
Chris@16
|
339 reverse_iterator_base &operator -- () {
|
Chris@16
|
340 return *this = ++ this->base ();
|
Chris@16
|
341 }
|
Chris@16
|
342 BOOST_UBLAS_INLINE
|
Chris@16
|
343 reverse_iterator_base operator -- (int) {
|
Chris@16
|
344 reverse_iterator_base tmp (*this);
|
Chris@16
|
345 *this = ++ this->base ();
|
Chris@16
|
346 return tmp;
|
Chris@16
|
347 }
|
Chris@16
|
348 BOOST_UBLAS_INLINE
|
Chris@16
|
349 reverse_iterator_base &operator += (difference_type n) {
|
Chris@16
|
350 return *this = this->base () - n;
|
Chris@16
|
351 }
|
Chris@16
|
352 BOOST_UBLAS_INLINE
|
Chris@16
|
353 reverse_iterator_base &operator -= (difference_type n) {
|
Chris@16
|
354 return *this = this->base () + n;
|
Chris@16
|
355 }
|
Chris@16
|
356
|
Chris@16
|
357 BOOST_UBLAS_INLINE
|
Chris@16
|
358 friend reverse_iterator_base operator + (const reverse_iterator_base &it, difference_type n) {
|
Chris@16
|
359 reverse_iterator_base tmp (it);
|
Chris@16
|
360 return tmp += n;
|
Chris@16
|
361 }
|
Chris@16
|
362 BOOST_UBLAS_INLINE
|
Chris@16
|
363 friend reverse_iterator_base operator + (difference_type n, const reverse_iterator_base &it) {
|
Chris@16
|
364 reverse_iterator_base tmp (it);
|
Chris@16
|
365 return tmp += n;
|
Chris@16
|
366 }
|
Chris@16
|
367 BOOST_UBLAS_INLINE
|
Chris@16
|
368 friend reverse_iterator_base operator - (const reverse_iterator_base &it, difference_type n) {
|
Chris@16
|
369 reverse_iterator_base tmp (it);
|
Chris@16
|
370 return tmp -= n;
|
Chris@16
|
371 }
|
Chris@16
|
372 BOOST_UBLAS_INLINE
|
Chris@16
|
373 friend difference_type operator - (const reverse_iterator_base &it1, const reverse_iterator_base &it2) {
|
Chris@16
|
374 return it2.base () - it1.base ();
|
Chris@16
|
375 }
|
Chris@16
|
376
|
Chris@16
|
377 BOOST_UBLAS_INLINE
|
Chris@16
|
378 const container_type &operator () () const {
|
Chris@16
|
379 return this->base () ();
|
Chris@16
|
380 }
|
Chris@16
|
381
|
Chris@16
|
382 BOOST_UBLAS_INLINE
|
Chris@16
|
383 size_type index () const {
|
Chris@16
|
384 iterator_type tmp (this->base ());
|
Chris@16
|
385 return (-- tmp).index ();
|
Chris@16
|
386 }
|
Chris@16
|
387 };
|
Chris@16
|
388
|
Chris@16
|
389 /** \brief 1st base class of all matrix reverse iterators. (non-MSVC version)
|
Chris@16
|
390 *
|
Chris@16
|
391 * \param I the derived iterator type
|
Chris@16
|
392 *
|
Chris@16
|
393 * The reverse iterator implements a bidirectional iterator
|
Chris@16
|
394 * reversing the elements of the underlying iterator. It
|
Chris@16
|
395 * implements most operators of a random access iterator.
|
Chris@16
|
396 *
|
Chris@16
|
397 * uBLAS extension: it.index1(), it.index2() and access to
|
Chris@16
|
398 * the dual iterator via begin(), end(), rbegin(), rend()
|
Chris@16
|
399 */
|
Chris@16
|
400
|
Chris@16
|
401 // Renamed this class from reverse_iterator1 to get
|
Chris@16
|
402 // typedef reverse_iterator1<...> reverse_iterator1
|
Chris@16
|
403 // working. Thanks to Gabriel Dos Reis for explaining this.
|
Chris@16
|
404 template <class I>
|
Chris@16
|
405 class reverse_iterator_base1:
|
Chris@16
|
406 public std::reverse_iterator<I> {
|
Chris@16
|
407 public:
|
Chris@16
|
408 typedef typename I::container_type container_type;
|
Chris@16
|
409 typedef typename container_type::size_type size_type;
|
Chris@16
|
410 typedef typename I::difference_type difference_type;
|
Chris@16
|
411 typedef I iterator_type;
|
Chris@16
|
412 typedef typename I::dual_iterator_type dual_iterator_type;
|
Chris@16
|
413 typedef typename I::dual_reverse_iterator_type dual_reverse_iterator_type;
|
Chris@16
|
414
|
Chris@16
|
415 // Construction and destruction
|
Chris@16
|
416 BOOST_UBLAS_INLINE
|
Chris@16
|
417 reverse_iterator_base1 ():
|
Chris@16
|
418 std::reverse_iterator<iterator_type> () {}
|
Chris@16
|
419 BOOST_UBLAS_INLINE
|
Chris@16
|
420 reverse_iterator_base1 (const iterator_type &it):
|
Chris@16
|
421 std::reverse_iterator<iterator_type> (it) {}
|
Chris@16
|
422
|
Chris@16
|
423 // Arithmetic
|
Chris@16
|
424 BOOST_UBLAS_INLINE
|
Chris@16
|
425 reverse_iterator_base1 &operator ++ () {
|
Chris@16
|
426 return *this = -- this->base ();
|
Chris@16
|
427 }
|
Chris@16
|
428 BOOST_UBLAS_INLINE
|
Chris@16
|
429 reverse_iterator_base1 operator ++ (int) {
|
Chris@16
|
430 reverse_iterator_base1 tmp (*this);
|
Chris@16
|
431 *this = -- this->base ();
|
Chris@16
|
432 return tmp;
|
Chris@16
|
433 }
|
Chris@16
|
434 BOOST_UBLAS_INLINE
|
Chris@16
|
435 reverse_iterator_base1 &operator -- () {
|
Chris@16
|
436 return *this = ++ this->base ();
|
Chris@16
|
437 }
|
Chris@16
|
438 BOOST_UBLAS_INLINE
|
Chris@16
|
439 reverse_iterator_base1 operator -- (int) {
|
Chris@16
|
440 reverse_iterator_base1 tmp (*this);
|
Chris@16
|
441 *this = ++ this->base ();
|
Chris@16
|
442 return tmp;
|
Chris@16
|
443 }
|
Chris@16
|
444 BOOST_UBLAS_INLINE
|
Chris@16
|
445 reverse_iterator_base1 &operator += (difference_type n) {
|
Chris@16
|
446 return *this = this->base () - n;
|
Chris@16
|
447 }
|
Chris@16
|
448 BOOST_UBLAS_INLINE
|
Chris@16
|
449 reverse_iterator_base1 &operator -= (difference_type n) {
|
Chris@16
|
450 return *this = this->base () + n;
|
Chris@16
|
451 }
|
Chris@16
|
452
|
Chris@16
|
453 BOOST_UBLAS_INLINE
|
Chris@16
|
454 friend reverse_iterator_base1 operator + (const reverse_iterator_base1 &it, difference_type n) {
|
Chris@16
|
455 reverse_iterator_base1 tmp (it);
|
Chris@16
|
456 return tmp += n;
|
Chris@16
|
457 }
|
Chris@16
|
458 BOOST_UBLAS_INLINE
|
Chris@16
|
459 friend reverse_iterator_base1 operator + (difference_type n, const reverse_iterator_base1 &it) {
|
Chris@16
|
460 reverse_iterator_base1 tmp (it);
|
Chris@16
|
461 return tmp += n;
|
Chris@16
|
462 }
|
Chris@16
|
463 BOOST_UBLAS_INLINE
|
Chris@16
|
464 friend reverse_iterator_base1 operator - (const reverse_iterator_base1 &it, difference_type n) {
|
Chris@16
|
465 reverse_iterator_base1 tmp (it);
|
Chris@16
|
466 return tmp -= n;
|
Chris@16
|
467 }
|
Chris@16
|
468 BOOST_UBLAS_INLINE
|
Chris@16
|
469 friend difference_type operator - (const reverse_iterator_base1 &it1, const reverse_iterator_base1 &it2) {
|
Chris@16
|
470 return it2.base () - it1.base ();
|
Chris@16
|
471 }
|
Chris@16
|
472
|
Chris@16
|
473 BOOST_UBLAS_INLINE
|
Chris@16
|
474 const container_type &operator () () const {
|
Chris@16
|
475 return this->base () ();
|
Chris@16
|
476 }
|
Chris@16
|
477
|
Chris@16
|
478 BOOST_UBLAS_INLINE
|
Chris@16
|
479 size_type index1 () const {
|
Chris@16
|
480 iterator_type tmp (this->base ());
|
Chris@16
|
481 return (-- tmp).index1 ();
|
Chris@16
|
482 }
|
Chris@16
|
483 BOOST_UBLAS_INLINE
|
Chris@16
|
484 size_type index2 () const {
|
Chris@16
|
485 iterator_type tmp (this->base ());
|
Chris@16
|
486 return (-- tmp).index2 ();
|
Chris@16
|
487 }
|
Chris@16
|
488
|
Chris@16
|
489 BOOST_UBLAS_INLINE
|
Chris@16
|
490 dual_iterator_type begin () const {
|
Chris@16
|
491 iterator_type tmp (this->base ());
|
Chris@16
|
492 return (-- tmp).begin ();
|
Chris@16
|
493 }
|
Chris@16
|
494 BOOST_UBLAS_INLINE
|
Chris@16
|
495 dual_iterator_type end () const {
|
Chris@16
|
496 iterator_type tmp (this->base ());
|
Chris@16
|
497 return (-- tmp).end ();
|
Chris@16
|
498 }
|
Chris@16
|
499 BOOST_UBLAS_INLINE
|
Chris@16
|
500 dual_reverse_iterator_type rbegin () const {
|
Chris@16
|
501 return dual_reverse_iterator_type (end ());
|
Chris@16
|
502 }
|
Chris@16
|
503 BOOST_UBLAS_INLINE
|
Chris@16
|
504 dual_reverse_iterator_type rend () const {
|
Chris@16
|
505 return dual_reverse_iterator_type (begin ());
|
Chris@16
|
506 }
|
Chris@16
|
507 };
|
Chris@16
|
508
|
Chris@16
|
509 /** \brief 2nd base class of all matrix reverse iterators. (non-MSVC version)
|
Chris@16
|
510 *
|
Chris@16
|
511 * \param I the derived iterator type
|
Chris@16
|
512 *
|
Chris@16
|
513 * The reverse iterator implements a bidirectional iterator
|
Chris@16
|
514 * reversing the elements of the underlying iterator. It
|
Chris@16
|
515 * implements most operators of a random access iterator.
|
Chris@16
|
516 *
|
Chris@16
|
517 * uBLAS extension: it.index1(), it.index2() and access to
|
Chris@16
|
518 * the dual iterator via begin(), end(), rbegin(), rend()
|
Chris@16
|
519 *
|
Chris@16
|
520 * Note: this type is _identical_ to reverse_iterator_base1
|
Chris@16
|
521 */
|
Chris@16
|
522
|
Chris@16
|
523 // Renamed this class from reverse_iterator2 to get
|
Chris@16
|
524 // typedef reverse_iterator2<...> reverse_iterator2
|
Chris@16
|
525 // working. Thanks to Gabriel Dos Reis for explaining this.
|
Chris@16
|
526 template <class I>
|
Chris@16
|
527 class reverse_iterator_base2:
|
Chris@16
|
528 public std::reverse_iterator<I> {
|
Chris@16
|
529 public:
|
Chris@16
|
530 typedef typename I::container_type container_type;
|
Chris@16
|
531 typedef typename container_type::size_type size_type;
|
Chris@16
|
532 typedef typename I::difference_type difference_type;
|
Chris@16
|
533 typedef I iterator_type;
|
Chris@16
|
534 typedef typename I::dual_iterator_type dual_iterator_type;
|
Chris@16
|
535 typedef typename I::dual_reverse_iterator_type dual_reverse_iterator_type;
|
Chris@16
|
536
|
Chris@16
|
537 // Construction and destruction
|
Chris@16
|
538 BOOST_UBLAS_INLINE
|
Chris@16
|
539 reverse_iterator_base2 ():
|
Chris@16
|
540 std::reverse_iterator<iterator_type> () {}
|
Chris@16
|
541 BOOST_UBLAS_INLINE
|
Chris@16
|
542 reverse_iterator_base2 (const iterator_type &it):
|
Chris@16
|
543 std::reverse_iterator<iterator_type> (it) {}
|
Chris@16
|
544
|
Chris@16
|
545 // Arithmetic
|
Chris@16
|
546 BOOST_UBLAS_INLINE
|
Chris@16
|
547 reverse_iterator_base2 &operator ++ () {
|
Chris@16
|
548 return *this = -- this->base ();
|
Chris@16
|
549 }
|
Chris@16
|
550 BOOST_UBLAS_INLINE
|
Chris@16
|
551 reverse_iterator_base2 operator ++ (int) {
|
Chris@16
|
552 reverse_iterator_base2 tmp (*this);
|
Chris@16
|
553 *this = -- this->base ();
|
Chris@16
|
554 return tmp;
|
Chris@16
|
555 }
|
Chris@16
|
556 BOOST_UBLAS_INLINE
|
Chris@16
|
557 reverse_iterator_base2 &operator -- () {
|
Chris@16
|
558 return *this = ++ this->base ();
|
Chris@16
|
559 }
|
Chris@16
|
560 BOOST_UBLAS_INLINE
|
Chris@16
|
561 reverse_iterator_base2 operator -- (int) {
|
Chris@16
|
562 reverse_iterator_base2 tmp (*this);
|
Chris@16
|
563 *this = ++ this->base ();
|
Chris@16
|
564 return tmp;
|
Chris@16
|
565 }
|
Chris@16
|
566 BOOST_UBLAS_INLINE
|
Chris@16
|
567 reverse_iterator_base2 &operator += (difference_type n) {
|
Chris@16
|
568 return *this = this->base () - n;
|
Chris@16
|
569 }
|
Chris@16
|
570 BOOST_UBLAS_INLINE
|
Chris@16
|
571 reverse_iterator_base2 &operator -= (difference_type n) {
|
Chris@16
|
572 return *this = this->base () + n;
|
Chris@16
|
573 }
|
Chris@16
|
574
|
Chris@16
|
575 BOOST_UBLAS_INLINE
|
Chris@16
|
576 friend reverse_iterator_base2 operator + (const reverse_iterator_base2 &it, difference_type n) {
|
Chris@16
|
577 reverse_iterator_base2 tmp (it);
|
Chris@16
|
578 return tmp += n;
|
Chris@16
|
579 }
|
Chris@16
|
580 BOOST_UBLAS_INLINE
|
Chris@16
|
581 friend reverse_iterator_base2 operator + (difference_type n, const reverse_iterator_base2 &it) {
|
Chris@16
|
582 reverse_iterator_base2 tmp (it);
|
Chris@16
|
583 return tmp += n;
|
Chris@16
|
584 }
|
Chris@16
|
585 BOOST_UBLAS_INLINE
|
Chris@16
|
586 friend reverse_iterator_base2 operator - (const reverse_iterator_base2 &it, difference_type n) {
|
Chris@16
|
587 reverse_iterator_base2 tmp (it);
|
Chris@16
|
588 return tmp -= n;
|
Chris@16
|
589 }
|
Chris@16
|
590 BOOST_UBLAS_INLINE
|
Chris@16
|
591 friend difference_type operator - (const reverse_iterator_base2 &it1, const reverse_iterator_base2 &it2) {
|
Chris@16
|
592 return it2.base () - it1.base ();
|
Chris@16
|
593 }
|
Chris@16
|
594
|
Chris@16
|
595 BOOST_UBLAS_INLINE
|
Chris@16
|
596 const container_type &operator () () const {
|
Chris@16
|
597 return this->base () ();
|
Chris@16
|
598 }
|
Chris@16
|
599
|
Chris@16
|
600 BOOST_UBLAS_INLINE
|
Chris@16
|
601 size_type index1 () const {
|
Chris@16
|
602 iterator_type tmp (this->base ());
|
Chris@16
|
603 return (-- tmp).index1 ();
|
Chris@16
|
604 }
|
Chris@16
|
605 BOOST_UBLAS_INLINE
|
Chris@16
|
606 size_type index2 () const {
|
Chris@16
|
607 iterator_type tmp (this->base ());
|
Chris@16
|
608 return (-- tmp).index2 ();
|
Chris@16
|
609 }
|
Chris@16
|
610
|
Chris@16
|
611 BOOST_UBLAS_INLINE
|
Chris@16
|
612 dual_iterator_type begin () const {
|
Chris@16
|
613 iterator_type tmp (this->base ());
|
Chris@16
|
614 return (-- tmp).begin ();
|
Chris@16
|
615 }
|
Chris@16
|
616 BOOST_UBLAS_INLINE
|
Chris@16
|
617 dual_iterator_type end () const {
|
Chris@16
|
618 iterator_type tmp (this->base ());
|
Chris@16
|
619 return (-- tmp).end ();
|
Chris@16
|
620 }
|
Chris@16
|
621 BOOST_UBLAS_INLINE
|
Chris@16
|
622 dual_reverse_iterator_type rbegin () const {
|
Chris@16
|
623 return dual_reverse_iterator_type (end ());
|
Chris@16
|
624 }
|
Chris@16
|
625 BOOST_UBLAS_INLINE
|
Chris@16
|
626 dual_reverse_iterator_type rend () const {
|
Chris@16
|
627 return dual_reverse_iterator_type (begin ());
|
Chris@16
|
628 }
|
Chris@16
|
629 };
|
Chris@16
|
630
|
Chris@16
|
631 /** \brief A class implementing an indexed random access iterator.
|
Chris@16
|
632 *
|
Chris@16
|
633 * \param C the (mutable) container type
|
Chris@16
|
634 * \param IC the iterator category
|
Chris@16
|
635 *
|
Chris@16
|
636 * This class implements a random access iterator. The current
|
Chris@16
|
637 * position is stored as the unsigned integer it_ and the
|
Chris@16
|
638 * values are accessed via operator()(it_) of the container.
|
Chris@16
|
639 *
|
Chris@16
|
640 * uBLAS extension: index()
|
Chris@16
|
641 */
|
Chris@16
|
642
|
Chris@16
|
643 template<class C, class IC>
|
Chris@16
|
644 class indexed_iterator:
|
Chris@16
|
645 public container_reference<C>,
|
Chris@16
|
646 public random_access_iterator_base<IC,
|
Chris@16
|
647 indexed_iterator<C, IC>,
|
Chris@16
|
648 typename C::value_type,
|
Chris@16
|
649 typename C::difference_type> {
|
Chris@16
|
650 public:
|
Chris@16
|
651 typedef C container_type;
|
Chris@16
|
652 typedef IC iterator_category;
|
Chris@16
|
653 typedef typename container_type::size_type size_type;
|
Chris@16
|
654 typedef typename container_type::difference_type difference_type;
|
Chris@16
|
655 typedef typename container_type::value_type value_type;
|
Chris@16
|
656 typedef typename container_type::reference reference;
|
Chris@16
|
657
|
Chris@16
|
658 // Construction and destruction
|
Chris@16
|
659 BOOST_UBLAS_INLINE
|
Chris@16
|
660 indexed_iterator ():
|
Chris@16
|
661 container_reference<container_type> (), it_ () {}
|
Chris@16
|
662 BOOST_UBLAS_INLINE
|
Chris@16
|
663 indexed_iterator (container_type &c, size_type it):
|
Chris@16
|
664 container_reference<container_type> (c), it_ (it) {}
|
Chris@16
|
665
|
Chris@16
|
666 // Arithmetic
|
Chris@16
|
667 BOOST_UBLAS_INLINE
|
Chris@16
|
668 indexed_iterator &operator ++ () {
|
Chris@16
|
669 ++ it_;
|
Chris@16
|
670 return *this;
|
Chris@16
|
671 }
|
Chris@16
|
672 BOOST_UBLAS_INLINE
|
Chris@16
|
673 indexed_iterator &operator -- () {
|
Chris@16
|
674 -- it_;
|
Chris@16
|
675 return *this;
|
Chris@16
|
676 }
|
Chris@16
|
677 BOOST_UBLAS_INLINE
|
Chris@16
|
678 indexed_iterator &operator += (difference_type n) {
|
Chris@16
|
679 it_ += n;
|
Chris@16
|
680 return *this;
|
Chris@16
|
681 }
|
Chris@16
|
682 BOOST_UBLAS_INLINE
|
Chris@16
|
683 indexed_iterator &operator -= (difference_type n) {
|
Chris@16
|
684 it_ -= n;
|
Chris@16
|
685 return *this;
|
Chris@16
|
686 }
|
Chris@16
|
687 BOOST_UBLAS_INLINE
|
Chris@16
|
688 difference_type operator - (const indexed_iterator &it) const {
|
Chris@16
|
689 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
|
Chris@16
|
690 return it_ - it.it_;
|
Chris@16
|
691 }
|
Chris@16
|
692
|
Chris@16
|
693 // Dereference
|
Chris@16
|
694 BOOST_UBLAS_INLINE
|
Chris@16
|
695 reference operator * () const {
|
Chris@16
|
696 BOOST_UBLAS_CHECK (index () < (*this) ().size (), bad_index ());
|
Chris@16
|
697 return (*this) () (it_);
|
Chris@16
|
698 }
|
Chris@16
|
699 BOOST_UBLAS_INLINE
|
Chris@16
|
700 reference operator [] (difference_type n) const {
|
Chris@16
|
701 return *((*this) + n);
|
Chris@16
|
702 }
|
Chris@16
|
703
|
Chris@16
|
704 // Index
|
Chris@16
|
705 BOOST_UBLAS_INLINE
|
Chris@16
|
706 size_type index () const {
|
Chris@16
|
707 return it_;
|
Chris@16
|
708 }
|
Chris@16
|
709
|
Chris@16
|
710 // Assignment
|
Chris@16
|
711 BOOST_UBLAS_INLINE
|
Chris@16
|
712 indexed_iterator &operator = (const indexed_iterator &it) {
|
Chris@16
|
713 // FIX: ICC needs full qualification?!
|
Chris@16
|
714 // assign (&it ());
|
Chris@16
|
715 container_reference<C>::assign (&it ());
|
Chris@16
|
716 it_ = it.it_;
|
Chris@16
|
717 return *this;
|
Chris@16
|
718 }
|
Chris@16
|
719
|
Chris@16
|
720 // Comparison
|
Chris@16
|
721 BOOST_UBLAS_INLINE
|
Chris@16
|
722 bool operator == (const indexed_iterator &it) const {
|
Chris@16
|
723 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
|
Chris@16
|
724 return it_ == it.it_;
|
Chris@16
|
725 }
|
Chris@16
|
726 BOOST_UBLAS_INLINE
|
Chris@16
|
727 bool operator < (const indexed_iterator &it) const {
|
Chris@16
|
728 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
|
Chris@16
|
729 return it_ < it.it_;
|
Chris@16
|
730 }
|
Chris@16
|
731
|
Chris@16
|
732 private:
|
Chris@16
|
733 size_type it_;
|
Chris@16
|
734 };
|
Chris@16
|
735
|
Chris@16
|
736 /** \brief A class implementing an indexed random access iterator.
|
Chris@16
|
737 *
|
Chris@16
|
738 * \param C the (immutable) container type
|
Chris@16
|
739 * \param IC the iterator category
|
Chris@16
|
740 *
|
Chris@16
|
741 * This class implements a random access iterator. The current
|
Chris@16
|
742 * position is stored as the unsigned integer \c it_ and the
|
Chris@16
|
743 * values are accessed via \c operator()(it_) of the container.
|
Chris@16
|
744 *
|
Chris@16
|
745 * uBLAS extension: \c index()
|
Chris@16
|
746 *
|
Chris@16
|
747 * Note: there is an automatic conversion from
|
Chris@16
|
748 * \c indexed_iterator to \c indexed_const_iterator
|
Chris@16
|
749 */
|
Chris@16
|
750
|
Chris@16
|
751 template<class C, class IC>
|
Chris@16
|
752 class indexed_const_iterator:
|
Chris@16
|
753 public container_const_reference<C>,
|
Chris@16
|
754 public random_access_iterator_base<IC,
|
Chris@16
|
755 indexed_const_iterator<C, IC>,
|
Chris@16
|
756 typename C::value_type,
|
Chris@16
|
757 typename C::difference_type> {
|
Chris@16
|
758 public:
|
Chris@16
|
759 typedef C container_type;
|
Chris@16
|
760 typedef IC iterator_category;
|
Chris@16
|
761 typedef typename container_type::size_type size_type;
|
Chris@16
|
762 typedef typename container_type::difference_type difference_type;
|
Chris@16
|
763 typedef typename container_type::value_type value_type;
|
Chris@16
|
764 typedef typename container_type::const_reference reference;
|
Chris@16
|
765 typedef indexed_iterator<container_type, iterator_category> iterator_type;
|
Chris@16
|
766
|
Chris@16
|
767 // Construction and destruction
|
Chris@16
|
768 BOOST_UBLAS_INLINE
|
Chris@16
|
769 indexed_const_iterator ():
|
Chris@16
|
770 container_const_reference<container_type> (), it_ () {}
|
Chris@16
|
771 BOOST_UBLAS_INLINE
|
Chris@16
|
772 indexed_const_iterator (const container_type &c, size_type it):
|
Chris@16
|
773 container_const_reference<container_type> (c), it_ (it) {}
|
Chris@16
|
774 BOOST_UBLAS_INLINE
|
Chris@16
|
775 indexed_const_iterator (const iterator_type &it):
|
Chris@16
|
776 container_const_reference<container_type> (it ()), it_ (it.index ()) {}
|
Chris@16
|
777
|
Chris@16
|
778 // Arithmetic
|
Chris@16
|
779 BOOST_UBLAS_INLINE
|
Chris@16
|
780 indexed_const_iterator &operator ++ () {
|
Chris@16
|
781 ++ it_;
|
Chris@16
|
782 return *this;
|
Chris@16
|
783 }
|
Chris@16
|
784 BOOST_UBLAS_INLINE
|
Chris@16
|
785 indexed_const_iterator &operator -- () {
|
Chris@16
|
786 -- it_;
|
Chris@16
|
787 return *this;
|
Chris@16
|
788 }
|
Chris@16
|
789 BOOST_UBLAS_INLINE
|
Chris@16
|
790 indexed_const_iterator &operator += (difference_type n) {
|
Chris@16
|
791 it_ += n;
|
Chris@16
|
792 return *this;
|
Chris@16
|
793 }
|
Chris@16
|
794 BOOST_UBLAS_INLINE
|
Chris@16
|
795 indexed_const_iterator &operator -= (difference_type n) {
|
Chris@16
|
796 it_ -= n;
|
Chris@16
|
797 return *this;
|
Chris@16
|
798 }
|
Chris@16
|
799 BOOST_UBLAS_INLINE
|
Chris@16
|
800 difference_type operator - (const indexed_const_iterator &it) const {
|
Chris@16
|
801 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
|
Chris@16
|
802 return it_ - it.it_;
|
Chris@16
|
803 }
|
Chris@16
|
804
|
Chris@16
|
805 // Dereference
|
Chris@16
|
806 BOOST_UBLAS_INLINE
|
Chris@16
|
807 reference operator * () const {
|
Chris@16
|
808 BOOST_UBLAS_CHECK (index () < (*this) ().size (), bad_index ());
|
Chris@16
|
809 return (*this) () (it_);
|
Chris@16
|
810 }
|
Chris@16
|
811 BOOST_UBLAS_INLINE
|
Chris@16
|
812 reference operator [] (difference_type n) const {
|
Chris@16
|
813 return *((*this) + n);
|
Chris@16
|
814 }
|
Chris@16
|
815
|
Chris@16
|
816 // Index
|
Chris@16
|
817 BOOST_UBLAS_INLINE
|
Chris@16
|
818 size_type index () const {
|
Chris@16
|
819 return it_;
|
Chris@16
|
820 }
|
Chris@16
|
821
|
Chris@16
|
822 // Assignment
|
Chris@16
|
823 BOOST_UBLAS_INLINE
|
Chris@16
|
824 indexed_const_iterator &operator = (const indexed_const_iterator &it) {
|
Chris@16
|
825 // FIX: ICC needs full qualification?!
|
Chris@16
|
826 // assign (&it ());
|
Chris@16
|
827 container_const_reference<C>::assign (&it ());
|
Chris@16
|
828 it_ = it.it_;
|
Chris@16
|
829 return *this;
|
Chris@16
|
830 }
|
Chris@16
|
831
|
Chris@16
|
832 // Comparison
|
Chris@16
|
833 BOOST_UBLAS_INLINE
|
Chris@16
|
834 bool operator == (const indexed_const_iterator &it) const {
|
Chris@16
|
835 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
|
Chris@16
|
836 return it_ == it.it_;
|
Chris@16
|
837 }
|
Chris@16
|
838 BOOST_UBLAS_INLINE
|
Chris@16
|
839 bool operator < (const indexed_const_iterator &it) const {
|
Chris@16
|
840 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
|
Chris@16
|
841 return it_ < it.it_;
|
Chris@16
|
842 }
|
Chris@16
|
843
|
Chris@16
|
844 private:
|
Chris@16
|
845 size_type it_;
|
Chris@16
|
846
|
Chris@16
|
847 friend class indexed_iterator<container_type, iterator_category>;
|
Chris@16
|
848 };
|
Chris@16
|
849
|
Chris@16
|
850 template<class C, class IC>
|
Chris@16
|
851 class indexed_iterator2;
|
Chris@16
|
852
|
Chris@16
|
853 /** \brief A class implementing an indexed random access iterator
|
Chris@16
|
854 * of a matrix.
|
Chris@16
|
855 *
|
Chris@16
|
856 * \param C the (mutable) container type
|
Chris@16
|
857 * \param IC the iterator category
|
Chris@16
|
858 *
|
Chris@16
|
859 * This class implements a random access iterator. The current
|
Chris@16
|
860 * position is stored as two unsigned integers \c it1_ and \c it2_
|
Chris@16
|
861 * and the values are accessed via \c operator()(it1_, it2_) of the
|
Chris@16
|
862 * container. The iterator changes the first index.
|
Chris@16
|
863 *
|
Chris@16
|
864 * uBLAS extension: \c index1(), \c index2() and access to the
|
Chris@16
|
865 * dual iterator via \c begin(), \c end(), \c rbegin() and \c rend()
|
Chris@16
|
866 *
|
Chris@16
|
867 * Note: The container has to support the \code find2(rank, i, j) \endcode
|
Chris@16
|
868 * method
|
Chris@16
|
869 */
|
Chris@16
|
870
|
Chris@16
|
871 template<class C, class IC>
|
Chris@16
|
872 class indexed_iterator1:
|
Chris@16
|
873 public container_reference<C>,
|
Chris@16
|
874 public random_access_iterator_base<IC,
|
Chris@16
|
875 indexed_iterator1<C, IC>,
|
Chris@16
|
876 typename C::value_type,
|
Chris@16
|
877 typename C::difference_type> {
|
Chris@16
|
878 public:
|
Chris@16
|
879 typedef C container_type;
|
Chris@16
|
880 typedef IC iterator_category;
|
Chris@16
|
881 typedef typename container_type::size_type size_type;
|
Chris@16
|
882 typedef typename container_type::difference_type difference_type;
|
Chris@16
|
883 typedef typename container_type::value_type value_type;
|
Chris@16
|
884 typedef typename container_type::reference reference;
|
Chris@16
|
885
|
Chris@16
|
886 typedef indexed_iterator2<container_type, iterator_category> dual_iterator_type;
|
Chris@16
|
887 typedef reverse_iterator_base2<dual_iterator_type> dual_reverse_iterator_type;
|
Chris@16
|
888
|
Chris@16
|
889 // Construction and destruction
|
Chris@16
|
890 BOOST_UBLAS_INLINE
|
Chris@16
|
891 indexed_iterator1 ():
|
Chris@16
|
892 container_reference<container_type> (), it1_ (), it2_ () {}
|
Chris@16
|
893 BOOST_UBLAS_INLINE
|
Chris@16
|
894 indexed_iterator1 (container_type &c, size_type it1, size_type it2):
|
Chris@16
|
895 container_reference<container_type> (c), it1_ (it1), it2_ (it2) {}
|
Chris@16
|
896
|
Chris@16
|
897 // Arithmetic
|
Chris@16
|
898 BOOST_UBLAS_INLINE
|
Chris@16
|
899 indexed_iterator1 &operator ++ () {
|
Chris@16
|
900 ++ it1_;
|
Chris@16
|
901 return *this;
|
Chris@16
|
902 }
|
Chris@16
|
903 BOOST_UBLAS_INLINE
|
Chris@16
|
904 indexed_iterator1 &operator -- () {
|
Chris@16
|
905 -- it1_;
|
Chris@16
|
906 return *this;
|
Chris@16
|
907 }
|
Chris@16
|
908 BOOST_UBLAS_INLINE
|
Chris@16
|
909 indexed_iterator1 &operator += (difference_type n) {
|
Chris@16
|
910 it1_ += n;
|
Chris@16
|
911 return *this;
|
Chris@16
|
912 }
|
Chris@16
|
913 BOOST_UBLAS_INLINE
|
Chris@16
|
914 indexed_iterator1 &operator -= (difference_type n) {
|
Chris@16
|
915 it1_ -= n;
|
Chris@16
|
916 return *this;
|
Chris@16
|
917 }
|
Chris@16
|
918 BOOST_UBLAS_INLINE
|
Chris@16
|
919 difference_type operator - (const indexed_iterator1 &it) const {
|
Chris@16
|
920 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
|
Chris@16
|
921 BOOST_UBLAS_CHECK (it2_ == it.it2_, external_logic ());
|
Chris@16
|
922 return it1_ - it.it1_;
|
Chris@16
|
923 }
|
Chris@16
|
924
|
Chris@16
|
925 // Dereference
|
Chris@16
|
926 BOOST_UBLAS_INLINE
|
Chris@16
|
927 reference operator * () const {
|
Chris@16
|
928 BOOST_UBLAS_CHECK (index1 () < (*this) ().size1 (), bad_index ());
|
Chris@16
|
929 BOOST_UBLAS_CHECK (index2 () < (*this) ().size2 (), bad_index ());
|
Chris@16
|
930 return (*this) () (it1_, it2_);
|
Chris@16
|
931 }
|
Chris@16
|
932 BOOST_UBLAS_INLINE
|
Chris@16
|
933 reference operator [] (difference_type n) const {
|
Chris@16
|
934 return *((*this) + n);
|
Chris@16
|
935 }
|
Chris@16
|
936
|
Chris@16
|
937 // Index
|
Chris@16
|
938 BOOST_UBLAS_INLINE
|
Chris@16
|
939 size_type index1 () const {
|
Chris@16
|
940 return it1_;
|
Chris@16
|
941 }
|
Chris@16
|
942 BOOST_UBLAS_INLINE
|
Chris@16
|
943 size_type index2 () const {
|
Chris@16
|
944 return it2_;
|
Chris@16
|
945 }
|
Chris@16
|
946
|
Chris@16
|
947 BOOST_UBLAS_INLINE
|
Chris@16
|
948 dual_iterator_type begin () const {
|
Chris@16
|
949 return (*this) ().find2 (1, index1 (), 0);
|
Chris@16
|
950 }
|
Chris@16
|
951 BOOST_UBLAS_INLINE
|
Chris@16
|
952 dual_iterator_type end () const {
|
Chris@16
|
953 return (*this) ().find2 (1, index1 (), (*this) ().size2 ());
|
Chris@16
|
954 }
|
Chris@16
|
955 BOOST_UBLAS_INLINE
|
Chris@16
|
956 dual_reverse_iterator_type rbegin () const {
|
Chris@16
|
957 return dual_reverse_iterator_type (end ());
|
Chris@16
|
958 }
|
Chris@16
|
959 BOOST_UBLAS_INLINE
|
Chris@16
|
960 dual_reverse_iterator_type rend () const {
|
Chris@16
|
961 return dual_reverse_iterator_type (begin ());
|
Chris@16
|
962 }
|
Chris@16
|
963
|
Chris@16
|
964 // Assignment
|
Chris@16
|
965 BOOST_UBLAS_INLINE
|
Chris@16
|
966 indexed_iterator1 &operator = (const indexed_iterator1 &it) {
|
Chris@16
|
967 // FIX: ICC needs full qualification?!
|
Chris@16
|
968 // assign (&it ());
|
Chris@16
|
969 container_reference<C>::assign (&it ());
|
Chris@16
|
970 it1_ = it.it1_;
|
Chris@16
|
971 it2_ = it.it2_;
|
Chris@16
|
972 return *this;
|
Chris@16
|
973 }
|
Chris@16
|
974
|
Chris@16
|
975 // Comparison
|
Chris@16
|
976 BOOST_UBLAS_INLINE
|
Chris@16
|
977 bool operator == (const indexed_iterator1 &it) const {
|
Chris@16
|
978 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
|
Chris@16
|
979 BOOST_UBLAS_CHECK (it2_ == it.it2_, external_logic ());
|
Chris@16
|
980 return it1_ == it.it1_;
|
Chris@16
|
981 }
|
Chris@16
|
982 BOOST_UBLAS_INLINE
|
Chris@16
|
983 bool operator < (const indexed_iterator1 &it) const {
|
Chris@16
|
984 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
|
Chris@16
|
985 BOOST_UBLAS_CHECK (it2_ == it.it2_, external_logic ());
|
Chris@16
|
986 return it1_ < it.it1_;
|
Chris@16
|
987 }
|
Chris@16
|
988
|
Chris@16
|
989 private:
|
Chris@16
|
990 size_type it1_;
|
Chris@16
|
991 size_type it2_;
|
Chris@16
|
992 };
|
Chris@16
|
993
|
Chris@16
|
994 template<class C, class IC>
|
Chris@16
|
995 class indexed_const_iterator2;
|
Chris@16
|
996
|
Chris@16
|
997 /** \brief A class implementing an indexed random access iterator
|
Chris@16
|
998 * of a matrix.
|
Chris@16
|
999 *
|
Chris@16
|
1000 * \param C the (immutable) container type
|
Chris@16
|
1001 * \param IC the iterator category
|
Chris@16
|
1002 *
|
Chris@16
|
1003 * This class implements a random access iterator. The current
|
Chris@16
|
1004 * position is stored as two unsigned integers \c it1_ and \c it2_
|
Chris@16
|
1005 * and the values are accessed via \c operator()(it1_, it2_) of the
|
Chris@16
|
1006 * container. The iterator changes the first index.
|
Chris@16
|
1007 *
|
Chris@16
|
1008 * uBLAS extension: \c index1(), \c index2() and access to the
|
Chris@16
|
1009 * dual iterator via \c begin(), \c end(), \c rbegin() and \c rend()
|
Chris@16
|
1010 *
|
Chris@16
|
1011 * Note 1: The container has to support the find2(rank, i, j) method
|
Chris@16
|
1012 *
|
Chris@16
|
1013 * Note 2: there is an automatic conversion from
|
Chris@16
|
1014 * \c indexed_iterator1 to \c indexed_const_iterator1
|
Chris@16
|
1015 */
|
Chris@16
|
1016
|
Chris@16
|
1017 template<class C, class IC>
|
Chris@16
|
1018 class indexed_const_iterator1:
|
Chris@16
|
1019 public container_const_reference<C>,
|
Chris@16
|
1020 public random_access_iterator_base<IC,
|
Chris@16
|
1021 indexed_const_iterator1<C, IC>,
|
Chris@16
|
1022 typename C::value_type,
|
Chris@16
|
1023 typename C::difference_type> {
|
Chris@16
|
1024 public:
|
Chris@16
|
1025 typedef C container_type;
|
Chris@16
|
1026 typedef IC iterator_category;
|
Chris@16
|
1027 typedef typename container_type::size_type size_type;
|
Chris@16
|
1028 typedef typename container_type::difference_type difference_type;
|
Chris@16
|
1029 typedef typename container_type::value_type value_type;
|
Chris@16
|
1030 typedef typename container_type::const_reference reference;
|
Chris@16
|
1031
|
Chris@16
|
1032 typedef indexed_iterator1<container_type, iterator_category> iterator_type;
|
Chris@16
|
1033 typedef indexed_const_iterator2<container_type, iterator_category> dual_iterator_type;
|
Chris@16
|
1034 typedef reverse_iterator_base2<dual_iterator_type> dual_reverse_iterator_type;
|
Chris@16
|
1035
|
Chris@16
|
1036 // Construction and destruction
|
Chris@16
|
1037 BOOST_UBLAS_INLINE
|
Chris@16
|
1038 indexed_const_iterator1 ():
|
Chris@16
|
1039 container_const_reference<container_type> (), it1_ (), it2_ () {}
|
Chris@16
|
1040 BOOST_UBLAS_INLINE
|
Chris@16
|
1041 indexed_const_iterator1 (const container_type &c, size_type it1, size_type it2):
|
Chris@16
|
1042 container_const_reference<container_type> (c), it1_ (it1), it2_ (it2) {}
|
Chris@16
|
1043 BOOST_UBLAS_INLINE
|
Chris@16
|
1044 indexed_const_iterator1 (const iterator_type &it):
|
Chris@16
|
1045 container_const_reference<container_type> (it ()), it1_ (it.index1 ()), it2_ (it.index2 ()) {}
|
Chris@16
|
1046
|
Chris@16
|
1047 // Arithmetic
|
Chris@16
|
1048 BOOST_UBLAS_INLINE
|
Chris@16
|
1049 indexed_const_iterator1 &operator ++ () {
|
Chris@16
|
1050 ++ it1_;
|
Chris@16
|
1051 return *this;
|
Chris@16
|
1052 }
|
Chris@16
|
1053 BOOST_UBLAS_INLINE
|
Chris@16
|
1054 indexed_const_iterator1 &operator -- () {
|
Chris@16
|
1055 -- it1_;
|
Chris@16
|
1056 return *this;
|
Chris@16
|
1057 }
|
Chris@16
|
1058 BOOST_UBLAS_INLINE
|
Chris@16
|
1059 indexed_const_iterator1 &operator += (difference_type n) {
|
Chris@16
|
1060 it1_ += n;
|
Chris@16
|
1061 return *this;
|
Chris@16
|
1062 }
|
Chris@16
|
1063 BOOST_UBLAS_INLINE
|
Chris@16
|
1064 indexed_const_iterator1 &operator -= (difference_type n) {
|
Chris@16
|
1065 it1_ -= n;
|
Chris@16
|
1066 return *this;
|
Chris@16
|
1067 }
|
Chris@16
|
1068 BOOST_UBLAS_INLINE
|
Chris@16
|
1069 difference_type operator - (const indexed_const_iterator1 &it) const {
|
Chris@16
|
1070 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
|
Chris@16
|
1071 BOOST_UBLAS_CHECK (it2_ == it.it2_, external_logic ());
|
Chris@16
|
1072 return it1_ - it.it1_;
|
Chris@16
|
1073 }
|
Chris@16
|
1074
|
Chris@16
|
1075 // Dereference
|
Chris@16
|
1076 BOOST_UBLAS_INLINE
|
Chris@16
|
1077 reference operator * () const {
|
Chris@16
|
1078 BOOST_UBLAS_CHECK (index1 () < (*this) ().size1 (), bad_index ());
|
Chris@16
|
1079 BOOST_UBLAS_CHECK (index2 () < (*this) ().size2 (), bad_index ());
|
Chris@16
|
1080 return (*this) () (it1_, it2_);
|
Chris@16
|
1081 }
|
Chris@16
|
1082 BOOST_UBLAS_INLINE
|
Chris@16
|
1083 reference operator [] (difference_type n) const {
|
Chris@16
|
1084 return *((*this) + n);
|
Chris@16
|
1085 }
|
Chris@16
|
1086
|
Chris@16
|
1087 // Index
|
Chris@16
|
1088 BOOST_UBLAS_INLINE
|
Chris@16
|
1089 size_type index1 () const {
|
Chris@16
|
1090 return it1_;
|
Chris@16
|
1091 }
|
Chris@16
|
1092 BOOST_UBLAS_INLINE
|
Chris@16
|
1093 size_type index2 () const {
|
Chris@16
|
1094 return it2_;
|
Chris@16
|
1095 }
|
Chris@16
|
1096
|
Chris@16
|
1097 BOOST_UBLAS_INLINE
|
Chris@16
|
1098 dual_iterator_type begin () const {
|
Chris@16
|
1099 return (*this) ().find2 (1, index1 (), 0);
|
Chris@16
|
1100 }
|
Chris@16
|
1101 BOOST_UBLAS_INLINE
|
Chris@16
|
1102 dual_iterator_type end () const {
|
Chris@16
|
1103 return (*this) ().find2 (1, index1 (), (*this) ().size2 ());
|
Chris@16
|
1104 }
|
Chris@16
|
1105 BOOST_UBLAS_INLINE
|
Chris@16
|
1106 dual_reverse_iterator_type rbegin () const {
|
Chris@16
|
1107 return dual_reverse_iterator_type (end ());
|
Chris@16
|
1108 }
|
Chris@16
|
1109 BOOST_UBLAS_INLINE
|
Chris@16
|
1110 dual_reverse_iterator_type rend () const {
|
Chris@16
|
1111 return dual_reverse_iterator_type (begin ());
|
Chris@16
|
1112 }
|
Chris@16
|
1113
|
Chris@16
|
1114 // Assignment
|
Chris@16
|
1115 BOOST_UBLAS_INLINE
|
Chris@16
|
1116 indexed_const_iterator1 &operator = (const indexed_const_iterator1 &it) {
|
Chris@16
|
1117 // FIX: ICC needs full qualification?!
|
Chris@16
|
1118 // assign (&it ());
|
Chris@16
|
1119 container_const_reference<C>::assign (&it ());
|
Chris@16
|
1120 it1_ = it.it1_;
|
Chris@16
|
1121 it2_ = it.it2_;
|
Chris@16
|
1122 return *this;
|
Chris@16
|
1123 }
|
Chris@16
|
1124
|
Chris@16
|
1125 // Comparison
|
Chris@16
|
1126 BOOST_UBLAS_INLINE
|
Chris@16
|
1127 bool operator == (const indexed_const_iterator1 &it) const {
|
Chris@16
|
1128 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
|
Chris@16
|
1129 BOOST_UBLAS_CHECK (it2_ == it.it2_, external_logic ());
|
Chris@16
|
1130 return it1_ == it.it1_;
|
Chris@16
|
1131 }
|
Chris@16
|
1132 BOOST_UBLAS_INLINE
|
Chris@16
|
1133 bool operator < (const indexed_const_iterator1 &it) const {
|
Chris@16
|
1134 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
|
Chris@16
|
1135 BOOST_UBLAS_CHECK (it2_ == it.it2_, external_logic ());
|
Chris@16
|
1136 return it1_ < it.it1_;
|
Chris@16
|
1137 }
|
Chris@16
|
1138
|
Chris@16
|
1139 private:
|
Chris@16
|
1140 size_type it1_;
|
Chris@16
|
1141 size_type it2_;
|
Chris@16
|
1142
|
Chris@16
|
1143 friend class indexed_iterator1<container_type, iterator_category>;
|
Chris@16
|
1144 };
|
Chris@16
|
1145
|
Chris@16
|
1146 /** \brief A class implementing an indexed random access iterator
|
Chris@16
|
1147 * of a matrix.
|
Chris@16
|
1148 *
|
Chris@16
|
1149 * \param C the (mutable) container type
|
Chris@16
|
1150 * \param IC the iterator category
|
Chris@16
|
1151 *
|
Chris@16
|
1152 * This class implements a random access iterator. The current
|
Chris@16
|
1153 * position is stored as two unsigned integers \c it1_ and \c it2_
|
Chris@16
|
1154 * and the values are accessed via \c operator()(it1_, it2_) of the
|
Chris@16
|
1155 * container. The iterator changes the second index.
|
Chris@16
|
1156 *
|
Chris@16
|
1157 * uBLAS extension: \c index1(), \c index2() and access to the
|
Chris@16
|
1158 * dual iterator via \c begin(), \c end(), \c rbegin() and \c rend()
|
Chris@16
|
1159 *
|
Chris@16
|
1160 * Note: The container has to support the find1(rank, i, j) method
|
Chris@16
|
1161 */
|
Chris@16
|
1162 template<class C, class IC>
|
Chris@16
|
1163 class indexed_iterator2:
|
Chris@16
|
1164 public container_reference<C>,
|
Chris@16
|
1165 public random_access_iterator_base<IC,
|
Chris@16
|
1166 indexed_iterator2<C, IC>,
|
Chris@16
|
1167 typename C::value_type,
|
Chris@16
|
1168 typename C::difference_type> {
|
Chris@16
|
1169 public:
|
Chris@16
|
1170 typedef C container_type;
|
Chris@16
|
1171 typedef IC iterator_category;
|
Chris@16
|
1172 typedef typename container_type::size_type size_type;
|
Chris@16
|
1173 typedef typename container_type::difference_type difference_type;
|
Chris@16
|
1174 typedef typename container_type::value_type value_type;
|
Chris@16
|
1175 typedef typename container_type::reference reference;
|
Chris@16
|
1176
|
Chris@16
|
1177 typedef indexed_iterator1<container_type, iterator_category> dual_iterator_type;
|
Chris@16
|
1178 typedef reverse_iterator_base1<dual_iterator_type> dual_reverse_iterator_type;
|
Chris@16
|
1179
|
Chris@16
|
1180 // Construction and destruction
|
Chris@16
|
1181 BOOST_UBLAS_INLINE
|
Chris@16
|
1182 indexed_iterator2 ():
|
Chris@16
|
1183 container_reference<container_type> (), it1_ (), it2_ () {}
|
Chris@16
|
1184 BOOST_UBLAS_INLINE
|
Chris@16
|
1185 indexed_iterator2 (container_type &c, size_type it1, size_type it2):
|
Chris@16
|
1186 container_reference<container_type> (c), it1_ (it1), it2_ (it2) {}
|
Chris@16
|
1187
|
Chris@16
|
1188 // Arithmetic
|
Chris@16
|
1189 BOOST_UBLAS_INLINE
|
Chris@16
|
1190 indexed_iterator2 &operator ++ () {
|
Chris@16
|
1191 ++ it2_;
|
Chris@16
|
1192 return *this;
|
Chris@16
|
1193 }
|
Chris@16
|
1194 BOOST_UBLAS_INLINE
|
Chris@16
|
1195 indexed_iterator2 &operator -- () {
|
Chris@16
|
1196 -- it2_;
|
Chris@16
|
1197 return *this;
|
Chris@16
|
1198 }
|
Chris@16
|
1199 BOOST_UBLAS_INLINE
|
Chris@16
|
1200 indexed_iterator2 &operator += (difference_type n) {
|
Chris@16
|
1201 it2_ += n;
|
Chris@16
|
1202 return *this;
|
Chris@16
|
1203 }
|
Chris@16
|
1204 BOOST_UBLAS_INLINE
|
Chris@16
|
1205 indexed_iterator2 &operator -= (difference_type n) {
|
Chris@16
|
1206 it2_ -= n;
|
Chris@16
|
1207 return *this;
|
Chris@16
|
1208 }
|
Chris@16
|
1209 BOOST_UBLAS_INLINE
|
Chris@16
|
1210 difference_type operator - (const indexed_iterator2 &it) const {
|
Chris@16
|
1211 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
|
Chris@16
|
1212 BOOST_UBLAS_CHECK (it1_ == it.it1_, external_logic ());
|
Chris@16
|
1213 return it2_ - it.it2_;
|
Chris@16
|
1214 }
|
Chris@16
|
1215
|
Chris@16
|
1216 // Dereference
|
Chris@16
|
1217 BOOST_UBLAS_INLINE
|
Chris@16
|
1218 reference operator * () const {
|
Chris@16
|
1219 BOOST_UBLAS_CHECK (index1 () < (*this) ().size1 (), bad_index ());
|
Chris@16
|
1220 BOOST_UBLAS_CHECK (index2 () < (*this) ().size2 (), bad_index ());
|
Chris@16
|
1221 return (*this) () (it1_, it2_);
|
Chris@16
|
1222 }
|
Chris@16
|
1223 BOOST_UBLAS_INLINE
|
Chris@16
|
1224 reference operator [] (difference_type n) const {
|
Chris@16
|
1225 return *((*this) + n);
|
Chris@16
|
1226 }
|
Chris@16
|
1227
|
Chris@16
|
1228 // Index
|
Chris@16
|
1229 BOOST_UBLAS_INLINE
|
Chris@16
|
1230 size_type index1 () const {
|
Chris@16
|
1231 return it1_;
|
Chris@16
|
1232 }
|
Chris@16
|
1233 BOOST_UBLAS_INLINE
|
Chris@16
|
1234 size_type index2 () const {
|
Chris@16
|
1235 return it2_;
|
Chris@16
|
1236 }
|
Chris@16
|
1237
|
Chris@16
|
1238 BOOST_UBLAS_INLINE
|
Chris@16
|
1239 dual_iterator_type begin () const {
|
Chris@16
|
1240 return (*this) ().find1 (1, 0, index2 ());
|
Chris@16
|
1241 }
|
Chris@16
|
1242 BOOST_UBLAS_INLINE
|
Chris@16
|
1243 dual_iterator_type end () const {
|
Chris@16
|
1244 return (*this) ().find1 (1, (*this) ().size1 (), index2 ());
|
Chris@16
|
1245 }
|
Chris@16
|
1246 BOOST_UBLAS_INLINE
|
Chris@16
|
1247 dual_reverse_iterator_type rbegin () const {
|
Chris@16
|
1248 return dual_reverse_iterator_type (end ());
|
Chris@16
|
1249 }
|
Chris@16
|
1250 BOOST_UBLAS_INLINE
|
Chris@16
|
1251 dual_reverse_iterator_type rend () const {
|
Chris@16
|
1252 return dual_reverse_iterator_type (begin ());
|
Chris@16
|
1253 }
|
Chris@16
|
1254
|
Chris@16
|
1255 // Assignment
|
Chris@16
|
1256 BOOST_UBLAS_INLINE
|
Chris@16
|
1257 indexed_iterator2 &operator = (const indexed_iterator2 &it) {
|
Chris@16
|
1258 // FIX: ICC needs full qualification?!
|
Chris@16
|
1259 // assign (&it ());
|
Chris@16
|
1260 container_reference<C>::assign (&it ());
|
Chris@16
|
1261 it1_ = it.it1_;
|
Chris@16
|
1262 it2_ = it.it2_;
|
Chris@16
|
1263 return *this;
|
Chris@16
|
1264 }
|
Chris@16
|
1265
|
Chris@16
|
1266 // Comparison
|
Chris@16
|
1267 BOOST_UBLAS_INLINE
|
Chris@16
|
1268 bool operator == (const indexed_iterator2 &it) const {
|
Chris@16
|
1269 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
|
Chris@16
|
1270 BOOST_UBLAS_CHECK (it1_ == it.it1_, external_logic ());
|
Chris@16
|
1271 return it2_ == it.it2_;
|
Chris@16
|
1272 }
|
Chris@16
|
1273 BOOST_UBLAS_INLINE
|
Chris@16
|
1274 bool operator < (const indexed_iterator2 &it) const {
|
Chris@16
|
1275 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
|
Chris@16
|
1276 BOOST_UBLAS_CHECK (it1_ == it.it1_, external_logic ());
|
Chris@16
|
1277 return it2_ < it.it2_;
|
Chris@16
|
1278 }
|
Chris@16
|
1279
|
Chris@16
|
1280 private:
|
Chris@16
|
1281 size_type it1_;
|
Chris@16
|
1282 size_type it2_;
|
Chris@16
|
1283 };
|
Chris@16
|
1284
|
Chris@16
|
1285 /** \brief A class implementing an indexed random access iterator
|
Chris@16
|
1286 * of a matrix.
|
Chris@16
|
1287 *
|
Chris@16
|
1288 * \param C the (immutable) container type
|
Chris@16
|
1289 * \param IC the iterator category
|
Chris@16
|
1290 *
|
Chris@16
|
1291 * This class implements a random access iterator. The current
|
Chris@16
|
1292 * position is stored as two unsigned integers \c it1_ and \c it2_
|
Chris@16
|
1293 * and the values are accessed via \c operator()(it1_, it2_) of the
|
Chris@16
|
1294 * container. The iterator changes the second index.
|
Chris@16
|
1295 *
|
Chris@16
|
1296 * uBLAS extension: \c index1(), \c index2() and access to the
|
Chris@16
|
1297 * dual iterator via \c begin(), \c end(), \c rbegin() and \c rend()
|
Chris@16
|
1298 *
|
Chris@16
|
1299 * Note 1: The container has to support the \c find2(rank, i, j) method
|
Chris@16
|
1300 *
|
Chris@16
|
1301 * Note 2: there is an automatic conversion from
|
Chris@16
|
1302 * \c indexed_iterator2 to \c indexed_const_iterator2
|
Chris@16
|
1303 */
|
Chris@16
|
1304
|
Chris@16
|
1305 template<class C, class IC>
|
Chris@16
|
1306 class indexed_const_iterator2:
|
Chris@16
|
1307 public container_const_reference<C>,
|
Chris@16
|
1308 public random_access_iterator_base<IC,
|
Chris@16
|
1309 indexed_const_iterator2<C, IC>,
|
Chris@16
|
1310 typename C::value_type,
|
Chris@16
|
1311 typename C::difference_type> {
|
Chris@16
|
1312 public:
|
Chris@16
|
1313 typedef C container_type;
|
Chris@16
|
1314 typedef IC iterator_category;
|
Chris@16
|
1315 typedef typename container_type::size_type size_type;
|
Chris@16
|
1316 typedef typename container_type::difference_type difference_type;
|
Chris@16
|
1317 typedef typename container_type::value_type value_type;
|
Chris@16
|
1318 typedef typename container_type::const_reference reference;
|
Chris@16
|
1319
|
Chris@16
|
1320 typedef indexed_iterator2<container_type, iterator_category> iterator_type;
|
Chris@16
|
1321 typedef indexed_const_iterator1<container_type, iterator_category> dual_iterator_type;
|
Chris@16
|
1322 typedef reverse_iterator_base1<dual_iterator_type> dual_reverse_iterator_type;
|
Chris@16
|
1323
|
Chris@16
|
1324 // Construction and destruction
|
Chris@16
|
1325 BOOST_UBLAS_INLINE
|
Chris@16
|
1326 indexed_const_iterator2 ():
|
Chris@16
|
1327 container_const_reference<container_type> (), it1_ (), it2_ () {}
|
Chris@16
|
1328 BOOST_UBLAS_INLINE
|
Chris@16
|
1329 indexed_const_iterator2 (const container_type &c, size_type it1, size_type it2):
|
Chris@16
|
1330 container_const_reference<container_type> (c), it1_ (it1), it2_ (it2) {}
|
Chris@16
|
1331 BOOST_UBLAS_INLINE
|
Chris@16
|
1332 indexed_const_iterator2 (const iterator_type &it):
|
Chris@16
|
1333 container_const_reference<container_type> (it ()), it1_ (it.index1 ()), it2_ (it.index2 ()) {}
|
Chris@16
|
1334
|
Chris@16
|
1335 // Arithmetic
|
Chris@16
|
1336 BOOST_UBLAS_INLINE
|
Chris@16
|
1337 indexed_const_iterator2 &operator ++ () {
|
Chris@16
|
1338 ++ it2_;
|
Chris@16
|
1339 return *this;
|
Chris@16
|
1340 }
|
Chris@16
|
1341 BOOST_UBLAS_INLINE
|
Chris@16
|
1342 indexed_const_iterator2 &operator -- () {
|
Chris@16
|
1343 -- it2_;
|
Chris@16
|
1344 return *this;
|
Chris@16
|
1345 }
|
Chris@16
|
1346 BOOST_UBLAS_INLINE
|
Chris@16
|
1347 indexed_const_iterator2 &operator += (difference_type n) {
|
Chris@16
|
1348 it2_ += n;
|
Chris@16
|
1349 return *this;
|
Chris@16
|
1350 }
|
Chris@16
|
1351 BOOST_UBLAS_INLINE
|
Chris@16
|
1352 indexed_const_iterator2 &operator -= (difference_type n) {
|
Chris@16
|
1353 it2_ -= n;
|
Chris@16
|
1354 return *this;
|
Chris@16
|
1355 }
|
Chris@16
|
1356 BOOST_UBLAS_INLINE
|
Chris@16
|
1357 difference_type operator - (const indexed_const_iterator2 &it) const {
|
Chris@16
|
1358 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
|
Chris@16
|
1359 BOOST_UBLAS_CHECK (it1_ == it.it1_, external_logic ());
|
Chris@16
|
1360 return it2_ - it.it2_;
|
Chris@16
|
1361 }
|
Chris@16
|
1362
|
Chris@16
|
1363 // Dereference
|
Chris@16
|
1364 BOOST_UBLAS_INLINE
|
Chris@16
|
1365 reference operator * () const {
|
Chris@16
|
1366 BOOST_UBLAS_CHECK (index1 () < (*this) ().size1 (), bad_index ());
|
Chris@16
|
1367 BOOST_UBLAS_CHECK (index2 () < (*this) ().size2 (), bad_index ());
|
Chris@16
|
1368 return (*this) () (it1_, it2_);
|
Chris@16
|
1369 }
|
Chris@16
|
1370 BOOST_UBLAS_INLINE
|
Chris@16
|
1371 reference operator [] (difference_type n) const {
|
Chris@16
|
1372 return *((*this) + n);
|
Chris@16
|
1373 }
|
Chris@16
|
1374
|
Chris@16
|
1375 // Index
|
Chris@16
|
1376 BOOST_UBLAS_INLINE
|
Chris@16
|
1377 size_type index1 () const {
|
Chris@16
|
1378 return it1_;
|
Chris@16
|
1379 }
|
Chris@16
|
1380 BOOST_UBLAS_INLINE
|
Chris@16
|
1381 size_type index2 () const {
|
Chris@16
|
1382 return it2_;
|
Chris@16
|
1383 }
|
Chris@16
|
1384
|
Chris@16
|
1385 BOOST_UBLAS_INLINE
|
Chris@16
|
1386 dual_iterator_type begin () const {
|
Chris@16
|
1387 return (*this) ().find1 (1, 0, index2 ());
|
Chris@16
|
1388 }
|
Chris@16
|
1389 BOOST_UBLAS_INLINE
|
Chris@16
|
1390 dual_iterator_type end () const {
|
Chris@16
|
1391 return (*this) ().find1 (1, (*this) ().size1 (), index2 ());
|
Chris@16
|
1392 }
|
Chris@16
|
1393 BOOST_UBLAS_INLINE
|
Chris@16
|
1394 dual_reverse_iterator_type rbegin () const {
|
Chris@16
|
1395 return dual_reverse_iterator_type (end ());
|
Chris@16
|
1396 }
|
Chris@16
|
1397 BOOST_UBLAS_INLINE
|
Chris@16
|
1398 dual_reverse_iterator_type rend () const {
|
Chris@16
|
1399 return dual_reverse_iterator_type (begin ());
|
Chris@16
|
1400 }
|
Chris@16
|
1401
|
Chris@16
|
1402 // Assignment
|
Chris@16
|
1403 BOOST_UBLAS_INLINE
|
Chris@16
|
1404 indexed_const_iterator2 &operator = (const indexed_const_iterator2 &it) {
|
Chris@16
|
1405 // FIX: ICC needs full qualification?!
|
Chris@16
|
1406 // assign (&it ());
|
Chris@16
|
1407 container_const_reference<C>::assign (&it ());
|
Chris@16
|
1408 it1_ = it.it1_;
|
Chris@16
|
1409 it2_ = it.it2_;
|
Chris@16
|
1410 return *this;
|
Chris@16
|
1411 }
|
Chris@16
|
1412
|
Chris@16
|
1413 // Comparison
|
Chris@16
|
1414 BOOST_UBLAS_INLINE
|
Chris@16
|
1415 bool operator == (const indexed_const_iterator2 &it) const {
|
Chris@16
|
1416 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
|
Chris@16
|
1417 BOOST_UBLAS_CHECK (it1_ == it.it1_, external_logic ());
|
Chris@16
|
1418 return it2_ == it.it2_;
|
Chris@16
|
1419 }
|
Chris@16
|
1420 BOOST_UBLAS_INLINE
|
Chris@16
|
1421 bool operator < (const indexed_const_iterator2 &it) const {
|
Chris@16
|
1422 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
|
Chris@16
|
1423 BOOST_UBLAS_CHECK (it1_ == it.it1_, external_logic ());
|
Chris@16
|
1424 return it2_ < it.it2_;
|
Chris@16
|
1425 }
|
Chris@16
|
1426
|
Chris@16
|
1427 private:
|
Chris@16
|
1428 size_type it1_;
|
Chris@16
|
1429 size_type it2_;
|
Chris@16
|
1430
|
Chris@16
|
1431 friend class indexed_iterator2<container_type, iterator_category>;
|
Chris@16
|
1432 };
|
Chris@16
|
1433
|
Chris@16
|
1434 }}}
|
Chris@16
|
1435
|
Chris@16
|
1436 #endif
|