00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
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
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
00053 BOOST_UBLAS_INLINE
00054 matrix_row (matrix_type &data, size_type i):
00055 data_ (data), i_ (i) {
00056
00057
00058 }
00059
00060
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
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
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
00112 BOOST_UBLAS_INLINE
00113 matrix_row &operator = (const matrix_row &mr) {
00114
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
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
00174 BOOST_UBLAS_INLINE
00175 bool same_closure (const matrix_row &mr) const {
00176 return (*this).data_.same_closure (mr.data_);
00177 }
00178
00179
00180 BOOST_UBLAS_INLINE
00181 bool operator == (const matrix_row &mr) const {
00182 return (*this).data_ == mr.data_ && index () == mr.index ();
00183 }
00184
00185
00186 BOOST_UBLAS_INLINE
00187 void swap (matrix_row mr) {
00188 if (this != &mr) {
00189 BOOST_UBLAS_CHECK (size () == mr.size (), bad_size ());
00190
00191
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
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
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
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):
00258 container_const_reference<self_type> (it ()), it_ (it.it_) {}
00259
00260
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
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
00299 BOOST_UBLAS_INLINE
00300 size_type index () const {
00301 return it_.index2 ();
00302 }
00303
00304
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
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
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
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
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
00396 BOOST_UBLAS_INLINE
00397 size_type index () const {
00398 return it_.index2 ();
00399 }
00400
00401
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
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
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
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
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
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
00510 BOOST_UBLAS_INLINE
00511 matrix_column (matrix_type &data, size_type j):
00512 data_ (data), j_ (j) {
00513
00514
00515 }
00516
00517
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
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
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
00569 BOOST_UBLAS_INLINE
00570 matrix_column &operator = (const matrix_column &mc) {
00571
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
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
00631 BOOST_UBLAS_INLINE
00632 bool same_closure (const matrix_column &mc) const {
00633 return (*this).data_.same_closure (mc.data_);
00634 }
00635
00636
00637 BOOST_UBLAS_INLINE
00638 bool operator == (const matrix_column &mc) const {
00639 return (*this).data_ == mc.data_ && index () == mc.index ();
00640 }
00641
00642
00643 BOOST_UBLAS_INLINE
00644 void swap (matrix_column mc) {
00645 if (this != &mc) {
00646 BOOST_UBLAS_CHECK (size () == mc.size (), bad_size ());
00647
00648
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
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
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
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):
00715 container_const_reference<self_type> (it ()), it_ (it.it_) {}
00716
00717
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
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
00756 BOOST_UBLAS_INLINE
00757 size_type index () const {
00758 return it_.index1 ();
00759 }
00760
00761
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
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
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
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
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
00853 BOOST_UBLAS_INLINE
00854 size_type index () const {
00855 return it_.index1 ();
00856 }
00857
00858
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
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
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
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
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
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
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
00971
00972
00973
00974
00975
00976 }
00977
00978
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
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
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
01034 BOOST_UBLAS_INLINE
01035 matrix_vector_range &operator = (const matrix_vector_range &mvr) {
01036
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
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
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
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
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
01113
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
01123 private:
01124
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
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
01150
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
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):
01167 container_const_reference<self_type> (it ()), it1_ (it.it1_), it2_ (it.it2_) {}
01168
01169
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
01201 BOOST_UBLAS_INLINE
01202 const_reference operator * () const {
01203
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
01212 BOOST_UBLAS_INLINE
01213 size_type index () const {
01214 return BOOST_UBLAS_SAME (it1_.index (), it2_.index ());
01215 }
01216
01217
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
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
01258
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
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
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
01306 BOOST_UBLAS_INLINE
01307 reference operator * () const {
01308
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
01317 BOOST_UBLAS_INLINE
01318 size_type index () const {
01319 return BOOST_UBLAS_SAME (it1_.index (), it2_.index ());
01320 }
01321
01322
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
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
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
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
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
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
01427
01428
01429
01430
01431 }
01432
01433
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
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
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
01497 BOOST_UBLAS_INLINE
01498 matrix_vector_slice &operator = (const matrix_vector_slice &mvs) {
01499
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
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
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
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
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
01576
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
01586 private:
01587
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
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
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
01615
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
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):
01632 container_const_reference<self_type> (it ()), it1_ (it.it1_), it2_ (it.it2_) {}
01633
01634
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
01666 BOOST_UBLAS_INLINE
01667 const_reference operator * () const {
01668
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
01677 BOOST_UBLAS_INLINE
01678 size_type index () const {
01679 return BOOST_UBLAS_SAME (it1_.index (), it2_.index ());
01680 }
01681
01682
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
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
01723
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
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
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
01771 BOOST_UBLAS_INLINE
01772 reference operator * () const {
01773
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
01782 BOOST_UBLAS_INLINE
01783 size_type index () const {
01784 return BOOST_UBLAS_SAME (it1_.index (), it2_.index ());
01785 }
01786
01787
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
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
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
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
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
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
01895
01896 }
01897
01898
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
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
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
01962 BOOST_UBLAS_INLINE
01963 matrix_vector_indirect &operator = (const matrix_vector_indirect &mvi) {
01964
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
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
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
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
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
02041
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
02051 private:
02052
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
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
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
02080
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
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):
02097 container_const_reference<self_type> (it ()), it1_ (it.it1_), it2_ (it.it2_) {}
02098
02099
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
02131 BOOST_UBLAS_INLINE
02132 const_reference operator * () const {
02133
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
02142 BOOST_UBLAS_INLINE
02143 size_type index () const {
02144 return BOOST_UBLAS_SAME (it1_.index (), it2_.index ());
02145 }
02146
02147
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
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
02188
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
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
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
02236 BOOST_UBLAS_INLINE
02237 reference operator * () const {
02238
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
02247 BOOST_UBLAS_INLINE
02248 size_type index () const {
02249 return BOOST_UBLAS_SAME (it1_.index (), it2_.index ());
02250 }
02251
02252
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
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
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
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
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
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
02357
02358
02359
02360
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
02366
02367
02368
02369
02370 }
02371
02372
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
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
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
02418
02419
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
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
02485 BOOST_UBLAS_INLINE
02486 bool same_closure (const matrix_range &mr) const {
02487 return (*this).data_.same_closure (mr.data_);
02488 }
02489
02490
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
03261
03262
03263
03264
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
03270
03271
03272
03273
03274 }
03275
03276
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
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
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
03330
03331
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
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
03401 BOOST_UBLAS_INLINE
03402 bool same_closure (const matrix_slice &ms) const {
03403 return (*this).data_.same_closure (ms.data_);
03404 }
03405
03406
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
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
03427 private:
03428
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
03456 BOOST_UBLAS_INLINE
03457 const_iterator1 find1 (int , 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 , 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 , 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 , 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
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;
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
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
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
03544 BOOST_UBLAS_INLINE
03545 const_reference operator * () const {
03546
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
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
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
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;
03642 typedef typename M::iterator1::pointer pointer;
03643 typedef iterator2 dual_iterator_type;
03644 typedef reverse_iterator2 dual_reverse_iterator_type;
03645
03646
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
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
03683 BOOST_UBLAS_INLINE
03684 reference operator * () const {
03685
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
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
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
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;
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
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
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
03827 BOOST_UBLAS_INLINE
03828 const_reference operator * () const {
03829
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
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
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
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;
03925 typedef typename M::iterator2::pointer pointer;
03926 typedef iterator1 dual_iterator_type;
03927 typedef reverse_iterator1 dual_reverse_iterator_type;
03928
03929
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
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
03966 BOOST_UBLAS_INLINE
03967 reference operator * () const {
03968
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
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
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
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
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
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
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
04125 return matrix_slice<const M> (data, s1, s2);
04126 }
04127
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
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
04165
04166
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
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
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
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
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
04279
04280
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
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
04354 BOOST_UBLAS_INLINE
04355 bool same_closure (const matrix_indirect &mi) const {
04356 return (*this).data_.same_closure (mi.data_);
04357 }
04358
04359
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
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
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
04408 BOOST_UBLAS_INLINE
04409 const_iterator1 find1 (int , 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 , 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 , 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 , 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
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;
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
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
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
04496 BOOST_UBLAS_INLINE
04497 const_reference operator * () const {
04498
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
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
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
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;
04594 typedef typename M::iterator1::pointer pointer;
04595 typedef iterator2 dual_iterator_type;
04596 typedef reverse_iterator2 dual_reverse_iterator_type;
04597
04598
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
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
04635 BOOST_UBLAS_INLINE
04636 reference operator * () const {
04637
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
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
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
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;
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
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
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
04779 BOOST_UBLAS_INLINE
04780 const_reference operator * () const {
04781
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
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
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
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;
04877 typedef typename M::iterator2::pointer pointer;
04878 typedef iterator1 dual_iterator_type;
04879 typedef reverse_iterator1 dual_reverse_iterator_type;
04880
04881
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
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
04918 BOOST_UBLAS_INLINE
04919 reference operator * () const {
04920
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
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
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
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
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
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
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