source: NonGTP/Boost/boost/numeric/ublas/detail/iterator.hpp @ 857

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