os/ossrv/ossrv_pub/boost_apis/boost/numeric/ublas/banded.hpp
author sl@SLION-WIN7.fritz.box
Fri, 15 Jun 2012 03:10:57 +0200
changeset 0 bde4ae8d615e
permissions -rw-r--r--
First public contribution.
sl@0
     1
//
sl@0
     2
//  Copyright (c) 2000-2002
sl@0
     3
//  Joerg Walter, Mathias Koch
sl@0
     4
//
sl@0
     5
//  Permission to use, copy, modify, distribute and sell this software
sl@0
     6
//  and its documentation for any purpose is hereby granted without fee,
sl@0
     7
//  provided that the above copyright notice appear in all copies and
sl@0
     8
//  that both that copyright notice and this permission notice appear
sl@0
     9
//  in supporting documentation.  The authors make no representations
sl@0
    10
//  about the suitability of this software for any purpose.
sl@0
    11
//  It is provided "as is" without express or implied warranty.
sl@0
    12
//
sl@0
    13
//  The authors gratefully acknowledge the support of
sl@0
    14
//  GeNeSys mbH & Co. KG in producing this work.
sl@0
    15
//
sl@0
    16
sl@0
    17
#ifndef _BOOST_UBLAS_BANDED_
sl@0
    18
#define _BOOST_UBLAS_BANDED_
sl@0
    19
sl@0
    20
#include <boost/numeric/ublas/matrix.hpp>
sl@0
    21
#include <boost/numeric/ublas/detail/temporary.hpp>
sl@0
    22
sl@0
    23
// Iterators based on ideas of Jeremy Siek
sl@0
    24
sl@0
    25
namespace boost { namespace numeric { namespace ublas {
sl@0
    26
sl@0
    27
    // Array based banded matrix class
sl@0
    28
    template<class T, class L, class A>
sl@0
    29
    class banded_matrix:
sl@0
    30
        public matrix_container<banded_matrix<T, L, A> > {
sl@0
    31
sl@0
    32
        typedef T *pointer;
sl@0
    33
        typedef L layout_type;
sl@0
    34
        typedef banded_matrix<T, L, A> self_type;
sl@0
    35
    public:
sl@0
    36
#ifdef BOOST_UBLAS_ENABLE_PROXY_SHORTCUTS
sl@0
    37
        using matrix_container<self_type>::operator ();
sl@0
    38
#endif
sl@0
    39
        typedef typename A::size_type size_type;
sl@0
    40
        typedef typename A::difference_type difference_type;
sl@0
    41
        typedef T value_type;
sl@0
    42
        typedef const T &const_reference;
sl@0
    43
        typedef T &reference;
sl@0
    44
        typedef A array_type;
sl@0
    45
        typedef const matrix_reference<const self_type> const_closure_type;
sl@0
    46
        typedef matrix_reference<self_type> closure_type;
sl@0
    47
        typedef vector<T, A> vector_temporary_type;
sl@0
    48
        typedef matrix<T, L, A> matrix_temporary_type;  // general sub-matrix
sl@0
    49
        typedef packed_tag storage_category;
sl@0
    50
        typedef typename L::orientation_category orientation_category;
sl@0
    51
sl@0
    52
        // Construction and destruction
sl@0
    53
        BOOST_UBLAS_INLINE
sl@0
    54
        banded_matrix ():
sl@0
    55
            matrix_container<self_type> (),
sl@0
    56
            size1_ (0), size2_ (0),
sl@0
    57
            lower_ (0), upper_ (0), data_ (0) {}
sl@0
    58
        BOOST_UBLAS_INLINE
sl@0
    59
        banded_matrix (size_type size1, size_type size2, size_type lower = 0, size_type upper = 0):
sl@0
    60
            matrix_container<self_type> (),
sl@0
    61
            size1_ (size1), size2_ (size2),
sl@0
    62
            lower_ (lower), upper_ (upper), data_ ((std::max) (size1, size2) * (lower + 1 + upper)) {
sl@0
    63
        }
sl@0
    64
        BOOST_UBLAS_INLINE
sl@0
    65
        banded_matrix (size_type size1, size_type size2, size_type lower, size_type upper, const array_type &data):
sl@0
    66
            matrix_container<self_type> (),
sl@0
    67
            size1_ (size1), size2_ (size2),
sl@0
    68
            lower_ (lower), upper_ (upper), data_ (data) {}
sl@0
    69
        BOOST_UBLAS_INLINE
sl@0
    70
        banded_matrix (const banded_matrix &m):
sl@0
    71
            matrix_container<self_type> (),
sl@0
    72
            size1_ (m.size1_), size2_ (m.size2_),
sl@0
    73
            lower_ (m.lower_), upper_ (m.upper_), data_ (m.data_) {}
sl@0
    74
        template<class AE>
sl@0
    75
        BOOST_UBLAS_INLINE
sl@0
    76
        banded_matrix (const matrix_expression<AE> &ae, size_type lower = 0, size_type upper = 0):
sl@0
    77
            matrix_container<self_type> (),
sl@0
    78
            size1_ (ae ().size1 ()), size2_ (ae ().size2 ()),
sl@0
    79
            lower_ (lower), upper_ (upper),
sl@0
    80
            data_ ((std::max) (size1_, size2_) * (lower_ + 1 + upper_)) {
sl@0
    81
            matrix_assign<scalar_assign> (*this, ae);
sl@0
    82
        }
sl@0
    83
sl@0
    84
        // Accessors
sl@0
    85
        BOOST_UBLAS_INLINE
sl@0
    86
        size_type size1 () const {
sl@0
    87
            return size1_;
sl@0
    88
        }
sl@0
    89
        BOOST_UBLAS_INLINE
sl@0
    90
        size_type size2 () const {
sl@0
    91
            return size2_;
sl@0
    92
        }
sl@0
    93
        BOOST_UBLAS_INLINE
sl@0
    94
        size_type lower () const {
sl@0
    95
            return lower_;
sl@0
    96
        }
sl@0
    97
        BOOST_UBLAS_INLINE
sl@0
    98
        size_type upper () const {
sl@0
    99
            return upper_;
sl@0
   100
        }
sl@0
   101
sl@0
   102
        // Storage accessors
sl@0
   103
        BOOST_UBLAS_INLINE
sl@0
   104
        const array_type &data () const {
sl@0
   105
            return data_;
sl@0
   106
        }
sl@0
   107
        BOOST_UBLAS_INLINE
sl@0
   108
        array_type &data () {
sl@0
   109
            return data_;
sl@0
   110
        }
sl@0
   111
sl@0
   112
        // Resizing
sl@0
   113
        BOOST_UBLAS_INLINE
sl@0
   114
        void resize (size_type size1, size_type size2, size_type lower = 0, size_type upper = 0, bool preserve = true) {
sl@0
   115
            if (preserve) {
sl@0
   116
                self_type temporary (size1, size2, lower, upper);
sl@0
   117
                detail::matrix_resize_preserve<layout_type> (*this, temporary);
sl@0
   118
            }
sl@0
   119
            else {
sl@0
   120
                data ().resize ((std::max) (size1, size2) * (lower + 1 + upper));
sl@0
   121
                size1_ = size1;
sl@0
   122
                size2_ = size2;
sl@0
   123
                lower_ = lower;
sl@0
   124
                upper_ = upper;
sl@0
   125
            }
sl@0
   126
        }
sl@0
   127
sl@0
   128
        BOOST_UBLAS_INLINE
sl@0
   129
        void resize_packed_preserve (size_type size1, size_type size2, size_type lower = 0, size_type upper = 0) {
sl@0
   130
            size1_ = size1;
sl@0
   131
            size2_ = size2;
sl@0
   132
            lower_ = lower;
sl@0
   133
            upper_ = upper;
sl@0
   134
            data ().resize ((std::max) (size1, size2) * (lower + 1 + upper), value_type ());
sl@0
   135
        }
sl@0
   136
sl@0
   137
        // Element access
sl@0
   138
        BOOST_UBLAS_INLINE
sl@0
   139
        const_reference operator () (size_type i, size_type j) const {
sl@0
   140
            BOOST_UBLAS_CHECK (i < size1_, bad_index ());
sl@0
   141
            BOOST_UBLAS_CHECK (j < size2_, bad_index ());
sl@0
   142
#ifdef BOOST_UBLAS_OWN_BANDED
sl@0
   143
            const size_type k = (std::max) (i, j);
sl@0
   144
            const size_type l = lower_ + j - i;
sl@0
   145
            if (k < (std::max) (size1_, size2_) &&
sl@0
   146
                l < lower_ + 1 + upper_)
sl@0
   147
                return data () [layout_type::element (k, (std::max) (size1_, size2_),
sl@0
   148
                                                       l, lower_ + 1 + upper_)];
sl@0
   149
#else
sl@0
   150
            const size_type k = j;
sl@0
   151
            const size_type l = upper_ + i - j;
sl@0
   152
            if (k < size2_ &&
sl@0
   153
                l < lower_ + 1 + upper_)
sl@0
   154
                return data () [layout_type::element (k, size2_,
sl@0
   155
                                                       l, lower_ + 1 + upper_)];
sl@0
   156
#endif
sl@0
   157
            return zero_;
sl@0
   158
        }
sl@0
   159
        BOOST_UBLAS_INLINE
sl@0
   160
        reference at_element (size_type i, size_type j) {
sl@0
   161
            BOOST_UBLAS_CHECK (i < size1_, bad_index ());
sl@0
   162
            BOOST_UBLAS_CHECK (j < size2_, bad_index ());
sl@0
   163
#ifdef BOOST_UBLAS_OWN_BANDED
sl@0
   164
            const size_type k = (std::max) (i, j);
sl@0
   165
            const size_type l = lower_ + j - i;
sl@0
   166
            return data () [layout_type::element (k, (std::max) (size1_, size2_),
sl@0
   167
                                                   l, lower_ + 1 + upper_)];
sl@0
   168
#else
sl@0
   169
            const size_type k = j;
sl@0
   170
            const size_type l = upper_ + i - j;
sl@0
   171
            return data () [layout_type::element (k, size2_,
sl@0
   172
                                                   l, lower_ + 1 + upper_)];
sl@0
   173
#endif
sl@0
   174
        }
sl@0
   175
        BOOST_UBLAS_INLINE
sl@0
   176
        reference operator () (size_type i, size_type j) {
sl@0
   177
            BOOST_UBLAS_CHECK (i < size1_, bad_index ());
sl@0
   178
            BOOST_UBLAS_CHECK (j < size2_, bad_index ());
sl@0
   179
#ifdef BOOST_UBLAS_OWN_BANDED
sl@0
   180
            const size_type k = (std::max) (i, j);
sl@0
   181
            const size_type l = lower_ + j - i;
sl@0
   182
            if (k < (std::max) (size1_, size2_) &&
sl@0
   183
                l < lower_ + 1 + upper_)
sl@0
   184
                return data () [layout_type::element (k, (std::max) (size1_, size2_),
sl@0
   185
                                                       l, lower_ + 1 + upper_)];
sl@0
   186
#else
sl@0
   187
            const size_type k = j;
sl@0
   188
            const size_type l = upper_ + i - j;
sl@0
   189
            if (k < size2_ &&
sl@0
   190
                l < lower_ + 1 + upper_)
sl@0
   191
                return data () [layout_type::element (k, size2_,
sl@0
   192
                                                       l, lower_ + 1 + upper_)];
sl@0
   193
#endif
sl@0
   194
            bad_index ().raise ();
sl@0
   195
                // arbitary return value
sl@0
   196
            return const_cast<reference>(zero_);
sl@0
   197
        }
sl@0
   198
sl@0
   199
        // Element assignment
sl@0
   200
        BOOST_UBLAS_INLINE
sl@0
   201
        reference insert_element (size_type i, size_type j, const_reference t) {
sl@0
   202
            return (operator () (i, j) = t);
sl@0
   203
        }
sl@0
   204
        BOOST_UBLAS_INLINE
sl@0
   205
        void erase_element (size_type i, size_type j) {
sl@0
   206
            operator () (i, j) = value_type/*zero*/();
sl@0
   207
        }
sl@0
   208
sl@0
   209
        // Zeroing
sl@0
   210
        BOOST_UBLAS_INLINE
sl@0
   211
        void clear () {
sl@0
   212
            std::fill (data ().begin (), data ().end (), value_type/*zero*/());
sl@0
   213
        }
sl@0
   214
sl@0
   215
        // Assignment
sl@0
   216
        BOOST_UBLAS_INLINE
sl@0
   217
        banded_matrix &operator = (const banded_matrix &m) {
sl@0
   218
            size1_ = m.size1_;
sl@0
   219
            size2_ = m.size2_;
sl@0
   220
            lower_ = m.lower_;
sl@0
   221
            upper_ = m.upper_;
sl@0
   222
            data () = m.data ();
sl@0
   223
            return *this;
sl@0
   224
        }
sl@0
   225
        BOOST_UBLAS_INLINE
sl@0
   226
        banded_matrix &assign_temporary (banded_matrix &m) {
sl@0
   227
            swap (m);
sl@0
   228
            return *this;
sl@0
   229
        }
sl@0
   230
        template<class AE>
sl@0
   231
        BOOST_UBLAS_INLINE
sl@0
   232
        banded_matrix &operator = (const matrix_expression<AE> &ae) {
sl@0
   233
            self_type temporary (ae, lower_, upper_);
sl@0
   234
            return assign_temporary (temporary);
sl@0
   235
        }
sl@0
   236
        template<class AE>
sl@0
   237
        BOOST_UBLAS_INLINE
sl@0
   238
        banded_matrix &assign (const matrix_expression<AE> &ae) {
sl@0
   239
            matrix_assign<scalar_assign> (*this, ae);
sl@0
   240
            return *this;
sl@0
   241
        }
sl@0
   242
        template<class AE>
sl@0
   243
        BOOST_UBLAS_INLINE
sl@0
   244
        banded_matrix& operator += (const matrix_expression<AE> &ae) {
sl@0
   245
            self_type temporary (*this + ae, lower_, upper_);
sl@0
   246
            return assign_temporary (temporary);
sl@0
   247
        }
sl@0
   248
        template<class AE>
sl@0
   249
        BOOST_UBLAS_INLINE
sl@0
   250
        banded_matrix &plus_assign (const matrix_expression<AE> &ae) {
sl@0
   251
            matrix_assign<scalar_plus_assign> (*this, ae);
sl@0
   252
            return *this;
sl@0
   253
        }
sl@0
   254
        template<class AE>
sl@0
   255
        BOOST_UBLAS_INLINE
sl@0
   256
        banded_matrix& operator -= (const matrix_expression<AE> &ae) {
sl@0
   257
            self_type temporary (*this - ae, lower_, upper_);
sl@0
   258
            return assign_temporary (temporary);
sl@0
   259
        }
sl@0
   260
        template<class AE>
sl@0
   261
        BOOST_UBLAS_INLINE
sl@0
   262
        banded_matrix &minus_assign (const matrix_expression<AE> &ae) {
sl@0
   263
            matrix_assign<scalar_minus_assign> (*this, ae);
sl@0
   264
            return *this;
sl@0
   265
        }
sl@0
   266
        template<class AT>
sl@0
   267
        BOOST_UBLAS_INLINE
sl@0
   268
        banded_matrix& operator *= (const AT &at) {
sl@0
   269
            matrix_assign_scalar<scalar_multiplies_assign> (*this, at);
sl@0
   270
            return *this;
sl@0
   271
        }
sl@0
   272
        template<class AT>
sl@0
   273
        BOOST_UBLAS_INLINE
sl@0
   274
        banded_matrix& operator /= (const AT &at) {
sl@0
   275
            matrix_assign_scalar<scalar_divides_assign> (*this, at);
sl@0
   276
            return *this;
sl@0
   277
        }
sl@0
   278
sl@0
   279
        // Swapping
sl@0
   280
        BOOST_UBLAS_INLINE
sl@0
   281
        void swap (banded_matrix &m) {
sl@0
   282
            if (this != &m) {
sl@0
   283
                std::swap (size1_, m.size1_);
sl@0
   284
                std::swap (size2_, m.size2_);
sl@0
   285
                std::swap (lower_, m.lower_);
sl@0
   286
                std::swap (upper_, m.upper_);
sl@0
   287
                data ().swap (m.data ());
sl@0
   288
            }
sl@0
   289
        }
sl@0
   290
        BOOST_UBLAS_INLINE
sl@0
   291
        friend void swap (banded_matrix &m1, banded_matrix &m2) {
sl@0
   292
            m1.swap (m2);
sl@0
   293
        }
sl@0
   294
sl@0
   295
        // Iterator types
sl@0
   296
#ifdef BOOST_UBLAS_USE_INDEXED_ITERATOR
sl@0
   297
        typedef indexed_iterator1<self_type, packed_random_access_iterator_tag> iterator1;
sl@0
   298
        typedef indexed_iterator2<self_type, packed_random_access_iterator_tag> iterator2;
sl@0
   299
        typedef indexed_const_iterator1<self_type, packed_random_access_iterator_tag> const_iterator1;
sl@0
   300
        typedef indexed_const_iterator2<self_type, packed_random_access_iterator_tag> const_iterator2;
sl@0
   301
#else
sl@0
   302
        class const_iterator1;
sl@0
   303
        class iterator1;
sl@0
   304
        class const_iterator2;
sl@0
   305
        class iterator2;
sl@0
   306
#endif
sl@0
   307
        typedef reverse_iterator_base1<const_iterator1> const_reverse_iterator1;
sl@0
   308
        typedef reverse_iterator_base1<iterator1> reverse_iterator1;
sl@0
   309
        typedef reverse_iterator_base2<const_iterator2> const_reverse_iterator2;
sl@0
   310
        typedef reverse_iterator_base2<iterator2> reverse_iterator2;
sl@0
   311
sl@0
   312
        // Element lookup
sl@0
   313
        BOOST_UBLAS_INLINE
sl@0
   314
        const_iterator1 find1 (int rank, size_type i, size_type j) const {
sl@0
   315
            if (rank == 1) {
sl@0
   316
                size_type lower_i = (std::max) (difference_type (j - upper_), difference_type (0));
sl@0
   317
                i = (std::max) (i, lower_i);
sl@0
   318
                size_type upper_i = (std::min) (j + 1 + lower_, size1_);
sl@0
   319
                i = (std::min) (i, upper_i);
sl@0
   320
            }
sl@0
   321
            return const_iterator1 (*this, i, j);
sl@0
   322
        }
sl@0
   323
        BOOST_UBLAS_INLINE
sl@0
   324
        iterator1 find1 (int rank, size_type i, size_type j) {
sl@0
   325
            if (rank == 1) {
sl@0
   326
                size_type lower_i = (std::max) (difference_type (j - upper_), difference_type (0));
sl@0
   327
                i = (std::max) (i, lower_i);
sl@0
   328
                size_type upper_i = (std::min) (j + 1 + lower_, size1_);
sl@0
   329
                i = (std::min) (i, upper_i);
sl@0
   330
            }
sl@0
   331
            return iterator1 (*this, i, j);
sl@0
   332
        }
sl@0
   333
        BOOST_UBLAS_INLINE
sl@0
   334
        const_iterator2 find2 (int rank, size_type i, size_type j) const {
sl@0
   335
            if (rank == 1) {
sl@0
   336
                size_type lower_j = (std::max) (difference_type (i - lower_), difference_type (0));
sl@0
   337
                j = (std::max) (j, lower_j);
sl@0
   338
                size_type upper_j = (std::min) (i + 1 + upper_, size2_);
sl@0
   339
                j = (std::min) (j, upper_j);
sl@0
   340
            }
sl@0
   341
            return const_iterator2 (*this, i, j);
sl@0
   342
        }
sl@0
   343
        BOOST_UBLAS_INLINE
sl@0
   344
        iterator2 find2 (int rank, size_type i, size_type j) {
sl@0
   345
            if (rank == 1) {
sl@0
   346
                size_type lower_j = (std::max) (difference_type (i - lower_), difference_type (0));
sl@0
   347
                j = (std::max) (j, lower_j);
sl@0
   348
                size_type upper_j = (std::min) (i + 1 + upper_, size2_);
sl@0
   349
                j = (std::min) (j, upper_j);
sl@0
   350
            }
sl@0
   351
            return iterator2 (*this, i, j);
sl@0
   352
        }
sl@0
   353
sl@0
   354
        // Iterators simply are indices.
sl@0
   355
sl@0
   356
#ifndef BOOST_UBLAS_USE_INDEXED_ITERATOR
sl@0
   357
        class const_iterator1:
sl@0
   358
            public container_const_reference<banded_matrix>,
sl@0
   359
            public random_access_iterator_base<packed_random_access_iterator_tag,
sl@0
   360
                                               const_iterator1, value_type> {
sl@0
   361
        public:
sl@0
   362
            typedef typename banded_matrix::value_type value_type;
sl@0
   363
            typedef typename banded_matrix::difference_type difference_type;
sl@0
   364
            typedef typename banded_matrix::const_reference reference;
sl@0
   365
            typedef const typename banded_matrix::pointer pointer;
sl@0
   366
sl@0
   367
            typedef const_iterator2 dual_iterator_type;
sl@0
   368
            typedef const_reverse_iterator2 dual_reverse_iterator_type;
sl@0
   369
sl@0
   370
            // Construction and destruction
sl@0
   371
            BOOST_UBLAS_INLINE
sl@0
   372
            const_iterator1 ():
sl@0
   373
                container_const_reference<self_type> (), it1_ (), it2_ () {}
sl@0
   374
            BOOST_UBLAS_INLINE
sl@0
   375
            const_iterator1 (const self_type &m, size_type it1, size_type it2):
sl@0
   376
                container_const_reference<self_type> (m), it1_ (it1), it2_ (it2) {}
sl@0
   377
            BOOST_UBLAS_INLINE
sl@0
   378
            const_iterator1 (const iterator1 &it):
sl@0
   379
                container_const_reference<self_type> (it ()), it1_ (it.it1_), it2_ (it.it2_) {}
sl@0
   380
sl@0
   381
            // Arithmetic
sl@0
   382
            BOOST_UBLAS_INLINE
sl@0
   383
            const_iterator1 &operator ++ () {
sl@0
   384
                ++ it1_;
sl@0
   385
                return *this;
sl@0
   386
            }
sl@0
   387
            BOOST_UBLAS_INLINE
sl@0
   388
            const_iterator1 &operator -- () {
sl@0
   389
                -- it1_;
sl@0
   390
                return *this;
sl@0
   391
            }
sl@0
   392
            BOOST_UBLAS_INLINE
sl@0
   393
            const_iterator1 &operator += (difference_type n) {
sl@0
   394
                it1_ += n;
sl@0
   395
                return *this;
sl@0
   396
            }
sl@0
   397
            BOOST_UBLAS_INLINE
sl@0
   398
            const_iterator1 &operator -= (difference_type n) {
sl@0
   399
                it1_ -= n;
sl@0
   400
                return *this;
sl@0
   401
            }
sl@0
   402
            BOOST_UBLAS_INLINE
sl@0
   403
            difference_type operator - (const const_iterator1 &it) const {
sl@0
   404
                BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
sl@0
   405
                BOOST_UBLAS_CHECK (it2_ == it.it2_, external_logic ());
sl@0
   406
                return it1_ - it.it1_;
sl@0
   407
            }
sl@0
   408
sl@0
   409
            // Dereference
sl@0
   410
            BOOST_UBLAS_INLINE
sl@0
   411
            const_reference operator * () const {
sl@0
   412
                return (*this) () (it1_, it2_);
sl@0
   413
            }
sl@0
   414
            BOOST_UBLAS_INLINE
sl@0
   415
            const_reference operator [] (difference_type n) const {
sl@0
   416
                return *(*this + n);
sl@0
   417
            }
sl@0
   418
sl@0
   419
#ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
sl@0
   420
            BOOST_UBLAS_INLINE
sl@0
   421
#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
sl@0
   422
            typename self_type::
sl@0
   423
#endif
sl@0
   424
            const_iterator2 begin () const {
sl@0
   425
                return (*this) ().find2 (1, it1_, 0);
sl@0
   426
            }
sl@0
   427
            BOOST_UBLAS_INLINE
sl@0
   428
#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
sl@0
   429
            typename self_type::
sl@0
   430
#endif
sl@0
   431
            const_iterator2 end () const {
sl@0
   432
                return (*this) ().find2 (1, it1_, (*this) ().size2 ());
sl@0
   433
            }
sl@0
   434
            BOOST_UBLAS_INLINE
sl@0
   435
#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
sl@0
   436
            typename self_type::
sl@0
   437
#endif
sl@0
   438
            const_reverse_iterator2 rbegin () const {
sl@0
   439
                return const_reverse_iterator2 (end ());
sl@0
   440
            }
sl@0
   441
            BOOST_UBLAS_INLINE
sl@0
   442
#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
sl@0
   443
            typename self_type::
sl@0
   444
#endif
sl@0
   445
            const_reverse_iterator2 rend () const {
sl@0
   446
                return const_reverse_iterator2 (begin ());
sl@0
   447
            }
sl@0
   448
#endif
sl@0
   449
sl@0
   450
            // Indices
sl@0
   451
            BOOST_UBLAS_INLINE
sl@0
   452
            size_type index1 () const {
sl@0
   453
                return it1_;
sl@0
   454
            }
sl@0
   455
            BOOST_UBLAS_INLINE
sl@0
   456
            size_type index2 () const {
sl@0
   457
                return it2_;
sl@0
   458
            }
sl@0
   459
sl@0
   460
            // Assignment
sl@0
   461
            BOOST_UBLAS_INLINE
sl@0
   462
            const_iterator1 &operator = (const const_iterator1 &it) {
sl@0
   463
                container_const_reference<self_type>::assign (&it ());
sl@0
   464
                it1_ = it.it1_;
sl@0
   465
                it2_ = it.it2_;
sl@0
   466
                return *this;
sl@0
   467
            }
sl@0
   468
sl@0
   469
            // Comparison
sl@0
   470
            BOOST_UBLAS_INLINE
sl@0
   471
            bool operator == (const const_iterator1 &it) const {
sl@0
   472
                BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
sl@0
   473
                BOOST_UBLAS_CHECK (it2_ == it.it2_, external_logic ());
sl@0
   474
                return it1_ == it.it1_;
sl@0
   475
            }
sl@0
   476
            BOOST_UBLAS_INLINE
sl@0
   477
            bool operator < (const const_iterator1 &it) const {
sl@0
   478
                BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
sl@0
   479
                BOOST_UBLAS_CHECK (it2_ == it.it2_, external_logic ());
sl@0
   480
                return it1_ < it.it1_;
sl@0
   481
            }
sl@0
   482
sl@0
   483
        private:
sl@0
   484
            size_type it1_;
sl@0
   485
            size_type it2_;
sl@0
   486
        };
sl@0
   487
#endif
sl@0
   488
sl@0
   489
        BOOST_UBLAS_INLINE
sl@0
   490
        const_iterator1 begin1 () const {
sl@0
   491
            return find1 (0, 0, 0);
sl@0
   492
        }
sl@0
   493
        BOOST_UBLAS_INLINE
sl@0
   494
        const_iterator1 end1 () const {
sl@0
   495
            return find1 (0, size1_, 0);
sl@0
   496
        }
sl@0
   497
sl@0
   498
#ifndef BOOST_UBLAS_USE_INDEXED_ITERATOR
sl@0
   499
        class iterator1:
sl@0
   500
            public container_reference<banded_matrix>,
sl@0
   501
            public random_access_iterator_base<packed_random_access_iterator_tag,
sl@0
   502
                                               iterator1, value_type> {
sl@0
   503
        public:
sl@0
   504
            typedef typename banded_matrix::value_type value_type;
sl@0
   505
            typedef typename banded_matrix::difference_type difference_type;
sl@0
   506
            typedef typename banded_matrix::reference reference;
sl@0
   507
            typedef typename banded_matrix::pointer pointer;
sl@0
   508
sl@0
   509
            typedef iterator2 dual_iterator_type;
sl@0
   510
            typedef reverse_iterator2 dual_reverse_iterator_type;
sl@0
   511
sl@0
   512
            // Construction and destruction
sl@0
   513
            BOOST_UBLAS_INLINE
sl@0
   514
            iterator1 ():
sl@0
   515
                container_reference<self_type> (), it1_ (), it2_ () {}
sl@0
   516
            BOOST_UBLAS_INLINE
sl@0
   517
            iterator1 (self_type &m, size_type it1, size_type it2):
sl@0
   518
                container_reference<self_type> (m), it1_ (it1), it2_ (it2) {}
sl@0
   519
sl@0
   520
            // Arithmetic
sl@0
   521
            BOOST_UBLAS_INLINE
sl@0
   522
            iterator1 &operator ++ () {
sl@0
   523
                ++ it1_;
sl@0
   524
                return *this;
sl@0
   525
            }
sl@0
   526
            BOOST_UBLAS_INLINE
sl@0
   527
            iterator1 &operator -- () {
sl@0
   528
                -- it1_;
sl@0
   529
                return *this;
sl@0
   530
            }
sl@0
   531
            BOOST_UBLAS_INLINE
sl@0
   532
            iterator1 &operator += (difference_type n) {
sl@0
   533
                it1_ += n;
sl@0
   534
                return *this;
sl@0
   535
            }
sl@0
   536
            BOOST_UBLAS_INLINE
sl@0
   537
            iterator1 &operator -= (difference_type n) {
sl@0
   538
                it1_ -= n;
sl@0
   539
                return *this;
sl@0
   540
            }
sl@0
   541
            BOOST_UBLAS_INLINE
sl@0
   542
            difference_type operator - (const iterator1 &it) const {
sl@0
   543
                BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
sl@0
   544
                BOOST_UBLAS_CHECK (it2_ == it.it2_, external_logic ());
sl@0
   545
                return it1_ - it.it1_;
sl@0
   546
            }
sl@0
   547
sl@0
   548
            // Dereference
sl@0
   549
            BOOST_UBLAS_INLINE
sl@0
   550
            reference operator * () const {
sl@0
   551
                return (*this) ().at_element (it1_, it2_);
sl@0
   552
            }
sl@0
   553
            BOOST_UBLAS_INLINE
sl@0
   554
            reference operator [] (difference_type n) const {
sl@0
   555
                return *(*this + n);
sl@0
   556
            }
sl@0
   557
sl@0
   558
#ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
sl@0
   559
            BOOST_UBLAS_INLINE
sl@0
   560
#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
sl@0
   561
            typename self_type::
sl@0
   562
#endif
sl@0
   563
            iterator2 begin () const {
sl@0
   564
                return (*this) ().find2 (1, it1_, 0);
sl@0
   565
            }
sl@0
   566
            BOOST_UBLAS_INLINE
sl@0
   567
#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
sl@0
   568
            typename self_type::
sl@0
   569
#endif
sl@0
   570
            iterator2 end () const {
sl@0
   571
                return (*this) ().find2 (1, it1_, (*this) ().size2 ());
sl@0
   572
            }
sl@0
   573
            BOOST_UBLAS_INLINE
sl@0
   574
#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
sl@0
   575
            typename self_type::
sl@0
   576
#endif
sl@0
   577
            reverse_iterator2 rbegin () const {
sl@0
   578
                return reverse_iterator2 (end ());
sl@0
   579
            }
sl@0
   580
            BOOST_UBLAS_INLINE
sl@0
   581
#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
sl@0
   582
            typename self_type::
sl@0
   583
#endif
sl@0
   584
            reverse_iterator2 rend () const {
sl@0
   585
                return reverse_iterator2 (begin ());
sl@0
   586
            }
sl@0
   587
#endif
sl@0
   588
sl@0
   589
            // Indices
sl@0
   590
            BOOST_UBLAS_INLINE
sl@0
   591
            size_type index1 () const {
sl@0
   592
                return it1_;
sl@0
   593
            }
sl@0
   594
            BOOST_UBLAS_INLINE
sl@0
   595
            size_type index2 () const {
sl@0
   596
                return it2_;
sl@0
   597
            }
sl@0
   598
sl@0
   599
            // Assignment
sl@0
   600
            BOOST_UBLAS_INLINE
sl@0
   601
            iterator1 &operator = (const iterator1 &it) {
sl@0
   602
                container_reference<self_type>::assign (&it ());
sl@0
   603
                it1_ = it.it1_;
sl@0
   604
                it2_ = it.it2_;
sl@0
   605
                return *this;
sl@0
   606
            }
sl@0
   607
sl@0
   608
            // Comparison
sl@0
   609
            BOOST_UBLAS_INLINE
sl@0
   610
            bool operator == (const iterator1 &it) const {
sl@0
   611
                BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
sl@0
   612
                BOOST_UBLAS_CHECK (it2_ == it.it2_, external_logic ());
sl@0
   613
                return it1_ == it.it1_;
sl@0
   614
            }
sl@0
   615
            BOOST_UBLAS_INLINE
sl@0
   616
            bool operator < (const iterator1 &it) const {
sl@0
   617
                BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
sl@0
   618
                BOOST_UBLAS_CHECK (it2_ == it.it2_, external_logic ());
sl@0
   619
                return it1_ < it.it1_;
sl@0
   620
            }
sl@0
   621
sl@0
   622
        private:
sl@0
   623
            size_type it1_;
sl@0
   624
            size_type it2_;
sl@0
   625
sl@0
   626
            friend class const_iterator1;
sl@0
   627
        };
sl@0
   628
#endif
sl@0
   629
sl@0
   630
        BOOST_UBLAS_INLINE
sl@0
   631
        iterator1 begin1 () {
sl@0
   632
            return find1 (0, 0, 0);
sl@0
   633
        }
sl@0
   634
        BOOST_UBLAS_INLINE
sl@0
   635
        iterator1 end1 () {
sl@0
   636
            return find1 (0, size1_, 0);
sl@0
   637
        }
sl@0
   638
sl@0
   639
#ifndef BOOST_UBLAS_USE_INDEXED_ITERATOR
sl@0
   640
        class const_iterator2:
sl@0
   641
            public container_const_reference<banded_matrix>,
sl@0
   642
            public random_access_iterator_base<packed_random_access_iterator_tag,
sl@0
   643
                                               const_iterator2, value_type> {
sl@0
   644
        public:
sl@0
   645
            typedef typename banded_matrix::value_type value_type;
sl@0
   646
            typedef typename banded_matrix::difference_type difference_type;
sl@0
   647
            typedef typename banded_matrix::const_reference reference;
sl@0
   648
            typedef const typename banded_matrix::pointer pointer;
sl@0
   649
sl@0
   650
            typedef const_iterator1 dual_iterator_type;
sl@0
   651
            typedef const_reverse_iterator1 dual_reverse_iterator_type;
sl@0
   652
sl@0
   653
            // Construction and destruction
sl@0
   654
            BOOST_UBLAS_INLINE
sl@0
   655
            const_iterator2 ():
sl@0
   656
                container_const_reference<self_type> (), it1_ (), it2_ () {}
sl@0
   657
            BOOST_UBLAS_INLINE
sl@0
   658
            const_iterator2 (const self_type &m, size_type it1, size_type it2):
sl@0
   659
                container_const_reference<self_type> (m), it1_ (it1), it2_ (it2) {}
sl@0
   660
            BOOST_UBLAS_INLINE
sl@0
   661
            const_iterator2 (const iterator2 &it):
sl@0
   662
                container_const_reference<self_type> (it ()), it1_ (it.it1_), it2_ (it.it2_) {}
sl@0
   663
sl@0
   664
            // Arithmetic
sl@0
   665
            BOOST_UBLAS_INLINE
sl@0
   666
            const_iterator2 &operator ++ () {
sl@0
   667
                ++ it2_;
sl@0
   668
                return *this;
sl@0
   669
            }
sl@0
   670
            BOOST_UBLAS_INLINE
sl@0
   671
            const_iterator2 &operator -- () {
sl@0
   672
                -- it2_;
sl@0
   673
                return *this;
sl@0
   674
            }
sl@0
   675
            BOOST_UBLAS_INLINE
sl@0
   676
            const_iterator2 &operator += (difference_type n) {
sl@0
   677
                it2_ += n;
sl@0
   678
                return *this;
sl@0
   679
            }
sl@0
   680
            BOOST_UBLAS_INLINE
sl@0
   681
            const_iterator2 &operator -= (difference_type n) {
sl@0
   682
                it2_ -= n;
sl@0
   683
                return *this;
sl@0
   684
            }
sl@0
   685
            BOOST_UBLAS_INLINE
sl@0
   686
            difference_type operator - (const const_iterator2 &it) const {
sl@0
   687
                BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
sl@0
   688
                BOOST_UBLAS_CHECK (it1_ == it.it1_, external_logic ());
sl@0
   689
                return it2_ - it.it2_;
sl@0
   690
            }
sl@0
   691
sl@0
   692
            // Dereference
sl@0
   693
            BOOST_UBLAS_INLINE
sl@0
   694
            const_reference operator * () const {
sl@0
   695
                return (*this) () (it1_, it2_);
sl@0
   696
            }
sl@0
   697
            BOOST_UBLAS_INLINE
sl@0
   698
            const_reference operator [] (difference_type n) const {
sl@0
   699
                return *(*this + n);
sl@0
   700
            }
sl@0
   701
sl@0
   702
#ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
sl@0
   703
            BOOST_UBLAS_INLINE
sl@0
   704
#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
sl@0
   705
            typename self_type::
sl@0
   706
#endif
sl@0
   707
            const_iterator1 begin () const {
sl@0
   708
                return (*this) ().find1 (1, 0, it2_);
sl@0
   709
            }
sl@0
   710
            BOOST_UBLAS_INLINE
sl@0
   711
#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
sl@0
   712
            typename self_type::
sl@0
   713
#endif
sl@0
   714
            const_iterator1 end () const {
sl@0
   715
                return (*this) ().find1 (1, (*this) ().size1 (), it2_);
sl@0
   716
            }
sl@0
   717
            BOOST_UBLAS_INLINE
sl@0
   718
#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
sl@0
   719
            typename self_type::
sl@0
   720
#endif
sl@0
   721
            const_reverse_iterator1 rbegin () const {
sl@0
   722
                return const_reverse_iterator1 (end ());
sl@0
   723
            }
sl@0
   724
            BOOST_UBLAS_INLINE
sl@0
   725
#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
sl@0
   726
            typename self_type::
sl@0
   727
#endif
sl@0
   728
            const_reverse_iterator1 rend () const {
sl@0
   729
                return const_reverse_iterator1 (begin ());
sl@0
   730
            }
sl@0
   731
#endif
sl@0
   732
sl@0
   733
            // Indices
sl@0
   734
            BOOST_UBLAS_INLINE
sl@0
   735
            size_type index1 () const {
sl@0
   736
                return it1_;
sl@0
   737
            }
sl@0
   738
            BOOST_UBLAS_INLINE
sl@0
   739
            size_type index2 () const {
sl@0
   740
                return it2_;
sl@0
   741
            }
sl@0
   742
sl@0
   743
            // Assignment
sl@0
   744
            BOOST_UBLAS_INLINE
sl@0
   745
            const_iterator2 &operator = (const const_iterator2 &it) {
sl@0
   746
                container_const_reference<self_type>::assign (&it ());
sl@0
   747
                it1_ = it.it1_;
sl@0
   748
                it2_ = it.it2_;
sl@0
   749
                return *this;
sl@0
   750
            }
sl@0
   751
sl@0
   752
            // Comparison
sl@0
   753
            BOOST_UBLAS_INLINE
sl@0
   754
            bool operator == (const const_iterator2 &it) const {
sl@0
   755
                BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
sl@0
   756
                BOOST_UBLAS_CHECK (it1_ == it.it1_, external_logic ());
sl@0
   757
                return it2_ == it.it2_;
sl@0
   758
            }
sl@0
   759
            BOOST_UBLAS_INLINE
sl@0
   760
            bool operator < (const const_iterator2 &it) const {
sl@0
   761
                BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
sl@0
   762
                BOOST_UBLAS_CHECK (it1_ == it.it1_, external_logic ());
sl@0
   763
                return it2_ < it.it2_;
sl@0
   764
            }
sl@0
   765
sl@0
   766
        private:
sl@0
   767
            size_type it1_;
sl@0
   768
            size_type it2_;
sl@0
   769
        };
sl@0
   770
#endif
sl@0
   771
sl@0
   772
        BOOST_UBLAS_INLINE
sl@0
   773
        const_iterator2 begin2 () const {
sl@0
   774
            return find2 (0, 0, 0);
sl@0
   775
        }
sl@0
   776
        BOOST_UBLAS_INLINE
sl@0
   777
        const_iterator2 end2 () const {
sl@0
   778
            return find2 (0, 0, size2_);
sl@0
   779
        }
sl@0
   780
sl@0
   781
#ifndef BOOST_UBLAS_USE_INDEXED_ITERATOR
sl@0
   782
        class iterator2:
sl@0
   783
            public container_reference<banded_matrix>,
sl@0
   784
            public random_access_iterator_base<packed_random_access_iterator_tag,
sl@0
   785
                                               iterator2, value_type> {
sl@0
   786
        public:
sl@0
   787
            typedef typename banded_matrix::value_type value_type;
sl@0
   788
            typedef typename banded_matrix::difference_type difference_type;
sl@0
   789
            typedef typename banded_matrix::reference reference;
sl@0
   790
            typedef typename banded_matrix::pointer pointer;
sl@0
   791
sl@0
   792
            typedef iterator1 dual_iterator_type;
sl@0
   793
            typedef reverse_iterator1 dual_reverse_iterator_type;
sl@0
   794
sl@0
   795
            // Construction and destruction
sl@0
   796
            BOOST_UBLAS_INLINE
sl@0
   797
            iterator2 ():
sl@0
   798
                container_reference<self_type> (), it1_ (), it2_ () {}
sl@0
   799
            BOOST_UBLAS_INLINE
sl@0
   800
            iterator2 (self_type &m, size_type it1, size_type it2):
sl@0
   801
                container_reference<self_type> (m), it1_ (it1), it2_ (it2) {}
sl@0
   802
sl@0
   803
            // Arithmetic
sl@0
   804
            BOOST_UBLAS_INLINE
sl@0
   805
            iterator2 &operator ++ () {
sl@0
   806
                ++ it2_;
sl@0
   807
                return *this;
sl@0
   808
            }
sl@0
   809
            BOOST_UBLAS_INLINE
sl@0
   810
            iterator2 &operator -- () {
sl@0
   811
                -- it2_;
sl@0
   812
                return *this;
sl@0
   813
            }
sl@0
   814
            BOOST_UBLAS_INLINE
sl@0
   815
            iterator2 &operator += (difference_type n) {
sl@0
   816
                it2_ += n;
sl@0
   817
                return *this;
sl@0
   818
            }
sl@0
   819
            BOOST_UBLAS_INLINE
sl@0
   820
            iterator2 &operator -= (difference_type n) {
sl@0
   821
                it2_ -= n;
sl@0
   822
                return *this;
sl@0
   823
            }
sl@0
   824
            BOOST_UBLAS_INLINE
sl@0
   825
            difference_type operator - (const iterator2 &it) const {
sl@0
   826
                BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
sl@0
   827
                BOOST_UBLAS_CHECK (it1_ == it.it1_, external_logic ());
sl@0
   828
                return it2_ - it.it2_;
sl@0
   829
            }
sl@0
   830
sl@0
   831
            // Dereference
sl@0
   832
            BOOST_UBLAS_INLINE
sl@0
   833
            reference operator * () const {
sl@0
   834
                return (*this) ().at_element (it1_, it2_);
sl@0
   835
            }
sl@0
   836
            BOOST_UBLAS_INLINE
sl@0
   837
            reference operator [] (difference_type n) const {
sl@0
   838
                return *(*this + n);
sl@0
   839
            }
sl@0
   840
sl@0
   841
#ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
sl@0
   842
            BOOST_UBLAS_INLINE
sl@0
   843
#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
sl@0
   844
            typename self_type::
sl@0
   845
#endif
sl@0
   846
            iterator1 begin () const {
sl@0
   847
                return (*this) ().find1 (1, 0, it2_);
sl@0
   848
            }
sl@0
   849
            BOOST_UBLAS_INLINE
sl@0
   850
#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
sl@0
   851
            typename self_type::
sl@0
   852
#endif
sl@0
   853
            iterator1 end () const {
sl@0
   854
                return (*this) ().find1 (1, (*this) ().size1 (), it2_);
sl@0
   855
            }
sl@0
   856
            BOOST_UBLAS_INLINE
sl@0
   857
#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
sl@0
   858
            typename self_type::
sl@0
   859
#endif
sl@0
   860
            reverse_iterator1 rbegin () const {
sl@0
   861
                return reverse_iterator1 (end ());
sl@0
   862
            }
sl@0
   863
            BOOST_UBLAS_INLINE
sl@0
   864
#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
sl@0
   865
            typename self_type::
sl@0
   866
#endif
sl@0
   867
            reverse_iterator1 rend () const {
sl@0
   868
                return reverse_iterator1 (begin ());
sl@0
   869
            }
sl@0
   870
#endif
sl@0
   871
sl@0
   872
            // Indices
sl@0
   873
            BOOST_UBLAS_INLINE
sl@0
   874
            size_type index1 () const {
sl@0
   875
                return it1_;
sl@0
   876
            }
sl@0
   877
            BOOST_UBLAS_INLINE
sl@0
   878
            size_type index2 () const {
sl@0
   879
                return it2_;
sl@0
   880
            }
sl@0
   881
sl@0
   882
            // Assignment
sl@0
   883
            BOOST_UBLAS_INLINE
sl@0
   884
            iterator2 &operator = (const iterator2 &it) {
sl@0
   885
                container_reference<self_type>::assign (&it ());
sl@0
   886
                it1_ = it.it1_;
sl@0
   887
                it2_ = it.it2_;
sl@0
   888
                return *this;
sl@0
   889
            }
sl@0
   890
sl@0
   891
            // Comparison
sl@0
   892
            BOOST_UBLAS_INLINE
sl@0
   893
            bool operator == (const iterator2 &it) const {
sl@0
   894
                BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
sl@0
   895
                BOOST_UBLAS_CHECK (it1_ == it.it1_, external_logic ());
sl@0
   896
                return it2_ == it.it2_;
sl@0
   897
            }
sl@0
   898
            BOOST_UBLAS_INLINE
sl@0
   899
            bool operator < (const iterator2 &it) const {
sl@0
   900
                BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
sl@0
   901
                BOOST_UBLAS_CHECK (it1_ == it.it1_, external_logic ());
sl@0
   902
                return it2_ < it.it2_;
sl@0
   903
            }
sl@0
   904
sl@0
   905
        private:
sl@0
   906
            size_type it1_;
sl@0
   907
            size_type it2_;
sl@0
   908
sl@0
   909
            friend class const_iterator2;
sl@0
   910
        };
sl@0
   911
#endif
sl@0
   912
sl@0
   913
        BOOST_UBLAS_INLINE
sl@0
   914
        iterator2 begin2 () {
sl@0
   915
            return find2 (0, 0, 0);
sl@0
   916
        }
sl@0
   917
        BOOST_UBLAS_INLINE
sl@0
   918
        iterator2 end2 () {
sl@0
   919
            return find2 (0, 0, size2_);
sl@0
   920
        }
sl@0
   921
sl@0
   922
        // Reverse iterators
sl@0
   923
sl@0
   924
        BOOST_UBLAS_INLINE
sl@0
   925
        const_reverse_iterator1 rbegin1 () const {
sl@0
   926
            return const_reverse_iterator1 (end1 ());
sl@0
   927
        }
sl@0
   928
        BOOST_UBLAS_INLINE
sl@0
   929
        const_reverse_iterator1 rend1 () const {
sl@0
   930
            return const_reverse_iterator1 (begin1 ());
sl@0
   931
        }
sl@0
   932
sl@0
   933
        BOOST_UBLAS_INLINE
sl@0
   934
        reverse_iterator1 rbegin1 () {
sl@0
   935
            return reverse_iterator1 (end1 ());
sl@0
   936
        }
sl@0
   937
        BOOST_UBLAS_INLINE
sl@0
   938
        reverse_iterator1 rend1 () {
sl@0
   939
            return reverse_iterator1 (begin1 ());
sl@0
   940
        }
sl@0
   941
sl@0
   942
        BOOST_UBLAS_INLINE
sl@0
   943
        const_reverse_iterator2 rbegin2 () const {
sl@0
   944
            return const_reverse_iterator2 (end2 ());
sl@0
   945
        }
sl@0
   946
        BOOST_UBLAS_INLINE
sl@0
   947
        const_reverse_iterator2 rend2 () const {
sl@0
   948
            return const_reverse_iterator2 (begin2 ());
sl@0
   949
        }
sl@0
   950
sl@0
   951
        BOOST_UBLAS_INLINE
sl@0
   952
        reverse_iterator2 rbegin2 () {
sl@0
   953
            return reverse_iterator2 (end2 ());
sl@0
   954
        }
sl@0
   955
        BOOST_UBLAS_INLINE
sl@0
   956
        reverse_iterator2 rend2 () {
sl@0
   957
            return reverse_iterator2 (begin2 ());
sl@0
   958
        }
sl@0
   959
sl@0
   960
    private:
sl@0
   961
        size_type size1_;
sl@0
   962
        size_type size2_;
sl@0
   963
        size_type lower_;
sl@0
   964
        size_type upper_;
sl@0
   965
        array_type data_;
sl@0
   966
        typedef const value_type const_value_type;
sl@0
   967
        static const_value_type zero_;
sl@0
   968
    };
sl@0
   969
sl@0
   970
    template<class T, class L, class A>
sl@0
   971
    typename banded_matrix<T, L, A>::const_value_type banded_matrix<T, L, A>::zero_ = value_type/*zero*/();
sl@0
   972
sl@0
   973
sl@0
   974
    // Diagonal matrix class
sl@0
   975
    template<class T, class L, class A>
sl@0
   976
    class diagonal_matrix:
sl@0
   977
        public banded_matrix<T, L, A> {
sl@0
   978
    public:
sl@0
   979
        typedef typename A::size_type size_type;
sl@0
   980
        typedef banded_matrix<T, L, A> matrix_type;
sl@0
   981
        typedef A array_type;
sl@0
   982
sl@0
   983
        // Construction and destruction
sl@0
   984
        BOOST_UBLAS_INLINE
sl@0
   985
        diagonal_matrix ():
sl@0
   986
            matrix_type () {}
sl@0
   987
        BOOST_UBLAS_INLINE
sl@0
   988
        diagonal_matrix (size_type size):
sl@0
   989
            matrix_type (size, size) {}
sl@0
   990
        BOOST_UBLAS_INLINE
sl@0
   991
        diagonal_matrix (size_type size, const array_type& data):
sl@0
   992
            matrix_type (size, size, 0, 0, data) {}
sl@0
   993
        BOOST_UBLAS_INLINE
sl@0
   994
        diagonal_matrix (size_type size1, size_type size2):
sl@0
   995
            matrix_type (size1, size2) {}
sl@0
   996
        template<class AE>
sl@0
   997
        BOOST_UBLAS_INLINE
sl@0
   998
        diagonal_matrix (const matrix_expression<AE> &ae):
sl@0
   999
            matrix_type (ae) {}
sl@0
  1000
        BOOST_UBLAS_INLINE
sl@0
  1001
        ~diagonal_matrix () {}
sl@0
  1002
sl@0
  1003
        // Assignment
sl@0
  1004
        BOOST_UBLAS_INLINE
sl@0
  1005
        diagonal_matrix &operator = (const diagonal_matrix &m) {
sl@0
  1006
            matrix_type::operator = (m);
sl@0
  1007
            return *this;
sl@0
  1008
        }
sl@0
  1009
        template<class AE>
sl@0
  1010
        BOOST_UBLAS_INLINE
sl@0
  1011
        diagonal_matrix &operator = (const matrix_expression<AE> &ae) {
sl@0
  1012
            matrix_type::operator = (ae);
sl@0
  1013
            return *this;
sl@0
  1014
        }
sl@0
  1015
    };
sl@0
  1016
sl@0
  1017
    // Banded matrix adaptor class
sl@0
  1018
    template<class M>
sl@0
  1019
    class banded_adaptor:
sl@0
  1020
        public matrix_expression<banded_adaptor<M> > {
sl@0
  1021
sl@0
  1022
        typedef banded_adaptor<M> self_type;
sl@0
  1023
    public:
sl@0
  1024
#ifdef BOOST_UBLAS_ENABLE_PROXY_SHORTCUTS
sl@0
  1025
        using matrix_expression<self_type>::operator ();
sl@0
  1026
#endif
sl@0
  1027
        typedef const M const_matrix_type;
sl@0
  1028
        typedef M matrix_type;
sl@0
  1029
        typedef typename M::size_type size_type;
sl@0
  1030
        typedef typename M::difference_type difference_type;
sl@0
  1031
        typedef typename M::value_type value_type;
sl@0
  1032
        typedef typename M::const_reference const_reference;
sl@0
  1033
        typedef typename boost::mpl::if_<boost::is_const<M>,
sl@0
  1034
                                          typename M::const_reference,
sl@0
  1035
                                          typename M::reference>::type reference;
sl@0
  1036
        typedef typename boost::mpl::if_<boost::is_const<M>,
sl@0
  1037
                                          typename M::const_closure_type,
sl@0
  1038
                                          typename M::closure_type>::type matrix_closure_type;
sl@0
  1039
        typedef const self_type const_closure_type;
sl@0
  1040
        typedef self_type closure_type;
sl@0
  1041
        // Replaced by _temporary_traits to avoid type requirements on M
sl@0
  1042
        //typedef typename M::vector_temporary_type vector_temporary_type;
sl@0
  1043
        //typedef typename M::matrix_temporary_type matrix_temporary_type;
sl@0
  1044
        typedef typename storage_restrict_traits<typename M::storage_category,
sl@0
  1045
                                                 packed_proxy_tag>::storage_category storage_category;
sl@0
  1046
        typedef typename M::orientation_category orientation_category;
sl@0
  1047
sl@0
  1048
        // Construction and destruction
sl@0
  1049
        BOOST_UBLAS_INLINE
sl@0
  1050
        banded_adaptor (matrix_type &data, size_type lower = 0, size_type upper = 0):
sl@0
  1051
            matrix_expression<self_type> (),
sl@0
  1052
            data_ (data), lower_ (lower), upper_ (upper) {}
sl@0
  1053
        BOOST_UBLAS_INLINE
sl@0
  1054
        banded_adaptor (const banded_adaptor &m):
sl@0
  1055
            matrix_expression<self_type> (),
sl@0
  1056
            data_ (m.data_), lower_ (m.lower_), upper_ (m.upper_) {}
sl@0
  1057
sl@0
  1058
        // Accessors
sl@0
  1059
        BOOST_UBLAS_INLINE
sl@0
  1060
        size_type size1 () const {
sl@0
  1061
            return data_.size1 ();
sl@0
  1062
        }
sl@0
  1063
        BOOST_UBLAS_INLINE
sl@0
  1064
        size_type size2 () const {
sl@0
  1065
            return data_.size2 ();
sl@0
  1066
        }
sl@0
  1067
        BOOST_UBLAS_INLINE
sl@0
  1068
        size_type lower () const {
sl@0
  1069
            return lower_;
sl@0
  1070
        }
sl@0
  1071
        BOOST_UBLAS_INLINE
sl@0
  1072
        size_type upper () const {
sl@0
  1073
            return upper_;
sl@0
  1074
        }
sl@0
  1075
sl@0
  1076
        // Storage accessors
sl@0
  1077
        BOOST_UBLAS_INLINE
sl@0
  1078
        const matrix_closure_type &data () const {
sl@0
  1079
            return data_;
sl@0
  1080
        }
sl@0
  1081
        BOOST_UBLAS_INLINE
sl@0
  1082
        matrix_closure_type &data () {
sl@0
  1083
            return data_;
sl@0
  1084
        }
sl@0
  1085
sl@0
  1086
        // Element access
sl@0
  1087
#ifndef BOOST_UBLAS_PROXY_CONST_MEMBER
sl@0
  1088
        BOOST_UBLAS_INLINE
sl@0
  1089
        const_reference operator () (size_type i, size_type j) const {
sl@0
  1090
            BOOST_UBLAS_CHECK (i < size1 (), bad_index ());
sl@0
  1091
            BOOST_UBLAS_CHECK (j < size2 (), bad_index ());
sl@0
  1092
#ifdef BOOST_UBLAS_OWN_BANDED
sl@0
  1093
            size_type k = (std::max) (i, j);
sl@0
  1094
            size_type l = lower_ + j - i;
sl@0
  1095
            if (k < (std::max) (size1 (), size2 ()) &&
sl@0
  1096
                l < lower_ + 1 + upper_)
sl@0
  1097
                return data () (i, j);
sl@0
  1098
#else
sl@0
  1099
            size_type k = j;
sl@0
  1100
            size_type l = upper_ + i - j;
sl@0
  1101
            if (k < size2 () &&
sl@0
  1102
                l < lower_ + 1 + upper_)
sl@0
  1103
                return data () (i, j);
sl@0
  1104
#endif
sl@0
  1105
            return zero_;
sl@0
  1106
        }
sl@0
  1107
        BOOST_UBLAS_INLINE
sl@0
  1108
        reference operator () (size_type i, size_type j) {
sl@0
  1109
            BOOST_UBLAS_CHECK (i < size1 (), bad_index ());
sl@0
  1110
            BOOST_UBLAS_CHECK (j < size2 (), bad_index ());
sl@0
  1111
#ifdef BOOST_UBLAS_OWN_BANDED
sl@0
  1112
            size_type k = (std::max) (i, j);
sl@0
  1113
            size_type l = lower_ + j - i;
sl@0
  1114
            if (k < (std::max) (size1 (), size2 ()) &&
sl@0
  1115
                l < lower_ + 1 + upper_)
sl@0
  1116
                return data () (i, j);
sl@0
  1117
#else
sl@0
  1118
            size_type k = j;
sl@0
  1119
            size_type l = upper_ + i - j;
sl@0
  1120
            if (k < size2 () &&
sl@0
  1121
                l < lower_ + 1 + upper_)
sl@0
  1122
                return data () (i, j);
sl@0
  1123
#endif
sl@0
  1124
#ifndef BOOST_UBLAS_REFERENCE_CONST_MEMBER
sl@0
  1125
            bad_index ().raise ();
sl@0
  1126
#endif
sl@0
  1127
            return const_cast<reference>(zero_);
sl@0
  1128
        }
sl@0
  1129
#else
sl@0
  1130
        BOOST_UBLAS_INLINE
sl@0
  1131
        reference operator () (size_type i, size_type j) const {
sl@0
  1132
            BOOST_UBLAS_CHECK (i < size1 (), bad_index ());
sl@0
  1133
            BOOST_UBLAS_CHECK (j < size2 (), bad_index ());
sl@0
  1134
#ifdef BOOST_UBLAS_OWN_BANDED
sl@0
  1135
            size_type k = (std::max) (i, j);
sl@0
  1136
            size_type l = lower_ + j - i;
sl@0
  1137
            if (k < (std::max) (size1 (), size2 ()) &&
sl@0
  1138
                l < lower_ + 1 + upper_)
sl@0
  1139
                return data () (i, j);
sl@0
  1140
#else
sl@0
  1141
            size_type k = j;
sl@0
  1142
            size_type l = upper_ + i - j;
sl@0
  1143
            if (k < size2 () &&
sl@0
  1144
                l < lower_ + 1 + upper_)
sl@0
  1145
                return data () (i, j);
sl@0
  1146
#endif
sl@0
  1147
#ifndef BOOST_UBLAS_REFERENCE_CONST_MEMBER
sl@0
  1148
            bad_index ().raise ();
sl@0
  1149
#endif
sl@0
  1150
            return const_cast<reference>(zero_);
sl@0
  1151
        }
sl@0
  1152
#endif
sl@0
  1153
sl@0
  1154
        // Assignment
sl@0
  1155
        BOOST_UBLAS_INLINE
sl@0
  1156
        banded_adaptor &operator = (const banded_adaptor &m) {
sl@0
  1157
            matrix_assign<scalar_assign> (*this, m);
sl@0
  1158
            return *this;
sl@0
  1159
        }
sl@0
  1160
        BOOST_UBLAS_INLINE
sl@0
  1161
        banded_adaptor &assign_temporary (banded_adaptor &m) {
sl@0
  1162
            *this = m;
sl@0
  1163
            return *this;
sl@0
  1164
        }
sl@0
  1165
        template<class AE>
sl@0
  1166
        BOOST_UBLAS_INLINE
sl@0
  1167
        banded_adaptor &operator = (const matrix_expression<AE> &ae) {
sl@0
  1168
            matrix_assign<scalar_assign> (*this, matrix<value_type> (ae));
sl@0
  1169
            return *this;
sl@0
  1170
        }
sl@0
  1171
        template<class AE>
sl@0
  1172
        BOOST_UBLAS_INLINE
sl@0
  1173
        banded_adaptor &assign (const matrix_expression<AE> &ae) {
sl@0
  1174
            matrix_assign<scalar_assign> (*this, ae);
sl@0
  1175
            return *this;
sl@0
  1176
        }
sl@0
  1177
        template<class AE>
sl@0
  1178
        BOOST_UBLAS_INLINE
sl@0
  1179
        banded_adaptor& operator += (const matrix_expression<AE> &ae) {
sl@0
  1180
            matrix_assign<scalar_assign> (*this, matrix<value_type> (*this + ae));
sl@0
  1181
            return *this;
sl@0
  1182
        }
sl@0
  1183
        template<class AE>
sl@0
  1184
        BOOST_UBLAS_INLINE
sl@0
  1185
        banded_adaptor &plus_assign (const matrix_expression<AE> &ae) {
sl@0
  1186
            matrix_assign<scalar_plus_assign> (*this, ae);
sl@0
  1187
            return *this;
sl@0
  1188
        }
sl@0
  1189
        template<class AE>
sl@0
  1190
        BOOST_UBLAS_INLINE
sl@0
  1191
        banded_adaptor& operator -= (const matrix_expression<AE> &ae) {
sl@0
  1192
            matrix_assign<scalar_assign> (*this, matrix<value_type> (*this - ae));
sl@0
  1193
            return *this;
sl@0
  1194
        }
sl@0
  1195
        template<class AE>
sl@0
  1196
        BOOST_UBLAS_INLINE
sl@0
  1197
        banded_adaptor &minus_assign (const matrix_expression<AE> &ae) {
sl@0
  1198
            matrix_assign<scalar_minus_assign> (*this, ae);
sl@0
  1199
            return *this;
sl@0
  1200
        }
sl@0
  1201
        template<class AT>
sl@0
  1202
        BOOST_UBLAS_INLINE
sl@0
  1203
        banded_adaptor& operator *= (const AT &at) {
sl@0
  1204
            matrix_assign_scalar<scalar_multiplies_assign> (*this, at);
sl@0
  1205
            return *this;
sl@0
  1206
        }
sl@0
  1207
        template<class AT>
sl@0
  1208
        BOOST_UBLAS_INLINE
sl@0
  1209
        banded_adaptor& operator /= (const AT &at) {
sl@0
  1210
            matrix_assign_scalar<scalar_divides_assign> (*this, at);
sl@0
  1211
            return *this;
sl@0
  1212
        }
sl@0
  1213
sl@0
  1214
        // Closure comparison
sl@0
  1215
        BOOST_UBLAS_INLINE
sl@0
  1216
        bool same_closure (const banded_adaptor &ba) const {
sl@0
  1217
            return (*this).data ().same_closure (ba.data ());
sl@0
  1218
        }
sl@0
  1219
sl@0
  1220
        // Swapping
sl@0
  1221
        BOOST_UBLAS_INLINE
sl@0
  1222
        void swap (banded_adaptor &m) {
sl@0
  1223
            if (this != &m) {
sl@0
  1224
                BOOST_UBLAS_CHECK (lower_ == m.lower_, bad_size ());
sl@0
  1225
                BOOST_UBLAS_CHECK (upper_ == m.upper_, bad_size ());
sl@0
  1226
                matrix_swap<scalar_swap> (*this, m);
sl@0
  1227
            }
sl@0
  1228
        }
sl@0
  1229
        BOOST_UBLAS_INLINE
sl@0
  1230
        friend void swap (banded_adaptor &m1, banded_adaptor &m2) {
sl@0
  1231
            m1.swap (m2);
sl@0
  1232
        }
sl@0
  1233
sl@0
  1234
        // Iterator types
sl@0
  1235
    private:
sl@0
  1236
        // Use the matrix iterator
sl@0
  1237
        typedef typename M::const_iterator1 const_subiterator1_type;
sl@0
  1238
        typedef typename boost::mpl::if_<boost::is_const<M>,
sl@0
  1239
                                          typename M::const_iterator1,
sl@0
  1240
                                          typename M::iterator1>::type subiterator1_type;
sl@0
  1241
        typedef typename M::const_iterator2 const_subiterator2_type;
sl@0
  1242
        typedef typename boost::mpl::if_<boost::is_const<M>,
sl@0
  1243
                                          typename M::const_iterator2,
sl@0
  1244
                                          typename M::iterator2>::type subiterator2_type;
sl@0
  1245
sl@0
  1246
    public:
sl@0
  1247
#ifdef BOOST_UBLAS_USE_INDEXED_ITERATOR
sl@0
  1248
        typedef indexed_iterator1<self_type, packed_random_access_iterator_tag> iterator1;
sl@0
  1249
        typedef indexed_iterator2<self_type, packed_random_access_iterator_tag> iterator2;
sl@0
  1250
        typedef indexed_const_iterator1<self_type, packed_random_access_iterator_tag> const_iterator1;
sl@0
  1251
        typedef indexed_const_iterator2<self_type, packed_random_access_iterator_tag> const_iterator2;
sl@0
  1252
#else
sl@0
  1253
        class const_iterator1;
sl@0
  1254
        class iterator1;
sl@0
  1255
        class const_iterator2;
sl@0
  1256
        class iterator2;
sl@0
  1257
#endif
sl@0
  1258
        typedef reverse_iterator_base1<const_iterator1> const_reverse_iterator1;
sl@0
  1259
        typedef reverse_iterator_base1<iterator1> reverse_iterator1;
sl@0
  1260
        typedef reverse_iterator_base2<const_iterator2> const_reverse_iterator2;
sl@0
  1261
        typedef reverse_iterator_base2<iterator2> reverse_iterator2;
sl@0
  1262
sl@0
  1263
        // Element lookup
sl@0
  1264
        BOOST_UBLAS_INLINE
sl@0
  1265
        const_iterator1 find1 (int rank, size_type i, size_type j) const {
sl@0
  1266
            if (rank == 1) {
sl@0
  1267
                size_type lower_i = (std::max) (difference_type (j - upper_), difference_type (0));
sl@0
  1268
                i = (std::max) (i, lower_i);
sl@0
  1269
                size_type upper_i = (std::min) (j + 1 + lower_, size1 ());
sl@0
  1270
                i = (std::min) (i, upper_i);
sl@0
  1271
            }
sl@0
  1272
            return const_iterator1 (*this, data ().find1 (rank, i, j));
sl@0
  1273
        }
sl@0
  1274
        BOOST_UBLAS_INLINE
sl@0
  1275
        iterator1 find1 (int rank, size_type i, size_type j) {
sl@0
  1276
            if (rank == 1) {
sl@0
  1277
                size_type lower_i = (std::max) (difference_type (j - upper_), difference_type (0));
sl@0
  1278
                i = (std::max) (i, lower_i);
sl@0
  1279
                size_type upper_i = (std::min) (j + 1 + lower_, size1 ());
sl@0
  1280
                i = (std::min) (i, upper_i);
sl@0
  1281
            }
sl@0
  1282
            return iterator1 (*this, data ().find1 (rank, i, j));
sl@0
  1283
        }
sl@0
  1284
        BOOST_UBLAS_INLINE
sl@0
  1285
        const_iterator2 find2 (int rank, size_type i, size_type j) const {
sl@0
  1286
            if (rank == 1) {
sl@0
  1287
                size_type lower_j = (std::max) (difference_type (i - lower_), difference_type (0));
sl@0
  1288
                j = (std::max) (j, lower_j);
sl@0
  1289
                size_type upper_j = (std::min) (i + 1 + upper_, size2 ());
sl@0
  1290
                j = (std::min) (j, upper_j);
sl@0
  1291
            }
sl@0
  1292
            return const_iterator2 (*this, data ().find2 (rank, i, j));
sl@0
  1293
        }
sl@0
  1294
        BOOST_UBLAS_INLINE
sl@0
  1295
        iterator2 find2 (int rank, size_type i, size_type j) {
sl@0
  1296
            if (rank == 1) {
sl@0
  1297
                size_type lower_j = (std::max) (difference_type (i - lower_), difference_type (0));
sl@0
  1298
                j = (std::max) (j, lower_j);
sl@0
  1299
                size_type upper_j = (std::min) (i + 1 + upper_, size2 ());
sl@0
  1300
                j = (std::min) (j, upper_j);
sl@0
  1301
            }
sl@0
  1302
            return iterator2 (*this, data ().find2 (rank, i, j));
sl@0
  1303
        }
sl@0
  1304
sl@0
  1305
        // Iterators simply are indices.
sl@0
  1306
sl@0
  1307
#ifndef BOOST_UBLAS_USE_INDEXED_ITERATOR
sl@0
  1308
        class const_iterator1:
sl@0
  1309
            public container_const_reference<banded_adaptor>,
sl@0
  1310
            public random_access_iterator_base<typename iterator_restrict_traits<
sl@0
  1311
                                                   typename const_subiterator1_type::iterator_category, packed_random_access_iterator_tag>::iterator_category,
sl@0
  1312
                                               const_iterator1, value_type> {
sl@0
  1313
        public:
sl@0
  1314
            typedef typename const_subiterator1_type::value_type value_type;
sl@0
  1315
            typedef typename const_subiterator1_type::difference_type difference_type;
sl@0
  1316
            typedef typename const_subiterator1_type::reference reference;
sl@0
  1317
            typedef typename const_subiterator1_type::pointer pointer;
sl@0
  1318
sl@0
  1319
            typedef const_iterator2 dual_iterator_type;
sl@0
  1320
            typedef const_reverse_iterator2 dual_reverse_iterator_type;
sl@0
  1321
sl@0
  1322
            // Construction and destruction
sl@0
  1323
            BOOST_UBLAS_INLINE
sl@0
  1324
            const_iterator1 ():
sl@0
  1325
                container_const_reference<self_type> (), it1_ () {}
sl@0
  1326
            BOOST_UBLAS_INLINE
sl@0
  1327
            const_iterator1 (const self_type &m, const const_subiterator1_type &it1):
sl@0
  1328
                container_const_reference<self_type> (m), it1_ (it1) {}
sl@0
  1329
            BOOST_UBLAS_INLINE
sl@0
  1330
            const_iterator1 (const iterator1 &it):
sl@0
  1331
                container_const_reference<self_type> (it ()), it1_ (it.it1_) {}
sl@0
  1332
sl@0
  1333
            // Arithmetic
sl@0
  1334
            BOOST_UBLAS_INLINE
sl@0
  1335
            const_iterator1 &operator ++ () {
sl@0
  1336
                ++ it1_;
sl@0
  1337
                return *this;
sl@0
  1338
            }
sl@0
  1339
            BOOST_UBLAS_INLINE
sl@0
  1340
            const_iterator1 &operator -- () {
sl@0
  1341
                -- it1_;
sl@0
  1342
                return *this;
sl@0
  1343
            }
sl@0
  1344
            BOOST_UBLAS_INLINE
sl@0
  1345
            const_iterator1 &operator += (difference_type n) {
sl@0
  1346
                it1_ += n;
sl@0
  1347
                return *this;
sl@0
  1348
            }
sl@0
  1349
            BOOST_UBLAS_INLINE
sl@0
  1350
            const_iterator1 &operator -= (difference_type n) {
sl@0
  1351
                it1_ -= n;
sl@0
  1352
                return *this;
sl@0
  1353
            }
sl@0
  1354
            BOOST_UBLAS_INLINE
sl@0
  1355
            difference_type operator - (const const_iterator1 &it) const {
sl@0
  1356
                BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
sl@0
  1357
                return it1_ - it.it1_;
sl@0
  1358
            }
sl@0
  1359
sl@0
  1360
            // Dereference
sl@0
  1361
            BOOST_UBLAS_INLINE
sl@0
  1362
            const_reference operator * () const {
sl@0
  1363
                size_type i = index1 ();
sl@0
  1364
                size_type j = index2 ();
sl@0
  1365
                BOOST_UBLAS_CHECK (i < (*this) ().size1 (), bad_index ());
sl@0
  1366
                BOOST_UBLAS_CHECK (j < (*this) ().size2 (), bad_index ());
sl@0
  1367
#ifdef BOOST_UBLAS_OWN_BANDED
sl@0
  1368
                size_type k = (std::max) (i, j);
sl@0
  1369
                size_type l = (*this) ().lower () + j - i;
sl@0
  1370
                if (k < (std::max) ((*this) ().size1 (), (*this) ().size2 ()) &&
sl@0
  1371
                    l < (*this) ().lower () + 1 + (*this) ().upper ())
sl@0
  1372
                    return *it1_;
sl@0
  1373
#else
sl@0
  1374
                size_type k = j;
sl@0
  1375
                size_type l = (*this) ().upper () + i - j;
sl@0
  1376
                if (k < (*this) ().size2 () &&
sl@0
  1377
                    l < (*this) ().lower () + 1 + (*this) ().upper ())
sl@0
  1378
                    return *it1_;
sl@0
  1379
#endif
sl@0
  1380
                return (*this) () (i, j);
sl@0
  1381
            }
sl@0
  1382
            BOOST_UBLAS_INLINE
sl@0
  1383
            const_reference operator [] (difference_type n) const {
sl@0
  1384
                return *(*this + n);
sl@0
  1385
            }
sl@0
  1386
sl@0
  1387
#ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
sl@0
  1388
            BOOST_UBLAS_INLINE
sl@0
  1389
#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
sl@0
  1390
            typename self_type::
sl@0
  1391
#endif
sl@0
  1392
            const_iterator2 begin () const {
sl@0
  1393
                return (*this) ().find2 (1, index1 (), 0);
sl@0
  1394
            }
sl@0
  1395
            BOOST_UBLAS_INLINE
sl@0
  1396
#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
sl@0
  1397
            typename self_type::
sl@0
  1398
#endif
sl@0
  1399
            const_iterator2 end () const {
sl@0
  1400
                return (*this) ().find2 (1, index1 (), (*this) ().size2 ());
sl@0
  1401
            }
sl@0
  1402
            BOOST_UBLAS_INLINE
sl@0
  1403
#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
sl@0
  1404
            typename self_type::
sl@0
  1405
#endif
sl@0
  1406
            const_reverse_iterator2 rbegin () const {
sl@0
  1407
                return const_reverse_iterator2 (end ());
sl@0
  1408
            }
sl@0
  1409
            BOOST_UBLAS_INLINE
sl@0
  1410
#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
sl@0
  1411
            typename self_type::
sl@0
  1412
#endif
sl@0
  1413
            const_reverse_iterator2 rend () const {
sl@0
  1414
                return const_reverse_iterator2 (begin ());
sl@0
  1415
            }
sl@0
  1416
#endif
sl@0
  1417
sl@0
  1418
            // Indices
sl@0
  1419
            BOOST_UBLAS_INLINE
sl@0
  1420
            size_type index1 () const {
sl@0
  1421
                return it1_.index1 ();
sl@0
  1422
            }
sl@0
  1423
            BOOST_UBLAS_INLINE
sl@0
  1424
            size_type index2 () const {
sl@0
  1425
                return it1_.index2 ();
sl@0
  1426
            }
sl@0
  1427
sl@0
  1428
            // Assignment
sl@0
  1429
            BOOST_UBLAS_INLINE
sl@0
  1430
            const_iterator1 &operator = (const const_iterator1 &it) {
sl@0
  1431
                container_const_reference<self_type>::assign (&it ());
sl@0
  1432
                it1_ = it.it1_;
sl@0
  1433
                return *this;
sl@0
  1434
            }
sl@0
  1435
sl@0
  1436
            // Comparison
sl@0
  1437
            BOOST_UBLAS_INLINE
sl@0
  1438
            bool operator == (const const_iterator1 &it) const {
sl@0
  1439
                BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
sl@0
  1440
                return it1_ == it.it1_;
sl@0
  1441
            }
sl@0
  1442
            BOOST_UBLAS_INLINE
sl@0
  1443
            bool operator < (const const_iterator1 &it) const {
sl@0
  1444
                BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
sl@0
  1445
                return it1_ < it.it1_;
sl@0
  1446
            }
sl@0
  1447
sl@0
  1448
        private:
sl@0
  1449
            const_subiterator1_type it1_;
sl@0
  1450
        };
sl@0
  1451
#endif
sl@0
  1452
sl@0
  1453
        BOOST_UBLAS_INLINE
sl@0
  1454
        const_iterator1 begin1 () const {
sl@0
  1455
            return find1 (0, 0, 0);
sl@0
  1456
        }
sl@0
  1457
        BOOST_UBLAS_INLINE
sl@0
  1458
        const_iterator1 end1 () const {
sl@0
  1459
            return find1 (0, size1 (), 0);
sl@0
  1460
        }
sl@0
  1461
sl@0
  1462
#ifndef BOOST_UBLAS_USE_INDEXED_ITERATOR
sl@0
  1463
        class iterator1:
sl@0
  1464
            public container_reference<banded_adaptor>,
sl@0
  1465
            public random_access_iterator_base<typename iterator_restrict_traits<
sl@0
  1466
                                                   typename subiterator1_type::iterator_category, packed_random_access_iterator_tag>::iterator_category,
sl@0
  1467
                                               iterator1, value_type> {
sl@0
  1468
        public:
sl@0
  1469
            typedef typename subiterator1_type::value_type value_type;
sl@0
  1470
            typedef typename subiterator1_type::difference_type difference_type;
sl@0
  1471
            typedef typename subiterator1_type::reference reference;
sl@0
  1472
            typedef typename subiterator1_type::pointer pointer;
sl@0
  1473
sl@0
  1474
            typedef iterator2 dual_iterator_type;
sl@0
  1475
            typedef reverse_iterator2 dual_reverse_iterator_type;
sl@0
  1476
sl@0
  1477
            // Construction and destruction
sl@0
  1478
            BOOST_UBLAS_INLINE
sl@0
  1479
            iterator1 ():
sl@0
  1480
                container_reference<self_type> (), it1_ () {}
sl@0
  1481
            BOOST_UBLAS_INLINE
sl@0
  1482
            iterator1 (self_type &m, const subiterator1_type &it1):
sl@0
  1483
                container_reference<self_type> (m), it1_ (it1) {}
sl@0
  1484
sl@0
  1485
            // Arithmetic
sl@0
  1486
            BOOST_UBLAS_INLINE
sl@0
  1487
            iterator1 &operator ++ () {
sl@0
  1488
                ++ it1_;
sl@0
  1489
                return *this;
sl@0
  1490
            }
sl@0
  1491
            BOOST_UBLAS_INLINE
sl@0
  1492
            iterator1 &operator -- () {
sl@0
  1493
                -- it1_;
sl@0
  1494
                return *this;
sl@0
  1495
            }
sl@0
  1496
            BOOST_UBLAS_INLINE
sl@0
  1497
            iterator1 &operator += (difference_type n) {
sl@0
  1498
                it1_ += n;
sl@0
  1499
                return *this;
sl@0
  1500
            }
sl@0
  1501
            BOOST_UBLAS_INLINE
sl@0
  1502
            iterator1 &operator -= (difference_type n) {
sl@0
  1503
                it1_ -= n;
sl@0
  1504
                return *this;
sl@0
  1505
            }
sl@0
  1506
            BOOST_UBLAS_INLINE
sl@0
  1507
            difference_type operator - (const iterator1 &it) const {
sl@0
  1508
                BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
sl@0
  1509
                return it1_ - it.it1_;
sl@0
  1510
            }
sl@0
  1511
sl@0
  1512
            // Dereference
sl@0
  1513
            BOOST_UBLAS_INLINE
sl@0
  1514
            reference operator * () const {
sl@0
  1515
                size_type i = index1 ();
sl@0
  1516
                size_type j = index2 ();
sl@0
  1517
                BOOST_UBLAS_CHECK (i < (*this) ().size1 (), bad_index ());
sl@0
  1518
                BOOST_UBLAS_CHECK (j < (*this) ().size2 (), bad_index ());
sl@0
  1519
#ifdef BOOST_UBLAS_OWN_BANDED
sl@0
  1520
                size_type k = (std::max) (i, j);
sl@0
  1521
                size_type l = (*this) ().lower () + j - i;
sl@0
  1522
                if (k < (std::max) ((*this) ().size1 (), (*this) ().size2 ()) &&
sl@0
  1523
                    l < (*this) ().lower () + 1 + (*this) ().upper ())
sl@0
  1524
                    return *it1_;
sl@0
  1525
#else
sl@0
  1526
                size_type k = j;
sl@0
  1527
                size_type l = (*this) ().upper () + i - j;
sl@0
  1528
                if (k < (*this) ().size2 () &&
sl@0
  1529
                    l < (*this) ().lower () + 1 + (*this) ().upper ())
sl@0
  1530
                    return *it1_;
sl@0
  1531
#endif
sl@0
  1532
                return (*this) () (i, j);
sl@0
  1533
            }
sl@0
  1534
            BOOST_UBLAS_INLINE
sl@0
  1535
            reference operator [] (difference_type n) const {
sl@0
  1536
                return *(*this + n);
sl@0
  1537
            }
sl@0
  1538
sl@0
  1539
#ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
sl@0
  1540
            BOOST_UBLAS_INLINE
sl@0
  1541
#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
sl@0
  1542
            typename self_type::
sl@0
  1543
#endif
sl@0
  1544
            iterator2 begin () const {
sl@0
  1545
                return (*this) ().find2 (1, index1 (), 0);
sl@0
  1546
            }
sl@0
  1547
            BOOST_UBLAS_INLINE
sl@0
  1548
#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
sl@0
  1549
            typename self_type::
sl@0
  1550
#endif
sl@0
  1551
            iterator2 end () const {
sl@0
  1552
                return (*this) ().find2 (1, index1 (), (*this) ().size2 ());
sl@0
  1553
            }
sl@0
  1554
            BOOST_UBLAS_INLINE
sl@0
  1555
#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
sl@0
  1556
            typename self_type::
sl@0
  1557
#endif
sl@0
  1558
            reverse_iterator2 rbegin () const {
sl@0
  1559
                return reverse_iterator2 (end ());
sl@0
  1560
            }
sl@0
  1561
            BOOST_UBLAS_INLINE
sl@0
  1562
#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
sl@0
  1563
            typename self_type::
sl@0
  1564
#endif
sl@0
  1565
            reverse_iterator2 rend () const {
sl@0
  1566
                return reverse_iterator2 (begin ());
sl@0
  1567
            }
sl@0
  1568
#endif
sl@0
  1569
sl@0
  1570
            // Indices
sl@0
  1571
            BOOST_UBLAS_INLINE
sl@0
  1572
            size_type index1 () const {
sl@0
  1573
                return it1_.index1 ();
sl@0
  1574
            }
sl@0
  1575
            BOOST_UBLAS_INLINE
sl@0
  1576
            size_type index2 () const {
sl@0
  1577
                return it1_.index2 ();
sl@0
  1578
            }
sl@0
  1579
sl@0
  1580
            // Assignment
sl@0
  1581
            BOOST_UBLAS_INLINE
sl@0
  1582
            iterator1 &operator = (const iterator1 &it) {
sl@0
  1583
                container_reference<self_type>::assign (&it ());
sl@0
  1584
                it1_ = it.it1_;
sl@0
  1585
                return *this;
sl@0
  1586
            }
sl@0
  1587
sl@0
  1588
            // Comparison
sl@0
  1589
            BOOST_UBLAS_INLINE
sl@0
  1590
            bool operator == (const iterator1 &it) const {
sl@0
  1591
                BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
sl@0
  1592
                return it1_ == it.it1_;
sl@0
  1593
            }
sl@0
  1594
            BOOST_UBLAS_INLINE
sl@0
  1595
            bool operator < (const iterator1 &it) const {
sl@0
  1596
                BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
sl@0
  1597
                return it1_ < it.it1_;
sl@0
  1598
            }
sl@0
  1599
sl@0
  1600
        private:
sl@0
  1601
            subiterator1_type it1_;
sl@0
  1602
sl@0
  1603
            friend class const_iterator1;
sl@0
  1604
        };
sl@0
  1605
#endif
sl@0
  1606
sl@0
  1607
        BOOST_UBLAS_INLINE
sl@0
  1608
        iterator1 begin1 () {
sl@0
  1609
            return find1 (0, 0, 0);
sl@0
  1610
        }
sl@0
  1611
        BOOST_UBLAS_INLINE
sl@0
  1612
        iterator1 end1 () {
sl@0
  1613
            return find1 (0, size1 (), 0);
sl@0
  1614
        }
sl@0
  1615
sl@0
  1616
#ifndef BOOST_UBLAS_USE_INDEXED_ITERATOR
sl@0
  1617
        class const_iterator2:
sl@0
  1618
            public container_const_reference<banded_adaptor>,
sl@0
  1619
            public random_access_iterator_base<packed_random_access_iterator_tag,
sl@0
  1620
                                               const_iterator2, value_type> {
sl@0
  1621
        public:
sl@0
  1622
            typedef typename iterator_restrict_traits<typename const_subiterator2_type::iterator_category,
sl@0
  1623
                                                      packed_random_access_iterator_tag>::iterator_category iterator_category;
sl@0
  1624
            typedef typename const_subiterator2_type::value_type value_type;
sl@0
  1625
            typedef typename const_subiterator2_type::difference_type difference_type;
sl@0
  1626
            typedef typename const_subiterator2_type::reference reference;
sl@0
  1627
            typedef typename const_subiterator2_type::pointer pointer;
sl@0
  1628
sl@0
  1629
            typedef const_iterator1 dual_iterator_type;
sl@0
  1630
            typedef const_reverse_iterator1 dual_reverse_iterator_type;
sl@0
  1631
sl@0
  1632
            // Construction and destruction
sl@0
  1633
            BOOST_UBLAS_INLINE
sl@0
  1634
            const_iterator2 ():
sl@0
  1635
                container_const_reference<self_type> (), it2_ () {}
sl@0
  1636
            BOOST_UBLAS_INLINE
sl@0
  1637
            const_iterator2 (const self_type &m, const const_subiterator2_type &it2):
sl@0
  1638
                container_const_reference<self_type> (m), it2_ (it2) {}
sl@0
  1639
            BOOST_UBLAS_INLINE
sl@0
  1640
            const_iterator2 (const iterator2 &it):
sl@0
  1641
                container_const_reference<self_type> (it ()), it2_ (it.it2_) {}
sl@0
  1642
sl@0
  1643
            // Arithmetic
sl@0
  1644
            BOOST_UBLAS_INLINE
sl@0
  1645
            const_iterator2 &operator ++ () {
sl@0
  1646
                ++ it2_;
sl@0
  1647
                return *this;
sl@0
  1648
            }
sl@0
  1649
            BOOST_UBLAS_INLINE
sl@0
  1650
            const_iterator2 &operator -- () {
sl@0
  1651
                -- it2_;
sl@0
  1652
                return *this;
sl@0
  1653
            }
sl@0
  1654
            BOOST_UBLAS_INLINE
sl@0
  1655
            const_iterator2 &operator += (difference_type n) {
sl@0
  1656
                it2_ += n;
sl@0
  1657
                return *this;
sl@0
  1658
            }
sl@0
  1659
            BOOST_UBLAS_INLINE
sl@0
  1660
            const_iterator2 &operator -= (difference_type n) {
sl@0
  1661
                it2_ -= n;
sl@0
  1662
                return *this;
sl@0
  1663
            }
sl@0
  1664
            BOOST_UBLAS_INLINE
sl@0
  1665
            difference_type operator - (const const_iterator2 &it) const {
sl@0
  1666
                BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
sl@0
  1667
                return it2_ - it.it2_;
sl@0
  1668
            }
sl@0
  1669
sl@0
  1670
            // Dereference
sl@0
  1671
            BOOST_UBLAS_INLINE
sl@0
  1672
            const_reference operator * () const {
sl@0
  1673
                size_type i = index1 ();
sl@0
  1674
                size_type j = index2 ();
sl@0
  1675
                BOOST_UBLAS_CHECK (i < (*this) ().size1 (), bad_index ());
sl@0
  1676
                BOOST_UBLAS_CHECK (j < (*this) ().size2 (), bad_index ());
sl@0
  1677
#ifdef BOOST_UBLAS_OWN_BANDED
sl@0
  1678
                size_type k = (std::max) (i, j);
sl@0
  1679
                size_type l = (*this) ().lower () + j - i;
sl@0
  1680
                if (k < (std::max) ((*this) ().size1 (), (*this) ().size2 ()) &&
sl@0
  1681
                    l < (*this) ().lower () + 1 + (*this) ().upper ())
sl@0
  1682
                    return *it2_;
sl@0
  1683
#else
sl@0
  1684
                size_type k = j;
sl@0
  1685
                size_type l = (*this) ().upper () + i - j;
sl@0
  1686
                if (k < (*this) ().size2 () &&
sl@0
  1687
                    l < (*this) ().lower () + 1 + (*this) ().upper ())
sl@0
  1688
                    return *it2_;
sl@0
  1689
#endif
sl@0
  1690
                return (*this) () (i, j);
sl@0
  1691
            }
sl@0
  1692
            BOOST_UBLAS_INLINE
sl@0
  1693
            const_reference operator [] (difference_type n) const {
sl@0
  1694
                return *(*this + n);
sl@0
  1695
            }
sl@0
  1696
sl@0
  1697
#ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
sl@0
  1698
            BOOST_UBLAS_INLINE
sl@0
  1699
#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
sl@0
  1700
            typename self_type::
sl@0
  1701
#endif
sl@0
  1702
            const_iterator1 begin () const {
sl@0
  1703
                return (*this) ().find1 (1, 0, index2 ());
sl@0
  1704
            }
sl@0
  1705
            BOOST_UBLAS_INLINE
sl@0
  1706
#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
sl@0
  1707
            typename self_type::
sl@0
  1708
#endif
sl@0
  1709
            const_iterator1 end () const {
sl@0
  1710
                return (*this) ().find1 (1, (*this) ().size1 (), index2 ());
sl@0
  1711
            }
sl@0
  1712
            BOOST_UBLAS_INLINE
sl@0
  1713
#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
sl@0
  1714
            typename self_type::
sl@0
  1715
#endif
sl@0
  1716
            const_reverse_iterator1 rbegin () const {
sl@0
  1717
                return const_reverse_iterator1 (end ());
sl@0
  1718
            }
sl@0
  1719
            BOOST_UBLAS_INLINE
sl@0
  1720
#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
sl@0
  1721
            typename self_type::
sl@0
  1722
#endif
sl@0
  1723
            const_reverse_iterator1 rend () const {
sl@0
  1724
                return const_reverse_iterator1 (begin ());
sl@0
  1725
            }
sl@0
  1726
#endif
sl@0
  1727
sl@0
  1728
            // Indices
sl@0
  1729
            BOOST_UBLAS_INLINE
sl@0
  1730
            size_type index1 () const {
sl@0
  1731
                return it2_.index1 ();
sl@0
  1732
            }
sl@0
  1733
            BOOST_UBLAS_INLINE
sl@0
  1734
            size_type index2 () const {
sl@0
  1735
                return it2_.index2 ();
sl@0
  1736
            }
sl@0
  1737
sl@0
  1738
            // Assignment
sl@0
  1739
            BOOST_UBLAS_INLINE
sl@0
  1740
            const_iterator2 &operator = (const const_iterator2 &it) {
sl@0
  1741
                container_const_reference<self_type>::assign (&it ());
sl@0
  1742
                it2_ = it.it2_;
sl@0
  1743
                return *this;
sl@0
  1744
            }
sl@0
  1745
sl@0
  1746
            // Comparison
sl@0
  1747
            BOOST_UBLAS_INLINE
sl@0
  1748
            bool operator == (const const_iterator2 &it) const {
sl@0
  1749
                BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
sl@0
  1750
                return it2_ == it.it2_;
sl@0
  1751
            }
sl@0
  1752
            BOOST_UBLAS_INLINE
sl@0
  1753
            bool operator < (const const_iterator2 &it) const {
sl@0
  1754
                BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
sl@0
  1755
                return it2_ < it.it2_;
sl@0
  1756
            }
sl@0
  1757
sl@0
  1758
        private:
sl@0
  1759
            const_subiterator2_type it2_;
sl@0
  1760
        };
sl@0
  1761
#endif
sl@0
  1762
sl@0
  1763
        BOOST_UBLAS_INLINE
sl@0
  1764
        const_iterator2 begin2 () const {
sl@0
  1765
            return find2 (0, 0, 0);
sl@0
  1766
        }
sl@0
  1767
        BOOST_UBLAS_INLINE
sl@0
  1768
        const_iterator2 end2 () const {
sl@0
  1769
            return find2 (0, 0, size2 ());
sl@0
  1770
        }
sl@0
  1771
sl@0
  1772
#ifndef BOOST_UBLAS_USE_INDEXED_ITERATOR
sl@0
  1773
        class iterator2:
sl@0
  1774
            public container_reference<banded_adaptor>,
sl@0
  1775
            public random_access_iterator_base<typename iterator_restrict_traits<
sl@0
  1776
                                                   typename subiterator2_type::iterator_category, packed_random_access_iterator_tag>::iterator_category,
sl@0
  1777
                                               iterator2, value_type> {
sl@0
  1778
        public:
sl@0
  1779
            typedef typename subiterator2_type::value_type value_type;
sl@0
  1780
            typedef typename subiterator2_type::difference_type difference_type;
sl@0
  1781
            typedef typename subiterator2_type::reference reference;
sl@0
  1782
            typedef typename subiterator2_type::pointer pointer;
sl@0
  1783
sl@0
  1784
            typedef iterator1 dual_iterator_type;
sl@0
  1785
            typedef reverse_iterator1 dual_reverse_iterator_type;
sl@0
  1786
sl@0
  1787
            // Construction and destruction
sl@0
  1788
            BOOST_UBLAS_INLINE
sl@0
  1789
            iterator2 ():
sl@0
  1790
                container_reference<self_type> (), it2_ () {}
sl@0
  1791
            BOOST_UBLAS_INLINE
sl@0
  1792
            iterator2 (self_type &m, const subiterator2_type &it2):
sl@0
  1793
                container_reference<self_type> (m), it2_ (it2) {}
sl@0
  1794
sl@0
  1795
            // Arithmetic
sl@0
  1796
            BOOST_UBLAS_INLINE
sl@0
  1797
            iterator2 &operator ++ () {
sl@0
  1798
                ++ it2_;
sl@0
  1799
                return *this;
sl@0
  1800
            }
sl@0
  1801
            BOOST_UBLAS_INLINE
sl@0
  1802
            iterator2 &operator -- () {
sl@0
  1803
                -- it2_;
sl@0
  1804
                return *this;
sl@0
  1805
            }
sl@0
  1806
            BOOST_UBLAS_INLINE
sl@0
  1807
            iterator2 &operator += (difference_type n) {
sl@0
  1808
                it2_ += n;
sl@0
  1809
                return *this;
sl@0
  1810
            }
sl@0
  1811
            BOOST_UBLAS_INLINE
sl@0
  1812
            iterator2 &operator -= (difference_type n) {
sl@0
  1813
                it2_ -= n;
sl@0
  1814
                return *this;
sl@0
  1815
            }
sl@0
  1816
            BOOST_UBLAS_INLINE
sl@0
  1817
            difference_type operator - (const iterator2 &it) const {
sl@0
  1818
                BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
sl@0
  1819
                return it2_ - it.it2_;
sl@0
  1820
            }
sl@0
  1821
sl@0
  1822
            // Dereference
sl@0
  1823
            BOOST_UBLAS_INLINE
sl@0
  1824
            reference operator * () const {
sl@0
  1825
                size_type i = index1 ();
sl@0
  1826
                size_type j = index2 ();
sl@0
  1827
                BOOST_UBLAS_CHECK (i < (*this) ().size1 (), bad_index ());
sl@0
  1828
                BOOST_UBLAS_CHECK (j < (*this) ().size2 (), bad_index ());
sl@0
  1829
#ifdef BOOST_UBLAS_OWN_BANDED
sl@0
  1830
                size_type k = (std::max) (i, j);
sl@0
  1831
                size_type l = (*this) ().lower () + j - i;
sl@0
  1832
                if (k < (std::max) ((*this) ().size1 (), (*this) ().size2 ()) &&
sl@0
  1833
                    l < (*this) ().lower () + 1 + (*this) ().upper ())
sl@0
  1834
                    return *it2_;
sl@0
  1835
#else
sl@0
  1836
                size_type k = j;
sl@0
  1837
                size_type l = (*this) ().upper () + i - j;
sl@0
  1838
                if (k < (*this) ().size2 () &&
sl@0
  1839
                    l < (*this) ().lower () + 1 + (*this) ().upper ())
sl@0
  1840
                    return *it2_;
sl@0
  1841
#endif
sl@0
  1842
                return (*this) () (i, j);
sl@0
  1843
            }
sl@0
  1844
            BOOST_UBLAS_INLINE
sl@0
  1845
            reference operator [] (difference_type n) const {
sl@0
  1846
                return *(*this + n);
sl@0
  1847
            }
sl@0
  1848
sl@0
  1849
#ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
sl@0
  1850
            BOOST_UBLAS_INLINE
sl@0
  1851
#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
sl@0
  1852
            typename self_type::
sl@0
  1853
#endif
sl@0
  1854
            iterator1 begin () const {
sl@0
  1855
                return (*this) ().find1 (1, 0, index2 ());
sl@0
  1856
            }
sl@0
  1857
            BOOST_UBLAS_INLINE
sl@0
  1858
#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
sl@0
  1859
            typename self_type::
sl@0
  1860
#endif
sl@0
  1861
            iterator1 end () const {
sl@0
  1862
                return (*this) ().find1 (1, (*this) ().size1 (), index2 ());
sl@0
  1863
            }
sl@0
  1864
            BOOST_UBLAS_INLINE
sl@0
  1865
#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
sl@0
  1866
            typename self_type::
sl@0
  1867
#endif
sl@0
  1868
            reverse_iterator1 rbegin () const {
sl@0
  1869
                return reverse_iterator1 (end ());
sl@0
  1870
            }
sl@0
  1871
            BOOST_UBLAS_INLINE
sl@0
  1872
#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
sl@0
  1873
            typename self_type::
sl@0
  1874
#endif
sl@0
  1875
            reverse_iterator1 rend () const {
sl@0
  1876
                return reverse_iterator1 (begin ());
sl@0
  1877
            }
sl@0
  1878
#endif
sl@0
  1879
sl@0
  1880
            // Indices
sl@0
  1881
            BOOST_UBLAS_INLINE
sl@0
  1882
            size_type index1 () const {
sl@0
  1883
                return it2_.index1 ();
sl@0
  1884
            }
sl@0
  1885
            BOOST_UBLAS_INLINE
sl@0
  1886
            size_type index2 () const {
sl@0
  1887
                return it2_.index2 ();
sl@0
  1888
            }
sl@0
  1889
sl@0
  1890
            // Assignment
sl@0
  1891
            BOOST_UBLAS_INLINE
sl@0
  1892
            iterator2 &operator = (const iterator2 &it) {
sl@0
  1893
                container_reference<self_type>::assign (&it ());
sl@0
  1894
                it2_ = it.it2_;
sl@0
  1895
                return *this;
sl@0
  1896
            }
sl@0
  1897
sl@0
  1898
            // Comparison
sl@0
  1899
            BOOST_UBLAS_INLINE
sl@0
  1900
            bool operator == (const iterator2 &it) const {
sl@0
  1901
                BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
sl@0
  1902
                return it2_ == it.it2_;
sl@0
  1903
            }
sl@0
  1904
            BOOST_UBLAS_INLINE
sl@0
  1905
            bool operator < (const iterator2 &it) const {
sl@0
  1906
                BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
sl@0
  1907
                return it2_ < it.it2_;
sl@0
  1908
            }
sl@0
  1909
sl@0
  1910
        private:
sl@0
  1911
            subiterator2_type it2_;
sl@0
  1912
sl@0
  1913
            friend class const_iterator2;
sl@0
  1914
        };
sl@0
  1915
#endif
sl@0
  1916
sl@0
  1917
        BOOST_UBLAS_INLINE
sl@0
  1918
        iterator2 begin2 () {
sl@0
  1919
            return find2 (0, 0, 0);
sl@0
  1920
        }
sl@0
  1921
        BOOST_UBLAS_INLINE
sl@0
  1922
        iterator2 end2 () {
sl@0
  1923
            return find2 (0, 0, size2 ());
sl@0
  1924
        }
sl@0
  1925
sl@0
  1926
        // Reverse iterators
sl@0
  1927
sl@0
  1928
        BOOST_UBLAS_INLINE
sl@0
  1929
        const_reverse_iterator1 rbegin1 () const {
sl@0
  1930
            return const_reverse_iterator1 (end1 ());
sl@0
  1931
        }
sl@0
  1932
        BOOST_UBLAS_INLINE
sl@0
  1933
        const_reverse_iterator1 rend1 () const {
sl@0
  1934
            return const_reverse_iterator1 (begin1 ());
sl@0
  1935
        }
sl@0
  1936
sl@0
  1937
        BOOST_UBLAS_INLINE
sl@0
  1938
        reverse_iterator1 rbegin1 () {
sl@0
  1939
            return reverse_iterator1 (end1 ());
sl@0
  1940
        }
sl@0
  1941
        BOOST_UBLAS_INLINE
sl@0
  1942
        reverse_iterator1 rend1 () {
sl@0
  1943
            return reverse_iterator1 (begin1 ());
sl@0
  1944
        }
sl@0
  1945
sl@0
  1946
        BOOST_UBLAS_INLINE
sl@0
  1947
        const_reverse_iterator2 rbegin2 () const {
sl@0
  1948
            return const_reverse_iterator2 (end2 ());
sl@0
  1949
        }
sl@0
  1950
        BOOST_UBLAS_INLINE
sl@0
  1951
        const_reverse_iterator2 rend2 () const {
sl@0
  1952
            return const_reverse_iterator2 (begin2 ());
sl@0
  1953
        }
sl@0
  1954
sl@0
  1955
        BOOST_UBLAS_INLINE
sl@0
  1956
        reverse_iterator2 rbegin2 () {
sl@0
  1957
            return reverse_iterator2 (end2 ());
sl@0
  1958
        }
sl@0
  1959
        BOOST_UBLAS_INLINE
sl@0
  1960
        reverse_iterator2 rend2 () {
sl@0
  1961
            return reverse_iterator2 (begin2 ());
sl@0
  1962
        }
sl@0
  1963
sl@0
  1964
    private:
sl@0
  1965
        matrix_closure_type data_;
sl@0
  1966
        size_type lower_;
sl@0
  1967
        size_type upper_;
sl@0
  1968
        typedef const value_type const_value_type;
sl@0
  1969
        static const_value_type zero_;
sl@0
  1970
    };
sl@0
  1971
sl@0
  1972
    // Specialization for temporary_traits
sl@0
  1973
    template <class M>
sl@0
  1974
    struct vector_temporary_traits< banded_adaptor<M> >
sl@0
  1975
    : vector_temporary_traits< M > {} ;
sl@0
  1976
    template <class M>
sl@0
  1977
    struct vector_temporary_traits< const banded_adaptor<M> >
sl@0
  1978
    : vector_temporary_traits< M > {} ;
sl@0
  1979
sl@0
  1980
    template <class M>
sl@0
  1981
    struct matrix_temporary_traits< banded_adaptor<M> >
sl@0
  1982
    : matrix_temporary_traits< M > {} ;
sl@0
  1983
    template <class M>
sl@0
  1984
    struct matrix_temporary_traits< const banded_adaptor<M> >
sl@0
  1985
    : matrix_temporary_traits< M > {} ;
sl@0
  1986
sl@0
  1987
sl@0
  1988
    template<class M>
sl@0
  1989
    typename banded_adaptor<M>::const_value_type banded_adaptor<M>::zero_ = value_type/*zero*/();
sl@0
  1990
sl@0
  1991
    // Diagonal matrix adaptor class
sl@0
  1992
    template<class M>
sl@0
  1993
    class diagonal_adaptor:
sl@0
  1994
        public banded_adaptor<M> {
sl@0
  1995
    public:
sl@0
  1996
        typedef M matrix_type;
sl@0
  1997
        typedef banded_adaptor<M> adaptor_type;
sl@0
  1998
sl@0
  1999
        // Construction and destruction
sl@0
  2000
        BOOST_UBLAS_INLINE
sl@0
  2001
        diagonal_adaptor ():
sl@0
  2002
            adaptor_type () {}
sl@0
  2003
        BOOST_UBLAS_INLINE
sl@0
  2004
        diagonal_adaptor (matrix_type &data):
sl@0
  2005
            adaptor_type (data) {}
sl@0
  2006
        BOOST_UBLAS_INLINE
sl@0
  2007
        ~diagonal_adaptor () {}
sl@0
  2008
sl@0
  2009
        // Assignment
sl@0
  2010
        BOOST_UBLAS_INLINE
sl@0
  2011
        diagonal_adaptor &operator = (const diagonal_adaptor &m) {
sl@0
  2012
            adaptor_type::operator = (m);
sl@0
  2013
            return *this;
sl@0
  2014
        }
sl@0
  2015
        template<class AE>
sl@0
  2016
        BOOST_UBLAS_INLINE
sl@0
  2017
        diagonal_adaptor &operator = (const matrix_expression<AE> &ae) {
sl@0
  2018
            adaptor_type::operator = (ae);
sl@0
  2019
            return *this;
sl@0
  2020
        }
sl@0
  2021
    };
sl@0
  2022
sl@0
  2023
}}}
sl@0
  2024
sl@0
  2025
#endif