Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-07-02 08:20:05

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