...one of the most highly
regarded and expertly designed C++ library projects in the
world.
— Herb Sutter and Andrei
Alexandrescu, C++
Coding Standards
00001 // 00002 // Copyright (c) 2000-2002 00003 // Joerg Walter, Mathias Koch 00004 // 00005 // Distributed under the Boost Software License, Version 1.0. (See 00006 // accompanying file LICENSE_1_0.txt or copy at 00007 // http://www.boost.org/LICENSE_1_0.txt) 00008 // 00009 // The authors gratefully acknowledge the support of 00010 // GeNeSys mbH & Co. KG in producing this work. 00011 // 00012 00013 #ifndef _BOOST_UBLAS_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 // Iterators based on ideas of Jeremy Siek 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 // Construction and destruction 00061 BOOST_UBLAS_INLINE 00062 vector_range (vector_type &data, const range_type &r): 00063 data_ (data), r_ (r.preprocess (data.size ())) { 00064 // Early checking of preconditions here. 00065 // BOOST_UBLAS_CHECK (r_.start () <= data_.size () && 00066 // r_.start () + r_.size () <= data_.size (), bad_index ()); 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 // Early checking of preconditions here. 00072 // BOOST_UBLAS_CHECK (r_.start () <= data_.size () && 00073 // r_.start () + r_.size () <= data_.size (), bad_index ()); 00074 } 00075 00076 // Accessors 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 // Storage accessors 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 // Element access 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 // ISSUE can this be done in free project function? 00128 // Although a const function can create a non-const proxy to a non-const object 00129 // Critical is that vector_type and data_ (vector_closure_type) are const correct 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 // Assignment 00136 BOOST_UBLAS_INLINE 00137 vector_range &operator = (const vector_range &vr) { 00138 // ISSUE need a temporary, proxy can be overlaping alias 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 // assign elements, proxied container remains the same 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 // Closure comparison 00198 BOOST_UBLAS_INLINE 00199 bool same_closure (const vector_range &vr) const { 00200 return (*this).data_.same_closure (vr.data_); 00201 } 00202 00203 // Comparison 00204 BOOST_UBLAS_INLINE 00205 bool operator == (const vector_range &vr) const { 00206 return (*this).data_ == vr.data_ && r_ == vr.r_; 00207 } 00208 00209 // Swapping 00210 BOOST_UBLAS_INLINE 00211 void swap (vector_range vr) { 00212 if (this != &vr) { 00213 BOOST_UBLAS_CHECK (size () == vr.size (), bad_size ()); 00214 // Sparse ranges may be nonconformant now. 00215 // std::swap_ranges (begin (), end (), vr.begin ()); 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 // Iterator types 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 // Element lookup 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 // Construction and destruction 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): // ISSUE self_type:: stops VC8 using std::iterator here 00282 container_const_reference<self_type> (it ()), it_ (it.it_) {} 00283 00284 // Arithmetic 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 // Dereference 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 // Index 00323 BOOST_UBLAS_INLINE 00324 size_type index () const { 00325 return it_.index () - (*this) ().start (); 00326 } 00327 00328 // Assignment 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 // Comparison 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 // Construction and destruction 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 // Arithmetic 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 // Dereference 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 // Index 00420 BOOST_UBLAS_INLINE 00421 size_type index () const { 00422 return it_.index () - (*this) ().start (); 00423 } 00424 00425 // Assignment 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 // Comparison 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 // Reverse iterator 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 // Simple Projections 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 // Generic Projections 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 // ISSUE was: return vector_range<V> (const_cast<V &> (data), r); 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 // Specialization of temporary_traits 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 // Construction and destruction 00616 BOOST_UBLAS_INLINE 00617 vector_slice (vector_type &data, const slice_type &s): 00618 data_ (data), s_ (s.preprocess (data.size ())) { 00619 // Early checking of preconditions here. 00620 // BOOST_UBLAS_CHECK (s_.start () <= data_.size () && 00621 // s_.start () + s_.stride () * (s_.size () - (s_.size () > 0)) <= data_.size (), bad_index ()); 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 // Early checking of preconditions here. 00627 // BOOST_UBLAS_CHECK (s_.start () <= data_.size () && 00628 // s_.start () + s_.stride () * (s_.size () - (s_.size () > 0)) <= data_.size (), bad_index ()); 00629 } 00630 00631 // Accessors 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 // Storage accessors 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 // Element access 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 // ISSUE can this be done in free project function? 00687 // Although a const function can create a non-const proxy to a non-const object 00688 // Critical is that vector_type and data_ (vector_closure_type) are const correct 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 // Assignment 00699 BOOST_UBLAS_INLINE 00700 vector_slice &operator = (const vector_slice &vs) { 00701 // ISSUE need a temporary, proxy can be overlaping alias 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 // assign elements, proxied container remains the same 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 // Closure comparison 00761 BOOST_UBLAS_INLINE 00762 bool same_closure (const vector_slice &vr) const { 00763 return (*this).data_.same_closure (vr.data_); 00764 } 00765 00766 // Comparison 00767 BOOST_UBLAS_INLINE 00768 bool operator == (const vector_slice &vs) const { 00769 return (*this).data_ == vs.data_ && s_ == vs.s_; 00770 } 00771 00772 // Swapping 00773 BOOST_UBLAS_INLINE 00774 void swap (vector_slice vs) { 00775 if (this != &vs) { 00776 BOOST_UBLAS_CHECK (size () == vs.size (), bad_size ()); 00777 // Sparse ranges may be nonconformant now. 00778 // std::swap_ranges (begin (), end (), vs.begin ()); 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 // Iterator types 00788 private: 00789 // Use slice as an index - FIXME this fails for packed assignment 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 // Element lookup 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; //FIXME due to indexing access 00831 typedef typename V::const_iterator::pointer pointer; 00832 00833 // Construction and destruction 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): // ISSUE self_type:: stops VC8 using std::iterator here 00842 container_const_reference<self_type> (it ()), it_ (it.it_) {} 00843 00844 // Arithmetic 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 // Dereference 00872 BOOST_UBLAS_INLINE 00873 const_reference operator * () const { 00874 // FIXME replace find with at_element 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 // Index 00884 BOOST_UBLAS_INLINE 00885 size_type index () const { 00886 return it_.index (); 00887 } 00888 00889 // Assignment 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 // Comparison 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; //FIXME due to indexing access 00932 typedef typename V::iterator::pointer pointer; 00933 00934 // Construction and destruction 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 // Arithmetic 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 // Dereference 00970 BOOST_UBLAS_INLINE 00971 reference operator * () const { 00972 // FIXME replace find with at_element 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 // Index 00983 BOOST_UBLAS_INLINE 00984 size_type index () const { 00985 return it_.index (); 00986 } 00987 00988 // Assignment 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 // Comparison 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 // Reverse iterator 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 // Simple Projections 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 // Generic Projections 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 // ISSUE was: return vector_slice<V> (const_cast<V &> (data), s); 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 // ISSUE in the following two functions it would be logical to use vector_slice<V>::range_type but this confuses VC7.1 and 8.0 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 // Specialization of temporary_traits 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 // Vector based indirection class 01108 // Contributed by Toon Knapen. 01109 // Extended and optimized by Kresimir Fresl. 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 // Construction and destruction 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 // Accessors 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 // Storage accessors 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 // Element access 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 // ISSUE can this be done in free project function? 01227 // Although a const function can create a non-const proxy to a non-const object 01228 // Critical is that vector_type and data_ (vector_closure_type) are const correct 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 // Assignment 01243 BOOST_UBLAS_INLINE 01244 vector_indirect &operator = (const vector_indirect &vi) { 01245 // ISSUE need a temporary, proxy can be overlaping alias 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 // assign elements, proxied container remains the same 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 // Closure comparison 01305 BOOST_UBLAS_INLINE 01306 bool same_closure (const vector_indirect &vr) const { 01307 return true; 01308 } 01309 01310 // Comparison 01311 BOOST_UBLAS_INLINE 01312 bool operator == (const vector_indirect &vi) const { 01313 return (*this).data_ == vi.data_ && ia_ == vi.ia_; 01314 } 01315 01316 // Swapping 01317 BOOST_UBLAS_INLINE 01318 void swap (vector_indirect vi) { 01319 if (this != &vi) { 01320 BOOST_UBLAS_CHECK (size () == vi.size (), bad_size ()); 01321 // Sparse ranges may be nonconformant now. 01322 // std::swap_ranges (begin (), end (), vi.begin ()); 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 // Iterator types 01332 private: 01333 // Use indirect array as an index - FIXME this fails for packed assignment 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 // Element lookup 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 // Iterators simply are indices. 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; //FIXME due to indexing access 01376 typedef typename V::const_iterator::pointer pointer; 01377 01378 // Construction and destruction 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): // ISSUE self_type:: stops VC8 using std::iterator here 01387 container_const_reference<self_type> (it ()), it_ (it.it_) {} 01388 01389 // Arithmetic 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 // Dereference 01417 BOOST_UBLAS_INLINE 01418 const_reference operator * () const { 01419 // FIXME replace find with at_element 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 // Index 01429 BOOST_UBLAS_INLINE 01430 size_type index () const { 01431 return it_.index (); 01432 } 01433 01434 // Assignment 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 // Comparison 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; //FIXME due to indexing access 01477 typedef typename V::iterator::pointer pointer; 01478 01479 // Construction and destruction 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 // Arithmetic 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 // Dereference 01515 BOOST_UBLAS_INLINE 01516 reference operator * () const { 01517 // FIXME replace find with at_element 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 // Index 01527 BOOST_UBLAS_INLINE 01528 size_type index () const { 01529 return it_.index (); 01530 } 01531 01532 // Assignment 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 // Comparison 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 // Reverse iterator 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 // Projections 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 // ISSUE was: return vector_indirect<V, indirect_array<A> > (const_cast<V &> (data), ia) 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 // Specialization of temporary_traits 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