...one of the most highly
regarded and expertly designed C++ library projects in the
world.
— Herb Sutter and Andrei
Alexandrescu, C++
Coding Standards
00001 // 00002 // Copyright (c) 2000-2002 00003 // Joerg Walter, Mathias Koch 00004 // 00005 // Distributed under the Boost Software License, Version 1.0. (See 00006 // accompanying file LICENSE_1_0.txt or copy at 00007 // http://www.boost.org/LICENSE_1_0.txt) 00008 // 00009 // The authors gratefully acknowledge the support of 00010 // GeNeSys mbH & Co. KG in producing this work. 00011 // 00012 00013 #ifndef _BOOST_UBLAS_MATRIX_PROXY_ 00014 #define _BOOST_UBLAS_MATRIX_PROXY_ 00015 00016 #include <boost/numeric/ublas/matrix_expression.hpp> 00017 #include <boost/numeric/ublas/detail/vector_assign.hpp> 00018 #include <boost/numeric/ublas/detail/matrix_assign.hpp> 00019 #include <boost/numeric/ublas/detail/temporary.hpp> 00020 00021 // Iterators based on ideas of Jeremy Siek 00022 00023 namespace boost { namespace numeric { namespace ublas { 00024 00027 template<class M> 00028 class matrix_row: 00029 public vector_expression<matrix_row<M> > { 00030 00031 typedef matrix_row<M> self_type; 00032 public: 00033 #ifdef BOOST_UBLAS_ENABLE_PROXY_SHORTCUTS 00034 using vector_expression<self_type>::operator (); 00035 #endif 00036 typedef M matrix_type; 00037 typedef typename M::size_type size_type; 00038 typedef typename M::difference_type difference_type; 00039 typedef typename M::value_type value_type; 00040 typedef typename M::const_reference const_reference; 00041 typedef typename boost::mpl::if_<boost::is_const<M>, 00042 typename M::const_reference, 00043 typename M::reference>::type reference; 00044 typedef typename boost::mpl::if_<boost::is_const<M>, 00045 typename M::const_closure_type, 00046 typename M::closure_type>::type matrix_closure_type; 00047 typedef const self_type const_closure_type; 00048 typedef self_type closure_type; 00049 typedef typename storage_restrict_traits<typename M::storage_category, 00050 dense_proxy_tag>::storage_category storage_category; 00051 00052 // Construction and destruction 00053 BOOST_UBLAS_INLINE 00054 matrix_row (matrix_type &data, size_type i): 00055 data_ (data), i_ (i) { 00056 // Early checking of preconditions here. 00057 // BOOST_UBLAS_CHECK (i_ < data_.size1 (), bad_index ()); 00058 } 00059 00060 // Accessors 00061 BOOST_UBLAS_INLINE 00062 size_type size () const { 00063 return data_.size2 (); 00064 } 00065 BOOST_UBLAS_INLINE 00066 size_type index () const { 00067 return i_; 00068 } 00069 00070 // Storage accessors 00071 BOOST_UBLAS_INLINE 00072 const matrix_closure_type &data () const { 00073 return data_; 00074 } 00075 BOOST_UBLAS_INLINE 00076 matrix_closure_type &data () { 00077 return data_; 00078 } 00079 00080 // Element access 00081 #ifndef BOOST_UBLAS_PROXY_CONST_MEMBER 00082 BOOST_UBLAS_INLINE 00083 const_reference operator () (size_type j) const { 00084 return data_ (i_, j); 00085 } 00086 BOOST_UBLAS_INLINE 00087 reference operator () (size_type j) { 00088 return data_ (i_, j); 00089 } 00090 00091 BOOST_UBLAS_INLINE 00092 const_reference operator [] (size_type j) const { 00093 return (*this) (j); 00094 } 00095 BOOST_UBLAS_INLINE 00096 reference operator [] (size_type j) { 00097 return (*this) (j); 00098 } 00099 #else 00100 BOOST_UBLAS_INLINE 00101 reference operator () (size_type j) const { 00102 return data_ (i_, j); 00103 } 00104 00105 BOOST_UBLAS_INLINE 00106 reference operator [] (size_type j) const { 00107 return (*this) (j); 00108 } 00109 #endif 00110 00111 // Assignment 00112 BOOST_UBLAS_INLINE 00113 matrix_row &operator = (const matrix_row &mr) { 00114 // ISSUE need a temporary, proxy can be overlaping alias 00115 vector_assign<scalar_assign> (*this, typename vector_temporary_traits<M>::type (mr)); 00116 return *this; 00117 } 00118 BOOST_UBLAS_INLINE 00119 matrix_row &assign_temporary (matrix_row &mr) { 00120 // assign elements, proxied container remains the same 00121 vector_assign<scalar_assign> (*this, mr); 00122 return *this; 00123 } 00124 template<class AE> 00125 BOOST_UBLAS_INLINE 00126 matrix_row &operator = (const vector_expression<AE> &ae) { 00127 vector_assign<scalar_assign> (*this, typename vector_temporary_traits<M>::type (ae)); 00128 return *this; 00129 } 00130 template<class AE> 00131 BOOST_UBLAS_INLINE 00132 matrix_row &assign (const vector_expression<AE> &ae) { 00133 vector_assign<scalar_assign> (*this, ae); 00134 return *this; 00135 } 00136 template<class AE> 00137 BOOST_UBLAS_INLINE 00138 matrix_row &operator += (const vector_expression<AE> &ae) { 00139 vector_assign<scalar_assign> (*this, typename vector_temporary_traits<M>::type (*this + ae)); 00140 return *this; 00141 } 00142 template<class AE> 00143 BOOST_UBLAS_INLINE 00144 matrix_row &plus_assign (const vector_expression<AE> &ae) { 00145 vector_assign<scalar_plus_assign> (*this, ae); 00146 return *this; 00147 } 00148 template<class AE> 00149 BOOST_UBLAS_INLINE 00150 matrix_row &operator -= (const vector_expression<AE> &ae) { 00151 vector_assign<scalar_assign> (*this, typename vector_temporary_traits<M>::type (*this - ae)); 00152 return *this; 00153 } 00154 template<class AE> 00155 BOOST_UBLAS_INLINE 00156 matrix_row &minus_assign (const vector_expression<AE> &ae) { 00157 vector_assign<scalar_minus_assign> (*this, ae); 00158 return *this; 00159 } 00160 template<class AT> 00161 BOOST_UBLAS_INLINE 00162 matrix_row &operator *= (const AT &at) { 00163 vector_assign_scalar<scalar_multiplies_assign> (*this, at); 00164 return *this; 00165 } 00166 template<class AT> 00167 BOOST_UBLAS_INLINE 00168 matrix_row &operator /= (const AT &at) { 00169 vector_assign_scalar<scalar_divides_assign> (*this, at); 00170 return *this; 00171 } 00172 00173 // Closure comparison 00174 BOOST_UBLAS_INLINE 00175 bool same_closure (const matrix_row &mr) const { 00176 return (*this).data_.same_closure (mr.data_); 00177 } 00178 00179 // Comparison 00180 BOOST_UBLAS_INLINE 00181 bool operator == (const matrix_row &mr) const { 00182 return (*this).data_ == mr.data_ && index () == mr.index (); 00183 } 00184 00185 // Swapping 00186 BOOST_UBLAS_INLINE 00187 void swap (matrix_row mr) { 00188 if (this != &mr) { 00189 BOOST_UBLAS_CHECK (size () == mr.size (), bad_size ()); 00190 // Sparse ranges may be nonconformant now. 00191 // std::swap_ranges (begin (), end (), mr.begin ()); 00192 vector_swap<scalar_swap> (*this, mr); 00193 } 00194 } 00195 BOOST_UBLAS_INLINE 00196 friend void swap (matrix_row mr1, matrix_row mr2) { 00197 mr1.swap (mr2); 00198 } 00199 00200 // Iterator types 00201 private: 00202 typedef typename M::const_iterator2 const_subiterator_type; 00203 typedef typename boost::mpl::if_<boost::is_const<M>, 00204 typename M::const_iterator2, 00205 typename M::iterator2>::type subiterator_type; 00206 00207 public: 00208 #ifdef BOOST_UBLAS_USE_INDEXED_ITERATOR 00209 typedef indexed_iterator<matrix_row<matrix_type>, 00210 typename subiterator_type::iterator_category> iterator; 00211 typedef indexed_const_iterator<matrix_row<matrix_type>, 00212 typename const_subiterator_type::iterator_category> const_iterator; 00213 #else 00214 class const_iterator; 00215 class iterator; 00216 #endif 00217 00218 // Element lookup 00219 BOOST_UBLAS_INLINE 00220 const_iterator find (size_type j) const { 00221 const_subiterator_type it2 (data_.find2 (1, i_, j)); 00222 #ifdef BOOST_UBLAS_USE_INDEXED_ITERATOR 00223 return const_iterator (*this, it2.index2 ()); 00224 #else 00225 return const_iterator (*this, it2); 00226 #endif 00227 } 00228 BOOST_UBLAS_INLINE 00229 iterator find (size_type j) { 00230 subiterator_type it2 (data_.find2 (1, i_, j)); 00231 #ifdef BOOST_UBLAS_USE_INDEXED_ITERATOR 00232 return iterator (*this, it2.index2 ()); 00233 #else 00234 return iterator (*this, it2); 00235 #endif 00236 } 00237 00238 #ifndef BOOST_UBLAS_USE_INDEXED_ITERATOR 00239 class const_iterator: 00240 public container_const_reference<matrix_row>, 00241 public iterator_base_traits<typename const_subiterator_type::iterator_category>::template 00242 iterator_base<const_iterator, value_type>::type { 00243 public: 00244 typedef typename const_subiterator_type::value_type value_type; 00245 typedef typename const_subiterator_type::difference_type difference_type; 00246 typedef typename const_subiterator_type::reference reference; 00247 typedef typename const_subiterator_type::pointer pointer; 00248 00249 // Construction and destruction 00250 BOOST_UBLAS_INLINE 00251 const_iterator (): 00252 container_const_reference<self_type> (), it_ () {} 00253 BOOST_UBLAS_INLINE 00254 const_iterator (const self_type &mr, const const_subiterator_type &it): 00255 container_const_reference<self_type> (mr), it_ (it) {} 00256 BOOST_UBLAS_INLINE 00257 const_iterator (const typename self_type::iterator &it): // ISSUE self_type:: stops VC8 using std::iterator here 00258 container_const_reference<self_type> (it ()), it_ (it.it_) {} 00259 00260 // Arithmetic 00261 BOOST_UBLAS_INLINE 00262 const_iterator &operator ++ () { 00263 ++ it_; 00264 return *this; 00265 } 00266 BOOST_UBLAS_INLINE 00267 const_iterator &operator -- () { 00268 -- it_; 00269 return *this; 00270 } 00271 BOOST_UBLAS_INLINE 00272 const_iterator &operator += (difference_type n) { 00273 it_ += n; 00274 return *this; 00275 } 00276 BOOST_UBLAS_INLINE 00277 const_iterator &operator -= (difference_type n) { 00278 it_ -= n; 00279 return *this; 00280 } 00281 BOOST_UBLAS_INLINE 00282 difference_type operator - (const const_iterator &it) const { 00283 BOOST_UBLAS_CHECK ((*this) ().same_closure (it ()), external_logic ()); 00284 return it_ - it.it_; 00285 } 00286 00287 // Dereference 00288 BOOST_UBLAS_INLINE 00289 const_reference operator * () const { 00290 BOOST_UBLAS_CHECK (index () < (*this) ().size (), bad_index ()); 00291 return *it_; 00292 } 00293 BOOST_UBLAS_INLINE 00294 const_reference operator [] (difference_type n) const { 00295 return *(*this + n); 00296 } 00297 00298 // Index 00299 BOOST_UBLAS_INLINE 00300 size_type index () const { 00301 return it_.index2 (); 00302 } 00303 00304 // Assignment 00305 BOOST_UBLAS_INLINE 00306 const_iterator &operator = (const const_iterator &it) { 00307 container_const_reference<self_type>::assign (&it ()); 00308 it_ = it.it_; 00309 return *this; 00310 } 00311 00312 // Comparison 00313 BOOST_UBLAS_INLINE 00314 bool operator == (const const_iterator &it) const { 00315 BOOST_UBLAS_CHECK ((*this) ().same_closure (it ()), external_logic ()); 00316 return it_ == it.it_; 00317 } 00318 BOOST_UBLAS_INLINE 00319 bool operator < (const const_iterator &it) const { 00320 BOOST_UBLAS_CHECK ((*this) ().same_closure (it ()), external_logic ()); 00321 return it_ < it.it_; 00322 } 00323 00324 private: 00325 const_subiterator_type it_; 00326 }; 00327 #endif 00328 00329 BOOST_UBLAS_INLINE 00330 const_iterator begin () const { 00331 return find (0); 00332 } 00333 BOOST_UBLAS_INLINE 00334 const_iterator end () const { 00335 return find (size ()); 00336 } 00337 00338 #ifndef BOOST_UBLAS_USE_INDEXED_ITERATOR 00339 class iterator: 00340 public container_reference<matrix_row>, 00341 public iterator_base_traits<typename subiterator_type::iterator_category>::template 00342 iterator_base<iterator, value_type>::type { 00343 public: 00344 typedef typename subiterator_type::value_type value_type; 00345 typedef typename subiterator_type::difference_type difference_type; 00346 typedef typename subiterator_type::reference reference; 00347 typedef typename subiterator_type::pointer pointer; 00348 00349 // Construction and destruction 00350 BOOST_UBLAS_INLINE 00351 iterator (): 00352 container_reference<self_type> (), it_ () {} 00353 BOOST_UBLAS_INLINE 00354 iterator (self_type &mr, const subiterator_type &it): 00355 container_reference<self_type> (mr), it_ (it) {} 00356 00357 // Arithmetic 00358 BOOST_UBLAS_INLINE 00359 iterator &operator ++ () { 00360 ++ it_; 00361 return *this; 00362 } 00363 BOOST_UBLAS_INLINE 00364 iterator &operator -- () { 00365 -- it_; 00366 return *this; 00367 } 00368 BOOST_UBLAS_INLINE 00369 iterator &operator += (difference_type n) { 00370 it_ += n; 00371 return *this; 00372 } 00373 BOOST_UBLAS_INLINE 00374 iterator &operator -= (difference_type n) { 00375 it_ -= n; 00376 return *this; 00377 } 00378 BOOST_UBLAS_INLINE 00379 difference_type operator - (const iterator &it) const { 00380 BOOST_UBLAS_CHECK ((*this) ().same_closure (it ()), external_logic ()); 00381 return it_ - it.it_; 00382 } 00383 00384 // Dereference 00385 BOOST_UBLAS_INLINE 00386 reference operator * () const { 00387 BOOST_UBLAS_CHECK (index () < (*this) ().size (), bad_index ()); 00388 return *it_; 00389 } 00390 BOOST_UBLAS_INLINE 00391 reference operator [] (difference_type n) const { 00392 return *(*this + n); 00393 } 00394 00395 // Index 00396 BOOST_UBLAS_INLINE 00397 size_type index () const { 00398 return it_.index2 (); 00399 } 00400 00401 // Assignment 00402 BOOST_UBLAS_INLINE 00403 iterator &operator = (const iterator &it) { 00404 container_reference<self_type>::assign (&it ()); 00405 it_ = it.it_; 00406 return *this; 00407 } 00408 00409 // Comparison 00410 BOOST_UBLAS_INLINE 00411 bool operator == (const iterator &it) const { 00412 BOOST_UBLAS_CHECK ((*this) ().same_closure (it ()), external_logic ()); 00413 return it_ == it.it_; 00414 } 00415 BOOST_UBLAS_INLINE 00416 bool operator < (const iterator &it) const { 00417 BOOST_UBLAS_CHECK ((*this) ().same_closure (it ()), external_logic ()); 00418 return it_ < it.it_; 00419 } 00420 00421 private: 00422 subiterator_type it_; 00423 00424 friend class const_iterator; 00425 }; 00426 #endif 00427 00428 BOOST_UBLAS_INLINE 00429 iterator begin () { 00430 return find (0); 00431 } 00432 BOOST_UBLAS_INLINE 00433 iterator end () { 00434 return find (size ()); 00435 } 00436 00437 // Reverse iterator 00438 typedef reverse_iterator_base<const_iterator> const_reverse_iterator; 00439 typedef reverse_iterator_base<iterator> reverse_iterator; 00440 00441 BOOST_UBLAS_INLINE 00442 const_reverse_iterator rbegin () const { 00443 return const_reverse_iterator (end ()); 00444 } 00445 BOOST_UBLAS_INLINE 00446 const_reverse_iterator rend () const { 00447 return const_reverse_iterator (begin ()); 00448 } 00449 BOOST_UBLAS_INLINE 00450 reverse_iterator rbegin () { 00451 return reverse_iterator (end ()); 00452 } 00453 BOOST_UBLAS_INLINE 00454 reverse_iterator rend () { 00455 return reverse_iterator (begin ()); 00456 } 00457 00458 private: 00459 matrix_closure_type data_; 00460 size_type i_; 00461 }; 00462 00463 // Projections 00464 template<class M> 00465 BOOST_UBLAS_INLINE 00466 matrix_row<M> row (M &data, typename M::size_type i) { 00467 return matrix_row<M> (data, i); 00468 } 00469 template<class M> 00470 BOOST_UBLAS_INLINE 00471 const matrix_row<const M> row (const M &data, typename M::size_type i) { 00472 return matrix_row<const M> (data, i); 00473 } 00474 00475 // Specialize temporary 00476 template <class M> 00477 struct vector_temporary_traits< matrix_row<M> > 00478 : vector_temporary_traits< M > {} ; 00479 template <class M> 00480 struct vector_temporary_traits< const matrix_row<M> > 00481 : vector_temporary_traits< M > {} ; 00482 00483 // Matrix based column vector class 00484 template<class M> 00485 class matrix_column: 00486 public vector_expression<matrix_column<M> > { 00487 00488 typedef matrix_column<M> self_type; 00489 public: 00490 #ifdef BOOST_UBLAS_ENABLE_PROXY_SHORTCUTS 00491 using vector_expression<self_type>::operator (); 00492 #endif 00493 typedef M matrix_type; 00494 typedef typename M::size_type size_type; 00495 typedef typename M::difference_type difference_type; 00496 typedef typename M::value_type value_type; 00497 typedef typename M::const_reference const_reference; 00498 typedef typename boost::mpl::if_<boost::is_const<M>, 00499 typename M::const_reference, 00500 typename M::reference>::type reference; 00501 typedef typename boost::mpl::if_<boost::is_const<M>, 00502 typename M::const_closure_type, 00503 typename M::closure_type>::type matrix_closure_type; 00504 typedef const self_type const_closure_type; 00505 typedef self_type closure_type; 00506 typedef typename storage_restrict_traits<typename M::storage_category, 00507 dense_proxy_tag>::storage_category storage_category; 00508 00509 // Construction and destruction 00510 BOOST_UBLAS_INLINE 00511 matrix_column (matrix_type &data, size_type j): 00512 data_ (data), j_ (j) { 00513 // Early checking of preconditions here. 00514 // BOOST_UBLAS_CHECK (j_ < data_.size2 (), bad_index ()); 00515 } 00516 00517 // Accessors 00518 BOOST_UBLAS_INLINE 00519 size_type size () const { 00520 return data_.size1 (); 00521 } 00522 BOOST_UBLAS_INLINE 00523 size_type index () const { 00524 return j_; 00525 } 00526 00527 // Storage accessors 00528 BOOST_UBLAS_INLINE 00529 const matrix_closure_type &data () const { 00530 return data_; 00531 } 00532 BOOST_UBLAS_INLINE 00533 matrix_closure_type &data () { 00534 return data_; 00535 } 00536 00537 // Element access 00538 #ifndef BOOST_UBLAS_PROXY_CONST_MEMBER 00539 BOOST_UBLAS_INLINE 00540 const_reference operator () (size_type i) const { 00541 return data_ (i, j_); 00542 } 00543 BOOST_UBLAS_INLINE 00544 reference operator () (size_type i) { 00545 return data_ (i, j_); 00546 } 00547 00548 BOOST_UBLAS_INLINE 00549 const_reference operator [] (size_type i) const { 00550 return (*this) (i); 00551 } 00552 BOOST_UBLAS_INLINE 00553 reference operator [] (size_type i) { 00554 return (*this) (i); 00555 } 00556 #else 00557 BOOST_UBLAS_INLINE 00558 reference operator () (size_type i) const { 00559 return data_ (i, j_); 00560 } 00561 00562 BOOST_UBLAS_INLINE 00563 reference operator [] (size_type i) const { 00564 return (*this) (i); 00565 } 00566 #endif 00567 00568 // Assignment 00569 BOOST_UBLAS_INLINE 00570 matrix_column &operator = (const matrix_column &mc) { 00571 // ISSUE need a temporary, proxy can be overlaping alias 00572 vector_assign<scalar_assign> (*this, typename vector_temporary_traits<M>::type (mc)); 00573 return *this; 00574 } 00575 BOOST_UBLAS_INLINE 00576 matrix_column &assign_temporary (matrix_column &mc) { 00577 // assign elements, proxied container remains the same 00578 vector_assign<scalar_assign> (*this, mc); 00579 return *this; 00580 } 00581 template<class AE> 00582 BOOST_UBLAS_INLINE 00583 matrix_column &operator = (const vector_expression<AE> &ae) { 00584 vector_assign<scalar_assign> (*this, typename vector_temporary_traits<M>::type (ae)); 00585 return *this; 00586 } 00587 template<class AE> 00588 BOOST_UBLAS_INLINE 00589 matrix_column &assign (const vector_expression<AE> &ae) { 00590 vector_assign<scalar_assign> (*this, ae); 00591 return *this; 00592 } 00593 template<class AE> 00594 BOOST_UBLAS_INLINE 00595 matrix_column &operator += (const vector_expression<AE> &ae) { 00596 vector_assign<scalar_assign> (*this, typename vector_temporary_traits<M>::type (*this + ae)); 00597 return *this; 00598 } 00599 template<class AE> 00600 BOOST_UBLAS_INLINE 00601 matrix_column &plus_assign (const vector_expression<AE> &ae) { 00602 vector_assign<scalar_plus_assign> (*this, ae); 00603 return *this; 00604 } 00605 template<class AE> 00606 BOOST_UBLAS_INLINE 00607 matrix_column &operator -= (const vector_expression<AE> &ae) { 00608 vector_assign<scalar_assign> (*this, typename vector_temporary_traits<M>::type (*this - ae)); 00609 return *this; 00610 } 00611 template<class AE> 00612 BOOST_UBLAS_INLINE 00613 matrix_column &minus_assign (const vector_expression<AE> &ae) { 00614 vector_assign<scalar_minus_assign> (*this, ae); 00615 return *this; 00616 } 00617 template<class AT> 00618 BOOST_UBLAS_INLINE 00619 matrix_column &operator *= (const AT &at) { 00620 vector_assign_scalar<scalar_multiplies_assign> (*this, at); 00621 return *this; 00622 } 00623 template<class AT> 00624 BOOST_UBLAS_INLINE 00625 matrix_column &operator /= (const AT &at) { 00626 vector_assign_scalar<scalar_divides_assign> (*this, at); 00627 return *this; 00628 } 00629 00630 // Closure comparison 00631 BOOST_UBLAS_INLINE 00632 bool same_closure (const matrix_column &mc) const { 00633 return (*this).data_.same_closure (mc.data_); 00634 } 00635 00636 // Comparison 00637 BOOST_UBLAS_INLINE 00638 bool operator == (const matrix_column &mc) const { 00639 return (*this).data_ == mc.data_ && index () == mc.index (); 00640 } 00641 00642 // Swapping 00643 BOOST_UBLAS_INLINE 00644 void swap (matrix_column mc) { 00645 if (this != &mc) { 00646 BOOST_UBLAS_CHECK (size () == mc.size (), bad_size ()); 00647 // Sparse ranges may be nonconformant now. 00648 // std::swap_ranges (begin (), end (), mc.begin ()); 00649 vector_swap<scalar_swap> (*this, mc); 00650 } 00651 } 00652 BOOST_UBLAS_INLINE 00653 friend void swap (matrix_column mc1, matrix_column mc2) { 00654 mc1.swap (mc2); 00655 } 00656 00657 // Iterator types 00658 private: 00659 typedef typename M::const_iterator1 const_subiterator_type; 00660 typedef typename boost::mpl::if_<boost::is_const<M>, 00661 typename M::const_iterator1, 00662 typename M::iterator1>::type subiterator_type; 00663 00664 public: 00665 #ifdef BOOST_UBLAS_USE_INDEXED_ITERATOR 00666 typedef indexed_iterator<matrix_column<matrix_type>, 00667 typename subiterator_type::iterator_category> iterator; 00668 typedef indexed_const_iterator<matrix_column<matrix_type>, 00669 typename const_subiterator_type::iterator_category> const_iterator; 00670 #else 00671 class const_iterator; 00672 class iterator; 00673 #endif 00674 00675 // Element lookup 00676 BOOST_UBLAS_INLINE 00677 const_iterator find (size_type i) const { 00678 const_subiterator_type it1 (data_.find1 (1, i, j_)); 00679 #ifdef BOOST_UBLAS_USE_INDEXED_ITERATOR 00680 return const_iterator (*this, it1.index1 ()); 00681 #else 00682 return const_iterator (*this, it1); 00683 #endif 00684 } 00685 BOOST_UBLAS_INLINE 00686 iterator find (size_type i) { 00687 subiterator_type it1 (data_.find1 (1, i, j_)); 00688 #ifdef BOOST_UBLAS_USE_INDEXED_ITERATOR 00689 return iterator (*this, it1.index1 ()); 00690 #else 00691 return iterator (*this, it1); 00692 #endif 00693 } 00694 00695 #ifndef BOOST_UBLAS_USE_INDEXED_ITERATOR 00696 class const_iterator: 00697 public container_const_reference<matrix_column>, 00698 public iterator_base_traits<typename const_subiterator_type::iterator_category>::template 00699 iterator_base<const_iterator, value_type>::type { 00700 public: 00701 typedef typename const_subiterator_type::value_type value_type; 00702 typedef typename const_subiterator_type::difference_type difference_type; 00703 typedef typename const_subiterator_type::reference reference; 00704 typedef typename const_subiterator_type::pointer pointer; 00705 00706 // Construction and destruction 00707 BOOST_UBLAS_INLINE 00708 const_iterator (): 00709 container_const_reference<self_type> (), it_ () {} 00710 BOOST_UBLAS_INLINE 00711 const_iterator (const self_type &mc, const const_subiterator_type &it): 00712 container_const_reference<self_type> (mc), it_ (it) {} 00713 BOOST_UBLAS_INLINE 00714 const_iterator (const typename self_type::iterator &it): // ISSUE self_type:: stops VC8 using std::iterator here 00715 container_const_reference<self_type> (it ()), it_ (it.it_) {} 00716 00717 // Arithmetic 00718 BOOST_UBLAS_INLINE 00719 const_iterator &operator ++ () { 00720 ++ it_; 00721 return *this; 00722 } 00723 BOOST_UBLAS_INLINE 00724 const_iterator &operator -- () { 00725 -- it_; 00726 return *this; 00727 } 00728 BOOST_UBLAS_INLINE 00729 const_iterator &operator += (difference_type n) { 00730 it_ += n; 00731 return *this; 00732 } 00733 BOOST_UBLAS_INLINE 00734 const_iterator &operator -= (difference_type n) { 00735 it_ -= n; 00736 return *this; 00737 } 00738 BOOST_UBLAS_INLINE 00739 difference_type operator - (const const_iterator &it) const { 00740 BOOST_UBLAS_CHECK ((*this) ().same_closure (it ()), external_logic ()); 00741 return it_ - it.it_; 00742 } 00743 00744 // Dereference 00745 BOOST_UBLAS_INLINE 00746 const_reference operator * () const { 00747 BOOST_UBLAS_CHECK (index () < (*this) ().size (), bad_index ()); 00748 return *it_; 00749 } 00750 BOOST_UBLAS_INLINE 00751 const_reference operator [] (difference_type n) const { 00752 return *(*this + n); 00753 } 00754 00755 // Index 00756 BOOST_UBLAS_INLINE 00757 size_type index () const { 00758 return it_.index1 (); 00759 } 00760 00761 // Assignment 00762 BOOST_UBLAS_INLINE 00763 const_iterator &operator = (const const_iterator &it) { 00764 container_const_reference<self_type>::assign (&it ()); 00765 it_ = it.it_; 00766 return *this; 00767 } 00768 00769 // Comparison 00770 BOOST_UBLAS_INLINE 00771 bool operator == (const const_iterator &it) const { 00772 BOOST_UBLAS_CHECK ((*this) ().same_closure (it ()), external_logic ()); 00773 return it_ == it.it_; 00774 } 00775 BOOST_UBLAS_INLINE 00776 bool operator < (const const_iterator &it) const { 00777 BOOST_UBLAS_CHECK ((*this) ().same_closure (it ()), external_logic ()); 00778 return it_ < it.it_; 00779 } 00780 00781 private: 00782 const_subiterator_type it_; 00783 }; 00784 #endif 00785 00786 BOOST_UBLAS_INLINE 00787 const_iterator begin () const { 00788 return find (0); 00789 } 00790 BOOST_UBLAS_INLINE 00791 const_iterator end () const { 00792 return find (size ()); 00793 } 00794 00795 #ifndef BOOST_UBLAS_USE_INDEXED_ITERATOR 00796 class iterator: 00797 public container_reference<matrix_column>, 00798 public iterator_base_traits<typename subiterator_type::iterator_category>::template 00799 iterator_base<iterator, value_type>::type { 00800 public: 00801 typedef typename subiterator_type::value_type value_type; 00802 typedef typename subiterator_type::difference_type difference_type; 00803 typedef typename subiterator_type::reference reference; 00804 typedef typename subiterator_type::pointer pointer; 00805 00806 // Construction and destruction 00807 BOOST_UBLAS_INLINE 00808 iterator (): 00809 container_reference<self_type> (), it_ () {} 00810 BOOST_UBLAS_INLINE 00811 iterator (self_type &mc, const subiterator_type &it): 00812 container_reference<self_type> (mc), it_ (it) {} 00813 00814 // Arithmetic 00815 BOOST_UBLAS_INLINE 00816 iterator &operator ++ () { 00817 ++ it_; 00818 return *this; 00819 } 00820 BOOST_UBLAS_INLINE 00821 iterator &operator -- () { 00822 -- it_; 00823 return *this; 00824 } 00825 BOOST_UBLAS_INLINE 00826 iterator &operator += (difference_type n) { 00827 it_ += n; 00828 return *this; 00829 } 00830 BOOST_UBLAS_INLINE 00831 iterator &operator -= (difference_type n) { 00832 it_ -= n; 00833 return *this; 00834 } 00835 BOOST_UBLAS_INLINE 00836 difference_type operator - (const iterator &it) const { 00837 BOOST_UBLAS_CHECK ((*this) ().same_closure (it ()), external_logic ()); 00838 return it_ - it.it_; 00839 } 00840 00841 // Dereference 00842 BOOST_UBLAS_INLINE 00843 reference operator * () const { 00844 BOOST_UBLAS_CHECK (index () < (*this) ().size (), bad_index ()); 00845 return *it_; 00846 } 00847 BOOST_UBLAS_INLINE 00848 reference operator [] (difference_type n) const { 00849 return *(*this + n); 00850 } 00851 00852 // Index 00853 BOOST_UBLAS_INLINE 00854 size_type index () const { 00855 return it_.index1 (); 00856 } 00857 00858 // Assignment 00859 BOOST_UBLAS_INLINE 00860 iterator &operator = (const iterator &it) { 00861 container_reference<self_type>::assign (&it ()); 00862 it_ = it.it_; 00863 return *this; 00864 } 00865 00866 // Comparison 00867 BOOST_UBLAS_INLINE 00868 bool operator == (const iterator &it) const { 00869 BOOST_UBLAS_CHECK ((*this) ().same_closure (it ()), external_logic ()); 00870 return it_ == it.it_; 00871 } 00872 BOOST_UBLAS_INLINE 00873 bool operator < (const iterator &it) const { 00874 BOOST_UBLAS_CHECK ((*this) ().same_closure (it ()), external_logic ()); 00875 return it_ < it.it_; 00876 } 00877 00878 private: 00879 subiterator_type it_; 00880 00881 friend class const_iterator; 00882 }; 00883 #endif 00884 00885 BOOST_UBLAS_INLINE 00886 iterator begin () { 00887 return find (0); 00888 } 00889 BOOST_UBLAS_INLINE 00890 iterator end () { 00891 return find (size ()); 00892 } 00893 00894 // Reverse iterator 00895 typedef reverse_iterator_base<const_iterator> const_reverse_iterator; 00896 typedef reverse_iterator_base<iterator> reverse_iterator; 00897 00898 BOOST_UBLAS_INLINE 00899 const_reverse_iterator rbegin () const { 00900 return const_reverse_iterator (end ()); 00901 } 00902 BOOST_UBLAS_INLINE 00903 const_reverse_iterator rend () const { 00904 return const_reverse_iterator (begin ()); 00905 } 00906 reverse_iterator rbegin () { 00907 return reverse_iterator (end ()); 00908 } 00909 BOOST_UBLAS_INLINE 00910 reverse_iterator rend () { 00911 return reverse_iterator (begin ()); 00912 } 00913 00914 private: 00915 matrix_closure_type data_; 00916 size_type j_; 00917 }; 00918 00919 // Projections 00920 template<class M> 00921 BOOST_UBLAS_INLINE 00922 matrix_column<M> column (M &data, typename M::size_type j) { 00923 return matrix_column<M> (data, j); 00924 } 00925 template<class M> 00926 BOOST_UBLAS_INLINE 00927 const matrix_column<const M> column (const M &data, typename M::size_type j) { 00928 return matrix_column<const M> (data, j); 00929 } 00930 00931 // Specialize temporary 00932 template <class M> 00933 struct vector_temporary_traits< matrix_column<M> > 00934 : vector_temporary_traits< M > {} ; 00935 template <class M> 00936 struct vector_temporary_traits< const matrix_column<M> > 00937 : vector_temporary_traits< M > {} ; 00938 00939 // Matrix based vector range class 00940 template<class M> 00941 class matrix_vector_range: 00942 public vector_expression<matrix_vector_range<M> > { 00943 00944 typedef matrix_vector_range<M> self_type; 00945 public: 00946 #ifdef BOOST_UBLAS_ENABLE_PROXY_SHORTCUTS 00947 using vector_expression<self_type>::operator (); 00948 #endif 00949 typedef M matrix_type; 00950 typedef typename M::size_type size_type; 00951 typedef typename M::difference_type difference_type; 00952 typedef typename M::value_type value_type; 00953 typedef typename M::const_reference const_reference; 00954 typedef typename boost::mpl::if_<boost::is_const<M>, 00955 typename M::const_reference, 00956 typename M::reference>::type reference; 00957 typedef typename boost::mpl::if_<boost::is_const<M>, 00958 typename M::const_closure_type, 00959 typename M::closure_type>::type matrix_closure_type; 00960 typedef basic_range<size_type, difference_type> range_type; 00961 typedef const self_type const_closure_type; 00962 typedef self_type closure_type; 00963 typedef typename storage_restrict_traits<typename M::storage_category, 00964 dense_proxy_tag>::storage_category storage_category; 00965 00966 // Construction and destruction 00967 BOOST_UBLAS_INLINE 00968 matrix_vector_range (matrix_type &data, const range_type &r1, const range_type &r2): 00969 data_ (data), r1_ (r1.preprocess (data.size1 ())), r2_ (r2.preprocess (data.size2 ())) { 00970 // Early checking of preconditions here. 00971 // BOOST_UBLAS_CHECK (r1_.start () <= data_.size1 () && 00972 // r1_.start () + r1_.size () <= data_.size1 (), bad_index ()); 00973 // BOOST_UBLAS_CHECK (r2_.start () <= data_.size2 () && 00974 // r2_.start () + r2_.size () <= data_.size2 (), bad_index ()); 00975 // BOOST_UBLAS_CHECK (r1_.size () == r2_.size (), bad_size ()); 00976 } 00977 00978 // Accessors 00979 BOOST_UBLAS_INLINE 00980 size_type start1 () const { 00981 return r1_.start (); 00982 } 00983 BOOST_UBLAS_INLINE 00984 size_type start2 () const { 00985 return r2_.start (); 00986 } 00987 BOOST_UBLAS_INLINE 00988 size_type size () const { 00989 return BOOST_UBLAS_SAME (r1_.size (), r2_.size ()); 00990 } 00991 00992 // Storage accessors 00993 BOOST_UBLAS_INLINE 00994 const matrix_closure_type &data () const { 00995 return data_; 00996 } 00997 BOOST_UBLAS_INLINE 00998 matrix_closure_type &data () { 00999 return data_; 01000 } 01001 01002 // Element access 01003 #ifndef BOOST_UBLAS_PROXY_CONST_MEMBER 01004 BOOST_UBLAS_INLINE 01005 const_reference operator () (size_type i) const { 01006 return data_ (r1_ (i), r2_ (i)); 01007 } 01008 BOOST_UBLAS_INLINE 01009 reference operator () (size_type i) { 01010 return data_ (r1_ (i), r2_ (i)); 01011 } 01012 01013 BOOST_UBLAS_INLINE 01014 const_reference operator [] (size_type i) const { 01015 return (*this) (i); 01016 } 01017 BOOST_UBLAS_INLINE 01018 reference operator [] (size_type i) { 01019 return (*this) (i); 01020 } 01021 #else 01022 BOOST_UBLAS_INLINE 01023 reference operator () (size_type i) const { 01024 return data_ (r1_ (i), r2_ (i)); 01025 } 01026 01027 BOOST_UBLAS_INLINE 01028 reference operator [] (size_type i) const { 01029 return (*this) (i); 01030 } 01031 #endif 01032 01033 // Assignment 01034 BOOST_UBLAS_INLINE 01035 matrix_vector_range &operator = (const matrix_vector_range &mvr) { 01036 // ISSUE need a temporary, proxy can be overlaping alias 01037 vector_assign<scalar_assign> (*this, typename vector_temporary_traits<M>::type (mvr)); 01038 return *this; 01039 } 01040 BOOST_UBLAS_INLINE 01041 matrix_vector_range &assign_temporary (matrix_vector_range &mvr) { 01042 // assign elements, proxied container remains the same 01043 vector_assign<scalar_assign> (*this, mvr); 01044 return *this; 01045 } 01046 template<class AE> 01047 BOOST_UBLAS_INLINE 01048 matrix_vector_range &operator = (const vector_expression<AE> &ae) { 01049 vector_assign<scalar_assign> (*this, typename vector_temporary_traits<M>::type (ae)); 01050 return *this; 01051 } 01052 template<class AE> 01053 BOOST_UBLAS_INLINE 01054 matrix_vector_range &assign (const vector_expression<AE> &ae) { 01055 vector_assign<scalar_assign> (*this, ae); 01056 return *this; 01057 } 01058 template<class AE> 01059 BOOST_UBLAS_INLINE 01060 matrix_vector_range &operator += (const vector_expression<AE> &ae) { 01061 vector_assign<scalar_assign> (*this, typename vector_temporary_traits<M>::type (*this + ae)); 01062 return *this; 01063 } 01064 template<class AE> 01065 BOOST_UBLAS_INLINE 01066 matrix_vector_range &plus_assign (const vector_expression<AE> &ae) { 01067 vector_assign<scalar_plus_assign> (*this, ae); 01068 return *this; 01069 } 01070 template<class AE> 01071 BOOST_UBLAS_INLINE 01072 matrix_vector_range &operator -= (const vector_expression<AE> &ae) { 01073 vector_assign<scalar_assign> (*this, typename vector_temporary_traits<M>::type (*this - ae)); 01074 return *this; 01075 } 01076 template<class AE> 01077 BOOST_UBLAS_INLINE 01078 matrix_vector_range &minus_assign (const vector_expression<AE> &ae) { 01079 vector_assign<scalar_minus_assign> (*this, ae); 01080 return *this; 01081 } 01082 template<class AT> 01083 BOOST_UBLAS_INLINE 01084 matrix_vector_range &operator *= (const AT &at) { 01085 vector_assign_scalar<scalar_multiplies_assign> (*this, at); 01086 return *this; 01087 } 01088 template<class AT> 01089 BOOST_UBLAS_INLINE 01090 matrix_vector_range &operator /= (const AT &at) { 01091 vector_assign_scalar<scalar_divides_assign> (*this, at); 01092 return *this; 01093 } 01094 01095 // Closure comparison 01096 BOOST_UBLAS_INLINE 01097 bool same_closure (const matrix_vector_range &mvr) const { 01098 return (*this).data_.same_closure (mvr.data_); 01099 } 01100 01101 // Comparison 01102 BOOST_UBLAS_INLINE 01103 bool operator == (const matrix_vector_range &mvr) const { 01104 return (*this).data_ == mvr.data_ && r1_ == mvr.r1_ && r2_ == mvr.r2_; 01105 } 01106 01107 // Swapping 01108 BOOST_UBLAS_INLINE 01109 void swap (matrix_vector_range mvr) { 01110 if (this != &mvr) { 01111 BOOST_UBLAS_CHECK (size () == mvr.size (), bad_size ()); 01112 // Sparse ranges may be nonconformant now. 01113 // std::swap_ranges (begin (), end (), mvr.begin ()); 01114 vector_swap<scalar_swap> (*this, mvr); 01115 } 01116 } 01117 BOOST_UBLAS_INLINE 01118 friend void swap (matrix_vector_range mvr1, matrix_vector_range mvr2) { 01119 mvr1.swap (mvr2); 01120 } 01121 01122 // Iterator types 01123 private: 01124 // Use range as an index - FIXME this fails for packed assignment 01125 typedef typename range_type::const_iterator const_subiterator1_type; 01126 typedef typename range_type::const_iterator subiterator1_type; 01127 typedef typename range_type::const_iterator const_subiterator2_type; 01128 typedef typename range_type::const_iterator subiterator2_type; 01129 01130 public: 01131 class const_iterator; 01132 class iterator; 01133 01134 // Element lookup 01135 BOOST_UBLAS_INLINE 01136 const_iterator find (size_type i) const { 01137 return const_iterator (*this, r1_.begin () + i, r2_.begin () + i); 01138 } 01139 BOOST_UBLAS_INLINE 01140 iterator find (size_type i) { 01141 return iterator (*this, r1_.begin () + i, r2_.begin () + i); 01142 } 01143 01144 class const_iterator: 01145 public container_const_reference<matrix_vector_range>, 01146 public iterator_base_traits<typename M::const_iterator1::iterator_category>::template 01147 iterator_base<const_iterator, value_type>::type { 01148 public: 01149 // FIXME Iterator can never be different code was: 01150 // typename iterator_restrict_traits<typename M::const_iterator1::iterator_category, typename M::const_iterator2::iterator_category>::iterator_category> 01151 BOOST_STATIC_ASSERT ((boost::is_same<typename M::const_iterator1::iterator_category, typename M::const_iterator2::iterator_category>::value )); 01152 01153 typedef typename matrix_vector_range::value_type value_type; 01154 typedef typename matrix_vector_range::difference_type difference_type; 01155 typedef typename matrix_vector_range::const_reference reference; 01156 typedef const typename matrix_vector_range::value_type *pointer; 01157 01158 // Construction and destruction 01159 BOOST_UBLAS_INLINE 01160 const_iterator (): 01161 container_const_reference<self_type> (), it1_ (), it2_ () {} 01162 BOOST_UBLAS_INLINE 01163 const_iterator (const self_type &mvr, const const_subiterator1_type &it1, const const_subiterator2_type &it2): 01164 container_const_reference<self_type> (mvr), it1_ (it1), it2_ (it2) {} 01165 BOOST_UBLAS_INLINE 01166 const_iterator (const typename self_type::iterator &it): // ISSUE self_type:: stops VC8 using std::iterator here 01167 container_const_reference<self_type> (it ()), it1_ (it.it1_), it2_ (it.it2_) {} 01168 01169 // Arithmetic 01170 BOOST_UBLAS_INLINE 01171 const_iterator &operator ++ () { 01172 ++ it1_; 01173 ++ it2_; 01174 return *this; 01175 } 01176 BOOST_UBLAS_INLINE 01177 const_iterator &operator -- () { 01178 -- it1_; 01179 -- it2_; 01180 return *this; 01181 } 01182 BOOST_UBLAS_INLINE 01183 const_iterator &operator += (difference_type n) { 01184 it1_ += n; 01185 it2_ += n; 01186 return *this; 01187 } 01188 BOOST_UBLAS_INLINE 01189 const_iterator &operator -= (difference_type n) { 01190 it1_ -= n; 01191 it2_ -= n; 01192 return *this; 01193 } 01194 BOOST_UBLAS_INLINE 01195 difference_type operator - (const const_iterator &it) const { 01196 BOOST_UBLAS_CHECK ((*this) ().same_closure (it ()), external_logic ()); 01197 return BOOST_UBLAS_SAME (it1_ - it.it1_, it2_ - it.it2_); 01198 } 01199 01200 // Dereference 01201 BOOST_UBLAS_INLINE 01202 const_reference operator * () const { 01203 // FIXME replace find with at_element 01204 return (*this) ().data_ (*it1_, *it2_); 01205 } 01206 BOOST_UBLAS_INLINE 01207 const_reference operator [] (difference_type n) const { 01208 return *(*this + n); 01209 } 01210 01211 // Index 01212 BOOST_UBLAS_INLINE 01213 size_type index () const { 01214 return BOOST_UBLAS_SAME (it1_.index (), it2_.index ()); 01215 } 01216 01217 // Assignment 01218 BOOST_UBLAS_INLINE 01219 const_iterator &operator = (const const_iterator &it) { 01220 container_const_reference<self_type>::assign (&it ()); 01221 it1_ = it.it1_; 01222 it2_ = it.it2_; 01223 return *this; 01224 } 01225 01226 // Comparison 01227 BOOST_UBLAS_INLINE 01228 bool operator == (const const_iterator &it) const { 01229 BOOST_UBLAS_CHECK ((*this) ().same_closure (it ()), external_logic ()); 01230 return it1_ == it.it1_ && it2_ == it.it2_; 01231 } 01232 BOOST_UBLAS_INLINE 01233 bool operator < (const const_iterator &it) const { 01234 BOOST_UBLAS_CHECK ((*this) ().same_closure (it ()), external_logic ()); 01235 return it1_ < it.it1_ && it2_ < it.it2_; 01236 } 01237 01238 private: 01239 const_subiterator1_type it1_; 01240 const_subiterator2_type it2_; 01241 }; 01242 01243 BOOST_UBLAS_INLINE 01244 const_iterator begin () const { 01245 return find (0); 01246 } 01247 BOOST_UBLAS_INLINE 01248 const_iterator end () const { 01249 return find (size ()); 01250 } 01251 01252 class iterator: 01253 public container_reference<matrix_vector_range>, 01254 public iterator_base_traits<typename M::iterator1::iterator_category>::template 01255 iterator_base<iterator, value_type>::type { 01256 public: 01257 // FIXME Iterator can never be different code was: 01258 // typename iterator_restrict_traits<typename M::const_iterator1::iterator_category, typename M::const_iterator2::iterator_category>::iterator_category> 01259 BOOST_STATIC_ASSERT ((boost::is_same<typename M::const_iterator1::iterator_category, typename M::const_iterator2::iterator_category>::value )); 01260 01261 typedef typename matrix_vector_range::value_type value_type; 01262 typedef typename matrix_vector_range::difference_type difference_type; 01263 typedef typename matrix_vector_range::reference reference; 01264 typedef typename matrix_vector_range::value_type *pointer; 01265 01266 // Construction and destruction 01267 BOOST_UBLAS_INLINE 01268 iterator (): 01269 container_reference<self_type> (), it1_ (), it2_ () {} 01270 BOOST_UBLAS_INLINE 01271 iterator (self_type &mvr, const subiterator1_type &it1, const subiterator2_type &it2): 01272 container_reference<self_type> (mvr), it1_ (it1), it2_ (it2) {} 01273 01274 // Arithmetic 01275 BOOST_UBLAS_INLINE 01276 iterator &operator ++ () { 01277 ++ it1_; 01278 ++ it2_; 01279 return *this; 01280 } 01281 BOOST_UBLAS_INLINE 01282 iterator &operator -- () { 01283 -- it1_; 01284 -- it2_; 01285 return *this; 01286 } 01287 BOOST_UBLAS_INLINE 01288 iterator &operator += (difference_type n) { 01289 it1_ += n; 01290 it2_ += n; 01291 return *this; 01292 } 01293 BOOST_UBLAS_INLINE 01294 iterator &operator -= (difference_type n) { 01295 it1_ -= n; 01296 it2_ -= n; 01297 return *this; 01298 } 01299 BOOST_UBLAS_INLINE 01300 difference_type operator - (const iterator &it) const { 01301 BOOST_UBLAS_CHECK ((*this) ().same_closure (it ()), external_logic ()); 01302 return BOOST_UBLAS_SAME (it1_ - it.it1_, it2_ - it.it2_); 01303 } 01304 01305 // Dereference 01306 BOOST_UBLAS_INLINE 01307 reference operator * () const { 01308 // FIXME replace find with at_element 01309 return (*this) ().data_ (*it1_, *it2_); 01310 } 01311 BOOST_UBLAS_INLINE 01312 reference operator [] (difference_type n) const { 01313 return *(*this + n); 01314 } 01315 01316 // Index 01317 BOOST_UBLAS_INLINE 01318 size_type index () const { 01319 return BOOST_UBLAS_SAME (it1_.index (), it2_.index ()); 01320 } 01321 01322 // Assignment 01323 BOOST_UBLAS_INLINE 01324 iterator &operator = (const iterator &it) { 01325 container_reference<self_type>::assign (&it ()); 01326 it1_ = it.it1_; 01327 it2_ = it.it2_; 01328 return *this; 01329 } 01330 01331 // Comparison 01332 BOOST_UBLAS_INLINE 01333 bool operator == (const iterator &it) const { 01334 BOOST_UBLAS_CHECK ((*this) ().same_closure (it ()), external_logic ()); 01335 return it1_ == it.it1_ && it2_ == it.it2_; 01336 } 01337 BOOST_UBLAS_INLINE 01338 bool operator < (const iterator &it) const { 01339 BOOST_UBLAS_CHECK ((*this) ().same_closure (it ()), external_logic ()); 01340 return it1_ < it.it1_ && it2_ < it.it2_; 01341 } 01342 01343 private: 01344 subiterator1_type it1_; 01345 subiterator2_type it2_; 01346 01347 friend class const_iterator; 01348 }; 01349 01350 BOOST_UBLAS_INLINE 01351 iterator begin () { 01352 return find (0); 01353 } 01354 BOOST_UBLAS_INLINE 01355 iterator end () { 01356 return find (size ()); 01357 } 01358 01359 // Reverse iterator 01360 typedef reverse_iterator_base<const_iterator> const_reverse_iterator; 01361 typedef reverse_iterator_base<iterator> reverse_iterator; 01362 01363 BOOST_UBLAS_INLINE 01364 const_reverse_iterator rbegin () const { 01365 return const_reverse_iterator (end ()); 01366 } 01367 BOOST_UBLAS_INLINE 01368 const_reverse_iterator rend () const { 01369 return const_reverse_iterator (begin ()); 01370 } 01371 BOOST_UBLAS_INLINE 01372 reverse_iterator rbegin () { 01373 return reverse_iterator (end ()); 01374 } 01375 BOOST_UBLAS_INLINE 01376 reverse_iterator rend () { 01377 return reverse_iterator (begin ()); 01378 } 01379 01380 private: 01381 matrix_closure_type data_; 01382 range_type r1_; 01383 range_type r2_; 01384 }; 01385 01386 // Specialize temporary 01387 template <class M> 01388 struct vector_temporary_traits< matrix_vector_range<M> > 01389 : vector_temporary_traits< M > {} ; 01390 template <class M> 01391 struct vector_temporary_traits< const matrix_vector_range<M> > 01392 : vector_temporary_traits< M > {} ; 01393 01394 // Matrix based vector slice class 01395 template<class M> 01396 class matrix_vector_slice: 01397 public vector_expression<matrix_vector_slice<M> > { 01398 01399 typedef matrix_vector_slice<M> self_type; 01400 public: 01401 #ifdef BOOST_UBLAS_ENABLE_PROXY_SHORTCUTS 01402 using vector_expression<self_type>::operator (); 01403 #endif 01404 typedef M matrix_type; 01405 typedef typename M::size_type size_type; 01406 typedef typename M::difference_type difference_type; 01407 typedef typename M::value_type value_type; 01408 typedef typename M::const_reference const_reference; 01409 typedef typename boost::mpl::if_<boost::is_const<M>, 01410 typename M::const_reference, 01411 typename M::reference>::type reference; 01412 typedef typename boost::mpl::if_<boost::is_const<M>, 01413 typename M::const_closure_type, 01414 typename M::closure_type>::type matrix_closure_type; 01415 typedef basic_range<size_type, difference_type> range_type; 01416 typedef basic_slice<size_type, difference_type> slice_type; 01417 typedef const self_type const_closure_type; 01418 typedef self_type closure_type; 01419 typedef typename storage_restrict_traits<typename M::storage_category, 01420 dense_proxy_tag>::storage_category storage_category; 01421 01422 // Construction and destruction 01423 BOOST_UBLAS_INLINE 01424 matrix_vector_slice (matrix_type &data, const slice_type &s1, const slice_type &s2): 01425 data_ (data), s1_ (s1.preprocess (data.size1 ())), s2_ (s2.preprocess (data.size2 ())) { 01426 // Early checking of preconditions here. 01427 // BOOST_UBLAS_CHECK (s1_.start () <= data_.size1 () && 01428 // s1_.start () + s1_.stride () * (s1_.size () - (s1_.size () > 0)) <= data_.size1 (), bad_index ()); 01429 // BOOST_UBLAS_CHECK (s2_.start () <= data_.size2 () && 01430 // s2_.start () + s2_.stride () * (s2_.size () - (s2_.size () > 0)) <= data_.size2 (), bad_index ()); 01431 } 01432 01433 // Accessors 01434 BOOST_UBLAS_INLINE 01435 size_type start1 () const { 01436 return s1_.start (); 01437 } 01438 BOOST_UBLAS_INLINE 01439 size_type start2 () const { 01440 return s2_.start (); 01441 } 01442 BOOST_UBLAS_INLINE 01443 difference_type stride1 () const { 01444 return s1_.stride (); 01445 } 01446 BOOST_UBLAS_INLINE 01447 difference_type stride2 () const { 01448 return s2_.stride (); 01449 } 01450 BOOST_UBLAS_INLINE 01451 size_type size () const { 01452 return BOOST_UBLAS_SAME (s1_.size (), s2_.size ()); 01453 } 01454 01455 // Storage accessors 01456 BOOST_UBLAS_INLINE 01457 const matrix_closure_type &data () const { 01458 return data_; 01459 } 01460 BOOST_UBLAS_INLINE 01461 matrix_closure_type &data () { 01462 return data_; 01463 } 01464 01465 // Element access 01466 #ifndef BOOST_UBLAS_PROXY_CONST_MEMBER 01467 BOOST_UBLAS_INLINE 01468 const_reference operator () (size_type i) const { 01469 return data_ (s1_ (i), s2_ (i)); 01470 } 01471 BOOST_UBLAS_INLINE 01472 reference operator () (size_type i) { 01473 return data_ (s1_ (i), s2_ (i)); 01474 } 01475 01476 BOOST_UBLAS_INLINE 01477 const_reference operator [] (size_type i) const { 01478 return (*this) (i); 01479 } 01480 BOOST_UBLAS_INLINE 01481 reference operator [] (size_type i) { 01482 return (*this) (i); 01483 } 01484 #else 01485 BOOST_UBLAS_INLINE 01486 reference operator () (size_type i) const { 01487 return data_ (s1_ (i), s2_ (i)); 01488 } 01489 01490 BOOST_UBLAS_INLINE 01491 reference operator [] (size_type i) const { 01492 return (*this) (i); 01493 } 01494 #endif 01495 01496 // Assignment 01497 BOOST_UBLAS_INLINE 01498 matrix_vector_slice &operator = (const matrix_vector_slice &mvs) { 01499 // ISSUE need a temporary, proxy can be overlaping alias 01500 vector_assign<scalar_assign> (*this, typename vector_temporary_traits<M>::type (mvs)); 01501 return *this; 01502 } 01503 BOOST_UBLAS_INLINE 01504 matrix_vector_slice &assign_temporary (matrix_vector_slice &mvs) { 01505 // assign elements, proxied container remains the same 01506 vector_assign<scalar_assign> (*this, mvs); 01507 return *this; 01508 } 01509 template<class AE> 01510 BOOST_UBLAS_INLINE 01511 matrix_vector_slice &operator = (const vector_expression<AE> &ae) { 01512 vector_assign<scalar_assign> (*this, typename vector_temporary_traits<M>::type (ae)); 01513 return *this; 01514 } 01515 template<class AE> 01516 BOOST_UBLAS_INLINE 01517 matrix_vector_slice &assign (const vector_expression<AE> &ae) { 01518 vector_assign<scalar_assign> (*this, ae); 01519 return *this; 01520 } 01521 template<class AE> 01522 BOOST_UBLAS_INLINE 01523 matrix_vector_slice &operator += (const vector_expression<AE> &ae) { 01524 vector_assign<scalar_assign> (*this, typename vector_temporary_traits<M>::type (*this + ae)); 01525 return *this; 01526 } 01527 template<class AE> 01528 BOOST_UBLAS_INLINE 01529 matrix_vector_slice &plus_assign (const vector_expression<AE> &ae) { 01530 vector_assign<scalar_plus_assign> (*this, ae); 01531 return *this; 01532 } 01533 template<class AE> 01534 BOOST_UBLAS_INLINE 01535 matrix_vector_slice &operator -= (const vector_expression<AE> &ae) { 01536 vector_assign<scalar_assign> (*this, typename vector_temporary_traits<M>::type (*this - ae)); 01537 return *this; 01538 } 01539 template<class AE> 01540 BOOST_UBLAS_INLINE 01541 matrix_vector_slice &minus_assign (const vector_expression<AE> &ae) { 01542 vector_assign<scalar_minus_assign> (*this, ae); 01543 return *this; 01544 } 01545 template<class AT> 01546 BOOST_UBLAS_INLINE 01547 matrix_vector_slice &operator *= (const AT &at) { 01548 vector_assign_scalar<scalar_multiplies_assign> (*this, at); 01549 return *this; 01550 } 01551 template<class AT> 01552 BOOST_UBLAS_INLINE 01553 matrix_vector_slice &operator /= (const AT &at) { 01554 vector_assign_scalar<scalar_divides_assign> (*this, at); 01555 return *this; 01556 } 01557 01558 // Closure comparison 01559 BOOST_UBLAS_INLINE 01560 bool same_closure (const matrix_vector_slice &mvs) const { 01561 return (*this).data_.same_closure (mvs.data_); 01562 } 01563 01564 // Comparison 01565 BOOST_UBLAS_INLINE 01566 bool operator == (const matrix_vector_slice &mvs) const { 01567 return (*this).data_ == mvs.data_ && s1_ == mvs.s1_ && s2_ == mvs.s2_; 01568 } 01569 01570 // Swapping 01571 BOOST_UBLAS_INLINE 01572 void swap (matrix_vector_slice mvs) { 01573 if (this != &mvs) { 01574 BOOST_UBLAS_CHECK (size () == mvs.size (), bad_size ()); 01575 // Sparse ranges may be nonconformant now. 01576 // std::swap_ranges (begin (), end (), mvs.begin ()); 01577 vector_swap<scalar_swap> (*this, mvs); 01578 } 01579 } 01580 BOOST_UBLAS_INLINE 01581 friend void swap (matrix_vector_slice mvs1, matrix_vector_slice mvs2) { 01582 mvs1.swap (mvs2); 01583 } 01584 01585 // Iterator types 01586 private: 01587 // Use slice as an index - FIXME this fails for packed assignment 01588 typedef typename slice_type::const_iterator const_subiterator1_type; 01589 typedef typename slice_type::const_iterator subiterator1_type; 01590 typedef typename slice_type::const_iterator const_subiterator2_type; 01591 typedef typename slice_type::const_iterator subiterator2_type; 01592 01593 public: 01594 class const_iterator; 01595 class iterator; 01596 01597 // Element lookup 01598 BOOST_UBLAS_INLINE 01599 const_iterator find (size_type i) const { 01600 return const_iterator (*this, s1_.begin () + i, s2_.begin () + i); 01601 } 01602 BOOST_UBLAS_INLINE 01603 iterator find (size_type i) { 01604 return iterator (*this, s1_.begin () + i, s2_.begin () + i); 01605 } 01606 01607 // Iterators simply are indices. 01608 01609 class const_iterator: 01610 public container_const_reference<matrix_vector_slice>, 01611 public iterator_base_traits<typename M::const_iterator1::iterator_category>::template 01612 iterator_base<const_iterator, value_type>::type { 01613 public: 01614 // FIXME Iterator can never be different code was: 01615 // typename iterator_restrict_traits<typename M::const_iterator1::iterator_category, typename M::const_iterator2::iterator_category>::iterator_category> 01616 BOOST_STATIC_ASSERT ((boost::is_same<typename M::const_iterator1::iterator_category, typename M::const_iterator2::iterator_category>::value )); 01617 01618 typedef typename matrix_vector_slice::value_type value_type; 01619 typedef typename matrix_vector_slice::difference_type difference_type; 01620 typedef typename matrix_vector_slice::const_reference reference; 01621 typedef const typename matrix_vector_slice::value_type *pointer; 01622 01623 // Construction and destruction 01624 BOOST_UBLAS_INLINE 01625 const_iterator (): 01626 container_const_reference<self_type> (), it1_ (), it2_ () {} 01627 BOOST_UBLAS_INLINE 01628 const_iterator (const self_type &mvs, const const_subiterator1_type &it1, const const_subiterator2_type &it2): 01629 container_const_reference<self_type> (mvs), it1_ (it1), it2_ (it2) {} 01630 BOOST_UBLAS_INLINE 01631 const_iterator (const typename self_type::iterator &it): // ISSUE vector:: stops VC8 using std::iterator here 01632 container_const_reference<self_type> (it ()), it1_ (it.it1_), it2_ (it.it2_) {} 01633 01634 // Arithmetic 01635 BOOST_UBLAS_INLINE 01636 const_iterator &operator ++ () { 01637 ++ it1_; 01638 ++ it2_; 01639 return *this; 01640 } 01641 BOOST_UBLAS_INLINE 01642 const_iterator &operator -- () { 01643 -- it1_; 01644 -- it2_; 01645 return *this; 01646 } 01647 BOOST_UBLAS_INLINE 01648 const_iterator &operator += (difference_type n) { 01649 it1_ += n; 01650 it2_ += n; 01651 return *this; 01652 } 01653 BOOST_UBLAS_INLINE 01654 const_iterator &operator -= (difference_type n) { 01655 it1_ -= n; 01656 it2_ -= n; 01657 return *this; 01658 } 01659 BOOST_UBLAS_INLINE 01660 difference_type operator - (const const_iterator &it) const { 01661 BOOST_UBLAS_CHECK ((*this) ().same_closure (it ()), external_logic ()); 01662 return BOOST_UBLAS_SAME (it1_ - it.it1_, it2_ - it.it2_); 01663 } 01664 01665 // Dereference 01666 BOOST_UBLAS_INLINE 01667 const_reference operator * () const { 01668 // FIXME replace find with at_element 01669 return (*this) ().data_ (*it1_, *it2_); 01670 } 01671 BOOST_UBLAS_INLINE 01672 const_reference operator [] (difference_type n) const { 01673 return *(*this + n); 01674 } 01675 01676 // Index 01677 BOOST_UBLAS_INLINE 01678 size_type index () const { 01679 return BOOST_UBLAS_SAME (it1_.index (), it2_.index ()); 01680 } 01681 01682 // Assignment 01683 BOOST_UBLAS_INLINE 01684 const_iterator &operator = (const const_iterator &it) { 01685 container_const_reference<self_type>::assign (&it ()); 01686 it1_ = it.it1_; 01687 it2_ = it.it2_; 01688 return *this; 01689 } 01690 01691 // Comparison 01692 BOOST_UBLAS_INLINE 01693 bool operator == (const const_iterator &it) const { 01694 BOOST_UBLAS_CHECK ((*this) ().same_closure (it ()), external_logic ()); 01695 return it1_ == it.it1_ && it2_ == it.it2_; 01696 } 01697 BOOST_UBLAS_INLINE 01698 bool operator < (const const_iterator &it) const { 01699 BOOST_UBLAS_CHECK ((*this) ().same_closure (it ()), external_logic ()); 01700 return it1_ < it.it1_ && it2_ < it.it2_; 01701 } 01702 01703 private: 01704 const_subiterator1_type it1_; 01705 const_subiterator2_type it2_; 01706 }; 01707 01708 BOOST_UBLAS_INLINE 01709 const_iterator begin () const { 01710 return find (0); 01711 } 01712 BOOST_UBLAS_INLINE 01713 const_iterator end () const { 01714 return find (size ()); 01715 } 01716 01717 class iterator: 01718 public container_reference<matrix_vector_slice>, 01719 public iterator_base_traits<typename M::iterator1::iterator_category>::template 01720 iterator_base<iterator, value_type>::type { 01721 public: 01722 // FIXME Iterator can never be different code was: 01723 // typename iterator_restrict_traits<typename M::const_iterator1::iterator_category, typename M::const_iterator2::iterator_category>::iterator_category> 01724 BOOST_STATIC_ASSERT ((boost::is_same<typename M::const_iterator1::iterator_category, typename M::const_iterator2::iterator_category>::value )); 01725 01726 typedef typename matrix_vector_slice::value_type value_type; 01727 typedef typename matrix_vector_slice::difference_type difference_type; 01728 typedef typename matrix_vector_slice::reference reference; 01729 typedef typename matrix_vector_slice::value_type *pointer; 01730 01731 // Construction and destruction 01732 BOOST_UBLAS_INLINE 01733 iterator (): 01734 container_reference<self_type> (), it1_ (), it2_ () {} 01735 BOOST_UBLAS_INLINE 01736 iterator (self_type &mvs, const subiterator1_type &it1, const subiterator2_type &it2): 01737 container_reference<self_type> (mvs), it1_ (it1), it2_ (it2) {} 01738 01739 // Arithmetic 01740 BOOST_UBLAS_INLINE 01741 iterator &operator ++ () { 01742 ++ it1_; 01743 ++ it2_; 01744 return *this; 01745 } 01746 BOOST_UBLAS_INLINE 01747 iterator &operator -- () { 01748 -- it1_; 01749 -- it2_; 01750 return *this; 01751 } 01752 BOOST_UBLAS_INLINE 01753 iterator &operator += (difference_type n) { 01754 it1_ += n; 01755 it2_ += n; 01756 return *this; 01757 } 01758 BOOST_UBLAS_INLINE 01759 iterator &operator -= (difference_type n) { 01760 it1_ -= n; 01761 it2_ -= n; 01762 return *this; 01763 } 01764 BOOST_UBLAS_INLINE 01765 difference_type operator - (const iterator &it) const { 01766 BOOST_UBLAS_CHECK ((*this) ().same_closure (it ()), external_logic ()); 01767 return BOOST_UBLAS_SAME (it1_ - it.it1_, it2_ - it.it2_); 01768 } 01769 01770 // Dereference 01771 BOOST_UBLAS_INLINE 01772 reference operator * () const { 01773 // FIXME replace find with at_element 01774 return (*this) ().data_ (*it1_, *it2_); 01775 } 01776 BOOST_UBLAS_INLINE 01777 reference operator [] (difference_type n) const { 01778 return *(*this + n); 01779 } 01780 01781 // Index 01782 BOOST_UBLAS_INLINE 01783 size_type index () const { 01784 return BOOST_UBLAS_SAME (it1_.index (), it2_.index ()); 01785 } 01786 01787 // Assignment 01788 BOOST_UBLAS_INLINE 01789 iterator &operator = (const iterator &it) { 01790 container_reference<self_type>::assign (&it ()); 01791 it1_ = it.it1_; 01792 it2_ = it.it2_; 01793 return *this; 01794 } 01795 01796 // Comparison 01797 BOOST_UBLAS_INLINE 01798 bool operator == (const iterator &it) const { 01799 BOOST_UBLAS_CHECK ((*this) ().same_closure (it ()), external_logic ()); 01800 return it1_ == it.it1_ && it2_ == it.it2_; 01801 } 01802 BOOST_UBLAS_INLINE 01803 bool operator < (const iterator &it) const { 01804 BOOST_UBLAS_CHECK ((*this) ().same_closure (it ()), external_logic ()); 01805 return it1_ < it.it1_ && it2_ < it.it2_; 01806 } 01807 01808 private: 01809 subiterator1_type it1_; 01810 subiterator2_type it2_; 01811 01812 friend class const_iterator; 01813 }; 01814 01815 BOOST_UBLAS_INLINE 01816 iterator begin () { 01817 return find (0); 01818 } 01819 BOOST_UBLAS_INLINE 01820 iterator end () { 01821 return find (size ()); 01822 } 01823 01824 // Reverse iterator 01825 typedef reverse_iterator_base<const_iterator> const_reverse_iterator; 01826 typedef reverse_iterator_base<iterator> reverse_iterator; 01827 01828 BOOST_UBLAS_INLINE 01829 const_reverse_iterator rbegin () const { 01830 return const_reverse_iterator (end ()); 01831 } 01832 BOOST_UBLAS_INLINE 01833 const_reverse_iterator rend () const { 01834 return const_reverse_iterator (begin ()); 01835 } 01836 BOOST_UBLAS_INLINE 01837 reverse_iterator rbegin () { 01838 return reverse_iterator (end ()); 01839 } 01840 BOOST_UBLAS_INLINE 01841 reverse_iterator rend () { 01842 return reverse_iterator (begin ()); 01843 } 01844 01845 private: 01846 matrix_closure_type data_; 01847 slice_type s1_; 01848 slice_type s2_; 01849 }; 01850 01851 // Specialize temporary 01852 template <class M> 01853 struct vector_temporary_traits< matrix_vector_slice<M> > 01854 : vector_temporary_traits< M > {} ; 01855 template <class M> 01856 struct vector_temporary_traits< const matrix_vector_slice<M> > 01857 : vector_temporary_traits< M > {} ; 01858 01859 // Matrix based vector indirection class 01860 01861 template<class M, class IA> 01862 class matrix_vector_indirect: 01863 public vector_expression<matrix_vector_indirect<M, IA> > { 01864 01865 typedef matrix_vector_indirect<M, IA> self_type; 01866 public: 01867 #ifdef BOOST_UBLAS_ENABLE_PROXY_SHORTCUTS 01868 using vector_expression<self_type>::operator (); 01869 #endif 01870 typedef M matrix_type; 01871 typedef IA indirect_array_type; 01872 typedef typename M::size_type size_type; 01873 typedef typename M::difference_type difference_type; 01874 typedef typename M::value_type value_type; 01875 typedef typename M::const_reference const_reference; 01876 typedef typename boost::mpl::if_<boost::is_const<M>, 01877 typename M::const_reference, 01878 typename M::reference>::type reference; 01879 typedef typename boost::mpl::if_<boost::is_const<M>, 01880 typename M::const_closure_type, 01881 typename M::closure_type>::type matrix_closure_type; 01882 typedef const self_type const_closure_type; 01883 typedef self_type closure_type; 01884 typedef typename storage_restrict_traits<typename M::storage_category, 01885 dense_proxy_tag>::storage_category storage_category; 01886 01887 // Construction and destruction 01888 BOOST_UBLAS_INLINE 01889 matrix_vector_indirect (matrix_type &data, size_type size): 01890 data_ (data), ia1_ (size), ia2_ (size) {} 01891 BOOST_UBLAS_INLINE 01892 matrix_vector_indirect (matrix_type &data, const indirect_array_type &ia1, const indirect_array_type &ia2): 01893 data_ (data), ia1_ (ia1), ia2_ (ia2) { 01894 // Early checking of preconditions here. 01895 // BOOST_UBLAS_CHECK (ia1_.size () == ia2_.size (), bad_size ()); 01896 } 01897 01898 // Accessors 01899 BOOST_UBLAS_INLINE 01900 size_type size () const { 01901 return BOOST_UBLAS_SAME (ia1_.size (), ia2_.size ()); 01902 } 01903 BOOST_UBLAS_INLINE 01904 const indirect_array_type &indirect1 () const { 01905 return ia1_; 01906 } 01907 BOOST_UBLAS_INLINE 01908 indirect_array_type &indirect1 () { 01909 return ia1_; 01910 } 01911 BOOST_UBLAS_INLINE 01912 const indirect_array_type &indirect2 () const { 01913 return ia2_; 01914 } 01915 BOOST_UBLAS_INLINE 01916 indirect_array_type &indirect2 () { 01917 return ia2_; 01918 } 01919 01920 // Storage accessors 01921 BOOST_UBLAS_INLINE 01922 const matrix_closure_type &data () const { 01923 return data_; 01924 } 01925 BOOST_UBLAS_INLINE 01926 matrix_closure_type &data () { 01927 return data_; 01928 } 01929 01930 // Element access 01931 #ifndef BOOST_UBLAS_PROXY_CONST_MEMBER 01932 BOOST_UBLAS_INLINE 01933 const_reference operator () (size_type i) const { 01934 return data_ (ia1_ (i), ia2_ (i)); 01935 } 01936 BOOST_UBLAS_INLINE 01937 reference operator () (size_type i) { 01938 return data_ (ia1_ (i), ia2_ (i)); 01939 } 01940 01941 BOOST_UBLAS_INLINE 01942 const_reference operator [] (size_type i) const { 01943 return (*this) (i); 01944 } 01945 BOOST_UBLAS_INLINE 01946 reference operator [] (size_type i) { 01947 return (*this) (i); 01948 } 01949 #else 01950 BOOST_UBLAS_INLINE 01951 reference operator () (size_type i) const { 01952 return data_ (ia1_ (i), ia2_ (i)); 01953 } 01954 01955 BOOST_UBLAS_INLINE 01956 reference operator [] (size_type i) const { 01957 return (*this) (i); 01958 } 01959 #endif 01960 01961 // Assignment 01962 BOOST_UBLAS_INLINE 01963 matrix_vector_indirect &operator = (const matrix_vector_indirect &mvi) { 01964 // ISSUE need a temporary, proxy can be overlaping alias 01965 vector_assign<scalar_assign> (*this, typename vector_temporary_traits<M>::type (mvi)); 01966 return *this; 01967 } 01968 BOOST_UBLAS_INLINE 01969 matrix_vector_indirect &assign_temporary (matrix_vector_indirect &mvi) { 01970 // assign elements, proxied container remains the same 01971 vector_assign<scalar_assign> (*this, mvi); 01972 return *this; 01973 } 01974 template<class AE> 01975 BOOST_UBLAS_INLINE 01976 matrix_vector_indirect &operator = (const vector_expression<AE> &ae) { 01977 vector_assign<scalar_assign> (*this, typename vector_temporary_traits<M>::type (ae)); 01978 return *this; 01979 } 01980 template<class AE> 01981 BOOST_UBLAS_INLINE 01982 matrix_vector_indirect &assign (const vector_expression<AE> &ae) { 01983 vector_assign<scalar_assign> (*this, ae); 01984 return *this; 01985 } 01986 template<class AE> 01987 BOOST_UBLAS_INLINE 01988 matrix_vector_indirect &operator += (const vector_expression<AE> &ae) { 01989 vector_assign<scalar_assign> (*this, typename vector_temporary_traits<M>::type (*this + ae)); 01990 return *this; 01991 } 01992 template<class AE> 01993 BOOST_UBLAS_INLINE 01994 matrix_vector_indirect &plus_assign (const vector_expression<AE> &ae) { 01995 vector_assign<scalar_plus_assign> (*this, ae); 01996 return *this; 01997 } 01998 template<class AE> 01999 BOOST_UBLAS_INLINE 02000 matrix_vector_indirect &operator -= (const vector_expression<AE> &ae) { 02001 vector_assign<scalar_assign> (*this, typename vector_temporary_traits<M>::type (*this - ae)); 02002 return *this; 02003 } 02004 template<class AE> 02005 BOOST_UBLAS_INLINE 02006 matrix_vector_indirect &minus_assign (const vector_expression<AE> &ae) { 02007 vector_assign<scalar_minus_assign> (*this, ae); 02008 return *this; 02009 } 02010 template<class AT> 02011 BOOST_UBLAS_INLINE 02012 matrix_vector_indirect &operator *= (const AT &at) { 02013 vector_assign_scalar<scalar_multiplies_assign> (*this, at); 02014 return *this; 02015 } 02016 template<class AT> 02017 BOOST_UBLAS_INLINE 02018 matrix_vector_indirect &operator /= (const AT &at) { 02019 vector_assign_scalar<scalar_divides_assign> (*this, at); 02020 return *this; 02021 } 02022 02023 // Closure comparison 02024 BOOST_UBLAS_INLINE 02025 bool same_closure (const matrix_vector_indirect &mvi) const { 02026 return (*this).data_.same_closure (mvi.data_); 02027 } 02028 02029 // Comparison 02030 BOOST_UBLAS_INLINE 02031 bool operator == (const matrix_vector_indirect &mvi) const { 02032 return (*this).data_ == mvi.data_ && ia1_ == mvi.ia1_ && ia2_ == mvi.ia2_; 02033 } 02034 02035 // Swapping 02036 BOOST_UBLAS_INLINE 02037 void swap (matrix_vector_indirect mvi) { 02038 if (this != &mvi) { 02039 BOOST_UBLAS_CHECK (size () == mvi.size (), bad_size ()); 02040 // Sparse ranges may be nonconformant now. 02041 // std::swap_ranges (begin (), end (), mvi.begin ()); 02042 vector_swap<scalar_swap> (*this, mvi); 02043 } 02044 } 02045 BOOST_UBLAS_INLINE 02046 friend void swap (matrix_vector_indirect mvi1, matrix_vector_indirect mvi2) { 02047 mvi1.swap (mvi2); 02048 } 02049 02050 // Iterator types 02051 private: 02052 // Use indirect array as an index - FIXME this fails for packed assignment 02053 typedef typename IA::const_iterator const_subiterator1_type; 02054 typedef typename IA::const_iterator subiterator1_type; 02055 typedef typename IA::const_iterator const_subiterator2_type; 02056 typedef typename IA::const_iterator subiterator2_type; 02057 02058 public: 02059 class const_iterator; 02060 class iterator; 02061 02062 // Element lookup 02063 BOOST_UBLAS_INLINE 02064 const_iterator find (size_type i) const { 02065 return const_iterator (*this, ia1_.begin () + i, ia2_.begin () + i); 02066 } 02067 BOOST_UBLAS_INLINE 02068 iterator find (size_type i) { 02069 return iterator (*this, ia1_.begin () + i, ia2_.begin () + i); 02070 } 02071 02072 // Iterators simply are indices. 02073 02074 class const_iterator: 02075 public container_const_reference<matrix_vector_indirect>, 02076 public iterator_base_traits<typename M::const_iterator1::iterator_category>::template 02077 iterator_base<const_iterator, value_type>::type { 02078 public: 02079 // FIXME Iterator can never be different code was: 02080 // typename iterator_restrict_traits<typename M::const_iterator1::iterator_category, typename M::const_iterator2::iterator_category>::iterator_category> 02081 BOOST_STATIC_ASSERT ((boost::is_same<typename M::const_iterator1::iterator_category, typename M::const_iterator2::iterator_category>::value )); 02082 02083 typedef typename matrix_vector_indirect::value_type value_type; 02084 typedef typename matrix_vector_indirect::difference_type difference_type; 02085 typedef typename matrix_vector_indirect::const_reference reference; 02086 typedef const typename matrix_vector_indirect::value_type *pointer; 02087 02088 // Construction and destruction 02089 BOOST_UBLAS_INLINE 02090 const_iterator (): 02091 container_const_reference<self_type> (), it1_ (), it2_ () {} 02092 BOOST_UBLAS_INLINE 02093 const_iterator (const self_type &mvi, const const_subiterator1_type &it1, const const_subiterator2_type &it2): 02094 container_const_reference<self_type> (mvi), it1_ (it1), it2_ (it2) {} 02095 BOOST_UBLAS_INLINE 02096 const_iterator (const typename self_type::iterator &it): // ISSUE self_type:: stops VC8 using std::iterator here 02097 container_const_reference<self_type> (it ()), it1_ (it.it1_), it2_ (it.it2_) {} 02098 02099 // Arithmetic 02100 BOOST_UBLAS_INLINE 02101 const_iterator &operator ++ () { 02102 ++ it1_; 02103 ++ it2_; 02104 return *this; 02105 } 02106 BOOST_UBLAS_INLINE 02107 const_iterator &operator -- () { 02108 -- it1_; 02109 -- it2_; 02110 return *this; 02111 } 02112 BOOST_UBLAS_INLINE 02113 const_iterator &operator += (difference_type n) { 02114 it1_ += n; 02115 it2_ += n; 02116 return *this; 02117 } 02118 BOOST_UBLAS_INLINE 02119 const_iterator &operator -= (difference_type n) { 02120 it1_ -= n; 02121 it2_ -= n; 02122 return *this; 02123 } 02124 BOOST_UBLAS_INLINE 02125 difference_type operator - (const const_iterator &it) const { 02126 BOOST_UBLAS_CHECK ((*this) ().same_closure (it ()), external_logic ()); 02127 return BOOST_UBLAS_SAME (it1_ - it.it1_, it2_ - it.it2_); 02128 } 02129 02130 // Dereference 02131 BOOST_UBLAS_INLINE 02132 const_reference operator * () const { 02133 // FIXME replace find with at_element 02134 return (*this) ().data_ (*it1_, *it2_); 02135 } 02136 BOOST_UBLAS_INLINE 02137 const_reference operator [] (difference_type n) const { 02138 return *(*this + n); 02139 } 02140 02141 // Index 02142 BOOST_UBLAS_INLINE 02143 size_type index () const { 02144 return BOOST_UBLAS_SAME (it1_.index (), it2_.index ()); 02145 } 02146 02147 // Assignment 02148 BOOST_UBLAS_INLINE 02149 const_iterator &operator = (const const_iterator &it) { 02150 container_const_reference<self_type>::assign (&it ()); 02151 it1_ = it.it1_; 02152 it2_ = it.it2_; 02153 return *this; 02154 } 02155 02156 // Comparison 02157 BOOST_UBLAS_INLINE 02158 bool operator == (const const_iterator &it) const { 02159 BOOST_UBLAS_CHECK ((*this) ().same_closure (it ()), external_logic ()); 02160 return it1_ == it.it1_ && it2_ == it.it2_; 02161 } 02162 BOOST_UBLAS_INLINE 02163 bool operator < (const const_iterator &it) const { 02164 BOOST_UBLAS_CHECK ((*this) ().same_closure (it ()), external_logic ()); 02165 return it1_ < it.it1_ && it2_ < it.it2_; 02166 } 02167 02168 private: 02169 const_subiterator1_type it1_; 02170 const_subiterator2_type it2_; 02171 }; 02172 02173 BOOST_UBLAS_INLINE 02174 const_iterator begin () const { 02175 return find (0); 02176 } 02177 BOOST_UBLAS_INLINE 02178 const_iterator end () const { 02179 return find (size ()); 02180 } 02181 02182 class iterator: 02183 public container_reference<matrix_vector_indirect>, 02184 public iterator_base_traits<typename M::iterator1::iterator_category>::template 02185 iterator_base<iterator, value_type>::type { 02186 public: 02187 // FIXME Iterator can never be different code was: 02188 // typename iterator_restrict_traits<typename M::const_iterator1::iterator_category, typename M::const_iterator2::iterator_category>::iterator_category> 02189 BOOST_STATIC_ASSERT ((boost::is_same<typename M::const_iterator1::iterator_category, typename M::const_iterator2::iterator_category>::value )); 02190 02191 typedef typename matrix_vector_indirect::value_type value_type; 02192 typedef typename matrix_vector_indirect::difference_type difference_type; 02193 typedef typename matrix_vector_indirect::reference reference; 02194 typedef typename matrix_vector_indirect::value_type *pointer; 02195 02196 // Construction and destruction 02197 BOOST_UBLAS_INLINE 02198 iterator (): 02199 container_reference<self_type> (), it1_ (), it2_ () {} 02200 BOOST_UBLAS_INLINE 02201 iterator (self_type &mvi, const subiterator1_type &it1, const subiterator2_type &it2): 02202 container_reference<self_type> (mvi), it1_ (it1), it2_ (it2) {} 02203 02204 // Arithmetic 02205 BOOST_UBLAS_INLINE 02206 iterator &operator ++ () { 02207 ++ it1_; 02208 ++ it2_; 02209 return *this; 02210 } 02211 BOOST_UBLAS_INLINE 02212 iterator &operator -- () { 02213 -- it1_; 02214 -- it2_; 02215 return *this; 02216 } 02217 BOOST_UBLAS_INLINE 02218 iterator &operator += (difference_type n) { 02219 it1_ += n; 02220 it2_ += n; 02221 return *this; 02222 } 02223 BOOST_UBLAS_INLINE 02224 iterator &operator -= (difference_type n) { 02225 it1_ -= n; 02226 it2_ -= n; 02227 return *this; 02228 } 02229 BOOST_UBLAS_INLINE 02230 difference_type operator - (const iterator &it) const { 02231 BOOST_UBLAS_CHECK ((*this) ().same_closure (it ()), external_logic ()); 02232 return BOOST_UBLAS_SAME (it1_ - it.it1_, it2_ - it.it2_); 02233 } 02234 02235 // Dereference 02236 BOOST_UBLAS_INLINE 02237 reference operator * () const { 02238 // FIXME replace find with at_element 02239 return (*this) ().data_ (*it1_, *it2_); 02240 } 02241 BOOST_UBLAS_INLINE 02242 reference operator [] (difference_type n) const { 02243 return *(*this + n); 02244 } 02245 02246 // Index 02247 BOOST_UBLAS_INLINE 02248 size_type index () const { 02249 return BOOST_UBLAS_SAME (it1_.index (), it2_.index ()); 02250 } 02251 02252 // Assignment 02253 BOOST_UBLAS_INLINE 02254 iterator &operator = (const iterator &it) { 02255 container_reference<self_type>::assign (&it ()); 02256 it1_ = it.it1_; 02257 it2_ = it.it2_; 02258 return *this; 02259 } 02260 02261 // Comparison 02262 BOOST_UBLAS_INLINE 02263 bool operator == (const iterator &it) const { 02264 BOOST_UBLAS_CHECK ((*this) ().same_closure (it ()), external_logic ()); 02265 return it1_ == it.it1_ && it2_ == it.it2_; 02266 } 02267 BOOST_UBLAS_INLINE 02268 bool operator < (const iterator &it) const { 02269 BOOST_UBLAS_CHECK ((*this) ().same_closure (it ()), external_logic ()); 02270 return it1_ < it.it1_ && it2_ < it.it2_; 02271 } 02272 02273 private: 02274 subiterator1_type it1_; 02275 subiterator2_type it2_; 02276 02277 friend class const_iterator; 02278 }; 02279 02280 BOOST_UBLAS_INLINE 02281 iterator begin () { 02282 return find (0); 02283 } 02284 BOOST_UBLAS_INLINE 02285 iterator end () { 02286 return find (size ()); 02287 } 02288 02289 // Reverse iterator 02290 typedef reverse_iterator_base<const_iterator> const_reverse_iterator; 02291 typedef reverse_iterator_base<iterator> reverse_iterator; 02292 02293 BOOST_UBLAS_INLINE 02294 const_reverse_iterator rbegin () const { 02295 return const_reverse_iterator (end ()); 02296 } 02297 BOOST_UBLAS_INLINE 02298 const_reverse_iterator rend () const { 02299 return const_reverse_iterator (begin ()); 02300 } 02301 BOOST_UBLAS_INLINE 02302 reverse_iterator rbegin () { 02303 return reverse_iterator (end ()); 02304 } 02305 BOOST_UBLAS_INLINE 02306 reverse_iterator rend () { 02307 return reverse_iterator (begin ()); 02308 } 02309 02310 private: 02311 matrix_closure_type data_; 02312 indirect_array_type ia1_; 02313 indirect_array_type ia2_; 02314 }; 02315 02316 // Specialize temporary 02317 template <class M, class IA> 02318 struct vector_temporary_traits< matrix_vector_indirect<M,IA> > 02319 : vector_temporary_traits< M > {} ; 02320 template <class M, class IA> 02321 struct vector_temporary_traits< const matrix_vector_indirect<M,IA> > 02322 : vector_temporary_traits< M > {} ; 02323 02324 // Matrix based range class 02325 template<class M> 02326 class matrix_range: 02327 public matrix_expression<matrix_range<M> > { 02328 02329 typedef matrix_range<M> self_type; 02330 public: 02331 #ifdef BOOST_UBLAS_ENABLE_PROXY_SHORTCUTS 02332 using matrix_expression<self_type>::operator (); 02333 #endif 02334 typedef M matrix_type; 02335 typedef typename M::size_type size_type; 02336 typedef typename M::difference_type difference_type; 02337 typedef typename M::value_type value_type; 02338 typedef typename M::const_reference const_reference; 02339 typedef typename boost::mpl::if_<boost::is_const<M>, 02340 typename M::const_reference, 02341 typename M::reference>::type reference; 02342 typedef typename boost::mpl::if_<boost::is_const<M>, 02343 typename M::const_closure_type, 02344 typename M::closure_type>::type matrix_closure_type; 02345 typedef basic_range<size_type, difference_type> range_type; 02346 typedef const self_type const_closure_type; 02347 typedef self_type closure_type; 02348 typedef typename storage_restrict_traits<typename M::storage_category, 02349 dense_proxy_tag>::storage_category storage_category; 02350 typedef typename M::orientation_category orientation_category; 02351 02352 // Construction and destruction 02353 BOOST_UBLAS_INLINE 02354 matrix_range (matrix_type &data, const range_type &r1, const range_type &r2): 02355 data_ (data), r1_ (r1.preprocess (data.size1 ())), r2_ (r2.preprocess (data.size2 ())) { 02356 // Early checking of preconditions here. 02357 // BOOST_UBLAS_CHECK (r1_.start () <= data_.size1 () && 02358 // r1_.start () + r1_.size () <= data_.size1 (), bad_index ()); 02359 // BOOST_UBLAS_CHECK (r2_.start () <= data_.size2 () && 02360 // r2_.start () + r2_.size () <= data_.size2 (), bad_index ()); 02361 } 02362 BOOST_UBLAS_INLINE 02363 matrix_range (const matrix_closure_type &data, const range_type &r1, const range_type &r2, int): 02364 data_ (data), r1_ (r1.preprocess (data.size1 ())), r2_ (r2.preprocess (data.size2 ())) { 02365 // Early checking of preconditions here. 02366 // BOOST_UBLAS_CHECK (r1_.start () <= data_.size1 () && 02367 // r1_.start () + r1_.size () <= data_.size1 (), bad_index ()); 02368 // BOOST_UBLAS_CHECK (r2_.start () <= data_.size2 () && 02369 // r2_.start () + r2_.size () <= data_.size2 (), bad_index ()); 02370 } 02371 02372 // Accessors 02373 BOOST_UBLAS_INLINE 02374 size_type start1 () const { 02375 return r1_.start (); 02376 } 02377 BOOST_UBLAS_INLINE 02378 size_type size1 () const { 02379 return r1_.size (); 02380 } 02381 BOOST_UBLAS_INLINE 02382 size_type start2() const { 02383 return r2_.start (); 02384 } 02385 BOOST_UBLAS_INLINE 02386 size_type size2 () const { 02387 return r2_.size (); 02388 } 02389 02390 // Storage accessors 02391 BOOST_UBLAS_INLINE 02392 const matrix_closure_type &data () const { 02393 return data_; 02394 } 02395 BOOST_UBLAS_INLINE 02396 matrix_closure_type &data () { 02397 return data_; 02398 } 02399 02400 // Element access 02401 #ifndef BOOST_UBLAS_PROXY_CONST_MEMBER 02402 BOOST_UBLAS_INLINE 02403 const_reference operator () (size_type i, size_type j) const { 02404 return data_ (r1_ (i), r2_ (j)); 02405 } 02406 BOOST_UBLAS_INLINE 02407 reference operator () (size_type i, size_type j) { 02408 return data_ (r1_ (i), r2_ (j)); 02409 } 02410 #else 02411 BOOST_UBLAS_INLINE 02412 reference operator () (size_type i, size_type j) const { 02413 return data_ (r1_ (i), r2_ (j)); 02414 } 02415 #endif 02416 02417 // ISSUE can this be done in free project function? 02418 // Although a const function can create a non-const proxy to a non-const object 02419 // Critical is that matrix_type and data_ (vector_closure_type) are const correct 02420 BOOST_UBLAS_INLINE 02421 matrix_range<matrix_type> project (const range_type &r1, const range_type &r2) const { 02422 return matrix_range<matrix_type> (data_, r1_.compose (r1.preprocess (data_.size1 ())), r2_.compose (r2.preprocess (data_.size2 ())), 0); 02423 } 02424 02425 // Assignment 02426 BOOST_UBLAS_INLINE 02427 matrix_range &operator = (const matrix_range &mr) { 02428 matrix_assign<scalar_assign> (*this, mr); 02429 return *this; 02430 } 02431 BOOST_UBLAS_INLINE 02432 matrix_range &assign_temporary (matrix_range &mr) { 02433 return *this = mr; 02434 } 02435 template<class AE> 02436 BOOST_UBLAS_INLINE 02437 matrix_range &operator = (const matrix_expression<AE> &ae) { 02438 matrix_assign<scalar_assign> (*this, typename matrix_temporary_traits<M>::type (ae)); 02439 return *this; 02440 } 02441 template<class AE> 02442 BOOST_UBLAS_INLINE 02443 matrix_range &assign (const matrix_expression<AE> &ae) { 02444 matrix_assign<scalar_assign> (*this, ae); 02445 return *this; 02446 } 02447 template<class AE> 02448 BOOST_UBLAS_INLINE 02449 matrix_range& operator += (const matrix_expression<AE> &ae) { 02450 matrix_assign<scalar_assign> (*this, typename matrix_temporary_traits<M>::type (*this + ae)); 02451 return *this; 02452 } 02453 template<class AE> 02454 BOOST_UBLAS_INLINE 02455 matrix_range &plus_assign (const matrix_expression<AE> &ae) { 02456 matrix_assign<scalar_plus_assign> (*this, ae); 02457 return *this; 02458 } 02459 template<class AE> 02460 BOOST_UBLAS_INLINE 02461 matrix_range& operator -= (const matrix_expression<AE> &ae) { 02462 matrix_assign<scalar_assign> (*this, typename matrix_temporary_traits<M>::type (*this - ae)); 02463 return *this; 02464 } 02465 template<class AE> 02466 BOOST_UBLAS_INLINE 02467 matrix_range &minus_assign (const matrix_expression<AE> &ae) { 02468 matrix_assign<scalar_minus_assign> (*this, ae); 02469 return *this; 02470 } 02471 template<class AT> 02472 BOOST_UBLAS_INLINE 02473 matrix_range& operator *= (const AT &at) { 02474 matrix_assign_scalar<scalar_multiplies_assign> (*this, at); 02475 return *this; 02476 } 02477 template<class AT> 02478 BOOST_UBLAS_INLINE 02479 matrix_range& operator /= (const AT &at) { 02480 matrix_assign_scalar<scalar_divides_assign> (*this, at); 02481 return *this; 02482 } 02483 02484 // Closure comparison 02485 BOOST_UBLAS_INLINE 02486 bool same_closure (const matrix_range &mr) const { 02487 return (*this).data_.same_closure (mr.data_); 02488 } 02489 02490 // Comparison 02491 BOOST_UBLAS_INLINE 02492 bool operator == (const matrix_range &mr) const { 02493 return (*this).data_ == (mr.data_) && r1_ == mr.r1_ && r2_ == mr.r2_; 02494 } 02495 02496 // Swapping 02497 BOOST_UBLAS_INLINE 02498 void swap (matrix_range mr) { 02499 if (this != &mr) { 02500 BOOST_UBLAS_CHECK (size1 () == mr.size1 (), bad_size ()); 02501 BOOST_UBLAS_CHECK (size2 () == mr.size2 (), bad_size ()); 02502 matrix_swap<scalar_swap> (*this, mr); 02503 } 02504 } 02505 BOOST_UBLAS_INLINE 02506 friend void swap (matrix_range mr1, matrix_range mr2) { 02507 mr1.swap (mr2); 02508 } 02509 02510 // Iterator types 02511 private: 02512 typedef typename M::const_iterator1 const_subiterator1_type; 02513 typedef typename boost::mpl::if_<boost::is_const<M>, 02514 typename M::const_iterator1, 02515 typename M::iterator1>::type subiterator1_type; 02516 typedef typename M::const_iterator2 const_subiterator2_type; 02517 typedef typename boost::mpl::if_<boost::is_const<M>, 02518 typename M::const_iterator2, 02519 typename M::iterator2>::type subiterator2_type; 02520 02521 public: 02522 #ifdef BOOST_UBLAS_USE_INDEXED_ITERATOR 02523 typedef indexed_iterator1<matrix_range<matrix_type>, 02524 typename subiterator1_type::iterator_category> iterator1; 02525 typedef indexed_iterator2<matrix_range<matrix_type>, 02526 typename subiterator2_type::iterator_category> iterator2; 02527 typedef indexed_const_iterator1<matrix_range<matrix_type>, 02528 typename const_subiterator1_type::iterator_category> const_iterator1; 02529 typedef indexed_const_iterator2<matrix_range<matrix_type>, 02530 typename const_subiterator2_type::iterator_category> const_iterator2; 02531 #else 02532 class const_iterator1; 02533 class iterator1; 02534 class const_iterator2; 02535 class iterator2; 02536 #endif 02537 typedef reverse_iterator_base1<const_iterator1> const_reverse_iterator1; 02538 typedef reverse_iterator_base1<iterator1> reverse_iterator1; 02539 typedef reverse_iterator_base2<const_iterator2> const_reverse_iterator2; 02540 typedef reverse_iterator_base2<iterator2> reverse_iterator2; 02541 02542 // Element lookup 02543 BOOST_UBLAS_INLINE 02544 const_iterator1 find1 (int rank, size_type i, size_type j) const { 02545 const_subiterator1_type it1 (data_.find1 (rank, start1 () + i, start2 () + j)); 02546 #ifdef BOOST_UBLAS_USE_INDEXED_ITERATOR 02547 return const_iterator1 (*this, it1.index1 (), it1.index2 ()); 02548 #else 02549 return const_iterator1 (*this, it1); 02550 #endif 02551 } 02552 BOOST_UBLAS_INLINE 02553 iterator1 find1 (int rank, size_type i, size_type j) { 02554 subiterator1_type it1 (data_.find1 (rank, start1 () + i, start2 () + j)); 02555 #ifdef BOOST_UBLAS_USE_INDEXED_ITERATOR 02556 return iterator1 (*this, it1.index1 (), it1.index2 ()); 02557 #else 02558 return iterator1 (*this, it1); 02559 #endif 02560 } 02561 BOOST_UBLAS_INLINE 02562 const_iterator2 find2 (int rank, size_type i, size_type j) const { 02563 const_subiterator2_type it2 (data_.find2 (rank, start1 () + i, start2 () + j)); 02564 #ifdef BOOST_UBLAS_USE_INDEXED_ITERATOR 02565 return const_iterator2 (*this, it2.index1 (), it2.index2 ()); 02566 #else 02567 return const_iterator2 (*this, it2); 02568 #endif 02569 } 02570 BOOST_UBLAS_INLINE 02571 iterator2 find2 (int rank, size_type i, size_type j) { 02572 subiterator2_type it2 (data_.find2 (rank, start1 () + i, start2 () + j)); 02573 #ifdef BOOST_UBLAS_USE_INDEXED_ITERATOR 02574 return iterator2 (*this, it2.index1 (), it2.index2 ()); 02575 #else 02576 return iterator2 (*this, it2); 02577 #endif 02578 } 02579 02580 02581 #ifndef BOOST_UBLAS_USE_INDEXED_ITERATOR 02582 class const_iterator1: 02583 public container_const_reference<matrix_range>, 02584 public iterator_base_traits<typename const_subiterator1_type::iterator_category>::template 02585 iterator_base<const_iterator1, value_type>::type { 02586 public: 02587 typedef typename const_subiterator1_type::value_type value_type; 02588 typedef typename const_subiterator1_type::difference_type difference_type; 02589 typedef typename const_subiterator1_type::reference reference; 02590 typedef typename const_subiterator1_type::pointer pointer; 02591 typedef const_iterator2 dual_iterator_type; 02592 typedef const_reverse_iterator2 dual_reverse_iterator_type; 02593 02594 // Construction and destruction 02595 BOOST_UBLAS_INLINE 02596 const_iterator1 (): 02597 container_const_reference<self_type> (), it_ () {} 02598 BOOST_UBLAS_INLINE 02599 const_iterator1 (const self_type &mr, const const_subiterator1_type &it): 02600 container_const_reference<self_type> (mr), it_ (it) {} 02601 BOOST_UBLAS_INLINE 02602 const_iterator1 (const iterator1 &it): 02603 container_const_reference<self_type> (it ()), it_ (it.it_) {} 02604 02605 // Arithmetic 02606 BOOST_UBLAS_INLINE 02607 const_iterator1 &operator ++ () { 02608 ++ it_; 02609 return *this; 02610 } 02611 BOOST_UBLAS_INLINE 02612 const_iterator1 &operator -- () { 02613 -- it_; 02614 return *this; 02615 } 02616 BOOST_UBLAS_INLINE 02617 const_iterator1 &operator += (difference_type n) { 02618 it_ += n; 02619 return *this; 02620 } 02621 BOOST_UBLAS_INLINE 02622 const_iterator1 &operator -= (difference_type n) { 02623 it_ -= n; 02624 return *this; 02625 } 02626 BOOST_UBLAS_INLINE 02627 difference_type operator - (const const_iterator1 &it) const { 02628 BOOST_UBLAS_CHECK ((*this) ().same_closure (it ()), external_logic ()); 02629 return it_ - it.it_; 02630 } 02631 02632 // Dereference 02633 BOOST_UBLAS_INLINE 02634 const_reference operator * () const { 02635 return *it_; 02636 } 02637 BOOST_UBLAS_INLINE 02638 const_reference operator [] (difference_type n) const { 02639 return *(*this + n); 02640 } 02641 02642 #ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION 02643 BOOST_UBLAS_INLINE 02644 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION 02645 typename self_type:: 02646 #endif 02647 const_iterator2 begin () const { 02648 const self_type &mr = (*this) (); 02649 return mr.find2 (1, index1 (), 0); 02650 } 02651 BOOST_UBLAS_INLINE 02652 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION 02653 typename self_type:: 02654 #endif 02655 const_iterator2 end () const { 02656 const self_type &mr = (*this) (); 02657 return mr.find2 (1, index1 (), mr.size2 ()); 02658 } 02659 BOOST_UBLAS_INLINE 02660 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION 02661 typename self_type:: 02662 #endif 02663 const_reverse_iterator2 rbegin () const { 02664 return const_reverse_iterator2 (end ()); 02665 } 02666 BOOST_UBLAS_INLINE 02667 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION 02668 typename self_type:: 02669 #endif 02670 const_reverse_iterator2 rend () const { 02671 return const_reverse_iterator2 (begin ()); 02672 } 02673 #endif 02674 02675 // Indices 02676 BOOST_UBLAS_INLINE 02677 size_type index1 () const { 02678 return it_.index1 () - (*this) ().start1 (); 02679 } 02680 BOOST_UBLAS_INLINE 02681 size_type index2 () const { 02682 return it_.index2 () - (*this) ().start2 (); 02683 } 02684 02685 // Assignment 02686 BOOST_UBLAS_INLINE 02687 const_iterator1 &operator = (const const_iterator1 &it) { 02688 container_const_reference<self_type>::assign (&it ()); 02689 it_ = it.it_; 02690 return *this; 02691 } 02692 02693 // Comparison 02694 BOOST_UBLAS_INLINE 02695 bool operator == (const const_iterator1 &it) const { 02696 BOOST_UBLAS_CHECK ((*this) ().same_closure (it ()), external_logic ()); 02697 return it_ == it.it_; 02698 } 02699 BOOST_UBLAS_INLINE 02700 bool operator < (const const_iterator1 &it) const { 02701 BOOST_UBLAS_CHECK ((*this) ().same_closure (it ()), external_logic ()); 02702 return it_ < it.it_; 02703 } 02704 02705 private: 02706 const_subiterator1_type it_; 02707 }; 02708 #endif 02709 02710 BOOST_UBLAS_INLINE 02711 const_iterator1 begin1 () const { 02712 return find1 (0, 0, 0); 02713 } 02714 BOOST_UBLAS_INLINE 02715 const_iterator1 end1 () const { 02716 return find1 (0, size1 (), 0); 02717 } 02718 02719 #ifndef BOOST_UBLAS_USE_INDEXED_ITERATOR 02720 class iterator1: 02721 public container_reference<matrix_range>, 02722 public iterator_base_traits<typename subiterator1_type::iterator_category>::template 02723 iterator_base<iterator1, value_type>::type { 02724 public: 02725 typedef typename subiterator1_type::value_type value_type; 02726 typedef typename subiterator1_type::difference_type difference_type; 02727 typedef typename subiterator1_type::reference reference; 02728 typedef typename subiterator1_type::pointer pointer; 02729 typedef iterator2 dual_iterator_type; 02730 typedef reverse_iterator2 dual_reverse_iterator_type; 02731 02732 // Construction and destruction 02733 BOOST_UBLAS_INLINE 02734 iterator1 (): 02735 container_reference<self_type> (), it_ () {} 02736 BOOST_UBLAS_INLINE 02737 iterator1 (self_type &mr, const subiterator1_type &it): 02738 container_reference<self_type> (mr), it_ (it) {} 02739 02740 // Arithmetic 02741 BOOST_UBLAS_INLINE 02742 iterator1 &operator ++ () { 02743 ++ it_; 02744 return *this; 02745 } 02746 BOOST_UBLAS_INLINE 02747 iterator1 &operator -- () { 02748 -- it_; 02749 return *this; 02750 } 02751 BOOST_UBLAS_INLINE 02752 iterator1 &operator += (difference_type n) { 02753 it_ += n; 02754 return *this; 02755 } 02756 BOOST_UBLAS_INLINE 02757 iterator1 &operator -= (difference_type n) { 02758 it_ -= n; 02759 return *this; 02760 } 02761 BOOST_UBLAS_INLINE 02762 difference_type operator - (const iterator1 &it) const { 02763 BOOST_UBLAS_CHECK ((*this) ().same_closure (it ()), external_logic ()); 02764 return it_ - it.it_; 02765 } 02766 02767 // Dereference 02768 BOOST_UBLAS_INLINE 02769 reference operator * () const { 02770 return *it_; 02771 } 02772 BOOST_UBLAS_INLINE 02773 reference operator [] (difference_type n) const { 02774 return *(*this + n); 02775 } 02776 02777 #ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION 02778 BOOST_UBLAS_INLINE 02779 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION 02780 typename self_type:: 02781 #endif 02782 iterator2 begin () const { 02783 self_type &mr = (*this) (); 02784 return mr.find2 (1, index1 (), 0); 02785 } 02786 BOOST_UBLAS_INLINE 02787 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION 02788 typename self_type:: 02789 #endif 02790 iterator2 end () const { 02791 self_type &mr = (*this) (); 02792 return mr.find2 (1, index1 (), mr.size2 ()); 02793 } 02794 BOOST_UBLAS_INLINE 02795 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION 02796 typename self_type:: 02797 #endif 02798 reverse_iterator2 rbegin () const { 02799 return reverse_iterator2 (end ()); 02800 } 02801 BOOST_UBLAS_INLINE 02802 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION 02803 typename self_type:: 02804 #endif 02805 reverse_iterator2 rend () const { 02806 return reverse_iterator2 (begin ()); 02807 } 02808 #endif 02809 02810 // Indices 02811 BOOST_UBLAS_INLINE 02812 size_type index1 () const { 02813 return it_.index1 () - (*this) ().start1 (); 02814 } 02815 BOOST_UBLAS_INLINE 02816 size_type index2 () const { 02817 return it_.index2 () - (*this) ().start2 (); 02818 } 02819 02820 // Assignment 02821 BOOST_UBLAS_INLINE 02822 iterator1 &operator = (const iterator1 &it) { 02823 container_reference<self_type>::assign (&it ()); 02824 it_ = it.it_; 02825 return *this; 02826 } 02827 02828 // Comparison 02829 BOOST_UBLAS_INLINE 02830 bool operator == (const iterator1 &it) const { 02831 BOOST_UBLAS_CHECK ((*this) ().same_closure (it ()), external_logic ()); 02832 return it_ == it.it_; 02833 } 02834 BOOST_UBLAS_INLINE 02835 bool operator < (const iterator1 &it) const { 02836 BOOST_UBLAS_CHECK ((*this) ().same_closure (it ()), external_logic ()); 02837 return it_ < it.it_; 02838 } 02839 02840 private: 02841 subiterator1_type it_; 02842 02843 friend class const_iterator1; 02844 }; 02845 #endif 02846 02847 BOOST_UBLAS_INLINE 02848 iterator1 begin1 () { 02849 return find1 (0, 0, 0); 02850 } 02851 BOOST_UBLAS_INLINE 02852 iterator1 end1 () { 02853 return find1 (0, size1 (), 0); 02854 } 02855 02856 #ifndef BOOST_UBLAS_USE_INDEXED_ITERATOR 02857 class const_iterator2: 02858 public container_const_reference<matrix_range>, 02859 public iterator_base_traits<typename const_subiterator2_type::iterator_category>::template 02860 iterator_base<const_iterator2, value_type>::type { 02861 public: 02862 typedef typename const_subiterator2_type::value_type value_type; 02863 typedef typename const_subiterator2_type::difference_type difference_type; 02864 typedef typename const_subiterator2_type::reference reference; 02865 typedef typename const_subiterator2_type::pointer pointer; 02866 typedef const_iterator1 dual_iterator_type; 02867 typedef const_reverse_iterator1 dual_reverse_iterator_type; 02868 02869 // Construction and destruction 02870 BOOST_UBLAS_INLINE 02871 const_iterator2 (): 02872 container_const_reference<self_type> (), it_ () {} 02873 BOOST_UBLAS_INLINE 02874 const_iterator2 (const self_type &mr, const const_subiterator2_type &it): 02875 container_const_reference<self_type> (mr), it_ (it) {} 02876 BOOST_UBLAS_INLINE 02877 const_iterator2 (const iterator2 &it): 02878 container_const_reference<self_type> (it ()), it_ (it.it_) {} 02879 02880 // Arithmetic 02881 BOOST_UBLAS_INLINE 02882 const_iterator2 &operator ++ () { 02883 ++ it_; 02884 return *this; 02885 } 02886 BOOST_UBLAS_INLINE 02887 const_iterator2 &operator -- () { 02888 -- it_; 02889 return *this; 02890 } 02891 BOOST_UBLAS_INLINE 02892 const_iterator2 &operator += (difference_type n) { 02893 it_ += n; 02894 return *this; 02895 } 02896 BOOST_UBLAS_INLINE 02897 const_iterator2 &operator -= (difference_type n) { 02898 it_ -= n; 02899 return *this; 02900 } 02901 BOOST_UBLAS_INLINE 02902 difference_type operator - (const const_iterator2 &it) const { 02903 BOOST_UBLAS_CHECK ((*this) ().same_closure (it ()), external_logic ()); 02904 return it_ - it.it_; 02905 } 02906 02907 // Dereference 02908 BOOST_UBLAS_INLINE 02909 const_reference operator * () const { 02910 return *it_; 02911 } 02912 BOOST_UBLAS_INLINE 02913 const_reference operator [] (difference_type n) const { 02914 return *(*this + n); 02915 } 02916 02917 #ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION 02918 BOOST_UBLAS_INLINE 02919 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION 02920 typename self_type:: 02921 #endif 02922 const_iterator1 begin () const { 02923 const self_type &mr = (*this) (); 02924 return mr.find1 (1, 0, index2 ()); 02925 } 02926 BOOST_UBLAS_INLINE 02927 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION 02928 typename self_type:: 02929 #endif 02930 const_iterator1 end () const { 02931 const self_type &mr = (*this) (); 02932 return mr.find1 (1, mr.size1 (), index2 ()); 02933 } 02934 BOOST_UBLAS_INLINE 02935 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION 02936 typename self_type:: 02937 #endif 02938 const_reverse_iterator1 rbegin () const { 02939 return const_reverse_iterator1 (end ()); 02940 } 02941 BOOST_UBLAS_INLINE 02942 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION 02943 typename self_type:: 02944 #endif 02945 const_reverse_iterator1 rend () const { 02946 return const_reverse_iterator1 (begin ()); 02947 } 02948 #endif 02949 02950 // Indices 02951 BOOST_UBLAS_INLINE 02952 size_type index1 () const { 02953 return it_.index1 () - (*this) ().start1 (); 02954 } 02955 BOOST_UBLAS_INLINE 02956 size_type index2 () const { 02957 return it_.index2 () - (*this) ().start2 (); 02958 } 02959 02960 // Assignment 02961 BOOST_UBLAS_INLINE 02962 const_iterator2 &operator = (const const_iterator2 &it) { 02963 container_const_reference<self_type>::assign (&it ()); 02964 it_ = it.it_; 02965 return *this; 02966 } 02967 02968 // Comparison 02969 BOOST_UBLAS_INLINE 02970 bool operator == (const const_iterator2 &it) const { 02971 BOOST_UBLAS_CHECK ((*this) ().same_closure (it ()), external_logic ()); 02972 return it_ == it.it_; 02973 } 02974 BOOST_UBLAS_INLINE 02975 bool operator < (const const_iterator2 &it) const { 02976 BOOST_UBLAS_CHECK ((*this) ().same_closure (it ()), external_logic ()); 02977 return it_ < it.it_; 02978 } 02979 02980 private: 02981 const_subiterator2_type it_; 02982 }; 02983 #endif 02984 02985 BOOST_UBLAS_INLINE 02986 const_iterator2 begin2 () const { 02987 return find2 (0, 0, 0); 02988 } 02989 BOOST_UBLAS_INLINE 02990 const_iterator2 end2 () const { 02991 return find2 (0, 0, size2 ()); 02992 } 02993 02994 #ifndef BOOST_UBLAS_USE_INDEXED_ITERATOR 02995 class iterator2: 02996 public container_reference<matrix_range>, 02997 public iterator_base_traits<typename subiterator2_type::iterator_category>::template 02998 iterator_base<iterator2, value_type>::type { 02999 public: 03000 typedef typename subiterator2_type::value_type value_type; 03001 typedef typename subiterator2_type::difference_type difference_type; 03002 typedef typename subiterator2_type::reference reference; 03003 typedef typename subiterator2_type::pointer pointer; 03004 typedef iterator1 dual_iterator_type; 03005 typedef reverse_iterator1 dual_reverse_iterator_type; 03006 03007 // Construction and destruction 03008 BOOST_UBLAS_INLINE 03009 iterator2 (): 03010 container_reference<self_type> (), it_ () {} 03011 BOOST_UBLAS_INLINE 03012 iterator2 (self_type &mr, const subiterator2_type &it): 03013 container_reference<self_type> (mr), it_ (it) {} 03014 03015 // Arithmetic 03016 BOOST_UBLAS_INLINE 03017 iterator2 &operator ++ () { 03018 ++ it_; 03019 return *this; 03020 } 03021 BOOST_UBLAS_INLINE 03022 iterator2 &operator -- () { 03023 -- it_; 03024 return *this; 03025 } 03026 BOOST_UBLAS_INLINE 03027 iterator2 &operator += (difference_type n) { 03028 it_ += n; 03029 return *this; 03030 } 03031 BOOST_UBLAS_INLINE 03032 iterator2 &operator -= (difference_type n) { 03033 it_ -= n; 03034 return *this; 03035 } 03036 BOOST_UBLAS_INLINE 03037 difference_type operator - (const iterator2 &it) const { 03038 BOOST_UBLAS_CHECK ((*this) ().same_closure (it ()), external_logic ()); 03039 return it_ - it.it_; 03040 } 03041 03042 // Dereference 03043 BOOST_UBLAS_INLINE 03044 reference operator * () const { 03045 return *it_; 03046 } 03047 BOOST_UBLAS_INLINE 03048 reference operator [] (difference_type n) const { 03049 return *(*this + n); 03050 } 03051 03052 #ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION 03053 BOOST_UBLAS_INLINE 03054 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION 03055 typename self_type:: 03056 #endif 03057 iterator1 begin () const { 03058 self_type &mr = (*this) (); 03059 return mr.find1 (1, 0, index2 ()); 03060 } 03061 BOOST_UBLAS_INLINE 03062 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION 03063 typename self_type:: 03064 #endif 03065 iterator1 end () const { 03066 self_type &mr = (*this) (); 03067 return mr.find1 (1, mr.size1 (), index2 ()); 03068 } 03069 BOOST_UBLAS_INLINE 03070 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION 03071 typename self_type:: 03072 #endif 03073 reverse_iterator1 rbegin () const { 03074 return reverse_iterator1 (end ()); 03075 } 03076 BOOST_UBLAS_INLINE 03077 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION 03078 typename self_type:: 03079 #endif 03080 reverse_iterator1 rend () const { 03081 return reverse_iterator1 (begin ()); 03082 } 03083 #endif 03084 03085 // Indices 03086 BOOST_UBLAS_INLINE 03087 size_type index1 () const { 03088 return it_.index1 () - (*this) ().start1 (); 03089 } 03090 BOOST_UBLAS_INLINE 03091 size_type index2 () const { 03092 return it_.index2 () - (*this) ().start2 (); 03093 } 03094 03095 // Assignment 03096 BOOST_UBLAS_INLINE 03097 iterator2 &operator = (const iterator2 &it) { 03098 container_reference<self_type>::assign (&it ()); 03099 it_ = it.it_; 03100 return *this; 03101 } 03102 03103 // Comparison 03104 BOOST_UBLAS_INLINE 03105 bool operator == (const iterator2 &it) const { 03106 BOOST_UBLAS_CHECK ((*this) ().same_closure (it ()), external_logic ()); 03107 return it_ == it.it_; 03108 } 03109 BOOST_UBLAS_INLINE 03110 bool operator < (const iterator2 &it) const { 03111 BOOST_UBLAS_CHECK ((*this) ().same_closure (it ()), external_logic ()); 03112 return it_ < it.it_; 03113 } 03114 03115 private: 03116 subiterator2_type it_; 03117 03118 friend class const_iterator2; 03119 }; 03120 #endif 03121 03122 BOOST_UBLAS_INLINE 03123 iterator2 begin2 () { 03124 return find2 (0, 0, 0); 03125 } 03126 BOOST_UBLAS_INLINE 03127 iterator2 end2 () { 03128 return find2 (0, 0, size2 ()); 03129 } 03130 03131 // Reverse iterators 03132 03133 BOOST_UBLAS_INLINE 03134 const_reverse_iterator1 rbegin1 () const { 03135 return const_reverse_iterator1 (end1 ()); 03136 } 03137 BOOST_UBLAS_INLINE 03138 const_reverse_iterator1 rend1 () const { 03139 return const_reverse_iterator1 (begin1 ()); 03140 } 03141 03142 BOOST_UBLAS_INLINE 03143 reverse_iterator1 rbegin1 () { 03144 return reverse_iterator1 (end1 ()); 03145 } 03146 BOOST_UBLAS_INLINE 03147 reverse_iterator1 rend1 () { 03148 return reverse_iterator1 (begin1 ()); 03149 } 03150 03151 BOOST_UBLAS_INLINE 03152 const_reverse_iterator2 rbegin2 () const { 03153 return const_reverse_iterator2 (end2 ()); 03154 } 03155 BOOST_UBLAS_INLINE 03156 const_reverse_iterator2 rend2 () const { 03157 return const_reverse_iterator2 (begin2 ()); 03158 } 03159 03160 BOOST_UBLAS_INLINE 03161 reverse_iterator2 rbegin2 () { 03162 return reverse_iterator2 (end2 ()); 03163 } 03164 BOOST_UBLAS_INLINE 03165 reverse_iterator2 rend2 () { 03166 return reverse_iterator2 (begin2 ()); 03167 } 03168 03169 private: 03170 matrix_closure_type data_; 03171 range_type r1_; 03172 range_type r2_; 03173 }; 03174 03175 // Simple Projections 03176 template<class M> 03177 BOOST_UBLAS_INLINE 03178 matrix_range<M> subrange (M &data, typename M::size_type start1, typename M::size_type stop1, typename M::size_type start2, typename M::size_type stop2) { 03179 typedef basic_range<typename M::size_type, typename M::difference_type> range_type; 03180 return matrix_range<M> (data, range_type (start1, stop1), range_type (start2, stop2)); 03181 } 03182 template<class M> 03183 BOOST_UBLAS_INLINE 03184 matrix_range<const M> subrange (const M &data, typename M::size_type start1, typename M::size_type stop1, typename M::size_type start2, typename M::size_type stop2) { 03185 typedef basic_range<typename M::size_type, typename M::difference_type> range_type; 03186 return matrix_range<const M> (data, range_type (start1, stop1), range_type (start2, stop2)); 03187 } 03188 03189 // Generic Projections 03190 template<class M> 03191 BOOST_UBLAS_INLINE 03192 matrix_range<M> project (M &data, const typename matrix_range<M>::range_type &r1, const typename matrix_range<M>::range_type &r2) { 03193 return matrix_range<M> (data, r1, r2); 03194 } 03195 template<class M> 03196 BOOST_UBLAS_INLINE 03197 const matrix_range<const M> project (const M &data, const typename matrix_range<M>::range_type &r1, const typename matrix_range<M>::range_type &r2) { 03198 // ISSUE was: return matrix_range<M> (const_cast<M &> (data), r1, r2); 03199 return matrix_range<const M> (data, r1, r2); 03200 } 03201 template<class M> 03202 BOOST_UBLAS_INLINE 03203 matrix_range<M> project (matrix_range<M> &data, const typename matrix_range<M>::range_type &r1, const typename matrix_range<M>::range_type &r2) { 03204 return data.project (r1, r2); 03205 } 03206 template<class M> 03207 BOOST_UBLAS_INLINE 03208 const matrix_range<M> project (const matrix_range<M> &data, const typename matrix_range<M>::range_type &r1, const typename matrix_range<M>::range_type &r2) { 03209 return data.project (r1, r2); 03210 } 03211 03212 // Specialization of temporary_traits 03213 template <class M> 03214 struct matrix_temporary_traits< matrix_range<M> > 03215 : matrix_temporary_traits< M > {} ; 03216 template <class M> 03217 struct matrix_temporary_traits< const matrix_range<M> > 03218 : matrix_temporary_traits< M > {} ; 03219 03220 template <class M> 03221 struct vector_temporary_traits< matrix_range<M> > 03222 : vector_temporary_traits< M > {} ; 03223 template <class M> 03224 struct vector_temporary_traits< const matrix_range<M> > 03225 : vector_temporary_traits< M > {} ; 03226 03227 // Matrix based slice class 03228 template<class M> 03229 class matrix_slice: 03230 public matrix_expression<matrix_slice<M> > { 03231 03232 typedef matrix_slice<M> self_type; 03233 public: 03234 #ifdef BOOST_UBLAS_ENABLE_PROXY_SHORTCUTS 03235 using matrix_expression<self_type>::operator (); 03236 #endif 03237 typedef M matrix_type; 03238 typedef typename M::size_type size_type; 03239 typedef typename M::difference_type difference_type; 03240 typedef typename M::value_type value_type; 03241 typedef typename M::const_reference const_reference; 03242 typedef typename boost::mpl::if_<boost::is_const<M>, 03243 typename M::const_reference, 03244 typename M::reference>::type reference; 03245 typedef typename boost::mpl::if_<boost::is_const<M>, 03246 typename M::const_closure_type, 03247 typename M::closure_type>::type matrix_closure_type; 03248 typedef basic_range<size_type, difference_type> range_type; 03249 typedef basic_slice<size_type, difference_type> slice_type; 03250 typedef const self_type const_closure_type; 03251 typedef self_type closure_type; 03252 typedef typename storage_restrict_traits<typename M::storage_category, 03253 dense_proxy_tag>::storage_category storage_category; 03254 typedef typename M::orientation_category orientation_category; 03255 03256 // Construction and destruction 03257 BOOST_UBLAS_INLINE 03258 matrix_slice (matrix_type &data, const slice_type &s1, const slice_type &s2): 03259 data_ (data), s1_ (s1.preprocess (data.size1 ())), s2_ (s2.preprocess (data.size2 ())) { 03260 // Early checking of preconditions here. 03261 // BOOST_UBLAS_CHECK (s1_.start () <= data_.size1 () && 03262 // s1_.start () + s1_.stride () * (s1_.size () - (s1_.size () > 0)) <= data_.size1 (), bad_index ()); 03263 // BOOST_UBLAS_CHECK (s2_.start () <= data_.size2 () && 03264 // s2_.start () + s2_.stride () * (s2_.size () - (s2_.size () > 0)) <= data_.size2 (), bad_index ()); 03265 } 03266 BOOST_UBLAS_INLINE 03267 matrix_slice (const matrix_closure_type &data, const slice_type &s1, const slice_type &s2, int): 03268 data_ (data), s1_ (s1.preprocess (data.size1 ())), s2_ (s2.preprocess (data.size2 ())) { 03269 // Early checking of preconditions. 03270 // BOOST_UBLAS_CHECK (s1_.start () <= data_.size1 () && 03271 // s1_.start () + s1_.stride () * (s1_.size () - (s1_.size () > 0)) <= data_.size1 (), bad_index ()); 03272 // BOOST_UBLAS_CHECK (s2_.start () <= data_.size2 () && 03273 // s2_.start () + s2_.stride () * (s2_.size () - (s2_.size () > 0)) <= data_.size2 (), bad_index ()); 03274 } 03275 03276 // Accessors 03277 BOOST_UBLAS_INLINE 03278 size_type start1 () const { 03279 return s1_.start (); 03280 } 03281 BOOST_UBLAS_INLINE 03282 size_type start2 () const { 03283 return s2_.start (); 03284 } 03285 BOOST_UBLAS_INLINE 03286 difference_type stride1 () const { 03287 return s1_.stride (); 03288 } 03289 BOOST_UBLAS_INLINE 03290 difference_type stride2 () const { 03291 return s2_.stride (); 03292 } 03293 BOOST_UBLAS_INLINE 03294 size_type size1 () const { 03295 return s1_.size (); 03296 } 03297 BOOST_UBLAS_INLINE 03298 size_type size2 () const { 03299 return s2_.size (); 03300 } 03301 03302 // Storage accessors 03303 BOOST_UBLAS_INLINE 03304 const matrix_closure_type &data () const { 03305 return data_; 03306 } 03307 BOOST_UBLAS_INLINE 03308 matrix_closure_type &data () { 03309 return data_; 03310 } 03311 03312 // Element access 03313 #ifndef BOOST_UBLAS_PROXY_CONST_MEMBER 03314 BOOST_UBLAS_INLINE 03315 const_reference operator () (size_type i, size_type j) const { 03316 return data_ (s1_ (i), s2_ (j)); 03317 } 03318 BOOST_UBLAS_INLINE 03319 reference operator () (size_type i, size_type j) { 03320 return data_ (s1_ (i), s2_ (j)); 03321 } 03322 #else 03323 BOOST_UBLAS_INLINE 03324 reference operator () (size_type i, size_type j) const { 03325 return data_ (s1_ (i), s2_ (j)); 03326 } 03327 #endif 03328 03329 // ISSUE can this be done in free project function? 03330 // Although a const function can create a non-const proxy to a non-const object 03331 // Critical is that matrix_type and data_ (vector_closure_type) are const correct 03332 BOOST_UBLAS_INLINE 03333 matrix_slice<matrix_type> project (const range_type &r1, const range_type &r2) const { 03334 return matrix_slice<matrix_type> (data_, s1_.compose (r1.preprocess (data_.size1 ())), s2_.compose (r2.preprocess (data_.size2 ())), 0); 03335 } 03336 BOOST_UBLAS_INLINE 03337 matrix_slice<matrix_type> project (const slice_type &s1, const slice_type &s2) const { 03338 return matrix_slice<matrix_type> (data_, s1_.compose (s1.preprocess (data_.size1 ())), s2_.compose (s2.preprocess (data_.size2 ())), 0); 03339 } 03340 03341 // Assignment 03342 BOOST_UBLAS_INLINE 03343 matrix_slice &operator = (const matrix_slice &ms) { 03344 matrix_assign<scalar_assign> (*this, ms); 03345 return *this; 03346 } 03347 BOOST_UBLAS_INLINE 03348 matrix_slice &assign_temporary (matrix_slice &ms) { 03349 return *this = ms; 03350 } 03351 template<class AE> 03352 BOOST_UBLAS_INLINE 03353 matrix_slice &operator = (const matrix_expression<AE> &ae) { 03354 matrix_assign<scalar_assign> (*this, typename matrix_temporary_traits<M>::type (ae)); 03355 return *this; 03356 } 03357 template<class AE> 03358 BOOST_UBLAS_INLINE 03359 matrix_slice &assign (const matrix_expression<AE> &ae) { 03360 matrix_assign<scalar_assign> (*this, ae); 03361 return *this; 03362 } 03363 template<class AE> 03364 BOOST_UBLAS_INLINE 03365 matrix_slice& operator += (const matrix_expression<AE> &ae) { 03366 matrix_assign<scalar_assign> (*this, typename matrix_temporary_traits<M>::type (*this + ae)); 03367 return *this; 03368 } 03369 template<class AE> 03370 BOOST_UBLAS_INLINE 03371 matrix_slice &plus_assign (const matrix_expression<AE> &ae) { 03372 matrix_assign<scalar_plus_assign> (*this, ae); 03373 return *this; 03374 } 03375 template<class AE> 03376 BOOST_UBLAS_INLINE 03377 matrix_slice& operator -= (const matrix_expression<AE> &ae) { 03378 matrix_assign<scalar_assign> (*this, typename matrix_temporary_traits<M>::type (*this - ae)); 03379 return *this; 03380 } 03381 template<class AE> 03382 BOOST_UBLAS_INLINE 03383 matrix_slice &minus_assign (const matrix_expression<AE> &ae) { 03384 matrix_assign<scalar_minus_assign> (*this, ae); 03385 return *this; 03386 } 03387 template<class AT> 03388 BOOST_UBLAS_INLINE 03389 matrix_slice& operator *= (const AT &at) { 03390 matrix_assign_scalar<scalar_multiplies_assign> (*this, at); 03391 return *this; 03392 } 03393 template<class AT> 03394 BOOST_UBLAS_INLINE 03395 matrix_slice& operator /= (const AT &at) { 03396 matrix_assign_scalar<scalar_divides_assign> (*this, at); 03397 return *this; 03398 } 03399 03400 // Closure comparison 03401 BOOST_UBLAS_INLINE 03402 bool same_closure (const matrix_slice &ms) const { 03403 return (*this).data_.same_closure (ms.data_); 03404 } 03405 03406 // Comparison 03407 BOOST_UBLAS_INLINE 03408 bool operator == (const matrix_slice &ms) const { 03409 return (*this).data_ == ms.data_ && s1_ == ms.s1_ && s2_ == ms.s2_; 03410 } 03411 03412 // Swapping 03413 BOOST_UBLAS_INLINE 03414 void swap (matrix_slice ms) { 03415 if (this != &ms) { 03416 BOOST_UBLAS_CHECK (size1 () == ms.size1 (), bad_size ()); 03417 BOOST_UBLAS_CHECK (size2 () == ms.size2 (), bad_size ()); 03418 matrix_swap<scalar_swap> (*this, ms); 03419 } 03420 } 03421 BOOST_UBLAS_INLINE 03422 friend void swap (matrix_slice ms1, matrix_slice ms2) { 03423 ms1.swap (ms2); 03424 } 03425 03426 // Iterator types 03427 private: 03428 // Use slice as an index - FIXME this fails for packed assignment 03429 typedef typename slice_type::const_iterator const_subiterator1_type; 03430 typedef typename slice_type::const_iterator subiterator1_type; 03431 typedef typename slice_type::const_iterator const_subiterator2_type; 03432 typedef typename slice_type::const_iterator subiterator2_type; 03433 03434 public: 03435 #ifdef BOOST_UBLAS_USE_INDEXED_ITERATOR 03436 typedef indexed_iterator1<matrix_slice<matrix_type>, 03437 typename matrix_type::iterator1::iterator_category> iterator1; 03438 typedef indexed_iterator2<matrix_slice<matrix_type>, 03439 typename matrix_type::iterator2::iterator_category> iterator2; 03440 typedef indexed_const_iterator1<matrix_slice<matrix_type>, 03441 typename matrix_type::const_iterator1::iterator_category> const_iterator1; 03442 typedef indexed_const_iterator2<matrix_slice<matrix_type>, 03443 typename matrix_type::const_iterator2::iterator_category> const_iterator2; 03444 #else 03445 class const_iterator1; 03446 class iterator1; 03447 class const_iterator2; 03448 class iterator2; 03449 #endif 03450 typedef reverse_iterator_base1<const_iterator1> const_reverse_iterator1; 03451 typedef reverse_iterator_base1<iterator1> reverse_iterator1; 03452 typedef reverse_iterator_base2<const_iterator2> const_reverse_iterator2; 03453 typedef reverse_iterator_base2<iterator2> reverse_iterator2; 03454 03455 // Element lookup 03456 BOOST_UBLAS_INLINE 03457 const_iterator1 find1 (int /* rank */, size_type i, size_type j) const { 03458 #ifdef BOOST_UBLAS_USE_INDEXED_ITERATOR 03459 return const_iterator1 (*this, i, j); 03460 #else 03461 return const_iterator1 (*this, s1_.begin () + i, s2_.begin () + j); 03462 #endif 03463 } 03464 BOOST_UBLAS_INLINE 03465 iterator1 find1 (int /* rank */, size_type i, size_type j) { 03466 #ifdef BOOST_UBLAS_USE_INDEXED_ITERATOR 03467 return iterator1 (*this, i, j); 03468 #else 03469 return iterator1 (*this, s1_.begin () + i, s2_.begin () + j); 03470 #endif 03471 } 03472 BOOST_UBLAS_INLINE 03473 const_iterator2 find2 (int /* rank */, size_type i, size_type j) const { 03474 #ifdef BOOST_UBLAS_USE_INDEXED_ITERATOR 03475 return const_iterator2 (*this, i, j); 03476 #else 03477 return const_iterator2 (*this, s1_.begin () + i, s2_.begin () + j); 03478 #endif 03479 } 03480 BOOST_UBLAS_INLINE 03481 iterator2 find2 (int /* rank */, size_type i, size_type j) { 03482 #ifdef BOOST_UBLAS_USE_INDEXED_ITERATOR 03483 return iterator2 (*this, i, j); 03484 #else 03485 return iterator2 (*this, s1_.begin () + i, s2_.begin () + j); 03486 #endif 03487 } 03488 03489 // Iterators simply are indices. 03490 03491 #ifndef BOOST_UBLAS_USE_INDEXED_ITERATOR 03492 class const_iterator1: 03493 public container_const_reference<matrix_slice>, 03494 public iterator_base_traits<typename M::const_iterator1::iterator_category>::template 03495 iterator_base<const_iterator1, value_type>::type { 03496 public: 03497 typedef typename M::const_iterator1::value_type value_type; 03498 typedef typename M::const_iterator1::difference_type difference_type; 03499 typedef typename M::const_reference reference; //FIXME due to indexing access 03500 typedef typename M::const_iterator1::pointer pointer; 03501 typedef const_iterator2 dual_iterator_type; 03502 typedef const_reverse_iterator2 dual_reverse_iterator_type; 03503 03504 // Construction and destruction 03505 BOOST_UBLAS_INLINE 03506 const_iterator1 (): 03507 container_const_reference<self_type> (), it1_ (), it2_ () {} 03508 BOOST_UBLAS_INLINE 03509 const_iterator1 (const self_type &ms, const const_subiterator1_type &it1, const const_subiterator2_type &it2): 03510 container_const_reference<self_type> (ms), it1_ (it1), it2_ (it2) {} 03511 BOOST_UBLAS_INLINE 03512 const_iterator1 (const iterator1 &it): 03513 container_const_reference<self_type> (it ()), it1_ (it.it1_), it2_ (it.it2_) {} 03514 03515 // Arithmetic 03516 BOOST_UBLAS_INLINE 03517 const_iterator1 &operator ++ () { 03518 ++ it1_; 03519 return *this; 03520 } 03521 BOOST_UBLAS_INLINE 03522 const_iterator1 &operator -- () { 03523 -- it1_; 03524 return *this; 03525 } 03526 BOOST_UBLAS_INLINE 03527 const_iterator1 &operator += (difference_type n) { 03528 it1_ += n; 03529 return *this; 03530 } 03531 BOOST_UBLAS_INLINE 03532 const_iterator1 &operator -= (difference_type n) { 03533 it1_ -= n; 03534 return *this; 03535 } 03536 BOOST_UBLAS_INLINE 03537 difference_type operator - (const const_iterator1 &it) const { 03538 BOOST_UBLAS_CHECK ((*this) ().same_closure (it ()), external_logic ()); 03539 BOOST_UBLAS_CHECK (it2_ == it.it2_, external_logic ()); 03540 return it1_ - it.it1_; 03541 } 03542 03543 // Dereference 03544 BOOST_UBLAS_INLINE 03545 const_reference operator * () const { 03546 // FIXME replace find with at_element 03547 return (*this) ().data_ (*it1_, *it2_); 03548 } 03549 BOOST_UBLAS_INLINE 03550 const_reference operator [] (difference_type n) const { 03551 return *(*this + n); 03552 } 03553 03554 #ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION 03555 BOOST_UBLAS_INLINE 03556 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION 03557 typename self_type:: 03558 #endif 03559 const_iterator2 begin () const { 03560 return const_iterator2 ((*this) (), it1_, it2_ ().begin ()); 03561 } 03562 BOOST_UBLAS_INLINE 03563 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION 03564 typename self_type:: 03565 #endif 03566 const_iterator2 end () const { 03567 return const_iterator2 ((*this) (), it1_, it2_ ().end ()); 03568 } 03569 BOOST_UBLAS_INLINE 03570 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION 03571 typename self_type:: 03572 #endif 03573 const_reverse_iterator2 rbegin () const { 03574 return const_reverse_iterator2 (end ()); 03575 } 03576 BOOST_UBLAS_INLINE 03577 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION 03578 typename self_type:: 03579 #endif 03580 const_reverse_iterator2 rend () const { 03581 return const_reverse_iterator2 (begin ()); 03582 } 03583 #endif 03584 03585 // Indices 03586 BOOST_UBLAS_INLINE 03587 size_type index1 () const { 03588 return it1_.index (); 03589 } 03590 BOOST_UBLAS_INLINE 03591 size_type index2 () const { 03592 return it2_.index (); 03593 } 03594 03595 // Assignment 03596 BOOST_UBLAS_INLINE 03597 const_iterator1 &operator = (const const_iterator1 &it) { 03598 container_const_reference<self_type>::assign (&it ()); 03599 it1_ = it.it1_; 03600 it2_ = it.it2_; 03601 return *this; 03602 } 03603 03604 // Comparison 03605 BOOST_UBLAS_INLINE 03606 bool operator == (const const_iterator1 &it) const { 03607 BOOST_UBLAS_CHECK ((*this) ().same_closure (it ()), external_logic ()); 03608 BOOST_UBLAS_CHECK (it2_ == it.it2_, external_logic ()); 03609 return it1_ == it.it1_; 03610 } 03611 BOOST_UBLAS_INLINE 03612 bool operator < (const const_iterator1 &it) const { 03613 BOOST_UBLAS_CHECK ((*this) ().same_closure (it ()), external_logic ()); 03614 BOOST_UBLAS_CHECK (it2_ == it.it2_, external_logic ()); 03615 return it1_ < it.it1_; 03616 } 03617 03618 private: 03619 const_subiterator1_type it1_; 03620 const_subiterator2_type it2_; 03621 }; 03622 #endif 03623 03624 BOOST_UBLAS_INLINE 03625 const_iterator1 begin1 () const { 03626 return find1 (0, 0, 0); 03627 } 03628 BOOST_UBLAS_INLINE 03629 const_iterator1 end1 () const { 03630 return find1 (0, size1 (), 0); 03631 } 03632 03633 #ifndef BOOST_UBLAS_USE_INDEXED_ITERATOR 03634 class iterator1: 03635 public container_reference<matrix_slice>, 03636 public iterator_base_traits<typename M::iterator1::iterator_category>::template 03637 iterator_base<iterator1, value_type>::type { 03638 public: 03639 typedef typename M::iterator1::value_type value_type; 03640 typedef typename M::iterator1::difference_type difference_type; 03641 typedef typename M::reference reference; //FIXME due to indexing access 03642 typedef typename M::iterator1::pointer pointer; 03643 typedef iterator2 dual_iterator_type; 03644 typedef reverse_iterator2 dual_reverse_iterator_type; 03645 03646 // Construction and destruction 03647 BOOST_UBLAS_INLINE 03648 iterator1 (): 03649 container_reference<self_type> (), it1_ (), it2_ () {} 03650 BOOST_UBLAS_INLINE 03651 iterator1 (self_type &ms, const subiterator1_type &it1, const subiterator2_type &it2): 03652 container_reference<self_type> (ms), it1_ (it1), it2_ (it2) {} 03653 03654 // Arithmetic 03655 BOOST_UBLAS_INLINE 03656 iterator1 &operator ++ () { 03657 ++ it1_; 03658 return *this; 03659 } 03660 BOOST_UBLAS_INLINE 03661 iterator1 &operator -- () { 03662 -- it1_; 03663 return *this; 03664 } 03665 BOOST_UBLAS_INLINE 03666 iterator1 &operator += (difference_type n) { 03667 it1_ += n; 03668 return *this; 03669 } 03670 BOOST_UBLAS_INLINE 03671 iterator1 &operator -= (difference_type n) { 03672 it1_ -= n; 03673 return *this; 03674 } 03675 BOOST_UBLAS_INLINE 03676 difference_type operator - (const iterator1 &it) const { 03677 BOOST_UBLAS_CHECK ((*this) ().same_closure (it ()), external_logic ()); 03678 BOOST_UBLAS_CHECK (it2_ == it.it2_, external_logic ()); 03679 return it1_ - it.it1_; 03680 } 03681 03682 // Dereference 03683 BOOST_UBLAS_INLINE 03684 reference operator * () const { 03685 // FIXME replace find with at_element 03686 return (*this) ().data_ (*it1_, *it2_); 03687 } 03688 BOOST_UBLAS_INLINE 03689 reference operator [] (difference_type n) const { 03690 return *(*this + n); 03691 } 03692 03693 #ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION 03694 BOOST_UBLAS_INLINE 03695 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION 03696 typename self_type:: 03697 #endif 03698 iterator2 begin () const { 03699 return iterator2 ((*this) (), it1_, it2_ ().begin ()); 03700 } 03701 BOOST_UBLAS_INLINE 03702 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION 03703 typename self_type:: 03704 #endif 03705 iterator2 end () const { 03706 return iterator2 ((*this) (), it1_, it2_ ().end ()); 03707 } 03708 BOOST_UBLAS_INLINE 03709 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION 03710 typename self_type:: 03711 #endif 03712 reverse_iterator2 rbegin () const { 03713 return reverse_iterator2 (end ()); 03714 } 03715 BOOST_UBLAS_INLINE 03716 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION 03717 typename self_type:: 03718 #endif 03719 reverse_iterator2 rend () const { 03720 return reverse_iterator2 (begin ()); 03721 } 03722 #endif 03723 03724 // Indices 03725 BOOST_UBLAS_INLINE 03726 size_type index1 () const { 03727 return it1_.index (); 03728 } 03729 BOOST_UBLAS_INLINE 03730 size_type index2 () const { 03731 return it2_.index (); 03732 } 03733 03734 // Assignment 03735 BOOST_UBLAS_INLINE 03736 iterator1 &operator = (const iterator1 &it) { 03737 container_reference<self_type>::assign (&it ()); 03738 it1_ = it.it1_; 03739 it2_ = it.it2_; 03740 return *this; 03741 } 03742 03743 // Comparison 03744 BOOST_UBLAS_INLINE 03745 bool operator == (const iterator1 &it) const { 03746 BOOST_UBLAS_CHECK ((*this) ().same_closure (it ()), external_logic ()); 03747 BOOST_UBLAS_CHECK (it2_ == it.it2_, external_logic ()); 03748 return it1_ == it.it1_; 03749 } 03750 BOOST_UBLAS_INLINE 03751 bool operator < (const iterator1 &it) const { 03752 BOOST_UBLAS_CHECK ((*this) ().same_closure (it ()), external_logic ()); 03753 BOOST_UBLAS_CHECK (it2_ == it.it2_, external_logic ()); 03754 return it1_ < it.it1_; 03755 } 03756 03757 private: 03758 subiterator1_type it1_; 03759 subiterator2_type it2_; 03760 03761 friend class const_iterator1; 03762 }; 03763 #endif 03764 03765 BOOST_UBLAS_INLINE 03766 iterator1 begin1 () { 03767 return find1 (0, 0, 0); 03768 } 03769 BOOST_UBLAS_INLINE 03770 iterator1 end1 () { 03771 return find1 (0, size1 (), 0); 03772 } 03773 03774 #ifndef BOOST_UBLAS_USE_INDEXED_ITERATOR 03775 class const_iterator2: 03776 public container_const_reference<matrix_slice>, 03777 public iterator_base_traits<typename M::const_iterator2::iterator_category>::template 03778 iterator_base<const_iterator2, value_type>::type { 03779 public: 03780 typedef typename M::const_iterator2::value_type value_type; 03781 typedef typename M::const_iterator2::difference_type difference_type; 03782 typedef typename M::const_reference reference; //FIXME due to indexing access 03783 typedef typename M::const_iterator2::pointer pointer; 03784 typedef const_iterator1 dual_iterator_type; 03785 typedef const_reverse_iterator1 dual_reverse_iterator_type; 03786 03787 // Construction and destruction 03788 BOOST_UBLAS_INLINE 03789 const_iterator2 (): 03790 container_const_reference<self_type> (), it1_ (), it2_ () {} 03791 BOOST_UBLAS_INLINE 03792 const_iterator2 (const self_type &ms, const const_subiterator1_type &it1, const const_subiterator2_type &it2): 03793 container_const_reference<self_type> (ms), it1_ (it1), it2_ (it2) {} 03794 BOOST_UBLAS_INLINE 03795 const_iterator2 (const iterator2 &it): 03796 container_const_reference<self_type> (it ()), it1_ (it.it1_), it2_ (it.it2_) {} 03797 03798 // Arithmetic 03799 BOOST_UBLAS_INLINE 03800 const_iterator2 &operator ++ () { 03801 ++ it2_; 03802 return *this; 03803 } 03804 BOOST_UBLAS_INLINE 03805 const_iterator2 &operator -- () { 03806 -- it2_; 03807 return *this; 03808 } 03809 BOOST_UBLAS_INLINE 03810 const_iterator2 &operator += (difference_type n) { 03811 it2_ += n; 03812 return *this; 03813 } 03814 BOOST_UBLAS_INLINE 03815 const_iterator2 &operator -= (difference_type n) { 03816 it2_ -= n; 03817 return *this; 03818 } 03819 BOOST_UBLAS_INLINE 03820 difference_type operator - (const const_iterator2 &it) const { 03821 BOOST_UBLAS_CHECK ((*this) ().same_closure (it ()), external_logic ()); 03822 BOOST_UBLAS_CHECK (it1_ == it.it1_, external_logic ()); 03823 return it2_ - it.it2_; 03824 } 03825 03826 // Dereference 03827 BOOST_UBLAS_INLINE 03828 const_reference operator * () const { 03829 // FIXME replace find with at_element 03830 return (*this) ().data_ (*it1_, *it2_); 03831 } 03832 BOOST_UBLAS_INLINE 03833 const_reference operator [] (difference_type n) const { 03834 return *(*this + n); 03835 } 03836 03837 #ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION 03838 BOOST_UBLAS_INLINE 03839 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION 03840 typename self_type:: 03841 #endif 03842 const_iterator1 begin () const { 03843 return const_iterator1 ((*this) (), it1_ ().begin (), it2_); 03844 } 03845 BOOST_UBLAS_INLINE 03846 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION 03847 typename self_type:: 03848 #endif 03849 const_iterator1 end () const { 03850 return const_iterator1 ((*this) (), it1_ ().end (), it2_); 03851 } 03852 BOOST_UBLAS_INLINE 03853 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION 03854 typename self_type:: 03855 #endif 03856 const_reverse_iterator1 rbegin () const { 03857 return const_reverse_iterator1 (end ()); 03858 } 03859 BOOST_UBLAS_INLINE 03860 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION 03861 typename self_type:: 03862 #endif 03863 const_reverse_iterator1 rend () const { 03864 return const_reverse_iterator1 (begin ()); 03865 } 03866 #endif 03867 03868 // Indices 03869 BOOST_UBLAS_INLINE 03870 size_type index1 () const { 03871 return it1_.index (); 03872 } 03873 BOOST_UBLAS_INLINE 03874 size_type index2 () const { 03875 return it2_.index (); 03876 } 03877 03878 // Assignment 03879 BOOST_UBLAS_INLINE 03880 const_iterator2 &operator = (const const_iterator2 &it) { 03881 container_const_reference<self_type>::assign (&it ()); 03882 it1_ = it.it1_; 03883 it2_ = it.it2_; 03884 return *this; 03885 } 03886 03887 // Comparison 03888 BOOST_UBLAS_INLINE 03889 bool operator == (const const_iterator2 &it) const { 03890 BOOST_UBLAS_CHECK ((*this) ().same_closure (it ()), external_logic ()); 03891 BOOST_UBLAS_CHECK (it1_ == it.it1_, external_logic ()); 03892 return it2_ == it.it2_; 03893 } 03894 BOOST_UBLAS_INLINE 03895 bool operator < (const const_iterator2 &it) const { 03896 BOOST_UBLAS_CHECK ((*this) ().same_closure (it ()), external_logic ()); 03897 BOOST_UBLAS_CHECK (it1_ == it.it1_, external_logic ()); 03898 return it2_ < it.it2_; 03899 } 03900 03901 private: 03902 const_subiterator1_type it1_; 03903 const_subiterator2_type it2_; 03904 }; 03905 #endif 03906 03907 BOOST_UBLAS_INLINE 03908 const_iterator2 begin2 () const { 03909 return find2 (0, 0, 0); 03910 } 03911 BOOST_UBLAS_INLINE 03912 const_iterator2 end2 () const { 03913 return find2 (0, 0, size2 ()); 03914 } 03915 03916 #ifndef BOOST_UBLAS_USE_INDEXED_ITERATOR 03917 class iterator2: 03918 public container_reference<matrix_slice>, 03919 public iterator_base_traits<typename M::iterator2::iterator_category>::template 03920 iterator_base<iterator2, value_type>::type { 03921 public: 03922 typedef typename M::iterator2::value_type value_type; 03923 typedef typename M::iterator2::difference_type difference_type; 03924 typedef typename M::reference reference; //FIXME due to indexing access 03925 typedef typename M::iterator2::pointer pointer; 03926 typedef iterator1 dual_iterator_type; 03927 typedef reverse_iterator1 dual_reverse_iterator_type; 03928 03929 // Construction and destruction 03930 BOOST_UBLAS_INLINE 03931 iterator2 (): 03932 container_reference<self_type> (), it1_ (), it2_ () {} 03933 BOOST_UBLAS_INLINE 03934 iterator2 (self_type &ms, const subiterator1_type &it1, const subiterator2_type &it2): 03935 container_reference<self_type> (ms), it1_ (it1), it2_ (it2) {} 03936 03937 // Arithmetic 03938 BOOST_UBLAS_INLINE 03939 iterator2 &operator ++ () { 03940 ++ it2_; 03941 return *this; 03942 } 03943 BOOST_UBLAS_INLINE 03944 iterator2 &operator -- () { 03945 -- it2_; 03946 return *this; 03947 } 03948 BOOST_UBLAS_INLINE 03949 iterator2 &operator += (difference_type n) { 03950 it2_ += n; 03951 return *this; 03952 } 03953 BOOST_UBLAS_INLINE 03954 iterator2 &operator -= (difference_type n) { 03955 it2_ -= n; 03956 return *this; 03957 } 03958 BOOST_UBLAS_INLINE 03959 difference_type operator - (const iterator2 &it) const { 03960 BOOST_UBLAS_CHECK ((*this) ().same_closure (it ()), external_logic ()); 03961 BOOST_UBLAS_CHECK (it1_ == it.it1_, external_logic ()); 03962 return it2_ - it.it2_; 03963 } 03964 03965 // Dereference 03966 BOOST_UBLAS_INLINE 03967 reference operator * () const { 03968 // FIXME replace find with at_element 03969 return (*this) ().data_ (*it1_, *it2_); 03970 } 03971 BOOST_UBLAS_INLINE 03972 reference operator [] (difference_type n) const { 03973 return *(*this + n); 03974 } 03975 03976 #ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION 03977 BOOST_UBLAS_INLINE 03978 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION 03979 typename self_type:: 03980 #endif 03981 iterator1 begin () const { 03982 return iterator1 ((*this) (), it1_ ().begin (), it2_); 03983 } 03984 BOOST_UBLAS_INLINE 03985 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION 03986 typename self_type:: 03987 #endif 03988 iterator1 end () const { 03989 return iterator1 ((*this) (), it1_ ().end (), it2_); 03990 } 03991 BOOST_UBLAS_INLINE 03992 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION 03993 typename self_type:: 03994 #endif 03995 reverse_iterator1 rbegin () const { 03996 return reverse_iterator1 (end ()); 03997 } 03998 BOOST_UBLAS_INLINE 03999 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION 04000 typename self_type:: 04001 #endif 04002 reverse_iterator1 rend () const { 04003 return reverse_iterator1 (begin ()); 04004 } 04005 #endif 04006 04007 // Indices 04008 BOOST_UBLAS_INLINE 04009 size_type index1 () const { 04010 return it1_.index (); 04011 } 04012 BOOST_UBLAS_INLINE 04013 size_type index2 () const { 04014 return it2_.index (); 04015 } 04016 04017 // Assignment 04018 BOOST_UBLAS_INLINE 04019 iterator2 &operator = (const iterator2 &it) { 04020 container_reference<self_type>::assign (&it ()); 04021 it1_ = it.it1_; 04022 it2_ = it.it2_; 04023 return *this; 04024 } 04025 04026 // Comparison 04027 BOOST_UBLAS_INLINE 04028 bool operator == (const iterator2 &it) const { 04029 BOOST_UBLAS_CHECK ((*this) ().same_closure (it ()), external_logic ()); 04030 BOOST_UBLAS_CHECK (it1_ == it.it1_, external_logic ()); 04031 return it2_ == it.it2_; 04032 } 04033 BOOST_UBLAS_INLINE 04034 bool operator < (const iterator2 &it) const { 04035 BOOST_UBLAS_CHECK ((*this) ().same_closure (it ()), external_logic ()); 04036 BOOST_UBLAS_CHECK (it1_ == it.it1_, external_logic ()); 04037 return it2_ < it.it2_; 04038 } 04039 04040 private: 04041 subiterator1_type it1_; 04042 subiterator2_type it2_; 04043 04044 friend class const_iterator2; 04045 }; 04046 #endif 04047 04048 BOOST_UBLAS_INLINE 04049 iterator2 begin2 () { 04050 return find2 (0, 0, 0); 04051 } 04052 BOOST_UBLAS_INLINE 04053 iterator2 end2 () { 04054 return find2 (0, 0, size2 ()); 04055 } 04056 04057 // Reverse iterators 04058 04059 BOOST_UBLAS_INLINE 04060 const_reverse_iterator1 rbegin1 () const { 04061 return const_reverse_iterator1 (end1 ()); 04062 } 04063 BOOST_UBLAS_INLINE 04064 const_reverse_iterator1 rend1 () const { 04065 return const_reverse_iterator1 (begin1 ()); 04066 } 04067 04068 BOOST_UBLAS_INLINE 04069 reverse_iterator1 rbegin1 () { 04070 return reverse_iterator1 (end1 ()); 04071 } 04072 BOOST_UBLAS_INLINE 04073 reverse_iterator1 rend1 () { 04074 return reverse_iterator1 (begin1 ()); 04075 } 04076 04077 BOOST_UBLAS_INLINE 04078 const_reverse_iterator2 rbegin2 () const { 04079 return const_reverse_iterator2 (end2 ()); 04080 } 04081 BOOST_UBLAS_INLINE 04082 const_reverse_iterator2 rend2 () const { 04083 return const_reverse_iterator2 (begin2 ()); 04084 } 04085 04086 BOOST_UBLAS_INLINE 04087 reverse_iterator2 rbegin2 () { 04088 return reverse_iterator2 (end2 ()); 04089 } 04090 BOOST_UBLAS_INLINE 04091 reverse_iterator2 rend2 () { 04092 return reverse_iterator2 (begin2 ()); 04093 } 04094 04095 private: 04096 matrix_closure_type data_; 04097 slice_type s1_; 04098 slice_type s2_; 04099 }; 04100 04101 // Simple Projections 04102 template<class M> 04103 BOOST_UBLAS_INLINE 04104 matrix_slice<M> subslice (M &data, typename M::size_type start1, typename M::difference_type stride1, typename M::size_type size1, typename M::size_type start2, typename M::difference_type stride2, typename M::size_type size2) { 04105 typedef basic_slice<typename M::size_type, typename M::difference_type> slice_type; 04106 return matrix_slice<M> (data, slice_type (start1, stride1, size1), slice_type (start2, stride2, size2)); 04107 } 04108 template<class M> 04109 BOOST_UBLAS_INLINE 04110 matrix_slice<const M> subslice (const M &data, typename M::size_type start1, typename M::difference_type stride1, typename M::size_type size1, typename M::size_type start2, typename M::difference_type stride2, typename M::size_type size2) { 04111 typedef basic_slice<typename M::size_type, typename M::difference_type> slice_type; 04112 return matrix_slice<const M> (data, slice_type (start1, stride1, size1), slice_type (start2, stride2, size2)); 04113 } 04114 04115 // Generic Projections 04116 template<class M> 04117 BOOST_UBLAS_INLINE 04118 matrix_slice<M> project (M &data, const typename matrix_slice<M>::slice_type &s1, const typename matrix_slice<M>::slice_type &s2) { 04119 return matrix_slice<M> (data, s1, s2); 04120 } 04121 template<class M> 04122 BOOST_UBLAS_INLINE 04123 const matrix_slice<const M> project (const M &data, const typename matrix_slice<M>::slice_type &s1, const typename matrix_slice<M>::slice_type &s2) { 04124 // ISSUE was: return matrix_slice<M> (const_cast<M &> (data), s1, s2); 04125 return matrix_slice<const M> (data, s1, s2); 04126 } 04127 // ISSUE in the following two functions it would be logical to use matrix_slice<V>::range_type but this confuses VC7.1 and 8.0 04128 template<class M> 04129 BOOST_UBLAS_INLINE 04130 matrix_slice<M> project (matrix_slice<M> &data, const typename matrix_range<M>::range_type &r1, const typename matrix_range<M>::range_type &r2) { 04131 return data.project (r1, r2); 04132 } 04133 template<class M> 04134 BOOST_UBLAS_INLINE 04135 const matrix_slice<M> project (const matrix_slice<M> &data, const typename matrix_range<M>::range_type &r1, const typename matrix_range<M>::range_type &r2) { 04136 return data.project (r1, r2); 04137 } 04138 template<class M> 04139 BOOST_UBLAS_INLINE 04140 matrix_slice<M> project (matrix_slice<M> &data, const typename matrix_slice<M>::slice_type &s1, const typename matrix_slice<M>::slice_type &s2) { 04141 return data.project (s1, s2); 04142 } 04143 template<class M> 04144 BOOST_UBLAS_INLINE 04145 const matrix_slice<M> project (const matrix_slice<M> &data, const typename matrix_slice<M>::slice_type &s1, const typename matrix_slice<M>::slice_type &s2) { 04146 return data.project (s1, s2); 04147 } 04148 04149 // Specialization of temporary_traits 04150 template <class M> 04151 struct matrix_temporary_traits< matrix_slice<M> > 04152 : matrix_temporary_traits< M > {}; 04153 template <class M> 04154 struct matrix_temporary_traits< const matrix_slice<M> > 04155 : matrix_temporary_traits< M > {}; 04156 04157 template <class M> 04158 struct vector_temporary_traits< matrix_slice<M> > 04159 : vector_temporary_traits< M > {}; 04160 template <class M> 04161 struct vector_temporary_traits< const matrix_slice<M> > 04162 : vector_temporary_traits< M > {}; 04163 04164 // Matrix based indirection class 04165 // Contributed by Toon Knapen. 04166 // Extended and optimized by Kresimir Fresl. 04185 template<class M, class IA> 04186 class matrix_indirect: 04187 public matrix_expression<matrix_indirect<M, IA> > { 04188 04189 typedef matrix_indirect<M, IA> self_type; 04190 public: 04191 #ifdef BOOST_UBLAS_ENABLE_PROXY_SHORTCUTS 04192 using matrix_expression<self_type>::operator (); 04193 #endif 04194 typedef M matrix_type; 04195 typedef IA indirect_array_type; 04196 typedef typename M::size_type size_type; 04197 typedef typename M::difference_type difference_type; 04198 typedef typename M::value_type value_type; 04199 typedef typename M::const_reference const_reference; 04200 typedef typename boost::mpl::if_<boost::is_const<M>, 04201 typename M::const_reference, 04202 typename M::reference>::type reference; 04203 typedef typename boost::mpl::if_<boost::is_const<M>, 04204 typename M::const_closure_type, 04205 typename M::closure_type>::type matrix_closure_type; 04206 typedef basic_range<size_type, difference_type> range_type; 04207 typedef basic_slice<size_type, difference_type> slice_type; 04208 typedef const self_type const_closure_type; 04209 typedef self_type closure_type; 04210 typedef typename storage_restrict_traits<typename M::storage_category, 04211 dense_proxy_tag>::storage_category storage_category; 04212 typedef typename M::orientation_category orientation_category; 04213 04214 // Construction and destruction 04215 BOOST_UBLAS_INLINE 04216 matrix_indirect (matrix_type &data, size_type size1, size_type size2): 04217 data_ (data), ia1_ (size1), ia2_ (size2) {} 04218 BOOST_UBLAS_INLINE 04219 matrix_indirect (matrix_type &data, const indirect_array_type &ia1, const indirect_array_type &ia2): 04220 data_ (data), ia1_ (ia1.preprocess (data.size1 ())), ia2_ (ia2.preprocess (data.size2 ())) {} 04221 BOOST_UBLAS_INLINE 04222 matrix_indirect (const matrix_closure_type &data, const indirect_array_type &ia1, const indirect_array_type &ia2, int): 04223 data_ (data), ia1_ (ia1.preprocess (data.size1 ())), ia2_ (ia2.preprocess (data.size2 ())) {} 04224 04225 // Accessors 04226 BOOST_UBLAS_INLINE 04227 size_type size1 () const { 04228 return ia1_.size (); 04229 } 04230 BOOST_UBLAS_INLINE 04231 size_type size2 () const { 04232 return ia2_.size (); 04233 } 04234 BOOST_UBLAS_INLINE 04235 const indirect_array_type &indirect1 () const { 04236 return ia1_; 04237 } 04238 BOOST_UBLAS_INLINE 04239 indirect_array_type &indirect1 () { 04240 return ia1_; 04241 } 04242 BOOST_UBLAS_INLINE 04243 const indirect_array_type &indirect2 () const { 04244 return ia2_; 04245 } 04246 BOOST_UBLAS_INLINE 04247 indirect_array_type &indirect2 () { 04248 return ia2_; 04249 } 04250 04251 // Storage accessors 04252 BOOST_UBLAS_INLINE 04253 const matrix_closure_type &data () const { 04254 return data_; 04255 } 04256 BOOST_UBLAS_INLINE 04257 matrix_closure_type &data () { 04258 return data_; 04259 } 04260 04261 // Element access 04262 #ifndef BOOST_UBLAS_PROXY_CONST_MEMBER 04263 BOOST_UBLAS_INLINE 04264 const_reference operator () (size_type i, size_type j) const { 04265 return data_ (ia1_ (i), ia2_ (j)); 04266 } 04267 BOOST_UBLAS_INLINE 04268 reference operator () (size_type i, size_type j) { 04269 return data_ (ia1_ (i), ia2_ (j)); 04270 } 04271 #else 04272 BOOST_UBLAS_INLINE 04273 reference operator () (size_type i, size_type j) const { 04274 return data_ (ia1_ (i), ia2_ (j)); 04275 } 04276 #endif 04277 04278 // ISSUE can this be done in free project function? 04279 // Although a const function can create a non-const proxy to a non-const object 04280 // Critical is that matrix_type and data_ (vector_closure_type) are const correct 04281 BOOST_UBLAS_INLINE 04282 matrix_indirect<matrix_type, indirect_array_type> project (const range_type &r1, const range_type &r2) const { 04283 return matrix_indirect<matrix_type, indirect_array_type> (data_, ia1_.compose (r1.preprocess (data_.size1 ())), ia2_.compose (r2.preprocess (data_.size2 ())), 0); 04284 } 04285 BOOST_UBLAS_INLINE 04286 matrix_indirect<matrix_type, indirect_array_type> project (const slice_type &s1, const slice_type &s2) const { 04287 return matrix_indirect<matrix_type, indirect_array_type> (data_, ia1_.compose (s1.preprocess (data_.size1 ())), ia2_.compose (s2.preprocess (data_.size2 ())), 0); 04288 } 04289 BOOST_UBLAS_INLINE 04290 matrix_indirect<matrix_type, indirect_array_type> project (const indirect_array_type &ia1, const indirect_array_type &ia2) const { 04291 return matrix_indirect<matrix_type, indirect_array_type> (data_, ia1_.compose (ia1.preprocess (data_.size1 ())), ia2_.compose (ia2.preprocess (data_.size2 ())), 0); 04292 } 04293 04294 // Assignment 04295 BOOST_UBLAS_INLINE 04296 matrix_indirect &operator = (const matrix_indirect &mi) { 04297 matrix_assign<scalar_assign> (*this, mi); 04298 return *this; 04299 } 04300 BOOST_UBLAS_INLINE 04301 matrix_indirect &assign_temporary (matrix_indirect &mi) { 04302 return *this = mi; 04303 } 04304 template<class AE> 04305 BOOST_UBLAS_INLINE 04306 matrix_indirect &operator = (const matrix_expression<AE> &ae) { 04307 matrix_assign<scalar_assign> (*this, typename matrix_temporary_traits<M>::type (ae)); 04308 return *this; 04309 } 04310 template<class AE> 04311 BOOST_UBLAS_INLINE 04312 matrix_indirect &assign (const matrix_expression<AE> &ae) { 04313 matrix_assign<scalar_assign> (*this, ae); 04314 return *this; 04315 } 04316 template<class AE> 04317 BOOST_UBLAS_INLINE 04318 matrix_indirect& operator += (const matrix_expression<AE> &ae) { 04319 matrix_assign<scalar_assign> (*this, typename matrix_temporary_traits<M>::type (*this + ae)); 04320 return *this; 04321 } 04322 template<class AE> 04323 BOOST_UBLAS_INLINE 04324 matrix_indirect &plus_assign (const matrix_expression<AE> &ae) { 04325 matrix_assign<scalar_plus_assign> (*this, ae); 04326 return *this; 04327 } 04328 template<class AE> 04329 BOOST_UBLAS_INLINE 04330 matrix_indirect& operator -= (const matrix_expression<AE> &ae) { 04331 matrix_assign<scalar_assign> (*this, typename matrix_temporary_traits<M>::type (*this - ae)); 04332 return *this; 04333 } 04334 template<class AE> 04335 BOOST_UBLAS_INLINE 04336 matrix_indirect &minus_assign (const matrix_expression<AE> &ae) { 04337 matrix_assign<scalar_minus_assign> (*this, ae); 04338 return *this; 04339 } 04340 template<class AT> 04341 BOOST_UBLAS_INLINE 04342 matrix_indirect& operator *= (const AT &at) { 04343 matrix_assign_scalar<scalar_multiplies_assign> (*this, at); 04344 return *this; 04345 } 04346 template<class AT> 04347 BOOST_UBLAS_INLINE 04348 matrix_indirect& operator /= (const AT &at) { 04349 matrix_assign_scalar<scalar_divides_assign> (*this, at); 04350 return *this; 04351 } 04352 04353 // Closure comparison 04354 BOOST_UBLAS_INLINE 04355 bool same_closure (const matrix_indirect &mi) const { 04356 return (*this).data_.same_closure (mi.data_); 04357 } 04358 04359 // Comparison 04360 BOOST_UBLAS_INLINE 04361 bool operator == (const matrix_indirect &mi) const { 04362 return (*this).data_ == mi.data_ && ia1_ == mi.ia1_ && ia2_ == mi.ia2_; 04363 } 04364 04365 // Swapping 04366 BOOST_UBLAS_INLINE 04367 void swap (matrix_indirect mi) { 04368 if (this != &mi) { 04369 BOOST_UBLAS_CHECK (size1 () == mi.size1 (), bad_size ()); 04370 BOOST_UBLAS_CHECK (size2 () == mi.size2 (), bad_size ()); 04371 matrix_swap<scalar_swap> (*this, mi); 04372 } 04373 } 04374 BOOST_UBLAS_INLINE 04375 friend void swap (matrix_indirect mi1, matrix_indirect mi2) { 04376 mi1.swap (mi2); 04377 } 04378 04379 // Iterator types 04380 private: 04381 typedef typename IA::const_iterator const_subiterator1_type; 04382 typedef typename IA::const_iterator subiterator1_type; 04383 typedef typename IA::const_iterator const_subiterator2_type; 04384 typedef typename IA::const_iterator subiterator2_type; 04385 04386 public: 04387 #ifdef BOOST_UBLAS_USE_INDEXED_ITERATOR 04388 typedef indexed_iterator1<matrix_indirect<matrix_type, indirect_array_type>, 04389 typename matrix_type::iterator1::iterator_category> iterator1; 04390 typedef indexed_iterator2<matrix_indirect<matrix_type, indirect_array_type>, 04391 typename matrix_type::iterator2::iterator_category> iterator2; 04392 typedef indexed_const_iterator1<matrix_indirect<matrix_type, indirect_array_type>, 04393 typename matrix_type::const_iterator1::iterator_category> const_iterator1; 04394 typedef indexed_const_iterator2<matrix_indirect<matrix_type, indirect_array_type>, 04395 typename matrix_type::const_iterator2::iterator_category> const_iterator2; 04396 #else 04397 class const_iterator1; 04398 class iterator1; 04399 class const_iterator2; 04400 class iterator2; 04401 #endif 04402 typedef reverse_iterator_base1<const_iterator1> const_reverse_iterator1; 04403 typedef reverse_iterator_base1<iterator1> reverse_iterator1; 04404 typedef reverse_iterator_base2<const_iterator2> const_reverse_iterator2; 04405 typedef reverse_iterator_base2<iterator2> reverse_iterator2; 04406 04407 // Element lookup 04408 BOOST_UBLAS_INLINE 04409 const_iterator1 find1 (int /* rank */, size_type i, size_type j) const { 04410 #ifdef BOOST_UBLAS_USE_INDEXED_ITERATOR 04411 return const_iterator1 (*this, i, j); 04412 #else 04413 return const_iterator1 (*this, ia1_.begin () + i, ia2_.begin () + j); 04414 #endif 04415 } 04416 BOOST_UBLAS_INLINE 04417 iterator1 find1 (int /* rank */, size_type i, size_type j) { 04418 #ifdef BOOST_UBLAS_USE_INDEXED_ITERATOR 04419 return iterator1 (*this, i, j); 04420 #else 04421 return iterator1 (*this, ia1_.begin () + i, ia2_.begin () + j); 04422 #endif 04423 } 04424 BOOST_UBLAS_INLINE 04425 const_iterator2 find2 (int /* rank */, size_type i, size_type j) const { 04426 #ifdef BOOST_UBLAS_USE_INDEXED_ITERATOR 04427 return const_iterator2 (*this, i, j); 04428 #else 04429 return const_iterator2 (*this, ia1_.begin () + i, ia2_.begin () + j); 04430 #endif 04431 } 04432 BOOST_UBLAS_INLINE 04433 iterator2 find2 (int /* rank */, size_type i, size_type j) { 04434 #ifdef BOOST_UBLAS_USE_INDEXED_ITERATOR 04435 return iterator2 (*this, i, j); 04436 #else 04437 return iterator2 (*this, ia1_.begin () + i, ia2_.begin () + j); 04438 #endif 04439 } 04440 04441 // Iterators simply are indices. 04442 04443 #ifndef BOOST_UBLAS_USE_INDEXED_ITERATOR 04444 class const_iterator1: 04445 public container_const_reference<matrix_indirect>, 04446 public iterator_base_traits<typename M::const_iterator1::iterator_category>::template 04447 iterator_base<const_iterator1, value_type>::type { 04448 public: 04449 typedef typename M::const_iterator1::value_type value_type; 04450 typedef typename M::const_iterator1::difference_type difference_type; 04451 typedef typename M::const_reference reference; //FIXME due to indexing access 04452 typedef typename M::const_iterator1::pointer pointer; 04453 typedef const_iterator2 dual_iterator_type; 04454 typedef const_reverse_iterator2 dual_reverse_iterator_type; 04455 04456 // Construction and destruction 04457 BOOST_UBLAS_INLINE 04458 const_iterator1 (): 04459 container_const_reference<self_type> (), it1_ (), it2_ () {} 04460 BOOST_UBLAS_INLINE 04461 const_iterator1 (const self_type &mi, const const_subiterator1_type &it1, const const_subiterator2_type &it2): 04462 container_const_reference<self_type> (mi), it1_ (it1), it2_ (it2) {} 04463 BOOST_UBLAS_INLINE 04464 const_iterator1 (const iterator1 &it): 04465 container_const_reference<self_type> (it ()), it1_ (it.it1_), it2_ (it.it2_) {} 04466 04467 // Arithmetic 04468 BOOST_UBLAS_INLINE 04469 const_iterator1 &operator ++ () { 04470 ++ it1_; 04471 return *this; 04472 } 04473 BOOST_UBLAS_INLINE 04474 const_iterator1 &operator -- () { 04475 -- it1_; 04476 return *this; 04477 } 04478 BOOST_UBLAS_INLINE 04479 const_iterator1 &operator += (difference_type n) { 04480 it1_ += n; 04481 return *this; 04482 } 04483 BOOST_UBLAS_INLINE 04484 const_iterator1 &operator -= (difference_type n) { 04485 it1_ -= n; 04486 return *this; 04487 } 04488 BOOST_UBLAS_INLINE 04489 difference_type operator - (const const_iterator1 &it) const { 04490 BOOST_UBLAS_CHECK ((*this) ().same_closure (it ()), external_logic ()); 04491 BOOST_UBLAS_CHECK (it2_ == it.it2_, external_logic ()); 04492 return it1_ - it.it1_; 04493 } 04494 04495 // Dereference 04496 BOOST_UBLAS_INLINE 04497 const_reference operator * () const { 04498 // FIXME replace find with at_element 04499 return (*this) ().data_ (*it1_, *it2_); 04500 } 04501 BOOST_UBLAS_INLINE 04502 const_reference operator [] (difference_type n) const { 04503 return *(*this + n); 04504 } 04505 04506 #ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION 04507 BOOST_UBLAS_INLINE 04508 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION 04509 typename self_type:: 04510 #endif 04511 const_iterator2 begin () const { 04512 return const_iterator2 ((*this) (), it1_, it2_ ().begin ()); 04513 } 04514 BOOST_UBLAS_INLINE 04515 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION 04516 typename self_type:: 04517 #endif 04518 const_iterator2 end () const { 04519 return const_iterator2 ((*this) (), it1_, it2_ ().end ()); 04520 } 04521 BOOST_UBLAS_INLINE 04522 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION 04523 typename self_type:: 04524 #endif 04525 const_reverse_iterator2 rbegin () const { 04526 return const_reverse_iterator2 (end ()); 04527 } 04528 BOOST_UBLAS_INLINE 04529 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION 04530 typename self_type:: 04531 #endif 04532 const_reverse_iterator2 rend () const { 04533 return const_reverse_iterator2 (begin ()); 04534 } 04535 #endif 04536 04537 // Indices 04538 BOOST_UBLAS_INLINE 04539 size_type index1 () const { 04540 return it1_.index (); 04541 } 04542 BOOST_UBLAS_INLINE 04543 size_type index2 () const { 04544 return it2_.index (); 04545 } 04546 04547 // Assignment 04548 BOOST_UBLAS_INLINE 04549 const_iterator1 &operator = (const const_iterator1 &it) { 04550 container_const_reference<self_type>::assign (&it ()); 04551 it1_ = it.it1_; 04552 it2_ = it.it2_; 04553 return *this; 04554 } 04555 04556 // Comparison 04557 BOOST_UBLAS_INLINE 04558 bool operator == (const const_iterator1 &it) const { 04559 BOOST_UBLAS_CHECK ((*this) ().same_closure (it ()), external_logic ()); 04560 BOOST_UBLAS_CHECK (it2_ == it.it2_, external_logic ()); 04561 return it1_ == it.it1_; 04562 } 04563 BOOST_UBLAS_INLINE 04564 bool operator < (const const_iterator1 &it) const { 04565 BOOST_UBLAS_CHECK ((*this) ().same_closure (it ()), external_logic ()); 04566 BOOST_UBLAS_CHECK (it2_ == it.it2_, external_logic ()); 04567 return it1_ < it.it1_; 04568 } 04569 04570 private: 04571 const_subiterator1_type it1_; 04572 const_subiterator2_type it2_; 04573 }; 04574 #endif 04575 04576 BOOST_UBLAS_INLINE 04577 const_iterator1 begin1 () const { 04578 return find1 (0, 0, 0); 04579 } 04580 BOOST_UBLAS_INLINE 04581 const_iterator1 end1 () const { 04582 return find1 (0, size1 (), 0); 04583 } 04584 04585 #ifndef BOOST_UBLAS_USE_INDEXED_ITERATOR 04586 class iterator1: 04587 public container_reference<matrix_indirect>, 04588 public iterator_base_traits<typename M::iterator1::iterator_category>::template 04589 iterator_base<iterator1, value_type>::type { 04590 public: 04591 typedef typename M::iterator1::value_type value_type; 04592 typedef typename M::iterator1::difference_type difference_type; 04593 typedef typename M::reference reference; //FIXME due to indexing access 04594 typedef typename M::iterator1::pointer pointer; 04595 typedef iterator2 dual_iterator_type; 04596 typedef reverse_iterator2 dual_reverse_iterator_type; 04597 04598 // Construction and destruction 04599 BOOST_UBLAS_INLINE 04600 iterator1 (): 04601 container_reference<self_type> (), it1_ (), it2_ () {} 04602 BOOST_UBLAS_INLINE 04603 iterator1 (self_type &mi, const subiterator1_type &it1, const subiterator2_type &it2): 04604 container_reference<self_type> (mi), it1_ (it1), it2_ (it2) {} 04605 04606 // Arithmetic 04607 BOOST_UBLAS_INLINE 04608 iterator1 &operator ++ () { 04609 ++ it1_; 04610 return *this; 04611 } 04612 BOOST_UBLAS_INLINE 04613 iterator1 &operator -- () { 04614 -- it1_; 04615 return *this; 04616 } 04617 BOOST_UBLAS_INLINE 04618 iterator1 &operator += (difference_type n) { 04619 it1_ += n; 04620 return *this; 04621 } 04622 BOOST_UBLAS_INLINE 04623 iterator1 &operator -= (difference_type n) { 04624 it1_ -= n; 04625 return *this; 04626 } 04627 BOOST_UBLAS_INLINE 04628 difference_type operator - (const iterator1 &it) const { 04629 BOOST_UBLAS_CHECK ((*this) ().same_closure (it ()), external_logic ()); 04630 BOOST_UBLAS_CHECK (it2_ == it.it2_, external_logic ()); 04631 return it1_ - it.it1_; 04632 } 04633 04634 // Dereference 04635 BOOST_UBLAS_INLINE 04636 reference operator * () const { 04637 // FIXME replace find with at_element 04638 return (*this) ().data_ (*it1_, *it2_); 04639 } 04640 BOOST_UBLAS_INLINE 04641 reference operator [] (difference_type n) const { 04642 return *(*this + n); 04643 } 04644 04645 #ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION 04646 BOOST_UBLAS_INLINE 04647 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION 04648 typename self_type:: 04649 #endif 04650 iterator2 begin () const { 04651 return iterator2 ((*this) (), it1_, it2_ ().begin ()); 04652 } 04653 BOOST_UBLAS_INLINE 04654 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION 04655 typename self_type:: 04656 #endif 04657 iterator2 end () const { 04658 return iterator2 ((*this) (), it1_, it2_ ().end ()); 04659 } 04660 BOOST_UBLAS_INLINE 04661 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION 04662 typename self_type:: 04663 #endif 04664 reverse_iterator2 rbegin () const { 04665 return reverse_iterator2 (end ()); 04666 } 04667 BOOST_UBLAS_INLINE 04668 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION 04669 typename self_type:: 04670 #endif 04671 reverse_iterator2 rend () const { 04672 return reverse_iterator2 (begin ()); 04673 } 04674 #endif 04675 04676 // Indices 04677 BOOST_UBLAS_INLINE 04678 size_type index1 () const { 04679 return it1_.index (); 04680 } 04681 BOOST_UBLAS_INLINE 04682 size_type index2 () const { 04683 return it2_.index (); 04684 } 04685 04686 // Assignment 04687 BOOST_UBLAS_INLINE 04688 iterator1 &operator = (const iterator1 &it) { 04689 container_reference<self_type>::assign (&it ()); 04690 it1_ = it.it1_; 04691 it2_ = it.it2_; 04692 return *this; 04693 } 04694 04695 // Comparison 04696 BOOST_UBLAS_INLINE 04697 bool operator == (const iterator1 &it) const { 04698 BOOST_UBLAS_CHECK ((*this) ().same_closure (it ()), external_logic ()); 04699 BOOST_UBLAS_CHECK (it2_ == it.it2_, external_logic ()); 04700 return it1_ == it.it1_; 04701 } 04702 BOOST_UBLAS_INLINE 04703 bool operator < (const iterator1 &it) const { 04704 BOOST_UBLAS_CHECK ((*this) ().same_closure (it ()), external_logic ()); 04705 BOOST_UBLAS_CHECK (it2_ == it.it2_, external_logic ()); 04706 return it1_ < it.it1_; 04707 } 04708 04709 private: 04710 subiterator1_type it1_; 04711 subiterator2_type it2_; 04712 04713 friend class const_iterator1; 04714 }; 04715 #endif 04716 04717 BOOST_UBLAS_INLINE 04718 iterator1 begin1 () { 04719 return find1 (0, 0, 0); 04720 } 04721 BOOST_UBLAS_INLINE 04722 iterator1 end1 () { 04723 return find1 (0, size1 (), 0); 04724 } 04725 04726 #ifndef BOOST_UBLAS_USE_INDEXED_ITERATOR 04727 class const_iterator2: 04728 public container_const_reference<matrix_indirect>, 04729 public iterator_base_traits<typename M::const_iterator2::iterator_category>::template 04730 iterator_base<const_iterator2, value_type>::type { 04731 public: 04732 typedef typename M::const_iterator2::value_type value_type; 04733 typedef typename M::const_iterator2::difference_type difference_type; 04734 typedef typename M::const_reference reference; //FIXME due to indexing access 04735 typedef typename M::const_iterator2::pointer pointer; 04736 typedef const_iterator1 dual_iterator_type; 04737 typedef const_reverse_iterator1 dual_reverse_iterator_type; 04738 04739 // Construction and destruction 04740 BOOST_UBLAS_INLINE 04741 const_iterator2 (): 04742 container_const_reference<self_type> (), it1_ (), it2_ () {} 04743 BOOST_UBLAS_INLINE 04744 const_iterator2 (const self_type &mi, const const_subiterator1_type &it1, const const_subiterator2_type &it2): 04745 container_const_reference<self_type> (mi), it1_ (it1), it2_ (it2) {} 04746 BOOST_UBLAS_INLINE 04747 const_iterator2 (const iterator2 &it): 04748 container_const_reference<self_type> (it ()), it1_ (it.it1_), it2_ (it.it2_) {} 04749 04750 // Arithmetic 04751 BOOST_UBLAS_INLINE 04752 const_iterator2 &operator ++ () { 04753 ++ it2_; 04754 return *this; 04755 } 04756 BOOST_UBLAS_INLINE 04757 const_iterator2 &operator -- () { 04758 -- it2_; 04759 return *this; 04760 } 04761 BOOST_UBLAS_INLINE 04762 const_iterator2 &operator += (difference_type n) { 04763 it2_ += n; 04764 return *this; 04765 } 04766 BOOST_UBLAS_INLINE 04767 const_iterator2 &operator -= (difference_type n) { 04768 it2_ -= n; 04769 return *this; 04770 } 04771 BOOST_UBLAS_INLINE 04772 difference_type operator - (const const_iterator2 &it) const { 04773 BOOST_UBLAS_CHECK ((*this) ().same_closure (it ()), external_logic ()); 04774 BOOST_UBLAS_CHECK (it1_ == it.it1_, external_logic ()); 04775 return it2_ - it.it2_; 04776 } 04777 04778 // Dereference 04779 BOOST_UBLAS_INLINE 04780 const_reference operator * () const { 04781 // FIXME replace find with at_element 04782 return (*this) ().data_ (*it1_, *it2_); 04783 } 04784 BOOST_UBLAS_INLINE 04785 const_reference operator [] (difference_type n) const { 04786 return *(*this + n); 04787 } 04788 04789 #ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION 04790 BOOST_UBLAS_INLINE 04791 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION 04792 typename self_type:: 04793 #endif 04794 const_iterator1 begin () const { 04795 return const_iterator1 ((*this) (), it1_ ().begin (), it2_); 04796 } 04797 BOOST_UBLAS_INLINE 04798 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION 04799 typename self_type:: 04800 #endif 04801 const_iterator1 end () const { 04802 return const_iterator1 ((*this) (), it1_ ().end (), it2_); 04803 } 04804 BOOST_UBLAS_INLINE 04805 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION 04806 typename self_type:: 04807 #endif 04808 const_reverse_iterator1 rbegin () const { 04809 return const_reverse_iterator1 (end ()); 04810 } 04811 BOOST_UBLAS_INLINE 04812 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION 04813 typename self_type:: 04814 #endif 04815 const_reverse_iterator1 rend () const { 04816 return const_reverse_iterator1 (begin ()); 04817 } 04818 #endif 04819 04820 // Indices 04821 BOOST_UBLAS_INLINE 04822 size_type index1 () const { 04823 return it1_.index (); 04824 } 04825 BOOST_UBLAS_INLINE 04826 size_type index2 () const { 04827 return it2_.index (); 04828 } 04829 04830 // Assignment 04831 BOOST_UBLAS_INLINE 04832 const_iterator2 &operator = (const const_iterator2 &it) { 04833 container_const_reference<self_type>::assign (&it ()); 04834 it1_ = it.it1_; 04835 it2_ = it.it2_; 04836 return *this; 04837 } 04838 04839 // Comparison 04840 BOOST_UBLAS_INLINE 04841 bool operator == (const const_iterator2 &it) const { 04842 BOOST_UBLAS_CHECK ((*this) ().same_closure (it ()), external_logic ()); 04843 BOOST_UBLAS_CHECK (it1_ == it.it1_, external_logic ()); 04844 return it2_ == it.it2_; 04845 } 04846 BOOST_UBLAS_INLINE 04847 bool operator < (const const_iterator2 &it) const { 04848 BOOST_UBLAS_CHECK ((*this) ().same_closure (it ()), external_logic ()); 04849 BOOST_UBLAS_CHECK (it1_ == it.it1_, external_logic ()); 04850 return it2_ < it.it2_; 04851 } 04852 04853 private: 04854 const_subiterator1_type it1_; 04855 const_subiterator2_type it2_; 04856 }; 04857 #endif 04858 04859 BOOST_UBLAS_INLINE 04860 const_iterator2 begin2 () const { 04861 return find2 (0, 0, 0); 04862 } 04863 BOOST_UBLAS_INLINE 04864 const_iterator2 end2 () const { 04865 return find2 (0, 0, size2 ()); 04866 } 04867 04868 #ifndef BOOST_UBLAS_USE_INDEXED_ITERATOR 04869 class iterator2: 04870 public container_reference<matrix_indirect>, 04871 public iterator_base_traits<typename M::iterator2::iterator_category>::template 04872 iterator_base<iterator2, value_type>::type { 04873 public: 04874 typedef typename M::iterator2::value_type value_type; 04875 typedef typename M::iterator2::difference_type difference_type; 04876 typedef typename M::reference reference; //FIXME due to indexing access 04877 typedef typename M::iterator2::pointer pointer; 04878 typedef iterator1 dual_iterator_type; 04879 typedef reverse_iterator1 dual_reverse_iterator_type; 04880 04881 // Construction and destruction 04882 BOOST_UBLAS_INLINE 04883 iterator2 (): 04884 container_reference<self_type> (), it1_ (), it2_ () {} 04885 BOOST_UBLAS_INLINE 04886 iterator2 (self_type &mi, const subiterator1_type &it1, const subiterator2_type &it2): 04887 container_reference<self_type> (mi), it1_ (it1), it2_ (it2) {} 04888 04889 // Arithmetic 04890 BOOST_UBLAS_INLINE 04891 iterator2 &operator ++ () { 04892 ++ it2_; 04893 return *this; 04894 } 04895 BOOST_UBLAS_INLINE 04896 iterator2 &operator -- () { 04897 -- it2_; 04898 return *this; 04899 } 04900 BOOST_UBLAS_INLINE 04901 iterator2 &operator += (difference_type n) { 04902 it2_ += n; 04903 return *this; 04904 } 04905 BOOST_UBLAS_INLINE 04906 iterator2 &operator -= (difference_type n) { 04907 it2_ -= n; 04908 return *this; 04909 } 04910 BOOST_UBLAS_INLINE 04911 difference_type operator - (const iterator2 &it) const { 04912 BOOST_UBLAS_CHECK ((*this) ().same_closure (it ()), external_logic ()); 04913 BOOST_UBLAS_CHECK (it1_ == it.it1_, external_logic ()); 04914 return it2_ - it.it2_; 04915 } 04916 04917 // Dereference 04918 BOOST_UBLAS_INLINE 04919 reference operator * () const { 04920 // FIXME replace find with at_element 04921 return (*this) ().data_ (*it1_, *it2_); 04922 } 04923 BOOST_UBLAS_INLINE 04924 reference operator [] (difference_type n) const { 04925 return *(*this + n); 04926 } 04927 04928 #ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION 04929 BOOST_UBLAS_INLINE 04930 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION 04931 typename self_type:: 04932 #endif 04933 iterator1 begin () const { 04934 return iterator1 ((*this) (), it1_ ().begin (), it2_); 04935 } 04936 BOOST_UBLAS_INLINE 04937 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION 04938 typename self_type:: 04939 #endif 04940 iterator1 end () const { 04941 return iterator1 ((*this) (), it1_ ().end (), it2_); 04942 } 04943 BOOST_UBLAS_INLINE 04944 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION 04945 typename self_type:: 04946 #endif 04947 reverse_iterator1 rbegin () const { 04948 return reverse_iterator1 (end ()); 04949 } 04950 BOOST_UBLAS_INLINE 04951 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION 04952 typename self_type:: 04953 #endif 04954 reverse_iterator1 rend () const { 04955 return reverse_iterator1 (begin ()); 04956 } 04957 #endif 04958 04959 // Indices 04960 BOOST_UBLAS_INLINE 04961 size_type index1 () const { 04962 return it1_.index (); 04963 } 04964 BOOST_UBLAS_INLINE 04965 size_type index2 () const { 04966 return it2_.index (); 04967 } 04968 04969 // Assignment 04970 BOOST_UBLAS_INLINE 04971 iterator2 &operator = (const iterator2 &it) { 04972 container_reference<self_type>::assign (&it ()); 04973 it1_ = it.it1_; 04974 it2_ = it.it2_; 04975 return *this; 04976 } 04977 04978 // Comparison 04979 BOOST_UBLAS_INLINE 04980 bool operator == (const iterator2 &it) const { 04981 BOOST_UBLAS_CHECK ((*this) ().same_closure (it ()), external_logic ()); 04982 BOOST_UBLAS_CHECK (it1_ == it.it1_, external_logic ()); 04983 return it2_ == it.it2_; 04984 } 04985 BOOST_UBLAS_INLINE 04986 bool operator < (const iterator2 &it) const { 04987 BOOST_UBLAS_CHECK ((*this) ().same_closure (it ()), external_logic ()); 04988 BOOST_UBLAS_CHECK (it1_ == it.it1_, external_logic ()); 04989 return it2_ < it.it2_; 04990 } 04991 04992 private: 04993 subiterator1_type it1_; 04994 subiterator2_type it2_; 04995 04996 friend class const_iterator2; 04997 }; 04998 #endif 04999 05000 BOOST_UBLAS_INLINE 05001 iterator2 begin2 () { 05002 return find2 (0, 0, 0); 05003 } 05004 BOOST_UBLAS_INLINE 05005 iterator2 end2 () { 05006 return find2 (0, 0, size2 ()); 05007 } 05008 05009 // Reverse iterators 05010 05011 BOOST_UBLAS_INLINE 05012 const_reverse_iterator1 rbegin1 () const { 05013 return const_reverse_iterator1 (end1 ()); 05014 } 05015 BOOST_UBLAS_INLINE 05016 const_reverse_iterator1 rend1 () const { 05017 return const_reverse_iterator1 (begin1 ()); 05018 } 05019 05020 BOOST_UBLAS_INLINE 05021 reverse_iterator1 rbegin1 () { 05022 return reverse_iterator1 (end1 ()); 05023 } 05024 BOOST_UBLAS_INLINE 05025 reverse_iterator1 rend1 () { 05026 return reverse_iterator1 (begin1 ()); 05027 } 05028 05029 BOOST_UBLAS_INLINE 05030 const_reverse_iterator2 rbegin2 () const { 05031 return const_reverse_iterator2 (end2 ()); 05032 } 05033 BOOST_UBLAS_INLINE 05034 const_reverse_iterator2 rend2 () const { 05035 return const_reverse_iterator2 (begin2 ()); 05036 } 05037 05038 BOOST_UBLAS_INLINE 05039 reverse_iterator2 rbegin2 () { 05040 return reverse_iterator2 (end2 ()); 05041 } 05042 BOOST_UBLAS_INLINE 05043 reverse_iterator2 rend2 () { 05044 return reverse_iterator2 (begin2 ()); 05045 } 05046 05047 private: 05048 matrix_closure_type data_; 05049 indirect_array_type ia1_; 05050 indirect_array_type ia2_; 05051 }; 05052 05053 // Projections 05054 template<class M, class A> 05055 BOOST_UBLAS_INLINE 05056 matrix_indirect<M, indirect_array<A> > project (M &data, const indirect_array<A> &ia1, const indirect_array<A> &ia2) { 05057 return matrix_indirect<M, indirect_array<A> > (data, ia1, ia2); 05058 } 05059 template<class M, class A> 05060 BOOST_UBLAS_INLINE 05061 const matrix_indirect<const M, indirect_array<A> > project (const M &data, const indirect_array<A> &ia1, const indirect_array<A> &ia2) { 05062 // ISSUE was: return matrix_indirect<M, indirect_array<A> > (const_cast<M &> (data), ia1, ia2); 05063 return matrix_indirect<const M, indirect_array<A> > (data, ia1, ia2); 05064 } 05065 template<class M, class IA> 05066 BOOST_UBLAS_INLINE 05067 matrix_indirect<M, IA> project (matrix_indirect<M, IA> &data, const typename matrix_indirect<M, IA>::range_type &r1, const typename matrix_indirect<M, IA>::range_type &r2) { 05068 return data.project (r1, r2); 05069 } 05070 template<class M, class IA> 05071 BOOST_UBLAS_INLINE 05072 const matrix_indirect<M, IA> project (const matrix_indirect<M, IA> &data, const typename matrix_indirect<M, IA>::range_type &r1, const typename matrix_indirect<M, IA>::range_type &r2) { 05073 return data.project (r1, r2); 05074 } 05075 template<class M, class IA> 05076 BOOST_UBLAS_INLINE 05077 matrix_indirect<M, IA> project (matrix_indirect<M, IA> &data, const typename matrix_indirect<M, IA>::slice_type &s1, const typename matrix_indirect<M, IA>::slice_type &s2) { 05078 return data.project (s1, s2); 05079 } 05080 template<class M, class IA> 05081 BOOST_UBLAS_INLINE 05082 const matrix_indirect<M, IA> project (const matrix_indirect<M, IA> &data, const typename matrix_indirect<M, IA>::slice_type &s1, const typename matrix_indirect<M, IA>::slice_type &s2) { 05083 return data.project (s1, s2); 05084 } 05085 template<class M, class A> 05086 BOOST_UBLAS_INLINE 05087 matrix_indirect<M, indirect_array<A> > project (matrix_indirect<M, indirect_array<A> > &data, const indirect_array<A> &ia1, const indirect_array<A> &ia2) { 05088 return data.project (ia1, ia2); 05089 } 05090 template<class M, class A> 05091 BOOST_UBLAS_INLINE 05092 const matrix_indirect<M, indirect_array<A> > project (const matrix_indirect<M, indirect_array<A> > &data, const indirect_array<A> &ia1, const indirect_array<A> &ia2) { 05093 return data.project (ia1, ia2); 05094 } 05095 05097 template <class M> 05098 struct matrix_temporary_traits< matrix_indirect<M> > 05099 : matrix_temporary_traits< M > {}; 05100 template <class M> 05101 struct matrix_temporary_traits< const matrix_indirect<M> > 05102 : matrix_temporary_traits< M > {}; 05103 05104 template <class M> 05105 struct vector_temporary_traits< matrix_indirect<M> > 05106 : vector_temporary_traits< M > {}; 05107 template <class M> 05108 struct vector_temporary_traits< const matrix_indirect<M> > 05109 : vector_temporary_traits< M > {}; 05110 05111 }}} 05112 05113 #endif