Chris@16: // Chris@16: // Copyright (c) 2000-2010 Chris@16: // Joerg Walter, Mathias Koch, Gunter Winkler, David Bellot Chris@101: // Copyright (c) 2014, Athanasios Iliopoulos Chris@16: // Chris@16: // Distributed under the Boost Software License, Version 1.0. (See Chris@16: // accompanying file LICENSE_1_0.txt or copy at Chris@16: // http://www.boost.org/LICENSE_1_0.txt) Chris@16: // Chris@16: // The authors gratefully acknowledge the support of Chris@16: // GeNeSys mbH & Co. KG in producing this work. Chris@16: // Chris@16: Chris@16: #ifndef _BOOST_UBLAS_MATRIX_ Chris@16: #define _BOOST_UBLAS_MATRIX_ Chris@16: Chris@101: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: Chris@16: // Iterators based on ideas of Jeremy Siek Chris@16: Chris@16: namespace boost { namespace numeric { Chris@16: Chris@16: /** \brief main namespace of uBLAS. Chris@16: * Chris@16: * Use this namespace for all operations with uBLAS. It can also be abbreviated with Chris@16: * \code namespace ublas = boost::numeric::ublas; \endcode Chris@16: * Chris@16: * A common practice is to bring this namespace into the current scope with Chris@16: * \code using namespace boost::numeric::ublas; \endcode. Chris@16: * Chris@16: * However, be warned that using the ublas namespace and the std::vector at the same time can lead to the compiler to confusion. Chris@16: * The solution is simply to prefix each ublas vector like \c boost::numeric::ublas::vector. If you think it's too long to Chris@16: * write, you can define a new namespace like \c namespace ublas = boost::numeric::ublas and then just declare your vectors Chris@16: * with \c ublas::vector. STL vectors will be declared as vector. No need to prefix with \c std:: Chris@16: */ Chris@16: namespace ublas { Chris@16: Chris@16: namespace detail { Chris@16: using namespace boost::numeric::ublas; Chris@16: Chris@16: // Matrix resizing algorithm Chris@16: template Chris@16: BOOST_UBLAS_INLINE Chris@16: void matrix_resize_preserve (M& m, M& temporary) { Chris@16: typedef L layout_type; Chris@16: typedef typename M::size_type size_type; Chris@16: const size_type msize1 (m.size1 ()); // original size Chris@16: const size_type msize2 (m.size2 ()); Chris@16: const size_type size1 (temporary.size1 ()); // new size is specified by temporary Chris@16: const size_type size2 (temporary.size2 ()); Chris@16: // Common elements to preserve Chris@16: const size_type size1_min = (std::min) (size1, msize1); Chris@16: const size_type size2_min = (std::min) (size2, msize2); Chris@16: // Order for major and minor sizes Chris@16: const size_type major_size = layout_type::size_M (size1_min, size2_min); Chris@16: const size_type minor_size = layout_type::size_m (size1_min, size2_min); Chris@16: // Indexing copy over major Chris@16: for (size_type major = 0; major != major_size; ++major) { Chris@16: for (size_type minor = 0; minor != minor_size; ++minor) { Chris@16: // find indexes - use invertability of element_ functions Chris@16: const size_type i1 = layout_type::index_M(major, minor); Chris@16: const size_type i2 = layout_type::index_m(major, minor); Chris@16: temporary.data () [layout_type::element (i1, size1, i2, size2)] = Chris@16: m.data() [layout_type::element (i1, msize1, i2, msize2)]; Chris@16: } Chris@16: } Chris@16: m.assign_temporary (temporary); Chris@16: } Chris@16: } Chris@16: Chris@16: /** \brief A dense matrix of values of type \c T. Chris@16: * Chris@16: * For a \f$(m \times n)\f$-dimensional matrix and \f$ 0 \leq i < m, 0 \leq j < n\f$, every element \f$ m_{i,j} \f$ is mapped to Chris@16: * the \f$(i.n + j)\f$-th element of the container for row major orientation or the \f$ (i + j.m) \f$-th element of Chris@16: * the container for column major orientation. In a dense matrix all elements are represented in memory in a Chris@16: * contiguous chunk of memory by definition. Chris@16: * Chris@16: * Orientation and storage can also be specified, otherwise a \c row_major and \c unbounded_array are used. It is \b not Chris@16: * required by the storage to initialize elements of the matrix. Chris@16: * Chris@16: * \tparam T the type of object stored in the matrix (like double, float, complex, etc...) Chris@16: * \tparam L the storage organization. It can be either \c row_major or \c column_major. Default is \c row_major Chris@16: * \tparam A the type of Storage array. Default is \c unbounded_array Chris@16: */ Chris@16: template Chris@16: class matrix: Chris@16: public matrix_container > { Chris@16: Chris@16: typedef T *pointer; Chris@16: typedef L layout_type; Chris@16: typedef matrix self_type; Chris@16: public: Chris@16: #ifdef BOOST_UBLAS_ENABLE_PROXY_SHORTCUTS Chris@16: using matrix_container::operator (); Chris@16: #endif Chris@16: typedef typename A::size_type size_type; Chris@16: typedef typename A::difference_type difference_type; Chris@16: typedef T value_type; Chris@16: typedef const T &const_reference; Chris@16: typedef T &reference; Chris@16: typedef A array_type; Chris@16: typedef const matrix_reference const_closure_type; Chris@16: typedef matrix_reference closure_type; Chris@16: typedef vector vector_temporary_type; Chris@16: typedef self_type matrix_temporary_type; Chris@16: typedef dense_tag storage_category; Chris@16: // This could be better for performance, Chris@16: // typedef typename unknown_orientation_tag orientation_category; Chris@16: // but others depend on the orientation information... Chris@16: typedef typename L::orientation_category orientation_category; Chris@16: Chris@16: // Construction and destruction Chris@16: Chris@16: /// Default dense matrix constructor. Make a dense matrix of size (0,0) Chris@16: BOOST_UBLAS_INLINE Chris@16: matrix (): Chris@16: matrix_container (), Chris@16: size1_ (0), size2_ (0), data_ () {} Chris@16: Chris@16: /** Dense matrix constructor with defined size Chris@16: * \param size1 number of rows Chris@16: * \param size2 number of columns Chris@16: */ Chris@16: BOOST_UBLAS_INLINE Chris@16: matrix (size_type size1, size_type size2): Chris@16: matrix_container (), Chris@16: size1_ (size1), size2_ (size2), data_ (layout_type::storage_size (size1, size2)) { Chris@16: } Chris@16: Chris@16: /** Dense matrix constructor with defined size a initial value for all the matrix elements Chris@16: * \param size1 number of rows Chris@16: * \param size2 number of columns Chris@16: * \param init initial value assigned to all elements Chris@16: */ Chris@16: matrix (size_type size1, size_type size2, const value_type &init): Chris@16: matrix_container (), Chris@16: size1_ (size1), size2_ (size2), data_ (layout_type::storage_size (size1, size2), init) { Chris@16: } Chris@16: Chris@16: /** Dense matrix constructor with defined size and an initial data array Chris@16: * \param size1 number of rows Chris@16: * \param size2 number of columns Chris@16: * \param data array to copy into the matrix. Must have the same dimension as the matrix Chris@16: */ Chris@16: BOOST_UBLAS_INLINE Chris@16: matrix (size_type size1, size_type size2, const array_type &data): Chris@16: matrix_container (), Chris@16: size1_ (size1), size2_ (size2), data_ (data) {} Chris@16: Chris@16: /** Copy-constructor of a dense matrix Chris@16: * \param m is a dense matrix Chris@16: */ Chris@16: BOOST_UBLAS_INLINE Chris@16: matrix (const matrix &m): Chris@16: matrix_container (), Chris@16: size1_ (m.size1_), size2_ (m.size2_), data_ (m.data_) {} Chris@16: Chris@16: /** Copy-constructor of a dense matrix from a matrix expression Chris@16: * \param ae is a matrix expression Chris@16: */ Chris@16: template Chris@16: BOOST_UBLAS_INLINE Chris@16: matrix (const matrix_expression &ae): Chris@16: matrix_container (), Chris@16: size1_ (ae ().size1 ()), size2_ (ae ().size2 ()), data_ (layout_type::storage_size (size1_, size2_)) { Chris@16: matrix_assign (*this, ae); Chris@16: } Chris@16: Chris@16: // Accessors Chris@16: /** Return the number of rows of the matrix Chris@16: * You can also use the free size<>() function in operation/size.hpp as size<1>(m) where m is a matrix Chris@16: */ Chris@16: BOOST_UBLAS_INLINE Chris@16: size_type size1 () const { Chris@16: return size1_; Chris@16: } Chris@16: Chris@16: /** Return the number of colums of the matrix Chris@16: * You can also use the free size<>() function in operation/size.hpp as size<2>(m) where m is a matrix Chris@16: */ Chris@16: BOOST_UBLAS_INLINE Chris@16: size_type size2 () const { Chris@16: return size2_; Chris@16: } Chris@16: Chris@16: // Storage accessors Chris@16: /** Return a constant reference to the internal storage of a dense matrix, i.e. the raw data Chris@16: * It's type depends on the type used by the matrix to store its data Chris@16: */ Chris@16: BOOST_UBLAS_INLINE Chris@16: const array_type &data () const { Chris@16: return data_; Chris@16: } Chris@16: /** Return a reference to the internal storage of a dense matrix, i.e. the raw data Chris@16: * It's type depends on the type used by the matrix to store its data Chris@16: */ Chris@16: BOOST_UBLAS_INLINE Chris@16: array_type &data () { Chris@16: return data_; Chris@16: } Chris@16: Chris@16: // Resizing Chris@16: /** Resize a matrix to new dimensions Chris@16: * If data are preserved, then if the size if bigger at least on one dimension, extra values are filled with zeros. Chris@16: * If data are not preserved, then nothing has to be assumed regarding the content of the matrix after resizing. Chris@16: * \param size1 the new number of rows Chris@16: * \param size2 the new number of colums Chris@16: * \param preserve a boolean to say if one wants the data to be preserved during the resizing. Default is true. Chris@16: */ Chris@16: BOOST_UBLAS_INLINE Chris@16: void resize (size_type size1, size_type size2, bool preserve = true) { Chris@16: if (preserve) { Chris@16: self_type temporary (size1, size2); Chris@16: detail::matrix_resize_preserve (*this, temporary); Chris@16: } Chris@16: else { Chris@16: data ().resize (layout_type::storage_size (size1, size2)); Chris@16: size1_ = size1; Chris@16: size2_ = size2; Chris@16: } Chris@16: } Chris@16: Chris@16: // Element access Chris@16: Chris@16: /** Access a matrix element. Here we return a const reference Chris@16: * \param i the first coordinate of the element. By default it's the row Chris@16: * \param j the second coordinate of the element. By default it's the column Chris@16: * \return a const reference to the element Chris@16: */ Chris@16: BOOST_UBLAS_INLINE Chris@16: const_reference operator () (size_type i, size_type j) const { Chris@16: return data () [layout_type::element (i, size1_, j, size2_)]; Chris@16: } Chris@16: Chris@16: /** Access a matrix element. Here we return a reference Chris@16: * \param i the first coordinate of the element. By default it's the row Chris@16: * \param j the second coordinate of the element. By default it's the column Chris@16: * \return a reference to the element Chris@16: */ Chris@16: BOOST_UBLAS_INLINE Chris@16: reference at_element (size_type i, size_type j) { Chris@16: return data () [layout_type::element (i, size1_, j, size2_)]; Chris@16: } Chris@16: Chris@16: /** Access a matrix element. Here we return a reference Chris@16: * \param i the first coordinate of the element. By default it's the row Chris@16: * \param j the second coordinate of the element. By default it's the column Chris@16: * \return a reference to the element Chris@16: */ Chris@16: BOOST_UBLAS_INLINE Chris@16: reference operator () (size_type i, size_type j) { Chris@16: return at_element (i, j); Chris@16: } Chris@16: Chris@16: // Element assignment Chris@16: Chris@16: /** Change the value of a matrix element. Return back a reference to it Chris@16: * \param i the first coordinate of the element. By default it's the row Chris@16: * \param j the second coordinate of the element. By default it's the column Chris@16: * \param t the new value of the element Chris@16: * \return a reference to the newly changed element Chris@16: */ Chris@16: BOOST_UBLAS_INLINE Chris@16: reference insert_element (size_type i, size_type j, const_reference t) { Chris@16: return (at_element (i, j) = t); Chris@16: } Chris@16: Chris@16: /** Erase the element Chris@16: * For most types (int, double, etc...) it means setting 0 (zero) the element at zero in fact. Chris@16: * For user-defined types, it could be another value if you decided it. Your type in that case must Chris@16: * contain a default null value. Chris@16: * \param i the first coordinate of the element. By default it's the row Chris@16: * \param j the second coordinate of the element. By default it's the column Chris@16: */ Chris@16: void erase_element (size_type i, size_type j) { Chris@16: at_element (i, j) = value_type/*zero*/(); Chris@16: } Chris@16: Chris@16: // Zeroing Chris@16: /** Erase all elements in the matrix Chris@16: * For most types (int, double, etc...) it means writing 0 (zero) everywhere. Chris@16: * For user-defined types, it could be another value if you decided it. Your type in that case must Chris@16: * contain a default null value. Chris@16: */ Chris@16: BOOST_UBLAS_INLINE Chris@16: void clear () { Chris@16: std::fill (data ().begin (), data ().end (), value_type/*zero*/()); Chris@16: } Chris@16: Chris@16: // Assignment Chris@16: #ifdef BOOST_UBLAS_MOVE_SEMANTICS Chris@16: Chris@16: /*! @note "pass by value" the key idea to enable move semantics */ Chris@16: BOOST_UBLAS_INLINE Chris@16: matrix &operator = (matrix m) { Chris@16: assign_temporary(m); Chris@16: return *this; Chris@16: } Chris@16: #else Chris@16: BOOST_UBLAS_INLINE Chris@16: matrix &operator = (const matrix &m) { Chris@16: size1_ = m.size1_; Chris@16: size2_ = m.size2_; Chris@16: data () = m.data (); Chris@16: return *this; Chris@16: } Chris@16: #endif Chris@16: template // Container assignment without temporary Chris@16: BOOST_UBLAS_INLINE Chris@16: matrix &operator = (const matrix_container &m) { Chris@16: resize (m ().size1 (), m ().size2 (), false); Chris@16: assign (m); Chris@16: return *this; Chris@16: } Chris@16: BOOST_UBLAS_INLINE Chris@16: matrix &assign_temporary (matrix &m) { Chris@16: swap (m); Chris@16: return *this; Chris@16: } Chris@16: template Chris@16: BOOST_UBLAS_INLINE Chris@16: matrix &operator = (const matrix_expression &ae) { Chris@16: self_type temporary (ae); Chris@16: return assign_temporary (temporary); Chris@16: } Chris@16: template Chris@16: BOOST_UBLAS_INLINE Chris@16: matrix &assign (const matrix_expression &ae) { Chris@16: matrix_assign (*this, ae); Chris@16: return *this; Chris@16: } Chris@16: template Chris@16: BOOST_UBLAS_INLINE Chris@16: matrix& operator += (const matrix_expression &ae) { Chris@16: self_type temporary (*this + ae); Chris@16: return assign_temporary (temporary); Chris@16: } Chris@16: template // Container assignment without temporary Chris@16: BOOST_UBLAS_INLINE Chris@16: matrix &operator += (const matrix_container &m) { Chris@16: plus_assign (m); Chris@16: return *this; Chris@16: } Chris@16: template Chris@16: BOOST_UBLAS_INLINE Chris@16: matrix &plus_assign (const matrix_expression &ae) { Chris@16: matrix_assign (*this, ae); Chris@16: return *this; Chris@16: } Chris@16: template Chris@16: BOOST_UBLAS_INLINE Chris@16: matrix& operator -= (const matrix_expression &ae) { Chris@16: self_type temporary (*this - ae); Chris@16: return assign_temporary (temporary); Chris@16: } Chris@16: template // Container assignment without temporary Chris@16: BOOST_UBLAS_INLINE Chris@16: matrix &operator -= (const matrix_container &m) { Chris@16: minus_assign (m); Chris@16: return *this; Chris@16: } Chris@16: template Chris@16: BOOST_UBLAS_INLINE Chris@16: matrix &minus_assign (const matrix_expression &ae) { Chris@16: matrix_assign (*this, ae); Chris@16: return *this; Chris@16: } Chris@16: template Chris@16: BOOST_UBLAS_INLINE Chris@16: matrix& operator *= (const AT &at) { Chris@16: matrix_assign_scalar (*this, at); Chris@16: return *this; Chris@16: } Chris@16: template Chris@16: BOOST_UBLAS_INLINE Chris@16: matrix& operator /= (const AT &at) { Chris@16: matrix_assign_scalar (*this, at); Chris@16: return *this; Chris@16: } Chris@16: Chris@16: // Swapping Chris@16: BOOST_UBLAS_INLINE Chris@16: void swap (matrix &m) { Chris@16: if (this != &m) { Chris@16: std::swap (size1_, m.size1_); Chris@16: std::swap (size2_, m.size2_); Chris@16: data ().swap (m.data ()); Chris@16: } Chris@16: } Chris@16: BOOST_UBLAS_INLINE Chris@16: friend void swap (matrix &m1, matrix &m2) { Chris@16: m1.swap (m2); Chris@16: } Chris@16: Chris@16: // Iterator types Chris@16: private: Chris@16: // Use the storage array iterator Chris@16: typedef typename A::const_iterator const_subiterator_type; Chris@16: typedef typename A::iterator subiterator_type; Chris@16: Chris@16: public: Chris@16: #ifdef BOOST_UBLAS_USE_INDEXED_ITERATOR Chris@16: typedef indexed_iterator1 iterator1; Chris@16: typedef indexed_iterator2 iterator2; Chris@16: typedef indexed_const_iterator1 const_iterator1; Chris@16: typedef indexed_const_iterator2 const_iterator2; Chris@16: #else Chris@16: class const_iterator1; Chris@16: class iterator1; Chris@16: class const_iterator2; Chris@16: class iterator2; Chris@16: #endif Chris@16: typedef reverse_iterator_base1 const_reverse_iterator1; Chris@16: typedef reverse_iterator_base1 reverse_iterator1; Chris@16: typedef reverse_iterator_base2 const_reverse_iterator2; Chris@16: typedef reverse_iterator_base2 reverse_iterator2; Chris@16: Chris@16: // Element lookup Chris@16: BOOST_UBLAS_INLINE Chris@16: const_iterator1 find1 (int /* rank */, size_type i, size_type j) const { Chris@16: #ifdef BOOST_UBLAS_USE_INDEXED_ITERATOR Chris@16: return const_iterator1 (*this, i, j); Chris@16: #else Chris@16: return const_iterator1 (*this, data ().begin () + layout_type::address (i, size1_, j, size2_)); Chris@16: #endif Chris@16: } Chris@16: BOOST_UBLAS_INLINE Chris@16: iterator1 find1 (int /* rank */, size_type i, size_type j) { Chris@16: #ifdef BOOST_UBLAS_USE_INDEXED_ITERATOR Chris@16: return iterator1 (*this, i, j); Chris@16: #else Chris@16: return iterator1 (*this, data ().begin () + layout_type::address (i, size1_, j, size2_)); Chris@16: #endif Chris@16: } Chris@16: BOOST_UBLAS_INLINE Chris@16: const_iterator2 find2 (int /* rank */, size_type i, size_type j) const { Chris@16: #ifdef BOOST_UBLAS_USE_INDEXED_ITERATOR Chris@16: return const_iterator2 (*this, i, j); Chris@16: #else Chris@16: return const_iterator2 (*this, data ().begin () + layout_type::address (i, size1_, j, size2_)); Chris@16: #endif Chris@16: } Chris@16: BOOST_UBLAS_INLINE Chris@16: iterator2 find2 (int /* rank */, size_type i, size_type j) { Chris@16: #ifdef BOOST_UBLAS_USE_INDEXED_ITERATOR Chris@16: return iterator2 (*this, i, j); Chris@16: #else Chris@16: return iterator2 (*this, data ().begin () + layout_type::address (i, size1_, j, size2_)); Chris@16: #endif Chris@16: } Chris@16: Chris@16: Chris@16: #ifndef BOOST_UBLAS_USE_INDEXED_ITERATOR Chris@16: class const_iterator1: Chris@16: public container_const_reference, Chris@16: public random_access_iterator_base { Chris@16: public: Chris@16: typedef typename matrix::value_type value_type; Chris@16: typedef typename matrix::difference_type difference_type; Chris@16: typedef typename matrix::const_reference reference; Chris@16: typedef const typename matrix::pointer pointer; Chris@16: Chris@16: typedef const_iterator2 dual_iterator_type; Chris@16: typedef const_reverse_iterator2 dual_reverse_iterator_type; Chris@16: Chris@16: // Construction and destruction Chris@16: BOOST_UBLAS_INLINE Chris@16: const_iterator1 (): Chris@16: container_const_reference (), it_ () {} Chris@16: BOOST_UBLAS_INLINE Chris@16: const_iterator1 (const self_type &m, const const_subiterator_type &it): Chris@16: container_const_reference (m), it_ (it) {} Chris@16: BOOST_UBLAS_INLINE Chris@16: const_iterator1 (const iterator1 &it): Chris@16: container_const_reference (it ()), it_ (it.it_) {} Chris@16: Chris@16: // Arithmetic Chris@16: BOOST_UBLAS_INLINE Chris@16: const_iterator1 &operator ++ () { Chris@16: layout_type::increment_i (it_, (*this) ().size1 (), (*this) ().size2 ()); Chris@16: return *this; Chris@16: } Chris@16: BOOST_UBLAS_INLINE Chris@16: const_iterator1 &operator -- () { Chris@16: layout_type::decrement_i (it_, (*this) ().size1 (), (*this) ().size2 ()); Chris@16: return *this; Chris@16: } Chris@16: BOOST_UBLAS_INLINE Chris@16: const_iterator1 &operator += (difference_type n) { Chris@16: layout_type::increment_i (it_, n, (*this) ().size1 (), (*this) ().size2 ()); Chris@16: return *this; Chris@16: } Chris@16: BOOST_UBLAS_INLINE Chris@16: const_iterator1 &operator -= (difference_type n) { Chris@16: layout_type::decrement_i (it_, n, (*this) ().size1 (), (*this) ().size2 ()); Chris@16: return *this; Chris@16: } Chris@16: BOOST_UBLAS_INLINE Chris@16: difference_type operator - (const const_iterator1 &it) const { Chris@16: BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ()); Chris@16: return layout_type::distance_i (it_ - it.it_, (*this) ().size1 (), (*this) ().size2 ()); Chris@16: } Chris@16: Chris@16: // Dereference Chris@16: BOOST_UBLAS_INLINE Chris@16: const_reference operator * () const { Chris@16: BOOST_UBLAS_CHECK (index1 () < (*this) ().size1 (), bad_index ()); Chris@16: BOOST_UBLAS_CHECK (index2 () < (*this) ().size2 (), bad_index ()); Chris@16: return *it_; Chris@16: } Chris@16: BOOST_UBLAS_INLINE Chris@16: const_reference operator [] (difference_type n) const { Chris@16: return *(*this + n); Chris@16: } Chris@16: Chris@16: #ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION Chris@16: BOOST_UBLAS_INLINE Chris@16: #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION Chris@16: typename self_type:: Chris@16: #endif Chris@16: const_iterator2 begin () const { Chris@16: const self_type &m = (*this) (); Chris@16: return m.find2 (1, index1 (), 0); Chris@16: } Chris@16: BOOST_UBLAS_INLINE Chris@16: #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION Chris@16: typename self_type:: Chris@16: #endif Chris@101: const_iterator2 cbegin () const { Chris@101: return begin (); Chris@101: } Chris@101: BOOST_UBLAS_INLINE Chris@101: #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION Chris@101: typename self_type:: Chris@101: #endif Chris@16: const_iterator2 end () const { Chris@16: const self_type &m = (*this) (); Chris@16: return m.find2 (1, index1 (), m.size2 ()); Chris@16: } Chris@16: BOOST_UBLAS_INLINE Chris@16: #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION Chris@16: typename self_type:: Chris@16: #endif Chris@101: const_iterator2 cend () const { Chris@101: return end (); Chris@101: } Chris@101: BOOST_UBLAS_INLINE Chris@101: #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION Chris@101: typename self_type:: Chris@101: #endif Chris@16: const_reverse_iterator2 rbegin () const { Chris@16: return const_reverse_iterator2 (end ()); Chris@16: } Chris@16: BOOST_UBLAS_INLINE Chris@16: #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION Chris@16: typename self_type:: Chris@16: #endif Chris@101: const_reverse_iterator2 crbegin () const { Chris@101: return rbegin (); Chris@101: } Chris@101: BOOST_UBLAS_INLINE Chris@101: #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION Chris@101: typename self_type:: Chris@101: #endif Chris@16: const_reverse_iterator2 rend () const { Chris@16: return const_reverse_iterator2 (begin ()); Chris@16: } Chris@101: BOOST_UBLAS_INLINE Chris@101: #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION Chris@101: typename self_type:: Chris@101: #endif Chris@101: const_reverse_iterator2 crend () const { Chris@101: return rend (); Chris@101: } Chris@16: #endif Chris@16: Chris@16: // Indices Chris@16: BOOST_UBLAS_INLINE Chris@16: size_type index1 () const { Chris@16: const self_type &m = (*this) (); Chris@16: return layout_type::index_i (it_ - m.begin1 ().it_, m.size1 (), m.size2 ()); Chris@16: } Chris@16: BOOST_UBLAS_INLINE Chris@16: size_type index2 () const { Chris@16: const self_type &m = (*this) (); Chris@16: return layout_type::index_j (it_ - m.begin1 ().it_, m.size1 (), m.size2 ()); Chris@16: } Chris@16: Chris@16: // Assignment Chris@16: BOOST_UBLAS_INLINE Chris@16: const_iterator1 &operator = (const const_iterator1 &it) { Chris@16: container_const_reference::assign (&it ()); Chris@16: it_ = it.it_; Chris@16: return *this; Chris@16: } Chris@16: Chris@16: // Comparison Chris@16: BOOST_UBLAS_INLINE Chris@16: bool operator == (const const_iterator1 &it) const { Chris@16: BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ()); Chris@16: return it_ == it.it_; Chris@16: } Chris@16: BOOST_UBLAS_INLINE Chris@16: bool operator < (const const_iterator1 &it) const { Chris@16: BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ()); Chris@16: return it_ < it.it_; Chris@16: } Chris@16: Chris@16: private: Chris@16: const_subiterator_type it_; Chris@16: Chris@16: friend class iterator1; Chris@16: }; Chris@16: #endif Chris@16: Chris@16: BOOST_UBLAS_INLINE Chris@16: const_iterator1 begin1 () const { Chris@16: return find1 (0, 0, 0); Chris@16: } Chris@16: BOOST_UBLAS_INLINE Chris@101: const_iterator1 cbegin1 () const { Chris@101: return begin1 (); Chris@101: } Chris@101: BOOST_UBLAS_INLINE Chris@16: const_iterator1 end1 () const { Chris@16: return find1 (0, size1_, 0); Chris@16: } Chris@101: BOOST_UBLAS_INLINE Chris@101: const_iterator1 cend1 () const { Chris@101: return end1 (); Chris@101: } Chris@16: Chris@16: #ifndef BOOST_UBLAS_USE_INDEXED_ITERATOR Chris@16: class iterator1: Chris@16: public container_reference, Chris@16: public random_access_iterator_base { Chris@16: public: Chris@16: typedef typename matrix::value_type value_type; Chris@16: typedef typename matrix::difference_type difference_type; Chris@16: typedef typename matrix::reference reference; Chris@16: typedef typename matrix::pointer pointer; Chris@16: Chris@16: typedef iterator2 dual_iterator_type; Chris@16: typedef reverse_iterator2 dual_reverse_iterator_type; Chris@16: Chris@16: // Construction and destruction Chris@16: BOOST_UBLAS_INLINE Chris@16: iterator1 (): Chris@16: container_reference (), it_ () {} Chris@16: BOOST_UBLAS_INLINE Chris@16: iterator1 (self_type &m, const subiterator_type &it): Chris@16: container_reference (m), it_ (it) {} Chris@16: Chris@16: // Arithmetic Chris@16: BOOST_UBLAS_INLINE Chris@16: iterator1 &operator ++ () { Chris@16: layout_type::increment_i (it_, (*this) ().size1 (), (*this) ().size2 ()); Chris@16: return *this; Chris@16: } Chris@16: BOOST_UBLAS_INLINE Chris@16: iterator1 &operator -- () { Chris@16: layout_type::decrement_i (it_, (*this) ().size1 (), (*this) ().size2 ()); Chris@16: return *this; Chris@16: } Chris@16: BOOST_UBLAS_INLINE Chris@16: iterator1 &operator += (difference_type n) { Chris@16: layout_type::increment_i (it_, n, (*this) ().size1 (), (*this) ().size2 ()); Chris@16: return *this; Chris@16: } Chris@16: BOOST_UBLAS_INLINE Chris@16: iterator1 &operator -= (difference_type n) { Chris@16: layout_type::decrement_i (it_, n, (*this) ().size1 (), (*this) ().size2 ()); Chris@16: return *this; Chris@16: } Chris@16: BOOST_UBLAS_INLINE Chris@16: difference_type operator - (const iterator1 &it) const { Chris@16: BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ()); Chris@16: return layout_type::distance_i (it_ - it.it_, (*this) ().size1 (), (*this) ().size2 ()); Chris@16: } Chris@16: Chris@16: // Dereference Chris@16: BOOST_UBLAS_INLINE Chris@16: reference operator * () const { Chris@16: BOOST_UBLAS_CHECK (index1 () < (*this) ().size1 (), bad_index ()); Chris@16: BOOST_UBLAS_CHECK (index2 () < (*this) ().size2 (), bad_index ()); Chris@16: return *it_; Chris@16: } Chris@16: BOOST_UBLAS_INLINE Chris@16: reference operator [] (difference_type n) const { Chris@16: return *(*this + n); Chris@16: } Chris@16: Chris@16: #ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION Chris@16: BOOST_UBLAS_INLINE Chris@16: #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION Chris@16: typename self_type:: Chris@16: #endif Chris@16: iterator2 begin () const { Chris@16: self_type &m = (*this) (); Chris@16: return m.find2 (1, index1 (), 0); Chris@16: } Chris@16: BOOST_UBLAS_INLINE Chris@16: #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION Chris@16: typename self_type:: Chris@16: #endif Chris@16: iterator2 end () const { Chris@16: self_type &m = (*this) (); Chris@16: return m.find2 (1, index1 (), m.size2 ()); Chris@16: } Chris@16: BOOST_UBLAS_INLINE Chris@16: #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION Chris@16: typename self_type:: Chris@16: #endif Chris@16: reverse_iterator2 rbegin () const { Chris@16: return reverse_iterator2 (end ()); Chris@16: } Chris@16: BOOST_UBLAS_INLINE Chris@16: #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION Chris@16: typename self_type:: Chris@16: #endif Chris@16: reverse_iterator2 rend () const { Chris@16: return reverse_iterator2 (begin ()); Chris@16: } Chris@16: #endif Chris@16: Chris@16: // Indices Chris@16: BOOST_UBLAS_INLINE Chris@16: size_type index1 () const { Chris@16: self_type &m = (*this) (); Chris@16: return layout_type::index_i (it_ - m.begin1 ().it_, m.size1 (), m.size2 ()); Chris@16: } Chris@16: BOOST_UBLAS_INLINE Chris@16: size_type index2 () const { Chris@16: self_type &m = (*this) (); Chris@16: return layout_type::index_j (it_ - m.begin1 ().it_, m.size1 (), m.size2 ()); Chris@16: } Chris@16: Chris@16: // Assignment Chris@16: BOOST_UBLAS_INLINE Chris@16: iterator1 &operator = (const iterator1 &it) { Chris@16: container_reference::assign (&it ()); Chris@16: it_ = it.it_; Chris@16: return *this; Chris@16: } Chris@16: Chris@16: // Comparison Chris@16: BOOST_UBLAS_INLINE Chris@16: bool operator == (const iterator1 &it) const { Chris@16: BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ()); Chris@16: return it_ == it.it_; Chris@16: } Chris@16: BOOST_UBLAS_INLINE Chris@16: bool operator < (const iterator1 &it) const { Chris@16: BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ()); Chris@16: return it_ < it.it_; Chris@16: } Chris@16: Chris@16: private: Chris@16: subiterator_type it_; Chris@16: Chris@16: friend class const_iterator1; Chris@16: }; Chris@16: #endif Chris@16: Chris@16: BOOST_UBLAS_INLINE Chris@16: iterator1 begin1 () { Chris@16: return find1 (0, 0, 0); Chris@16: } Chris@16: BOOST_UBLAS_INLINE Chris@16: iterator1 end1 () { Chris@16: return find1 (0, size1_, 0); Chris@16: } Chris@16: Chris@16: #ifndef BOOST_UBLAS_USE_INDEXED_ITERATOR Chris@16: class const_iterator2: Chris@16: public container_const_reference, Chris@16: public random_access_iterator_base { Chris@16: public: Chris@16: typedef typename matrix::value_type value_type; Chris@16: typedef typename matrix::difference_type difference_type; Chris@16: typedef typename matrix::const_reference reference; Chris@16: typedef const typename matrix::pointer pointer; Chris@16: Chris@16: typedef const_iterator1 dual_iterator_type; Chris@16: typedef const_reverse_iterator1 dual_reverse_iterator_type; Chris@16: Chris@16: // Construction and destruction Chris@16: BOOST_UBLAS_INLINE Chris@16: const_iterator2 (): Chris@16: container_const_reference (), it_ () {} Chris@16: BOOST_UBLAS_INLINE Chris@16: const_iterator2 (const self_type &m, const const_subiterator_type &it): Chris@16: container_const_reference (m), it_ (it) {} Chris@16: BOOST_UBLAS_INLINE Chris@16: const_iterator2 (const iterator2 &it): Chris@16: container_const_reference (it ()), it_ (it.it_) {} Chris@16: Chris@16: // Arithmetic Chris@16: BOOST_UBLAS_INLINE Chris@16: const_iterator2 &operator ++ () { Chris@16: layout_type::increment_j (it_, (*this) ().size1 (), (*this) ().size2 ()); Chris@16: return *this; Chris@16: } Chris@16: BOOST_UBLAS_INLINE Chris@16: const_iterator2 &operator -- () { Chris@16: layout_type::decrement_j (it_, (*this) ().size1 (), (*this) ().size2 ()); Chris@16: return *this; Chris@16: } Chris@16: BOOST_UBLAS_INLINE Chris@16: const_iterator2 &operator += (difference_type n) { Chris@16: layout_type::increment_j (it_, n, (*this) ().size1 (), (*this) ().size2 ()); Chris@16: return *this; Chris@16: } Chris@16: BOOST_UBLAS_INLINE Chris@16: const_iterator2 &operator -= (difference_type n) { Chris@16: layout_type::decrement_j (it_, n, (*this) ().size1 (), (*this) ().size2 ()); Chris@16: return *this; Chris@16: } Chris@16: BOOST_UBLAS_INLINE Chris@16: difference_type operator - (const const_iterator2 &it) const { Chris@16: BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ()); Chris@16: return layout_type::distance_j (it_ - it.it_, (*this) ().size1 (), (*this) ().size2 ()); Chris@16: } Chris@16: Chris@16: // Dereference Chris@16: BOOST_UBLAS_INLINE Chris@16: const_reference operator * () const { Chris@16: BOOST_UBLAS_CHECK (index1 () < (*this) ().size1 (), bad_index ()); Chris@16: BOOST_UBLAS_CHECK (index2 () < (*this) ().size2 (), bad_index ()); Chris@16: return *it_; Chris@16: } Chris@16: BOOST_UBLAS_INLINE Chris@16: const_reference operator [] (difference_type n) const { Chris@16: return *(*this + n); Chris@16: } Chris@16: Chris@16: #ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION Chris@16: BOOST_UBLAS_INLINE Chris@16: #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION Chris@16: typename self_type:: Chris@16: #endif Chris@16: const_iterator1 begin () const { Chris@16: const self_type &m = (*this) (); Chris@16: return m.find1 (1, 0, index2 ()); Chris@16: } Chris@16: BOOST_UBLAS_INLINE Chris@16: #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION Chris@16: typename self_type:: Chris@16: #endif Chris@101: const_iterator1 cbegin () const { Chris@101: return begin (); Chris@101: } Chris@101: BOOST_UBLAS_INLINE Chris@101: #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION Chris@101: typename self_type:: Chris@101: #endif Chris@16: const_iterator1 end () const { Chris@16: const self_type &m = (*this) (); Chris@16: return m.find1 (1, m.size1 (), index2 ()); Chris@16: } Chris@16: BOOST_UBLAS_INLINE Chris@16: #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION Chris@16: typename self_type:: Chris@16: #endif Chris@101: const_iterator1 cend () const { Chris@101: return end (); Chris@101: } Chris@101: BOOST_UBLAS_INLINE Chris@101: #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION Chris@101: typename self_type:: Chris@101: #endif Chris@16: const_reverse_iterator1 rbegin () const { Chris@16: return const_reverse_iterator1 (end ()); Chris@16: } Chris@16: BOOST_UBLAS_INLINE Chris@16: #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION Chris@16: typename self_type:: Chris@16: #endif Chris@101: const_reverse_iterator1 crbegin () const { Chris@101: return rbegin (); Chris@101: } Chris@101: BOOST_UBLAS_INLINE Chris@101: #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION Chris@101: typename self_type:: Chris@101: #endif Chris@16: const_reverse_iterator1 rend () const { Chris@16: return const_reverse_iterator1 (begin ()); Chris@16: } Chris@101: BOOST_UBLAS_INLINE Chris@101: #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION Chris@101: typename self_type:: Chris@101: #endif Chris@101: const_reverse_iterator1 crend () const { Chris@101: return rend (); Chris@101: } Chris@16: #endif Chris@16: Chris@16: // Indices Chris@16: BOOST_UBLAS_INLINE Chris@16: size_type index1 () const { Chris@16: const self_type &m = (*this) (); Chris@16: return layout_type::index_i (it_ - m.begin2 ().it_, m.size1 (), m.size2 ()); Chris@16: } Chris@16: BOOST_UBLAS_INLINE Chris@16: size_type index2 () const { Chris@16: const self_type &m = (*this) (); Chris@16: return layout_type::index_j (it_ - m.begin2 ().it_, m.size1 (), m.size2 ()); Chris@16: } Chris@16: Chris@16: // Assignment Chris@16: BOOST_UBLAS_INLINE Chris@16: const_iterator2 &operator = (const const_iterator2 &it) { Chris@16: container_const_reference::assign (&it ()); Chris@16: it_ = it.it_; Chris@16: return *this; Chris@16: } Chris@16: Chris@16: // Comparison Chris@16: BOOST_UBLAS_INLINE Chris@16: bool operator == (const const_iterator2 &it) const { Chris@16: BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ()); Chris@16: return it_ == it.it_; Chris@16: } Chris@16: BOOST_UBLAS_INLINE Chris@16: bool operator < (const const_iterator2 &it) const { Chris@16: BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ()); Chris@16: return it_ < it.it_; Chris@16: } Chris@16: Chris@16: private: Chris@16: const_subiterator_type it_; Chris@16: Chris@16: friend class iterator2; Chris@16: }; Chris@16: #endif Chris@16: Chris@16: BOOST_UBLAS_INLINE Chris@16: const_iterator2 begin2 () const { Chris@16: return find2 (0, 0, 0); Chris@16: } Chris@16: BOOST_UBLAS_INLINE Chris@101: const_iterator2 cbegin2 () const { Chris@101: return begin2 (); Chris@101: } Chris@101: BOOST_UBLAS_INLINE Chris@16: const_iterator2 end2 () const { Chris@16: return find2 (0, 0, size2_); Chris@16: } Chris@101: BOOST_UBLAS_INLINE Chris@101: const_iterator2 cend2 () const { Chris@101: return end2 (); Chris@101: } Chris@16: Chris@16: #ifndef BOOST_UBLAS_USE_INDEXED_ITERATOR Chris@16: class iterator2: Chris@16: public container_reference, Chris@16: public random_access_iterator_base { Chris@16: public: Chris@16: typedef typename matrix::value_type value_type; Chris@16: typedef typename matrix::difference_type difference_type; Chris@16: typedef typename matrix::reference reference; Chris@16: typedef typename matrix::pointer pointer; Chris@16: Chris@16: typedef iterator1 dual_iterator_type; Chris@16: typedef reverse_iterator1 dual_reverse_iterator_type; Chris@16: Chris@16: // Construction and destruction Chris@16: BOOST_UBLAS_INLINE Chris@16: iterator2 (): Chris@16: container_reference (), it_ () {} Chris@16: BOOST_UBLAS_INLINE Chris@16: iterator2 (self_type &m, const subiterator_type &it): Chris@16: container_reference (m), it_ (it) {} Chris@16: Chris@16: // Arithmetic Chris@16: BOOST_UBLAS_INLINE Chris@16: iterator2 &operator ++ () { Chris@16: layout_type::increment_j (it_, (*this) ().size1 (), (*this) ().size2 ()); Chris@16: return *this; Chris@16: } Chris@16: BOOST_UBLAS_INLINE Chris@16: iterator2 &operator -- () { Chris@16: layout_type::decrement_j (it_, (*this) ().size1 (), (*this) ().size2 ()); Chris@16: return *this; Chris@16: } Chris@16: BOOST_UBLAS_INLINE Chris@16: iterator2 &operator += (difference_type n) { Chris@16: layout_type::increment_j (it_, n, (*this) ().size1 (), (*this) ().size2 ()); Chris@16: return *this; Chris@16: } Chris@16: BOOST_UBLAS_INLINE Chris@16: iterator2 &operator -= (difference_type n) { Chris@16: layout_type::decrement_j (it_, n, (*this) ().size1 (), (*this) ().size2 ()); Chris@16: return *this; Chris@16: } Chris@16: BOOST_UBLAS_INLINE Chris@16: difference_type operator - (const iterator2 &it) const { Chris@16: BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ()); Chris@16: return layout_type::distance_j (it_ - it.it_, (*this) ().size1 (), (*this) ().size2 ()); Chris@16: } Chris@16: Chris@16: // Dereference Chris@16: BOOST_UBLAS_INLINE Chris@16: reference operator * () const { Chris@16: BOOST_UBLAS_CHECK (index1 () < (*this) ().size1 (), bad_index ()); Chris@16: BOOST_UBLAS_CHECK (index2 () < (*this) ().size2 (), bad_index ()); Chris@16: return *it_; Chris@16: } Chris@16: BOOST_UBLAS_INLINE Chris@16: reference operator [] (difference_type n) const { Chris@16: return *(*this + n); Chris@16: } Chris@16: Chris@16: #ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION Chris@16: BOOST_UBLAS_INLINE Chris@16: #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION Chris@16: typename self_type:: Chris@16: #endif Chris@16: iterator1 begin () const { Chris@16: self_type &m = (*this) (); Chris@16: return m.find1 (1, 0, index2 ()); Chris@16: } Chris@16: BOOST_UBLAS_INLINE Chris@16: #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION Chris@16: typename self_type:: Chris@16: #endif Chris@16: iterator1 end () const { Chris@16: self_type &m = (*this) (); Chris@16: return m.find1 (1, m.size1 (), index2 ()); Chris@16: } Chris@16: BOOST_UBLAS_INLINE Chris@16: #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION Chris@16: typename self_type:: Chris@16: #endif Chris@16: reverse_iterator1 rbegin () const { Chris@16: return reverse_iterator1 (end ()); Chris@16: } Chris@16: BOOST_UBLAS_INLINE Chris@16: #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION Chris@16: typename self_type:: Chris@16: #endif Chris@16: reverse_iterator1 rend () const { Chris@16: return reverse_iterator1 (begin ()); Chris@16: } Chris@16: #endif Chris@16: Chris@16: // Indices Chris@16: BOOST_UBLAS_INLINE Chris@16: size_type index1 () const { Chris@16: self_type &m = (*this) (); Chris@16: return layout_type::index_i (it_ - m.begin2 ().it_, m.size1 (), m.size2 ()); Chris@16: } Chris@16: BOOST_UBLAS_INLINE Chris@16: size_type index2 () const { Chris@16: self_type &m = (*this) (); Chris@16: return layout_type::index_j (it_ - m.begin2 ().it_, m.size1 (), m.size2 ()); Chris@16: } Chris@16: Chris@16: // Assignment Chris@16: BOOST_UBLAS_INLINE Chris@16: iterator2 &operator = (const iterator2 &it) { Chris@16: container_reference::assign (&it ()); Chris@16: it_ = it.it_; Chris@16: return *this; Chris@16: } Chris@16: Chris@16: // Comparison Chris@16: BOOST_UBLAS_INLINE Chris@16: bool operator == (const iterator2 &it) const { Chris@16: BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ()); Chris@16: return it_ == it.it_; Chris@16: } Chris@16: BOOST_UBLAS_INLINE Chris@16: bool operator < (const iterator2 &it) const { Chris@16: BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ()); Chris@16: return it_ < it.it_; Chris@16: } Chris@16: Chris@16: private: Chris@16: subiterator_type it_; Chris@16: Chris@16: friend class const_iterator2; Chris@16: }; Chris@16: #endif Chris@16: Chris@16: BOOST_UBLAS_INLINE Chris@16: iterator2 begin2 () { Chris@16: return find2 (0, 0, 0); Chris@16: } Chris@16: BOOST_UBLAS_INLINE Chris@16: iterator2 end2 () { Chris@16: return find2 (0, 0, size2_); Chris@16: } Chris@16: Chris@16: // Reverse iterators Chris@16: Chris@16: BOOST_UBLAS_INLINE Chris@16: const_reverse_iterator1 rbegin1 () const { Chris@16: return const_reverse_iterator1 (end1 ()); Chris@16: } Chris@16: BOOST_UBLAS_INLINE Chris@101: const_reverse_iterator1 crbegin1 () const { Chris@101: return rbegin1 (); Chris@101: } Chris@101: BOOST_UBLAS_INLINE Chris@16: const_reverse_iterator1 rend1 () const { Chris@16: return const_reverse_iterator1 (begin1 ()); Chris@16: } Chris@101: BOOST_UBLAS_INLINE Chris@101: const_reverse_iterator1 crend1 () const { Chris@101: return rend1 (); Chris@101: } Chris@16: Chris@16: BOOST_UBLAS_INLINE Chris@16: reverse_iterator1 rbegin1 () { Chris@16: return reverse_iterator1 (end1 ()); Chris@16: } Chris@16: BOOST_UBLAS_INLINE Chris@16: reverse_iterator1 rend1 () { Chris@16: return reverse_iterator1 (begin1 ()); Chris@16: } Chris@16: Chris@16: BOOST_UBLAS_INLINE Chris@16: const_reverse_iterator2 rbegin2 () const { Chris@16: return const_reverse_iterator2 (end2 ()); Chris@16: } Chris@16: BOOST_UBLAS_INLINE Chris@101: const_reverse_iterator2 crbegin2 () const { Chris@101: return rbegin2 (); Chris@101: } Chris@101: BOOST_UBLAS_INLINE Chris@16: const_reverse_iterator2 rend2 () const { Chris@16: return const_reverse_iterator2 (begin2 ()); Chris@16: } Chris@101: BOOST_UBLAS_INLINE Chris@101: const_reverse_iterator2 crend2 () const { Chris@101: return rend2 (); Chris@101: } Chris@16: Chris@16: BOOST_UBLAS_INLINE Chris@16: reverse_iterator2 rbegin2 () { Chris@16: return reverse_iterator2 (end2 ()); Chris@16: } Chris@16: BOOST_UBLAS_INLINE Chris@16: reverse_iterator2 rend2 () { Chris@16: return reverse_iterator2 (begin2 ()); Chris@16: } Chris@16: Chris@16: // Serialization Chris@16: template Chris@16: void serialize(Archive & ar, const unsigned int /* file_version */){ Chris@16: Chris@16: // we need to copy to a collection_size_type to get a portable Chris@16: // and efficient serialization Chris@16: serialization::collection_size_type s1 (size1_); Chris@16: serialization::collection_size_type s2 (size2_); Chris@16: Chris@16: // serialize the sizes Chris@16: ar & serialization::make_nvp("size1",s1) Chris@16: & serialization::make_nvp("size2",s2); Chris@16: Chris@16: // copy the values back if loading Chris@16: if (Archive::is_loading::value) { Chris@16: size1_ = s1; Chris@16: size2_ = s2; Chris@16: } Chris@16: ar & serialization::make_nvp("data",data_); Chris@16: } Chris@16: Chris@16: private: Chris@16: size_type size1_; Chris@16: size_type size2_; Chris@16: array_type data_; Chris@16: }; Chris@16: Chris@101: Chris@101: #ifdef BOOST_UBLAS_CPP_GE_2011 Chris@101: /** \brief A fixed size dense matrix of values of type \c T. Equivalent to a c-style 2 dimensional array. Chris@101: * Chris@101: * For a \f$(m \times n)\f$-dimensional fixed_matrix and \f$ 0 \leq i < m, 0 \leq j < n\f$, every element \f$ m_{i,j} \f$ is mapped to Chris@101: * the \f$(i.n + j)\f$-th element of the container for row major orientation or the \f$ (i + j.m) \f$-th element of Chris@101: * the container for column major orientation. In a dense matrix all elements are represented in memory in a Chris@101: * contiguous chunk of memory by definition. Chris@101: * Chris@101: * Orientation and storage can also be specified, otherwise \c row_major and \c std::array are used. It is \b not Chris@101: * required by the storage container to initialize elements of the matrix. Chris@101: * Chris@101: * \tparam T the type of object stored in the matrix (like double, float, std::complex, etc...) Chris@101: * \tparam L the storage organization. It can be either \c row_major or \c column_major. Default is \c row_major Chris@101: * \tparam A the type of Storage array. Default is \c std::array Chris@101: */ Chris@101: template Chris@101: class fixed_matrix: Chris@101: public matrix_container > { Chris@101: Chris@101: typedef T *pointer; Chris@101: typedef L layout_type; Chris@101: typedef fixed_matrix self_type; Chris@101: public: Chris@101: #ifdef BOOST_UBLAS_ENABLE_PROXY_SHORTCUTS Chris@101: using matrix_container::operator (); Chris@101: #endif Chris@101: typedef typename A::size_type size_type; Chris@101: typedef typename A::difference_type difference_type; Chris@101: typedef T value_type; Chris@101: typedef const T &const_reference; Chris@101: typedef T &reference; Chris@101: typedef A array_type; Chris@101: typedef const matrix_reference const_closure_type; Chris@101: typedef matrix_reference closure_type; Chris@101: typedef vector vector_temporary_type; Chris@101: typedef self_type matrix_temporary_type; Chris@101: typedef dense_tag storage_category; Chris@101: // This could be better for performance, Chris@101: // typedef typename unknown_orientation_tag orientation_category; Chris@101: // but others depend on the orientation information... Chris@101: typedef typename L::orientation_category orientation_category; Chris@101: Chris@101: // Construction and destruction Chris@101: Chris@101: /// Default dense fixed_matrix constructor. Make a dense fixed_matrix of size M x N Chris@101: BOOST_UBLAS_INLINE Chris@101: fixed_matrix (): Chris@101: matrix_container (), Chris@101: data_ () {} Chris@101: Chris@101: /// \brief Construct a fixed_matrix from a list of values Chris@101: /// The list may be included in curly braces. Typical syntax is choices are : Chris@101: /// fixed_matrix v = { 1, 2, 3, 4 } or fixed_matrix v( {1, 2, 3, 4} ) or fixed_matrix v( 1, 2, 3, 4 ) Chris@101: template Chris@101: fixed_matrix(value_type v0, Types... vrest) : Chris@101: matrix_container (), Chris@101: data_{ { v0, vrest... } } {} Chris@101: Chris@101: /** Dense fixed_matrix constructor with defined initial value for all the matrix elements Chris@101: * \param init initial value assigned to all elements Chris@101: */ Chris@101: fixed_matrix (const value_type &init): Chris@101: matrix_container (), Chris@101: data_ ( ) { Chris@101: data_.fill(init); Chris@101: } Chris@101: Chris@101: /** Dense matrix constructor with defined initial data array Chris@101: * \param data array to copy into the matrix. Must have the same dimension as the matrix Chris@101: */ Chris@101: BOOST_UBLAS_INLINE Chris@101: fixed_matrix (const array_type &data): Chris@101: matrix_container (), Chris@101: data_ (data) {} Chris@101: Chris@101: /** Copy-constructor of a dense fixed_matrix Chris@101: * \param m is a dense fixed_matrix Chris@101: */ Chris@101: BOOST_UBLAS_INLINE Chris@101: fixed_matrix (const fixed_matrix &m): Chris@101: matrix_container (), Chris@101: data_ (m.data_) {} Chris@101: Chris@101: /** Copy-constructor of a dense matrix from a matrix expression Chris@101: * \param ae is a matrix expression Chris@101: */ Chris@101: template Chris@101: BOOST_UBLAS_INLINE Chris@101: fixed_matrix (const matrix_expression &ae): Chris@101: matrix_container (), Chris@101: data_ () { Chris@101: matrix_assign (*this, ae); Chris@101: } Chris@101: Chris@101: // Accessors Chris@101: /** Return the number of rows of the fixed_matrix Chris@101: * You can also use the free size<>() function in operation/size.hpp as size<1>(m) where m is a fixed_matrix Chris@101: */ Chris@101: BOOST_UBLAS_INLINE Chris@101: BOOST_CONSTEXPR size_type size1 () const { Chris@101: return M; Chris@101: } Chris@101: Chris@101: /** Return the number of colums of the fixed_matrix Chris@101: * You can also use the free size<>() function in operation/size.hpp as size<2>(m) where m is a fixed_matrix Chris@101: */ Chris@101: BOOST_UBLAS_INLINE Chris@101: BOOST_CONSTEXPR size_type size2 () const { Chris@101: return N; Chris@101: } Chris@101: Chris@101: // Storage accessors Chris@101: /** Return a constant reference to the internal storage of a dense matrix, i.e. the raw data Chris@101: * It's type depends on the type used by the matrix to store its data Chris@101: */ Chris@101: BOOST_UBLAS_INLINE Chris@101: const array_type &data () const { Chris@101: return data_; Chris@101: } Chris@101: /** Return a reference to the internal storage of a dense fixed_matrix, i.e. the raw data Chris@101: * It's type depends on the type used by the fixed_matrix to store its data Chris@101: */ Chris@101: BOOST_UBLAS_INLINE Chris@101: array_type &data () { Chris@101: return data_; Chris@101: } Chris@101: Chris@101: Chris@101: // Element access Chris@101: Chris@101: /** Access a fixed_matrix element. Here we return a const reference Chris@101: * \param i the first coordinate of the element. By default it's the row Chris@101: * \param j the second coordinate of the element. By default it's the column Chris@101: * \return a const reference to the element Chris@101: */ Chris@101: BOOST_UBLAS_INLINE Chris@101: const_reference operator () (size_type i, size_type j) const { Chris@101: return data () [layout_type::element (i, M, j, N)]; // Fixme: add static lookup for element(...) i.e.: element(i,j) Chris@101: } Chris@101: Chris@101: /** Access a fixed_matrix element. Here we return a reference Chris@101: * \param i the first coordinate of the element. By default it's the row Chris@101: * \param j the second coordinate of the element. By default it's the column Chris@101: * \return a reference to the element Chris@101: */ Chris@101: BOOST_UBLAS_INLINE Chris@101: reference at_element (size_type i, size_type j) { Chris@101: return data () [layout_type::element (i, M, j, N)]; Chris@101: } Chris@101: Chris@101: /** Access a fixed_matrix element. Here we return a reference Chris@101: * \param i the first coordinate of the element. By default it's the row Chris@101: * \param j the second coordinate of the element. By default it's the column Chris@101: * \return a reference to the element Chris@101: */ Chris@101: BOOST_UBLAS_INLINE Chris@101: reference operator () (size_type i, size_type j) { Chris@101: return at_element (i, j); Chris@101: } Chris@101: Chris@101: // Element assignment Chris@101: Chris@101: /** Change the value of a fixed_matrix element. Return back a reference to it Chris@101: * \param i the first coordinate of the element. By default it's the row Chris@101: * \param j the second coordinate of the element. By default it's the column Chris@101: * \param t the new value of the element Chris@101: * \return a reference to the newly changed element Chris@101: */ Chris@101: BOOST_UBLAS_INLINE Chris@101: reference insert_element (size_type i, size_type j, const_reference t) { Chris@101: return (at_element (i, j) = t); Chris@101: } Chris@101: Chris@101: /** Erase the element Chris@101: * For most types (int, double, etc...) it means setting 0 (zero) the element at zero in fact. Chris@101: * For user-defined types, it could be another value if you decided it. Your type in that case must Chris@101: * contain a default null value. Chris@101: * \param i the first coordinate of the element. By default it's the row Chris@101: * \param j the second coordinate of the element. By default it's the column Chris@101: */ Chris@101: void erase_element (size_type i, size_type j) { Chris@101: at_element (i, j) = value_type/*zero*/(); Chris@101: } Chris@101: Chris@101: // Zeroing Chris@101: /** Erase all elements in the fixed_matrix Chris@101: * For most types (int, double, etc...) it means writing 0 (zero) everywhere. Chris@101: * For user-defined types, it could be another value if you decided it. Your type in that case must Chris@101: * contain a default null value. Chris@101: */ Chris@101: BOOST_UBLAS_INLINE Chris@101: void clear () { Chris@101: std::fill (data ().begin (), data ().end (), value_type/*zero*/()); Chris@101: } Chris@101: Chris@101: // Assignment Chris@101: #ifdef BOOST_UBLAS_MOVE_SEMANTICS Chris@101: Chris@101: /*! @note "pass by value" the key idea to enable move semantics */ Chris@101: BOOST_UBLAS_INLINE Chris@101: fixed_matrix &operator = (matrix m) { Chris@101: assign_temporary(m); Chris@101: return *this; Chris@101: } Chris@101: #else Chris@101: BOOST_UBLAS_INLINE Chris@101: fixed_matrix &operator = (const fixed_matrix &m) { Chris@101: data () = m.data (); Chris@101: return *this; Chris@101: } Chris@101: #endif Chris@101: template // Container assignment without temporary Chris@101: BOOST_UBLAS_INLINE Chris@101: fixed_matrix &operator = (const matrix_container &m) { Chris@101: resize (m ().size1 (), m ().size2 (), false); Chris@101: assign (m); Chris@101: return *this; Chris@101: } Chris@101: BOOST_UBLAS_INLINE Chris@101: fixed_matrix &assign_temporary (fixed_matrix &m) { Chris@101: swap (m); Chris@101: return *this; Chris@101: } Chris@101: template Chris@101: BOOST_UBLAS_INLINE Chris@101: fixed_matrix &operator = (const matrix_expression &ae) { Chris@101: self_type temporary (ae); Chris@101: return assign_temporary (temporary); Chris@101: } Chris@101: template Chris@101: BOOST_UBLAS_INLINE Chris@101: fixed_matrix &assign (const matrix_expression &ae) { Chris@101: matrix_assign (*this, ae); Chris@101: return *this; Chris@101: } Chris@101: template Chris@101: BOOST_UBLAS_INLINE Chris@101: fixed_matrix& operator += (const matrix_expression &ae) { Chris@101: self_type temporary (*this + ae); Chris@101: return assign_temporary (temporary); Chris@101: } Chris@101: template // Container assignment without temporary Chris@101: BOOST_UBLAS_INLINE Chris@101: fixed_matrix &operator += (const matrix_container &m) { Chris@101: plus_assign (m); Chris@101: return *this; Chris@101: } Chris@101: template Chris@101: BOOST_UBLAS_INLINE Chris@101: fixed_matrix &plus_assign (const matrix_expression &ae) { Chris@101: matrix_assign (*this, ae); Chris@101: return *this; Chris@101: } Chris@101: template Chris@101: BOOST_UBLAS_INLINE Chris@101: fixed_matrix& operator -= (const matrix_expression &ae) { Chris@101: self_type temporary (*this - ae); Chris@101: return assign_temporary (temporary); Chris@101: } Chris@101: template // Container assignment without temporary Chris@101: BOOST_UBLAS_INLINE Chris@101: fixed_matrix &operator -= (const matrix_container &m) { Chris@101: minus_assign (m); Chris@101: return *this; Chris@101: } Chris@101: template Chris@101: BOOST_UBLAS_INLINE Chris@101: fixed_matrix &minus_assign (const matrix_expression &ae) { Chris@101: matrix_assign (*this, ae); Chris@101: return *this; Chris@101: } Chris@101: template Chris@101: BOOST_UBLAS_INLINE Chris@101: fixed_matrix& operator *= (const AT &at) { Chris@101: matrix_assign_scalar (*this, at); Chris@101: return *this; Chris@101: } Chris@101: template Chris@101: BOOST_UBLAS_INLINE Chris@101: fixed_matrix& operator /= (const AT &at) { Chris@101: matrix_assign_scalar (*this, at); Chris@101: return *this; Chris@101: } Chris@101: Chris@101: // Swapping Chris@101: BOOST_UBLAS_INLINE Chris@101: void swap (fixed_matrix &m) { Chris@101: if (this != &m) { Chris@101: data ().swap (m.data ()); Chris@101: } Chris@101: } Chris@101: BOOST_UBLAS_INLINE Chris@101: friend void swap (fixed_matrix &m1, fixed_matrix &m2) { Chris@101: m1.swap (m2); Chris@101: } Chris@101: Chris@101: // Iterator types Chris@101: private: Chris@101: // Use the storage array iterator Chris@101: typedef typename A::const_iterator const_subiterator_type; Chris@101: typedef typename A::iterator subiterator_type; Chris@101: Chris@101: public: Chris@101: #ifdef BOOST_UBLAS_USE_INDEXED_ITERATOR Chris@101: typedef indexed_iterator1 iterator1; Chris@101: typedef indexed_iterator2 iterator2; Chris@101: typedef indexed_const_iterator1 const_iterator1; Chris@101: typedef indexed_const_iterator2 const_iterator2; Chris@101: #else Chris@101: class const_iterator1; Chris@101: class iterator1; Chris@101: class const_iterator2; Chris@101: class iterator2; Chris@101: #endif Chris@101: typedef reverse_iterator_base1 const_reverse_iterator1; Chris@101: typedef reverse_iterator_base1 reverse_iterator1; Chris@101: typedef reverse_iterator_base2 const_reverse_iterator2; Chris@101: typedef reverse_iterator_base2 reverse_iterator2; Chris@101: Chris@101: // Element lookup Chris@101: BOOST_UBLAS_INLINE Chris@101: const_iterator1 find1 (int /* rank */, size_type i, size_type j) const { Chris@101: #ifdef BOOST_UBLAS_USE_INDEXED_ITERATOR Chris@101: return const_iterator1 (*this, i, j); Chris@101: #else Chris@101: return const_iterator1 (*this, data ().begin () + layout_type::address (i, M, j, N)); Chris@101: #endif Chris@101: } Chris@101: BOOST_UBLAS_INLINE Chris@101: iterator1 find1 (int /* rank */, size_type i, size_type j) { Chris@101: #ifdef BOOST_UBLAS_USE_INDEXED_ITERATOR Chris@101: return iterator1 (*this, i, j); Chris@101: #else Chris@101: return iterator1 (*this, data ().begin () + layout_type::address (i, M, j, N)); Chris@101: #endif Chris@101: } Chris@101: BOOST_UBLAS_INLINE Chris@101: const_iterator2 find2 (int /* rank */, size_type i, size_type j) const { Chris@101: #ifdef BOOST_UBLAS_USE_INDEXED_ITERATOR Chris@101: return const_iterator2 (*this, i, j); Chris@101: #else Chris@101: return const_iterator2 (*this, data ().begin () + layout_type::address (i, M, j, N)); Chris@101: #endif Chris@101: } Chris@101: BOOST_UBLAS_INLINE Chris@101: iterator2 find2 (int /* rank */, size_type i, size_type j) { Chris@101: #ifdef BOOST_UBLAS_USE_INDEXED_ITERATOR Chris@101: return iterator2 (*this, i, j); Chris@101: #else Chris@101: return iterator2 (*this, data ().begin () + layout_type::address (i, M, j, N)); Chris@101: #endif Chris@101: } Chris@101: Chris@101: Chris@101: #ifndef BOOST_UBLAS_USE_INDEXED_ITERATOR Chris@101: class const_iterator1: Chris@101: public container_const_reference, Chris@101: public random_access_iterator_base { Chris@101: public: Chris@101: typedef typename fixed_matrix::value_type value_type; Chris@101: typedef typename fixed_matrix::difference_type difference_type; Chris@101: typedef typename fixed_matrix::const_reference reference; Chris@101: typedef const typename fixed_matrix::pointer pointer; Chris@101: Chris@101: typedef const_iterator2 dual_iterator_type; Chris@101: typedef const_reverse_iterator2 dual_reverse_iterator_type; Chris@101: Chris@101: // Construction and destruction Chris@101: BOOST_UBLAS_INLINE Chris@101: const_iterator1 (): Chris@101: container_const_reference (), it_ () {} Chris@101: BOOST_UBLAS_INLINE Chris@101: const_iterator1 (const self_type &m, const const_subiterator_type &it): Chris@101: container_const_reference (m), it_ (it) {} Chris@101: BOOST_UBLAS_INLINE Chris@101: const_iterator1 (const iterator1 &it): Chris@101: container_const_reference (it ()), it_ (it.it_) {} Chris@101: Chris@101: // Arithmetic Chris@101: BOOST_UBLAS_INLINE Chris@101: const_iterator1 &operator ++ () { Chris@101: layout_type::increment_i (it_, (*this) ().size1 (), (*this) ().size2 ()); Chris@101: return *this; Chris@101: } Chris@101: BOOST_UBLAS_INLINE Chris@101: const_iterator1 &operator -- () { Chris@101: layout_type::decrement_i (it_, (*this) ().size1 (), (*this) ().size2 ()); Chris@101: return *this; Chris@101: } Chris@101: BOOST_UBLAS_INLINE Chris@101: const_iterator1 &operator += (difference_type n) { Chris@101: layout_type::increment_i (it_, n, (*this) ().size1 (), (*this) ().size2 ()); Chris@101: return *this; Chris@101: } Chris@101: BOOST_UBLAS_INLINE Chris@101: const_iterator1 &operator -= (difference_type n) { Chris@101: layout_type::decrement_i (it_, n, (*this) ().size1 (), (*this) ().size2 ()); Chris@101: return *this; Chris@101: } Chris@101: BOOST_UBLAS_INLINE Chris@101: difference_type operator - (const const_iterator1 &it) const { Chris@101: BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ()); Chris@101: return layout_type::distance_i (it_ - it.it_, (*this) ().size1 (), (*this) ().size2 ()); Chris@101: } Chris@101: Chris@101: // Dereference Chris@101: BOOST_UBLAS_INLINE Chris@101: const_reference operator * () const { Chris@101: BOOST_UBLAS_CHECK (index1 () < (*this) ().size1 (), bad_index ()); Chris@101: BOOST_UBLAS_CHECK (index2 () < (*this) ().size2 (), bad_index ()); Chris@101: return *it_; Chris@101: } Chris@101: BOOST_UBLAS_INLINE Chris@101: const_reference operator [] (difference_type n) const { Chris@101: return *(*this + n); Chris@101: } Chris@101: Chris@101: #ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION Chris@101: BOOST_UBLAS_INLINE Chris@101: #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION Chris@101: typename self_type:: Chris@101: #endif Chris@101: const_iterator2 begin () const { Chris@101: const self_type &m = (*this) (); Chris@101: return m.find2 (1, index1 (), 0); Chris@101: } Chris@101: BOOST_UBLAS_INLINE Chris@101: #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION Chris@101: typename self_type:: Chris@101: #endif Chris@101: const_iterator2 cbegin () const { Chris@101: return begin (); Chris@101: } Chris@101: BOOST_UBLAS_INLINE Chris@101: #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION Chris@101: typename self_type:: Chris@101: #endif Chris@101: const_iterator2 end () const { Chris@101: const self_type &m = (*this) (); Chris@101: return m.find2 (1, index1 (), m.size2 ()); Chris@101: } Chris@101: BOOST_UBLAS_INLINE Chris@101: #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION Chris@101: typename self_type:: Chris@101: #endif Chris@101: const_iterator2 cend () const { Chris@101: return end (); Chris@101: } Chris@101: BOOST_UBLAS_INLINE Chris@101: #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION Chris@101: typename self_type:: Chris@101: #endif Chris@101: const_reverse_iterator2 rbegin () const { Chris@101: return const_reverse_iterator2 (end ()); Chris@101: } Chris@101: BOOST_UBLAS_INLINE Chris@101: #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION Chris@101: typename self_type:: Chris@101: #endif Chris@101: const_reverse_iterator2 crbegin () const { Chris@101: return rbegin (); Chris@101: } Chris@101: BOOST_UBLAS_INLINE Chris@101: #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION Chris@101: typename self_type:: Chris@101: #endif Chris@101: const_reverse_iterator2 rend () const { Chris@101: return const_reverse_iterator2 (begin ()); Chris@101: } Chris@101: BOOST_UBLAS_INLINE Chris@101: #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION Chris@101: typename self_type:: Chris@101: #endif Chris@101: const_reverse_iterator2 crend () const { Chris@101: return rend (); Chris@101: } Chris@101: #endif Chris@101: Chris@101: // Indices Chris@101: BOOST_UBLAS_INLINE Chris@101: size_type index1 () const { Chris@101: const self_type &m = (*this) (); Chris@101: return layout_type::index_i (it_ - m.begin1 ().it_, m.size1 (), m.size2 ()); Chris@101: } Chris@101: BOOST_UBLAS_INLINE Chris@101: size_type index2 () const { Chris@101: const self_type &m = (*this) (); Chris@101: return layout_type::index_j (it_ - m.begin1 ().it_, m.size1 (), m.size2 ()); Chris@101: } Chris@101: Chris@101: // Assignment Chris@101: BOOST_UBLAS_INLINE Chris@101: const_iterator1 &operator = (const const_iterator1 &it) { Chris@101: container_const_reference::assign (&it ()); Chris@101: it_ = it.it_; Chris@101: return *this; Chris@101: } Chris@101: Chris@101: // Comparison Chris@101: BOOST_UBLAS_INLINE Chris@101: bool operator == (const const_iterator1 &it) const { Chris@101: BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ()); Chris@101: return it_ == it.it_; Chris@101: } Chris@101: BOOST_UBLAS_INLINE Chris@101: bool operator < (const const_iterator1 &it) const { Chris@101: BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ()); Chris@101: return it_ < it.it_; Chris@101: } Chris@101: Chris@101: private: Chris@101: const_subiterator_type it_; Chris@101: Chris@101: friend class iterator1; Chris@101: }; Chris@101: #endif Chris@101: Chris@101: BOOST_UBLAS_INLINE Chris@101: const_iterator1 begin1 () const { Chris@101: return find1 (0, 0, 0); Chris@101: } Chris@101: BOOST_UBLAS_INLINE Chris@101: const_iterator1 cbegin1 () const { Chris@101: return begin1 (); Chris@101: } Chris@101: BOOST_UBLAS_INLINE Chris@101: const_iterator1 end1 () const { Chris@101: return find1 (0, M, 0); Chris@101: } Chris@101: BOOST_UBLAS_INLINE Chris@101: const_iterator1 cend1 () const { Chris@101: return end1 (); Chris@101: } Chris@101: Chris@101: #ifndef BOOST_UBLAS_USE_INDEXED_ITERATOR Chris@101: class iterator1: Chris@101: public container_reference, Chris@101: public random_access_iterator_base { Chris@101: public: Chris@101: typedef typename fixed_matrix::value_type value_type; Chris@101: typedef typename fixed_matrix::difference_type difference_type; Chris@101: typedef typename fixed_matrix::reference reference; Chris@101: typedef typename fixed_matrix::pointer pointer; Chris@101: Chris@101: typedef iterator2 dual_iterator_type; Chris@101: typedef reverse_iterator2 dual_reverse_iterator_type; Chris@101: Chris@101: // Construction and destruction Chris@101: BOOST_UBLAS_INLINE Chris@101: iterator1 (): Chris@101: container_reference (), it_ () {} Chris@101: BOOST_UBLAS_INLINE Chris@101: iterator1 (self_type &m, const subiterator_type &it): Chris@101: container_reference (m), it_ (it) {} Chris@101: Chris@101: // Arithmetic Chris@101: BOOST_UBLAS_INLINE Chris@101: iterator1 &operator ++ () { Chris@101: layout_type::increment_i (it_, (*this) ().size1 (), (*this) ().size2 ()); Chris@101: return *this; Chris@101: } Chris@101: BOOST_UBLAS_INLINE Chris@101: iterator1 &operator -- () { Chris@101: layout_type::decrement_i (it_, (*this) ().size1 (), (*this) ().size2 ()); Chris@101: return *this; Chris@101: } Chris@101: BOOST_UBLAS_INLINE Chris@101: iterator1 &operator += (difference_type n) { Chris@101: layout_type::increment_i (it_, n, (*this) ().size1 (), (*this) ().size2 ()); Chris@101: return *this; Chris@101: } Chris@101: BOOST_UBLAS_INLINE Chris@101: iterator1 &operator -= (difference_type n) { Chris@101: layout_type::decrement_i (it_, n, (*this) ().size1 (), (*this) ().size2 ()); Chris@101: return *this; Chris@101: } Chris@101: BOOST_UBLAS_INLINE Chris@101: difference_type operator - (const iterator1 &it) const { Chris@101: BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ()); Chris@101: return layout_type::distance_i (it_ - it.it_, (*this) ().size1 (), (*this) ().size2 ()); Chris@101: } Chris@101: Chris@101: // Dereference Chris@101: BOOST_UBLAS_INLINE Chris@101: reference operator * () const { Chris@101: BOOST_UBLAS_CHECK (index1 () < (*this) ().size1 (), bad_index ()); Chris@101: BOOST_UBLAS_CHECK (index2 () < (*this) ().size2 (), bad_index ()); Chris@101: return *it_; Chris@101: } Chris@101: BOOST_UBLAS_INLINE Chris@101: reference operator [] (difference_type n) const { Chris@101: return *(*this + n); Chris@101: } Chris@101: Chris@101: #ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION Chris@101: BOOST_UBLAS_INLINE Chris@101: #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION Chris@101: typename self_type:: Chris@101: #endif Chris@101: iterator2 begin () const { Chris@101: self_type &m = (*this) (); Chris@101: return m.find2 (1, index1 (), 0); Chris@101: } Chris@101: BOOST_UBLAS_INLINE Chris@101: #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION Chris@101: typename self_type:: Chris@101: #endif Chris@101: iterator2 end () const { Chris@101: self_type &m = (*this) (); Chris@101: return m.find2 (1, index1 (), m.size2 ()); Chris@101: } Chris@101: BOOST_UBLAS_INLINE Chris@101: #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION Chris@101: typename self_type:: Chris@101: #endif Chris@101: reverse_iterator2 rbegin () const { Chris@101: return reverse_iterator2 (end ()); Chris@101: } Chris@101: BOOST_UBLAS_INLINE Chris@101: #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION Chris@101: typename self_type:: Chris@101: #endif Chris@101: reverse_iterator2 rend () const { Chris@101: return reverse_iterator2 (begin ()); Chris@101: } Chris@101: #endif Chris@101: Chris@101: // Indices Chris@101: BOOST_UBLAS_INLINE Chris@101: size_type index1 () const { Chris@101: self_type &m = (*this) (); Chris@101: return layout_type::index_i (it_ - m.begin1 ().it_, m.size1 (), m.size2 ()); Chris@101: } Chris@101: BOOST_UBLAS_INLINE Chris@101: size_type index2 () const { Chris@101: self_type &m = (*this) (); Chris@101: return layout_type::index_j (it_ - m.begin1 ().it_, m.size1 (), m.size2 ()); Chris@101: } Chris@101: Chris@101: // Assignment Chris@101: BOOST_UBLAS_INLINE Chris@101: iterator1 &operator = (const iterator1 &it) { Chris@101: container_reference::assign (&it ()); Chris@101: it_ = it.it_; Chris@101: return *this; Chris@101: } Chris@101: Chris@101: // Comparison Chris@101: BOOST_UBLAS_INLINE Chris@101: bool operator == (const iterator1 &it) const { Chris@101: BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ()); Chris@101: return it_ == it.it_; Chris@101: } Chris@101: BOOST_UBLAS_INLINE Chris@101: bool operator < (const iterator1 &it) const { Chris@101: BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ()); Chris@101: return it_ < it.it_; Chris@101: } Chris@101: Chris@101: private: Chris@101: subiterator_type it_; Chris@101: Chris@101: friend class const_iterator1; Chris@101: }; Chris@101: #endif Chris@101: Chris@101: BOOST_UBLAS_INLINE Chris@101: iterator1 begin1 () { Chris@101: return find1 (0, 0, 0); Chris@101: } Chris@101: BOOST_UBLAS_INLINE Chris@101: iterator1 end1 () { Chris@101: return find1 (0, M, 0); Chris@101: } Chris@101: Chris@101: #ifndef BOOST_UBLAS_USE_INDEXED_ITERATOR Chris@101: class const_iterator2: Chris@101: public container_const_reference, Chris@101: public random_access_iterator_base { Chris@101: public: Chris@101: typedef typename fixed_matrix::value_type value_type; Chris@101: typedef typename fixed_matrix::difference_type difference_type; Chris@101: typedef typename fixed_matrix::const_reference reference; Chris@101: typedef const typename fixed_matrix::pointer pointer; Chris@101: Chris@101: typedef const_iterator1 dual_iterator_type; Chris@101: typedef const_reverse_iterator1 dual_reverse_iterator_type; Chris@101: Chris@101: // Construction and destruction Chris@101: BOOST_UBLAS_INLINE Chris@101: const_iterator2 (): Chris@101: container_const_reference (), it_ () {} Chris@101: BOOST_UBLAS_INLINE Chris@101: const_iterator2 (const self_type &m, const const_subiterator_type &it): Chris@101: container_const_reference (m), it_ (it) {} Chris@101: BOOST_UBLAS_INLINE Chris@101: const_iterator2 (const iterator2 &it): Chris@101: container_const_reference (it ()), it_ (it.it_) {} Chris@101: Chris@101: // Arithmetic Chris@101: BOOST_UBLAS_INLINE Chris@101: const_iterator2 &operator ++ () { Chris@101: layout_type::increment_j (it_, (*this) ().size1 (), (*this) ().size2 ()); Chris@101: return *this; Chris@101: } Chris@101: BOOST_UBLAS_INLINE Chris@101: const_iterator2 &operator -- () { Chris@101: layout_type::decrement_j (it_, (*this) ().size1 (), (*this) ().size2 ()); Chris@101: return *this; Chris@101: } Chris@101: BOOST_UBLAS_INLINE Chris@101: const_iterator2 &operator += (difference_type n) { Chris@101: layout_type::increment_j (it_, n, (*this) ().size1 (), (*this) ().size2 ()); Chris@101: return *this; Chris@101: } Chris@101: BOOST_UBLAS_INLINE Chris@101: const_iterator2 &operator -= (difference_type n) { Chris@101: layout_type::decrement_j (it_, n, (*this) ().size1 (), (*this) ().size2 ()); Chris@101: return *this; Chris@101: } Chris@101: BOOST_UBLAS_INLINE Chris@101: difference_type operator - (const const_iterator2 &it) const { Chris@101: BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ()); Chris@101: return layout_type::distance_j (it_ - it.it_, (*this) ().size1 (), (*this) ().size2 ()); Chris@101: } Chris@101: Chris@101: // Dereference Chris@101: BOOST_UBLAS_INLINE Chris@101: const_reference operator * () const { Chris@101: BOOST_UBLAS_CHECK (index1 () < (*this) ().size1 (), bad_index ()); Chris@101: BOOST_UBLAS_CHECK (index2 () < (*this) ().size2 (), bad_index ()); Chris@101: return *it_; Chris@101: } Chris@101: BOOST_UBLAS_INLINE Chris@101: const_reference operator [] (difference_type n) const { Chris@101: return *(*this + n); Chris@101: } Chris@101: Chris@101: #ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION Chris@101: BOOST_UBLAS_INLINE Chris@101: #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION Chris@101: typename self_type:: Chris@101: #endif Chris@101: const_iterator1 begin () const { Chris@101: const self_type &m = (*this) (); Chris@101: return m.find1 (1, 0, index2 ()); Chris@101: } Chris@101: BOOST_UBLAS_INLINE Chris@101: #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION Chris@101: typename self_type:: Chris@101: #endif Chris@101: const_iterator1 cbegin () const { Chris@101: return begin (); Chris@101: } Chris@101: BOOST_UBLAS_INLINE Chris@101: #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION Chris@101: typename self_type:: Chris@101: #endif Chris@101: const_iterator1 end () const { Chris@101: const self_type &m = (*this) (); Chris@101: return m.find1 (1, m.size1 (), index2 ()); Chris@101: } Chris@101: BOOST_UBLAS_INLINE Chris@101: #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION Chris@101: typename self_type:: Chris@101: #endif Chris@101: const_iterator1 cend () const { Chris@101: return end (); Chris@101: } Chris@101: BOOST_UBLAS_INLINE Chris@101: #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION Chris@101: typename self_type:: Chris@101: #endif Chris@101: const_reverse_iterator1 rbegin () const { Chris@101: return const_reverse_iterator1 (end ()); Chris@101: } Chris@101: BOOST_UBLAS_INLINE Chris@101: #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION Chris@101: typename self_type:: Chris@101: #endif Chris@101: const_reverse_iterator1 crbegin () const { Chris@101: return rbegin (); Chris@101: } Chris@101: BOOST_UBLAS_INLINE Chris@101: #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION Chris@101: typename self_type:: Chris@101: #endif Chris@101: const_reverse_iterator1 rend () const { Chris@101: return const_reverse_iterator1 (begin ()); Chris@101: } Chris@101: BOOST_UBLAS_INLINE Chris@101: #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION Chris@101: typename self_type:: Chris@101: #endif Chris@101: const_reverse_iterator1 crend () const { Chris@101: return rend (); Chris@101: } Chris@101: #endif Chris@101: Chris@101: // Indices Chris@101: BOOST_UBLAS_INLINE Chris@101: size_type index1 () const { Chris@101: const self_type &m = (*this) (); Chris@101: return layout_type::index_i (it_ - m.begin2 ().it_, m.size1 (), m.size2 ()); Chris@101: } Chris@101: BOOST_UBLAS_INLINE Chris@101: size_type index2 () const { Chris@101: const self_type &m = (*this) (); Chris@101: return layout_type::index_j (it_ - m.begin2 ().it_, m.size1 (), m.size2 ()); Chris@101: } Chris@101: Chris@101: // Assignment Chris@101: BOOST_UBLAS_INLINE Chris@101: const_iterator2 &operator = (const const_iterator2 &it) { Chris@101: container_const_reference::assign (&it ()); Chris@101: it_ = it.it_; Chris@101: return *this; Chris@101: } Chris@101: Chris@101: // Comparison Chris@101: BOOST_UBLAS_INLINE Chris@101: bool operator == (const const_iterator2 &it) const { Chris@101: BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ()); Chris@101: return it_ == it.it_; Chris@101: } Chris@101: BOOST_UBLAS_INLINE Chris@101: bool operator < (const const_iterator2 &it) const { Chris@101: BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ()); Chris@101: return it_ < it.it_; Chris@101: } Chris@101: Chris@101: private: Chris@101: const_subiterator_type it_; Chris@101: Chris@101: friend class iterator2; Chris@101: }; Chris@101: #endif Chris@101: Chris@101: BOOST_UBLAS_INLINE Chris@101: const_iterator2 begin2 () const { Chris@101: return find2 (0, 0, 0); Chris@101: } Chris@101: BOOST_UBLAS_INLINE Chris@101: const_iterator2 cbegin2 () const { Chris@101: return begin2 (); Chris@101: } Chris@101: BOOST_UBLAS_INLINE Chris@101: const_iterator2 end2 () const { Chris@101: return find2 (0, 0, N); Chris@101: } Chris@101: BOOST_UBLAS_INLINE Chris@101: const_iterator2 cend2 () const { Chris@101: return end2 (); Chris@101: } Chris@101: Chris@101: #ifndef BOOST_UBLAS_USE_INDEXED_ITERATOR Chris@101: class iterator2: Chris@101: public container_reference, Chris@101: public random_access_iterator_base { Chris@101: public: Chris@101: typedef typename fixed_matrix::value_type value_type; Chris@101: typedef typename fixed_matrix::difference_type difference_type; Chris@101: typedef typename fixed_matrix::reference reference; Chris@101: typedef typename fixed_matrix::pointer pointer; Chris@101: Chris@101: typedef iterator1 dual_iterator_type; Chris@101: typedef reverse_iterator1 dual_reverse_iterator_type; Chris@101: Chris@101: // Construction and destruction Chris@101: BOOST_UBLAS_INLINE Chris@101: iterator2 (): Chris@101: container_reference (), it_ () {} Chris@101: BOOST_UBLAS_INLINE Chris@101: iterator2 (self_type &m, const subiterator_type &it): Chris@101: container_reference (m), it_ (it) {} Chris@101: Chris@101: // Arithmetic Chris@101: BOOST_UBLAS_INLINE Chris@101: iterator2 &operator ++ () { Chris@101: layout_type::increment_j (it_, (*this) ().size1 (), (*this) ().size2 ()); Chris@101: return *this; Chris@101: } Chris@101: BOOST_UBLAS_INLINE Chris@101: iterator2 &operator -- () { Chris@101: layout_type::decrement_j (it_, (*this) ().size1 (), (*this) ().size2 ()); Chris@101: return *this; Chris@101: } Chris@101: BOOST_UBLAS_INLINE Chris@101: iterator2 &operator += (difference_type n) { Chris@101: layout_type::increment_j (it_, n, (*this) ().size1 (), (*this) ().size2 ()); Chris@101: return *this; Chris@101: } Chris@101: BOOST_UBLAS_INLINE Chris@101: iterator2 &operator -= (difference_type n) { Chris@101: layout_type::decrement_j (it_, n, (*this) ().size1 (), (*this) ().size2 ()); Chris@101: return *this; Chris@101: } Chris@101: BOOST_UBLAS_INLINE Chris@101: difference_type operator - (const iterator2 &it) const { Chris@101: BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ()); Chris@101: return layout_type::distance_j (it_ - it.it_, (*this) ().size1 (), (*this) ().size2 ()); Chris@101: } Chris@101: Chris@101: // Dereference Chris@101: BOOST_UBLAS_INLINE Chris@101: reference operator * () const { Chris@101: BOOST_UBLAS_CHECK (index1 () < (*this) ().size1 (), bad_index ()); Chris@101: BOOST_UBLAS_CHECK (index2 () < (*this) ().size2 (), bad_index ()); Chris@101: return *it_; Chris@101: } Chris@101: BOOST_UBLAS_INLINE Chris@101: reference operator [] (difference_type n) const { Chris@101: return *(*this + n); Chris@101: } Chris@101: Chris@101: #ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION Chris@101: BOOST_UBLAS_INLINE Chris@101: #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION Chris@101: typename self_type:: Chris@101: #endif Chris@101: iterator1 begin () const { Chris@101: self_type &m = (*this) (); Chris@101: return m.find1 (1, 0, index2 ()); Chris@101: } Chris@101: BOOST_UBLAS_INLINE Chris@101: #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION Chris@101: typename self_type:: Chris@101: #endif Chris@101: iterator1 end () const { Chris@101: self_type &m = (*this) (); Chris@101: return m.find1 (1, m.size1 (), index2 ()); Chris@101: } Chris@101: BOOST_UBLAS_INLINE Chris@101: #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION Chris@101: typename self_type:: Chris@101: #endif Chris@101: reverse_iterator1 rbegin () const { Chris@101: return reverse_iterator1 (end ()); Chris@101: } Chris@101: BOOST_UBLAS_INLINE Chris@101: #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION Chris@101: typename self_type:: Chris@101: #endif Chris@101: reverse_iterator1 rend () const { Chris@101: return reverse_iterator1 (begin ()); Chris@101: } Chris@101: #endif Chris@101: Chris@101: // Indices Chris@101: BOOST_UBLAS_INLINE Chris@101: size_type index1 () const { Chris@101: self_type &m = (*this) (); Chris@101: return layout_type::index_i (it_ - m.begin2 ().it_, m.size1 (), m.size2 ()); Chris@101: } Chris@101: BOOST_UBLAS_INLINE Chris@101: size_type index2 () const { Chris@101: self_type &m = (*this) (); Chris@101: return layout_type::index_j (it_ - m.begin2 ().it_, m.size1 (), m.size2 ()); Chris@101: } Chris@101: Chris@101: // Assignment Chris@101: BOOST_UBLAS_INLINE Chris@101: iterator2 &operator = (const iterator2 &it) { Chris@101: container_reference::assign (&it ()); Chris@101: it_ = it.it_; Chris@101: return *this; Chris@101: } Chris@101: Chris@101: // Comparison Chris@101: BOOST_UBLAS_INLINE Chris@101: bool operator == (const iterator2 &it) const { Chris@101: BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ()); Chris@101: return it_ == it.it_; Chris@101: } Chris@101: BOOST_UBLAS_INLINE Chris@101: bool operator < (const iterator2 &it) const { Chris@101: BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ()); Chris@101: return it_ < it.it_; Chris@101: } Chris@101: Chris@101: private: Chris@101: subiterator_type it_; Chris@101: Chris@101: friend class const_iterator2; Chris@101: }; Chris@101: #endif Chris@101: Chris@101: BOOST_UBLAS_INLINE Chris@101: iterator2 begin2 () { Chris@101: return find2 (0, 0, 0); Chris@101: } Chris@101: BOOST_UBLAS_INLINE Chris@101: iterator2 end2 () { Chris@101: return find2 (0, 0, N); Chris@101: } Chris@101: Chris@101: // Reverse iterators Chris@101: Chris@101: BOOST_UBLAS_INLINE Chris@101: const_reverse_iterator1 rbegin1 () const { Chris@101: return const_reverse_iterator1 (end1 ()); Chris@101: } Chris@101: BOOST_UBLAS_INLINE Chris@101: const_reverse_iterator1 crbegin1 () const { Chris@101: return rbegin1 (); Chris@101: } Chris@101: BOOST_UBLAS_INLINE Chris@101: const_reverse_iterator1 rend1 () const { Chris@101: return const_reverse_iterator1 (begin1 ()); Chris@101: } Chris@101: BOOST_UBLAS_INLINE Chris@101: const_reverse_iterator1 crend1 () const { Chris@101: return rend1 (); Chris@101: } Chris@101: Chris@101: BOOST_UBLAS_INLINE Chris@101: reverse_iterator1 rbegin1 () { Chris@101: return reverse_iterator1 (end1 ()); Chris@101: } Chris@101: BOOST_UBLAS_INLINE Chris@101: reverse_iterator1 rend1 () { Chris@101: return reverse_iterator1 (begin1 ()); Chris@101: } Chris@101: Chris@101: BOOST_UBLAS_INLINE Chris@101: const_reverse_iterator2 rbegin2 () const { Chris@101: return const_reverse_iterator2 (end2 ()); Chris@101: } Chris@101: BOOST_UBLAS_INLINE Chris@101: const_reverse_iterator2 crbegin2 () const { Chris@101: return rbegin2 (); Chris@101: } Chris@101: BOOST_UBLAS_INLINE Chris@101: const_reverse_iterator2 rend2 () const { Chris@101: return const_reverse_iterator2 (begin2 ()); Chris@101: } Chris@101: BOOST_UBLAS_INLINE Chris@101: const_reverse_iterator2 crend2 () const { Chris@101: return rend2 (); Chris@101: } Chris@101: Chris@101: BOOST_UBLAS_INLINE Chris@101: reverse_iterator2 rbegin2 () { Chris@101: return reverse_iterator2 (end2 ()); Chris@101: } Chris@101: BOOST_UBLAS_INLINE Chris@101: reverse_iterator2 rend2 () { Chris@101: return reverse_iterator2 (begin2 ()); Chris@101: } Chris@101: Chris@101: // Serialization Chris@101: template Chris@101: void serialize(Archive & ar, const unsigned int /* file_version */){ Chris@101: ar & serialization::make_nvp("data",data_); Chris@101: } Chris@101: Chris@101: private: Chris@101: array_type data_; Chris@101: }; Chris@101: Chris@101: #endif // BOOST_UBLAS_CPP_GE_2011 Chris@101: Chris@16: /** \brief A dense matrix of values of type \c T with a variable size bounded to a maximum of \f$M\f$ by \f$N\f$. Chris@16: * Chris@16: * For a \f$(m \times n)\f$-dimensional matrix and \f$ 0 \leq i < m, 0 \leq j < n\f$, every element \f$m_{i,j}\f$ is mapped Chris@16: * to the \f$(i.n + j)\f$-th element of the container for row major orientation or the \f$(i + j.m)\f$-th element Chris@16: * of the container for column major orientation. Finally in a dense matrix all elements are represented in memory Chris@16: * in a contiguous chunk of memory. Chris@16: * Chris@16: * Orientation can be specified. Default is \c row_major Chris@16: * The default constructor creates the matrix with size \f$M\f$ by \f$N\f$. Elements are constructed by the storage Chris@16: * type \c bounded_array, which need not initialise their value. Chris@16: * Chris@16: * \tparam T the type of object stored in the matrix (like double, float, complex, etc...) Chris@16: * \tparam M maximum and default number of rows (if not specified at construction) Chris@16: * \tparam N maximum and default number of columns (if not specified at construction) Chris@16: * \tparam L the storage organization. It can be either \c row_major or \c column_major. Default is \c row_major Chris@16: */ Chris@16: template Chris@16: class bounded_matrix: Chris@16: public matrix > { Chris@16: Chris@16: typedef matrix > matrix_type; Chris@16: public: Chris@16: typedef typename matrix_type::size_type size_type; Chris@16: static const size_type max_size1 = M; Chris@16: static const size_type max_size2 = N; Chris@16: Chris@16: // Construction and destruction Chris@16: BOOST_UBLAS_INLINE Chris@16: bounded_matrix (): Chris@16: matrix_type (M, N) {} Chris@16: BOOST_UBLAS_INLINE Chris@16: bounded_matrix (size_type size1, size_type size2): Chris@16: matrix_type (size1, size2) {} Chris@16: BOOST_UBLAS_INLINE Chris@16: bounded_matrix (const bounded_matrix &m): Chris@16: matrix_type (m) {} Chris@16: template // Allow matrix > construction Chris@16: BOOST_UBLAS_INLINE Chris@16: bounded_matrix (const matrix &m): Chris@16: matrix_type (m) {} Chris@16: template Chris@16: BOOST_UBLAS_INLINE Chris@16: bounded_matrix (const matrix_expression &ae): Chris@16: matrix_type (ae) {} Chris@16: BOOST_UBLAS_INLINE Chris@16: ~bounded_matrix () {} Chris@16: Chris@16: // Assignment Chris@16: #ifdef BOOST_UBLAS_MOVE_SEMANTICS Chris@16: Chris@16: /*! @note "pass by value" the key idea to enable move semantics */ Chris@16: BOOST_UBLAS_INLINE Chris@16: bounded_matrix &operator = (bounded_matrix m) { Chris@16: matrix_type::operator = (m); Chris@16: return *this; Chris@16: } Chris@16: #else Chris@16: BOOST_UBLAS_INLINE Chris@16: bounded_matrix &operator = (const bounded_matrix &m) { Chris@16: matrix_type::operator = (m); Chris@16: return *this; Chris@16: } Chris@16: #endif Chris@16: template // Generic matrix assignment Chris@16: BOOST_UBLAS_INLINE Chris@16: bounded_matrix &operator = (const matrix &m) { Chris@16: matrix_type::operator = (m); Chris@16: return *this; Chris@16: } Chris@16: template // Container assignment without temporary Chris@16: BOOST_UBLAS_INLINE Chris@16: bounded_matrix &operator = (const matrix_container &m) { Chris@16: matrix_type::operator = (m); Chris@16: return *this; Chris@16: } Chris@16: template Chris@16: BOOST_UBLAS_INLINE Chris@16: bounded_matrix &operator = (const matrix_expression &ae) { Chris@16: matrix_type::operator = (ae); Chris@16: return *this; Chris@16: } Chris@16: }; Chris@16: Chris@101: Chris@16: /** \brief A dense matrix of values of type \c T stored as a vector of vectors. Chris@16: * Chris@16: * Rows or columns are not stored into contiguous chunks of memory but data inside rows (or columns) are. Chris@16: * Orientation and storage can also be specified, otherwise a row major and unbounded arrays are used. Chris@16: * The data is stored as a vector of vectors, meaning that rows or columns might not be stored into contiguous chunks Chris@16: * of memory. Orientation and storage can also be specified, otherwise a row major and unbounded arrays are used. Chris@16: * The storage type defaults to \c unbounded_array> and orientation is \c row_major. It is \b not Chris@16: * required by the storage to initialize elements of the matrix. For a \f$(m \times n)\f$-dimensional matrix and Chris@16: * \f$ 0 \leq i < m, 0 \leq j < n\f$, every element \f$m_{i,j}\f$ is mapped to the \f$(i.n + j)\f$-th element of the Chris@16: * container for row major orientation or the \f$(i + j.m)\f$-th element of the container for column major orientation. Chris@16: * Chris@16: * \tparam T the type of object stored in the matrix (like double, float, complex, etc...) Chris@16: * \tparam L the storage organization. It can be either \c row_major or \c column_major. By default it is \c row_major Chris@16: * \tparam A the type of Storage array. By default, it is an \unbounded_array> Chris@16: */ Chris@16: template Chris@16: class vector_of_vector: Chris@16: public matrix_container > { Chris@16: Chris@16: typedef T *pointer; Chris@16: typedef L layout_type; Chris@16: typedef vector_of_vector self_type; Chris@16: public: Chris@16: #ifdef BOOST_UBLAS_ENABLE_PROXY_SHORTCUTS Chris@16: using matrix_container::operator (); Chris@16: #endif Chris@16: typedef typename A::size_type size_type; Chris@16: typedef typename A::difference_type difference_type; Chris@16: typedef T value_type; Chris@16: typedef const T &const_reference; Chris@16: typedef T &reference; Chris@16: typedef A array_type; Chris@16: typedef const matrix_reference const_closure_type; Chris@16: typedef matrix_reference closure_type; Chris@16: typedef vector vector_temporary_type; Chris@16: typedef self_type matrix_temporary_type; Chris@16: typedef dense_tag storage_category; Chris@16: // This could be better for performance, Chris@16: // typedef typename unknown_orientation_tag orientation_category; Chris@16: // but others depend on the orientation information... Chris@16: typedef typename L::orientation_category orientation_category; Chris@16: Chris@16: // Construction and destruction Chris@16: BOOST_UBLAS_INLINE Chris@16: vector_of_vector (): Chris@16: matrix_container (), Chris@16: size1_ (0), size2_ (0), data_ (1) {} Chris@16: BOOST_UBLAS_INLINE Chris@16: vector_of_vector (size_type size1, size_type size2): Chris@16: matrix_container (), Chris@16: size1_ (size1), size2_ (size2), data_ (1) { Chris@16: resize (size1, size2, true); Chris@16: } Chris@16: BOOST_UBLAS_INLINE Chris@16: vector_of_vector (const vector_of_vector &m): Chris@16: matrix_container (), Chris@16: size1_ (m.size1_), size2_ (m.size2_), data_ (m.data_) {} Chris@16: template Chris@16: BOOST_UBLAS_INLINE Chris@16: vector_of_vector (const matrix_expression &ae): Chris@16: matrix_container (), Chris@16: size1_ (ae ().size1 ()), size2_ (ae ().size2 ()), data_ (layout_type::size_M (size1_, size2_) + 1) { Chris@16: for (size_type k = 0; k < layout_type::size_M (size1_, size2_); ++ k) Chris@16: data ()[k].resize (layout_type::size_m (size1_, size2_)); Chris@16: matrix_assign (*this, ae); Chris@16: } Chris@16: Chris@16: // Accessors Chris@16: BOOST_UBLAS_INLINE Chris@16: size_type size1 () const { Chris@16: return size1_; Chris@16: } Chris@16: BOOST_UBLAS_INLINE Chris@16: size_type size2 () const { Chris@16: return size2_; Chris@16: } Chris@16: Chris@16: // Storage accessors Chris@16: BOOST_UBLAS_INLINE Chris@16: const array_type &data () const { Chris@16: return data_; Chris@16: } Chris@16: BOOST_UBLAS_INLINE Chris@16: array_type &data () { Chris@16: return data_; Chris@16: } Chris@16: Chris@16: // Resizing Chris@16: BOOST_UBLAS_INLINE Chris@16: void resize (size_type size1, size_type size2, bool preserve = true) { Chris@16: size1_ = size1; Chris@16: size2_ = size2; Chris@16: if (preserve) Chris@16: data ().resize (layout_type::size_M (size1, size2) + 1, typename array_type::value_type ()); Chris@16: else Chris@16: data ().resize (layout_type::size_M (size1, size2) + 1); Chris@16: for (size_type k = 0; k < layout_type::size_M (size1, size2); ++ k) { Chris@16: if (preserve) Chris@16: data () [k].resize (layout_type::size_m (size1, size2), value_type ()); Chris@16: else Chris@16: data () [k].resize (layout_type::size_m (size1, size2)); Chris@16: } Chris@16: } Chris@16: Chris@16: // Element access Chris@16: BOOST_UBLAS_INLINE Chris@16: const_reference operator () (size_type i, size_type j) const { Chris@16: return data () [layout_type::index_M (i, j)] [layout_type::index_m (i, j)]; Chris@16: } Chris@16: BOOST_UBLAS_INLINE Chris@16: reference at_element (size_type i, size_type j) { Chris@16: return data () [layout_type::index_M (i, j)] [layout_type::index_m (i, j)]; Chris@16: } Chris@16: BOOST_UBLAS_INLINE Chris@16: reference operator () (size_type i, size_type j) { Chris@16: return at_element (i, j); Chris@16: } Chris@16: Chris@16: // Element assignment Chris@16: BOOST_UBLAS_INLINE Chris@16: reference insert_element (size_type i, size_type j, const_reference t) { Chris@16: return (at_element (i, j) = t); Chris@16: } Chris@16: BOOST_UBLAS_INLINE Chris@16: void erase_element (size_type i, size_type j) { Chris@16: at_element (i, j) = value_type/*zero*/(); Chris@16: } Chris@16: Chris@16: // Zeroing Chris@16: BOOST_UBLAS_INLINE Chris@16: void clear () { Chris@16: for (size_type k = 0; k < layout_type::size_M (size1_, size2_); ++ k) Chris@16: std::fill (data () [k].begin (), data () [k].end (), value_type/*zero*/()); Chris@16: } Chris@16: Chris@16: // Assignment Chris@16: BOOST_UBLAS_INLINE Chris@16: vector_of_vector &operator = (const vector_of_vector &m) { Chris@16: size1_ = m.size1_; Chris@16: size2_ = m.size2_; Chris@16: data () = m.data (); Chris@16: return *this; Chris@16: } Chris@16: BOOST_UBLAS_INLINE Chris@16: vector_of_vector &assign_temporary (vector_of_vector &m) { Chris@16: swap (m); Chris@16: return *this; Chris@16: } Chris@16: template Chris@16: BOOST_UBLAS_INLINE Chris@16: vector_of_vector &operator = (const matrix_expression &ae) { Chris@16: self_type temporary (ae); Chris@16: return assign_temporary (temporary); Chris@16: } Chris@16: template // Container assignment without temporary Chris@16: BOOST_UBLAS_INLINE Chris@16: vector_of_vector &operator = (const matrix_container &m) { Chris@16: resize (m ().size1 (), m ().size2 (), false); Chris@16: assign (m); Chris@16: return *this; Chris@16: } Chris@16: template Chris@16: BOOST_UBLAS_INLINE Chris@16: vector_of_vector &assign (const matrix_expression &ae) { Chris@16: matrix_assign (*this, ae); Chris@16: return *this; Chris@16: } Chris@16: template Chris@16: BOOST_UBLAS_INLINE Chris@16: vector_of_vector& operator += (const matrix_expression &ae) { Chris@16: self_type temporary (*this + ae); Chris@16: return assign_temporary (temporary); Chris@16: } Chris@16: template // Container assignment without temporary Chris@16: BOOST_UBLAS_INLINE Chris@16: vector_of_vector &operator += (const matrix_container &m) { Chris@16: plus_assign (m); Chris@16: return *this; Chris@16: } Chris@16: template Chris@16: BOOST_UBLAS_INLINE Chris@16: vector_of_vector &plus_assign (const matrix_expression &ae) { Chris@16: matrix_assign (*this, ae); Chris@16: return *this; Chris@16: } Chris@16: template Chris@16: BOOST_UBLAS_INLINE Chris@16: vector_of_vector& operator -= (const matrix_expression &ae) { Chris@16: self_type temporary (*this - ae); Chris@16: return assign_temporary (temporary); Chris@16: } Chris@16: template // Container assignment without temporary Chris@16: BOOST_UBLAS_INLINE Chris@16: vector_of_vector &operator -= (const matrix_container &m) { Chris@16: minus_assign (m); Chris@16: return *this; Chris@16: } Chris@16: template Chris@16: BOOST_UBLAS_INLINE Chris@16: vector_of_vector &minus_assign (const matrix_expression &ae) { Chris@16: matrix_assign (*this, ae); Chris@16: return *this; Chris@16: } Chris@16: template Chris@16: BOOST_UBLAS_INLINE Chris@16: vector_of_vector& operator *= (const AT &at) { Chris@16: matrix_assign_scalar (*this, at); Chris@16: return *this; Chris@16: } Chris@16: template Chris@16: BOOST_UBLAS_INLINE Chris@16: vector_of_vector& operator /= (const AT &at) { Chris@16: matrix_assign_scalar (*this, at); Chris@16: return *this; Chris@16: } Chris@16: Chris@16: // Swapping Chris@16: BOOST_UBLAS_INLINE Chris@16: void swap (vector_of_vector &m) { Chris@16: if (this != &m) { Chris@16: std::swap (size1_, m.size1_); Chris@16: std::swap (size2_, m.size2_); Chris@16: data ().swap (m.data ()); Chris@16: } Chris@16: } Chris@16: BOOST_UBLAS_INLINE Chris@16: friend void swap (vector_of_vector &m1, vector_of_vector &m2) { Chris@16: m1.swap (m2); Chris@16: } Chris@16: Chris@16: // Iterator types Chris@16: private: Chris@16: // Use the vector iterator Chris@16: typedef typename A::value_type::const_iterator const_subiterator_type; Chris@16: typedef typename A::value_type::iterator subiterator_type; Chris@16: public: Chris@16: #ifdef BOOST_UBLAS_USE_INDEXED_ITERATOR Chris@16: typedef indexed_iterator1 iterator1; Chris@16: typedef indexed_iterator2 iterator2; Chris@16: typedef indexed_const_iterator1 const_iterator1; Chris@16: typedef indexed_const_iterator2 const_iterator2; Chris@16: #else Chris@16: class const_iterator1; Chris@16: class iterator1; Chris@16: class const_iterator2; Chris@16: class iterator2; Chris@16: #endif Chris@16: typedef reverse_iterator_base1 const_reverse_iterator1; Chris@16: typedef reverse_iterator_base1 reverse_iterator1; Chris@16: typedef reverse_iterator_base2 const_reverse_iterator2; Chris@16: typedef reverse_iterator_base2 reverse_iterator2; Chris@16: Chris@16: // Element lookup Chris@16: BOOST_UBLAS_INLINE Chris@16: const_iterator1 find1 (int /*rank*/, size_type i, size_type j) const { Chris@16: #ifdef BOOST_UBLAS_USE_INDEXED_ITERATOR Chris@16: return const_iterator1 (*this, i, j); Chris@16: #else Chris@16: return const_iterator1 (*this, i, j, data () [layout_type::index_M (i, j)].begin () + layout_type::index_m (i, j)); Chris@16: #endif Chris@16: } Chris@16: BOOST_UBLAS_INLINE Chris@16: iterator1 find1 (int /*rank*/, size_type i, size_type j) { Chris@16: #ifdef BOOST_UBLAS_USE_INDEXED_ITERATOR Chris@16: return iterator1 (*this, i, j); Chris@16: #else Chris@16: return iterator1 (*this, i, j, data () [layout_type::index_M (i, j)].begin () + layout_type::index_m (i, j)); Chris@16: #endif Chris@16: } Chris@16: BOOST_UBLAS_INLINE Chris@16: const_iterator2 find2 (int /*rank*/, size_type i, size_type j) const { Chris@16: #ifdef BOOST_UBLAS_USE_INDEXED_ITERATOR Chris@16: return const_iterator2 (*this, i, j); Chris@16: #else Chris@16: return const_iterator2 (*this, i, j, data () [layout_type::index_M (i, j)].begin () + layout_type::index_m (i, j)); Chris@16: #endif Chris@16: } Chris@16: BOOST_UBLAS_INLINE Chris@16: iterator2 find2 (int /*rank*/, size_type i, size_type j) { Chris@16: #ifdef BOOST_UBLAS_USE_INDEXED_ITERATOR Chris@16: return iterator2 (*this, i, j); Chris@16: #else Chris@16: return iterator2 (*this, i, j, data () [layout_type::index_M (i, j)].begin () + layout_type::index_m (i, j)); Chris@16: #endif Chris@16: } Chris@16: Chris@16: Chris@16: #ifndef BOOST_UBLAS_USE_INDEXED_ITERATOR Chris@16: class const_iterator1: Chris@16: public container_const_reference, Chris@16: public random_access_iterator_base { Chris@16: public: Chris@16: typedef typename vector_of_vector::value_type value_type; Chris@16: typedef typename vector_of_vector::difference_type difference_type; Chris@16: typedef typename vector_of_vector::const_reference reference; Chris@16: typedef const typename vector_of_vector::pointer pointer; Chris@16: Chris@16: typedef const_iterator2 dual_iterator_type; Chris@16: typedef const_reverse_iterator2 dual_reverse_iterator_type; Chris@16: Chris@16: // Construction and destruction Chris@16: BOOST_UBLAS_INLINE Chris@16: const_iterator1 (): Chris@16: container_const_reference (), i_ (), j_ (), it_ () {} Chris@16: BOOST_UBLAS_INLINE Chris@16: const_iterator1 (const self_type &m, size_type i, size_type j, const const_subiterator_type &it): Chris@16: container_const_reference (m), i_ (i), j_ (j), it_ (it) {} Chris@16: BOOST_UBLAS_INLINE Chris@16: const_iterator1 (const iterator1 &it): Chris@16: container_const_reference (it ()), i_ (it.i_), j_ (it.j_), it_ (it.it_) {} Chris@16: Chris@16: // Arithmetic Chris@16: BOOST_UBLAS_INLINE Chris@16: const_iterator1 &operator ++ () { Chris@16: ++ i_; Chris@16: const self_type &m = (*this) (); Chris@16: if (layout_type::fast_i ()) Chris@16: ++ it_; Chris@16: else Chris@16: it_ = m.find1 (1, i_, j_).it_; Chris@16: return *this; Chris@16: } Chris@16: BOOST_UBLAS_INLINE Chris@16: const_iterator1 &operator -- () { Chris@16: -- i_; Chris@16: const self_type &m = (*this) (); Chris@16: if (layout_type::fast_i ()) Chris@16: -- it_; Chris@16: else Chris@16: it_ = m.find1 (1, i_, j_).it_; Chris@16: return *this; Chris@16: } Chris@16: BOOST_UBLAS_INLINE Chris@16: const_iterator1 &operator += (difference_type n) { Chris@16: i_ += n; Chris@16: const self_type &m = (*this) (); Chris@16: it_ = m.find1 (1, i_, j_).it_; Chris@16: return *this; Chris@16: } Chris@16: BOOST_UBLAS_INLINE Chris@16: const_iterator1 &operator -= (difference_type n) { Chris@16: i_ -= n; Chris@16: const self_type &m = (*this) (); Chris@16: it_ = m.find1 (1, i_, j_).it_; Chris@16: return *this; Chris@16: } Chris@16: BOOST_UBLAS_INLINE Chris@16: difference_type operator - (const const_iterator1 &it) const { Chris@16: BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ()); Chris@16: BOOST_UBLAS_CHECK (index2 () == it.index2 (), bad_index ()); Chris@16: return index1 () - it.index1 (); Chris@16: } Chris@16: Chris@16: // Dereference Chris@16: BOOST_UBLAS_INLINE Chris@16: const_reference operator * () const { Chris@16: BOOST_UBLAS_CHECK (index1 () < (*this) ().size1 (), bad_index ()); Chris@16: BOOST_UBLAS_CHECK (index2 () < (*this) ().size2 (), bad_index ()); Chris@16: return *it_; Chris@16: } Chris@16: BOOST_UBLAS_INLINE Chris@16: const_reference operator [] (difference_type n) const { Chris@16: return *(*this + n); Chris@16: } Chris@16: Chris@16: #ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION Chris@16: BOOST_UBLAS_INLINE Chris@16: #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION Chris@16: typename self_type:: Chris@16: #endif Chris@16: const_iterator2 begin () const { Chris@16: const self_type &m = (*this) (); Chris@16: return m.find2 (1, index1 (), 0); Chris@16: } Chris@16: BOOST_UBLAS_INLINE Chris@16: #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION Chris@16: typename self_type:: Chris@16: #endif Chris@101: const_iterator2 cbegin () const { Chris@101: return begin (); Chris@101: } Chris@101: BOOST_UBLAS_INLINE Chris@101: #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION Chris@101: typename self_type:: Chris@101: #endif Chris@16: const_iterator2 end () const { Chris@16: const self_type &m = (*this) (); Chris@16: return m.find2 (1, index1 (), m.size2 ()); Chris@16: } Chris@16: BOOST_UBLAS_INLINE Chris@16: #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION Chris@16: typename self_type:: Chris@16: #endif Chris@101: const_iterator2 cend () const { Chris@101: return end (); Chris@101: } Chris@101: BOOST_UBLAS_INLINE Chris@101: #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION Chris@101: typename self_type:: Chris@101: #endif Chris@16: const_reverse_iterator2 rbegin () const { Chris@16: return const_reverse_iterator2 (end ()); Chris@16: } Chris@16: BOOST_UBLAS_INLINE Chris@16: #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION Chris@16: typename self_type:: Chris@16: #endif Chris@101: const_reverse_iterator2 crbegin () const { Chris@101: return rbegin (); Chris@101: } Chris@101: BOOST_UBLAS_INLINE Chris@101: #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION Chris@101: typename self_type:: Chris@101: #endif Chris@16: const_reverse_iterator2 rend () const { Chris@16: return const_reverse_iterator2 (begin ()); Chris@16: } Chris@101: BOOST_UBLAS_INLINE Chris@101: #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION Chris@101: typename self_type:: Chris@101: #endif Chris@101: const_reverse_iterator2 crend () const { Chris@101: return rend (); Chris@101: } Chris@16: #endif Chris@16: Chris@16: // Indices Chris@16: BOOST_UBLAS_INLINE Chris@16: size_type index1 () const { Chris@16: return i_; Chris@16: } Chris@16: BOOST_UBLAS_INLINE Chris@16: size_type index2 () const { Chris@16: return j_; Chris@16: } Chris@16: Chris@16: // Assignment Chris@16: BOOST_UBLAS_INLINE Chris@16: const_iterator1 &operator = (const const_iterator1 &it) { Chris@16: container_const_reference::assign (&it ()); Chris@16: it_ = it.it_; Chris@16: return *this; Chris@16: } Chris@16: Chris@16: // Comparison Chris@16: BOOST_UBLAS_INLINE Chris@16: bool operator == (const const_iterator1 &it) const { Chris@16: BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ()); Chris@16: BOOST_UBLAS_CHECK (index2 () == it.index2 (), bad_index ()); Chris@16: return it_ == it.it_; Chris@16: } Chris@16: BOOST_UBLAS_INLINE Chris@16: bool operator < (const const_iterator1 &it) const { Chris@16: BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ()); Chris@16: BOOST_UBLAS_CHECK (index2 () == it.index2 (), bad_index ()); Chris@16: return it_ < it.it_; Chris@16: } Chris@16: Chris@16: private: Chris@16: size_type i_; Chris@16: size_type j_; Chris@16: const_subiterator_type it_; Chris@16: Chris@16: friend class iterator1; Chris@16: }; Chris@16: #endif Chris@16: Chris@16: BOOST_UBLAS_INLINE Chris@16: const_iterator1 begin1 () const { Chris@16: return find1 (0, 0, 0); Chris@16: } Chris@16: BOOST_UBLAS_INLINE Chris@101: const_iterator1 cbegin1 () const { Chris@101: return begin1 (); Chris@101: } Chris@101: BOOST_UBLAS_INLINE Chris@16: const_iterator1 end1 () const { Chris@16: return find1 (0, size1_, 0); Chris@16: } Chris@101: BOOST_UBLAS_INLINE Chris@101: const_iterator1 cend1 () const { Chris@101: return end1 (); Chris@101: } Chris@16: Chris@16: #ifndef BOOST_UBLAS_USE_INDEXED_ITERATOR Chris@16: class iterator1: Chris@16: public container_reference, Chris@16: public random_access_iterator_base { Chris@16: public: Chris@16: typedef typename vector_of_vector::value_type value_type; Chris@16: typedef typename vector_of_vector::difference_type difference_type; Chris@16: typedef typename vector_of_vector::reference reference; Chris@16: typedef typename vector_of_vector::pointer pointer; Chris@16: Chris@16: typedef iterator2 dual_iterator_type; Chris@16: typedef reverse_iterator2 dual_reverse_iterator_type; Chris@16: Chris@16: // Construction and destruction Chris@16: BOOST_UBLAS_INLINE Chris@16: iterator1 (): Chris@16: container_reference (), i_ (), j_ (), it_ () {} Chris@16: BOOST_UBLAS_INLINE Chris@16: iterator1 (self_type &m, size_type i, size_type j, const subiterator_type &it): Chris@16: container_reference (m), i_ (i), j_ (j), it_ (it) {} Chris@16: Chris@16: // Arithmetic Chris@16: BOOST_UBLAS_INLINE Chris@16: iterator1 &operator ++ () { Chris@16: ++ i_; Chris@16: self_type &m = (*this) (); Chris@16: if (layout_type::fast_i ()) Chris@16: ++ it_; Chris@16: else Chris@16: it_ = m.find1 (1, i_, j_).it_; Chris@16: return *this; Chris@16: } Chris@16: BOOST_UBLAS_INLINE Chris@16: iterator1 &operator -- () { Chris@16: -- i_; Chris@16: self_type &m = (*this) (); Chris@16: if (layout_type::fast_i ()) Chris@16: -- it_; Chris@16: else Chris@16: it_ = m.find1 (1, i_, j_).it_; Chris@16: return *this; Chris@16: } Chris@16: BOOST_UBLAS_INLINE Chris@16: iterator1 &operator += (difference_type n) { Chris@16: i_ += n; Chris@16: self_type &m = (*this) (); Chris@16: it_ = m.find1 (1, i_, j_).it_; Chris@16: return *this; Chris@16: } Chris@16: BOOST_UBLAS_INLINE Chris@16: iterator1 &operator -= (difference_type n) { Chris@16: i_ -= n; Chris@16: self_type &m = (*this) (); Chris@16: it_ = m.find1 (1, i_, j_).it_; Chris@16: return *this; Chris@16: } Chris@16: BOOST_UBLAS_INLINE Chris@16: difference_type operator - (const iterator1 &it) const { Chris@16: BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ()); Chris@16: BOOST_UBLAS_CHECK (index2 () == it.index2 (), bad_index ()); Chris@16: return index1 () - it.index1 (); Chris@16: } Chris@16: Chris@16: // Dereference Chris@16: BOOST_UBLAS_INLINE Chris@16: reference operator * () const { Chris@16: BOOST_UBLAS_CHECK (index1 () < (*this) ().size1 (), bad_index ()); Chris@16: BOOST_UBLAS_CHECK (index2 () < (*this) ().size2 (), bad_index ()); Chris@16: return *it_; Chris@16: } Chris@16: BOOST_UBLAS_INLINE Chris@16: reference operator [] (difference_type n) const { Chris@16: return *(*this + n); Chris@16: } Chris@16: Chris@16: #ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION Chris@16: BOOST_UBLAS_INLINE Chris@16: #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION Chris@16: typename self_type:: Chris@16: #endif Chris@16: iterator2 begin () const { Chris@16: self_type &m = (*this) (); Chris@16: return m.find2 (1, index1 (), 0); Chris@16: } Chris@16: BOOST_UBLAS_INLINE Chris@16: #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION Chris@16: typename self_type:: Chris@16: #endif Chris@16: iterator2 end () const { Chris@16: self_type &m = (*this) (); Chris@16: return m.find2 (1, index1 (), m.size2 ()); Chris@16: } Chris@16: BOOST_UBLAS_INLINE Chris@16: #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION Chris@16: typename self_type:: Chris@16: #endif Chris@16: reverse_iterator2 rbegin () const { Chris@16: return reverse_iterator2 (end ()); Chris@16: } Chris@16: BOOST_UBLAS_INLINE Chris@16: #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION Chris@16: typename self_type:: Chris@16: #endif Chris@16: reverse_iterator2 rend () const { Chris@16: return reverse_iterator2 (begin ()); Chris@16: } Chris@16: #endif Chris@16: Chris@16: // Indices Chris@16: BOOST_UBLAS_INLINE Chris@16: size_type index1 () const { Chris@16: return i_; Chris@16: } Chris@16: BOOST_UBLAS_INLINE Chris@16: size_type index2 () const { Chris@16: return j_; Chris@16: } Chris@16: Chris@16: // Assignment Chris@16: BOOST_UBLAS_INLINE Chris@16: iterator1 &operator = (const iterator1 &it) { Chris@16: container_reference::assign (&it ()); Chris@16: it_ = it.it_; Chris@16: return *this; Chris@16: } Chris@16: Chris@16: // Comparison Chris@16: BOOST_UBLAS_INLINE Chris@16: bool operator == (const iterator1 &it) const { Chris@16: BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ()); Chris@16: BOOST_UBLAS_CHECK (index2 () == it.index2 (), bad_index ()); Chris@16: return it_ == it.it_; Chris@16: } Chris@16: BOOST_UBLAS_INLINE Chris@16: bool operator < (const iterator1 &it) const { Chris@16: BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ()); Chris@16: BOOST_UBLAS_CHECK (index2 () == it.index2 (), bad_index ()); Chris@16: return it_ < it.it_; Chris@16: } Chris@16: Chris@16: private: Chris@16: size_type i_; Chris@16: size_type j_; Chris@16: subiterator_type it_; Chris@16: Chris@16: friend class const_iterator1; Chris@16: }; Chris@16: #endif Chris@16: Chris@16: BOOST_UBLAS_INLINE Chris@16: iterator1 begin1 () { Chris@16: return find1 (0, 0, 0); Chris@16: } Chris@16: BOOST_UBLAS_INLINE Chris@16: iterator1 end1 () { Chris@16: return find1 (0, size1_, 0); Chris@16: } Chris@16: Chris@16: #ifndef BOOST_UBLAS_USE_INDEXED_ITERATOR Chris@16: class const_iterator2: Chris@16: public container_const_reference, Chris@16: public random_access_iterator_base { Chris@16: public: Chris@16: typedef typename vector_of_vector::value_type value_type; Chris@16: typedef typename vector_of_vector::difference_type difference_type; Chris@16: typedef typename vector_of_vector::const_reference reference; Chris@16: typedef const typename vector_of_vector::pointer pointer; Chris@16: Chris@16: typedef const_iterator1 dual_iterator_type; Chris@16: typedef const_reverse_iterator1 dual_reverse_iterator_type; Chris@16: Chris@16: // Construction and destruction Chris@16: BOOST_UBLAS_INLINE Chris@16: const_iterator2 (): Chris@16: container_const_reference (), i_ (), j_ (), it_ () {} Chris@16: BOOST_UBLAS_INLINE Chris@16: const_iterator2 (const self_type &m, size_type i, size_type j, const const_subiterator_type &it): Chris@16: container_const_reference (m), i_ (i), j_ (j), it_ (it) {} Chris@16: BOOST_UBLAS_INLINE Chris@16: const_iterator2 (const iterator2 &it): Chris@16: container_const_reference (it ()), i_ (it.i_), j_ (it.j_), it_ (it.it_) {} Chris@16: Chris@16: // Arithmetic Chris@16: BOOST_UBLAS_INLINE Chris@16: const_iterator2 &operator ++ () { Chris@16: ++ j_; Chris@16: const self_type &m = (*this) (); Chris@16: if (layout_type::fast_j ()) Chris@16: ++ it_; Chris@16: else Chris@16: it_ = m.find2 (1, i_, j_).it_; Chris@16: return *this; Chris@16: } Chris@16: BOOST_UBLAS_INLINE Chris@16: const_iterator2 &operator -- () { Chris@16: -- j_; Chris@16: const self_type &m = (*this) (); Chris@16: if (layout_type::fast_j ()) Chris@16: -- it_; Chris@16: else Chris@16: it_ = m.find2 (1, i_, j_).it_; Chris@16: return *this; Chris@16: } Chris@16: BOOST_UBLAS_INLINE Chris@16: const_iterator2 &operator += (difference_type n) { Chris@16: j_ += n; Chris@16: const self_type &m = (*this) (); Chris@16: it_ = m.find2 (1, i_, j_).it_; Chris@16: return *this; Chris@16: } Chris@16: BOOST_UBLAS_INLINE Chris@16: const_iterator2 &operator -= (difference_type n) { Chris@16: j_ -= n; Chris@16: const self_type &m = (*this) (); Chris@16: it_ = m.find2 (1, i_, j_).it_; Chris@16: return *this; Chris@16: } Chris@16: BOOST_UBLAS_INLINE Chris@16: difference_type operator - (const const_iterator2 &it) const { Chris@16: BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ()); Chris@16: BOOST_UBLAS_CHECK (index1 () == it.index1 (), bad_index ()); Chris@16: return index2 () - it.index2 (); Chris@16: } Chris@16: Chris@16: // Dereference Chris@16: BOOST_UBLAS_INLINE Chris@16: const_reference operator * () const { Chris@16: BOOST_UBLAS_CHECK (index1 () < (*this) ().size1 (), bad_index ()); Chris@16: BOOST_UBLAS_CHECK (index2 () < (*this) ().size2 (), bad_index ()); Chris@16: return *it_; Chris@16: } Chris@16: BOOST_UBLAS_INLINE Chris@16: const_reference operator [] (difference_type n) const { Chris@16: return *(*this + n); Chris@16: } Chris@16: Chris@16: #ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION Chris@16: BOOST_UBLAS_INLINE Chris@16: #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION Chris@16: typename self_type:: Chris@16: #endif Chris@16: const_iterator1 begin () const { Chris@16: const self_type &m = (*this) (); Chris@16: return m.find1 (1, 0, index2 ()); Chris@16: } Chris@16: BOOST_UBLAS_INLINE Chris@16: #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION Chris@16: typename self_type:: Chris@16: #endif Chris@101: const_iterator1 cbegin () const { Chris@101: return begin (); Chris@101: } Chris@101: BOOST_UBLAS_INLINE Chris@101: #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION Chris@101: typename self_type:: Chris@101: #endif Chris@16: const_iterator1 end () const { Chris@16: const self_type &m = (*this) (); Chris@16: return m.find1 (1, m.size1 (), index2 ()); Chris@16: } Chris@16: BOOST_UBLAS_INLINE Chris@16: #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION Chris@16: typename self_type:: Chris@16: #endif Chris@101: const_iterator1 cend () const { Chris@101: return end (); Chris@101: } Chris@101: BOOST_UBLAS_INLINE Chris@101: #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION Chris@101: typename self_type:: Chris@101: #endif Chris@16: const_reverse_iterator1 rbegin () const { Chris@16: return const_reverse_iterator1 (end ()); Chris@16: } Chris@16: BOOST_UBLAS_INLINE Chris@16: #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION Chris@16: typename self_type:: Chris@16: #endif Chris@101: const_reverse_iterator1 crbegin () const { Chris@101: return rbegin (); Chris@101: } Chris@101: BOOST_UBLAS_INLINE Chris@101: #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION Chris@101: typename self_type:: Chris@101: #endif Chris@16: const_reverse_iterator1 rend () const { Chris@16: return const_reverse_iterator1 (begin ()); Chris@16: } Chris@101: BOOST_UBLAS_INLINE Chris@101: #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION Chris@101: typename self_type:: Chris@101: #endif Chris@101: const_reverse_iterator2 crend () const { Chris@101: return rend (); Chris@101: } Chris@16: #endif Chris@16: Chris@16: // Indices Chris@16: BOOST_UBLAS_INLINE Chris@16: size_type index1 () const { Chris@16: return i_; Chris@16: } Chris@16: BOOST_UBLAS_INLINE Chris@16: size_type index2 () const { Chris@16: return j_; Chris@16: } Chris@16: Chris@16: // Assignment Chris@16: BOOST_UBLAS_INLINE Chris@16: const_iterator2 &operator = (const const_iterator2 &it) { Chris@16: container_const_reference::assign (&it ()); Chris@16: it_ = it.it_; Chris@16: return *this; Chris@16: } Chris@16: Chris@16: // Comparison Chris@16: BOOST_UBLAS_INLINE Chris@16: bool operator == (const const_iterator2 &it) const { Chris@16: BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ()); Chris@16: BOOST_UBLAS_CHECK (index1 () == it.index1 (), bad_index ()); Chris@16: return it_ == it.it_; Chris@16: } Chris@16: BOOST_UBLAS_INLINE Chris@16: bool operator < (const const_iterator2 &it) const { Chris@16: BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ()); Chris@16: BOOST_UBLAS_CHECK (index1 () == it.index1 (), bad_index ()); Chris@16: return it_ < it.it_; Chris@16: } Chris@16: Chris@16: private: Chris@16: size_type i_; Chris@16: size_type j_; Chris@16: const_subiterator_type it_; Chris@16: Chris@16: friend class iterator2; Chris@16: }; Chris@16: #endif Chris@16: Chris@16: BOOST_UBLAS_INLINE Chris@16: const_iterator2 begin2 () const { Chris@16: return find2 (0, 0, 0); Chris@16: } Chris@16: BOOST_UBLAS_INLINE Chris@101: const_iterator2 cbegin2 () const { Chris@101: return begin2 (); Chris@101: } Chris@101: BOOST_UBLAS_INLINE Chris@16: const_iterator2 end2 () const { Chris@16: return find2 (0, 0, size2_); Chris@16: } Chris@101: BOOST_UBLAS_INLINE Chris@101: const_iterator2 cend2 () const { Chris@101: return end2 (); Chris@101: } Chris@16: Chris@16: #ifndef BOOST_UBLAS_USE_INDEXED_ITERATOR Chris@16: class iterator2: Chris@16: public container_reference, Chris@16: public random_access_iterator_base { Chris@16: public: Chris@16: typedef typename vector_of_vector::value_type value_type; Chris@16: typedef typename vector_of_vector::difference_type difference_type; Chris@16: typedef typename vector_of_vector::reference reference; Chris@16: typedef typename vector_of_vector::pointer pointer; Chris@16: Chris@16: typedef iterator1 dual_iterator_type; Chris@16: typedef reverse_iterator1 dual_reverse_iterator_type; Chris@16: Chris@16: // Construction and destruction Chris@16: BOOST_UBLAS_INLINE Chris@16: iterator2 (): Chris@16: container_reference (), i_ (), j_ (), it_ () {} Chris@16: BOOST_UBLAS_INLINE Chris@16: iterator2 (self_type &m, size_type i, size_type j, const subiterator_type &it): Chris@16: container_reference (m), i_ (i), j_ (j), it_ (it) {} Chris@16: Chris@16: // Arithmetic Chris@16: BOOST_UBLAS_INLINE Chris@16: iterator2 &operator ++ () { Chris@16: ++ j_; Chris@16: self_type &m = (*this) (); Chris@16: if (layout_type::fast_j ()) Chris@16: ++ it_; Chris@16: else Chris@16: it_ = m.find2 (1, i_, j_).it_; Chris@16: return *this; Chris@16: } Chris@16: BOOST_UBLAS_INLINE Chris@16: iterator2 &operator -- () { Chris@16: -- j_; Chris@16: self_type &m = (*this) (); Chris@16: if (layout_type::fast_j ()) Chris@16: -- it_; Chris@16: else Chris@16: it_ = m.find2 (1, i_, j_).it_; Chris@16: return *this; Chris@16: } Chris@16: BOOST_UBLAS_INLINE Chris@16: iterator2 &operator += (difference_type n) { Chris@16: j_ += n; Chris@16: self_type &m = (*this) (); Chris@16: it_ = m.find2 (1, i_, j_).it_; Chris@16: return *this; Chris@16: } Chris@16: BOOST_UBLAS_INLINE Chris@16: iterator2 &operator -= (difference_type n) { Chris@16: j_ -= n; Chris@16: self_type &m = (*this) (); Chris@16: it_ = m.find2 (1, i_, j_).it_; Chris@16: return *this; Chris@16: } Chris@16: BOOST_UBLAS_INLINE Chris@16: difference_type operator - (const iterator2 &it) const { Chris@16: BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ()); Chris@16: BOOST_UBLAS_CHECK (index1 () == it.index1 (), bad_index ()); Chris@16: return index2 () - it.index2 (); Chris@16: } Chris@16: Chris@16: // Dereference Chris@16: BOOST_UBLAS_INLINE Chris@16: reference operator * () const { Chris@16: BOOST_UBLAS_CHECK (index1 () < (*this) ().size1 (), bad_index ()); Chris@16: BOOST_UBLAS_CHECK (index2 () < (*this) ().size2 (), bad_index ()); Chris@16: return *it_; Chris@16: } Chris@16: BOOST_UBLAS_INLINE Chris@16: reference operator [] (difference_type n) const { Chris@16: return *(*this + n); Chris@16: } Chris@16: Chris@16: #ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION Chris@16: BOOST_UBLAS_INLINE Chris@16: #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION Chris@16: typename self_type:: Chris@16: #endif Chris@16: iterator1 begin () const { Chris@16: self_type &m = (*this) (); Chris@16: return m.find1 (1, 0, index2 ()); Chris@16: } Chris@16: BOOST_UBLAS_INLINE Chris@16: #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION Chris@16: typename self_type:: Chris@16: #endif Chris@16: iterator1 end () const { Chris@16: self_type &m = (*this) (); Chris@16: return m.find1 (1, m.size1 (), index2 ()); Chris@16: } Chris@16: BOOST_UBLAS_INLINE Chris@16: #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION Chris@16: typename self_type:: Chris@16: #endif Chris@16: reverse_iterator1 rbegin () const { Chris@16: return reverse_iterator1 (end ()); Chris@16: } Chris@16: BOOST_UBLAS_INLINE Chris@16: #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION Chris@16: typename self_type:: Chris@16: #endif Chris@16: reverse_iterator1 rend () const { Chris@16: return reverse_iterator1 (begin ()); Chris@16: } Chris@16: #endif Chris@16: Chris@16: // Indices Chris@16: BOOST_UBLAS_INLINE Chris@16: size_type index1 () const { Chris@16: return i_; Chris@16: } Chris@16: BOOST_UBLAS_INLINE Chris@16: size_type index2 () const { Chris@16: return j_; Chris@16: } Chris@16: Chris@16: // Assignment Chris@16: BOOST_UBLAS_INLINE Chris@16: iterator2 &operator = (const iterator2 &it) { Chris@16: container_reference::assign (&it ()); Chris@16: it_ = it.it_; Chris@16: return *this; Chris@16: } Chris@16: Chris@16: // Comparison Chris@16: BOOST_UBLAS_INLINE Chris@16: bool operator == (const iterator2 &it) const { Chris@16: BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ()); Chris@16: BOOST_UBLAS_CHECK (index1 () == it.index1 (), bad_index ()); Chris@16: return it_ == it.it_; Chris@16: } Chris@16: BOOST_UBLAS_INLINE Chris@16: bool operator < (const iterator2 &it) const { Chris@16: BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ()); Chris@16: BOOST_UBLAS_CHECK (index1 () == it.index1 (), bad_index ()); Chris@16: return it_ < it.it_; Chris@16: } Chris@16: Chris@16: private: Chris@16: size_type i_; Chris@16: size_type j_; Chris@16: subiterator_type it_; Chris@16: Chris@16: friend class const_iterator2; Chris@16: }; Chris@16: #endif Chris@16: Chris@16: BOOST_UBLAS_INLINE Chris@16: iterator2 begin2 () { Chris@16: return find2 (0, 0, 0); Chris@16: } Chris@16: BOOST_UBLAS_INLINE Chris@16: iterator2 end2 () { Chris@16: return find2 (0, 0, size2_); Chris@16: } Chris@16: Chris@16: // Reverse iterators Chris@16: Chris@16: BOOST_UBLAS_INLINE Chris@16: const_reverse_iterator1 rbegin1 () const { Chris@16: return const_reverse_iterator1 (end1 ()); Chris@16: } Chris@16: BOOST_UBLAS_INLINE Chris@101: const_reverse_iterator1 crbegin1 () const { Chris@101: return rbegin1 (); Chris@101: } Chris@101: BOOST_UBLAS_INLINE Chris@16: const_reverse_iterator1 rend1 () const { Chris@16: return const_reverse_iterator1 (begin1 ()); Chris@16: } Chris@101: BOOST_UBLAS_INLINE Chris@101: const_reverse_iterator1 crend1 () const { Chris@101: return rend1 (); Chris@101: } Chris@16: Chris@16: BOOST_UBLAS_INLINE Chris@16: reverse_iterator1 rbegin1 () { Chris@16: return reverse_iterator1 (end1 ()); Chris@16: } Chris@16: BOOST_UBLAS_INLINE Chris@16: reverse_iterator1 rend1 () { Chris@16: return reverse_iterator1 (begin1 ()); Chris@16: } Chris@16: Chris@16: BOOST_UBLAS_INLINE Chris@16: const_reverse_iterator2 rbegin2 () const { Chris@16: return const_reverse_iterator2 (end2 ()); Chris@16: } Chris@16: BOOST_UBLAS_INLINE Chris@101: const_reverse_iterator2 crbegin2 () const { Chris@101: return rbegin2 (); Chris@101: } Chris@101: BOOST_UBLAS_INLINE Chris@16: const_reverse_iterator2 rend2 () const { Chris@16: return const_reverse_iterator2 (begin2 ()); Chris@16: } Chris@101: BOOST_UBLAS_INLINE Chris@101: const_reverse_iterator2 crend2 () const { Chris@101: return rend2 (); Chris@101: } Chris@16: Chris@16: BOOST_UBLAS_INLINE Chris@16: reverse_iterator2 rbegin2 () { Chris@16: return reverse_iterator2 (end2 ()); Chris@16: } Chris@16: BOOST_UBLAS_INLINE Chris@16: reverse_iterator2 rend2 () { Chris@16: return reverse_iterator2 (begin2 ()); Chris@16: } Chris@16: Chris@16: // Serialization Chris@16: template Chris@16: void serialize(Archive & ar, const unsigned int /* file_version */){ Chris@16: Chris@16: // we need to copy to a collection_size_type to get a portable Chris@16: // and efficient serialization Chris@16: serialization::collection_size_type s1 (size1_); Chris@16: serialization::collection_size_type s2 (size2_); Chris@16: Chris@16: // serialize the sizes Chris@16: ar & serialization::make_nvp("size1",s1) Chris@16: & serialization::make_nvp("size2",s2); Chris@16: Chris@16: // copy the values back if loading Chris@16: if (Archive::is_loading::value) { Chris@16: size1_ = s1; Chris@16: size2_ = s2; Chris@16: } Chris@16: ar & serialization::make_nvp("data",data_); Chris@16: } Chris@16: Chris@16: private: Chris@16: size_type size1_; Chris@16: size_type size2_; Chris@16: array_type data_; Chris@16: }; Chris@16: Chris@16: Chris@16: /** \brief A matrix with all values of type \c T equal to zero Chris@16: * Chris@16: * Changing values does not affect the matrix, however assigning it to a normal matrix will put zero Chris@16: * everywhere in the target matrix. All accesses are constant time, due to the trivial value. Chris@16: * Chris@16: * \tparam T the type of object stored in the matrix (like double, float, complex, etc...) Chris@16: * \tparam ALLOC an allocator for storing the zero element. By default, a standar allocator is used. Chris@16: */ Chris@16: template Chris@16: class zero_matrix: Chris@16: public matrix_container > { Chris@16: Chris@16: typedef const T *const_pointer; Chris@16: typedef zero_matrix self_type; Chris@16: public: Chris@16: #ifdef BOOST_UBLAS_ENABLE_PROXY_SHORTCUTS Chris@16: using matrix_container::operator (); Chris@16: #endif Chris@16: typedef typename ALLOC::size_type size_type; Chris@16: typedef typename ALLOC::difference_type difference_type; Chris@16: typedef T value_type; Chris@16: typedef const T &const_reference; Chris@16: typedef T &reference; Chris@16: typedef const matrix_reference const_closure_type; Chris@16: typedef matrix_reference closure_type; Chris@16: typedef sparse_tag storage_category; Chris@16: typedef unknown_orientation_tag orientation_category; Chris@16: Chris@16: // Construction and destruction Chris@16: BOOST_UBLAS_INLINE Chris@16: zero_matrix (): Chris@16: matrix_container (), Chris@16: size1_ (0), size2_ (0) {} Chris@16: BOOST_UBLAS_INLINE Chris@16: zero_matrix (size_type size): Chris@16: matrix_container (), Chris@16: size1_ (size), size2_ (size) {} Chris@16: BOOST_UBLAS_INLINE Chris@16: zero_matrix (size_type size1, size_type size2): Chris@16: matrix_container (), Chris@16: size1_ (size1), size2_ (size2) {} Chris@16: BOOST_UBLAS_INLINE Chris@16: zero_matrix (const zero_matrix &m): Chris@16: matrix_container (), Chris@16: size1_ (m.size1_), size2_ (m.size2_) {} Chris@16: Chris@16: // Accessors Chris@16: BOOST_UBLAS_INLINE Chris@16: size_type size1 () const { Chris@16: return size1_; Chris@16: } Chris@16: BOOST_UBLAS_INLINE Chris@16: size_type size2 () const { Chris@16: return size2_; Chris@16: } Chris@16: Chris@16: // Resizing Chris@16: BOOST_UBLAS_INLINE Chris@101: void resize (size_type size, bool /*preserve*/ = true) { Chris@16: size1_ = size; Chris@16: size2_ = size; Chris@16: } Chris@16: BOOST_UBLAS_INLINE Chris@16: void resize (size_type size1, size_type size2, bool /*preserve*/ = true) { Chris@16: size1_ = size1; Chris@16: size2_ = size2; Chris@16: } Chris@16: Chris@16: // Element access Chris@16: BOOST_UBLAS_INLINE Chris@16: const_reference operator () (size_type /* i */, size_type /* j */) const { Chris@16: return zero_; Chris@16: } Chris@16: Chris@16: // Assignment Chris@16: BOOST_UBLAS_INLINE Chris@16: zero_matrix &operator = (const zero_matrix &m) { Chris@16: size1_ = m.size1_; Chris@16: size2_ = m.size2_; Chris@16: return *this; Chris@16: } Chris@16: BOOST_UBLAS_INLINE Chris@16: zero_matrix &assign_temporary (zero_matrix &m) { Chris@16: swap (m); Chris@16: return *this; Chris@16: } Chris@16: Chris@16: // Swapping Chris@16: BOOST_UBLAS_INLINE Chris@16: void swap (zero_matrix &m) { Chris@16: if (this != &m) { Chris@16: std::swap (size1_, m.size1_); Chris@16: std::swap (size2_, m.size2_); Chris@16: } Chris@16: } Chris@16: BOOST_UBLAS_INLINE Chris@16: friend void swap (zero_matrix &m1, zero_matrix &m2) { Chris@16: m1.swap (m2); Chris@16: } Chris@16: Chris@16: // Iterator types Chris@16: public: Chris@16: class const_iterator1; Chris@16: class const_iterator2; Chris@16: typedef reverse_iterator_base1 const_reverse_iterator1; Chris@16: typedef reverse_iterator_base2 const_reverse_iterator2; Chris@16: Chris@16: // Element lookup Chris@16: BOOST_UBLAS_INLINE Chris@16: const_iterator1 find1 (int /*rank*/, size_type /*i*/, size_type /*j*/) const { Chris@16: return const_iterator1 (*this); Chris@16: } Chris@16: BOOST_UBLAS_INLINE Chris@16: const_iterator2 find2 (int /*rank*/, size_type /*i*/, size_type /*j*/) const { Chris@16: return const_iterator2 (*this); Chris@16: } Chris@16: Chris@16: class const_iterator1: Chris@16: public container_const_reference, Chris@16: public bidirectional_iterator_base { Chris@16: public: Chris@16: typedef typename zero_matrix::value_type value_type; Chris@16: typedef typename zero_matrix::difference_type difference_type; Chris@16: typedef typename zero_matrix::const_reference reference; Chris@16: typedef typename zero_matrix::const_pointer pointer; Chris@16: Chris@16: typedef const_iterator2 dual_iterator_type; Chris@16: typedef const_reverse_iterator2 dual_reverse_iterator_type; Chris@16: Chris@16: // Construction and destruction Chris@16: BOOST_UBLAS_INLINE Chris@16: const_iterator1 (): Chris@16: container_const_reference () {} Chris@16: BOOST_UBLAS_INLINE Chris@16: const_iterator1 (const self_type &m): Chris@16: container_const_reference (m) {} Chris@16: Chris@16: // Arithmetic Chris@16: BOOST_UBLAS_INLINE Chris@16: const_iterator1 &operator ++ () { Chris@16: BOOST_UBLAS_CHECK_FALSE (bad_index ()); Chris@16: return *this; Chris@16: } Chris@16: BOOST_UBLAS_INLINE Chris@16: const_iterator1 &operator -- () { Chris@16: BOOST_UBLAS_CHECK_FALSE (bad_index ()); Chris@16: return *this; Chris@16: } Chris@16: Chris@16: // Dereference Chris@16: BOOST_UBLAS_INLINE Chris@16: const_reference operator * () const { Chris@16: BOOST_UBLAS_CHECK_FALSE (bad_index ()); Chris@16: return zero_; // arbitary return value Chris@16: } Chris@16: Chris@16: #ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION Chris@16: BOOST_UBLAS_INLINE Chris@16: #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION Chris@16: typename self_type:: Chris@16: #endif Chris@16: const_iterator2 begin () const { Chris@16: return const_iterator2 ((*this) ()); Chris@16: } Chris@16: BOOST_UBLAS_INLINE Chris@16: #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION Chris@16: typename self_type:: Chris@16: #endif Chris@101: const_iterator2 cbegin () const { Chris@101: return begin (); Chris@101: } Chris@101: BOOST_UBLAS_INLINE Chris@101: #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION Chris@101: typename self_type:: Chris@101: #endif Chris@16: const_iterator2 end () const { Chris@16: return const_iterator2 ((*this) ()); Chris@16: } Chris@16: BOOST_UBLAS_INLINE Chris@16: #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION Chris@16: typename self_type:: Chris@16: #endif Chris@101: const_iterator2 cend () const { Chris@101: return end (); Chris@101: } Chris@101: BOOST_UBLAS_INLINE Chris@101: #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION Chris@101: typename self_type:: Chris@101: #endif Chris@16: const_reverse_iterator2 rbegin () const { Chris@16: return const_reverse_iterator2 (end ()); Chris@16: } Chris@16: BOOST_UBLAS_INLINE Chris@16: #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION Chris@16: typename self_type:: Chris@16: #endif Chris@101: const_reverse_iterator2 crbegin () const { Chris@101: return rbegin (); Chris@101: } Chris@101: BOOST_UBLAS_INLINE Chris@101: #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION Chris@101: typename self_type:: Chris@101: #endif Chris@16: const_reverse_iterator2 rend () const { Chris@16: return const_reverse_iterator2 (begin ()); Chris@16: } Chris@101: BOOST_UBLAS_INLINE Chris@101: #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION Chris@101: typename self_type:: Chris@101: #endif Chris@101: const_reverse_iterator2 crend () const { Chris@101: return rend (); Chris@101: } Chris@16: #endif Chris@16: Chris@16: // Indices Chris@16: BOOST_UBLAS_INLINE Chris@16: size_type index1 () const { Chris@16: BOOST_UBLAS_CHECK_FALSE (bad_index ()); Chris@16: return 0; // arbitary return value Chris@16: } Chris@16: BOOST_UBLAS_INLINE Chris@16: size_type index2 () const { Chris@16: BOOST_UBLAS_CHECK_FALSE (bad_index ()); Chris@16: return 0; // arbitary return value Chris@16: } Chris@16: Chris@16: // Assignment Chris@16: BOOST_UBLAS_INLINE Chris@16: const_iterator1 &operator = (const const_iterator1 &it) { Chris@16: container_const_reference::assign (&it ()); Chris@16: return *this; Chris@16: } Chris@16: Chris@16: // Comparison Chris@16: BOOST_UBLAS_INLINE Chris@16: bool operator == (const const_iterator1 &it) const { Chris@16: BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ()); Chris@16: detail::ignore_unused_variable_warning(it); Chris@16: return true; Chris@16: } Chris@16: }; Chris@16: Chris@16: typedef const_iterator1 iterator1; Chris@16: Chris@16: BOOST_UBLAS_INLINE Chris@16: const_iterator1 begin1 () const { Chris@16: return const_iterator1 (*this); Chris@16: } Chris@16: BOOST_UBLAS_INLINE Chris@101: const_iterator1 cbegin1 () const { Chris@101: return begin1 (); Chris@101: } Chris@101: BOOST_UBLAS_INLINE Chris@16: const_iterator1 end1 () const { Chris@16: return const_iterator1 (*this); Chris@16: } Chris@101: BOOST_UBLAS_INLINE Chris@101: const_iterator1 cend1 () const { Chris@101: return end1 (); Chris@101: } Chris@16: Chris@16: class const_iterator2: Chris@16: public container_const_reference, Chris@16: public bidirectional_iterator_base { Chris@16: public: Chris@16: typedef typename zero_matrix::value_type value_type; Chris@16: typedef typename zero_matrix::difference_type difference_type; Chris@16: typedef typename zero_matrix::const_reference reference; Chris@16: typedef typename zero_matrix::const_pointer pointer; Chris@16: Chris@16: typedef const_iterator1 dual_iterator_type; Chris@16: typedef const_reverse_iterator1 dual_reverse_iterator_type; Chris@16: Chris@16: // Construction and destruction Chris@16: BOOST_UBLAS_INLINE Chris@16: const_iterator2 (): Chris@16: container_const_reference () {} Chris@16: BOOST_UBLAS_INLINE Chris@16: const_iterator2 (const self_type &m): Chris@16: container_const_reference (m) {} Chris@16: Chris@16: // Arithmetic Chris@16: BOOST_UBLAS_INLINE Chris@16: const_iterator2 &operator ++ () { Chris@16: BOOST_UBLAS_CHECK_FALSE (bad_index ()); Chris@16: return *this; Chris@16: } Chris@16: BOOST_UBLAS_INLINE Chris@16: const_iterator2 &operator -- () { Chris@16: BOOST_UBLAS_CHECK_FALSE (bad_index ()); Chris@16: return *this; Chris@16: } Chris@16: Chris@16: // Dereference Chris@16: BOOST_UBLAS_INLINE Chris@16: const_reference operator * () const { Chris@16: BOOST_UBLAS_CHECK_FALSE (bad_index ()); Chris@16: return zero_; // arbitary return value Chris@16: } Chris@16: Chris@16: #ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION Chris@16: BOOST_UBLAS_INLINE Chris@16: #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION Chris@16: typename self_type:: Chris@16: #endif Chris@16: const_iterator1 begin () const { Chris@16: return const_iterator1 ((*this) ()); Chris@16: } Chris@16: BOOST_UBLAS_INLINE Chris@16: #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION Chris@16: typename self_type:: Chris@16: #endif Chris@101: const_iterator1 cbegin () const { Chris@101: return begin (); Chris@101: } Chris@101: BOOST_UBLAS_INLINE Chris@101: #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION Chris@101: typename self_type:: Chris@101: #endif Chris@16: const_iterator1 end () const { Chris@16: return const_iterator1 ((*this) ()); Chris@16: } Chris@16: BOOST_UBLAS_INLINE Chris@16: #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION Chris@16: typename self_type:: Chris@16: #endif Chris@101: const_iterator1 cend () const { Chris@101: return end (); Chris@101: } Chris@101: BOOST_UBLAS_INLINE Chris@101: #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION Chris@101: typename self_type:: Chris@101: #endif Chris@16: const_reverse_iterator1 rbegin () const { Chris@16: return const_reverse_iterator1 (end ()); Chris@16: } Chris@16: BOOST_UBLAS_INLINE Chris@16: #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION Chris@16: typename self_type:: Chris@16: #endif Chris@101: const_reverse_iterator1 crbegin () const { Chris@101: return rbegin (); Chris@101: } Chris@101: BOOST_UBLAS_INLINE Chris@101: #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION Chris@101: typename self_type:: Chris@101: #endif Chris@16: const_reverse_iterator1 rend () const { Chris@16: return const_reverse_iterator1 (begin ()); Chris@16: } Chris@101: BOOST_UBLAS_INLINE Chris@101: #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION Chris@101: typename self_type:: Chris@101: #endif Chris@101: const_reverse_iterator1 crend () const { Chris@101: return rend (); Chris@101: } Chris@16: #endif Chris@16: Chris@16: // Indices Chris@16: BOOST_UBLAS_INLINE Chris@16: size_type index1 () const { Chris@16: BOOST_UBLAS_CHECK_FALSE (bad_index ()); Chris@16: return 0; // arbitary return value Chris@16: } Chris@16: BOOST_UBLAS_INLINE Chris@16: size_type index2 () const { Chris@16: BOOST_UBLAS_CHECK_FALSE (bad_index ()); Chris@16: return 0; // arbitary return value Chris@16: } Chris@16: Chris@16: // Assignment Chris@16: BOOST_UBLAS_INLINE Chris@16: const_iterator2 &operator = (const const_iterator2 &it) { Chris@16: container_const_reference::assign (&it ()); Chris@16: return *this; Chris@16: } Chris@16: Chris@16: // Comparison Chris@16: BOOST_UBLAS_INLINE Chris@16: bool operator == (const const_iterator2 &it) const { Chris@16: BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ()); Chris@16: detail::ignore_unused_variable_warning(it); Chris@16: return true; Chris@16: } Chris@16: }; Chris@16: Chris@16: typedef const_iterator2 iterator2; Chris@16: Chris@16: BOOST_UBLAS_INLINE Chris@16: const_iterator2 begin2 () const { Chris@16: return find2 (0, 0, 0); Chris@16: } Chris@16: BOOST_UBLAS_INLINE Chris@101: const_iterator2 cbegin2 () const { Chris@101: return begin2 (); Chris@101: } Chris@101: BOOST_UBLAS_INLINE Chris@16: const_iterator2 end2 () const { Chris@16: return find2 (0, 0, size2_); Chris@16: } Chris@101: BOOST_UBLAS_INLINE Chris@101: const_iterator2 cend2 () const { Chris@101: return end2 (); Chris@101: } Chris@16: Chris@16: // Reverse iterators Chris@16: Chris@16: BOOST_UBLAS_INLINE Chris@16: const_reverse_iterator1 rbegin1 () const { Chris@16: return const_reverse_iterator1 (end1 ()); Chris@16: } Chris@16: BOOST_UBLAS_INLINE Chris@101: const_reverse_iterator1 crbegin1 () const { Chris@101: return rbegin1 (); Chris@101: } Chris@101: BOOST_UBLAS_INLINE Chris@16: const_reverse_iterator1 rend1 () const { Chris@16: return const_reverse_iterator1 (begin1 ()); Chris@16: } Chris@101: BOOST_UBLAS_INLINE Chris@101: const_reverse_iterator1 crend1 () const { Chris@101: return rend1 (); Chris@101: } Chris@16: Chris@16: BOOST_UBLAS_INLINE Chris@16: const_reverse_iterator2 rbegin2 () const { Chris@16: return const_reverse_iterator2 (end2 ()); Chris@16: } Chris@16: BOOST_UBLAS_INLINE Chris@101: const_reverse_iterator2 crbegin2 () const { Chris@101: return rbegin2 (); Chris@101: } Chris@101: BOOST_UBLAS_INLINE Chris@16: const_reverse_iterator2 rend2 () const { Chris@16: return const_reverse_iterator2 (begin2 ()); Chris@16: } Chris@101: BOOST_UBLAS_INLINE Chris@101: const_reverse_iterator2 crend2 () const { Chris@101: return rend2 (); Chris@101: } Chris@16: Chris@16: // Serialization Chris@16: template Chris@16: void serialize(Archive & ar, const unsigned int /* file_version */){ Chris@16: Chris@16: // we need to copy to a collection_size_type to get a portable Chris@16: // and efficient serialization Chris@16: serialization::collection_size_type s1 (size1_); Chris@16: serialization::collection_size_type s2 (size2_); Chris@16: Chris@16: // serialize the sizes Chris@16: ar & serialization::make_nvp("size1",s1) Chris@16: & serialization::make_nvp("size2",s2); Chris@16: Chris@16: // copy the values back if loading Chris@16: if (Archive::is_loading::value) { Chris@16: size1_ = s1; Chris@16: size2_ = s2; Chris@16: } Chris@16: } Chris@16: Chris@16: private: Chris@16: size_type size1_; Chris@16: size_type size2_; Chris@16: static const value_type zero_; Chris@16: }; Chris@16: Chris@16: template Chris@16: const typename zero_matrix::value_type zero_matrix::zero_ = T(/*zero*/); Chris@16: Chris@16: /** \brief An identity matrix with values of type \c T Chris@16: * Chris@16: * Elements or cordinates \f$(i,i)\f$ are equal to 1 (one) and all others to 0 (zero). Chris@16: * Changing values does not affect the matrix, however assigning it to a normal matrix will Chris@16: * make the matrix equal to an identity matrix. All accesses are constant du to the trivial values. Chris@16: * Chris@16: * \tparam T the type of object stored in the matrix (like double, float, complex, etc...) Chris@16: * \tparam ALLOC an allocator for storing the zeros and one elements. By default, a standar allocator is used. Chris@16: */ Chris@16: template Chris@16: class identity_matrix: Chris@16: public matrix_container > { Chris@16: Chris@16: typedef const T *const_pointer; Chris@16: typedef identity_matrix self_type; Chris@16: public: Chris@16: #ifdef BOOST_UBLAS_ENABLE_PROXY_SHORTCUTS Chris@16: using matrix_container::operator (); Chris@16: #endif Chris@16: typedef typename ALLOC::size_type size_type; Chris@16: typedef typename ALLOC::difference_type difference_type; Chris@16: typedef T value_type; Chris@16: typedef const T &const_reference; Chris@16: typedef T &reference; Chris@16: typedef const matrix_reference const_closure_type; Chris@16: typedef matrix_reference closure_type; Chris@16: typedef sparse_tag storage_category; Chris@16: typedef unknown_orientation_tag orientation_category; Chris@16: Chris@16: // Construction and destruction Chris@16: BOOST_UBLAS_INLINE Chris@16: identity_matrix (): Chris@16: matrix_container (), Chris@16: size1_ (0), size2_ (0), size_common_ (0) {} Chris@16: BOOST_UBLAS_INLINE Chris@16: identity_matrix (size_type size): Chris@16: matrix_container (), Chris@16: size1_ (size), size2_ (size), size_common_ ((std::min) (size1_, size2_)) {} Chris@16: BOOST_UBLAS_INLINE Chris@16: identity_matrix (size_type size1, size_type size2): Chris@16: matrix_container (), Chris@16: size1_ (size1), size2_ (size2), size_common_ ((std::min) (size1_, size2_)) {} Chris@16: BOOST_UBLAS_INLINE Chris@16: identity_matrix (const identity_matrix &m): Chris@16: matrix_container (), Chris@16: size1_ (m.size1_), size2_ (m.size2_), size_common_ ((std::min) (size1_, size2_)) {} Chris@16: Chris@16: // Accessors Chris@16: BOOST_UBLAS_INLINE Chris@16: size_type size1 () const { Chris@16: return size1_; Chris@16: } Chris@16: BOOST_UBLAS_INLINE Chris@16: size_type size2 () const { Chris@16: return size2_; Chris@16: } Chris@16: Chris@16: // Resizing Chris@16: BOOST_UBLAS_INLINE Chris@101: void resize (size_type size, bool /*preserve*/ = true) { Chris@16: size1_ = size; Chris@16: size2_ = size; Chris@16: size_common_ = ((std::min)(size1_, size2_)); Chris@16: } Chris@16: BOOST_UBLAS_INLINE Chris@16: void resize (size_type size1, size_type size2, bool /*preserve*/ = true) { Chris@16: size1_ = size1; Chris@16: size2_ = size2; Chris@16: size_common_ = ((std::min)(size1_, size2_)); Chris@16: } Chris@16: Chris@16: // Element access Chris@16: BOOST_UBLAS_INLINE Chris@16: const_reference operator () (size_type i, size_type j) const { Chris@16: if (i == j) Chris@16: return one_; Chris@16: else Chris@16: return zero_; Chris@16: } Chris@16: Chris@16: // Assignment Chris@16: BOOST_UBLAS_INLINE Chris@16: identity_matrix &operator = (const identity_matrix &m) { Chris@16: size1_ = m.size1_; Chris@16: size2_ = m.size2_; Chris@16: size_common_ = m.size_common_; Chris@16: return *this; Chris@16: } Chris@16: BOOST_UBLAS_INLINE Chris@16: identity_matrix &assign_temporary (identity_matrix &m) { Chris@16: swap (m); Chris@16: return *this; Chris@16: } Chris@16: Chris@16: // Swapping Chris@16: BOOST_UBLAS_INLINE Chris@16: void swap (identity_matrix &m) { Chris@16: if (this != &m) { Chris@16: std::swap (size1_, m.size1_); Chris@16: std::swap (size2_, m.size2_); Chris@16: std::swap (size_common_, m.size_common_); Chris@16: } Chris@16: } Chris@16: BOOST_UBLAS_INLINE Chris@16: friend void swap (identity_matrix &m1, identity_matrix &m2) { Chris@16: m1.swap (m2); Chris@16: } Chris@16: Chris@16: // Iterator types Chris@16: private: Chris@16: // Use an index Chris@16: typedef size_type const_subiterator_type; Chris@16: Chris@16: public: Chris@16: class const_iterator1; Chris@16: class const_iterator2; Chris@16: typedef reverse_iterator_base1 const_reverse_iterator1; Chris@16: typedef reverse_iterator_base2 const_reverse_iterator2; Chris@16: Chris@16: // Element lookup Chris@16: BOOST_UBLAS_INLINE Chris@16: const_iterator1 find1 (int rank, size_type i, size_type j) const { Chris@16: if (rank == 1) { Chris@16: i = (std::max) (i, j); Chris@16: i = (std::min) (i, j + 1); Chris@16: } Chris@16: return const_iterator1 (*this, i); Chris@16: } Chris@16: BOOST_UBLAS_INLINE Chris@16: const_iterator2 find2 (int rank, size_type i, size_type j) const { Chris@16: if (rank == 1) { Chris@16: j = (std::max) (j, i); Chris@16: j = (std::min) (j, i + 1); Chris@16: } Chris@16: return const_iterator2 (*this, j); Chris@16: } Chris@16: Chris@16: Chris@16: class const_iterator1: Chris@16: public container_const_reference, Chris@16: public bidirectional_iterator_base { Chris@16: public: Chris@16: typedef typename identity_matrix::value_type value_type; Chris@16: typedef typename identity_matrix::difference_type difference_type; Chris@16: typedef typename identity_matrix::const_reference reference; Chris@16: typedef typename identity_matrix::const_pointer pointer; Chris@16: Chris@16: typedef const_iterator2 dual_iterator_type; Chris@16: typedef const_reverse_iterator2 dual_reverse_iterator_type; Chris@16: Chris@16: // Construction and destruction Chris@16: BOOST_UBLAS_INLINE Chris@16: const_iterator1 (): Chris@16: container_const_reference (), it_ () {} Chris@16: BOOST_UBLAS_INLINE Chris@16: const_iterator1 (const self_type &m, const const_subiterator_type &it): Chris@16: container_const_reference (m), it_ (it) {} Chris@16: Chris@16: // Arithmetic Chris@16: BOOST_UBLAS_INLINE Chris@16: const_iterator1 &operator ++ () { Chris@16: BOOST_UBLAS_CHECK (it_ < (*this) ().size1 (), bad_index ()); Chris@16: ++it_; Chris@16: return *this; Chris@16: } Chris@16: BOOST_UBLAS_INLINE Chris@16: const_iterator1 &operator -- () { Chris@16: BOOST_UBLAS_CHECK (it_ > 0, bad_index ()); Chris@16: --it_; Chris@16: return *this; Chris@16: } Chris@16: Chris@16: // Dereference Chris@16: BOOST_UBLAS_INLINE Chris@16: const_reference operator * () const { Chris@16: return one_; Chris@16: } Chris@16: Chris@16: #ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION Chris@16: BOOST_UBLAS_INLINE Chris@16: #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION Chris@16: typename self_type:: Chris@16: #endif Chris@16: const_iterator2 begin () const { Chris@16: return const_iterator2 ((*this) (), it_); Chris@16: } Chris@16: BOOST_UBLAS_INLINE Chris@16: #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION Chris@16: typename self_type:: Chris@16: #endif Chris@101: const_iterator2 cbegin () const { Chris@101: return begin (); Chris@101: } Chris@101: BOOST_UBLAS_INLINE Chris@101: #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION Chris@101: typename self_type:: Chris@101: #endif Chris@16: const_iterator2 end () const { Chris@16: return const_iterator2 ((*this) (), it_ + 1); Chris@16: } Chris@16: BOOST_UBLAS_INLINE Chris@16: #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION Chris@16: typename self_type:: Chris@16: #endif Chris@101: const_iterator2 cend () const { Chris@101: return end (); Chris@101: } Chris@101: BOOST_UBLAS_INLINE Chris@101: #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION Chris@101: typename self_type:: Chris@101: #endif Chris@16: const_reverse_iterator2 rbegin () const { Chris@16: return const_reverse_iterator2 (end ()); Chris@16: } Chris@16: BOOST_UBLAS_INLINE Chris@16: #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION Chris@16: typename self_type:: Chris@16: #endif Chris@101: const_reverse_iterator2 crbegin () const { Chris@101: return rbegin (); Chris@101: } Chris@101: BOOST_UBLAS_INLINE Chris@101: #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION Chris@101: typename self_type:: Chris@101: #endif Chris@16: const_reverse_iterator2 rend () const { Chris@16: return const_reverse_iterator2 (begin ()); Chris@16: } Chris@101: BOOST_UBLAS_INLINE Chris@101: #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION Chris@101: typename self_type:: Chris@101: #endif Chris@101: const_reverse_iterator2 crend () const { Chris@101: return rend (); Chris@101: } Chris@16: #endif Chris@16: Chris@16: // Indices Chris@16: BOOST_UBLAS_INLINE Chris@16: size_type index1 () const { Chris@16: return it_; Chris@16: } Chris@16: BOOST_UBLAS_INLINE Chris@16: size_type index2 () const { Chris@16: return it_; Chris@16: } Chris@16: Chris@16: // Assignment Chris@16: BOOST_UBLAS_INLINE Chris@16: const_iterator1 &operator = (const const_iterator1 &it) { Chris@16: container_const_reference::assign (&it ()); Chris@16: it_ = it.it_; Chris@16: return *this; Chris@16: } Chris@16: Chris@16: // Comparison Chris@16: BOOST_UBLAS_INLINE Chris@16: bool operator == (const const_iterator1 &it) const { Chris@16: BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ()); Chris@16: return it_ == it.it_; Chris@16: } Chris@16: Chris@16: private: Chris@16: const_subiterator_type it_; Chris@16: }; Chris@16: Chris@16: typedef const_iterator1 iterator1; Chris@16: Chris@16: BOOST_UBLAS_INLINE Chris@16: const_iterator1 begin1 () const { Chris@16: return const_iterator1 (*this, 0); Chris@16: } Chris@16: BOOST_UBLAS_INLINE Chris@101: const_iterator1 cbegin1 () const { Chris@101: return begin1 (); Chris@101: } Chris@101: BOOST_UBLAS_INLINE Chris@16: const_iterator1 end1 () const { Chris@16: return const_iterator1 (*this, size_common_); Chris@16: } Chris@101: BOOST_UBLAS_INLINE Chris@101: const_iterator1 cend1 () const { Chris@101: return end1 (); Chris@101: } Chris@16: Chris@16: class const_iterator2: Chris@16: public container_const_reference, Chris@16: public bidirectional_iterator_base { Chris@16: public: Chris@16: typedef typename identity_matrix::value_type value_type; Chris@16: typedef typename identity_matrix::difference_type difference_type; Chris@16: typedef typename identity_matrix::const_reference reference; Chris@16: typedef typename identity_matrix::const_pointer pointer; Chris@16: Chris@16: typedef const_iterator1 dual_iterator_type; Chris@16: typedef const_reverse_iterator1 dual_reverse_iterator_type; Chris@16: Chris@16: // Construction and destruction Chris@16: BOOST_UBLAS_INLINE Chris@16: const_iterator2 (): Chris@16: container_const_reference (), it_ () {} Chris@16: BOOST_UBLAS_INLINE Chris@16: const_iterator2 (const self_type &m, const const_subiterator_type &it): Chris@16: container_const_reference (m), it_ (it) {} Chris@16: Chris@16: // Arithmetic Chris@16: BOOST_UBLAS_INLINE Chris@16: const_iterator2 &operator ++ () { Chris@16: BOOST_UBLAS_CHECK (it_ < (*this) ().size_common_, bad_index ()); Chris@16: ++it_; Chris@16: return *this; Chris@16: } Chris@16: BOOST_UBLAS_INLINE Chris@16: const_iterator2 &operator -- () { Chris@16: BOOST_UBLAS_CHECK (it_ > 0, bad_index ()); Chris@16: --it_; Chris@16: return *this; Chris@16: } Chris@16: Chris@16: // Dereference Chris@16: BOOST_UBLAS_INLINE Chris@16: const_reference operator * () const { Chris@16: return one_; Chris@16: } Chris@16: Chris@16: #ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION Chris@16: BOOST_UBLAS_INLINE Chris@16: #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION Chris@16: typename self_type:: Chris@16: #endif Chris@16: const_iterator1 begin () const { Chris@16: return const_iterator1 ((*this) (), it_); Chris@16: } Chris@16: BOOST_UBLAS_INLINE Chris@16: #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION Chris@16: typename self_type:: Chris@16: #endif Chris@101: const_iterator1 cbegin () const { Chris@101: return begin (); Chris@101: } Chris@101: BOOST_UBLAS_INLINE Chris@101: #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION Chris@101: typename self_type:: Chris@101: #endif Chris@16: const_iterator1 end () const { Chris@16: return const_iterator1 ((*this) (), it_ + 1); Chris@16: } Chris@16: BOOST_UBLAS_INLINE Chris@16: #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION Chris@16: typename self_type:: Chris@16: #endif Chris@101: const_iterator1 cend () const { Chris@101: return end (); Chris@101: } Chris@101: BOOST_UBLAS_INLINE Chris@101: #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION Chris@101: typename self_type:: Chris@101: #endif Chris@16: const_reverse_iterator1 rbegin () const { Chris@16: return const_reverse_iterator1 (end ()); Chris@16: } Chris@16: BOOST_UBLAS_INLINE Chris@16: #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION Chris@16: typename self_type:: Chris@16: #endif Chris@101: const_reverse_iterator1 crbegin () const { Chris@101: return rbegin (); Chris@101: } Chris@101: BOOST_UBLAS_INLINE Chris@101: #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION Chris@101: typename self_type:: Chris@101: #endif Chris@16: const_reverse_iterator1 rend () const { Chris@16: return const_reverse_iterator1 (begin ()); Chris@16: } Chris@101: BOOST_UBLAS_INLINE Chris@101: #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION Chris@101: typename self_type:: Chris@101: #endif Chris@101: const_reverse_iterator1 crend () const { Chris@101: return rend (); Chris@101: } Chris@16: #endif Chris@16: Chris@16: // Indices Chris@16: BOOST_UBLAS_INLINE Chris@16: size_type index1 () const { Chris@16: return it_; Chris@16: } Chris@16: BOOST_UBLAS_INLINE Chris@16: size_type index2 () const { Chris@16: return it_; Chris@16: } Chris@16: Chris@16: // Assignment Chris@16: BOOST_UBLAS_INLINE Chris@16: const_iterator2 &operator = (const const_iterator2 &it) { Chris@16: container_const_reference::assign (&it ()); Chris@16: it_ = it.it_; Chris@16: return *this; Chris@16: } Chris@16: Chris@16: // Comparison Chris@16: BOOST_UBLAS_INLINE Chris@16: bool operator == (const const_iterator2 &it) const { Chris@16: BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ()); Chris@16: return it_ == it.it_; Chris@16: } Chris@16: Chris@16: private: Chris@16: const_subiterator_type it_; Chris@16: }; Chris@16: Chris@16: typedef const_iterator2 iterator2; Chris@16: Chris@16: BOOST_UBLAS_INLINE Chris@16: const_iterator2 begin2 () const { Chris@16: return const_iterator2 (*this, 0); Chris@16: } Chris@16: BOOST_UBLAS_INLINE Chris@101: const_iterator2 cbegin2 () const { Chris@101: return begin2 (); Chris@101: } Chris@101: BOOST_UBLAS_INLINE Chris@16: const_iterator2 end2 () const { Chris@16: return const_iterator2 (*this, size_common_); Chris@16: } Chris@101: BOOST_UBLAS_INLINE Chris@101: const_iterator2 cend2 () const { Chris@101: return end2 (); Chris@101: } Chris@16: Chris@16: // Reverse iterators Chris@16: Chris@16: BOOST_UBLAS_INLINE Chris@16: const_reverse_iterator1 rbegin1 () const { Chris@16: return const_reverse_iterator1 (end1 ()); Chris@16: } Chris@16: BOOST_UBLAS_INLINE Chris@101: const_reverse_iterator1 crbegin1 () const { Chris@101: return rbegin1 (); Chris@101: } Chris@101: BOOST_UBLAS_INLINE Chris@16: const_reverse_iterator1 rend1 () const { Chris@16: return const_reverse_iterator1 (begin1 ()); Chris@16: } Chris@101: BOOST_UBLAS_INLINE Chris@101: const_reverse_iterator1 crend1 () const { Chris@101: return rend1 (); Chris@101: } Chris@16: Chris@16: BOOST_UBLAS_INLINE Chris@16: const_reverse_iterator2 rbegin2 () const { Chris@16: return const_reverse_iterator2 (end2 ()); Chris@16: } Chris@16: BOOST_UBLAS_INLINE Chris@101: const_reverse_iterator2 crbegin2 () const { Chris@101: return rbegin2 (); Chris@101: } Chris@101: BOOST_UBLAS_INLINE Chris@16: const_reverse_iterator2 rend2 () const { Chris@16: return const_reverse_iterator2 (begin2 ()); Chris@16: } Chris@101: BOOST_UBLAS_INLINE Chris@101: const_reverse_iterator2 crend2 () const { Chris@101: return rend2 (); Chris@101: } Chris@16: Chris@16: // Serialization Chris@16: template Chris@16: void serialize(Archive & ar, const unsigned int /* file_version */){ Chris@16: Chris@16: // we need to copy to a collection_size_type to get a portable Chris@16: // and efficient serialization Chris@16: serialization::collection_size_type s1 (size1_); Chris@16: serialization::collection_size_type s2 (size2_); Chris@16: Chris@16: // serialize the sizes Chris@16: ar & serialization::make_nvp("size1",s1) Chris@16: & serialization::make_nvp("size2",s2); Chris@16: Chris@16: // copy the values back if loading Chris@16: if (Archive::is_loading::value) { Chris@16: size1_ = s1; Chris@16: size2_ = s2; Chris@16: size_common_ = ((std::min)(size1_, size2_)); Chris@16: } Chris@16: } Chris@16: Chris@16: private: Chris@16: size_type size1_; Chris@16: size_type size2_; Chris@16: size_type size_common_; Chris@16: static const value_type zero_; Chris@16: static const value_type one_; Chris@16: }; Chris@16: Chris@16: template Chris@16: const typename identity_matrix::value_type identity_matrix::zero_ = T(/*zero*/); Chris@16: template Chris@16: const typename identity_matrix::value_type identity_matrix::one_ (1); // ISSUE: need 'one'-traits here Chris@16: Chris@16: Chris@16: /** \brief A matrix with all values of type \c T equal to the same value Chris@16: * Chris@16: * Changing one value has the effect of changing all the values. Assigning it to a normal matrix will copy Chris@16: * the same value everywhere in this matrix. All accesses are constant time, due to the trivial value. Chris@16: * Chris@16: * \tparam T the type of object stored in the matrix (like double, float, complex, etc...) Chris@16: * \tparam ALLOC an allocator for storing the unique value. By default, a standar allocator is used. Chris@16: */ Chris@16: template Chris@16: class scalar_matrix: Chris@16: public matrix_container > { Chris@16: Chris@16: typedef const T *const_pointer; Chris@16: typedef scalar_matrix self_type; Chris@16: public: Chris@16: #ifdef BOOST_UBLAS_ENABLE_PROXY_SHORTCUTS Chris@16: using matrix_container::operator (); Chris@16: #endif Chris@16: typedef std::size_t size_type; Chris@16: typedef std::ptrdiff_t difference_type; Chris@16: typedef T value_type; Chris@16: typedef const T &const_reference; Chris@16: typedef T &reference; Chris@16: typedef const matrix_reference const_closure_type; Chris@16: typedef matrix_reference closure_type; Chris@16: typedef dense_tag storage_category; Chris@16: typedef unknown_orientation_tag orientation_category; Chris@16: Chris@16: // Construction and destruction Chris@16: BOOST_UBLAS_INLINE Chris@16: scalar_matrix (): Chris@16: matrix_container (), Chris@16: size1_ (0), size2_ (0), value_ () {} Chris@16: BOOST_UBLAS_INLINE Chris@16: scalar_matrix (size_type size1, size_type size2, const value_type &value = value_type(1)): Chris@16: matrix_container (), Chris@16: size1_ (size1), size2_ (size2), value_ (value) {} Chris@16: BOOST_UBLAS_INLINE Chris@16: scalar_matrix (const scalar_matrix &m): Chris@16: matrix_container (), Chris@16: size1_ (m.size1_), size2_ (m.size2_), value_ (m.value_) {} Chris@16: Chris@16: // Accessors Chris@16: BOOST_UBLAS_INLINE Chris@16: size_type size1 () const { Chris@16: return size1_; Chris@16: } Chris@16: BOOST_UBLAS_INLINE Chris@16: size_type size2 () const { Chris@16: return size2_; Chris@16: } Chris@16: Chris@16: // Resizing Chris@16: BOOST_UBLAS_INLINE Chris@16: void resize (size_type size1, size_type size2, bool /*preserve*/ = true) { Chris@16: size1_ = size1; Chris@16: size2_ = size2; Chris@16: } Chris@16: Chris@16: // Element access Chris@16: BOOST_UBLAS_INLINE Chris@16: const_reference operator () (size_type /*i*/, size_type /*j*/) const { Chris@16: return value_; Chris@16: } Chris@16: Chris@16: // Assignment Chris@16: BOOST_UBLAS_INLINE Chris@16: scalar_matrix &operator = (const scalar_matrix &m) { Chris@16: size1_ = m.size1_; Chris@16: size2_ = m.size2_; Chris@16: value_ = m.value_; Chris@16: return *this; Chris@16: } Chris@16: BOOST_UBLAS_INLINE Chris@16: scalar_matrix &assign_temporary (scalar_matrix &m) { Chris@16: swap (m); Chris@16: return *this; Chris@16: } Chris@16: Chris@16: // Swapping Chris@16: BOOST_UBLAS_INLINE Chris@16: void swap (scalar_matrix &m) { Chris@16: if (this != &m) { Chris@16: std::swap (size1_, m.size1_); Chris@16: std::swap (size2_, m.size2_); Chris@16: std::swap (value_, m.value_); Chris@16: } Chris@16: } Chris@16: BOOST_UBLAS_INLINE Chris@16: friend void swap (scalar_matrix &m1, scalar_matrix &m2) { Chris@16: m1.swap (m2); Chris@16: } Chris@16: Chris@16: // Iterator types Chris@16: private: Chris@16: // Use an index Chris@16: typedef size_type const_subiterator_type; Chris@16: Chris@16: public: Chris@16: #ifdef BOOST_UBLAS_USE_INDEXED_ITERATOR Chris@16: typedef indexed_const_iterator1 iterator1; Chris@16: typedef indexed_const_iterator2 iterator2; Chris@16: typedef indexed_const_iterator1 const_iterator1; Chris@16: typedef indexed_const_iterator2 const_iterator2; Chris@16: #else Chris@16: class const_iterator1; Chris@16: class const_iterator2; Chris@16: #endif Chris@16: typedef reverse_iterator_base1 const_reverse_iterator1; Chris@16: typedef reverse_iterator_base2 const_reverse_iterator2; Chris@16: Chris@16: // Element lookup Chris@16: BOOST_UBLAS_INLINE Chris@16: const_iterator1 find1 (int /*rank*/, size_type i, size_type j) const { Chris@16: return const_iterator1 (*this, i, j); Chris@16: } Chris@16: BOOST_UBLAS_INLINE Chris@16: const_iterator2 find2 (int /*rank*/, size_type i, size_type j) const { Chris@16: return const_iterator2 (*this, i, j); Chris@16: } Chris@16: Chris@16: Chris@16: #ifndef BOOST_UBLAS_USE_INDEXED_ITERATOR Chris@16: class const_iterator1: Chris@16: public container_const_reference, Chris@16: public random_access_iterator_base { Chris@16: public: Chris@16: typedef typename scalar_matrix::value_type value_type; Chris@16: typedef typename scalar_matrix::difference_type difference_type; Chris@16: typedef typename scalar_matrix::const_reference reference; Chris@16: typedef typename scalar_matrix::const_pointer pointer; Chris@16: Chris@16: typedef const_iterator2 dual_iterator_type; Chris@16: typedef const_reverse_iterator2 dual_reverse_iterator_type; Chris@16: Chris@16: // Construction and destruction Chris@16: BOOST_UBLAS_INLINE Chris@16: const_iterator1 (): Chris@16: container_const_reference (), it1_ (), it2_ () {} Chris@16: BOOST_UBLAS_INLINE Chris@16: const_iterator1 (const scalar_matrix &m, const const_subiterator_type &it1, const const_subiterator_type &it2): Chris@16: container_const_reference (m), it1_ (it1), it2_ (it2) {} Chris@16: Chris@16: // Arithmetic Chris@16: BOOST_UBLAS_INLINE Chris@16: const_iterator1 &operator ++ () { Chris@16: ++ it1_; Chris@16: return *this; Chris@16: } Chris@16: BOOST_UBLAS_INLINE Chris@16: const_iterator1 &operator -- () { Chris@16: -- it1_; Chris@16: return *this; Chris@16: } Chris@16: BOOST_UBLAS_INLINE Chris@16: const_iterator1 &operator += (difference_type n) { Chris@16: it1_ += n; Chris@16: return *this; Chris@16: } Chris@16: BOOST_UBLAS_INLINE Chris@16: const_iterator1 &operator -= (difference_type n) { Chris@16: it1_ -= n; Chris@16: return *this; Chris@16: } Chris@16: BOOST_UBLAS_INLINE Chris@16: difference_type operator - (const const_iterator1 &it) const { Chris@16: BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ()); Chris@16: BOOST_UBLAS_CHECK (it2_ == it.it2_, external_logic ()); Chris@16: return it1_ - it.it1_; Chris@16: } Chris@16: Chris@16: // Dereference Chris@16: BOOST_UBLAS_INLINE Chris@16: const_reference operator * () const { Chris@16: BOOST_UBLAS_CHECK (index1 () < (*this) ().size1 (), bad_index ()); Chris@16: BOOST_UBLAS_CHECK (index2 () < (*this) ().size2 (), bad_index ()); Chris@16: return (*this) () (index1 (), index2 ()); Chris@16: } Chris@16: BOOST_UBLAS_INLINE Chris@16: const_reference operator [] (difference_type n) const { Chris@16: return *(*this + n); Chris@16: } Chris@16: Chris@16: #ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION Chris@16: BOOST_UBLAS_INLINE Chris@16: #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION Chris@16: typename self_type:: Chris@16: #endif Chris@16: const_iterator2 begin () const { Chris@16: const scalar_matrix &m = (*this) (); Chris@16: return m.find2 (1, index1 (), 0); Chris@16: } Chris@16: BOOST_UBLAS_INLINE Chris@16: #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION Chris@16: typename self_type:: Chris@16: #endif Chris@101: const_iterator2 cbegin () const { Chris@101: return begin (); Chris@101: } Chris@101: BOOST_UBLAS_INLINE Chris@101: #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION Chris@101: typename self_type:: Chris@101: #endif Chris@16: const_iterator2 end () const { Chris@16: const scalar_matrix &m = (*this) (); Chris@16: return m.find2 (1, index1 (), m.size2 ()); Chris@16: } Chris@16: BOOST_UBLAS_INLINE Chris@16: #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION Chris@16: typename self_type:: Chris@16: #endif Chris@101: const_iterator2 cend () const { Chris@101: return end (); Chris@101: } Chris@101: BOOST_UBLAS_INLINE Chris@101: #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION Chris@101: typename self_type:: Chris@101: #endif Chris@16: const_reverse_iterator2 rbegin () const { Chris@16: return const_reverse_iterator2 (end ()); Chris@16: } Chris@16: BOOST_UBLAS_INLINE Chris@16: #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION Chris@16: typename self_type:: Chris@16: #endif Chris@101: const_reverse_iterator2 crbegin () const { Chris@101: return rbegin (); Chris@101: } Chris@101: BOOST_UBLAS_INLINE Chris@101: #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION Chris@101: typename self_type:: Chris@101: #endif Chris@16: const_reverse_iterator2 rend () const { Chris@16: return const_reverse_iterator2 (begin ()); Chris@16: } Chris@101: BOOST_UBLAS_INLINE Chris@101: #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION Chris@101: typename self_type:: Chris@101: #endif Chris@101: const_reverse_iterator2 crend () const { Chris@101: return rend (); Chris@101: } Chris@16: #endif Chris@16: Chris@16: // Indices Chris@16: BOOST_UBLAS_INLINE Chris@16: size_type index1 () const { Chris@16: return it1_; Chris@16: } Chris@16: BOOST_UBLAS_INLINE Chris@16: size_type index2 () const { Chris@16: return it2_; Chris@16: } Chris@16: Chris@16: // Assignment Chris@16: BOOST_UBLAS_INLINE Chris@16: const_iterator1 &operator = (const const_iterator1 &it) { Chris@16: container_const_reference::assign (&it ()); Chris@16: it1_ = it.it1_; Chris@16: it2_ = it.it2_; Chris@16: return *this; Chris@16: } Chris@16: Chris@16: // Comparison Chris@16: BOOST_UBLAS_INLINE Chris@16: bool operator == (const const_iterator1 &it) const { Chris@16: BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ()); Chris@16: BOOST_UBLAS_CHECK (it2_ == it.it2_, external_logic ()); Chris@16: return it1_ == it.it1_; Chris@16: } Chris@16: BOOST_UBLAS_INLINE Chris@16: bool operator < (const const_iterator1 &it) const { Chris@16: BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ()); Chris@16: BOOST_UBLAS_CHECK (it2_ == it.it2_, external_logic ()); Chris@16: return it1_ < it.it1_; Chris@16: } Chris@16: Chris@16: private: Chris@16: const_subiterator_type it1_; Chris@16: const_subiterator_type it2_; Chris@16: }; Chris@16: Chris@16: typedef const_iterator1 iterator1; Chris@16: #endif Chris@16: Chris@16: BOOST_UBLAS_INLINE Chris@16: const_iterator1 begin1 () const { Chris@16: return find1 (0, 0, 0); Chris@16: } Chris@16: BOOST_UBLAS_INLINE Chris@101: const_iterator1 cbegin1 () const { Chris@101: return begin1 (); Chris@101: } Chris@101: BOOST_UBLAS_INLINE Chris@16: const_iterator1 end1 () const { Chris@16: return find1 (0, size1_, 0); Chris@16: } Chris@101: BOOST_UBLAS_INLINE Chris@101: const_iterator1 cend1 () const { Chris@101: return end1 (); Chris@101: } Chris@16: Chris@16: #ifndef BOOST_UBLAS_USE_INDEXED_ITERATOR Chris@16: class const_iterator2: Chris@16: public container_const_reference, Chris@16: public random_access_iterator_base { Chris@16: public: Chris@16: typedef typename scalar_matrix::value_type value_type; Chris@16: typedef typename scalar_matrix::difference_type difference_type; Chris@16: typedef typename scalar_matrix::const_reference reference; Chris@16: typedef typename scalar_matrix::const_pointer pointer; Chris@16: Chris@16: typedef const_iterator1 dual_iterator_type; Chris@16: typedef const_reverse_iterator1 dual_reverse_iterator_type; Chris@16: Chris@16: // Construction and destruction Chris@16: BOOST_UBLAS_INLINE Chris@16: const_iterator2 (): Chris@16: container_const_reference (), it1_ (), it2_ () {} Chris@16: BOOST_UBLAS_INLINE Chris@16: const_iterator2 (const scalar_matrix &m, const const_subiterator_type &it1, const const_subiterator_type &it2): Chris@16: container_const_reference (m), it1_ (it1), it2_ (it2) {} Chris@16: Chris@16: // Arithmetic Chris@16: BOOST_UBLAS_INLINE Chris@16: const_iterator2 &operator ++ () { Chris@16: ++ it2_; Chris@16: return *this; Chris@16: } Chris@16: BOOST_UBLAS_INLINE Chris@16: const_iterator2 &operator -- () { Chris@16: -- it2_; Chris@16: return *this; Chris@16: } Chris@16: BOOST_UBLAS_INLINE Chris@16: const_iterator2 &operator += (difference_type n) { Chris@16: it2_ += n; Chris@16: return *this; Chris@16: } Chris@16: BOOST_UBLAS_INLINE Chris@16: const_iterator2 &operator -= (difference_type n) { Chris@16: it2_ -= n; Chris@16: return *this; Chris@16: } Chris@16: BOOST_UBLAS_INLINE Chris@16: difference_type operator - (const const_iterator2 &it) const { Chris@16: BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ()); Chris@16: BOOST_UBLAS_CHECK (it1_ == it.it1_, external_logic ()); Chris@16: return it2_ - it.it2_; Chris@16: } Chris@16: Chris@16: // Dereference Chris@16: BOOST_UBLAS_INLINE Chris@16: const_reference operator * () const { Chris@16: BOOST_UBLAS_CHECK (index1 () < (*this) ().size1 (), bad_index ()); Chris@16: BOOST_UBLAS_CHECK (index2 () < (*this) ().size2 (), bad_index ()); Chris@16: return (*this) () (index1 (), index2 ()); Chris@16: } Chris@16: BOOST_UBLAS_INLINE Chris@16: const_reference operator [] (difference_type n) const { Chris@16: return *(*this + n); Chris@16: } Chris@16: Chris@16: #ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION Chris@16: BOOST_UBLAS_INLINE Chris@16: #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION Chris@16: typename self_type:: Chris@16: #endif Chris@16: const_iterator1 begin () const { Chris@16: const scalar_matrix &m = (*this) (); Chris@16: return m.find1 (1, 0, index2 ()); Chris@16: } Chris@16: BOOST_UBLAS_INLINE Chris@16: #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION Chris@16: typename self_type:: Chris@16: #endif Chris@101: const_iterator1 cbegin () const { Chris@101: return begin (); Chris@101: } Chris@101: BOOST_UBLAS_INLINE Chris@101: #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION Chris@101: typename self_type:: Chris@101: #endif Chris@16: const_iterator1 end () const { Chris@16: const scalar_matrix &m = (*this) (); Chris@16: return m.find1 (1, m.size1 (), index2 ()); Chris@16: } Chris@16: BOOST_UBLAS_INLINE Chris@16: #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION Chris@16: typename self_type:: Chris@16: #endif Chris@101: const_iterator1 cend () const { Chris@101: return end (); Chris@101: } Chris@101: BOOST_UBLAS_INLINE Chris@101: #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION Chris@101: typename self_type:: Chris@101: #endif Chris@16: const_reverse_iterator1 rbegin () const { Chris@16: return const_reverse_iterator1 (end ()); Chris@16: } Chris@16: BOOST_UBLAS_INLINE Chris@16: #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION Chris@16: typename self_type:: Chris@16: #endif Chris@101: const_reverse_iterator1 crbegin () const { Chris@101: return rbegin (); Chris@101: } Chris@101: BOOST_UBLAS_INLINE Chris@101: #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION Chris@101: typename self_type:: Chris@101: #endif Chris@16: const_reverse_iterator1 rend () const { Chris@16: return const_reverse_iterator1 (begin ()); Chris@16: } Chris@101: BOOST_UBLAS_INLINE Chris@101: #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION Chris@101: typename self_type:: Chris@101: #endif Chris@101: const_reverse_iterator1 crend () const { Chris@101: return rend (); Chris@101: } Chris@16: #endif Chris@16: Chris@16: // Indices Chris@16: BOOST_UBLAS_INLINE Chris@16: size_type index1 () const { Chris@16: return it1_; Chris@16: } Chris@16: BOOST_UBLAS_INLINE Chris@16: size_type index2 () const { Chris@16: return it2_; Chris@16: } Chris@16: Chris@16: // Assignment Chris@16: BOOST_UBLAS_INLINE Chris@16: const_iterator2 &operator = (const const_iterator2 &it) { Chris@16: container_const_reference::assign (&it ()); Chris@16: it1_ = it.it1_; Chris@16: it2_ = it.it2_; Chris@16: return *this; Chris@16: } Chris@16: Chris@16: // Comparison Chris@16: BOOST_UBLAS_INLINE Chris@16: bool operator == (const const_iterator2 &it) const { Chris@16: BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ()); Chris@16: BOOST_UBLAS_CHECK (it1_ == it.it1_, external_logic ()); Chris@16: return it2_ == it.it2_; Chris@16: } Chris@16: BOOST_UBLAS_INLINE Chris@16: bool operator < (const const_iterator2 &it) const { Chris@16: BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ()); Chris@16: BOOST_UBLAS_CHECK (it1_ == it.it1_, external_logic ()); Chris@16: return it2_ < it.it2_; Chris@16: } Chris@16: Chris@16: private: Chris@16: const_subiterator_type it1_; Chris@16: const_subiterator_type it2_; Chris@16: }; Chris@16: Chris@16: typedef const_iterator2 iterator2; Chris@16: #endif Chris@16: Chris@16: BOOST_UBLAS_INLINE Chris@16: const_iterator2 begin2 () const { Chris@16: return find2 (0, 0, 0); Chris@16: } Chris@16: BOOST_UBLAS_INLINE Chris@101: const_iterator2 cbegin2 () const { Chris@101: return begin2 (); Chris@101: } Chris@101: BOOST_UBLAS_INLINE Chris@16: const_iterator2 end2 () const { Chris@16: return find2 (0, 0, size2_); Chris@16: } Chris@101: BOOST_UBLAS_INLINE Chris@101: const_iterator2 cend2 () const { Chris@101: return end2 (); Chris@101: } Chris@16: Chris@16: // Reverse iterators Chris@16: Chris@16: BOOST_UBLAS_INLINE Chris@16: const_reverse_iterator1 rbegin1 () const { Chris@16: return const_reverse_iterator1 (end1 ()); Chris@16: } Chris@16: BOOST_UBLAS_INLINE Chris@101: const_reverse_iterator1 crbegin1 () const { Chris@101: return rbegin1 (); Chris@101: } Chris@101: BOOST_UBLAS_INLINE Chris@16: const_reverse_iterator1 rend1 () const { Chris@16: return const_reverse_iterator1 (begin1 ()); Chris@16: } Chris@101: BOOST_UBLAS_INLINE Chris@101: const_reverse_iterator1 crend1 () const { Chris@101: return rend1 (); Chris@101: } Chris@16: Chris@16: BOOST_UBLAS_INLINE Chris@16: const_reverse_iterator2 rbegin2 () const { Chris@16: return const_reverse_iterator2 (end2 ()); Chris@16: } Chris@16: BOOST_UBLAS_INLINE Chris@101: const_reverse_iterator2 crbegin2 () const { Chris@101: return rbegin2 (); Chris@101: } Chris@101: BOOST_UBLAS_INLINE Chris@16: const_reverse_iterator2 rend2 () const { Chris@16: return const_reverse_iterator2 (begin2 ()); Chris@16: } Chris@101: BOOST_UBLAS_INLINE Chris@101: const_reverse_iterator2 crend2 () const { Chris@101: return rend2 (); Chris@101: } Chris@16: Chris@16: // Serialization Chris@16: template Chris@16: void serialize(Archive & ar, const unsigned int /* file_version */){ Chris@16: Chris@16: // we need to copy to a collection_size_type to get a portable Chris@16: // and efficient serialization Chris@16: serialization::collection_size_type s1 (size1_); Chris@16: serialization::collection_size_type s2 (size2_); Chris@16: Chris@16: // serialize the sizes Chris@16: ar & serialization::make_nvp("size1",s1) Chris@16: & serialization::make_nvp("size2",s2); Chris@16: Chris@16: // copy the values back if loading Chris@16: if (Archive::is_loading::value) { Chris@16: size1_ = s1; Chris@16: size2_ = s2; Chris@16: } Chris@16: Chris@16: ar & serialization::make_nvp("value", value_); Chris@16: } Chris@16: Chris@16: private: Chris@16: size_type size1_; Chris@16: size_type size2_; Chris@16: value_type value_; Chris@16: }; Chris@16: Chris@16: Chris@16: /** \brief An array based matrix class which size is defined at type specification or object instanciation Chris@16: * Chris@16: * This matrix is directly based on a predefined C-style arry of data, thus providing the fastest Chris@16: * implementation possible. The constraint is that dimensions of the matrix must be specified at Chris@16: * the instanciation or the type specification. Chris@16: * Chris@16: * For instance, \code typedef c_matrix my_4by4_matrix \endcode Chris@16: * defines a 4 by 4 double-precision matrix. You can also instantiate it directly with Chris@16: * \code c_matrix my_fast_matrix \endcode. This will make a 8 by 5 integer matrix. The Chris@16: * price to pay for this speed is that you cannot resize it to a size larger than the one defined Chris@16: * in the template parameters. In the previous example, a size of 4 by 5 or 3 by 2 is acceptable, Chris@16: * but a new size of 9 by 5 or even 10 by 10 will raise a bad_size() exception. Chris@16: * Chris@16: * \tparam T the type of object stored in the matrix (like double, float, complex, etc...) Chris@16: * \tparam N the default maximum number of rows Chris@16: * \tparam M the default maximum number of columns Chris@16: */ Chris@16: template Chris@16: class c_matrix: Chris@16: public matrix_container > { Chris@16: Chris@16: typedef c_matrix self_type; Chris@16: public: Chris@16: #ifdef BOOST_UBLAS_ENABLE_PROXY_SHORTCUTS Chris@16: using matrix_container::operator (); Chris@16: #endif Chris@16: typedef std::size_t size_type; Chris@16: typedef std::ptrdiff_t difference_type; Chris@16: typedef T value_type; Chris@16: typedef const T &const_reference; Chris@16: typedef T &reference; Chris@16: typedef const T *const_pointer; Chris@16: typedef T *pointer; Chris@16: typedef const matrix_reference const_closure_type; Chris@16: typedef matrix_reference closure_type; Chris@16: typedef c_vector vector_temporary_type; // vector able to store all elements of c_matrix Chris@16: typedef self_type matrix_temporary_type; Chris@16: typedef dense_tag storage_category; Chris@16: // This could be better for performance, Chris@16: // typedef typename unknown_orientation_tag orientation_category; Chris@16: // but others depend on the orientation information... Chris@16: typedef row_major_tag orientation_category; Chris@16: Chris@16: // Construction and destruction Chris@16: BOOST_UBLAS_INLINE Chris@16: c_matrix (): Chris@16: size1_ (N), size2_ (M) /* , data_ () */ { Chris@16: } Chris@16: BOOST_UBLAS_INLINE Chris@16: c_matrix (size_type size1, size_type size2): Chris@16: size1_ (size1), size2_ (size2) /* , data_ () */ { Chris@16: if (size1_ > N || size2_ > M) Chris@16: bad_size ().raise (); Chris@16: } Chris@16: BOOST_UBLAS_INLINE Chris@16: c_matrix (const c_matrix &m): Chris@16: size1_ (m.size1_), size2_ (m.size2_) /* , data_ () */ { Chris@16: if (size1_ > N || size2_ > M) Chris@16: bad_size ().raise (); Chris@16: assign(m); Chris@16: } Chris@16: template Chris@16: BOOST_UBLAS_INLINE Chris@16: c_matrix (const matrix_expression &ae): Chris@16: size1_ (ae ().size1 ()), size2_ (ae ().size2 ()) /* , data_ () */ { Chris@16: if (size1_ > N || size2_ > M) Chris@16: bad_size ().raise (); Chris@16: matrix_assign (*this, ae); Chris@16: } Chris@16: Chris@16: // Accessors Chris@16: BOOST_UBLAS_INLINE Chris@16: size_type size1 () const { Chris@16: return size1_; Chris@16: } Chris@16: BOOST_UBLAS_INLINE Chris@16: size_type size2 () const { Chris@16: return size2_; Chris@16: } Chris@16: BOOST_UBLAS_INLINE Chris@16: const_pointer data () const { Chris@16: return reinterpret_cast (data_); Chris@16: } Chris@16: BOOST_UBLAS_INLINE Chris@16: pointer data () { Chris@16: return reinterpret_cast (data_); Chris@16: } Chris@16: Chris@16: // Resizing Chris@16: BOOST_UBLAS_INLINE Chris@16: void resize (size_type size1, size_type size2, bool preserve = true) { Chris@16: if (size1 > N || size2 > M) Chris@16: bad_size ().raise (); Chris@16: if (preserve) { Chris@16: self_type temporary (size1, size2); Chris@16: // Common elements to preserve Chris@16: const size_type size1_min = (std::min) (size1, size1_); Chris@16: const size_type size2_min = (std::min) (size2, size2_); Chris@16: for (size_type i = 0; i != size1_min; ++i) { // indexing copy over major Chris@16: for (size_type j = 0; j != size2_min; ++j) { Chris@16: temporary.data_[i][j] = data_[i][j]; Chris@16: } Chris@16: } Chris@16: assign_temporary (temporary); Chris@16: } Chris@16: else { Chris@16: size1_ = size1; Chris@16: size2_ = size2; Chris@16: } Chris@16: } Chris@16: Chris@16: // Element access Chris@16: BOOST_UBLAS_INLINE Chris@16: const_reference operator () (size_type i, size_type j) const { Chris@16: BOOST_UBLAS_CHECK (i < size1_, bad_index ()); Chris@16: BOOST_UBLAS_CHECK (j < size2_, bad_index ()); Chris@16: return data_ [i] [j]; Chris@16: } Chris@16: BOOST_UBLAS_INLINE Chris@16: reference at_element (size_type i, size_type j) { Chris@16: BOOST_UBLAS_CHECK (i < size1_, bad_index ()); Chris@16: BOOST_UBLAS_CHECK (j < size2_, bad_index ()); Chris@16: return data_ [i] [j]; Chris@16: } Chris@16: BOOST_UBLAS_INLINE Chris@16: reference operator () (size_type i, size_type j) { Chris@16: return at_element (i, j); Chris@16: } Chris@16: Chris@16: // Element assignment Chris@16: BOOST_UBLAS_INLINE Chris@16: reference insert_element (size_type i, size_type j, const_reference t) { Chris@16: return (at_element (i, j) = t); Chris@16: } Chris@16: Chris@16: // Zeroing Chris@16: BOOST_UBLAS_INLINE Chris@16: void clear () { Chris@16: for (size_type i = 0; i < size1_; ++ i) Chris@16: std::fill (data_ [i], data_ [i] + size2_, value_type/*zero*/()); Chris@16: } Chris@16: Chris@16: // Assignment Chris@16: #ifdef BOOST_UBLAS_MOVE_SEMANTICS Chris@16: Chris@16: /*! @note "pass by value" the key idea to enable move semantics */ Chris@16: BOOST_UBLAS_INLINE Chris@16: c_matrix &operator = (c_matrix m) { Chris@16: assign_temporary(m); Chris@16: return *this; Chris@16: } Chris@16: #else Chris@16: BOOST_UBLAS_INLINE Chris@16: c_matrix &operator = (const c_matrix &m) { Chris@16: size1_ = m.size1_; Chris@16: size2_ = m.size2_; Chris@16: for (size_type i = 0; i < m.size1_; ++ i) Chris@16: std::copy (m.data_ [i], m.data_ [i] + m.size2_, data_ [i]); Chris@16: return *this; Chris@16: } Chris@16: #endif Chris@16: template // Container assignment without temporary Chris@16: BOOST_UBLAS_INLINE Chris@16: c_matrix &operator = (const matrix_container &m) { Chris@16: resize (m ().size1 (), m ().size2 (), false); Chris@16: assign (m); Chris@16: return *this; Chris@16: } Chris@16: BOOST_UBLAS_INLINE Chris@16: c_matrix &assign_temporary (c_matrix &m) { Chris@16: swap (m); Chris@16: return *this; Chris@16: } Chris@16: template Chris@16: BOOST_UBLAS_INLINE Chris@16: c_matrix &operator = (const matrix_expression &ae) { Chris@16: self_type temporary (ae); Chris@16: return assign_temporary (temporary); Chris@16: } Chris@16: template Chris@16: BOOST_UBLAS_INLINE Chris@16: c_matrix &assign (const matrix_expression &ae) { Chris@16: matrix_assign (*this, ae); Chris@16: return *this; Chris@16: } Chris@16: template Chris@16: BOOST_UBLAS_INLINE Chris@16: c_matrix& operator += (const matrix_expression &ae) { Chris@16: self_type temporary (*this + ae); Chris@16: return assign_temporary (temporary); Chris@16: } Chris@16: template // Container assignment without temporary Chris@16: BOOST_UBLAS_INLINE Chris@16: c_matrix &operator += (const matrix_container &m) { Chris@16: plus_assign (m); Chris@16: return *this; Chris@16: } Chris@16: template Chris@16: BOOST_UBLAS_INLINE Chris@16: c_matrix &plus_assign (const matrix_expression &ae) { Chris@16: matrix_assign (*this, ae); Chris@16: return *this; Chris@16: } Chris@16: template Chris@16: BOOST_UBLAS_INLINE Chris@16: c_matrix& operator -= (const matrix_expression &ae) { Chris@16: self_type temporary (*this - ae); Chris@16: return assign_temporary (temporary); Chris@16: } Chris@16: template // Container assignment without temporary Chris@16: BOOST_UBLAS_INLINE Chris@16: c_matrix &operator -= (const matrix_container &m) { Chris@16: minus_assign (m); Chris@16: return *this; Chris@16: } Chris@16: template Chris@16: BOOST_UBLAS_INLINE Chris@16: c_matrix &minus_assign (const matrix_expression &ae) { Chris@16: matrix_assign (*this, ae); Chris@16: return *this; Chris@16: } Chris@16: template Chris@16: BOOST_UBLAS_INLINE Chris@16: c_matrix& operator *= (const AT &at) { Chris@16: matrix_assign_scalar (*this, at); Chris@16: return *this; Chris@16: } Chris@16: template Chris@16: BOOST_UBLAS_INLINE Chris@16: c_matrix& operator /= (const AT &at) { Chris@16: matrix_assign_scalar (*this, at); Chris@16: return *this; Chris@16: } Chris@16: Chris@16: // Swapping Chris@16: BOOST_UBLAS_INLINE Chris@16: void swap (c_matrix &m) { Chris@16: if (this != &m) { Chris@16: BOOST_UBLAS_CHECK (size1_ == m.size1_, bad_size ()); Chris@16: BOOST_UBLAS_CHECK (size2_ == m.size2_, bad_size ()); Chris@16: std::swap (size1_, m.size1_); Chris@16: std::swap (size2_, m.size2_); Chris@16: for (size_type i = 0; i < size1_; ++ i) Chris@16: std::swap_ranges (data_ [i], data_ [i] + size2_, m.data_ [i]); Chris@16: } Chris@16: } Chris@16: BOOST_UBLAS_INLINE Chris@16: friend void swap (c_matrix &m1, c_matrix &m2) { Chris@16: m1.swap (m2); Chris@16: } Chris@16: Chris@16: // Iterator types Chris@16: private: Chris@16: // Use pointers for iterator Chris@16: typedef const_pointer const_subiterator_type; Chris@16: typedef pointer subiterator_type; Chris@16: Chris@16: public: Chris@16: #ifdef BOOST_UBLAS_USE_INDEXED_ITERATOR Chris@16: typedef indexed_iterator1 iterator1; Chris@16: typedef indexed_iterator2 iterator2; Chris@16: typedef indexed_const_iterator1 const_iterator1; Chris@16: typedef indexed_const_iterator2 const_iterator2; Chris@16: #else Chris@16: class const_iterator1; Chris@16: class iterator1; Chris@16: class const_iterator2; Chris@16: class iterator2; Chris@16: #endif Chris@16: typedef reverse_iterator_base1 const_reverse_iterator1; Chris@16: typedef reverse_iterator_base1 reverse_iterator1; Chris@16: typedef reverse_iterator_base2 const_reverse_iterator2; Chris@16: typedef reverse_iterator_base2 reverse_iterator2; Chris@16: Chris@16: // Element lookup Chris@16: BOOST_UBLAS_INLINE Chris@101: const_iterator1 find1 (int /*rank*/, size_type i, size_type j) const { Chris@16: #ifdef BOOST_UBLAS_USE_INDEXED_ITERATOR Chris@16: return const_iterator1 (*this, i, j); Chris@16: #else Chris@16: return const_iterator1 (*this, &data_ [i] [j]); Chris@16: #endif Chris@16: } Chris@16: BOOST_UBLAS_INLINE Chris@101: iterator1 find1 (int /*rank*/, size_type i, size_type j) { Chris@16: #ifdef BOOST_UBLAS_USE_INDEXED_ITERATOR Chris@16: return iterator1 (*this, i, j); Chris@16: #else Chris@16: return iterator1 (*this, &data_ [i] [j]); Chris@16: #endif Chris@16: } Chris@16: BOOST_UBLAS_INLINE Chris@101: const_iterator2 find2 (int /*rank*/, size_type i, size_type j) const { Chris@16: #ifdef BOOST_UBLAS_USE_INDEXED_ITERATOR Chris@16: return const_iterator2 (*this, i, j); Chris@16: #else Chris@16: return const_iterator2 (*this, &data_ [i] [j]); Chris@16: #endif Chris@16: } Chris@16: BOOST_UBLAS_INLINE Chris@101: iterator2 find2 (int /*rank*/, size_type i, size_type j) { Chris@16: #ifdef BOOST_UBLAS_USE_INDEXED_ITERATOR Chris@16: return iterator2 (*this, i, j); Chris@16: #else Chris@16: return iterator2 (*this, &data_ [i] [j]); Chris@16: #endif Chris@16: } Chris@16: Chris@16: Chris@16: #ifndef BOOST_UBLAS_USE_INDEXED_ITERATOR Chris@16: class const_iterator1: Chris@16: public container_const_reference, Chris@16: public random_access_iterator_base { Chris@16: public: Chris@16: typedef typename c_matrix::difference_type difference_type; Chris@16: typedef typename c_matrix::value_type value_type; Chris@16: typedef typename c_matrix::const_reference reference; Chris@16: typedef typename c_matrix::const_pointer pointer; Chris@16: Chris@16: typedef const_iterator2 dual_iterator_type; Chris@16: typedef const_reverse_iterator2 dual_reverse_iterator_type; Chris@16: Chris@16: // Construction and destruction Chris@16: BOOST_UBLAS_INLINE Chris@16: const_iterator1 (): Chris@16: container_const_reference (), it_ () {} Chris@16: BOOST_UBLAS_INLINE Chris@16: const_iterator1 (const self_type &m, const const_subiterator_type &it): Chris@16: container_const_reference (m), it_ (it) {} Chris@16: BOOST_UBLAS_INLINE Chris@16: const_iterator1 (const iterator1 &it): Chris@16: container_const_reference (it ()), it_ (it.it_) {} Chris@16: Chris@16: // Arithmetic Chris@16: BOOST_UBLAS_INLINE Chris@16: const_iterator1 &operator ++ () { Chris@16: it_ += M; Chris@16: return *this; Chris@16: } Chris@16: BOOST_UBLAS_INLINE Chris@16: const_iterator1 &operator -- () { Chris@16: it_ -= M; Chris@16: return *this; Chris@16: } Chris@16: BOOST_UBLAS_INLINE Chris@16: const_iterator1 &operator += (difference_type n) { Chris@16: it_ += n * M; Chris@16: return *this; Chris@16: } Chris@16: BOOST_UBLAS_INLINE Chris@16: const_iterator1 &operator -= (difference_type n) { Chris@16: it_ -= n * M; Chris@16: return *this; Chris@16: } Chris@16: BOOST_UBLAS_INLINE Chris@16: difference_type operator - (const const_iterator1 &it) const { Chris@16: BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ()); Chris@16: return (it_ - it.it_) / M; Chris@16: } Chris@16: Chris@16: // Dereference Chris@16: BOOST_UBLAS_INLINE Chris@16: const_reference operator * () const { Chris@16: BOOST_UBLAS_CHECK (index1 () < (*this) ().size1 (), bad_index ()); Chris@16: BOOST_UBLAS_CHECK (index2 () < (*this) ().size2 (), bad_index ()); Chris@16: return *it_; Chris@16: } Chris@16: BOOST_UBLAS_INLINE Chris@16: const_reference operator [] (difference_type n) const { Chris@16: return *(*this + n); Chris@16: } Chris@16: Chris@16: #ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION Chris@16: BOOST_UBLAS_INLINE Chris@16: #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION Chris@16: typename self_type:: Chris@16: #endif Chris@16: const_iterator2 begin () const { Chris@16: const self_type &m = (*this) (); Chris@16: return m.find2 (1, index1 (), 0); Chris@16: } Chris@16: BOOST_UBLAS_INLINE Chris@16: #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION Chris@16: typename self_type:: Chris@16: #endif Chris@101: const_iterator2 cbegin () const { Chris@101: return begin (); Chris@101: } Chris@101: BOOST_UBLAS_INLINE Chris@101: #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION Chris@101: typename self_type:: Chris@101: #endif Chris@16: const_iterator2 end () const { Chris@16: const self_type &m = (*this) (); Chris@16: return m.find2 (1, index1 (), m.size2 ()); Chris@16: } Chris@16: BOOST_UBLAS_INLINE Chris@16: #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION Chris@16: typename self_type:: Chris@16: #endif Chris@101: const_iterator2 cend () const { Chris@101: return end (); Chris@101: } Chris@101: BOOST_UBLAS_INLINE Chris@101: #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION Chris@101: typename self_type:: Chris@101: #endif Chris@16: const_reverse_iterator2 rbegin () const { Chris@16: return const_reverse_iterator2 (end ()); Chris@16: } Chris@16: BOOST_UBLAS_INLINE Chris@16: #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION Chris@16: typename self_type:: Chris@16: #endif Chris@101: const_reverse_iterator2 crbegin () const { Chris@101: return rbegin (); Chris@101: } Chris@101: BOOST_UBLAS_INLINE Chris@101: #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION Chris@101: typename self_type:: Chris@101: #endif Chris@16: const_reverse_iterator2 rend () const { Chris@16: return const_reverse_iterator2 (begin ()); Chris@16: } Chris@101: BOOST_UBLAS_INLINE Chris@101: #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION Chris@101: typename self_type:: Chris@101: #endif Chris@101: const_reverse_iterator2 crend () const { Chris@101: return rend (); Chris@101: } Chris@16: #endif Chris@16: Chris@16: // Indices Chris@16: BOOST_UBLAS_INLINE Chris@16: size_type index1 () const { Chris@16: const self_type &m = (*this) (); Chris@16: return (it_ - m.begin1 ().it_) / M; Chris@16: } Chris@16: BOOST_UBLAS_INLINE Chris@16: size_type index2 () const { Chris@16: const self_type &m = (*this) (); Chris@16: return (it_ - m.begin1 ().it_) % M; Chris@16: } Chris@16: Chris@16: // Assignment Chris@16: BOOST_UBLAS_INLINE Chris@16: const_iterator1 &operator = (const const_iterator1 &it) { Chris@16: container_const_reference::assign (&it ()); Chris@16: it_ = it.it_; Chris@16: return *this; Chris@16: } Chris@16: Chris@16: // Comparison Chris@16: BOOST_UBLAS_INLINE Chris@16: bool operator == (const const_iterator1 &it) const { Chris@16: BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ()); Chris@16: return it_ == it.it_; Chris@16: } Chris@16: BOOST_UBLAS_INLINE Chris@16: bool operator < (const const_iterator1 &it) const { Chris@16: BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ()); Chris@16: return it_ < it.it_; Chris@16: } Chris@16: Chris@16: private: Chris@16: const_subiterator_type it_; Chris@16: Chris@16: friend class iterator1; Chris@16: }; Chris@16: #endif Chris@16: Chris@16: BOOST_UBLAS_INLINE Chris@16: const_iterator1 begin1 () const { Chris@16: return find1 (0, 0, 0); Chris@16: } Chris@16: BOOST_UBLAS_INLINE Chris@101: const_iterator1 cbegin1 () const { Chris@101: return begin1 (); Chris@101: } Chris@101: BOOST_UBLAS_INLINE Chris@16: const_iterator1 end1 () const { Chris@16: return find1 (0, size1_, 0); Chris@16: } Chris@101: BOOST_UBLAS_INLINE Chris@101: const_iterator1 cend1 () const { Chris@101: return end1 (); Chris@101: } Chris@16: Chris@16: #ifndef BOOST_UBLAS_USE_INDEXED_ITERATOR Chris@16: class iterator1: Chris@16: public container_reference, Chris@16: public random_access_iterator_base { Chris@16: public: Chris@16: Chris@16: typedef typename c_matrix::difference_type difference_type; Chris@16: typedef typename c_matrix::value_type value_type; Chris@16: typedef typename c_matrix::reference reference; Chris@16: typedef typename c_matrix::pointer pointer; Chris@16: Chris@16: typedef iterator2 dual_iterator_type; Chris@16: typedef reverse_iterator2 dual_reverse_iterator_type; Chris@16: Chris@16: // Construction and destruction Chris@16: BOOST_UBLAS_INLINE Chris@16: iterator1 (): Chris@16: container_reference (), it_ () {} Chris@16: BOOST_UBLAS_INLINE Chris@16: iterator1 (self_type &m, const subiterator_type &it): Chris@16: container_reference (m), it_ (it) {} Chris@16: Chris@16: // Arithmetic Chris@16: BOOST_UBLAS_INLINE Chris@16: iterator1 &operator ++ () { Chris@16: it_ += M; Chris@16: return *this; Chris@16: } Chris@16: BOOST_UBLAS_INLINE Chris@16: iterator1 &operator -- () { Chris@16: it_ -= M; Chris@16: return *this; Chris@16: } Chris@16: BOOST_UBLAS_INLINE Chris@16: iterator1 &operator += (difference_type n) { Chris@16: it_ += n * M; Chris@16: return *this; Chris@16: } Chris@16: BOOST_UBLAS_INLINE Chris@16: iterator1 &operator -= (difference_type n) { Chris@16: it_ -= n * M; Chris@16: return *this; Chris@16: } Chris@16: BOOST_UBLAS_INLINE Chris@16: difference_type operator - (const iterator1 &it) const { Chris@16: BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ()); Chris@16: return (it_ - it.it_) / M; Chris@16: } Chris@16: Chris@16: // Dereference Chris@16: BOOST_UBLAS_INLINE Chris@16: reference operator * () const { Chris@16: BOOST_UBLAS_CHECK (index1 () < (*this) ().size1 (), bad_index ()); Chris@16: BOOST_UBLAS_CHECK (index2 () < (*this) ().size2 (), bad_index ()); Chris@16: return *it_; Chris@16: } Chris@16: BOOST_UBLAS_INLINE Chris@16: reference operator [] (difference_type n) const { Chris@16: return *(*this + n); Chris@16: } Chris@16: Chris@16: #ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION Chris@16: BOOST_UBLAS_INLINE Chris@16: #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION Chris@16: typename self_type:: Chris@16: #endif Chris@16: iterator2 begin () const { Chris@16: self_type &m = (*this) (); Chris@16: return m.find2 (1, index1 (), 0); Chris@16: } Chris@16: BOOST_UBLAS_INLINE Chris@16: #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION Chris@16: typename self_type:: Chris@16: #endif Chris@16: iterator2 end () const { Chris@16: self_type &m = (*this) (); Chris@16: return m.find2 (1, index1 (), m.size2 ()); Chris@16: } Chris@16: BOOST_UBLAS_INLINE Chris@16: #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION Chris@16: typename self_type:: Chris@16: #endif Chris@16: reverse_iterator2 rbegin () const { Chris@16: return reverse_iterator2 (end ()); Chris@16: } Chris@16: BOOST_UBLAS_INLINE Chris@16: #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION Chris@16: typename self_type:: Chris@16: #endif Chris@16: reverse_iterator2 rend () const { Chris@16: return reverse_iterator2 (begin ()); Chris@16: } Chris@16: #endif Chris@16: Chris@16: // Indices Chris@16: BOOST_UBLAS_INLINE Chris@16: size_type index1 () const { Chris@16: const self_type &m = (*this) (); Chris@16: return (it_ - m.begin1 ().it_) / M; Chris@16: } Chris@16: BOOST_UBLAS_INLINE Chris@16: size_type index2 () const { Chris@16: const self_type &m = (*this) (); Chris@16: return (it_ - m.begin1 ().it_) % M; Chris@16: } Chris@16: Chris@16: // Assignment Chris@16: BOOST_UBLAS_INLINE Chris@16: iterator1 &operator = (const iterator1 &it) { Chris@16: container_reference::assign (&it ()); Chris@16: it_ = it.it_; Chris@16: return *this; Chris@16: } Chris@16: Chris@16: // Comparison Chris@16: BOOST_UBLAS_INLINE Chris@16: bool operator == (const iterator1 &it) const { Chris@16: BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ()); Chris@16: return it_ == it.it_; Chris@16: } Chris@16: BOOST_UBLAS_INLINE Chris@16: bool operator < (const iterator1 &it) const { Chris@16: BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ()); Chris@16: return it_ < it.it_; Chris@16: } Chris@16: Chris@16: private: Chris@16: subiterator_type it_; Chris@16: Chris@16: friend class const_iterator1; Chris@16: }; Chris@16: #endif Chris@16: Chris@16: BOOST_UBLAS_INLINE Chris@16: iterator1 begin1 () { Chris@16: return find1 (0, 0, 0); Chris@16: } Chris@16: BOOST_UBLAS_INLINE Chris@16: iterator1 end1 () { Chris@16: return find1 (0, size1_, 0); Chris@16: } Chris@16: Chris@16: #ifndef BOOST_UBLAS_USE_INDEXED_ITERATOR Chris@16: class const_iterator2: Chris@16: public container_const_reference, Chris@16: public random_access_iterator_base { Chris@16: public: Chris@16: typedef typename c_matrix::difference_type difference_type; Chris@16: typedef typename c_matrix::value_type value_type; Chris@16: typedef typename c_matrix::const_reference reference; Chris@16: typedef typename c_matrix::const_reference pointer; Chris@16: Chris@16: typedef const_iterator1 dual_iterator_type; Chris@16: typedef const_reverse_iterator1 dual_reverse_iterator_type; Chris@16: Chris@16: // Construction and destruction Chris@16: BOOST_UBLAS_INLINE Chris@16: const_iterator2 (): Chris@16: container_const_reference (), it_ () {} Chris@16: BOOST_UBLAS_INLINE Chris@16: const_iterator2 (const self_type &m, const const_subiterator_type &it): Chris@16: container_const_reference (m), it_ (it) {} Chris@16: BOOST_UBLAS_INLINE Chris@16: const_iterator2 (const iterator2 &it): Chris@16: container_const_reference (it ()), it_ (it.it_) {} Chris@16: Chris@16: // Arithmetic Chris@16: BOOST_UBLAS_INLINE Chris@16: const_iterator2 &operator ++ () { Chris@16: ++ it_; Chris@16: return *this; Chris@16: } Chris@16: BOOST_UBLAS_INLINE Chris@16: const_iterator2 &operator -- () { Chris@16: -- it_; Chris@16: return *this; Chris@16: } Chris@16: BOOST_UBLAS_INLINE Chris@16: const_iterator2 &operator += (difference_type n) { Chris@16: it_ += n; Chris@16: return *this; Chris@16: } Chris@16: BOOST_UBLAS_INLINE Chris@16: const_iterator2 &operator -= (difference_type n) { Chris@16: it_ -= n; Chris@16: return *this; Chris@16: } Chris@16: BOOST_UBLAS_INLINE Chris@16: difference_type operator - (const const_iterator2 &it) const { Chris@16: BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ()); Chris@16: return it_ - it.it_; Chris@16: } Chris@16: Chris@16: // Dereference Chris@16: BOOST_UBLAS_INLINE Chris@16: const_reference operator * () const { Chris@16: BOOST_UBLAS_CHECK (index1 () < (*this) ().size1 (), bad_index ()); Chris@16: BOOST_UBLAS_CHECK (index2 () < (*this) ().size2 (), bad_index ()); Chris@16: return *it_; Chris@16: } Chris@16: BOOST_UBLAS_INLINE Chris@16: const_reference operator [] (difference_type n) const { Chris@16: return *(*this + n); Chris@16: } Chris@16: Chris@16: #ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION Chris@16: BOOST_UBLAS_INLINE Chris@16: #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION Chris@16: typename self_type:: Chris@16: #endif Chris@16: const_iterator1 begin () const { Chris@16: const self_type &m = (*this) (); Chris@16: return m.find1 (1, 0, index2 ()); Chris@16: } Chris@16: BOOST_UBLAS_INLINE Chris@16: #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION Chris@16: typename self_type:: Chris@16: #endif Chris@101: const_iterator1 cbegin () const { Chris@101: return begin (); Chris@101: } Chris@101: BOOST_UBLAS_INLINE Chris@101: #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION Chris@101: typename self_type:: Chris@101: #endif Chris@16: const_iterator1 end () const { Chris@16: const self_type &m = (*this) (); Chris@16: return m.find1 (1, m.size1 (), index2 ()); Chris@16: } Chris@16: BOOST_UBLAS_INLINE Chris@16: #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION Chris@16: typename self_type:: Chris@16: #endif Chris@101: const_iterator1 cend () const { Chris@101: return end (); Chris@101: } Chris@101: BOOST_UBLAS_INLINE Chris@101: #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION Chris@101: typename self_type:: Chris@101: #endif Chris@16: const_reverse_iterator1 rbegin () const { Chris@16: return const_reverse_iterator1 (end ()); Chris@16: } Chris@16: BOOST_UBLAS_INLINE Chris@16: #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION Chris@16: typename self_type:: Chris@16: #endif Chris@101: const_reverse_iterator1 crbegin () const { Chris@101: return rbegin (); Chris@101: } Chris@101: BOOST_UBLAS_INLINE Chris@101: #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION Chris@101: typename self_type:: Chris@101: #endif Chris@16: const_reverse_iterator1 rend () const { Chris@16: return const_reverse_iterator1 (begin ()); Chris@16: } Chris@101: BOOST_UBLAS_INLINE Chris@101: #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION Chris@101: typename self_type:: Chris@101: #endif Chris@101: const_reverse_iterator1 crend () const { Chris@101: return rend (); Chris@101: } Chris@16: #endif Chris@16: Chris@16: // Indices Chris@16: BOOST_UBLAS_INLINE Chris@16: size_type index1 () const { Chris@16: const self_type &m = (*this) (); Chris@16: return (it_ - m.begin2 ().it_) / M; Chris@16: } Chris@16: BOOST_UBLAS_INLINE Chris@16: size_type index2 () const { Chris@16: const self_type &m = (*this) (); Chris@16: return (it_ - m.begin2 ().it_) % M; Chris@16: } Chris@16: Chris@16: // Assignment Chris@16: BOOST_UBLAS_INLINE Chris@16: const_iterator2 &operator = (const const_iterator2 &it) { Chris@16: container_const_reference::assign (&it ()); Chris@16: it_ = it.it_; Chris@16: return *this; Chris@16: } Chris@16: Chris@16: // Comparison Chris@16: BOOST_UBLAS_INLINE Chris@16: bool operator == (const const_iterator2 &it) const { Chris@16: BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ()); Chris@16: return it_ == it.it_; Chris@16: } Chris@16: BOOST_UBLAS_INLINE Chris@16: bool operator < (const const_iterator2 &it) const { Chris@16: BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ()); Chris@16: return it_ < it.it_; Chris@16: } Chris@16: Chris@16: private: Chris@16: const_subiterator_type it_; Chris@16: Chris@16: friend class iterator2; Chris@16: }; Chris@16: #endif Chris@16: Chris@16: BOOST_UBLAS_INLINE Chris@16: const_iterator2 begin2 () const { Chris@16: return find2 (0, 0, 0); Chris@16: } Chris@16: BOOST_UBLAS_INLINE Chris@101: const_iterator2 cbegin2 () const { Chris@101: return begin2 (); Chris@101: } Chris@101: BOOST_UBLAS_INLINE Chris@16: const_iterator2 end2 () const { Chris@16: return find2 (0, 0, size2_); Chris@16: } Chris@101: BOOST_UBLAS_INLINE Chris@101: const_iterator2 cend2 () const { Chris@101: return end2 (); Chris@101: } Chris@16: Chris@16: #ifndef BOOST_UBLAS_USE_INDEXED_ITERATOR Chris@16: class iterator2: Chris@16: public container_reference, Chris@16: public random_access_iterator_base { Chris@16: public: Chris@16: typedef typename c_matrix::difference_type difference_type; Chris@16: typedef typename c_matrix::value_type value_type; Chris@16: typedef typename c_matrix::reference reference; Chris@16: typedef typename c_matrix::pointer pointer; Chris@16: Chris@16: typedef iterator1 dual_iterator_type; Chris@16: typedef reverse_iterator1 dual_reverse_iterator_type; Chris@16: Chris@16: // Construction and destruction Chris@16: BOOST_UBLAS_INLINE Chris@16: iterator2 (): Chris@16: container_reference (), it_ () {} Chris@16: BOOST_UBLAS_INLINE Chris@16: iterator2 (self_type &m, const subiterator_type &it): Chris@16: container_reference (m), it_ (it) {} Chris@16: Chris@16: // Arithmetic Chris@16: BOOST_UBLAS_INLINE Chris@16: iterator2 &operator ++ () { Chris@16: ++ it_; Chris@16: return *this; Chris@16: } Chris@16: BOOST_UBLAS_INLINE Chris@16: iterator2 &operator -- () { Chris@16: -- it_; Chris@16: return *this; Chris@16: } Chris@16: BOOST_UBLAS_INLINE Chris@16: iterator2 &operator += (difference_type n) { Chris@16: it_ += n; Chris@16: return *this; Chris@16: } Chris@16: BOOST_UBLAS_INLINE Chris@16: iterator2 &operator -= (difference_type n) { Chris@16: it_ -= n; Chris@16: return *this; Chris@16: } Chris@16: BOOST_UBLAS_INLINE Chris@16: difference_type operator - (const iterator2 &it) const { Chris@16: BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ()); Chris@16: return it_ - it.it_; Chris@16: } Chris@16: Chris@16: // Dereference Chris@16: BOOST_UBLAS_INLINE Chris@16: reference operator * () const { Chris@16: BOOST_UBLAS_CHECK (index1 () < (*this) ().size1 (), bad_index ()); Chris@16: BOOST_UBLAS_CHECK (index2 () < (*this) ().size2 (), bad_index ()); Chris@16: return *it_; Chris@16: } Chris@16: BOOST_UBLAS_INLINE Chris@16: reference operator [] (difference_type n) const { Chris@16: return *(*this + n); Chris@16: } Chris@16: Chris@16: #ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION Chris@16: BOOST_UBLAS_INLINE Chris@16: #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION Chris@16: typename self_type:: Chris@16: #endif Chris@16: iterator1 begin () const { Chris@16: self_type &m = (*this) (); Chris@16: return m.find1 (1, 0, index2 ()); Chris@16: } Chris@16: BOOST_UBLAS_INLINE Chris@16: #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION Chris@16: typename self_type:: Chris@16: #endif Chris@16: iterator1 end () const { Chris@16: self_type &m = (*this) (); Chris@16: return m.find1 (1, m.size1 (), index2 ()); Chris@16: } Chris@16: BOOST_UBLAS_INLINE Chris@16: #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION Chris@16: typename self_type:: Chris@16: #endif Chris@16: reverse_iterator1 rbegin () const { Chris@16: return reverse_iterator1 (end ()); Chris@16: } Chris@16: BOOST_UBLAS_INLINE Chris@16: #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION Chris@16: typename self_type:: Chris@16: #endif Chris@16: reverse_iterator1 rend () const { Chris@16: return reverse_iterator1 (begin ()); Chris@16: } Chris@16: #endif Chris@16: Chris@16: // Indices Chris@16: BOOST_UBLAS_INLINE Chris@16: size_type index1 () const { Chris@16: const self_type &m = (*this) (); Chris@16: return (it_ - m.begin2 ().it_) / M; Chris@16: } Chris@16: BOOST_UBLAS_INLINE Chris@16: size_type index2 () const { Chris@16: const self_type &m = (*this) (); Chris@16: return (it_ - m.begin2 ().it_) % M; Chris@16: } Chris@16: Chris@16: // Assignment Chris@16: BOOST_UBLAS_INLINE Chris@16: iterator2 &operator = (const iterator2 &it) { Chris@16: container_reference::assign (&it ()); Chris@16: it_ = it.it_; Chris@16: return *this; Chris@16: } Chris@16: Chris@16: // Comparison Chris@16: BOOST_UBLAS_INLINE Chris@16: bool operator == (const iterator2 &it) const { Chris@16: BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ()); Chris@16: return it_ == it.it_; Chris@16: } Chris@16: BOOST_UBLAS_INLINE Chris@16: bool operator < (const iterator2 &it) const { Chris@16: BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ()); Chris@16: return it_ < it.it_; Chris@16: } Chris@16: Chris@16: private: Chris@16: subiterator_type it_; Chris@16: Chris@16: friend class const_iterator2; Chris@16: }; Chris@16: #endif Chris@16: Chris@16: BOOST_UBLAS_INLINE Chris@16: iterator2 begin2 () { Chris@16: return find2 (0, 0, 0); Chris@16: } Chris@16: BOOST_UBLAS_INLINE Chris@16: iterator2 end2 () { Chris@16: return find2 (0, 0, size2_); Chris@16: } Chris@16: Chris@16: // Reverse iterators Chris@16: Chris@16: BOOST_UBLAS_INLINE Chris@16: const_reverse_iterator1 rbegin1 () const { Chris@16: return const_reverse_iterator1 (end1 ()); Chris@16: } Chris@16: BOOST_UBLAS_INLINE Chris@101: const_reverse_iterator1 crbegin1 () const { Chris@101: return rbegin1 (); Chris@101: } Chris@101: BOOST_UBLAS_INLINE Chris@16: const_reverse_iterator1 rend1 () const { Chris@16: return const_reverse_iterator1 (begin1 ()); Chris@16: } Chris@101: BOOST_UBLAS_INLINE Chris@101: const_reverse_iterator1 crend1 () const { Chris@101: return rend1 (); Chris@101: } Chris@16: Chris@16: BOOST_UBLAS_INLINE Chris@16: reverse_iterator1 rbegin1 () { Chris@16: return reverse_iterator1 (end1 ()); Chris@16: } Chris@16: BOOST_UBLAS_INLINE Chris@16: reverse_iterator1 rend1 () { Chris@16: return reverse_iterator1 (begin1 ()); Chris@16: } Chris@16: Chris@16: BOOST_UBLAS_INLINE Chris@16: const_reverse_iterator2 rbegin2 () const { Chris@16: return const_reverse_iterator2 (end2 ()); Chris@16: } Chris@16: BOOST_UBLAS_INLINE Chris@101: const_reverse_iterator2 crbegin2 () const { Chris@101: return rbegin2 (); Chris@101: } Chris@101: BOOST_UBLAS_INLINE Chris@16: const_reverse_iterator2 rend2 () const { Chris@16: return const_reverse_iterator2 (begin2 ()); Chris@16: } Chris@101: BOOST_UBLAS_INLINE Chris@101: const_reverse_iterator2 crend2 () const { Chris@101: return rend2 (); Chris@101: } Chris@16: Chris@16: BOOST_UBLAS_INLINE Chris@16: reverse_iterator2 rbegin2 () { Chris@16: return reverse_iterator2 (end2 ()); Chris@16: } Chris@16: BOOST_UBLAS_INLINE Chris@16: reverse_iterator2 rend2 () { Chris@16: return reverse_iterator2 (begin2 ()); Chris@16: } Chris@16: Chris@16: // Serialization Chris@16: template Chris@16: void serialize(Archive & ar, const unsigned int /* file_version */){ Chris@16: Chris@16: // we need to copy to a collection_size_type to get a portable Chris@16: // and efficient serialization Chris@16: serialization::collection_size_type s1 (size1_); Chris@16: serialization::collection_size_type s2 (size2_); Chris@16: Chris@16: // serialize the sizes Chris@16: ar & serialization::make_nvp("size1",s1) Chris@16: & serialization::make_nvp("size2",s2); Chris@16: Chris@16: // copy the values back if loading Chris@16: if (Archive::is_loading::value) { Chris@16: size1_ = s1; Chris@16: size2_ = s2; Chris@16: } Chris@16: // could probably use make_array( &(data[0][0]), N*M ) Chris@16: ar & serialization::make_array(data_, N); Chris@16: } Chris@16: Chris@16: private: Chris@16: size_type size1_; Chris@16: size_type size2_; Chris@16: value_type data_ [N] [M]; Chris@16: }; Chris@16: Chris@16: }}} Chris@16: Chris@16: #endif