Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 09:42:59

0001 //
0002 //  Copyright (c) 2000-2002
0003 //  Joerg Walter, Mathias Koch
0004 //
0005 //  Distributed under the Boost Software License, Version 1.0. (See
0006 //  accompanying file LICENSE_1_0.txt or copy at
0007 //  http://www.boost.org/LICENSE_1_0.txt)
0008 //
0009 //  The authors gratefully acknowledge the support of
0010 //  GeNeSys mbH & Co. KG in producing this work.
0011 //
0012 
0013 #ifndef _BOOST_UBLAS_ITERATOR_
0014 #define _BOOST_UBLAS_ITERATOR_
0015 
0016 #include <boost/numeric/ublas/exception.hpp>
0017 #include <iterator>
0018 
0019 
0020 namespace boost { namespace numeric { namespace ublas {
0021 
0022   /** \brief Base class of all proxy classes that contain
0023    *       a (redirectable) reference to an immutable object.
0024    *
0025    *       \param C the type of the container referred to
0026    */
0027     template<class C>
0028     class container_const_reference:
0029         private nonassignable {
0030     public:
0031         typedef C container_type;
0032 
0033         BOOST_UBLAS_INLINE
0034         container_const_reference ():
0035             c_ (0) {}
0036         BOOST_UBLAS_INLINE
0037         container_const_reference (const container_type &c):
0038             c_ (&c) {}
0039 
0040         BOOST_UBLAS_INLINE
0041         const container_type &operator () () const {
0042             return *c_;
0043         }
0044 
0045         BOOST_UBLAS_INLINE
0046         container_const_reference &assign (const container_type *c) {
0047             c_ = c;
0048             return *this;
0049         }
0050         
0051         // Closure comparison
0052         BOOST_UBLAS_INLINE
0053         bool same_closure (const container_const_reference &cr) const {
0054             return c_ == cr.c_;
0055         }
0056 
0057     private:
0058         const container_type *c_;
0059     };
0060 
0061   /** \brief Base class of all proxy classes that contain
0062    *         a (redirectable) reference to a mutable object.
0063    *
0064    * \param C the type of the container referred to
0065    */
0066     template<class C>
0067     class container_reference:
0068         private nonassignable {
0069     public:
0070         typedef C container_type;
0071 
0072         BOOST_UBLAS_INLINE
0073         container_reference ():
0074             c_ (0) {}
0075         BOOST_UBLAS_INLINE
0076         container_reference (container_type &c):
0077             c_ (&c) {}
0078 
0079         BOOST_UBLAS_INLINE
0080         container_type &operator () () const {
0081            return *c_;
0082         }
0083 
0084         BOOST_UBLAS_INLINE
0085         container_reference &assign (container_type *c) {
0086             c_ = c;
0087             return *this;
0088         }
0089 
0090         // Closure comparison
0091         BOOST_UBLAS_INLINE
0092         bool same_closure (const container_reference &cr) const {
0093             return c_ == cr.c_;
0094         }
0095 
0096     private:
0097         container_type *c_;
0098     };
0099 
0100   /** \brief Base class of all forward iterators.
0101    * 
0102    *  \param IC the iterator category
0103    *  \param I the derived iterator type
0104    *  \param T the value type
0105    * 
0106    * The forward iterator can only proceed in one direction
0107    * via the post increment operator.
0108    */
0109     template<class IC, class I, class T>
0110     struct forward_iterator_base:
0111         public std::iterator<IC, T> {
0112         typedef I derived_iterator_type;
0113         typedef T derived_value_type;
0114 
0115         // Arithmetic
0116         BOOST_UBLAS_INLINE
0117         derived_iterator_type operator ++ (int) {
0118             derived_iterator_type &d (*static_cast<const derived_iterator_type *> (this));
0119             derived_iterator_type tmp (d);
0120             ++ d;
0121             return tmp;
0122         }
0123         BOOST_UBLAS_INLINE
0124         friend derived_iterator_type operator ++ (derived_iterator_type &d, int) {
0125             derived_iterator_type tmp (d);
0126             ++ d;
0127             return tmp;
0128         }
0129 
0130         // Comparison
0131         BOOST_UBLAS_INLINE
0132         bool operator != (const derived_iterator_type &it) const {
0133             const derived_iterator_type *d = static_cast<const derived_iterator_type *> (this);
0134             return ! (*d == it);
0135         }
0136     };
0137 
0138   /** \brief Base class of all bidirectional iterators.
0139    *
0140    * \param IC the iterator category
0141    * \param I the derived iterator type
0142    * \param T the value type
0143    *
0144    * The bidirectional iterator can proceed in both directions
0145    * via the post increment and post decrement operator.
0146    */
0147     template<class IC, class I, class T>
0148     struct bidirectional_iterator_base:
0149         public std::iterator<IC, T> {
0150         typedef I derived_iterator_type;
0151         typedef T derived_value_type;
0152 
0153         // Arithmetic
0154         BOOST_UBLAS_INLINE
0155         derived_iterator_type operator ++ (int) {
0156             derived_iterator_type &d (*static_cast<const derived_iterator_type *> (this));
0157             derived_iterator_type tmp (d);
0158             ++ d;
0159             return tmp;
0160         }
0161         BOOST_UBLAS_INLINE
0162         friend derived_iterator_type operator ++ (derived_iterator_type &d, int) {
0163             derived_iterator_type tmp (d);
0164             ++ d;
0165             return tmp;
0166         }
0167         BOOST_UBLAS_INLINE
0168         derived_iterator_type operator -- (int) {
0169             derived_iterator_type &d (*static_cast<const derived_iterator_type *> (this));
0170             derived_iterator_type tmp (d);
0171             -- d;
0172             return tmp;
0173         }
0174         BOOST_UBLAS_INLINE
0175         friend derived_iterator_type operator -- (derived_iterator_type &d, int) {
0176             derived_iterator_type tmp (d);
0177             -- d;
0178             return tmp;
0179         }
0180 
0181         // Comparison
0182         BOOST_UBLAS_INLINE
0183         bool operator != (const derived_iterator_type &it) const {
0184             const derived_iterator_type *d = static_cast<const derived_iterator_type *> (this);
0185             return ! (*d == it);
0186         }
0187     };
0188 
0189   /** \brief Base class of all random access iterators.
0190    *
0191    * \param IC the iterator category
0192    * \param I the derived iterator type
0193    * \param T the value type
0194    * \param D the difference type, default: std::ptrdiff_t
0195    *
0196    * The random access iterator can proceed in both directions
0197    * via the post increment/decrement operator or in larger steps
0198    * via the +, - and +=, -= operators. The random access iterator
0199    * is LessThan Comparable.
0200    */
0201     template<class IC, class I, class T, class D = std::ptrdiff_t>
0202     // ISSUE the default for D seems rather dangerous as it can easily be (silently) incorrect
0203     struct random_access_iterator_base:
0204         public std::iterator<IC, T> {
0205         typedef I derived_iterator_type;
0206         typedef T derived_value_type;
0207         typedef D derived_difference_type;
0208 
0209         /* FIXME Need to explicitly pass derived_reference_type as otherwise I undefined type or forward declared
0210         typedef typename derived_iterator_type::reference derived_reference_type;
0211         // Indexed element
0212         BOOST_UBLAS_INLINE
0213         derived_reference_type operator [] (derived_difference_type n) {
0214             return *(*this + n);
0215         }
0216         */
0217 
0218         // Arithmetic
0219         BOOST_UBLAS_INLINE
0220         derived_iterator_type operator ++ (int) {
0221             derived_iterator_type &d (*static_cast<derived_iterator_type *> (this));
0222             derived_iterator_type tmp (d);
0223             ++ d;
0224             return tmp;
0225         }
0226         BOOST_UBLAS_INLINE
0227         friend derived_iterator_type operator ++ (derived_iterator_type &d, int) {
0228             derived_iterator_type tmp (d);
0229             ++ d;
0230             return tmp;
0231         }
0232         BOOST_UBLAS_INLINE
0233         derived_iterator_type operator -- (int) {
0234             derived_iterator_type &d (*static_cast<derived_iterator_type *> (this));
0235             derived_iterator_type tmp (d);
0236             -- d;
0237             return tmp;
0238         }
0239         BOOST_UBLAS_INLINE
0240         friend derived_iterator_type operator -- (derived_iterator_type &d, int) {
0241             derived_iterator_type tmp (d);
0242             -- d;
0243             return tmp;
0244         }
0245         BOOST_UBLAS_INLINE
0246         derived_iterator_type operator + (derived_difference_type n) const {
0247             derived_iterator_type tmp (*static_cast<const derived_iterator_type *> (this));
0248             return tmp += n;
0249         }
0250         BOOST_UBLAS_INLINE
0251         friend derived_iterator_type operator + (const derived_iterator_type &d, derived_difference_type n) {
0252             derived_iterator_type tmp (d);
0253             return tmp += n;
0254         }
0255         BOOST_UBLAS_INLINE
0256         friend derived_iterator_type operator + (derived_difference_type n, const derived_iterator_type &d) {
0257             derived_iterator_type tmp (d);
0258             return tmp += n;
0259         }
0260         BOOST_UBLAS_INLINE
0261         derived_iterator_type operator - (derived_difference_type n) const {
0262             derived_iterator_type tmp (*static_cast<const derived_iterator_type *> (this));
0263             return tmp -= n;
0264         }
0265         BOOST_UBLAS_INLINE
0266         friend derived_iterator_type operator - (const derived_iterator_type &d, derived_difference_type n) {
0267             derived_iterator_type tmp (d);
0268             return tmp -= n;
0269         }
0270 
0271         // Comparison
0272         BOOST_UBLAS_INLINE
0273         bool operator != (const derived_iterator_type &it) const {
0274             const derived_iterator_type *d = static_cast<const derived_iterator_type *> (this);
0275             return ! (*d == it);
0276         }
0277         BOOST_UBLAS_INLINE
0278         bool operator <= (const derived_iterator_type &it) const {
0279             const derived_iterator_type *d = static_cast<const derived_iterator_type *> (this);
0280             return ! (it < *d);
0281         }
0282         BOOST_UBLAS_INLINE
0283         bool operator >= (const derived_iterator_type &it) const {
0284             const derived_iterator_type *d = static_cast<const derived_iterator_type *> (this);
0285             return ! (*d < it);
0286         }
0287         BOOST_UBLAS_INLINE
0288         bool operator > (const derived_iterator_type &it) const {
0289             const derived_iterator_type *d = static_cast<const derived_iterator_type *> (this);
0290             return it < *d;
0291         }
0292     };
0293 
0294   /** \brief Base class of all reverse iterators. (non-MSVC version)
0295    *
0296    * \param I the derived iterator type
0297    * \param T the value type
0298    * \param R the reference type
0299    *
0300    * The reverse iterator implements a bidirectional iterator
0301    * reversing the elements of the underlying iterator. It
0302    * implements most operators of a random access iterator.
0303    *
0304    * uBLAS extension: it.index()
0305    */
0306 
0307     // Renamed this class from reverse_iterator to get
0308     // typedef reverse_iterator<...> reverse_iterator
0309     // working. Thanks to Gabriel Dos Reis for explaining this.
0310     template <class I>
0311     class reverse_iterator_base:
0312         public std::reverse_iterator<I> {
0313     public:
0314         typedef typename I::container_type container_type;
0315         typedef typename container_type::size_type size_type;
0316         typedef typename I::difference_type difference_type;
0317         typedef I iterator_type;
0318 
0319         // Construction and destruction
0320         BOOST_UBLAS_INLINE
0321         reverse_iterator_base ():
0322             std::reverse_iterator<iterator_type> () {}
0323         BOOST_UBLAS_INLINE
0324         reverse_iterator_base (const iterator_type &it):
0325             std::reverse_iterator<iterator_type> (it) {}
0326 
0327         // Arithmetic
0328         BOOST_UBLAS_INLINE
0329         reverse_iterator_base &operator ++ () {
0330             return *this = -- this->base ();
0331         }
0332         BOOST_UBLAS_INLINE
0333         reverse_iterator_base operator ++ (int) {
0334             reverse_iterator_base tmp (*this);
0335             *this = -- this->base ();
0336             return tmp;
0337         }
0338         BOOST_UBLAS_INLINE
0339         reverse_iterator_base &operator -- () {
0340             return *this = ++ this->base ();
0341         }
0342         BOOST_UBLAS_INLINE
0343         reverse_iterator_base operator -- (int) {
0344             reverse_iterator_base tmp (*this);
0345             *this = ++ this->base ();
0346             return tmp;
0347         }
0348         BOOST_UBLAS_INLINE
0349         reverse_iterator_base &operator += (difference_type n) {
0350             return *this = this->base () - n;
0351         }
0352         BOOST_UBLAS_INLINE
0353         reverse_iterator_base &operator -= (difference_type n) {
0354             return *this = this->base () + n;
0355         }
0356 
0357         BOOST_UBLAS_INLINE
0358         friend reverse_iterator_base operator + (const reverse_iterator_base &it, difference_type n) {
0359             reverse_iterator_base tmp (it);
0360             return tmp += n;
0361         }
0362         BOOST_UBLAS_INLINE
0363         friend reverse_iterator_base operator + (difference_type n, const reverse_iterator_base &it) {
0364             reverse_iterator_base tmp (it);
0365             return tmp += n;
0366         }
0367         BOOST_UBLAS_INLINE
0368         friend reverse_iterator_base operator - (const reverse_iterator_base &it, difference_type n) {
0369             reverse_iterator_base tmp (it);
0370             return tmp -= n;
0371         }
0372         BOOST_UBLAS_INLINE
0373         friend difference_type operator - (const reverse_iterator_base &it1, const reverse_iterator_base &it2) {
0374             return it2.base () - it1.base ();
0375         }
0376 
0377         BOOST_UBLAS_INLINE
0378         const container_type &operator () () const {
0379             return this->base () ();
0380         }
0381 
0382         BOOST_UBLAS_INLINE
0383         size_type index () const {
0384             iterator_type tmp (this->base ());
0385             return (-- tmp).index ();
0386         }
0387     };
0388 
0389   /** \brief 1st base class of all matrix reverse iterators. (non-MSVC version)
0390    *
0391    * \param I the derived iterator type
0392    *
0393    * The reverse iterator implements a bidirectional iterator
0394    * reversing the elements of the underlying iterator. It
0395    * implements most operators of a random access iterator.
0396    *
0397    * uBLAS extension: it.index1(), it.index2() and access to
0398    * the dual iterator via begin(), end(), rbegin(), rend()
0399    */
0400 
0401     // Renamed this class from reverse_iterator1 to get
0402     // typedef reverse_iterator1<...> reverse_iterator1
0403     // working. Thanks to Gabriel Dos Reis for explaining this.
0404     template <class I>
0405     class reverse_iterator_base1:
0406         public std::reverse_iterator<I> {
0407     public:
0408         typedef typename I::container_type container_type;
0409         typedef typename container_type::size_type size_type;
0410         typedef typename I::difference_type difference_type;
0411         typedef I iterator_type;
0412         typedef typename I::dual_iterator_type dual_iterator_type;
0413         typedef typename I::dual_reverse_iterator_type dual_reverse_iterator_type;
0414 
0415         // Construction and destruction
0416         BOOST_UBLAS_INLINE
0417         reverse_iterator_base1 ():
0418             std::reverse_iterator<iterator_type> () {}
0419         BOOST_UBLAS_INLINE
0420         reverse_iterator_base1 (const iterator_type &it):
0421             std::reverse_iterator<iterator_type> (it) {}
0422 
0423         // Arithmetic
0424         BOOST_UBLAS_INLINE
0425         reverse_iterator_base1 &operator ++ () {
0426             return *this = -- this->base ();
0427         }
0428         BOOST_UBLAS_INLINE
0429         reverse_iterator_base1 operator ++ (int) {
0430             reverse_iterator_base1 tmp (*this);
0431             *this = -- this->base ();
0432             return tmp;
0433         }
0434         BOOST_UBLAS_INLINE
0435         reverse_iterator_base1 &operator -- () {
0436             return *this = ++ this->base ();
0437         }
0438         BOOST_UBLAS_INLINE
0439         reverse_iterator_base1 operator -- (int) {
0440             reverse_iterator_base1 tmp (*this);
0441             *this = ++ this->base ();
0442             return tmp;
0443         }
0444         BOOST_UBLAS_INLINE
0445         reverse_iterator_base1 &operator += (difference_type n) {
0446             return *this = this->base () - n;
0447         }
0448         BOOST_UBLAS_INLINE
0449         reverse_iterator_base1 &operator -= (difference_type n) {
0450             return *this = this->base () + n;
0451         }
0452 
0453         BOOST_UBLAS_INLINE
0454         friend reverse_iterator_base1 operator + (const reverse_iterator_base1 &it, difference_type n) {
0455             reverse_iterator_base1 tmp (it);
0456             return tmp += n;
0457         }
0458         BOOST_UBLAS_INLINE
0459         friend reverse_iterator_base1 operator + (difference_type n, const reverse_iterator_base1 &it) {
0460             reverse_iterator_base1 tmp (it);
0461             return tmp += n;
0462         }
0463         BOOST_UBLAS_INLINE
0464         friend reverse_iterator_base1 operator - (const reverse_iterator_base1 &it, difference_type n) {
0465             reverse_iterator_base1 tmp (it);
0466             return tmp -= n;
0467         }
0468         BOOST_UBLAS_INLINE
0469         friend difference_type operator - (const reverse_iterator_base1 &it1, const reverse_iterator_base1 &it2) {
0470             return it2.base () - it1.base ();
0471         }
0472 
0473         BOOST_UBLAS_INLINE
0474         const container_type &operator () () const {
0475             return this->base () ();
0476         }
0477 
0478         BOOST_UBLAS_INLINE
0479         size_type index1 () const {
0480             iterator_type tmp (this->base ());
0481             return (-- tmp).index1 ();
0482         }
0483         BOOST_UBLAS_INLINE
0484         size_type index2 () const {
0485             iterator_type tmp (this->base ());
0486             return (-- tmp).index2 ();
0487         }
0488 
0489         BOOST_UBLAS_INLINE
0490         dual_iterator_type begin () const {
0491             iterator_type tmp (this->base ());
0492             return (-- tmp).begin ();
0493         }
0494         BOOST_UBLAS_INLINE
0495         dual_iterator_type end () const {
0496             iterator_type tmp (this->base ());
0497             return (-- tmp).end ();
0498         }
0499         BOOST_UBLAS_INLINE
0500         dual_reverse_iterator_type rbegin () const {
0501             return dual_reverse_iterator_type (end ());
0502         }
0503         BOOST_UBLAS_INLINE
0504         dual_reverse_iterator_type rend () const {
0505             return dual_reverse_iterator_type (begin ());
0506         }
0507     };
0508 
0509   /** \brief 2nd base class of all matrix reverse iterators. (non-MSVC version)
0510    *
0511    * \param I the derived iterator type
0512    *
0513    * The reverse iterator implements a bidirectional iterator
0514    * reversing the elements of the underlying iterator. It
0515    * implements most operators of a random access iterator.
0516    *
0517    * uBLAS extension: it.index1(), it.index2() and access to
0518    * the dual iterator via begin(), end(), rbegin(), rend()
0519    *
0520    * Note: this type is _identical_ to reverse_iterator_base1
0521    */
0522 
0523     // Renamed this class from reverse_iterator2 to get
0524     // typedef reverse_iterator2<...> reverse_iterator2
0525     // working. Thanks to Gabriel Dos Reis for explaining this.
0526     template <class I>
0527     class reverse_iterator_base2:
0528         public std::reverse_iterator<I> {
0529     public:
0530         typedef typename I::container_type container_type;
0531         typedef typename container_type::size_type size_type;
0532         typedef typename I::difference_type difference_type;
0533         typedef I iterator_type;
0534         typedef typename I::dual_iterator_type dual_iterator_type;
0535         typedef typename I::dual_reverse_iterator_type dual_reverse_iterator_type;
0536 
0537         // Construction and destruction
0538         BOOST_UBLAS_INLINE
0539         reverse_iterator_base2 ():
0540             std::reverse_iterator<iterator_type> () {}
0541         BOOST_UBLAS_INLINE
0542         reverse_iterator_base2 (const iterator_type &it):
0543             std::reverse_iterator<iterator_type> (it) {}
0544 
0545         // Arithmetic
0546         BOOST_UBLAS_INLINE
0547         reverse_iterator_base2 &operator ++ () {
0548             return *this = -- this->base ();
0549         }
0550         BOOST_UBLAS_INLINE
0551         reverse_iterator_base2 operator ++ (int) {
0552             reverse_iterator_base2 tmp (*this);
0553             *this = -- this->base ();
0554             return tmp;
0555         }
0556         BOOST_UBLAS_INLINE
0557         reverse_iterator_base2 &operator -- () {
0558             return *this = ++ this->base ();
0559         }
0560         BOOST_UBLAS_INLINE
0561         reverse_iterator_base2 operator -- (int) {
0562             reverse_iterator_base2 tmp (*this);
0563             *this = ++ this->base ();
0564             return tmp;
0565         }
0566         BOOST_UBLAS_INLINE
0567         reverse_iterator_base2 &operator += (difference_type n) {
0568             return *this = this->base () - n;
0569         }
0570         BOOST_UBLAS_INLINE
0571         reverse_iterator_base2 &operator -= (difference_type n) {
0572             return *this = this->base () + n;
0573         }
0574 
0575         BOOST_UBLAS_INLINE
0576         friend reverse_iterator_base2 operator + (const reverse_iterator_base2 &it, difference_type n) {
0577             reverse_iterator_base2 tmp (it);
0578             return tmp += n;
0579         }
0580         BOOST_UBLAS_INLINE
0581         friend reverse_iterator_base2 operator + (difference_type n, const reverse_iterator_base2 &it) {
0582             reverse_iterator_base2 tmp (it);
0583             return tmp += n;
0584         }
0585         BOOST_UBLAS_INLINE
0586         friend reverse_iterator_base2 operator - (const reverse_iterator_base2 &it, difference_type n) {
0587             reverse_iterator_base2 tmp (it);
0588             return tmp -= n;
0589         }
0590         BOOST_UBLAS_INLINE
0591         friend difference_type operator - (const reverse_iterator_base2 &it1, const reverse_iterator_base2 &it2) {
0592             return it2.base () - it1.base ();
0593         }
0594 
0595         BOOST_UBLAS_INLINE
0596         const container_type &operator () () const {
0597             return this->base () ();
0598         }
0599 
0600         BOOST_UBLAS_INLINE
0601         size_type index1 () const {
0602             iterator_type tmp (this->base ());
0603             return (-- tmp).index1 ();
0604         }
0605         BOOST_UBLAS_INLINE
0606         size_type index2 () const {
0607             iterator_type tmp (this->base ());
0608             return (-- tmp).index2 ();
0609         }
0610 
0611         BOOST_UBLAS_INLINE
0612         dual_iterator_type begin () const {
0613             iterator_type tmp (this->base ());
0614             return (-- tmp).begin ();
0615         }
0616         BOOST_UBLAS_INLINE
0617         dual_iterator_type end () const {
0618             iterator_type tmp (this->base ());
0619             return (-- tmp).end ();
0620         }
0621         BOOST_UBLAS_INLINE
0622         dual_reverse_iterator_type rbegin () const {
0623             return dual_reverse_iterator_type (end ());
0624         }
0625         BOOST_UBLAS_INLINE
0626         dual_reverse_iterator_type rend () const {
0627             return dual_reverse_iterator_type (begin ());
0628         }
0629     };
0630 
0631   /** \brief A class implementing an indexed random access iterator.
0632    *
0633    * \param C the (mutable) container type
0634    * \param IC the iterator category
0635    *
0636    * This class implements a random access iterator. The current 
0637    * position is stored as the unsigned integer it_ and the
0638    * values are accessed via operator()(it_) of the container.
0639    *
0640    * uBLAS extension: index()
0641    */
0642 
0643     template<class C, class IC>
0644     class indexed_iterator:
0645         public container_reference<C>,
0646         public random_access_iterator_base<IC,
0647                                            indexed_iterator<C, IC>,
0648                                            typename C::value_type,
0649                                            typename C::difference_type> {
0650     public:
0651         typedef C container_type;
0652         typedef IC iterator_category;
0653         typedef typename container_type::size_type size_type;
0654         typedef typename container_type::difference_type difference_type;
0655         typedef typename container_type::value_type value_type;
0656         typedef typename container_type::reference reference;
0657 
0658         // Construction and destruction
0659         BOOST_UBLAS_INLINE
0660         indexed_iterator ():
0661             container_reference<container_type> (), it_ () {}
0662         BOOST_UBLAS_INLINE
0663         indexed_iterator (container_type &c, size_type it):
0664             container_reference<container_type> (c), it_ (it) {}
0665 
0666         // Arithmetic
0667         BOOST_UBLAS_INLINE
0668         indexed_iterator &operator ++ () {
0669             ++ it_;
0670             return *this;
0671         }
0672         BOOST_UBLAS_INLINE
0673         indexed_iterator &operator -- () {
0674             -- it_;
0675             return *this;
0676         }
0677         BOOST_UBLAS_INLINE
0678         indexed_iterator &operator += (difference_type n) {
0679             it_ += n;
0680             return *this;
0681         }
0682         BOOST_UBLAS_INLINE
0683         indexed_iterator &operator -= (difference_type n) {
0684             it_ -= n;
0685             return *this;
0686         }
0687         BOOST_UBLAS_INLINE
0688         difference_type operator - (const indexed_iterator &it) const {
0689             BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
0690             return it_ - it.it_;
0691         }
0692 
0693         // Dereference
0694         BOOST_UBLAS_INLINE
0695         reference operator * () const {
0696             BOOST_UBLAS_CHECK (index () < (*this) ().size (), bad_index ());
0697             return (*this) () (it_);
0698         }
0699         BOOST_UBLAS_INLINE
0700         reference operator [] (difference_type n) const {
0701             return *((*this) + n);
0702         }
0703 
0704         // Index
0705         BOOST_UBLAS_INLINE
0706         size_type index () const {
0707             return it_;
0708         }
0709 
0710         // Assignment
0711         BOOST_UBLAS_INLINE
0712         indexed_iterator &operator = (const indexed_iterator &it) {
0713             // FIX: ICC needs full qualification?!
0714             // assign (&it ());
0715             container_reference<C>::assign (&it ());
0716             it_ = it.it_;
0717             return *this;
0718         }
0719 
0720         // Comparison
0721         BOOST_UBLAS_INLINE
0722         bool operator == (const indexed_iterator &it) const {
0723             BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
0724             return it_ == it.it_;
0725         }
0726         BOOST_UBLAS_INLINE
0727         bool operator < (const indexed_iterator &it) const {
0728             BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
0729             return it_ < it.it_;
0730         }
0731 
0732     private:
0733         size_type it_;
0734     };
0735 
0736   /** \brief A class implementing an indexed random access iterator.
0737    *
0738    * \param C the (immutable) container type
0739    * \param IC the iterator category
0740    *
0741    * This class implements a random access iterator. The current 
0742    * position is stored as the unsigned integer \c it_ and the
0743    * values are accessed via \c operator()(it_) of the container.
0744    *
0745    * uBLAS extension: \c index()
0746    *
0747    * Note: there is an automatic conversion from 
0748    * \c indexed_iterator to \c indexed_const_iterator
0749    */
0750 
0751     template<class C, class IC>
0752     class indexed_const_iterator:
0753         public container_const_reference<C>,
0754         public random_access_iterator_base<IC,
0755                                            indexed_const_iterator<C, IC>,
0756                                            typename C::value_type,
0757                                            typename C::difference_type> {
0758     public:
0759         typedef C container_type;
0760         typedef IC iterator_category;
0761         typedef typename container_type::size_type size_type;
0762         typedef typename container_type::difference_type difference_type;
0763         typedef typename container_type::value_type value_type;
0764         typedef typename container_type::const_reference reference;
0765         typedef indexed_iterator<container_type, iterator_category> iterator_type;
0766 
0767         // Construction and destruction
0768         BOOST_UBLAS_INLINE
0769         indexed_const_iterator ():
0770             container_const_reference<container_type> (), it_ () {}
0771         BOOST_UBLAS_INLINE
0772         indexed_const_iterator (const container_type &c, size_type it):
0773             container_const_reference<container_type> (c), it_ (it) {}
0774         BOOST_UBLAS_INLINE 
0775         indexed_const_iterator (const iterator_type &it):
0776             container_const_reference<container_type> (it ()), it_ (it.index ()) {}
0777 
0778         // Arithmetic
0779         BOOST_UBLAS_INLINE
0780         indexed_const_iterator &operator ++ () {
0781             ++ it_;
0782             return *this;
0783         }
0784         BOOST_UBLAS_INLINE
0785         indexed_const_iterator &operator -- () {
0786             -- it_;
0787             return *this;
0788         }
0789         BOOST_UBLAS_INLINE
0790         indexed_const_iterator &operator += (difference_type n) {
0791             it_ += n;
0792             return *this;
0793         }
0794         BOOST_UBLAS_INLINE
0795         indexed_const_iterator &operator -= (difference_type n) {
0796             it_ -= n;
0797             return *this;
0798         }
0799         BOOST_UBLAS_INLINE
0800         difference_type operator - (const indexed_const_iterator &it) const {
0801             BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
0802             return it_ - it.it_;
0803         }
0804 
0805         // Dereference
0806         BOOST_UBLAS_INLINE
0807         reference operator * () const {
0808             BOOST_UBLAS_CHECK (index () < (*this) ().size (), bad_index ());
0809             return (*this) () (it_);
0810         }
0811         BOOST_UBLAS_INLINE
0812         reference operator [] (difference_type n) const {
0813             return *((*this) + n);
0814         }
0815 
0816         // Index
0817         BOOST_UBLAS_INLINE
0818         size_type index () const {
0819             return it_;
0820         }
0821 
0822         // Assignment
0823         BOOST_UBLAS_INLINE
0824         indexed_const_iterator &operator = (const indexed_const_iterator &it) {
0825             // FIX: ICC needs full qualification?!
0826             // assign (&it ());
0827             container_const_reference<C>::assign (&it ());
0828             it_ = it.it_;
0829             return *this;
0830         }
0831 
0832         // Comparison
0833         BOOST_UBLAS_INLINE
0834         bool operator == (const indexed_const_iterator &it) const {
0835             BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
0836             return it_ == it.it_;
0837         }
0838         BOOST_UBLAS_INLINE
0839         bool operator < (const indexed_const_iterator &it) const {
0840             BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
0841             return it_ < it.it_;
0842         }
0843 
0844     private:
0845         size_type it_;
0846 
0847         friend class indexed_iterator<container_type, iterator_category>;
0848     };
0849 
0850     template<class C, class IC>
0851     class indexed_iterator2;
0852 
0853   /** \brief A class implementing an indexed random access iterator 
0854    * of a matrix.
0855    *
0856    * \param C the (mutable) container type
0857    * \param IC the iterator category
0858    *
0859    * This class implements a random access iterator. The current
0860    * position is stored as two unsigned integers \c it1_ and \c it2_
0861    * and the values are accessed via \c operator()(it1_, it2_) of the
0862    * container. The iterator changes the first index.
0863    *
0864    * uBLAS extension: \c index1(), \c index2() and access to the
0865    * dual iterator via \c begin(), \c end(), \c rbegin() and \c rend()
0866    *
0867    * Note: The container has to support the \code find2(rank, i, j) \endcode 
0868    * method
0869    */
0870 
0871     template<class C, class IC>
0872     class indexed_iterator1:
0873         public container_reference<C>, 
0874         public random_access_iterator_base<IC,
0875                                            indexed_iterator1<C, IC>, 
0876                                            typename C::value_type,
0877                                            typename C::difference_type> {
0878     public:
0879         typedef C container_type;
0880         typedef IC iterator_category;
0881         typedef typename container_type::size_type size_type;
0882         typedef typename container_type::difference_type difference_type;
0883         typedef typename container_type::value_type value_type;
0884         typedef typename container_type::reference reference;
0885 
0886         typedef indexed_iterator2<container_type, iterator_category> dual_iterator_type;
0887         typedef reverse_iterator_base2<dual_iterator_type> dual_reverse_iterator_type;
0888 
0889         // Construction and destruction
0890         BOOST_UBLAS_INLINE
0891         indexed_iterator1 ():
0892             container_reference<container_type> (), it1_ (), it2_ () {}
0893         BOOST_UBLAS_INLINE 
0894         indexed_iterator1 (container_type &c, size_type it1, size_type it2):
0895             container_reference<container_type> (c), it1_ (it1), it2_ (it2) {}
0896 
0897         // Arithmetic
0898         BOOST_UBLAS_INLINE
0899         indexed_iterator1 &operator ++ () {
0900             ++ it1_;
0901             return *this;
0902         }
0903         BOOST_UBLAS_INLINE
0904         indexed_iterator1 &operator -- () {
0905             -- it1_;
0906             return *this;
0907         }
0908         BOOST_UBLAS_INLINE
0909         indexed_iterator1 &operator += (difference_type n) {
0910             it1_ += n;
0911             return *this;
0912         }
0913         BOOST_UBLAS_INLINE
0914         indexed_iterator1 &operator -= (difference_type n) {
0915             it1_ -= n;
0916             return *this;
0917         }
0918         BOOST_UBLAS_INLINE
0919         difference_type operator - (const indexed_iterator1 &it) const {
0920             BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
0921             BOOST_UBLAS_CHECK (it2_ == it.it2_, external_logic ());
0922             return it1_ - it.it1_;
0923         }
0924 
0925         // Dereference
0926         BOOST_UBLAS_INLINE
0927         reference operator * () const {
0928             BOOST_UBLAS_CHECK (index1 () < (*this) ().size1 (), bad_index ());
0929             BOOST_UBLAS_CHECK (index2 () < (*this) ().size2 (), bad_index ());
0930             return (*this) () (it1_, it2_);
0931         }
0932         BOOST_UBLAS_INLINE
0933         reference operator [] (difference_type n) const {
0934             return *((*this) + n);
0935         }
0936 
0937         // Index
0938         BOOST_UBLAS_INLINE
0939         size_type index1 () const {
0940             return it1_;
0941         }
0942         BOOST_UBLAS_INLINE
0943         size_type index2 () const {
0944             return it2_;
0945         }
0946 
0947         BOOST_UBLAS_INLINE
0948         dual_iterator_type begin () const {
0949             return (*this) ().find2 (1, index1 (), 0); 
0950         }
0951         BOOST_UBLAS_INLINE
0952         dual_iterator_type end () const {
0953             return (*this) ().find2 (1, index1 (), (*this) ().size2 ());
0954         }
0955         BOOST_UBLAS_INLINE
0956         dual_reverse_iterator_type rbegin () const {
0957             return dual_reverse_iterator_type (end ());
0958         }
0959         BOOST_UBLAS_INLINE
0960         dual_reverse_iterator_type rend () const {
0961             return dual_reverse_iterator_type (begin ());
0962         }
0963 
0964         // Assignment
0965         BOOST_UBLAS_INLINE
0966         indexed_iterator1 &operator = (const indexed_iterator1 &it) {
0967             // FIX: ICC needs full qualification?!
0968             // assign (&it ());
0969             container_reference<C>::assign (&it ());
0970             it1_ = it.it1_;
0971             it2_ = it.it2_;
0972             return *this;
0973         }
0974 
0975         // Comparison
0976         BOOST_UBLAS_INLINE
0977         bool operator == (const indexed_iterator1 &it) const {
0978             BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
0979             BOOST_UBLAS_CHECK (it2_ == it.it2_, external_logic ());
0980             return it1_ == it.it1_;
0981         }
0982         BOOST_UBLAS_INLINE
0983         bool operator < (const indexed_iterator1 &it) const {
0984             BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
0985             BOOST_UBLAS_CHECK (it2_ == it.it2_, external_logic ());
0986             return it1_ < it.it1_;
0987         }
0988 
0989     private:
0990         size_type it1_;
0991         size_type it2_;
0992     };
0993 
0994     template<class C, class IC>
0995     class indexed_const_iterator2;
0996 
0997   /** \brief A class implementing an indexed random access iterator 
0998    * of a matrix.
0999    *
1000    * \param C the (immutable) container type
1001    * \param IC the iterator category
1002    *
1003    * This class implements a random access iterator. The current
1004    * position is stored as two unsigned integers \c it1_ and \c it2_
1005    * and the values are accessed via \c operator()(it1_, it2_) of the
1006    * container. The iterator changes the first index.
1007    *
1008    * uBLAS extension: \c index1(), \c index2() and access to the
1009    * dual iterator via \c begin(), \c end(), \c rbegin() and \c rend()
1010    *
1011    * Note 1: The container has to support the find2(rank, i, j) method
1012    *
1013    * Note 2: there is an automatic conversion from 
1014    * \c indexed_iterator1 to \c indexed_const_iterator1
1015    */
1016 
1017     template<class C, class IC>
1018     class indexed_const_iterator1:
1019         public container_const_reference<C>, 
1020         public random_access_iterator_base<IC,
1021                                            indexed_const_iterator1<C, IC>, 
1022                                            typename C::value_type,
1023                                            typename C::difference_type> {
1024     public:
1025         typedef C container_type;
1026         typedef IC iterator_category;
1027         typedef typename container_type::size_type size_type;
1028         typedef typename container_type::difference_type difference_type;
1029         typedef typename container_type::value_type value_type;
1030         typedef typename container_type::const_reference reference;
1031 
1032         typedef indexed_iterator1<container_type, iterator_category> iterator_type;
1033         typedef indexed_const_iterator2<container_type, iterator_category> dual_iterator_type;
1034         typedef reverse_iterator_base2<dual_iterator_type> dual_reverse_iterator_type;
1035 
1036         // Construction and destruction
1037         BOOST_UBLAS_INLINE
1038         indexed_const_iterator1 ():
1039             container_const_reference<container_type> (), it1_ (), it2_ () {}
1040         BOOST_UBLAS_INLINE
1041         indexed_const_iterator1 (const container_type &c, size_type it1, size_type it2):
1042             container_const_reference<container_type> (c), it1_ (it1), it2_ (it2) {}
1043         BOOST_UBLAS_INLINE 
1044         indexed_const_iterator1 (const iterator_type &it):
1045             container_const_reference<container_type> (it ()), it1_ (it.index1 ()), it2_ (it.index2 ()) {}
1046 
1047         // Arithmetic
1048         BOOST_UBLAS_INLINE
1049         indexed_const_iterator1 &operator ++ () {
1050             ++ it1_;
1051             return *this;
1052         }
1053         BOOST_UBLAS_INLINE
1054         indexed_const_iterator1 &operator -- () {
1055             -- it1_;
1056             return *this;
1057         }
1058         BOOST_UBLAS_INLINE
1059         indexed_const_iterator1 &operator += (difference_type n) {
1060             it1_ += n;
1061             return *this;
1062         }
1063         BOOST_UBLAS_INLINE
1064         indexed_const_iterator1 &operator -= (difference_type n) {
1065             it1_ -= n;
1066             return *this;
1067         }
1068         BOOST_UBLAS_INLINE
1069         difference_type operator - (const indexed_const_iterator1 &it) const {
1070             BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
1071             BOOST_UBLAS_CHECK (it2_ == it.it2_, external_logic ());
1072             return it1_ - it.it1_;
1073         }
1074 
1075         // Dereference
1076         BOOST_UBLAS_INLINE
1077         reference operator * () const {
1078             BOOST_UBLAS_CHECK (index1 () < (*this) ().size1 (), bad_index ());
1079             BOOST_UBLAS_CHECK (index2 () < (*this) ().size2 (), bad_index ());
1080             return (*this) () (it1_, it2_);
1081         }
1082         BOOST_UBLAS_INLINE
1083         reference operator [] (difference_type n) const {
1084             return *((*this) + n);
1085         }
1086 
1087         // Index
1088         BOOST_UBLAS_INLINE
1089         size_type index1 () const {
1090             return it1_;
1091         }
1092         BOOST_UBLAS_INLINE
1093         size_type index2 () const {
1094             return it2_;
1095         }
1096 
1097         BOOST_UBLAS_INLINE
1098         dual_iterator_type begin () const {
1099             return (*this) ().find2 (1, index1 (), 0); 
1100         }
1101         BOOST_UBLAS_INLINE
1102         dual_iterator_type end () const {
1103             return (*this) ().find2 (1, index1 (), (*this) ().size2 ()); 
1104         }
1105         BOOST_UBLAS_INLINE
1106         dual_reverse_iterator_type rbegin () const {
1107             return dual_reverse_iterator_type (end ()); 
1108         }
1109         BOOST_UBLAS_INLINE
1110         dual_reverse_iterator_type rend () const {
1111             return dual_reverse_iterator_type (begin ()); 
1112         }
1113 
1114         // Assignment
1115         BOOST_UBLAS_INLINE
1116         indexed_const_iterator1 &operator = (const indexed_const_iterator1 &it) {
1117             // FIX: ICC needs full qualification?!
1118             // assign (&it ());
1119             container_const_reference<C>::assign (&it ());
1120             it1_ = it.it1_;
1121             it2_ = it.it2_;
1122             return *this;
1123         }
1124 
1125         // Comparison
1126         BOOST_UBLAS_INLINE
1127         bool operator == (const indexed_const_iterator1 &it) const {
1128             BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
1129             BOOST_UBLAS_CHECK (it2_ == it.it2_, external_logic ());
1130             return it1_ == it.it1_;
1131         }
1132         BOOST_UBLAS_INLINE
1133         bool operator < (const indexed_const_iterator1 &it) const {
1134             BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
1135             BOOST_UBLAS_CHECK (it2_ == it.it2_, external_logic ());
1136             return it1_ < it.it1_;
1137         }
1138 
1139     private:
1140         size_type it1_;
1141         size_type it2_;
1142 
1143         friend class indexed_iterator1<container_type, iterator_category>;
1144     };
1145 
1146   /** \brief A class implementing an indexed random access iterator 
1147    * of a matrix.
1148    *
1149    * \param C the (mutable) container type
1150    * \param IC the iterator category
1151    *
1152    * This class implements a random access iterator. The current
1153    * position is stored as two unsigned integers \c it1_ and \c it2_
1154    * and the values are accessed via \c operator()(it1_, it2_) of the
1155    * container. The iterator changes the second index.
1156    *
1157    * uBLAS extension: \c index1(), \c index2() and access to the
1158    * dual iterator via \c begin(), \c end(), \c rbegin() and \c rend()
1159    *
1160    * Note: The container has to support the find1(rank, i, j) method
1161    */
1162     template<class C, class IC>
1163     class indexed_iterator2:
1164         public container_reference<C>, 
1165         public random_access_iterator_base<IC,
1166                                            indexed_iterator2<C, IC>, 
1167                                            typename C::value_type,
1168                                            typename C::difference_type> {
1169     public:
1170         typedef C container_type;
1171         typedef IC iterator_category;
1172         typedef typename container_type::size_type size_type;
1173         typedef typename container_type::difference_type difference_type;
1174         typedef typename container_type::value_type value_type;
1175         typedef typename container_type::reference reference;
1176 
1177         typedef indexed_iterator1<container_type, iterator_category> dual_iterator_type;
1178         typedef reverse_iterator_base1<dual_iterator_type> dual_reverse_iterator_type;
1179 
1180         // Construction and destruction
1181         BOOST_UBLAS_INLINE
1182         indexed_iterator2 ():
1183             container_reference<container_type> (), it1_ (), it2_ () {}
1184         BOOST_UBLAS_INLINE
1185         indexed_iterator2 (container_type &c, size_type it1, size_type it2):
1186             container_reference<container_type> (c), it1_ (it1), it2_ (it2) {}
1187 
1188         // Arithmetic
1189         BOOST_UBLAS_INLINE
1190         indexed_iterator2 &operator ++ () {
1191             ++ it2_;
1192             return *this;
1193         }
1194         BOOST_UBLAS_INLINE
1195         indexed_iterator2 &operator -- () {
1196             -- it2_;
1197             return *this;
1198         }
1199         BOOST_UBLAS_INLINE
1200         indexed_iterator2 &operator += (difference_type n) {
1201             it2_ += n;
1202             return *this;
1203         }
1204         BOOST_UBLAS_INLINE
1205         indexed_iterator2 &operator -= (difference_type n) {
1206             it2_ -= n;
1207             return *this;
1208         }
1209         BOOST_UBLAS_INLINE
1210         difference_type operator - (const indexed_iterator2 &it) const {
1211             BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
1212             BOOST_UBLAS_CHECK (it1_ == it.it1_, external_logic ());
1213             return it2_ - it.it2_;
1214         }
1215 
1216         // Dereference
1217         BOOST_UBLAS_INLINE
1218         reference operator * () const {
1219             BOOST_UBLAS_CHECK (index1 () < (*this) ().size1 (), bad_index ());
1220             BOOST_UBLAS_CHECK (index2 () < (*this) ().size2 (), bad_index ());
1221             return (*this) () (it1_, it2_);
1222         }
1223         BOOST_UBLAS_INLINE
1224         reference operator [] (difference_type n) const {
1225             return *((*this) + n);
1226         }
1227 
1228         // Index
1229         BOOST_UBLAS_INLINE
1230         size_type index1 () const {
1231             return it1_;
1232         }
1233         BOOST_UBLAS_INLINE
1234         size_type index2 () const {
1235             return it2_;
1236         }
1237 
1238         BOOST_UBLAS_INLINE
1239         dual_iterator_type begin () const {
1240             return (*this) ().find1 (1, 0, index2 ());
1241         }
1242         BOOST_UBLAS_INLINE
1243         dual_iterator_type end () const {
1244             return (*this) ().find1 (1, (*this) ().size1 (), index2 ());
1245         }
1246         BOOST_UBLAS_INLINE
1247         dual_reverse_iterator_type rbegin () const {
1248             return dual_reverse_iterator_type (end ());
1249         }
1250         BOOST_UBLAS_INLINE
1251         dual_reverse_iterator_type rend () const {
1252             return dual_reverse_iterator_type (begin ());
1253         }
1254 
1255         // Assignment
1256         BOOST_UBLAS_INLINE
1257         indexed_iterator2 &operator = (const indexed_iterator2 &it) {
1258             // FIX: ICC needs full qualification?!
1259             // assign (&it ());
1260             container_reference<C>::assign (&it ());
1261             it1_ = it.it1_;
1262             it2_ = it.it2_;
1263             return *this;
1264         }
1265 
1266         // Comparison
1267         BOOST_UBLAS_INLINE
1268         bool operator == (const indexed_iterator2 &it) const {
1269             BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
1270             BOOST_UBLAS_CHECK (it1_ == it.it1_, external_logic ());
1271             return it2_ == it.it2_;
1272         }
1273         BOOST_UBLAS_INLINE
1274         bool operator < (const indexed_iterator2 &it) const {
1275             BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
1276             BOOST_UBLAS_CHECK (it1_ == it.it1_, external_logic ());
1277             return it2_ < it.it2_;
1278         }
1279 
1280     private:
1281         size_type it1_;
1282         size_type it2_;
1283     };
1284 
1285   /** \brief A class implementing an indexed random access iterator 
1286    * of a matrix.
1287    *
1288    * \param C the (immutable) container type
1289    * \param IC the iterator category
1290    *
1291    * This class implements a random access iterator. The current
1292    * position is stored as two unsigned integers \c it1_ and \c it2_
1293    * and the values are accessed via \c operator()(it1_, it2_) of the
1294    * container. The iterator changes the second index.
1295    *
1296    * uBLAS extension: \c index1(), \c index2() and access to the
1297    * dual iterator via \c begin(), \c end(), \c rbegin() and \c rend()
1298    *
1299    * Note 1: The container has to support the \c find2(rank, i, j) method
1300    *
1301    * Note 2: there is an automatic conversion from 
1302    * \c indexed_iterator2 to \c indexed_const_iterator2
1303    */
1304 
1305     template<class C, class IC>
1306     class indexed_const_iterator2:
1307         public container_const_reference<C>,
1308         public random_access_iterator_base<IC,
1309                                            indexed_const_iterator2<C, IC>,
1310                                            typename C::value_type,
1311                                            typename C::difference_type> {
1312     public:
1313         typedef C container_type;
1314         typedef IC iterator_category;
1315         typedef typename container_type::size_type size_type;
1316         typedef typename container_type::difference_type difference_type;
1317         typedef typename container_type::value_type value_type;
1318         typedef typename container_type::const_reference reference;
1319 
1320         typedef indexed_iterator2<container_type, iterator_category> iterator_type;
1321         typedef indexed_const_iterator1<container_type, iterator_category> dual_iterator_type;
1322         typedef reverse_iterator_base1<dual_iterator_type> dual_reverse_iterator_type;
1323 
1324         // Construction and destruction
1325         BOOST_UBLAS_INLINE
1326         indexed_const_iterator2 ():
1327             container_const_reference<container_type> (), it1_ (), it2_ () {}
1328         BOOST_UBLAS_INLINE
1329         indexed_const_iterator2 (const container_type &c, size_type it1, size_type it2):
1330             container_const_reference<container_type> (c), it1_ (it1), it2_ (it2) {}
1331         BOOST_UBLAS_INLINE
1332         indexed_const_iterator2 (const iterator_type &it):
1333             container_const_reference<container_type> (it ()), it1_ (it.index1 ()), it2_ (it.index2 ()) {}
1334 
1335         // Arithmetic
1336         BOOST_UBLAS_INLINE
1337         indexed_const_iterator2 &operator ++ () {
1338             ++ it2_;
1339             return *this;
1340         }
1341         BOOST_UBLAS_INLINE
1342         indexed_const_iterator2 &operator -- () {
1343             -- it2_;
1344             return *this;
1345         }
1346         BOOST_UBLAS_INLINE
1347         indexed_const_iterator2 &operator += (difference_type n) {
1348             it2_ += n;
1349             return *this;
1350         }
1351         BOOST_UBLAS_INLINE
1352         indexed_const_iterator2 &operator -= (difference_type n) {
1353             it2_ -= n;
1354             return *this;
1355         }
1356         BOOST_UBLAS_INLINE
1357         difference_type operator - (const indexed_const_iterator2 &it) const {
1358             BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
1359             BOOST_UBLAS_CHECK (it1_ == it.it1_, external_logic ());
1360             return it2_ - it.it2_;
1361         }
1362 
1363         // Dereference
1364         BOOST_UBLAS_INLINE
1365         reference operator * () const {
1366             BOOST_UBLAS_CHECK (index1 () < (*this) ().size1 (), bad_index ());
1367             BOOST_UBLAS_CHECK (index2 () < (*this) ().size2 (), bad_index ());
1368             return (*this) () (it1_, it2_);
1369         }
1370         BOOST_UBLAS_INLINE
1371         reference operator [] (difference_type n) const {
1372             return *((*this) + n);
1373         }
1374 
1375         // Index
1376         BOOST_UBLAS_INLINE
1377         size_type index1 () const {
1378             return it1_;
1379         }
1380         BOOST_UBLAS_INLINE
1381         size_type index2 () const {
1382             return it2_;
1383         }
1384 
1385         BOOST_UBLAS_INLINE
1386         dual_iterator_type begin () const {
1387             return (*this) ().find1 (1, 0, index2 ());
1388         }
1389         BOOST_UBLAS_INLINE
1390         dual_iterator_type end () const {
1391             return (*this) ().find1 (1, (*this) ().size1 (), index2 ());
1392         }
1393         BOOST_UBLAS_INLINE
1394         dual_reverse_iterator_type rbegin () const {
1395             return dual_reverse_iterator_type (end ());
1396         }
1397         BOOST_UBLAS_INLINE
1398         dual_reverse_iterator_type rend () const {
1399             return dual_reverse_iterator_type (begin ());
1400         }
1401 
1402         // Assignment
1403         BOOST_UBLAS_INLINE
1404         indexed_const_iterator2 &operator = (const indexed_const_iterator2 &it) {
1405             // FIX: ICC needs full qualification?!
1406             // assign (&it ());
1407             container_const_reference<C>::assign (&it ());
1408             it1_ = it.it1_;
1409             it2_ = it.it2_;
1410             return *this;
1411         }
1412 
1413         // Comparison
1414         BOOST_UBLAS_INLINE
1415         bool operator == (const indexed_const_iterator2 &it) const {
1416             BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
1417             BOOST_UBLAS_CHECK (it1_ == it.it1_, external_logic ());
1418             return it2_ == it.it2_;
1419         }
1420         BOOST_UBLAS_INLINE
1421         bool operator < (const indexed_const_iterator2 &it) const {
1422             BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
1423             BOOST_UBLAS_CHECK (it1_ == it.it1_, external_logic ());
1424             return it2_ < it.it2_;
1425         }
1426 
1427     private:
1428         size_type it1_;
1429         size_type it2_;
1430 
1431         friend class indexed_iterator2<container_type, iterator_category>;
1432     };
1433 
1434 }}}
1435 
1436 #endif