Chris@16: // Chris@16: // Copyright (c) 2000-2002 Chris@16: // Joerg Walter, Mathias Koch Chris@16: // Chris@16: // Distributed under the Boost Software License, Version 1.0. (See Chris@16: // accompanying file LICENSE_1_0.txt or copy at Chris@16: // http://www.boost.org/LICENSE_1_0.txt) Chris@16: // Chris@16: // The authors gratefully acknowledge the support of Chris@16: // GeNeSys mbH & Co. KG in producing this work. Chris@16: // Chris@16: Chris@16: #ifndef _BOOST_UBLAS_MATRIX_EXPRESSION_ Chris@16: #define _BOOST_UBLAS_MATRIX_EXPRESSION_ Chris@16: Chris@16: #include Chris@16: Chris@16: // Expression templates based on ideas of Todd Veldhuizen and Geoffrey Furnish Chris@16: // Iterators based on ideas of Jeremy Siek Chris@16: // Chris@16: // Classes that model the Matrix Expression concept Chris@16: Chris@16: namespace boost { namespace numeric { namespace ublas { Chris@16: Chris@16: template Chris@16: class matrix_reference: Chris@16: public matrix_expression > { Chris@16: Chris@16: typedef matrix_reference self_type; Chris@16: public: Chris@16: #ifdef BOOST_UBLAS_ENABLE_PROXY_SHORTCUTS Chris@16: using matrix_expression::operator (); Chris@16: #endif Chris@16: typedef typename E::size_type size_type; Chris@16: typedef typename E::difference_type difference_type; Chris@16: typedef typename E::value_type value_type; Chris@16: typedef typename E::const_reference const_reference; Chris@16: typedef typename boost::mpl::if_, Chris@16: typename E::const_reference, Chris@16: typename E::reference>::type reference; Chris@16: typedef E referred_type; Chris@16: typedef const self_type const_closure_type; Chris@16: typedef self_type closure_type; Chris@16: typedef typename E::orientation_category orientation_category; Chris@16: typedef typename E::storage_category storage_category; Chris@16: Chris@16: // Construction and destruction Chris@16: BOOST_UBLAS_INLINE Chris@16: explicit matrix_reference (referred_type &e): Chris@16: e_ (e) {} Chris@16: Chris@16: // Accessors Chris@16: BOOST_UBLAS_INLINE Chris@16: size_type size1 () const { Chris@16: return e_.size1 (); Chris@16: } Chris@16: BOOST_UBLAS_INLINE Chris@16: size_type size2 () const { Chris@16: return e_.size2 (); Chris@16: } Chris@16: Chris@16: public: Chris@16: // Expression accessors - const correct Chris@16: BOOST_UBLAS_INLINE Chris@16: const referred_type &expression () const { Chris@16: return e_; Chris@16: } Chris@16: BOOST_UBLAS_INLINE Chris@16: referred_type &expression () { Chris@16: return e_; Chris@16: } Chris@16: Chris@16: public: Chris@16: // Element access Chris@16: #ifndef BOOST_UBLAS_REFERENCE_CONST_MEMBER Chris@16: BOOST_UBLAS_INLINE Chris@16: const_reference operator () (size_type i, size_type j) const { Chris@16: return expression () (i, j); Chris@16: } Chris@16: BOOST_UBLAS_INLINE Chris@16: reference operator () (size_type i, size_type j) { Chris@16: return expression () (i, j); Chris@16: } Chris@16: #else Chris@16: BOOST_UBLAS_INLINE Chris@16: reference operator () (size_type i, size_type j) const { Chris@16: return expression () (i, j); Chris@16: } Chris@16: #endif Chris@16: Chris@16: // Assignment Chris@16: BOOST_UBLAS_INLINE Chris@16: matrix_reference &operator = (const matrix_reference &m) { Chris@16: expression ().operator = (m); Chris@16: return *this; Chris@16: } Chris@16: template Chris@16: BOOST_UBLAS_INLINE Chris@16: matrix_reference &operator = (const matrix_expression &ae) { Chris@16: expression ().operator = (ae); Chris@16: return *this; Chris@16: } Chris@16: template Chris@16: BOOST_UBLAS_INLINE Chris@16: matrix_reference &assign (const matrix_expression &ae) { Chris@16: expression ().assign (ae); Chris@16: return *this; Chris@16: } Chris@16: template Chris@16: BOOST_UBLAS_INLINE Chris@16: matrix_reference &operator += (const matrix_expression &ae) { Chris@16: expression ().operator += (ae); Chris@16: return *this; Chris@16: } Chris@16: template Chris@16: BOOST_UBLAS_INLINE Chris@16: matrix_reference &plus_assign (const matrix_expression &ae) { Chris@16: expression ().plus_assign (ae); Chris@16: return *this; Chris@16: } Chris@16: template Chris@16: BOOST_UBLAS_INLINE Chris@16: matrix_reference &operator -= (const matrix_expression &ae) { Chris@16: expression ().operator -= (ae); Chris@16: return *this; Chris@16: } Chris@16: template Chris@16: BOOST_UBLAS_INLINE Chris@16: matrix_reference &minus_assign (const matrix_expression &ae) { Chris@16: expression ().minus_assign (ae); Chris@16: return *this; Chris@16: } Chris@16: template Chris@16: BOOST_UBLAS_INLINE Chris@16: matrix_reference &operator *= (const AT &at) { Chris@16: expression ().operator *= (at); Chris@16: return *this; Chris@16: } Chris@16: template Chris@16: BOOST_UBLAS_INLINE Chris@16: matrix_reference &operator /= (const AT &at) { Chris@16: expression ().operator /= (at); Chris@16: return *this; Chris@16: } Chris@16: Chris@16: // Swapping Chris@16: BOOST_UBLAS_INLINE Chris@16: void swap (matrix_reference &m) { Chris@16: expression ().swap (m.expression ()); Chris@16: } Chris@16: Chris@16: // Closure comparison Chris@16: BOOST_UBLAS_INLINE Chris@16: bool same_closure (const matrix_reference &mr) const { Chris@16: return &(*this).e_ == &mr.e_; Chris@16: } Chris@16: Chris@16: // Iterator types Chris@16: typedef typename E::const_iterator1 const_iterator1; Chris@16: typedef typename boost::mpl::if_, Chris@16: typename E::const_iterator1, Chris@16: typename E::iterator1>::type iterator1; Chris@16: typedef typename E::const_iterator2 const_iterator2; Chris@16: typedef typename boost::mpl::if_, Chris@16: typename E::const_iterator2, Chris@16: typename E::iterator2>::type iterator2; Chris@16: Chris@16: // Element lookup Chris@16: BOOST_UBLAS_INLINE Chris@16: const_iterator1 find1 (int rank, size_type i, size_type j) const { Chris@16: return expression ().find1 (rank, i, j); Chris@16: } Chris@16: BOOST_UBLAS_INLINE Chris@16: iterator1 find1 (int rank, size_type i, size_type j) { Chris@16: return expression ().find1 (rank, i, j); Chris@16: } Chris@16: BOOST_UBLAS_INLINE Chris@16: const_iterator2 find2 (int rank, size_type i, size_type j) const { Chris@16: return expression ().find2 (rank, i, j); Chris@16: } Chris@16: BOOST_UBLAS_INLINE Chris@16: iterator2 find2 (int rank, size_type i, size_type j) { Chris@16: return expression ().find2 (rank, i, j); Chris@16: } Chris@16: Chris@16: // Iterators are the iterators of the referenced expression. Chris@16: Chris@16: BOOST_UBLAS_INLINE Chris@16: const_iterator1 begin1 () const { Chris@16: return expression ().begin1 (); Chris@16: } Chris@16: BOOST_UBLAS_INLINE Chris@101: const_iterator1 cbegin1 () const { Chris@101: return begin1 (); Chris@101: } Chris@101: BOOST_UBLAS_INLINE Chris@16: const_iterator1 end1 () const { Chris@16: return expression ().end1 (); Chris@16: } Chris@101: BOOST_UBLAS_INLINE Chris@101: const_iterator1 cend1 () const { Chris@101: return end1 (); Chris@101: } Chris@16: Chris@16: BOOST_UBLAS_INLINE Chris@16: iterator1 begin1 () { Chris@16: return expression ().begin1 (); Chris@16: } Chris@16: BOOST_UBLAS_INLINE Chris@16: iterator1 end1 () { Chris@16: return expression ().end1 (); Chris@16: } Chris@16: Chris@16: BOOST_UBLAS_INLINE Chris@16: const_iterator2 begin2 () const { Chris@16: return expression ().begin2 (); Chris@16: } Chris@16: BOOST_UBLAS_INLINE Chris@101: const_iterator2 cbegin2 () const { Chris@101: return begin2 (); Chris@101: } Chris@101: BOOST_UBLAS_INLINE Chris@16: const_iterator2 end2 () const { Chris@16: return expression ().end2 (); Chris@16: } Chris@101: BOOST_UBLAS_INLINE Chris@101: const_iterator2 cend2 () const { Chris@101: return end2 (); Chris@101: } Chris@16: Chris@16: BOOST_UBLAS_INLINE Chris@16: iterator2 begin2 () { Chris@16: return expression ().begin2 (); Chris@16: } Chris@16: BOOST_UBLAS_INLINE Chris@16: iterator2 end2 () { Chris@16: return expression ().end2 (); Chris@16: } Chris@16: Chris@16: // Reverse iterators Chris@16: typedef reverse_iterator_base1 const_reverse_iterator1; Chris@16: typedef reverse_iterator_base1 reverse_iterator1; Chris@16: Chris@16: BOOST_UBLAS_INLINE Chris@16: const_reverse_iterator1 rbegin1 () const { Chris@16: return const_reverse_iterator1 (end1 ()); Chris@16: } Chris@16: BOOST_UBLAS_INLINE Chris@101: const_reverse_iterator1 crbegin1 () const { Chris@101: return rbegin1 (); Chris@101: } Chris@101: BOOST_UBLAS_INLINE Chris@16: const_reverse_iterator1 rend1 () const { Chris@16: return const_reverse_iterator1 (begin1 ()); Chris@16: } Chris@101: BOOST_UBLAS_INLINE Chris@101: const_reverse_iterator1 crend1 () const { Chris@101: return rend1 (); Chris@101: } Chris@16: Chris@16: BOOST_UBLAS_INLINE Chris@16: reverse_iterator1 rbegin1 () { Chris@16: return reverse_iterator1 (end1 ()); Chris@16: } Chris@16: BOOST_UBLAS_INLINE Chris@16: reverse_iterator1 rend1 () { Chris@16: return reverse_iterator1 (begin1 ()); Chris@16: } Chris@16: Chris@16: typedef reverse_iterator_base2 const_reverse_iterator2; Chris@16: typedef reverse_iterator_base2 reverse_iterator2; Chris@16: Chris@16: BOOST_UBLAS_INLINE Chris@16: const_reverse_iterator2 rbegin2 () const { Chris@16: return const_reverse_iterator2 (end2 ()); Chris@16: } Chris@16: BOOST_UBLAS_INLINE Chris@101: const_reverse_iterator2 crbegin2 () const { Chris@101: return rbegin2 (); Chris@101: } Chris@101: BOOST_UBLAS_INLINE Chris@16: const_reverse_iterator2 rend2 () const { Chris@16: return const_reverse_iterator2 (begin2 ()); Chris@16: } Chris@101: BOOST_UBLAS_INLINE Chris@101: const_reverse_iterator2 crend2 () const { Chris@101: return rend2 (); Chris@101: } Chris@16: Chris@16: BOOST_UBLAS_INLINE Chris@16: reverse_iterator2 rbegin2 () { Chris@16: return reverse_iterator2 (end2 ()); Chris@16: } Chris@16: BOOST_UBLAS_INLINE Chris@16: reverse_iterator2 rend2 () { Chris@16: return reverse_iterator2 (begin2 ()); Chris@16: } Chris@16: Chris@16: private: Chris@16: referred_type &e_; Chris@16: }; Chris@16: Chris@16: Chris@16: template Chris@16: class vector_matrix_binary: Chris@16: public matrix_expression > { Chris@16: Chris@16: typedef E1 expression1_type; Chris@16: typedef E2 expression2_type; Chris@16: public: Chris@16: typedef typename E1::const_closure_type expression1_closure_type; Chris@16: typedef typename E2::const_closure_type expression2_closure_type; Chris@16: private: Chris@16: typedef vector_matrix_binary self_type; Chris@16: public: Chris@16: #ifdef BOOST_UBLAS_ENABLE_PROXY_SHORTCUTS Chris@16: using matrix_expression::operator (); Chris@16: #endif Chris@16: typedef F functor_type; Chris@16: typedef typename promote_traits::promote_type size_type; Chris@16: typedef typename promote_traits::promote_type difference_type; Chris@16: typedef typename F::result_type value_type; Chris@16: typedef value_type const_reference; Chris@16: typedef const_reference reference; Chris@16: typedef const self_type const_closure_type; Chris@16: typedef const_closure_type closure_type; Chris@16: typedef unknown_orientation_tag orientation_category; Chris@16: typedef unknown_storage_tag storage_category; Chris@16: Chris@16: // Construction and destruction Chris@16: BOOST_UBLAS_INLINE Chris@16: vector_matrix_binary (const expression1_type &e1, const expression2_type &e2): Chris@16: e1_ (e1), e2_ (e2) {} Chris@16: Chris@16: // Accessors Chris@16: BOOST_UBLAS_INLINE Chris@16: size_type size1 () const { Chris@16: return e1_.size (); Chris@16: } Chris@16: BOOST_UBLAS_INLINE Chris@16: size_type size2 () const { Chris@16: return e2_.size (); Chris@16: } Chris@16: Chris@16: public: Chris@16: // Expression accessors Chris@16: BOOST_UBLAS_INLINE Chris@16: const expression1_closure_type &expression1 () const { Chris@16: return e1_; Chris@16: } Chris@16: BOOST_UBLAS_INLINE Chris@16: const expression2_closure_type &expression2 () const { Chris@16: return e2_; Chris@16: } Chris@16: Chris@16: public: Chris@16: // Element access Chris@16: BOOST_UBLAS_INLINE Chris@16: const_reference operator () (size_type i, size_type j) const { Chris@16: return functor_type::apply (e1_ (i), e2_ (j)); Chris@16: } Chris@16: Chris@16: // Closure comparison Chris@16: BOOST_UBLAS_INLINE Chris@16: bool same_closure (const vector_matrix_binary &vmb) const { Chris@16: return (*this).expression1 ().same_closure (vmb.expression1 ()) && Chris@16: (*this).expression2 ().same_closure (vmb.expression2 ()); Chris@16: } Chris@16: Chris@16: // Iterator types Chris@16: private: Chris@16: typedef typename E1::const_iterator const_subiterator1_type; Chris@16: typedef typename E2::const_iterator const_subiterator2_type; Chris@16: typedef const value_type *const_pointer; Chris@16: Chris@16: public: Chris@16: #ifdef BOOST_UBLAS_USE_INDEXED_ITERATOR Chris@16: typedef typename iterator_restrict_traits::iterator_category iterator_category; Chris@16: typedef indexed_const_iterator1 const_iterator1; Chris@16: typedef const_iterator1 iterator1; Chris@16: typedef indexed_const_iterator2 const_iterator2; Chris@16: typedef const_iterator2 iterator2; Chris@16: #else Chris@16: class const_iterator1; Chris@16: typedef const_iterator1 iterator1; Chris@16: class const_iterator2; Chris@16: typedef const_iterator2 iterator2; Chris@16: #endif Chris@16: typedef reverse_iterator_base1 const_reverse_iterator1; Chris@16: typedef reverse_iterator_base2 const_reverse_iterator2; Chris@16: Chris@16: // Element lookup Chris@16: BOOST_UBLAS_INLINE Chris@16: const_iterator1 find1 (int rank, size_type i, size_type j) const { Chris@16: const_subiterator1_type it1 (e1_.find (i)); Chris@16: const_subiterator1_type it1_end (e1_.find (size1 ())); Chris@16: const_subiterator2_type it2 (e2_.find (j)); Chris@16: const_subiterator2_type it2_end (e2_.find (size2 ())); Chris@16: if (it2 == it2_end || (rank == 1 && (it2.index () != j || *it2 == value_type/*zero*/()))) { Chris@16: it1 = it1_end; Chris@16: it2 = it2_end; Chris@16: } Chris@16: #ifdef BOOST_UBLAS_USE_INDEXED_ITERATOR Chris@16: return const_iterator1 (*this, it1.index (), it2.index ()); Chris@16: #else Chris@16: #ifdef BOOST_UBLAS_USE_INVARIANT_HOISTING Chris@16: return const_iterator1 (*this, it1, it2, it2 != it2_end ? *it2 : value_type/*zero*/()); Chris@16: #else Chris@16: return const_iterator1 (*this, it1, it2); Chris@16: #endif Chris@16: #endif Chris@16: } Chris@16: BOOST_UBLAS_INLINE Chris@16: const_iterator2 find2 (int rank, size_type i, size_type j) const { Chris@16: const_subiterator2_type it2 (e2_.find (j)); Chris@16: const_subiterator2_type it2_end (e2_.find (size2 ())); Chris@16: const_subiterator1_type it1 (e1_.find (i)); Chris@16: const_subiterator1_type it1_end (e1_.find (size1 ())); Chris@16: if (it1 == it1_end || (rank == 1 && (it1.index () != i || *it1 == value_type/*zero*/()))) { Chris@16: it2 = it2_end; Chris@16: it1 = it1_end; Chris@16: } Chris@16: #ifdef BOOST_UBLAS_USE_INDEXED_ITERATOR Chris@16: return const_iterator2 (*this, it1.index (), it2.index ()); Chris@16: #else Chris@16: #ifdef BOOST_UBLAS_USE_INVARIANT_HOISTING Chris@16: return const_iterator2 (*this, it1, it2, it1 != it1_end ? *it1 : value_type/*zero*/()); Chris@16: #else Chris@16: return const_iterator2 (*this, it1, it2); Chris@16: #endif Chris@16: #endif Chris@16: } Chris@16: Chris@16: // Iterators enhance the iterators of the referenced expressions Chris@16: // with the binary functor. Chris@16: Chris@16: #ifndef BOOST_UBLAS_USE_INDEXED_ITERATOR Chris@16: class const_iterator1: Chris@16: public container_const_reference, Chris@16: public iterator_base_traits::iterator_category>::template Chris@16: iterator_base::type { Chris@16: public: Chris@16: typedef typename iterator_restrict_traits::iterator_category iterator_category; Chris@16: typedef typename vector_matrix_binary::difference_type difference_type; Chris@16: typedef typename vector_matrix_binary::value_type value_type; Chris@16: typedef typename vector_matrix_binary::const_reference reference; Chris@16: typedef typename vector_matrix_binary::const_pointer pointer; Chris@16: Chris@16: typedef const_iterator2 dual_iterator_type; Chris@16: typedef const_reverse_iterator2 dual_reverse_iterator_type; Chris@16: Chris@16: // Construction and destruction Chris@16: #ifdef BOOST_UBLAS_USE_INVARIANT_HOISTING Chris@16: BOOST_UBLAS_INLINE Chris@16: const_iterator1 (): Chris@16: container_const_reference (), it1_ (), it2_ (), t2_ () {} Chris@16: BOOST_UBLAS_INLINE Chris@16: const_iterator1 (const self_type &vmb, const const_subiterator1_type &it1, const const_subiterator2_type &it2, value_type t2): Chris@16: container_const_reference (vmb), it1_ (it1), it2_ (it2), t2_ (t2) {} Chris@16: #else Chris@16: BOOST_UBLAS_INLINE Chris@16: const_iterator1 (): Chris@16: container_const_reference (), it1_ (), it2_ () {} Chris@16: BOOST_UBLAS_INLINE Chris@16: const_iterator1 (const self_type &vmb, const const_subiterator1_type &it1, const const_subiterator2_type &it2): Chris@16: container_const_reference (vmb), it1_ (it1), it2_ (it2) {} Chris@16: #endif Chris@16: Chris@16: // Arithmetic Chris@16: BOOST_UBLAS_INLINE Chris@16: const_iterator1 &operator ++ () { Chris@16: ++ it1_; Chris@16: return *this; Chris@16: } Chris@16: BOOST_UBLAS_INLINE Chris@16: const_iterator1 &operator -- () { Chris@16: -- it1_; Chris@16: return *this; Chris@16: } Chris@16: BOOST_UBLAS_INLINE Chris@16: const_iterator1 &operator += (difference_type n) { Chris@16: it1_ += n; Chris@16: return *this; Chris@16: } Chris@16: BOOST_UBLAS_INLINE Chris@16: const_iterator1 &operator -= (difference_type n) { Chris@16: it1_ -= n; Chris@16: return *this; Chris@16: } Chris@16: BOOST_UBLAS_INLINE Chris@16: difference_type operator - (const const_iterator1 &it) const { Chris@16: BOOST_UBLAS_CHECK ((*this) ().same_closure (it ()), external_logic ()); Chris@16: BOOST_UBLAS_CHECK (it2_ == it.it2_, external_logic ()); Chris@16: return it1_ - it.it1_; Chris@16: } Chris@16: Chris@16: // Dereference Chris@16: BOOST_UBLAS_INLINE Chris@16: const_reference operator * () const { Chris@16: #ifdef BOOST_UBLAS_USE_INVARIANT_HOISTING Chris@16: return functor_type::apply (*it1_, t2_); Chris@16: #else Chris@16: return functor_type::apply (*it1_, *it2_); Chris@16: #endif Chris@16: } Chris@16: BOOST_UBLAS_INLINE Chris@16: const_reference operator [] (difference_type n) const { Chris@16: return *(*this + n); Chris@16: } Chris@16: Chris@16: #ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION Chris@16: BOOST_UBLAS_INLINE Chris@16: #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION Chris@16: typename self_type:: Chris@16: #endif Chris@16: const_iterator2 begin () const { Chris@16: return (*this) ().find2 (1, index1 (), 0); Chris@16: } Chris@16: BOOST_UBLAS_INLINE Chris@16: #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION Chris@16: typename self_type:: Chris@16: #endif Chris@101: const_iterator2 cbegin () const { Chris@101: return begin (); Chris@101: } Chris@101: BOOST_UBLAS_INLINE Chris@101: #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION Chris@101: typename self_type:: Chris@101: #endif Chris@16: const_iterator2 end () const { Chris@16: return (*this) ().find2 (1, index1 (), (*this) ().size2 ()); Chris@16: } Chris@16: BOOST_UBLAS_INLINE Chris@16: #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION Chris@16: typename self_type:: Chris@16: #endif Chris@101: const_iterator2 cend () const { Chris@101: return end (); Chris@101: } Chris@101: BOOST_UBLAS_INLINE Chris@101: #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION Chris@101: typename self_type:: Chris@101: #endif Chris@16: const_reverse_iterator2 rbegin () const { Chris@16: return const_reverse_iterator2 (end ()); Chris@16: } Chris@16: BOOST_UBLAS_INLINE Chris@16: #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION Chris@16: typename self_type:: Chris@16: #endif Chris@101: const_reverse_iterator2 crbegin () const { Chris@101: return rbegin (); Chris@101: } Chris@101: BOOST_UBLAS_INLINE Chris@101: #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION Chris@101: typename self_type:: Chris@101: #endif Chris@16: const_reverse_iterator2 rend () const { Chris@16: return const_reverse_iterator2 (begin ()); Chris@16: } Chris@101: BOOST_UBLAS_INLINE Chris@101: #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION Chris@101: typename self_type:: Chris@101: #endif Chris@101: const_reverse_iterator2 crend () const { Chris@101: return rend (); Chris@101: } Chris@16: #endif Chris@16: Chris@16: // Indices Chris@16: BOOST_UBLAS_INLINE Chris@16: size_type index1 () const { Chris@16: return it1_.index (); Chris@16: } Chris@16: BOOST_UBLAS_INLINE Chris@16: size_type index2 () const { Chris@16: return it2_.index (); Chris@16: } Chris@16: Chris@16: // Assignment Chris@16: BOOST_UBLAS_INLINE Chris@16: const_iterator1 &operator = (const const_iterator1 &it) { Chris@16: container_const_reference::assign (&it ()); Chris@16: it1_ = it.it1_; Chris@16: it2_ = it.it2_; Chris@16: #ifdef BOOST_UBLAS_USE_INVARIANT_HOISTING Chris@16: t2_ = it.t2_; Chris@16: #endif Chris@16: return *this; Chris@16: } Chris@16: Chris@16: // Comparison Chris@16: BOOST_UBLAS_INLINE Chris@16: bool operator == (const const_iterator1 &it) const { Chris@16: BOOST_UBLAS_CHECK ((*this) ().same_closure (it ()), external_logic ()); Chris@16: BOOST_UBLAS_CHECK (it2_ == it.it2_, external_logic ()); Chris@16: return it1_ == it.it1_; Chris@16: } Chris@16: BOOST_UBLAS_INLINE Chris@16: bool operator < (const const_iterator1 &it) const { Chris@16: BOOST_UBLAS_CHECK ((*this) ().same_closure (it ()), external_logic ()); Chris@16: BOOST_UBLAS_CHECK (it2_ == it.it2_, external_logic ()); Chris@16: return it1_ < it.it1_; Chris@16: } Chris@16: Chris@16: private: Chris@16: #ifdef BOOST_UBLAS_USE_INVARIANT_HOISTING Chris@16: const_subiterator1_type it1_; Chris@16: // Mutable due to assignment Chris@16: /* const */ const_subiterator2_type it2_; Chris@16: value_type t2_; Chris@16: #else Chris@16: const_subiterator1_type it1_; Chris@16: const_subiterator2_type it2_; Chris@16: #endif Chris@16: }; Chris@16: #endif Chris@16: Chris@16: BOOST_UBLAS_INLINE Chris@16: const_iterator1 begin1 () const { Chris@16: return find1 (0, 0, 0); Chris@16: } Chris@16: BOOST_UBLAS_INLINE Chris@101: const_iterator1 cbegin1 () const { Chris@101: return begin1 (); Chris@101: } Chris@101: BOOST_UBLAS_INLINE Chris@16: const_iterator1 end1 () const { Chris@16: return find1 (0, size1 (), 0); Chris@16: } Chris@101: BOOST_UBLAS_INLINE Chris@101: const_iterator1 cend1 () const { Chris@101: return end1 (); Chris@101: } Chris@16: Chris@16: #ifndef BOOST_UBLAS_USE_INDEXED_ITERATOR Chris@16: class const_iterator2: Chris@16: public container_const_reference, Chris@16: public iterator_base_traits::iterator_category>::template Chris@16: iterator_base::type { Chris@16: public: Chris@16: typedef typename iterator_restrict_traits::iterator_category iterator_category; Chris@16: typedef typename vector_matrix_binary::difference_type difference_type; Chris@16: typedef typename vector_matrix_binary::value_type value_type; Chris@16: typedef typename vector_matrix_binary::const_reference reference; Chris@16: typedef typename vector_matrix_binary::const_pointer pointer; Chris@16: Chris@16: typedef const_iterator1 dual_iterator_type; Chris@16: typedef const_reverse_iterator1 dual_reverse_iterator_type; Chris@16: Chris@16: // Construction and destruction Chris@16: #ifdef BOOST_UBLAS_USE_INVARIANT_HOISTING Chris@16: BOOST_UBLAS_INLINE Chris@16: const_iterator2 (): Chris@16: container_const_reference (), it1_ (), it2_ (), t1_ () {} Chris@16: BOOST_UBLAS_INLINE Chris@16: const_iterator2 (const self_type &vmb, const const_subiterator1_type &it1, const const_subiterator2_type &it2, value_type t1): Chris@16: container_const_reference (vmb), it1_ (it1), it2_ (it2), t1_ (t1) {} Chris@16: #else Chris@16: BOOST_UBLAS_INLINE Chris@16: const_iterator2 (): Chris@16: container_const_reference (), it1_ (), it2_ () {} Chris@16: BOOST_UBLAS_INLINE Chris@16: const_iterator2 (const self_type &vmb, const const_subiterator1_type &it1, const const_subiterator2_type &it2): Chris@16: container_const_reference (vmb), it1_ (it1), it2_ (it2) {} Chris@16: #endif Chris@16: Chris@16: // Arithmetic Chris@16: BOOST_UBLAS_INLINE Chris@16: const_iterator2 &operator ++ () { Chris@16: ++ it2_; Chris@16: return *this; Chris@16: } Chris@16: BOOST_UBLAS_INLINE Chris@16: const_iterator2 &operator -- () { Chris@16: -- it2_; Chris@16: return *this; Chris@16: } Chris@16: BOOST_UBLAS_INLINE Chris@16: const_iterator2 &operator += (difference_type n) { Chris@16: it2_ += n; Chris@16: return *this; Chris@16: } Chris@16: BOOST_UBLAS_INLINE Chris@16: const_iterator2 &operator -= (difference_type n) { Chris@16: it2_ -= n; Chris@16: return *this; Chris@16: } Chris@16: BOOST_UBLAS_INLINE Chris@16: difference_type operator - (const const_iterator2 &it) const { Chris@16: BOOST_UBLAS_CHECK ((*this) ().same_closure(it ()), external_logic ()); Chris@16: BOOST_UBLAS_CHECK (it1_ == it.it1_, external_logic ()); Chris@16: return it2_ - it.it2_; Chris@16: } Chris@16: Chris@16: // Dereference Chris@16: BOOST_UBLAS_INLINE Chris@16: const_reference operator * () const { Chris@16: #ifdef BOOST_UBLAS_USE_INVARIANT_HOISTING Chris@16: return functor_type::apply (t1_, *it2_); Chris@16: #else Chris@16: return functor_type::apply (*it1_, *it2_); Chris@16: #endif Chris@16: } Chris@16: BOOST_UBLAS_INLINE Chris@16: const_reference operator [] (difference_type n) const { Chris@16: return *(*this + n); Chris@16: } Chris@16: Chris@16: #ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION Chris@16: BOOST_UBLAS_INLINE Chris@16: #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION Chris@16: typename self_type:: Chris@16: #endif Chris@16: const_iterator1 begin () const { Chris@16: return (*this) ().find1 (1, 0, index2 ()); Chris@16: } Chris@16: BOOST_UBLAS_INLINE Chris@16: #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION Chris@16: typename self_type:: Chris@16: #endif Chris@101: const_iterator1 cbegin () const { Chris@101: return begin (); Chris@101: } Chris@101: BOOST_UBLAS_INLINE Chris@101: #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION Chris@101: typename self_type:: Chris@101: #endif Chris@16: const_iterator1 end () const { Chris@16: return (*this) ().find1 (1, (*this) ().size1 (), index2 ()); Chris@16: } Chris@16: BOOST_UBLAS_INLINE Chris@16: #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION Chris@16: typename self_type:: Chris@16: #endif Chris@101: const_iterator1 cend () const { Chris@101: return end (); Chris@101: } Chris@101: BOOST_UBLAS_INLINE Chris@101: #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION Chris@101: typename self_type:: Chris@101: #endif Chris@16: const_reverse_iterator1 rbegin () const { Chris@16: return const_reverse_iterator1 (end ()); Chris@16: } Chris@16: BOOST_UBLAS_INLINE Chris@16: #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION Chris@16: typename self_type:: Chris@16: #endif Chris@101: const_reverse_iterator1 crbegin () const { Chris@101: return rbegin (); Chris@101: } Chris@101: BOOST_UBLAS_INLINE Chris@101: #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION Chris@101: typename self_type:: Chris@101: #endif Chris@16: const_reverse_iterator1 rend () const { Chris@16: return const_reverse_iterator1 (begin ()); Chris@16: } Chris@101: BOOST_UBLAS_INLINE Chris@101: #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION Chris@101: typename self_type:: Chris@101: #endif Chris@101: const_reverse_iterator1 crend () const { Chris@101: return rend (); Chris@101: } Chris@16: #endif Chris@16: Chris@16: // Indices Chris@16: BOOST_UBLAS_INLINE Chris@16: size_type index1 () const { Chris@16: return it1_.index (); Chris@16: } Chris@16: BOOST_UBLAS_INLINE Chris@16: size_type index2 () const { Chris@16: return it2_.index (); Chris@16: } Chris@16: Chris@16: // Assignment Chris@16: BOOST_UBLAS_INLINE Chris@16: const_iterator2 &operator = (const const_iterator2 &it) { Chris@16: container_const_reference::assign (&it ()); Chris@16: it1_ = it.it1_; Chris@16: it2_ = it.it2_; Chris@16: #ifdef BOOST_UBLAS_USE_INVARIANT_HOISTING Chris@16: t1_ = it.t1_; Chris@16: #endif Chris@16: return *this; Chris@16: } Chris@16: Chris@16: // Comparison Chris@16: BOOST_UBLAS_INLINE Chris@16: bool operator == (const const_iterator2 &it) const { Chris@16: BOOST_UBLAS_CHECK ((*this) ().same_closure( it ()), external_logic ()); Chris@16: BOOST_UBLAS_CHECK (it1_ == it.it1_, external_logic ()); Chris@16: return it2_ == it.it2_; Chris@16: } Chris@16: BOOST_UBLAS_INLINE Chris@16: bool operator < (const const_iterator2 &it) const { Chris@16: BOOST_UBLAS_CHECK ((*this) ().same_closure (it ()), external_logic ()); Chris@16: BOOST_UBLAS_CHECK (it1_ == it.it1_, external_logic ()); Chris@16: return it2_ < it.it2_; Chris@16: } Chris@16: Chris@16: private: Chris@16: #ifdef BOOST_UBLAS_USE_INVARIANT_HOISTING Chris@16: // Mutable due to assignment Chris@16: /* const */ const_subiterator1_type it1_; Chris@16: const_subiterator2_type it2_; Chris@16: value_type t1_; Chris@16: #else Chris@16: const_subiterator1_type it1_; Chris@16: const_subiterator2_type it2_; Chris@16: #endif Chris@16: }; Chris@16: #endif Chris@16: Chris@16: BOOST_UBLAS_INLINE Chris@16: const_iterator2 begin2 () const { Chris@16: return find2 (0, 0, 0); Chris@16: } Chris@16: BOOST_UBLAS_INLINE Chris@101: const_iterator2 cbegin2 () const { Chris@101: return begin2 (); Chris@101: } Chris@101: BOOST_UBLAS_INLINE Chris@16: const_iterator2 end2 () const { Chris@16: return find2 (0, 0, size2 ()); Chris@16: } Chris@101: BOOST_UBLAS_INLINE Chris@101: const_iterator2 cend2 () const { Chris@101: return end2 (); Chris@101: } Chris@16: Chris@16: // Reverse iterators Chris@16: Chris@16: BOOST_UBLAS_INLINE Chris@16: const_reverse_iterator1 rbegin1 () const { Chris@16: return const_reverse_iterator1 (end1 ()); Chris@16: } Chris@16: BOOST_UBLAS_INLINE Chris@101: const_reverse_iterator1 crbegin1 () const { Chris@101: return rbegin1 (); Chris@101: } Chris@101: BOOST_UBLAS_INLINE Chris@16: const_reverse_iterator1 rend1 () const { Chris@16: return const_reverse_iterator1 (begin1 ()); Chris@16: } Chris@101: BOOST_UBLAS_INLINE Chris@101: const_reverse_iterator1 crend1 () const { Chris@101: return rend1 (); Chris@101: } Chris@16: BOOST_UBLAS_INLINE Chris@16: const_reverse_iterator2 rbegin2 () const { Chris@16: return const_reverse_iterator2 (end2 ()); Chris@16: } Chris@16: BOOST_UBLAS_INLINE Chris@101: const_reverse_iterator2 crbegin2 () const { Chris@101: return rbegin2 (); Chris@101: } Chris@101: BOOST_UBLAS_INLINE Chris@16: const_reverse_iterator2 rend2 () const { Chris@16: return const_reverse_iterator2 (begin2 ()); Chris@16: } Chris@101: BOOST_UBLAS_INLINE Chris@101: const_reverse_iterator2 crend2 () const { Chris@101: return rend2 (); Chris@101: } Chris@16: Chris@16: private: Chris@16: expression1_closure_type e1_; Chris@16: expression2_closure_type e2_; Chris@16: }; Chris@16: Chris@16: template Chris@16: struct vector_matrix_binary_traits { Chris@16: typedef vector_matrix_binary expression_type; Chris@16: #ifndef BOOST_UBLAS_SIMPLE_ET_DEBUG Chris@16: typedef expression_type result_type; Chris@16: #else Chris@16: // ISSUE matrix is arbitary temporary type Chris@16: typedef matrix result_type; Chris@16: #endif Chris@16: }; Chris@16: Chris@16: // (outer_prod (v1, v2)) [i] [j] = v1 [i] * v2 [j] Chris@16: template Chris@16: BOOST_UBLAS_INLINE Chris@16: typename vector_matrix_binary_traits >::result_type Chris@16: outer_prod (const vector_expression &e1, Chris@16: const vector_expression &e2) { Chris@16: BOOST_STATIC_ASSERT (E1::complexity == 0 && E2::complexity == 0); Chris@16: typedef typename vector_matrix_binary_traits >::expression_type expression_type; Chris@16: return expression_type (e1 (), e2 ()); Chris@16: } Chris@16: Chris@16: template Chris@16: class matrix_unary1: Chris@16: public matrix_expression > { Chris@16: Chris@16: typedef E expression_type; Chris@16: typedef F functor_type; Chris@16: public: Chris@16: typedef typename E::const_closure_type expression_closure_type; Chris@16: private: Chris@16: typedef matrix_unary1 self_type; Chris@16: public: Chris@16: #ifdef BOOST_UBLAS_ENABLE_PROXY_SHORTCUTS Chris@16: using matrix_expression::operator (); Chris@16: #endif Chris@16: typedef typename E::size_type size_type; Chris@16: typedef typename E::difference_type difference_type; Chris@16: typedef typename F::result_type value_type; Chris@16: typedef value_type const_reference; Chris@16: typedef const_reference reference; Chris@16: typedef const self_type const_closure_type; Chris@16: typedef const_closure_type closure_type; Chris@16: typedef typename E::orientation_category orientation_category; Chris@16: typedef unknown_storage_tag storage_category; Chris@16: Chris@16: // Construction and destruction Chris@16: BOOST_UBLAS_INLINE Chris@16: explicit matrix_unary1 (const expression_type &e): Chris@16: e_ (e) {} Chris@16: Chris@16: // Accessors Chris@16: BOOST_UBLAS_INLINE Chris@16: size_type size1 () const { Chris@16: return e_.size1 (); Chris@16: } Chris@16: BOOST_UBLAS_INLINE Chris@16: size_type size2 () const { Chris@16: return e_.size2 (); Chris@16: } Chris@16: Chris@16: public: Chris@16: // Expression accessors Chris@16: BOOST_UBLAS_INLINE Chris@16: const expression_closure_type &expression () const { Chris@16: return e_; Chris@16: } Chris@16: Chris@16: public: Chris@16: // Element access Chris@16: BOOST_UBLAS_INLINE Chris@16: const_reference operator () (size_type i, size_type j) const { Chris@16: return functor_type::apply (e_ (i, j)); Chris@16: } Chris@16: Chris@16: // Closure comparison Chris@16: BOOST_UBLAS_INLINE Chris@16: bool same_closure (const matrix_unary1 &mu1) const { Chris@16: return (*this).expression ().same_closure (mu1.expression ()); Chris@16: } Chris@16: Chris@16: // Iterator types Chris@16: private: Chris@16: typedef typename E::const_iterator1 const_subiterator1_type; Chris@16: typedef typename E::const_iterator2 const_subiterator2_type; Chris@16: typedef const value_type *const_pointer; Chris@16: Chris@16: public: Chris@16: #ifdef BOOST_UBLAS_USE_INDEXED_ITERATOR Chris@16: typedef indexed_const_iterator1 const_iterator1; Chris@16: typedef const_iterator1 iterator1; Chris@16: typedef indexed_const_iterator2 const_iterator2; Chris@16: typedef const_iterator2 iterator2; Chris@16: #else Chris@16: class const_iterator1; Chris@16: typedef const_iterator1 iterator1; Chris@16: class const_iterator2; Chris@16: typedef const_iterator2 iterator2; Chris@16: #endif Chris@16: typedef reverse_iterator_base1 const_reverse_iterator1; Chris@16: typedef reverse_iterator_base2 const_reverse_iterator2; Chris@16: Chris@16: // Element lookup Chris@16: BOOST_UBLAS_INLINE Chris@16: const_iterator1 find1 (int rank, size_type i, size_type j) const { Chris@16: const_subiterator1_type it1 (e_.find1 (rank, i, j)); Chris@16: #ifdef BOOST_UBLAS_USE_INDEXED_ITERATOR Chris@16: return const_iterator1 (*this, it1.index1 (), it1.index2 ()); Chris@16: #else Chris@16: return const_iterator1 (*this, it1); Chris@16: #endif Chris@16: } Chris@16: BOOST_UBLAS_INLINE Chris@16: const_iterator2 find2 (int rank, size_type i, size_type j) const { Chris@16: const_subiterator2_type it2 (e_.find2 (rank, i, j)); Chris@16: #ifdef BOOST_UBLAS_USE_INDEXED_ITERATOR Chris@16: return const_iterator2 (*this, it2.index1 (), it2.index2 ()); Chris@16: #else Chris@16: return const_iterator2 (*this, it2); Chris@16: #endif Chris@16: } Chris@16: Chris@16: // Iterators enhance the iterators of the referenced expression Chris@16: // with the unary functor. Chris@16: Chris@16: #ifndef BOOST_UBLAS_USE_INDEXED_ITERATOR Chris@16: class const_iterator1: Chris@16: public container_const_reference, Chris@16: public iterator_base_traits::template Chris@16: iterator_base::type { Chris@16: public: Chris@16: typedef typename E::const_iterator1::iterator_category iterator_category; Chris@16: typedef typename matrix_unary1::difference_type difference_type; Chris@16: typedef typename matrix_unary1::value_type value_type; Chris@16: typedef typename matrix_unary1::const_reference reference; Chris@16: typedef typename matrix_unary1::const_pointer pointer; Chris@16: Chris@16: typedef const_iterator2 dual_iterator_type; Chris@16: typedef const_reverse_iterator2 dual_reverse_iterator_type; Chris@16: Chris@16: // Construction and destruction Chris@16: BOOST_UBLAS_INLINE Chris@16: const_iterator1 (): Chris@16: container_const_reference (), it_ () {} Chris@16: BOOST_UBLAS_INLINE Chris@16: const_iterator1 (const self_type &mu, const const_subiterator1_type &it): Chris@16: container_const_reference (mu), it_ (it) {} Chris@16: Chris@16: // Arithmetic Chris@16: BOOST_UBLAS_INLINE Chris@16: const_iterator1 &operator ++ () { Chris@16: ++ it_; Chris@16: return *this; Chris@16: } Chris@16: BOOST_UBLAS_INLINE Chris@16: const_iterator1 &operator -- () { Chris@16: -- it_; Chris@16: return *this; Chris@16: } Chris@16: BOOST_UBLAS_INLINE Chris@16: const_iterator1 &operator += (difference_type n) { Chris@16: it_ += n; Chris@16: return *this; Chris@16: } Chris@16: BOOST_UBLAS_INLINE Chris@16: const_iterator1 &operator -= (difference_type n) { Chris@16: it_ -= n; Chris@16: return *this; Chris@16: } Chris@16: BOOST_UBLAS_INLINE Chris@16: difference_type operator - (const const_iterator1 &it) const { Chris@16: BOOST_UBLAS_CHECK ((*this) ().same_closure (it ()), external_logic ()); Chris@16: return it_ - it.it_; Chris@16: } Chris@16: Chris@16: // Dereference Chris@16: BOOST_UBLAS_INLINE Chris@16: const_reference operator * () const { Chris@16: return functor_type::apply (*it_); Chris@16: } Chris@16: BOOST_UBLAS_INLINE Chris@16: const_reference operator [] (difference_type n) const { Chris@16: return *(*this + n); Chris@16: } Chris@16: Chris@16: #ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION Chris@16: BOOST_UBLAS_INLINE Chris@16: #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION Chris@16: typename self_type:: Chris@16: #endif Chris@16: const_iterator2 begin () const { Chris@16: return (*this) ().find2 (1, index1 (), 0); Chris@16: } Chris@16: BOOST_UBLAS_INLINE Chris@16: #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION Chris@16: typename self_type:: Chris@16: #endif Chris@101: const_iterator2 cbegin () const { Chris@101: return begin (); Chris@101: } Chris@101: BOOST_UBLAS_INLINE Chris@101: #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION Chris@101: typename self_type:: Chris@101: #endif Chris@16: const_iterator2 end () const { Chris@16: return (*this) ().find2 (1, index1 (), (*this) ().size2 ()); Chris@16: } Chris@16: BOOST_UBLAS_INLINE Chris@16: #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION Chris@16: typename self_type:: Chris@16: #endif Chris@101: const_iterator2 cend () const { Chris@101: return end (); Chris@101: } Chris@101: BOOST_UBLAS_INLINE Chris@101: #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION Chris@101: typename self_type:: Chris@101: #endif Chris@16: const_reverse_iterator2 rbegin () const { Chris@16: return const_reverse_iterator2 (end ()); Chris@16: } Chris@16: BOOST_UBLAS_INLINE Chris@16: #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION Chris@16: typename self_type:: Chris@16: #endif Chris@101: const_reverse_iterator2 crbegin () const { Chris@101: return rbegin (); Chris@101: } Chris@101: BOOST_UBLAS_INLINE Chris@101: #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION Chris@101: typename self_type:: Chris@101: #endif Chris@16: const_reverse_iterator2 rend () const { Chris@16: return const_reverse_iterator2 (begin ()); Chris@16: } Chris@101: BOOST_UBLAS_INLINE Chris@101: #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION Chris@101: typename self_type:: Chris@101: #endif Chris@101: const_reverse_iterator2 crend () const { Chris@101: return rend (); Chris@101: } Chris@16: #endif Chris@16: Chris@16: // Indices Chris@16: BOOST_UBLAS_INLINE Chris@16: size_type index1 () const { Chris@16: return it_.index1 (); Chris@16: } Chris@16: BOOST_UBLAS_INLINE Chris@16: size_type index2 () const { Chris@16: return it_.index2 (); Chris@16: } Chris@16: Chris@16: // Assignment Chris@16: BOOST_UBLAS_INLINE Chris@16: const_iterator1 &operator = (const const_iterator1 &it) { Chris@16: container_const_reference::assign (&it ()); Chris@16: it_ = it.it_; Chris@16: return *this; Chris@16: } Chris@16: Chris@16: // Comparison Chris@16: BOOST_UBLAS_INLINE Chris@16: bool operator == (const const_iterator1 &it) const { Chris@16: BOOST_UBLAS_CHECK ((*this) ().same_closure (it ()), external_logic ()); Chris@16: return it_ == it.it_; Chris@16: } Chris@16: BOOST_UBLAS_INLINE Chris@16: bool operator < (const const_iterator1 &it) const { Chris@16: BOOST_UBLAS_CHECK ((*this) ().same_closure (it ()), external_logic ()); Chris@16: return it_ < it.it_; Chris@16: } Chris@16: Chris@16: private: Chris@16: const_subiterator1_type it_; Chris@16: }; Chris@16: #endif Chris@16: Chris@16: BOOST_UBLAS_INLINE Chris@16: const_iterator1 begin1 () const { Chris@16: return find1 (0, 0, 0); Chris@16: } Chris@16: BOOST_UBLAS_INLINE Chris@101: const_iterator1 cbegin1 () const { Chris@101: return begin1 (); Chris@101: } Chris@101: BOOST_UBLAS_INLINE Chris@16: const_iterator1 end1 () const { Chris@16: return find1 (0, size1 (), 0); Chris@16: } Chris@101: BOOST_UBLAS_INLINE Chris@101: const_iterator1 cend1 () const { Chris@101: return end1 (); Chris@101: } Chris@16: Chris@16: #ifndef BOOST_UBLAS_USE_INDEXED_ITERATOR Chris@16: class const_iterator2: Chris@16: public container_const_reference, Chris@16: public iterator_base_traits::template Chris@16: iterator_base::type { Chris@16: public: Chris@16: typedef typename E::const_iterator2::iterator_category iterator_category; Chris@16: typedef typename matrix_unary1::difference_type difference_type; Chris@16: typedef typename matrix_unary1::value_type value_type; Chris@16: typedef typename matrix_unary1::const_reference reference; Chris@16: typedef typename matrix_unary1::const_pointer pointer; Chris@16: Chris@16: typedef const_iterator1 dual_iterator_type; Chris@16: typedef const_reverse_iterator1 dual_reverse_iterator_type; Chris@16: Chris@16: // Construction and destruction Chris@16: BOOST_UBLAS_INLINE Chris@16: const_iterator2 (): Chris@16: container_const_reference (), it_ () {} Chris@16: BOOST_UBLAS_INLINE Chris@16: const_iterator2 (const self_type &mu, const const_subiterator2_type &it): Chris@16: container_const_reference (mu), it_ (it) {} Chris@16: Chris@16: // Arithmetic Chris@16: BOOST_UBLAS_INLINE Chris@16: const_iterator2 &operator ++ () { Chris@16: ++ it_; Chris@16: return *this; Chris@16: } Chris@16: BOOST_UBLAS_INLINE Chris@16: const_iterator2 &operator -- () { Chris@16: -- it_; Chris@16: return *this; Chris@16: } Chris@16: BOOST_UBLAS_INLINE Chris@16: const_iterator2 &operator += (difference_type n) { Chris@16: it_ += n; Chris@16: return *this; Chris@16: } Chris@16: BOOST_UBLAS_INLINE Chris@16: const_iterator2 &operator -= (difference_type n) { Chris@16: it_ -= n; Chris@16: return *this; Chris@16: } Chris@16: BOOST_UBLAS_INLINE Chris@16: difference_type operator - (const const_iterator2 &it) const { Chris@16: BOOST_UBLAS_CHECK ((*this) ().same_closure (it ()), external_logic ()); Chris@16: return it_ - it.it_; Chris@16: } Chris@16: Chris@16: // Dereference Chris@16: BOOST_UBLAS_INLINE Chris@16: const_reference operator * () const { Chris@16: return functor_type::apply (*it_); Chris@16: } Chris@16: BOOST_UBLAS_INLINE Chris@16: const_reference operator [] (difference_type n) const { Chris@16: return *(*this + n); Chris@16: } Chris@16: Chris@16: #ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION Chris@16: BOOST_UBLAS_INLINE Chris@16: #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION Chris@16: typename self_type:: Chris@16: #endif Chris@16: const_iterator1 begin () const { Chris@16: return (*this) ().find1 (1, 0, index2 ()); Chris@16: } Chris@16: BOOST_UBLAS_INLINE Chris@16: #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION Chris@16: typename self_type:: Chris@16: #endif Chris@101: const_iterator1 cbegin () const { Chris@101: return begin (); Chris@101: } Chris@101: BOOST_UBLAS_INLINE Chris@101: #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION Chris@101: typename self_type:: Chris@101: #endif Chris@16: const_iterator1 end () const { Chris@16: return (*this) ().find1 (1, (*this) ().size1 (), index2 ()); Chris@16: } Chris@16: BOOST_UBLAS_INLINE Chris@16: #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION Chris@16: typename self_type:: Chris@16: #endif Chris@101: const_iterator1 cend () const { Chris@101: return end (); Chris@101: } Chris@101: BOOST_UBLAS_INLINE Chris@101: #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION Chris@101: typename self_type:: Chris@101: #endif Chris@16: const_reverse_iterator1 rbegin () const { Chris@16: return const_reverse_iterator1 (end ()); Chris@16: } Chris@16: BOOST_UBLAS_INLINE Chris@16: #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION Chris@16: typename self_type:: Chris@16: #endif Chris@101: const_reverse_iterator1 crbegin () const { Chris@101: return rbegin (); Chris@101: } Chris@101: BOOST_UBLAS_INLINE Chris@101: #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION Chris@101: typename self_type:: Chris@101: #endif Chris@16: const_reverse_iterator1 rend () const { Chris@16: return const_reverse_iterator1 (begin ()); Chris@16: } Chris@101: BOOST_UBLAS_INLINE Chris@101: #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION Chris@101: typename self_type:: Chris@101: #endif Chris@101: const_reverse_iterator1 crend () const { Chris@101: return rend (); Chris@101: } Chris@16: #endif Chris@16: Chris@16: // Indices Chris@16: BOOST_UBLAS_INLINE Chris@16: size_type index1 () const { Chris@16: return it_.index1 (); Chris@16: } Chris@16: BOOST_UBLAS_INLINE Chris@16: size_type index2 () const { Chris@16: return it_.index2 (); Chris@16: } Chris@16: Chris@16: // Assignment Chris@16: BOOST_UBLAS_INLINE Chris@16: const_iterator2 &operator = (const const_iterator2 &it) { Chris@16: container_const_reference::assign (&it ()); Chris@16: it_ = it.it_; Chris@16: return *this; Chris@16: } Chris@16: Chris@16: // Comparison Chris@16: BOOST_UBLAS_INLINE Chris@16: bool operator == (const const_iterator2 &it) const { Chris@16: BOOST_UBLAS_CHECK ((*this) ().same_closure (it ()), external_logic ()); Chris@16: return it_ == it.it_; Chris@16: } Chris@16: BOOST_UBLAS_INLINE Chris@16: bool operator < (const const_iterator2 &it) const { Chris@16: BOOST_UBLAS_CHECK ((*this) ().same_closure (it ()), external_logic ()); Chris@16: return it_ < it.it_; Chris@16: } Chris@16: Chris@16: private: Chris@16: const_subiterator2_type it_; Chris@16: }; Chris@16: #endif Chris@16: Chris@16: BOOST_UBLAS_INLINE Chris@16: const_iterator2 begin2 () const { Chris@16: return find2 (0, 0, 0); Chris@16: } Chris@16: BOOST_UBLAS_INLINE Chris@101: const_iterator2 cbegin2 () const { Chris@101: return begin2 (); Chris@101: } Chris@101: BOOST_UBLAS_INLINE Chris@16: const_iterator2 end2 () const { Chris@16: return find2 (0, 0, size2 ()); Chris@16: } Chris@101: BOOST_UBLAS_INLINE Chris@101: const_iterator2 cend2 () const { Chris@101: return end2 (); Chris@101: } Chris@16: Chris@16: // Reverse iterators Chris@16: Chris@16: BOOST_UBLAS_INLINE Chris@16: const_reverse_iterator1 rbegin1 () const { Chris@16: return const_reverse_iterator1 (end1 ()); Chris@16: } Chris@16: BOOST_UBLAS_INLINE Chris@101: const_reverse_iterator1 crbegin1 () const { Chris@101: return rbegin1 (); Chris@101: } Chris@101: BOOST_UBLAS_INLINE Chris@16: const_reverse_iterator1 rend1 () const { Chris@16: return const_reverse_iterator1 (begin1 ()); Chris@16: } Chris@101: BOOST_UBLAS_INLINE Chris@101: const_reverse_iterator1 crend1 () const { Chris@101: return rend1 (); Chris@101: } Chris@16: Chris@16: BOOST_UBLAS_INLINE Chris@16: const_reverse_iterator2 rbegin2 () const { Chris@16: return const_reverse_iterator2 (end2 ()); Chris@16: } Chris@16: BOOST_UBLAS_INLINE Chris@101: const_reverse_iterator2 crbegin2 () const { Chris@101: return rbegin2 (); Chris@101: } Chris@101: BOOST_UBLAS_INLINE Chris@16: const_reverse_iterator2 rend2 () const { Chris@16: return const_reverse_iterator2 (begin2 ()); Chris@16: } Chris@101: BOOST_UBLAS_INLINE Chris@101: const_reverse_iterator2 crend2 () const { Chris@101: return rend2 (); Chris@101: } Chris@16: Chris@16: private: Chris@16: expression_closure_type e_; Chris@16: }; Chris@16: Chris@16: template Chris@16: struct matrix_unary1_traits { Chris@16: typedef matrix_unary1 expression_type; Chris@16: #ifndef BOOST_UBLAS_SIMPLE_ET_DEBUG Chris@16: typedef expression_type result_type; Chris@16: #else Chris@16: typedef typename E::matrix_temporary_type result_type; Chris@16: #endif Chris@16: }; Chris@16: Chris@16: // (- m) [i] [j] = - m [i] [j] Chris@16: template Chris@16: BOOST_UBLAS_INLINE Chris@16: typename matrix_unary1_traits >::result_type Chris@16: operator - (const matrix_expression &e) { Chris@16: typedef typename matrix_unary1_traits >::expression_type expression_type; Chris@16: return expression_type (e ()); Chris@16: } Chris@16: Chris@16: // (conj m) [i] [j] = conj (m [i] [j]) Chris@16: template Chris@16: BOOST_UBLAS_INLINE Chris@16: typename matrix_unary1_traits >::result_type Chris@16: conj (const matrix_expression &e) { Chris@16: typedef typename matrix_unary1_traits >::expression_type expression_type; Chris@16: return expression_type (e ()); Chris@16: } Chris@16: Chris@16: // (real m) [i] [j] = real (m [i] [j]) Chris@16: template Chris@16: BOOST_UBLAS_INLINE Chris@16: typename matrix_unary1_traits >::result_type Chris@16: real (const matrix_expression &e) { Chris@16: typedef typename matrix_unary1_traits >::expression_type expression_type; Chris@16: return expression_type (e ()); Chris@16: } Chris@16: Chris@16: // (imag m) [i] [j] = imag (m [i] [j]) Chris@16: template Chris@16: BOOST_UBLAS_INLINE Chris@16: typename matrix_unary1_traits >::result_type Chris@16: imag (const matrix_expression &e) { Chris@16: typedef typename matrix_unary1_traits >::expression_type expression_type; Chris@16: return expression_type (e ()); Chris@16: } Chris@16: Chris@16: template Chris@16: class matrix_unary2: Chris@16: public matrix_expression > { Chris@16: Chris@16: typedef typename boost::mpl::if_ >, Chris@16: E, Chris@16: const E>::type expression_type; Chris@16: typedef F functor_type; Chris@16: public: Chris@16: typedef typename boost::mpl::if_, Chris@16: typename E::const_closure_type, Chris@16: typename E::closure_type>::type expression_closure_type; Chris@16: private: Chris@16: typedef matrix_unary2 self_type; Chris@16: public: Chris@16: #ifdef BOOST_UBLAS_ENABLE_PROXY_SHORTCUTS Chris@16: using matrix_expression::operator (); Chris@16: #endif Chris@16: typedef typename E::size_type size_type; Chris@16: typedef typename E::difference_type difference_type; Chris@16: typedef typename F::result_type value_type; Chris@16: typedef value_type const_reference; Chris@16: typedef typename boost::mpl::if_ >, Chris@16: typename E::reference, Chris@16: value_type>::type reference; Chris@16: Chris@16: typedef const self_type const_closure_type; Chris@16: typedef self_type closure_type; Chris@16: typedef typename boost::mpl::if_, Chris@16: column_major_tag, Chris@16: typename boost::mpl::if_, Chris@16: row_major_tag, Chris@16: typename E::orientation_category>::type>::type orientation_category; Chris@16: typedef typename E::storage_category storage_category; Chris@16: Chris@16: // Construction and destruction Chris@16: BOOST_UBLAS_INLINE Chris@16: // matrix_unary2 may be used as mutable expression - Chris@16: // this is the only non const expression constructor Chris@16: explicit matrix_unary2 (expression_type &e): Chris@16: e_ (e) {} Chris@16: Chris@16: // Accessors Chris@16: BOOST_UBLAS_INLINE Chris@16: size_type size1 () const { Chris@16: return e_.size2 (); Chris@16: } Chris@16: BOOST_UBLAS_INLINE Chris@16: size_type size2 () const { Chris@16: return e_.size1 (); Chris@16: } Chris@16: Chris@16: public: Chris@16: // Expression accessors Chris@16: BOOST_UBLAS_INLINE Chris@16: const expression_closure_type &expression () const { Chris@16: return e_; Chris@16: } Chris@16: Chris@16: public: Chris@16: // Element access Chris@16: BOOST_UBLAS_INLINE Chris@16: const_reference operator () (size_type i, size_type j) const { Chris@16: return functor_type::apply (e_ (j, i)); Chris@16: } Chris@16: BOOST_UBLAS_INLINE Chris@16: reference operator () (size_type i, size_type j) { Chris@16: BOOST_STATIC_ASSERT ((boost::is_same >::value)); Chris@16: return e_ (j, i); Chris@16: } Chris@16: Chris@16: // Closure comparison Chris@16: BOOST_UBLAS_INLINE Chris@16: bool same_closure (const matrix_unary2 &mu2) const { Chris@16: return (*this).expression ().same_closure (mu2.expression ()); Chris@16: } Chris@16: Chris@16: // Iterator types Chris@16: private: Chris@16: typedef typename E::const_iterator1 const_subiterator2_type; Chris@16: typedef typename E::const_iterator2 const_subiterator1_type; Chris@16: typedef const value_type *const_pointer; Chris@16: Chris@16: public: Chris@16: #ifdef BOOST_UBLAS_USE_INDEXED_ITERATOR Chris@16: typedef indexed_const_iterator1 const_iterator1; Chris@16: typedef const_iterator1 iterator1; Chris@16: typedef indexed_const_iterator2 const_iterator2; Chris@16: typedef const_iterator2 iterator2; Chris@16: #else Chris@16: class const_iterator1; Chris@16: typedef const_iterator1 iterator1; Chris@16: class const_iterator2; Chris@16: typedef const_iterator2 iterator2; Chris@16: #endif Chris@16: typedef reverse_iterator_base1 const_reverse_iterator1; Chris@16: typedef reverse_iterator_base2 const_reverse_iterator2; Chris@16: Chris@16: // Element lookup Chris@16: BOOST_UBLAS_INLINE Chris@16: const_iterator1 find1 (int rank, size_type i, size_type j) const { Chris@16: const_subiterator1_type it1 (e_.find2 (rank, j, i)); Chris@16: #ifdef BOOST_UBLAS_USE_INDEXED_ITERATOR Chris@16: return const_iterator1 (*this, it1.index2 (), it1.index1 ()); Chris@16: #else Chris@16: return const_iterator1 (*this, it1); Chris@16: #endif Chris@16: } Chris@16: BOOST_UBLAS_INLINE Chris@16: const_iterator2 find2 (int rank, size_type i, size_type j) const { Chris@16: const_subiterator2_type it2 (e_.find1 (rank, j, i)); Chris@16: #ifdef BOOST_UBLAS_USE_INDEXED_ITERATOR Chris@16: return const_iterator2 (*this, it2.index2 (), it2.index1 ()); Chris@16: #else Chris@16: return const_iterator2 (*this, it2); Chris@16: #endif Chris@16: } Chris@16: Chris@16: // Iterators enhance the iterators of the referenced expression Chris@16: // with the unary functor. Chris@16: Chris@16: #ifndef BOOST_UBLAS_USE_INDEXED_ITERATOR Chris@16: class const_iterator1: Chris@16: public container_const_reference, Chris@16: public iterator_base_traits::template Chris@16: iterator_base::type { Chris@16: public: Chris@16: typedef typename E::const_iterator2::iterator_category iterator_category; Chris@16: typedef typename matrix_unary2::difference_type difference_type; Chris@16: typedef typename matrix_unary2::value_type value_type; Chris@16: typedef typename matrix_unary2::const_reference reference; Chris@16: typedef typename matrix_unary2::const_pointer pointer; Chris@16: Chris@16: typedef const_iterator2 dual_iterator_type; Chris@16: typedef const_reverse_iterator2 dual_reverse_iterator_type; Chris@16: Chris@16: // Construction and destruction Chris@16: BOOST_UBLAS_INLINE Chris@16: const_iterator1 (): Chris@16: container_const_reference (), it_ () {} Chris@16: BOOST_UBLAS_INLINE Chris@16: const_iterator1 (const self_type &mu, const const_subiterator1_type &it): Chris@16: container_const_reference (mu), it_ (it) {} Chris@16: Chris@16: // Arithmetic Chris@16: BOOST_UBLAS_INLINE Chris@16: const_iterator1 &operator ++ () { Chris@16: ++ it_; Chris@16: return *this; Chris@16: } Chris@16: BOOST_UBLAS_INLINE Chris@16: const_iterator1 &operator -- () { Chris@16: -- it_; Chris@16: return *this; Chris@16: } Chris@16: BOOST_UBLAS_INLINE Chris@16: const_iterator1 &operator += (difference_type n) { Chris@16: it_ += n; Chris@16: return *this; Chris@16: } Chris@16: BOOST_UBLAS_INLINE Chris@16: const_iterator1 &operator -= (difference_type n) { Chris@16: it_ -= n; Chris@16: return *this; Chris@16: } Chris@16: BOOST_UBLAS_INLINE Chris@16: difference_type operator - (const const_iterator1 &it) const { Chris@16: BOOST_UBLAS_CHECK ((*this) ().same_closure (it ()), external_logic ()); Chris@16: return it_ - it.it_; Chris@16: } Chris@16: Chris@16: // Dereference Chris@16: BOOST_UBLAS_INLINE Chris@16: const_reference operator * () const { Chris@16: return functor_type::apply (*it_); Chris@16: } Chris@16: BOOST_UBLAS_INLINE Chris@16: const_reference operator [] (difference_type n) const { Chris@16: return *(*this + n); Chris@16: } Chris@16: Chris@16: #ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION Chris@16: BOOST_UBLAS_INLINE Chris@16: #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION Chris@16: typename self_type:: Chris@16: #endif Chris@16: const_iterator2 begin () const { Chris@16: return (*this) ().find2 (1, index1 (), 0); Chris@16: } Chris@16: BOOST_UBLAS_INLINE Chris@16: #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION Chris@16: typename self_type:: Chris@16: #endif Chris@101: const_iterator2 cbegin () const { Chris@101: return begin (); Chris@101: } Chris@101: BOOST_UBLAS_INLINE Chris@101: #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION Chris@101: typename self_type:: Chris@101: #endif Chris@16: const_iterator2 end () const { Chris@16: return (*this) ().find2 (1, index1 (), (*this) ().size2 ()); Chris@16: } Chris@16: BOOST_UBLAS_INLINE Chris@16: #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION Chris@16: typename self_type:: Chris@16: #endif Chris@101: const_iterator2 cend () const { Chris@101: return end (); Chris@101: } Chris@101: BOOST_UBLAS_INLINE Chris@101: #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION Chris@101: typename self_type:: Chris@101: #endif Chris@16: const_reverse_iterator2 rbegin () const { Chris@16: return const_reverse_iterator2 (end ()); Chris@16: } Chris@16: BOOST_UBLAS_INLINE Chris@16: #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION Chris@16: typename self_type:: Chris@16: #endif Chris@101: const_reverse_iterator2 crbegin () const { Chris@101: return rbegin (); Chris@101: } Chris@101: BOOST_UBLAS_INLINE Chris@101: #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION Chris@101: typename self_type:: Chris@101: #endif Chris@16: const_reverse_iterator2 rend () const { Chris@16: return const_reverse_iterator2 (begin ()); Chris@16: } Chris@101: BOOST_UBLAS_INLINE Chris@101: #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION Chris@101: typename self_type:: Chris@101: #endif Chris@101: const_reverse_iterator2 crend () const { Chris@101: return rend (); Chris@101: } Chris@16: #endif Chris@16: Chris@16: // Indices Chris@16: BOOST_UBLAS_INLINE Chris@16: size_type index1 () const { Chris@16: return it_.index2 (); Chris@16: } Chris@16: BOOST_UBLAS_INLINE Chris@16: size_type index2 () const { Chris@16: return it_.index1 (); Chris@16: } Chris@16: Chris@16: // Assignment Chris@16: BOOST_UBLAS_INLINE Chris@16: const_iterator1 &operator = (const const_iterator1 &it) { Chris@16: container_const_reference::assign (&it ()); Chris@16: it_ = it.it_; Chris@16: return *this; Chris@16: } Chris@16: Chris@16: // Comparison Chris@16: BOOST_UBLAS_INLINE Chris@16: bool operator == (const const_iterator1 &it) const { Chris@16: BOOST_UBLAS_CHECK ((*this) ().same_closure (it ()), external_logic ()); Chris@16: return it_ == it.it_; Chris@16: } Chris@16: BOOST_UBLAS_INLINE Chris@16: bool operator < (const const_iterator1 &it) const { Chris@16: BOOST_UBLAS_CHECK ((*this) ().same_closure (it ()), external_logic ()); Chris@16: return it_ < it.it_; Chris@16: } Chris@16: Chris@16: private: Chris@16: const_subiterator1_type it_; Chris@16: }; Chris@16: #endif Chris@16: Chris@16: BOOST_UBLAS_INLINE Chris@16: const_iterator1 begin1 () const { Chris@16: return find1 (0, 0, 0); Chris@16: } Chris@16: BOOST_UBLAS_INLINE Chris@101: const_iterator1 cbegin1 () const { Chris@101: return begin1 (); Chris@101: } Chris@101: BOOST_UBLAS_INLINE Chris@16: const_iterator1 end1 () const { Chris@16: return find1 (0, size1 (), 0); Chris@16: } Chris@101: BOOST_UBLAS_INLINE Chris@101: const_iterator1 cend1 () const { Chris@101: return end1 (); Chris@101: } Chris@16: Chris@16: #ifndef BOOST_UBLAS_USE_INDEXED_ITERATOR Chris@16: class const_iterator2: Chris@16: public container_const_reference, Chris@16: public iterator_base_traits::template Chris@16: iterator_base::type { Chris@16: public: Chris@16: typedef typename E::const_iterator1::iterator_category iterator_category; Chris@16: typedef typename matrix_unary2::difference_type difference_type; Chris@16: typedef typename matrix_unary2::value_type value_type; Chris@16: typedef typename matrix_unary2::const_reference reference; Chris@16: typedef typename matrix_unary2::const_pointer pointer; Chris@16: Chris@16: typedef const_iterator1 dual_iterator_type; Chris@16: typedef const_reverse_iterator1 dual_reverse_iterator_type; Chris@16: Chris@16: // Construction and destruction Chris@16: BOOST_UBLAS_INLINE Chris@16: const_iterator2 (): Chris@16: container_const_reference (), it_ () {} Chris@16: BOOST_UBLAS_INLINE Chris@16: const_iterator2 (const self_type &mu, const const_subiterator2_type &it): Chris@16: container_const_reference (mu), it_ (it) {} Chris@16: Chris@16: // Arithmetic Chris@16: BOOST_UBLAS_INLINE Chris@16: const_iterator2 &operator ++ () { Chris@16: ++ it_; Chris@16: return *this; Chris@16: } Chris@16: BOOST_UBLAS_INLINE Chris@16: const_iterator2 &operator -- () { Chris@16: -- it_; Chris@16: return *this; Chris@16: } Chris@16: BOOST_UBLAS_INLINE Chris@16: const_iterator2 &operator += (difference_type n) { Chris@16: it_ += n; Chris@16: return *this; Chris@16: } Chris@16: BOOST_UBLAS_INLINE Chris@16: const_iterator2 &operator -= (difference_type n) { Chris@16: it_ -= n; Chris@16: return *this; Chris@16: } Chris@16: BOOST_UBLAS_INLINE Chris@16: difference_type operator - (const const_iterator2 &it) const { Chris@16: BOOST_UBLAS_CHECK ((*this) ().same_closure (it ()), external_logic ()); Chris@16: return it_ - it.it_; Chris@16: } Chris@16: Chris@16: // Dereference Chris@16: BOOST_UBLAS_INLINE Chris@16: const_reference operator * () const { Chris@16: return functor_type::apply (*it_); Chris@16: } Chris@16: BOOST_UBLAS_INLINE Chris@16: const_reference operator [] (difference_type n) const { Chris@16: return *(*this + n); Chris@16: } Chris@16: Chris@16: #ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION Chris@16: BOOST_UBLAS_INLINE Chris@16: #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION Chris@16: typename self_type:: Chris@16: #endif Chris@16: const_iterator1 begin () const { Chris@16: return (*this) ().find1 (1, 0, index2 ()); Chris@16: } Chris@16: BOOST_UBLAS_INLINE Chris@16: #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION Chris@16: typename self_type:: Chris@16: #endif Chris@101: const_iterator1 cbegin () const { Chris@101: return begin (); Chris@101: } Chris@101: BOOST_UBLAS_INLINE Chris@101: #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION Chris@101: typename self_type:: Chris@101: #endif Chris@16: const_iterator1 end () const { Chris@16: return (*this) ().find1 (1, (*this) ().size1 (), index2 ()); Chris@16: } Chris@16: BOOST_UBLAS_INLINE Chris@16: #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION Chris@16: typename self_type:: Chris@16: #endif Chris@101: const_iterator1 cend () const { Chris@101: return end (); Chris@101: } Chris@101: BOOST_UBLAS_INLINE Chris@101: #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION Chris@101: typename self_type:: Chris@101: #endif Chris@16: const_reverse_iterator1 rbegin () const { Chris@16: return const_reverse_iterator1 (end ()); Chris@16: } Chris@16: BOOST_UBLAS_INLINE Chris@16: #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION Chris@16: typename self_type:: Chris@16: #endif Chris@101: const_reverse_iterator1 crbegin () const { Chris@101: return rbegin (); Chris@101: } Chris@101: BOOST_UBLAS_INLINE Chris@101: #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION Chris@101: typename self_type:: Chris@101: #endif Chris@16: const_reverse_iterator1 rend () const { Chris@16: return const_reverse_iterator1 (begin ()); Chris@16: } Chris@101: BOOST_UBLAS_INLINE Chris@101: #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION Chris@101: typename self_type:: Chris@101: #endif Chris@101: const_reverse_iterator1 crend () const { Chris@101: return rend (); Chris@101: } Chris@16: #endif Chris@16: Chris@16: // Indices Chris@16: BOOST_UBLAS_INLINE Chris@16: size_type index1 () const { Chris@16: return it_.index2 (); Chris@16: } Chris@16: BOOST_UBLAS_INLINE Chris@16: size_type index2 () const { Chris@16: return it_.index1 (); Chris@16: } Chris@16: Chris@16: // Assignment Chris@16: BOOST_UBLAS_INLINE Chris@16: const_iterator2 &operator = (const const_iterator2 &it) { Chris@16: container_const_reference::assign (&it ()); Chris@16: it_ = it.it_; Chris@16: return *this; Chris@16: } Chris@16: Chris@16: // Comparison Chris@16: BOOST_UBLAS_INLINE Chris@16: bool operator == (const const_iterator2 &it) const { Chris@16: BOOST_UBLAS_CHECK ((*this) ().same_closure (it ()), external_logic ()); Chris@16: return it_ == it.it_; Chris@16: } Chris@16: BOOST_UBLAS_INLINE Chris@16: bool operator < (const const_iterator2 &it) const { Chris@16: BOOST_UBLAS_CHECK ((*this) ().same_closure (it ()), external_logic ()); Chris@16: return it_ < it.it_; Chris@16: } Chris@16: Chris@16: private: Chris@16: const_subiterator2_type it_; Chris@16: }; Chris@16: #endif Chris@16: Chris@16: BOOST_UBLAS_INLINE Chris@16: const_iterator2 begin2 () const { Chris@16: return find2 (0, 0, 0); Chris@16: } Chris@16: BOOST_UBLAS_INLINE Chris@101: const_iterator2 cbegin2 () const { Chris@101: return begin2 (); Chris@101: } Chris@101: BOOST_UBLAS_INLINE Chris@16: const_iterator2 end2 () const { Chris@16: return find2 (0, 0, size2 ()); Chris@16: } Chris@101: BOOST_UBLAS_INLINE Chris@101: const_iterator2 cend2 () const { Chris@101: return end2 (); Chris@101: } Chris@16: Chris@16: // Reverse iterators Chris@16: Chris@16: BOOST_UBLAS_INLINE Chris@16: const_reverse_iterator1 rbegin1 () const { Chris@16: return const_reverse_iterator1 (end1 ()); Chris@16: } Chris@16: BOOST_UBLAS_INLINE Chris@101: const_reverse_iterator1 crbegin1 () const { Chris@101: return rbegin1 (); Chris@101: } Chris@101: BOOST_UBLAS_INLINE Chris@16: const_reverse_iterator1 rend1 () const { Chris@16: return const_reverse_iterator1 (begin1 ()); Chris@16: } Chris@101: BOOST_UBLAS_INLINE Chris@101: const_reverse_iterator1 crend1 () const { Chris@101: return rend1 (); Chris@101: } Chris@16: Chris@16: BOOST_UBLAS_INLINE Chris@16: const_reverse_iterator2 rbegin2 () const { Chris@16: return const_reverse_iterator2 (end2 ()); Chris@16: } Chris@16: BOOST_UBLAS_INLINE Chris@101: const_reverse_iterator2 crbegin2 () const { Chris@101: return rbegin2 (); Chris@101: } Chris@101: BOOST_UBLAS_INLINE Chris@16: const_reverse_iterator2 rend2 () const { Chris@16: return const_reverse_iterator2 (begin2 ()); Chris@16: } Chris@101: BOOST_UBLAS_INLINE Chris@101: const_reverse_iterator2 crend2 () const { Chris@101: return rend2 (); Chris@101: } Chris@16: Chris@16: private: Chris@16: expression_closure_type e_; Chris@16: }; Chris@16: Chris@16: template Chris@16: struct matrix_unary2_traits { Chris@16: typedef matrix_unary2 expression_type; Chris@16: #ifndef BOOST_UBLAS_SIMPLE_ET_DEBUG Chris@16: typedef expression_type result_type; Chris@16: #else Chris@16: typedef typename E::matrix_temporary_type result_type; Chris@16: #endif Chris@16: }; Chris@16: Chris@16: // (trans m) [i] [j] = m [j] [i] Chris@16: template Chris@16: BOOST_UBLAS_INLINE Chris@16: typename matrix_unary2_traits >::result_type Chris@16: trans (const matrix_expression &e) { Chris@16: typedef typename matrix_unary2_traits >::expression_type expression_type; Chris@16: return expression_type (e ()); Chris@16: } Chris@16: template Chris@16: BOOST_UBLAS_INLINE Chris@16: typename matrix_unary2_traits >::result_type Chris@16: trans (matrix_expression &e) { Chris@16: typedef typename matrix_unary2_traits >::expression_type expression_type; Chris@16: return expression_type (e ()); Chris@16: } Chris@16: Chris@16: // (herm m) [i] [j] = conj (m [j] [i]) Chris@16: template Chris@16: BOOST_UBLAS_INLINE Chris@16: typename matrix_unary2_traits >::result_type Chris@16: herm (const matrix_expression &e) { Chris@16: typedef typename matrix_unary2_traits >::expression_type expression_type; Chris@16: return expression_type (e ()); Chris@16: } Chris@16: Chris@16: template Chris@16: class matrix_binary: Chris@16: public matrix_expression > { Chris@16: Chris@16: typedef E1 expression1_type; Chris@16: typedef E2 expression2_type; Chris@16: typedef F functor_type; Chris@16: public: Chris@16: typedef typename E1::const_closure_type expression1_closure_type; Chris@16: typedef typename E2::const_closure_type expression2_closure_type; Chris@16: private: Chris@16: typedef matrix_binary self_type; Chris@16: public: Chris@16: #ifdef BOOST_UBLAS_ENABLE_PROXY_SHORTCUTS Chris@16: using matrix_expression::operator (); Chris@16: #endif Chris@16: typedef typename promote_traits::promote_type size_type; Chris@16: typedef typename promote_traits::promote_type difference_type; Chris@16: typedef typename F::result_type value_type; Chris@16: typedef value_type const_reference; Chris@16: typedef const_reference reference; Chris@16: typedef const self_type const_closure_type; Chris@16: typedef const_closure_type closure_type; Chris@16: typedef unknown_orientation_tag orientation_category; Chris@16: typedef unknown_storage_tag storage_category; Chris@16: Chris@16: // Construction and destruction Chris@16: BOOST_UBLAS_INLINE Chris@16: matrix_binary (const E1 &e1, const E2 &e2): Chris@16: e1_ (e1), e2_ (e2) {} Chris@16: Chris@16: // Accessors Chris@16: BOOST_UBLAS_INLINE Chris@16: size_type size1 () const { Chris@16: return BOOST_UBLAS_SAME (e1_.size1 (), e2_.size1 ()); Chris@16: } Chris@16: BOOST_UBLAS_INLINE Chris@16: size_type size2 () const { Chris@16: return BOOST_UBLAS_SAME (e1_.size2 (), e2_.size2 ()); Chris@16: } Chris@16: Chris@16: public: Chris@16: // Expression accessors Chris@16: BOOST_UBLAS_INLINE Chris@16: const expression1_closure_type &expression1 () const { Chris@16: return e1_; Chris@16: } Chris@16: BOOST_UBLAS_INLINE Chris@16: const expression2_closure_type &expression2 () const { Chris@16: return e2_; Chris@16: } Chris@16: Chris@16: public: Chris@16: // Element access Chris@16: BOOST_UBLAS_INLINE Chris@16: const_reference operator () (size_type i, size_type j) const { Chris@16: return functor_type::apply (e1_ (i, j), e2_ (i, j)); Chris@16: } Chris@16: Chris@16: // Closure comparison Chris@16: BOOST_UBLAS_INLINE Chris@16: bool same_closure (const matrix_binary &mb) const { Chris@16: return (*this).expression1 ().same_closure (mb.expression1 ()) && Chris@16: (*this).expression2 ().same_closure (mb.expression2 ()); Chris@16: } Chris@16: Chris@16: // Iterator types Chris@16: private: Chris@16: typedef typename E1::const_iterator1 const_iterator11_type; Chris@16: typedef typename E1::const_iterator2 const_iterator12_type; Chris@16: typedef typename E2::const_iterator1 const_iterator21_type; Chris@16: typedef typename E2::const_iterator2 const_iterator22_type; Chris@16: typedef const value_type *const_pointer; Chris@16: Chris@16: public: Chris@16: #ifdef BOOST_UBLAS_USE_INDEXED_ITERATOR Chris@16: typedef typename iterator_restrict_traits::iterator_category iterator_category1; Chris@16: typedef indexed_const_iterator1 const_iterator1; Chris@16: typedef const_iterator1 iterator1; Chris@16: typedef typename iterator_restrict_traits::iterator_category iterator_category2; Chris@16: typedef indexed_const_iterator2 const_iterator2; Chris@16: typedef const_iterator2 iterator2; Chris@16: #else Chris@16: class const_iterator1; Chris@16: typedef const_iterator1 iterator1; Chris@16: class const_iterator2; Chris@16: typedef const_iterator2 iterator2; Chris@16: #endif Chris@16: typedef reverse_iterator_base1 const_reverse_iterator1; Chris@16: typedef reverse_iterator_base2 const_reverse_iterator2; Chris@16: Chris@16: // Element lookup Chris@16: BOOST_UBLAS_INLINE Chris@16: const_iterator1 find1 (int rank, size_type i, size_type j) const { Chris@16: const_iterator11_type it11 (e1_.find1 (rank, i, j)); Chris@16: const_iterator11_type it11_end (e1_.find1 (rank, size1 (), j)); Chris@16: const_iterator21_type it21 (e2_.find1 (rank, i, j)); Chris@16: const_iterator21_type it21_end (e2_.find1 (rank, size1 (), j)); Chris@16: BOOST_UBLAS_CHECK (rank == 0 || it11 == it11_end || it11.index2 () == j, internal_logic ()) Chris@16: BOOST_UBLAS_CHECK (rank == 0 || it21 == it21_end || it21.index2 () == j, internal_logic ()) Chris@16: i = (std::min) (it11 != it11_end ? it11.index1 () : size1 (), Chris@16: it21 != it21_end ? it21.index1 () : size1 ()); Chris@16: #ifdef BOOST_UBLAS_USE_INDEXED_ITERATOR Chris@16: return const_iterator1 (*this, i, j); Chris@16: #else Chris@16: return const_iterator1 (*this, i, j, it11, it11_end, it21, it21_end); Chris@16: #endif Chris@16: } Chris@16: BOOST_UBLAS_INLINE Chris@16: const_iterator2 find2 (int rank, size_type i, size_type j) const { Chris@16: const_iterator12_type it12 (e1_.find2 (rank, i, j)); Chris@16: const_iterator12_type it12_end (e1_.find2 (rank, i, size2 ())); Chris@16: const_iterator22_type it22 (e2_.find2 (rank, i, j)); Chris@16: const_iterator22_type it22_end (e2_.find2 (rank, i, size2 ())); Chris@16: BOOST_UBLAS_CHECK (rank == 0 || it12 == it12_end || it12.index1 () == i, internal_logic ()) Chris@16: BOOST_UBLAS_CHECK (rank == 0 || it22 == it22_end || it22.index1 () == i, internal_logic ()) Chris@16: j = (std::min) (it12 != it12_end ? it12.index2 () : size2 (), Chris@16: it22 != it22_end ? it22.index2 () : size2 ()); Chris@16: #ifdef BOOST_UBLAS_USE_INDEXED_ITERATOR Chris@16: return const_iterator2 (*this, i, j); Chris@16: #else Chris@16: return const_iterator2 (*this, i, j, it12, it12_end, it22, it22_end); Chris@16: #endif Chris@16: } Chris@16: Chris@16: // Iterators enhance the iterators of the referenced expression Chris@16: // with the binary functor. Chris@16: Chris@16: #ifndef BOOST_UBLAS_USE_INDEXED_ITERATOR Chris@16: class const_iterator1: Chris@16: public container_const_reference, Chris@16: public iterator_base_traits::iterator_category>::template Chris@16: iterator_base::type { Chris@16: public: Chris@16: typedef typename iterator_restrict_traits::iterator_category iterator_category; Chris@16: typedef typename matrix_binary::difference_type difference_type; Chris@16: typedef typename matrix_binary::value_type value_type; Chris@16: typedef typename matrix_binary::const_reference reference; Chris@16: typedef typename matrix_binary::const_pointer pointer; Chris@16: Chris@16: typedef const_iterator2 dual_iterator_type; Chris@16: typedef const_reverse_iterator2 dual_reverse_iterator_type; Chris@16: Chris@16: // Construction and destruction Chris@16: BOOST_UBLAS_INLINE Chris@16: const_iterator1 (): Chris@16: container_const_reference (), i_ (), j_ (), it1_ (), it1_end_ (), it2_ (), it2_end_ () {} Chris@16: BOOST_UBLAS_INLINE Chris@16: const_iterator1 (const self_type &mb, size_type i, size_type j, Chris@16: const const_iterator11_type &it1, const const_iterator11_type &it1_end, Chris@16: const const_iterator21_type &it2, const const_iterator21_type &it2_end): Chris@16: container_const_reference (mb), i_ (i), j_ (j), it1_ (it1), it1_end_ (it1_end), it2_ (it2), it2_end_ (it2_end) {} Chris@16: Chris@16: private: Chris@16: // Dense specializations Chris@16: BOOST_UBLAS_INLINE Chris@16: void increment (dense_random_access_iterator_tag) { Chris@16: ++ i_; ++ it1_; ++ it2_; Chris@16: } Chris@16: BOOST_UBLAS_INLINE Chris@16: void decrement (dense_random_access_iterator_tag) { Chris@16: -- i_; -- it1_; -- it2_; Chris@16: } Chris@16: BOOST_UBLAS_INLINE Chris@16: void increment (dense_random_access_iterator_tag, difference_type n) { Chris@16: i_ += n; it1_ += n; it2_ += n; Chris@16: } Chris@16: BOOST_UBLAS_INLINE Chris@16: void decrement (dense_random_access_iterator_tag, difference_type n) { Chris@16: i_ -= n; it1_ -= n; it2_ -= n; Chris@16: } Chris@16: BOOST_UBLAS_INLINE Chris@16: value_type dereference (dense_random_access_iterator_tag) const { Chris@16: return functor_type::apply (*it1_, *it2_); Chris@16: } Chris@16: Chris@16: // Packed specializations Chris@16: BOOST_UBLAS_INLINE Chris@16: void increment (packed_random_access_iterator_tag) { Chris@16: if (it1_ != it1_end_) Chris@16: if (it1_.index1 () <= i_) Chris@16: ++ it1_; Chris@16: if (it2_ != it2_end_) Chris@16: if (it2_.index1 () <= i_) Chris@16: ++ it2_; Chris@16: ++ i_; Chris@16: } Chris@16: BOOST_UBLAS_INLINE Chris@16: void decrement (packed_random_access_iterator_tag) { Chris@16: if (it1_ != it1_end_) Chris@16: if (i_ <= it1_.index1 ()) Chris@16: -- it1_; Chris@16: if (it2_ != it2_end_) Chris@16: if (i_ <= it2_.index1 ()) Chris@16: -- it2_; Chris@16: -- i_; Chris@16: } Chris@16: BOOST_UBLAS_INLINE Chris@16: void increment (packed_random_access_iterator_tag, difference_type n) { Chris@16: while (n > 0) { Chris@16: increment (packed_random_access_iterator_tag ()); Chris@16: --n; Chris@16: } Chris@16: while (n < 0) { Chris@16: decrement (packed_random_access_iterator_tag ()); Chris@16: ++n; Chris@16: } Chris@16: } Chris@16: BOOST_UBLAS_INLINE Chris@16: void decrement (packed_random_access_iterator_tag, difference_type n) { Chris@16: while (n > 0) { Chris@16: decrement (packed_random_access_iterator_tag ()); Chris@16: --n; Chris@16: } Chris@16: while (n < 0) { Chris@16: increment (packed_random_access_iterator_tag ()); Chris@16: ++n; Chris@16: } Chris@16: } Chris@16: BOOST_UBLAS_INLINE Chris@16: value_type dereference (packed_random_access_iterator_tag) const { Chris@16: value_type t1 = value_type/*zero*/(); Chris@16: if (it1_ != it1_end_) { Chris@16: BOOST_UBLAS_CHECK (it1_.index2 () == j_, internal_logic ()); Chris@16: if (it1_.index1 () == i_) Chris@16: t1 = *it1_; Chris@16: } Chris@16: value_type t2 = value_type/*zero*/(); Chris@16: if (it2_ != it2_end_) { Chris@16: BOOST_UBLAS_CHECK (it2_.index2 () == j_, internal_logic ()); Chris@16: if (it2_.index1 () == i_) Chris@16: t2 = *it2_; Chris@16: } Chris@16: return functor_type::apply (t1, t2); Chris@16: } Chris@16: Chris@16: // Sparse specializations Chris@16: BOOST_UBLAS_INLINE Chris@16: void increment (sparse_bidirectional_iterator_tag) { Chris@16: size_type index1 = (*this) ().size1 (); Chris@16: if (it1_ != it1_end_) { Chris@16: if (it1_.index1 () <= i_) Chris@16: ++ it1_; Chris@16: if (it1_ != it1_end_) Chris@16: index1 = it1_.index1 (); Chris@16: } Chris@16: size_type index2 = (*this) ().size1 (); Chris@16: if (it2_ != it2_end_) Chris@16: if (it2_.index1 () <= i_) Chris@16: ++ it2_; Chris@16: if (it2_ != it2_end_) { Chris@16: index2 = it2_.index1 (); Chris@16: } Chris@16: i_ = (std::min) (index1, index2); Chris@16: } Chris@16: BOOST_UBLAS_INLINE Chris@16: void decrement (sparse_bidirectional_iterator_tag) { Chris@16: size_type index1 = (*this) ().size1 (); Chris@16: if (it1_ != it1_end_) { Chris@16: if (i_ <= it1_.index1 ()) Chris@16: -- it1_; Chris@16: if (it1_ != it1_end_) Chris@16: index1 = it1_.index1 (); Chris@16: } Chris@16: size_type index2 = (*this) ().size1 (); Chris@16: if (it2_ != it2_end_) { Chris@16: if (i_ <= it2_.index1 ()) Chris@16: -- it2_; Chris@16: if (it2_ != it2_end_) Chris@16: index2 = it2_.index1 (); Chris@16: } Chris@16: i_ = (std::max) (index1, index2); Chris@16: } Chris@16: BOOST_UBLAS_INLINE Chris@16: void increment (sparse_bidirectional_iterator_tag, difference_type n) { Chris@16: while (n > 0) { Chris@16: increment (sparse_bidirectional_iterator_tag ()); Chris@16: --n; Chris@16: } Chris@16: while (n < 0) { Chris@16: decrement (sparse_bidirectional_iterator_tag ()); Chris@16: ++n; Chris@16: } Chris@16: } Chris@16: BOOST_UBLAS_INLINE Chris@16: void decrement (sparse_bidirectional_iterator_tag, difference_type n) { Chris@16: while (n > 0) { Chris@16: decrement (sparse_bidirectional_iterator_tag ()); Chris@16: --n; Chris@16: } Chris@16: while (n < 0) { Chris@16: increment (sparse_bidirectional_iterator_tag ()); Chris@16: ++n; Chris@16: } Chris@16: } Chris@16: BOOST_UBLAS_INLINE Chris@16: value_type dereference (sparse_bidirectional_iterator_tag) const { Chris@16: value_type t1 = value_type/*zero*/(); Chris@16: if (it1_ != it1_end_) { Chris@16: BOOST_UBLAS_CHECK (it1_.index2 () == j_, internal_logic ()); Chris@16: if (it1_.index1 () == i_) Chris@16: t1 = *it1_; Chris@16: } Chris@16: value_type t2 = value_type/*zero*/(); Chris@16: if (it2_ != it2_end_) { Chris@16: BOOST_UBLAS_CHECK (it2_.index2 () == j_, internal_logic ()); Chris@16: if (it2_.index1 () == i_) Chris@16: t2 = *it2_; Chris@16: } Chris@16: return functor_type::apply (t1, t2); Chris@16: } Chris@16: Chris@16: public: Chris@16: // Arithmetic Chris@16: BOOST_UBLAS_INLINE Chris@16: const_iterator1 &operator ++ () { Chris@16: increment (iterator_category ()); Chris@16: return *this; Chris@16: } Chris@16: BOOST_UBLAS_INLINE Chris@16: const_iterator1 &operator -- () { Chris@16: decrement (iterator_category ()); Chris@16: return *this; Chris@16: } Chris@16: BOOST_UBLAS_INLINE Chris@16: const_iterator1 &operator += (difference_type n) { Chris@16: increment (iterator_category (), n); Chris@16: return *this; Chris@16: } Chris@16: BOOST_UBLAS_INLINE Chris@16: const_iterator1 &operator -= (difference_type n) { Chris@16: decrement (iterator_category (), n); Chris@16: return *this; Chris@16: } Chris@16: BOOST_UBLAS_INLINE Chris@16: difference_type operator - (const const_iterator1 &it) const { Chris@16: BOOST_UBLAS_CHECK ((*this) ().same_closure (it ()), external_logic ()); Chris@16: BOOST_UBLAS_CHECK (index2 () == it.index2 (), external_logic ()); Chris@16: return index1 () - it.index1 (); Chris@16: } Chris@16: Chris@16: // Dereference Chris@16: BOOST_UBLAS_INLINE Chris@16: const_reference operator * () const { Chris@16: return dereference (iterator_category ()); Chris@16: } Chris@16: BOOST_UBLAS_INLINE Chris@16: const_reference operator [] (difference_type n) const { Chris@16: return *(*this + n); Chris@16: } Chris@16: Chris@16: #ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION Chris@16: BOOST_UBLAS_INLINE Chris@16: #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION Chris@16: typename self_type:: Chris@16: #endif Chris@16: const_iterator2 begin () const { Chris@16: return (*this) ().find2 (1, index1 (), 0); Chris@16: } Chris@16: BOOST_UBLAS_INLINE Chris@16: #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION Chris@16: typename self_type:: Chris@16: #endif Chris@101: const_iterator2 cbegin () const { Chris@101: return begin (); Chris@101: } Chris@101: BOOST_UBLAS_INLINE Chris@101: #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION Chris@101: typename self_type:: Chris@101: #endif Chris@16: const_iterator2 end () const { Chris@16: return (*this) ().find2 (1, index1 (), (*this) ().size2 ()); Chris@16: } Chris@16: BOOST_UBLAS_INLINE Chris@16: #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION Chris@16: typename self_type:: Chris@16: #endif Chris@101: const_iterator2 cend () const { Chris@101: return end (); Chris@101: } Chris@101: BOOST_UBLAS_INLINE Chris@101: #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION Chris@101: typename self_type:: Chris@101: #endif Chris@16: const_reverse_iterator2 rbegin () const { Chris@16: return const_reverse_iterator2 (end ()); Chris@16: } Chris@16: BOOST_UBLAS_INLINE Chris@16: #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION Chris@16: typename self_type:: Chris@16: #endif Chris@101: const_reverse_iterator2 crbegin () const { Chris@101: return rbegin (); Chris@101: } Chris@101: BOOST_UBLAS_INLINE Chris@101: #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION Chris@101: typename self_type:: Chris@101: #endif Chris@16: const_reverse_iterator2 rend () const { Chris@16: return const_reverse_iterator2 (begin ()); Chris@16: } Chris@101: BOOST_UBLAS_INLINE Chris@101: #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION Chris@101: typename self_type:: Chris@101: #endif Chris@101: const_reverse_iterator2 crend () const { Chris@101: return rend (); Chris@101: } Chris@16: #endif Chris@16: Chris@16: // Indices Chris@16: BOOST_UBLAS_INLINE Chris@16: size_type index1 () const { Chris@16: return i_; Chris@16: } Chris@16: BOOST_UBLAS_INLINE Chris@16: size_type index2 () const { Chris@16: // if (it1_ != it1_end_ && it2_ != it2_end_) Chris@16: // return BOOST_UBLAS_SAME (it1_.index2 (), it2_.index2 ()); Chris@16: // else Chris@16: return j_; Chris@16: } Chris@16: Chris@16: // Assignment Chris@16: BOOST_UBLAS_INLINE Chris@16: const_iterator1 &operator = (const const_iterator1 &it) { Chris@16: container_const_reference::assign (&it ()); Chris@16: i_ = it.i_; Chris@16: j_ = it.j_; Chris@16: it1_ = it.it1_; Chris@16: it1_end_ = it.it1_end_; Chris@16: it2_ = it.it2_; Chris@16: it2_end_ = it.it2_end_; Chris@16: return *this; Chris@16: } Chris@16: Chris@16: // Comparison Chris@16: BOOST_UBLAS_INLINE Chris@16: bool operator == (const const_iterator1 &it) const { Chris@16: BOOST_UBLAS_CHECK ((*this) ().same_closure (it ()), external_logic ()); Chris@16: BOOST_UBLAS_CHECK (index2 () == it.index2 (), external_logic ()); Chris@16: return index1 () == it.index1 (); Chris@16: } Chris@16: BOOST_UBLAS_INLINE Chris@16: bool operator < (const const_iterator1 &it) const { Chris@16: BOOST_UBLAS_CHECK ((*this) ().same_closure (it ()), external_logic ()); Chris@16: BOOST_UBLAS_CHECK (index2 () == it.index2 (), external_logic ()); Chris@16: return index1 () < it.index1 (); Chris@16: } Chris@16: Chris@16: private: Chris@16: size_type i_; Chris@16: size_type j_; Chris@16: const_iterator11_type it1_; Chris@16: const_iterator11_type it1_end_; Chris@16: const_iterator21_type it2_; Chris@16: const_iterator21_type it2_end_; Chris@16: }; Chris@16: #endif Chris@16: Chris@16: BOOST_UBLAS_INLINE Chris@16: const_iterator1 begin1 () const { Chris@16: return find1 (0, 0, 0); Chris@16: } Chris@16: BOOST_UBLAS_INLINE Chris@101: const_iterator1 cbegin1 () const { Chris@101: return begin1 (); Chris@101: } Chris@101: BOOST_UBLAS_INLINE Chris@16: const_iterator1 end1 () const { Chris@16: return find1 (0, size1 (), 0); Chris@16: } Chris@101: BOOST_UBLAS_INLINE Chris@101: const_iterator1 cend1 () const { Chris@101: return end1 (); Chris@101: } Chris@16: Chris@16: #ifndef BOOST_UBLAS_USE_INDEXED_ITERATOR Chris@16: class const_iterator2: Chris@16: public container_const_reference, Chris@16: public iterator_base_traits::iterator_category>::template Chris@16: iterator_base::type { Chris@16: public: Chris@16: typedef typename iterator_restrict_traits::iterator_category iterator_category; Chris@16: typedef typename matrix_binary::difference_type difference_type; Chris@16: typedef typename matrix_binary::value_type value_type; Chris@16: typedef typename matrix_binary::const_reference reference; Chris@16: typedef typename matrix_binary::const_pointer pointer; Chris@16: Chris@16: typedef const_iterator1 dual_iterator_type; Chris@16: typedef const_reverse_iterator1 dual_reverse_iterator_type; Chris@16: Chris@16: // Construction and destruction Chris@16: BOOST_UBLAS_INLINE Chris@16: const_iterator2 (): Chris@16: container_const_reference (), i_ (), j_ (), it1_ (), it1_end_ (), it2_ (), it2_end_ () {} Chris@16: BOOST_UBLAS_INLINE Chris@16: const_iterator2 (const self_type &mb, size_type i, size_type j, Chris@16: const const_iterator12_type &it1, const const_iterator12_type &it1_end, Chris@16: const const_iterator22_type &it2, const const_iterator22_type &it2_end): Chris@16: container_const_reference (mb), i_ (i), j_ (j), it1_ (it1), it1_end_ (it1_end), it2_ (it2), it2_end_ (it2_end) {} Chris@16: Chris@16: private: Chris@16: // Dense access specializations Chris@16: BOOST_UBLAS_INLINE Chris@16: void increment (dense_random_access_iterator_tag) { Chris@16: ++ j_; ++ it1_; ++ it2_; Chris@16: } Chris@16: BOOST_UBLAS_INLINE Chris@16: void decrement (dense_random_access_iterator_tag) { Chris@16: -- j_; -- it1_; -- it2_; Chris@16: } Chris@16: BOOST_UBLAS_INLINE Chris@16: void increment (dense_random_access_iterator_tag, difference_type n) { Chris@16: j_ += n; it1_ += n; it2_ += n; Chris@16: } Chris@16: BOOST_UBLAS_INLINE Chris@16: void decrement (dense_random_access_iterator_tag, difference_type n) { Chris@16: j_ -= n; it1_ -= n; it2_ -= n; Chris@16: } Chris@16: BOOST_UBLAS_INLINE Chris@16: value_type dereference (dense_random_access_iterator_tag) const { Chris@16: return functor_type::apply (*it1_, *it2_); Chris@16: } Chris@16: Chris@16: // Packed specializations Chris@16: BOOST_UBLAS_INLINE Chris@16: void increment (packed_random_access_iterator_tag) { Chris@16: if (it1_ != it1_end_) Chris@16: if (it1_.index2 () <= j_) Chris@16: ++ it1_; Chris@16: if (it2_ != it2_end_) Chris@16: if (it2_.index2 () <= j_) Chris@16: ++ it2_; Chris@16: ++ j_; Chris@16: } Chris@16: BOOST_UBLAS_INLINE Chris@16: void decrement (packed_random_access_iterator_tag) { Chris@16: if (it1_ != it1_end_) Chris@16: if (j_ <= it1_.index2 ()) Chris@16: -- it1_; Chris@16: if (it2_ != it2_end_) Chris@16: if (j_ <= it2_.index2 ()) Chris@16: -- it2_; Chris@16: -- j_; Chris@16: } Chris@16: BOOST_UBLAS_INLINE Chris@16: void increment (packed_random_access_iterator_tag, difference_type n) { Chris@16: while (n > 0) { Chris@16: increment (packed_random_access_iterator_tag ()); Chris@16: --n; Chris@16: } Chris@16: while (n < 0) { Chris@16: decrement (packed_random_access_iterator_tag ()); Chris@16: ++n; Chris@16: } Chris@16: } Chris@16: BOOST_UBLAS_INLINE Chris@16: void decrement (packed_random_access_iterator_tag, difference_type n) { Chris@16: while (n > 0) { Chris@16: decrement (packed_random_access_iterator_tag ()); Chris@16: --n; Chris@16: } Chris@16: while (n < 0) { Chris@16: increment (packed_random_access_iterator_tag ()); Chris@16: ++n; Chris@16: } Chris@16: } Chris@16: BOOST_UBLAS_INLINE Chris@16: value_type dereference (packed_random_access_iterator_tag) const { Chris@16: value_type t1 = value_type/*zero*/(); Chris@16: if (it1_ != it1_end_) { Chris@16: BOOST_UBLAS_CHECK (it1_.index1 () == i_, internal_logic ()); Chris@16: if (it1_.index2 () == j_) Chris@16: t1 = *it1_; Chris@16: } Chris@16: value_type t2 = value_type/*zero*/(); Chris@16: if (it2_ != it2_end_) { Chris@16: BOOST_UBLAS_CHECK (it2_.index1 () == i_, internal_logic ()); Chris@16: if (it2_.index2 () == j_) Chris@16: t2 = *it2_; Chris@16: } Chris@16: return functor_type::apply (t1, t2); Chris@16: } Chris@16: Chris@16: // Sparse specializations Chris@16: BOOST_UBLAS_INLINE Chris@16: void increment (sparse_bidirectional_iterator_tag) { Chris@16: size_type index1 = (*this) ().size2 (); Chris@16: if (it1_ != it1_end_) { Chris@16: if (it1_.index2 () <= j_) Chris@16: ++ it1_; Chris@16: if (it1_ != it1_end_) Chris@16: index1 = it1_.index2 (); Chris@16: } Chris@16: size_type index2 = (*this) ().size2 (); Chris@16: if (it2_ != it2_end_) { Chris@16: if (it2_.index2 () <= j_) Chris@16: ++ it2_; Chris@16: if (it2_ != it2_end_) Chris@16: index2 = it2_.index2 (); Chris@16: } Chris@16: j_ = (std::min) (index1, index2); Chris@16: } Chris@16: BOOST_UBLAS_INLINE Chris@16: void decrement (sparse_bidirectional_iterator_tag) { Chris@16: size_type index1 = (*this) ().size2 (); Chris@16: if (it1_ != it1_end_) { Chris@16: if (j_ <= it1_.index2 ()) Chris@16: -- it1_; Chris@16: if (it1_ != it1_end_) Chris@16: index1 = it1_.index2 (); Chris@16: } Chris@16: size_type index2 = (*this) ().size2 (); Chris@16: if (it2_ != it2_end_) { Chris@16: if (j_ <= it2_.index2 ()) Chris@16: -- it2_; Chris@16: if (it2_ != it2_end_) Chris@16: index2 = it2_.index2 (); Chris@16: } Chris@16: j_ = (std::max) (index1, index2); Chris@16: } Chris@16: BOOST_UBLAS_INLINE Chris@16: void increment (sparse_bidirectional_iterator_tag, difference_type n) { Chris@16: while (n > 0) { Chris@16: increment (sparse_bidirectional_iterator_tag ()); Chris@16: --n; Chris@16: } Chris@16: while (n < 0) { Chris@16: decrement (sparse_bidirectional_iterator_tag ()); Chris@16: ++n; Chris@16: } Chris@16: } Chris@16: BOOST_UBLAS_INLINE Chris@16: void decrement (sparse_bidirectional_iterator_tag, difference_type n) { Chris@16: while (n > 0) { Chris@16: decrement (sparse_bidirectional_iterator_tag ()); Chris@16: --n; Chris@16: } Chris@16: while (n < 0) { Chris@16: increment (sparse_bidirectional_iterator_tag ()); Chris@16: ++n; Chris@16: } Chris@16: } Chris@16: BOOST_UBLAS_INLINE Chris@16: value_type dereference (sparse_bidirectional_iterator_tag) const { Chris@16: value_type t1 = value_type/*zero*/(); Chris@16: if (it1_ != it1_end_) { Chris@16: BOOST_UBLAS_CHECK (it1_.index1 () == i_, internal_logic ()); Chris@16: if (it1_.index2 () == j_) Chris@16: t1 = *it1_; Chris@16: } Chris@16: value_type t2 = value_type/*zero*/(); Chris@16: if (it2_ != it2_end_) { Chris@16: BOOST_UBLAS_CHECK (it2_.index1 () == i_, internal_logic ()); Chris@16: if (it2_.index2 () == j_) Chris@16: t2 = *it2_; Chris@16: } Chris@16: return functor_type::apply (t1, t2); Chris@16: } Chris@16: Chris@16: public: Chris@16: // Arithmetic Chris@16: BOOST_UBLAS_INLINE Chris@16: const_iterator2 &operator ++ () { Chris@16: increment (iterator_category ()); Chris@16: return *this; Chris@16: } Chris@16: BOOST_UBLAS_INLINE Chris@16: const_iterator2 &operator -- () { Chris@16: decrement (iterator_category ()); Chris@16: return *this; Chris@16: } Chris@16: BOOST_UBLAS_INLINE Chris@16: const_iterator2 &operator += (difference_type n) { Chris@16: increment (iterator_category (), n); Chris@16: return *this; Chris@16: } Chris@16: BOOST_UBLAS_INLINE Chris@16: const_iterator2 &operator -= (difference_type n) { Chris@16: decrement (iterator_category (), n); Chris@16: return *this; Chris@16: } Chris@16: BOOST_UBLAS_INLINE Chris@16: difference_type operator - (const const_iterator2 &it) const { Chris@16: BOOST_UBLAS_CHECK ((*this) ().same_closure (it ()), external_logic ()); Chris@16: BOOST_UBLAS_CHECK (index1 () == it.index1 (), external_logic ()); Chris@16: return index2 () - it.index2 (); Chris@16: } Chris@16: Chris@16: // Dereference Chris@16: BOOST_UBLAS_INLINE Chris@16: const_reference operator * () const { Chris@16: return dereference (iterator_category ()); Chris@16: } Chris@16: BOOST_UBLAS_INLINE Chris@16: const_reference operator [] (difference_type n) const { Chris@16: return *(*this + n); Chris@16: } Chris@16: Chris@16: #ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION Chris@16: BOOST_UBLAS_INLINE Chris@16: #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION Chris@16: typename self_type:: Chris@16: #endif Chris@16: const_iterator1 begin () const { Chris@16: return (*this) ().find1 (1, 0, index2 ()); Chris@16: } Chris@16: BOOST_UBLAS_INLINE Chris@16: #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION Chris@16: typename self_type:: Chris@16: #endif Chris@101: const_iterator1 cbegin () const { Chris@101: return begin (); Chris@101: } Chris@101: BOOST_UBLAS_INLINE Chris@101: #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION Chris@101: typename self_type:: Chris@101: #endif Chris@16: const_iterator1 end () const { Chris@16: return (*this) ().find1 (1, (*this) ().size1 (), index2 ()); Chris@16: } Chris@16: BOOST_UBLAS_INLINE Chris@16: #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION Chris@16: typename self_type:: Chris@16: #endif Chris@101: const_iterator1 cend () const { Chris@101: return end (); Chris@101: } Chris@101: BOOST_UBLAS_INLINE Chris@101: #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION Chris@101: typename self_type:: Chris@101: #endif Chris@16: const_reverse_iterator1 rbegin () const { Chris@16: return const_reverse_iterator1 (end ()); Chris@16: } Chris@16: BOOST_UBLAS_INLINE Chris@16: #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION Chris@16: typename self_type:: Chris@16: #endif Chris@101: const_reverse_iterator1 crbegin () const { Chris@101: return rbegin (); Chris@101: } Chris@101: BOOST_UBLAS_INLINE Chris@101: #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION Chris@101: typename self_type:: Chris@101: #endif Chris@16: const_reverse_iterator1 rend () const { Chris@16: return const_reverse_iterator1 (begin ()); Chris@16: } Chris@101: BOOST_UBLAS_INLINE Chris@101: #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION Chris@101: typename self_type:: Chris@101: #endif Chris@101: const_reverse_iterator1 crend () const { Chris@101: return rend (); Chris@101: } Chris@16: #endif Chris@16: Chris@16: // Indices Chris@16: BOOST_UBLAS_INLINE Chris@16: size_type index1 () const { Chris@16: // if (it1_ != it1_end_ && it2_ != it2_end_) Chris@16: // return BOOST_UBLAS_SAME (it1_.index1 (), it2_.index1 ()); Chris@16: // else Chris@16: return i_; Chris@16: } Chris@16: BOOST_UBLAS_INLINE Chris@16: size_type index2 () const { Chris@16: return j_; Chris@16: } Chris@16: Chris@16: // Assignment Chris@16: BOOST_UBLAS_INLINE Chris@16: const_iterator2 &operator = (const const_iterator2 &it) { Chris@16: container_const_reference::assign (&it ()); Chris@16: i_ = it.i_; Chris@16: j_ = it.j_; Chris@16: it1_ = it.it1_; Chris@16: it1_end_ = it.it1_end_; Chris@16: it2_ = it.it2_; Chris@16: it2_end_ = it.it2_end_; Chris@16: return *this; Chris@16: } Chris@16: Chris@16: // Comparison Chris@16: BOOST_UBLAS_INLINE Chris@16: bool operator == (const const_iterator2 &it) const { Chris@16: BOOST_UBLAS_CHECK ((*this) ().same_closure (it ()), external_logic ()); Chris@16: BOOST_UBLAS_CHECK (index1 () == it.index1 (), external_logic ()); Chris@16: return index2 () == it.index2 (); Chris@16: } Chris@16: BOOST_UBLAS_INLINE Chris@16: bool operator < (const const_iterator2 &it) const { Chris@16: BOOST_UBLAS_CHECK ((*this) ().same_closure (it ()), external_logic ()); Chris@16: BOOST_UBLAS_CHECK (index1 () == it.index1 (), external_logic ()); Chris@16: return index2 () < it.index2 (); Chris@16: } Chris@16: Chris@16: private: Chris@16: size_type i_; Chris@16: size_type j_; Chris@16: const_iterator12_type it1_; Chris@16: const_iterator12_type it1_end_; Chris@16: const_iterator22_type it2_; Chris@16: const_iterator22_type it2_end_; Chris@16: }; Chris@16: #endif Chris@16: Chris@16: BOOST_UBLAS_INLINE Chris@16: const_iterator2 begin2 () const { Chris@16: return find2 (0, 0, 0); Chris@16: } Chris@16: BOOST_UBLAS_INLINE Chris@101: const_iterator2 cbegin2 () const { Chris@101: return begin2 (); Chris@101: } Chris@101: BOOST_UBLAS_INLINE Chris@16: const_iterator2 end2 () const { Chris@16: return find2 (0, 0, size2 ()); Chris@16: } Chris@101: BOOST_UBLAS_INLINE Chris@101: const_iterator2 cend2 () const { Chris@101: return end2 (); Chris@101: } Chris@16: Chris@16: // Reverse iterators Chris@16: Chris@16: BOOST_UBLAS_INLINE Chris@16: const_reverse_iterator1 rbegin1 () const { Chris@16: return const_reverse_iterator1 (end1 ()); Chris@16: } Chris@16: BOOST_UBLAS_INLINE Chris@101: const_reverse_iterator1 crbegin1 () const { Chris@101: return rbegin1 (); Chris@101: } Chris@101: BOOST_UBLAS_INLINE Chris@16: const_reverse_iterator1 rend1 () const { Chris@16: return const_reverse_iterator1 (begin1 ()); Chris@16: } Chris@101: BOOST_UBLAS_INLINE Chris@101: const_reverse_iterator1 crend1 () const { Chris@101: return rend1 (); Chris@101: } Chris@16: Chris@16: BOOST_UBLAS_INLINE Chris@16: const_reverse_iterator2 rbegin2 () const { Chris@16: return const_reverse_iterator2 (end2 ()); Chris@16: } Chris@16: BOOST_UBLAS_INLINE Chris@101: const_reverse_iterator2 crbegin2 () const { Chris@101: return rbegin2 (); Chris@101: } Chris@101: BOOST_UBLAS_INLINE Chris@16: const_reverse_iterator2 rend2 () const { Chris@16: return const_reverse_iterator2 (begin2 ()); Chris@16: } Chris@101: BOOST_UBLAS_INLINE Chris@101: const_reverse_iterator2 crend2 () const { Chris@101: return rend2 (); Chris@101: } Chris@16: Chris@16: private: Chris@16: expression1_closure_type e1_; Chris@16: expression2_closure_type e2_; Chris@16: }; Chris@16: Chris@16: template Chris@16: struct matrix_binary_traits { Chris@16: typedef matrix_binary expression_type; Chris@16: #ifndef BOOST_UBLAS_SIMPLE_ET_DEBUG Chris@16: typedef expression_type result_type; Chris@16: #else Chris@16: typedef typename E1::matrix_temporary_type result_type; Chris@16: #endif Chris@16: }; Chris@16: Chris@16: // (m1 + m2) [i] [j] = m1 [i] [j] + m2 [i] [j] Chris@16: template Chris@16: BOOST_UBLAS_INLINE Chris@16: typename matrix_binary_traits >::result_type Chris@16: operator + (const matrix_expression &e1, Chris@16: const matrix_expression &e2) { Chris@16: typedef typename matrix_binary_traits >::expression_type expression_type; Chris@16: return expression_type (e1 (), e2 ()); Chris@16: } Chris@16: Chris@16: // (m1 - m2) [i] [j] = m1 [i] [j] - m2 [i] [j] Chris@16: template Chris@16: BOOST_UBLAS_INLINE Chris@16: typename matrix_binary_traits >::result_type Chris@16: operator - (const matrix_expression &e1, Chris@16: const matrix_expression &e2) { Chris@16: typedef typename matrix_binary_traits >::expression_type expression_type; Chris@16: return expression_type (e1 (), e2 ()); Chris@16: } Chris@16: Chris@16: // (m1 * m2) [i] [j] = m1 [i] [j] * m2 [i] [j] Chris@16: template Chris@16: BOOST_UBLAS_INLINE Chris@16: typename matrix_binary_traits >::result_type Chris@16: element_prod (const matrix_expression &e1, Chris@16: const matrix_expression &e2) { Chris@16: typedef typename matrix_binary_traits >::expression_type expression_type; Chris@16: return expression_type (e1 (), e2 ()); Chris@16: } Chris@16: Chris@16: // (m1 / m2) [i] [j] = m1 [i] [j] / m2 [i] [j] Chris@16: template Chris@16: BOOST_UBLAS_INLINE Chris@16: typename matrix_binary_traits >::result_type Chris@16: element_div (const matrix_expression &e1, Chris@16: const matrix_expression &e2) { Chris@16: typedef typename matrix_binary_traits >::expression_type expression_type; Chris@16: return expression_type (e1 (), e2 ()); Chris@16: } Chris@16: Chris@16: template Chris@16: class matrix_binary_scalar1: Chris@16: public matrix_expression > { Chris@16: Chris@16: typedef E1 expression1_type; Chris@16: typedef E2 expression2_type; Chris@16: typedef F functor_type; Chris@16: typedef const E1& expression1_closure_type; Chris@16: typedef typename E2::const_closure_type expression2_closure_type; Chris@16: typedef matrix_binary_scalar1 self_type; Chris@16: public: Chris@16: #ifdef BOOST_UBLAS_ENABLE_PROXY_SHORTCUTS Chris@16: using matrix_expression::operator (); Chris@16: #endif Chris@16: typedef typename E2::size_type size_type; Chris@16: typedef typename E2::difference_type difference_type; Chris@16: typedef typename F::result_type value_type; Chris@16: typedef value_type const_reference; Chris@16: typedef const_reference reference; Chris@16: typedef const self_type const_closure_type; Chris@16: typedef const_closure_type closure_type; Chris@16: typedef typename E2::orientation_category orientation_category; Chris@16: typedef unknown_storage_tag storage_category; Chris@16: Chris@16: // Construction and destruction Chris@16: BOOST_UBLAS_INLINE Chris@16: matrix_binary_scalar1 (const expression1_type &e1, const expression2_type &e2): Chris@16: e1_ (e1), e2_ (e2) {} Chris@16: Chris@16: // Accessors Chris@16: BOOST_UBLAS_INLINE Chris@16: size_type size1 () const { Chris@16: return e2_.size1 (); Chris@16: } Chris@16: BOOST_UBLAS_INLINE Chris@16: size_type size2 () const { Chris@16: return e2_.size2 (); Chris@16: } Chris@16: Chris@16: public: Chris@16: // Element access Chris@16: BOOST_UBLAS_INLINE Chris@16: const_reference operator () (size_type i, size_type j) const { Chris@16: return functor_type::apply (expression1_type (e1_), e2_ (i, j)); Chris@16: } Chris@16: Chris@16: // Closure comparison Chris@16: BOOST_UBLAS_INLINE Chris@16: bool same_closure (const matrix_binary_scalar1 &mbs1) const { Chris@16: return &e1_ == &(mbs1.e1_) && Chris@16: (*this).e2_.same_closure (mbs1.e2_); Chris@16: } Chris@16: Chris@16: // Iterator types Chris@16: private: Chris@16: typedef expression1_type const_subiterator1_type; Chris@16: typedef typename E2::const_iterator1 const_iterator21_type; Chris@16: typedef typename E2::const_iterator2 const_iterator22_type; Chris@16: typedef const value_type *const_pointer; Chris@16: Chris@16: public: Chris@16: #ifdef BOOST_UBLAS_USE_INDEXED_ITERATOR Chris@16: typedef indexed_const_iterator1 const_iterator1; Chris@16: typedef const_iterator1 iterator1; Chris@16: typedef indexed_const_iterator2 const_iterator2; Chris@16: typedef const_iterator2 iterator2; Chris@16: #else Chris@16: class const_iterator1; Chris@16: typedef const_iterator1 iterator1; Chris@16: class const_iterator2; Chris@16: typedef const_iterator2 iterator2; Chris@16: #endif Chris@16: typedef reverse_iterator_base1 const_reverse_iterator1; Chris@16: typedef reverse_iterator_base2 const_reverse_iterator2; Chris@16: Chris@16: // Element lookup Chris@16: BOOST_UBLAS_INLINE Chris@16: const_iterator1 find1 (int rank, size_type i, size_type j) const { Chris@16: const_iterator21_type it21 (e2_.find1 (rank, i, j)); Chris@16: #ifdef BOOST_UBLAS_USE_INDEXED_ITERATOR Chris@16: return const_iterator1 (*this, it21.index1 (), it21.index2 ()); Chris@16: #else Chris@16: return const_iterator1 (*this, const_subiterator1_type (e1_), it21); Chris@16: #endif Chris@16: } Chris@16: BOOST_UBLAS_INLINE Chris@16: const_iterator2 find2 (int rank, size_type i, size_type j) const { Chris@16: const_iterator22_type it22 (e2_.find2 (rank, i, j)); Chris@16: #ifdef BOOST_UBLAS_USE_INDEXED_ITERATOR Chris@16: return const_iterator2 (*this, it22.index1 (), it22.index2 ()); Chris@16: #else Chris@16: return const_iterator2 (*this, const_subiterator1_type (e1_), it22); Chris@16: #endif Chris@16: } Chris@16: Chris@16: // Iterators enhance the iterators of the referenced expression Chris@16: // with the binary functor. Chris@16: Chris@16: #ifndef BOOST_UBLAS_USE_INDEXED_ITERATOR Chris@16: class const_iterator1: Chris@16: public container_const_reference, Chris@16: public iterator_base_traits::template Chris@16: iterator_base::type { Chris@16: public: Chris@16: typedef typename E2::const_iterator1::iterator_category iterator_category; Chris@16: typedef typename matrix_binary_scalar1::difference_type difference_type; Chris@16: typedef typename matrix_binary_scalar1::value_type value_type; Chris@16: typedef typename matrix_binary_scalar1::const_reference reference; Chris@16: typedef typename matrix_binary_scalar1::const_pointer pointer; Chris@16: Chris@16: typedef const_iterator2 dual_iterator_type; Chris@16: typedef const_reverse_iterator2 dual_reverse_iterator_type; Chris@16: Chris@16: // Construction and destruction Chris@16: BOOST_UBLAS_INLINE Chris@16: const_iterator1 (): Chris@16: container_const_reference (), it1_ (), it2_ () {} Chris@16: BOOST_UBLAS_INLINE Chris@16: const_iterator1 (const self_type &mbs, const const_subiterator1_type &it1, const const_iterator21_type &it2): Chris@16: container_const_reference (mbs), it1_ (it1), it2_ (it2) {} Chris@16: Chris@16: // Arithmetic Chris@16: BOOST_UBLAS_INLINE Chris@16: const_iterator1 &operator ++ () { Chris@16: ++ it2_; Chris@16: return *this; Chris@16: } Chris@16: BOOST_UBLAS_INLINE Chris@16: const_iterator1 &operator -- () { Chris@16: -- it2_ ; Chris@16: return *this; Chris@16: } Chris@16: BOOST_UBLAS_INLINE Chris@16: const_iterator1 &operator += (difference_type n) { Chris@16: it2_ += n; Chris@16: return *this; Chris@16: } Chris@16: BOOST_UBLAS_INLINE Chris@16: const_iterator1 &operator -= (difference_type n) { Chris@16: it2_ -= n; Chris@16: return *this; Chris@16: } Chris@16: BOOST_UBLAS_INLINE Chris@16: difference_type operator - (const const_iterator1 &it) const { Chris@16: BOOST_UBLAS_CHECK ((*this) ().same_closure (it ()), external_logic ()); Chris@16: // FIXME we shouldn't compare floats Chris@16: // BOOST_UBLAS_CHECK (it1_ == it.it1_, external_logic ()); Chris@16: return it2_ - it.it2_; Chris@16: } Chris@16: Chris@16: // Dereference Chris@16: BOOST_UBLAS_INLINE Chris@16: const_reference operator * () const { Chris@16: return functor_type::apply (it1_, *it2_); Chris@16: } Chris@16: BOOST_UBLAS_INLINE Chris@16: const_reference operator [] (difference_type n) const { Chris@16: return *(*this + n); Chris@16: } Chris@16: Chris@16: #ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION Chris@16: BOOST_UBLAS_INLINE Chris@16: #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION Chris@16: typename self_type:: Chris@16: #endif Chris@16: const_iterator2 begin () const { Chris@16: return (*this) ().find2 (1, index1 (), 0); Chris@16: } Chris@16: BOOST_UBLAS_INLINE Chris@16: #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION Chris@16: typename self_type:: Chris@16: #endif Chris@101: const_iterator2 cbegin () const { Chris@101: return begin (); Chris@101: } Chris@101: BOOST_UBLAS_INLINE Chris@101: #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION Chris@101: typename self_type:: Chris@101: #endif Chris@16: const_iterator2 end () const { Chris@16: return (*this) ().find2 (1, index1 (), (*this) ().size2 ()); Chris@16: } Chris@16: BOOST_UBLAS_INLINE Chris@16: #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION Chris@16: typename self_type:: Chris@16: #endif Chris@101: const_iterator2 cend () const { Chris@101: return end (); Chris@101: } Chris@101: BOOST_UBLAS_INLINE Chris@101: #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION Chris@101: typename self_type:: Chris@101: #endif Chris@16: const_reverse_iterator2 rbegin () const { Chris@16: return const_reverse_iterator2 (end ()); Chris@16: } Chris@16: BOOST_UBLAS_INLINE Chris@16: #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION Chris@16: typename self_type:: Chris@16: #endif Chris@101: const_reverse_iterator2 crbegin () const { Chris@101: return rbegin (); Chris@101: } Chris@101: BOOST_UBLAS_INLINE Chris@101: #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION Chris@101: typename self_type:: Chris@101: #endif Chris@16: const_reverse_iterator2 rend () const { Chris@16: return const_reverse_iterator2 (begin ()); Chris@16: } Chris@101: BOOST_UBLAS_INLINE Chris@101: #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION Chris@101: typename self_type:: Chris@101: #endif Chris@101: const_reverse_iterator2 crend () const { Chris@101: return rend (); Chris@101: } Chris@16: #endif Chris@16: Chris@16: // Indices Chris@16: BOOST_UBLAS_INLINE Chris@16: size_type index1 () const { Chris@16: return it2_.index1 (); Chris@16: } Chris@16: BOOST_UBLAS_INLINE Chris@16: size_type index2 () const { Chris@16: return it2_.index2 (); Chris@16: } Chris@16: Chris@16: // Assignment Chris@16: BOOST_UBLAS_INLINE Chris@16: const_iterator1 &operator = (const const_iterator1 &it) { Chris@16: container_const_reference::assign (&it ()); Chris@16: it1_ = it.it1_; Chris@16: it2_ = it.it2_; Chris@16: return *this; Chris@16: } Chris@16: Chris@16: // Comparison Chris@16: BOOST_UBLAS_INLINE Chris@16: bool operator == (const const_iterator1 &it) const { Chris@16: BOOST_UBLAS_CHECK ((*this) ().same_closure (it ()), external_logic ()); Chris@16: // FIXME we shouldn't compare floats Chris@16: // BOOST_UBLAS_CHECK (it1_ == it.it1_, external_logic ()); Chris@16: return it2_ == it.it2_; Chris@16: } Chris@16: BOOST_UBLAS_INLINE Chris@16: bool operator < (const const_iterator1 &it) const { Chris@16: BOOST_UBLAS_CHECK ((*this) ().same_closure (it ()), external_logic ()); Chris@16: // FIXME we shouldn't compare floats Chris@16: // BOOST_UBLAS_CHECK (it1_ == it.it1_, external_logic ()); Chris@16: return it2_ < it.it2_; Chris@16: } Chris@16: Chris@16: private: Chris@16: const_subiterator1_type it1_; Chris@16: const_iterator21_type it2_; Chris@16: }; Chris@16: #endif Chris@16: Chris@16: BOOST_UBLAS_INLINE Chris@16: const_iterator1 begin1 () const { Chris@16: return find1 (0, 0, 0); Chris@16: } Chris@16: BOOST_UBLAS_INLINE Chris@101: const_iterator1 cbegin1 () const { Chris@101: return begin1 (); Chris@101: } Chris@101: BOOST_UBLAS_INLINE Chris@16: const_iterator1 end1 () const { Chris@16: return find1 (0, size1 (), 0); Chris@16: } Chris@101: BOOST_UBLAS_INLINE Chris@101: const_iterator1 cend1 () const { Chris@101: return end1 (); Chris@101: } Chris@16: Chris@16: #ifndef BOOST_UBLAS_USE_INDEXED_ITERATOR Chris@16: class const_iterator2: Chris@16: public container_const_reference, Chris@16: public iterator_base_traits::template Chris@16: iterator_base::type { Chris@16: public: Chris@16: typedef typename E2::const_iterator2::iterator_category iterator_category; Chris@16: typedef typename matrix_binary_scalar1::difference_type difference_type; Chris@16: typedef typename matrix_binary_scalar1::value_type value_type; Chris@16: typedef typename matrix_binary_scalar1::const_reference reference; Chris@16: typedef typename matrix_binary_scalar1::const_pointer pointer; Chris@16: Chris@16: typedef const_iterator1 dual_iterator_type; Chris@16: typedef const_reverse_iterator1 dual_reverse_iterator_type; Chris@16: Chris@16: // Construction and destruction Chris@16: BOOST_UBLAS_INLINE Chris@16: const_iterator2 (): Chris@16: container_const_reference (), it1_ (), it2_ () {} Chris@16: BOOST_UBLAS_INLINE Chris@16: const_iterator2 (const self_type &mbs, const const_subiterator1_type &it1, const const_iterator22_type &it2): Chris@16: container_const_reference (mbs), it1_ (it1), it2_ (it2) {} Chris@16: Chris@16: // Arithmetic Chris@16: BOOST_UBLAS_INLINE Chris@16: const_iterator2 &operator ++ () { Chris@16: ++ it2_; Chris@16: return *this; Chris@16: } Chris@16: BOOST_UBLAS_INLINE Chris@16: const_iterator2 &operator -- () { Chris@16: -- it2_; Chris@16: return *this; Chris@16: } Chris@16: BOOST_UBLAS_INLINE Chris@16: const_iterator2 &operator += (difference_type n) { Chris@16: it2_ += n; Chris@16: return *this; Chris@16: } Chris@16: BOOST_UBLAS_INLINE Chris@16: const_iterator2 &operator -= (difference_type n) { Chris@16: it2_ -= n; Chris@16: return *this; Chris@16: } Chris@16: BOOST_UBLAS_INLINE Chris@16: difference_type operator - (const const_iterator2 &it) const { Chris@16: BOOST_UBLAS_CHECK ((*this) ().same_closure (it ()), external_logic ()); Chris@16: // FIXME we shouldn't compare floats Chris@16: // BOOST_UBLAS_CHECK (it1_ == it.it1_, external_logic ()); Chris@16: return it2_ - it.it2_; Chris@16: } Chris@16: Chris@16: // Dereference Chris@16: BOOST_UBLAS_INLINE Chris@16: const_reference operator * () const { Chris@16: return functor_type::apply (it1_, *it2_); Chris@16: } Chris@16: BOOST_UBLAS_INLINE Chris@16: const_reference operator [] (difference_type n) const { Chris@16: return *(*this + n); Chris@16: } Chris@16: Chris@16: #ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION Chris@16: BOOST_UBLAS_INLINE Chris@16: #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION Chris@16: typename self_type:: Chris@16: #endif Chris@16: const_iterator1 begin () const { Chris@16: return (*this) ().find1 (1, 0, index2 ()); Chris@16: } Chris@16: BOOST_UBLAS_INLINE Chris@16: #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION Chris@16: typename self_type:: Chris@16: #endif Chris@101: const_iterator1 cbegin () const { Chris@101: return begin (); Chris@101: } Chris@101: BOOST_UBLAS_INLINE Chris@101: #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION Chris@101: typename self_type:: Chris@101: #endif Chris@16: const_iterator1 end () const { Chris@16: return (*this) ().find1 (1, (*this) ().size1 (), index2 ()); Chris@16: } Chris@16: BOOST_UBLAS_INLINE Chris@16: #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION Chris@16: typename self_type:: Chris@16: #endif Chris@101: const_iterator1 cend () const { Chris@101: return end (); Chris@101: } Chris@101: BOOST_UBLAS_INLINE Chris@101: #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION Chris@101: typename self_type:: Chris@101: #endif Chris@16: const_reverse_iterator1 rbegin () const { Chris@16: return const_reverse_iterator1 (end ()); Chris@16: } Chris@16: BOOST_UBLAS_INLINE Chris@16: #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION Chris@16: typename self_type:: Chris@16: #endif Chris@101: const_reverse_iterator1 crbegin () const { Chris@101: return rbegin (); Chris@101: } Chris@101: BOOST_UBLAS_INLINE Chris@101: #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION Chris@101: typename self_type:: Chris@101: #endif Chris@16: const_reverse_iterator1 rend () const { Chris@16: return const_reverse_iterator1 (begin ()); Chris@16: } Chris@101: BOOST_UBLAS_INLINE Chris@101: #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION Chris@101: typename self_type:: Chris@101: #endif Chris@101: const_reverse_iterator1 crend () const { Chris@101: return rend (); Chris@101: } Chris@16: #endif Chris@16: Chris@16: // Indices Chris@16: BOOST_UBLAS_INLINE Chris@16: size_type index1 () const { Chris@16: return it2_.index1 (); Chris@16: } Chris@16: BOOST_UBLAS_INLINE Chris@16: size_type index2 () const { Chris@16: return it2_.index2 (); Chris@16: } Chris@16: Chris@16: // Assignment Chris@16: BOOST_UBLAS_INLINE Chris@16: const_iterator2 &operator = (const const_iterator2 &it) { Chris@16: container_const_reference::assign (&it ()); Chris@16: it1_ = it.it1_; Chris@16: it2_ = it.it2_; Chris@16: return *this; Chris@16: } Chris@16: Chris@16: // Comparison Chris@16: BOOST_UBLAS_INLINE Chris@16: bool operator == (const const_iterator2 &it) const { Chris@16: BOOST_UBLAS_CHECK ((*this) ().same_closure (it ()), external_logic ()); Chris@16: // FIXME we shouldn't compare floats Chris@16: // BOOST_UBLAS_CHECK (it1_ == it.it1_, external_logic ()); Chris@16: return it2_ == it.it2_; Chris@16: } Chris@16: BOOST_UBLAS_INLINE Chris@16: bool operator < (const const_iterator2 &it) const { Chris@16: BOOST_UBLAS_CHECK ((*this) ().same_closure (it ()), external_logic ()); Chris@16: // FIXME we shouldn't compare floats Chris@16: // BOOST_UBLAS_CHECK (it1_ == it.it1_, external_logic ()); Chris@16: return it2_ < it.it2_; Chris@16: } Chris@16: Chris@16: private: Chris@16: const_subiterator1_type it1_; Chris@16: const_iterator22_type it2_; Chris@16: }; Chris@16: #endif Chris@16: Chris@16: BOOST_UBLAS_INLINE Chris@16: const_iterator2 begin2 () const { Chris@16: return find2 (0, 0, 0); Chris@16: } Chris@16: BOOST_UBLAS_INLINE Chris@101: const_iterator2 cbegin2 () const { Chris@101: return begin2 (); Chris@101: } Chris@101: BOOST_UBLAS_INLINE Chris@16: const_iterator2 end2 () const { Chris@16: return find2 (0, 0, size2 ()); Chris@16: } Chris@101: BOOST_UBLAS_INLINE Chris@101: const_iterator2 cend2 () const { Chris@101: return end2 (); Chris@101: } Chris@16: Chris@16: // Reverse iterators Chris@16: Chris@16: BOOST_UBLAS_INLINE Chris@16: const_reverse_iterator1 rbegin1 () const { Chris@16: return const_reverse_iterator1 (end1 ()); Chris@16: } Chris@16: BOOST_UBLAS_INLINE Chris@101: const_reverse_iterator1 crbegin1 () const { Chris@101: return rbegin1 (); Chris@101: } Chris@101: BOOST_UBLAS_INLINE Chris@16: const_reverse_iterator1 rend1 () const { Chris@16: return const_reverse_iterator1 (begin1 ()); Chris@16: } Chris@101: BOOST_UBLAS_INLINE Chris@101: const_reverse_iterator1 crend1 () const { Chris@101: return rend1 (); Chris@101: } Chris@16: Chris@16: BOOST_UBLAS_INLINE Chris@16: const_reverse_iterator2 rbegin2 () const { Chris@16: return const_reverse_iterator2 (end2 ()); Chris@16: } Chris@16: BOOST_UBLAS_INLINE Chris@101: const_reverse_iterator2 crbegin2 () const { Chris@101: return rbegin2 (); Chris@101: } Chris@101: BOOST_UBLAS_INLINE Chris@16: const_reverse_iterator2 rend2 () const { Chris@16: return const_reverse_iterator2 (begin2 ()); Chris@16: } Chris@101: BOOST_UBLAS_INLINE Chris@101: const_reverse_iterator2 crend2 () const { Chris@101: return rend2 (); Chris@101: } Chris@16: Chris@16: private: Chris@16: expression1_closure_type e1_; Chris@16: expression2_closure_type e2_; Chris@16: }; Chris@16: Chris@16: template Chris@16: struct matrix_binary_scalar1_traits { Chris@16: typedef matrix_binary_scalar1 expression_type; // allow E1 to be builtin type Chris@16: #ifndef BOOST_UBLAS_SIMPLE_ET_DEBUG Chris@16: typedef expression_type result_type; Chris@16: #else Chris@16: typedef typename E2::matrix_temporary_type result_type; Chris@16: #endif Chris@16: }; Chris@16: Chris@16: // (t * m) [i] [j] = t * m [i] [j] Chris@16: template Chris@16: BOOST_UBLAS_INLINE Chris@16: typename enable_if< is_convertible, Chris@16: typename matrix_binary_scalar1_traits >::result_type Chris@16: >::type Chris@16: operator * (const T1 &e1, Chris@16: const matrix_expression &e2) { Chris@16: typedef typename matrix_binary_scalar1_traits >::expression_type expression_type; Chris@16: return expression_type (e1, e2 ()); Chris@16: } Chris@16: Chris@16: Chris@16: template Chris@16: class matrix_binary_scalar2: Chris@16: public matrix_expression > { Chris@16: Chris@16: typedef E1 expression1_type; Chris@16: typedef E2 expression2_type; Chris@16: typedef F functor_type; Chris@16: public: Chris@16: typedef typename E1::const_closure_type expression1_closure_type; Chris@16: typedef const E2& expression2_closure_type; Chris@16: private: Chris@16: typedef matrix_binary_scalar2 self_type; Chris@16: public: Chris@16: #ifdef BOOST_UBLAS_ENABLE_PROXY_SHORTCUTS Chris@16: using matrix_expression::operator (); Chris@16: #endif Chris@16: typedef typename E1::size_type size_type; Chris@16: typedef typename E1::difference_type difference_type; Chris@16: typedef typename F::result_type value_type; Chris@16: typedef value_type const_reference; Chris@16: typedef const_reference reference; Chris@16: Chris@16: typedef const self_type const_closure_type; Chris@16: typedef const_closure_type closure_type; Chris@16: typedef typename E1::orientation_category orientation_category; Chris@16: typedef unknown_storage_tag storage_category; Chris@16: Chris@16: // Construction and destruction Chris@16: BOOST_UBLAS_INLINE Chris@16: matrix_binary_scalar2 (const expression1_type &e1, const expression2_type &e2): Chris@16: e1_ (e1), e2_ (e2) {} Chris@16: Chris@16: // Accessors Chris@16: BOOST_UBLAS_INLINE Chris@16: size_type size1 () const { Chris@16: return e1_.size1 (); Chris@16: } Chris@16: BOOST_UBLAS_INLINE Chris@16: size_type size2 () const { Chris@16: return e1_.size2 (); Chris@16: } Chris@16: Chris@16: public: Chris@16: // Element access Chris@16: BOOST_UBLAS_INLINE Chris@16: const_reference operator () (size_type i, size_type j) const { Chris@16: return functor_type::apply (e1_ (i, j), expression2_type (e2_)); Chris@16: } Chris@16: Chris@16: // Closure comparison Chris@16: BOOST_UBLAS_INLINE Chris@16: bool same_closure (const matrix_binary_scalar2 &mbs2) const { Chris@16: return (*this).e1_.same_closure (mbs2.e1_) && Chris@16: &e2_ == &(mbs2.e2_); Chris@16: } Chris@16: Chris@16: // Iterator types Chris@16: private: Chris@16: typedef typename E1::const_iterator1 const_iterator11_type; Chris@16: typedef typename E1::const_iterator2 const_iterator12_type; Chris@16: typedef expression2_type const_subiterator2_type; Chris@16: typedef const value_type *const_pointer; Chris@16: Chris@16: public: Chris@16: #ifdef BOOST_UBLAS_USE_INDEXED_ITERATOR Chris@16: typedef indexed_const_iterator1 const_iterator1; Chris@16: typedef const_iterator1 iterator1; Chris@16: typedef indexed_const_iterator2 const_iterator2; Chris@16: typedef const_iterator2 iterator2; Chris@16: #else Chris@16: class const_iterator1; Chris@16: typedef const_iterator1 iterator1; Chris@16: class const_iterator2; Chris@16: typedef const_iterator2 iterator2; Chris@16: #endif Chris@16: typedef reverse_iterator_base1 const_reverse_iterator1; Chris@16: typedef reverse_iterator_base2 const_reverse_iterator2; Chris@16: Chris@16: // Element lookup Chris@16: BOOST_UBLAS_INLINE Chris@16: const_iterator1 find1 (int rank, size_type i, size_type j) const { Chris@16: const_iterator11_type it11 (e1_.find1 (rank, i, j)); Chris@16: #ifdef BOOST_UBLAS_USE_INDEXED_ITERATOR Chris@16: return const_iterator1 (*this, it11.index1 (), it11.index2 ()); Chris@16: #else Chris@16: return const_iterator1 (*this, it11, const_subiterator2_type (e2_)); Chris@16: #endif Chris@16: } Chris@16: BOOST_UBLAS_INLINE Chris@16: const_iterator2 find2 (int rank, size_type i, size_type j) const { Chris@16: const_iterator12_type it12 (e1_.find2 (rank, i, j)); Chris@16: #ifdef BOOST_UBLAS_USE_INDEXED_ITERATOR Chris@16: return const_iterator2 (*this, it12.index1 (), it12.index2 ()); Chris@16: #else Chris@16: return const_iterator2 (*this, it12, const_subiterator2_type (e2_)); Chris@16: #endif Chris@16: } Chris@16: Chris@16: // Iterators enhance the iterators of the referenced expression Chris@16: // with the binary functor. Chris@16: Chris@16: #ifndef BOOST_UBLAS_USE_INDEXED_ITERATOR Chris@16: class const_iterator1: Chris@16: public container_const_reference, Chris@16: public iterator_base_traits::template Chris@16: iterator_base::type { Chris@16: public: Chris@16: typedef typename E1::const_iterator1::iterator_category iterator_category; Chris@16: typedef typename matrix_binary_scalar2::difference_type difference_type; Chris@16: typedef typename matrix_binary_scalar2::value_type value_type; Chris@16: typedef typename matrix_binary_scalar2::const_reference reference; Chris@16: typedef typename matrix_binary_scalar2::const_pointer pointer; Chris@16: Chris@16: typedef const_iterator2 dual_iterator_type; Chris@16: typedef const_reverse_iterator2 dual_reverse_iterator_type; Chris@16: Chris@16: // Construction and destruction Chris@16: BOOST_UBLAS_INLINE Chris@16: const_iterator1 (): Chris@16: container_const_reference (), it1_ (), it2_ () {} Chris@16: BOOST_UBLAS_INLINE Chris@16: const_iterator1 (const self_type &mbs, const const_iterator11_type &it1, const const_subiterator2_type &it2): Chris@16: container_const_reference (mbs), it1_ (it1), it2_ (it2) {} Chris@16: Chris@16: // Arithmetic Chris@16: BOOST_UBLAS_INLINE Chris@16: const_iterator1 &operator ++ () { Chris@16: ++ it1_; Chris@16: return *this; Chris@16: } Chris@16: BOOST_UBLAS_INLINE Chris@16: const_iterator1 &operator -- () { Chris@16: -- it1_ ; Chris@16: return *this; Chris@16: } Chris@16: BOOST_UBLAS_INLINE Chris@16: const_iterator1 &operator += (difference_type n) { Chris@16: it1_ += n; Chris@16: return *this; Chris@16: } Chris@16: BOOST_UBLAS_INLINE Chris@16: const_iterator1 &operator -= (difference_type n) { Chris@16: it1_ -= n; Chris@16: return *this; Chris@16: } Chris@16: BOOST_UBLAS_INLINE Chris@16: difference_type operator - (const const_iterator1 &it) const { Chris@16: BOOST_UBLAS_CHECK ((*this) ().same_closure (it ()), external_logic ()); Chris@16: // FIXME we shouldn't compare floats Chris@16: // BOOST_UBLAS_CHECK (it2_ == it.it2_, external_logic ()); Chris@16: return it1_ - it.it1_; Chris@16: } Chris@16: Chris@16: // Dereference Chris@16: BOOST_UBLAS_INLINE Chris@16: const_reference operator * () const { Chris@16: return functor_type::apply (*it1_, it2_); Chris@16: } Chris@16: BOOST_UBLAS_INLINE Chris@16: const_reference operator [] (difference_type n) const { Chris@16: return *(*this + n); Chris@16: } Chris@16: Chris@16: #ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION Chris@16: BOOST_UBLAS_INLINE Chris@16: #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION Chris@16: typename self_type:: Chris@16: #endif Chris@16: const_iterator2 begin () const { Chris@16: return (*this) ().find2 (1, index1 (), 0); Chris@16: } Chris@16: BOOST_UBLAS_INLINE Chris@16: #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION Chris@16: typename self_type:: Chris@16: #endif Chris@101: const_iterator2 cbegin () const { Chris@101: return begin (); Chris@101: } Chris@101: BOOST_UBLAS_INLINE Chris@101: #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION Chris@101: typename self_type:: Chris@101: #endif Chris@16: const_iterator2 end () const { Chris@16: return (*this) ().find2 (1, index1 (), (*this) ().size2 ()); Chris@16: } Chris@16: BOOST_UBLAS_INLINE Chris@16: #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION Chris@16: typename self_type:: Chris@16: #endif Chris@101: const_iterator2 cend () const { Chris@101: return end (); Chris@101: } Chris@101: BOOST_UBLAS_INLINE Chris@101: #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION Chris@101: typename self_type:: Chris@101: #endif Chris@16: const_reverse_iterator2 rbegin () const { Chris@16: return const_reverse_iterator2 (end ()); Chris@16: } Chris@16: BOOST_UBLAS_INLINE Chris@16: #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION Chris@16: typename self_type:: Chris@16: #endif Chris@101: const_reverse_iterator2 crbegin () const { Chris@101: return rbegin (); Chris@101: } Chris@101: BOOST_UBLAS_INLINE Chris@101: #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION Chris@101: typename self_type:: Chris@101: #endif Chris@16: const_reverse_iterator2 rend () const { Chris@16: return const_reverse_iterator2 (begin ()); Chris@16: } Chris@101: BOOST_UBLAS_INLINE Chris@101: #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION Chris@101: typename self_type:: Chris@101: #endif Chris@101: const_reverse_iterator2 crend () const { Chris@101: return rend (); Chris@101: } Chris@16: #endif Chris@16: Chris@16: // Indices Chris@16: BOOST_UBLAS_INLINE Chris@16: size_type index1 () const { Chris@16: return it1_.index1 (); Chris@16: } Chris@16: BOOST_UBLAS_INLINE Chris@16: size_type index2 () const { Chris@16: return it1_.index2 (); Chris@16: } Chris@16: Chris@16: // Assignment Chris@16: BOOST_UBLAS_INLINE Chris@16: const_iterator1 &operator = (const const_iterator1 &it) { Chris@16: container_const_reference::assign (&it ()); Chris@16: it1_ = it.it1_; Chris@16: it2_ = it.it2_; Chris@16: return *this; Chris@16: } Chris@16: Chris@16: // Comparison Chris@16: BOOST_UBLAS_INLINE Chris@16: bool operator == (const const_iterator1 &it) const { Chris@16: BOOST_UBLAS_CHECK ((*this) ().same_closure (it ()), external_logic ()); Chris@16: // FIXME we shouldn't compare floats Chris@16: // BOOST_UBLAS_CHECK (it2_ == it.it2_, external_logic ()); Chris@16: return it1_ == it.it1_; Chris@16: } Chris@16: BOOST_UBLAS_INLINE Chris@16: bool operator < (const const_iterator1 &it) const { Chris@16: BOOST_UBLAS_CHECK ((*this) ().same_closure (it ()), external_logic ()); Chris@16: // FIXME we shouldn't compare floats Chris@16: // BOOST_UBLAS_CHECK (it2_ == it.it2_, external_logic ()); Chris@16: return it1_ < it.it1_; Chris@16: } Chris@16: Chris@16: private: Chris@16: const_iterator11_type it1_; Chris@16: const_subiterator2_type it2_; Chris@16: }; Chris@16: #endif Chris@16: Chris@16: BOOST_UBLAS_INLINE Chris@16: const_iterator1 begin1 () const { Chris@16: return find1 (0, 0, 0); Chris@16: } Chris@16: BOOST_UBLAS_INLINE Chris@101: const_iterator1 cbegin1 () const { Chris@101: return begin1 (); Chris@101: } Chris@101: BOOST_UBLAS_INLINE Chris@16: const_iterator1 end1 () const { Chris@16: return find1 (0, size1 (), 0); Chris@16: } Chris@101: BOOST_UBLAS_INLINE Chris@101: const_iterator1 cend1 () const { Chris@101: return end1 (); Chris@101: } Chris@16: Chris@16: #ifndef BOOST_UBLAS_USE_INDEXED_ITERATOR Chris@16: class const_iterator2: Chris@16: public container_const_reference, Chris@16: public iterator_base_traits::template Chris@16: iterator_base::type { Chris@16: public: Chris@16: typedef typename E1::const_iterator2::iterator_category iterator_category; Chris@16: typedef typename matrix_binary_scalar2::difference_type difference_type; Chris@16: typedef typename matrix_binary_scalar2::value_type value_type; Chris@16: typedef typename matrix_binary_scalar2::const_reference reference; Chris@16: typedef typename matrix_binary_scalar2::const_pointer pointer; Chris@16: Chris@16: typedef const_iterator1 dual_iterator_type; Chris@16: typedef const_reverse_iterator1 dual_reverse_iterator_type; Chris@16: Chris@16: // Construction and destruction Chris@16: BOOST_UBLAS_INLINE Chris@16: const_iterator2 (): Chris@16: container_const_reference (), it1_ (), it2_ () {} Chris@16: BOOST_UBLAS_INLINE Chris@16: const_iterator2 (const self_type &mbs, const const_iterator12_type &it1, const const_subiterator2_type &it2): Chris@16: container_const_reference (mbs), it1_ (it1), it2_ (it2) {} Chris@16: Chris@16: // Arithmetic Chris@16: BOOST_UBLAS_INLINE Chris@16: const_iterator2 &operator ++ () { Chris@16: ++ it1_; Chris@16: return *this; Chris@16: } Chris@16: BOOST_UBLAS_INLINE Chris@16: const_iterator2 &operator -- () { Chris@16: -- it1_; Chris@16: return *this; Chris@16: } Chris@16: BOOST_UBLAS_INLINE Chris@16: const_iterator2 &operator += (difference_type n) { Chris@16: it1_ += n; Chris@16: return *this; Chris@16: } Chris@16: BOOST_UBLAS_INLINE Chris@16: const_iterator2 &operator -= (difference_type n) { Chris@16: it1_ -= n; Chris@16: return *this; Chris@16: } Chris@16: BOOST_UBLAS_INLINE Chris@16: difference_type operator - (const const_iterator2 &it) const { Chris@16: BOOST_UBLAS_CHECK ((*this) ().same_closure (it ()), external_logic ()); Chris@16: // FIXME we shouldn't compare floats Chris@16: // BOOST_UBLAS_CHECK (it2_ == it.it2_, external_logic ()); Chris@16: return it1_ - it.it1_; Chris@16: } Chris@16: Chris@16: // Dereference Chris@16: BOOST_UBLAS_INLINE Chris@16: const_reference operator * () const { Chris@16: return functor_type::apply (*it1_, it2_); Chris@16: } Chris@16: BOOST_UBLAS_INLINE Chris@16: const_reference operator [] (difference_type n) const { Chris@16: return *(*this + n); Chris@16: } Chris@16: Chris@16: #ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION Chris@16: BOOST_UBLAS_INLINE Chris@16: #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION Chris@16: typename self_type:: Chris@16: #endif Chris@16: const_iterator1 begin () const { Chris@16: return (*this) ().find1 (1, 0, index2 ()); Chris@16: } Chris@16: BOOST_UBLAS_INLINE Chris@16: #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION Chris@16: typename self_type:: Chris@16: #endif Chris@101: const_iterator1 cbegin () const { Chris@101: return begin (); Chris@101: } Chris@101: BOOST_UBLAS_INLINE Chris@101: #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION Chris@101: typename self_type:: Chris@101: #endif Chris@16: const_iterator1 end () const { Chris@16: return (*this) ().find1 (1, (*this) ().size1 (), index2 ()); Chris@16: } Chris@16: BOOST_UBLAS_INLINE Chris@16: #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION Chris@16: typename self_type:: Chris@16: #endif Chris@101: const_iterator1 cend () const { Chris@101: return end (); Chris@101: } Chris@101: BOOST_UBLAS_INLINE Chris@101: #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION Chris@101: typename self_type:: Chris@101: #endif Chris@16: const_reverse_iterator1 rbegin () const { Chris@16: return const_reverse_iterator1 (end ()); Chris@16: } Chris@16: BOOST_UBLAS_INLINE Chris@16: #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION Chris@16: typename self_type:: Chris@16: #endif Chris@101: const_reverse_iterator1 crbegin () const { Chris@101: return rbegin (); Chris@101: } Chris@101: BOOST_UBLAS_INLINE Chris@101: #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION Chris@101: typename self_type:: Chris@101: #endif Chris@16: const_reverse_iterator1 rend () const { Chris@16: return const_reverse_iterator1 (begin ()); Chris@16: } Chris@101: BOOST_UBLAS_INLINE Chris@101: #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION Chris@101: typename self_type:: Chris@101: #endif Chris@101: const_reverse_iterator1 crend () const { Chris@101: return rend (); Chris@101: } Chris@16: #endif Chris@16: Chris@16: // Indices Chris@16: BOOST_UBLAS_INLINE Chris@16: size_type index1 () const { Chris@16: return it1_.index1 (); Chris@16: } Chris@16: BOOST_UBLAS_INLINE Chris@16: size_type index2 () const { Chris@16: return it1_.index2 (); Chris@16: } Chris@16: Chris@16: // Assignment Chris@16: BOOST_UBLAS_INLINE Chris@16: const_iterator2 &operator = (const const_iterator2 &it) { Chris@16: container_const_reference::assign (&it ()); Chris@16: it1_ = it.it1_; Chris@16: it2_ = it.it2_; Chris@16: return *this; Chris@16: } Chris@16: Chris@16: // Comparison Chris@16: BOOST_UBLAS_INLINE Chris@16: bool operator == (const const_iterator2 &it) const { Chris@16: BOOST_UBLAS_CHECK ((*this) ().same_closure (it ()), external_logic ()); Chris@16: // FIXME we shouldn't compare floats Chris@16: // BOOST_UBLAS_CHECK (it2_ == it.it2_, external_logic ()); Chris@16: return it1_ == it.it1_; Chris@16: } Chris@16: BOOST_UBLAS_INLINE Chris@16: bool operator < (const const_iterator2 &it) const { Chris@16: BOOST_UBLAS_CHECK ((*this) ().same_closure (it ()), external_logic ()); Chris@16: // FIXME we shouldn't compare floats Chris@16: // BOOST_UBLAS_CHECK (it2_ == it.it2_, external_logic ()); Chris@16: return it1_ < it.it1_; Chris@16: } Chris@16: Chris@16: private: Chris@16: const_iterator12_type it1_; Chris@16: const_subiterator2_type it2_; Chris@16: }; Chris@16: #endif Chris@16: Chris@16: BOOST_UBLAS_INLINE Chris@16: const_iterator2 begin2 () const { Chris@16: return find2 (0, 0, 0); Chris@16: } Chris@16: BOOST_UBLAS_INLINE Chris@101: const_iterator2 cbegin2 () const { Chris@101: return begin2 (); Chris@101: } Chris@101: BOOST_UBLAS_INLINE Chris@16: const_iterator2 end2 () const { Chris@16: return find2 (0, 0, size2 ()); Chris@16: } Chris@101: BOOST_UBLAS_INLINE Chris@101: const_iterator2 cend2 () const { Chris@101: return end2 (); Chris@101: } Chris@16: Chris@16: // Reverse iterators Chris@16: Chris@16: BOOST_UBLAS_INLINE Chris@16: const_reverse_iterator1 rbegin1 () const { Chris@16: return const_reverse_iterator1 (end1 ()); Chris@16: } Chris@16: BOOST_UBLAS_INLINE Chris@101: const_reverse_iterator1 crbegin1 () const { Chris@101: return rbegin1 (); Chris@101: } Chris@101: BOOST_UBLAS_INLINE Chris@16: const_reverse_iterator1 rend1 () const { Chris@16: return const_reverse_iterator1 (begin1 ()); Chris@16: } Chris@101: BOOST_UBLAS_INLINE Chris@101: const_reverse_iterator1 crend1 () const { Chris@101: return rend1 (); Chris@101: } Chris@16: Chris@16: BOOST_UBLAS_INLINE Chris@16: const_reverse_iterator2 rbegin2 () const { Chris@16: return const_reverse_iterator2 (end2 ()); Chris@16: } Chris@16: BOOST_UBLAS_INLINE Chris@101: const_reverse_iterator2 crbegin2 () const { Chris@101: return rbegin2 (); Chris@101: } Chris@101: BOOST_UBLAS_INLINE Chris@16: const_reverse_iterator2 rend2 () const { Chris@16: return const_reverse_iterator2 (begin2 ()); Chris@16: } Chris@101: BOOST_UBLAS_INLINE Chris@101: const_reverse_iterator2 crend2 () const { Chris@101: return rend2 (); Chris@101: } Chris@16: Chris@16: private: Chris@16: expression1_closure_type e1_; Chris@16: expression2_closure_type e2_; Chris@16: }; Chris@16: Chris@16: template Chris@16: struct matrix_binary_scalar2_traits { Chris@16: typedef matrix_binary_scalar2 expression_type; // allow E2 to be builtin type Chris@16: #ifndef BOOST_UBLAS_SIMPLE_ET_DEBUG Chris@16: typedef expression_type result_type; Chris@16: #else Chris@16: typedef typename E1::matrix_temporary_type result_type; Chris@16: #endif Chris@16: }; Chris@16: Chris@16: // (m * t) [i] [j] = m [i] [j] * t Chris@16: template Chris@16: BOOST_UBLAS_INLINE Chris@16: typename enable_if< is_convertible, Chris@16: typename matrix_binary_scalar2_traits >::result_type Chris@16: >::type Chris@16: operator * (const matrix_expression &e1, Chris@16: const T2 &e2) { Chris@16: typedef typename matrix_binary_scalar2_traits >::expression_type expression_type; Chris@16: return expression_type (e1 (), e2); Chris@16: } Chris@16: Chris@16: // (m / t) [i] [j] = m [i] [j] / t Chris@16: template Chris@16: BOOST_UBLAS_INLINE Chris@101: typename enable_if< is_convertible, Chris@16: typename matrix_binary_scalar2_traits >::result_type Chris@101: >::type Chris@16: operator / (const matrix_expression &e1, Chris@16: const T2 &e2) { Chris@16: typedef typename matrix_binary_scalar2_traits >::expression_type expression_type; Chris@16: return expression_type (e1 (), e2); Chris@16: } Chris@16: Chris@16: Chris@16: template Chris@16: class matrix_vector_binary1: Chris@16: public vector_expression > { Chris@16: Chris@16: public: Chris@16: typedef E1 expression1_type; Chris@16: typedef E2 expression2_type; Chris@16: private: Chris@16: typedef F functor_type; Chris@16: public: Chris@16: typedef typename E1::const_closure_type expression1_closure_type; Chris@16: typedef typename E2::const_closure_type expression2_closure_type; Chris@16: private: Chris@16: typedef matrix_vector_binary1 self_type; Chris@16: public: Chris@16: #ifdef BOOST_UBLAS_ENABLE_PROXY_SHORTCUTS Chris@16: using vector_expression::operator (); Chris@16: #endif Chris@16: static const unsigned complexity = 1; Chris@16: typedef typename promote_traits::promote_type size_type; Chris@16: typedef typename promote_traits::promote_type difference_type; Chris@16: typedef typename F::result_type value_type; Chris@16: typedef value_type const_reference; Chris@16: typedef const_reference reference; Chris@16: typedef const self_type const_closure_type; Chris@16: typedef const_closure_type closure_type; Chris@16: typedef unknown_storage_tag storage_category; Chris@16: Chris@16: // Construction and destruction Chris@16: BOOST_UBLAS_INLINE Chris@16: matrix_vector_binary1 (const expression1_type &e1, const expression2_type &e2): Chris@16: e1_ (e1), e2_ (e2) {} Chris@16: Chris@16: // Accessors Chris@16: BOOST_UBLAS_INLINE Chris@16: size_type size () const { Chris@16: return e1_.size1 (); Chris@16: } Chris@16: Chris@16: public: Chris@16: // Expression accessors Chris@16: BOOST_UBLAS_INLINE Chris@16: const expression1_closure_type &expression1 () const { Chris@16: return e1_; Chris@16: } Chris@16: BOOST_UBLAS_INLINE Chris@16: const expression2_closure_type &expression2 () const { Chris@16: return e2_; Chris@16: } Chris@16: Chris@16: public: Chris@16: // Element access Chris@16: BOOST_UBLAS_INLINE Chris@16: const_reference operator () (size_type i) const { Chris@16: return functor_type::apply (e1_, e2_, i); Chris@16: } Chris@16: Chris@16: // Closure comparison Chris@16: BOOST_UBLAS_INLINE Chris@16: bool same_closure (const matrix_vector_binary1 &mvb1) const { Chris@16: return (*this).expression1 ().same_closure (mvb1.expression1 ()) && Chris@16: (*this).expression2 ().same_closure (mvb1.expression2 ()); Chris@16: } Chris@16: Chris@16: // Iterator types Chris@16: private: Chris@16: typedef typename E1::const_iterator1 const_subiterator1_type; Chris@16: typedef typename E2::const_iterator const_subiterator2_type; Chris@16: typedef const value_type *const_pointer; Chris@16: Chris@16: public: Chris@16: #ifdef BOOST_UBLAS_USE_INDEXED_ITERATOR Chris@16: typedef indexed_const_iterator const_iterator; Chris@16: typedef const_iterator iterator; Chris@16: #else Chris@16: class const_iterator; Chris@16: typedef const_iterator iterator; Chris@16: #endif Chris@16: Chris@16: // Element lookup Chris@16: BOOST_UBLAS_INLINE Chris@16: const_iterator find (size_type i) const { Chris@16: #ifdef BOOST_UBLAS_USE_INDEXED_ITERATOR Chris@16: const_subiterator1_type it1 (e1_.find1 (0, i, 0)); Chris@16: return const_iterator (*this, it1.index1 ()); Chris@16: #else Chris@16: return const_iterator (*this, e1_.find1 (0, i, 0)); Chris@16: #endif Chris@16: } Chris@16: Chris@16: Chris@16: #ifndef BOOST_UBLAS_USE_INDEXED_ITERATOR Chris@16: class const_iterator: Chris@16: public container_const_reference, Chris@16: public iterator_base_traits::iterator_category>::template Chris@16: iterator_base::type { Chris@16: public: Chris@16: typedef typename iterator_restrict_traits::iterator_category iterator_category; Chris@16: typedef typename matrix_vector_binary1::difference_type difference_type; Chris@16: typedef typename matrix_vector_binary1::value_type value_type; Chris@16: typedef typename matrix_vector_binary1::const_reference reference; Chris@16: typedef typename matrix_vector_binary1::const_pointer pointer; Chris@16: Chris@16: // Construction and destruction Chris@16: #ifdef BOOST_UBLAS_USE_INVARIANT_HOISTING Chris@16: BOOST_UBLAS_INLINE Chris@16: const_iterator (): Chris@16: container_const_reference (), it1_ (), e2_begin_ (), e2_end_ () {} Chris@16: BOOST_UBLAS_INLINE Chris@16: const_iterator (const self_type &mvb, const const_subiterator1_type &it1): Chris@16: container_const_reference (mvb), it1_ (it1), e2_begin_ (mvb.expression2 ().begin ()), e2_end_ (mvb.expression2 ().end ()) {} Chris@16: #else Chris@16: BOOST_UBLAS_INLINE Chris@16: const_iterator (): Chris@16: container_const_reference (), it1_ () {} Chris@16: BOOST_UBLAS_INLINE Chris@16: const_iterator (const self_type &mvb, const const_subiterator1_type &it1): Chris@16: container_const_reference (mvb), it1_ (it1) {} Chris@16: #endif Chris@16: Chris@16: private: Chris@16: // Dense random access specialization Chris@16: BOOST_UBLAS_INLINE Chris@16: value_type dereference (dense_random_access_iterator_tag) const { Chris@16: const self_type &mvb = (*this) (); Chris@16: #ifdef BOOST_UBLAS_USE_INDEXING Chris@16: return mvb (index ()); Chris@16: #elif BOOST_UBLAS_USE_ITERATING Chris@16: difference_type size = BOOST_UBLAS_SAME (mvb.expression1 ().size2 (), mvb.expression2 ().size ()); Chris@16: #ifdef BOOST_UBLAS_USE_INVARIANT_HOISTING Chris@16: return functor_type::apply (size, it1_.begin (), e2_begin_); Chris@16: #else Chris@16: return functor_type::apply (size, it1_.begin (), mvb.expression2 ().begin ()); Chris@16: #endif Chris@16: #else Chris@16: difference_type size = BOOST_UBLAS_SAME (mvb.expression1 ().size2 (), mvb.expression2 ().size ()); Chris@16: if (size >= BOOST_UBLAS_ITERATOR_THRESHOLD) Chris@16: #ifdef BOOST_UBLAS_USE_INVARIANT_HOISTING Chris@16: return functor_type::apply (size, it1_.begin (), e2_begin_); Chris@16: #else Chris@16: return functor_type::apply (size, it1_.begin (), mvb.expression2 ().begin ()); Chris@16: #endif Chris@16: else Chris@16: return mvb (index ()); Chris@16: #endif Chris@16: } Chris@16: Chris@16: // Packed bidirectional specialization Chris@16: BOOST_UBLAS_INLINE Chris@16: value_type dereference (packed_random_access_iterator_tag) const { Chris@16: #ifdef BOOST_UBLAS_USE_INVARIANT_HOISTING Chris@16: return functor_type::apply (it1_.begin (), it1_.end (), e2_begin_, e2_end_); Chris@16: #else Chris@16: const self_type &mvb = (*this) (); Chris@16: #ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION Chris@16: return functor_type::apply (it1_.begin (), it1_.end (), Chris@16: mvb.expression2 ().begin (), mvb.expression2 ().end ()); Chris@16: #else Chris@16: return functor_type::apply (boost::numeric::ublas::begin (it1_, iterator1_tag ()), Chris@16: boost::numeric::ublas::end (it1_, iterator1_tag ()), Chris@16: mvb.expression2 ().begin (), mvb.expression2 ().end ()); Chris@16: #endif Chris@16: #endif Chris@16: } Chris@16: Chris@16: // Sparse bidirectional specialization Chris@16: BOOST_UBLAS_INLINE Chris@16: value_type dereference (sparse_bidirectional_iterator_tag) const { Chris@16: #ifdef BOOST_UBLAS_USE_INVARIANT_HOISTING Chris@16: return functor_type::apply (it1_.begin (), it1_.end (), e2_begin_, e2_end_, sparse_bidirectional_iterator_tag ()); Chris@16: #else Chris@16: const self_type &mvb = (*this) (); Chris@16: #ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION Chris@16: return functor_type::apply (it1_.begin (), it1_.end (), Chris@16: mvb.expression2 ().begin (), mvb.expression2 ().end (), sparse_bidirectional_iterator_tag ()); Chris@16: #else Chris@16: return functor_type::apply (boost::numeric::ublas::begin (it1_, iterator1_tag ()), Chris@16: boost::numeric::ublas::end (it1_, iterator1_tag ()), Chris@16: mvb.expression2 ().begin (), mvb.expression2 ().end (), sparse_bidirectional_iterator_tag ()); Chris@16: #endif Chris@16: #endif Chris@16: } Chris@16: Chris@16: public: Chris@16: // Arithmetic Chris@16: BOOST_UBLAS_INLINE Chris@16: const_iterator &operator ++ () { Chris@16: ++ it1_; Chris@16: return *this; Chris@16: } Chris@16: BOOST_UBLAS_INLINE Chris@16: const_iterator &operator -- () { Chris@16: -- it1_; Chris@16: return *this; Chris@16: } Chris@16: BOOST_UBLAS_INLINE Chris@16: const_iterator &operator += (difference_type n) { Chris@16: it1_ += n; Chris@16: return *this; Chris@16: } Chris@16: BOOST_UBLAS_INLINE Chris@16: const_iterator &operator -= (difference_type n) { Chris@16: it1_ -= n; Chris@16: return *this; Chris@16: } Chris@16: BOOST_UBLAS_INLINE Chris@16: difference_type operator - (const const_iterator &it) const { Chris@16: BOOST_UBLAS_CHECK ((*this) ().same_closure (it ()), external_logic ()); Chris@16: return it1_ - it.it1_; Chris@16: } Chris@16: Chris@16: // Dereference Chris@16: BOOST_UBLAS_INLINE Chris@16: const_reference operator * () const { Chris@16: return dereference (iterator_category ()); Chris@16: } Chris@16: BOOST_UBLAS_INLINE Chris@16: const_reference operator [] (difference_type n) const { Chris@16: return *(*this + n); Chris@16: } Chris@16: Chris@16: // Index Chris@16: BOOST_UBLAS_INLINE Chris@16: size_type index () const { Chris@16: return it1_.index1 (); Chris@16: } Chris@16: Chris@16: // Assignment Chris@16: BOOST_UBLAS_INLINE Chris@16: const_iterator &operator = (const const_iterator &it) { Chris@16: container_const_reference::assign (&it ()); Chris@16: it1_ = it.it1_; Chris@16: #ifdef BOOST_UBLAS_USE_INVARIANT_HOISTING Chris@16: e2_begin_ = it.e2_begin_; Chris@16: e2_end_ = it.e2_end_; Chris@16: #endif Chris@16: return *this; Chris@16: } Chris@16: Chris@16: // Comparison Chris@16: BOOST_UBLAS_INLINE Chris@16: bool operator == (const const_iterator &it) const { Chris@16: BOOST_UBLAS_CHECK ((*this) ().same_closure (it ()), external_logic ()); Chris@16: return it1_ == it.it1_; Chris@16: } Chris@16: BOOST_UBLAS_INLINE Chris@16: bool operator < (const const_iterator &it) const { Chris@16: BOOST_UBLAS_CHECK ((*this) ().same_closure (it ()), external_logic ()); Chris@16: return it1_ < it.it1_; Chris@16: } Chris@16: Chris@16: private: Chris@16: const_subiterator1_type it1_; Chris@16: #ifdef BOOST_UBLAS_USE_INVARIANT_HOISTING Chris@16: // Mutable due to assignment Chris@16: /* const */ const_subiterator2_type e2_begin_; Chris@16: /* const */ const_subiterator2_type e2_end_; Chris@16: #endif Chris@16: }; Chris@16: #endif Chris@16: Chris@16: BOOST_UBLAS_INLINE Chris@16: const_iterator begin () const { Chris@16: return find (0); Chris@16: } Chris@16: BOOST_UBLAS_INLINE Chris@101: const_iterator cbegin () const { Chris@101: return begin (); Chris@101: } Chris@101: BOOST_UBLAS_INLINE Chris@16: const_iterator end () const { Chris@16: return find (size ()); Chris@16: } Chris@101: BOOST_UBLAS_INLINE Chris@101: const_iterator cend () const { Chris@101: return end (); Chris@101: } Chris@16: Chris@16: // Reverse iterator Chris@16: typedef reverse_iterator_base const_reverse_iterator; Chris@16: Chris@16: BOOST_UBLAS_INLINE Chris@16: const_reverse_iterator rbegin () const { Chris@16: return const_reverse_iterator (end ()); Chris@16: } Chris@16: BOOST_UBLAS_INLINE Chris@101: const_reverse_iterator crbegin () const { Chris@101: return rbegin (); Chris@101: } Chris@101: BOOST_UBLAS_INLINE Chris@16: const_reverse_iterator rend () const { Chris@16: return const_reverse_iterator (begin ()); Chris@16: } Chris@101: BOOST_UBLAS_INLINE Chris@101: const_reverse_iterator crend () const { Chris@101: return rend (); Chris@101: } Chris@16: Chris@16: private: Chris@16: expression1_closure_type e1_; Chris@16: expression2_closure_type e2_; Chris@16: }; Chris@16: Chris@16: template Chris@16: struct matrix_vector_binary1_traits { Chris@16: typedef unknown_storage_tag storage_category; Chris@16: typedef row_major_tag orientation_category; Chris@16: typedef typename promote_traits::promote_type promote_type; Chris@16: typedef matrix_vector_binary1 > expression_type; Chris@16: #ifndef BOOST_UBLAS_SIMPLE_ET_DEBUG Chris@16: typedef expression_type result_type; Chris@16: #else Chris@16: typedef typename E1::vector_temporary_type result_type; Chris@16: #endif Chris@16: }; Chris@16: Chris@16: template Chris@16: BOOST_UBLAS_INLINE Chris@16: typename matrix_vector_binary1_traits::result_type Chris@16: prod (const matrix_expression &e1, Chris@16: const vector_expression &e2, Chris@16: unknown_storage_tag, Chris@16: row_major_tag) { Chris@16: typedef typename matrix_vector_binary1_traits::expression_type expression_type; Chris@16: return expression_type (e1 (), e2 ()); Chris@16: } Chris@16: Chris@16: // Dispatcher Chris@16: template Chris@16: BOOST_UBLAS_INLINE Chris@16: typename matrix_vector_binary1_traits::result_type Chris@16: prod (const matrix_expression &e1, Chris@16: const vector_expression &e2) { Chris@16: BOOST_STATIC_ASSERT (E2::complexity == 0); Chris@16: typedef typename matrix_vector_binary1_traits::storage_category storage_category; Chris@16: typedef typename matrix_vector_binary1_traits::orientation_category orientation_category; Chris@16: return prod (e1, e2, storage_category (), orientation_category ()); Chris@16: } Chris@16: Chris@16: template Chris@16: BOOST_UBLAS_INLINE Chris@16: typename matrix_vector_binary1_traits::precision_type, E1, Chris@16: typename type_traits::precision_type, E2>::result_type Chris@16: prec_prod (const matrix_expression &e1, Chris@16: const vector_expression &e2, Chris@16: unknown_storage_tag, Chris@16: row_major_tag) { Chris@16: typedef typename matrix_vector_binary1_traits::precision_type, E1, Chris@16: typename type_traits::precision_type, E2>::expression_type expression_type; Chris@16: return expression_type (e1 (), e2 ()); Chris@16: } Chris@16: Chris@16: // Dispatcher Chris@16: template Chris@16: BOOST_UBLAS_INLINE Chris@16: typename matrix_vector_binary1_traits::precision_type, E1, Chris@16: typename type_traits::precision_type, E2>::result_type Chris@16: prec_prod (const matrix_expression &e1, Chris@16: const vector_expression &e2) { Chris@16: BOOST_STATIC_ASSERT (E2::complexity == 0); Chris@16: typedef typename matrix_vector_binary1_traits::precision_type, E1, Chris@16: typename type_traits::precision_type, E2>::storage_category storage_category; Chris@16: typedef typename matrix_vector_binary1_traits::precision_type, E1, Chris@16: typename type_traits::precision_type, E2>::orientation_category orientation_category; Chris@16: return prec_prod (e1, e2, storage_category (), orientation_category ()); Chris@16: } Chris@16: Chris@16: template Chris@16: BOOST_UBLAS_INLINE Chris@16: V & Chris@16: prod (const matrix_expression &e1, Chris@16: const vector_expression &e2, Chris@16: V &v) { Chris@16: return v.assign (prod (e1, e2)); Chris@16: } Chris@16: Chris@16: template Chris@16: BOOST_UBLAS_INLINE Chris@16: V & Chris@16: prec_prod (const matrix_expression &e1, Chris@16: const vector_expression &e2, Chris@16: V &v) { Chris@16: return v.assign (prec_prod (e1, e2)); Chris@16: } Chris@16: Chris@16: template Chris@16: BOOST_UBLAS_INLINE Chris@16: V Chris@16: prod (const matrix_expression &e1, Chris@16: const vector_expression &e2) { Chris@16: return V (prod (e1, e2)); Chris@16: } Chris@16: Chris@16: template Chris@16: BOOST_UBLAS_INLINE Chris@16: V Chris@16: prec_prod (const matrix_expression &e1, Chris@16: const vector_expression &e2) { Chris@16: return V (prec_prod (e1, e2)); Chris@16: } Chris@16: Chris@16: template Chris@16: class matrix_vector_binary2: Chris@16: public vector_expression > { Chris@16: Chris@16: typedef E1 expression1_type; Chris@16: typedef E2 expression2_type; Chris@16: typedef F functor_type; Chris@16: public: Chris@16: typedef typename E1::const_closure_type expression1_closure_type; Chris@16: typedef typename E2::const_closure_type expression2_closure_type; Chris@16: private: Chris@16: typedef matrix_vector_binary2 self_type; Chris@16: public: Chris@16: #ifdef BOOST_UBLAS_ENABLE_PROXY_SHORTCUTS Chris@16: using vector_expression::operator (); Chris@16: #endif Chris@16: static const unsigned complexity = 1; Chris@16: typedef typename promote_traits::promote_type size_type; Chris@16: typedef typename promote_traits::promote_type difference_type; Chris@16: typedef typename F::result_type value_type; Chris@16: typedef value_type const_reference; Chris@16: typedef const_reference reference; Chris@16: typedef const self_type const_closure_type; Chris@16: typedef const_closure_type closure_type; Chris@16: typedef unknown_storage_tag storage_category; Chris@16: Chris@16: // Construction and destruction Chris@16: BOOST_UBLAS_INLINE Chris@16: matrix_vector_binary2 (const expression1_type &e1, const expression2_type &e2): Chris@16: e1_ (e1), e2_ (e2) {} Chris@16: Chris@16: // Accessors Chris@16: BOOST_UBLAS_INLINE Chris@16: size_type size () const { Chris@16: return e2_.size2 (); Chris@16: } Chris@16: Chris@16: public: Chris@16: // Expression accessors Chris@16: BOOST_UBLAS_INLINE Chris@16: const expression1_closure_type &expression1 () const { Chris@16: return e1_; Chris@16: } Chris@16: BOOST_UBLAS_INLINE Chris@16: const expression2_closure_type &expression2 () const { Chris@16: return e2_; Chris@16: } Chris@16: public: Chris@16: Chris@16: // Element access Chris@16: BOOST_UBLAS_INLINE Chris@16: const_reference operator () (size_type j) const { Chris@16: return functor_type::apply (e1_, e2_, j); Chris@16: } Chris@16: Chris@16: // Closure comparison Chris@16: BOOST_UBLAS_INLINE Chris@16: bool same_closure (const matrix_vector_binary2 &mvb2) const { Chris@16: return (*this).expression1 ().same_closure (mvb2.expression1 ()) && Chris@16: (*this).expression2 ().same_closure (mvb2.expression2 ()); Chris@16: } Chris@16: Chris@16: // Iterator types Chris@16: private: Chris@16: typedef typename E1::const_iterator const_subiterator1_type; Chris@16: typedef typename E2::const_iterator2 const_subiterator2_type; Chris@16: typedef const value_type *const_pointer; Chris@16: Chris@16: public: Chris@16: #ifdef BOOST_UBLAS_USE_INDEXED_ITERATOR Chris@16: typedef indexed_const_iterator const_iterator; Chris@16: typedef const_iterator iterator; Chris@16: #else Chris@16: class const_iterator; Chris@16: typedef const_iterator iterator; Chris@16: #endif Chris@16: Chris@16: // Element lookup Chris@16: BOOST_UBLAS_INLINE Chris@16: const_iterator find (size_type j) const { Chris@16: #ifdef BOOST_UBLAS_USE_INDEXED_ITERATOR Chris@16: const_subiterator2_type it2 (e2_.find2 (0, 0, j)); Chris@16: return const_iterator (*this, it2.index2 ()); Chris@16: #else Chris@16: return const_iterator (*this, e2_.find2 (0, 0, j)); Chris@16: #endif Chris@16: } Chris@16: Chris@16: Chris@16: #ifndef BOOST_UBLAS_USE_INDEXED_ITERATOR Chris@16: class const_iterator: Chris@16: public container_const_reference, Chris@16: public iterator_base_traits::iterator_category>::template Chris@16: iterator_base::type { Chris@16: public: Chris@16: typedef typename iterator_restrict_traits::iterator_category iterator_category; Chris@16: typedef typename matrix_vector_binary2::difference_type difference_type; Chris@16: typedef typename matrix_vector_binary2::value_type value_type; Chris@16: typedef typename matrix_vector_binary2::const_reference reference; Chris@16: typedef typename matrix_vector_binary2::const_pointer pointer; Chris@16: Chris@16: // Construction and destruction Chris@16: #ifdef BOOST_UBLAS_USE_INVARIANT_HOISTING Chris@16: BOOST_UBLAS_INLINE Chris@16: const_iterator (): Chris@16: container_const_reference (), it2_ (), e1_begin_ (), e1_end_ () {} Chris@16: BOOST_UBLAS_INLINE Chris@16: const_iterator (const self_type &mvb, const const_subiterator2_type &it2): Chris@16: container_const_reference (mvb), it2_ (it2), e1_begin_ (mvb.expression1 ().begin ()), e1_end_ (mvb.expression1 ().end ()) {} Chris@16: #else Chris@16: BOOST_UBLAS_INLINE Chris@16: const_iterator (): Chris@16: container_const_reference (), it2_ () {} Chris@16: BOOST_UBLAS_INLINE Chris@16: const_iterator (const self_type &mvb, const const_subiterator2_type &it2): Chris@16: container_const_reference (mvb), it2_ (it2) {} Chris@16: #endif Chris@16: Chris@16: private: Chris@16: // Dense random access specialization Chris@16: BOOST_UBLAS_INLINE Chris@16: value_type dereference (dense_random_access_iterator_tag) const { Chris@16: const self_type &mvb = (*this) (); Chris@16: #ifdef BOOST_UBLAS_USE_INDEXING Chris@16: return mvb (index ()); Chris@16: #elif BOOST_UBLAS_USE_ITERATING Chris@16: difference_type size = BOOST_UBLAS_SAME (mvb.expression2 ().size1 (), mvb.expression1 ().size ()); Chris@16: #ifdef BOOST_UBLAS_USE_INVARIANT_HOISTING Chris@16: return functor_type::apply (size, e1_begin_, it2_.begin ()); Chris@16: #else Chris@16: return functor_type::apply (size, mvb.expression1 ().begin (), it2_.begin ()); Chris@16: #endif Chris@16: #else Chris@16: difference_type size = BOOST_UBLAS_SAME (mvb.expression2 ().size1 (), mvb.expression1 ().size ()); Chris@16: if (size >= BOOST_UBLAS_ITERATOR_THRESHOLD) Chris@16: #ifdef BOOST_UBLAS_USE_INVARIANT_HOISTING Chris@16: return functor_type::apply (size, e1_begin_, it2_.begin ()); Chris@16: #else Chris@16: return functor_type::apply (size, mvb.expression1 ().begin (), it2_.begin ()); Chris@16: #endif Chris@16: else Chris@16: return mvb (index ()); Chris@16: #endif Chris@16: } Chris@16: Chris@16: // Packed bidirectional specialization Chris@16: BOOST_UBLAS_INLINE Chris@16: value_type dereference (packed_random_access_iterator_tag) const { Chris@16: #ifdef BOOST_UBLAS_USE_INVARIANT_HOISTING Chris@16: return functor_type::apply (e1_begin_, e1_end_, it2_.begin (), it2_.end ()); Chris@16: #else Chris@16: const self_type &mvb = (*this) (); Chris@16: #ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION Chris@16: return functor_type::apply (mvb.expression1 ().begin (), mvb.expression1 ().end (), Chris@16: it2_.begin (), it2_.end ()); Chris@16: #else Chris@16: return functor_type::apply (mvb.expression1 ().begin (), mvb.expression1 ().end (), Chris@16: boost::numeric::ublas::begin (it2_, iterator2_tag ()), Chris@16: boost::numeric::ublas::end (it2_, iterator2_tag ())); Chris@16: #endif Chris@16: #endif Chris@16: } Chris@16: Chris@16: // Sparse bidirectional specialization Chris@16: BOOST_UBLAS_INLINE Chris@16: value_type dereference (sparse_bidirectional_iterator_tag) const { Chris@16: #ifdef BOOST_UBLAS_USE_INVARIANT_HOISTING Chris@16: return functor_type::apply (e1_begin_, e1_end_, it2_.begin (), it2_.end (), sparse_bidirectional_iterator_tag ()); Chris@16: #else Chris@16: const self_type &mvb = (*this) (); Chris@16: #ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION Chris@16: return functor_type::apply (mvb.expression1 ().begin (), mvb.expression1 ().end (), Chris@16: it2_.begin (), it2_.end (), sparse_bidirectional_iterator_tag ()); Chris@16: #else Chris@16: return functor_type::apply (mvb.expression1 ().begin (), mvb.expression1 ().end (), Chris@16: boost::numeric::ublas::begin (it2_, iterator2_tag ()), Chris@16: boost::numeric::ublas::end (it2_, iterator2_tag ()), sparse_bidirectional_iterator_tag ()); Chris@16: #endif Chris@16: #endif Chris@16: } Chris@16: Chris@16: public: Chris@16: // Arithmetic Chris@16: BOOST_UBLAS_INLINE Chris@16: const_iterator &operator ++ () { Chris@16: ++ it2_; Chris@16: return *this; Chris@16: } Chris@16: BOOST_UBLAS_INLINE Chris@16: const_iterator &operator -- () { Chris@16: -- it2_; Chris@16: return *this; Chris@16: } Chris@16: BOOST_UBLAS_INLINE Chris@16: const_iterator &operator += (difference_type n) { Chris@16: it2_ += n; Chris@16: return *this; Chris@16: } Chris@16: BOOST_UBLAS_INLINE Chris@16: const_iterator &operator -= (difference_type n) { Chris@16: it2_ -= n; Chris@16: return *this; Chris@16: } Chris@16: BOOST_UBLAS_INLINE Chris@16: difference_type operator - (const const_iterator &it) const { Chris@16: BOOST_UBLAS_CHECK ((*this) ().same_closure (it ()), external_logic ()); Chris@16: return it2_ - it.it2_; Chris@16: } Chris@16: Chris@16: // Dereference Chris@16: BOOST_UBLAS_INLINE Chris@16: const_reference operator * () const { Chris@16: return dereference (iterator_category ()); Chris@16: } Chris@16: BOOST_UBLAS_INLINE Chris@16: const_reference operator [] (difference_type n) const { Chris@16: return *(*this + n); Chris@16: } Chris@16: Chris@16: // Index Chris@16: BOOST_UBLAS_INLINE Chris@16: size_type index () const { Chris@16: return it2_.index2 (); Chris@16: } Chris@16: Chris@16: // Assignment Chris@16: BOOST_UBLAS_INLINE Chris@16: const_iterator &operator = (const const_iterator &it) { Chris@16: container_const_reference::assign (&it ()); Chris@16: it2_ = it.it2_; Chris@16: #ifdef BOOST_UBLAS_USE_INVARIANT_HOISTING Chris@16: e1_begin_ = it.e1_begin_; Chris@16: e1_end_ = it.e1_end_; Chris@16: #endif Chris@16: return *this; Chris@16: } Chris@16: Chris@16: // Comparison Chris@16: BOOST_UBLAS_INLINE Chris@16: bool operator == (const const_iterator &it) const { Chris@16: BOOST_UBLAS_CHECK ((*this) ().same_closure (it ()), external_logic ()); Chris@16: return it2_ == it.it2_; Chris@16: } Chris@16: BOOST_UBLAS_INLINE Chris@16: bool operator < (const const_iterator &it) const { Chris@16: BOOST_UBLAS_CHECK ((*this) ().same_closure (it ()), external_logic ()); Chris@16: return it2_ < it.it2_; Chris@16: } Chris@16: Chris@16: private: Chris@16: const_subiterator2_type it2_; Chris@16: #ifdef BOOST_UBLAS_USE_INVARIANT_HOISTING Chris@16: // Mutable due to assignment Chris@16: /* const */ const_subiterator1_type e1_begin_; Chris@16: /* const */ const_subiterator1_type e1_end_; Chris@16: #endif Chris@16: }; Chris@16: #endif Chris@16: Chris@16: BOOST_UBLAS_INLINE Chris@16: const_iterator begin () const { Chris@16: return find (0); Chris@16: } Chris@16: BOOST_UBLAS_INLINE Chris@101: const_iterator cbegin () const { Chris@101: return begin (); Chris@101: } Chris@101: BOOST_UBLAS_INLINE Chris@16: const_iterator end () const { Chris@16: return find (size ()); Chris@16: } Chris@101: BOOST_UBLAS_INLINE Chris@101: const_iterator cend () const { Chris@101: return end (); Chris@101: } Chris@16: Chris@16: // Reverse iterator Chris@16: typedef reverse_iterator_base const_reverse_iterator; Chris@16: Chris@16: BOOST_UBLAS_INLINE Chris@16: const_reverse_iterator rbegin () const { Chris@16: return const_reverse_iterator (end ()); Chris@16: } Chris@16: BOOST_UBLAS_INLINE Chris@101: const_reverse_iterator crbegin () const { Chris@101: return rbegin (); Chris@101: } Chris@101: BOOST_UBLAS_INLINE Chris@16: const_reverse_iterator rend () const { Chris@16: return const_reverse_iterator (begin ()); Chris@16: } Chris@101: BOOST_UBLAS_INLINE Chris@101: const_reverse_iterator crend () const { Chris@101: return rend (); Chris@101: } Chris@16: Chris@16: private: Chris@16: expression1_closure_type e1_; Chris@16: expression2_closure_type e2_; Chris@16: }; Chris@16: Chris@16: template Chris@16: struct matrix_vector_binary2_traits { Chris@16: typedef unknown_storage_tag storage_category; Chris@16: typedef column_major_tag orientation_category; Chris@16: typedef typename promote_traits::promote_type promote_type; Chris@16: typedef matrix_vector_binary2 > expression_type; Chris@16: #ifndef BOOST_UBLAS_SIMPLE_ET_DEBUG Chris@16: typedef expression_type result_type; Chris@16: #else Chris@16: typedef typename E2::vector_temporary_type result_type; Chris@16: #endif Chris@16: }; Chris@16: Chris@16: template Chris@16: BOOST_UBLAS_INLINE Chris@16: typename matrix_vector_binary2_traits::result_type Chris@16: prod (const vector_expression &e1, Chris@16: const matrix_expression &e2, Chris@16: unknown_storage_tag, Chris@16: column_major_tag) { Chris@16: typedef typename matrix_vector_binary2_traits::expression_type expression_type; Chris@16: return expression_type (e1 (), e2 ()); Chris@16: } Chris@16: Chris@16: // Dispatcher Chris@16: template Chris@16: BOOST_UBLAS_INLINE Chris@16: typename matrix_vector_binary2_traits::result_type Chris@16: prod (const vector_expression &e1, Chris@16: const matrix_expression &e2) { Chris@16: BOOST_STATIC_ASSERT (E1::complexity == 0); Chris@16: typedef typename matrix_vector_binary2_traits::storage_category storage_category; Chris@16: typedef typename matrix_vector_binary2_traits::orientation_category orientation_category; Chris@16: return prod (e1, e2, storage_category (), orientation_category ()); Chris@16: } Chris@16: Chris@16: template Chris@16: BOOST_UBLAS_INLINE Chris@16: typename matrix_vector_binary2_traits::precision_type, E1, Chris@16: typename type_traits::precision_type, E2>::result_type Chris@16: prec_prod (const vector_expression &e1, Chris@16: const matrix_expression &e2, Chris@16: unknown_storage_tag, Chris@16: column_major_tag) { Chris@16: typedef typename matrix_vector_binary2_traits::precision_type, E1, Chris@16: typename type_traits::precision_type, E2>::expression_type expression_type; Chris@16: return expression_type (e1 (), e2 ()); Chris@16: } Chris@16: Chris@16: // Dispatcher Chris@16: template Chris@16: BOOST_UBLAS_INLINE Chris@16: typename matrix_vector_binary2_traits::precision_type, E1, Chris@16: typename type_traits::precision_type, E2>::result_type Chris@16: prec_prod (const vector_expression &e1, Chris@16: const matrix_expression &e2) { Chris@16: BOOST_STATIC_ASSERT (E1::complexity == 0); Chris@16: typedef typename matrix_vector_binary2_traits::precision_type, E1, Chris@16: typename type_traits::precision_type, E2>::storage_category storage_category; Chris@16: typedef typename matrix_vector_binary2_traits::precision_type, E1, Chris@16: typename type_traits::precision_type, E2>::orientation_category orientation_category; Chris@16: return prec_prod (e1, e2, storage_category (), orientation_category ()); Chris@16: } Chris@16: Chris@16: template Chris@16: BOOST_UBLAS_INLINE Chris@16: V & Chris@16: prod (const vector_expression &e1, Chris@16: const matrix_expression &e2, Chris@16: V &v) { Chris@16: return v.assign (prod (e1, e2)); Chris@16: } Chris@16: Chris@16: template Chris@16: BOOST_UBLAS_INLINE Chris@16: V & Chris@16: prec_prod (const vector_expression &e1, Chris@16: const matrix_expression &e2, Chris@16: V &v) { Chris@16: return v.assign (prec_prod (e1, e2)); Chris@16: } Chris@16: Chris@16: template Chris@16: BOOST_UBLAS_INLINE Chris@16: V Chris@16: prod (const vector_expression &e1, Chris@16: const matrix_expression &e2) { Chris@16: return V (prod (e1, e2)); Chris@16: } Chris@16: Chris@16: template Chris@16: BOOST_UBLAS_INLINE Chris@16: V Chris@16: prec_prod (const vector_expression &e1, Chris@16: const matrix_expression &e2) { Chris@16: return V (prec_prod (e1, e2)); Chris@16: } Chris@16: Chris@16: template Chris@16: class matrix_matrix_binary: Chris@16: public matrix_expression > { Chris@16: Chris@16: public: Chris@16: typedef E1 expression1_type; Chris@16: typedef E2 expression2_type; Chris@16: private: Chris@16: typedef F functor_type; Chris@16: public: Chris@16: typedef typename E1::const_closure_type expression1_closure_type; Chris@16: typedef typename E2::const_closure_type expression2_closure_type; Chris@16: private: Chris@16: typedef matrix_matrix_binary self_type; Chris@16: public: Chris@16: #ifdef BOOST_UBLAS_ENABLE_PROXY_SHORTCUTS Chris@16: using matrix_expression::operator (); Chris@16: #endif Chris@16: static const unsigned complexity = 1; Chris@16: typedef typename promote_traits::promote_type size_type; Chris@16: typedef typename promote_traits::promote_type difference_type; Chris@16: typedef typename F::result_type value_type; Chris@16: typedef value_type const_reference; Chris@16: typedef const_reference reference; Chris@16: typedef const self_type const_closure_type; Chris@16: typedef const_closure_type closure_type; Chris@16: typedef unknown_orientation_tag orientation_category; Chris@16: typedef unknown_storage_tag storage_category; Chris@16: Chris@16: // Construction and destruction Chris@16: BOOST_UBLAS_INLINE Chris@16: matrix_matrix_binary (const expression1_type &e1, const expression2_type &e2): Chris@16: e1_ (e1), e2_ (e2) {} Chris@16: Chris@16: // Accessors Chris@16: BOOST_UBLAS_INLINE Chris@16: size_type size1 () const { Chris@16: return e1_.size1 (); Chris@16: } Chris@16: BOOST_UBLAS_INLINE Chris@16: size_type size2 () const { Chris@16: return e2_.size2 (); Chris@16: } Chris@16: Chris@16: public: Chris@16: // Expression accessors Chris@16: BOOST_UBLAS_INLINE Chris@16: const expression1_closure_type &expression1 () const { Chris@16: return e1_; Chris@16: } Chris@16: BOOST_UBLAS_INLINE Chris@16: const expression2_closure_type &expression2 () const { Chris@16: return e2_; Chris@16: } Chris@16: Chris@16: public: Chris@16: // Element access Chris@16: BOOST_UBLAS_INLINE Chris@16: const_reference operator () (size_type i, size_type j) const { Chris@16: return functor_type::apply (e1_, e2_, i, j); Chris@16: } Chris@16: Chris@16: // Closure comparison Chris@16: BOOST_UBLAS_INLINE Chris@16: bool same_closure (const matrix_matrix_binary &mmb) const { Chris@16: return (*this).expression1 ().same_closure (mmb.expression1 ()) && Chris@16: (*this).expression2 ().same_closure (mmb.expression2 ()); Chris@16: } Chris@16: Chris@16: // Iterator types Chris@16: private: Chris@16: typedef typename E1::const_iterator1 const_iterator11_type; Chris@16: typedef typename E1::const_iterator2 const_iterator12_type; Chris@16: typedef typename E2::const_iterator1 const_iterator21_type; Chris@16: typedef typename E2::const_iterator2 const_iterator22_type; Chris@16: typedef const value_type *const_pointer; Chris@16: Chris@16: public: Chris@16: #ifdef BOOST_UBLAS_USE_INDEXED_ITERATOR Chris@16: typedef typename iterator_restrict_traits::iterator_category iterator_category; Chris@16: typedef indexed_const_iterator1 const_iterator1; Chris@16: typedef const_iterator1 iterator1; Chris@16: typedef indexed_const_iterator2 const_iterator2; Chris@16: typedef const_iterator2 iterator2; Chris@16: #else Chris@16: class const_iterator1; Chris@16: typedef const_iterator1 iterator1; Chris@16: class const_iterator2; Chris@16: typedef const_iterator2 iterator2; Chris@16: #endif Chris@16: typedef reverse_iterator_base1 const_reverse_iterator1; Chris@16: typedef reverse_iterator_base2 const_reverse_iterator2; Chris@16: Chris@16: // Element lookup Chris@16: BOOST_UBLAS_INLINE Chris@16: const_iterator1 find1 (int /* rank */, size_type i, size_type j) const { Chris@16: // FIXME sparse matrix tests fail! Chris@16: // const_iterator11_type it11 (e1_.find1 (rank, i, 0)); Chris@16: const_iterator11_type it11 (e1_.find1 (0, i, 0)); Chris@16: #ifdef BOOST_UBLAS_USE_INDEXED_ITERATOR Chris@16: return const_iterator1 (*this, it11.index1 (), j); Chris@16: #else Chris@16: // FIXME sparse matrix tests fail! Chris@16: // const_iterator22_type it22 (e2_.find2 (rank, 0, j)); Chris@16: const_iterator22_type it22 (e2_.find2 (0, 0, j)); Chris@16: return const_iterator1 (*this, it11, it22); Chris@16: #endif Chris@16: } Chris@16: BOOST_UBLAS_INLINE Chris@16: const_iterator2 find2 (int /* rank */, size_type i, size_type j) const { Chris@16: // FIXME sparse matrix tests fail! Chris@16: // const_iterator22_type it22 (e2_.find2 (rank, 0, j)); Chris@16: const_iterator22_type it22 (e2_.find2 (0, 0, j)); Chris@16: #ifdef BOOST_UBLAS_USE_INDEXED_ITERATOR Chris@16: return const_iterator2 (*this, i, it22.index2 ()); Chris@16: #else Chris@16: // FIXME sparse matrix tests fail! Chris@16: // const_iterator11_type it11 (e1_.find1 (rank, i, 0)); Chris@16: const_iterator11_type it11 (e1_.find1 (0, i, 0)); Chris@16: return const_iterator2 (*this, it11, it22); Chris@16: #endif Chris@16: } Chris@16: Chris@16: Chris@16: #ifndef BOOST_UBLAS_USE_INDEXED_ITERATOR Chris@16: class const_iterator1: Chris@16: public container_const_reference, Chris@16: public iterator_base_traits::iterator_category>::template Chris@16: iterator_base::type { Chris@16: public: Chris@16: typedef typename iterator_restrict_traits::iterator_category iterator_category; Chris@16: typedef typename matrix_matrix_binary::difference_type difference_type; Chris@16: typedef typename matrix_matrix_binary::value_type value_type; Chris@16: typedef typename matrix_matrix_binary::const_reference reference; Chris@16: typedef typename matrix_matrix_binary::const_pointer pointer; Chris@16: Chris@16: typedef const_iterator2 dual_iterator_type; Chris@16: typedef const_reverse_iterator2 dual_reverse_iterator_type; Chris@16: Chris@16: // Construction and destruction Chris@16: #ifdef BOOST_UBLAS_USE_INVARIANT_HOISTING Chris@16: BOOST_UBLAS_INLINE Chris@16: const_iterator1 (): Chris@16: container_const_reference (), it1_ (), it2_ (), it2_begin_ (), it2_end_ () {} Chris@16: BOOST_UBLAS_INLINE Chris@16: const_iterator1 (const self_type &mmb, const const_iterator11_type &it1, const const_iterator22_type &it2): Chris@16: container_const_reference (mmb), it1_ (it1), it2_ (it2), it2_begin_ (it2.begin ()), it2_end_ (it2.end ()) {} Chris@16: #else Chris@16: BOOST_UBLAS_INLINE Chris@16: const_iterator1 (): Chris@16: container_const_reference (), it1_ (), it2_ () {} Chris@16: BOOST_UBLAS_INLINE Chris@16: const_iterator1 (const self_type &mmb, const const_iterator11_type &it1, const const_iterator22_type &it2): Chris@16: container_const_reference (mmb), it1_ (it1), it2_ (it2) {} Chris@16: #endif Chris@16: Chris@16: private: Chris@16: // Random access specialization Chris@16: BOOST_UBLAS_INLINE Chris@16: value_type dereference (dense_random_access_iterator_tag) const { Chris@16: const self_type &mmb = (*this) (); Chris@16: #ifdef BOOST_UBLAS_USE_INDEXING Chris@16: return mmb (index1 (), index2 ()); Chris@16: #elif BOOST_UBLAS_USE_ITERATING Chris@16: difference_type size = BOOST_UBLAS_SAME (mmb.expression1 ().size2 (), mmb.expression2 ().size1 ()); Chris@16: #ifdef BOOST_UBLAS_USE_INVARIANT_HOISTING Chris@16: return functor_type::apply (size, it1_.begin (), it2_begin_); Chris@16: #else Chris@16: return functor_type::apply (size, it1_.begin (), it2_.begin ()); Chris@16: #endif Chris@16: #else Chris@16: difference_type size = BOOST_UBLAS_SAME (mmb.expression1 ().size2 (), mmb.expression2 ().size1 ()); Chris@16: if (size >= BOOST_UBLAS_ITERATOR_THRESHOLD) Chris@16: #ifdef BOOST_UBLAS_USE_INVARIANT_HOISTING Chris@16: return functor_type::apply (size, it1_.begin (), it2_begin_); Chris@16: #else Chris@16: return functor_type::apply (size, it1_.begin (), it2_.begin ()); Chris@16: #endif Chris@16: else Chris@16: return mmb (index1 (), index2 ()); Chris@16: #endif Chris@16: } Chris@16: Chris@16: // Packed bidirectional specialization Chris@16: BOOST_UBLAS_INLINE Chris@16: value_type dereference (packed_random_access_iterator_tag) const { Chris@16: #ifdef BOOST_UBLAS_USE_INVARIANT_HOISTING Chris@16: return functor_type::apply (it1_.begin (), it1_.end (), Chris@16: it2_begin_, it2_end_, packed_random_access_iterator_tag ()); Chris@16: #else Chris@16: #ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION Chris@16: return functor_type::apply (it1_.begin (), it1_.end (), Chris@16: it2_.begin (), it2_.end (), packed_random_access_iterator_tag ()); Chris@16: #else Chris@16: return functor_type::apply (boost::numeric::ublas::begin (it1_, iterator1_tag ()), Chris@16: boost::numeric::ublas::end (it1_, iterator1_tag ()), Chris@16: boost::numeric::ublas::begin (it2_, iterator2_tag ()), Chris@16: boost::numeric::ublas::end (it2_, iterator2_tag ()), packed_random_access_iterator_tag ()); Chris@16: #endif Chris@16: #endif Chris@16: } Chris@16: Chris@16: // Sparse bidirectional specialization Chris@16: BOOST_UBLAS_INLINE Chris@16: value_type dereference (sparse_bidirectional_iterator_tag) const { Chris@16: #ifdef BOOST_UBLAS_USE_INVARIANT_HOISTING Chris@16: return functor_type::apply (it1_.begin (), it1_.end (), Chris@16: it2_begin_, it2_end_, sparse_bidirectional_iterator_tag ()); Chris@16: #else Chris@16: #ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION Chris@16: return functor_type::apply (it1_.begin (), it1_.end (), Chris@16: it2_.begin (), it2_.end (), sparse_bidirectional_iterator_tag ()); Chris@16: #else Chris@16: return functor_type::apply (boost::numeric::ublas::begin (it1_, iterator1_tag ()), Chris@16: boost::numeric::ublas::end (it1_, iterator1_tag ()), Chris@16: boost::numeric::ublas::begin (it2_, iterator2_tag ()), Chris@16: boost::numeric::ublas::end (it2_, iterator2_tag ()), sparse_bidirectional_iterator_tag ()); Chris@16: #endif Chris@16: #endif Chris@16: } Chris@16: Chris@16: public: Chris@16: // Arithmetic Chris@16: BOOST_UBLAS_INLINE Chris@16: const_iterator1 &operator ++ () { Chris@16: ++ it1_; Chris@16: return *this; Chris@16: } Chris@16: BOOST_UBLAS_INLINE Chris@16: const_iterator1 &operator -- () { Chris@16: -- it1_; Chris@16: return *this; Chris@16: } Chris@16: BOOST_UBLAS_INLINE Chris@16: const_iterator1 &operator += (difference_type n) { Chris@16: it1_ += n; Chris@16: return *this; Chris@16: } Chris@16: BOOST_UBLAS_INLINE Chris@16: const_iterator1 &operator -= (difference_type n) { Chris@16: it1_ -= n; Chris@16: return *this; Chris@16: } Chris@16: BOOST_UBLAS_INLINE Chris@16: difference_type operator - (const const_iterator1 &it) const { Chris@16: BOOST_UBLAS_CHECK ((*this) ().same_closure (it ()), external_logic ()); Chris@16: BOOST_UBLAS_CHECK (it2_ == it.it2_, external_logic ()); Chris@16: return it1_ - it.it1_; Chris@16: } Chris@16: Chris@16: // Dereference Chris@16: BOOST_UBLAS_INLINE Chris@16: const_reference operator * () const { Chris@16: return dereference (iterator_category ()); Chris@16: } Chris@16: BOOST_UBLAS_INLINE Chris@16: const_reference operator [] (difference_type n) const { Chris@16: return *(*this + n); Chris@16: } Chris@16: Chris@16: #ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION Chris@16: BOOST_UBLAS_INLINE Chris@16: #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION Chris@16: typename self_type:: Chris@16: #endif Chris@16: const_iterator2 begin () const { Chris@16: return (*this) ().find2 (1, index1 (), 0); Chris@16: } Chris@16: BOOST_UBLAS_INLINE Chris@16: #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION Chris@16: typename self_type:: Chris@16: #endif Chris@101: const_iterator2 cbegin () const { Chris@101: return begin (); Chris@101: } Chris@101: BOOST_UBLAS_INLINE Chris@101: #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION Chris@101: typename self_type:: Chris@101: #endif Chris@16: const_iterator2 end () const { Chris@16: return (*this) ().find2 (1, index1 (), (*this) ().size2 ()); Chris@16: } Chris@16: BOOST_UBLAS_INLINE Chris@16: #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION Chris@16: typename self_type:: Chris@16: #endif Chris@101: const_iterator2 cend () const { Chris@101: return end (); Chris@101: } Chris@101: BOOST_UBLAS_INLINE Chris@101: #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION Chris@101: typename self_type:: Chris@101: #endif Chris@16: const_reverse_iterator2 rbegin () const { Chris@16: return const_reverse_iterator2 (end ()); Chris@16: } Chris@16: BOOST_UBLAS_INLINE Chris@16: #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION Chris@16: typename self_type:: Chris@16: #endif Chris@101: const_reverse_iterator2 crbegin () const { Chris@101: return rbegin (); Chris@101: } Chris@101: BOOST_UBLAS_INLINE Chris@101: #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION Chris@101: typename self_type:: Chris@101: #endif Chris@16: const_reverse_iterator2 rend () const { Chris@16: return const_reverse_iterator2 (begin ()); Chris@16: } Chris@101: BOOST_UBLAS_INLINE Chris@101: #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION Chris@101: typename self_type:: Chris@101: #endif Chris@101: const_reverse_iterator2 crend () const { Chris@101: return rend (); Chris@101: } Chris@16: #endif Chris@16: Chris@16: // Indices Chris@16: BOOST_UBLAS_INLINE Chris@16: size_type index1 () const { Chris@16: return it1_.index1 (); Chris@16: } Chris@16: BOOST_UBLAS_INLINE Chris@16: size_type index2 () const { Chris@16: return it2_.index2 (); Chris@16: } Chris@16: Chris@16: // Assignment Chris@16: BOOST_UBLAS_INLINE Chris@16: const_iterator1 &operator = (const const_iterator1 &it) { Chris@16: container_const_reference::assign (&it ()); Chris@16: it1_ = it.it1_; Chris@16: it2_ = it.it2_; Chris@16: #ifdef BOOST_UBLAS_USE_INVARIANT_HOISTING Chris@16: it2_begin_ = it.it2_begin_; Chris@16: it2_end_ = it.it2_end_; Chris@16: #endif Chris@16: return *this; Chris@16: } Chris@16: Chris@16: // Comparison Chris@16: BOOST_UBLAS_INLINE Chris@16: bool operator == (const const_iterator1 &it) const { Chris@16: BOOST_UBLAS_CHECK ((*this) ().same_closure (it ()), external_logic ()); Chris@16: BOOST_UBLAS_CHECK (it2_ == it.it2_, external_logic ()); Chris@16: return it1_ == it.it1_; Chris@16: } Chris@16: BOOST_UBLAS_INLINE Chris@16: bool operator < (const const_iterator1 &it) const { Chris@16: BOOST_UBLAS_CHECK ((*this) ().same_closure (it ()), external_logic ()); Chris@16: BOOST_UBLAS_CHECK (it2_ == it.it2_, external_logic ()); Chris@16: return it1_ < it.it1_; Chris@16: } Chris@16: Chris@16: private: Chris@16: const_iterator11_type it1_; Chris@16: // Mutable due to assignment Chris@16: /* const */ const_iterator22_type it2_; Chris@16: #ifdef BOOST_UBLAS_USE_INVARIANT_HOISTING Chris@16: /* const */ const_iterator21_type it2_begin_; Chris@16: /* const */ const_iterator21_type it2_end_; Chris@16: #endif Chris@16: }; Chris@16: #endif Chris@16: Chris@16: BOOST_UBLAS_INLINE Chris@16: const_iterator1 begin1 () const { Chris@16: return find1 (0, 0, 0); Chris@16: } Chris@16: BOOST_UBLAS_INLINE Chris@101: const_iterator1 cbegin1 () const { Chris@101: return begin1 (); Chris@101: } Chris@101: BOOST_UBLAS_INLINE Chris@16: const_iterator1 end1 () const { Chris@16: return find1 (0, size1 (), 0); Chris@16: } Chris@101: BOOST_UBLAS_INLINE Chris@101: const_iterator1 cend1 () const { Chris@101: return end1 (); Chris@101: } Chris@16: Chris@16: #ifndef BOOST_UBLAS_USE_INDEXED_ITERATOR Chris@16: class const_iterator2: Chris@16: public container_const_reference, Chris@16: public iterator_base_traits::iterator_category>::template Chris@16: iterator_base::type { Chris@16: public: Chris@16: typedef typename iterator_restrict_traits::iterator_category iterator_category; Chris@16: typedef typename matrix_matrix_binary::difference_type difference_type; Chris@16: typedef typename matrix_matrix_binary::value_type value_type; Chris@16: typedef typename matrix_matrix_binary::const_reference reference; Chris@16: typedef typename matrix_matrix_binary::const_pointer pointer; Chris@16: Chris@16: typedef const_iterator1 dual_iterator_type; Chris@16: typedef const_reverse_iterator1 dual_reverse_iterator_type; Chris@16: Chris@16: // Construction and destruction Chris@16: #ifdef BOOST_UBLAS_USE_INVARIANT_HOISTING Chris@16: BOOST_UBLAS_INLINE Chris@16: const_iterator2 (): Chris@16: container_const_reference (), it1_ (), it2_ (), it1_begin_ (), it1_end_ () {} Chris@16: BOOST_UBLAS_INLINE Chris@16: const_iterator2 (const self_type &mmb, const const_iterator11_type &it1, const const_iterator22_type &it2): Chris@16: container_const_reference (mmb), it1_ (it1), it2_ (it2), it1_begin_ (it1.begin ()), it1_end_ (it1.end ()) {} Chris@16: #else Chris@16: BOOST_UBLAS_INLINE Chris@16: const_iterator2 (): Chris@16: container_const_reference (), it1_ (), it2_ () {} Chris@16: BOOST_UBLAS_INLINE Chris@16: const_iterator2 (const self_type &mmb, const const_iterator11_type &it1, const const_iterator22_type &it2): Chris@16: container_const_reference (mmb), it1_ (it1), it2_ (it2) {} Chris@16: #endif Chris@16: Chris@16: private: Chris@16: // Random access specialization Chris@16: BOOST_UBLAS_INLINE Chris@16: value_type dereference (dense_random_access_iterator_tag) const { Chris@16: const self_type &mmb = (*this) (); Chris@16: #ifdef BOOST_UBLAS_USE_INDEXING Chris@16: return mmb (index1 (), index2 ()); Chris@16: #elif BOOST_UBLAS_USE_ITERATING Chris@16: difference_type size = BOOST_UBLAS_SAME (mmb.expression1 ().size2 (), mmb.expression2 ().size1 ()); Chris@16: #ifdef BOOST_UBLAS_USE_INVARIANT_HOISTING Chris@16: return functor_type::apply (size, it1_begin_, it2_.begin ()); Chris@16: #else Chris@16: return functor_type::apply (size, it1_.begin (), it2_.begin ()); Chris@16: #endif Chris@16: #else Chris@16: difference_type size = BOOST_UBLAS_SAME (mmb.expression1 ().size2 (), mmb.expression2 ().size1 ()); Chris@16: if (size >= BOOST_UBLAS_ITERATOR_THRESHOLD) Chris@16: #ifdef BOOST_UBLAS_USE_INVARIANT_HOISTING Chris@16: return functor_type::apply (size, it1_begin_, it2_.begin ()); Chris@16: #else Chris@16: return functor_type::apply (size, it1_.begin (), it2_.begin ()); Chris@16: #endif Chris@16: else Chris@16: return mmb (index1 (), index2 ()); Chris@16: #endif Chris@16: } Chris@16: Chris@16: // Packed bidirectional specialization Chris@16: BOOST_UBLAS_INLINE Chris@16: value_type dereference (packed_random_access_iterator_tag) const { Chris@16: #ifdef BOOST_UBLAS_USE_INVARIANT_HOISTING Chris@16: return functor_type::apply (it1_begin_, it1_end_, Chris@16: it2_.begin (), it2_.end (), packed_random_access_iterator_tag ()); Chris@16: #else Chris@16: #ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION Chris@16: return functor_type::apply (it1_.begin (), it1_.end (), Chris@16: it2_.begin (), it2_.end (), packed_random_access_iterator_tag ()); Chris@16: #else Chris@16: return functor_type::apply (boost::numeric::ublas::begin (it1_, iterator1_tag ()), Chris@16: boost::numeric::ublas::end (it1_, iterator1_tag ()), Chris@16: boost::numeric::ublas::begin (it2_, iterator2_tag ()), Chris@16: boost::numeric::ublas::end (it2_, iterator2_tag ()), packed_random_access_iterator_tag ()); Chris@16: #endif Chris@16: #endif Chris@16: } Chris@16: Chris@16: // Sparse bidirectional specialization Chris@16: BOOST_UBLAS_INLINE Chris@16: value_type dereference (sparse_bidirectional_iterator_tag) const { Chris@16: #ifdef BOOST_UBLAS_USE_INVARIANT_HOISTING Chris@16: return functor_type::apply (it1_begin_, it1_end_, Chris@16: it2_.begin (), it2_.end (), sparse_bidirectional_iterator_tag ()); Chris@16: #else Chris@16: #ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION Chris@16: return functor_type::apply (it1_.begin (), it1_.end (), Chris@16: it2_.begin (), it2_.end (), sparse_bidirectional_iterator_tag ()); Chris@16: #else Chris@16: return functor_type::apply (boost::numeric::ublas::begin (it1_, iterator1_tag ()), Chris@16: boost::numeric::ublas::end (it1_, iterator1_tag ()), Chris@16: boost::numeric::ublas::begin (it2_, iterator2_tag ()), Chris@16: boost::numeric::ublas::end (it2_, iterator2_tag ()), sparse_bidirectional_iterator_tag ()); Chris@16: #endif Chris@16: #endif Chris@16: } Chris@16: Chris@16: public: Chris@16: // Arithmetic Chris@16: BOOST_UBLAS_INLINE Chris@16: const_iterator2 &operator ++ () { Chris@16: ++ it2_; Chris@16: return *this; Chris@16: } Chris@16: BOOST_UBLAS_INLINE Chris@16: const_iterator2 &operator -- () { Chris@16: -- it2_; Chris@16: return *this; Chris@16: } Chris@16: BOOST_UBLAS_INLINE Chris@16: const_iterator2 &operator += (difference_type n) { Chris@16: it2_ += n; Chris@16: return *this; Chris@16: } Chris@16: BOOST_UBLAS_INLINE Chris@16: const_iterator2 &operator -= (difference_type n) { Chris@16: it2_ -= n; Chris@16: return *this; Chris@16: } Chris@16: BOOST_UBLAS_INLINE Chris@16: difference_type operator - (const const_iterator2 &it) const { Chris@16: BOOST_UBLAS_CHECK ((*this) ().same_closure (it ()), external_logic ()); Chris@16: BOOST_UBLAS_CHECK (it1_ == it.it1_, external_logic ()); Chris@16: return it2_ - it.it2_; Chris@16: } Chris@16: Chris@16: // Dereference Chris@16: BOOST_UBLAS_INLINE Chris@16: const_reference operator * () const { Chris@16: return dereference (iterator_category ()); Chris@16: } Chris@16: BOOST_UBLAS_INLINE Chris@16: const_reference operator [] (difference_type n) const { Chris@16: return *(*this + n); Chris@16: } Chris@16: Chris@16: #ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION Chris@16: BOOST_UBLAS_INLINE Chris@16: #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION Chris@16: typename self_type:: Chris@16: #endif Chris@16: const_iterator1 begin () const { Chris@16: return (*this) ().find1 (1, 0, index2 ()); Chris@16: } Chris@16: BOOST_UBLAS_INLINE Chris@16: #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION Chris@16: typename self_type:: Chris@16: #endif Chris@101: const_iterator1 cbegin () const { Chris@101: return begin (); Chris@101: } Chris@101: BOOST_UBLAS_INLINE Chris@101: #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION Chris@101: typename self_type:: Chris@101: #endif Chris@16: const_iterator1 end () const { Chris@16: return (*this) ().find1 (1, (*this) ().size1 (), index2 ()); Chris@16: } Chris@16: BOOST_UBLAS_INLINE Chris@16: #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION Chris@16: typename self_type:: Chris@16: #endif Chris@101: const_iterator1 cend () const { Chris@101: return end (); Chris@101: } Chris@101: BOOST_UBLAS_INLINE Chris@101: #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION Chris@101: typename self_type:: Chris@101: #endif Chris@16: const_reverse_iterator1 rbegin () const { Chris@16: return const_reverse_iterator1 (end ()); Chris@16: } Chris@16: BOOST_UBLAS_INLINE Chris@16: #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION Chris@16: typename self_type:: Chris@16: #endif Chris@101: const_reverse_iterator1 crbegin () const { Chris@101: return rbegin (); Chris@101: } Chris@101: BOOST_UBLAS_INLINE Chris@101: #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION Chris@101: typename self_type:: Chris@101: #endif Chris@16: const_reverse_iterator1 rend () const { Chris@16: return const_reverse_iterator1 (begin ()); Chris@16: } Chris@101: BOOST_UBLAS_INLINE Chris@101: #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION Chris@101: typename self_type:: Chris@101: #endif Chris@101: const_reverse_iterator1 crend () const { Chris@101: return rend (); Chris@101: } Chris@16: #endif Chris@16: Chris@16: // Indices Chris@16: BOOST_UBLAS_INLINE Chris@16: size_type index1 () const { Chris@16: return it1_.index1 (); Chris@16: } Chris@16: BOOST_UBLAS_INLINE Chris@16: size_type index2 () const { Chris@16: return it2_.index2 (); Chris@16: } Chris@16: Chris@16: // Assignment Chris@16: BOOST_UBLAS_INLINE Chris@16: const_iterator2 &operator = (const const_iterator2 &it) { Chris@16: container_const_reference::assign (&it ()); Chris@16: it1_ = it.it1_; Chris@16: it2_ = it.it2_; Chris@16: #ifdef BOOST_UBLAS_USE_INVARIANT_HOISTING Chris@16: it1_begin_ = it.it1_begin_; Chris@16: it1_end_ = it.it1_end_; Chris@16: #endif Chris@16: return *this; Chris@16: } Chris@16: Chris@16: // Comparison Chris@16: BOOST_UBLAS_INLINE Chris@16: bool operator == (const const_iterator2 &it) const { Chris@16: BOOST_UBLAS_CHECK ((*this) ().same_closure (it ()), external_logic ()); Chris@16: BOOST_UBLAS_CHECK (it1_ == it.it1_, external_logic ()); Chris@16: return it2_ == it.it2_; Chris@16: } Chris@16: BOOST_UBLAS_INLINE Chris@16: bool operator < (const const_iterator2 &it) const { Chris@16: BOOST_UBLAS_CHECK ((*this) ().same_closure (it ()), external_logic ()); Chris@16: BOOST_UBLAS_CHECK (it1_ == it.it1_, external_logic ()); Chris@16: return it2_ < it.it2_; Chris@16: } Chris@16: Chris@16: private: Chris@16: // Mutable due to assignment Chris@16: /* const */ const_iterator11_type it1_; Chris@16: const_iterator22_type it2_; Chris@16: #ifdef BOOST_UBLAS_USE_INVARIANT_HOISTING Chris@16: /* const */ const_iterator12_type it1_begin_; Chris@16: /* const */ const_iterator12_type it1_end_; Chris@16: #endif Chris@16: }; Chris@16: #endif Chris@16: Chris@16: BOOST_UBLAS_INLINE Chris@16: const_iterator2 begin2 () const { Chris@16: return find2 (0, 0, 0); Chris@16: } Chris@16: BOOST_UBLAS_INLINE Chris@101: const_iterator2 cbegin2 () const { Chris@101: return begin2 (); Chris@101: } Chris@101: BOOST_UBLAS_INLINE Chris@16: const_iterator2 end2 () const { Chris@16: return find2 (0, 0, size2 ()); Chris@16: } Chris@101: BOOST_UBLAS_INLINE Chris@101: const_iterator2 cend2 () const { Chris@101: return end2 (); Chris@101: } Chris@16: Chris@16: // Reverse iterators Chris@16: Chris@16: BOOST_UBLAS_INLINE Chris@16: const_reverse_iterator1 rbegin1 () const { Chris@16: return const_reverse_iterator1 (end1 ()); Chris@16: } Chris@16: BOOST_UBLAS_INLINE Chris@101: const_reverse_iterator1 crbegin1 () const { Chris@101: return rbegin1 (); Chris@101: } Chris@101: BOOST_UBLAS_INLINE Chris@16: const_reverse_iterator1 rend1 () const { Chris@16: return const_reverse_iterator1 (begin1 ()); Chris@16: } Chris@101: BOOST_UBLAS_INLINE Chris@101: const_reverse_iterator1 crend1 () const { Chris@101: return rend1 (); Chris@101: } Chris@16: Chris@16: BOOST_UBLAS_INLINE Chris@16: const_reverse_iterator2 rbegin2 () const { Chris@16: return const_reverse_iterator2 (end2 ()); Chris@16: } Chris@16: BOOST_UBLAS_INLINE Chris@101: const_reverse_iterator2 crbegin2 () const { Chris@101: return rbegin2 (); Chris@101: } Chris@101: BOOST_UBLAS_INLINE Chris@16: const_reverse_iterator2 rend2 () const { Chris@16: return const_reverse_iterator2 (begin2 ()); Chris@16: } Chris@101: BOOST_UBLAS_INLINE Chris@101: const_reverse_iterator2 crend2 () const { Chris@101: return rend2 (); Chris@101: } Chris@16: Chris@16: private: Chris@16: expression1_closure_type e1_; Chris@16: expression2_closure_type e2_; Chris@16: }; Chris@16: Chris@16: template Chris@16: struct matrix_matrix_binary_traits { Chris@16: typedef unknown_storage_tag storage_category; Chris@16: typedef unknown_orientation_tag orientation_category; Chris@16: typedef typename promote_traits::promote_type promote_type; Chris@16: typedef matrix_matrix_binary > expression_type; Chris@16: #ifndef BOOST_UBLAS_SIMPLE_ET_DEBUG Chris@16: typedef expression_type result_type; Chris@16: #else Chris@16: typedef typename E1::matrix_temporary_type result_type; Chris@16: #endif Chris@16: }; Chris@16: Chris@16: template Chris@16: BOOST_UBLAS_INLINE Chris@16: typename matrix_matrix_binary_traits::result_type Chris@16: prod (const matrix_expression &e1, Chris@16: const matrix_expression &e2, Chris@16: unknown_storage_tag, Chris@16: unknown_orientation_tag) { Chris@16: typedef typename matrix_matrix_binary_traits::expression_type expression_type; Chris@16: return expression_type (e1 (), e2 ()); Chris@16: } Chris@16: Chris@16: // Dispatcher Chris@16: template Chris@16: BOOST_UBLAS_INLINE Chris@16: typename matrix_matrix_binary_traits::result_type Chris@16: prod (const matrix_expression &e1, Chris@16: const matrix_expression &e2) { Chris@16: BOOST_STATIC_ASSERT (E1::complexity == 0 && E2::complexity == 0); Chris@16: typedef typename matrix_matrix_binary_traits::storage_category storage_category; Chris@16: typedef typename matrix_matrix_binary_traits::orientation_category orientation_category; Chris@16: return prod (e1, e2, storage_category (), orientation_category ()); Chris@16: } Chris@16: Chris@16: template Chris@16: BOOST_UBLAS_INLINE Chris@16: typename matrix_matrix_binary_traits::precision_type, E1, Chris@16: typename type_traits::precision_type, E2>::result_type Chris@16: prec_prod (const matrix_expression &e1, Chris@16: const matrix_expression &e2, Chris@16: unknown_storage_tag, Chris@16: unknown_orientation_tag) { Chris@16: typedef typename matrix_matrix_binary_traits::precision_type, E1, Chris@16: typename type_traits::precision_type, E2>::expression_type expression_type; Chris@16: return expression_type (e1 (), e2 ()); Chris@16: } Chris@16: Chris@16: // Dispatcher Chris@16: template Chris@16: BOOST_UBLAS_INLINE Chris@16: typename matrix_matrix_binary_traits::precision_type, E1, Chris@16: typename type_traits::precision_type, E2>::result_type Chris@16: prec_prod (const matrix_expression &e1, Chris@16: const matrix_expression &e2) { Chris@16: BOOST_STATIC_ASSERT (E1::complexity == 0 && E2::complexity == 0); Chris@16: typedef typename matrix_matrix_binary_traits::precision_type, E1, Chris@16: typename type_traits::precision_type, E2>::storage_category storage_category; Chris@16: typedef typename matrix_matrix_binary_traits::precision_type, E1, Chris@16: typename type_traits::precision_type, E2>::orientation_category orientation_category; Chris@16: return prec_prod (e1, e2, storage_category (), orientation_category ()); Chris@16: } Chris@16: Chris@16: template Chris@16: BOOST_UBLAS_INLINE Chris@16: M & Chris@16: prod (const matrix_expression &e1, Chris@16: const matrix_expression &e2, Chris@16: M &m) { Chris@16: return m.assign (prod (e1, e2)); Chris@16: } Chris@16: Chris@16: template Chris@16: BOOST_UBLAS_INLINE Chris@16: M & Chris@16: prec_prod (const matrix_expression &e1, Chris@16: const matrix_expression &e2, Chris@16: M &m) { Chris@16: return m.assign (prec_prod (e1, e2)); Chris@16: } Chris@16: Chris@16: template Chris@16: BOOST_UBLAS_INLINE Chris@16: M Chris@16: prod (const matrix_expression &e1, Chris@16: const matrix_expression &e2) { Chris@16: return M (prod (e1, e2)); Chris@16: } Chris@16: Chris@16: template Chris@16: BOOST_UBLAS_INLINE Chris@16: M Chris@16: prec_prod (const matrix_expression &e1, Chris@16: const matrix_expression &e2) { Chris@16: return M (prec_prod (e1, e2)); Chris@16: } Chris@16: Chris@16: template Chris@16: class matrix_scalar_unary: Chris@16: public scalar_expression > { Chris@16: public: Chris@16: typedef E expression_type; Chris@16: typedef F functor_type; Chris@16: typedef typename F::result_type value_type; Chris@16: typedef typename E::const_closure_type expression_closure_type; Chris@16: Chris@16: // Construction and destruction Chris@16: BOOST_UBLAS_INLINE Chris@16: explicit matrix_scalar_unary (const expression_type &e): Chris@16: e_ (e) {} Chris@16: Chris@16: private: Chris@16: // Expression accessors Chris@16: BOOST_UBLAS_INLINE Chris@16: const expression_closure_type &expression () const { Chris@16: return e_; Chris@16: } Chris@16: Chris@16: public: Chris@16: BOOST_UBLAS_INLINE Chris@16: operator value_type () const { Chris@16: return functor_type::apply (e_); Chris@16: } Chris@16: Chris@16: private: Chris@16: expression_closure_type e_; Chris@16: }; Chris@16: Chris@16: template Chris@16: struct matrix_scalar_unary_traits { Chris@16: typedef matrix_scalar_unary expression_type; Chris@16: #ifndef BOOST_UBLAS_SIMPLE_ET_DEBUG Chris@16: typedef expression_type result_type; Chris@16: #else Chris@16: typedef typename F::result_type result_type; Chris@16: #endif Chris@16: }; Chris@16: Chris@16: template Chris@16: BOOST_UBLAS_INLINE Chris@16: typename matrix_scalar_unary_traits >::result_type Chris@16: norm_1 (const matrix_expression &e) { Chris@16: typedef typename matrix_scalar_unary_traits >::expression_type expression_type; Chris@16: return expression_type (e ()); Chris@16: } Chris@16: Chris@16: template Chris@16: BOOST_UBLAS_INLINE Chris@16: typename matrix_scalar_unary_traits >::result_type Chris@16: norm_frobenius (const matrix_expression &e) { Chris@16: typedef typename matrix_scalar_unary_traits >::expression_type expression_type; Chris@16: return expression_type (e ()); Chris@16: } Chris@16: Chris@16: template Chris@16: BOOST_UBLAS_INLINE Chris@16: typename matrix_scalar_unary_traits >::result_type Chris@16: norm_inf (const matrix_expression &e) { Chris@16: typedef typename matrix_scalar_unary_traits >::expression_type expression_type; Chris@16: return expression_type (e ()); Chris@16: } Chris@16: Chris@16: }}} Chris@16: Chris@16: #endif