File indexing completed on 2025-01-18 09:43:18
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013 #ifndef _BOOST_UBLAS_VECTOR_PROXY_
0014 #define _BOOST_UBLAS_VECTOR_PROXY_
0015
0016 #include <boost/numeric/ublas/vector_expression.hpp>
0017 #include <boost/numeric/ublas/detail/vector_assign.hpp>
0018 #include <boost/numeric/ublas/detail/temporary.hpp>
0019
0020
0021
0022 namespace boost { namespace numeric { namespace ublas {
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033 template<class V>
0034 class vector_range:
0035 public vector_expression<vector_range<V> > {
0036
0037 typedef vector_range<V> self_type;
0038 public:
0039 #ifdef BOOST_UBLAS_ENABLE_PROXY_SHORTCUTS
0040 using vector_expression<self_type>::operator ();
0041 #endif
0042 typedef const V const_vector_type;
0043 typedef V vector_type;
0044 typedef typename V::size_type size_type;
0045 typedef typename V::difference_type difference_type;
0046 typedef typename V::value_type value_type;
0047 typedef typename V::const_reference const_reference;
0048 typedef typename boost::mpl::if_<boost::is_const<V>,
0049 typename V::const_reference,
0050 typename V::reference>::type reference;
0051 typedef typename boost::mpl::if_<boost::is_const<V>,
0052 typename V::const_closure_type,
0053 typename V::closure_type>::type vector_closure_type;
0054 typedef basic_range<size_type, difference_type> range_type;
0055 typedef const self_type const_closure_type;
0056 typedef self_type closure_type;
0057 typedef typename storage_restrict_traits<typename V::storage_category,
0058 dense_proxy_tag>::storage_category storage_category;
0059
0060
0061 BOOST_UBLAS_INLINE
0062 vector_range (vector_type &data, const range_type &r):
0063 data_ (data), r_ (r.preprocess (data.size ())) {
0064
0065
0066
0067 }
0068 BOOST_UBLAS_INLINE
0069 vector_range (const vector_closure_type &data, const range_type &r, bool):
0070 data_ (data), r_ (r.preprocess (data.size ())) {
0071
0072
0073
0074 }
0075
0076
0077 BOOST_UBLAS_INLINE
0078 size_type start () const {
0079 return r_.start ();
0080 }
0081 BOOST_UBLAS_INLINE
0082 size_type size () const {
0083 return r_.size ();
0084 }
0085
0086
0087 BOOST_UBLAS_INLINE
0088 const vector_closure_type &data () const {
0089 return data_;
0090 }
0091 BOOST_UBLAS_INLINE
0092 vector_closure_type &data () {
0093 return data_;
0094 }
0095
0096
0097 #ifndef BOOST_UBLAS_PROXY_CONST_MEMBER
0098 BOOST_UBLAS_INLINE
0099 const_reference operator () (size_type i) const {
0100 return data_ (r_ (i));
0101 }
0102 BOOST_UBLAS_INLINE
0103 reference operator () (size_type i) {
0104 return data_ (r_ (i));
0105 }
0106
0107 BOOST_UBLAS_INLINE
0108 const_reference operator [] (size_type i) const {
0109 return (*this) (i);
0110 }
0111 BOOST_UBLAS_INLINE
0112 reference operator [] (size_type i) {
0113 return (*this) (i);
0114 }
0115 #else
0116 BOOST_UBLAS_INLINE
0117 reference operator () (size_type i) const {
0118 return data_ (r_ (i));
0119 }
0120
0121 BOOST_UBLAS_INLINE
0122 reference operator [] (size_type i) const {
0123 return (*this) (i);
0124 }
0125 #endif
0126
0127
0128
0129
0130 BOOST_UBLAS_INLINE
0131 vector_range<vector_type> project (const range_type &r) const {
0132 return vector_range<vector_type> (data_, r_.compose (r.preprocess (data_.size ())), false);
0133 }
0134
0135
0136 BOOST_UBLAS_INLINE
0137 vector_range &operator = (const vector_range &vr) {
0138
0139 vector_assign<scalar_assign> (*this, typename vector_temporary_traits<V>::type (vr));
0140 return *this;
0141 }
0142 BOOST_UBLAS_INLINE
0143 vector_range &assign_temporary (vector_range &vr) {
0144
0145 vector_assign<scalar_assign> (*this, vr);
0146 return *this;
0147 }
0148 template<class AE>
0149 BOOST_UBLAS_INLINE
0150 vector_range &operator = (const vector_expression<AE> &ae) {
0151 vector_assign<scalar_assign> (*this, typename vector_temporary_traits<V>::type (ae));
0152 return *this;
0153 }
0154 template<class AE>
0155 BOOST_UBLAS_INLINE
0156 vector_range &assign (const vector_expression<AE> &ae) {
0157 vector_assign<scalar_assign> (*this, ae);
0158 return *this;
0159 }
0160 template<class AE>
0161 BOOST_UBLAS_INLINE
0162 vector_range &operator += (const vector_expression<AE> &ae) {
0163 vector_assign<scalar_assign> (*this, typename vector_temporary_traits<V>::type (*this + ae));
0164 return *this;
0165 }
0166 template<class AE>
0167 BOOST_UBLAS_INLINE
0168 vector_range &plus_assign (const vector_expression<AE> &ae) {
0169 vector_assign<scalar_plus_assign> (*this, ae);
0170 return *this;
0171 }
0172 template<class AE>
0173 BOOST_UBLAS_INLINE
0174 vector_range &operator -= (const vector_expression<AE> &ae) {
0175 vector_assign<scalar_assign> (*this, typename vector_temporary_traits<V>::type (*this - ae));
0176 return *this;
0177 }
0178 template<class AE>
0179 BOOST_UBLAS_INLINE
0180 vector_range &minus_assign (const vector_expression<AE> &ae) {
0181 vector_assign<scalar_minus_assign> (*this, ae);
0182 return *this;
0183 }
0184 template<class AT>
0185 BOOST_UBLAS_INLINE
0186 vector_range &operator *= (const AT &at) {
0187 vector_assign_scalar<scalar_multiplies_assign> (*this, at);
0188 return *this;
0189 }
0190 template<class AT>
0191 BOOST_UBLAS_INLINE
0192 vector_range &operator /= (const AT &at) {
0193 vector_assign_scalar<scalar_divides_assign> (*this, at);
0194 return *this;
0195 }
0196
0197
0198 BOOST_UBLAS_INLINE
0199 bool same_closure (const vector_range &vr) const {
0200 return (*this).data_.same_closure (vr.data_);
0201 }
0202
0203
0204 BOOST_UBLAS_INLINE
0205 bool operator == (const vector_range &vr) const {
0206 return (*this).data_ == vr.data_ && r_ == vr.r_;
0207 }
0208
0209
0210 BOOST_UBLAS_INLINE
0211 void swap (vector_range vr) {
0212 if (this != &vr) {
0213 BOOST_UBLAS_CHECK (size () == vr.size (), bad_size ());
0214
0215
0216 vector_swap<scalar_swap> (*this, vr);
0217 }
0218 }
0219 BOOST_UBLAS_INLINE
0220 friend void swap (vector_range vr1, vector_range vr2) {
0221 vr1.swap (vr2);
0222 }
0223
0224
0225 private:
0226 typedef typename V::const_iterator const_subiterator_type;
0227 typedef typename boost::mpl::if_<boost::is_const<V>,
0228 typename V::const_iterator,
0229 typename V::iterator>::type subiterator_type;
0230
0231 public:
0232 #ifdef BOOST_UBLAS_USE_INDEXED_ITERATOR
0233 typedef indexed_iterator<vector_range<vector_type>,
0234 typename subiterator_type::iterator_category> iterator;
0235 typedef indexed_const_iterator<vector_range<vector_type>,
0236 typename const_subiterator_type::iterator_category> const_iterator;
0237 #else
0238 class const_iterator;
0239 class iterator;
0240 #endif
0241
0242
0243 BOOST_UBLAS_INLINE
0244 const_iterator find (size_type i) const {
0245 const_subiterator_type it (data_.find (start () + i));
0246 #ifdef BOOST_UBLAS_USE_INDEXED_ITERATOR
0247 return const_iterator (*this, it.index ());
0248 #else
0249 return const_iterator (*this, it);
0250 #endif
0251 }
0252 BOOST_UBLAS_INLINE
0253 iterator find (size_type i) {
0254 subiterator_type it (data_.find (start () + i));
0255 #ifdef BOOST_UBLAS_USE_INDEXED_ITERATOR
0256 return iterator (*this, it.index ());
0257 #else
0258 return iterator (*this, it);
0259 #endif
0260 }
0261
0262 #ifndef BOOST_UBLAS_USE_INDEXED_ITERATOR
0263 class const_iterator:
0264 public container_const_reference<vector_range>,
0265 public iterator_base_traits<typename const_subiterator_type::iterator_category>::template
0266 iterator_base<const_iterator, value_type>::type {
0267 public:
0268 typedef typename const_subiterator_type::difference_type difference_type;
0269 typedef typename const_subiterator_type::value_type value_type;
0270 typedef typename const_subiterator_type::reference reference;
0271 typedef typename const_subiterator_type::pointer pointer;
0272
0273
0274 BOOST_UBLAS_INLINE
0275 const_iterator ():
0276 container_const_reference<self_type> (), it_ () {}
0277 BOOST_UBLAS_INLINE
0278 const_iterator (const self_type &vr, const const_subiterator_type &it):
0279 container_const_reference<self_type> (vr), it_ (it) {}
0280 BOOST_UBLAS_INLINE
0281 const_iterator (const typename self_type::iterator &it):
0282 container_const_reference<self_type> (it ()), it_ (it.it_) {}
0283
0284
0285 BOOST_UBLAS_INLINE
0286 const_iterator &operator ++ () {
0287 ++ it_;
0288 return *this;
0289 }
0290 BOOST_UBLAS_INLINE
0291 const_iterator &operator -- () {
0292 -- it_;
0293 return *this;
0294 }
0295 BOOST_UBLAS_INLINE
0296 const_iterator &operator += (difference_type n) {
0297 it_ += n;
0298 return *this;
0299 }
0300 BOOST_UBLAS_INLINE
0301 const_iterator &operator -= (difference_type n) {
0302 it_ -= n;
0303 return *this;
0304 }
0305 BOOST_UBLAS_INLINE
0306 difference_type operator - (const const_iterator &it) const {
0307 BOOST_UBLAS_CHECK ((*this) ().same_closure (it ()), external_logic ());
0308 return it_ - it.it_;
0309 }
0310
0311
0312 BOOST_UBLAS_INLINE
0313 const_reference operator * () const {
0314 BOOST_UBLAS_CHECK (index () < (*this) ().size (), bad_index ());
0315 return *it_;
0316 }
0317 BOOST_UBLAS_INLINE
0318 const_reference operator [] (difference_type n) const {
0319 return *(*this + n);
0320 }
0321
0322
0323 BOOST_UBLAS_INLINE
0324 size_type index () const {
0325 return it_.index () - (*this) ().start ();
0326 }
0327
0328
0329 BOOST_UBLAS_INLINE
0330 const_iterator &operator = (const const_iterator &it) {
0331 container_const_reference<self_type>::assign (&it ());
0332 it_ = it.it_;
0333 return *this;
0334 }
0335
0336
0337 BOOST_UBLAS_INLINE
0338 bool operator == (const const_iterator &it) const {
0339 BOOST_UBLAS_CHECK ((*this) ().same_closure (it ()), external_logic ());
0340 return it_ == it.it_;
0341 }
0342 BOOST_UBLAS_INLINE
0343 bool operator < (const const_iterator &it) const {
0344 BOOST_UBLAS_CHECK ((*this) ().same_closure (it ()), external_logic ());
0345 return it_ < it.it_;
0346 }
0347
0348 private:
0349 const_subiterator_type it_;
0350 };
0351 #endif
0352
0353 BOOST_UBLAS_INLINE
0354 const_iterator begin () const {
0355 return find (0);
0356 }
0357 BOOST_UBLAS_INLINE
0358 const_iterator cbegin () const {
0359 return begin ();
0360 }
0361 BOOST_UBLAS_INLINE
0362 const_iterator end () const {
0363 return find (size ());
0364 }
0365 BOOST_UBLAS_INLINE
0366 const_iterator cend () const {
0367 return end ();
0368 }
0369
0370 #ifndef BOOST_UBLAS_USE_INDEXED_ITERATOR
0371 class iterator:
0372 public container_reference<vector_range>,
0373 public iterator_base_traits<typename subiterator_type::iterator_category>::template
0374 iterator_base<iterator, value_type>::type {
0375 public:
0376 typedef typename subiterator_type::difference_type difference_type;
0377 typedef typename subiterator_type::value_type value_type;
0378 typedef typename subiterator_type::reference reference;
0379 typedef typename subiterator_type::pointer pointer;
0380
0381
0382 BOOST_UBLAS_INLINE
0383 iterator ():
0384 container_reference<self_type> (), it_ () {}
0385 BOOST_UBLAS_INLINE
0386 iterator (self_type &vr, const subiterator_type &it):
0387 container_reference<self_type> (vr), it_ (it) {}
0388
0389
0390 BOOST_UBLAS_INLINE
0391 iterator &operator ++ () {
0392 ++ it_;
0393 return *this;
0394 }
0395 BOOST_UBLAS_INLINE
0396 iterator &operator -- () {
0397 -- it_;
0398 return *this;
0399 }
0400 BOOST_UBLAS_INLINE
0401 iterator &operator += (difference_type n) {
0402 it_ += n;
0403 return *this;
0404 }
0405 BOOST_UBLAS_INLINE
0406 iterator &operator -= (difference_type n) {
0407 it_ -= n;
0408 return *this;
0409 }
0410 BOOST_UBLAS_INLINE
0411 difference_type operator - (const iterator &it) const {
0412 BOOST_UBLAS_CHECK ((*this) ().same_closure (it ()), external_logic ());
0413 return it_ - it.it_;
0414 }
0415
0416
0417 BOOST_UBLAS_INLINE
0418 reference operator * () const {
0419 BOOST_UBLAS_CHECK (index () < (*this) ().size (), bad_index ());
0420 return *it_;
0421 }
0422 BOOST_UBLAS_INLINE
0423 reference operator [] (difference_type n) const {
0424 return *(*this + n);
0425 }
0426
0427
0428 BOOST_UBLAS_INLINE
0429 size_type index () const {
0430 return it_.index () - (*this) ().start ();
0431 }
0432
0433
0434 BOOST_UBLAS_INLINE
0435 iterator &operator = (const iterator &it) {
0436 container_reference<self_type>::assign (&it ());
0437 it_ = it.it_;
0438 return *this;
0439 }
0440
0441
0442 BOOST_UBLAS_INLINE
0443 bool operator == (const iterator &it) const {
0444 BOOST_UBLAS_CHECK ((*this) ().same_closure (it ()), external_logic ());
0445 return it_ == it.it_;
0446 }
0447 BOOST_UBLAS_INLINE
0448 bool operator < (const iterator &it) const {
0449 BOOST_UBLAS_CHECK ((*this) ().same_closure (it ()), external_logic ());
0450 return it_ < it.it_;
0451 }
0452
0453 private:
0454 subiterator_type it_;
0455
0456 friend class const_iterator;
0457 };
0458 #endif
0459
0460 BOOST_UBLAS_INLINE
0461 iterator begin () {
0462 return find (0);
0463 }
0464 BOOST_UBLAS_INLINE
0465 iterator end () {
0466 return find (size ());
0467 }
0468
0469
0470 typedef reverse_iterator_base<const_iterator> const_reverse_iterator;
0471 typedef reverse_iterator_base<iterator> reverse_iterator;
0472
0473 BOOST_UBLAS_INLINE
0474 const_reverse_iterator rbegin () const {
0475 return const_reverse_iterator (end ());
0476 }
0477 BOOST_UBLAS_INLINE
0478 const_reverse_iterator crbegin () const {
0479 return rbegin ();
0480 }
0481 BOOST_UBLAS_INLINE
0482 const_reverse_iterator rend () const {
0483 return const_reverse_iterator (begin ());
0484 }
0485 BOOST_UBLAS_INLINE
0486 const_reverse_iterator crend () const {
0487 return rend ();
0488 }
0489
0490 BOOST_UBLAS_INLINE
0491 reverse_iterator rbegin () {
0492 return reverse_iterator (end ());
0493 }
0494 BOOST_UBLAS_INLINE
0495 reverse_iterator rend () {
0496 return reverse_iterator (begin ());
0497 }
0498
0499 private:
0500 vector_closure_type data_;
0501 range_type r_;
0502 };
0503
0504
0505
0506
0507
0508
0509
0510
0511
0512
0513 template<class V>
0514 BOOST_UBLAS_INLINE
0515 vector_range<V> subrange (V &data, typename V::size_type start, typename V::size_type stop) {
0516 typedef basic_range<typename V::size_type, typename V::difference_type> range_type;
0517 return vector_range<V> (data, range_type (start, stop));
0518 }
0519
0520
0521
0522
0523
0524
0525 template<class V>
0526 BOOST_UBLAS_INLINE
0527 vector_range<const V> subrange (const V &data, typename V::size_type start, typename V::size_type stop) {
0528 typedef basic_range<typename V::size_type, typename V::difference_type> range_type;
0529 return vector_range<const V> (data, range_type (start, stop));
0530 }
0531
0532
0533
0534
0535
0536
0537
0538
0539
0540
0541 template<class V>
0542 BOOST_UBLAS_INLINE
0543 vector_range<V> project (V &data, typename vector_range<V>::range_type const &r) {
0544 return vector_range<V> (data, r);
0545 }
0546
0547
0548
0549
0550
0551
0552 template<class V>
0553 BOOST_UBLAS_INLINE
0554 const vector_range<const V> project (const V &data, typename vector_range<V>::range_type const &r) {
0555
0556 return vector_range<const V> (data, r);
0557 }
0558
0559
0560
0561
0562
0563
0564 template<class V>
0565 BOOST_UBLAS_INLINE
0566 vector_range<V> project (vector_range<V> &data, const typename vector_range<V>::range_type &r) {
0567 return data.project (r);
0568 }
0569
0570
0571
0572
0573
0574
0575 template<class V>
0576 BOOST_UBLAS_INLINE
0577 const vector_range<V> project (const vector_range<V> &data, const typename vector_range<V>::range_type &r) {
0578 return data.project (r);
0579 }
0580
0581
0582 template <class V>
0583 struct vector_temporary_traits< vector_range<V> >
0584 : vector_temporary_traits< V > {} ;
0585 template <class V>
0586 struct vector_temporary_traits< const vector_range<V> >
0587 : vector_temporary_traits< V > {} ;
0588
0589
0590
0591
0592
0593
0594
0595
0596
0597
0598
0599
0600
0601
0602
0603
0604 template<class V>
0605 class vector_slice:
0606 public vector_expression<vector_slice<V> > {
0607
0608 typedef vector_slice<V> self_type;
0609 public:
0610 #ifdef BOOST_UBLAS_ENABLE_PROXY_SHORTCUTS
0611 using vector_expression<self_type>::operator ();
0612 #endif
0613 typedef const V const_vector_type;
0614 typedef V vector_type;
0615 typedef typename V::size_type size_type;
0616 typedef typename V::difference_type difference_type;
0617 typedef typename V::value_type value_type;
0618 typedef typename V::const_reference const_reference;
0619 typedef typename boost::mpl::if_<boost::is_const<V>,
0620 typename V::const_reference,
0621 typename V::reference>::type reference;
0622 typedef typename boost::mpl::if_<boost::is_const<V>,
0623 typename V::const_closure_type,
0624 typename V::closure_type>::type vector_closure_type;
0625 typedef basic_range<size_type, difference_type> range_type;
0626 typedef basic_slice<size_type, difference_type> slice_type;
0627 typedef const self_type const_closure_type;
0628 typedef self_type closure_type;
0629 typedef typename storage_restrict_traits<typename V::storage_category,
0630 dense_proxy_tag>::storage_category storage_category;
0631
0632
0633 BOOST_UBLAS_INLINE
0634 vector_slice (vector_type &data, const slice_type &s):
0635 data_ (data), s_ (s.preprocess (data.size ())) {
0636
0637
0638
0639 }
0640 BOOST_UBLAS_INLINE
0641 vector_slice (const vector_closure_type &data, const slice_type &s, int):
0642 data_ (data), s_ (s.preprocess (data.size ())) {
0643
0644
0645
0646 }
0647
0648
0649 BOOST_UBLAS_INLINE
0650 size_type start () const {
0651 return s_.start ();
0652 }
0653 BOOST_UBLAS_INLINE
0654 difference_type stride () const {
0655 return s_.stride ();
0656 }
0657 BOOST_UBLAS_INLINE
0658 size_type size () const {
0659 return s_.size ();
0660 }
0661
0662
0663 BOOST_UBLAS_INLINE
0664 const vector_closure_type &data () const {
0665 return data_;
0666 }
0667 BOOST_UBLAS_INLINE
0668 vector_closure_type &data () {
0669 return data_;
0670 }
0671
0672
0673 #ifndef BOOST_UBLAS_PROXY_CONST_MEMBER
0674 BOOST_UBLAS_INLINE
0675 const_reference operator () (size_type i) const {
0676 return data_ (s_ (i));
0677 }
0678 BOOST_UBLAS_INLINE
0679 reference operator () (size_type i) {
0680 return data_ (s_ (i));
0681 }
0682
0683 BOOST_UBLAS_INLINE
0684 const_reference operator [] (size_type i) const {
0685 return (*this) (i);
0686 }
0687 BOOST_UBLAS_INLINE
0688 reference operator [] (size_type i) {
0689 return (*this) (i);
0690 }
0691 #else
0692 BOOST_UBLAS_INLINE
0693 reference operator () (size_type i) const {
0694 return data_ (s_ (i));
0695 }
0696
0697 BOOST_UBLAS_INLINE
0698 reference operator [] (size_type i) const {
0699 return (*this) (i);
0700 }
0701 #endif
0702
0703
0704
0705
0706 BOOST_UBLAS_INLINE
0707 vector_slice<vector_type> project (const range_type &r) const {
0708 return vector_slice<vector_type> (data_, s_.compose (r.preprocess (data_.size ())), false);
0709 }
0710 BOOST_UBLAS_INLINE
0711 vector_slice<vector_type> project (const slice_type &s) const {
0712 return vector_slice<vector_type> (data_, s_.compose (s.preprocess (data_.size ())), false);
0713 }
0714
0715
0716 BOOST_UBLAS_INLINE
0717 vector_slice &operator = (const vector_slice &vs) {
0718
0719 vector_assign<scalar_assign> (*this, typename vector_temporary_traits<V>::type (vs));
0720 return *this;
0721 }
0722 BOOST_UBLAS_INLINE
0723 vector_slice &assign_temporary (vector_slice &vs) {
0724
0725 vector_assign<scalar_assign> (*this, vs);
0726 return *this;
0727 }
0728 template<class AE>
0729 BOOST_UBLAS_INLINE
0730 vector_slice &operator = (const vector_expression<AE> &ae) {
0731 vector_assign<scalar_assign> (*this, typename vector_temporary_traits<V>::type (ae));
0732 return *this;
0733 }
0734 template<class AE>
0735 BOOST_UBLAS_INLINE
0736 vector_slice &assign (const vector_expression<AE> &ae) {
0737 vector_assign<scalar_assign> (*this, ae);
0738 return *this;
0739 }
0740 template<class AE>
0741 BOOST_UBLAS_INLINE
0742 vector_slice &operator += (const vector_expression<AE> &ae) {
0743 vector_assign<scalar_assign> (*this, typename vector_temporary_traits<V>::type (*this + ae));
0744 return *this;
0745 }
0746 template<class AE>
0747 BOOST_UBLAS_INLINE
0748 vector_slice &plus_assign (const vector_expression<AE> &ae) {
0749 vector_assign<scalar_plus_assign> (*this, ae);
0750 return *this;
0751 }
0752 template<class AE>
0753 BOOST_UBLAS_INLINE
0754 vector_slice &operator -= (const vector_expression<AE> &ae) {
0755 vector_assign<scalar_assign> (*this, typename vector_temporary_traits<V>::type (*this - ae));
0756 return *this;
0757 }
0758 template<class AE>
0759 BOOST_UBLAS_INLINE
0760 vector_slice &minus_assign (const vector_expression<AE> &ae) {
0761 vector_assign<scalar_minus_assign> (*this, ae);
0762 return *this;
0763 }
0764 template<class AT>
0765 BOOST_UBLAS_INLINE
0766 vector_slice &operator *= (const AT &at) {
0767 vector_assign_scalar<scalar_multiplies_assign> (*this, at);
0768 return *this;
0769 }
0770 template<class AT>
0771 BOOST_UBLAS_INLINE
0772 vector_slice &operator /= (const AT &at) {
0773 vector_assign_scalar<scalar_divides_assign> (*this, at);
0774 return *this;
0775 }
0776
0777
0778 BOOST_UBLAS_INLINE
0779 bool same_closure (const vector_slice &vr) const {
0780 return (*this).data_.same_closure (vr.data_);
0781 }
0782
0783
0784 BOOST_UBLAS_INLINE
0785 bool operator == (const vector_slice &vs) const {
0786 return (*this).data_ == vs.data_ && s_ == vs.s_;
0787 }
0788
0789
0790 BOOST_UBLAS_INLINE
0791 void swap (vector_slice vs) {
0792 if (this != &vs) {
0793 BOOST_UBLAS_CHECK (size () == vs.size (), bad_size ());
0794
0795
0796 vector_swap<scalar_swap> (*this, vs);
0797 }
0798 }
0799 BOOST_UBLAS_INLINE
0800 friend void swap (vector_slice vs1, vector_slice vs2) {
0801 vs1.swap (vs2);
0802 }
0803
0804
0805 private:
0806
0807 typedef typename slice_type::const_iterator const_subiterator_type;
0808 typedef typename slice_type::const_iterator subiterator_type;
0809
0810 public:
0811 #ifdef BOOST_UBLAS_USE_INDEXED_ITERATOR
0812 typedef indexed_iterator<vector_slice<vector_type>,
0813 typename vector_type::iterator::iterator_category> iterator;
0814 typedef indexed_const_iterator<vector_slice<vector_type>,
0815 typename vector_type::const_iterator::iterator_category> const_iterator;
0816 #else
0817 class const_iterator;
0818 class iterator;
0819 #endif
0820
0821
0822 BOOST_UBLAS_INLINE
0823 const_iterator find (size_type i) const {
0824 #ifdef BOOST_UBLAS_USE_INDEXED_ITERATOR
0825 return const_iterator (*this, i);
0826 #else
0827 return const_iterator (*this, s_.begin () + i);
0828 #endif
0829 }
0830 BOOST_UBLAS_INLINE
0831 iterator find (size_type i) {
0832 #ifdef BOOST_UBLAS_USE_INDEXED_ITERATOR
0833 return iterator (*this, i);
0834 #else
0835 return iterator (*this, s_.begin () + i);
0836 #endif
0837 }
0838
0839 #ifndef BOOST_UBLAS_USE_INDEXED_ITERATOR
0840 class const_iterator:
0841 public container_const_reference<vector_slice>,
0842 public iterator_base_traits<typename V::const_iterator::iterator_category>::template
0843 iterator_base<const_iterator, value_type>::type {
0844 public:
0845 typedef typename V::const_iterator::difference_type difference_type;
0846 typedef typename V::const_iterator::value_type value_type;
0847 typedef typename V::const_reference reference;
0848 typedef typename V::const_iterator::pointer pointer;
0849
0850
0851 BOOST_UBLAS_INLINE
0852 const_iterator ():
0853 container_const_reference<self_type> (), it_ () {}
0854 BOOST_UBLAS_INLINE
0855 const_iterator (const self_type &vs, const const_subiterator_type &it):
0856 container_const_reference<self_type> (vs), it_ (it) {}
0857 BOOST_UBLAS_INLINE
0858 const_iterator (const typename self_type::iterator &it):
0859 container_const_reference<self_type> (it ()), it_ (it.it_) {}
0860
0861
0862 BOOST_UBLAS_INLINE
0863 const_iterator &operator ++ () {
0864 ++ it_;
0865 return *this;
0866 }
0867 BOOST_UBLAS_INLINE
0868 const_iterator &operator -- () {
0869 -- it_;
0870 return *this;
0871 }
0872 BOOST_UBLAS_INLINE
0873 const_iterator &operator += (difference_type n) {
0874 it_ += n;
0875 return *this;
0876 }
0877 BOOST_UBLAS_INLINE
0878 const_iterator &operator -= (difference_type n) {
0879 it_ -= n;
0880 return *this;
0881 }
0882 BOOST_UBLAS_INLINE
0883 difference_type operator - (const const_iterator &it) const {
0884 BOOST_UBLAS_CHECK ((*this) ().same_closure (it ()), external_logic ());
0885 return it_ - it.it_;
0886 }
0887
0888
0889 BOOST_UBLAS_INLINE
0890 const_reference operator * () const {
0891
0892 BOOST_UBLAS_CHECK (index () < (*this) ().size (), bad_index ());
0893 return (*this) ().data_ (*it_);
0894 }
0895 BOOST_UBLAS_INLINE
0896 const_reference operator [] (difference_type n) const {
0897 return *(*this + n);
0898 }
0899
0900
0901 BOOST_UBLAS_INLINE
0902 size_type index () const {
0903 return it_.index ();
0904 }
0905
0906
0907 BOOST_UBLAS_INLINE
0908 const_iterator &operator = (const const_iterator &it) {
0909 container_const_reference<self_type>::assign (&it ());
0910 it_ = it.it_;
0911 return *this;
0912 }
0913
0914
0915 BOOST_UBLAS_INLINE
0916 bool operator == (const const_iterator &it) const {
0917 BOOST_UBLAS_CHECK ((*this) ().same_closure (it ()), external_logic ());
0918 return it_ == it.it_;
0919 }
0920 BOOST_UBLAS_INLINE
0921 bool operator < (const const_iterator &it) const {
0922 BOOST_UBLAS_CHECK ((*this) ().same_closure (it ()), external_logic ());
0923 return it_ < it.it_;
0924 }
0925
0926 private:
0927 const_subiterator_type it_;
0928 };
0929 #endif
0930
0931 BOOST_UBLAS_INLINE
0932 const_iterator begin () const {
0933 return find (0);
0934 }
0935 BOOST_UBLAS_INLINE
0936 const_iterator cbegin () const {
0937 return begin ();
0938 }
0939 BOOST_UBLAS_INLINE
0940 const_iterator end () const {
0941 return find (size ());
0942 }
0943 BOOST_UBLAS_INLINE
0944 const_iterator cend () const {
0945 return end ();
0946 }
0947
0948 #ifndef BOOST_UBLAS_USE_INDEXED_ITERATOR
0949 class iterator:
0950 public container_reference<vector_slice>,
0951 public iterator_base_traits<typename V::iterator::iterator_category>::template
0952 iterator_base<iterator, value_type>::type {
0953 public:
0954 typedef typename V::iterator::difference_type difference_type;
0955 typedef typename V::iterator::value_type value_type;
0956 typedef typename V::reference reference;
0957 typedef typename V::iterator::pointer pointer;
0958
0959
0960 BOOST_UBLAS_INLINE
0961 iterator ():
0962 container_reference<self_type> (), it_ () {}
0963 BOOST_UBLAS_INLINE
0964 iterator (self_type &vs, const subiterator_type &it):
0965 container_reference<self_type> (vs), it_ (it) {}
0966
0967
0968 BOOST_UBLAS_INLINE
0969 iterator &operator ++ () {
0970 ++ it_;
0971 return *this;
0972 }
0973 BOOST_UBLAS_INLINE
0974 iterator &operator -- () {
0975 -- it_;
0976 return *this;
0977 }
0978 BOOST_UBLAS_INLINE
0979 iterator &operator += (difference_type n) {
0980 it_ += n;
0981 return *this;
0982 }
0983 BOOST_UBLAS_INLINE
0984 iterator &operator -= (difference_type n) {
0985 it_ -= n;
0986 return *this;
0987 }
0988 BOOST_UBLAS_INLINE
0989 difference_type operator - (const iterator &it) const {
0990 BOOST_UBLAS_CHECK ((*this) ().same_closure (it ()), external_logic ());
0991 return it_ - it.it_;
0992 }
0993
0994
0995 BOOST_UBLAS_INLINE
0996 reference operator * () const {
0997
0998 BOOST_UBLAS_CHECK (index () < (*this) ().size (), bad_index ());
0999 return (*this) ().data_ (*it_);
1000 }
1001 BOOST_UBLAS_INLINE
1002 reference operator [] (difference_type n) const {
1003 return *(*this + n);
1004 }
1005
1006
1007
1008 BOOST_UBLAS_INLINE
1009 size_type index () const {
1010 return it_.index ();
1011 }
1012
1013
1014 BOOST_UBLAS_INLINE
1015 iterator &operator = (const iterator &it) {
1016 container_reference<self_type>::assign (&it ());
1017 it_ = it.it_;
1018 return *this;
1019 }
1020
1021
1022 BOOST_UBLAS_INLINE
1023 bool operator == (const iterator &it) const {
1024 BOOST_UBLAS_CHECK ((*this) ().same_closure (it ()), external_logic ());
1025 return it_ == it.it_;
1026 }
1027 BOOST_UBLAS_INLINE
1028 bool operator < (const iterator &it) const {
1029 BOOST_UBLAS_CHECK ((*this) ().same_closure (it ()), external_logic ());
1030 return it_ < it.it_;
1031 }
1032
1033 private:
1034 subiterator_type it_;
1035
1036 friend class const_iterator;
1037 };
1038 #endif
1039
1040 BOOST_UBLAS_INLINE
1041 iterator begin () {
1042 return find (0);
1043 }
1044 BOOST_UBLAS_INLINE
1045 iterator end () {
1046 return find (size ());
1047 }
1048
1049
1050 typedef reverse_iterator_base<const_iterator> const_reverse_iterator;
1051 typedef reverse_iterator_base<iterator> reverse_iterator;
1052
1053 BOOST_UBLAS_INLINE
1054 const_reverse_iterator rbegin () const {
1055 return const_reverse_iterator (end ());
1056 }
1057 BOOST_UBLAS_INLINE
1058 const_reverse_iterator crbegin () const {
1059 return rbegin ();
1060 }
1061 BOOST_UBLAS_INLINE
1062 const_reverse_iterator rend () const {
1063 return const_reverse_iterator (begin ());
1064 }
1065 BOOST_UBLAS_INLINE
1066 const_reverse_iterator crend () const {
1067 return rend ();
1068 }
1069 BOOST_UBLAS_INLINE
1070 reverse_iterator rbegin () {
1071 return reverse_iterator (end ());
1072 }
1073 BOOST_UBLAS_INLINE
1074 reverse_iterator rend () {
1075 return reverse_iterator (begin ());
1076 }
1077
1078 private:
1079 vector_closure_type data_;
1080 slice_type s_;
1081 };
1082
1083
1084 template<class V>
1085 BOOST_UBLAS_INLINE
1086 vector_slice<V> subslice (V &data, typename V::size_type start, typename V::difference_type stride, typename V::size_type size) {
1087 typedef basic_slice<typename V::size_type, typename V::difference_type> slice_type;
1088 return vector_slice<V> (data, slice_type (start, stride, size));
1089 }
1090 template<class V>
1091 BOOST_UBLAS_INLINE
1092 vector_slice<const V> subslice (const V &data, typename V::size_type start, typename V::difference_type stride, typename V::size_type size) {
1093 typedef basic_slice<typename V::size_type, typename V::difference_type> slice_type;
1094 return vector_slice<const V> (data, slice_type (start, stride, size));
1095 }
1096
1097
1098 template<class V>
1099 BOOST_UBLAS_INLINE
1100 vector_slice<V> project (V &data, const typename vector_slice<V>::slice_type &s) {
1101 return vector_slice<V> (data, s);
1102 }
1103 template<class V>
1104 BOOST_UBLAS_INLINE
1105 const vector_slice<const V> project (const V &data, const typename vector_slice<V>::slice_type &s) {
1106
1107 return vector_slice<const V> (data, s);
1108 }
1109 template<class V>
1110 BOOST_UBLAS_INLINE
1111 vector_slice<V> project (vector_slice<V> &data, const typename vector_slice<V>::slice_type &s) {
1112 return data.project (s);
1113 }
1114 template<class V>
1115 BOOST_UBLAS_INLINE
1116 const vector_slice<V> project (const vector_slice<V> &data, const typename vector_slice<V>::slice_type &s) {
1117 return data.project (s);
1118 }
1119
1120 template<class V>
1121 BOOST_UBLAS_INLINE
1122 vector_slice<V> project (vector_slice<V> &data, const typename vector_range<V>::range_type &r) {
1123 return data.project (r);
1124 }
1125 template<class V>
1126 BOOST_UBLAS_INLINE
1127 const vector_slice<V> project (const vector_slice<V> &data, const typename vector_range<V>::range_type &r) {
1128 return data.project (r);
1129 }
1130
1131
1132 template <class V>
1133 struct vector_temporary_traits< vector_slice<V> >
1134 : vector_temporary_traits< V > {} ;
1135 template <class V>
1136 struct vector_temporary_traits< const vector_slice<V> >
1137 : vector_temporary_traits< V > {} ;
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163 template<class V, class IA>
1164 class vector_indirect:
1165 public vector_expression<vector_indirect<V, IA> > {
1166
1167 typedef vector_indirect<V, IA> self_type;
1168 public:
1169 #ifdef BOOST_UBLAS_ENABLE_PROXY_SHORTCUTS
1170 using vector_expression<self_type>::operator ();
1171 #endif
1172 typedef const V const_vector_type;
1173 typedef V vector_type;
1174 typedef const IA const_indirect_array_type;
1175 typedef IA indirect_array_type;
1176 typedef typename V::size_type size_type;
1177 typedef typename V::difference_type difference_type;
1178 typedef typename V::value_type value_type;
1179 typedef typename V::const_reference const_reference;
1180 typedef typename boost::mpl::if_<boost::is_const<V>,
1181 typename V::const_reference,
1182 typename V::reference>::type reference;
1183 typedef typename boost::mpl::if_<boost::is_const<V>,
1184 typename V::const_closure_type,
1185 typename V::closure_type>::type vector_closure_type;
1186 typedef basic_range<size_type, difference_type> range_type;
1187 typedef basic_slice<size_type, difference_type> slice_type;
1188 typedef const self_type const_closure_type;
1189 typedef self_type closure_type;
1190 typedef typename storage_restrict_traits<typename V::storage_category,
1191 dense_proxy_tag>::storage_category storage_category;
1192
1193
1194 BOOST_UBLAS_INLINE
1195 vector_indirect (vector_type &data, size_type size):
1196 data_ (data), ia_ (size) {}
1197 BOOST_UBLAS_INLINE
1198 vector_indirect (vector_type &data, const indirect_array_type &ia):
1199 data_ (data), ia_ (ia.preprocess (data.size ())) {}
1200 BOOST_UBLAS_INLINE
1201 vector_indirect (const vector_closure_type &data, const indirect_array_type &ia, int):
1202 data_ (data), ia_ (ia.preprocess (data.size ())) {}
1203
1204
1205 BOOST_UBLAS_INLINE
1206 size_type size () const {
1207 return ia_.size ();
1208 }
1209 BOOST_UBLAS_INLINE
1210 const_indirect_array_type &indirect () const {
1211 return ia_;
1212 }
1213 BOOST_UBLAS_INLINE
1214 indirect_array_type &indirect () {
1215 return ia_;
1216 }
1217
1218
1219 BOOST_UBLAS_INLINE
1220 const vector_closure_type &data () const {
1221 return data_;
1222 }
1223 BOOST_UBLAS_INLINE
1224 vector_closure_type &data () {
1225 return data_;
1226 }
1227
1228
1229 #ifndef BOOST_UBLAS_PROXY_CONST_MEMBER
1230 BOOST_UBLAS_INLINE
1231 const_reference operator () (size_type i) const {
1232 return data_ (ia_ (i));
1233 }
1234 BOOST_UBLAS_INLINE
1235 reference operator () (size_type i) {
1236 return data_ (ia_ (i));
1237 }
1238
1239 BOOST_UBLAS_INLINE
1240 const_reference operator [] (size_type i) const {
1241 return (*this) (i);
1242 }
1243 BOOST_UBLAS_INLINE
1244 reference operator [] (size_type i) {
1245 return (*this) (i);
1246 }
1247 #else
1248 BOOST_UBLAS_INLINE
1249 reference operator () (size_type i) const {
1250 return data_ (ia_ (i));
1251 }
1252
1253 BOOST_UBLAS_INLINE
1254 reference operator [] (size_type i) const {
1255 return (*this) (i);
1256 }
1257 #endif
1258
1259
1260
1261
1262 BOOST_UBLAS_INLINE
1263 vector_indirect<vector_type, indirect_array_type> project (const range_type &r) const {
1264 return vector_indirect<vector_type, indirect_array_type> (data_, ia_.compose (r.preprocess (data_.size ())), 0);
1265 }
1266 BOOST_UBLAS_INLINE
1267 vector_indirect<vector_type, indirect_array_type> project (const slice_type &s) const {
1268 return vector_indirect<vector_type, indirect_array_type> (data_, ia_.compose (s.preprocess (data_.size ())), 0);
1269 }
1270 BOOST_UBLAS_INLINE
1271 vector_indirect<vector_type, indirect_array_type> project (const indirect_array_type &ia) const {
1272 return vector_indirect<vector_type, indirect_array_type> (data_, ia_.compose (ia.preprocess (data_.size ())), 0);
1273 }
1274
1275
1276 BOOST_UBLAS_INLINE
1277 vector_indirect &operator = (const vector_indirect &vi) {
1278
1279 vector_assign<scalar_assign> (*this, typename vector_temporary_traits<V>::type (vi));
1280 return *this;
1281 }
1282 BOOST_UBLAS_INLINE
1283 vector_indirect &assign_temporary (vector_indirect &vi) {
1284
1285 vector_assign<scalar_assign> (*this, vi);
1286 return *this;
1287 }
1288 template<class AE>
1289 BOOST_UBLAS_INLINE
1290 vector_indirect &operator = (const vector_expression<AE> &ae) {
1291 vector_assign<scalar_assign> (*this, typename vector_temporary_traits<V>::type (ae));
1292 return *this;
1293 }
1294 template<class AE>
1295 BOOST_UBLAS_INLINE
1296 vector_indirect &assign (const vector_expression<AE> &ae) {
1297 vector_assign<scalar_assign> (*this, ae);
1298 return *this;
1299 }
1300 template<class AE>
1301 BOOST_UBLAS_INLINE
1302 vector_indirect &operator += (const vector_expression<AE> &ae) {
1303 vector_assign<scalar_assign> (*this, typename vector_temporary_traits<V>::type (*this + ae));
1304 return *this;
1305 }
1306 template<class AE>
1307 BOOST_UBLAS_INLINE
1308 vector_indirect &plus_assign (const vector_expression<AE> &ae) {
1309 vector_assign<scalar_plus_assign> (*this, ae);
1310 return *this;
1311 }
1312 template<class AE>
1313 BOOST_UBLAS_INLINE
1314 vector_indirect &operator -= (const vector_expression<AE> &ae) {
1315 vector_assign<scalar_assign> (*this, typename vector_temporary_traits<V>::type (*this - ae));
1316 return *this;
1317 }
1318 template<class AE>
1319 BOOST_UBLAS_INLINE
1320 vector_indirect &minus_assign (const vector_expression<AE> &ae) {
1321 vector_assign<scalar_minus_assign> (*this, ae);
1322 return *this;
1323 }
1324 template<class AT>
1325 BOOST_UBLAS_INLINE
1326 vector_indirect &operator *= (const AT &at) {
1327 vector_assign_scalar<scalar_multiplies_assign> (*this, at);
1328 return *this;
1329 }
1330 template<class AT>
1331 BOOST_UBLAS_INLINE
1332 vector_indirect &operator /= (const AT &at) {
1333 vector_assign_scalar<scalar_divides_assign> (*this, at);
1334 return *this;
1335 }
1336
1337
1338 BOOST_UBLAS_INLINE
1339 bool same_closure (const vector_indirect &) const {
1340 return true;
1341 }
1342
1343
1344 BOOST_UBLAS_INLINE
1345 bool operator == (const vector_indirect &vi) const {
1346 return (*this).data_ == vi.data_ && ia_ == vi.ia_;
1347 }
1348
1349
1350 BOOST_UBLAS_INLINE
1351 void swap (vector_indirect vi) {
1352 if (this != &vi) {
1353 BOOST_UBLAS_CHECK (size () == vi.size (), bad_size ());
1354
1355
1356 vector_swap<scalar_swap> (*this, vi);
1357 }
1358 }
1359 BOOST_UBLAS_INLINE
1360 friend void swap (vector_indirect vi1, vector_indirect vi2) {
1361 vi1.swap (vi2);
1362 }
1363
1364
1365 private:
1366
1367 typedef typename IA::const_iterator const_subiterator_type;
1368 typedef typename IA::const_iterator subiterator_type;
1369
1370 public:
1371 #ifdef BOOST_UBLAS_USE_INDEXED_ITERATOR
1372 typedef indexed_iterator<vector_indirect<vector_type, indirect_array_type>,
1373 typename vector_type::iterator::iterator_category> iterator;
1374 typedef indexed_const_iterator<vector_indirect<vector_type, indirect_array_type>,
1375 typename vector_type::const_iterator::iterator_category> const_iterator;
1376 #else
1377 class const_iterator;
1378 class iterator;
1379 #endif
1380
1381 BOOST_UBLAS_INLINE
1382 const_iterator find (size_type i) const {
1383 #ifdef BOOST_UBLAS_USE_INDEXED_ITERATOR
1384 return const_iterator (*this, i);
1385 #else
1386 return const_iterator (*this, ia_.begin () + i);
1387 #endif
1388 }
1389 BOOST_UBLAS_INLINE
1390 iterator find (size_type i) {
1391 #ifdef BOOST_UBLAS_USE_INDEXED_ITERATOR
1392 return iterator (*this, i);
1393 #else
1394 return iterator (*this, ia_.begin () + i);
1395 #endif
1396 }
1397
1398
1399
1400 #ifndef BOOST_UBLAS_USE_INDEXED_ITERATOR
1401 class const_iterator:
1402 public container_const_reference<vector_indirect>,
1403 public iterator_base_traits<typename V::const_iterator::iterator_category>::template
1404 iterator_base<const_iterator, value_type>::type {
1405 public:
1406 typedef typename V::const_iterator::difference_type difference_type;
1407 typedef typename V::const_iterator::value_type value_type;
1408 typedef typename V::const_reference reference;
1409 typedef typename V::const_iterator::pointer pointer;
1410
1411
1412 BOOST_UBLAS_INLINE
1413 const_iterator ():
1414 container_const_reference<self_type> (), it_ () {}
1415 BOOST_UBLAS_INLINE
1416 const_iterator (const self_type &vi, const const_subiterator_type &it):
1417 container_const_reference<self_type> (vi), it_ (it) {}
1418 BOOST_UBLAS_INLINE
1419 const_iterator (const typename self_type::iterator &it):
1420 container_const_reference<self_type> (it ()), it_ (it.it_) {}
1421
1422
1423 BOOST_UBLAS_INLINE
1424 const_iterator &operator ++ () {
1425 ++ it_;
1426 return *this;
1427 }
1428 BOOST_UBLAS_INLINE
1429 const_iterator &operator -- () {
1430 -- it_;
1431 return *this;
1432 }
1433 BOOST_UBLAS_INLINE
1434 const_iterator &operator += (difference_type n) {
1435 it_ += n;
1436 return *this;
1437 }
1438 BOOST_UBLAS_INLINE
1439 const_iterator &operator -= (difference_type n) {
1440 it_ -= n;
1441 return *this;
1442 }
1443 BOOST_UBLAS_INLINE
1444 difference_type operator - (const const_iterator &it) const {
1445 BOOST_UBLAS_CHECK ((*this) ().same_closure (it ()), external_logic ());
1446 return it_ - it.it_;
1447 }
1448
1449
1450 BOOST_UBLAS_INLINE
1451 const_reference operator * () const {
1452
1453 BOOST_UBLAS_CHECK (index () < (*this) ().size (), bad_index ());
1454 return (*this) ().data_ (*it_);
1455 }
1456 BOOST_UBLAS_INLINE
1457 const_reference operator [] (difference_type n) const {
1458 return *(*this + n);
1459 }
1460
1461
1462 BOOST_UBLAS_INLINE
1463 size_type index () const {
1464 return it_.index ();
1465 }
1466
1467
1468 BOOST_UBLAS_INLINE
1469 const_iterator &operator = (const const_iterator &it) {
1470 container_const_reference<self_type>::assign (&it ());
1471 it_ = it.it_;
1472 return *this;
1473 }
1474
1475
1476 BOOST_UBLAS_INLINE
1477 bool operator == (const const_iterator &it) const {
1478 BOOST_UBLAS_CHECK ((*this) ().same_closure (it ()), external_logic ());
1479 return it_ == it.it_;
1480 }
1481 BOOST_UBLAS_INLINE
1482 bool operator < (const const_iterator &it) const {
1483 BOOST_UBLAS_CHECK ((*this) ().same_closure (it ()), external_logic ());
1484 return it_ < it.it_;
1485 }
1486
1487 private:
1488 const_subiterator_type it_;
1489 };
1490 #endif
1491
1492 BOOST_UBLAS_INLINE
1493 const_iterator begin () const {
1494 return find (0);
1495 }
1496 BOOST_UBLAS_INLINE
1497 const_iterator cbegin () const {
1498 return begin ();
1499 }
1500 BOOST_UBLAS_INLINE
1501 const_iterator end () const {
1502 return find (size ());
1503 }
1504 BOOST_UBLAS_INLINE
1505 const_iterator cend () const {
1506 return end ();
1507 }
1508
1509 #ifndef BOOST_UBLAS_USE_INDEXED_ITERATOR
1510 class iterator:
1511 public container_reference<vector_indirect>,
1512 public iterator_base_traits<typename V::iterator::iterator_category>::template
1513 iterator_base<iterator, value_type>::type {
1514 public:
1515 typedef typename V::iterator::difference_type difference_type;
1516 typedef typename V::iterator::value_type value_type;
1517 typedef typename V::reference reference;
1518 typedef typename V::iterator::pointer pointer;
1519
1520
1521 BOOST_UBLAS_INLINE
1522 iterator ():
1523 container_reference<self_type> (), it_ () {}
1524 BOOST_UBLAS_INLINE
1525 iterator (self_type &vi, const subiterator_type &it):
1526 container_reference<self_type> (vi), it_ (it) {}
1527
1528
1529 BOOST_UBLAS_INLINE
1530 iterator &operator ++ () {
1531 ++ it_;
1532 return *this;
1533 }
1534 BOOST_UBLAS_INLINE
1535 iterator &operator -- () {
1536 -- it_;
1537 return *this;
1538 }
1539 BOOST_UBLAS_INLINE
1540 iterator &operator += (difference_type n) {
1541 it_ += n;
1542 return *this;
1543 }
1544 BOOST_UBLAS_INLINE
1545 iterator &operator -= (difference_type n) {
1546 it_ -= n;
1547 return *this;
1548 }
1549 BOOST_UBLAS_INLINE
1550 difference_type operator - (const iterator &it) const {
1551 BOOST_UBLAS_CHECK ((*this) ().same_closure (it ()), external_logic ());
1552 return it_ - it.it_;
1553 }
1554
1555
1556 BOOST_UBLAS_INLINE
1557 reference operator * () const {
1558
1559 BOOST_UBLAS_CHECK (index () < (*this) ().size (), bad_index ());
1560 return (*this) ().data_ (*it_);
1561 }
1562 BOOST_UBLAS_INLINE
1563 reference operator [] (difference_type n) const {
1564 return *(*this + n);
1565 }
1566
1567
1568 BOOST_UBLAS_INLINE
1569 size_type index () const {
1570 return it_.index ();
1571 }
1572
1573
1574 BOOST_UBLAS_INLINE
1575 iterator &operator = (const iterator &it) {
1576 container_reference<self_type>::assign (&it ());
1577 it_ = it.it_;
1578 return *this;
1579 }
1580
1581
1582 BOOST_UBLAS_INLINE
1583 bool operator == (const iterator &it) const {
1584 BOOST_UBLAS_CHECK ((*this) ().same_closure (it ()), external_logic ());
1585 return it_ == it.it_;
1586 }
1587 BOOST_UBLAS_INLINE
1588 bool operator < (const iterator &it) const {
1589 BOOST_UBLAS_CHECK ((*this) ().same_closure (it ()), external_logic ());
1590 return it_ < it.it_;
1591 }
1592
1593 private:
1594 subiterator_type it_;
1595
1596 friend class const_iterator;
1597 };
1598 #endif
1599
1600 BOOST_UBLAS_INLINE
1601 iterator begin () {
1602 return find (0);
1603 }
1604 BOOST_UBLAS_INLINE
1605 iterator end () {
1606 return find (size ());
1607 }
1608
1609
1610 typedef reverse_iterator_base<const_iterator> const_reverse_iterator;
1611 typedef reverse_iterator_base<iterator> reverse_iterator;
1612
1613 BOOST_UBLAS_INLINE
1614 const_reverse_iterator rbegin () const {
1615 return const_reverse_iterator (end ());
1616 }
1617 BOOST_UBLAS_INLINE
1618 const_reverse_iterator crbegin () const {
1619 return rbegin ();
1620 }
1621 BOOST_UBLAS_INLINE
1622 const_reverse_iterator rend () const {
1623 return const_reverse_iterator (begin ());
1624 }
1625 BOOST_UBLAS_INLINE
1626 const_reverse_iterator crend () const {
1627 return rend ();
1628 }
1629
1630 BOOST_UBLAS_INLINE
1631 reverse_iterator rbegin () {
1632 return reverse_iterator (end ());
1633 }
1634 BOOST_UBLAS_INLINE
1635 reverse_iterator rend () {
1636 return reverse_iterator (begin ());
1637 }
1638
1639 private:
1640 vector_closure_type data_;
1641 indirect_array_type ia_;
1642 };
1643
1644
1645 template<class V, class A>
1646 BOOST_UBLAS_INLINE
1647 vector_indirect<V, indirect_array<A> > project (V &data, const indirect_array<A> &ia) {
1648 return vector_indirect<V, indirect_array<A> > (data, ia);
1649 }
1650 template<class V, class A>
1651 BOOST_UBLAS_INLINE
1652 const vector_indirect<const V, indirect_array<A> > project (const V &data, const indirect_array<A> &ia) {
1653
1654 return vector_indirect<const V, indirect_array<A> > (data, ia);
1655 }
1656 template<class V, class IA>
1657 BOOST_UBLAS_INLINE
1658 vector_indirect<V, IA> project (vector_indirect<V, IA> &data, const typename vector_indirect<V, IA>::range_type &r) {
1659 return data.project (r);
1660 }
1661 template<class V, class IA>
1662 BOOST_UBLAS_INLINE
1663 const vector_indirect<V, IA> project (const vector_indirect<V, IA> &data, const typename vector_indirect<V, IA>::range_type &r) {
1664 return data.project (r);
1665 }
1666 template<class V, class IA>
1667 BOOST_UBLAS_INLINE
1668 vector_indirect<V, IA> project (vector_indirect<V, IA> &data, const typename vector_indirect<V, IA>::slice_type &s) {
1669 return data.project (s);
1670 }
1671 template<class V, class IA>
1672 BOOST_UBLAS_INLINE
1673 const vector_indirect<V, IA> project (const vector_indirect<V, IA> &data, const typename vector_indirect<V, IA>::slice_type &s) {
1674 return data.project (s);
1675 }
1676 template<class V, class A>
1677 BOOST_UBLAS_INLINE
1678 vector_indirect<V, indirect_array<A> > project (vector_indirect<V, indirect_array<A> > &data, const indirect_array<A> &ia) {
1679 return data.project (ia);
1680 }
1681 template<class V, class A>
1682 BOOST_UBLAS_INLINE
1683 const vector_indirect<V, indirect_array<A> > project (const vector_indirect<V, indirect_array<A> > &data, const indirect_array<A> &ia) {
1684 return data.project (ia);
1685 }
1686
1687
1688 template <class V>
1689 struct vector_temporary_traits< vector_indirect<V> >
1690 : vector_temporary_traits< V > {} ;
1691 template <class V>
1692 struct vector_temporary_traits< const vector_indirect<V> >
1693 : vector_temporary_traits< V > {} ;
1694
1695 }}}
1696
1697 #endif