sl@0: // sl@0: // Copyright (c) 2000-2002 sl@0: // Joerg Walter, Mathias Koch sl@0: // sl@0: // Permission to use, copy, modify, distribute and sell this software sl@0: // and its documentation for any purpose is hereby granted without fee, sl@0: // provided that the above copyright notice appear in all copies and sl@0: // that both that copyright notice and this permission notice appear sl@0: // in supporting documentation. The authors make no representations sl@0: // about the suitability of this software for any purpose. sl@0: // It is provided "as is" without express or implied warranty. sl@0: // sl@0: // The authors gratefully acknowledge the support of sl@0: // GeNeSys mbH & Co. KG in producing this work. sl@0: // sl@0: sl@0: #ifndef _BOOST_UBLAS_MATRIX_ sl@0: #define _BOOST_UBLAS_MATRIX_ sl@0: sl@0: #include sl@0: #include sl@0: #include sl@0: sl@0: // Iterators based on ideas of Jeremy Siek sl@0: sl@0: namespace boost { namespace numeric { namespace ublas { sl@0: sl@0: namespace detail { sl@0: using namespace boost::numeric::ublas; sl@0: sl@0: // Matrix resizing algorithm sl@0: template sl@0: BOOST_UBLAS_INLINE sl@0: void matrix_resize_preserve (M& m, M& temporary) { sl@0: typedef L layout_type; sl@0: typedef typename M::size_type size_type; sl@0: const size_type msize1 (m.size1 ()); // original size sl@0: const size_type msize2 (m.size2 ()); sl@0: const size_type size1 (temporary.size1 ()); // new size is specified by temporary sl@0: const size_type size2 (temporary.size2 ()); sl@0: // Common elements to preserve sl@0: const size_type size1_min = (std::min) (size1, msize1); sl@0: const size_type size2_min = (std::min) (size2, msize2); sl@0: // Order loop for i-major and j-minor sizes sl@0: const size_type i_size = layout_type::size1 (size1_min, size2_min); sl@0: const size_type j_size = layout_type::size2 (size1_min, size2_min); sl@0: for (size_type i = 0; i != i_size; ++i) { // indexing copy over major sl@0: for (size_type j = 0; j != j_size; ++j) { sl@0: const size_type element1 = layout_type::element1(i,i_size, j,j_size); sl@0: const size_type element2 = layout_type::element2(i,i_size, j,j_size); sl@0: temporary.data () [layout_type::element (element1, size1, element2, size2)] = sl@0: m.data() [layout_type::element (element1, msize1, element2, msize2)]; sl@0: } sl@0: } sl@0: m.assign_temporary (temporary); sl@0: } sl@0: } sl@0: sl@0: sl@0: // Array based matrix class sl@0: template sl@0: class matrix: sl@0: public matrix_container > { sl@0: sl@0: typedef T *pointer; sl@0: typedef L layout_type; sl@0: typedef matrix self_type; sl@0: public: sl@0: #ifdef BOOST_UBLAS_ENABLE_PROXY_SHORTCUTS sl@0: using matrix_container::operator (); sl@0: #endif sl@0: typedef typename A::size_type size_type; sl@0: typedef typename A::difference_type difference_type; sl@0: typedef T value_type; sl@0: typedef const T &const_reference; sl@0: typedef T &reference; sl@0: typedef A array_type; sl@0: typedef const matrix_reference const_closure_type; sl@0: typedef matrix_reference closure_type; sl@0: typedef vector vector_temporary_type; sl@0: typedef self_type matrix_temporary_type; sl@0: typedef dense_tag storage_category; sl@0: // This could be better for performance, sl@0: // typedef typename unknown_orientation_tag orientation_category; sl@0: // but others depend on the orientation information... sl@0: typedef typename L::orientation_category orientation_category; sl@0: sl@0: // Construction and destruction sl@0: BOOST_UBLAS_INLINE sl@0: matrix (): sl@0: matrix_container (), sl@0: size1_ (0), size2_ (0), data_ () {} sl@0: BOOST_UBLAS_INLINE sl@0: matrix (size_type size1, size_type size2): sl@0: matrix_container (), sl@0: size1_ (size1), size2_ (size2), data_ (layout_type::storage_size (size1, size2)) { sl@0: } sl@0: BOOST_UBLAS_INLINE sl@0: matrix (size_type size1, size_type size2, const array_type &data): sl@0: matrix_container (), sl@0: size1_ (size1), size2_ (size2), data_ (data) {} sl@0: BOOST_UBLAS_INLINE sl@0: matrix (const matrix &m): sl@0: matrix_container (), sl@0: size1_ (m.size1_), size2_ (m.size2_), data_ (m.data_) {} sl@0: template sl@0: BOOST_UBLAS_INLINE sl@0: matrix (const matrix_expression &ae): sl@0: matrix_container (), sl@0: size1_ (ae ().size1 ()), size2_ (ae ().size2 ()), data_ (layout_type::storage_size (size1_, size2_)) { sl@0: matrix_assign (*this, ae); sl@0: } sl@0: sl@0: // Accessors sl@0: BOOST_UBLAS_INLINE sl@0: size_type size1 () const { sl@0: return size1_; sl@0: } sl@0: BOOST_UBLAS_INLINE sl@0: size_type size2 () const { sl@0: return size2_; sl@0: } sl@0: sl@0: // Storage accessors sl@0: BOOST_UBLAS_INLINE sl@0: const array_type &data () const { sl@0: return data_; sl@0: } sl@0: BOOST_UBLAS_INLINE sl@0: array_type &data () { sl@0: return data_; sl@0: } sl@0: sl@0: // Resizing sl@0: BOOST_UBLAS_INLINE sl@0: void resize (size_type size1, size_type size2, bool preserve = true) { sl@0: if (preserve) { sl@0: self_type temporary (size1, size2); sl@0: detail::matrix_resize_preserve (*this, temporary); sl@0: } sl@0: else { sl@0: data ().resize (layout_type::storage_size (size1, size2)); sl@0: size1_ = size1; sl@0: size2_ = size2; sl@0: } sl@0: } sl@0: sl@0: // Element access sl@0: BOOST_UBLAS_INLINE sl@0: const_reference operator () (size_type i, size_type j) const { sl@0: return data () [layout_type::element (i, size1_, j, size2_)]; sl@0: } sl@0: BOOST_UBLAS_INLINE sl@0: reference at_element (size_type i, size_type j) { sl@0: return data () [layout_type::element (i, size1_, j, size2_)]; sl@0: } sl@0: BOOST_UBLAS_INLINE sl@0: reference operator () (size_type i, size_type j) { sl@0: return at_element (i, j); sl@0: } sl@0: sl@0: // Element assignment sl@0: BOOST_UBLAS_INLINE sl@0: reference insert_element (size_type i, size_type j, const_reference t) { sl@0: return (at_element (i, j) = t); sl@0: } sl@0: void erase_element (size_type i, size_type j) { sl@0: at_element (i, j) = value_type/*zero*/(); sl@0: } sl@0: sl@0: // Zeroing sl@0: BOOST_UBLAS_INLINE sl@0: void clear () { sl@0: std::fill (data ().begin (), data ().end (), value_type/*zero*/()); sl@0: } sl@0: sl@0: // Assignment sl@0: BOOST_UBLAS_INLINE sl@0: matrix &operator = (const matrix &m) { sl@0: size1_ = m.size1_; sl@0: size2_ = m.size2_; sl@0: data () = m.data (); sl@0: return *this; sl@0: } sl@0: template // Container assignment without temporary sl@0: BOOST_UBLAS_INLINE sl@0: matrix &operator = (const matrix_container &m) { sl@0: resize (m ().size1 (), m ().size2 (), false); sl@0: assign (m); sl@0: return *this; sl@0: } sl@0: BOOST_UBLAS_INLINE sl@0: matrix &assign_temporary (matrix &m) { sl@0: swap (m); sl@0: return *this; sl@0: } sl@0: template sl@0: BOOST_UBLAS_INLINE sl@0: matrix &operator = (const matrix_expression &ae) { sl@0: self_type temporary (ae); sl@0: return assign_temporary (temporary); sl@0: } sl@0: template sl@0: BOOST_UBLAS_INLINE sl@0: matrix &assign (const matrix_expression &ae) { sl@0: matrix_assign (*this, ae); sl@0: return *this; sl@0: } sl@0: template sl@0: BOOST_UBLAS_INLINE sl@0: matrix& operator += (const matrix_expression &ae) { sl@0: self_type temporary (*this + ae); sl@0: return assign_temporary (temporary); sl@0: } sl@0: template // Container assignment without temporary sl@0: BOOST_UBLAS_INLINE sl@0: matrix &operator += (const matrix_container &m) { sl@0: plus_assign (m); sl@0: return *this; sl@0: } sl@0: template sl@0: BOOST_UBLAS_INLINE sl@0: matrix &plus_assign (const matrix_expression &ae) { sl@0: matrix_assign (*this, ae); sl@0: return *this; sl@0: } sl@0: template sl@0: BOOST_UBLAS_INLINE sl@0: matrix& operator -= (const matrix_expression &ae) { sl@0: self_type temporary (*this - ae); sl@0: return assign_temporary (temporary); sl@0: } sl@0: template // Container assignment without temporary sl@0: BOOST_UBLAS_INLINE sl@0: matrix &operator -= (const matrix_container &m) { sl@0: minus_assign (m); sl@0: return *this; sl@0: } sl@0: template sl@0: BOOST_UBLAS_INLINE sl@0: matrix &minus_assign (const matrix_expression &ae) { sl@0: matrix_assign (*this, ae); sl@0: return *this; sl@0: } sl@0: template sl@0: BOOST_UBLAS_INLINE sl@0: matrix& operator *= (const AT &at) { sl@0: matrix_assign_scalar (*this, at); sl@0: return *this; sl@0: } sl@0: template sl@0: BOOST_UBLAS_INLINE sl@0: matrix& operator /= (const AT &at) { sl@0: matrix_assign_scalar (*this, at); sl@0: return *this; sl@0: } sl@0: sl@0: // Swapping sl@0: BOOST_UBLAS_INLINE sl@0: void swap (matrix &m) { sl@0: if (this != &m) { sl@0: std::swap (size1_, m.size1_); sl@0: std::swap (size2_, m.size2_); sl@0: data ().swap (m.data ()); sl@0: } sl@0: } sl@0: BOOST_UBLAS_INLINE sl@0: friend void swap (matrix &m1, matrix &m2) { sl@0: m1.swap (m2); sl@0: } sl@0: sl@0: // Iterator types sl@0: private: sl@0: // Use the storage array iterator sl@0: typedef typename A::const_iterator const_subiterator_type; sl@0: typedef typename A::iterator subiterator_type; sl@0: sl@0: public: sl@0: #ifdef BOOST_UBLAS_USE_INDEXED_ITERATOR sl@0: typedef indexed_iterator1 iterator1; sl@0: typedef indexed_iterator2 iterator2; sl@0: typedef indexed_const_iterator1 const_iterator1; sl@0: typedef indexed_const_iterator2 const_iterator2; sl@0: #else sl@0: class const_iterator1; sl@0: class iterator1; sl@0: class const_iterator2; sl@0: class iterator2; sl@0: #endif sl@0: typedef reverse_iterator_base1 const_reverse_iterator1; sl@0: typedef reverse_iterator_base1 reverse_iterator1; sl@0: typedef reverse_iterator_base2 const_reverse_iterator2; sl@0: typedef reverse_iterator_base2 reverse_iterator2; sl@0: sl@0: // Element lookup sl@0: BOOST_UBLAS_INLINE sl@0: const_iterator1 find1 (int /* rank */, size_type i, size_type j) const { sl@0: #ifdef BOOST_UBLAS_USE_INDEXED_ITERATOR sl@0: return const_iterator1 (*this, i, j); sl@0: #else sl@0: return const_iterator1 (*this, data ().begin () + layout_type::address (i, size1_, j, size2_)); sl@0: #endif sl@0: } sl@0: BOOST_UBLAS_INLINE sl@0: iterator1 find1 (int /* rank */, size_type i, size_type j) { sl@0: #ifdef BOOST_UBLAS_USE_INDEXED_ITERATOR sl@0: return iterator1 (*this, i, j); sl@0: #else sl@0: return iterator1 (*this, data ().begin () + layout_type::address (i, size1_, j, size2_)); sl@0: #endif sl@0: } sl@0: BOOST_UBLAS_INLINE sl@0: const_iterator2 find2 (int /* rank */, size_type i, size_type j) const { sl@0: #ifdef BOOST_UBLAS_USE_INDEXED_ITERATOR sl@0: return const_iterator2 (*this, i, j); sl@0: #else sl@0: return const_iterator2 (*this, data ().begin () + layout_type::address (i, size1_, j, size2_)); sl@0: #endif sl@0: } sl@0: BOOST_UBLAS_INLINE sl@0: iterator2 find2 (int /* rank */, size_type i, size_type j) { sl@0: #ifdef BOOST_UBLAS_USE_INDEXED_ITERATOR sl@0: return iterator2 (*this, i, j); sl@0: #else sl@0: return iterator2 (*this, data ().begin () + layout_type::address (i, size1_, j, size2_)); sl@0: #endif sl@0: } sl@0: sl@0: sl@0: #ifndef BOOST_UBLAS_USE_INDEXED_ITERATOR sl@0: class const_iterator1: sl@0: public container_const_reference, sl@0: public random_access_iterator_base { sl@0: public: sl@0: typedef typename matrix::value_type value_type; sl@0: typedef typename matrix::difference_type difference_type; sl@0: typedef typename matrix::const_reference reference; sl@0: typedef const typename matrix::pointer pointer; sl@0: sl@0: typedef const_iterator2 dual_iterator_type; sl@0: typedef const_reverse_iterator2 dual_reverse_iterator_type; sl@0: sl@0: // Construction and destruction sl@0: BOOST_UBLAS_INLINE sl@0: const_iterator1 (): sl@0: container_const_reference (), it_ () {} sl@0: BOOST_UBLAS_INLINE sl@0: const_iterator1 (const self_type &m, const const_subiterator_type &it): sl@0: container_const_reference (m), it_ (it) {} sl@0: BOOST_UBLAS_INLINE sl@0: const_iterator1 (const iterator1 &it): sl@0: container_const_reference (it ()), it_ (it.it_) {} sl@0: sl@0: // Arithmetic sl@0: BOOST_UBLAS_INLINE sl@0: const_iterator1 &operator ++ () { sl@0: layout_type::increment1 (it_, (*this) ().size1 (), (*this) ().size2 ()); sl@0: return *this; sl@0: } sl@0: BOOST_UBLAS_INLINE sl@0: const_iterator1 &operator -- () { sl@0: layout_type::decrement1 (it_, (*this) ().size1 (), (*this) ().size2 ()); sl@0: return *this; sl@0: } sl@0: BOOST_UBLAS_INLINE sl@0: const_iterator1 &operator += (difference_type n) { sl@0: it_ += n * layout_type::one1 ((*this) ().size1 (), (*this) ().size2 ()); sl@0: return *this; sl@0: } sl@0: BOOST_UBLAS_INLINE sl@0: const_iterator1 &operator -= (difference_type n) { sl@0: it_ -= n * layout_type::one1 ((*this) ().size1 (), (*this) ().size2 ()); sl@0: return *this; sl@0: } sl@0: BOOST_UBLAS_INLINE sl@0: difference_type operator - (const const_iterator1 &it) const { sl@0: BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ()); sl@0: return layout_type::distance1 (it_ - it.it_, (*this) ().size1 (), (*this) ().size2 ()); sl@0: } sl@0: sl@0: // Dereference sl@0: BOOST_UBLAS_INLINE sl@0: const_reference operator * () const { sl@0: BOOST_UBLAS_CHECK (index1 () < (*this) ().size1 (), bad_index ()); sl@0: BOOST_UBLAS_CHECK (index2 () < (*this) ().size2 (), bad_index ()); sl@0: return *it_; sl@0: } sl@0: BOOST_UBLAS_INLINE sl@0: const_reference operator [] (difference_type n) const { sl@0: return *(*this + n); sl@0: } sl@0: sl@0: #ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION sl@0: BOOST_UBLAS_INLINE sl@0: #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION sl@0: typename self_type:: sl@0: #endif sl@0: const_iterator2 begin () const { sl@0: const self_type &m = (*this) (); sl@0: return m.find2 (1, index1 (), 0); sl@0: } sl@0: BOOST_UBLAS_INLINE sl@0: #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION sl@0: typename self_type:: sl@0: #endif sl@0: const_iterator2 end () const { sl@0: const self_type &m = (*this) (); sl@0: return m.find2 (1, index1 (), m.size2 ()); sl@0: } sl@0: BOOST_UBLAS_INLINE sl@0: #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION sl@0: typename self_type:: sl@0: #endif sl@0: const_reverse_iterator2 rbegin () const { sl@0: return const_reverse_iterator2 (end ()); sl@0: } sl@0: BOOST_UBLAS_INLINE sl@0: #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION sl@0: typename self_type:: sl@0: #endif sl@0: const_reverse_iterator2 rend () const { sl@0: return const_reverse_iterator2 (begin ()); sl@0: } sl@0: #endif sl@0: sl@0: // Indices sl@0: BOOST_UBLAS_INLINE sl@0: size_type index1 () const { sl@0: const self_type &m = (*this) (); sl@0: return layout_type::index1 (it_ - m.begin1 ().it_, m.size1 (), m.size2 ()); sl@0: } sl@0: BOOST_UBLAS_INLINE sl@0: size_type index2 () const { sl@0: const self_type &m = (*this) (); sl@0: return layout_type::index2 (it_ - m.begin1 ().it_, m.size1 (), m.size2 ()); sl@0: } sl@0: sl@0: // Assignment sl@0: BOOST_UBLAS_INLINE sl@0: const_iterator1 &operator = (const const_iterator1 &it) { sl@0: container_const_reference::assign (&it ()); sl@0: it_ = it.it_; sl@0: return *this; sl@0: } sl@0: sl@0: // Comparison sl@0: BOOST_UBLAS_INLINE sl@0: bool operator == (const const_iterator1 &it) const { sl@0: BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ()); sl@0: return it_ == it.it_; sl@0: } sl@0: BOOST_UBLAS_INLINE sl@0: bool operator < (const const_iterator1 &it) const { sl@0: BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ()); sl@0: return it_ < it.it_; sl@0: } sl@0: sl@0: private: sl@0: const_subiterator_type it_; sl@0: sl@0: friend class iterator1; sl@0: }; sl@0: #endif sl@0: sl@0: BOOST_UBLAS_INLINE sl@0: const_iterator1 begin1 () const { sl@0: return find1 (0, 0, 0); sl@0: } sl@0: BOOST_UBLAS_INLINE sl@0: const_iterator1 end1 () const { sl@0: return find1 (0, size1_, 0); sl@0: } sl@0: sl@0: #ifndef BOOST_UBLAS_USE_INDEXED_ITERATOR sl@0: class iterator1: sl@0: public container_reference, sl@0: public random_access_iterator_base { sl@0: public: sl@0: typedef typename matrix::value_type value_type; sl@0: typedef typename matrix::difference_type difference_type; sl@0: typedef typename matrix::reference reference; sl@0: typedef typename matrix::pointer pointer; sl@0: sl@0: typedef iterator2 dual_iterator_type; sl@0: typedef reverse_iterator2 dual_reverse_iterator_type; sl@0: sl@0: // Construction and destruction sl@0: BOOST_UBLAS_INLINE sl@0: iterator1 (): sl@0: container_reference (), it_ () {} sl@0: BOOST_UBLAS_INLINE sl@0: iterator1 (self_type &m, const subiterator_type &it): sl@0: container_reference (m), it_ (it) {} sl@0: sl@0: // Arithmetic sl@0: BOOST_UBLAS_INLINE sl@0: iterator1 &operator ++ () { sl@0: layout_type::increment1 (it_, (*this) ().size1 (), (*this) ().size2 ()); sl@0: return *this; sl@0: } sl@0: BOOST_UBLAS_INLINE sl@0: iterator1 &operator -- () { sl@0: layout_type::decrement1 (it_, (*this) ().size1 (), (*this) ().size2 ()); sl@0: return *this; sl@0: } sl@0: BOOST_UBLAS_INLINE sl@0: iterator1 &operator += (difference_type n) { sl@0: it_ += n * layout_type::one1 ((*this) ().size1 (), (*this) ().size2 ()); sl@0: return *this; sl@0: } sl@0: BOOST_UBLAS_INLINE sl@0: iterator1 &operator -= (difference_type n) { sl@0: it_ -= n * layout_type::one1 ((*this) ().size1 (), (*this) ().size2 ()); sl@0: return *this; sl@0: } sl@0: BOOST_UBLAS_INLINE sl@0: difference_type operator - (const iterator1 &it) const { sl@0: BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ()); sl@0: return layout_type::distance1 (it_ - it.it_, (*this) ().size1 (), (*this) ().size2 ()); sl@0: } sl@0: sl@0: // Dereference sl@0: BOOST_UBLAS_INLINE sl@0: reference operator * () const { sl@0: BOOST_UBLAS_CHECK (index1 () < (*this) ().size1 (), bad_index ()); sl@0: BOOST_UBLAS_CHECK (index2 () < (*this) ().size2 (), bad_index ()); sl@0: return *it_; sl@0: } sl@0: BOOST_UBLAS_INLINE sl@0: reference operator [] (difference_type n) const { sl@0: return *(*this + n); sl@0: } sl@0: sl@0: #ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION sl@0: BOOST_UBLAS_INLINE sl@0: #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION sl@0: typename self_type:: sl@0: #endif sl@0: iterator2 begin () const { sl@0: self_type &m = (*this) (); sl@0: return m.find2 (1, index1 (), 0); sl@0: } sl@0: BOOST_UBLAS_INLINE sl@0: #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION sl@0: typename self_type:: sl@0: #endif sl@0: iterator2 end () const { sl@0: self_type &m = (*this) (); sl@0: return m.find2 (1, index1 (), m.size2 ()); sl@0: } sl@0: BOOST_UBLAS_INLINE sl@0: #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION sl@0: typename self_type:: sl@0: #endif sl@0: reverse_iterator2 rbegin () const { sl@0: return reverse_iterator2 (end ()); sl@0: } sl@0: BOOST_UBLAS_INLINE sl@0: #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION sl@0: typename self_type:: sl@0: #endif sl@0: reverse_iterator2 rend () const { sl@0: return reverse_iterator2 (begin ()); sl@0: } sl@0: #endif sl@0: sl@0: // Indices sl@0: BOOST_UBLAS_INLINE sl@0: size_type index1 () const { sl@0: self_type &m = (*this) (); sl@0: return layout_type::index1 (it_ - m.begin1 ().it_, m.size1 (), m.size2 ()); sl@0: } sl@0: BOOST_UBLAS_INLINE sl@0: size_type index2 () const { sl@0: self_type &m = (*this) (); sl@0: return layout_type::index2 (it_ - m.begin1 ().it_, m.size1 (), m.size2 ()); sl@0: } sl@0: sl@0: // Assignment sl@0: BOOST_UBLAS_INLINE sl@0: iterator1 &operator = (const iterator1 &it) { sl@0: container_reference::assign (&it ()); sl@0: it_ = it.it_; sl@0: return *this; sl@0: } sl@0: sl@0: // Comparison sl@0: BOOST_UBLAS_INLINE sl@0: bool operator == (const iterator1 &it) const { sl@0: BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ()); sl@0: return it_ == it.it_; sl@0: } sl@0: BOOST_UBLAS_INLINE sl@0: bool operator < (const iterator1 &it) const { sl@0: BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ()); sl@0: return it_ < it.it_; sl@0: } sl@0: sl@0: private: sl@0: subiterator_type it_; sl@0: sl@0: friend class const_iterator1; sl@0: }; sl@0: #endif sl@0: sl@0: BOOST_UBLAS_INLINE sl@0: iterator1 begin1 () { sl@0: return find1 (0, 0, 0); sl@0: } sl@0: BOOST_UBLAS_INLINE sl@0: iterator1 end1 () { sl@0: return find1 (0, size1_, 0); sl@0: } sl@0: sl@0: #ifndef BOOST_UBLAS_USE_INDEXED_ITERATOR sl@0: class const_iterator2: sl@0: public container_const_reference, sl@0: public random_access_iterator_base { sl@0: public: sl@0: typedef typename matrix::value_type value_type; sl@0: typedef typename matrix::difference_type difference_type; sl@0: typedef typename matrix::const_reference reference; sl@0: typedef const typename matrix::pointer pointer; sl@0: sl@0: typedef const_iterator1 dual_iterator_type; sl@0: typedef const_reverse_iterator1 dual_reverse_iterator_type; sl@0: sl@0: // Construction and destruction sl@0: BOOST_UBLAS_INLINE sl@0: const_iterator2 (): sl@0: container_const_reference (), it_ () {} sl@0: BOOST_UBLAS_INLINE sl@0: const_iterator2 (const self_type &m, const const_subiterator_type &it): sl@0: container_const_reference (m), it_ (it) {} sl@0: BOOST_UBLAS_INLINE sl@0: const_iterator2 (const iterator2 &it): sl@0: container_const_reference (it ()), it_ (it.it_) {} sl@0: sl@0: // Arithmetic sl@0: BOOST_UBLAS_INLINE sl@0: const_iterator2 &operator ++ () { sl@0: layout_type::increment2 (it_, (*this) ().size1 (), (*this) ().size2 ()); sl@0: return *this; sl@0: } sl@0: BOOST_UBLAS_INLINE sl@0: const_iterator2 &operator -- () { sl@0: layout_type::decrement2 (it_, (*this) ().size1 (), (*this) ().size2 ()); sl@0: return *this; sl@0: } sl@0: BOOST_UBLAS_INLINE sl@0: const_iterator2 &operator += (difference_type n) { sl@0: it_ += n * layout_type::one2 ((*this) ().size1 (), (*this) ().size2 ()); sl@0: return *this; sl@0: } sl@0: BOOST_UBLAS_INLINE sl@0: const_iterator2 &operator -= (difference_type n) { sl@0: it_ -= n * layout_type::one2 ((*this) ().size1 (), (*this) ().size2 ()); sl@0: return *this; sl@0: } sl@0: BOOST_UBLAS_INLINE sl@0: difference_type operator - (const const_iterator2 &it) const { sl@0: BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ()); sl@0: return layout_type::distance2 (it_ - it.it_, (*this) ().size1 (), (*this) ().size2 ()); sl@0: } sl@0: sl@0: // Dereference sl@0: BOOST_UBLAS_INLINE sl@0: const_reference operator * () const { sl@0: BOOST_UBLAS_CHECK (index1 () < (*this) ().size1 (), bad_index ()); sl@0: BOOST_UBLAS_CHECK (index2 () < (*this) ().size2 (), bad_index ()); sl@0: return *it_; sl@0: } sl@0: BOOST_UBLAS_INLINE sl@0: const_reference operator [] (difference_type n) const { sl@0: return *(*this + n); sl@0: } sl@0: sl@0: #ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION sl@0: BOOST_UBLAS_INLINE sl@0: #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION sl@0: typename self_type:: sl@0: #endif sl@0: const_iterator1 begin () const { sl@0: const self_type &m = (*this) (); sl@0: return m.find1 (1, 0, index2 ()); sl@0: } sl@0: BOOST_UBLAS_INLINE sl@0: #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION sl@0: typename self_type:: sl@0: #endif sl@0: const_iterator1 end () const { sl@0: const self_type &m = (*this) (); sl@0: return m.find1 (1, m.size1 (), index2 ()); sl@0: } sl@0: BOOST_UBLAS_INLINE sl@0: #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION sl@0: typename self_type:: sl@0: #endif sl@0: const_reverse_iterator1 rbegin () const { sl@0: return const_reverse_iterator1 (end ()); sl@0: } sl@0: BOOST_UBLAS_INLINE sl@0: #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION sl@0: typename self_type:: sl@0: #endif sl@0: const_reverse_iterator1 rend () const { sl@0: return const_reverse_iterator1 (begin ()); sl@0: } sl@0: #endif sl@0: sl@0: // Indices sl@0: BOOST_UBLAS_INLINE sl@0: size_type index1 () const { sl@0: const self_type &m = (*this) (); sl@0: return layout_type::index1 (it_ - m.begin2 ().it_, m.size1 (), m.size2 ()); sl@0: } sl@0: BOOST_UBLAS_INLINE sl@0: size_type index2 () const { sl@0: const self_type &m = (*this) (); sl@0: return layout_type::index2 (it_ - m.begin2 ().it_, m.size1 (), m.size2 ()); sl@0: } sl@0: sl@0: // Assignment sl@0: BOOST_UBLAS_INLINE sl@0: const_iterator2 &operator = (const const_iterator2 &it) { sl@0: container_const_reference::assign (&it ()); sl@0: it_ = it.it_; sl@0: return *this; sl@0: } sl@0: sl@0: // Comparison sl@0: BOOST_UBLAS_INLINE sl@0: bool operator == (const const_iterator2 &it) const { sl@0: BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ()); sl@0: return it_ == it.it_; sl@0: } sl@0: BOOST_UBLAS_INLINE sl@0: bool operator < (const const_iterator2 &it) const { sl@0: BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ()); sl@0: return it_ < it.it_; sl@0: } sl@0: sl@0: private: sl@0: const_subiterator_type it_; sl@0: sl@0: friend class iterator2; sl@0: }; sl@0: #endif sl@0: sl@0: BOOST_UBLAS_INLINE sl@0: const_iterator2 begin2 () const { sl@0: return find2 (0, 0, 0); sl@0: } sl@0: BOOST_UBLAS_INLINE sl@0: const_iterator2 end2 () const { sl@0: return find2 (0, 0, size2_); sl@0: } sl@0: sl@0: #ifndef BOOST_UBLAS_USE_INDEXED_ITERATOR sl@0: class iterator2: sl@0: public container_reference, sl@0: public random_access_iterator_base { sl@0: public: sl@0: typedef typename matrix::value_type value_type; sl@0: typedef typename matrix::difference_type difference_type; sl@0: typedef typename matrix::reference reference; sl@0: typedef typename matrix::pointer pointer; sl@0: sl@0: typedef iterator1 dual_iterator_type; sl@0: typedef reverse_iterator1 dual_reverse_iterator_type; sl@0: sl@0: // Construction and destruction sl@0: BOOST_UBLAS_INLINE sl@0: iterator2 (): sl@0: container_reference (), it_ () {} sl@0: BOOST_UBLAS_INLINE sl@0: iterator2 (self_type &m, const subiterator_type &it): sl@0: container_reference (m), it_ (it) {} sl@0: sl@0: // Arithmetic sl@0: BOOST_UBLAS_INLINE sl@0: iterator2 &operator ++ () { sl@0: layout_type::increment2 (it_, (*this) ().size1 (), (*this) ().size2 ()); sl@0: return *this; sl@0: } sl@0: BOOST_UBLAS_INLINE sl@0: iterator2 &operator -- () { sl@0: layout_type::decrement2 (it_, (*this) ().size1 (), (*this) ().size2 ()); sl@0: return *this; sl@0: } sl@0: BOOST_UBLAS_INLINE sl@0: iterator2 &operator += (difference_type n) { sl@0: it_ += n * layout_type::one2 ((*this) ().size1 (), (*this) ().size2 ()); sl@0: return *this; sl@0: } sl@0: BOOST_UBLAS_INLINE sl@0: iterator2 &operator -= (difference_type n) { sl@0: it_ -= n * layout_type::one2 ((*this) ().size1 (), (*this) ().size2 ()); sl@0: return *this; sl@0: } sl@0: BOOST_UBLAS_INLINE sl@0: difference_type operator - (const iterator2 &it) const { sl@0: BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ()); sl@0: return layout_type::distance2 (it_ - it.it_, (*this) ().size1 (), (*this) ().size2 ()); sl@0: } sl@0: sl@0: // Dereference sl@0: BOOST_UBLAS_INLINE sl@0: reference operator * () const { sl@0: BOOST_UBLAS_CHECK (index1 () < (*this) ().size1 (), bad_index ()); sl@0: BOOST_UBLAS_CHECK (index2 () < (*this) ().size2 (), bad_index ()); sl@0: return *it_; sl@0: } sl@0: BOOST_UBLAS_INLINE sl@0: reference operator [] (difference_type n) const { sl@0: return *(*this + n); sl@0: } sl@0: sl@0: #ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION sl@0: BOOST_UBLAS_INLINE sl@0: #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION sl@0: typename self_type:: sl@0: #endif sl@0: iterator1 begin () const { sl@0: self_type &m = (*this) (); sl@0: return m.find1 (1, 0, index2 ()); sl@0: } sl@0: BOOST_UBLAS_INLINE sl@0: #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION sl@0: typename self_type:: sl@0: #endif sl@0: iterator1 end () const { sl@0: self_type &m = (*this) (); sl@0: return m.find1 (1, m.size1 (), index2 ()); sl@0: } sl@0: BOOST_UBLAS_INLINE sl@0: #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION sl@0: typename self_type:: sl@0: #endif sl@0: reverse_iterator1 rbegin () const { sl@0: return reverse_iterator1 (end ()); sl@0: } sl@0: BOOST_UBLAS_INLINE sl@0: #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION sl@0: typename self_type:: sl@0: #endif sl@0: reverse_iterator1 rend () const { sl@0: return reverse_iterator1 (begin ()); sl@0: } sl@0: #endif sl@0: sl@0: // Indices sl@0: BOOST_UBLAS_INLINE sl@0: size_type index1 () const { sl@0: self_type &m = (*this) (); sl@0: return layout_type::index1 (it_ - m.begin2 ().it_, m.size1 (), m.size2 ()); sl@0: } sl@0: BOOST_UBLAS_INLINE sl@0: size_type index2 () const { sl@0: self_type &m = (*this) (); sl@0: return layout_type::index2 (it_ - m.begin2 ().it_, m.size1 (), m.size2 ()); sl@0: } sl@0: sl@0: // Assignment sl@0: BOOST_UBLAS_INLINE sl@0: iterator2 &operator = (const iterator2 &it) { sl@0: container_reference::assign (&it ()); sl@0: it_ = it.it_; sl@0: return *this; sl@0: } sl@0: sl@0: // Comparison sl@0: BOOST_UBLAS_INLINE sl@0: bool operator == (const iterator2 &it) const { sl@0: BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ()); sl@0: return it_ == it.it_; sl@0: } sl@0: BOOST_UBLAS_INLINE sl@0: bool operator < (const iterator2 &it) const { sl@0: BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ()); sl@0: return it_ < it.it_; sl@0: } sl@0: sl@0: private: sl@0: subiterator_type it_; sl@0: sl@0: friend class const_iterator2; sl@0: }; sl@0: #endif sl@0: sl@0: BOOST_UBLAS_INLINE sl@0: iterator2 begin2 () { sl@0: return find2 (0, 0, 0); sl@0: } sl@0: BOOST_UBLAS_INLINE sl@0: iterator2 end2 () { sl@0: return find2 (0, 0, size2_); sl@0: } sl@0: sl@0: // Reverse iterators sl@0: sl@0: BOOST_UBLAS_INLINE sl@0: const_reverse_iterator1 rbegin1 () const { sl@0: return const_reverse_iterator1 (end1 ()); sl@0: } sl@0: BOOST_UBLAS_INLINE sl@0: const_reverse_iterator1 rend1 () const { sl@0: return const_reverse_iterator1 (begin1 ()); sl@0: } sl@0: sl@0: BOOST_UBLAS_INLINE sl@0: reverse_iterator1 rbegin1 () { sl@0: return reverse_iterator1 (end1 ()); sl@0: } sl@0: BOOST_UBLAS_INLINE sl@0: reverse_iterator1 rend1 () { sl@0: return reverse_iterator1 (begin1 ()); sl@0: } sl@0: sl@0: BOOST_UBLAS_INLINE sl@0: const_reverse_iterator2 rbegin2 () const { sl@0: return const_reverse_iterator2 (end2 ()); sl@0: } sl@0: BOOST_UBLAS_INLINE sl@0: const_reverse_iterator2 rend2 () const { sl@0: return const_reverse_iterator2 (begin2 ()); sl@0: } sl@0: sl@0: BOOST_UBLAS_INLINE sl@0: reverse_iterator2 rbegin2 () { sl@0: return reverse_iterator2 (end2 ()); sl@0: } sl@0: BOOST_UBLAS_INLINE sl@0: reverse_iterator2 rend2 () { sl@0: return reverse_iterator2 (begin2 ()); sl@0: } sl@0: sl@0: private: sl@0: size_type size1_; sl@0: size_type size2_; sl@0: array_type data_; sl@0: }; sl@0: sl@0: sl@0: // Bounded matrix class sl@0: template sl@0: class bounded_matrix: sl@0: public matrix > { sl@0: sl@0: typedef matrix > matrix_type; sl@0: public: sl@0: typedef typename matrix_type::size_type size_type; sl@0: static const size_type max_size1 = M; sl@0: static const size_type max_size2 = N; sl@0: sl@0: // Construction and destruction sl@0: BOOST_UBLAS_INLINE sl@0: bounded_matrix (): sl@0: matrix_type (M, N) {} sl@0: BOOST_UBLAS_INLINE sl@0: bounded_matrix (size_type size1, size_type size2): sl@0: matrix_type (size1, size2) {} sl@0: BOOST_UBLAS_INLINE sl@0: bounded_matrix (const bounded_matrix &m): sl@0: matrix_type (m) {} sl@0: template // Allow matrix > construction sl@0: BOOST_UBLAS_INLINE sl@0: bounded_matrix (const matrix &m): sl@0: matrix_type (m) {} sl@0: template sl@0: BOOST_UBLAS_INLINE sl@0: bounded_matrix (const matrix_expression &ae): sl@0: matrix_type (ae) {} sl@0: BOOST_UBLAS_INLINE sl@0: ~bounded_matrix () {} sl@0: sl@0: // Assignment sl@0: BOOST_UBLAS_INLINE sl@0: bounded_matrix &operator = (const bounded_matrix &m) { sl@0: matrix_type::operator = (m); sl@0: return *this; sl@0: } sl@0: template // Generic matrix assignment sl@0: BOOST_UBLAS_INLINE sl@0: bounded_matrix &operator = (const matrix &m) { sl@0: matrix_type::operator = (m); sl@0: return *this; sl@0: } sl@0: template // Container assignment without temporary sl@0: BOOST_UBLAS_INLINE sl@0: bounded_matrix &operator = (const matrix_container &m) { sl@0: matrix_type::operator = (m); sl@0: return *this; sl@0: } sl@0: template sl@0: BOOST_UBLAS_INLINE sl@0: bounded_matrix &operator = (const matrix_expression &ae) { sl@0: matrix_type::operator = (ae); sl@0: return *this; sl@0: } sl@0: }; sl@0: sl@0: sl@0: // Array based matrix class sl@0: template sl@0: class vector_of_vector: sl@0: public matrix_container > { sl@0: sl@0: typedef T *pointer; sl@0: typedef L layout_type; sl@0: typedef vector_of_vector self_type; sl@0: public: sl@0: #ifdef BOOST_UBLAS_ENABLE_PROXY_SHORTCUTS sl@0: using matrix_container::operator (); sl@0: #endif sl@0: typedef typename A::size_type size_type; sl@0: typedef typename A::difference_type difference_type; sl@0: typedef T value_type; sl@0: typedef const T &const_reference; sl@0: typedef T &reference; sl@0: typedef A array_type; sl@0: typedef const matrix_reference const_closure_type; sl@0: typedef matrix_reference closure_type; sl@0: typedef vector vector_temporary_type; sl@0: typedef self_type matrix_temporary_type; sl@0: typedef dense_tag storage_category; sl@0: // This could be better for performance, sl@0: // typedef typename unknown_orientation_tag orientation_category; sl@0: // but others depend on the orientation information... sl@0: typedef typename L::orientation_category orientation_category; sl@0: sl@0: // Construction and destruction sl@0: BOOST_UBLAS_INLINE sl@0: vector_of_vector (): sl@0: matrix_container (), sl@0: size1_ (0), size2_ (0), data_ (1) {} sl@0: BOOST_UBLAS_INLINE sl@0: vector_of_vector (size_type size1, size_type size2): sl@0: matrix_container (), sl@0: size1_ (size1), size2_ (size2), data_ (1) { sl@0: resize (size1, size2, true); sl@0: } sl@0: BOOST_UBLAS_INLINE sl@0: vector_of_vector (const vector_of_vector &m): sl@0: matrix_container (), sl@0: size1_ (m.size1_), size2_ (m.size2_), data_ (m.data_) {} sl@0: template sl@0: BOOST_UBLAS_INLINE sl@0: vector_of_vector (const matrix_expression &ae): sl@0: matrix_container (), sl@0: size1_ (ae ().size1 ()), size2_ (ae ().size2 ()), data_ (layout_type::size1 (size1_, size2_) + 1) { sl@0: for (size_type k = 0; k < layout_type::size1 (size1_, size2_); ++ k) sl@0: data ()[k].resize (layout_type::size2 (size1_, size2_)); sl@0: matrix_assign (*this, ae); sl@0: } sl@0: sl@0: // Accessors sl@0: BOOST_UBLAS_INLINE sl@0: size_type size1 () const { sl@0: return size1_; sl@0: } sl@0: BOOST_UBLAS_INLINE sl@0: size_type size2 () const { sl@0: return size2_; sl@0: } sl@0: sl@0: // Storage accessors sl@0: BOOST_UBLAS_INLINE sl@0: const array_type &data () const { sl@0: return data_; sl@0: } sl@0: BOOST_UBLAS_INLINE sl@0: array_type &data () { sl@0: return data_; sl@0: } sl@0: sl@0: // Resizing sl@0: BOOST_UBLAS_INLINE sl@0: void resize (size_type size1, size_type size2, bool preserve = true) { sl@0: size1_ = size1; sl@0: size2_ = size2; sl@0: if (preserve) sl@0: data ().resize (layout_type::size1 (size1, size2) + 1, typename array_type::value_type ()); sl@0: else sl@0: data ().resize (layout_type::size1 (size1, size2) + 1); sl@0: for (size_type k = 0; k < layout_type::size1 (size1, size2); ++ k) { sl@0: if (preserve) sl@0: data () [k].resize (layout_type::size2 (size1, size2), value_type ()); sl@0: else sl@0: data () [k].resize (layout_type::size2 (size1, size2)); sl@0: } sl@0: } sl@0: sl@0: // Element access sl@0: BOOST_UBLAS_INLINE sl@0: const_reference operator () (size_type i, size_type j) const { sl@0: return data () [layout_type::element1 (i, size1_, j, size2_)] [layout_type::element2 (i, size1_, j, size2_)]; sl@0: } sl@0: BOOST_UBLAS_INLINE sl@0: reference at_element (size_type i, size_type j) { sl@0: return data () [layout_type::element1 (i, size1_, j, size2_)] [layout_type::element2 (i, size1_, j, size2_)]; sl@0: } sl@0: BOOST_UBLAS_INLINE sl@0: reference operator () (size_type i, size_type j) { sl@0: return at_element (i, j); sl@0: } sl@0: sl@0: // Element assignment sl@0: BOOST_UBLAS_INLINE sl@0: reference insert_element (size_type i, size_type j, const_reference t) { sl@0: return (at_element (i, j) = t); sl@0: } sl@0: BOOST_UBLAS_INLINE sl@0: void erase_element (size_type i, size_type j) { sl@0: at_element (i, j) = value_type/*zero*/(); sl@0: } sl@0: sl@0: // Zeroing sl@0: BOOST_UBLAS_INLINE sl@0: void clear () { sl@0: for (size_type k = 0; k < layout_type::size1 (size1_, size2_); ++ k) sl@0: std::fill (data () [k].begin (), data () [k].end (), value_type/*zero*/()); sl@0: } sl@0: sl@0: // Assignment sl@0: BOOST_UBLAS_INLINE sl@0: vector_of_vector &operator = (const vector_of_vector &m) { sl@0: size1_ = m.size1_; sl@0: size2_ = m.size2_; sl@0: data () = m.data (); sl@0: return *this; sl@0: } sl@0: BOOST_UBLAS_INLINE sl@0: vector_of_vector &assign_temporary (vector_of_vector &m) { sl@0: swap (m); sl@0: return *this; sl@0: } sl@0: template sl@0: BOOST_UBLAS_INLINE sl@0: vector_of_vector &operator = (const matrix_expression &ae) { sl@0: self_type temporary (ae); sl@0: return assign_temporary (temporary); sl@0: } sl@0: template // Container assignment without temporary sl@0: BOOST_UBLAS_INLINE sl@0: vector_of_vector &operator = (const matrix_container &m) { sl@0: resize (m ().size1 (), m ().size2 (), false); sl@0: assign (m); sl@0: return *this; sl@0: } sl@0: template sl@0: BOOST_UBLAS_INLINE sl@0: vector_of_vector &assign (const matrix_expression &ae) { sl@0: matrix_assign (*this, ae); sl@0: return *this; sl@0: } sl@0: template sl@0: BOOST_UBLAS_INLINE sl@0: vector_of_vector& operator += (const matrix_expression &ae) { sl@0: self_type temporary (*this + ae); sl@0: return assign_temporary (temporary); sl@0: } sl@0: template // Container assignment without temporary sl@0: BOOST_UBLAS_INLINE sl@0: vector_of_vector &operator += (const matrix_container &m) { sl@0: plus_assign (m); sl@0: return *this; sl@0: } sl@0: template sl@0: BOOST_UBLAS_INLINE sl@0: vector_of_vector &plus_assign (const matrix_expression &ae) { sl@0: matrix_assign (*this, ae); sl@0: return *this; sl@0: } sl@0: template sl@0: BOOST_UBLAS_INLINE sl@0: vector_of_vector& operator -= (const matrix_expression &ae) { sl@0: self_type temporary (*this - ae); sl@0: return assign_temporary (temporary); sl@0: } sl@0: template // Container assignment without temporary sl@0: BOOST_UBLAS_INLINE sl@0: vector_of_vector &operator -= (const matrix_container &m) { sl@0: minus_assign (m); sl@0: return *this; sl@0: } sl@0: template sl@0: BOOST_UBLAS_INLINE sl@0: vector_of_vector &minus_assign (const matrix_expression &ae) { sl@0: matrix_assign (*this, ae); sl@0: return *this; sl@0: } sl@0: template sl@0: BOOST_UBLAS_INLINE sl@0: vector_of_vector& operator *= (const AT &at) { sl@0: matrix_assign_scalar (*this, at); sl@0: return *this; sl@0: } sl@0: template sl@0: BOOST_UBLAS_INLINE sl@0: vector_of_vector& operator /= (const AT &at) { sl@0: matrix_assign_scalar (*this, at); sl@0: return *this; sl@0: } sl@0: sl@0: // Swapping sl@0: BOOST_UBLAS_INLINE sl@0: void swap (vector_of_vector &m) { sl@0: if (this != &m) { sl@0: std::swap (size1_, m.size1_); sl@0: std::swap (size2_, m.size2_); sl@0: data ().swap (m.data ()); sl@0: } sl@0: } sl@0: BOOST_UBLAS_INLINE sl@0: friend void swap (vector_of_vector &m1, vector_of_vector &m2) { sl@0: m1.swap (m2); sl@0: } sl@0: sl@0: // Iterator types sl@0: private: sl@0: // Use the vector iterator sl@0: typedef typename A::value_type::const_iterator const_subiterator_type; sl@0: typedef typename A::value_type::iterator subiterator_type; sl@0: public: sl@0: #ifdef BOOST_UBLAS_USE_INDEXED_ITERATOR sl@0: typedef indexed_iterator1 iterator1; sl@0: typedef indexed_iterator2 iterator2; sl@0: typedef indexed_const_iterator1 const_iterator1; sl@0: typedef indexed_const_iterator2 const_iterator2; sl@0: #else sl@0: class const_iterator1; sl@0: class iterator1; sl@0: class const_iterator2; sl@0: class iterator2; sl@0: #endif sl@0: typedef reverse_iterator_base1 const_reverse_iterator1; sl@0: typedef reverse_iterator_base1 reverse_iterator1; sl@0: typedef reverse_iterator_base2 const_reverse_iterator2; sl@0: typedef reverse_iterator_base2 reverse_iterator2; sl@0: sl@0: // Element lookup sl@0: BOOST_UBLAS_INLINE sl@0: const_iterator1 find1 (int /*rank*/, size_type i, size_type j) const { sl@0: #ifdef BOOST_UBLAS_USE_INDEXED_ITERATOR sl@0: return const_iterator1 (*this, i, j); sl@0: #else sl@0: return const_iterator1 (*this, i, j, data () [layout_type::address1 (i, size1_, j, size2_)].begin () + layout_type::address2 (i, size1_, j, size2_)); sl@0: #endif sl@0: } sl@0: BOOST_UBLAS_INLINE sl@0: iterator1 find1 (int /*rank*/, size_type i, size_type j) { sl@0: #ifdef BOOST_UBLAS_USE_INDEXED_ITERATOR sl@0: return iterator1 (*this, i, j); sl@0: #else sl@0: return iterator1 (*this, i, j, data () [layout_type::address1 (i, size1_, j, size2_)].begin () + layout_type::address2 (i, size1_, j, size2_)); sl@0: #endif sl@0: } sl@0: BOOST_UBLAS_INLINE sl@0: const_iterator2 find2 (int /*rank*/, size_type i, size_type j) const { sl@0: #ifdef BOOST_UBLAS_USE_INDEXED_ITERATOR sl@0: return const_iterator2 (*this, i, j); sl@0: #else sl@0: return const_iterator2 (*this, i, j, data () [layout_type::address1 (i, size1_, j, size2_)].begin () + layout_type::address2 (i, size1_, j, size2_)); sl@0: #endif sl@0: } sl@0: BOOST_UBLAS_INLINE sl@0: iterator2 find2 (int /*rank*/, size_type i, size_type j) { sl@0: #ifdef BOOST_UBLAS_USE_INDEXED_ITERATOR sl@0: return iterator2 (*this, i, j); sl@0: #else sl@0: return iterator2 (*this, i, j, data () [layout_type::address1 (i, size1_, j, size2_)].begin () + layout_type::address2 (i, size1_, j, size2_)); sl@0: #endif sl@0: } sl@0: sl@0: sl@0: #ifndef BOOST_UBLAS_USE_INDEXED_ITERATOR sl@0: class const_iterator1: sl@0: public container_const_reference, sl@0: public random_access_iterator_base { sl@0: public: sl@0: typedef typename vector_of_vector::value_type value_type; sl@0: typedef typename vector_of_vector::difference_type difference_type; sl@0: typedef typename vector_of_vector::const_reference reference; sl@0: typedef const typename vector_of_vector::pointer pointer; sl@0: sl@0: typedef const_iterator2 dual_iterator_type; sl@0: typedef const_reverse_iterator2 dual_reverse_iterator_type; sl@0: sl@0: // Construction and destruction sl@0: BOOST_UBLAS_INLINE sl@0: const_iterator1 (): sl@0: container_const_reference (), i_ (), j_ (), it_ () {} sl@0: BOOST_UBLAS_INLINE sl@0: const_iterator1 (const self_type &m, size_type i, size_type j, const const_subiterator_type &it): sl@0: container_const_reference (m), i_ (i), j_ (j), it_ (it) {} sl@0: BOOST_UBLAS_INLINE sl@0: const_iterator1 (const iterator1 &it): sl@0: container_const_reference (it ()), i_ (it.i_), j_ (it.j_), it_ (it.it_) {} sl@0: sl@0: // Arithmetic sl@0: BOOST_UBLAS_INLINE sl@0: const_iterator1 &operator ++ () { sl@0: ++ i_; sl@0: const self_type &m = (*this) (); sl@0: if (layout_type::fast1 ()) sl@0: ++ it_; sl@0: else sl@0: it_ = m.find1 (1, i_, j_).it_; sl@0: return *this; sl@0: } sl@0: BOOST_UBLAS_INLINE sl@0: const_iterator1 &operator -- () { sl@0: -- i_; sl@0: const self_type &m = (*this) (); sl@0: if (layout_type::fast1 ()) sl@0: -- it_; sl@0: else sl@0: it_ = m.find1 (1, i_, j_).it_; sl@0: return *this; sl@0: } sl@0: BOOST_UBLAS_INLINE sl@0: const_iterator1 &operator += (difference_type n) { sl@0: i_ += n; sl@0: const self_type &m = (*this) (); sl@0: it_ = m.find1 (1, i_, j_).it_; sl@0: return *this; sl@0: } sl@0: BOOST_UBLAS_INLINE sl@0: const_iterator1 &operator -= (difference_type n) { sl@0: i_ -= n; sl@0: const self_type &m = (*this) (); sl@0: it_ = m.find1 (1, i_, j_).it_; sl@0: return *this; sl@0: } sl@0: BOOST_UBLAS_INLINE sl@0: difference_type operator - (const const_iterator1 &it) const { sl@0: BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ()); sl@0: BOOST_UBLAS_CHECK (index2 () == it.index2 (), bad_index ()); sl@0: return index1 () - it.index1 (); sl@0: } sl@0: sl@0: // Dereference sl@0: BOOST_UBLAS_INLINE sl@0: const_reference operator * () const { sl@0: BOOST_UBLAS_CHECK (index1 () < (*this) ().size1 (), bad_index ()); sl@0: BOOST_UBLAS_CHECK (index2 () < (*this) ().size2 (), bad_index ()); sl@0: return *it_; sl@0: } sl@0: BOOST_UBLAS_INLINE sl@0: const_reference operator [] (difference_type n) const { sl@0: return *(*this + n); sl@0: } sl@0: sl@0: #ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION sl@0: BOOST_UBLAS_INLINE sl@0: #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION sl@0: typename self_type:: sl@0: #endif sl@0: const_iterator2 begin () const { sl@0: const self_type &m = (*this) (); sl@0: return m.find2 (1, index1 (), 0); sl@0: } sl@0: BOOST_UBLAS_INLINE sl@0: #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION sl@0: typename self_type:: sl@0: #endif sl@0: const_iterator2 end () const { sl@0: const self_type &m = (*this) (); sl@0: return m.find2 (1, index1 (), m.size2 ()); sl@0: } sl@0: BOOST_UBLAS_INLINE sl@0: #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION sl@0: typename self_type:: sl@0: #endif sl@0: const_reverse_iterator2 rbegin () const { sl@0: return const_reverse_iterator2 (end ()); sl@0: } sl@0: BOOST_UBLAS_INLINE sl@0: #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION sl@0: typename self_type:: sl@0: #endif sl@0: const_reverse_iterator2 rend () const { sl@0: return const_reverse_iterator2 (begin ()); sl@0: } sl@0: #endif sl@0: sl@0: // Indices sl@0: BOOST_UBLAS_INLINE sl@0: size_type index1 () const { sl@0: return i_; sl@0: } sl@0: BOOST_UBLAS_INLINE sl@0: size_type index2 () const { sl@0: return j_; sl@0: } sl@0: sl@0: // Assignment sl@0: BOOST_UBLAS_INLINE sl@0: const_iterator1 &operator = (const const_iterator1 &it) { sl@0: container_const_reference::assign (&it ()); sl@0: it_ = it.it_; sl@0: return *this; sl@0: } sl@0: sl@0: // Comparison sl@0: BOOST_UBLAS_INLINE sl@0: bool operator == (const const_iterator1 &it) const { sl@0: BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ()); sl@0: BOOST_UBLAS_CHECK (index2 () == it.index2 (), bad_index ()); sl@0: return it_ == it.it_; sl@0: } sl@0: BOOST_UBLAS_INLINE sl@0: bool operator < (const const_iterator1 &it) const { sl@0: BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ()); sl@0: BOOST_UBLAS_CHECK (index2 () == it.index2 (), bad_index ()); sl@0: return it_ < it.it_; sl@0: } sl@0: sl@0: private: sl@0: size_type i_; sl@0: size_type j_; sl@0: const_subiterator_type it_; sl@0: sl@0: friend class iterator1; sl@0: }; sl@0: #endif sl@0: sl@0: BOOST_UBLAS_INLINE sl@0: const_iterator1 begin1 () const { sl@0: return find1 (0, 0, 0); sl@0: } sl@0: BOOST_UBLAS_INLINE sl@0: const_iterator1 end1 () const { sl@0: return find1 (0, size1_, 0); sl@0: } sl@0: sl@0: #ifndef BOOST_UBLAS_USE_INDEXED_ITERATOR sl@0: class iterator1: sl@0: public container_reference, sl@0: public random_access_iterator_base { sl@0: public: sl@0: typedef typename vector_of_vector::value_type value_type; sl@0: typedef typename vector_of_vector::difference_type difference_type; sl@0: typedef typename vector_of_vector::reference reference; sl@0: typedef typename vector_of_vector::pointer pointer; sl@0: sl@0: typedef iterator2 dual_iterator_type; sl@0: typedef reverse_iterator2 dual_reverse_iterator_type; sl@0: sl@0: // Construction and destruction sl@0: BOOST_UBLAS_INLINE sl@0: iterator1 (): sl@0: container_reference (), i_ (), j_ (), it_ () {} sl@0: BOOST_UBLAS_INLINE sl@0: iterator1 (self_type &m, size_type i, size_type j, const subiterator_type &it): sl@0: container_reference (m), i_ (i), j_ (j), it_ (it) {} sl@0: sl@0: // Arithmetic sl@0: BOOST_UBLAS_INLINE sl@0: iterator1 &operator ++ () { sl@0: ++ i_; sl@0: self_type &m = (*this) (); sl@0: if (layout_type::fast1 ()) sl@0: ++ it_; sl@0: else sl@0: it_ = m.find1 (1, i_, j_).it_; sl@0: return *this; sl@0: } sl@0: BOOST_UBLAS_INLINE sl@0: iterator1 &operator -- () { sl@0: -- i_; sl@0: self_type &m = (*this) (); sl@0: if (layout_type::fast1 ()) sl@0: -- it_; sl@0: else sl@0: it_ = m.find1 (1, i_, j_).it_; sl@0: return *this; sl@0: } sl@0: BOOST_UBLAS_INLINE sl@0: iterator1 &operator += (difference_type n) { sl@0: i_ += n; sl@0: self_type &m = (*this) (); sl@0: it_ = m.find1 (1, i_, j_).it_; sl@0: return *this; sl@0: } sl@0: BOOST_UBLAS_INLINE sl@0: iterator1 &operator -= (difference_type n) { sl@0: i_ -= n; sl@0: self_type &m = (*this) (); sl@0: it_ = m.find1 (1, i_, j_).it_; sl@0: return *this; sl@0: } sl@0: BOOST_UBLAS_INLINE sl@0: difference_type operator - (const iterator1 &it) const { sl@0: BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ()); sl@0: BOOST_UBLAS_CHECK (index2 () == it.index2 (), bad_index ()); sl@0: return index1 () - it.index1 (); sl@0: } sl@0: sl@0: // Dereference sl@0: BOOST_UBLAS_INLINE sl@0: reference operator * () const { sl@0: BOOST_UBLAS_CHECK (index1 () < (*this) ().size1 (), bad_index ()); sl@0: BOOST_UBLAS_CHECK (index2 () < (*this) ().size2 (), bad_index ()); sl@0: return *it_; sl@0: } sl@0: BOOST_UBLAS_INLINE sl@0: reference operator [] (difference_type n) const { sl@0: return *(*this + n); sl@0: } sl@0: sl@0: #ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION sl@0: BOOST_UBLAS_INLINE sl@0: #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION sl@0: typename self_type:: sl@0: #endif sl@0: iterator2 begin () const { sl@0: self_type &m = (*this) (); sl@0: return m.find2 (1, index1 (), 0); sl@0: } sl@0: BOOST_UBLAS_INLINE sl@0: #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION sl@0: typename self_type:: sl@0: #endif sl@0: iterator2 end () const { sl@0: self_type &m = (*this) (); sl@0: return m.find2 (1, index1 (), m.size2 ()); sl@0: } sl@0: BOOST_UBLAS_INLINE sl@0: #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION sl@0: typename self_type:: sl@0: #endif sl@0: reverse_iterator2 rbegin () const { sl@0: return reverse_iterator2 (end ()); sl@0: } sl@0: BOOST_UBLAS_INLINE sl@0: #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION sl@0: typename self_type:: sl@0: #endif sl@0: reverse_iterator2 rend () const { sl@0: return reverse_iterator2 (begin ()); sl@0: } sl@0: #endif sl@0: sl@0: // Indices sl@0: BOOST_UBLAS_INLINE sl@0: size_type index1 () const { sl@0: return i_; sl@0: } sl@0: BOOST_UBLAS_INLINE sl@0: size_type index2 () const { sl@0: return j_; sl@0: } sl@0: sl@0: // Assignment sl@0: BOOST_UBLAS_INLINE sl@0: iterator1 &operator = (const iterator1 &it) { sl@0: container_reference::assign (&it ()); sl@0: it_ = it.it_; sl@0: return *this; sl@0: } sl@0: sl@0: // Comparison sl@0: BOOST_UBLAS_INLINE sl@0: bool operator == (const iterator1 &it) const { sl@0: BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ()); sl@0: BOOST_UBLAS_CHECK (index2 () == it.index2 (), bad_index ()); sl@0: return it_ == it.it_; sl@0: } sl@0: BOOST_UBLAS_INLINE sl@0: bool operator < (const iterator1 &it) const { sl@0: BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ()); sl@0: BOOST_UBLAS_CHECK (index2 () == it.index2 (), bad_index ()); sl@0: return it_ < it.it_; sl@0: } sl@0: sl@0: private: sl@0: size_type i_; sl@0: size_type j_; sl@0: subiterator_type it_; sl@0: sl@0: friend class const_iterator1; sl@0: }; sl@0: #endif sl@0: sl@0: BOOST_UBLAS_INLINE sl@0: iterator1 begin1 () { sl@0: return find1 (0, 0, 0); sl@0: } sl@0: BOOST_UBLAS_INLINE sl@0: iterator1 end1 () { sl@0: return find1 (0, size1_, 0); sl@0: } sl@0: sl@0: #ifndef BOOST_UBLAS_USE_INDEXED_ITERATOR sl@0: class const_iterator2: sl@0: public container_const_reference, sl@0: public random_access_iterator_base { sl@0: public: sl@0: typedef typename vector_of_vector::value_type value_type; sl@0: typedef typename vector_of_vector::difference_type difference_type; sl@0: typedef typename vector_of_vector::const_reference reference; sl@0: typedef const typename vector_of_vector::pointer pointer; sl@0: sl@0: typedef const_iterator1 dual_iterator_type; sl@0: typedef const_reverse_iterator1 dual_reverse_iterator_type; sl@0: sl@0: // Construction and destruction sl@0: BOOST_UBLAS_INLINE sl@0: const_iterator2 (): sl@0: container_const_reference (), i_ (), j_ (), it_ () {} sl@0: BOOST_UBLAS_INLINE sl@0: const_iterator2 (const self_type &m, size_type i, size_type j, const const_subiterator_type &it): sl@0: container_const_reference (m), i_ (i), j_ (j), it_ (it) {} sl@0: BOOST_UBLAS_INLINE sl@0: const_iterator2 (const iterator2 &it): sl@0: container_const_reference (it ()), i_ (it.i_), j_ (it.j_), it_ (it.it_) {} sl@0: sl@0: // Arithmetic sl@0: BOOST_UBLAS_INLINE sl@0: const_iterator2 &operator ++ () { sl@0: ++ j_; sl@0: const self_type &m = (*this) (); sl@0: if (layout_type::fast2 ()) sl@0: ++ it_; sl@0: else sl@0: it_ = m.find2 (1, i_, j_).it_; sl@0: return *this; sl@0: } sl@0: BOOST_UBLAS_INLINE sl@0: const_iterator2 &operator -- () { sl@0: -- j_; sl@0: const self_type &m = (*this) (); sl@0: if (layout_type::fast2 ()) sl@0: -- it_; sl@0: else sl@0: it_ = m.find2 (1, i_, j_).it_; sl@0: return *this; sl@0: } sl@0: BOOST_UBLAS_INLINE sl@0: const_iterator2 &operator += (difference_type n) { sl@0: j_ += n; sl@0: const self_type &m = (*this) (); sl@0: it_ = m.find2 (1, i_, j_).it_; sl@0: return *this; sl@0: } sl@0: BOOST_UBLAS_INLINE sl@0: const_iterator2 &operator -= (difference_type n) { sl@0: j_ -= n; sl@0: const self_type &m = (*this) (); sl@0: it_ = m.find2 (1, i_, j_).it_; sl@0: return *this; sl@0: } sl@0: BOOST_UBLAS_INLINE sl@0: difference_type operator - (const const_iterator2 &it) const { sl@0: BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ()); sl@0: BOOST_UBLAS_CHECK (index1 () == it.index1 (), bad_index ()); sl@0: return index2 () - it.index2 (); sl@0: } sl@0: sl@0: // Dereference sl@0: BOOST_UBLAS_INLINE sl@0: const_reference operator * () const { sl@0: BOOST_UBLAS_CHECK (index1 () < (*this) ().size1 (), bad_index ()); sl@0: BOOST_UBLAS_CHECK (index2 () < (*this) ().size2 (), bad_index ()); sl@0: return *it_; sl@0: } sl@0: BOOST_UBLAS_INLINE sl@0: const_reference operator [] (difference_type n) const { sl@0: return *(*this + n); sl@0: } sl@0: sl@0: #ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION sl@0: BOOST_UBLAS_INLINE sl@0: #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION sl@0: typename self_type:: sl@0: #endif sl@0: const_iterator1 begin () const { sl@0: const self_type &m = (*this) (); sl@0: return m.find1 (1, 0, index2 ()); sl@0: } sl@0: BOOST_UBLAS_INLINE sl@0: #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION sl@0: typename self_type:: sl@0: #endif sl@0: const_iterator1 end () const { sl@0: const self_type &m = (*this) (); sl@0: return m.find1 (1, m.size1 (), index2 ()); sl@0: } sl@0: BOOST_UBLAS_INLINE sl@0: #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION sl@0: typename self_type:: sl@0: #endif sl@0: const_reverse_iterator1 rbegin () const { sl@0: return const_reverse_iterator1 (end ()); sl@0: } sl@0: BOOST_UBLAS_INLINE sl@0: #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION sl@0: typename self_type:: sl@0: #endif sl@0: const_reverse_iterator1 rend () const { sl@0: return const_reverse_iterator1 (begin ()); sl@0: } sl@0: #endif sl@0: sl@0: // Indices sl@0: BOOST_UBLAS_INLINE sl@0: size_type index1 () const { sl@0: return i_; sl@0: } sl@0: BOOST_UBLAS_INLINE sl@0: size_type index2 () const { sl@0: return j_; sl@0: } sl@0: sl@0: // Assignment sl@0: BOOST_UBLAS_INLINE sl@0: const_iterator2 &operator = (const const_iterator2 &it) { sl@0: container_const_reference::assign (&it ()); sl@0: it_ = it.it_; sl@0: return *this; sl@0: } sl@0: sl@0: // Comparison sl@0: BOOST_UBLAS_INLINE sl@0: bool operator == (const const_iterator2 &it) const { sl@0: BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ()); sl@0: BOOST_UBLAS_CHECK (index1 () == it.index1 (), bad_index ()); sl@0: return it_ == it.it_; sl@0: } sl@0: BOOST_UBLAS_INLINE sl@0: bool operator < (const const_iterator2 &it) const { sl@0: BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ()); sl@0: BOOST_UBLAS_CHECK (index1 () == it.index1 (), bad_index ()); sl@0: return it_ < it.it_; sl@0: } sl@0: sl@0: private: sl@0: size_type i_; sl@0: size_type j_; sl@0: const_subiterator_type it_; sl@0: sl@0: friend class iterator2; sl@0: }; sl@0: #endif sl@0: sl@0: BOOST_UBLAS_INLINE sl@0: const_iterator2 begin2 () const { sl@0: return find2 (0, 0, 0); sl@0: } sl@0: BOOST_UBLAS_INLINE sl@0: const_iterator2 end2 () const { sl@0: return find2 (0, 0, size2_); sl@0: } sl@0: sl@0: #ifndef BOOST_UBLAS_USE_INDEXED_ITERATOR sl@0: class iterator2: sl@0: public container_reference, sl@0: public random_access_iterator_base { sl@0: public: sl@0: typedef typename vector_of_vector::value_type value_type; sl@0: typedef typename vector_of_vector::difference_type difference_type; sl@0: typedef typename vector_of_vector::reference reference; sl@0: typedef typename vector_of_vector::pointer pointer; sl@0: sl@0: typedef iterator1 dual_iterator_type; sl@0: typedef reverse_iterator1 dual_reverse_iterator_type; sl@0: sl@0: // Construction and destruction sl@0: BOOST_UBLAS_INLINE sl@0: iterator2 (): sl@0: container_reference (), i_ (), j_ (), it_ () {} sl@0: BOOST_UBLAS_INLINE sl@0: iterator2 (self_type &m, size_type i, size_type j, const subiterator_type &it): sl@0: container_reference (m), i_ (i), j_ (j), it_ (it) {} sl@0: sl@0: // Arithmetic sl@0: BOOST_UBLAS_INLINE sl@0: iterator2 &operator ++ () { sl@0: ++ j_; sl@0: self_type &m = (*this) (); sl@0: if (layout_type::fast2 ()) sl@0: ++ it_; sl@0: else sl@0: it_ = m.find2 (1, i_, j_).it_; sl@0: return *this; sl@0: } sl@0: BOOST_UBLAS_INLINE sl@0: iterator2 &operator -- () { sl@0: -- j_; sl@0: self_type &m = (*this) (); sl@0: if (layout_type::fast2 ()) sl@0: -- it_; sl@0: else sl@0: it_ = m.find2 (1, i_, j_).it_; sl@0: return *this; sl@0: } sl@0: BOOST_UBLAS_INLINE sl@0: iterator2 &operator += (difference_type n) { sl@0: j_ += n; sl@0: self_type &m = (*this) (); sl@0: it_ = m.find2 (1, i_, j_).it_; sl@0: return *this; sl@0: } sl@0: BOOST_UBLAS_INLINE sl@0: iterator2 &operator -= (difference_type n) { sl@0: j_ -= n; sl@0: self_type &m = (*this) (); sl@0: it_ = m.find2 (1, i_, j_).it_; sl@0: return *this; sl@0: } sl@0: BOOST_UBLAS_INLINE sl@0: difference_type operator - (const iterator2 &it) const { sl@0: BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ()); sl@0: BOOST_UBLAS_CHECK (index1 () == it.index1 (), bad_index ()); sl@0: return index2 () - it.index2 (); sl@0: } sl@0: sl@0: // Dereference sl@0: BOOST_UBLAS_INLINE sl@0: reference operator * () const { sl@0: BOOST_UBLAS_CHECK (index1 () < (*this) ().size1 (), bad_index ()); sl@0: BOOST_UBLAS_CHECK (index2 () < (*this) ().size2 (), bad_index ()); sl@0: return *it_; sl@0: } sl@0: BOOST_UBLAS_INLINE sl@0: reference operator [] (difference_type n) const { sl@0: return *(*this + n); sl@0: } sl@0: sl@0: #ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION sl@0: BOOST_UBLAS_INLINE sl@0: #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION sl@0: typename self_type:: sl@0: #endif sl@0: iterator1 begin () const { sl@0: self_type &m = (*this) (); sl@0: return m.find1 (1, 0, index2 ()); sl@0: } sl@0: BOOST_UBLAS_INLINE sl@0: #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION sl@0: typename self_type:: sl@0: #endif sl@0: iterator1 end () const { sl@0: self_type &m = (*this) (); sl@0: return m.find1 (1, m.size1 (), index2 ()); sl@0: } sl@0: BOOST_UBLAS_INLINE sl@0: #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION sl@0: typename self_type:: sl@0: #endif sl@0: reverse_iterator1 rbegin () const { sl@0: return reverse_iterator1 (end ()); sl@0: } sl@0: BOOST_UBLAS_INLINE sl@0: #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION sl@0: typename self_type:: sl@0: #endif sl@0: reverse_iterator1 rend () const { sl@0: return reverse_iterator1 (begin ()); sl@0: } sl@0: #endif sl@0: sl@0: // Indices sl@0: BOOST_UBLAS_INLINE sl@0: size_type index1 () const { sl@0: return i_; sl@0: } sl@0: BOOST_UBLAS_INLINE sl@0: size_type index2 () const { sl@0: return j_; sl@0: } sl@0: sl@0: // Assignment sl@0: BOOST_UBLAS_INLINE sl@0: iterator2 &operator = (const iterator2 &it) { sl@0: container_reference::assign (&it ()); sl@0: it_ = it.it_; sl@0: return *this; sl@0: } sl@0: sl@0: // Comparison sl@0: BOOST_UBLAS_INLINE sl@0: bool operator == (const iterator2 &it) const { sl@0: BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ()); sl@0: BOOST_UBLAS_CHECK (index1 () == it.index1 (), bad_index ()); sl@0: return it_ == it.it_; sl@0: } sl@0: BOOST_UBLAS_INLINE sl@0: bool operator < (const iterator2 &it) const { sl@0: BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ()); sl@0: BOOST_UBLAS_CHECK (index1 () == it.index1 (), bad_index ()); sl@0: return it_ < it.it_; sl@0: } sl@0: sl@0: private: sl@0: size_type i_; sl@0: size_type j_; sl@0: subiterator_type it_; sl@0: sl@0: friend class const_iterator2; sl@0: }; sl@0: #endif sl@0: sl@0: BOOST_UBLAS_INLINE sl@0: iterator2 begin2 () { sl@0: return find2 (0, 0, 0); sl@0: } sl@0: BOOST_UBLAS_INLINE sl@0: iterator2 end2 () { sl@0: return find2 (0, 0, size2_); sl@0: } sl@0: sl@0: // Reverse iterators sl@0: sl@0: BOOST_UBLAS_INLINE sl@0: const_reverse_iterator1 rbegin1 () const { sl@0: return const_reverse_iterator1 (end1 ()); sl@0: } sl@0: BOOST_UBLAS_INLINE sl@0: const_reverse_iterator1 rend1 () const { sl@0: return const_reverse_iterator1 (begin1 ()); sl@0: } sl@0: sl@0: BOOST_UBLAS_INLINE sl@0: reverse_iterator1 rbegin1 () { sl@0: return reverse_iterator1 (end1 ()); sl@0: } sl@0: BOOST_UBLAS_INLINE sl@0: reverse_iterator1 rend1 () { sl@0: return reverse_iterator1 (begin1 ()); sl@0: } sl@0: sl@0: BOOST_UBLAS_INLINE sl@0: const_reverse_iterator2 rbegin2 () const { sl@0: return const_reverse_iterator2 (end2 ()); sl@0: } sl@0: BOOST_UBLAS_INLINE sl@0: const_reverse_iterator2 rend2 () const { sl@0: return const_reverse_iterator2 (begin2 ()); sl@0: } sl@0: sl@0: BOOST_UBLAS_INLINE sl@0: reverse_iterator2 rbegin2 () { sl@0: return reverse_iterator2 (end2 ()); sl@0: } sl@0: BOOST_UBLAS_INLINE sl@0: reverse_iterator2 rend2 () { sl@0: return reverse_iterator2 (begin2 ()); sl@0: } sl@0: sl@0: private: sl@0: size_type size1_; sl@0: size_type size2_; sl@0: array_type data_; sl@0: }; sl@0: sl@0: sl@0: // Zero matrix class sl@0: template sl@0: class zero_matrix: sl@0: public matrix_container > { sl@0: sl@0: typedef const T *const_pointer; sl@0: typedef zero_matrix self_type; sl@0: public: sl@0: #ifdef BOOST_UBLAS_ENABLE_PROXY_SHORTCUTS sl@0: using matrix_container::operator (); sl@0: #endif sl@0: typedef std::size_t size_type; sl@0: typedef std::ptrdiff_t difference_type; sl@0: typedef T value_type; sl@0: typedef const T &const_reference; sl@0: typedef T &reference; sl@0: typedef const matrix_reference const_closure_type; sl@0: typedef matrix_reference closure_type; sl@0: typedef sparse_tag storage_category; sl@0: typedef unknown_orientation_tag orientation_category; sl@0: sl@0: // Construction and destruction sl@0: BOOST_UBLAS_INLINE sl@0: zero_matrix (): sl@0: matrix_container (), sl@0: size1_ (0), size2_ (0) {} sl@0: BOOST_UBLAS_INLINE sl@0: zero_matrix (size_type size): sl@0: matrix_container (), sl@0: size1_ (size), size2_ (size) {} sl@0: BOOST_UBLAS_INLINE sl@0: zero_matrix (size_type size1, size_type size2): sl@0: matrix_container (), sl@0: size1_ (size1), size2_ (size2) {} sl@0: BOOST_UBLAS_INLINE sl@0: zero_matrix (const zero_matrix &m): sl@0: matrix_container (), sl@0: size1_ (m.size1_), size2_ (m.size2_) {} sl@0: sl@0: // Accessors sl@0: BOOST_UBLAS_INLINE sl@0: size_type size1 () const { sl@0: return size1_; sl@0: } sl@0: BOOST_UBLAS_INLINE sl@0: size_type size2 () const { sl@0: return size2_; sl@0: } sl@0: sl@0: // Resizing sl@0: BOOST_UBLAS_INLINE sl@0: void resize (size_type size, bool preserve = true) { sl@0: size1_ = size; sl@0: size2_ = size; sl@0: } sl@0: BOOST_UBLAS_INLINE sl@0: void resize (size_type size1, size_type size2, bool /*preserve*/ = true) { sl@0: size1_ = size1; sl@0: size2_ = size2; sl@0: } sl@0: sl@0: // Element access sl@0: BOOST_UBLAS_INLINE sl@0: const_reference operator () (size_type /* i */, size_type /* j */) const { sl@0: return zero_; sl@0: } sl@0: sl@0: // Assignment sl@0: BOOST_UBLAS_INLINE sl@0: zero_matrix &operator = (const zero_matrix &m) { sl@0: size1_ = m.size1_; sl@0: size2_ = m.size2_; sl@0: return *this; sl@0: } sl@0: BOOST_UBLAS_INLINE sl@0: zero_matrix &assign_temporary (zero_matrix &m) { sl@0: swap (m); sl@0: return *this; sl@0: } sl@0: sl@0: // Swapping sl@0: BOOST_UBLAS_INLINE sl@0: void swap (zero_matrix &m) { sl@0: if (this != &m) { sl@0: std::swap (size1_, m.size1_); sl@0: std::swap (size2_, m.size2_); sl@0: } sl@0: } sl@0: BOOST_UBLAS_INLINE sl@0: friend void swap (zero_matrix &m1, zero_matrix &m2) { sl@0: m1.swap (m2); sl@0: } sl@0: sl@0: // Iterator types sl@0: public: sl@0: class const_iterator1; sl@0: class const_iterator2; sl@0: typedef reverse_iterator_base1 const_reverse_iterator1; sl@0: typedef reverse_iterator_base2 const_reverse_iterator2; sl@0: sl@0: // Element lookup sl@0: BOOST_UBLAS_INLINE sl@0: const_iterator1 find1 (int /*rank*/, size_type /*i*/, size_type /*j*/) const { sl@0: return const_iterator1 (*this); sl@0: } sl@0: BOOST_UBLAS_INLINE sl@0: const_iterator2 find2 (int /*rank*/, size_type /*i*/, size_type /*j*/) const { sl@0: return const_iterator2 (*this); sl@0: } sl@0: sl@0: class const_iterator1: sl@0: public container_const_reference, sl@0: public bidirectional_iterator_base { sl@0: public: sl@0: typedef typename zero_matrix::value_type value_type; sl@0: typedef typename zero_matrix::difference_type difference_type; sl@0: typedef typename zero_matrix::const_reference reference; sl@0: typedef typename zero_matrix::const_pointer pointer; sl@0: sl@0: typedef const_iterator2 dual_iterator_type; sl@0: typedef const_reverse_iterator2 dual_reverse_iterator_type; sl@0: sl@0: // Construction and destruction sl@0: BOOST_UBLAS_INLINE sl@0: const_iterator1 (): sl@0: container_const_reference () {} sl@0: BOOST_UBLAS_INLINE sl@0: const_iterator1 (const self_type &m): sl@0: container_const_reference (m) {} sl@0: sl@0: // Arithmetic sl@0: BOOST_UBLAS_INLINE sl@0: const_iterator1 &operator ++ () { sl@0: BOOST_UBLAS_CHECK_FALSE (bad_index ()); sl@0: return *this; sl@0: } sl@0: BOOST_UBLAS_INLINE sl@0: const_iterator1 &operator -- () { sl@0: BOOST_UBLAS_CHECK_FALSE (bad_index ()); sl@0: return *this; sl@0: } sl@0: sl@0: // Dereference sl@0: BOOST_UBLAS_INLINE sl@0: const_reference operator * () const { sl@0: BOOST_UBLAS_CHECK_FALSE (bad_index ()); sl@0: return zero_; // arbitary return value sl@0: } sl@0: sl@0: #ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION sl@0: BOOST_UBLAS_INLINE sl@0: #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION sl@0: typename self_type:: sl@0: #endif sl@0: const_iterator2 begin () const { sl@0: return const_iterator2 ((*this) ()); sl@0: } sl@0: BOOST_UBLAS_INLINE sl@0: #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION sl@0: typename self_type:: sl@0: #endif sl@0: const_iterator2 end () const { sl@0: return const_iterator2 ((*this) ()); sl@0: } sl@0: BOOST_UBLAS_INLINE sl@0: #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION sl@0: typename self_type:: sl@0: #endif sl@0: const_reverse_iterator2 rbegin () const { sl@0: return const_reverse_iterator2 (end ()); sl@0: } sl@0: BOOST_UBLAS_INLINE sl@0: #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION sl@0: typename self_type:: sl@0: #endif sl@0: const_reverse_iterator2 rend () const { sl@0: return const_reverse_iterator2 (begin ()); sl@0: } sl@0: #endif sl@0: sl@0: // Indices sl@0: BOOST_UBLAS_INLINE sl@0: size_type index1 () const { sl@0: BOOST_UBLAS_CHECK_FALSE (bad_index ()); sl@0: return 0; // arbitary return value sl@0: } sl@0: BOOST_UBLAS_INLINE sl@0: size_type index2 () const { sl@0: BOOST_UBLAS_CHECK_FALSE (bad_index ()); sl@0: return 0; // arbitary return value sl@0: } sl@0: sl@0: // Assignment sl@0: BOOST_UBLAS_INLINE sl@0: const_iterator1 &operator = (const const_iterator1 &it) { sl@0: container_const_reference::assign (&it ()); sl@0: return *this; sl@0: } sl@0: sl@0: // Comparison sl@0: BOOST_UBLAS_INLINE sl@0: bool operator == (const const_iterator1 &it) const { sl@0: BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ()); sl@0: return true; sl@0: } sl@0: }; sl@0: sl@0: typedef const_iterator1 iterator1; sl@0: sl@0: BOOST_UBLAS_INLINE sl@0: const_iterator1 begin1 () const { sl@0: return const_iterator1 (*this); sl@0: } sl@0: BOOST_UBLAS_INLINE sl@0: const_iterator1 end1 () const { sl@0: return const_iterator1 (*this); sl@0: } sl@0: sl@0: class const_iterator2: sl@0: public container_const_reference, sl@0: public bidirectional_iterator_base { sl@0: public: sl@0: typedef typename zero_matrix::value_type value_type; sl@0: typedef typename zero_matrix::difference_type difference_type; sl@0: typedef typename zero_matrix::const_reference reference; sl@0: typedef typename zero_matrix::const_pointer pointer; sl@0: sl@0: typedef const_iterator1 dual_iterator_type; sl@0: typedef const_reverse_iterator1 dual_reverse_iterator_type; sl@0: sl@0: // Construction and destruction sl@0: BOOST_UBLAS_INLINE sl@0: const_iterator2 (): sl@0: container_const_reference () {} sl@0: BOOST_UBLAS_INLINE sl@0: const_iterator2 (const self_type &m): sl@0: container_const_reference (m) {} sl@0: sl@0: // Arithmetic sl@0: BOOST_UBLAS_INLINE sl@0: const_iterator2 &operator ++ () { sl@0: BOOST_UBLAS_CHECK_FALSE (bad_index ()); sl@0: return *this; sl@0: } sl@0: BOOST_UBLAS_INLINE sl@0: const_iterator2 &operator -- () { sl@0: BOOST_UBLAS_CHECK_FALSE (bad_index ()); sl@0: return *this; sl@0: } sl@0: sl@0: // Dereference sl@0: BOOST_UBLAS_INLINE sl@0: const_reference operator * () const { sl@0: BOOST_UBLAS_CHECK_FALSE (bad_index ()); sl@0: return zero_; // arbitary return value sl@0: } sl@0: sl@0: #ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION sl@0: BOOST_UBLAS_INLINE sl@0: #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION sl@0: typename self_type:: sl@0: #endif sl@0: const_iterator1 begin () const { sl@0: return const_iterator1 ((*this) ()); sl@0: } sl@0: BOOST_UBLAS_INLINE sl@0: #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION sl@0: typename self_type:: sl@0: #endif sl@0: const_iterator1 end () const { sl@0: return const_iterator1 ((*this) ()); sl@0: } sl@0: BOOST_UBLAS_INLINE sl@0: #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION sl@0: typename self_type:: sl@0: #endif sl@0: const_reverse_iterator1 rbegin () const { sl@0: return const_reverse_iterator1 (end ()); sl@0: } sl@0: BOOST_UBLAS_INLINE sl@0: #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION sl@0: typename self_type:: sl@0: #endif sl@0: const_reverse_iterator1 rend () const { sl@0: return const_reverse_iterator1 (begin ()); sl@0: } sl@0: #endif sl@0: sl@0: // Indices sl@0: BOOST_UBLAS_INLINE sl@0: size_type index1 () const { sl@0: BOOST_UBLAS_CHECK_FALSE (bad_index ()); sl@0: return 0; // arbitary return value sl@0: } sl@0: BOOST_UBLAS_INLINE sl@0: size_type index2 () const { sl@0: BOOST_UBLAS_CHECK_FALSE (bad_index ()); sl@0: return 0; // arbitary return value sl@0: } sl@0: sl@0: // Assignment sl@0: BOOST_UBLAS_INLINE sl@0: const_iterator2 &operator = (const const_iterator2 &it) { sl@0: container_const_reference::assign (&it ()); sl@0: return *this; sl@0: } sl@0: sl@0: // Comparison sl@0: BOOST_UBLAS_INLINE sl@0: bool operator == (const const_iterator2 &it) const { sl@0: BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ()); sl@0: return true; sl@0: } sl@0: }; sl@0: sl@0: typedef const_iterator2 iterator2; sl@0: sl@0: BOOST_UBLAS_INLINE sl@0: const_iterator2 begin2 () const { sl@0: return find2 (0, 0, 0); sl@0: } sl@0: BOOST_UBLAS_INLINE sl@0: const_iterator2 end2 () const { sl@0: return find2 (0, 0, size2_); sl@0: } sl@0: sl@0: // Reverse iterators sl@0: sl@0: BOOST_UBLAS_INLINE sl@0: const_reverse_iterator1 rbegin1 () const { sl@0: return const_reverse_iterator1 (end1 ()); sl@0: } sl@0: BOOST_UBLAS_INLINE sl@0: const_reverse_iterator1 rend1 () const { sl@0: return const_reverse_iterator1 (begin1 ()); sl@0: } sl@0: sl@0: BOOST_UBLAS_INLINE sl@0: const_reverse_iterator2 rbegin2 () const { sl@0: return const_reverse_iterator2 (end2 ()); sl@0: } sl@0: BOOST_UBLAS_INLINE sl@0: const_reverse_iterator2 rend2 () const { sl@0: return const_reverse_iterator2 (begin2 ()); sl@0: } sl@0: sl@0: private: sl@0: size_type size1_; sl@0: size_type size2_; sl@0: static const value_type zero_; sl@0: }; sl@0: sl@0: template sl@0: const typename zero_matrix::value_type zero_matrix::zero_ (0); sl@0: sl@0: sl@0: // Identity matrix class sl@0: template sl@0: class identity_matrix: sl@0: public matrix_container > { sl@0: sl@0: typedef const T *const_pointer; sl@0: typedef identity_matrix self_type; sl@0: public: sl@0: #ifdef BOOST_UBLAS_ENABLE_PROXY_SHORTCUTS sl@0: using matrix_container::operator (); sl@0: #endif sl@0: typedef std::size_t size_type; sl@0: typedef std::ptrdiff_t difference_type; sl@0: typedef T value_type; sl@0: typedef const T &const_reference; sl@0: typedef T &reference; sl@0: typedef const matrix_reference const_closure_type; sl@0: typedef matrix_reference closure_type; sl@0: typedef sparse_tag storage_category; sl@0: typedef unknown_orientation_tag orientation_category; sl@0: sl@0: // Construction and destruction sl@0: BOOST_UBLAS_INLINE sl@0: identity_matrix (): sl@0: matrix_container (), sl@0: size1_ (0), size2_ (0), size_common_ (0) {} sl@0: BOOST_UBLAS_INLINE sl@0: identity_matrix (size_type size): sl@0: matrix_container (), sl@0: size1_ (size), size2_ (size), size_common_ ((std::min) (size1_, size2_)) {} sl@0: BOOST_UBLAS_INLINE sl@0: identity_matrix (size_type size1, size_type size2): sl@0: matrix_container (), sl@0: size1_ (size1), size2_ (size2), size_common_ ((std::min) (size1_, size2_)) {} sl@0: BOOST_UBLAS_INLINE sl@0: identity_matrix (const identity_matrix &m): sl@0: matrix_container (), sl@0: size1_ (m.size1_), size2_ (m.size2_), size_common_ ((std::min) (size1_, size2_)) {} sl@0: sl@0: // Accessors sl@0: BOOST_UBLAS_INLINE sl@0: size_type size1 () const { sl@0: return size1_; sl@0: } sl@0: BOOST_UBLAS_INLINE sl@0: size_type size2 () const { sl@0: return size2_; sl@0: } sl@0: sl@0: // Resizing sl@0: BOOST_UBLAS_INLINE sl@0: void resize (size_type size, bool preserve = true) { sl@0: size1_ = size; sl@0: size2_ = size; sl@0: } sl@0: BOOST_UBLAS_INLINE sl@0: void resize (size_type size1, size_type size2, bool /*preserve*/ = true) { sl@0: size1_ = size1; sl@0: size2_ = size2; sl@0: } sl@0: sl@0: // Element access sl@0: BOOST_UBLAS_INLINE sl@0: const_reference operator () (size_type i, size_type j) const { sl@0: if (i == j) sl@0: return one_; sl@0: else sl@0: return zero_; sl@0: } sl@0: sl@0: // Assignment sl@0: BOOST_UBLAS_INLINE sl@0: identity_matrix &operator = (const identity_matrix &m) { sl@0: size1_ = m.size1_; sl@0: size2_ = m.size2_; sl@0: return *this; sl@0: } sl@0: BOOST_UBLAS_INLINE sl@0: identity_matrix &assign_temporary (identity_matrix &m) { sl@0: swap (m); sl@0: return *this; sl@0: } sl@0: sl@0: // Swapping sl@0: BOOST_UBLAS_INLINE sl@0: void swap (identity_matrix &m) { sl@0: if (this != &m) { sl@0: std::swap (size1_, m.size1_); sl@0: std::swap (size2_, m.size2_); sl@0: } sl@0: } sl@0: BOOST_UBLAS_INLINE sl@0: friend void swap (identity_matrix &m1, identity_matrix &m2) { sl@0: m1.swap (m2); sl@0: } sl@0: sl@0: // Iterator types sl@0: private: sl@0: // Use an index sl@0: typedef size_type const_subiterator_type; sl@0: sl@0: public: sl@0: class const_iterator1; sl@0: class const_iterator2; sl@0: typedef reverse_iterator_base1 const_reverse_iterator1; sl@0: typedef reverse_iterator_base2 const_reverse_iterator2; sl@0: sl@0: // Element lookup sl@0: BOOST_UBLAS_INLINE sl@0: const_iterator1 find1 (int rank, size_type i, size_type j) const { sl@0: if (rank == 1) { sl@0: i = (std::max) (i, j); sl@0: i = (std::min) (i, j + 1); sl@0: } sl@0: return const_iterator1 (*this, i); sl@0: } sl@0: BOOST_UBLAS_INLINE sl@0: const_iterator2 find2 (int rank, size_type i, size_type j) const { sl@0: if (rank == 1) { sl@0: j = (std::max) (j, i); sl@0: j = (std::min) (j, i + 1); sl@0: } sl@0: return const_iterator2 (*this, j); sl@0: } sl@0: sl@0: sl@0: class const_iterator1: sl@0: public container_const_reference, sl@0: public bidirectional_iterator_base { sl@0: public: sl@0: typedef typename identity_matrix::value_type value_type; sl@0: typedef typename identity_matrix::difference_type difference_type; sl@0: typedef typename identity_matrix::const_reference reference; sl@0: typedef typename identity_matrix::const_pointer pointer; sl@0: sl@0: typedef const_iterator2 dual_iterator_type; sl@0: typedef const_reverse_iterator2 dual_reverse_iterator_type; sl@0: sl@0: // Construction and destruction sl@0: BOOST_UBLAS_INLINE sl@0: const_iterator1 (): sl@0: container_const_reference (), it_ () {} sl@0: BOOST_UBLAS_INLINE sl@0: const_iterator1 (const self_type &m, const const_subiterator_type &it): sl@0: container_const_reference (m), it_ (it) {} sl@0: sl@0: // Arithmetic sl@0: BOOST_UBLAS_INLINE sl@0: const_iterator1 &operator ++ () { sl@0: BOOST_UBLAS_CHECK (it_ < (*this) ().size1 (), bad_index ()); sl@0: ++it_; sl@0: return *this; sl@0: } sl@0: BOOST_UBLAS_INLINE sl@0: const_iterator1 &operator -- () { sl@0: BOOST_UBLAS_CHECK (it_ > 0, bad_index ()); sl@0: --it_; sl@0: return *this; sl@0: } sl@0: sl@0: // Dereference sl@0: BOOST_UBLAS_INLINE sl@0: const_reference operator * () const { sl@0: return one_; sl@0: } sl@0: sl@0: #ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION sl@0: BOOST_UBLAS_INLINE sl@0: #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION sl@0: typename self_type:: sl@0: #endif sl@0: const_iterator2 begin () const { sl@0: return const_iterator2 ((*this) (), it_); sl@0: } sl@0: BOOST_UBLAS_INLINE sl@0: #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION sl@0: typename self_type:: sl@0: #endif sl@0: const_iterator2 end () const { sl@0: return const_iterator2 ((*this) (), it_ + 1); sl@0: } sl@0: BOOST_UBLAS_INLINE sl@0: #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION sl@0: typename self_type:: sl@0: #endif sl@0: const_reverse_iterator2 rbegin () const { sl@0: return const_reverse_iterator2 (end ()); sl@0: } sl@0: BOOST_UBLAS_INLINE sl@0: #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION sl@0: typename self_type:: sl@0: #endif sl@0: const_reverse_iterator2 rend () const { sl@0: return const_reverse_iterator2 (begin ()); sl@0: } sl@0: #endif sl@0: sl@0: // Indices sl@0: BOOST_UBLAS_INLINE sl@0: size_type index1 () const { sl@0: return it_; sl@0: } sl@0: BOOST_UBLAS_INLINE sl@0: size_type index2 () const { sl@0: return it_; sl@0: } sl@0: sl@0: // Assignment sl@0: BOOST_UBLAS_INLINE sl@0: const_iterator1 &operator = (const const_iterator1 &it) { sl@0: container_const_reference::assign (&it ()); sl@0: it_ = it.it_; sl@0: return *this; sl@0: } sl@0: sl@0: // Comparison sl@0: BOOST_UBLAS_INLINE sl@0: bool operator == (const const_iterator1 &it) const { sl@0: BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ()); sl@0: return it_ == it.it_; sl@0: } sl@0: sl@0: private: sl@0: const_subiterator_type it_; sl@0: }; sl@0: sl@0: typedef const_iterator1 iterator1; sl@0: sl@0: BOOST_UBLAS_INLINE sl@0: const_iterator1 begin1 () const { sl@0: return const_iterator1 (*this, 0); sl@0: } sl@0: BOOST_UBLAS_INLINE sl@0: const_iterator1 end1 () const { sl@0: return const_iterator1 (*this, size_common_); sl@0: } sl@0: sl@0: class const_iterator2: sl@0: public container_const_reference, sl@0: public bidirectional_iterator_base { sl@0: public: sl@0: typedef typename identity_matrix::value_type value_type; sl@0: typedef typename identity_matrix::difference_type difference_type; sl@0: typedef typename identity_matrix::const_reference reference; sl@0: typedef typename identity_matrix::const_pointer pointer; sl@0: sl@0: typedef const_iterator1 dual_iterator_type; sl@0: typedef const_reverse_iterator1 dual_reverse_iterator_type; sl@0: sl@0: // Construction and destruction sl@0: BOOST_UBLAS_INLINE sl@0: const_iterator2 (): sl@0: container_const_reference (), it_ () {} sl@0: BOOST_UBLAS_INLINE sl@0: const_iterator2 (const self_type &m, const const_subiterator_type &it): sl@0: container_const_reference (m), it_ (it) {} sl@0: sl@0: // Arithmetic sl@0: BOOST_UBLAS_INLINE sl@0: const_iterator2 &operator ++ () { sl@0: BOOST_UBLAS_CHECK (it_ < (*this) ().size_common_, bad_index ()); sl@0: ++it_; sl@0: return *this; sl@0: } sl@0: BOOST_UBLAS_INLINE sl@0: const_iterator2 &operator -- () { sl@0: BOOST_UBLAS_CHECK (it_ > 0, bad_index ()); sl@0: --it_; sl@0: return *this; sl@0: } sl@0: sl@0: // Dereference sl@0: BOOST_UBLAS_INLINE sl@0: const_reference operator * () const { sl@0: return one_; sl@0: } sl@0: sl@0: #ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION sl@0: BOOST_UBLAS_INLINE sl@0: #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION sl@0: typename self_type:: sl@0: #endif sl@0: const_iterator1 begin () const { sl@0: return const_iterator1 ((*this) (), it_); sl@0: } sl@0: BOOST_UBLAS_INLINE sl@0: #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION sl@0: typename self_type:: sl@0: #endif sl@0: const_iterator1 end () const { sl@0: return const_iterator1 ((*this) (), it_ + 1); sl@0: } sl@0: BOOST_UBLAS_INLINE sl@0: #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION sl@0: typename self_type:: sl@0: #endif sl@0: const_reverse_iterator1 rbegin () const { sl@0: return const_reverse_iterator1 (end ()); sl@0: } sl@0: BOOST_UBLAS_INLINE sl@0: #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION sl@0: typename self_type:: sl@0: #endif sl@0: const_reverse_iterator1 rend () const { sl@0: return const_reverse_iterator1 (begin ()); sl@0: } sl@0: #endif sl@0: sl@0: // Indices sl@0: BOOST_UBLAS_INLINE sl@0: size_type index1 () const { sl@0: return it_; sl@0: } sl@0: BOOST_UBLAS_INLINE sl@0: size_type index2 () const { sl@0: return it_; sl@0: } sl@0: sl@0: // Assignment sl@0: BOOST_UBLAS_INLINE sl@0: const_iterator2 &operator = (const const_iterator2 &it) { sl@0: container_const_reference::assign (&it ()); sl@0: it_ = it.it_; sl@0: return *this; sl@0: } sl@0: sl@0: // Comparison sl@0: BOOST_UBLAS_INLINE sl@0: bool operator == (const const_iterator2 &it) const { sl@0: BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ()); sl@0: return it_ == it.it_; sl@0: } sl@0: sl@0: private: sl@0: const_subiterator_type it_; sl@0: }; sl@0: sl@0: typedef const_iterator2 iterator2; sl@0: sl@0: BOOST_UBLAS_INLINE sl@0: const_iterator2 begin2 () const { sl@0: return const_iterator2 (*this, 0); sl@0: } sl@0: BOOST_UBLAS_INLINE sl@0: const_iterator2 end2 () const { sl@0: return const_iterator2 (*this, size_common_); sl@0: } sl@0: sl@0: // Reverse iterators sl@0: sl@0: BOOST_UBLAS_INLINE sl@0: const_reverse_iterator1 rbegin1 () const { sl@0: return const_reverse_iterator1 (end1 ()); sl@0: } sl@0: BOOST_UBLAS_INLINE sl@0: const_reverse_iterator1 rend1 () const { sl@0: return const_reverse_iterator1 (begin1 ()); sl@0: } sl@0: sl@0: BOOST_UBLAS_INLINE sl@0: const_reverse_iterator2 rbegin2 () const { sl@0: return const_reverse_iterator2 (end2 ()); sl@0: } sl@0: BOOST_UBLAS_INLINE sl@0: const_reverse_iterator2 rend2 () const { sl@0: return const_reverse_iterator2 (begin2 ()); sl@0: } sl@0: sl@0: private: sl@0: size_type size1_; sl@0: size_type size2_; sl@0: size_type size_common_; sl@0: static const value_type zero_; sl@0: static const value_type one_; sl@0: }; sl@0: sl@0: template sl@0: const typename identity_matrix::value_type identity_matrix::zero_ (0); sl@0: template sl@0: const typename identity_matrix::value_type identity_matrix::one_ (1); sl@0: sl@0: sl@0: // Scalar matrix class sl@0: template sl@0: class scalar_matrix: sl@0: public matrix_container > { sl@0: sl@0: typedef const T *const_pointer; sl@0: typedef scalar_matrix self_type; sl@0: public: sl@0: #ifdef BOOST_UBLAS_ENABLE_PROXY_SHORTCUTS sl@0: using matrix_container::operator (); sl@0: #endif sl@0: typedef std::size_t size_type; sl@0: typedef std::ptrdiff_t difference_type; sl@0: typedef T value_type; sl@0: typedef const T &const_reference; sl@0: typedef T &reference; sl@0: typedef const matrix_reference const_closure_type; sl@0: typedef dense_tag storage_category; sl@0: typedef unknown_orientation_tag orientation_category; sl@0: sl@0: // Construction and destruction sl@0: BOOST_UBLAS_INLINE sl@0: scalar_matrix (): sl@0: matrix_container (), sl@0: size1_ (0), size2_ (0), value_ () {} sl@0: BOOST_UBLAS_INLINE sl@0: scalar_matrix (size_type size1, size_type size2, const value_type &value = value_type(1)): sl@0: matrix_container (), sl@0: size1_ (size1), size2_ (size2), value_ (value) {} sl@0: BOOST_UBLAS_INLINE sl@0: scalar_matrix (const scalar_matrix &m): sl@0: matrix_container (), sl@0: size1_ (m.size1_), size2_ (m.size2_), value_ (m.value_) {} sl@0: sl@0: // Accessors sl@0: BOOST_UBLAS_INLINE sl@0: size_type size1 () const { sl@0: return size1_; sl@0: } sl@0: BOOST_UBLAS_INLINE sl@0: size_type size2 () const { sl@0: return size2_; sl@0: } sl@0: sl@0: // Resizing sl@0: BOOST_UBLAS_INLINE sl@0: void resize (size_type size1, size_type size2, bool /*preserve*/ = true) { sl@0: size1_ = size1; sl@0: size2_ = size2; sl@0: } sl@0: sl@0: // Element access sl@0: BOOST_UBLAS_INLINE sl@0: const_reference operator () (size_type /*i*/, size_type /*j*/) const { sl@0: return value_; sl@0: } sl@0: sl@0: // Assignment sl@0: BOOST_UBLAS_INLINE sl@0: scalar_matrix &operator = (const scalar_matrix &m) { sl@0: size1_ = m.size1_; sl@0: size2_ = m.size2_; sl@0: value_ = m.value_; sl@0: return *this; sl@0: } sl@0: BOOST_UBLAS_INLINE sl@0: scalar_matrix &assign_temporary (scalar_matrix &m) { sl@0: swap (m); sl@0: return *this; sl@0: } sl@0: sl@0: // Swapping sl@0: BOOST_UBLAS_INLINE sl@0: void swap (scalar_matrix &m) { sl@0: if (this != &m) { sl@0: std::swap (size1_, m.size1_); sl@0: std::swap (size2_, m.size2_); sl@0: std::swap (value_, m.value_); sl@0: } sl@0: } sl@0: BOOST_UBLAS_INLINE sl@0: friend void swap (scalar_matrix &m1, scalar_matrix &m2) { sl@0: m1.swap (m2); sl@0: } sl@0: sl@0: // Iterator types sl@0: private: sl@0: // Use an index sl@0: typedef size_type const_subiterator_type; sl@0: sl@0: public: sl@0: #ifdef BOOST_UBLAS_USE_INDEXED_ITERATOR sl@0: typedef indexed_const_iterator1 iterator1; sl@0: typedef indexed_const_iterator2 iterator2; sl@0: typedef indexed_const_iterator1 const_iterator1; sl@0: typedef indexed_const_iterator2 const_iterator2; sl@0: #else sl@0: class const_iterator1; sl@0: class const_iterator2; sl@0: #endif sl@0: typedef reverse_iterator_base1 const_reverse_iterator1; sl@0: typedef reverse_iterator_base2 const_reverse_iterator2; sl@0: sl@0: // Element lookup sl@0: BOOST_UBLAS_INLINE sl@0: const_iterator1 find1 (int /*rank*/, size_type i, size_type j) const { sl@0: return const_iterator1 (*this, i, j); sl@0: } sl@0: BOOST_UBLAS_INLINE sl@0: const_iterator2 find2 (int /*rank*/, size_type i, size_type j) const { sl@0: return const_iterator2 (*this, i, j); sl@0: } sl@0: sl@0: sl@0: #ifndef BOOST_UBLAS_USE_INDEXED_ITERATOR sl@0: class const_iterator1: sl@0: public container_const_reference, sl@0: public random_access_iterator_base { sl@0: public: sl@0: typedef typename scalar_matrix::value_type value_type; sl@0: typedef typename scalar_matrix::difference_type difference_type; sl@0: typedef typename scalar_matrix::const_reference reference; sl@0: typedef typename scalar_matrix::const_pointer pointer; sl@0: sl@0: typedef const_iterator2 dual_iterator_type; sl@0: typedef const_reverse_iterator2 dual_reverse_iterator_type; sl@0: sl@0: // Construction and destruction sl@0: BOOST_UBLAS_INLINE sl@0: const_iterator1 (): sl@0: container_const_reference (), it1_ (), it2_ () {} sl@0: BOOST_UBLAS_INLINE sl@0: const_iterator1 (const scalar_matrix &m, const const_subiterator_type &it1, const const_subiterator_type &it2): sl@0: container_const_reference (m), it1_ (it1), it2_ (it2) {} sl@0: sl@0: // Arithmetic sl@0: BOOST_UBLAS_INLINE sl@0: const_iterator1 &operator ++ () { sl@0: ++ it1_; sl@0: return *this; sl@0: } sl@0: BOOST_UBLAS_INLINE sl@0: const_iterator1 &operator -- () { sl@0: -- it1_; sl@0: return *this; sl@0: } sl@0: BOOST_UBLAS_INLINE sl@0: const_iterator1 &operator += (difference_type n) { sl@0: it1_ += n; sl@0: return *this; sl@0: } sl@0: BOOST_UBLAS_INLINE sl@0: const_iterator1 &operator -= (difference_type n) { sl@0: it1_ -= n; sl@0: return *this; sl@0: } sl@0: BOOST_UBLAS_INLINE sl@0: difference_type operator - (const const_iterator1 &it) const { sl@0: BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ()); sl@0: BOOST_UBLAS_CHECK (it2_ == it.it2_, external_logic ()); sl@0: return it1_ - it.it1_; sl@0: } sl@0: sl@0: // Dereference sl@0: BOOST_UBLAS_INLINE sl@0: const_reference operator * () const { sl@0: BOOST_UBLAS_CHECK (index1 () < (*this) ().size1 (), bad_index ()); sl@0: BOOST_UBLAS_CHECK (index2 () < (*this) ().size2 (), bad_index ()); sl@0: return (*this) () (index1 (), index2 ()); sl@0: } sl@0: BOOST_UBLAS_INLINE sl@0: const_reference operator [] (difference_type n) const { sl@0: return *(*this + n); sl@0: } sl@0: sl@0: #ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION sl@0: BOOST_UBLAS_INLINE sl@0: #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION sl@0: typename self_type:: sl@0: #endif sl@0: const_iterator2 begin () const { sl@0: const scalar_matrix &m = (*this) (); sl@0: return m.find2 (1, index1 (), 0); sl@0: } sl@0: BOOST_UBLAS_INLINE sl@0: #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION sl@0: typename self_type:: sl@0: #endif sl@0: const_iterator2 end () const { sl@0: const scalar_matrix &m = (*this) (); sl@0: return m.find2 (1, index1 (), m.size2 ()); sl@0: } sl@0: BOOST_UBLAS_INLINE sl@0: #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION sl@0: typename self_type:: sl@0: #endif sl@0: const_reverse_iterator2 rbegin () const { sl@0: return const_reverse_iterator2 (end ()); sl@0: } sl@0: BOOST_UBLAS_INLINE sl@0: #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION sl@0: typename self_type:: sl@0: #endif sl@0: const_reverse_iterator2 rend () const { sl@0: return const_reverse_iterator2 (begin ()); sl@0: } sl@0: #endif sl@0: sl@0: // Indices sl@0: BOOST_UBLAS_INLINE sl@0: size_type index1 () const { sl@0: return it1_; sl@0: } sl@0: BOOST_UBLAS_INLINE sl@0: size_type index2 () const { sl@0: return it2_; sl@0: } sl@0: sl@0: // Assignment sl@0: BOOST_UBLAS_INLINE sl@0: const_iterator1 &operator = (const const_iterator1 &it) { sl@0: container_const_reference::assign (&it ()); sl@0: it1_ = it.it1_; sl@0: it2_ = it.it2_; sl@0: return *this; sl@0: } sl@0: sl@0: // Comparison sl@0: BOOST_UBLAS_INLINE sl@0: bool operator == (const const_iterator1 &it) const { sl@0: BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ()); sl@0: BOOST_UBLAS_CHECK (it2_ == it.it2_, external_logic ()); sl@0: return it1_ == it.it1_; sl@0: } sl@0: BOOST_UBLAS_INLINE sl@0: bool operator < (const const_iterator1 &it) const { sl@0: BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ()); sl@0: BOOST_UBLAS_CHECK (it2_ == it.it2_, external_logic ()); sl@0: return it1_ < it.it1_; sl@0: } sl@0: sl@0: private: sl@0: const_subiterator_type it1_; sl@0: const_subiterator_type it2_; sl@0: }; sl@0: sl@0: typedef const_iterator1 iterator1; sl@0: #endif sl@0: sl@0: BOOST_UBLAS_INLINE sl@0: const_iterator1 begin1 () const { sl@0: return find1 (0, 0, 0); sl@0: } sl@0: BOOST_UBLAS_INLINE sl@0: const_iterator1 end1 () const { sl@0: return find1 (0, size1_, 0); sl@0: } sl@0: sl@0: #ifndef BOOST_UBLAS_USE_INDEXED_ITERATOR sl@0: class const_iterator2: sl@0: public container_const_reference, sl@0: public random_access_iterator_base { sl@0: public: sl@0: typedef typename scalar_matrix::value_type value_type; sl@0: typedef typename scalar_matrix::difference_type difference_type; sl@0: typedef typename scalar_matrix::const_reference reference; sl@0: typedef typename scalar_matrix::const_pointer pointer; sl@0: sl@0: typedef const_iterator1 dual_iterator_type; sl@0: typedef const_reverse_iterator1 dual_reverse_iterator_type; sl@0: sl@0: // Construction and destruction sl@0: BOOST_UBLAS_INLINE sl@0: const_iterator2 (): sl@0: container_const_reference (), it1_ (), it2_ () {} sl@0: BOOST_UBLAS_INLINE sl@0: const_iterator2 (const scalar_matrix &m, const const_subiterator_type &it1, const const_subiterator_type &it2): sl@0: container_const_reference (m), it1_ (it1), it2_ (it2) {} sl@0: sl@0: // Arithmetic sl@0: BOOST_UBLAS_INLINE sl@0: const_iterator2 &operator ++ () { sl@0: ++ it2_; sl@0: return *this; sl@0: } sl@0: BOOST_UBLAS_INLINE sl@0: const_iterator2 &operator -- () { sl@0: -- it2_; sl@0: return *this; sl@0: } sl@0: BOOST_UBLAS_INLINE sl@0: const_iterator2 &operator += (difference_type n) { sl@0: it2_ += n; sl@0: return *this; sl@0: } sl@0: BOOST_UBLAS_INLINE sl@0: const_iterator2 &operator -= (difference_type n) { sl@0: it2_ -= n; sl@0: return *this; sl@0: } sl@0: BOOST_UBLAS_INLINE sl@0: difference_type operator - (const const_iterator2 &it) const { sl@0: BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ()); sl@0: BOOST_UBLAS_CHECK (it1_ == it.it1_, external_logic ()); sl@0: return it2_ - it.it2_; sl@0: } sl@0: sl@0: // Dereference sl@0: BOOST_UBLAS_INLINE sl@0: const_reference operator * () const { sl@0: BOOST_UBLAS_CHECK (index1 () < (*this) ().size1 (), bad_index ()); sl@0: BOOST_UBLAS_CHECK (index2 () < (*this) ().size2 (), bad_index ()); sl@0: return (*this) () (index1 (), index2 ()); sl@0: } sl@0: BOOST_UBLAS_INLINE sl@0: const_reference operator [] (difference_type n) const { sl@0: return *(*this + n); sl@0: } sl@0: sl@0: #ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION sl@0: BOOST_UBLAS_INLINE sl@0: #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION sl@0: typename self_type:: sl@0: #endif sl@0: const_iterator1 begin () const { sl@0: const scalar_matrix &m = (*this) (); sl@0: return m.find1 (1, 0, index2 ()); sl@0: } sl@0: BOOST_UBLAS_INLINE sl@0: #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION sl@0: typename self_type:: sl@0: #endif sl@0: const_iterator1 end () const { sl@0: const scalar_matrix &m = (*this) (); sl@0: return m.find1 (1, m.size1 (), index2 ()); sl@0: } sl@0: BOOST_UBLAS_INLINE sl@0: #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION sl@0: typename self_type:: sl@0: #endif sl@0: const_reverse_iterator1 rbegin () const { sl@0: return const_reverse_iterator1 (end ()); sl@0: } sl@0: BOOST_UBLAS_INLINE sl@0: #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION sl@0: typename self_type:: sl@0: #endif sl@0: const_reverse_iterator1 rend () const { sl@0: return const_reverse_iterator1 (begin ()); sl@0: } sl@0: #endif sl@0: sl@0: // Indices sl@0: BOOST_UBLAS_INLINE sl@0: size_type index1 () const { sl@0: return it1_; sl@0: } sl@0: BOOST_UBLAS_INLINE sl@0: size_type index2 () const { sl@0: return it2_; sl@0: } sl@0: sl@0: // Assignment sl@0: BOOST_UBLAS_INLINE sl@0: const_iterator2 &operator = (const const_iterator2 &it) { sl@0: container_const_reference::assign (&it ()); sl@0: it1_ = it.it1_; sl@0: it2_ = it.it2_; sl@0: return *this; sl@0: } sl@0: sl@0: // Comparison sl@0: BOOST_UBLAS_INLINE sl@0: bool operator == (const const_iterator2 &it) const { sl@0: BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ()); sl@0: BOOST_UBLAS_CHECK (it1_ == it.it1_, external_logic ()); sl@0: return it2_ == it.it2_; sl@0: } sl@0: BOOST_UBLAS_INLINE sl@0: bool operator < (const const_iterator2 &it) const { sl@0: BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ()); sl@0: BOOST_UBLAS_CHECK (it1_ == it.it1_, external_logic ()); sl@0: return it2_ < it.it2_; sl@0: } sl@0: sl@0: private: sl@0: const_subiterator_type it1_; sl@0: const_subiterator_type it2_; sl@0: }; sl@0: sl@0: typedef const_iterator2 iterator2; sl@0: #endif sl@0: sl@0: BOOST_UBLAS_INLINE sl@0: const_iterator2 begin2 () const { sl@0: return find2 (0, 0, 0); sl@0: } sl@0: BOOST_UBLAS_INLINE sl@0: const_iterator2 end2 () const { sl@0: return find2 (0, 0, size2_); sl@0: } sl@0: sl@0: // Reverse iterators sl@0: sl@0: BOOST_UBLAS_INLINE sl@0: const_reverse_iterator1 rbegin1 () const { sl@0: return const_reverse_iterator1 (end1 ()); sl@0: } sl@0: BOOST_UBLAS_INLINE sl@0: const_reverse_iterator1 rend1 () const { sl@0: return const_reverse_iterator1 (begin1 ()); sl@0: } sl@0: sl@0: BOOST_UBLAS_INLINE sl@0: const_reverse_iterator2 rbegin2 () const { sl@0: return const_reverse_iterator2 (end2 ()); sl@0: } sl@0: BOOST_UBLAS_INLINE sl@0: const_reverse_iterator2 rend2 () const { sl@0: return const_reverse_iterator2 (begin2 ()); sl@0: } sl@0: sl@0: private: sl@0: size_type size1_; sl@0: size_type size2_; sl@0: value_type value_; sl@0: }; sl@0: sl@0: sl@0: // Array based matrix class sl@0: template sl@0: class c_matrix: sl@0: public matrix_container > { sl@0: sl@0: typedef c_matrix self_type; sl@0: public: sl@0: #ifdef BOOST_UBLAS_ENABLE_PROXY_SHORTCUTS sl@0: using matrix_container::operator (); sl@0: #endif sl@0: typedef std::size_t size_type; sl@0: typedef std::ptrdiff_t difference_type; sl@0: typedef T value_type; sl@0: typedef const T &const_reference; sl@0: typedef T &reference; sl@0: typedef const T *const_pointer; sl@0: typedef T *pointer; sl@0: typedef const matrix_reference const_closure_type; sl@0: typedef matrix_reference closure_type; sl@0: typedef c_vector vector_temporary_type; // vector able to store all elements of c_matrix sl@0: typedef self_type matrix_temporary_type; sl@0: typedef dense_tag storage_category; sl@0: // This could be better for performance, sl@0: // typedef typename unknown_orientation_tag orientation_category; sl@0: // but others depend on the orientation information... sl@0: typedef row_major_tag orientation_category; sl@0: sl@0: // Construction and destruction sl@0: BOOST_UBLAS_INLINE sl@0: c_matrix (): sl@0: size1_ (N), size2_ (M) /* , data_ () */ { sl@0: } sl@0: BOOST_UBLAS_INLINE sl@0: c_matrix (size_type size1, size_type size2): sl@0: size1_ (size1), size2_ (size2) /* , data_ () */ { sl@0: if (size1_ > N || size2_ > M) sl@0: bad_size ().raise (); sl@0: } sl@0: BOOST_UBLAS_INLINE sl@0: c_matrix (const c_matrix &m): sl@0: size1_ (m.size1_), size2_ (m.size2_) /* , data_ () */ { sl@0: if (size1_ > N || size2_ > M) sl@0: bad_size ().raise (); sl@0: *this = m; sl@0: } sl@0: template sl@0: BOOST_UBLAS_INLINE sl@0: c_matrix (const matrix_expression &ae): sl@0: size1_ (ae ().size1 ()), size2_ (ae ().size2 ()) /* , data_ () */ { sl@0: if (size1_ > N || size2_ > M) sl@0: bad_size ().raise (); sl@0: matrix_assign (*this, ae); sl@0: } sl@0: sl@0: // Accessors sl@0: BOOST_UBLAS_INLINE sl@0: size_type size1 () const { sl@0: return size1_; sl@0: } sl@0: BOOST_UBLAS_INLINE sl@0: size_type size2 () const { sl@0: return size2_; sl@0: } sl@0: BOOST_UBLAS_INLINE sl@0: const_pointer data () const { sl@0: return reinterpret_cast (data_); sl@0: } sl@0: BOOST_UBLAS_INLINE sl@0: pointer data () { sl@0: return reinterpret_cast (data_); sl@0: } sl@0: sl@0: // Resizing sl@0: BOOST_UBLAS_INLINE sl@0: void resize (size_type size1, size_type size2, bool preserve = true) { sl@0: if (size1 > N || size2 > M) sl@0: bad_size ().raise (); sl@0: if (preserve) { sl@0: self_type temporary (size1, size2); sl@0: // Common elements to preserve sl@0: const size_type size1_min = (std::min) (size1, size1_); sl@0: const size_type size2_min = (std::min) (size2, size2_); sl@0: for (size_type i = 0; i != size1_min; ++i) { // indexing copy over major sl@0: for (size_type j = 0; j != size2_min; ++j) { sl@0: temporary.data_[i][j] = data_[i][j]; sl@0: } sl@0: } sl@0: assign_temporary (temporary); sl@0: } sl@0: else { sl@0: size1_ = size1; sl@0: size2_ = size2; sl@0: } sl@0: } sl@0: sl@0: // Element access sl@0: BOOST_UBLAS_INLINE sl@0: const_reference operator () (size_type i, size_type j) const { sl@0: BOOST_UBLAS_CHECK (i < size1_, bad_index ()); sl@0: BOOST_UBLAS_CHECK (j < size2_, bad_index ()); sl@0: return data_ [i] [j]; sl@0: } sl@0: BOOST_UBLAS_INLINE sl@0: reference at_element (size_type i, size_type j) { sl@0: BOOST_UBLAS_CHECK (i < size1_, bad_index ()); sl@0: BOOST_UBLAS_CHECK (j < size2_, bad_index ()); sl@0: return data_ [i] [j]; sl@0: } sl@0: BOOST_UBLAS_INLINE sl@0: reference operator () (size_type i, size_type j) { sl@0: return at_element (i, j); sl@0: } sl@0: sl@0: // Element assignment sl@0: BOOST_UBLAS_INLINE sl@0: reference insert_element (size_type i, size_type j, const_reference t) { sl@0: return (at_element (i, j) = t); sl@0: } sl@0: sl@0: // Zeroing sl@0: BOOST_UBLAS_INLINE sl@0: void clear () { sl@0: for (size_type i = 0; i < size1_; ++ i) sl@0: std::fill (data_ [i], data_ [i] + size2_, value_type/*zero*/()); sl@0: } sl@0: sl@0: // Assignment sl@0: BOOST_UBLAS_INLINE sl@0: c_matrix &operator = (const c_matrix &m) { sl@0: size1_ = m.size1_; sl@0: size2_ = m.size2_; sl@0: for (size_type i = 0; i < m.size1_; ++ i) sl@0: std::copy (m.data_ [i], m.data_ [i] + m.size2_, data_ [i]); sl@0: return *this; sl@0: } sl@0: template // Container assignment without temporary sl@0: BOOST_UBLAS_INLINE sl@0: c_matrix &operator = (const matrix_container &m) { sl@0: resize (m ().size1 (), m ().size2 (), false); sl@0: assign (m); sl@0: return *this; sl@0: } sl@0: BOOST_UBLAS_INLINE sl@0: c_matrix &assign_temporary (c_matrix &m) { sl@0: swap (m); sl@0: return *this; sl@0: } sl@0: template sl@0: BOOST_UBLAS_INLINE sl@0: c_matrix &operator = (const matrix_expression &ae) { sl@0: self_type temporary (ae); sl@0: return assign_temporary (temporary); sl@0: } sl@0: template sl@0: BOOST_UBLAS_INLINE sl@0: c_matrix &assign (const matrix_expression &ae) { sl@0: matrix_assign (*this, ae); sl@0: return *this; sl@0: } sl@0: template sl@0: BOOST_UBLAS_INLINE sl@0: c_matrix& operator += (const matrix_expression &ae) { sl@0: self_type temporary (*this + ae); sl@0: return assign_temporary (temporary); sl@0: } sl@0: template // Container assignment without temporary sl@0: BOOST_UBLAS_INLINE sl@0: c_matrix &operator += (const matrix_container &m) { sl@0: plus_assign (m); sl@0: return *this; sl@0: } sl@0: template sl@0: BOOST_UBLAS_INLINE sl@0: c_matrix &plus_assign (const matrix_expression &ae) { sl@0: matrix_assign (*this, ae); sl@0: return *this; sl@0: } sl@0: template sl@0: BOOST_UBLAS_INLINE sl@0: c_matrix& operator -= (const matrix_expression &ae) { sl@0: self_type temporary (*this - ae); sl@0: return assign_temporary (temporary); sl@0: } sl@0: template // Container assignment without temporary sl@0: BOOST_UBLAS_INLINE sl@0: c_matrix &operator -= (const matrix_container &m) { sl@0: minus_assign (m); sl@0: return *this; sl@0: } sl@0: template sl@0: BOOST_UBLAS_INLINE sl@0: c_matrix &minus_assign (const matrix_expression &ae) { sl@0: matrix_assign (*this, ae); sl@0: return *this; sl@0: } sl@0: template sl@0: BOOST_UBLAS_INLINE sl@0: c_matrix& operator *= (const AT &at) { sl@0: matrix_assign_scalar (*this, at); sl@0: return *this; sl@0: } sl@0: template sl@0: BOOST_UBLAS_INLINE sl@0: c_matrix& operator /= (const AT &at) { sl@0: matrix_assign_scalar (*this, at); sl@0: return *this; sl@0: } sl@0: sl@0: // Swapping sl@0: BOOST_UBLAS_INLINE sl@0: void swap (c_matrix &m) { sl@0: if (this != &m) { sl@0: BOOST_UBLAS_CHECK (size1_ == m.size1_, bad_size ()); sl@0: BOOST_UBLAS_CHECK (size2_ == m.size2_, bad_size ()); sl@0: std::swap (size1_, m.size1_); sl@0: std::swap (size2_, m.size2_); sl@0: for (size_type i = 0; i < size1_; ++ i) sl@0: std::swap_ranges (data_ [i], data_ [i] + size2_, m.data_ [i]); sl@0: } sl@0: } sl@0: BOOST_UBLAS_INLINE sl@0: friend void swap (c_matrix &m1, c_matrix &m2) { sl@0: m1.swap (m2); sl@0: } sl@0: sl@0: // Iterator types sl@0: private: sl@0: // Use pointers for iterator sl@0: typedef const_pointer const_subiterator_type; sl@0: typedef pointer subiterator_type; sl@0: sl@0: public: sl@0: #ifdef BOOST_UBLAS_USE_INDEXED_ITERATOR sl@0: typedef indexed_iterator1 iterator1; sl@0: typedef indexed_iterator2 iterator2; sl@0: typedef indexed_const_iterator1 const_iterator1; sl@0: typedef indexed_const_iterator2 const_iterator2; sl@0: #else sl@0: class const_iterator1; sl@0: class iterator1; sl@0: class const_iterator2; sl@0: class iterator2; sl@0: #endif sl@0: typedef reverse_iterator_base1 const_reverse_iterator1; sl@0: typedef reverse_iterator_base1 reverse_iterator1; sl@0: typedef reverse_iterator_base2 const_reverse_iterator2; sl@0: typedef reverse_iterator_base2 reverse_iterator2; sl@0: sl@0: // Element lookup sl@0: BOOST_UBLAS_INLINE sl@0: const_iterator1 find1 (int rank, size_type i, size_type j) const { sl@0: #ifdef BOOST_UBLAS_USE_INDEXED_ITERATOR sl@0: return const_iterator1 (*this, i, j); sl@0: #else sl@0: return const_iterator1 (*this, &data_ [i] [j]); sl@0: #endif sl@0: } sl@0: BOOST_UBLAS_INLINE sl@0: iterator1 find1 (int rank, size_type i, size_type j) { sl@0: #ifdef BOOST_UBLAS_USE_INDEXED_ITERATOR sl@0: return iterator1 (*this, i, j); sl@0: #else sl@0: return iterator1 (*this, &data_ [i] [j]); sl@0: #endif sl@0: } sl@0: BOOST_UBLAS_INLINE sl@0: const_iterator2 find2 (int rank, size_type i, size_type j) const { sl@0: #ifdef BOOST_UBLAS_USE_INDEXED_ITERATOR sl@0: return const_iterator2 (*this, i, j); sl@0: #else sl@0: return const_iterator2 (*this, &data_ [i] [j]); sl@0: #endif sl@0: } sl@0: BOOST_UBLAS_INLINE sl@0: iterator2 find2 (int rank, size_type i, size_type j) { sl@0: #ifdef BOOST_UBLAS_USE_INDEXED_ITERATOR sl@0: return iterator2 (*this, i, j); sl@0: #else sl@0: return iterator2 (*this, &data_ [i] [j]); sl@0: #endif sl@0: } sl@0: sl@0: sl@0: #ifndef BOOST_UBLAS_USE_INDEXED_ITERATOR sl@0: class const_iterator1: sl@0: public container_const_reference, sl@0: public random_access_iterator_base { sl@0: public: sl@0: typedef typename c_matrix::difference_type difference_type; sl@0: typedef typename c_matrix::value_type value_type; sl@0: typedef typename c_matrix::const_reference reference; sl@0: typedef typename c_matrix::const_pointer pointer; sl@0: sl@0: typedef const_iterator2 dual_iterator_type; sl@0: typedef const_reverse_iterator2 dual_reverse_iterator_type; sl@0: sl@0: // Construction and destruction sl@0: BOOST_UBLAS_INLINE sl@0: const_iterator1 (): sl@0: container_const_reference (), it_ () {} sl@0: BOOST_UBLAS_INLINE sl@0: const_iterator1 (const self_type &m, const const_subiterator_type &it): sl@0: container_const_reference (m), it_ (it) {} sl@0: BOOST_UBLAS_INLINE sl@0: const_iterator1 (const iterator1 &it): sl@0: container_const_reference (it ()), it_ (it.it_) {} sl@0: sl@0: // Arithmetic sl@0: BOOST_UBLAS_INLINE sl@0: const_iterator1 &operator ++ () { sl@0: it_ += M; sl@0: return *this; sl@0: } sl@0: BOOST_UBLAS_INLINE sl@0: const_iterator1 &operator -- () { sl@0: it_ -= M; sl@0: return *this; sl@0: } sl@0: BOOST_UBLAS_INLINE sl@0: const_iterator1 &operator += (difference_type n) { sl@0: it_ += n * M; sl@0: return *this; sl@0: } sl@0: BOOST_UBLAS_INLINE sl@0: const_iterator1 &operator -= (difference_type n) { sl@0: it_ -= n * M; sl@0: return *this; sl@0: } sl@0: BOOST_UBLAS_INLINE sl@0: difference_type operator - (const const_iterator1 &it) const { sl@0: BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ()); sl@0: return (it_ - it.it_) / M; sl@0: } sl@0: sl@0: // Dereference sl@0: BOOST_UBLAS_INLINE sl@0: const_reference operator * () const { sl@0: BOOST_UBLAS_CHECK (index1 () < (*this) ().size1 (), bad_index ()); sl@0: BOOST_UBLAS_CHECK (index2 () < (*this) ().size2 (), bad_index ()); sl@0: return *it_; sl@0: } sl@0: BOOST_UBLAS_INLINE sl@0: const_reference operator [] (difference_type n) const { sl@0: return *(*this + n); sl@0: } sl@0: sl@0: #ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION sl@0: BOOST_UBLAS_INLINE sl@0: #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION sl@0: typename self_type:: sl@0: #endif sl@0: const_iterator2 begin () const { sl@0: const self_type &m = (*this) (); sl@0: return m.find2 (1, index1 (), 0); sl@0: } sl@0: BOOST_UBLAS_INLINE sl@0: #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION sl@0: typename self_type:: sl@0: #endif sl@0: const_iterator2 end () const { sl@0: const self_type &m = (*this) (); sl@0: return m.find2 (1, index1 (), m.size2 ()); sl@0: } sl@0: BOOST_UBLAS_INLINE sl@0: #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION sl@0: typename self_type:: sl@0: #endif sl@0: const_reverse_iterator2 rbegin () const { sl@0: return const_reverse_iterator2 (end ()); sl@0: } sl@0: BOOST_UBLAS_INLINE sl@0: #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION sl@0: typename self_type:: sl@0: #endif sl@0: const_reverse_iterator2 rend () const { sl@0: return const_reverse_iterator2 (begin ()); sl@0: } sl@0: #endif sl@0: sl@0: // Indices sl@0: BOOST_UBLAS_INLINE sl@0: size_type index1 () const { sl@0: const self_type &m = (*this) (); sl@0: return (it_ - m.begin1 ().it_) / M; sl@0: } sl@0: BOOST_UBLAS_INLINE sl@0: size_type index2 () const { sl@0: const self_type &m = (*this) (); sl@0: return (it_ - m.begin1 ().it_) % M; sl@0: } sl@0: sl@0: // Assignment sl@0: BOOST_UBLAS_INLINE sl@0: const_iterator1 &operator = (const const_iterator1 &it) { sl@0: container_const_reference::assign (&it ()); sl@0: it_ = it.it_; sl@0: return *this; sl@0: } sl@0: sl@0: // Comparison sl@0: BOOST_UBLAS_INLINE sl@0: bool operator == (const const_iterator1 &it) const { sl@0: BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ()); sl@0: return it_ == it.it_; sl@0: } sl@0: BOOST_UBLAS_INLINE sl@0: bool operator < (const const_iterator1 &it) const { sl@0: BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ()); sl@0: return it_ < it.it_; sl@0: } sl@0: sl@0: private: sl@0: const_subiterator_type it_; sl@0: sl@0: friend class iterator1; sl@0: }; sl@0: #endif sl@0: sl@0: BOOST_UBLAS_INLINE sl@0: const_iterator1 begin1 () const { sl@0: return find1 (0, 0, 0); sl@0: } sl@0: BOOST_UBLAS_INLINE sl@0: const_iterator1 end1 () const { sl@0: return find1 (0, size1_, 0); sl@0: } sl@0: sl@0: #ifndef BOOST_UBLAS_USE_INDEXED_ITERATOR sl@0: class iterator1: sl@0: public container_reference, sl@0: public random_access_iterator_base { sl@0: public: sl@0: sl@0: typedef typename c_matrix::difference_type difference_type; sl@0: typedef typename c_matrix::value_type value_type; sl@0: typedef typename c_matrix::reference reference; sl@0: typedef typename c_matrix::pointer pointer; sl@0: sl@0: typedef iterator2 dual_iterator_type; sl@0: typedef reverse_iterator2 dual_reverse_iterator_type; sl@0: sl@0: // Construction and destruction sl@0: BOOST_UBLAS_INLINE sl@0: iterator1 (): sl@0: container_reference (), it_ () {} sl@0: BOOST_UBLAS_INLINE sl@0: iterator1 (self_type &m, const subiterator_type &it): sl@0: container_reference (m), it_ (it) {} sl@0: sl@0: // Arithmetic sl@0: BOOST_UBLAS_INLINE sl@0: iterator1 &operator ++ () { sl@0: it_ += M; sl@0: return *this; sl@0: } sl@0: BOOST_UBLAS_INLINE sl@0: iterator1 &operator -- () { sl@0: it_ -= M; sl@0: return *this; sl@0: } sl@0: BOOST_UBLAS_INLINE sl@0: iterator1 &operator += (difference_type n) { sl@0: it_ += n * M; sl@0: return *this; sl@0: } sl@0: BOOST_UBLAS_INLINE sl@0: iterator1 &operator -= (difference_type n) { sl@0: it_ -= n * M; sl@0: return *this; sl@0: } sl@0: BOOST_UBLAS_INLINE sl@0: difference_type operator - (const iterator1 &it) const { sl@0: BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ()); sl@0: return (it_ - it.it_) / M; sl@0: } sl@0: sl@0: // Dereference sl@0: BOOST_UBLAS_INLINE sl@0: reference operator * () const { sl@0: BOOST_UBLAS_CHECK (index1 () < (*this) ().size1 (), bad_index ()); sl@0: BOOST_UBLAS_CHECK (index2 () < (*this) ().size2 (), bad_index ()); sl@0: return *it_; sl@0: } sl@0: BOOST_UBLAS_INLINE sl@0: reference operator [] (difference_type n) const { sl@0: return *(*this + n); sl@0: } sl@0: sl@0: #ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION sl@0: BOOST_UBLAS_INLINE sl@0: #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION sl@0: typename self_type:: sl@0: #endif sl@0: iterator2 begin () const { sl@0: self_type &m = (*this) (); sl@0: return m.find2 (1, index1 (), 0); sl@0: } sl@0: BOOST_UBLAS_INLINE sl@0: #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION sl@0: typename self_type:: sl@0: #endif sl@0: iterator2 end () const { sl@0: self_type &m = (*this) (); sl@0: return m.find2 (1, index1 (), m.size2 ()); sl@0: } sl@0: BOOST_UBLAS_INLINE sl@0: #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION sl@0: typename self_type:: sl@0: #endif sl@0: reverse_iterator2 rbegin () const { sl@0: return reverse_iterator2 (end ()); sl@0: } sl@0: BOOST_UBLAS_INLINE sl@0: #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION sl@0: typename self_type:: sl@0: #endif sl@0: reverse_iterator2 rend () const { sl@0: return reverse_iterator2 (begin ()); sl@0: } sl@0: #endif sl@0: sl@0: // Indices sl@0: BOOST_UBLAS_INLINE sl@0: size_type index1 () const { sl@0: const self_type &m = (*this) (); sl@0: return (it_ - m.begin1 ().it_) / M; sl@0: } sl@0: BOOST_UBLAS_INLINE sl@0: size_type index2 () const { sl@0: const self_type &m = (*this) (); sl@0: return (it_ - m.begin1 ().it_) % M; sl@0: } sl@0: sl@0: // Assignment sl@0: BOOST_UBLAS_INLINE sl@0: iterator1 &operator = (const iterator1 &it) { sl@0: container_reference::assign (&it ()); sl@0: it_ = it.it_; sl@0: return *this; sl@0: } sl@0: sl@0: // Comparison sl@0: BOOST_UBLAS_INLINE sl@0: bool operator == (const iterator1 &it) const { sl@0: BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ()); sl@0: return it_ == it.it_; sl@0: } sl@0: BOOST_UBLAS_INLINE sl@0: bool operator < (const iterator1 &it) const { sl@0: BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ()); sl@0: return it_ < it.it_; sl@0: } sl@0: sl@0: private: sl@0: subiterator_type it_; sl@0: sl@0: friend class const_iterator1; sl@0: }; sl@0: #endif sl@0: sl@0: BOOST_UBLAS_INLINE sl@0: iterator1 begin1 () { sl@0: return find1 (0, 0, 0); sl@0: } sl@0: BOOST_UBLAS_INLINE sl@0: iterator1 end1 () { sl@0: return find1 (0, size1_, 0); sl@0: } sl@0: sl@0: #ifndef BOOST_UBLAS_USE_INDEXED_ITERATOR sl@0: class const_iterator2: sl@0: public container_const_reference, sl@0: public random_access_iterator_base { sl@0: public: sl@0: typedef typename c_matrix::difference_type difference_type; sl@0: typedef typename c_matrix::value_type value_type; sl@0: typedef typename c_matrix::const_reference reference; sl@0: typedef typename c_matrix::const_reference pointer; sl@0: sl@0: typedef const_iterator1 dual_iterator_type; sl@0: typedef const_reverse_iterator1 dual_reverse_iterator_type; sl@0: sl@0: // Construction and destruction sl@0: BOOST_UBLAS_INLINE sl@0: const_iterator2 (): sl@0: container_const_reference (), it_ () {} sl@0: BOOST_UBLAS_INLINE sl@0: const_iterator2 (const self_type &m, const const_subiterator_type &it): sl@0: container_const_reference (m), it_ (it) {} sl@0: BOOST_UBLAS_INLINE sl@0: const_iterator2 (const iterator2 &it): sl@0: container_const_reference (it ()), it_ (it.it_) {} sl@0: sl@0: // Arithmetic sl@0: BOOST_UBLAS_INLINE sl@0: const_iterator2 &operator ++ () { sl@0: ++ it_; sl@0: return *this; sl@0: } sl@0: BOOST_UBLAS_INLINE sl@0: const_iterator2 &operator -- () { sl@0: -- it_; sl@0: return *this; sl@0: } sl@0: BOOST_UBLAS_INLINE sl@0: const_iterator2 &operator += (difference_type n) { sl@0: it_ += n; sl@0: return *this; sl@0: } sl@0: BOOST_UBLAS_INLINE sl@0: const_iterator2 &operator -= (difference_type n) { sl@0: it_ -= n; sl@0: return *this; sl@0: } sl@0: BOOST_UBLAS_INLINE sl@0: difference_type operator - (const const_iterator2 &it) const { sl@0: BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ()); sl@0: return it_ - it.it_; sl@0: } sl@0: sl@0: // Dereference sl@0: BOOST_UBLAS_INLINE sl@0: const_reference operator * () const { sl@0: BOOST_UBLAS_CHECK (index1 () < (*this) ().size1 (), bad_index ()); sl@0: BOOST_UBLAS_CHECK (index2 () < (*this) ().size2 (), bad_index ()); sl@0: return *it_; sl@0: } sl@0: BOOST_UBLAS_INLINE sl@0: const_reference operator [] (difference_type n) const { sl@0: return *(*this + n); sl@0: } sl@0: sl@0: #ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION sl@0: BOOST_UBLAS_INLINE sl@0: #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION sl@0: typename self_type:: sl@0: #endif sl@0: const_iterator1 begin () const { sl@0: const self_type &m = (*this) (); sl@0: return m.find1 (1, 0, index2 ()); sl@0: } sl@0: BOOST_UBLAS_INLINE sl@0: #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION sl@0: typename self_type:: sl@0: #endif sl@0: const_iterator1 end () const { sl@0: const self_type &m = (*this) (); sl@0: return m.find1 (1, m.size1 (), index2 ()); sl@0: } sl@0: BOOST_UBLAS_INLINE sl@0: #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION sl@0: typename self_type:: sl@0: #endif sl@0: const_reverse_iterator1 rbegin () const { sl@0: return const_reverse_iterator1 (end ()); sl@0: } sl@0: BOOST_UBLAS_INLINE sl@0: #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION sl@0: typename self_type:: sl@0: #endif sl@0: const_reverse_iterator1 rend () const { sl@0: return const_reverse_iterator1 (begin ()); sl@0: } sl@0: #endif sl@0: sl@0: // Indices sl@0: BOOST_UBLAS_INLINE sl@0: size_type index1 () const { sl@0: const self_type &m = (*this) (); sl@0: return (it_ - m.begin2 ().it_) / M; sl@0: } sl@0: BOOST_UBLAS_INLINE sl@0: size_type index2 () const { sl@0: const self_type &m = (*this) (); sl@0: return (it_ - m.begin2 ().it_) % M; sl@0: } sl@0: sl@0: // Assignment sl@0: BOOST_UBLAS_INLINE sl@0: const_iterator2 &operator = (const const_iterator2 &it) { sl@0: container_const_reference::assign (&it ()); sl@0: it_ = it.it_; sl@0: return *this; sl@0: } sl@0: sl@0: // Comparison sl@0: BOOST_UBLAS_INLINE sl@0: bool operator == (const const_iterator2 &it) const { sl@0: BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ()); sl@0: return it_ == it.it_; sl@0: } sl@0: BOOST_UBLAS_INLINE sl@0: bool operator < (const const_iterator2 &it) const { sl@0: BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ()); sl@0: return it_ < it.it_; sl@0: } sl@0: sl@0: private: sl@0: const_subiterator_type it_; sl@0: sl@0: friend class iterator2; sl@0: }; sl@0: #endif sl@0: sl@0: BOOST_UBLAS_INLINE sl@0: const_iterator2 begin2 () const { sl@0: return find2 (0, 0, 0); sl@0: } sl@0: BOOST_UBLAS_INLINE sl@0: const_iterator2 end2 () const { sl@0: return find2 (0, 0, size2_); sl@0: } sl@0: sl@0: #ifndef BOOST_UBLAS_USE_INDEXED_ITERATOR sl@0: class iterator2: sl@0: public container_reference, sl@0: public random_access_iterator_base { sl@0: public: sl@0: typedef typename c_matrix::difference_type difference_type; sl@0: typedef typename c_matrix::value_type value_type; sl@0: typedef typename c_matrix::reference reference; sl@0: typedef typename c_matrix::pointer pointer; sl@0: sl@0: typedef iterator1 dual_iterator_type; sl@0: typedef reverse_iterator1 dual_reverse_iterator_type; sl@0: sl@0: // Construction and destruction sl@0: BOOST_UBLAS_INLINE sl@0: iterator2 (): sl@0: container_reference (), it_ () {} sl@0: BOOST_UBLAS_INLINE sl@0: iterator2 (self_type &m, const subiterator_type &it): sl@0: container_reference (m), it_ (it) {} sl@0: sl@0: // Arithmetic sl@0: BOOST_UBLAS_INLINE sl@0: iterator2 &operator ++ () { sl@0: ++ it_; sl@0: return *this; sl@0: } sl@0: BOOST_UBLAS_INLINE sl@0: iterator2 &operator -- () { sl@0: -- it_; sl@0: return *this; sl@0: } sl@0: BOOST_UBLAS_INLINE sl@0: iterator2 &operator += (difference_type n) { sl@0: it_ += n; sl@0: return *this; sl@0: } sl@0: BOOST_UBLAS_INLINE sl@0: iterator2 &operator -= (difference_type n) { sl@0: it_ -= n; sl@0: return *this; sl@0: } sl@0: BOOST_UBLAS_INLINE sl@0: difference_type operator - (const iterator2 &it) const { sl@0: BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ()); sl@0: return it_ - it.it_; sl@0: } sl@0: sl@0: // Dereference sl@0: BOOST_UBLAS_INLINE sl@0: reference operator * () const { sl@0: BOOST_UBLAS_CHECK (index1 () < (*this) ().size1 (), bad_index ()); sl@0: BOOST_UBLAS_CHECK (index2 () < (*this) ().size2 (), bad_index ()); sl@0: return *it_; sl@0: } sl@0: BOOST_UBLAS_INLINE sl@0: reference operator [] (difference_type n) const { sl@0: return *(*this + n); sl@0: } sl@0: sl@0: #ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION sl@0: BOOST_UBLAS_INLINE sl@0: #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION sl@0: typename self_type:: sl@0: #endif sl@0: iterator1 begin () const { sl@0: self_type &m = (*this) (); sl@0: return m.find1 (1, 0, index2 ()); sl@0: } sl@0: BOOST_UBLAS_INLINE sl@0: #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION sl@0: typename self_type:: sl@0: #endif sl@0: iterator1 end () const { sl@0: self_type &m = (*this) (); sl@0: return m.find1 (1, m.size1 (), index2 ()); sl@0: } sl@0: BOOST_UBLAS_INLINE sl@0: #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION sl@0: typename self_type:: sl@0: #endif sl@0: reverse_iterator1 rbegin () const { sl@0: return reverse_iterator1 (end ()); sl@0: } sl@0: BOOST_UBLAS_INLINE sl@0: #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION sl@0: typename self_type:: sl@0: #endif sl@0: reverse_iterator1 rend () const { sl@0: return reverse_iterator1 (begin ()); sl@0: } sl@0: #endif sl@0: sl@0: // Indices sl@0: BOOST_UBLAS_INLINE sl@0: size_type index1 () const { sl@0: const self_type &m = (*this) (); sl@0: return (it_ - m.begin2 ().it_) / M; sl@0: } sl@0: BOOST_UBLAS_INLINE sl@0: size_type index2 () const { sl@0: const self_type &m = (*this) (); sl@0: return (it_ - m.begin2 ().it_) % M; sl@0: } sl@0: sl@0: // Assignment sl@0: BOOST_UBLAS_INLINE sl@0: iterator2 &operator = (const iterator2 &it) { sl@0: container_reference::assign (&it ()); sl@0: it_ = it.it_; sl@0: return *this; sl@0: } sl@0: sl@0: // Comparison sl@0: BOOST_UBLAS_INLINE sl@0: bool operator == (const iterator2 &it) const { sl@0: BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ()); sl@0: return it_ == it.it_; sl@0: } sl@0: BOOST_UBLAS_INLINE sl@0: bool operator < (const iterator2 &it) const { sl@0: BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ()); sl@0: return it_ < it.it_; sl@0: } sl@0: sl@0: private: sl@0: subiterator_type it_; sl@0: sl@0: friend class const_iterator2; sl@0: }; sl@0: #endif sl@0: sl@0: BOOST_UBLAS_INLINE sl@0: iterator2 begin2 () { sl@0: return find2 (0, 0, 0); sl@0: } sl@0: BOOST_UBLAS_INLINE sl@0: iterator2 end2 () { sl@0: return find2 (0, 0, size2_); sl@0: } sl@0: sl@0: // Reverse iterators sl@0: sl@0: BOOST_UBLAS_INLINE sl@0: const_reverse_iterator1 rbegin1 () const { sl@0: return const_reverse_iterator1 (end1 ()); sl@0: } sl@0: BOOST_UBLAS_INLINE sl@0: const_reverse_iterator1 rend1 () const { sl@0: return const_reverse_iterator1 (begin1 ()); sl@0: } sl@0: sl@0: BOOST_UBLAS_INLINE sl@0: reverse_iterator1 rbegin1 () { sl@0: return reverse_iterator1 (end1 ()); sl@0: } sl@0: BOOST_UBLAS_INLINE sl@0: reverse_iterator1 rend1 () { sl@0: return reverse_iterator1 (begin1 ()); sl@0: } sl@0: sl@0: BOOST_UBLAS_INLINE sl@0: const_reverse_iterator2 rbegin2 () const { sl@0: return const_reverse_iterator2 (end2 ()); sl@0: } sl@0: BOOST_UBLAS_INLINE sl@0: const_reverse_iterator2 rend2 () const { sl@0: return const_reverse_iterator2 (begin2 ()); sl@0: } sl@0: sl@0: BOOST_UBLAS_INLINE sl@0: reverse_iterator2 rbegin2 () { sl@0: return reverse_iterator2 (end2 ()); sl@0: } sl@0: BOOST_UBLAS_INLINE sl@0: reverse_iterator2 rend2 () { sl@0: return reverse_iterator2 (begin2 ()); sl@0: } sl@0: sl@0: private: sl@0: size_type size1_; sl@0: size_type size2_; sl@0: value_type data_ [N] [M]; sl@0: }; sl@0: sl@0: }}} sl@0: sl@0: #endif