source: XIOS/dev/dev_olga/src/extern/boost/include/boost/numeric/ublas/detail/iterator.hpp @ 1022

Last change on this file since 1022 was 1022, checked in by mhnguyen, 7 years ago
File size: 49.2 KB
Line 
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
Note: See TracBrowser for help on using the repository browser.