Boost.uBlas 1.49
Linear Algebra in C++: matrices, vectors and numeric algorithms

iterator.hpp

Go to the documentation of this file.
00001 //
00002 //  Copyright (c) 2000-2002
00003 //  Joerg Walter, Mathias Koch
00004 //
00005 //  Distributed under the Boost Software License, Version 1.0. (See
00006 //  accompanying file LICENSE_1_0.txt or copy at
00007 //  http://www.boost.org/LICENSE_1_0.txt)
00008 //
00009 //  The authors gratefully acknowledge the support of
00010 //  GeNeSys mbH & Co. KG in producing this work.
00011 //
00012 
00013 #ifndef _BOOST_UBLAS_ITERATOR_
00014 #define _BOOST_UBLAS_ITERATOR_
00015 
00016 #include <boost/numeric/ublas/exception.hpp>
00017 #include <iterator>
00018 
00019 
00020 namespace boost { namespace numeric { namespace ublas {
00021 
00027     template<class C>
00028     class container_const_reference:
00029         private nonassignable {
00030     public:
00031         typedef C container_type;
00032 
00033         BOOST_UBLAS_INLINE
00034         container_const_reference ():
00035             c_ (0) {}
00036         BOOST_UBLAS_INLINE
00037         container_const_reference (const container_type &c):
00038             c_ (&c) {}
00039 
00040         BOOST_UBLAS_INLINE
00041         const container_type &operator () () const {
00042             return *c_;
00043         }
00044 
00045         BOOST_UBLAS_INLINE
00046         container_const_reference &assign (const container_type *c) {
00047             c_ = c;
00048             return *this;
00049         }
00050         
00051         // Closure comparison
00052         BOOST_UBLAS_INLINE
00053         bool same_closure (const container_const_reference &cr) const {
00054             return c_ == cr.c_;
00055         }
00056 
00057     private:
00058         const container_type *c_;
00059     };
00060 
00066     template<class C>
00067     class container_reference:
00068         private nonassignable {
00069     public:
00070         typedef C container_type;
00071 
00072         BOOST_UBLAS_INLINE
00073         container_reference ():
00074             c_ (0) {}
00075         BOOST_UBLAS_INLINE
00076         container_reference (container_type &c):
00077             c_ (&c) {}
00078 
00079         BOOST_UBLAS_INLINE
00080         container_type &operator () () const {
00081            return *c_;
00082         }
00083 
00084         BOOST_UBLAS_INLINE
00085         container_reference &assign (container_type *c) {
00086             c_ = c;
00087             return *this;
00088         }
00089 
00090         // Closure comparison
00091         BOOST_UBLAS_INLINE
00092         bool same_closure (const container_reference &cr) const {
00093             return c_ == cr.c_;
00094         }
00095 
00096     private:
00097         container_type *c_;
00098     };
00099 
00109     template<class IC, class I, class T>
00110     struct forward_iterator_base:
00111         public std::iterator<IC, T> {
00112         typedef I derived_iterator_type;
00113         typedef T derived_value_type;
00114 
00115         // Arithmetic
00116         BOOST_UBLAS_INLINE
00117         derived_iterator_type operator ++ (int) {
00118             derived_iterator_type &d (*static_cast<const derived_iterator_type *> (this));
00119             derived_iterator_type tmp (d);
00120             ++ d;
00121             return tmp;
00122         }
00123         BOOST_UBLAS_INLINE
00124         friend derived_iterator_type operator ++ (derived_iterator_type &d, int) {
00125             derived_iterator_type tmp (d);
00126             ++ d;
00127             return tmp;
00128         }
00129 
00130         // Comparison
00131         BOOST_UBLAS_INLINE
00132         bool operator != (const derived_iterator_type &it) const {
00133             const derived_iterator_type *d = static_cast<const derived_iterator_type *> (this);
00134             return ! (*d == it);
00135         }
00136     };
00137 
00147     template<class IC, class I, class T>
00148     struct bidirectional_iterator_base:
00149         public std::iterator<IC, T> {
00150         typedef I derived_iterator_type;
00151         typedef T derived_value_type;
00152 
00153         // Arithmetic
00154         BOOST_UBLAS_INLINE
00155         derived_iterator_type operator ++ (int) {
00156             derived_iterator_type &d (*static_cast<const derived_iterator_type *> (this));
00157             derived_iterator_type tmp (d);
00158             ++ d;
00159             return tmp;
00160         }
00161         BOOST_UBLAS_INLINE
00162         friend derived_iterator_type operator ++ (derived_iterator_type &d, int) {
00163             derived_iterator_type tmp (d);
00164             ++ d;
00165             return tmp;
00166         }
00167         BOOST_UBLAS_INLINE
00168         derived_iterator_type operator -- (int) {
00169             derived_iterator_type &d (*static_cast<const derived_iterator_type *> (this));
00170             derived_iterator_type tmp (d);
00171             -- d;
00172             return tmp;
00173         }
00174         BOOST_UBLAS_INLINE
00175         friend derived_iterator_type operator -- (derived_iterator_type &d, int) {
00176             derived_iterator_type tmp (d);
00177             -- d;
00178             return tmp;
00179         }
00180 
00181         // Comparison
00182         BOOST_UBLAS_INLINE
00183         bool operator != (const derived_iterator_type &it) const {
00184             const derived_iterator_type *d = static_cast<const derived_iterator_type *> (this);
00185             return ! (*d == it);
00186         }
00187     };
00188 
00201     template<class IC, class I, class T, class D = std::ptrdiff_t>
00202     // ISSUE the default for D seems rather dangerous as it can easily be (silently) incorrect
00203     struct random_access_iterator_base:
00204         public std::iterator<IC, T> {
00205         typedef I derived_iterator_type;
00206         typedef T derived_value_type;
00207         typedef D derived_difference_type;
00208 
00209         /* FIXME Need to explicitly pass derived_reference_type as otherwise I undefined type or forward declared
00210         typedef typename derived_iterator_type::reference derived_reference_type;
00211         // Indexed element
00212         BOOST_UBLAS_INLINE
00213         derived_reference_type operator [] (derived_difference_type n) {
00214             return *(*this + n);
00215         }
00216         */
00217 
00218         // Arithmetic
00219         BOOST_UBLAS_INLINE
00220         derived_iterator_type operator ++ (int) {
00221             derived_iterator_type &d (*static_cast<derived_iterator_type *> (this));
00222             derived_iterator_type tmp (d);
00223             ++ d;
00224             return tmp;
00225         }
00226         BOOST_UBLAS_INLINE
00227         friend derived_iterator_type operator ++ (derived_iterator_type &d, int) {
00228             derived_iterator_type tmp (d);
00229             ++ d;
00230             return tmp;
00231         }
00232         BOOST_UBLAS_INLINE
00233         derived_iterator_type operator -- (int) {
00234             derived_iterator_type &d (*static_cast<derived_iterator_type *> (this));
00235             derived_iterator_type tmp (d);
00236             -- d;
00237             return tmp;
00238         }
00239         BOOST_UBLAS_INLINE
00240         friend derived_iterator_type operator -- (derived_iterator_type &d, int) {
00241             derived_iterator_type tmp (d);
00242             -- d;
00243             return tmp;
00244         }
00245         BOOST_UBLAS_INLINE
00246         derived_iterator_type operator + (derived_difference_type n) const {
00247             derived_iterator_type tmp (*static_cast<const derived_iterator_type *> (this));
00248             return tmp += n;
00249         }
00250         BOOST_UBLAS_INLINE
00251         friend derived_iterator_type operator + (const derived_iterator_type &d, derived_difference_type n) {
00252             derived_iterator_type tmp (d);
00253             return tmp += n;
00254         }
00255         BOOST_UBLAS_INLINE
00256         friend derived_iterator_type operator + (derived_difference_type n, const derived_iterator_type &d) {
00257             derived_iterator_type tmp (d);
00258             return tmp += n;
00259         }
00260         BOOST_UBLAS_INLINE
00261         derived_iterator_type operator - (derived_difference_type n) const {
00262             derived_iterator_type tmp (*static_cast<const derived_iterator_type *> (this));
00263             return tmp -= n;
00264         }
00265         BOOST_UBLAS_INLINE
00266         friend derived_iterator_type operator - (const derived_iterator_type &d, derived_difference_type n) {
00267             derived_iterator_type tmp (d);
00268             return tmp -= n;
00269         }
00270 
00271         // Comparison
00272         BOOST_UBLAS_INLINE
00273         bool operator != (const derived_iterator_type &it) const {
00274             const derived_iterator_type *d = static_cast<const derived_iterator_type *> (this);
00275             return ! (*d == it);
00276         }
00277         BOOST_UBLAS_INLINE
00278         bool operator <= (const derived_iterator_type &it) const {
00279             const derived_iterator_type *d = static_cast<const derived_iterator_type *> (this);
00280             return ! (it < *d);
00281         }
00282         BOOST_UBLAS_INLINE
00283         bool operator >= (const derived_iterator_type &it) const {
00284             const derived_iterator_type *d = static_cast<const derived_iterator_type *> (this);
00285             return ! (*d < it);
00286         }
00287         BOOST_UBLAS_INLINE
00288         bool operator > (const derived_iterator_type &it) const {
00289             const derived_iterator_type *d = static_cast<const derived_iterator_type *> (this);
00290             return it < *d;
00291         }
00292     };
00293 
00307     // Renamed this class from reverse_iterator to get
00308     // typedef reverse_iterator<...> reverse_iterator
00309     // working. Thanks to Gabriel Dos Reis for explaining this.
00310     template <class I>
00311     class reverse_iterator_base:
00312         public std::reverse_iterator<I> {
00313     public:
00314         typedef typename I::container_type container_type;
00315         typedef typename container_type::size_type size_type;
00316         typedef typename I::difference_type difference_type;
00317         typedef I iterator_type;
00318 
00319         // Construction and destruction
00320         BOOST_UBLAS_INLINE
00321         reverse_iterator_base ():
00322             std::reverse_iterator<iterator_type> () {}
00323         BOOST_UBLAS_INLINE
00324         reverse_iterator_base (const iterator_type &it):
00325             std::reverse_iterator<iterator_type> (it) {}
00326 
00327         // Arithmetic
00328         BOOST_UBLAS_INLINE
00329         reverse_iterator_base &operator ++ () {
00330             return *this = -- this->base ();
00331         }
00332         BOOST_UBLAS_INLINE
00333         reverse_iterator_base operator ++ (int) {
00334             reverse_iterator_base tmp (*this);
00335             *this = -- this->base ();
00336             return tmp;
00337         }
00338         BOOST_UBLAS_INLINE
00339         reverse_iterator_base &operator -- () {
00340             return *this = ++ this->base ();
00341         }
00342         BOOST_UBLAS_INLINE
00343         reverse_iterator_base operator -- (int) {
00344             reverse_iterator_base tmp (*this);
00345             *this = ++ this->base ();
00346             return tmp;
00347         }
00348         BOOST_UBLAS_INLINE
00349         reverse_iterator_base &operator += (difference_type n) {
00350             return *this = this->base () - n;
00351         }
00352         BOOST_UBLAS_INLINE
00353         reverse_iterator_base &operator -= (difference_type n) {
00354             return *this = this->base () + n;
00355         }
00356 
00357         BOOST_UBLAS_INLINE
00358         friend reverse_iterator_base operator + (const reverse_iterator_base &it, difference_type n) {
00359             reverse_iterator_base tmp (it);
00360             return tmp += n;
00361         }
00362         BOOST_UBLAS_INLINE
00363         friend reverse_iterator_base operator + (difference_type n, const reverse_iterator_base &it) {
00364             reverse_iterator_base tmp (it);
00365             return tmp += n;
00366         }
00367         BOOST_UBLAS_INLINE
00368         friend reverse_iterator_base operator - (const reverse_iterator_base &it, difference_type n) {
00369             reverse_iterator_base tmp (it);
00370             return tmp -= n;
00371         }
00372         BOOST_UBLAS_INLINE
00373         friend difference_type operator - (const reverse_iterator_base &it1, const reverse_iterator_base &it2) {
00374             return it2.base () - it1.base ();
00375         }
00376 
00377         BOOST_UBLAS_INLINE
00378         const container_type &operator () () const {
00379             return this->base () ();
00380         }
00381 
00382         BOOST_UBLAS_INLINE
00383         size_type index () const {
00384             iterator_type tmp (this->base ());
00385             return (-- tmp).index ();
00386         }
00387     };
00388 
00401     // Renamed this class from reverse_iterator1 to get
00402     // typedef reverse_iterator1<...> reverse_iterator1
00403     // working. Thanks to Gabriel Dos Reis for explaining this.
00404     template <class I>
00405     class reverse_iterator_base1:
00406         public std::reverse_iterator<I> {
00407     public:
00408         typedef typename I::container_type container_type;
00409         typedef typename container_type::size_type size_type;
00410         typedef typename I::difference_type difference_type;
00411         typedef I iterator_type;
00412         typedef typename I::dual_iterator_type dual_iterator_type;
00413         typedef typename I::dual_reverse_iterator_type dual_reverse_iterator_type;
00414 
00415         // Construction and destruction
00416         BOOST_UBLAS_INLINE
00417         reverse_iterator_base1 ():
00418             std::reverse_iterator<iterator_type> () {}
00419         BOOST_UBLAS_INLINE
00420         reverse_iterator_base1 (const iterator_type &it):
00421             std::reverse_iterator<iterator_type> (it) {}
00422 
00423         // Arithmetic
00424         BOOST_UBLAS_INLINE
00425         reverse_iterator_base1 &operator ++ () {
00426             return *this = -- this->base ();
00427         }
00428         BOOST_UBLAS_INLINE
00429         reverse_iterator_base1 operator ++ (int) {
00430             reverse_iterator_base1 tmp (*this);
00431             *this = -- this->base ();
00432             return tmp;
00433         }
00434         BOOST_UBLAS_INLINE
00435         reverse_iterator_base1 &operator -- () {
00436             return *this = ++ this->base ();
00437         }
00438         BOOST_UBLAS_INLINE
00439         reverse_iterator_base1 operator -- (int) {
00440             reverse_iterator_base1 tmp (*this);
00441             *this = ++ this->base ();
00442             return tmp;
00443         }
00444         BOOST_UBLAS_INLINE
00445         reverse_iterator_base1 &operator += (difference_type n) {
00446             return *this = this->base () - n;
00447         }
00448         BOOST_UBLAS_INLINE
00449         reverse_iterator_base1 &operator -= (difference_type n) {
00450             return *this = this->base () + n;
00451         }
00452 
00453         BOOST_UBLAS_INLINE
00454         friend reverse_iterator_base1 operator + (const reverse_iterator_base1 &it, difference_type n) {
00455             reverse_iterator_base1 tmp (it);
00456             return tmp += n;
00457         }
00458         BOOST_UBLAS_INLINE
00459         friend reverse_iterator_base1 operator + (difference_type n, const reverse_iterator_base1 &it) {
00460             reverse_iterator_base1 tmp (it);
00461             return tmp += n;
00462         }
00463         BOOST_UBLAS_INLINE
00464         friend reverse_iterator_base1 operator - (const reverse_iterator_base1 &it, difference_type n) {
00465             reverse_iterator_base1 tmp (it);
00466             return tmp -= n;
00467         }
00468         BOOST_UBLAS_INLINE
00469         friend difference_type operator - (const reverse_iterator_base1 &it1, const reverse_iterator_base1 &it2) {
00470             return it2.base () - it1.base ();
00471         }
00472 
00473         BOOST_UBLAS_INLINE
00474         const container_type &operator () () const {
00475             return this->base () ();
00476         }
00477 
00478         BOOST_UBLAS_INLINE
00479         size_type index1 () const {
00480             iterator_type tmp (this->base ());
00481             return (-- tmp).index1 ();
00482         }
00483         BOOST_UBLAS_INLINE
00484         size_type index2 () const {
00485             iterator_type tmp (this->base ());
00486             return (-- tmp).index2 ();
00487         }
00488 
00489         BOOST_UBLAS_INLINE
00490         dual_iterator_type begin () const {
00491             iterator_type tmp (this->base ());
00492             return (-- tmp).begin ();
00493         }
00494         BOOST_UBLAS_INLINE
00495         dual_iterator_type end () const {
00496             iterator_type tmp (this->base ());
00497             return (-- tmp).end ();
00498         }
00499         BOOST_UBLAS_INLINE
00500         dual_reverse_iterator_type rbegin () const {
00501             return dual_reverse_iterator_type (end ());
00502         }
00503         BOOST_UBLAS_INLINE
00504         dual_reverse_iterator_type rend () const {
00505             return dual_reverse_iterator_type (begin ());
00506         }
00507     };
00508 
00523     // Renamed this class from reverse_iterator2 to get
00524     // typedef reverse_iterator2<...> reverse_iterator2
00525     // working. Thanks to Gabriel Dos Reis for explaining this.
00526     template <class I>
00527     class reverse_iterator_base2:
00528         public std::reverse_iterator<I> {
00529     public:
00530         typedef typename I::container_type container_type;
00531         typedef typename container_type::size_type size_type;
00532         typedef typename I::difference_type difference_type;
00533         typedef I iterator_type;
00534         typedef typename I::dual_iterator_type dual_iterator_type;
00535         typedef typename I::dual_reverse_iterator_type dual_reverse_iterator_type;
00536 
00537         // Construction and destruction
00538         BOOST_UBLAS_INLINE
00539         reverse_iterator_base2 ():
00540             std::reverse_iterator<iterator_type> () {}
00541         BOOST_UBLAS_INLINE
00542         reverse_iterator_base2 (const iterator_type &it):
00543             std::reverse_iterator<iterator_type> (it) {}
00544 
00545         // Arithmetic
00546         BOOST_UBLAS_INLINE
00547         reverse_iterator_base2 &operator ++ () {
00548             return *this = -- this->base ();
00549         }
00550         BOOST_UBLAS_INLINE
00551         reverse_iterator_base2 operator ++ (int) {
00552             reverse_iterator_base2 tmp (*this);
00553             *this = -- this->base ();
00554             return tmp;
00555         }
00556         BOOST_UBLAS_INLINE
00557         reverse_iterator_base2 &operator -- () {
00558             return *this = ++ this->base ();
00559         }
00560         BOOST_UBLAS_INLINE
00561         reverse_iterator_base2 operator -- (int) {
00562             reverse_iterator_base2 tmp (*this);
00563             *this = ++ this->base ();
00564             return tmp;
00565         }
00566         BOOST_UBLAS_INLINE
00567         reverse_iterator_base2 &operator += (difference_type n) {
00568             return *this = this->base () - n;
00569         }
00570         BOOST_UBLAS_INLINE
00571         reverse_iterator_base2 &operator -= (difference_type n) {
00572             return *this = this->base () + n;
00573         }
00574 
00575         BOOST_UBLAS_INLINE
00576         friend reverse_iterator_base2 operator + (const reverse_iterator_base2 &it, difference_type n) {
00577             reverse_iterator_base2 tmp (it);
00578             return tmp += n;
00579         }
00580         BOOST_UBLAS_INLINE
00581         friend reverse_iterator_base2 operator + (difference_type n, const reverse_iterator_base2 &it) {
00582             reverse_iterator_base2 tmp (it);
00583             return tmp += n;
00584         }
00585         BOOST_UBLAS_INLINE
00586         friend reverse_iterator_base2 operator - (const reverse_iterator_base2 &it, difference_type n) {
00587             reverse_iterator_base2 tmp (it);
00588             return tmp -= n;
00589         }
00590         BOOST_UBLAS_INLINE
00591         friend difference_type operator - (const reverse_iterator_base2 &it1, const reverse_iterator_base2 &it2) {
00592             return it2.base () - it1.base ();
00593         }
00594 
00595         BOOST_UBLAS_INLINE
00596         const container_type &operator () () const {
00597             return this->base () ();
00598         }
00599 
00600         BOOST_UBLAS_INLINE
00601         size_type index1 () const {
00602             iterator_type tmp (this->base ());
00603             return (-- tmp).index1 ();
00604         }
00605         BOOST_UBLAS_INLINE
00606         size_type index2 () const {
00607             iterator_type tmp (this->base ());
00608             return (-- tmp).index2 ();
00609         }
00610 
00611         BOOST_UBLAS_INLINE
00612         dual_iterator_type begin () const {
00613             iterator_type tmp (this->base ());
00614             return (-- tmp).begin ();
00615         }
00616         BOOST_UBLAS_INLINE
00617         dual_iterator_type end () const {
00618             iterator_type tmp (this->base ());
00619             return (-- tmp).end ();
00620         }
00621         BOOST_UBLAS_INLINE
00622         dual_reverse_iterator_type rbegin () const {
00623             return dual_reverse_iterator_type (end ());
00624         }
00625         BOOST_UBLAS_INLINE
00626         dual_reverse_iterator_type rend () const {
00627             return dual_reverse_iterator_type (begin ());
00628         }
00629     };
00630 
00643     template<class C, class IC>
00644     class indexed_iterator:
00645         public container_reference<C>,
00646         public random_access_iterator_base<IC,
00647                                            indexed_iterator<C, IC>,
00648                                            typename C::value_type,
00649                                            typename C::difference_type> {
00650     public:
00651         typedef C container_type;
00652         typedef IC iterator_category;
00653         typedef typename container_type::size_type size_type;
00654         typedef typename container_type::difference_type difference_type;
00655         typedef typename container_type::value_type value_type;
00656         typedef typename container_type::reference reference;
00657 
00658         // Construction and destruction
00659         BOOST_UBLAS_INLINE
00660         indexed_iterator ():
00661             container_reference<container_type> (), it_ () {}
00662         BOOST_UBLAS_INLINE
00663         indexed_iterator (container_type &c, size_type it):
00664             container_reference<container_type> (c), it_ (it) {}
00665 
00666         // Arithmetic
00667         BOOST_UBLAS_INLINE
00668         indexed_iterator &operator ++ () {
00669             ++ it_;
00670             return *this;
00671         }
00672         BOOST_UBLAS_INLINE
00673         indexed_iterator &operator -- () {
00674             -- it_;
00675             return *this;
00676         }
00677         BOOST_UBLAS_INLINE
00678         indexed_iterator &operator += (difference_type n) {
00679             it_ += n;
00680             return *this;
00681         }
00682         BOOST_UBLAS_INLINE
00683         indexed_iterator &operator -= (difference_type n) {
00684             it_ -= n;
00685             return *this;
00686         }
00687         BOOST_UBLAS_INLINE
00688         difference_type operator - (const indexed_iterator &it) const {
00689             BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
00690             return it_ - it.it_;
00691         }
00692 
00693         // Dereference
00694         BOOST_UBLAS_INLINE
00695         reference operator * () const {
00696             BOOST_UBLAS_CHECK (index () < (*this) ().size (), bad_index ());
00697             return (*this) () (it_);
00698         }
00699         BOOST_UBLAS_INLINE
00700         reference operator [] (difference_type n) const {
00701             return *((*this) + n);
00702         }
00703 
00704         // Index
00705         BOOST_UBLAS_INLINE
00706         size_type index () const {
00707             return it_;
00708         }
00709 
00710         // Assignment
00711         BOOST_UBLAS_INLINE
00712         indexed_iterator &operator = (const indexed_iterator &it) {
00713             // FIX: ICC needs full qualification?!
00714             // assign (&it ());
00715             container_reference<C>::assign (&it ());
00716             it_ = it.it_;
00717             return *this;
00718         }
00719 
00720         // Comparison
00721         BOOST_UBLAS_INLINE
00722         bool operator == (const indexed_iterator &it) const {
00723             BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
00724             return it_ == it.it_;
00725         }
00726         BOOST_UBLAS_INLINE
00727         bool operator < (const indexed_iterator &it) const {
00728             BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
00729             return it_ < it.it_;
00730         }
00731 
00732     private:
00733         size_type it_;
00734     };
00735 
00751     template<class C, class IC>
00752     class indexed_const_iterator:
00753         public container_const_reference<C>,
00754         public random_access_iterator_base<IC,
00755                                            indexed_const_iterator<C, IC>,
00756                                            typename C::value_type,
00757                                            typename C::difference_type> {
00758     public:
00759         typedef C container_type;
00760         typedef IC iterator_category;
00761         typedef typename container_type::size_type size_type;
00762         typedef typename container_type::difference_type difference_type;
00763         typedef typename container_type::value_type value_type;
00764         typedef typename container_type::const_reference reference;
00765         typedef indexed_iterator<container_type, iterator_category> iterator_type;
00766 
00767         // Construction and destruction
00768         BOOST_UBLAS_INLINE
00769         indexed_const_iterator ():
00770             container_const_reference<container_type> (), it_ () {}
00771         BOOST_UBLAS_INLINE
00772         indexed_const_iterator (const container_type &c, size_type it):
00773             container_const_reference<container_type> (c), it_ (it) {}
00774         BOOST_UBLAS_INLINE 
00775         indexed_const_iterator (const iterator_type &it):
00776             container_const_reference<container_type> (it ()), it_ (it.index ()) {}
00777 
00778         // Arithmetic
00779         BOOST_UBLAS_INLINE
00780         indexed_const_iterator &operator ++ () {
00781             ++ it_;
00782             return *this;
00783         }
00784         BOOST_UBLAS_INLINE
00785         indexed_const_iterator &operator -- () {
00786             -- it_;
00787             return *this;
00788         }
00789         BOOST_UBLAS_INLINE
00790         indexed_const_iterator &operator += (difference_type n) {
00791             it_ += n;
00792             return *this;
00793         }
00794         BOOST_UBLAS_INLINE
00795         indexed_const_iterator &operator -= (difference_type n) {
00796             it_ -= n;
00797             return *this;
00798         }
00799         BOOST_UBLAS_INLINE
00800         difference_type operator - (const indexed_const_iterator &it) const {
00801             BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
00802             return it_ - it.it_;
00803         }
00804 
00805         // Dereference
00806         BOOST_UBLAS_INLINE
00807         reference operator * () const {
00808             BOOST_UBLAS_CHECK (index () < (*this) ().size (), bad_index ());
00809             return (*this) () (it_);
00810         }
00811         BOOST_UBLAS_INLINE
00812         reference operator [] (difference_type n) const {
00813             return *((*this) + n);
00814         }
00815 
00816         // Index
00817         BOOST_UBLAS_INLINE
00818         size_type index () const {
00819             return it_;
00820         }
00821 
00822         // Assignment
00823         BOOST_UBLAS_INLINE
00824         indexed_const_iterator &operator = (const indexed_const_iterator &it) {
00825             // FIX: ICC needs full qualification?!
00826             // assign (&it ());
00827             container_const_reference<C>::assign (&it ());
00828             it_ = it.it_;
00829             return *this;
00830         }
00831 
00832         // Comparison
00833         BOOST_UBLAS_INLINE
00834         bool operator == (const indexed_const_iterator &it) const {
00835             BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
00836             return it_ == it.it_;
00837         }
00838         BOOST_UBLAS_INLINE
00839         bool operator < (const indexed_const_iterator &it) const {
00840             BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
00841             return it_ < it.it_;
00842         }
00843 
00844     private:
00845         size_type it_;
00846 
00847         friend class indexed_iterator<container_type, iterator_category>;
00848     };
00849 
00850     template<class C, class IC>
00851     class indexed_iterator2;
00852 
00871     template<class C, class IC>
00872     class indexed_iterator1:
00873         public container_reference<C>, 
00874         public random_access_iterator_base<IC,
00875                                            indexed_iterator1<C, IC>, 
00876                                            typename C::value_type,
00877                                            typename C::difference_type> {
00878     public:
00879         typedef C container_type;
00880         typedef IC iterator_category;
00881         typedef typename container_type::size_type size_type;
00882         typedef typename container_type::difference_type difference_type;
00883         typedef typename container_type::value_type value_type;
00884         typedef typename container_type::reference reference;
00885 
00886         typedef indexed_iterator2<container_type, iterator_category> dual_iterator_type;
00887         typedef reverse_iterator_base2<dual_iterator_type> dual_reverse_iterator_type;
00888 
00889         // Construction and destruction
00890         BOOST_UBLAS_INLINE
00891         indexed_iterator1 ():
00892             container_reference<container_type> (), it1_ (), it2_ () {}
00893         BOOST_UBLAS_INLINE 
00894         indexed_iterator1 (container_type &c, size_type it1, size_type it2):
00895             container_reference<container_type> (c), it1_ (it1), it2_ (it2) {}
00896 
00897         // Arithmetic
00898         BOOST_UBLAS_INLINE
00899         indexed_iterator1 &operator ++ () {
00900             ++ it1_;
00901             return *this;
00902         }
00903         BOOST_UBLAS_INLINE
00904         indexed_iterator1 &operator -- () {
00905             -- it1_;
00906             return *this;
00907         }
00908         BOOST_UBLAS_INLINE
00909         indexed_iterator1 &operator += (difference_type n) {
00910             it1_ += n;
00911             return *this;
00912         }
00913         BOOST_UBLAS_INLINE
00914         indexed_iterator1 &operator -= (difference_type n) {
00915             it1_ -= n;
00916             return *this;
00917         }
00918         BOOST_UBLAS_INLINE
00919         difference_type operator - (const indexed_iterator1 &it) const {
00920             BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
00921             BOOST_UBLAS_CHECK (it2_ == it.it2_, external_logic ());
00922             return it1_ - it.it1_;
00923         }
00924 
00925         // Dereference
00926         BOOST_UBLAS_INLINE
00927         reference operator * () const {
00928             BOOST_UBLAS_CHECK (index1 () < (*this) ().size1 (), bad_index ());
00929             BOOST_UBLAS_CHECK (index2 () < (*this) ().size2 (), bad_index ());
00930             return (*this) () (it1_, it2_);
00931         }
00932         BOOST_UBLAS_INLINE
00933         reference operator [] (difference_type n) const {
00934             return *((*this) + n);
00935         }
00936 
00937         // Index
00938         BOOST_UBLAS_INLINE
00939         size_type index1 () const {
00940             return it1_;
00941         }
00942         BOOST_UBLAS_INLINE
00943         size_type index2 () const {
00944             return it2_;
00945         }
00946 
00947         BOOST_UBLAS_INLINE
00948         dual_iterator_type begin () const {
00949             return (*this) ().find2 (1, index1 (), 0); 
00950         }
00951         BOOST_UBLAS_INLINE
00952         dual_iterator_type end () const {
00953             return (*this) ().find2 (1, index1 (), (*this) ().size2 ());
00954         }
00955         BOOST_UBLAS_INLINE
00956         dual_reverse_iterator_type rbegin () const {
00957             return dual_reverse_iterator_type (end ());
00958         }
00959         BOOST_UBLAS_INLINE
00960         dual_reverse_iterator_type rend () const {
00961             return dual_reverse_iterator_type (begin ());
00962         }
00963 
00964         // Assignment
00965         BOOST_UBLAS_INLINE
00966         indexed_iterator1 &operator = (const indexed_iterator1 &it) {
00967             // FIX: ICC needs full qualification?!
00968             // assign (&it ());
00969             container_reference<C>::assign (&it ());
00970             it1_ = it.it1_;
00971             it2_ = it.it2_;
00972             return *this;
00973         }
00974 
00975         // Comparison
00976         BOOST_UBLAS_INLINE
00977         bool operator == (const indexed_iterator1 &it) const {
00978             BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
00979             BOOST_UBLAS_CHECK (it2_ == it.it2_, external_logic ());
00980             return it1_ == it.it1_;
00981         }
00982         BOOST_UBLAS_INLINE
00983         bool operator < (const indexed_iterator1 &it) const {
00984             BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
00985             BOOST_UBLAS_CHECK (it2_ == it.it2_, external_logic ());
00986             return it1_ < it.it1_;
00987         }
00988 
00989     private:
00990         size_type it1_;
00991         size_type it2_;
00992     };
00993 
00994     template<class C, class IC>
00995     class indexed_const_iterator2;
00996 
01017     template<class C, class IC>
01018     class indexed_const_iterator1:
01019         public container_const_reference<C>, 
01020         public random_access_iterator_base<IC,
01021                                            indexed_const_iterator1<C, IC>, 
01022                                            typename C::value_type,
01023                                            typename C::difference_type> {
01024     public:
01025         typedef C container_type;
01026         typedef IC iterator_category;
01027         typedef typename container_type::size_type size_type;
01028         typedef typename container_type::difference_type difference_type;
01029         typedef typename container_type::value_type value_type;
01030         typedef typename container_type::const_reference reference;
01031 
01032         typedef indexed_iterator1<container_type, iterator_category> iterator_type;
01033         typedef indexed_const_iterator2<container_type, iterator_category> dual_iterator_type;
01034         typedef reverse_iterator_base2<dual_iterator_type> dual_reverse_iterator_type;
01035 
01036         // Construction and destruction
01037         BOOST_UBLAS_INLINE
01038         indexed_const_iterator1 ():
01039             container_const_reference<container_type> (), it1_ (), it2_ () {}
01040         BOOST_UBLAS_INLINE
01041         indexed_const_iterator1 (const container_type &c, size_type it1, size_type it2):
01042             container_const_reference<container_type> (c), it1_ (it1), it2_ (it2) {}
01043         BOOST_UBLAS_INLINE 
01044         indexed_const_iterator1 (const iterator_type &it):
01045             container_const_reference<container_type> (it ()), it1_ (it.index1 ()), it2_ (it.index2 ()) {}
01046 
01047         // Arithmetic
01048         BOOST_UBLAS_INLINE
01049         indexed_const_iterator1 &operator ++ () {
01050             ++ it1_;
01051             return *this;
01052         }
01053         BOOST_UBLAS_INLINE
01054         indexed_const_iterator1 &operator -- () {
01055             -- it1_;
01056             return *this;
01057         }
01058         BOOST_UBLAS_INLINE
01059         indexed_const_iterator1 &operator += (difference_type n) {
01060             it1_ += n;
01061             return *this;
01062         }
01063         BOOST_UBLAS_INLINE
01064         indexed_const_iterator1 &operator -= (difference_type n) {
01065             it1_ -= n;
01066             return *this;
01067         }
01068         BOOST_UBLAS_INLINE
01069         difference_type operator - (const indexed_const_iterator1 &it) const {
01070             BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
01071             BOOST_UBLAS_CHECK (it2_ == it.it2_, external_logic ());
01072             return it1_ - it.it1_;
01073         }
01074 
01075         // Dereference
01076         BOOST_UBLAS_INLINE
01077         reference operator * () const {
01078             BOOST_UBLAS_CHECK (index1 () < (*this) ().size1 (), bad_index ());
01079             BOOST_UBLAS_CHECK (index2 () < (*this) ().size2 (), bad_index ());
01080             return (*this) () (it1_, it2_);
01081         }
01082         BOOST_UBLAS_INLINE
01083         reference operator [] (difference_type n) const {
01084             return *((*this) + n);
01085         }
01086 
01087         // Index
01088         BOOST_UBLAS_INLINE
01089         size_type index1 () const {
01090             return it1_;
01091         }
01092         BOOST_UBLAS_INLINE
01093         size_type index2 () const {
01094             return it2_;
01095         }
01096 
01097         BOOST_UBLAS_INLINE
01098         dual_iterator_type begin () const {
01099             return (*this) ().find2 (1, index1 (), 0); 
01100         }
01101         BOOST_UBLAS_INLINE
01102         dual_iterator_type end () const {
01103             return (*this) ().find2 (1, index1 (), (*this) ().size2 ()); 
01104         }
01105         BOOST_UBLAS_INLINE
01106         dual_reverse_iterator_type rbegin () const {
01107             return dual_reverse_iterator_type (end ()); 
01108         }
01109         BOOST_UBLAS_INLINE
01110         dual_reverse_iterator_type rend () const {
01111             return dual_reverse_iterator_type (begin ()); 
01112         }
01113 
01114         // Assignment
01115         BOOST_UBLAS_INLINE
01116         indexed_const_iterator1 &operator = (const indexed_const_iterator1 &it) {
01117             // FIX: ICC needs full qualification?!
01118             // assign (&it ());
01119             container_const_reference<C>::assign (&it ());
01120             it1_ = it.it1_;
01121             it2_ = it.it2_;
01122             return *this;
01123         }
01124 
01125         // Comparison
01126         BOOST_UBLAS_INLINE
01127         bool operator == (const indexed_const_iterator1 &it) const {
01128             BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
01129             BOOST_UBLAS_CHECK (it2_ == it.it2_, external_logic ());
01130             return it1_ == it.it1_;
01131         }
01132         BOOST_UBLAS_INLINE
01133         bool operator < (const indexed_const_iterator1 &it) const {
01134             BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
01135             BOOST_UBLAS_CHECK (it2_ == it.it2_, external_logic ());
01136             return it1_ < it.it1_;
01137         }
01138 
01139     private:
01140         size_type it1_;
01141         size_type it2_;
01142 
01143         friend class indexed_iterator1<container_type, iterator_category>;
01144     };
01145 
01162     template<class C, class IC>
01163     class indexed_iterator2:
01164         public container_reference<C>, 
01165         public random_access_iterator_base<IC,
01166                                            indexed_iterator2<C, IC>, 
01167                                            typename C::value_type,
01168                                            typename C::difference_type> {
01169     public:
01170         typedef C container_type;
01171         typedef IC iterator_category;
01172         typedef typename container_type::size_type size_type;
01173         typedef typename container_type::difference_type difference_type;
01174         typedef typename container_type::value_type value_type;
01175         typedef typename container_type::reference reference;
01176 
01177         typedef indexed_iterator1<container_type, iterator_category> dual_iterator_type;
01178         typedef reverse_iterator_base1<dual_iterator_type> dual_reverse_iterator_type;
01179 
01180         // Construction and destruction
01181         BOOST_UBLAS_INLINE
01182         indexed_iterator2 ():
01183             container_reference<container_type> (), it1_ (), it2_ () {}
01184         BOOST_UBLAS_INLINE
01185         indexed_iterator2 (container_type &c, size_type it1, size_type it2):
01186             container_reference<container_type> (c), it1_ (it1), it2_ (it2) {}
01187 
01188         // Arithmetic
01189         BOOST_UBLAS_INLINE
01190         indexed_iterator2 &operator ++ () {
01191             ++ it2_;
01192             return *this;
01193         }
01194         BOOST_UBLAS_INLINE
01195         indexed_iterator2 &operator -- () {
01196             -- it2_;
01197             return *this;
01198         }
01199         BOOST_UBLAS_INLINE
01200         indexed_iterator2 &operator += (difference_type n) {
01201             it2_ += n;
01202             return *this;
01203         }
01204         BOOST_UBLAS_INLINE
01205         indexed_iterator2 &operator -= (difference_type n) {
01206             it2_ -= n;
01207             return *this;
01208         }
01209         BOOST_UBLAS_INLINE
01210         difference_type operator - (const indexed_iterator2 &it) const {
01211             BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
01212             BOOST_UBLAS_CHECK (it1_ == it.it1_, external_logic ());
01213             return it2_ - it.it2_;
01214         }
01215 
01216         // Dereference
01217         BOOST_UBLAS_INLINE
01218         reference operator * () const {
01219             BOOST_UBLAS_CHECK (index1 () < (*this) ().size1 (), bad_index ());
01220             BOOST_UBLAS_CHECK (index2 () < (*this) ().size2 (), bad_index ());
01221             return (*this) () (it1_, it2_);
01222         }
01223         BOOST_UBLAS_INLINE
01224         reference operator [] (difference_type n) const {
01225             return *((*this) + n);
01226         }
01227 
01228         // Index
01229         BOOST_UBLAS_INLINE
01230         size_type index1 () const {
01231             return it1_;
01232         }
01233         BOOST_UBLAS_INLINE
01234         size_type index2 () const {
01235             return it2_;
01236         }
01237 
01238         BOOST_UBLAS_INLINE
01239         dual_iterator_type begin () const {
01240             return (*this) ().find1 (1, 0, index2 ());
01241         }
01242         BOOST_UBLAS_INLINE
01243         dual_iterator_type end () const {
01244             return (*this) ().find1 (1, (*this) ().size1 (), index2 ());
01245         }
01246         BOOST_UBLAS_INLINE
01247         dual_reverse_iterator_type rbegin () const {
01248             return dual_reverse_iterator_type (end ());
01249         }
01250         BOOST_UBLAS_INLINE
01251         dual_reverse_iterator_type rend () const {
01252             return dual_reverse_iterator_type (begin ());
01253         }
01254 
01255         // Assignment
01256         BOOST_UBLAS_INLINE
01257         indexed_iterator2 &operator = (const indexed_iterator2 &it) {
01258             // FIX: ICC needs full qualification?!
01259             // assign (&it ());
01260             container_reference<C>::assign (&it ());
01261             it1_ = it.it1_;
01262             it2_ = it.it2_;
01263             return *this;
01264         }
01265 
01266         // Comparison
01267         BOOST_UBLAS_INLINE
01268         bool operator == (const indexed_iterator2 &it) const {
01269             BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
01270             BOOST_UBLAS_CHECK (it1_ == it.it1_, external_logic ());
01271             return it2_ == it.it2_;
01272         }
01273         BOOST_UBLAS_INLINE
01274         bool operator < (const indexed_iterator2 &it) const {
01275             BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
01276             BOOST_UBLAS_CHECK (it1_ == it.it1_, external_logic ());
01277             return it2_ < it.it2_;
01278         }
01279 
01280     private:
01281         size_type it1_;
01282         size_type it2_;
01283     };
01284 
01305     template<class C, class IC>
01306     class indexed_const_iterator2:
01307         public container_const_reference<C>,
01308         public random_access_iterator_base<IC,
01309                                            indexed_const_iterator2<C, IC>,
01310                                            typename C::value_type,
01311                                            typename C::difference_type> {
01312     public:
01313         typedef C container_type;
01314         typedef IC iterator_category;
01315         typedef typename container_type::size_type size_type;
01316         typedef typename container_type::difference_type difference_type;
01317         typedef typename container_type::value_type value_type;
01318         typedef typename container_type::const_reference reference;
01319 
01320         typedef indexed_iterator2<container_type, iterator_category> iterator_type;
01321         typedef indexed_const_iterator1<container_type, iterator_category> dual_iterator_type;
01322         typedef reverse_iterator_base1<dual_iterator_type> dual_reverse_iterator_type;
01323 
01324         // Construction and destruction
01325         BOOST_UBLAS_INLINE
01326         indexed_const_iterator2 ():
01327             container_const_reference<container_type> (), it1_ (), it2_ () {}
01328         BOOST_UBLAS_INLINE
01329         indexed_const_iterator2 (const container_type &c, size_type it1, size_type it2):
01330             container_const_reference<container_type> (c), it1_ (it1), it2_ (it2) {}
01331         BOOST_UBLAS_INLINE
01332         indexed_const_iterator2 (const iterator_type &it):
01333             container_const_reference<container_type> (it ()), it1_ (it.index1 ()), it2_ (it.index2 ()) {}
01334 
01335         // Arithmetic
01336         BOOST_UBLAS_INLINE
01337         indexed_const_iterator2 &operator ++ () {
01338             ++ it2_;
01339             return *this;
01340         }
01341         BOOST_UBLAS_INLINE
01342         indexed_const_iterator2 &operator -- () {
01343             -- it2_;
01344             return *this;
01345         }
01346         BOOST_UBLAS_INLINE
01347         indexed_const_iterator2 &operator += (difference_type n) {
01348             it2_ += n;
01349             return *this;
01350         }
01351         BOOST_UBLAS_INLINE
01352         indexed_const_iterator2 &operator -= (difference_type n) {
01353             it2_ -= n;
01354             return *this;
01355         }
01356         BOOST_UBLAS_INLINE
01357         difference_type operator - (const indexed_const_iterator2 &it) const {
01358             BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
01359             BOOST_UBLAS_CHECK (it1_ == it.it1_, external_logic ());
01360             return it2_ - it.it2_;
01361         }
01362 
01363         // Dereference
01364         BOOST_UBLAS_INLINE
01365         reference operator * () const {
01366             BOOST_UBLAS_CHECK (index1 () < (*this) ().size1 (), bad_index ());
01367             BOOST_UBLAS_CHECK (index2 () < (*this) ().size2 (), bad_index ());
01368             return (*this) () (it1_, it2_);
01369         }
01370         BOOST_UBLAS_INLINE
01371         reference operator [] (difference_type n) const {
01372             return *((*this) + n);
01373         }
01374 
01375         // Index
01376         BOOST_UBLAS_INLINE
01377         size_type index1 () const {
01378             return it1_;
01379         }
01380         BOOST_UBLAS_INLINE
01381         size_type index2 () const {
01382             return it2_;
01383         }
01384 
01385         BOOST_UBLAS_INLINE
01386         dual_iterator_type begin () const {
01387             return (*this) ().find1 (1, 0, index2 ());
01388         }
01389         BOOST_UBLAS_INLINE
01390         dual_iterator_type end () const {
01391             return (*this) ().find1 (1, (*this) ().size1 (), index2 ());
01392         }
01393         BOOST_UBLAS_INLINE
01394         dual_reverse_iterator_type rbegin () const {
01395             return dual_reverse_iterator_type (end ());
01396         }
01397         BOOST_UBLAS_INLINE
01398         dual_reverse_iterator_type rend () const {
01399             return dual_reverse_iterator_type (begin ());
01400         }
01401 
01402         // Assignment
01403         BOOST_UBLAS_INLINE
01404         indexed_const_iterator2 &operator = (const indexed_const_iterator2 &it) {
01405             // FIX: ICC needs full qualification?!
01406             // assign (&it ());
01407             container_const_reference<C>::assign (&it ());
01408             it1_ = it.it1_;
01409             it2_ = it.it2_;
01410             return *this;
01411         }
01412 
01413         // Comparison
01414         BOOST_UBLAS_INLINE
01415         bool operator == (const indexed_const_iterator2 &it) const {
01416             BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
01417             BOOST_UBLAS_CHECK (it1_ == it.it1_, external_logic ());
01418             return it2_ == it.it2_;
01419         }
01420         BOOST_UBLAS_INLINE
01421         bool operator < (const indexed_const_iterator2 &it) const {
01422             BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
01423             BOOST_UBLAS_CHECK (it1_ == it.it1_, external_logic ());
01424             return it2_ < it.it2_;
01425         }
01426 
01427     private:
01428         size_type it1_;
01429         size_type it2_;
01430 
01431         friend class indexed_iterator2<container_type, iterator_category>;
01432     };
01433 
01434 }}}
01435 
01436 #endif