os/ossrv/ossrv_pub/boost_apis/boost/numeric/ublas/matrix.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_MATRIX_
sl@0
    18
#define _BOOST_UBLAS_MATRIX_
sl@0
    19
sl@0
    20
#include <boost/numeric/ublas/vector.hpp>
sl@0
    21
#include <boost/numeric/ublas/matrix_expression.hpp>
sl@0
    22
#include <boost/numeric/ublas/detail/matrix_assign.hpp>
sl@0
    23
sl@0
    24
// Iterators based on ideas of Jeremy Siek
sl@0
    25
sl@0
    26
namespace boost { namespace numeric { namespace ublas {
sl@0
    27
sl@0
    28
    namespace detail {
sl@0
    29
        using namespace boost::numeric::ublas;
sl@0
    30
sl@0
    31
        // Matrix resizing algorithm
sl@0
    32
        template <class L, class M>
sl@0
    33
        BOOST_UBLAS_INLINE
sl@0
    34
        void matrix_resize_preserve (M& m, M& temporary) {
sl@0
    35
            typedef L layout_type;
sl@0
    36
            typedef typename M::size_type size_type;
sl@0
    37
            const size_type msize1 (m.size1 ());        // original size
sl@0
    38
            const size_type msize2 (m.size2 ());
sl@0
    39
            const size_type size1 (temporary.size1 ());    // new size is specified by temporary
sl@0
    40
            const size_type size2 (temporary.size2 ());
sl@0
    41
            // Common elements to preserve
sl@0
    42
            const size_type size1_min = (std::min) (size1, msize1);
sl@0
    43
            const size_type size2_min = (std::min) (size2, msize2);
sl@0
    44
            // Order loop for i-major and j-minor sizes
sl@0
    45
            const size_type i_size = layout_type::size1 (size1_min, size2_min);
sl@0
    46
            const size_type j_size = layout_type::size2 (size1_min, size2_min);
sl@0
    47
            for (size_type i = 0; i != i_size; ++i) {    // indexing copy over major
sl@0
    48
                for (size_type j = 0; j != j_size; ++j) {
sl@0
    49
                    const size_type element1 = layout_type::element1(i,i_size, j,j_size);
sl@0
    50
                    const size_type element2 = layout_type::element2(i,i_size, j,j_size);
sl@0
    51
                    temporary.data () [layout_type::element (element1, size1, element2, size2)] =
sl@0
    52
                            m.data() [layout_type::element (element1, msize1, element2, msize2)];
sl@0
    53
                }
sl@0
    54
            }
sl@0
    55
            m.assign_temporary (temporary);
sl@0
    56
        }
sl@0
    57
    }
sl@0
    58
sl@0
    59
sl@0
    60
    // Array based matrix class
sl@0
    61
    template<class T, class L, class A>
sl@0
    62
    class matrix:
sl@0
    63
        public matrix_container<matrix<T, L, A> > {
sl@0
    64
sl@0
    65
        typedef T *pointer;
sl@0
    66
        typedef L layout_type;
sl@0
    67
        typedef matrix<T, L, A> self_type;
sl@0
    68
    public:
sl@0
    69
#ifdef BOOST_UBLAS_ENABLE_PROXY_SHORTCUTS
sl@0
    70
        using matrix_container<self_type>::operator ();
sl@0
    71
#endif
sl@0
    72
        typedef typename A::size_type size_type;
sl@0
    73
        typedef typename A::difference_type difference_type;
sl@0
    74
        typedef T value_type;
sl@0
    75
        typedef const T &const_reference;
sl@0
    76
        typedef T &reference;
sl@0
    77
        typedef A array_type;
sl@0
    78
        typedef const matrix_reference<const self_type> const_closure_type;
sl@0
    79
        typedef matrix_reference<self_type> closure_type;
sl@0
    80
        typedef vector<T, A> vector_temporary_type;
sl@0
    81
        typedef self_type matrix_temporary_type;
sl@0
    82
        typedef dense_tag storage_category;
sl@0
    83
        // This could be better for performance,
sl@0
    84
        // typedef typename unknown_orientation_tag orientation_category;
sl@0
    85
        // but others depend on the orientation information...
sl@0
    86
        typedef typename L::orientation_category orientation_category;
sl@0
    87
sl@0
    88
        // Construction and destruction
sl@0
    89
        BOOST_UBLAS_INLINE
sl@0
    90
        matrix ():
sl@0
    91
            matrix_container<self_type> (),
sl@0
    92
            size1_ (0), size2_ (0), data_ () {}
sl@0
    93
        BOOST_UBLAS_INLINE
sl@0
    94
        matrix (size_type size1, size_type size2):
sl@0
    95
            matrix_container<self_type> (),
sl@0
    96
            size1_ (size1), size2_ (size2), data_ (layout_type::storage_size (size1, size2)) {
sl@0
    97
        }
sl@0
    98
        BOOST_UBLAS_INLINE
sl@0
    99
        matrix (size_type size1, size_type size2, const array_type &data):
sl@0
   100
            matrix_container<self_type> (),
sl@0
   101
            size1_ (size1), size2_ (size2), data_ (data) {}
sl@0
   102
        BOOST_UBLAS_INLINE
sl@0
   103
        matrix (const matrix &m):
sl@0
   104
            matrix_container<self_type> (),
sl@0
   105
            size1_ (m.size1_), size2_ (m.size2_), data_ (m.data_) {}
sl@0
   106
        template<class AE>
sl@0
   107
        BOOST_UBLAS_INLINE
sl@0
   108
        matrix (const matrix_expression<AE> &ae):
sl@0
   109
            matrix_container<self_type> (),
sl@0
   110
            size1_ (ae ().size1 ()), size2_ (ae ().size2 ()), data_ (layout_type::storage_size (size1_, size2_)) {
sl@0
   111
            matrix_assign<scalar_assign> (*this, ae);
sl@0
   112
        }
sl@0
   113
sl@0
   114
        // Accessors
sl@0
   115
        BOOST_UBLAS_INLINE
sl@0
   116
        size_type size1 () const {
sl@0
   117
            return size1_;
sl@0
   118
        }
sl@0
   119
        BOOST_UBLAS_INLINE
sl@0
   120
        size_type size2 () const {
sl@0
   121
            return size2_;
sl@0
   122
        }
sl@0
   123
sl@0
   124
        // Storage accessors
sl@0
   125
        BOOST_UBLAS_INLINE
sl@0
   126
        const array_type &data () const {
sl@0
   127
            return data_;
sl@0
   128
        }
sl@0
   129
        BOOST_UBLAS_INLINE
sl@0
   130
        array_type &data () {
sl@0
   131
            return data_;
sl@0
   132
        }
sl@0
   133
sl@0
   134
        // Resizing
sl@0
   135
        BOOST_UBLAS_INLINE
sl@0
   136
        void resize (size_type size1, size_type size2, bool preserve = true) {
sl@0
   137
            if (preserve) {
sl@0
   138
                self_type temporary (size1, size2);
sl@0
   139
                detail::matrix_resize_preserve<layout_type> (*this, temporary);
sl@0
   140
            }
sl@0
   141
            else {
sl@0
   142
                data ().resize (layout_type::storage_size (size1, size2));
sl@0
   143
                size1_ = size1;
sl@0
   144
                size2_ = size2;
sl@0
   145
            }
sl@0
   146
        }
sl@0
   147
sl@0
   148
        // Element access
sl@0
   149
        BOOST_UBLAS_INLINE
sl@0
   150
        const_reference operator () (size_type i, size_type j) const {
sl@0
   151
            return data () [layout_type::element (i, size1_, j, size2_)];
sl@0
   152
        }
sl@0
   153
        BOOST_UBLAS_INLINE
sl@0
   154
        reference at_element (size_type i, size_type j) {
sl@0
   155
            return data () [layout_type::element (i, size1_, j, size2_)];
sl@0
   156
        }
sl@0
   157
        BOOST_UBLAS_INLINE
sl@0
   158
        reference operator () (size_type i, size_type j) {
sl@0
   159
            return at_element (i, j);
sl@0
   160
        }
sl@0
   161
sl@0
   162
        // Element assignment
sl@0
   163
        BOOST_UBLAS_INLINE
sl@0
   164
        reference insert_element (size_type i, size_type j, const_reference t) {
sl@0
   165
            return (at_element (i, j) = t);
sl@0
   166
        }
sl@0
   167
        void erase_element (size_type i, size_type j) {
sl@0
   168
            at_element (i, j) = value_type/*zero*/();
sl@0
   169
        }
sl@0
   170
sl@0
   171
        // Zeroing
sl@0
   172
        BOOST_UBLAS_INLINE
sl@0
   173
        void clear () {
sl@0
   174
            std::fill (data ().begin (), data ().end (), value_type/*zero*/());
sl@0
   175
        }
sl@0
   176
sl@0
   177
        // Assignment
sl@0
   178
        BOOST_UBLAS_INLINE
sl@0
   179
        matrix &operator = (const matrix &m) {
sl@0
   180
            size1_ = m.size1_;
sl@0
   181
            size2_ = m.size2_;
sl@0
   182
            data () = m.data ();
sl@0
   183
            return *this;
sl@0
   184
        }
sl@0
   185
        template<class C>          // Container assignment without temporary
sl@0
   186
        BOOST_UBLAS_INLINE
sl@0
   187
        matrix &operator = (const matrix_container<C> &m) {
sl@0
   188
            resize (m ().size1 (), m ().size2 (), false);
sl@0
   189
            assign (m);
sl@0
   190
            return *this;
sl@0
   191
        }
sl@0
   192
        BOOST_UBLAS_INLINE
sl@0
   193
        matrix &assign_temporary (matrix &m) {
sl@0
   194
            swap (m);
sl@0
   195
            return *this;
sl@0
   196
        }
sl@0
   197
        template<class AE>
sl@0
   198
        BOOST_UBLAS_INLINE
sl@0
   199
        matrix &operator = (const matrix_expression<AE> &ae) {
sl@0
   200
            self_type temporary (ae);
sl@0
   201
            return assign_temporary (temporary);
sl@0
   202
        }
sl@0
   203
        template<class AE>
sl@0
   204
        BOOST_UBLAS_INLINE
sl@0
   205
        matrix &assign (const matrix_expression<AE> &ae) {
sl@0
   206
            matrix_assign<scalar_assign> (*this, ae);
sl@0
   207
            return *this;
sl@0
   208
        }
sl@0
   209
        template<class AE>
sl@0
   210
        BOOST_UBLAS_INLINE
sl@0
   211
        matrix& operator += (const matrix_expression<AE> &ae) {
sl@0
   212
            self_type temporary (*this + ae);
sl@0
   213
            return assign_temporary (temporary);
sl@0
   214
        }
sl@0
   215
        template<class C>          // Container assignment without temporary
sl@0
   216
        BOOST_UBLAS_INLINE
sl@0
   217
        matrix &operator += (const matrix_container<C> &m) {
sl@0
   218
            plus_assign (m);
sl@0
   219
            return *this;
sl@0
   220
        }
sl@0
   221
        template<class AE>
sl@0
   222
        BOOST_UBLAS_INLINE
sl@0
   223
        matrix &plus_assign (const matrix_expression<AE> &ae) {
sl@0
   224
            matrix_assign<scalar_plus_assign> (*this, ae);
sl@0
   225
            return *this;
sl@0
   226
        }
sl@0
   227
        template<class AE>
sl@0
   228
        BOOST_UBLAS_INLINE
sl@0
   229
        matrix& operator -= (const matrix_expression<AE> &ae) {
sl@0
   230
            self_type temporary (*this - ae);
sl@0
   231
            return assign_temporary (temporary);
sl@0
   232
        }
sl@0
   233
        template<class C>          // Container assignment without temporary
sl@0
   234
        BOOST_UBLAS_INLINE
sl@0
   235
        matrix &operator -= (const matrix_container<C> &m) {
sl@0
   236
            minus_assign (m);
sl@0
   237
            return *this;
sl@0
   238
        }
sl@0
   239
        template<class AE>
sl@0
   240
        BOOST_UBLAS_INLINE
sl@0
   241
        matrix &minus_assign (const matrix_expression<AE> &ae) {
sl@0
   242
            matrix_assign<scalar_minus_assign> (*this, ae);
sl@0
   243
            return *this;
sl@0
   244
        }
sl@0
   245
        template<class AT>
sl@0
   246
        BOOST_UBLAS_INLINE
sl@0
   247
        matrix& operator *= (const AT &at) {
sl@0
   248
            matrix_assign_scalar<scalar_multiplies_assign> (*this, at);
sl@0
   249
            return *this;
sl@0
   250
        }
sl@0
   251
        template<class AT>
sl@0
   252
        BOOST_UBLAS_INLINE
sl@0
   253
        matrix& operator /= (const AT &at) {
sl@0
   254
            matrix_assign_scalar<scalar_divides_assign> (*this, at);
sl@0
   255
            return *this;
sl@0
   256
        }
sl@0
   257
sl@0
   258
        // Swapping
sl@0
   259
        BOOST_UBLAS_INLINE
sl@0
   260
        void swap (matrix &m) {
sl@0
   261
            if (this != &m) {
sl@0
   262
                std::swap (size1_, m.size1_);
sl@0
   263
                std::swap (size2_, m.size2_);
sl@0
   264
                data ().swap (m.data ());
sl@0
   265
            }
sl@0
   266
        }
sl@0
   267
        BOOST_UBLAS_INLINE
sl@0
   268
        friend void swap (matrix &m1, matrix &m2) {
sl@0
   269
            m1.swap (m2);
sl@0
   270
        }
sl@0
   271
sl@0
   272
        // Iterator types
sl@0
   273
    private:
sl@0
   274
        // Use the storage array iterator
sl@0
   275
        typedef typename A::const_iterator const_subiterator_type;
sl@0
   276
        typedef typename A::iterator subiterator_type;
sl@0
   277
sl@0
   278
    public:
sl@0
   279
#ifdef BOOST_UBLAS_USE_INDEXED_ITERATOR
sl@0
   280
        typedef indexed_iterator1<self_type, dense_random_access_iterator_tag> iterator1;
sl@0
   281
        typedef indexed_iterator2<self_type, dense_random_access_iterator_tag> iterator2;
sl@0
   282
        typedef indexed_const_iterator1<self_type, dense_random_access_iterator_tag> const_iterator1;
sl@0
   283
        typedef indexed_const_iterator2<self_type, dense_random_access_iterator_tag> const_iterator2;
sl@0
   284
#else
sl@0
   285
        class const_iterator1;
sl@0
   286
        class iterator1;
sl@0
   287
        class const_iterator2;
sl@0
   288
        class iterator2;
sl@0
   289
#endif
sl@0
   290
        typedef reverse_iterator_base1<const_iterator1> const_reverse_iterator1;
sl@0
   291
        typedef reverse_iterator_base1<iterator1> reverse_iterator1;
sl@0
   292
        typedef reverse_iterator_base2<const_iterator2> const_reverse_iterator2;
sl@0
   293
        typedef reverse_iterator_base2<iterator2> reverse_iterator2;
sl@0
   294
sl@0
   295
        // Element lookup
sl@0
   296
        BOOST_UBLAS_INLINE
sl@0
   297
        const_iterator1 find1 (int /* rank */, size_type i, size_type j) const {
sl@0
   298
#ifdef BOOST_UBLAS_USE_INDEXED_ITERATOR
sl@0
   299
            return const_iterator1 (*this, i, j);
sl@0
   300
#else
sl@0
   301
            return const_iterator1 (*this, data ().begin () + layout_type::address (i, size1_, j, size2_));
sl@0
   302
#endif
sl@0
   303
        }
sl@0
   304
        BOOST_UBLAS_INLINE
sl@0
   305
        iterator1 find1 (int /* rank */, size_type i, size_type j) {
sl@0
   306
#ifdef BOOST_UBLAS_USE_INDEXED_ITERATOR
sl@0
   307
            return iterator1 (*this, i, j);
sl@0
   308
#else
sl@0
   309
            return iterator1 (*this, data ().begin () + layout_type::address (i, size1_, j, size2_));
sl@0
   310
#endif
sl@0
   311
        }
sl@0
   312
        BOOST_UBLAS_INLINE
sl@0
   313
        const_iterator2 find2 (int /* rank */, size_type i, size_type j) const {
sl@0
   314
#ifdef BOOST_UBLAS_USE_INDEXED_ITERATOR
sl@0
   315
            return const_iterator2 (*this, i, j);
sl@0
   316
#else
sl@0
   317
            return const_iterator2 (*this, data ().begin () + layout_type::address (i, size1_, j, size2_));
sl@0
   318
#endif
sl@0
   319
        }
sl@0
   320
        BOOST_UBLAS_INLINE
sl@0
   321
        iterator2 find2 (int /* rank */, size_type i, size_type j) {
sl@0
   322
#ifdef BOOST_UBLAS_USE_INDEXED_ITERATOR
sl@0
   323
            return iterator2 (*this, i, j);
sl@0
   324
#else
sl@0
   325
            return iterator2 (*this, data ().begin () + layout_type::address (i, size1_, j, size2_));
sl@0
   326
#endif
sl@0
   327
        }
sl@0
   328
sl@0
   329
sl@0
   330
#ifndef BOOST_UBLAS_USE_INDEXED_ITERATOR
sl@0
   331
        class const_iterator1:
sl@0
   332
            public container_const_reference<matrix>,
sl@0
   333
            public random_access_iterator_base<dense_random_access_iterator_tag,
sl@0
   334
                                               const_iterator1, value_type> {
sl@0
   335
        public:
sl@0
   336
            typedef typename matrix::value_type value_type;
sl@0
   337
            typedef typename matrix::difference_type difference_type;
sl@0
   338
            typedef typename matrix::const_reference reference;
sl@0
   339
            typedef const typename matrix::pointer pointer;
sl@0
   340
sl@0
   341
            typedef const_iterator2 dual_iterator_type;
sl@0
   342
            typedef const_reverse_iterator2 dual_reverse_iterator_type;
sl@0
   343
sl@0
   344
            // Construction and destruction
sl@0
   345
            BOOST_UBLAS_INLINE
sl@0
   346
            const_iterator1 ():
sl@0
   347
                container_const_reference<self_type> (), it_ () {}
sl@0
   348
            BOOST_UBLAS_INLINE
sl@0
   349
            const_iterator1 (const self_type &m, const const_subiterator_type &it):
sl@0
   350
                container_const_reference<self_type> (m), it_ (it) {}
sl@0
   351
            BOOST_UBLAS_INLINE
sl@0
   352
            const_iterator1 (const iterator1 &it):
sl@0
   353
                container_const_reference<self_type> (it ()), it_ (it.it_) {}
sl@0
   354
sl@0
   355
            // Arithmetic
sl@0
   356
            BOOST_UBLAS_INLINE
sl@0
   357
            const_iterator1 &operator ++ () {
sl@0
   358
                layout_type::increment1 (it_, (*this) ().size1 (), (*this) ().size2 ());
sl@0
   359
                return *this;
sl@0
   360
            }
sl@0
   361
            BOOST_UBLAS_INLINE
sl@0
   362
            const_iterator1 &operator -- () {
sl@0
   363
                layout_type::decrement1 (it_, (*this) ().size1 (), (*this) ().size2 ());
sl@0
   364
                return *this;
sl@0
   365
            }
sl@0
   366
            BOOST_UBLAS_INLINE
sl@0
   367
            const_iterator1 &operator += (difference_type n) {
sl@0
   368
                it_ += n * layout_type::one1 ((*this) ().size1 (), (*this) ().size2 ());
sl@0
   369
                return *this;
sl@0
   370
            }
sl@0
   371
            BOOST_UBLAS_INLINE
sl@0
   372
            const_iterator1 &operator -= (difference_type n) {
sl@0
   373
                it_ -= n * layout_type::one1 ((*this) ().size1 (), (*this) ().size2 ());
sl@0
   374
                return *this;
sl@0
   375
            }
sl@0
   376
            BOOST_UBLAS_INLINE
sl@0
   377
            difference_type operator - (const const_iterator1 &it) const {
sl@0
   378
                BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
sl@0
   379
                return layout_type::distance1 (it_ - it.it_, (*this) ().size1 (), (*this) ().size2 ());
sl@0
   380
            }
sl@0
   381
sl@0
   382
            // Dereference
sl@0
   383
            BOOST_UBLAS_INLINE
sl@0
   384
            const_reference operator * () const {
sl@0
   385
                BOOST_UBLAS_CHECK (index1 () < (*this) ().size1 (), bad_index ());
sl@0
   386
                BOOST_UBLAS_CHECK (index2 () < (*this) ().size2 (), bad_index ());
sl@0
   387
                return *it_;
sl@0
   388
            }
sl@0
   389
            BOOST_UBLAS_INLINE
sl@0
   390
            const_reference operator [] (difference_type n) const {
sl@0
   391
                return *(*this + n);
sl@0
   392
            }
sl@0
   393
sl@0
   394
#ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
sl@0
   395
            BOOST_UBLAS_INLINE
sl@0
   396
#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
sl@0
   397
            typename self_type::
sl@0
   398
#endif
sl@0
   399
            const_iterator2 begin () const {
sl@0
   400
                const self_type &m = (*this) ();
sl@0
   401
                return m.find2 (1, index1 (), 0);
sl@0
   402
            }
sl@0
   403
            BOOST_UBLAS_INLINE
sl@0
   404
#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
sl@0
   405
            typename self_type::
sl@0
   406
#endif
sl@0
   407
            const_iterator2 end () const {
sl@0
   408
                const self_type &m = (*this) ();
sl@0
   409
                return m.find2 (1, index1 (), m.size2 ());
sl@0
   410
            }
sl@0
   411
            BOOST_UBLAS_INLINE
sl@0
   412
#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
sl@0
   413
            typename self_type::
sl@0
   414
#endif
sl@0
   415
            const_reverse_iterator2 rbegin () const {
sl@0
   416
                return const_reverse_iterator2 (end ());
sl@0
   417
            }
sl@0
   418
            BOOST_UBLAS_INLINE
sl@0
   419
#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
sl@0
   420
            typename self_type::
sl@0
   421
#endif
sl@0
   422
            const_reverse_iterator2 rend () const {
sl@0
   423
                return const_reverse_iterator2 (begin ());
sl@0
   424
            }
sl@0
   425
#endif
sl@0
   426
sl@0
   427
            // Indices
sl@0
   428
            BOOST_UBLAS_INLINE
sl@0
   429
            size_type index1 () const {
sl@0
   430
                const self_type &m = (*this) ();
sl@0
   431
                return layout_type::index1 (it_ - m.begin1 ().it_, m.size1 (), m.size2 ());
sl@0
   432
            }
sl@0
   433
            BOOST_UBLAS_INLINE
sl@0
   434
            size_type index2 () const {
sl@0
   435
                const self_type &m = (*this) ();
sl@0
   436
                return layout_type::index2 (it_ - m.begin1 ().it_, m.size1 (), m.size2 ());
sl@0
   437
            }
sl@0
   438
sl@0
   439
            // Assignment
sl@0
   440
            BOOST_UBLAS_INLINE
sl@0
   441
            const_iterator1 &operator = (const const_iterator1 &it) {
sl@0
   442
                container_const_reference<self_type>::assign (&it ());
sl@0
   443
                it_ = it.it_;
sl@0
   444
                return *this;
sl@0
   445
            }
sl@0
   446
sl@0
   447
            // Comparison
sl@0
   448
            BOOST_UBLAS_INLINE
sl@0
   449
            bool operator == (const const_iterator1 &it) const {
sl@0
   450
                BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
sl@0
   451
                return it_ == it.it_;
sl@0
   452
            }
sl@0
   453
            BOOST_UBLAS_INLINE
sl@0
   454
            bool operator < (const const_iterator1 &it) const {
sl@0
   455
                BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
sl@0
   456
                return it_ < it.it_;
sl@0
   457
            }
sl@0
   458
sl@0
   459
        private:
sl@0
   460
            const_subiterator_type it_;
sl@0
   461
sl@0
   462
            friend class iterator1;
sl@0
   463
        };
sl@0
   464
#endif
sl@0
   465
sl@0
   466
        BOOST_UBLAS_INLINE
sl@0
   467
        const_iterator1 begin1 () const {
sl@0
   468
            return find1 (0, 0, 0);
sl@0
   469
        }
sl@0
   470
        BOOST_UBLAS_INLINE
sl@0
   471
        const_iterator1 end1 () const {
sl@0
   472
            return find1 (0, size1_, 0);
sl@0
   473
        }
sl@0
   474
sl@0
   475
#ifndef BOOST_UBLAS_USE_INDEXED_ITERATOR
sl@0
   476
        class iterator1:
sl@0
   477
            public container_reference<matrix>,
sl@0
   478
            public random_access_iterator_base<dense_random_access_iterator_tag,
sl@0
   479
                                               iterator1, value_type> {
sl@0
   480
        public:
sl@0
   481
            typedef typename matrix::value_type value_type;
sl@0
   482
            typedef typename matrix::difference_type difference_type;
sl@0
   483
            typedef typename matrix::reference reference;
sl@0
   484
            typedef typename matrix::pointer pointer;
sl@0
   485
sl@0
   486
            typedef iterator2 dual_iterator_type;
sl@0
   487
            typedef reverse_iterator2 dual_reverse_iterator_type;
sl@0
   488
sl@0
   489
            // Construction and destruction
sl@0
   490
            BOOST_UBLAS_INLINE
sl@0
   491
            iterator1 ():
sl@0
   492
                container_reference<self_type> (), it_ () {}
sl@0
   493
            BOOST_UBLAS_INLINE
sl@0
   494
            iterator1 (self_type &m, const subiterator_type &it):
sl@0
   495
                container_reference<self_type> (m), it_ (it) {}
sl@0
   496
sl@0
   497
            // Arithmetic
sl@0
   498
            BOOST_UBLAS_INLINE
sl@0
   499
            iterator1 &operator ++ () {
sl@0
   500
                layout_type::increment1 (it_, (*this) ().size1 (), (*this) ().size2 ());
sl@0
   501
                return *this;
sl@0
   502
            }
sl@0
   503
            BOOST_UBLAS_INLINE
sl@0
   504
            iterator1 &operator -- () {
sl@0
   505
                layout_type::decrement1 (it_, (*this) ().size1 (), (*this) ().size2 ());
sl@0
   506
                return *this;
sl@0
   507
            }
sl@0
   508
            BOOST_UBLAS_INLINE
sl@0
   509
            iterator1 &operator += (difference_type n) {
sl@0
   510
                it_ += n * layout_type::one1 ((*this) ().size1 (), (*this) ().size2 ());
sl@0
   511
                return *this;
sl@0
   512
            }
sl@0
   513
            BOOST_UBLAS_INLINE
sl@0
   514
            iterator1 &operator -= (difference_type n) {
sl@0
   515
                it_ -= n * layout_type::one1 ((*this) ().size1 (), (*this) ().size2 ());
sl@0
   516
                return *this;
sl@0
   517
            }
sl@0
   518
            BOOST_UBLAS_INLINE
sl@0
   519
            difference_type operator - (const iterator1 &it) const {
sl@0
   520
                BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
sl@0
   521
                return layout_type::distance1 (it_ - it.it_, (*this) ().size1 (), (*this) ().size2 ());
sl@0
   522
            }
sl@0
   523
sl@0
   524
            // Dereference
sl@0
   525
            BOOST_UBLAS_INLINE
sl@0
   526
            reference operator * () const {
sl@0
   527
                BOOST_UBLAS_CHECK (index1 () < (*this) ().size1 (), bad_index ());
sl@0
   528
                BOOST_UBLAS_CHECK (index2 () < (*this) ().size2 (), bad_index ());
sl@0
   529
                return *it_;
sl@0
   530
            }
sl@0
   531
            BOOST_UBLAS_INLINE
sl@0
   532
            reference operator [] (difference_type n) const {
sl@0
   533
                return *(*this + n);
sl@0
   534
            }
sl@0
   535
sl@0
   536
#ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
sl@0
   537
            BOOST_UBLAS_INLINE
sl@0
   538
#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
sl@0
   539
            typename self_type::
sl@0
   540
#endif
sl@0
   541
            iterator2 begin () const {
sl@0
   542
                self_type &m = (*this) ();
sl@0
   543
                return m.find2 (1, index1 (), 0);
sl@0
   544
            }
sl@0
   545
            BOOST_UBLAS_INLINE
sl@0
   546
#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
sl@0
   547
            typename self_type::
sl@0
   548
#endif
sl@0
   549
            iterator2 end () const {
sl@0
   550
                self_type &m = (*this) ();
sl@0
   551
                return m.find2 (1, index1 (), m.size2 ());
sl@0
   552
            }
sl@0
   553
            BOOST_UBLAS_INLINE
sl@0
   554
#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
sl@0
   555
            typename self_type::
sl@0
   556
#endif
sl@0
   557
            reverse_iterator2 rbegin () const {
sl@0
   558
                return reverse_iterator2 (end ());
sl@0
   559
            }
sl@0
   560
            BOOST_UBLAS_INLINE
sl@0
   561
#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
sl@0
   562
            typename self_type::
sl@0
   563
#endif
sl@0
   564
            reverse_iterator2 rend () const {
sl@0
   565
                return reverse_iterator2 (begin ());
sl@0
   566
            }
sl@0
   567
#endif
sl@0
   568
sl@0
   569
            // Indices
sl@0
   570
            BOOST_UBLAS_INLINE
sl@0
   571
            size_type index1 () const {
sl@0
   572
                self_type &m = (*this) ();
sl@0
   573
                return layout_type::index1 (it_ - m.begin1 ().it_, m.size1 (), m.size2 ());
sl@0
   574
            }
sl@0
   575
            BOOST_UBLAS_INLINE
sl@0
   576
            size_type index2 () const {
sl@0
   577
                self_type &m = (*this) ();
sl@0
   578
                return layout_type::index2 (it_ - m.begin1 ().it_, m.size1 (), m.size2 ());
sl@0
   579
            }
sl@0
   580
sl@0
   581
            // Assignment
sl@0
   582
            BOOST_UBLAS_INLINE
sl@0
   583
            iterator1 &operator = (const iterator1 &it) {
sl@0
   584
                container_reference<self_type>::assign (&it ());
sl@0
   585
                it_ = it.it_;
sl@0
   586
                return *this;
sl@0
   587
            }
sl@0
   588
sl@0
   589
            // Comparison
sl@0
   590
            BOOST_UBLAS_INLINE
sl@0
   591
            bool operator == (const iterator1 &it) const {
sl@0
   592
                BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
sl@0
   593
                return it_ == it.it_;
sl@0
   594
            }
sl@0
   595
            BOOST_UBLAS_INLINE
sl@0
   596
            bool operator < (const iterator1 &it) const {
sl@0
   597
                BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
sl@0
   598
                return it_ < it.it_;
sl@0
   599
            }
sl@0
   600
sl@0
   601
        private:
sl@0
   602
            subiterator_type it_;
sl@0
   603
sl@0
   604
            friend class const_iterator1;
sl@0
   605
        };
sl@0
   606
#endif
sl@0
   607
sl@0
   608
        BOOST_UBLAS_INLINE
sl@0
   609
        iterator1 begin1 () {
sl@0
   610
            return find1 (0, 0, 0);
sl@0
   611
        }
sl@0
   612
        BOOST_UBLAS_INLINE
sl@0
   613
        iterator1 end1 () {
sl@0
   614
            return find1 (0, size1_, 0);
sl@0
   615
        }
sl@0
   616
sl@0
   617
#ifndef BOOST_UBLAS_USE_INDEXED_ITERATOR
sl@0
   618
        class const_iterator2:
sl@0
   619
            public container_const_reference<matrix>,
sl@0
   620
            public random_access_iterator_base<dense_random_access_iterator_tag,
sl@0
   621
                                               const_iterator2, value_type> {
sl@0
   622
        public:
sl@0
   623
            typedef typename matrix::value_type value_type;
sl@0
   624
            typedef typename matrix::difference_type difference_type;
sl@0
   625
            typedef typename matrix::const_reference reference;
sl@0
   626
            typedef const typename matrix::pointer pointer;
sl@0
   627
sl@0
   628
            typedef const_iterator1 dual_iterator_type;
sl@0
   629
            typedef const_reverse_iterator1 dual_reverse_iterator_type;
sl@0
   630
sl@0
   631
            // Construction and destruction
sl@0
   632
            BOOST_UBLAS_INLINE
sl@0
   633
            const_iterator2 ():
sl@0
   634
                container_const_reference<self_type> (), it_ () {}
sl@0
   635
            BOOST_UBLAS_INLINE
sl@0
   636
            const_iterator2 (const self_type &m, const const_subiterator_type &it):
sl@0
   637
                container_const_reference<self_type> (m), it_ (it) {}
sl@0
   638
            BOOST_UBLAS_INLINE
sl@0
   639
            const_iterator2 (const iterator2 &it):
sl@0
   640
                container_const_reference<self_type> (it ()), it_ (it.it_) {}
sl@0
   641
sl@0
   642
            // Arithmetic
sl@0
   643
            BOOST_UBLAS_INLINE
sl@0
   644
            const_iterator2 &operator ++ () {
sl@0
   645
                layout_type::increment2 (it_, (*this) ().size1 (), (*this) ().size2 ());
sl@0
   646
                return *this;
sl@0
   647
            }
sl@0
   648
            BOOST_UBLAS_INLINE
sl@0
   649
            const_iterator2 &operator -- () {
sl@0
   650
                layout_type::decrement2 (it_, (*this) ().size1 (), (*this) ().size2 ());
sl@0
   651
                return *this;
sl@0
   652
            }
sl@0
   653
            BOOST_UBLAS_INLINE
sl@0
   654
            const_iterator2 &operator += (difference_type n) {
sl@0
   655
                it_ += n * layout_type::one2 ((*this) ().size1 (), (*this) ().size2 ());
sl@0
   656
                return *this;
sl@0
   657
            }
sl@0
   658
            BOOST_UBLAS_INLINE
sl@0
   659
            const_iterator2 &operator -= (difference_type n) {
sl@0
   660
                it_ -= n * layout_type::one2 ((*this) ().size1 (), (*this) ().size2 ());
sl@0
   661
                return *this;
sl@0
   662
            }
sl@0
   663
            BOOST_UBLAS_INLINE
sl@0
   664
            difference_type operator - (const const_iterator2 &it) const {
sl@0
   665
                BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
sl@0
   666
                return layout_type::distance2 (it_ - it.it_, (*this) ().size1 (), (*this) ().size2 ());
sl@0
   667
            }
sl@0
   668
sl@0
   669
            // Dereference
sl@0
   670
            BOOST_UBLAS_INLINE
sl@0
   671
            const_reference operator * () const {
sl@0
   672
                BOOST_UBLAS_CHECK (index1 () < (*this) ().size1 (), bad_index ());
sl@0
   673
                BOOST_UBLAS_CHECK (index2 () < (*this) ().size2 (), bad_index ());
sl@0
   674
                return *it_;
sl@0
   675
            }
sl@0
   676
            BOOST_UBLAS_INLINE
sl@0
   677
            const_reference operator [] (difference_type n) const {
sl@0
   678
                return *(*this + n);
sl@0
   679
            }
sl@0
   680
sl@0
   681
#ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
sl@0
   682
            BOOST_UBLAS_INLINE
sl@0
   683
#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
sl@0
   684
            typename self_type::
sl@0
   685
#endif
sl@0
   686
            const_iterator1 begin () const {
sl@0
   687
                const self_type &m = (*this) ();
sl@0
   688
                return m.find1 (1, 0, index2 ());
sl@0
   689
            }
sl@0
   690
            BOOST_UBLAS_INLINE
sl@0
   691
#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
sl@0
   692
            typename self_type::
sl@0
   693
#endif
sl@0
   694
            const_iterator1 end () const {
sl@0
   695
                const self_type &m = (*this) ();
sl@0
   696
                return m.find1 (1, m.size1 (), index2 ());
sl@0
   697
            }
sl@0
   698
            BOOST_UBLAS_INLINE
sl@0
   699
#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
sl@0
   700
            typename self_type::
sl@0
   701
#endif
sl@0
   702
            const_reverse_iterator1 rbegin () const {
sl@0
   703
                return const_reverse_iterator1 (end ());
sl@0
   704
            }
sl@0
   705
            BOOST_UBLAS_INLINE
sl@0
   706
#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
sl@0
   707
            typename self_type::
sl@0
   708
#endif
sl@0
   709
            const_reverse_iterator1 rend () const {
sl@0
   710
                return const_reverse_iterator1 (begin ());
sl@0
   711
            }
sl@0
   712
#endif
sl@0
   713
sl@0
   714
            // Indices
sl@0
   715
            BOOST_UBLAS_INLINE
sl@0
   716
            size_type index1 () const {
sl@0
   717
                const self_type &m = (*this) ();
sl@0
   718
                return layout_type::index1 (it_ - m.begin2 ().it_, m.size1 (), m.size2 ());
sl@0
   719
            }
sl@0
   720
            BOOST_UBLAS_INLINE
sl@0
   721
            size_type index2 () const {
sl@0
   722
                const self_type &m = (*this) ();
sl@0
   723
                return layout_type::index2 (it_ - m.begin2 ().it_, m.size1 (), m.size2 ());
sl@0
   724
            }
sl@0
   725
sl@0
   726
            // Assignment
sl@0
   727
            BOOST_UBLAS_INLINE
sl@0
   728
            const_iterator2 &operator = (const const_iterator2 &it) {
sl@0
   729
                container_const_reference<self_type>::assign (&it ());
sl@0
   730
                it_ = it.it_;
sl@0
   731
                return *this;
sl@0
   732
            }
sl@0
   733
sl@0
   734
            // Comparison
sl@0
   735
            BOOST_UBLAS_INLINE
sl@0
   736
            bool operator == (const const_iterator2 &it) const {
sl@0
   737
                BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
sl@0
   738
                return it_ == it.it_;
sl@0
   739
            }
sl@0
   740
            BOOST_UBLAS_INLINE
sl@0
   741
            bool operator < (const const_iterator2 &it) const {
sl@0
   742
                BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
sl@0
   743
                return it_ < it.it_;
sl@0
   744
            }
sl@0
   745
sl@0
   746
        private:
sl@0
   747
            const_subiterator_type it_;
sl@0
   748
sl@0
   749
            friend class iterator2;
sl@0
   750
        };
sl@0
   751
#endif
sl@0
   752
sl@0
   753
        BOOST_UBLAS_INLINE
sl@0
   754
        const_iterator2 begin2 () const {
sl@0
   755
            return find2 (0, 0, 0);
sl@0
   756
        }
sl@0
   757
        BOOST_UBLAS_INLINE
sl@0
   758
        const_iterator2 end2 () const {
sl@0
   759
            return find2 (0, 0, size2_);
sl@0
   760
        }
sl@0
   761
sl@0
   762
#ifndef BOOST_UBLAS_USE_INDEXED_ITERATOR
sl@0
   763
        class iterator2:
sl@0
   764
            public container_reference<matrix>,
sl@0
   765
            public random_access_iterator_base<dense_random_access_iterator_tag,
sl@0
   766
                                               iterator2, value_type> {
sl@0
   767
        public:
sl@0
   768
            typedef typename matrix::value_type value_type;
sl@0
   769
            typedef typename matrix::difference_type difference_type;
sl@0
   770
            typedef typename matrix::reference reference;
sl@0
   771
            typedef typename matrix::pointer pointer;
sl@0
   772
sl@0
   773
            typedef iterator1 dual_iterator_type;
sl@0
   774
            typedef reverse_iterator1 dual_reverse_iterator_type;
sl@0
   775
sl@0
   776
            // Construction and destruction
sl@0
   777
            BOOST_UBLAS_INLINE
sl@0
   778
            iterator2 ():
sl@0
   779
                container_reference<self_type> (), it_ () {}
sl@0
   780
            BOOST_UBLAS_INLINE
sl@0
   781
            iterator2 (self_type &m, const subiterator_type &it):
sl@0
   782
                container_reference<self_type> (m), it_ (it) {}
sl@0
   783
sl@0
   784
            // Arithmetic
sl@0
   785
            BOOST_UBLAS_INLINE
sl@0
   786
            iterator2 &operator ++ () {
sl@0
   787
                layout_type::increment2 (it_, (*this) ().size1 (), (*this) ().size2 ());
sl@0
   788
                return *this;
sl@0
   789
            }
sl@0
   790
            BOOST_UBLAS_INLINE
sl@0
   791
            iterator2 &operator -- () {
sl@0
   792
                layout_type::decrement2 (it_, (*this) ().size1 (), (*this) ().size2 ());
sl@0
   793
                return *this;
sl@0
   794
            }
sl@0
   795
            BOOST_UBLAS_INLINE
sl@0
   796
            iterator2 &operator += (difference_type n) {
sl@0
   797
                it_ += n * layout_type::one2 ((*this) ().size1 (), (*this) ().size2 ());
sl@0
   798
                return *this;
sl@0
   799
            }
sl@0
   800
            BOOST_UBLAS_INLINE
sl@0
   801
            iterator2 &operator -= (difference_type n) {
sl@0
   802
                it_ -= n * layout_type::one2 ((*this) ().size1 (), (*this) ().size2 ());
sl@0
   803
                return *this;
sl@0
   804
            }
sl@0
   805
            BOOST_UBLAS_INLINE
sl@0
   806
            difference_type operator - (const iterator2 &it) const {
sl@0
   807
                BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
sl@0
   808
                return layout_type::distance2 (it_ - it.it_, (*this) ().size1 (), (*this) ().size2 ());
sl@0
   809
            }
sl@0
   810
sl@0
   811
            // Dereference
sl@0
   812
            BOOST_UBLAS_INLINE
sl@0
   813
            reference operator * () const {
sl@0
   814
                BOOST_UBLAS_CHECK (index1 () < (*this) ().size1 (), bad_index ());
sl@0
   815
                BOOST_UBLAS_CHECK (index2 () < (*this) ().size2 (), bad_index ());
sl@0
   816
                return *it_;
sl@0
   817
            }
sl@0
   818
            BOOST_UBLAS_INLINE
sl@0
   819
            reference operator [] (difference_type n) const {
sl@0
   820
                return *(*this + n);
sl@0
   821
            }
sl@0
   822
sl@0
   823
#ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
sl@0
   824
            BOOST_UBLAS_INLINE
sl@0
   825
#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
sl@0
   826
            typename self_type::
sl@0
   827
#endif
sl@0
   828
            iterator1 begin () const {
sl@0
   829
                self_type &m = (*this) ();
sl@0
   830
                return m.find1 (1, 0, index2 ());
sl@0
   831
            }
sl@0
   832
            BOOST_UBLAS_INLINE
sl@0
   833
#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
sl@0
   834
            typename self_type::
sl@0
   835
#endif
sl@0
   836
            iterator1 end () const {
sl@0
   837
                self_type &m = (*this) ();
sl@0
   838
                return m.find1 (1, m.size1 (), index2 ());
sl@0
   839
            }
sl@0
   840
            BOOST_UBLAS_INLINE
sl@0
   841
#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
sl@0
   842
            typename self_type::
sl@0
   843
#endif
sl@0
   844
            reverse_iterator1 rbegin () const {
sl@0
   845
                return reverse_iterator1 (end ());
sl@0
   846
            }
sl@0
   847
            BOOST_UBLAS_INLINE
sl@0
   848
#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
sl@0
   849
            typename self_type::
sl@0
   850
#endif
sl@0
   851
            reverse_iterator1 rend () const {
sl@0
   852
                return reverse_iterator1 (begin ());
sl@0
   853
            }
sl@0
   854
#endif
sl@0
   855
sl@0
   856
            // Indices
sl@0
   857
            BOOST_UBLAS_INLINE
sl@0
   858
            size_type index1 () const {
sl@0
   859
                self_type &m = (*this) ();
sl@0
   860
                return layout_type::index1 (it_ - m.begin2 ().it_, m.size1 (), m.size2 ());
sl@0
   861
            }
sl@0
   862
            BOOST_UBLAS_INLINE
sl@0
   863
            size_type index2 () const {
sl@0
   864
                self_type &m = (*this) ();
sl@0
   865
                return layout_type::index2 (it_ - m.begin2 ().it_, m.size1 (), m.size2 ());
sl@0
   866
            }
sl@0
   867
sl@0
   868
            // Assignment
sl@0
   869
            BOOST_UBLAS_INLINE
sl@0
   870
            iterator2 &operator = (const iterator2 &it) {
sl@0
   871
                container_reference<self_type>::assign (&it ());
sl@0
   872
                it_ = it.it_;
sl@0
   873
                return *this;
sl@0
   874
            }
sl@0
   875
sl@0
   876
            // Comparison
sl@0
   877
            BOOST_UBLAS_INLINE
sl@0
   878
            bool operator == (const iterator2 &it) const {
sl@0
   879
                BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
sl@0
   880
                return it_ == it.it_;
sl@0
   881
            }
sl@0
   882
            BOOST_UBLAS_INLINE
sl@0
   883
            bool operator < (const iterator2 &it) const {
sl@0
   884
                BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
sl@0
   885
                return it_ < it.it_;
sl@0
   886
            }
sl@0
   887
sl@0
   888
        private:
sl@0
   889
            subiterator_type it_;
sl@0
   890
sl@0
   891
            friend class const_iterator2;
sl@0
   892
        };
sl@0
   893
#endif
sl@0
   894
sl@0
   895
        BOOST_UBLAS_INLINE
sl@0
   896
        iterator2 begin2 () {
sl@0
   897
            return find2 (0, 0, 0);
sl@0
   898
        }
sl@0
   899
        BOOST_UBLAS_INLINE
sl@0
   900
        iterator2 end2 () {
sl@0
   901
            return find2 (0, 0, size2_);
sl@0
   902
        }
sl@0
   903
sl@0
   904
        // Reverse iterators
sl@0
   905
sl@0
   906
        BOOST_UBLAS_INLINE
sl@0
   907
        const_reverse_iterator1 rbegin1 () const {
sl@0
   908
            return const_reverse_iterator1 (end1 ());
sl@0
   909
        }
sl@0
   910
        BOOST_UBLAS_INLINE
sl@0
   911
        const_reverse_iterator1 rend1 () const {
sl@0
   912
            return const_reverse_iterator1 (begin1 ());
sl@0
   913
        }
sl@0
   914
sl@0
   915
        BOOST_UBLAS_INLINE
sl@0
   916
        reverse_iterator1 rbegin1 () {
sl@0
   917
            return reverse_iterator1 (end1 ());
sl@0
   918
        }
sl@0
   919
        BOOST_UBLAS_INLINE
sl@0
   920
        reverse_iterator1 rend1 () {
sl@0
   921
            return reverse_iterator1 (begin1 ());
sl@0
   922
        }
sl@0
   923
sl@0
   924
        BOOST_UBLAS_INLINE
sl@0
   925
        const_reverse_iterator2 rbegin2 () const {
sl@0
   926
            return const_reverse_iterator2 (end2 ());
sl@0
   927
        }
sl@0
   928
        BOOST_UBLAS_INLINE
sl@0
   929
        const_reverse_iterator2 rend2 () const {
sl@0
   930
            return const_reverse_iterator2 (begin2 ());
sl@0
   931
        }
sl@0
   932
sl@0
   933
        BOOST_UBLAS_INLINE
sl@0
   934
        reverse_iterator2 rbegin2 () {
sl@0
   935
            return reverse_iterator2 (end2 ());
sl@0
   936
        }
sl@0
   937
        BOOST_UBLAS_INLINE
sl@0
   938
        reverse_iterator2 rend2 () {
sl@0
   939
            return reverse_iterator2 (begin2 ());
sl@0
   940
        }
sl@0
   941
sl@0
   942
    private:
sl@0
   943
        size_type size1_;
sl@0
   944
        size_type size2_;
sl@0
   945
        array_type data_;
sl@0
   946
    };
sl@0
   947
sl@0
   948
sl@0
   949
    // Bounded matrix class
sl@0
   950
    template<class T, std::size_t M, std::size_t N, class L>
sl@0
   951
    class bounded_matrix:
sl@0
   952
        public matrix<T, L, bounded_array<T, M * N> > {
sl@0
   953
sl@0
   954
        typedef matrix<T, L, bounded_array<T, M * N> > matrix_type;
sl@0
   955
    public:
sl@0
   956
        typedef typename matrix_type::size_type size_type;
sl@0
   957
        static const size_type max_size1 = M;
sl@0
   958
        static const size_type max_size2 = N;
sl@0
   959
sl@0
   960
        // Construction and destruction
sl@0
   961
        BOOST_UBLAS_INLINE
sl@0
   962
        bounded_matrix ():
sl@0
   963
            matrix_type (M, N) {}
sl@0
   964
        BOOST_UBLAS_INLINE
sl@0
   965
        bounded_matrix (size_type size1, size_type size2):
sl@0
   966
            matrix_type (size1, size2) {}
sl@0
   967
        BOOST_UBLAS_INLINE
sl@0
   968
        bounded_matrix (const bounded_matrix &m):
sl@0
   969
            matrix_type (m) {}
sl@0
   970
        template<class A2>              // Allow matrix<T, L, bounded_array<M,N> > construction
sl@0
   971
        BOOST_UBLAS_INLINE
sl@0
   972
        bounded_matrix (const matrix<T, L, A2> &m):
sl@0
   973
            matrix_type (m) {}
sl@0
   974
        template<class AE>
sl@0
   975
        BOOST_UBLAS_INLINE
sl@0
   976
        bounded_matrix (const matrix_expression<AE> &ae):
sl@0
   977
            matrix_type (ae) {}
sl@0
   978
        BOOST_UBLAS_INLINE
sl@0
   979
        ~bounded_matrix () {}
sl@0
   980
sl@0
   981
        // Assignment
sl@0
   982
        BOOST_UBLAS_INLINE
sl@0
   983
        bounded_matrix &operator = (const bounded_matrix &m) {
sl@0
   984
            matrix_type::operator = (m);
sl@0
   985
            return *this;
sl@0
   986
        }
sl@0
   987
        template<class L2, class A2>        // Generic matrix assignment
sl@0
   988
        BOOST_UBLAS_INLINE
sl@0
   989
        bounded_matrix &operator = (const matrix<T, L2, A2> &m) {
sl@0
   990
            matrix_type::operator = (m);
sl@0
   991
            return *this;
sl@0
   992
        }
sl@0
   993
        template<class C>          // Container assignment without temporary
sl@0
   994
        BOOST_UBLAS_INLINE
sl@0
   995
        bounded_matrix &operator = (const matrix_container<C> &m) {
sl@0
   996
            matrix_type::operator = (m);
sl@0
   997
            return *this;
sl@0
   998
        }
sl@0
   999
        template<class AE>
sl@0
  1000
        BOOST_UBLAS_INLINE
sl@0
  1001
        bounded_matrix &operator = (const matrix_expression<AE> &ae) {
sl@0
  1002
            matrix_type::operator = (ae);
sl@0
  1003
            return *this;
sl@0
  1004
        }
sl@0
  1005
    };
sl@0
  1006
sl@0
  1007
sl@0
  1008
    // Array based matrix class
sl@0
  1009
    template<class T, class L, class A>
sl@0
  1010
    class vector_of_vector:
sl@0
  1011
        public matrix_container<vector_of_vector<T, L, A> > {
sl@0
  1012
sl@0
  1013
        typedef T *pointer;
sl@0
  1014
        typedef L layout_type;
sl@0
  1015
        typedef vector_of_vector<T, L, A> self_type;
sl@0
  1016
    public:
sl@0
  1017
#ifdef BOOST_UBLAS_ENABLE_PROXY_SHORTCUTS
sl@0
  1018
        using matrix_container<self_type>::operator ();
sl@0
  1019
#endif
sl@0
  1020
        typedef typename A::size_type size_type;
sl@0
  1021
        typedef typename A::difference_type difference_type;
sl@0
  1022
        typedef T value_type;
sl@0
  1023
        typedef const T &const_reference;
sl@0
  1024
        typedef T &reference;
sl@0
  1025
        typedef A array_type;
sl@0
  1026
        typedef const matrix_reference<const self_type> const_closure_type;
sl@0
  1027
        typedef matrix_reference<self_type> closure_type;
sl@0
  1028
        typedef vector<T, typename A::value_type> vector_temporary_type;
sl@0
  1029
        typedef self_type matrix_temporary_type;
sl@0
  1030
        typedef dense_tag storage_category;
sl@0
  1031
        // This could be better for performance,
sl@0
  1032
        // typedef typename unknown_orientation_tag orientation_category;
sl@0
  1033
        // but others depend on the orientation information...
sl@0
  1034
        typedef typename L::orientation_category orientation_category;
sl@0
  1035
sl@0
  1036
        // Construction and destruction
sl@0
  1037
        BOOST_UBLAS_INLINE
sl@0
  1038
        vector_of_vector ():
sl@0
  1039
            matrix_container<self_type> (),
sl@0
  1040
            size1_ (0), size2_ (0), data_ (1) {}
sl@0
  1041
        BOOST_UBLAS_INLINE
sl@0
  1042
        vector_of_vector (size_type size1, size_type size2):
sl@0
  1043
            matrix_container<self_type> (),
sl@0
  1044
            size1_ (size1), size2_ (size2), data_ (1) {
sl@0
  1045
            resize (size1, size2, true);
sl@0
  1046
        }
sl@0
  1047
        BOOST_UBLAS_INLINE
sl@0
  1048
        vector_of_vector (const vector_of_vector &m):
sl@0
  1049
            matrix_container<self_type> (),
sl@0
  1050
            size1_ (m.size1_), size2_ (m.size2_), data_ (m.data_) {}
sl@0
  1051
        template<class AE>
sl@0
  1052
        BOOST_UBLAS_INLINE
sl@0
  1053
        vector_of_vector (const matrix_expression<AE> &ae):
sl@0
  1054
            matrix_container<self_type> (),
sl@0
  1055
            size1_ (ae ().size1 ()), size2_ (ae ().size2 ()), data_ (layout_type::size1 (size1_, size2_) + 1) {
sl@0
  1056
            for (size_type k = 0; k < layout_type::size1 (size1_, size2_); ++ k)
sl@0
  1057
                data ()[k].resize (layout_type::size2 (size1_, size2_));
sl@0
  1058
            matrix_assign<scalar_assign> (*this, ae);
sl@0
  1059
        }
sl@0
  1060
sl@0
  1061
        // Accessors
sl@0
  1062
        BOOST_UBLAS_INLINE
sl@0
  1063
        size_type size1 () const {
sl@0
  1064
            return size1_;
sl@0
  1065
        }
sl@0
  1066
        BOOST_UBLAS_INLINE
sl@0
  1067
        size_type size2 () const { 
sl@0
  1068
            return size2_;
sl@0
  1069
        }
sl@0
  1070
sl@0
  1071
        // Storage accessors
sl@0
  1072
        BOOST_UBLAS_INLINE
sl@0
  1073
        const array_type &data () const {
sl@0
  1074
            return data_;
sl@0
  1075
        }
sl@0
  1076
        BOOST_UBLAS_INLINE
sl@0
  1077
        array_type &data () {
sl@0
  1078
            return data_;
sl@0
  1079
        }
sl@0
  1080
sl@0
  1081
        // Resizing
sl@0
  1082
        BOOST_UBLAS_INLINE
sl@0
  1083
        void resize (size_type size1, size_type size2, bool preserve = true) {
sl@0
  1084
            size1_ = size1;
sl@0
  1085
            size2_ = size2;
sl@0
  1086
            if (preserve)
sl@0
  1087
                data ().resize (layout_type::size1 (size1, size2) + 1, typename array_type::value_type ());
sl@0
  1088
            else
sl@0
  1089
                data ().resize (layout_type::size1 (size1, size2) + 1);
sl@0
  1090
            for (size_type k = 0; k < layout_type::size1 (size1, size2); ++ k) {
sl@0
  1091
                if (preserve)
sl@0
  1092
                    data () [k].resize (layout_type::size2 (size1, size2), value_type ());
sl@0
  1093
                else
sl@0
  1094
                    data () [k].resize (layout_type::size2 (size1, size2));
sl@0
  1095
            }
sl@0
  1096
        }
sl@0
  1097
sl@0
  1098
        // Element access
sl@0
  1099
        BOOST_UBLAS_INLINE
sl@0
  1100
        const_reference operator () (size_type i, size_type j) const {
sl@0
  1101
            return data () [layout_type::element1 (i, size1_, j, size2_)] [layout_type::element2 (i, size1_, j, size2_)]; 
sl@0
  1102
        }
sl@0
  1103
        BOOST_UBLAS_INLINE
sl@0
  1104
        reference at_element (size_type i, size_type j) {
sl@0
  1105
            return data () [layout_type::element1 (i, size1_, j, size2_)] [layout_type::element2 (i, size1_, j, size2_)]; 
sl@0
  1106
        }
sl@0
  1107
        BOOST_UBLAS_INLINE
sl@0
  1108
        reference operator () (size_type i, size_type j) {
sl@0
  1109
            return at_element (i, j); 
sl@0
  1110
        }
sl@0
  1111
sl@0
  1112
        // Element assignment
sl@0
  1113
        BOOST_UBLAS_INLINE
sl@0
  1114
        reference insert_element (size_type i, size_type j, const_reference t) {
sl@0
  1115
            return (at_element (i, j) = t); 
sl@0
  1116
        }
sl@0
  1117
        BOOST_UBLAS_INLINE
sl@0
  1118
        void erase_element (size_type i, size_type j) {
sl@0
  1119
            at_element (i, j) = value_type/*zero*/(); 
sl@0
  1120
        }
sl@0
  1121
        
sl@0
  1122
        // Zeroing
sl@0
  1123
        BOOST_UBLAS_INLINE
sl@0
  1124
        void clear () {
sl@0
  1125
            for (size_type k = 0; k < layout_type::size1 (size1_, size2_); ++ k)
sl@0
  1126
                std::fill (data () [k].begin (), data () [k].end (), value_type/*zero*/());
sl@0
  1127
        }
sl@0
  1128
sl@0
  1129
        // Assignment
sl@0
  1130
        BOOST_UBLAS_INLINE
sl@0
  1131
        vector_of_vector &operator = (const vector_of_vector &m) {
sl@0
  1132
            size1_ = m.size1_;
sl@0
  1133
            size2_ = m.size2_;
sl@0
  1134
            data () = m.data ();
sl@0
  1135
            return *this;
sl@0
  1136
        }
sl@0
  1137
        BOOST_UBLAS_INLINE
sl@0
  1138
        vector_of_vector &assign_temporary (vector_of_vector &m) { 
sl@0
  1139
            swap (m);
sl@0
  1140
            return *this;
sl@0
  1141
        }
sl@0
  1142
        template<class AE>
sl@0
  1143
        BOOST_UBLAS_INLINE
sl@0
  1144
        vector_of_vector &operator = (const matrix_expression<AE> &ae) { 
sl@0
  1145
            self_type temporary (ae);
sl@0
  1146
            return assign_temporary (temporary);
sl@0
  1147
        }
sl@0
  1148
        template<class C>          // Container assignment without temporary
sl@0
  1149
        BOOST_UBLAS_INLINE
sl@0
  1150
        vector_of_vector &operator = (const matrix_container<C> &m) {
sl@0
  1151
            resize (m ().size1 (), m ().size2 (), false);
sl@0
  1152
            assign (m);
sl@0
  1153
            return *this;
sl@0
  1154
        }
sl@0
  1155
        template<class AE>
sl@0
  1156
        BOOST_UBLAS_INLINE
sl@0
  1157
        vector_of_vector &assign (const matrix_expression<AE> &ae) { 
sl@0
  1158
            matrix_assign<scalar_assign> (*this, ae); 
sl@0
  1159
            return *this;
sl@0
  1160
        }
sl@0
  1161
        template<class AE>
sl@0
  1162
        BOOST_UBLAS_INLINE
sl@0
  1163
        vector_of_vector& operator += (const matrix_expression<AE> &ae) {
sl@0
  1164
            self_type temporary (*this + ae);
sl@0
  1165
            return assign_temporary (temporary);
sl@0
  1166
        }
sl@0
  1167
        template<class C>          // Container assignment without temporary
sl@0
  1168
        BOOST_UBLAS_INLINE
sl@0
  1169
        vector_of_vector &operator += (const matrix_container<C> &m) {
sl@0
  1170
            plus_assign (m);
sl@0
  1171
            return *this;
sl@0
  1172
        }
sl@0
  1173
        template<class AE>
sl@0
  1174
        BOOST_UBLAS_INLINE
sl@0
  1175
        vector_of_vector &plus_assign (const matrix_expression<AE> &ae) { 
sl@0
  1176
            matrix_assign<scalar_plus_assign> (*this, ae); 
sl@0
  1177
            return *this;
sl@0
  1178
        }
sl@0
  1179
        template<class AE>
sl@0
  1180
        BOOST_UBLAS_INLINE
sl@0
  1181
        vector_of_vector& operator -= (const matrix_expression<AE> &ae) {
sl@0
  1182
            self_type temporary (*this - ae);
sl@0
  1183
            return assign_temporary (temporary);
sl@0
  1184
        }
sl@0
  1185
        template<class C>          // Container assignment without temporary
sl@0
  1186
        BOOST_UBLAS_INLINE
sl@0
  1187
        vector_of_vector &operator -= (const matrix_container<C> &m) {
sl@0
  1188
            minus_assign (m);
sl@0
  1189
            return *this;
sl@0
  1190
        }
sl@0
  1191
        template<class AE>
sl@0
  1192
        BOOST_UBLAS_INLINE
sl@0
  1193
        vector_of_vector &minus_assign (const matrix_expression<AE> &ae) {
sl@0
  1194
            matrix_assign<scalar_minus_assign> (*this, ae); 
sl@0
  1195
            return *this;
sl@0
  1196
        }
sl@0
  1197
        template<class AT>
sl@0
  1198
        BOOST_UBLAS_INLINE
sl@0
  1199
        vector_of_vector& operator *= (const AT &at) {
sl@0
  1200
            matrix_assign_scalar<scalar_multiplies_assign> (*this, at);
sl@0
  1201
            return *this;
sl@0
  1202
        }
sl@0
  1203
        template<class AT>
sl@0
  1204
        BOOST_UBLAS_INLINE
sl@0
  1205
        vector_of_vector& operator /= (const AT &at) {
sl@0
  1206
            matrix_assign_scalar<scalar_divides_assign> (*this, at);
sl@0
  1207
            return *this;
sl@0
  1208
        }
sl@0
  1209
sl@0
  1210
        // Swapping
sl@0
  1211
        BOOST_UBLAS_INLINE
sl@0
  1212
        void swap (vector_of_vector &m) {
sl@0
  1213
            if (this != &m) {
sl@0
  1214
                std::swap (size1_, m.size1_);
sl@0
  1215
                std::swap (size2_, m.size2_);
sl@0
  1216
                data ().swap (m.data ());
sl@0
  1217
            }
sl@0
  1218
        }
sl@0
  1219
        BOOST_UBLAS_INLINE
sl@0
  1220
        friend void swap (vector_of_vector &m1, vector_of_vector &m2) {
sl@0
  1221
            m1.swap (m2);
sl@0
  1222
        }
sl@0
  1223
sl@0
  1224
        // Iterator types
sl@0
  1225
    private:
sl@0
  1226
        // Use the vector iterator
sl@0
  1227
        typedef typename A::value_type::const_iterator const_subiterator_type;
sl@0
  1228
        typedef typename A::value_type::iterator subiterator_type;
sl@0
  1229
    public:
sl@0
  1230
#ifdef BOOST_UBLAS_USE_INDEXED_ITERATOR
sl@0
  1231
        typedef indexed_iterator1<self_type, dense_random_access_iterator_tag> iterator1;
sl@0
  1232
        typedef indexed_iterator2<self_type, dense_random_access_iterator_tag> iterator2;
sl@0
  1233
        typedef indexed_const_iterator1<self_type, dense_random_access_iterator_tag> const_iterator1;
sl@0
  1234
        typedef indexed_const_iterator2<self_type, dense_random_access_iterator_tag> const_iterator2;
sl@0
  1235
#else
sl@0
  1236
        class const_iterator1;
sl@0
  1237
        class iterator1;
sl@0
  1238
        class const_iterator2;
sl@0
  1239
        class iterator2;
sl@0
  1240
#endif
sl@0
  1241
        typedef reverse_iterator_base1<const_iterator1> const_reverse_iterator1;
sl@0
  1242
        typedef reverse_iterator_base1<iterator1> reverse_iterator1;
sl@0
  1243
        typedef reverse_iterator_base2<const_iterator2> const_reverse_iterator2;
sl@0
  1244
        typedef reverse_iterator_base2<iterator2> reverse_iterator2;
sl@0
  1245
sl@0
  1246
        // Element lookup
sl@0
  1247
        BOOST_UBLAS_INLINE
sl@0
  1248
        const_iterator1 find1 (int /*rank*/, size_type i, size_type j) const {
sl@0
  1249
#ifdef BOOST_UBLAS_USE_INDEXED_ITERATOR
sl@0
  1250
            return const_iterator1 (*this, i, j);
sl@0
  1251
#else
sl@0
  1252
            return const_iterator1 (*this, i, j, data () [layout_type::address1 (i, size1_, j, size2_)].begin ()  + layout_type::address2 (i, size1_, j, size2_));
sl@0
  1253
#endif
sl@0
  1254
        }
sl@0
  1255
        BOOST_UBLAS_INLINE
sl@0
  1256
        iterator1 find1 (int /*rank*/, size_type i, size_type j) {
sl@0
  1257
#ifdef BOOST_UBLAS_USE_INDEXED_ITERATOR
sl@0
  1258
            return iterator1 (*this, i, j);
sl@0
  1259
#else
sl@0
  1260
            return iterator1 (*this, i, j, data () [layout_type::address1 (i, size1_, j, size2_)].begin ()  + layout_type::address2 (i, size1_, j, size2_));
sl@0
  1261
#endif
sl@0
  1262
        }
sl@0
  1263
        BOOST_UBLAS_INLINE
sl@0
  1264
        const_iterator2 find2 (int /*rank*/, size_type i, size_type j) const {
sl@0
  1265
#ifdef BOOST_UBLAS_USE_INDEXED_ITERATOR
sl@0
  1266
            return const_iterator2 (*this, i, j);
sl@0
  1267
#else
sl@0
  1268
            return const_iterator2 (*this, i, j, data () [layout_type::address1 (i, size1_, j, size2_)].begin ()  + layout_type::address2 (i, size1_, j, size2_));
sl@0
  1269
#endif
sl@0
  1270
        }
sl@0
  1271
        BOOST_UBLAS_INLINE
sl@0
  1272
        iterator2 find2 (int /*rank*/, size_type i, size_type j) {
sl@0
  1273
#ifdef BOOST_UBLAS_USE_INDEXED_ITERATOR
sl@0
  1274
            return iterator2 (*this, i, j);
sl@0
  1275
#else
sl@0
  1276
            return iterator2 (*this, i, j, data () [layout_type::address1 (i, size1_, j, size2_)].begin () + layout_type::address2 (i, size1_, j, size2_));
sl@0
  1277
#endif
sl@0
  1278
        }
sl@0
  1279
sl@0
  1280
sl@0
  1281
#ifndef BOOST_UBLAS_USE_INDEXED_ITERATOR
sl@0
  1282
        class const_iterator1:
sl@0
  1283
            public container_const_reference<vector_of_vector>,
sl@0
  1284
            public random_access_iterator_base<dense_random_access_iterator_tag,
sl@0
  1285
                                               const_iterator1, value_type> {
sl@0
  1286
        public:
sl@0
  1287
            typedef typename vector_of_vector::value_type value_type;
sl@0
  1288
            typedef typename vector_of_vector::difference_type difference_type;
sl@0
  1289
            typedef typename vector_of_vector::const_reference reference;
sl@0
  1290
            typedef const typename vector_of_vector::pointer pointer;
sl@0
  1291
sl@0
  1292
            typedef const_iterator2 dual_iterator_type;
sl@0
  1293
            typedef const_reverse_iterator2 dual_reverse_iterator_type;
sl@0
  1294
sl@0
  1295
            // Construction and destruction
sl@0
  1296
            BOOST_UBLAS_INLINE
sl@0
  1297
            const_iterator1 ():
sl@0
  1298
                container_const_reference<self_type> (), i_ (), j_ (), it_ () {}
sl@0
  1299
            BOOST_UBLAS_INLINE
sl@0
  1300
            const_iterator1 (const self_type &m, size_type i, size_type j, const const_subiterator_type &it):
sl@0
  1301
                container_const_reference<self_type> (m), i_ (i), j_ (j), it_ (it) {}
sl@0
  1302
            BOOST_UBLAS_INLINE
sl@0
  1303
            const_iterator1 (const iterator1 &it):
sl@0
  1304
                container_const_reference<self_type> (it ()), i_ (it.i_), j_ (it.j_), it_ (it.it_) {}
sl@0
  1305
sl@0
  1306
            // Arithmetic
sl@0
  1307
            BOOST_UBLAS_INLINE
sl@0
  1308
            const_iterator1 &operator ++ () {
sl@0
  1309
                ++ i_;
sl@0
  1310
                const self_type &m = (*this) ();
sl@0
  1311
                if (layout_type::fast1 ())
sl@0
  1312
                    ++ it_;
sl@0
  1313
                else 
sl@0
  1314
                    it_ = m.find1 (1, i_, j_).it_;
sl@0
  1315
                return *this;
sl@0
  1316
            }
sl@0
  1317
            BOOST_UBLAS_INLINE
sl@0
  1318
            const_iterator1 &operator -- () {
sl@0
  1319
                -- i_;
sl@0
  1320
                const self_type &m = (*this) ();
sl@0
  1321
                if (layout_type::fast1 ())
sl@0
  1322
                    -- it_;
sl@0
  1323
                else
sl@0
  1324
                    it_ = m.find1 (1, i_, j_).it_;
sl@0
  1325
                return *this;
sl@0
  1326
            }
sl@0
  1327
            BOOST_UBLAS_INLINE
sl@0
  1328
            const_iterator1 &operator += (difference_type n) {
sl@0
  1329
                i_ += n;
sl@0
  1330
                const self_type &m = (*this) ();
sl@0
  1331
                it_ = m.find1 (1, i_, j_).it_;
sl@0
  1332
                return *this;
sl@0
  1333
            }
sl@0
  1334
            BOOST_UBLAS_INLINE
sl@0
  1335
            const_iterator1 &operator -= (difference_type n) {
sl@0
  1336
                i_ -= n;
sl@0
  1337
                const self_type &m = (*this) ();
sl@0
  1338
                it_ = m.find1 (1, i_, j_).it_;
sl@0
  1339
                return *this;
sl@0
  1340
            }
sl@0
  1341
            BOOST_UBLAS_INLINE
sl@0
  1342
            difference_type operator - (const const_iterator1 &it) const {
sl@0
  1343
                BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
sl@0
  1344
                BOOST_UBLAS_CHECK (index2 () == it.index2 (), bad_index ());
sl@0
  1345
                return index1 () - it.index1 ();
sl@0
  1346
            }
sl@0
  1347
sl@0
  1348
            // Dereference
sl@0
  1349
            BOOST_UBLAS_INLINE
sl@0
  1350
            const_reference operator * () const {
sl@0
  1351
                BOOST_UBLAS_CHECK (index1 () < (*this) ().size1 (), bad_index ());
sl@0
  1352
                BOOST_UBLAS_CHECK (index2 () < (*this) ().size2 (), bad_index ());
sl@0
  1353
                return *it_;
sl@0
  1354
            }
sl@0
  1355
            BOOST_UBLAS_INLINE
sl@0
  1356
            const_reference operator [] (difference_type n) const {
sl@0
  1357
                return *(*this + n);
sl@0
  1358
            }
sl@0
  1359
sl@0
  1360
#ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
sl@0
  1361
            BOOST_UBLAS_INLINE
sl@0
  1362
#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
sl@0
  1363
            typename self_type::
sl@0
  1364
#endif
sl@0
  1365
            const_iterator2 begin () const {
sl@0
  1366
                const self_type &m = (*this) ();
sl@0
  1367
                return m.find2 (1, index1 (), 0);
sl@0
  1368
            }
sl@0
  1369
            BOOST_UBLAS_INLINE
sl@0
  1370
#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
sl@0
  1371
            typename self_type::
sl@0
  1372
#endif
sl@0
  1373
            const_iterator2 end () const {
sl@0
  1374
                const self_type &m = (*this) ();
sl@0
  1375
                return m.find2 (1, index1 (), m.size2 ());
sl@0
  1376
            }
sl@0
  1377
            BOOST_UBLAS_INLINE
sl@0
  1378
#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
sl@0
  1379
            typename self_type::
sl@0
  1380
#endif
sl@0
  1381
            const_reverse_iterator2 rbegin () const {
sl@0
  1382
                return const_reverse_iterator2 (end ());
sl@0
  1383
            }
sl@0
  1384
            BOOST_UBLAS_INLINE
sl@0
  1385
#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
sl@0
  1386
            typename self_type::
sl@0
  1387
#endif
sl@0
  1388
            const_reverse_iterator2 rend () const {
sl@0
  1389
                return const_reverse_iterator2 (begin ());
sl@0
  1390
            }
sl@0
  1391
#endif
sl@0
  1392
sl@0
  1393
            // Indices
sl@0
  1394
            BOOST_UBLAS_INLINE
sl@0
  1395
            size_type index1 () const {
sl@0
  1396
                return i_;
sl@0
  1397
            }
sl@0
  1398
            BOOST_UBLAS_INLINE
sl@0
  1399
            size_type index2 () const {
sl@0
  1400
                return j_;
sl@0
  1401
            }
sl@0
  1402
sl@0
  1403
            // Assignment
sl@0
  1404
            BOOST_UBLAS_INLINE
sl@0
  1405
            const_iterator1 &operator = (const const_iterator1 &it) {
sl@0
  1406
                container_const_reference<self_type>::assign (&it ());
sl@0
  1407
                it_ = it.it_;
sl@0
  1408
                return *this;
sl@0
  1409
            }
sl@0
  1410
sl@0
  1411
            // Comparison
sl@0
  1412
            BOOST_UBLAS_INLINE
sl@0
  1413
            bool operator == (const const_iterator1 &it) const {
sl@0
  1414
                BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
sl@0
  1415
                BOOST_UBLAS_CHECK (index2 () == it.index2 (), bad_index ());
sl@0
  1416
                return it_ == it.it_;
sl@0
  1417
            }
sl@0
  1418
            BOOST_UBLAS_INLINE
sl@0
  1419
            bool operator < (const const_iterator1 &it) const {
sl@0
  1420
                BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
sl@0
  1421
                BOOST_UBLAS_CHECK (index2 () == it.index2 (), bad_index ());
sl@0
  1422
                return it_ < it.it_;
sl@0
  1423
            }
sl@0
  1424
sl@0
  1425
        private:
sl@0
  1426
            size_type i_;
sl@0
  1427
            size_type j_;
sl@0
  1428
            const_subiterator_type it_;
sl@0
  1429
sl@0
  1430
            friend class iterator1;
sl@0
  1431
        };
sl@0
  1432
#endif
sl@0
  1433
sl@0
  1434
        BOOST_UBLAS_INLINE
sl@0
  1435
        const_iterator1 begin1 () const {
sl@0
  1436
            return find1 (0, 0, 0);
sl@0
  1437
        }
sl@0
  1438
        BOOST_UBLAS_INLINE
sl@0
  1439
        const_iterator1 end1 () const {
sl@0
  1440
            return find1 (0, size1_, 0);
sl@0
  1441
        }
sl@0
  1442
sl@0
  1443
#ifndef BOOST_UBLAS_USE_INDEXED_ITERATOR
sl@0
  1444
        class iterator1:
sl@0
  1445
            public container_reference<vector_of_vector>,
sl@0
  1446
            public random_access_iterator_base<dense_random_access_iterator_tag,
sl@0
  1447
                                               iterator1, value_type> {
sl@0
  1448
        public:
sl@0
  1449
            typedef typename vector_of_vector::value_type value_type;
sl@0
  1450
            typedef typename vector_of_vector::difference_type difference_type;
sl@0
  1451
            typedef typename vector_of_vector::reference reference;
sl@0
  1452
            typedef typename vector_of_vector::pointer pointer;
sl@0
  1453
sl@0
  1454
            typedef iterator2 dual_iterator_type;
sl@0
  1455
            typedef reverse_iterator2 dual_reverse_iterator_type;
sl@0
  1456
sl@0
  1457
            // Construction and destruction
sl@0
  1458
            BOOST_UBLAS_INLINE
sl@0
  1459
            iterator1 ():
sl@0
  1460
                container_reference<self_type> (), i_ (), j_ (), it_ () {}
sl@0
  1461
            BOOST_UBLAS_INLINE
sl@0
  1462
            iterator1 (self_type &m, size_type i, size_type j, const subiterator_type &it):
sl@0
  1463
                container_reference<self_type> (m), i_ (i), j_ (j), it_ (it) {}
sl@0
  1464
sl@0
  1465
            // Arithmetic
sl@0
  1466
            BOOST_UBLAS_INLINE
sl@0
  1467
            iterator1 &operator ++ () {
sl@0
  1468
                ++ i_;
sl@0
  1469
                self_type &m = (*this) ();
sl@0
  1470
                if (layout_type::fast1 ())
sl@0
  1471
                    ++ it_;
sl@0
  1472
                else
sl@0
  1473
                    it_ = m.find1 (1, i_, j_).it_;
sl@0
  1474
                return *this;
sl@0
  1475
            }
sl@0
  1476
            BOOST_UBLAS_INLINE
sl@0
  1477
            iterator1 &operator -- () {
sl@0
  1478
                -- i_;
sl@0
  1479
                self_type &m = (*this) ();
sl@0
  1480
                if (layout_type::fast1 ())
sl@0
  1481
                    -- it_;
sl@0
  1482
                else
sl@0
  1483
                    it_ = m.find1 (1, i_, j_).it_;
sl@0
  1484
                return *this;
sl@0
  1485
            }
sl@0
  1486
            BOOST_UBLAS_INLINE
sl@0
  1487
            iterator1 &operator += (difference_type n) {
sl@0
  1488
                i_ += n;
sl@0
  1489
                self_type &m = (*this) ();
sl@0
  1490
                it_ = m.find1 (1, i_, j_).it_;
sl@0
  1491
                return *this;
sl@0
  1492
            }
sl@0
  1493
            BOOST_UBLAS_INLINE
sl@0
  1494
            iterator1 &operator -= (difference_type n) {
sl@0
  1495
                i_ -= n;
sl@0
  1496
                self_type &m = (*this) ();
sl@0
  1497
                it_ = m.find1 (1, i_, j_).it_;
sl@0
  1498
                return *this;
sl@0
  1499
            }
sl@0
  1500
            BOOST_UBLAS_INLINE
sl@0
  1501
            difference_type operator - (const iterator1 &it) const {
sl@0
  1502
                BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
sl@0
  1503
                BOOST_UBLAS_CHECK (index2 () == it.index2 (), bad_index ());
sl@0
  1504
                return index1 () - it.index1 ();
sl@0
  1505
            }
sl@0
  1506
sl@0
  1507
            // Dereference
sl@0
  1508
            BOOST_UBLAS_INLINE
sl@0
  1509
            reference operator * () const {
sl@0
  1510
                BOOST_UBLAS_CHECK (index1 () < (*this) ().size1 (), bad_index ());
sl@0
  1511
                BOOST_UBLAS_CHECK (index2 () < (*this) ().size2 (), bad_index ());
sl@0
  1512
                return *it_;
sl@0
  1513
            }
sl@0
  1514
            BOOST_UBLAS_INLINE
sl@0
  1515
            reference operator [] (difference_type n) const {
sl@0
  1516
                return *(*this + n);
sl@0
  1517
            }
sl@0
  1518
sl@0
  1519
#ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
sl@0
  1520
            BOOST_UBLAS_INLINE
sl@0
  1521
#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
sl@0
  1522
            typename self_type::
sl@0
  1523
#endif
sl@0
  1524
            iterator2 begin () const {
sl@0
  1525
                self_type &m = (*this) ();
sl@0
  1526
                return m.find2 (1, index1 (), 0);
sl@0
  1527
            }
sl@0
  1528
            BOOST_UBLAS_INLINE
sl@0
  1529
#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
sl@0
  1530
            typename self_type::
sl@0
  1531
#endif
sl@0
  1532
            iterator2 end () const {
sl@0
  1533
                self_type &m = (*this) ();
sl@0
  1534
                return m.find2 (1, index1 (), m.size2 ());
sl@0
  1535
            }
sl@0
  1536
            BOOST_UBLAS_INLINE
sl@0
  1537
#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
sl@0
  1538
            typename self_type::
sl@0
  1539
#endif
sl@0
  1540
            reverse_iterator2 rbegin () const {
sl@0
  1541
                return reverse_iterator2 (end ());
sl@0
  1542
            }
sl@0
  1543
            BOOST_UBLAS_INLINE
sl@0
  1544
#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
sl@0
  1545
            typename self_type::
sl@0
  1546
#endif
sl@0
  1547
            reverse_iterator2 rend () const {
sl@0
  1548
                return reverse_iterator2 (begin ());
sl@0
  1549
            }
sl@0
  1550
#endif
sl@0
  1551
sl@0
  1552
            // Indices
sl@0
  1553
            BOOST_UBLAS_INLINE
sl@0
  1554
            size_type index1 () const {
sl@0
  1555
                return i_;
sl@0
  1556
            }
sl@0
  1557
            BOOST_UBLAS_INLINE
sl@0
  1558
            size_type index2 () const {
sl@0
  1559
                return j_;
sl@0
  1560
            }
sl@0
  1561
sl@0
  1562
            // Assignment
sl@0
  1563
            BOOST_UBLAS_INLINE
sl@0
  1564
            iterator1 &operator = (const iterator1 &it) {
sl@0
  1565
                container_reference<self_type>::assign (&it ());
sl@0
  1566
                it_ = it.it_;
sl@0
  1567
                return *this;
sl@0
  1568
            }
sl@0
  1569
sl@0
  1570
            // Comparison
sl@0
  1571
            BOOST_UBLAS_INLINE
sl@0
  1572
            bool operator == (const iterator1 &it) const {
sl@0
  1573
                BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
sl@0
  1574
                BOOST_UBLAS_CHECK (index2 () == it.index2 (), bad_index ());
sl@0
  1575
                return it_ == it.it_;
sl@0
  1576
            }
sl@0
  1577
            BOOST_UBLAS_INLINE
sl@0
  1578
            bool operator < (const iterator1 &it) const {
sl@0
  1579
                BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
sl@0
  1580
                BOOST_UBLAS_CHECK (index2 () == it.index2 (), bad_index ());
sl@0
  1581
                return it_ < it.it_;
sl@0
  1582
            }
sl@0
  1583
sl@0
  1584
        private:
sl@0
  1585
            size_type i_;
sl@0
  1586
            size_type j_;
sl@0
  1587
            subiterator_type it_;
sl@0
  1588
sl@0
  1589
            friend class const_iterator1;
sl@0
  1590
        };
sl@0
  1591
#endif
sl@0
  1592
sl@0
  1593
        BOOST_UBLAS_INLINE
sl@0
  1594
        iterator1 begin1 () {
sl@0
  1595
            return find1 (0, 0, 0);
sl@0
  1596
        }
sl@0
  1597
        BOOST_UBLAS_INLINE
sl@0
  1598
        iterator1 end1 () {
sl@0
  1599
            return find1 (0, size1_, 0);
sl@0
  1600
        }
sl@0
  1601
sl@0
  1602
#ifndef BOOST_UBLAS_USE_INDEXED_ITERATOR
sl@0
  1603
        class const_iterator2:
sl@0
  1604
            public container_const_reference<vector_of_vector>,
sl@0
  1605
            public random_access_iterator_base<dense_random_access_iterator_tag,
sl@0
  1606
                                               const_iterator2, value_type> {
sl@0
  1607
        public:
sl@0
  1608
            typedef typename vector_of_vector::value_type value_type;
sl@0
  1609
            typedef typename vector_of_vector::difference_type difference_type;
sl@0
  1610
            typedef typename vector_of_vector::const_reference reference;
sl@0
  1611
            typedef const typename vector_of_vector::pointer pointer;
sl@0
  1612
sl@0
  1613
            typedef const_iterator1 dual_iterator_type;
sl@0
  1614
            typedef const_reverse_iterator1 dual_reverse_iterator_type;
sl@0
  1615
sl@0
  1616
            // Construction and destruction
sl@0
  1617
            BOOST_UBLAS_INLINE
sl@0
  1618
            const_iterator2 ():
sl@0
  1619
                container_const_reference<self_type> (), i_ (), j_ (), it_ () {}
sl@0
  1620
            BOOST_UBLAS_INLINE
sl@0
  1621
            const_iterator2 (const self_type &m, size_type i, size_type j, const const_subiterator_type &it):
sl@0
  1622
                container_const_reference<self_type> (m), i_ (i), j_ (j), it_ (it) {}
sl@0
  1623
            BOOST_UBLAS_INLINE
sl@0
  1624
            const_iterator2 (const iterator2 &it):
sl@0
  1625
                container_const_reference<self_type> (it ()), i_ (it.i_), j_ (it.j_), it_ (it.it_) {}
sl@0
  1626
sl@0
  1627
            // Arithmetic
sl@0
  1628
            BOOST_UBLAS_INLINE
sl@0
  1629
            const_iterator2 &operator ++ () {
sl@0
  1630
                ++ j_;
sl@0
  1631
                const self_type &m = (*this) ();
sl@0
  1632
                if (layout_type::fast2 ())
sl@0
  1633
                    ++ it_;
sl@0
  1634
                else
sl@0
  1635
                    it_ = m.find2 (1, i_, j_).it_;
sl@0
  1636
                return *this;
sl@0
  1637
            }
sl@0
  1638
            BOOST_UBLAS_INLINE
sl@0
  1639
            const_iterator2 &operator -- () {
sl@0
  1640
                -- j_;
sl@0
  1641
                const self_type &m = (*this) ();
sl@0
  1642
                if (layout_type::fast2 ())
sl@0
  1643
                    -- it_;
sl@0
  1644
                else
sl@0
  1645
                    it_ = m.find2 (1, i_, j_).it_;
sl@0
  1646
                return *this;
sl@0
  1647
            }
sl@0
  1648
            BOOST_UBLAS_INLINE
sl@0
  1649
            const_iterator2 &operator += (difference_type n) {
sl@0
  1650
                j_ += n;
sl@0
  1651
                const self_type &m = (*this) ();
sl@0
  1652
                it_ = m.find2 (1, i_, j_).it_;
sl@0
  1653
                return *this;
sl@0
  1654
            }
sl@0
  1655
            BOOST_UBLAS_INLINE
sl@0
  1656
            const_iterator2 &operator -= (difference_type n) {
sl@0
  1657
                j_ -= n;
sl@0
  1658
                const self_type &m = (*this) ();
sl@0
  1659
                it_ = m.find2 (1, i_, j_).it_;
sl@0
  1660
                return *this;
sl@0
  1661
            }
sl@0
  1662
            BOOST_UBLAS_INLINE
sl@0
  1663
            difference_type operator - (const const_iterator2 &it) const {
sl@0
  1664
                BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
sl@0
  1665
                BOOST_UBLAS_CHECK (index1 () == it.index1 (), bad_index ());
sl@0
  1666
                return index2 () - it.index2 ();
sl@0
  1667
            }
sl@0
  1668
sl@0
  1669
            // Dereference
sl@0
  1670
            BOOST_UBLAS_INLINE
sl@0
  1671
            const_reference operator * () const {
sl@0
  1672
                BOOST_UBLAS_CHECK (index1 () < (*this) ().size1 (), bad_index ());
sl@0
  1673
                BOOST_UBLAS_CHECK (index2 () < (*this) ().size2 (), bad_index ());
sl@0
  1674
                return *it_;
sl@0
  1675
            }
sl@0
  1676
            BOOST_UBLAS_INLINE
sl@0
  1677
            const_reference operator [] (difference_type n) const {
sl@0
  1678
                return *(*this + n);
sl@0
  1679
            }
sl@0
  1680
sl@0
  1681
#ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
sl@0
  1682
            BOOST_UBLAS_INLINE
sl@0
  1683
#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
sl@0
  1684
            typename self_type::
sl@0
  1685
#endif
sl@0
  1686
            const_iterator1 begin () const {
sl@0
  1687
                const self_type &m = (*this) ();
sl@0
  1688
                return m.find1 (1, 0, index2 ());
sl@0
  1689
            }
sl@0
  1690
            BOOST_UBLAS_INLINE
sl@0
  1691
#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
sl@0
  1692
            typename self_type::
sl@0
  1693
#endif
sl@0
  1694
            const_iterator1 end () const {
sl@0
  1695
                const self_type &m = (*this) ();
sl@0
  1696
                return m.find1 (1, m.size1 (), index2 ());
sl@0
  1697
            }
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_reverse_iterator1 rbegin () const {
sl@0
  1703
                return const_reverse_iterator1 (end ());
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_reverse_iterator1 rend () const {
sl@0
  1710
                return const_reverse_iterator1 (begin ());
sl@0
  1711
            }
sl@0
  1712
#endif
sl@0
  1713
sl@0
  1714
            // Indices
sl@0
  1715
            BOOST_UBLAS_INLINE
sl@0
  1716
            size_type index1 () const {
sl@0
  1717
                return i_;
sl@0
  1718
            }
sl@0
  1719
            BOOST_UBLAS_INLINE
sl@0
  1720
            size_type index2 () const {
sl@0
  1721
                return j_;
sl@0
  1722
            }
sl@0
  1723
sl@0
  1724
            // Assignment
sl@0
  1725
            BOOST_UBLAS_INLINE
sl@0
  1726
            const_iterator2 &operator = (const const_iterator2 &it) {
sl@0
  1727
                container_const_reference<self_type>::assign (&it ());
sl@0
  1728
                it_ = it.it_;
sl@0
  1729
                return *this;
sl@0
  1730
            }
sl@0
  1731
sl@0
  1732
            // Comparison
sl@0
  1733
            BOOST_UBLAS_INLINE
sl@0
  1734
            bool operator == (const const_iterator2 &it) const {
sl@0
  1735
                BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
sl@0
  1736
                BOOST_UBLAS_CHECK (index1 () == it.index1 (), bad_index ());
sl@0
  1737
                return it_ == it.it_;
sl@0
  1738
            }
sl@0
  1739
            BOOST_UBLAS_INLINE
sl@0
  1740
            bool operator < (const const_iterator2 &it) const {
sl@0
  1741
                BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
sl@0
  1742
                BOOST_UBLAS_CHECK (index1 () == it.index1 (), bad_index ());
sl@0
  1743
                return it_ < it.it_;
sl@0
  1744
            }
sl@0
  1745
sl@0
  1746
        private:
sl@0
  1747
            size_type i_;
sl@0
  1748
            size_type j_;
sl@0
  1749
            const_subiterator_type it_;
sl@0
  1750
sl@0
  1751
            friend class iterator2;
sl@0
  1752
        };
sl@0
  1753
#endif
sl@0
  1754
sl@0
  1755
        BOOST_UBLAS_INLINE
sl@0
  1756
        const_iterator2 begin2 () const {
sl@0
  1757
            return find2 (0, 0, 0);
sl@0
  1758
        }
sl@0
  1759
        BOOST_UBLAS_INLINE
sl@0
  1760
        const_iterator2 end2 () const {
sl@0
  1761
            return find2 (0, 0, size2_);
sl@0
  1762
        }
sl@0
  1763
sl@0
  1764
#ifndef BOOST_UBLAS_USE_INDEXED_ITERATOR
sl@0
  1765
        class iterator2:
sl@0
  1766
            public container_reference<vector_of_vector>,
sl@0
  1767
            public random_access_iterator_base<dense_random_access_iterator_tag,
sl@0
  1768
                                               iterator2, value_type> {
sl@0
  1769
        public:
sl@0
  1770
            typedef typename vector_of_vector::value_type value_type;
sl@0
  1771
            typedef typename vector_of_vector::difference_type difference_type;
sl@0
  1772
            typedef typename vector_of_vector::reference reference;
sl@0
  1773
            typedef typename vector_of_vector::pointer pointer;
sl@0
  1774
sl@0
  1775
            typedef iterator1 dual_iterator_type;
sl@0
  1776
            typedef reverse_iterator1 dual_reverse_iterator_type;
sl@0
  1777
sl@0
  1778
            // Construction and destruction
sl@0
  1779
            BOOST_UBLAS_INLINE
sl@0
  1780
            iterator2 ():
sl@0
  1781
                container_reference<self_type> (), i_ (), j_ (), it_ () {}
sl@0
  1782
            BOOST_UBLAS_INLINE
sl@0
  1783
            iterator2 (self_type &m, size_type i, size_type j, const subiterator_type &it):
sl@0
  1784
                container_reference<self_type> (m), i_ (i), j_ (j), it_ (it) {}
sl@0
  1785
sl@0
  1786
            // Arithmetic
sl@0
  1787
            BOOST_UBLAS_INLINE
sl@0
  1788
            iterator2 &operator ++ () {
sl@0
  1789
                ++ j_;
sl@0
  1790
                self_type &m = (*this) ();
sl@0
  1791
                if (layout_type::fast2 ())
sl@0
  1792
                    ++ it_;
sl@0
  1793
                else
sl@0
  1794
                    it_ = m.find2 (1, i_, j_).it_;
sl@0
  1795
                return *this;
sl@0
  1796
            }
sl@0
  1797
            BOOST_UBLAS_INLINE
sl@0
  1798
            iterator2 &operator -- () {
sl@0
  1799
                -- j_;
sl@0
  1800
                self_type &m = (*this) ();
sl@0
  1801
                if (layout_type::fast2 ())
sl@0
  1802
                    -- it_;
sl@0
  1803
                else
sl@0
  1804
                    it_ = m.find2 (1, i_, j_).it_;
sl@0
  1805
                return *this;
sl@0
  1806
            }
sl@0
  1807
            BOOST_UBLAS_INLINE
sl@0
  1808
            iterator2 &operator += (difference_type n) {
sl@0
  1809
                j_ += n;
sl@0
  1810
                self_type &m = (*this) ();
sl@0
  1811
                it_ = m.find2 (1, i_, j_).it_;
sl@0
  1812
                return *this;
sl@0
  1813
            }
sl@0
  1814
            BOOST_UBLAS_INLINE
sl@0
  1815
            iterator2 &operator -= (difference_type n) {
sl@0
  1816
                j_ -= n;
sl@0
  1817
                self_type &m = (*this) ();
sl@0
  1818
                it_ = m.find2 (1, i_, j_).it_;
sl@0
  1819
                return *this;
sl@0
  1820
            }
sl@0
  1821
            BOOST_UBLAS_INLINE
sl@0
  1822
            difference_type operator - (const iterator2 &it) const {
sl@0
  1823
                BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
sl@0
  1824
                BOOST_UBLAS_CHECK (index1 () == it.index1 (), bad_index ());
sl@0
  1825
                return index2 () - it.index2 ();
sl@0
  1826
            }
sl@0
  1827
sl@0
  1828
            // Dereference
sl@0
  1829
            BOOST_UBLAS_INLINE
sl@0
  1830
            reference operator * () const {
sl@0
  1831
                BOOST_UBLAS_CHECK (index1 () < (*this) ().size1 (), bad_index ());
sl@0
  1832
                BOOST_UBLAS_CHECK (index2 () < (*this) ().size2 (), bad_index ());
sl@0
  1833
                return *it_;
sl@0
  1834
            }
sl@0
  1835
            BOOST_UBLAS_INLINE
sl@0
  1836
            reference operator [] (difference_type n) const {
sl@0
  1837
                return *(*this + n);
sl@0
  1838
            }
sl@0
  1839
sl@0
  1840
#ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
sl@0
  1841
            BOOST_UBLAS_INLINE
sl@0
  1842
#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
sl@0
  1843
            typename self_type::
sl@0
  1844
#endif
sl@0
  1845
            iterator1 begin () const {
sl@0
  1846
                self_type &m = (*this) ();
sl@0
  1847
                return m.find1 (1, 0, index2 ());
sl@0
  1848
            }
sl@0
  1849
            BOOST_UBLAS_INLINE
sl@0
  1850
#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
sl@0
  1851
            typename self_type::
sl@0
  1852
#endif
sl@0
  1853
            iterator1 end () const {
sl@0
  1854
                self_type &m = (*this) ();
sl@0
  1855
                return m.find1 (1, m.size1 (), 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
            reverse_iterator1 rbegin () const {
sl@0
  1862
                return reverse_iterator1 (end ());
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 rend () const {
sl@0
  1869
                return reverse_iterator1 (begin ());
sl@0
  1870
            }
sl@0
  1871
#endif
sl@0
  1872
sl@0
  1873
            // Indices
sl@0
  1874
            BOOST_UBLAS_INLINE
sl@0
  1875
            size_type index1 () const {
sl@0
  1876
                return i_;
sl@0
  1877
            }
sl@0
  1878
            BOOST_UBLAS_INLINE
sl@0
  1879
            size_type index2 () const {
sl@0
  1880
                return j_;
sl@0
  1881
            }
sl@0
  1882
sl@0
  1883
            // Assignment
sl@0
  1884
            BOOST_UBLAS_INLINE
sl@0
  1885
            iterator2 &operator = (const iterator2 &it) {
sl@0
  1886
                container_reference<self_type>::assign (&it ());
sl@0
  1887
                it_ = it.it_;
sl@0
  1888
                return *this;
sl@0
  1889
            }
sl@0
  1890
sl@0
  1891
            // Comparison
sl@0
  1892
            BOOST_UBLAS_INLINE
sl@0
  1893
            bool operator == (const iterator2 &it) const {
sl@0
  1894
                BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
sl@0
  1895
                BOOST_UBLAS_CHECK (index1 () == it.index1 (), bad_index ());
sl@0
  1896
                return it_ == it.it_;
sl@0
  1897
            }
sl@0
  1898
            BOOST_UBLAS_INLINE
sl@0
  1899
            bool operator < (const iterator2 &it) const {
sl@0
  1900
                BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
sl@0
  1901
                BOOST_UBLAS_CHECK (index1 () == it.index1 (), bad_index ());
sl@0
  1902
                return it_ < it.it_;
sl@0
  1903
            }
sl@0
  1904
sl@0
  1905
        private:
sl@0
  1906
            size_type i_;
sl@0
  1907
            size_type j_;
sl@0
  1908
            subiterator_type it_;
sl@0
  1909
sl@0
  1910
            friend class const_iterator2;
sl@0
  1911
        };
sl@0
  1912
#endif
sl@0
  1913
sl@0
  1914
        BOOST_UBLAS_INLINE
sl@0
  1915
        iterator2 begin2 () {
sl@0
  1916
            return find2 (0, 0, 0);
sl@0
  1917
        }
sl@0
  1918
        BOOST_UBLAS_INLINE
sl@0
  1919
        iterator2 end2 () {
sl@0
  1920
            return find2 (0, 0, size2_);
sl@0
  1921
        }
sl@0
  1922
sl@0
  1923
        // Reverse iterators
sl@0
  1924
sl@0
  1925
        BOOST_UBLAS_INLINE
sl@0
  1926
        const_reverse_iterator1 rbegin1 () const {
sl@0
  1927
            return const_reverse_iterator1 (end1 ());
sl@0
  1928
        }
sl@0
  1929
        BOOST_UBLAS_INLINE
sl@0
  1930
        const_reverse_iterator1 rend1 () const {
sl@0
  1931
            return const_reverse_iterator1 (begin1 ());
sl@0
  1932
        }
sl@0
  1933
sl@0
  1934
        BOOST_UBLAS_INLINE
sl@0
  1935
        reverse_iterator1 rbegin1 () {
sl@0
  1936
            return reverse_iterator1 (end1 ());
sl@0
  1937
        }
sl@0
  1938
        BOOST_UBLAS_INLINE
sl@0
  1939
        reverse_iterator1 rend1 () {
sl@0
  1940
            return reverse_iterator1 (begin1 ());
sl@0
  1941
        }
sl@0
  1942
sl@0
  1943
        BOOST_UBLAS_INLINE
sl@0
  1944
        const_reverse_iterator2 rbegin2 () const {
sl@0
  1945
            return const_reverse_iterator2 (end2 ());
sl@0
  1946
        }
sl@0
  1947
        BOOST_UBLAS_INLINE
sl@0
  1948
        const_reverse_iterator2 rend2 () const {
sl@0
  1949
            return const_reverse_iterator2 (begin2 ());
sl@0
  1950
        }
sl@0
  1951
sl@0
  1952
        BOOST_UBLAS_INLINE
sl@0
  1953
        reverse_iterator2 rbegin2 () {
sl@0
  1954
            return reverse_iterator2 (end2 ());
sl@0
  1955
        }
sl@0
  1956
        BOOST_UBLAS_INLINE
sl@0
  1957
        reverse_iterator2 rend2 () {
sl@0
  1958
            return reverse_iterator2 (begin2 ());
sl@0
  1959
        }
sl@0
  1960
sl@0
  1961
    private:
sl@0
  1962
        size_type size1_;
sl@0
  1963
        size_type size2_;
sl@0
  1964
        array_type data_;
sl@0
  1965
    };
sl@0
  1966
sl@0
  1967
sl@0
  1968
    // Zero matrix class
sl@0
  1969
    template<class T>
sl@0
  1970
    class zero_matrix:
sl@0
  1971
        public matrix_container<zero_matrix<T> > {
sl@0
  1972
sl@0
  1973
        typedef const T *const_pointer;
sl@0
  1974
        typedef zero_matrix<T> self_type;
sl@0
  1975
    public:
sl@0
  1976
#ifdef BOOST_UBLAS_ENABLE_PROXY_SHORTCUTS
sl@0
  1977
        using matrix_container<self_type>::operator ();
sl@0
  1978
#endif
sl@0
  1979
        typedef std::size_t size_type;
sl@0
  1980
        typedef std::ptrdiff_t difference_type;
sl@0
  1981
        typedef T value_type;
sl@0
  1982
        typedef const T &const_reference;
sl@0
  1983
        typedef T &reference;
sl@0
  1984
        typedef const matrix_reference<const self_type> const_closure_type;
sl@0
  1985
        typedef matrix_reference<self_type> closure_type;
sl@0
  1986
        typedef sparse_tag storage_category;
sl@0
  1987
        typedef unknown_orientation_tag orientation_category;
sl@0
  1988
sl@0
  1989
        // Construction and destruction
sl@0
  1990
        BOOST_UBLAS_INLINE
sl@0
  1991
        zero_matrix ():
sl@0
  1992
            matrix_container<self_type> (),
sl@0
  1993
            size1_ (0), size2_ (0) {}
sl@0
  1994
        BOOST_UBLAS_INLINE
sl@0
  1995
        zero_matrix (size_type size):
sl@0
  1996
            matrix_container<self_type> (),
sl@0
  1997
            size1_ (size), size2_ (size) {}
sl@0
  1998
        BOOST_UBLAS_INLINE
sl@0
  1999
        zero_matrix (size_type size1, size_type size2):
sl@0
  2000
            matrix_container<self_type> (),
sl@0
  2001
            size1_ (size1), size2_ (size2) {}
sl@0
  2002
        BOOST_UBLAS_INLINE
sl@0
  2003
        zero_matrix (const zero_matrix &m):
sl@0
  2004
            matrix_container<self_type> (),
sl@0
  2005
            size1_ (m.size1_), size2_ (m.size2_) {}
sl@0
  2006
sl@0
  2007
        // Accessors
sl@0
  2008
        BOOST_UBLAS_INLINE
sl@0
  2009
        size_type size1 () const {
sl@0
  2010
            return size1_;
sl@0
  2011
        }
sl@0
  2012
        BOOST_UBLAS_INLINE
sl@0
  2013
        size_type size2 () const {
sl@0
  2014
            return size2_;
sl@0
  2015
        }
sl@0
  2016
sl@0
  2017
        // Resizing
sl@0
  2018
        BOOST_UBLAS_INLINE
sl@0
  2019
        void resize (size_type size, bool preserve = true) {
sl@0
  2020
            size1_ = size;
sl@0
  2021
            size2_ = size;
sl@0
  2022
        }
sl@0
  2023
        BOOST_UBLAS_INLINE
sl@0
  2024
        void resize (size_type size1, size_type size2, bool /*preserve*/ = true) {
sl@0
  2025
            size1_ = size1;
sl@0
  2026
            size2_ = size2;
sl@0
  2027
        }
sl@0
  2028
sl@0
  2029
        // Element access
sl@0
  2030
        BOOST_UBLAS_INLINE
sl@0
  2031
        const_reference operator () (size_type /* i */, size_type /* j */) const {
sl@0
  2032
            return zero_;
sl@0
  2033
        }
sl@0
  2034
sl@0
  2035
        // Assignment
sl@0
  2036
        BOOST_UBLAS_INLINE
sl@0
  2037
        zero_matrix &operator = (const zero_matrix &m) {
sl@0
  2038
            size1_ = m.size1_;
sl@0
  2039
            size2_ = m.size2_;
sl@0
  2040
            return *this;
sl@0
  2041
        }
sl@0
  2042
        BOOST_UBLAS_INLINE
sl@0
  2043
        zero_matrix &assign_temporary (zero_matrix &m) {
sl@0
  2044
            swap (m);
sl@0
  2045
            return *this;
sl@0
  2046
        }
sl@0
  2047
sl@0
  2048
        // Swapping
sl@0
  2049
        BOOST_UBLAS_INLINE
sl@0
  2050
        void swap (zero_matrix &m) {
sl@0
  2051
            if (this != &m) {
sl@0
  2052
                std::swap (size1_, m.size1_);
sl@0
  2053
                std::swap (size2_, m.size2_);
sl@0
  2054
            }
sl@0
  2055
        }
sl@0
  2056
        BOOST_UBLAS_INLINE
sl@0
  2057
        friend void swap (zero_matrix &m1, zero_matrix &m2) {
sl@0
  2058
            m1.swap (m2);
sl@0
  2059
        }
sl@0
  2060
sl@0
  2061
        // Iterator types
sl@0
  2062
    public:
sl@0
  2063
        class const_iterator1;
sl@0
  2064
        class const_iterator2;
sl@0
  2065
        typedef reverse_iterator_base1<const_iterator1> const_reverse_iterator1;
sl@0
  2066
        typedef reverse_iterator_base2<const_iterator2> const_reverse_iterator2;
sl@0
  2067
sl@0
  2068
        // Element lookup
sl@0
  2069
        BOOST_UBLAS_INLINE
sl@0
  2070
        const_iterator1 find1 (int /*rank*/, size_type /*i*/, size_type /*j*/) const {
sl@0
  2071
            return const_iterator1 (*this);
sl@0
  2072
        }
sl@0
  2073
        BOOST_UBLAS_INLINE
sl@0
  2074
        const_iterator2 find2 (int /*rank*/, size_type /*i*/, size_type /*j*/) const {
sl@0
  2075
            return const_iterator2 (*this);
sl@0
  2076
        }
sl@0
  2077
sl@0
  2078
        class const_iterator1:
sl@0
  2079
            public container_const_reference<zero_matrix>,
sl@0
  2080
            public bidirectional_iterator_base<sparse_bidirectional_iterator_tag,
sl@0
  2081
                                               const_iterator1, value_type> {
sl@0
  2082
        public:
sl@0
  2083
            typedef typename zero_matrix::value_type value_type;
sl@0
  2084
            typedef typename zero_matrix::difference_type difference_type;
sl@0
  2085
            typedef typename zero_matrix::const_reference reference;
sl@0
  2086
            typedef typename zero_matrix::const_pointer pointer;
sl@0
  2087
sl@0
  2088
            typedef const_iterator2 dual_iterator_type;
sl@0
  2089
            typedef const_reverse_iterator2 dual_reverse_iterator_type;
sl@0
  2090
sl@0
  2091
            // Construction and destruction
sl@0
  2092
            BOOST_UBLAS_INLINE
sl@0
  2093
            const_iterator1 ():
sl@0
  2094
                container_const_reference<self_type> () {}
sl@0
  2095
            BOOST_UBLAS_INLINE
sl@0
  2096
            const_iterator1 (const self_type &m):
sl@0
  2097
                container_const_reference<self_type> (m) {}
sl@0
  2098
sl@0
  2099
            // Arithmetic
sl@0
  2100
            BOOST_UBLAS_INLINE
sl@0
  2101
            const_iterator1 &operator ++ () {
sl@0
  2102
                BOOST_UBLAS_CHECK_FALSE (bad_index ());
sl@0
  2103
                return *this;
sl@0
  2104
            }
sl@0
  2105
            BOOST_UBLAS_INLINE
sl@0
  2106
            const_iterator1 &operator -- () {
sl@0
  2107
                BOOST_UBLAS_CHECK_FALSE (bad_index ());
sl@0
  2108
                return *this;
sl@0
  2109
            }
sl@0
  2110
sl@0
  2111
            // Dereference
sl@0
  2112
            BOOST_UBLAS_INLINE
sl@0
  2113
            const_reference operator * () const {
sl@0
  2114
                BOOST_UBLAS_CHECK_FALSE (bad_index ());
sl@0
  2115
                return zero_;   // arbitary return value
sl@0
  2116
            }
sl@0
  2117
sl@0
  2118
#ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
sl@0
  2119
            BOOST_UBLAS_INLINE
sl@0
  2120
#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
sl@0
  2121
            typename self_type::
sl@0
  2122
#endif
sl@0
  2123
            const_iterator2 begin () const {
sl@0
  2124
                return const_iterator2 ((*this) ());
sl@0
  2125
            }
sl@0
  2126
            BOOST_UBLAS_INLINE
sl@0
  2127
#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
sl@0
  2128
            typename self_type::
sl@0
  2129
#endif
sl@0
  2130
            const_iterator2 end () const {
sl@0
  2131
                return const_iterator2 ((*this) ());
sl@0
  2132
            }
sl@0
  2133
            BOOST_UBLAS_INLINE
sl@0
  2134
#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
sl@0
  2135
            typename self_type::
sl@0
  2136
#endif
sl@0
  2137
            const_reverse_iterator2 rbegin () const {
sl@0
  2138
                return const_reverse_iterator2 (end ());
sl@0
  2139
            }
sl@0
  2140
            BOOST_UBLAS_INLINE
sl@0
  2141
#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
sl@0
  2142
            typename self_type::
sl@0
  2143
#endif
sl@0
  2144
            const_reverse_iterator2 rend () const {
sl@0
  2145
                return const_reverse_iterator2 (begin ());
sl@0
  2146
            }
sl@0
  2147
#endif
sl@0
  2148
sl@0
  2149
            // Indices
sl@0
  2150
            BOOST_UBLAS_INLINE
sl@0
  2151
            size_type index1 () const {
sl@0
  2152
                BOOST_UBLAS_CHECK_FALSE (bad_index ());
sl@0
  2153
                return 0;   // arbitary return value
sl@0
  2154
            }
sl@0
  2155
            BOOST_UBLAS_INLINE
sl@0
  2156
            size_type index2 () const {
sl@0
  2157
                BOOST_UBLAS_CHECK_FALSE (bad_index ());
sl@0
  2158
                return 0;   // arbitary return value
sl@0
  2159
            }
sl@0
  2160
sl@0
  2161
            // Assignment
sl@0
  2162
            BOOST_UBLAS_INLINE
sl@0
  2163
            const_iterator1 &operator = (const const_iterator1 &it) {
sl@0
  2164
                container_const_reference<self_type>::assign (&it ());
sl@0
  2165
                return *this;
sl@0
  2166
            }
sl@0
  2167
sl@0
  2168
            // Comparison
sl@0
  2169
            BOOST_UBLAS_INLINE
sl@0
  2170
            bool operator == (const const_iterator1 &it) const {
sl@0
  2171
                BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
sl@0
  2172
                return true;
sl@0
  2173
            }
sl@0
  2174
        };
sl@0
  2175
sl@0
  2176
        typedef const_iterator1 iterator1;
sl@0
  2177
sl@0
  2178
        BOOST_UBLAS_INLINE
sl@0
  2179
        const_iterator1 begin1 () const {
sl@0
  2180
            return const_iterator1 (*this);
sl@0
  2181
        }
sl@0
  2182
        BOOST_UBLAS_INLINE
sl@0
  2183
        const_iterator1 end1 () const {
sl@0
  2184
            return const_iterator1 (*this);
sl@0
  2185
        }
sl@0
  2186
sl@0
  2187
        class const_iterator2:
sl@0
  2188
            public container_const_reference<zero_matrix>,
sl@0
  2189
            public bidirectional_iterator_base<sparse_bidirectional_iterator_tag,
sl@0
  2190
                                               const_iterator2, value_type> {
sl@0
  2191
        public:
sl@0
  2192
            typedef typename zero_matrix::value_type value_type;
sl@0
  2193
            typedef typename zero_matrix::difference_type difference_type;
sl@0
  2194
            typedef typename zero_matrix::const_reference reference;
sl@0
  2195
            typedef typename zero_matrix::const_pointer pointer;
sl@0
  2196
sl@0
  2197
            typedef const_iterator1 dual_iterator_type;
sl@0
  2198
            typedef const_reverse_iterator1 dual_reverse_iterator_type;
sl@0
  2199
sl@0
  2200
            // Construction and destruction
sl@0
  2201
            BOOST_UBLAS_INLINE
sl@0
  2202
            const_iterator2 ():
sl@0
  2203
                container_const_reference<self_type> () {}
sl@0
  2204
            BOOST_UBLAS_INLINE
sl@0
  2205
            const_iterator2 (const self_type &m):
sl@0
  2206
                container_const_reference<self_type> (m) {}
sl@0
  2207
sl@0
  2208
            // Arithmetic
sl@0
  2209
            BOOST_UBLAS_INLINE
sl@0
  2210
            const_iterator2 &operator ++ () {
sl@0
  2211
                BOOST_UBLAS_CHECK_FALSE (bad_index ());
sl@0
  2212
                return *this;
sl@0
  2213
            }
sl@0
  2214
            BOOST_UBLAS_INLINE
sl@0
  2215
            const_iterator2 &operator -- () {
sl@0
  2216
                BOOST_UBLAS_CHECK_FALSE (bad_index ());
sl@0
  2217
                return *this;
sl@0
  2218
            }
sl@0
  2219
sl@0
  2220
            // Dereference
sl@0
  2221
            BOOST_UBLAS_INLINE
sl@0
  2222
            const_reference operator * () const {
sl@0
  2223
                BOOST_UBLAS_CHECK_FALSE (bad_index ());
sl@0
  2224
                return zero_;   // arbitary return value
sl@0
  2225
            }
sl@0
  2226
sl@0
  2227
#ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
sl@0
  2228
            BOOST_UBLAS_INLINE
sl@0
  2229
#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
sl@0
  2230
            typename self_type::
sl@0
  2231
#endif
sl@0
  2232
            const_iterator1 begin () const {
sl@0
  2233
                return const_iterator1 ((*this) ());
sl@0
  2234
            }
sl@0
  2235
            BOOST_UBLAS_INLINE
sl@0
  2236
#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
sl@0
  2237
            typename self_type::
sl@0
  2238
#endif
sl@0
  2239
            const_iterator1 end () const {
sl@0
  2240
                return const_iterator1 ((*this) ());
sl@0
  2241
            }
sl@0
  2242
            BOOST_UBLAS_INLINE
sl@0
  2243
#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
sl@0
  2244
            typename self_type::
sl@0
  2245
#endif
sl@0
  2246
            const_reverse_iterator1 rbegin () const {
sl@0
  2247
                return const_reverse_iterator1 (end ());
sl@0
  2248
            }
sl@0
  2249
            BOOST_UBLAS_INLINE
sl@0
  2250
#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
sl@0
  2251
            typename self_type::
sl@0
  2252
#endif
sl@0
  2253
            const_reverse_iterator1 rend () const {
sl@0
  2254
                return const_reverse_iterator1 (begin ());
sl@0
  2255
            }
sl@0
  2256
#endif
sl@0
  2257
sl@0
  2258
            // Indices
sl@0
  2259
            BOOST_UBLAS_INLINE
sl@0
  2260
            size_type index1 () const {
sl@0
  2261
                BOOST_UBLAS_CHECK_FALSE (bad_index ());
sl@0
  2262
                return 0;   // arbitary return value
sl@0
  2263
            }
sl@0
  2264
            BOOST_UBLAS_INLINE
sl@0
  2265
            size_type index2 () const {
sl@0
  2266
                BOOST_UBLAS_CHECK_FALSE (bad_index ());
sl@0
  2267
                return 0;   // arbitary return value
sl@0
  2268
            }
sl@0
  2269
sl@0
  2270
            // Assignment
sl@0
  2271
            BOOST_UBLAS_INLINE
sl@0
  2272
            const_iterator2 &operator = (const const_iterator2 &it) {
sl@0
  2273
                container_const_reference<self_type>::assign (&it ());
sl@0
  2274
                return *this;
sl@0
  2275
            }
sl@0
  2276
sl@0
  2277
            // Comparison
sl@0
  2278
            BOOST_UBLAS_INLINE
sl@0
  2279
            bool operator == (const const_iterator2 &it) const {
sl@0
  2280
                BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
sl@0
  2281
                return true;
sl@0
  2282
            }
sl@0
  2283
        };
sl@0
  2284
sl@0
  2285
        typedef const_iterator2 iterator2;
sl@0
  2286
sl@0
  2287
        BOOST_UBLAS_INLINE
sl@0
  2288
        const_iterator2 begin2 () const {
sl@0
  2289
            return find2 (0, 0, 0);
sl@0
  2290
        }
sl@0
  2291
        BOOST_UBLAS_INLINE
sl@0
  2292
        const_iterator2 end2 () const {
sl@0
  2293
            return find2 (0, 0, size2_);
sl@0
  2294
        }
sl@0
  2295
sl@0
  2296
        // Reverse iterators
sl@0
  2297
sl@0
  2298
        BOOST_UBLAS_INLINE
sl@0
  2299
        const_reverse_iterator1 rbegin1 () const {
sl@0
  2300
            return const_reverse_iterator1 (end1 ());
sl@0
  2301
        }
sl@0
  2302
        BOOST_UBLAS_INLINE
sl@0
  2303
        const_reverse_iterator1 rend1 () const {
sl@0
  2304
            return const_reverse_iterator1 (begin1 ());
sl@0
  2305
        }
sl@0
  2306
sl@0
  2307
        BOOST_UBLAS_INLINE
sl@0
  2308
        const_reverse_iterator2 rbegin2 () const {
sl@0
  2309
            return const_reverse_iterator2 (end2 ());
sl@0
  2310
        }
sl@0
  2311
        BOOST_UBLAS_INLINE
sl@0
  2312
        const_reverse_iterator2 rend2 () const {
sl@0
  2313
            return const_reverse_iterator2 (begin2 ());
sl@0
  2314
        }
sl@0
  2315
sl@0
  2316
    private:
sl@0
  2317
        size_type size1_;
sl@0
  2318
        size_type size2_;
sl@0
  2319
        static const value_type zero_;
sl@0
  2320
    };
sl@0
  2321
sl@0
  2322
    template<class T>
sl@0
  2323
    const typename zero_matrix<T>::value_type zero_matrix<T>::zero_ (0);
sl@0
  2324
sl@0
  2325
sl@0
  2326
    // Identity matrix class
sl@0
  2327
    template<class T>
sl@0
  2328
    class identity_matrix:
sl@0
  2329
        public matrix_container<identity_matrix<T> > {
sl@0
  2330
sl@0
  2331
        typedef const T *const_pointer;
sl@0
  2332
        typedef identity_matrix<T> self_type;
sl@0
  2333
    public:
sl@0
  2334
#ifdef BOOST_UBLAS_ENABLE_PROXY_SHORTCUTS
sl@0
  2335
        using matrix_container<self_type>::operator ();
sl@0
  2336
#endif
sl@0
  2337
        typedef std::size_t size_type;
sl@0
  2338
        typedef std::ptrdiff_t difference_type;
sl@0
  2339
        typedef T value_type;
sl@0
  2340
        typedef const T &const_reference;
sl@0
  2341
        typedef T &reference;
sl@0
  2342
        typedef const matrix_reference<const self_type> const_closure_type;
sl@0
  2343
        typedef matrix_reference<self_type> closure_type;
sl@0
  2344
        typedef sparse_tag storage_category;
sl@0
  2345
        typedef unknown_orientation_tag orientation_category;
sl@0
  2346
sl@0
  2347
        // Construction and destruction
sl@0
  2348
        BOOST_UBLAS_INLINE
sl@0
  2349
        identity_matrix ():
sl@0
  2350
            matrix_container<self_type> (),
sl@0
  2351
            size1_ (0), size2_ (0), size_common_ (0) {}
sl@0
  2352
        BOOST_UBLAS_INLINE
sl@0
  2353
        identity_matrix (size_type size):
sl@0
  2354
            matrix_container<self_type> (),
sl@0
  2355
            size1_ (size), size2_ (size), size_common_ ((std::min) (size1_, size2_)) {}
sl@0
  2356
        BOOST_UBLAS_INLINE
sl@0
  2357
        identity_matrix (size_type size1, size_type size2):
sl@0
  2358
            matrix_container<self_type> (),
sl@0
  2359
            size1_ (size1), size2_ (size2), size_common_ ((std::min) (size1_, size2_)) {}
sl@0
  2360
        BOOST_UBLAS_INLINE
sl@0
  2361
        identity_matrix (const identity_matrix &m):
sl@0
  2362
            matrix_container<self_type> (),
sl@0
  2363
            size1_ (m.size1_), size2_ (m.size2_), size_common_ ((std::min) (size1_, size2_)) {}
sl@0
  2364
sl@0
  2365
        // Accessors
sl@0
  2366
        BOOST_UBLAS_INLINE
sl@0
  2367
        size_type size1 () const {
sl@0
  2368
            return size1_;
sl@0
  2369
        }
sl@0
  2370
        BOOST_UBLAS_INLINE
sl@0
  2371
        size_type size2 () const {
sl@0
  2372
            return size2_;
sl@0
  2373
        }
sl@0
  2374
sl@0
  2375
        // Resizing
sl@0
  2376
        BOOST_UBLAS_INLINE
sl@0
  2377
        void resize (size_type size, bool preserve = true) {
sl@0
  2378
            size1_ = size;
sl@0
  2379
            size2_ = size;
sl@0
  2380
        }
sl@0
  2381
        BOOST_UBLAS_INLINE
sl@0
  2382
        void resize (size_type size1, size_type size2, bool /*preserve*/ = true) {
sl@0
  2383
            size1_ = size1;
sl@0
  2384
            size2_ = size2;
sl@0
  2385
        }
sl@0
  2386
sl@0
  2387
        // Element access
sl@0
  2388
        BOOST_UBLAS_INLINE
sl@0
  2389
        const_reference operator () (size_type i, size_type j) const {
sl@0
  2390
            if (i == j)
sl@0
  2391
                return one_;
sl@0
  2392
            else
sl@0
  2393
                return zero_;
sl@0
  2394
        }
sl@0
  2395
sl@0
  2396
        // Assignment
sl@0
  2397
        BOOST_UBLAS_INLINE
sl@0
  2398
        identity_matrix &operator = (const identity_matrix &m) {
sl@0
  2399
            size1_ = m.size1_;
sl@0
  2400
            size2_ = m.size2_;
sl@0
  2401
            return *this;
sl@0
  2402
        }
sl@0
  2403
        BOOST_UBLAS_INLINE
sl@0
  2404
        identity_matrix &assign_temporary (identity_matrix &m) { 
sl@0
  2405
            swap (m);
sl@0
  2406
            return *this;
sl@0
  2407
        }
sl@0
  2408
sl@0
  2409
        // Swapping
sl@0
  2410
        BOOST_UBLAS_INLINE
sl@0
  2411
        void swap (identity_matrix &m) {
sl@0
  2412
            if (this != &m) {
sl@0
  2413
                std::swap (size1_, m.size1_);
sl@0
  2414
                std::swap (size2_, m.size2_);
sl@0
  2415
            }
sl@0
  2416
        }
sl@0
  2417
        BOOST_UBLAS_INLINE
sl@0
  2418
        friend void swap (identity_matrix &m1, identity_matrix &m2) {
sl@0
  2419
            m1.swap (m2);
sl@0
  2420
        }
sl@0
  2421
sl@0
  2422
        // Iterator types
sl@0
  2423
    private:
sl@0
  2424
        // Use an index
sl@0
  2425
        typedef size_type const_subiterator_type;
sl@0
  2426
sl@0
  2427
    public:
sl@0
  2428
        class const_iterator1;
sl@0
  2429
        class const_iterator2;
sl@0
  2430
        typedef reverse_iterator_base1<const_iterator1> const_reverse_iterator1;
sl@0
  2431
        typedef reverse_iterator_base2<const_iterator2> const_reverse_iterator2;
sl@0
  2432
sl@0
  2433
        // Element lookup
sl@0
  2434
        BOOST_UBLAS_INLINE
sl@0
  2435
        const_iterator1 find1 (int rank, size_type i, size_type j) const {
sl@0
  2436
            if (rank == 1) {
sl@0
  2437
                i = (std::max) (i, j);
sl@0
  2438
                i = (std::min) (i, j + 1);
sl@0
  2439
            }
sl@0
  2440
            return const_iterator1 (*this, i);
sl@0
  2441
        }
sl@0
  2442
        BOOST_UBLAS_INLINE
sl@0
  2443
        const_iterator2 find2 (int rank, size_type i, size_type j) const {
sl@0
  2444
            if (rank == 1) {
sl@0
  2445
                j = (std::max) (j, i);
sl@0
  2446
                j = (std::min) (j, i + 1);
sl@0
  2447
            }
sl@0
  2448
            return const_iterator2 (*this, j);
sl@0
  2449
        }
sl@0
  2450
sl@0
  2451
sl@0
  2452
        class const_iterator1:
sl@0
  2453
            public container_const_reference<identity_matrix>,
sl@0
  2454
            public bidirectional_iterator_base<sparse_bidirectional_iterator_tag,
sl@0
  2455
                                               const_iterator1, value_type> {
sl@0
  2456
        public:
sl@0
  2457
            typedef typename identity_matrix::value_type value_type;
sl@0
  2458
            typedef typename identity_matrix::difference_type difference_type;
sl@0
  2459
            typedef typename identity_matrix::const_reference reference;
sl@0
  2460
            typedef typename identity_matrix::const_pointer pointer;
sl@0
  2461
sl@0
  2462
            typedef const_iterator2 dual_iterator_type;
sl@0
  2463
            typedef const_reverse_iterator2 dual_reverse_iterator_type;
sl@0
  2464
sl@0
  2465
            // Construction and destruction
sl@0
  2466
            BOOST_UBLAS_INLINE
sl@0
  2467
            const_iterator1 ():
sl@0
  2468
                container_const_reference<self_type> (), it_ () {}
sl@0
  2469
            BOOST_UBLAS_INLINE
sl@0
  2470
            const_iterator1 (const self_type &m, const const_subiterator_type &it):
sl@0
  2471
                container_const_reference<self_type> (m), it_ (it) {}
sl@0
  2472
sl@0
  2473
            // Arithmetic
sl@0
  2474
            BOOST_UBLAS_INLINE
sl@0
  2475
            const_iterator1 &operator ++ () {
sl@0
  2476
                BOOST_UBLAS_CHECK (it_ < (*this) ().size1 (), bad_index ());
sl@0
  2477
                ++it_;
sl@0
  2478
                return *this;
sl@0
  2479
            }
sl@0
  2480
            BOOST_UBLAS_INLINE
sl@0
  2481
            const_iterator1 &operator -- () {
sl@0
  2482
                BOOST_UBLAS_CHECK (it_ > 0, bad_index ());
sl@0
  2483
                --it_;
sl@0
  2484
                return *this;
sl@0
  2485
            }
sl@0
  2486
sl@0
  2487
            // Dereference
sl@0
  2488
            BOOST_UBLAS_INLINE
sl@0
  2489
            const_reference operator * () const {
sl@0
  2490
                return one_;
sl@0
  2491
            }
sl@0
  2492
sl@0
  2493
#ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
sl@0
  2494
            BOOST_UBLAS_INLINE
sl@0
  2495
#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
sl@0
  2496
            typename self_type::
sl@0
  2497
#endif
sl@0
  2498
            const_iterator2 begin () const {
sl@0
  2499
                return const_iterator2 ((*this) (), it_); 
sl@0
  2500
            }
sl@0
  2501
            BOOST_UBLAS_INLINE
sl@0
  2502
#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
sl@0
  2503
            typename self_type::
sl@0
  2504
#endif
sl@0
  2505
            const_iterator2 end () const {
sl@0
  2506
                return const_iterator2 ((*this) (), it_ + 1); 
sl@0
  2507
            }
sl@0
  2508
            BOOST_UBLAS_INLINE
sl@0
  2509
#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
sl@0
  2510
            typename self_type::
sl@0
  2511
#endif
sl@0
  2512
            const_reverse_iterator2 rbegin () const {
sl@0
  2513
                return const_reverse_iterator2 (end ());
sl@0
  2514
            }
sl@0
  2515
            BOOST_UBLAS_INLINE
sl@0
  2516
#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
sl@0
  2517
            typename self_type::
sl@0
  2518
#endif
sl@0
  2519
            const_reverse_iterator2 rend () const {
sl@0
  2520
                return const_reverse_iterator2 (begin ());
sl@0
  2521
            }
sl@0
  2522
#endif
sl@0
  2523
sl@0
  2524
            // Indices
sl@0
  2525
            BOOST_UBLAS_INLINE
sl@0
  2526
            size_type index1 () const {
sl@0
  2527
                return it_;
sl@0
  2528
            }
sl@0
  2529
            BOOST_UBLAS_INLINE
sl@0
  2530
            size_type index2 () const {
sl@0
  2531
                return it_;
sl@0
  2532
            }
sl@0
  2533
sl@0
  2534
            // Assignment
sl@0
  2535
            BOOST_UBLAS_INLINE
sl@0
  2536
            const_iterator1 &operator = (const const_iterator1 &it) {
sl@0
  2537
                container_const_reference<self_type>::assign (&it ());
sl@0
  2538
                it_ = it.it_;
sl@0
  2539
                return *this;
sl@0
  2540
            }
sl@0
  2541
sl@0
  2542
            // Comparison
sl@0
  2543
            BOOST_UBLAS_INLINE
sl@0
  2544
            bool operator == (const const_iterator1 &it) const {
sl@0
  2545
                BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
sl@0
  2546
                return it_ == it.it_;
sl@0
  2547
            }
sl@0
  2548
sl@0
  2549
        private:
sl@0
  2550
            const_subiterator_type it_;
sl@0
  2551
        };
sl@0
  2552
sl@0
  2553
        typedef const_iterator1 iterator1;
sl@0
  2554
sl@0
  2555
        BOOST_UBLAS_INLINE
sl@0
  2556
        const_iterator1 begin1 () const {
sl@0
  2557
            return const_iterator1 (*this, 0);
sl@0
  2558
        }
sl@0
  2559
        BOOST_UBLAS_INLINE
sl@0
  2560
        const_iterator1 end1 () const {
sl@0
  2561
            return const_iterator1 (*this, size_common_);
sl@0
  2562
        }
sl@0
  2563
sl@0
  2564
        class const_iterator2:
sl@0
  2565
            public container_const_reference<identity_matrix>,
sl@0
  2566
            public bidirectional_iterator_base<sparse_bidirectional_iterator_tag,
sl@0
  2567
                                               const_iterator2, value_type> {
sl@0
  2568
        public:
sl@0
  2569
            typedef typename identity_matrix::value_type value_type;
sl@0
  2570
            typedef typename identity_matrix::difference_type difference_type;
sl@0
  2571
            typedef typename identity_matrix::const_reference reference;
sl@0
  2572
            typedef typename identity_matrix::const_pointer pointer;
sl@0
  2573
sl@0
  2574
            typedef const_iterator1 dual_iterator_type;
sl@0
  2575
            typedef const_reverse_iterator1 dual_reverse_iterator_type;
sl@0
  2576
sl@0
  2577
            // Construction and destruction
sl@0
  2578
            BOOST_UBLAS_INLINE
sl@0
  2579
            const_iterator2 ():
sl@0
  2580
                container_const_reference<self_type> (), it_ () {}
sl@0
  2581
            BOOST_UBLAS_INLINE
sl@0
  2582
            const_iterator2 (const self_type &m, const const_subiterator_type &it):
sl@0
  2583
                container_const_reference<self_type> (m), it_ (it) {}
sl@0
  2584
sl@0
  2585
            // Arithmetic
sl@0
  2586
            BOOST_UBLAS_INLINE
sl@0
  2587
            const_iterator2 &operator ++ () {
sl@0
  2588
                BOOST_UBLAS_CHECK (it_ < (*this) ().size_common_, bad_index ());
sl@0
  2589
                ++it_;
sl@0
  2590
                return *this;
sl@0
  2591
            }
sl@0
  2592
            BOOST_UBLAS_INLINE
sl@0
  2593
            const_iterator2 &operator -- () {
sl@0
  2594
                BOOST_UBLAS_CHECK (it_ > 0, bad_index ());
sl@0
  2595
                --it_;
sl@0
  2596
                return *this;
sl@0
  2597
            }
sl@0
  2598
sl@0
  2599
            // Dereference
sl@0
  2600
            BOOST_UBLAS_INLINE
sl@0
  2601
            const_reference operator * () const {
sl@0
  2602
                return one_;
sl@0
  2603
            }
sl@0
  2604
sl@0
  2605
#ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
sl@0
  2606
            BOOST_UBLAS_INLINE
sl@0
  2607
#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
sl@0
  2608
            typename self_type::
sl@0
  2609
#endif
sl@0
  2610
            const_iterator1 begin () const {
sl@0
  2611
                return const_iterator1 ((*this) (), it_); 
sl@0
  2612
            }
sl@0
  2613
            BOOST_UBLAS_INLINE
sl@0
  2614
#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
sl@0
  2615
            typename self_type::
sl@0
  2616
#endif
sl@0
  2617
            const_iterator1 end () const {
sl@0
  2618
                return const_iterator1 ((*this) (), it_ + 1); 
sl@0
  2619
            }
sl@0
  2620
            BOOST_UBLAS_INLINE
sl@0
  2621
#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
sl@0
  2622
            typename self_type::
sl@0
  2623
#endif
sl@0
  2624
            const_reverse_iterator1 rbegin () const {
sl@0
  2625
                return const_reverse_iterator1 (end ());
sl@0
  2626
            }
sl@0
  2627
            BOOST_UBLAS_INLINE
sl@0
  2628
#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
sl@0
  2629
            typename self_type::
sl@0
  2630
#endif
sl@0
  2631
            const_reverse_iterator1 rend () const {
sl@0
  2632
                return const_reverse_iterator1 (begin ());
sl@0
  2633
            }
sl@0
  2634
#endif
sl@0
  2635
sl@0
  2636
            // Indices
sl@0
  2637
            BOOST_UBLAS_INLINE
sl@0
  2638
            size_type index1 () const {
sl@0
  2639
                return it_;
sl@0
  2640
            }
sl@0
  2641
            BOOST_UBLAS_INLINE
sl@0
  2642
            size_type index2 () const {
sl@0
  2643
                return it_;
sl@0
  2644
            }
sl@0
  2645
sl@0
  2646
            // Assignment
sl@0
  2647
            BOOST_UBLAS_INLINE
sl@0
  2648
            const_iterator2 &operator = (const const_iterator2 &it) {
sl@0
  2649
                container_const_reference<self_type>::assign (&it ());
sl@0
  2650
                it_ = it.it_;
sl@0
  2651
                return *this;
sl@0
  2652
            }
sl@0
  2653
sl@0
  2654
            // Comparison
sl@0
  2655
            BOOST_UBLAS_INLINE
sl@0
  2656
            bool operator == (const const_iterator2 &it) const {
sl@0
  2657
                BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
sl@0
  2658
                return it_ == it.it_;
sl@0
  2659
            }
sl@0
  2660
sl@0
  2661
        private:
sl@0
  2662
            const_subiterator_type it_;
sl@0
  2663
        };
sl@0
  2664
sl@0
  2665
        typedef const_iterator2 iterator2;
sl@0
  2666
sl@0
  2667
        BOOST_UBLAS_INLINE
sl@0
  2668
        const_iterator2 begin2 () const {
sl@0
  2669
            return const_iterator2 (*this, 0);
sl@0
  2670
        }
sl@0
  2671
        BOOST_UBLAS_INLINE
sl@0
  2672
        const_iterator2 end2 () const {
sl@0
  2673
            return const_iterator2 (*this, size_common_);
sl@0
  2674
        }
sl@0
  2675
sl@0
  2676
        // Reverse iterators
sl@0
  2677
sl@0
  2678
        BOOST_UBLAS_INLINE
sl@0
  2679
        const_reverse_iterator1 rbegin1 () const {
sl@0
  2680
            return const_reverse_iterator1 (end1 ());
sl@0
  2681
        }
sl@0
  2682
        BOOST_UBLAS_INLINE
sl@0
  2683
        const_reverse_iterator1 rend1 () const {
sl@0
  2684
            return const_reverse_iterator1 (begin1 ());
sl@0
  2685
        }
sl@0
  2686
sl@0
  2687
        BOOST_UBLAS_INLINE
sl@0
  2688
        const_reverse_iterator2 rbegin2 () const {
sl@0
  2689
            return const_reverse_iterator2 (end2 ());
sl@0
  2690
        }
sl@0
  2691
        BOOST_UBLAS_INLINE
sl@0
  2692
        const_reverse_iterator2 rend2 () const {
sl@0
  2693
            return const_reverse_iterator2 (begin2 ());
sl@0
  2694
        }
sl@0
  2695
sl@0
  2696
    private:
sl@0
  2697
        size_type size1_;
sl@0
  2698
        size_type size2_;
sl@0
  2699
        size_type size_common_;
sl@0
  2700
        static const value_type zero_;
sl@0
  2701
        static const value_type one_;
sl@0
  2702
    };
sl@0
  2703
sl@0
  2704
    template<class T>
sl@0
  2705
    const typename identity_matrix<T>::value_type identity_matrix<T>::zero_ (0);
sl@0
  2706
    template<class T>
sl@0
  2707
    const typename identity_matrix<T>::value_type identity_matrix<T>::one_ (1);
sl@0
  2708
sl@0
  2709
sl@0
  2710
    // Scalar matrix class
sl@0
  2711
    template<class T>
sl@0
  2712
    class scalar_matrix:
sl@0
  2713
        public matrix_container<scalar_matrix<T> > {
sl@0
  2714
sl@0
  2715
        typedef const T *const_pointer;
sl@0
  2716
        typedef scalar_matrix<T> self_type;
sl@0
  2717
    public:
sl@0
  2718
#ifdef BOOST_UBLAS_ENABLE_PROXY_SHORTCUTS
sl@0
  2719
        using matrix_container<self_type>::operator ();
sl@0
  2720
#endif
sl@0
  2721
        typedef std::size_t size_type;
sl@0
  2722
        typedef std::ptrdiff_t difference_type;
sl@0
  2723
        typedef T value_type;
sl@0
  2724
        typedef const T &const_reference;
sl@0
  2725
        typedef T &reference;
sl@0
  2726
        typedef const matrix_reference<const self_type> const_closure_type;
sl@0
  2727
        typedef dense_tag storage_category;
sl@0
  2728
        typedef unknown_orientation_tag orientation_category;
sl@0
  2729
sl@0
  2730
        // Construction and destruction
sl@0
  2731
        BOOST_UBLAS_INLINE
sl@0
  2732
        scalar_matrix ():
sl@0
  2733
            matrix_container<self_type> (),
sl@0
  2734
            size1_ (0), size2_ (0), value_ () {}
sl@0
  2735
        BOOST_UBLAS_INLINE
sl@0
  2736
        scalar_matrix (size_type size1, size_type size2, const value_type &value = value_type(1)):
sl@0
  2737
            matrix_container<self_type> (),
sl@0
  2738
            size1_ (size1), size2_ (size2), value_ (value) {}
sl@0
  2739
        BOOST_UBLAS_INLINE
sl@0
  2740
        scalar_matrix (const scalar_matrix &m):
sl@0
  2741
            matrix_container<self_type> (),
sl@0
  2742
            size1_ (m.size1_), size2_ (m.size2_), value_ (m.value_) {}
sl@0
  2743
sl@0
  2744
        // Accessors
sl@0
  2745
        BOOST_UBLAS_INLINE
sl@0
  2746
        size_type size1 () const {
sl@0
  2747
            return size1_;
sl@0
  2748
        }
sl@0
  2749
        BOOST_UBLAS_INLINE
sl@0
  2750
        size_type size2 () const {
sl@0
  2751
            return size2_;
sl@0
  2752
        }
sl@0
  2753
sl@0
  2754
        // Resizing
sl@0
  2755
        BOOST_UBLAS_INLINE
sl@0
  2756
        void resize (size_type size1, size_type size2, bool /*preserve*/ = true) {
sl@0
  2757
            size1_ = size1;
sl@0
  2758
            size2_ = size2;
sl@0
  2759
        }
sl@0
  2760
sl@0
  2761
        // Element access
sl@0
  2762
        BOOST_UBLAS_INLINE
sl@0
  2763
        const_reference operator () (size_type /*i*/, size_type /*j*/) const {
sl@0
  2764
            return value_; 
sl@0
  2765
        }
sl@0
  2766
sl@0
  2767
        // Assignment
sl@0
  2768
        BOOST_UBLAS_INLINE
sl@0
  2769
        scalar_matrix &operator = (const scalar_matrix &m) {
sl@0
  2770
            size1_ = m.size1_;
sl@0
  2771
            size2_ = m.size2_;
sl@0
  2772
            value_ = m.value_;
sl@0
  2773
            return *this;
sl@0
  2774
        }
sl@0
  2775
        BOOST_UBLAS_INLINE
sl@0
  2776
        scalar_matrix &assign_temporary (scalar_matrix &m) { 
sl@0
  2777
            swap (m);
sl@0
  2778
            return *this;
sl@0
  2779
        }
sl@0
  2780
sl@0
  2781
        // Swapping
sl@0
  2782
        BOOST_UBLAS_INLINE
sl@0
  2783
        void swap (scalar_matrix &m) {
sl@0
  2784
            if (this != &m) {
sl@0
  2785
                std::swap (size1_, m.size1_);
sl@0
  2786
                std::swap (size2_, m.size2_);
sl@0
  2787
                std::swap (value_, m.value_);
sl@0
  2788
            }
sl@0
  2789
        }
sl@0
  2790
        BOOST_UBLAS_INLINE
sl@0
  2791
        friend void swap (scalar_matrix &m1, scalar_matrix &m2) {
sl@0
  2792
            m1.swap (m2);
sl@0
  2793
        }
sl@0
  2794
sl@0
  2795
        // Iterator types
sl@0
  2796
    private:
sl@0
  2797
        // Use an index
sl@0
  2798
        typedef size_type const_subiterator_type;
sl@0
  2799
sl@0
  2800
    public:
sl@0
  2801
#ifdef BOOST_UBLAS_USE_INDEXED_ITERATOR
sl@0
  2802
        typedef indexed_const_iterator1<self_type, dense_random_access_iterator_tag> iterator1;
sl@0
  2803
        typedef indexed_const_iterator2<self_type, dense_random_access_iterator_tag> iterator2;
sl@0
  2804
        typedef indexed_const_iterator1<self_type, dense_random_access_iterator_tag> const_iterator1;
sl@0
  2805
        typedef indexed_const_iterator2<self_type, dense_random_access_iterator_tag> const_iterator2;
sl@0
  2806
#else
sl@0
  2807
        class const_iterator1;
sl@0
  2808
        class const_iterator2;
sl@0
  2809
#endif
sl@0
  2810
        typedef reverse_iterator_base1<const_iterator1> const_reverse_iterator1;
sl@0
  2811
        typedef reverse_iterator_base2<const_iterator2> const_reverse_iterator2;
sl@0
  2812
sl@0
  2813
        // Element lookup
sl@0
  2814
        BOOST_UBLAS_INLINE
sl@0
  2815
        const_iterator1 find1 (int /*rank*/, size_type i, size_type j) const {
sl@0
  2816
            return const_iterator1 (*this, i, j);
sl@0
  2817
        }
sl@0
  2818
        BOOST_UBLAS_INLINE
sl@0
  2819
        const_iterator2 find2 (int /*rank*/, size_type i, size_type j) const {
sl@0
  2820
            return const_iterator2 (*this, i, j);
sl@0
  2821
        }   
sl@0
  2822
sl@0
  2823
sl@0
  2824
#ifndef BOOST_UBLAS_USE_INDEXED_ITERATOR
sl@0
  2825
        class const_iterator1:
sl@0
  2826
            public container_const_reference<scalar_matrix>,
sl@0
  2827
            public random_access_iterator_base<dense_random_access_iterator_tag,
sl@0
  2828
                                               const_iterator1, value_type> {
sl@0
  2829
        public:
sl@0
  2830
            typedef typename scalar_matrix::value_type value_type;
sl@0
  2831
            typedef typename scalar_matrix::difference_type difference_type;
sl@0
  2832
            typedef typename scalar_matrix::const_reference reference;
sl@0
  2833
            typedef typename scalar_matrix::const_pointer pointer;
sl@0
  2834
sl@0
  2835
            typedef const_iterator2 dual_iterator_type;
sl@0
  2836
            typedef const_reverse_iterator2 dual_reverse_iterator_type;
sl@0
  2837
sl@0
  2838
            // Construction and destruction
sl@0
  2839
            BOOST_UBLAS_INLINE
sl@0
  2840
            const_iterator1 ():
sl@0
  2841
                container_const_reference<scalar_matrix> (), it1_ (), it2_ () {}
sl@0
  2842
            BOOST_UBLAS_INLINE
sl@0
  2843
            const_iterator1 (const scalar_matrix &m, const const_subiterator_type &it1, const const_subiterator_type &it2):
sl@0
  2844
                container_const_reference<scalar_matrix> (m), it1_ (it1), it2_ (it2) {}
sl@0
  2845
sl@0
  2846
            // Arithmetic
sl@0
  2847
            BOOST_UBLAS_INLINE
sl@0
  2848
            const_iterator1 &operator ++ () {
sl@0
  2849
                ++ it1_;
sl@0
  2850
                return *this;
sl@0
  2851
            }
sl@0
  2852
            BOOST_UBLAS_INLINE
sl@0
  2853
            const_iterator1 &operator -- () {
sl@0
  2854
                -- it1_;
sl@0
  2855
                return *this;
sl@0
  2856
            }
sl@0
  2857
            BOOST_UBLAS_INLINE
sl@0
  2858
            const_iterator1 &operator += (difference_type n) {
sl@0
  2859
                it1_ += n;
sl@0
  2860
                return *this;
sl@0
  2861
            }
sl@0
  2862
            BOOST_UBLAS_INLINE
sl@0
  2863
            const_iterator1 &operator -= (difference_type n) {
sl@0
  2864
                it1_ -= n;
sl@0
  2865
                return *this;
sl@0
  2866
            }
sl@0
  2867
            BOOST_UBLAS_INLINE
sl@0
  2868
            difference_type operator - (const const_iterator1 &it) const {
sl@0
  2869
                BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
sl@0
  2870
                BOOST_UBLAS_CHECK (it2_ == it.it2_, external_logic ());
sl@0
  2871
                return it1_ - it.it1_;
sl@0
  2872
            }
sl@0
  2873
sl@0
  2874
            // Dereference
sl@0
  2875
            BOOST_UBLAS_INLINE
sl@0
  2876
            const_reference operator * () const {
sl@0
  2877
                BOOST_UBLAS_CHECK (index1 () < (*this) ().size1 (), bad_index ());
sl@0
  2878
                BOOST_UBLAS_CHECK (index2 () < (*this) ().size2 (), bad_index ());
sl@0
  2879
                return (*this) () (index1 (), index2 ());
sl@0
  2880
            }
sl@0
  2881
            BOOST_UBLAS_INLINE
sl@0
  2882
            const_reference operator [] (difference_type n) const {
sl@0
  2883
                return *(*this + n);
sl@0
  2884
            }
sl@0
  2885
sl@0
  2886
#ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
sl@0
  2887
            BOOST_UBLAS_INLINE
sl@0
  2888
#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
sl@0
  2889
            typename self_type::
sl@0
  2890
#endif
sl@0
  2891
            const_iterator2 begin () const {
sl@0
  2892
                const scalar_matrix &m = (*this) ();
sl@0
  2893
                return m.find2 (1, index1 (), 0);
sl@0
  2894
            }
sl@0
  2895
            BOOST_UBLAS_INLINE
sl@0
  2896
#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
sl@0
  2897
            typename self_type::
sl@0
  2898
#endif
sl@0
  2899
            const_iterator2 end () const {
sl@0
  2900
                const scalar_matrix &m = (*this) ();
sl@0
  2901
                return m.find2 (1, index1 (), m.size2 ());
sl@0
  2902
            }
sl@0
  2903
            BOOST_UBLAS_INLINE
sl@0
  2904
#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
sl@0
  2905
            typename self_type::
sl@0
  2906
#endif
sl@0
  2907
            const_reverse_iterator2 rbegin () const {
sl@0
  2908
                return const_reverse_iterator2 (end ());
sl@0
  2909
            }
sl@0
  2910
            BOOST_UBLAS_INLINE
sl@0
  2911
#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
sl@0
  2912
            typename self_type::
sl@0
  2913
#endif
sl@0
  2914
            const_reverse_iterator2 rend () const {
sl@0
  2915
                return const_reverse_iterator2 (begin ());
sl@0
  2916
            }
sl@0
  2917
#endif
sl@0
  2918
sl@0
  2919
            // Indices
sl@0
  2920
            BOOST_UBLAS_INLINE
sl@0
  2921
            size_type index1 () const {
sl@0
  2922
                return it1_;
sl@0
  2923
            }
sl@0
  2924
            BOOST_UBLAS_INLINE
sl@0
  2925
            size_type index2 () const {
sl@0
  2926
                return it2_;
sl@0
  2927
            }
sl@0
  2928
sl@0
  2929
            // Assignment
sl@0
  2930
            BOOST_UBLAS_INLINE
sl@0
  2931
            const_iterator1 &operator = (const const_iterator1 &it) {
sl@0
  2932
                container_const_reference<scalar_matrix>::assign (&it ());
sl@0
  2933
                it1_ = it.it1_;
sl@0
  2934
                it2_ = it.it2_;
sl@0
  2935
                return *this;
sl@0
  2936
            }
sl@0
  2937
sl@0
  2938
            // Comparison
sl@0
  2939
            BOOST_UBLAS_INLINE
sl@0
  2940
            bool operator == (const const_iterator1 &it) const {
sl@0
  2941
                BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
sl@0
  2942
                BOOST_UBLAS_CHECK (it2_ == it.it2_, external_logic ());
sl@0
  2943
                return it1_ == it.it1_;
sl@0
  2944
            }
sl@0
  2945
            BOOST_UBLAS_INLINE
sl@0
  2946
            bool operator < (const const_iterator1 &it) const {
sl@0
  2947
                BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
sl@0
  2948
                BOOST_UBLAS_CHECK (it2_ == it.it2_, external_logic ());
sl@0
  2949
                return it1_ < it.it1_;
sl@0
  2950
            }
sl@0
  2951
sl@0
  2952
        private:
sl@0
  2953
            const_subiterator_type it1_;
sl@0
  2954
            const_subiterator_type it2_;
sl@0
  2955
        };
sl@0
  2956
sl@0
  2957
        typedef const_iterator1 iterator1;
sl@0
  2958
#endif
sl@0
  2959
sl@0
  2960
        BOOST_UBLAS_INLINE
sl@0
  2961
        const_iterator1 begin1 () const {
sl@0
  2962
            return find1 (0, 0, 0);
sl@0
  2963
        }
sl@0
  2964
        BOOST_UBLAS_INLINE
sl@0
  2965
        const_iterator1 end1 () const {
sl@0
  2966
            return find1 (0, size1_, 0);
sl@0
  2967
        }
sl@0
  2968
sl@0
  2969
#ifndef BOOST_UBLAS_USE_INDEXED_ITERATOR
sl@0
  2970
        class const_iterator2:
sl@0
  2971
            public container_const_reference<scalar_matrix>,
sl@0
  2972
            public random_access_iterator_base<dense_random_access_iterator_tag,
sl@0
  2973
                                               const_iterator2, value_type> {
sl@0
  2974
        public:
sl@0
  2975
            typedef typename scalar_matrix::value_type value_type;
sl@0
  2976
            typedef typename scalar_matrix::difference_type difference_type;
sl@0
  2977
            typedef typename scalar_matrix::const_reference reference;
sl@0
  2978
            typedef typename scalar_matrix::const_pointer pointer;
sl@0
  2979
sl@0
  2980
            typedef const_iterator1 dual_iterator_type;
sl@0
  2981
            typedef const_reverse_iterator1 dual_reverse_iterator_type;
sl@0
  2982
sl@0
  2983
            // Construction and destruction
sl@0
  2984
            BOOST_UBLAS_INLINE
sl@0
  2985
            const_iterator2 ():
sl@0
  2986
                container_const_reference<scalar_matrix> (), it1_ (), it2_ () {}
sl@0
  2987
            BOOST_UBLAS_INLINE
sl@0
  2988
            const_iterator2 (const scalar_matrix &m, const const_subiterator_type &it1, const const_subiterator_type &it2):
sl@0
  2989
                container_const_reference<scalar_matrix> (m), it1_ (it1), it2_ (it2) {}
sl@0
  2990
sl@0
  2991
            // Arithmetic
sl@0
  2992
            BOOST_UBLAS_INLINE
sl@0
  2993
            const_iterator2 &operator ++ () {
sl@0
  2994
                ++ it2_;
sl@0
  2995
                return *this;
sl@0
  2996
            }
sl@0
  2997
            BOOST_UBLAS_INLINE
sl@0
  2998
            const_iterator2 &operator -- () {
sl@0
  2999
                -- it2_;
sl@0
  3000
                return *this;
sl@0
  3001
            }
sl@0
  3002
            BOOST_UBLAS_INLINE
sl@0
  3003
            const_iterator2 &operator += (difference_type n) {
sl@0
  3004
                it2_ += n;
sl@0
  3005
                return *this;
sl@0
  3006
            }
sl@0
  3007
            BOOST_UBLAS_INLINE
sl@0
  3008
            const_iterator2 &operator -= (difference_type n) {
sl@0
  3009
                it2_ -= n;
sl@0
  3010
                return *this;
sl@0
  3011
            }
sl@0
  3012
            BOOST_UBLAS_INLINE
sl@0
  3013
            difference_type operator - (const const_iterator2 &it) const {
sl@0
  3014
                BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
sl@0
  3015
                BOOST_UBLAS_CHECK (it1_ == it.it1_, external_logic ());
sl@0
  3016
                return it2_ - it.it2_;
sl@0
  3017
            }
sl@0
  3018
sl@0
  3019
            // Dereference
sl@0
  3020
            BOOST_UBLAS_INLINE
sl@0
  3021
            const_reference operator * () const {
sl@0
  3022
                BOOST_UBLAS_CHECK (index1 () < (*this) ().size1 (), bad_index ());
sl@0
  3023
                BOOST_UBLAS_CHECK (index2 () < (*this) ().size2 (), bad_index ());
sl@0
  3024
                return (*this) () (index1 (), index2 ());
sl@0
  3025
            }
sl@0
  3026
            BOOST_UBLAS_INLINE
sl@0
  3027
            const_reference operator [] (difference_type n) const {
sl@0
  3028
                return *(*this + n);
sl@0
  3029
            }
sl@0
  3030
sl@0
  3031
#ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
sl@0
  3032
            BOOST_UBLAS_INLINE
sl@0
  3033
#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
sl@0
  3034
            typename self_type::
sl@0
  3035
#endif
sl@0
  3036
            const_iterator1 begin () const {
sl@0
  3037
                const scalar_matrix &m = (*this) ();
sl@0
  3038
                return m.find1 (1, 0, index2 ());
sl@0
  3039
            }
sl@0
  3040
            BOOST_UBLAS_INLINE
sl@0
  3041
#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
sl@0
  3042
            typename self_type::
sl@0
  3043
#endif
sl@0
  3044
            const_iterator1 end () const {
sl@0
  3045
                const scalar_matrix &m = (*this) ();
sl@0
  3046
                return m.find1 (1, m.size1 (), index2 ());
sl@0
  3047
            }
sl@0
  3048
            BOOST_UBLAS_INLINE
sl@0
  3049
#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
sl@0
  3050
            typename self_type::
sl@0
  3051
#endif
sl@0
  3052
            const_reverse_iterator1 rbegin () const {
sl@0
  3053
                return const_reverse_iterator1 (end ());
sl@0
  3054
            }
sl@0
  3055
            BOOST_UBLAS_INLINE
sl@0
  3056
#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
sl@0
  3057
            typename self_type::
sl@0
  3058
#endif
sl@0
  3059
            const_reverse_iterator1 rend () const {
sl@0
  3060
                return const_reverse_iterator1 (begin ());
sl@0
  3061
            }
sl@0
  3062
#endif
sl@0
  3063
sl@0
  3064
            // Indices
sl@0
  3065
            BOOST_UBLAS_INLINE
sl@0
  3066
            size_type index1 () const {
sl@0
  3067
                return it1_;
sl@0
  3068
            }
sl@0
  3069
            BOOST_UBLAS_INLINE
sl@0
  3070
            size_type index2 () const {
sl@0
  3071
                return it2_;
sl@0
  3072
            }
sl@0
  3073
sl@0
  3074
            // Assignment
sl@0
  3075
            BOOST_UBLAS_INLINE
sl@0
  3076
            const_iterator2 &operator = (const const_iterator2 &it) {
sl@0
  3077
                container_const_reference<scalar_matrix>::assign (&it ());
sl@0
  3078
                it1_ = it.it1_;
sl@0
  3079
                it2_ = it.it2_;
sl@0
  3080
                return *this;
sl@0
  3081
            }
sl@0
  3082
sl@0
  3083
            // Comparison
sl@0
  3084
            BOOST_UBLAS_INLINE
sl@0
  3085
            bool operator == (const const_iterator2 &it) const {
sl@0
  3086
                BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
sl@0
  3087
                BOOST_UBLAS_CHECK (it1_ == it.it1_, external_logic ());
sl@0
  3088
                return it2_ == it.it2_;
sl@0
  3089
            }
sl@0
  3090
            BOOST_UBLAS_INLINE
sl@0
  3091
            bool operator < (const const_iterator2 &it) const {
sl@0
  3092
                BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
sl@0
  3093
                BOOST_UBLAS_CHECK (it1_ == it.it1_, external_logic ());
sl@0
  3094
                return it2_ < it.it2_;
sl@0
  3095
            }
sl@0
  3096
sl@0
  3097
        private:
sl@0
  3098
            const_subiterator_type it1_;
sl@0
  3099
            const_subiterator_type it2_;
sl@0
  3100
        };
sl@0
  3101
sl@0
  3102
        typedef const_iterator2 iterator2;
sl@0
  3103
#endif
sl@0
  3104
sl@0
  3105
        BOOST_UBLAS_INLINE
sl@0
  3106
        const_iterator2 begin2 () const {
sl@0
  3107
            return find2 (0, 0, 0);
sl@0
  3108
        }
sl@0
  3109
        BOOST_UBLAS_INLINE
sl@0
  3110
        const_iterator2 end2 () const {
sl@0
  3111
            return find2 (0, 0, size2_);
sl@0
  3112
        }
sl@0
  3113
sl@0
  3114
        // Reverse iterators
sl@0
  3115
sl@0
  3116
        BOOST_UBLAS_INLINE
sl@0
  3117
        const_reverse_iterator1 rbegin1 () const {
sl@0
  3118
            return const_reverse_iterator1 (end1 ());
sl@0
  3119
        }
sl@0
  3120
        BOOST_UBLAS_INLINE
sl@0
  3121
        const_reverse_iterator1 rend1 () const {
sl@0
  3122
            return const_reverse_iterator1 (begin1 ());
sl@0
  3123
        }
sl@0
  3124
sl@0
  3125
        BOOST_UBLAS_INLINE
sl@0
  3126
        const_reverse_iterator2 rbegin2 () const {
sl@0
  3127
            return const_reverse_iterator2 (end2 ());
sl@0
  3128
        }
sl@0
  3129
        BOOST_UBLAS_INLINE
sl@0
  3130
        const_reverse_iterator2 rend2 () const {
sl@0
  3131
            return const_reverse_iterator2 (begin2 ());
sl@0
  3132
        }
sl@0
  3133
sl@0
  3134
    private:
sl@0
  3135
        size_type size1_;
sl@0
  3136
        size_type size2_;
sl@0
  3137
        value_type value_;
sl@0
  3138
    };
sl@0
  3139
sl@0
  3140
sl@0
  3141
    // Array based matrix class
sl@0
  3142
    template<class T, std::size_t N, std::size_t M>
sl@0
  3143
    class c_matrix:
sl@0
  3144
        public matrix_container<c_matrix<T, N, M> > {
sl@0
  3145
sl@0
  3146
        typedef c_matrix<T, N, M> self_type;
sl@0
  3147
    public:
sl@0
  3148
#ifdef BOOST_UBLAS_ENABLE_PROXY_SHORTCUTS
sl@0
  3149
        using matrix_container<self_type>::operator ();
sl@0
  3150
#endif
sl@0
  3151
        typedef std::size_t size_type;
sl@0
  3152
        typedef std::ptrdiff_t difference_type;
sl@0
  3153
        typedef T value_type;
sl@0
  3154
        typedef const T &const_reference;
sl@0
  3155
        typedef T &reference;
sl@0
  3156
        typedef const T *const_pointer;
sl@0
  3157
        typedef T *pointer;
sl@0
  3158
        typedef const matrix_reference<const self_type> const_closure_type;
sl@0
  3159
        typedef matrix_reference<self_type> closure_type;
sl@0
  3160
        typedef c_vector<T, N * M> vector_temporary_type;     // vector able to store all elements of c_matrix
sl@0
  3161
        typedef self_type matrix_temporary_type;
sl@0
  3162
        typedef dense_tag storage_category;
sl@0
  3163
        // This could be better for performance,
sl@0
  3164
        // typedef typename unknown_orientation_tag orientation_category;
sl@0
  3165
        // but others depend on the orientation information...
sl@0
  3166
        typedef row_major_tag orientation_category;
sl@0
  3167
sl@0
  3168
        // Construction and destruction
sl@0
  3169
        BOOST_UBLAS_INLINE
sl@0
  3170
        c_matrix ():
sl@0
  3171
            size1_ (N), size2_ (M) /* , data_ () */ {
sl@0
  3172
        }
sl@0
  3173
        BOOST_UBLAS_INLINE
sl@0
  3174
        c_matrix (size_type size1, size_type size2):
sl@0
  3175
            size1_ (size1), size2_ (size2) /* , data_ () */ {
sl@0
  3176
            if (size1_ > N || size2_ > M)
sl@0
  3177
                bad_size ().raise ();
sl@0
  3178
        }
sl@0
  3179
        BOOST_UBLAS_INLINE
sl@0
  3180
        c_matrix (const c_matrix &m):
sl@0
  3181
            size1_ (m.size1_), size2_ (m.size2_) /* , data_ () */ {
sl@0
  3182
            if (size1_ > N || size2_ > M)
sl@0
  3183
                bad_size ().raise ();
sl@0
  3184
            *this = m;
sl@0
  3185
        }
sl@0
  3186
        template<class AE>
sl@0
  3187
        BOOST_UBLAS_INLINE
sl@0
  3188
        c_matrix (const matrix_expression<AE> &ae):
sl@0
  3189
            size1_ (ae ().size1 ()), size2_ (ae ().size2 ()) /* , data_ () */ {
sl@0
  3190
            if (size1_ > N || size2_ > M)
sl@0
  3191
                bad_size ().raise ();
sl@0
  3192
            matrix_assign<scalar_assign> (*this, ae);
sl@0
  3193
        }
sl@0
  3194
sl@0
  3195
        // Accessors
sl@0
  3196
        BOOST_UBLAS_INLINE
sl@0
  3197
        size_type size1 () const {
sl@0
  3198
            return size1_;
sl@0
  3199
        }
sl@0
  3200
        BOOST_UBLAS_INLINE
sl@0
  3201
        size_type size2 () const {
sl@0
  3202
            return size2_;
sl@0
  3203
        }
sl@0
  3204
        BOOST_UBLAS_INLINE
sl@0
  3205
        const_pointer data () const {
sl@0
  3206
            return reinterpret_cast<const_pointer> (data_);
sl@0
  3207
        }
sl@0
  3208
        BOOST_UBLAS_INLINE
sl@0
  3209
        pointer data () {
sl@0
  3210
            return reinterpret_cast<pointer> (data_);
sl@0
  3211
        }
sl@0
  3212
sl@0
  3213
        // Resizing
sl@0
  3214
        BOOST_UBLAS_INLINE
sl@0
  3215
        void resize (size_type size1, size_type size2, bool preserve = true) {
sl@0
  3216
            if (size1 > N || size2 > M)
sl@0
  3217
                bad_size ().raise ();
sl@0
  3218
            if (preserve) {
sl@0
  3219
                self_type temporary (size1, size2);
sl@0
  3220
                // Common elements to preserve
sl@0
  3221
                const size_type size1_min = (std::min) (size1, size1_);
sl@0
  3222
                const size_type size2_min = (std::min) (size2, size2_);
sl@0
  3223
                for (size_type i = 0; i != size1_min; ++i) {    // indexing copy over major
sl@0
  3224
                    for (size_type j = 0; j != size2_min; ++j) {
sl@0
  3225
                        temporary.data_[i][j] = data_[i][j];
sl@0
  3226
                    }
sl@0
  3227
                }
sl@0
  3228
                assign_temporary (temporary);
sl@0
  3229
            }
sl@0
  3230
            else {
sl@0
  3231
                size1_ = size1;
sl@0
  3232
                size2_ = size2;
sl@0
  3233
            }
sl@0
  3234
        }
sl@0
  3235
sl@0
  3236
        // Element access
sl@0
  3237
        BOOST_UBLAS_INLINE
sl@0
  3238
        const_reference operator () (size_type i, size_type j) const {
sl@0
  3239
            BOOST_UBLAS_CHECK (i < size1_, bad_index ());
sl@0
  3240
            BOOST_UBLAS_CHECK (j < size2_, bad_index ());
sl@0
  3241
            return data_ [i] [j];
sl@0
  3242
        }
sl@0
  3243
        BOOST_UBLAS_INLINE
sl@0
  3244
        reference at_element (size_type i, size_type j) {
sl@0
  3245
            BOOST_UBLAS_CHECK (i < size1_, bad_index ());
sl@0
  3246
            BOOST_UBLAS_CHECK (j < size2_, bad_index ());
sl@0
  3247
            return data_ [i] [j];
sl@0
  3248
        }
sl@0
  3249
        BOOST_UBLAS_INLINE
sl@0
  3250
        reference operator () (size_type i, size_type j) {
sl@0
  3251
            return at_element (i, j);
sl@0
  3252
        }
sl@0
  3253
sl@0
  3254
        // Element assignment
sl@0
  3255
        BOOST_UBLAS_INLINE
sl@0
  3256
        reference insert_element (size_type i, size_type j, const_reference t) {
sl@0
  3257
            return (at_element (i, j) = t);
sl@0
  3258
        }
sl@0
  3259
        
sl@0
  3260
        // Zeroing
sl@0
  3261
        BOOST_UBLAS_INLINE
sl@0
  3262
        void clear () {
sl@0
  3263
            for (size_type i = 0; i < size1_; ++ i)
sl@0
  3264
                std::fill (data_ [i], data_ [i] + size2_, value_type/*zero*/());
sl@0
  3265
        }
sl@0
  3266
sl@0
  3267
        // Assignment
sl@0
  3268
        BOOST_UBLAS_INLINE
sl@0
  3269
        c_matrix &operator = (const c_matrix &m) {
sl@0
  3270
            size1_ = m.size1_;
sl@0
  3271
            size2_ = m.size2_;
sl@0
  3272
            for (size_type i = 0; i < m.size1_; ++ i)
sl@0
  3273
                std::copy (m.data_ [i], m.data_ [i] + m.size2_, data_ [i]);
sl@0
  3274
            return *this;
sl@0
  3275
        }
sl@0
  3276
        template<class C>          // Container assignment without temporary
sl@0
  3277
        BOOST_UBLAS_INLINE
sl@0
  3278
        c_matrix &operator = (const matrix_container<C> &m) {
sl@0
  3279
            resize (m ().size1 (), m ().size2 (), false);
sl@0
  3280
            assign (m);
sl@0
  3281
            return *this;
sl@0
  3282
        }
sl@0
  3283
        BOOST_UBLAS_INLINE
sl@0
  3284
        c_matrix &assign_temporary (c_matrix &m) {
sl@0
  3285
            swap (m);
sl@0
  3286
            return *this;
sl@0
  3287
        }
sl@0
  3288
        template<class AE>
sl@0
  3289
        BOOST_UBLAS_INLINE
sl@0
  3290
        c_matrix &operator = (const matrix_expression<AE> &ae) { 
sl@0
  3291
            self_type temporary (ae);
sl@0
  3292
            return assign_temporary (temporary);
sl@0
  3293
        }
sl@0
  3294
        template<class AE>
sl@0
  3295
        BOOST_UBLAS_INLINE
sl@0
  3296
        c_matrix &assign (const matrix_expression<AE> &ae) { 
sl@0
  3297
            matrix_assign<scalar_assign> (*this, ae); 
sl@0
  3298
            return *this;
sl@0
  3299
        }
sl@0
  3300
        template<class AE>
sl@0
  3301
        BOOST_UBLAS_INLINE
sl@0
  3302
        c_matrix& operator += (const matrix_expression<AE> &ae) {
sl@0
  3303
            self_type temporary (*this + ae);
sl@0
  3304
            return assign_temporary (temporary);
sl@0
  3305
        }
sl@0
  3306
        template<class C>          // Container assignment without temporary
sl@0
  3307
        BOOST_UBLAS_INLINE
sl@0
  3308
        c_matrix &operator += (const matrix_container<C> &m) {
sl@0
  3309
            plus_assign (m);
sl@0
  3310
            return *this;
sl@0
  3311
        }
sl@0
  3312
        template<class AE>
sl@0
  3313
        BOOST_UBLAS_INLINE
sl@0
  3314
        c_matrix &plus_assign (const matrix_expression<AE> &ae) { 
sl@0
  3315
            matrix_assign<scalar_plus_assign> (*this, ae); 
sl@0
  3316
            return *this;
sl@0
  3317
        }
sl@0
  3318
        template<class AE>
sl@0
  3319
        BOOST_UBLAS_INLINE
sl@0
  3320
        c_matrix& operator -= (const matrix_expression<AE> &ae) {
sl@0
  3321
            self_type temporary (*this - ae);
sl@0
  3322
            return assign_temporary (temporary);
sl@0
  3323
        }
sl@0
  3324
        template<class C>          // Container assignment without temporary
sl@0
  3325
        BOOST_UBLAS_INLINE
sl@0
  3326
        c_matrix &operator -= (const matrix_container<C> &m) {
sl@0
  3327
            minus_assign (m);
sl@0
  3328
            return *this;
sl@0
  3329
        }
sl@0
  3330
        template<class AE>
sl@0
  3331
        BOOST_UBLAS_INLINE
sl@0
  3332
        c_matrix &minus_assign (const matrix_expression<AE> &ae) { 
sl@0
  3333
            matrix_assign<scalar_minus_assign> (*this, ae); 
sl@0
  3334
            return *this;
sl@0
  3335
        }
sl@0
  3336
        template<class AT>
sl@0
  3337
        BOOST_UBLAS_INLINE
sl@0
  3338
        c_matrix& operator *= (const AT &at) {
sl@0
  3339
            matrix_assign_scalar<scalar_multiplies_assign> (*this, at);
sl@0
  3340
            return *this;
sl@0
  3341
        }
sl@0
  3342
        template<class AT>
sl@0
  3343
        BOOST_UBLAS_INLINE
sl@0
  3344
        c_matrix& operator /= (const AT &at) {
sl@0
  3345
            matrix_assign_scalar<scalar_divides_assign> (*this, at);
sl@0
  3346
            return *this;
sl@0
  3347
        }
sl@0
  3348
sl@0
  3349
        // Swapping
sl@0
  3350
        BOOST_UBLAS_INLINE
sl@0
  3351
        void swap (c_matrix &m) {
sl@0
  3352
            if (this != &m) {
sl@0
  3353
                BOOST_UBLAS_CHECK (size1_ == m.size1_, bad_size ());
sl@0
  3354
                BOOST_UBLAS_CHECK (size2_ == m.size2_, bad_size ());
sl@0
  3355
                std::swap (size1_, m.size1_);
sl@0
  3356
                std::swap (size2_, m.size2_);
sl@0
  3357
                for (size_type i = 0; i < size1_; ++ i)
sl@0
  3358
                    std::swap_ranges (data_ [i], data_ [i] + size2_, m.data_ [i]);
sl@0
  3359
            }
sl@0
  3360
        }
sl@0
  3361
        BOOST_UBLAS_INLINE
sl@0
  3362
        friend void swap (c_matrix &m1, c_matrix &m2) {
sl@0
  3363
            m1.swap (m2);
sl@0
  3364
        }
sl@0
  3365
sl@0
  3366
        // Iterator types
sl@0
  3367
    private:
sl@0
  3368
        // Use pointers for iterator
sl@0
  3369
        typedef const_pointer const_subiterator_type;
sl@0
  3370
        typedef pointer subiterator_type;
sl@0
  3371
sl@0
  3372
    public:
sl@0
  3373
#ifdef BOOST_UBLAS_USE_INDEXED_ITERATOR
sl@0
  3374
        typedef indexed_iterator1<self_type, dense_random_access_iterator_tag> iterator1;
sl@0
  3375
        typedef indexed_iterator2<self_type, dense_random_access_iterator_tag> iterator2;
sl@0
  3376
        typedef indexed_const_iterator1<self_type, dense_random_access_iterator_tag> const_iterator1;
sl@0
  3377
        typedef indexed_const_iterator2<self_type, dense_random_access_iterator_tag> const_iterator2;
sl@0
  3378
#else
sl@0
  3379
        class const_iterator1;
sl@0
  3380
        class iterator1;
sl@0
  3381
        class const_iterator2;
sl@0
  3382
        class iterator2;
sl@0
  3383
#endif
sl@0
  3384
        typedef reverse_iterator_base1<const_iterator1> const_reverse_iterator1;
sl@0
  3385
        typedef reverse_iterator_base1<iterator1> reverse_iterator1;
sl@0
  3386
        typedef reverse_iterator_base2<const_iterator2> const_reverse_iterator2;
sl@0
  3387
        typedef reverse_iterator_base2<iterator2> reverse_iterator2;
sl@0
  3388
sl@0
  3389
        // Element lookup
sl@0
  3390
        BOOST_UBLAS_INLINE
sl@0
  3391
        const_iterator1 find1 (int rank, size_type i, size_type j) const {
sl@0
  3392
#ifdef BOOST_UBLAS_USE_INDEXED_ITERATOR
sl@0
  3393
            return const_iterator1 (*this, i, j);
sl@0
  3394
#else
sl@0
  3395
            return const_iterator1 (*this, &data_ [i] [j]);
sl@0
  3396
#endif
sl@0
  3397
        }
sl@0
  3398
        BOOST_UBLAS_INLINE
sl@0
  3399
        iterator1 find1 (int rank, size_type i, size_type j) {
sl@0
  3400
#ifdef BOOST_UBLAS_USE_INDEXED_ITERATOR
sl@0
  3401
            return iterator1 (*this, i, j);
sl@0
  3402
#else
sl@0
  3403
            return iterator1 (*this, &data_ [i] [j]);
sl@0
  3404
#endif
sl@0
  3405
        }
sl@0
  3406
        BOOST_UBLAS_INLINE
sl@0
  3407
        const_iterator2 find2 (int rank, size_type i, size_type j) const {
sl@0
  3408
#ifdef BOOST_UBLAS_USE_INDEXED_ITERATOR
sl@0
  3409
            return const_iterator2 (*this, i, j);
sl@0
  3410
#else
sl@0
  3411
            return const_iterator2 (*this, &data_ [i] [j]);
sl@0
  3412
#endif
sl@0
  3413
        }
sl@0
  3414
        BOOST_UBLAS_INLINE
sl@0
  3415
        iterator2 find2 (int rank, size_type i, size_type j) {
sl@0
  3416
#ifdef BOOST_UBLAS_USE_INDEXED_ITERATOR
sl@0
  3417
            return iterator2 (*this, i, j);
sl@0
  3418
#else
sl@0
  3419
            return iterator2 (*this, &data_ [i] [j]);
sl@0
  3420
#endif
sl@0
  3421
        }
sl@0
  3422
sl@0
  3423
sl@0
  3424
#ifndef BOOST_UBLAS_USE_INDEXED_ITERATOR
sl@0
  3425
        class const_iterator1:
sl@0
  3426
            public container_const_reference<c_matrix>,
sl@0
  3427
            public random_access_iterator_base<dense_random_access_iterator_tag,
sl@0
  3428
                                               const_iterator1, value_type> {
sl@0
  3429
        public:
sl@0
  3430
            typedef typename c_matrix::difference_type difference_type;
sl@0
  3431
            typedef typename c_matrix::value_type value_type;
sl@0
  3432
            typedef typename c_matrix::const_reference reference;
sl@0
  3433
            typedef typename c_matrix::const_pointer pointer;
sl@0
  3434
sl@0
  3435
            typedef const_iterator2 dual_iterator_type;
sl@0
  3436
            typedef const_reverse_iterator2 dual_reverse_iterator_type;
sl@0
  3437
sl@0
  3438
            // Construction and destruction
sl@0
  3439
            BOOST_UBLAS_INLINE
sl@0
  3440
            const_iterator1 ():
sl@0
  3441
                container_const_reference<self_type> (), it_ () {}
sl@0
  3442
            BOOST_UBLAS_INLINE
sl@0
  3443
            const_iterator1 (const self_type &m, const const_subiterator_type &it):
sl@0
  3444
                container_const_reference<self_type> (m), it_ (it) {}
sl@0
  3445
            BOOST_UBLAS_INLINE
sl@0
  3446
            const_iterator1 (const iterator1 &it):
sl@0
  3447
                container_const_reference<self_type> (it ()), it_ (it.it_) {}
sl@0
  3448
sl@0
  3449
            // Arithmetic
sl@0
  3450
            BOOST_UBLAS_INLINE
sl@0
  3451
            const_iterator1 &operator ++ () {
sl@0
  3452
                it_ += M;
sl@0
  3453
                return *this;
sl@0
  3454
            }
sl@0
  3455
            BOOST_UBLAS_INLINE
sl@0
  3456
            const_iterator1 &operator -- () {
sl@0
  3457
                it_ -= M;
sl@0
  3458
                return *this;
sl@0
  3459
            }
sl@0
  3460
            BOOST_UBLAS_INLINE
sl@0
  3461
            const_iterator1 &operator += (difference_type n) {
sl@0
  3462
                it_ += n * M;
sl@0
  3463
                return *this;
sl@0
  3464
            }
sl@0
  3465
            BOOST_UBLAS_INLINE
sl@0
  3466
            const_iterator1 &operator -= (difference_type n) {
sl@0
  3467
                it_ -= n * M;
sl@0
  3468
                return *this;
sl@0
  3469
            }
sl@0
  3470
            BOOST_UBLAS_INLINE
sl@0
  3471
            difference_type operator - (const const_iterator1 &it) const {
sl@0
  3472
                BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
sl@0
  3473
                return (it_ - it.it_) / M;
sl@0
  3474
            }
sl@0
  3475
sl@0
  3476
            // Dereference
sl@0
  3477
            BOOST_UBLAS_INLINE
sl@0
  3478
            const_reference operator * () const {
sl@0
  3479
                BOOST_UBLAS_CHECK (index1 () < (*this) ().size1 (), bad_index ());
sl@0
  3480
                BOOST_UBLAS_CHECK (index2 () < (*this) ().size2 (), bad_index ());
sl@0
  3481
                return *it_;
sl@0
  3482
            }
sl@0
  3483
            BOOST_UBLAS_INLINE
sl@0
  3484
            const_reference operator [] (difference_type n) const {
sl@0
  3485
                return *(*this + n);
sl@0
  3486
            }
sl@0
  3487
sl@0
  3488
#ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
sl@0
  3489
            BOOST_UBLAS_INLINE
sl@0
  3490
#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
sl@0
  3491
            typename self_type::
sl@0
  3492
#endif
sl@0
  3493
            const_iterator2 begin () const {
sl@0
  3494
                const self_type &m = (*this) ();
sl@0
  3495
                return m.find2 (1, index1 (), 0);
sl@0
  3496
            }
sl@0
  3497
            BOOST_UBLAS_INLINE
sl@0
  3498
#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
sl@0
  3499
            typename self_type::
sl@0
  3500
#endif
sl@0
  3501
            const_iterator2 end () const {
sl@0
  3502
                const self_type &m = (*this) ();
sl@0
  3503
                return m.find2 (1, index1 (), m.size2 ());
sl@0
  3504
            }
sl@0
  3505
            BOOST_UBLAS_INLINE
sl@0
  3506
#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
sl@0
  3507
            typename self_type::
sl@0
  3508
#endif
sl@0
  3509
            const_reverse_iterator2 rbegin () const {
sl@0
  3510
                return const_reverse_iterator2 (end ());
sl@0
  3511
            }
sl@0
  3512
            BOOST_UBLAS_INLINE
sl@0
  3513
#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
sl@0
  3514
            typename self_type::
sl@0
  3515
#endif
sl@0
  3516
            const_reverse_iterator2 rend () const {
sl@0
  3517
                return const_reverse_iterator2 (begin ());
sl@0
  3518
            }
sl@0
  3519
#endif
sl@0
  3520
sl@0
  3521
            // Indices
sl@0
  3522
            BOOST_UBLAS_INLINE
sl@0
  3523
            size_type index1 () const {
sl@0
  3524
                const self_type &m = (*this) ();
sl@0
  3525
                return (it_ - m.begin1 ().it_) / M;
sl@0
  3526
            }
sl@0
  3527
            BOOST_UBLAS_INLINE
sl@0
  3528
            size_type index2 () const {
sl@0
  3529
                const self_type &m = (*this) ();
sl@0
  3530
                return (it_ - m.begin1 ().it_) % M;
sl@0
  3531
            }
sl@0
  3532
sl@0
  3533
            // Assignment
sl@0
  3534
            BOOST_UBLAS_INLINE
sl@0
  3535
            const_iterator1 &operator = (const const_iterator1 &it) {
sl@0
  3536
                container_const_reference<self_type>::assign (&it ());
sl@0
  3537
                it_ = it.it_;
sl@0
  3538
                return *this;
sl@0
  3539
            }
sl@0
  3540
sl@0
  3541
            // Comparison
sl@0
  3542
            BOOST_UBLAS_INLINE
sl@0
  3543
            bool operator == (const const_iterator1 &it) const {
sl@0
  3544
                BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
sl@0
  3545
                return it_ == it.it_;
sl@0
  3546
            }
sl@0
  3547
            BOOST_UBLAS_INLINE
sl@0
  3548
            bool operator < (const const_iterator1 &it) const {
sl@0
  3549
                BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
sl@0
  3550
                return it_ < it.it_;
sl@0
  3551
            }
sl@0
  3552
sl@0
  3553
        private:
sl@0
  3554
            const_subiterator_type it_;
sl@0
  3555
sl@0
  3556
            friend class iterator1;
sl@0
  3557
        };
sl@0
  3558
#endif
sl@0
  3559
sl@0
  3560
        BOOST_UBLAS_INLINE
sl@0
  3561
        const_iterator1 begin1 () const {
sl@0
  3562
            return find1 (0, 0, 0);
sl@0
  3563
        }
sl@0
  3564
        BOOST_UBLAS_INLINE
sl@0
  3565
        const_iterator1 end1 () const {
sl@0
  3566
            return find1 (0, size1_, 0);
sl@0
  3567
        }
sl@0
  3568
sl@0
  3569
#ifndef BOOST_UBLAS_USE_INDEXED_ITERATOR
sl@0
  3570
        class iterator1:
sl@0
  3571
            public container_reference<c_matrix>,
sl@0
  3572
            public random_access_iterator_base<dense_random_access_iterator_tag,
sl@0
  3573
                                               iterator1, value_type> {
sl@0
  3574
        public:
sl@0
  3575
sl@0
  3576
            typedef typename c_matrix::difference_type difference_type;
sl@0
  3577
            typedef typename c_matrix::value_type value_type;
sl@0
  3578
            typedef typename c_matrix::reference reference;
sl@0
  3579
            typedef typename c_matrix::pointer pointer;
sl@0
  3580
sl@0
  3581
            typedef iterator2 dual_iterator_type;
sl@0
  3582
            typedef reverse_iterator2 dual_reverse_iterator_type;
sl@0
  3583
sl@0
  3584
            // Construction and destruction
sl@0
  3585
            BOOST_UBLAS_INLINE
sl@0
  3586
            iterator1 ():
sl@0
  3587
                container_reference<self_type> (), it_ () {}
sl@0
  3588
            BOOST_UBLAS_INLINE
sl@0
  3589
            iterator1 (self_type &m, const subiterator_type &it):
sl@0
  3590
                container_reference<self_type> (m), it_ (it) {}
sl@0
  3591
sl@0
  3592
            // Arithmetic
sl@0
  3593
            BOOST_UBLAS_INLINE
sl@0
  3594
            iterator1 &operator ++ () {
sl@0
  3595
                it_ += M;
sl@0
  3596
                return *this;
sl@0
  3597
            }
sl@0
  3598
            BOOST_UBLAS_INLINE
sl@0
  3599
            iterator1 &operator -- () {
sl@0
  3600
                it_ -= M;
sl@0
  3601
                return *this;
sl@0
  3602
            }
sl@0
  3603
            BOOST_UBLAS_INLINE
sl@0
  3604
            iterator1 &operator += (difference_type n) {
sl@0
  3605
                it_ += n * M;
sl@0
  3606
                return *this;
sl@0
  3607
            }
sl@0
  3608
            BOOST_UBLAS_INLINE
sl@0
  3609
            iterator1 &operator -= (difference_type n) {
sl@0
  3610
                it_ -= n * M;
sl@0
  3611
                return *this;
sl@0
  3612
            }
sl@0
  3613
            BOOST_UBLAS_INLINE
sl@0
  3614
            difference_type operator - (const iterator1 &it) const {
sl@0
  3615
                BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
sl@0
  3616
                return (it_ - it.it_) / M;
sl@0
  3617
            }
sl@0
  3618
sl@0
  3619
            // Dereference
sl@0
  3620
            BOOST_UBLAS_INLINE
sl@0
  3621
            reference operator * () const {
sl@0
  3622
                BOOST_UBLAS_CHECK (index1 () < (*this) ().size1 (), bad_index ());
sl@0
  3623
                BOOST_UBLAS_CHECK (index2 () < (*this) ().size2 (), bad_index ());
sl@0
  3624
                return *it_;
sl@0
  3625
            }
sl@0
  3626
            BOOST_UBLAS_INLINE
sl@0
  3627
            reference operator [] (difference_type n) const {
sl@0
  3628
                return *(*this + n);
sl@0
  3629
            }
sl@0
  3630
sl@0
  3631
#ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
sl@0
  3632
            BOOST_UBLAS_INLINE
sl@0
  3633
#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
sl@0
  3634
            typename self_type::
sl@0
  3635
#endif
sl@0
  3636
            iterator2 begin () const {
sl@0
  3637
                self_type &m = (*this) ();
sl@0
  3638
                return m.find2 (1, index1 (), 0);
sl@0
  3639
            }
sl@0
  3640
            BOOST_UBLAS_INLINE
sl@0
  3641
#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
sl@0
  3642
            typename self_type::
sl@0
  3643
#endif
sl@0
  3644
            iterator2 end () const {
sl@0
  3645
                self_type &m = (*this) ();
sl@0
  3646
                return m.find2 (1, index1 (), m.size2 ());
sl@0
  3647
            }
sl@0
  3648
            BOOST_UBLAS_INLINE
sl@0
  3649
#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
sl@0
  3650
            typename self_type::
sl@0
  3651
#endif
sl@0
  3652
            reverse_iterator2 rbegin () const {
sl@0
  3653
                return reverse_iterator2 (end ());
sl@0
  3654
            }
sl@0
  3655
            BOOST_UBLAS_INLINE
sl@0
  3656
#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
sl@0
  3657
            typename self_type::
sl@0
  3658
#endif
sl@0
  3659
            reverse_iterator2 rend () const {
sl@0
  3660
                return reverse_iterator2 (begin ());
sl@0
  3661
            }
sl@0
  3662
#endif
sl@0
  3663
sl@0
  3664
            // Indices
sl@0
  3665
            BOOST_UBLAS_INLINE
sl@0
  3666
            size_type index1 () const {
sl@0
  3667
                const self_type &m = (*this) ();
sl@0
  3668
                return (it_ - m.begin1 ().it_) / M;
sl@0
  3669
            }
sl@0
  3670
            BOOST_UBLAS_INLINE
sl@0
  3671
            size_type index2 () const {
sl@0
  3672
                const self_type &m = (*this) ();
sl@0
  3673
                return (it_ - m.begin1 ().it_) % M;
sl@0
  3674
            }
sl@0
  3675
sl@0
  3676
            // Assignment
sl@0
  3677
            BOOST_UBLAS_INLINE
sl@0
  3678
            iterator1 &operator = (const iterator1 &it) {
sl@0
  3679
                container_reference<self_type>::assign (&it ());
sl@0
  3680
                it_ = it.it_;
sl@0
  3681
                return *this;
sl@0
  3682
            }
sl@0
  3683
sl@0
  3684
            // Comparison
sl@0
  3685
            BOOST_UBLAS_INLINE
sl@0
  3686
            bool operator == (const iterator1 &it) const {
sl@0
  3687
                BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
sl@0
  3688
                return it_ == it.it_;
sl@0
  3689
            }
sl@0
  3690
            BOOST_UBLAS_INLINE
sl@0
  3691
            bool operator < (const iterator1 &it) const {
sl@0
  3692
                BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
sl@0
  3693
                return it_ < it.it_;
sl@0
  3694
            }
sl@0
  3695
sl@0
  3696
        private:
sl@0
  3697
            subiterator_type it_;
sl@0
  3698
sl@0
  3699
            friend class const_iterator1;
sl@0
  3700
        };
sl@0
  3701
#endif
sl@0
  3702
sl@0
  3703
        BOOST_UBLAS_INLINE
sl@0
  3704
        iterator1 begin1 () {
sl@0
  3705
            return find1 (0, 0, 0);
sl@0
  3706
        }
sl@0
  3707
        BOOST_UBLAS_INLINE
sl@0
  3708
        iterator1 end1 () {
sl@0
  3709
            return find1 (0, size1_, 0);
sl@0
  3710
        }
sl@0
  3711
sl@0
  3712
#ifndef BOOST_UBLAS_USE_INDEXED_ITERATOR
sl@0
  3713
        class const_iterator2:
sl@0
  3714
            public container_const_reference<c_matrix>,
sl@0
  3715
            public random_access_iterator_base<dense_random_access_iterator_tag,
sl@0
  3716
                                               const_iterator2, value_type> {
sl@0
  3717
        public:
sl@0
  3718
            typedef typename c_matrix::difference_type difference_type;
sl@0
  3719
            typedef typename c_matrix::value_type value_type;
sl@0
  3720
            typedef typename c_matrix::const_reference reference;
sl@0
  3721
            typedef typename c_matrix::const_reference pointer;
sl@0
  3722
sl@0
  3723
            typedef const_iterator1 dual_iterator_type;
sl@0
  3724
            typedef const_reverse_iterator1 dual_reverse_iterator_type;
sl@0
  3725
sl@0
  3726
            // Construction and destruction
sl@0
  3727
            BOOST_UBLAS_INLINE
sl@0
  3728
            const_iterator2 ():
sl@0
  3729
                container_const_reference<self_type> (), it_ () {}
sl@0
  3730
            BOOST_UBLAS_INLINE
sl@0
  3731
            const_iterator2 (const self_type &m, const const_subiterator_type &it):
sl@0
  3732
                container_const_reference<self_type> (m), it_ (it) {}
sl@0
  3733
            BOOST_UBLAS_INLINE
sl@0
  3734
            const_iterator2 (const iterator2 &it):
sl@0
  3735
                container_const_reference<self_type> (it ()), it_ (it.it_) {}
sl@0
  3736
sl@0
  3737
            // Arithmetic
sl@0
  3738
            BOOST_UBLAS_INLINE
sl@0
  3739
            const_iterator2 &operator ++ () {
sl@0
  3740
                ++ it_;
sl@0
  3741
                return *this;
sl@0
  3742
            }
sl@0
  3743
            BOOST_UBLAS_INLINE
sl@0
  3744
            const_iterator2 &operator -- () {
sl@0
  3745
                -- it_;
sl@0
  3746
                return *this;
sl@0
  3747
            }
sl@0
  3748
            BOOST_UBLAS_INLINE
sl@0
  3749
            const_iterator2 &operator += (difference_type n) {
sl@0
  3750
                it_ += n;
sl@0
  3751
                return *this;
sl@0
  3752
            }
sl@0
  3753
            BOOST_UBLAS_INLINE
sl@0
  3754
            const_iterator2 &operator -= (difference_type n) {
sl@0
  3755
                it_ -= n;
sl@0
  3756
                return *this;
sl@0
  3757
            }
sl@0
  3758
            BOOST_UBLAS_INLINE
sl@0
  3759
            difference_type operator - (const const_iterator2 &it) const {
sl@0
  3760
                BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
sl@0
  3761
                return it_ - it.it_;
sl@0
  3762
            }
sl@0
  3763
sl@0
  3764
            // Dereference
sl@0
  3765
            BOOST_UBLAS_INLINE
sl@0
  3766
            const_reference operator * () const {
sl@0
  3767
                BOOST_UBLAS_CHECK (index1 () < (*this) ().size1 (), bad_index ());
sl@0
  3768
                BOOST_UBLAS_CHECK (index2 () < (*this) ().size2 (), bad_index ());
sl@0
  3769
                return *it_;
sl@0
  3770
            }
sl@0
  3771
            BOOST_UBLAS_INLINE
sl@0
  3772
            const_reference operator [] (difference_type n) const {
sl@0
  3773
                return *(*this + n);
sl@0
  3774
            }
sl@0
  3775
sl@0
  3776
#ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
sl@0
  3777
            BOOST_UBLAS_INLINE
sl@0
  3778
#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
sl@0
  3779
            typename self_type::
sl@0
  3780
#endif
sl@0
  3781
            const_iterator1 begin () const {
sl@0
  3782
                const self_type &m = (*this) ();
sl@0
  3783
                return m.find1 (1, 0, index2 ());
sl@0
  3784
            }
sl@0
  3785
            BOOST_UBLAS_INLINE
sl@0
  3786
#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
sl@0
  3787
            typename self_type::
sl@0
  3788
#endif
sl@0
  3789
            const_iterator1 end () const {
sl@0
  3790
                const self_type &m = (*this) ();
sl@0
  3791
                return m.find1 (1, m.size1 (), index2 ());
sl@0
  3792
            }
sl@0
  3793
            BOOST_UBLAS_INLINE
sl@0
  3794
#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
sl@0
  3795
            typename self_type::
sl@0
  3796
#endif
sl@0
  3797
            const_reverse_iterator1 rbegin () const {
sl@0
  3798
                return const_reverse_iterator1 (end ());
sl@0
  3799
            }
sl@0
  3800
            BOOST_UBLAS_INLINE
sl@0
  3801
#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
sl@0
  3802
            typename self_type::
sl@0
  3803
#endif
sl@0
  3804
            const_reverse_iterator1 rend () const {
sl@0
  3805
                return const_reverse_iterator1 (begin ());
sl@0
  3806
            }
sl@0
  3807
#endif
sl@0
  3808
sl@0
  3809
            // Indices
sl@0
  3810
            BOOST_UBLAS_INLINE
sl@0
  3811
            size_type index1 () const {
sl@0
  3812
                const self_type &m = (*this) ();
sl@0
  3813
                return (it_ - m.begin2 ().it_) / M;
sl@0
  3814
            }
sl@0
  3815
            BOOST_UBLAS_INLINE
sl@0
  3816
            size_type index2 () const {
sl@0
  3817
                const self_type &m = (*this) ();
sl@0
  3818
                return (it_ - m.begin2 ().it_) % M;
sl@0
  3819
            }
sl@0
  3820
sl@0
  3821
            // Assignment
sl@0
  3822
            BOOST_UBLAS_INLINE
sl@0
  3823
            const_iterator2 &operator = (const const_iterator2 &it) {
sl@0
  3824
                container_const_reference<self_type>::assign (&it ());
sl@0
  3825
                it_ = it.it_;
sl@0
  3826
                return *this;
sl@0
  3827
            }
sl@0
  3828
sl@0
  3829
            // Comparison
sl@0
  3830
            BOOST_UBLAS_INLINE
sl@0
  3831
            bool operator == (const const_iterator2 &it) const {
sl@0
  3832
                BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
sl@0
  3833
                return it_ == it.it_;
sl@0
  3834
            }
sl@0
  3835
            BOOST_UBLAS_INLINE
sl@0
  3836
            bool operator < (const const_iterator2 &it) const {
sl@0
  3837
                BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
sl@0
  3838
                return it_ < it.it_;
sl@0
  3839
            }
sl@0
  3840
sl@0
  3841
        private:
sl@0
  3842
            const_subiterator_type it_;
sl@0
  3843
sl@0
  3844
            friend class iterator2;
sl@0
  3845
        };
sl@0
  3846
#endif
sl@0
  3847
sl@0
  3848
        BOOST_UBLAS_INLINE
sl@0
  3849
        const_iterator2 begin2 () const {
sl@0
  3850
            return find2 (0, 0, 0);
sl@0
  3851
        }
sl@0
  3852
        BOOST_UBLAS_INLINE
sl@0
  3853
        const_iterator2 end2 () const {
sl@0
  3854
            return find2 (0, 0, size2_);
sl@0
  3855
        }
sl@0
  3856
sl@0
  3857
#ifndef BOOST_UBLAS_USE_INDEXED_ITERATOR
sl@0
  3858
        class iterator2:
sl@0
  3859
            public container_reference<c_matrix>,
sl@0
  3860
            public random_access_iterator_base<dense_random_access_iterator_tag,
sl@0
  3861
                                               iterator2, value_type> {
sl@0
  3862
        public:
sl@0
  3863
            typedef typename c_matrix::difference_type difference_type;
sl@0
  3864
            typedef typename c_matrix::value_type value_type;
sl@0
  3865
            typedef typename c_matrix::reference reference;
sl@0
  3866
            typedef typename c_matrix::pointer pointer;
sl@0
  3867
sl@0
  3868
            typedef iterator1 dual_iterator_type;
sl@0
  3869
            typedef reverse_iterator1 dual_reverse_iterator_type;
sl@0
  3870
sl@0
  3871
            // Construction and destruction
sl@0
  3872
            BOOST_UBLAS_INLINE
sl@0
  3873
            iterator2 ():
sl@0
  3874
                container_reference<self_type> (), it_ () {}
sl@0
  3875
            BOOST_UBLAS_INLINE
sl@0
  3876
            iterator2 (self_type &m, const subiterator_type &it):
sl@0
  3877
                container_reference<self_type> (m), it_ (it) {}
sl@0
  3878
sl@0
  3879
            // Arithmetic
sl@0
  3880
            BOOST_UBLAS_INLINE
sl@0
  3881
            iterator2 &operator ++ () {
sl@0
  3882
                ++ it_;
sl@0
  3883
                return *this;
sl@0
  3884
            }
sl@0
  3885
            BOOST_UBLAS_INLINE
sl@0
  3886
            iterator2 &operator -- () {
sl@0
  3887
                -- it_;
sl@0
  3888
                return *this;
sl@0
  3889
            }
sl@0
  3890
            BOOST_UBLAS_INLINE
sl@0
  3891
            iterator2 &operator += (difference_type n) {
sl@0
  3892
                it_ += n;
sl@0
  3893
                return *this;
sl@0
  3894
            }
sl@0
  3895
            BOOST_UBLAS_INLINE
sl@0
  3896
            iterator2 &operator -= (difference_type n) {
sl@0
  3897
                it_ -= n;
sl@0
  3898
                return *this;
sl@0
  3899
            }
sl@0
  3900
            BOOST_UBLAS_INLINE
sl@0
  3901
            difference_type operator - (const iterator2 &it) const {
sl@0
  3902
                BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
sl@0
  3903
                return it_ - it.it_;
sl@0
  3904
            }
sl@0
  3905
sl@0
  3906
            // Dereference
sl@0
  3907
            BOOST_UBLAS_INLINE
sl@0
  3908
            reference operator * () const {
sl@0
  3909
                BOOST_UBLAS_CHECK (index1 () < (*this) ().size1 (), bad_index ());
sl@0
  3910
                BOOST_UBLAS_CHECK (index2 () < (*this) ().size2 (), bad_index ());
sl@0
  3911
                return *it_;
sl@0
  3912
            }
sl@0
  3913
            BOOST_UBLAS_INLINE
sl@0
  3914
            reference operator [] (difference_type n) const {
sl@0
  3915
                return *(*this + n);
sl@0
  3916
            }
sl@0
  3917
sl@0
  3918
#ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
sl@0
  3919
            BOOST_UBLAS_INLINE
sl@0
  3920
#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
sl@0
  3921
            typename self_type::
sl@0
  3922
#endif
sl@0
  3923
            iterator1 begin () const {
sl@0
  3924
                self_type &m = (*this) ();
sl@0
  3925
                return m.find1 (1, 0, index2 ());
sl@0
  3926
            }
sl@0
  3927
            BOOST_UBLAS_INLINE
sl@0
  3928
#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
sl@0
  3929
            typename self_type::
sl@0
  3930
#endif
sl@0
  3931
            iterator1 end () const {
sl@0
  3932
                self_type &m = (*this) ();
sl@0
  3933
                return m.find1 (1, m.size1 (), index2 ());
sl@0
  3934
            }
sl@0
  3935
            BOOST_UBLAS_INLINE
sl@0
  3936
#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
sl@0
  3937
            typename self_type::
sl@0
  3938
#endif
sl@0
  3939
            reverse_iterator1 rbegin () const {
sl@0
  3940
                return reverse_iterator1 (end ());
sl@0
  3941
            }
sl@0
  3942
            BOOST_UBLAS_INLINE
sl@0
  3943
#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
sl@0
  3944
            typename self_type::
sl@0
  3945
#endif
sl@0
  3946
            reverse_iterator1 rend () const {
sl@0
  3947
                return reverse_iterator1 (begin ());
sl@0
  3948
            }
sl@0
  3949
#endif
sl@0
  3950
sl@0
  3951
            // Indices
sl@0
  3952
            BOOST_UBLAS_INLINE
sl@0
  3953
            size_type index1 () const {
sl@0
  3954
                const self_type &m = (*this) ();
sl@0
  3955
                return (it_ - m.begin2 ().it_) / M;
sl@0
  3956
            }
sl@0
  3957
            BOOST_UBLAS_INLINE
sl@0
  3958
            size_type index2 () const {
sl@0
  3959
                const self_type &m = (*this) ();
sl@0
  3960
                return (it_ - m.begin2 ().it_) % M;
sl@0
  3961
            }
sl@0
  3962
sl@0
  3963
            // Assignment
sl@0
  3964
            BOOST_UBLAS_INLINE
sl@0
  3965
            iterator2 &operator = (const iterator2 &it) {
sl@0
  3966
                container_reference<self_type>::assign (&it ());
sl@0
  3967
                it_ = it.it_;
sl@0
  3968
                return *this;
sl@0
  3969
            }
sl@0
  3970
sl@0
  3971
            // Comparison
sl@0
  3972
            BOOST_UBLAS_INLINE
sl@0
  3973
            bool operator == (const iterator2 &it) const {
sl@0
  3974
                BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
sl@0
  3975
                return it_ == it.it_;
sl@0
  3976
            }
sl@0
  3977
            BOOST_UBLAS_INLINE
sl@0
  3978
            bool operator < (const iterator2 &it) const {
sl@0
  3979
                BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
sl@0
  3980
                return it_ < it.it_;
sl@0
  3981
            }
sl@0
  3982
sl@0
  3983
        private:
sl@0
  3984
            subiterator_type it_;
sl@0
  3985
sl@0
  3986
            friend class const_iterator2;
sl@0
  3987
        };
sl@0
  3988
#endif
sl@0
  3989
sl@0
  3990
        BOOST_UBLAS_INLINE
sl@0
  3991
        iterator2 begin2 () {
sl@0
  3992
            return find2 (0, 0, 0);
sl@0
  3993
        }
sl@0
  3994
        BOOST_UBLAS_INLINE
sl@0
  3995
        iterator2 end2 () {
sl@0
  3996
            return find2 (0, 0, size2_);
sl@0
  3997
        }
sl@0
  3998
sl@0
  3999
        // Reverse iterators
sl@0
  4000
sl@0
  4001
        BOOST_UBLAS_INLINE
sl@0
  4002
        const_reverse_iterator1 rbegin1 () const {
sl@0
  4003
            return const_reverse_iterator1 (end1 ());
sl@0
  4004
        }
sl@0
  4005
        BOOST_UBLAS_INLINE
sl@0
  4006
        const_reverse_iterator1 rend1 () const {
sl@0
  4007
            return const_reverse_iterator1 (begin1 ());
sl@0
  4008
        }
sl@0
  4009
sl@0
  4010
        BOOST_UBLAS_INLINE
sl@0
  4011
        reverse_iterator1 rbegin1 () {
sl@0
  4012
            return reverse_iterator1 (end1 ());
sl@0
  4013
        }
sl@0
  4014
        BOOST_UBLAS_INLINE
sl@0
  4015
        reverse_iterator1 rend1 () {
sl@0
  4016
            return reverse_iterator1 (begin1 ());
sl@0
  4017
        }
sl@0
  4018
sl@0
  4019
        BOOST_UBLAS_INLINE
sl@0
  4020
        const_reverse_iterator2 rbegin2 () const {
sl@0
  4021
            return const_reverse_iterator2 (end2 ());
sl@0
  4022
        }
sl@0
  4023
        BOOST_UBLAS_INLINE
sl@0
  4024
        const_reverse_iterator2 rend2 () const {
sl@0
  4025
            return const_reverse_iterator2 (begin2 ());
sl@0
  4026
        }
sl@0
  4027
sl@0
  4028
        BOOST_UBLAS_INLINE
sl@0
  4029
        reverse_iterator2 rbegin2 () {
sl@0
  4030
            return reverse_iterator2 (end2 ());
sl@0
  4031
        }
sl@0
  4032
        BOOST_UBLAS_INLINE
sl@0
  4033
        reverse_iterator2 rend2 () {
sl@0
  4034
            return reverse_iterator2 (begin2 ());
sl@0
  4035
        }
sl@0
  4036
sl@0
  4037
    private:
sl@0
  4038
        size_type size1_;
sl@0
  4039
        size_type size2_;
sl@0
  4040
        value_type data_ [N] [M];
sl@0
  4041
    };
sl@0
  4042
sl@0
  4043
}}}
sl@0
  4044
sl@0
  4045
#endif