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

source code of include/boost/numeric/ublas/detail/iterator.hpp