00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013 #ifndef _BOOST_UBLAS_VECTOR_PROXY_
00014 #define _BOOST_UBLAS_VECTOR_PROXY_
00015
00016 #include <boost/numeric/ublas/vector_expression.hpp>
00017 #include <boost/numeric/ublas/detail/vector_assign.hpp>
00018 #include <boost/numeric/ublas/detail/temporary.hpp>
00019
00020
00021
00022 namespace boost { namespace numeric { namespace ublas {
00023
00033 template<class V>
00034 class vector_range:
00035 public vector_expression<vector_range<V> > {
00036
00037 typedef vector_range<V> self_type;
00038 public:
00039 #ifdef BOOST_UBLAS_ENABLE_PROXY_SHORTCUTS
00040 using vector_expression<self_type>::operator ();
00041 #endif
00042 typedef const V const_vector_type;
00043 typedef V vector_type;
00044 typedef typename V::size_type size_type;
00045 typedef typename V::difference_type difference_type;
00046 typedef typename V::value_type value_type;
00047 typedef typename V::const_reference const_reference;
00048 typedef typename boost::mpl::if_<boost::is_const<V>,
00049 typename V::const_reference,
00050 typename V::reference>::type reference;
00051 typedef typename boost::mpl::if_<boost::is_const<V>,
00052 typename V::const_closure_type,
00053 typename V::closure_type>::type vector_closure_type;
00054 typedef basic_range<size_type, difference_type> range_type;
00055 typedef const self_type const_closure_type;
00056 typedef self_type closure_type;
00057 typedef typename storage_restrict_traits<typename V::storage_category,
00058 dense_proxy_tag>::storage_category storage_category;
00059
00060
00061 BOOST_UBLAS_INLINE
00062 vector_range (vector_type &data, const range_type &r):
00063 data_ (data), r_ (r.preprocess (data.size ())) {
00064
00065
00066
00067 }
00068 BOOST_UBLAS_INLINE
00069 vector_range (const vector_closure_type &data, const range_type &r, bool):
00070 data_ (data), r_ (r.preprocess (data.size ())) {
00071
00072
00073
00074 }
00075
00076
00077 BOOST_UBLAS_INLINE
00078 size_type start () const {
00079 return r_.start ();
00080 }
00081 BOOST_UBLAS_INLINE
00082 size_type size () const {
00083 return r_.size ();
00084 }
00085
00086
00087 BOOST_UBLAS_INLINE
00088 const vector_closure_type &data () const {
00089 return data_;
00090 }
00091 BOOST_UBLAS_INLINE
00092 vector_closure_type &data () {
00093 return data_;
00094 }
00095
00096
00097 #ifndef BOOST_UBLAS_PROXY_CONST_MEMBER
00098 BOOST_UBLAS_INLINE
00099 const_reference operator () (size_type i) const {
00100 return data_ (r_ (i));
00101 }
00102 BOOST_UBLAS_INLINE
00103 reference operator () (size_type i) {
00104 return data_ (r_ (i));
00105 }
00106
00107 BOOST_UBLAS_INLINE
00108 const_reference operator [] (size_type i) const {
00109 return (*this) (i);
00110 }
00111 BOOST_UBLAS_INLINE
00112 reference operator [] (size_type i) {
00113 return (*this) (i);
00114 }
00115 #else
00116 BOOST_UBLAS_INLINE
00117 reference operator () (size_type i) const {
00118 return data_ (r_ (i));
00119 }
00120
00121 BOOST_UBLAS_INLINE
00122 reference operator [] (size_type i) const {
00123 return (*this) (i);
00124 }
00125 #endif
00126
00127
00128
00129
00130 BOOST_UBLAS_INLINE
00131 vector_range<vector_type> project (const range_type &r) const {
00132 return vector_range<vector_type> (data_, r_.compose (r.preprocess (data_.size ())), false);
00133 }
00134
00135
00136 BOOST_UBLAS_INLINE
00137 vector_range &operator = (const vector_range &vr) {
00138
00139 vector_assign<scalar_assign> (*this, typename vector_temporary_traits<V>::type (vr));
00140 return *this;
00141 }
00142 BOOST_UBLAS_INLINE
00143 vector_range &assign_temporary (vector_range &vr) {
00144
00145 vector_assign<scalar_assign> (*this, vr);
00146 return *this;
00147 }
00148 template<class AE>
00149 BOOST_UBLAS_INLINE
00150 vector_range &operator = (const vector_expression<AE> &ae) {
00151 vector_assign<scalar_assign> (*this, typename vector_temporary_traits<V>::type (ae));
00152 return *this;
00153 }
00154 template<class AE>
00155 BOOST_UBLAS_INLINE
00156 vector_range &assign (const vector_expression<AE> &ae) {
00157 vector_assign<scalar_assign> (*this, ae);
00158 return *this;
00159 }
00160 template<class AE>
00161 BOOST_UBLAS_INLINE
00162 vector_range &operator += (const vector_expression<AE> &ae) {
00163 vector_assign<scalar_assign> (*this, typename vector_temporary_traits<V>::type (*this + ae));
00164 return *this;
00165 }
00166 template<class AE>
00167 BOOST_UBLAS_INLINE
00168 vector_range &plus_assign (const vector_expression<AE> &ae) {
00169 vector_assign<scalar_plus_assign> (*this, ae);
00170 return *this;
00171 }
00172 template<class AE>
00173 BOOST_UBLAS_INLINE
00174 vector_range &operator -= (const vector_expression<AE> &ae) {
00175 vector_assign<scalar_assign> (*this, typename vector_temporary_traits<V>::type (*this - ae));
00176 return *this;
00177 }
00178 template<class AE>
00179 BOOST_UBLAS_INLINE
00180 vector_range &minus_assign (const vector_expression<AE> &ae) {
00181 vector_assign<scalar_minus_assign> (*this, ae);
00182 return *this;
00183 }
00184 template<class AT>
00185 BOOST_UBLAS_INLINE
00186 vector_range &operator *= (const AT &at) {
00187 vector_assign_scalar<scalar_multiplies_assign> (*this, at);
00188 return *this;
00189 }
00190 template<class AT>
00191 BOOST_UBLAS_INLINE
00192 vector_range &operator /= (const AT &at) {
00193 vector_assign_scalar<scalar_divides_assign> (*this, at);
00194 return *this;
00195 }
00196
00197
00198 BOOST_UBLAS_INLINE
00199 bool same_closure (const vector_range &vr) const {
00200 return (*this).data_.same_closure (vr.data_);
00201 }
00202
00203
00204 BOOST_UBLAS_INLINE
00205 bool operator == (const vector_range &vr) const {
00206 return (*this).data_ == vr.data_ && r_ == vr.r_;
00207 }
00208
00209
00210 BOOST_UBLAS_INLINE
00211 void swap (vector_range vr) {
00212 if (this != &vr) {
00213 BOOST_UBLAS_CHECK (size () == vr.size (), bad_size ());
00214
00215
00216 vector_swap<scalar_swap> (*this, vr);
00217 }
00218 }
00219 BOOST_UBLAS_INLINE
00220 friend void swap (vector_range vr1, vector_range vr2) {
00221 vr1.swap (vr2);
00222 }
00223
00224
00225 private:
00226 typedef typename V::const_iterator const_subiterator_type;
00227 typedef typename boost::mpl::if_<boost::is_const<V>,
00228 typename V::const_iterator,
00229 typename V::iterator>::type subiterator_type;
00230
00231 public:
00232 #ifdef BOOST_UBLAS_USE_INDEXED_ITERATOR
00233 typedef indexed_iterator<vector_range<vector_type>,
00234 typename subiterator_type::iterator_category> iterator;
00235 typedef indexed_const_iterator<vector_range<vector_type>,
00236 typename const_subiterator_type::iterator_category> const_iterator;
00237 #else
00238 class const_iterator;
00239 class iterator;
00240 #endif
00241
00242
00243 BOOST_UBLAS_INLINE
00244 const_iterator find (size_type i) const {
00245 const_subiterator_type it (data_.find (start () + i));
00246 #ifdef BOOST_UBLAS_USE_INDEXED_ITERATOR
00247 return const_iterator (*this, it.index ());
00248 #else
00249 return const_iterator (*this, it);
00250 #endif
00251 }
00252 BOOST_UBLAS_INLINE
00253 iterator find (size_type i) {
00254 subiterator_type it (data_.find (start () + i));
00255 #ifdef BOOST_UBLAS_USE_INDEXED_ITERATOR
00256 return iterator (*this, it.index ());
00257 #else
00258 return iterator (*this, it);
00259 #endif
00260 }
00261
00262 #ifndef BOOST_UBLAS_USE_INDEXED_ITERATOR
00263 class const_iterator:
00264 public container_const_reference<vector_range>,
00265 public iterator_base_traits<typename const_subiterator_type::iterator_category>::template
00266 iterator_base<const_iterator, value_type>::type {
00267 public:
00268 typedef typename const_subiterator_type::difference_type difference_type;
00269 typedef typename const_subiterator_type::value_type value_type;
00270 typedef typename const_subiterator_type::reference reference;
00271 typedef typename const_subiterator_type::pointer pointer;
00272
00273
00274 BOOST_UBLAS_INLINE
00275 const_iterator ():
00276 container_const_reference<self_type> (), it_ () {}
00277 BOOST_UBLAS_INLINE
00278 const_iterator (const self_type &vr, const const_subiterator_type &it):
00279 container_const_reference<self_type> (vr), it_ (it) {}
00280 BOOST_UBLAS_INLINE
00281 const_iterator (const typename self_type::iterator &it):
00282 container_const_reference<self_type> (it ()), it_ (it.it_) {}
00283
00284
00285 BOOST_UBLAS_INLINE
00286 const_iterator &operator ++ () {
00287 ++ it_;
00288 return *this;
00289 }
00290 BOOST_UBLAS_INLINE
00291 const_iterator &operator -- () {
00292 -- it_;
00293 return *this;
00294 }
00295 BOOST_UBLAS_INLINE
00296 const_iterator &operator += (difference_type n) {
00297 it_ += n;
00298 return *this;
00299 }
00300 BOOST_UBLAS_INLINE
00301 const_iterator &operator -= (difference_type n) {
00302 it_ -= n;
00303 return *this;
00304 }
00305 BOOST_UBLAS_INLINE
00306 difference_type operator - (const const_iterator &it) const {
00307 BOOST_UBLAS_CHECK ((*this) ().same_closure (it ()), external_logic ());
00308 return it_ - it.it_;
00309 }
00310
00311
00312 BOOST_UBLAS_INLINE
00313 const_reference operator * () const {
00314 BOOST_UBLAS_CHECK (index () < (*this) ().size (), bad_index ());
00315 return *it_;
00316 }
00317 BOOST_UBLAS_INLINE
00318 const_reference operator [] (difference_type n) const {
00319 return *(*this + n);
00320 }
00321
00322
00323 BOOST_UBLAS_INLINE
00324 size_type index () const {
00325 return it_.index () - (*this) ().start ();
00326 }
00327
00328
00329 BOOST_UBLAS_INLINE
00330 const_iterator &operator = (const const_iterator &it) {
00331 container_const_reference<self_type>::assign (&it ());
00332 it_ = it.it_;
00333 return *this;
00334 }
00335
00336
00337 BOOST_UBLAS_INLINE
00338 bool operator == (const const_iterator &it) const {
00339 BOOST_UBLAS_CHECK ((*this) ().same_closure (it ()), external_logic ());
00340 return it_ == it.it_;
00341 }
00342 BOOST_UBLAS_INLINE
00343 bool operator < (const const_iterator &it) const {
00344 BOOST_UBLAS_CHECK ((*this) ().same_closure (it ()), external_logic ());
00345 return it_ < it.it_;
00346 }
00347
00348 private:
00349 const_subiterator_type it_;
00350 };
00351 #endif
00352
00353 BOOST_UBLAS_INLINE
00354 const_iterator begin () const {
00355 return find (0);
00356 }
00357 BOOST_UBLAS_INLINE
00358 const_iterator end () const {
00359 return find (size ());
00360 }
00361
00362 #ifndef BOOST_UBLAS_USE_INDEXED_ITERATOR
00363 class iterator:
00364 public container_reference<vector_range>,
00365 public iterator_base_traits<typename subiterator_type::iterator_category>::template
00366 iterator_base<iterator, value_type>::type {
00367 public:
00368 typedef typename subiterator_type::difference_type difference_type;
00369 typedef typename subiterator_type::value_type value_type;
00370 typedef typename subiterator_type::reference reference;
00371 typedef typename subiterator_type::pointer pointer;
00372
00373
00374 BOOST_UBLAS_INLINE
00375 iterator ():
00376 container_reference<self_type> (), it_ () {}
00377 BOOST_UBLAS_INLINE
00378 iterator (self_type &vr, const subiterator_type &it):
00379 container_reference<self_type> (vr), it_ (it) {}
00380
00381
00382 BOOST_UBLAS_INLINE
00383 iterator &operator ++ () {
00384 ++ it_;
00385 return *this;
00386 }
00387 BOOST_UBLAS_INLINE
00388 iterator &operator -- () {
00389 -- it_;
00390 return *this;
00391 }
00392 BOOST_UBLAS_INLINE
00393 iterator &operator += (difference_type n) {
00394 it_ += n;
00395 return *this;
00396 }
00397 BOOST_UBLAS_INLINE
00398 iterator &operator -= (difference_type n) {
00399 it_ -= n;
00400 return *this;
00401 }
00402 BOOST_UBLAS_INLINE
00403 difference_type operator - (const iterator &it) const {
00404 BOOST_UBLAS_CHECK ((*this) ().same_closure (it ()), external_logic ());
00405 return it_ - it.it_;
00406 }
00407
00408
00409 BOOST_UBLAS_INLINE
00410 reference operator * () const {
00411 BOOST_UBLAS_CHECK (index () < (*this) ().size (), bad_index ());
00412 return *it_;
00413 }
00414 BOOST_UBLAS_INLINE
00415 reference operator [] (difference_type n) const {
00416 return *(*this + n);
00417 }
00418
00419
00420 BOOST_UBLAS_INLINE
00421 size_type index () const {
00422 return it_.index () - (*this) ().start ();
00423 }
00424
00425
00426 BOOST_UBLAS_INLINE
00427 iterator &operator = (const iterator &it) {
00428 container_reference<self_type>::assign (&it ());
00429 it_ = it.it_;
00430 return *this;
00431 }
00432
00433
00434 BOOST_UBLAS_INLINE
00435 bool operator == (const iterator &it) const {
00436 BOOST_UBLAS_CHECK ((*this) ().same_closure (it ()), external_logic ());
00437 return it_ == it.it_;
00438 }
00439 BOOST_UBLAS_INLINE
00440 bool operator < (const iterator &it) const {
00441 BOOST_UBLAS_CHECK ((*this) ().same_closure (it ()), external_logic ());
00442 return it_ < it.it_;
00443 }
00444
00445 private:
00446 subiterator_type it_;
00447
00448 friend class const_iterator;
00449 };
00450 #endif
00451
00452 BOOST_UBLAS_INLINE
00453 iterator begin () {
00454 return find (0);
00455 }
00456 BOOST_UBLAS_INLINE
00457 iterator end () {
00458 return find (size ());
00459 }
00460
00461
00462 typedef reverse_iterator_base<const_iterator> const_reverse_iterator;
00463 typedef reverse_iterator_base<iterator> reverse_iterator;
00464
00465 BOOST_UBLAS_INLINE
00466 const_reverse_iterator rbegin () const {
00467 return const_reverse_iterator (end ());
00468 }
00469 BOOST_UBLAS_INLINE
00470 const_reverse_iterator rend () const {
00471 return const_reverse_iterator (begin ());
00472 }
00473 BOOST_UBLAS_INLINE
00474 reverse_iterator rbegin () {
00475 return reverse_iterator (end ());
00476 }
00477 BOOST_UBLAS_INLINE
00478 reverse_iterator rend () {
00479 return reverse_iterator (begin ());
00480 }
00481
00482 private:
00483 vector_closure_type data_;
00484 range_type r_;
00485 };
00486
00487
00488
00489
00490
00496 template<class V>
00497 BOOST_UBLAS_INLINE
00498 vector_range<V> subrange (V &data, typename V::size_type start, typename V::size_type stop) {
00499 typedef basic_range<typename V::size_type, typename V::difference_type> range_type;
00500 return vector_range<V> (data, range_type (start, stop));
00501 }
00502
00508 template<class V>
00509 BOOST_UBLAS_INLINE
00510 vector_range<const V> subrange (const V &data, typename V::size_type start, typename V::size_type stop) {
00511 typedef basic_range<typename V::size_type, typename V::difference_type> range_type;
00512 return vector_range<const V> (data, range_type (start, stop));
00513 }
00514
00515
00516
00517
00518
00524 template<class V>
00525 BOOST_UBLAS_INLINE
00526 vector_range<V> project (V &data, typename vector_range<V>::range_type const &r) {
00527 return vector_range<V> (data, r);
00528 }
00529
00535 template<class V>
00536 BOOST_UBLAS_INLINE
00537 const vector_range<const V> project (const V &data, typename vector_range<V>::range_type const &r) {
00538
00539 return vector_range<const V> (data, r);
00540 }
00541
00547 template<class V>
00548 BOOST_UBLAS_INLINE
00549 vector_range<V> project (vector_range<V> &data, const typename vector_range<V>::range_type &r) {
00550 return data.project (r);
00551 }
00552
00558 template<class V>
00559 BOOST_UBLAS_INLINE
00560 const vector_range<V> project (const vector_range<V> &data, const typename vector_range<V>::range_type &r) {
00561 return data.project (r);
00562 }
00563
00564
00565 template <class V>
00566 struct vector_temporary_traits< vector_range<V> >
00567 : vector_temporary_traits< V > {} ;
00568 template <class V>
00569 struct vector_temporary_traits< const vector_range<V> >
00570 : vector_temporary_traits< V > {} ;
00571
00572
00587 template<class V>
00588 class vector_slice:
00589 public vector_expression<vector_slice<V> > {
00590
00591 typedef vector_slice<V> self_type;
00592 public:
00593 #ifdef BOOST_UBLAS_ENABLE_PROXY_SHORTCUTS
00594 using vector_expression<self_type>::operator ();
00595 #endif
00596 typedef const V const_vector_type;
00597 typedef V vector_type;
00598 typedef typename V::size_type size_type;
00599 typedef typename V::difference_type difference_type;
00600 typedef typename V::value_type value_type;
00601 typedef typename V::const_reference const_reference;
00602 typedef typename boost::mpl::if_<boost::is_const<V>,
00603 typename V::const_reference,
00604 typename V::reference>::type reference;
00605 typedef typename boost::mpl::if_<boost::is_const<V>,
00606 typename V::const_closure_type,
00607 typename V::closure_type>::type vector_closure_type;
00608 typedef basic_range<size_type, difference_type> range_type;
00609 typedef basic_slice<size_type, difference_type> slice_type;
00610 typedef const self_type const_closure_type;
00611 typedef self_type closure_type;
00612 typedef typename storage_restrict_traits<typename V::storage_category,
00613 dense_proxy_tag>::storage_category storage_category;
00614
00615
00616 BOOST_UBLAS_INLINE
00617 vector_slice (vector_type &data, const slice_type &s):
00618 data_ (data), s_ (s.preprocess (data.size ())) {
00619
00620
00621
00622 }
00623 BOOST_UBLAS_INLINE
00624 vector_slice (const vector_closure_type &data, const slice_type &s, int):
00625 data_ (data), s_ (s.preprocess (data.size ())) {
00626
00627
00628
00629 }
00630
00631
00632 BOOST_UBLAS_INLINE
00633 size_type start () const {
00634 return s_.start ();
00635 }
00636 BOOST_UBLAS_INLINE
00637 difference_type stride () const {
00638 return s_.stride ();
00639 }
00640 BOOST_UBLAS_INLINE
00641 size_type size () const {
00642 return s_.size ();
00643 }
00644
00645
00646 BOOST_UBLAS_INLINE
00647 const vector_closure_type &data () const {
00648 return data_;
00649 }
00650 BOOST_UBLAS_INLINE
00651 vector_closure_type &data () {
00652 return data_;
00653 }
00654
00655
00656 #ifndef BOOST_UBLAS_PROXY_CONST_MEMBER
00657 BOOST_UBLAS_INLINE
00658 const_reference operator () (size_type i) const {
00659 return data_ (s_ (i));
00660 }
00661 BOOST_UBLAS_INLINE
00662 reference operator () (size_type i) {
00663 return data_ (s_ (i));
00664 }
00665
00666 BOOST_UBLAS_INLINE
00667 const_reference operator [] (size_type i) const {
00668 return (*this) (i);
00669 }
00670 BOOST_UBLAS_INLINE
00671 reference operator [] (size_type i) {
00672 return (*this) (i);
00673 }
00674 #else
00675 BOOST_UBLAS_INLINE
00676 reference operator () (size_type i) const {
00677 return data_ (s_ (i));
00678 }
00679
00680 BOOST_UBLAS_INLINE
00681 reference operator [] (size_type i) const {
00682 return (*this) (i);
00683 }
00684 #endif
00685
00686
00687
00688
00689 BOOST_UBLAS_INLINE
00690 vector_slice<vector_type> project (const range_type &r) const {
00691 return vector_slice<vector_type> (data_, s_.compose (r.preprocess (data_.size ())), false);
00692 }
00693 BOOST_UBLAS_INLINE
00694 vector_slice<vector_type> project (const slice_type &s) const {
00695 return vector_slice<vector_type> (data_, s_.compose (s.preprocess (data_.size ())), false);
00696 }
00697
00698
00699 BOOST_UBLAS_INLINE
00700 vector_slice &operator = (const vector_slice &vs) {
00701
00702 vector_assign<scalar_assign> (*this, typename vector_temporary_traits<V>::type (vs));
00703 return *this;
00704 }
00705 BOOST_UBLAS_INLINE
00706 vector_slice &assign_temporary (vector_slice &vs) {
00707
00708 vector_assign<scalar_assign> (*this, vs);
00709 return *this;
00710 }
00711 template<class AE>
00712 BOOST_UBLAS_INLINE
00713 vector_slice &operator = (const vector_expression<AE> &ae) {
00714 vector_assign<scalar_assign> (*this, typename vector_temporary_traits<V>::type (ae));
00715 return *this;
00716 }
00717 template<class AE>
00718 BOOST_UBLAS_INLINE
00719 vector_slice &assign (const vector_expression<AE> &ae) {
00720 vector_assign<scalar_assign> (*this, ae);
00721 return *this;
00722 }
00723 template<class AE>
00724 BOOST_UBLAS_INLINE
00725 vector_slice &operator += (const vector_expression<AE> &ae) {
00726 vector_assign<scalar_assign> (*this, typename vector_temporary_traits<V>::type (*this + ae));
00727 return *this;
00728 }
00729 template<class AE>
00730 BOOST_UBLAS_INLINE
00731 vector_slice &plus_assign (const vector_expression<AE> &ae) {
00732 vector_assign<scalar_plus_assign> (*this, ae);
00733 return *this;
00734 }
00735 template<class AE>
00736 BOOST_UBLAS_INLINE
00737 vector_slice &operator -= (const vector_expression<AE> &ae) {
00738 vector_assign<scalar_assign> (*this, typename vector_temporary_traits<V>::type (*this - ae));
00739 return *this;
00740 }
00741 template<class AE>
00742 BOOST_UBLAS_INLINE
00743 vector_slice &minus_assign (const vector_expression<AE> &ae) {
00744 vector_assign<scalar_minus_assign> (*this, ae);
00745 return *this;
00746 }
00747 template<class AT>
00748 BOOST_UBLAS_INLINE
00749 vector_slice &operator *= (const AT &at) {
00750 vector_assign_scalar<scalar_multiplies_assign> (*this, at);
00751 return *this;
00752 }
00753 template<class AT>
00754 BOOST_UBLAS_INLINE
00755 vector_slice &operator /= (const AT &at) {
00756 vector_assign_scalar<scalar_divides_assign> (*this, at);
00757 return *this;
00758 }
00759
00760
00761 BOOST_UBLAS_INLINE
00762 bool same_closure (const vector_slice &vr) const {
00763 return (*this).data_.same_closure (vr.data_);
00764 }
00765
00766
00767 BOOST_UBLAS_INLINE
00768 bool operator == (const vector_slice &vs) const {
00769 return (*this).data_ == vs.data_ && s_ == vs.s_;
00770 }
00771
00772
00773 BOOST_UBLAS_INLINE
00774 void swap (vector_slice vs) {
00775 if (this != &vs) {
00776 BOOST_UBLAS_CHECK (size () == vs.size (), bad_size ());
00777
00778
00779 vector_swap<scalar_swap> (*this, vs);
00780 }
00781 }
00782 BOOST_UBLAS_INLINE
00783 friend void swap (vector_slice vs1, vector_slice vs2) {
00784 vs1.swap (vs2);
00785 }
00786
00787
00788 private:
00789
00790 typedef typename slice_type::const_iterator const_subiterator_type;
00791 typedef typename slice_type::const_iterator subiterator_type;
00792
00793 public:
00794 #ifdef BOOST_UBLAS_USE_INDEXED_ITERATOR
00795 typedef indexed_iterator<vector_slice<vector_type>,
00796 typename vector_type::iterator::iterator_category> iterator;
00797 typedef indexed_const_iterator<vector_slice<vector_type>,
00798 typename vector_type::const_iterator::iterator_category> const_iterator;
00799 #else
00800 class const_iterator;
00801 class iterator;
00802 #endif
00803
00804
00805 BOOST_UBLAS_INLINE
00806 const_iterator find (size_type i) const {
00807 #ifdef BOOST_UBLAS_USE_INDEXED_ITERATOR
00808 return const_iterator (*this, i);
00809 #else
00810 return const_iterator (*this, s_.begin () + i);
00811 #endif
00812 }
00813 BOOST_UBLAS_INLINE
00814 iterator find (size_type i) {
00815 #ifdef BOOST_UBLAS_USE_INDEXED_ITERATOR
00816 return iterator (*this, i);
00817 #else
00818 return iterator (*this, s_.begin () + i);
00819 #endif
00820 }
00821
00822 #ifndef BOOST_UBLAS_USE_INDEXED_ITERATOR
00823 class const_iterator:
00824 public container_const_reference<vector_slice>,
00825 public iterator_base_traits<typename V::const_iterator::iterator_category>::template
00826 iterator_base<const_iterator, value_type>::type {
00827 public:
00828 typedef typename V::const_iterator::difference_type difference_type;
00829 typedef typename V::const_iterator::value_type value_type;
00830 typedef typename V::const_reference reference;
00831 typedef typename V::const_iterator::pointer pointer;
00832
00833
00834 BOOST_UBLAS_INLINE
00835 const_iterator ():
00836 container_const_reference<self_type> (), it_ () {}
00837 BOOST_UBLAS_INLINE
00838 const_iterator (const self_type &vs, const const_subiterator_type &it):
00839 container_const_reference<self_type> (vs), it_ (it) {}
00840 BOOST_UBLAS_INLINE
00841 const_iterator (const typename self_type::iterator &it):
00842 container_const_reference<self_type> (it ()), it_ (it.it_) {}
00843
00844
00845 BOOST_UBLAS_INLINE
00846 const_iterator &operator ++ () {
00847 ++ it_;
00848 return *this;
00849 }
00850 BOOST_UBLAS_INLINE
00851 const_iterator &operator -- () {
00852 -- it_;
00853 return *this;
00854 }
00855 BOOST_UBLAS_INLINE
00856 const_iterator &operator += (difference_type n) {
00857 it_ += n;
00858 return *this;
00859 }
00860 BOOST_UBLAS_INLINE
00861 const_iterator &operator -= (difference_type n) {
00862 it_ -= n;
00863 return *this;
00864 }
00865 BOOST_UBLAS_INLINE
00866 difference_type operator - (const const_iterator &it) const {
00867 BOOST_UBLAS_CHECK ((*this) ().same_closure (it ()), external_logic ());
00868 return it_ - it.it_;
00869 }
00870
00871
00872 BOOST_UBLAS_INLINE
00873 const_reference operator * () const {
00874
00875 BOOST_UBLAS_CHECK (index () < (*this) ().size (), bad_index ());
00876 return (*this) ().data_ (*it_);
00877 }
00878 BOOST_UBLAS_INLINE
00879 const_reference operator [] (difference_type n) const {
00880 return *(*this + n);
00881 }
00882
00883
00884 BOOST_UBLAS_INLINE
00885 size_type index () const {
00886 return it_.index ();
00887 }
00888
00889
00890 BOOST_UBLAS_INLINE
00891 const_iterator &operator = (const const_iterator &it) {
00892 container_const_reference<self_type>::assign (&it ());
00893 it_ = it.it_;
00894 return *this;
00895 }
00896
00897
00898 BOOST_UBLAS_INLINE
00899 bool operator == (const const_iterator &it) const {
00900 BOOST_UBLAS_CHECK ((*this) ().same_closure (it ()), external_logic ());
00901 return it_ == it.it_;
00902 }
00903 BOOST_UBLAS_INLINE
00904 bool operator < (const const_iterator &it) const {
00905 BOOST_UBLAS_CHECK ((*this) ().same_closure (it ()), external_logic ());
00906 return it_ < it.it_;
00907 }
00908
00909 private:
00910 const_subiterator_type it_;
00911 };
00912 #endif
00913
00914 BOOST_UBLAS_INLINE
00915 const_iterator begin () const {
00916 return find (0);
00917 }
00918 BOOST_UBLAS_INLINE
00919 const_iterator end () const {
00920 return find (size ());
00921 }
00922
00923 #ifndef BOOST_UBLAS_USE_INDEXED_ITERATOR
00924 class iterator:
00925 public container_reference<vector_slice>,
00926 public iterator_base_traits<typename V::iterator::iterator_category>::template
00927 iterator_base<iterator, value_type>::type {
00928 public:
00929 typedef typename V::iterator::difference_type difference_type;
00930 typedef typename V::iterator::value_type value_type;
00931 typedef typename V::reference reference;
00932 typedef typename V::iterator::pointer pointer;
00933
00934
00935 BOOST_UBLAS_INLINE
00936 iterator ():
00937 container_reference<self_type> (), it_ () {}
00938 BOOST_UBLAS_INLINE
00939 iterator (self_type &vs, const subiterator_type &it):
00940 container_reference<self_type> (vs), it_ (it) {}
00941
00942
00943 BOOST_UBLAS_INLINE
00944 iterator &operator ++ () {
00945 ++ it_;
00946 return *this;
00947 }
00948 BOOST_UBLAS_INLINE
00949 iterator &operator -- () {
00950 -- it_;
00951 return *this;
00952 }
00953 BOOST_UBLAS_INLINE
00954 iterator &operator += (difference_type n) {
00955 it_ += n;
00956 return *this;
00957 }
00958 BOOST_UBLAS_INLINE
00959 iterator &operator -= (difference_type n) {
00960 it_ -= n;
00961 return *this;
00962 }
00963 BOOST_UBLAS_INLINE
00964 difference_type operator - (const iterator &it) const {
00965 BOOST_UBLAS_CHECK ((*this) ().same_closure (it ()), external_logic ());
00966 return it_ - it.it_;
00967 }
00968
00969
00970 BOOST_UBLAS_INLINE
00971 reference operator * () const {
00972
00973 BOOST_UBLAS_CHECK (index () < (*this) ().size (), bad_index ());
00974 return (*this) ().data_ (*it_);
00975 }
00976 BOOST_UBLAS_INLINE
00977 reference operator [] (difference_type n) const {
00978 return *(*this + n);
00979 }
00980
00981
00982
00983 BOOST_UBLAS_INLINE
00984 size_type index () const {
00985 return it_.index ();
00986 }
00987
00988
00989 BOOST_UBLAS_INLINE
00990 iterator &operator = (const iterator &it) {
00991 container_reference<self_type>::assign (&it ());
00992 it_ = it.it_;
00993 return *this;
00994 }
00995
00996
00997 BOOST_UBLAS_INLINE
00998 bool operator == (const iterator &it) const {
00999 BOOST_UBLAS_CHECK ((*this) ().same_closure (it ()), external_logic ());
01000 return it_ == it.it_;
01001 }
01002 BOOST_UBLAS_INLINE
01003 bool operator < (const iterator &it) const {
01004 BOOST_UBLAS_CHECK ((*this) ().same_closure (it ()), external_logic ());
01005 return it_ < it.it_;
01006 }
01007
01008 private:
01009 subiterator_type it_;
01010
01011 friend class const_iterator;
01012 };
01013 #endif
01014
01015 BOOST_UBLAS_INLINE
01016 iterator begin () {
01017 return find (0);
01018 }
01019 BOOST_UBLAS_INLINE
01020 iterator end () {
01021 return find (size ());
01022 }
01023
01024
01025 typedef reverse_iterator_base<const_iterator> const_reverse_iterator;
01026 typedef reverse_iterator_base<iterator> reverse_iterator;
01027
01028 BOOST_UBLAS_INLINE
01029 const_reverse_iterator rbegin () const {
01030 return const_reverse_iterator (end ());
01031 }
01032 BOOST_UBLAS_INLINE
01033 const_reverse_iterator rend () const {
01034 return const_reverse_iterator (begin ());
01035 }
01036 BOOST_UBLAS_INLINE
01037 reverse_iterator rbegin () {
01038 return reverse_iterator (end ());
01039 }
01040 BOOST_UBLAS_INLINE
01041 reverse_iterator rend () {
01042 return reverse_iterator (begin ());
01043 }
01044
01045 private:
01046 vector_closure_type data_;
01047 slice_type s_;
01048 };
01049
01050
01051 template<class V>
01052 BOOST_UBLAS_INLINE
01053 vector_slice<V> subslice (V &data, typename V::size_type start, typename V::difference_type stride, typename V::size_type size) {
01054 typedef basic_slice<typename V::size_type, typename V::difference_type> slice_type;
01055 return vector_slice<V> (data, slice_type (start, stride, size));
01056 }
01057 template<class V>
01058 BOOST_UBLAS_INLINE
01059 vector_slice<const V> subslice (const V &data, typename V::size_type start, typename V::difference_type stride, typename V::size_type size) {
01060 typedef basic_slice<typename V::size_type, typename V::difference_type> slice_type;
01061 return vector_slice<const V> (data, slice_type (start, stride, size));
01062 }
01063
01064
01065 template<class V>
01066 BOOST_UBLAS_INLINE
01067 vector_slice<V> project (V &data, const typename vector_slice<V>::slice_type &s) {
01068 return vector_slice<V> (data, s);
01069 }
01070 template<class V>
01071 BOOST_UBLAS_INLINE
01072 const vector_slice<const V> project (const V &data, const typename vector_slice<V>::slice_type &s) {
01073
01074 return vector_slice<const V> (data, s);
01075 }
01076 template<class V>
01077 BOOST_UBLAS_INLINE
01078 vector_slice<V> project (vector_slice<V> &data, const typename vector_slice<V>::slice_type &s) {
01079 return data.project (s);
01080 }
01081 template<class V>
01082 BOOST_UBLAS_INLINE
01083 const vector_slice<V> project (const vector_slice<V> &data, const typename vector_slice<V>::slice_type &s) {
01084 return data.project (s);
01085 }
01086
01087 template<class V>
01088 BOOST_UBLAS_INLINE
01089 vector_slice<V> project (vector_slice<V> &data, const typename vector_range<V>::range_type &r) {
01090 return data.project (r);
01091 }
01092 template<class V>
01093 BOOST_UBLAS_INLINE
01094 const vector_slice<V> project (const vector_slice<V> &data, const typename vector_range<V>::range_type &r) {
01095 return data.project (r);
01096 }
01097
01098
01099 template <class V>
01100 struct vector_temporary_traits< vector_slice<V> >
01101 : vector_temporary_traits< V > {} ;
01102 template <class V>
01103 struct vector_temporary_traits< const vector_slice<V> >
01104 : vector_temporary_traits< V > {} ;
01105
01106
01107
01108
01109
01110
01130 template<class V, class IA>
01131 class vector_indirect:
01132 public vector_expression<vector_indirect<V, IA> > {
01133
01134 typedef vector_indirect<V, IA> self_type;
01135 public:
01136 #ifdef BOOST_UBLAS_ENABLE_PROXY_SHORTCUTS
01137 using vector_expression<self_type>::operator ();
01138 #endif
01139 typedef const V const_vector_type;
01140 typedef V vector_type;
01141 typedef const IA const_indirect_array_type;
01142 typedef IA indirect_array_type;
01143 typedef typename V::size_type size_type;
01144 typedef typename V::difference_type difference_type;
01145 typedef typename V::value_type value_type;
01146 typedef typename V::const_reference const_reference;
01147 typedef typename boost::mpl::if_<boost::is_const<V>,
01148 typename V::const_reference,
01149 typename V::reference>::type reference;
01150 typedef typename boost::mpl::if_<boost::is_const<V>,
01151 typename V::const_closure_type,
01152 typename V::closure_type>::type vector_closure_type;
01153 typedef basic_range<size_type, difference_type> range_type;
01154 typedef basic_slice<size_type, difference_type> slice_type;
01155 typedef const self_type const_closure_type;
01156 typedef self_type closure_type;
01157 typedef typename storage_restrict_traits<typename V::storage_category,
01158 dense_proxy_tag>::storage_category storage_category;
01159
01160
01161 BOOST_UBLAS_INLINE
01162 vector_indirect (vector_type &data, size_type size):
01163 data_ (data), ia_ (size) {}
01164 BOOST_UBLAS_INLINE
01165 vector_indirect (vector_type &data, const indirect_array_type &ia):
01166 data_ (data), ia_ (ia.preprocess (data.size ())) {}
01167 BOOST_UBLAS_INLINE
01168 vector_indirect (const vector_closure_type &data, const indirect_array_type &ia, int):
01169 data_ (data), ia_ (ia.preprocess (data.size ())) {}
01170
01171
01172 BOOST_UBLAS_INLINE
01173 size_type size () const {
01174 return ia_.size ();
01175 }
01176 BOOST_UBLAS_INLINE
01177 const_indirect_array_type &indirect () const {
01178 return ia_;
01179 }
01180 BOOST_UBLAS_INLINE
01181 indirect_array_type &indirect () {
01182 return ia_;
01183 }
01184
01185
01186 BOOST_UBLAS_INLINE
01187 const vector_closure_type &data () const {
01188 return data_;
01189 }
01190 BOOST_UBLAS_INLINE
01191 vector_closure_type &data () {
01192 return data_;
01193 }
01194
01195
01196 #ifndef BOOST_UBLAS_PROXY_CONST_MEMBER
01197 BOOST_UBLAS_INLINE
01198 const_reference operator () (size_type i) const {
01199 return data_ (ia_ (i));
01200 }
01201 BOOST_UBLAS_INLINE
01202 reference operator () (size_type i) {
01203 return data_ (ia_ (i));
01204 }
01205
01206 BOOST_UBLAS_INLINE
01207 const_reference operator [] (size_type i) const {
01208 return (*this) (i);
01209 }
01210 BOOST_UBLAS_INLINE
01211 reference operator [] (size_type i) {
01212 return (*this) (i);
01213 }
01214 #else
01215 BOOST_UBLAS_INLINE
01216 reference operator () (size_type i) const {
01217 return data_ (ia_ (i));
01218 }
01219
01220 BOOST_UBLAS_INLINE
01221 reference operator [] (size_type i) const {
01222 return (*this) (i);
01223 }
01224 #endif
01225
01226
01227
01228
01229 BOOST_UBLAS_INLINE
01230 vector_indirect<vector_type, indirect_array_type> project (const range_type &r) const {
01231 return vector_indirect<vector_type, indirect_array_type> (data_, ia_.compose (r.preprocess (data_.size ())), 0);
01232 }
01233 BOOST_UBLAS_INLINE
01234 vector_indirect<vector_type, indirect_array_type> project (const slice_type &s) const {
01235 return vector_indirect<vector_type, indirect_array_type> (data_, ia_.compose (s.preprocess (data_.size ())), 0);
01236 }
01237 BOOST_UBLAS_INLINE
01238 vector_indirect<vector_type, indirect_array_type> project (const indirect_array_type &ia) const {
01239 return vector_indirect<vector_type, indirect_array_type> (data_, ia_.compose (ia.preprocess (data_.size ())), 0);
01240 }
01241
01242
01243 BOOST_UBLAS_INLINE
01244 vector_indirect &operator = (const vector_indirect &vi) {
01245
01246 vector_assign<scalar_assign> (*this, typename vector_temporary_traits<V>::type (vi));
01247 return *this;
01248 }
01249 BOOST_UBLAS_INLINE
01250 vector_indirect &assign_temporary (vector_indirect &vi) {
01251
01252 vector_assign<scalar_assign> (*this, vi);
01253 return *this;
01254 }
01255 template<class AE>
01256 BOOST_UBLAS_INLINE
01257 vector_indirect &operator = (const vector_expression<AE> &ae) {
01258 vector_assign<scalar_assign> (*this, typename vector_temporary_traits<V>::type (ae));
01259 return *this;
01260 }
01261 template<class AE>
01262 BOOST_UBLAS_INLINE
01263 vector_indirect &assign (const vector_expression<AE> &ae) {
01264 vector_assign<scalar_assign> (*this, ae);
01265 return *this;
01266 }
01267 template<class AE>
01268 BOOST_UBLAS_INLINE
01269 vector_indirect &operator += (const vector_expression<AE> &ae) {
01270 vector_assign<scalar_assign> (*this, typename vector_temporary_traits<V>::type (*this + ae));
01271 return *this;
01272 }
01273 template<class AE>
01274 BOOST_UBLAS_INLINE
01275 vector_indirect &plus_assign (const vector_expression<AE> &ae) {
01276 vector_assign<scalar_plus_assign> (*this, ae);
01277 return *this;
01278 }
01279 template<class AE>
01280 BOOST_UBLAS_INLINE
01281 vector_indirect &operator -= (const vector_expression<AE> &ae) {
01282 vector_assign<scalar_assign> (*this, typename vector_temporary_traits<V>::type (*this - ae));
01283 return *this;
01284 }
01285 template<class AE>
01286 BOOST_UBLAS_INLINE
01287 vector_indirect &minus_assign (const vector_expression<AE> &ae) {
01288 vector_assign<scalar_minus_assign> (*this, ae);
01289 return *this;
01290 }
01291 template<class AT>
01292 BOOST_UBLAS_INLINE
01293 vector_indirect &operator *= (const AT &at) {
01294 vector_assign_scalar<scalar_multiplies_assign> (*this, at);
01295 return *this;
01296 }
01297 template<class AT>
01298 BOOST_UBLAS_INLINE
01299 vector_indirect &operator /= (const AT &at) {
01300 vector_assign_scalar<scalar_divides_assign> (*this, at);
01301 return *this;
01302 }
01303
01304
01305 BOOST_UBLAS_INLINE
01306 bool same_closure (const vector_indirect &vr) const {
01307 return true;
01308 }
01309
01310
01311 BOOST_UBLAS_INLINE
01312 bool operator == (const vector_indirect &vi) const {
01313 return (*this).data_ == vi.data_ && ia_ == vi.ia_;
01314 }
01315
01316
01317 BOOST_UBLAS_INLINE
01318 void swap (vector_indirect vi) {
01319 if (this != &vi) {
01320 BOOST_UBLAS_CHECK (size () == vi.size (), bad_size ());
01321
01322
01323 vector_swap<scalar_swap> (*this, vi);
01324 }
01325 }
01326 BOOST_UBLAS_INLINE
01327 friend void swap (vector_indirect vi1, vector_indirect vi2) {
01328 vi1.swap (vi2);
01329 }
01330
01331
01332 private:
01333
01334 typedef typename IA::const_iterator const_subiterator_type;
01335 typedef typename IA::const_iterator subiterator_type;
01336
01337 public:
01338 #ifdef BOOST_UBLAS_USE_INDEXED_ITERATOR
01339 typedef indexed_iterator<vector_indirect<vector_type, indirect_array_type>,
01340 typename vector_type::iterator::iterator_category> iterator;
01341 typedef indexed_const_iterator<vector_indirect<vector_type, indirect_array_type>,
01342 typename vector_type::const_iterator::iterator_category> const_iterator;
01343 #else
01344 class const_iterator;
01345 class iterator;
01346 #endif
01347
01348 BOOST_UBLAS_INLINE
01349 const_iterator find (size_type i) const {
01350 #ifdef BOOST_UBLAS_USE_INDEXED_ITERATOR
01351 return const_iterator (*this, i);
01352 #else
01353 return const_iterator (*this, ia_.begin () + i);
01354 #endif
01355 }
01356 BOOST_UBLAS_INLINE
01357 iterator find (size_type i) {
01358 #ifdef BOOST_UBLAS_USE_INDEXED_ITERATOR
01359 return iterator (*this, i);
01360 #else
01361 return iterator (*this, ia_.begin () + i);
01362 #endif
01363 }
01364
01365
01366
01367 #ifndef BOOST_UBLAS_USE_INDEXED_ITERATOR
01368 class const_iterator:
01369 public container_const_reference<vector_indirect>,
01370 public iterator_base_traits<typename V::const_iterator::iterator_category>::template
01371 iterator_base<const_iterator, value_type>::type {
01372 public:
01373 typedef typename V::const_iterator::difference_type difference_type;
01374 typedef typename V::const_iterator::value_type value_type;
01375 typedef typename V::const_reference reference;
01376 typedef typename V::const_iterator::pointer pointer;
01377
01378
01379 BOOST_UBLAS_INLINE
01380 const_iterator ():
01381 container_const_reference<self_type> (), it_ () {}
01382 BOOST_UBLAS_INLINE
01383 const_iterator (const self_type &vi, const const_subiterator_type &it):
01384 container_const_reference<self_type> (vi), it_ (it) {}
01385 BOOST_UBLAS_INLINE
01386 const_iterator (const typename self_type::iterator &it):
01387 container_const_reference<self_type> (it ()), it_ (it.it_) {}
01388
01389
01390 BOOST_UBLAS_INLINE
01391 const_iterator &operator ++ () {
01392 ++ it_;
01393 return *this;
01394 }
01395 BOOST_UBLAS_INLINE
01396 const_iterator &operator -- () {
01397 -- it_;
01398 return *this;
01399 }
01400 BOOST_UBLAS_INLINE
01401 const_iterator &operator += (difference_type n) {
01402 it_ += n;
01403 return *this;
01404 }
01405 BOOST_UBLAS_INLINE
01406 const_iterator &operator -= (difference_type n) {
01407 it_ -= n;
01408 return *this;
01409 }
01410 BOOST_UBLAS_INLINE
01411 difference_type operator - (const const_iterator &it) const {
01412 BOOST_UBLAS_CHECK ((*this) ().same_closure (it ()), external_logic ());
01413 return it_ - it.it_;
01414 }
01415
01416
01417 BOOST_UBLAS_INLINE
01418 const_reference operator * () const {
01419
01420 BOOST_UBLAS_CHECK (index () < (*this) ().size (), bad_index ());
01421 return (*this) ().data_ (*it_);
01422 }
01423 BOOST_UBLAS_INLINE
01424 const_reference operator [] (difference_type n) const {
01425 return *(*this + n);
01426 }
01427
01428
01429 BOOST_UBLAS_INLINE
01430 size_type index () const {
01431 return it_.index ();
01432 }
01433
01434
01435 BOOST_UBLAS_INLINE
01436 const_iterator &operator = (const const_iterator &it) {
01437 container_const_reference<self_type>::assign (&it ());
01438 it_ = it.it_;
01439 return *this;
01440 }
01441
01442
01443 BOOST_UBLAS_INLINE
01444 bool operator == (const const_iterator &it) const {
01445 BOOST_UBLAS_CHECK ((*this) ().same_closure (it ()), external_logic ());
01446 return it_ == it.it_;
01447 }
01448 BOOST_UBLAS_INLINE
01449 bool operator < (const const_iterator &it) const {
01450 BOOST_UBLAS_CHECK ((*this) ().same_closure (it ()), external_logic ());
01451 return it_ < it.it_;
01452 }
01453
01454 private:
01455 const_subiterator_type it_;
01456 };
01457 #endif
01458
01459 BOOST_UBLAS_INLINE
01460 const_iterator begin () const {
01461 return find (0);
01462 }
01463 BOOST_UBLAS_INLINE
01464 const_iterator end () const {
01465 return find (size ());
01466 }
01467
01468 #ifndef BOOST_UBLAS_USE_INDEXED_ITERATOR
01469 class iterator:
01470 public container_reference<vector_indirect>,
01471 public iterator_base_traits<typename V::iterator::iterator_category>::template
01472 iterator_base<iterator, value_type>::type {
01473 public:
01474 typedef typename V::iterator::difference_type difference_type;
01475 typedef typename V::iterator::value_type value_type;
01476 typedef typename V::reference reference;
01477 typedef typename V::iterator::pointer pointer;
01478
01479
01480 BOOST_UBLAS_INLINE
01481 iterator ():
01482 container_reference<self_type> (), it_ () {}
01483 BOOST_UBLAS_INLINE
01484 iterator (self_type &vi, const subiterator_type &it):
01485 container_reference<self_type> (vi), it_ (it) {}
01486
01487
01488 BOOST_UBLAS_INLINE
01489 iterator &operator ++ () {
01490 ++ it_;
01491 return *this;
01492 }
01493 BOOST_UBLAS_INLINE
01494 iterator &operator -- () {
01495 -- it_;
01496 return *this;
01497 }
01498 BOOST_UBLAS_INLINE
01499 iterator &operator += (difference_type n) {
01500 it_ += n;
01501 return *this;
01502 }
01503 BOOST_UBLAS_INLINE
01504 iterator &operator -= (difference_type n) {
01505 it_ -= n;
01506 return *this;
01507 }
01508 BOOST_UBLAS_INLINE
01509 difference_type operator - (const iterator &it) const {
01510 BOOST_UBLAS_CHECK ((*this) ().same_closure (it ()), external_logic ());
01511 return it_ - it.it_;
01512 }
01513
01514
01515 BOOST_UBLAS_INLINE
01516 reference operator * () const {
01517
01518 BOOST_UBLAS_CHECK (index () < (*this) ().size (), bad_index ());
01519 return (*this) ().data_ (*it_);
01520 }
01521 BOOST_UBLAS_INLINE
01522 reference operator [] (difference_type n) const {
01523 return *(*this + n);
01524 }
01525
01526
01527 BOOST_UBLAS_INLINE
01528 size_type index () const {
01529 return it_.index ();
01530 }
01531
01532
01533 BOOST_UBLAS_INLINE
01534 iterator &operator = (const iterator &it) {
01535 container_reference<self_type>::assign (&it ());
01536 it_ = it.it_;
01537 return *this;
01538 }
01539
01540
01541 BOOST_UBLAS_INLINE
01542 bool operator == (const iterator &it) const {
01543 BOOST_UBLAS_CHECK ((*this) ().same_closure (it ()), external_logic ());
01544 return it_ == it.it_;
01545 }
01546 BOOST_UBLAS_INLINE
01547 bool operator < (const iterator &it) const {
01548 BOOST_UBLAS_CHECK ((*this) ().same_closure (it ()), external_logic ());
01549 return it_ < it.it_;
01550 }
01551
01552 private:
01553 subiterator_type it_;
01554
01555 friend class const_iterator;
01556 };
01557 #endif
01558
01559 BOOST_UBLAS_INLINE
01560 iterator begin () {
01561 return find (0);
01562 }
01563 BOOST_UBLAS_INLINE
01564 iterator end () {
01565 return find (size ());
01566 }
01567
01568
01569 typedef reverse_iterator_base<const_iterator> const_reverse_iterator;
01570 typedef reverse_iterator_base<iterator> reverse_iterator;
01571
01572 BOOST_UBLAS_INLINE
01573 const_reverse_iterator rbegin () const {
01574 return const_reverse_iterator (end ());
01575 }
01576 BOOST_UBLAS_INLINE
01577 const_reverse_iterator rend () const {
01578 return const_reverse_iterator (begin ());
01579 }
01580 BOOST_UBLAS_INLINE
01581 reverse_iterator rbegin () {
01582 return reverse_iterator (end ());
01583 }
01584 BOOST_UBLAS_INLINE
01585 reverse_iterator rend () {
01586 return reverse_iterator (begin ());
01587 }
01588
01589 private:
01590 vector_closure_type data_;
01591 indirect_array_type ia_;
01592 };
01593
01594
01595 template<class V, class A>
01596 BOOST_UBLAS_INLINE
01597 vector_indirect<V, indirect_array<A> > project (V &data, const indirect_array<A> &ia) {
01598 return vector_indirect<V, indirect_array<A> > (data, ia);
01599 }
01600 template<class V, class A>
01601 BOOST_UBLAS_INLINE
01602 const vector_indirect<const V, indirect_array<A> > project (const V &data, const indirect_array<A> &ia) {
01603
01604 return vector_indirect<const V, indirect_array<A> > (data, ia);
01605 }
01606 template<class V, class IA>
01607 BOOST_UBLAS_INLINE
01608 vector_indirect<V, IA> project (vector_indirect<V, IA> &data, const typename vector_indirect<V, IA>::range_type &r) {
01609 return data.project (r);
01610 }
01611 template<class V, class IA>
01612 BOOST_UBLAS_INLINE
01613 const vector_indirect<V, IA> project (const vector_indirect<V, IA> &data, const typename vector_indirect<V, IA>::range_type &r) {
01614 return data.project (r);
01615 }
01616 template<class V, class IA>
01617 BOOST_UBLAS_INLINE
01618 vector_indirect<V, IA> project (vector_indirect<V, IA> &data, const typename vector_indirect<V, IA>::slice_type &s) {
01619 return data.project (s);
01620 }
01621 template<class V, class IA>
01622 BOOST_UBLAS_INLINE
01623 const vector_indirect<V, IA> project (const vector_indirect<V, IA> &data, const typename vector_indirect<V, IA>::slice_type &s) {
01624 return data.project (s);
01625 }
01626 template<class V, class A>
01627 BOOST_UBLAS_INLINE
01628 vector_indirect<V, indirect_array<A> > project (vector_indirect<V, indirect_array<A> > &data, const indirect_array<A> &ia) {
01629 return data.project (ia);
01630 }
01631 template<class V, class A>
01632 BOOST_UBLAS_INLINE
01633 const vector_indirect<V, indirect_array<A> > project (const vector_indirect<V, indirect_array<A> > &data, const indirect_array<A> &ia) {
01634 return data.project (ia);
01635 }
01636
01637
01638 template <class V>
01639 struct vector_temporary_traits< vector_indirect<V> >
01640 : vector_temporary_traits< V > {} ;
01641 template <class V>
01642 struct vector_temporary_traits< const vector_indirect<V> >
01643 : vector_temporary_traits< V > {} ;
01644
01645 }}}
01646
01647 #endif