annotate DEPENDENCIES/generic/include/boost/numeric/ublas/vector_proxy.hpp @ 133:4acb5d8d80b6 tip

Don't fail environmental check if README.md exists (but .txt and no-suffix don't)
author Chris Cannam
date Tue, 30 Jul 2019 12:25:44 +0100
parents c530137014c0
children
rev   line source
Chris@16 1 //
Chris@16 2 // Copyright (c) 2000-2002
Chris@16 3 // Joerg Walter, Mathias Koch
Chris@16 4 //
Chris@16 5 // Distributed under the Boost Software License, Version 1.0. (See
Chris@16 6 // accompanying file LICENSE_1_0.txt or copy at
Chris@16 7 // http://www.boost.org/LICENSE_1_0.txt)
Chris@16 8 //
Chris@16 9 // The authors gratefully acknowledge the support of
Chris@16 10 // GeNeSys mbH & Co. KG in producing this work.
Chris@16 11 //
Chris@16 12
Chris@16 13 #ifndef _BOOST_UBLAS_VECTOR_PROXY_
Chris@16 14 #define _BOOST_UBLAS_VECTOR_PROXY_
Chris@16 15
Chris@16 16 #include <boost/numeric/ublas/vector_expression.hpp>
Chris@16 17 #include <boost/numeric/ublas/detail/vector_assign.hpp>
Chris@16 18 #include <boost/numeric/ublas/detail/temporary.hpp>
Chris@16 19
Chris@16 20 // Iterators based on ideas of Jeremy Siek
Chris@16 21
Chris@16 22 namespace boost { namespace numeric { namespace ublas {
Chris@16 23
Chris@16 24 /** \brief A vector referencing a continuous subvector of elements of vector \c v containing all elements specified by \c range.
Chris@16 25 *
Chris@16 26 * A vector range can be used as a normal vector in any expression.
Chris@16 27 * If the specified range falls outside that of the index range of the vector, then
Chris@16 28 * the \c vector_range is not a well formed \i Vector \i Expression and access to an
Chris@16 29 * element outside of index range of the vector is \b undefined.
Chris@16 30 *
Chris@16 31 * \tparam V the type of vector referenced (for example \c vector<double>)
Chris@16 32 */
Chris@16 33 template<class V>
Chris@16 34 class vector_range:
Chris@16 35 public vector_expression<vector_range<V> > {
Chris@16 36
Chris@16 37 typedef vector_range<V> self_type;
Chris@16 38 public:
Chris@16 39 #ifdef BOOST_UBLAS_ENABLE_PROXY_SHORTCUTS
Chris@16 40 using vector_expression<self_type>::operator ();
Chris@16 41 #endif
Chris@16 42 typedef const V const_vector_type;
Chris@16 43 typedef V vector_type;
Chris@16 44 typedef typename V::size_type size_type;
Chris@16 45 typedef typename V::difference_type difference_type;
Chris@16 46 typedef typename V::value_type value_type;
Chris@16 47 typedef typename V::const_reference const_reference;
Chris@16 48 typedef typename boost::mpl::if_<boost::is_const<V>,
Chris@16 49 typename V::const_reference,
Chris@16 50 typename V::reference>::type reference;
Chris@16 51 typedef typename boost::mpl::if_<boost::is_const<V>,
Chris@16 52 typename V::const_closure_type,
Chris@16 53 typename V::closure_type>::type vector_closure_type;
Chris@16 54 typedef basic_range<size_type, difference_type> range_type;
Chris@16 55 typedef const self_type const_closure_type;
Chris@16 56 typedef self_type closure_type;
Chris@16 57 typedef typename storage_restrict_traits<typename V::storage_category,
Chris@16 58 dense_proxy_tag>::storage_category storage_category;
Chris@16 59
Chris@16 60 // Construction and destruction
Chris@16 61 BOOST_UBLAS_INLINE
Chris@16 62 vector_range (vector_type &data, const range_type &r):
Chris@16 63 data_ (data), r_ (r.preprocess (data.size ())) {
Chris@16 64 // Early checking of preconditions here.
Chris@16 65 // BOOST_UBLAS_CHECK (r_.start () <= data_.size () &&
Chris@16 66 // r_.start () + r_.size () <= data_.size (), bad_index ());
Chris@16 67 }
Chris@16 68 BOOST_UBLAS_INLINE
Chris@16 69 vector_range (const vector_closure_type &data, const range_type &r, bool):
Chris@16 70 data_ (data), r_ (r.preprocess (data.size ())) {
Chris@16 71 // Early checking of preconditions here.
Chris@16 72 // BOOST_UBLAS_CHECK (r_.start () <= data_.size () &&
Chris@16 73 // r_.start () + r_.size () <= data_.size (), bad_index ());
Chris@16 74 }
Chris@16 75
Chris@16 76 // Accessors
Chris@16 77 BOOST_UBLAS_INLINE
Chris@16 78 size_type start () const {
Chris@16 79 return r_.start ();
Chris@16 80 }
Chris@16 81 BOOST_UBLAS_INLINE
Chris@16 82 size_type size () const {
Chris@16 83 return r_.size ();
Chris@16 84 }
Chris@16 85
Chris@16 86 // Storage accessors
Chris@16 87 BOOST_UBLAS_INLINE
Chris@16 88 const vector_closure_type &data () const {
Chris@16 89 return data_;
Chris@16 90 }
Chris@16 91 BOOST_UBLAS_INLINE
Chris@16 92 vector_closure_type &data () {
Chris@16 93 return data_;
Chris@16 94 }
Chris@16 95
Chris@16 96 // Element access
Chris@16 97 #ifndef BOOST_UBLAS_PROXY_CONST_MEMBER
Chris@16 98 BOOST_UBLAS_INLINE
Chris@16 99 const_reference operator () (size_type i) const {
Chris@16 100 return data_ (r_ (i));
Chris@16 101 }
Chris@16 102 BOOST_UBLAS_INLINE
Chris@16 103 reference operator () (size_type i) {
Chris@16 104 return data_ (r_ (i));
Chris@16 105 }
Chris@16 106
Chris@16 107 BOOST_UBLAS_INLINE
Chris@16 108 const_reference operator [] (size_type i) const {
Chris@16 109 return (*this) (i);
Chris@16 110 }
Chris@16 111 BOOST_UBLAS_INLINE
Chris@16 112 reference operator [] (size_type i) {
Chris@16 113 return (*this) (i);
Chris@16 114 }
Chris@16 115 #else
Chris@16 116 BOOST_UBLAS_INLINE
Chris@16 117 reference operator () (size_type i) const {
Chris@16 118 return data_ (r_ (i));
Chris@16 119 }
Chris@16 120
Chris@16 121 BOOST_UBLAS_INLINE
Chris@16 122 reference operator [] (size_type i) const {
Chris@16 123 return (*this) (i);
Chris@16 124 }
Chris@16 125 #endif
Chris@16 126
Chris@16 127 // ISSUE can this be done in free project function?
Chris@16 128 // Although a const function can create a non-const proxy to a non-const object
Chris@16 129 // Critical is that vector_type and data_ (vector_closure_type) are const correct
Chris@16 130 BOOST_UBLAS_INLINE
Chris@16 131 vector_range<vector_type> project (const range_type &r) const {
Chris@16 132 return vector_range<vector_type> (data_, r_.compose (r.preprocess (data_.size ())), false);
Chris@16 133 }
Chris@16 134
Chris@16 135 // Assignment
Chris@16 136 BOOST_UBLAS_INLINE
Chris@16 137 vector_range &operator = (const vector_range &vr) {
Chris@16 138 // ISSUE need a temporary, proxy can be overlaping alias
Chris@16 139 vector_assign<scalar_assign> (*this, typename vector_temporary_traits<V>::type (vr));
Chris@16 140 return *this;
Chris@16 141 }
Chris@16 142 BOOST_UBLAS_INLINE
Chris@16 143 vector_range &assign_temporary (vector_range &vr) {
Chris@16 144 // assign elements, proxied container remains the same
Chris@16 145 vector_assign<scalar_assign> (*this, vr);
Chris@16 146 return *this;
Chris@16 147 }
Chris@16 148 template<class AE>
Chris@16 149 BOOST_UBLAS_INLINE
Chris@16 150 vector_range &operator = (const vector_expression<AE> &ae) {
Chris@16 151 vector_assign<scalar_assign> (*this, typename vector_temporary_traits<V>::type (ae));
Chris@16 152 return *this;
Chris@16 153 }
Chris@16 154 template<class AE>
Chris@16 155 BOOST_UBLAS_INLINE
Chris@16 156 vector_range &assign (const vector_expression<AE> &ae) {
Chris@16 157 vector_assign<scalar_assign> (*this, ae);
Chris@16 158 return *this;
Chris@16 159 }
Chris@16 160 template<class AE>
Chris@16 161 BOOST_UBLAS_INLINE
Chris@16 162 vector_range &operator += (const vector_expression<AE> &ae) {
Chris@16 163 vector_assign<scalar_assign> (*this, typename vector_temporary_traits<V>::type (*this + ae));
Chris@16 164 return *this;
Chris@16 165 }
Chris@16 166 template<class AE>
Chris@16 167 BOOST_UBLAS_INLINE
Chris@16 168 vector_range &plus_assign (const vector_expression<AE> &ae) {
Chris@16 169 vector_assign<scalar_plus_assign> (*this, ae);
Chris@16 170 return *this;
Chris@16 171 }
Chris@16 172 template<class AE>
Chris@16 173 BOOST_UBLAS_INLINE
Chris@16 174 vector_range &operator -= (const vector_expression<AE> &ae) {
Chris@16 175 vector_assign<scalar_assign> (*this, typename vector_temporary_traits<V>::type (*this - ae));
Chris@16 176 return *this;
Chris@16 177 }
Chris@16 178 template<class AE>
Chris@16 179 BOOST_UBLAS_INLINE
Chris@16 180 vector_range &minus_assign (const vector_expression<AE> &ae) {
Chris@16 181 vector_assign<scalar_minus_assign> (*this, ae);
Chris@16 182 return *this;
Chris@16 183 }
Chris@16 184 template<class AT>
Chris@16 185 BOOST_UBLAS_INLINE
Chris@16 186 vector_range &operator *= (const AT &at) {
Chris@16 187 vector_assign_scalar<scalar_multiplies_assign> (*this, at);
Chris@16 188 return *this;
Chris@16 189 }
Chris@16 190 template<class AT>
Chris@16 191 BOOST_UBLAS_INLINE
Chris@16 192 vector_range &operator /= (const AT &at) {
Chris@16 193 vector_assign_scalar<scalar_divides_assign> (*this, at);
Chris@16 194 return *this;
Chris@16 195 }
Chris@16 196
Chris@16 197 // Closure comparison
Chris@16 198 BOOST_UBLAS_INLINE
Chris@16 199 bool same_closure (const vector_range &vr) const {
Chris@16 200 return (*this).data_.same_closure (vr.data_);
Chris@16 201 }
Chris@16 202
Chris@16 203 // Comparison
Chris@16 204 BOOST_UBLAS_INLINE
Chris@16 205 bool operator == (const vector_range &vr) const {
Chris@16 206 return (*this).data_ == vr.data_ && r_ == vr.r_;
Chris@16 207 }
Chris@16 208
Chris@16 209 // Swapping
Chris@16 210 BOOST_UBLAS_INLINE
Chris@16 211 void swap (vector_range vr) {
Chris@16 212 if (this != &vr) {
Chris@16 213 BOOST_UBLAS_CHECK (size () == vr.size (), bad_size ());
Chris@16 214 // Sparse ranges may be nonconformant now.
Chris@16 215 // std::swap_ranges (begin (), end (), vr.begin ());
Chris@16 216 vector_swap<scalar_swap> (*this, vr);
Chris@16 217 }
Chris@16 218 }
Chris@16 219 BOOST_UBLAS_INLINE
Chris@16 220 friend void swap (vector_range vr1, vector_range vr2) {
Chris@16 221 vr1.swap (vr2);
Chris@16 222 }
Chris@16 223
Chris@16 224 // Iterator types
Chris@16 225 private:
Chris@16 226 typedef typename V::const_iterator const_subiterator_type;
Chris@16 227 typedef typename boost::mpl::if_<boost::is_const<V>,
Chris@16 228 typename V::const_iterator,
Chris@16 229 typename V::iterator>::type subiterator_type;
Chris@16 230
Chris@16 231 public:
Chris@16 232 #ifdef BOOST_UBLAS_USE_INDEXED_ITERATOR
Chris@16 233 typedef indexed_iterator<vector_range<vector_type>,
Chris@16 234 typename subiterator_type::iterator_category> iterator;
Chris@16 235 typedef indexed_const_iterator<vector_range<vector_type>,
Chris@16 236 typename const_subiterator_type::iterator_category> const_iterator;
Chris@16 237 #else
Chris@16 238 class const_iterator;
Chris@16 239 class iterator;
Chris@16 240 #endif
Chris@16 241
Chris@16 242 // Element lookup
Chris@16 243 BOOST_UBLAS_INLINE
Chris@16 244 const_iterator find (size_type i) const {
Chris@16 245 const_subiterator_type it (data_.find (start () + i));
Chris@16 246 #ifdef BOOST_UBLAS_USE_INDEXED_ITERATOR
Chris@16 247 return const_iterator (*this, it.index ());
Chris@16 248 #else
Chris@16 249 return const_iterator (*this, it);
Chris@16 250 #endif
Chris@16 251 }
Chris@16 252 BOOST_UBLAS_INLINE
Chris@16 253 iterator find (size_type i) {
Chris@16 254 subiterator_type it (data_.find (start () + i));
Chris@16 255 #ifdef BOOST_UBLAS_USE_INDEXED_ITERATOR
Chris@16 256 return iterator (*this, it.index ());
Chris@16 257 #else
Chris@16 258 return iterator (*this, it);
Chris@16 259 #endif
Chris@16 260 }
Chris@16 261
Chris@16 262 #ifndef BOOST_UBLAS_USE_INDEXED_ITERATOR
Chris@16 263 class const_iterator:
Chris@16 264 public container_const_reference<vector_range>,
Chris@16 265 public iterator_base_traits<typename const_subiterator_type::iterator_category>::template
Chris@16 266 iterator_base<const_iterator, value_type>::type {
Chris@16 267 public:
Chris@16 268 typedef typename const_subiterator_type::difference_type difference_type;
Chris@16 269 typedef typename const_subiterator_type::value_type value_type;
Chris@16 270 typedef typename const_subiterator_type::reference reference;
Chris@16 271 typedef typename const_subiterator_type::pointer pointer;
Chris@16 272
Chris@16 273 // Construction and destruction
Chris@16 274 BOOST_UBLAS_INLINE
Chris@16 275 const_iterator ():
Chris@16 276 container_const_reference<self_type> (), it_ () {}
Chris@16 277 BOOST_UBLAS_INLINE
Chris@16 278 const_iterator (const self_type &vr, const const_subiterator_type &it):
Chris@16 279 container_const_reference<self_type> (vr), it_ (it) {}
Chris@16 280 BOOST_UBLAS_INLINE
Chris@16 281 const_iterator (const typename self_type::iterator &it): // ISSUE self_type:: stops VC8 using std::iterator here
Chris@16 282 container_const_reference<self_type> (it ()), it_ (it.it_) {}
Chris@16 283
Chris@16 284 // Arithmetic
Chris@16 285 BOOST_UBLAS_INLINE
Chris@16 286 const_iterator &operator ++ () {
Chris@16 287 ++ it_;
Chris@16 288 return *this;
Chris@16 289 }
Chris@16 290 BOOST_UBLAS_INLINE
Chris@16 291 const_iterator &operator -- () {
Chris@16 292 -- it_;
Chris@16 293 return *this;
Chris@16 294 }
Chris@16 295 BOOST_UBLAS_INLINE
Chris@16 296 const_iterator &operator += (difference_type n) {
Chris@16 297 it_ += n;
Chris@16 298 return *this;
Chris@16 299 }
Chris@16 300 BOOST_UBLAS_INLINE
Chris@16 301 const_iterator &operator -= (difference_type n) {
Chris@16 302 it_ -= n;
Chris@16 303 return *this;
Chris@16 304 }
Chris@16 305 BOOST_UBLAS_INLINE
Chris@16 306 difference_type operator - (const const_iterator &it) const {
Chris@16 307 BOOST_UBLAS_CHECK ((*this) ().same_closure (it ()), external_logic ());
Chris@16 308 return it_ - it.it_;
Chris@16 309 }
Chris@16 310
Chris@16 311 // Dereference
Chris@16 312 BOOST_UBLAS_INLINE
Chris@16 313 const_reference operator * () const {
Chris@16 314 BOOST_UBLAS_CHECK (index () < (*this) ().size (), bad_index ());
Chris@16 315 return *it_;
Chris@16 316 }
Chris@16 317 BOOST_UBLAS_INLINE
Chris@16 318 const_reference operator [] (difference_type n) const {
Chris@16 319 return *(*this + n);
Chris@16 320 }
Chris@16 321
Chris@16 322 // Index
Chris@16 323 BOOST_UBLAS_INLINE
Chris@16 324 size_type index () const {
Chris@16 325 return it_.index () - (*this) ().start ();
Chris@16 326 }
Chris@16 327
Chris@16 328 // Assignment
Chris@16 329 BOOST_UBLAS_INLINE
Chris@16 330 const_iterator &operator = (const const_iterator &it) {
Chris@16 331 container_const_reference<self_type>::assign (&it ());
Chris@16 332 it_ = it.it_;
Chris@16 333 return *this;
Chris@16 334 }
Chris@16 335
Chris@16 336 // Comparison
Chris@16 337 BOOST_UBLAS_INLINE
Chris@16 338 bool operator == (const const_iterator &it) const {
Chris@16 339 BOOST_UBLAS_CHECK ((*this) ().same_closure (it ()), external_logic ());
Chris@16 340 return it_ == it.it_;
Chris@16 341 }
Chris@16 342 BOOST_UBLAS_INLINE
Chris@16 343 bool operator < (const const_iterator &it) const {
Chris@16 344 BOOST_UBLAS_CHECK ((*this) ().same_closure (it ()), external_logic ());
Chris@16 345 return it_ < it.it_;
Chris@16 346 }
Chris@16 347
Chris@16 348 private:
Chris@16 349 const_subiterator_type it_;
Chris@16 350 };
Chris@16 351 #endif
Chris@16 352
Chris@16 353 BOOST_UBLAS_INLINE
Chris@16 354 const_iterator begin () const {
Chris@16 355 return find (0);
Chris@16 356 }
Chris@16 357 BOOST_UBLAS_INLINE
Chris@101 358 const_iterator cbegin () const {
Chris@101 359 return begin ();
Chris@101 360 }
Chris@101 361 BOOST_UBLAS_INLINE
Chris@16 362 const_iterator end () const {
Chris@16 363 return find (size ());
Chris@16 364 }
Chris@101 365 BOOST_UBLAS_INLINE
Chris@101 366 const_iterator cend () const {
Chris@101 367 return end ();
Chris@101 368 }
Chris@16 369
Chris@16 370 #ifndef BOOST_UBLAS_USE_INDEXED_ITERATOR
Chris@16 371 class iterator:
Chris@16 372 public container_reference<vector_range>,
Chris@16 373 public iterator_base_traits<typename subiterator_type::iterator_category>::template
Chris@16 374 iterator_base<iterator, value_type>::type {
Chris@16 375 public:
Chris@16 376 typedef typename subiterator_type::difference_type difference_type;
Chris@16 377 typedef typename subiterator_type::value_type value_type;
Chris@16 378 typedef typename subiterator_type::reference reference;
Chris@16 379 typedef typename subiterator_type::pointer pointer;
Chris@16 380
Chris@16 381 // Construction and destruction
Chris@16 382 BOOST_UBLAS_INLINE
Chris@16 383 iterator ():
Chris@16 384 container_reference<self_type> (), it_ () {}
Chris@16 385 BOOST_UBLAS_INLINE
Chris@16 386 iterator (self_type &vr, const subiterator_type &it):
Chris@16 387 container_reference<self_type> (vr), it_ (it) {}
Chris@16 388
Chris@16 389 // Arithmetic
Chris@16 390 BOOST_UBLAS_INLINE
Chris@16 391 iterator &operator ++ () {
Chris@16 392 ++ it_;
Chris@16 393 return *this;
Chris@16 394 }
Chris@16 395 BOOST_UBLAS_INLINE
Chris@16 396 iterator &operator -- () {
Chris@16 397 -- it_;
Chris@16 398 return *this;
Chris@16 399 }
Chris@16 400 BOOST_UBLAS_INLINE
Chris@16 401 iterator &operator += (difference_type n) {
Chris@16 402 it_ += n;
Chris@16 403 return *this;
Chris@16 404 }
Chris@16 405 BOOST_UBLAS_INLINE
Chris@16 406 iterator &operator -= (difference_type n) {
Chris@16 407 it_ -= n;
Chris@16 408 return *this;
Chris@16 409 }
Chris@16 410 BOOST_UBLAS_INLINE
Chris@16 411 difference_type operator - (const iterator &it) const {
Chris@16 412 BOOST_UBLAS_CHECK ((*this) ().same_closure (it ()), external_logic ());
Chris@16 413 return it_ - it.it_;
Chris@16 414 }
Chris@16 415
Chris@16 416 // Dereference
Chris@16 417 BOOST_UBLAS_INLINE
Chris@16 418 reference operator * () const {
Chris@16 419 BOOST_UBLAS_CHECK (index () < (*this) ().size (), bad_index ());
Chris@16 420 return *it_;
Chris@16 421 }
Chris@16 422 BOOST_UBLAS_INLINE
Chris@16 423 reference operator [] (difference_type n) const {
Chris@16 424 return *(*this + n);
Chris@16 425 }
Chris@16 426
Chris@16 427 // Index
Chris@16 428 BOOST_UBLAS_INLINE
Chris@16 429 size_type index () const {
Chris@16 430 return it_.index () - (*this) ().start ();
Chris@16 431 }
Chris@16 432
Chris@16 433 // Assignment
Chris@16 434 BOOST_UBLAS_INLINE
Chris@16 435 iterator &operator = (const iterator &it) {
Chris@16 436 container_reference<self_type>::assign (&it ());
Chris@16 437 it_ = it.it_;
Chris@16 438 return *this;
Chris@16 439 }
Chris@16 440
Chris@16 441 // Comparison
Chris@16 442 BOOST_UBLAS_INLINE
Chris@16 443 bool operator == (const iterator &it) const {
Chris@16 444 BOOST_UBLAS_CHECK ((*this) ().same_closure (it ()), external_logic ());
Chris@16 445 return it_ == it.it_;
Chris@16 446 }
Chris@16 447 BOOST_UBLAS_INLINE
Chris@16 448 bool operator < (const iterator &it) const {
Chris@16 449 BOOST_UBLAS_CHECK ((*this) ().same_closure (it ()), external_logic ());
Chris@16 450 return it_ < it.it_;
Chris@16 451 }
Chris@16 452
Chris@16 453 private:
Chris@16 454 subiterator_type it_;
Chris@16 455
Chris@16 456 friend class const_iterator;
Chris@16 457 };
Chris@16 458 #endif
Chris@16 459
Chris@16 460 BOOST_UBLAS_INLINE
Chris@16 461 iterator begin () {
Chris@16 462 return find (0);
Chris@16 463 }
Chris@16 464 BOOST_UBLAS_INLINE
Chris@16 465 iterator end () {
Chris@16 466 return find (size ());
Chris@16 467 }
Chris@16 468
Chris@16 469 // Reverse iterator
Chris@16 470 typedef reverse_iterator_base<const_iterator> const_reverse_iterator;
Chris@16 471 typedef reverse_iterator_base<iterator> reverse_iterator;
Chris@16 472
Chris@16 473 BOOST_UBLAS_INLINE
Chris@16 474 const_reverse_iterator rbegin () const {
Chris@16 475 return const_reverse_iterator (end ());
Chris@16 476 }
Chris@16 477 BOOST_UBLAS_INLINE
Chris@101 478 const_reverse_iterator crbegin () const {
Chris@101 479 return rbegin ();
Chris@101 480 }
Chris@101 481 BOOST_UBLAS_INLINE
Chris@16 482 const_reverse_iterator rend () const {
Chris@16 483 return const_reverse_iterator (begin ());
Chris@16 484 }
Chris@16 485 BOOST_UBLAS_INLINE
Chris@101 486 const_reverse_iterator crend () const {
Chris@101 487 return rend ();
Chris@101 488 }
Chris@101 489
Chris@101 490 BOOST_UBLAS_INLINE
Chris@16 491 reverse_iterator rbegin () {
Chris@16 492 return reverse_iterator (end ());
Chris@16 493 }
Chris@16 494 BOOST_UBLAS_INLINE
Chris@16 495 reverse_iterator rend () {
Chris@16 496 return reverse_iterator (begin ());
Chris@16 497 }
Chris@16 498
Chris@16 499 private:
Chris@16 500 vector_closure_type data_;
Chris@16 501 range_type r_;
Chris@16 502 };
Chris@16 503
Chris@16 504 // ------------------
Chris@16 505 // Simple Projections
Chris@16 506 // ------------------
Chris@16 507
Chris@16 508 /** \brief Return a \c vector_range on a specified vector, a start and stop index.
Chris@16 509 * Return a \c vector_range on a specified vector, a start and stop index. The resulting \c vector_range can be manipulated like a normal vector.
Chris@16 510 * If the specified range falls outside that of of the index range of the vector, then the resulting \c vector_range is not a well formed
Chris@16 511 * Vector Expression and access to an element outside of index range of the vector is \b undefined.
Chris@16 512 */
Chris@16 513 template<class V>
Chris@16 514 BOOST_UBLAS_INLINE
Chris@16 515 vector_range<V> subrange (V &data, typename V::size_type start, typename V::size_type stop) {
Chris@16 516 typedef basic_range<typename V::size_type, typename V::difference_type> range_type;
Chris@16 517 return vector_range<V> (data, range_type (start, stop));
Chris@16 518 }
Chris@16 519
Chris@16 520 /** \brief Return a \c const \c vector_range on a specified vector, a start and stop index.
Chris@16 521 * Return a \c const \c vector_range on a specified vector, a start and stop index. The resulting \c const \c vector_range can be manipulated like a normal vector.
Chris@16 522 *If the specified range falls outside that of of the index range of the vector, then the resulting \c vector_range is not a well formed
Chris@16 523 * Vector Expression and access to an element outside of index range of the vector is \b undefined.
Chris@16 524 */
Chris@16 525 template<class V>
Chris@16 526 BOOST_UBLAS_INLINE
Chris@16 527 vector_range<const V> subrange (const V &data, typename V::size_type start, typename V::size_type stop) {
Chris@16 528 typedef basic_range<typename V::size_type, typename V::difference_type> range_type;
Chris@16 529 return vector_range<const V> (data, range_type (start, stop));
Chris@16 530 }
Chris@16 531
Chris@16 532 // -------------------
Chris@16 533 // Generic Projections
Chris@16 534 // -------------------
Chris@16 535
Chris@16 536 /** \brief Return a \c const \c vector_range on a specified vector and \c range
Chris@16 537 * Return a \c const \c vector_range on a specified vector and \c range. The resulting \c vector_range can be manipulated like a normal vector.
Chris@16 538 * If the specified range falls outside that of of the index range of the vector, then the resulting \c vector_range is not a well formed
Chris@16 539 * Vector Expression and access to an element outside of index range of the vector is \b undefined.
Chris@16 540 */
Chris@16 541 template<class V>
Chris@16 542 BOOST_UBLAS_INLINE
Chris@16 543 vector_range<V> project (V &data, typename vector_range<V>::range_type const &r) {
Chris@16 544 return vector_range<V> (data, r);
Chris@16 545 }
Chris@16 546
Chris@16 547 /** \brief Return a \c vector_range on a specified vector and \c range
Chris@16 548 * Return a \c vector_range on a specified vector and \c range. The resulting \c vector_range can be manipulated like a normal vector.
Chris@16 549 * If the specified range falls outside that of of the index range of the vector, then the resulting \c vector_range is not a well formed
Chris@16 550 * Vector Expression and access to an element outside of index range of the vector is \b undefined.
Chris@16 551 */
Chris@16 552 template<class V>
Chris@16 553 BOOST_UBLAS_INLINE
Chris@16 554 const vector_range<const V> project (const V &data, typename vector_range<V>::range_type const &r) {
Chris@16 555 // ISSUE was: return vector_range<V> (const_cast<V &> (data), r);
Chris@16 556 return vector_range<const V> (data, r);
Chris@16 557 }
Chris@16 558
Chris@16 559 /** \brief Return a \c const \c vector_range on a specified vector and const \c range
Chris@16 560 * Return a \c const \c vector_range on a specified vector and const \c range. The resulting \c vector_range can be manipulated like a normal vector.
Chris@16 561 * If the specified range falls outside that of of the index range of the vector, then the resulting \c vector_range is not a well formed
Chris@16 562 * Vector Expression and access to an element outside of index range of the vector is \b undefined.
Chris@16 563 */
Chris@16 564 template<class V>
Chris@16 565 BOOST_UBLAS_INLINE
Chris@16 566 vector_range<V> project (vector_range<V> &data, const typename vector_range<V>::range_type &r) {
Chris@16 567 return data.project (r);
Chris@16 568 }
Chris@16 569
Chris@16 570 /** \brief Return a \c vector_range on a specified vector and const \c range
Chris@16 571 * Return a \c vector_range on a specified vector and const \c range. The resulting \c vector_range can be manipulated like a normal vector.
Chris@16 572 * If the specified range falls outside that of of the index range of the vector, then the resulting \c vector_range is not a well formed
Chris@16 573 * Vector Expression and access to an element outside of index range of the vector is \b undefined.
Chris@16 574 */
Chris@16 575 template<class V>
Chris@16 576 BOOST_UBLAS_INLINE
Chris@16 577 const vector_range<V> project (const vector_range<V> &data, const typename vector_range<V>::range_type &r) {
Chris@16 578 return data.project (r);
Chris@16 579 }
Chris@16 580
Chris@16 581 // Specialization of temporary_traits
Chris@16 582 template <class V>
Chris@16 583 struct vector_temporary_traits< vector_range<V> >
Chris@16 584 : vector_temporary_traits< V > {} ;
Chris@16 585 template <class V>
Chris@16 586 struct vector_temporary_traits< const vector_range<V> >
Chris@16 587 : vector_temporary_traits< V > {} ;
Chris@16 588
Chris@16 589
Chris@16 590 /** \brief A vector referencing a non continuous subvector of elements of vector v containing all elements specified by \c slice.
Chris@16 591 *
Chris@16 592 * A vector slice can be used as a normal vector in any expression.
Chris@16 593 * If the specified slice falls outside that of the index slice of the vector, then
Chris@16 594 * the \c vector_slice is not a well formed \i Vector \i Expression and access to an
Chris@16 595 * element outside of index slice of the vector is \b undefined.
Chris@16 596 *
Chris@16 597 * A slice is a generalization of a range. In a range going from \f$a\f$ to \f$b\f$,
Chris@16 598 * all elements belong to the range. In a slice, a \i \f$step\f$ can be specified meaning to
Chris@16 599 * take one element over \f$step\f$ in the range specified from \f$a\f$ to \f$b\f$.
Chris@16 600 * Obviously, a slice with a \f$step\f$ of 1 is equivalent to a range.
Chris@16 601 *
Chris@16 602 * \tparam V the type of vector referenced (for example \c vector<double>)
Chris@16 603 */
Chris@16 604 template<class V>
Chris@16 605 class vector_slice:
Chris@16 606 public vector_expression<vector_slice<V> > {
Chris@16 607
Chris@16 608 typedef vector_slice<V> self_type;
Chris@16 609 public:
Chris@16 610 #ifdef BOOST_UBLAS_ENABLE_PROXY_SHORTCUTS
Chris@16 611 using vector_expression<self_type>::operator ();
Chris@16 612 #endif
Chris@16 613 typedef const V const_vector_type;
Chris@16 614 typedef V vector_type;
Chris@16 615 typedef typename V::size_type size_type;
Chris@16 616 typedef typename V::difference_type difference_type;
Chris@16 617 typedef typename V::value_type value_type;
Chris@16 618 typedef typename V::const_reference const_reference;
Chris@16 619 typedef typename boost::mpl::if_<boost::is_const<V>,
Chris@16 620 typename V::const_reference,
Chris@16 621 typename V::reference>::type reference;
Chris@16 622 typedef typename boost::mpl::if_<boost::is_const<V>,
Chris@16 623 typename V::const_closure_type,
Chris@16 624 typename V::closure_type>::type vector_closure_type;
Chris@16 625 typedef basic_range<size_type, difference_type> range_type;
Chris@16 626 typedef basic_slice<size_type, difference_type> slice_type;
Chris@16 627 typedef const self_type const_closure_type;
Chris@16 628 typedef self_type closure_type;
Chris@16 629 typedef typename storage_restrict_traits<typename V::storage_category,
Chris@16 630 dense_proxy_tag>::storage_category storage_category;
Chris@16 631
Chris@16 632 // Construction and destruction
Chris@16 633 BOOST_UBLAS_INLINE
Chris@16 634 vector_slice (vector_type &data, const slice_type &s):
Chris@16 635 data_ (data), s_ (s.preprocess (data.size ())) {
Chris@16 636 // Early checking of preconditions here.
Chris@16 637 // BOOST_UBLAS_CHECK (s_.start () <= data_.size () &&
Chris@16 638 // s_.start () + s_.stride () * (s_.size () - (s_.size () > 0)) <= data_.size (), bad_index ());
Chris@16 639 }
Chris@16 640 BOOST_UBLAS_INLINE
Chris@16 641 vector_slice (const vector_closure_type &data, const slice_type &s, int):
Chris@16 642 data_ (data), s_ (s.preprocess (data.size ())) {
Chris@16 643 // Early checking of preconditions here.
Chris@16 644 // BOOST_UBLAS_CHECK (s_.start () <= data_.size () &&
Chris@16 645 // s_.start () + s_.stride () * (s_.size () - (s_.size () > 0)) <= data_.size (), bad_index ());
Chris@16 646 }
Chris@16 647
Chris@16 648 // Accessors
Chris@16 649 BOOST_UBLAS_INLINE
Chris@16 650 size_type start () const {
Chris@16 651 return s_.start ();
Chris@16 652 }
Chris@16 653 BOOST_UBLAS_INLINE
Chris@16 654 difference_type stride () const {
Chris@16 655 return s_.stride ();
Chris@16 656 }
Chris@16 657 BOOST_UBLAS_INLINE
Chris@16 658 size_type size () const {
Chris@16 659 return s_.size ();
Chris@16 660 }
Chris@16 661
Chris@16 662 // Storage accessors
Chris@16 663 BOOST_UBLAS_INLINE
Chris@16 664 const vector_closure_type &data () const {
Chris@16 665 return data_;
Chris@16 666 }
Chris@16 667 BOOST_UBLAS_INLINE
Chris@16 668 vector_closure_type &data () {
Chris@16 669 return data_;
Chris@16 670 }
Chris@16 671
Chris@16 672 // Element access
Chris@16 673 #ifndef BOOST_UBLAS_PROXY_CONST_MEMBER
Chris@16 674 BOOST_UBLAS_INLINE
Chris@16 675 const_reference operator () (size_type i) const {
Chris@16 676 return data_ (s_ (i));
Chris@16 677 }
Chris@16 678 BOOST_UBLAS_INLINE
Chris@16 679 reference operator () (size_type i) {
Chris@16 680 return data_ (s_ (i));
Chris@16 681 }
Chris@16 682
Chris@16 683 BOOST_UBLAS_INLINE
Chris@16 684 const_reference operator [] (size_type i) const {
Chris@16 685 return (*this) (i);
Chris@16 686 }
Chris@16 687 BOOST_UBLAS_INLINE
Chris@16 688 reference operator [] (size_type i) {
Chris@16 689 return (*this) (i);
Chris@16 690 }
Chris@16 691 #else
Chris@16 692 BOOST_UBLAS_INLINE
Chris@16 693 reference operator () (size_type i) const {
Chris@16 694 return data_ (s_ (i));
Chris@16 695 }
Chris@16 696
Chris@16 697 BOOST_UBLAS_INLINE
Chris@16 698 reference operator [] (size_type i) const {
Chris@16 699 return (*this) (i);
Chris@16 700 }
Chris@16 701 #endif
Chris@16 702
Chris@16 703 // ISSUE can this be done in free project function?
Chris@16 704 // Although a const function can create a non-const proxy to a non-const object
Chris@16 705 // Critical is that vector_type and data_ (vector_closure_type) are const correct
Chris@16 706 BOOST_UBLAS_INLINE
Chris@16 707 vector_slice<vector_type> project (const range_type &r) const {
Chris@16 708 return vector_slice<vector_type> (data_, s_.compose (r.preprocess (data_.size ())), false);
Chris@16 709 }
Chris@16 710 BOOST_UBLAS_INLINE
Chris@16 711 vector_slice<vector_type> project (const slice_type &s) const {
Chris@16 712 return vector_slice<vector_type> (data_, s_.compose (s.preprocess (data_.size ())), false);
Chris@16 713 }
Chris@16 714
Chris@16 715 // Assignment
Chris@16 716 BOOST_UBLAS_INLINE
Chris@16 717 vector_slice &operator = (const vector_slice &vs) {
Chris@16 718 // ISSUE need a temporary, proxy can be overlaping alias
Chris@16 719 vector_assign<scalar_assign> (*this, typename vector_temporary_traits<V>::type (vs));
Chris@16 720 return *this;
Chris@16 721 }
Chris@16 722 BOOST_UBLAS_INLINE
Chris@16 723 vector_slice &assign_temporary (vector_slice &vs) {
Chris@16 724 // assign elements, proxied container remains the same
Chris@16 725 vector_assign<scalar_assign> (*this, vs);
Chris@16 726 return *this;
Chris@16 727 }
Chris@16 728 template<class AE>
Chris@16 729 BOOST_UBLAS_INLINE
Chris@16 730 vector_slice &operator = (const vector_expression<AE> &ae) {
Chris@16 731 vector_assign<scalar_assign> (*this, typename vector_temporary_traits<V>::type (ae));
Chris@16 732 return *this;
Chris@16 733 }
Chris@16 734 template<class AE>
Chris@16 735 BOOST_UBLAS_INLINE
Chris@16 736 vector_slice &assign (const vector_expression<AE> &ae) {
Chris@16 737 vector_assign<scalar_assign> (*this, ae);
Chris@16 738 return *this;
Chris@16 739 }
Chris@16 740 template<class AE>
Chris@16 741 BOOST_UBLAS_INLINE
Chris@16 742 vector_slice &operator += (const vector_expression<AE> &ae) {
Chris@16 743 vector_assign<scalar_assign> (*this, typename vector_temporary_traits<V>::type (*this + ae));
Chris@16 744 return *this;
Chris@16 745 }
Chris@16 746 template<class AE>
Chris@16 747 BOOST_UBLAS_INLINE
Chris@16 748 vector_slice &plus_assign (const vector_expression<AE> &ae) {
Chris@16 749 vector_assign<scalar_plus_assign> (*this, ae);
Chris@16 750 return *this;
Chris@16 751 }
Chris@16 752 template<class AE>
Chris@16 753 BOOST_UBLAS_INLINE
Chris@16 754 vector_slice &operator -= (const vector_expression<AE> &ae) {
Chris@16 755 vector_assign<scalar_assign> (*this, typename vector_temporary_traits<V>::type (*this - ae));
Chris@16 756 return *this;
Chris@16 757 }
Chris@16 758 template<class AE>
Chris@16 759 BOOST_UBLAS_INLINE
Chris@16 760 vector_slice &minus_assign (const vector_expression<AE> &ae) {
Chris@16 761 vector_assign<scalar_minus_assign> (*this, ae);
Chris@16 762 return *this;
Chris@16 763 }
Chris@16 764 template<class AT>
Chris@16 765 BOOST_UBLAS_INLINE
Chris@16 766 vector_slice &operator *= (const AT &at) {
Chris@16 767 vector_assign_scalar<scalar_multiplies_assign> (*this, at);
Chris@16 768 return *this;
Chris@16 769 }
Chris@16 770 template<class AT>
Chris@16 771 BOOST_UBLAS_INLINE
Chris@16 772 vector_slice &operator /= (const AT &at) {
Chris@16 773 vector_assign_scalar<scalar_divides_assign> (*this, at);
Chris@16 774 return *this;
Chris@16 775 }
Chris@16 776
Chris@16 777 // Closure comparison
Chris@16 778 BOOST_UBLAS_INLINE
Chris@16 779 bool same_closure (const vector_slice &vr) const {
Chris@16 780 return (*this).data_.same_closure (vr.data_);
Chris@16 781 }
Chris@16 782
Chris@16 783 // Comparison
Chris@16 784 BOOST_UBLAS_INLINE
Chris@16 785 bool operator == (const vector_slice &vs) const {
Chris@16 786 return (*this).data_ == vs.data_ && s_ == vs.s_;
Chris@16 787 }
Chris@16 788
Chris@16 789 // Swapping
Chris@16 790 BOOST_UBLAS_INLINE
Chris@16 791 void swap (vector_slice vs) {
Chris@16 792 if (this != &vs) {
Chris@16 793 BOOST_UBLAS_CHECK (size () == vs.size (), bad_size ());
Chris@16 794 // Sparse ranges may be nonconformant now.
Chris@16 795 // std::swap_ranges (begin (), end (), vs.begin ());
Chris@16 796 vector_swap<scalar_swap> (*this, vs);
Chris@16 797 }
Chris@16 798 }
Chris@16 799 BOOST_UBLAS_INLINE
Chris@16 800 friend void swap (vector_slice vs1, vector_slice vs2) {
Chris@16 801 vs1.swap (vs2);
Chris@16 802 }
Chris@16 803
Chris@16 804 // Iterator types
Chris@16 805 private:
Chris@16 806 // Use slice as an index - FIXME this fails for packed assignment
Chris@16 807 typedef typename slice_type::const_iterator const_subiterator_type;
Chris@16 808 typedef typename slice_type::const_iterator subiterator_type;
Chris@16 809
Chris@16 810 public:
Chris@16 811 #ifdef BOOST_UBLAS_USE_INDEXED_ITERATOR
Chris@16 812 typedef indexed_iterator<vector_slice<vector_type>,
Chris@16 813 typename vector_type::iterator::iterator_category> iterator;
Chris@16 814 typedef indexed_const_iterator<vector_slice<vector_type>,
Chris@16 815 typename vector_type::const_iterator::iterator_category> const_iterator;
Chris@16 816 #else
Chris@16 817 class const_iterator;
Chris@16 818 class iterator;
Chris@16 819 #endif
Chris@16 820
Chris@16 821 // Element lookup
Chris@16 822 BOOST_UBLAS_INLINE
Chris@16 823 const_iterator find (size_type i) const {
Chris@16 824 #ifdef BOOST_UBLAS_USE_INDEXED_ITERATOR
Chris@16 825 return const_iterator (*this, i);
Chris@16 826 #else
Chris@16 827 return const_iterator (*this, s_.begin () + i);
Chris@16 828 #endif
Chris@16 829 }
Chris@16 830 BOOST_UBLAS_INLINE
Chris@16 831 iterator find (size_type i) {
Chris@16 832 #ifdef BOOST_UBLAS_USE_INDEXED_ITERATOR
Chris@16 833 return iterator (*this, i);
Chris@16 834 #else
Chris@16 835 return iterator (*this, s_.begin () + i);
Chris@16 836 #endif
Chris@16 837 }
Chris@16 838
Chris@16 839 #ifndef BOOST_UBLAS_USE_INDEXED_ITERATOR
Chris@16 840 class const_iterator:
Chris@16 841 public container_const_reference<vector_slice>,
Chris@16 842 public iterator_base_traits<typename V::const_iterator::iterator_category>::template
Chris@16 843 iterator_base<const_iterator, value_type>::type {
Chris@16 844 public:
Chris@16 845 typedef typename V::const_iterator::difference_type difference_type;
Chris@16 846 typedef typename V::const_iterator::value_type value_type;
Chris@16 847 typedef typename V::const_reference reference; //FIXME due to indexing access
Chris@16 848 typedef typename V::const_iterator::pointer pointer;
Chris@16 849
Chris@16 850 // Construction and destruction
Chris@16 851 BOOST_UBLAS_INLINE
Chris@16 852 const_iterator ():
Chris@16 853 container_const_reference<self_type> (), it_ () {}
Chris@16 854 BOOST_UBLAS_INLINE
Chris@16 855 const_iterator (const self_type &vs, const const_subiterator_type &it):
Chris@16 856 container_const_reference<self_type> (vs), it_ (it) {}
Chris@16 857 BOOST_UBLAS_INLINE
Chris@16 858 const_iterator (const typename self_type::iterator &it): // ISSUE self_type:: stops VC8 using std::iterator here
Chris@16 859 container_const_reference<self_type> (it ()), it_ (it.it_) {}
Chris@16 860
Chris@16 861 // Arithmetic
Chris@16 862 BOOST_UBLAS_INLINE
Chris@16 863 const_iterator &operator ++ () {
Chris@16 864 ++ it_;
Chris@16 865 return *this;
Chris@16 866 }
Chris@16 867 BOOST_UBLAS_INLINE
Chris@16 868 const_iterator &operator -- () {
Chris@16 869 -- it_;
Chris@16 870 return *this;
Chris@16 871 }
Chris@16 872 BOOST_UBLAS_INLINE
Chris@16 873 const_iterator &operator += (difference_type n) {
Chris@16 874 it_ += n;
Chris@16 875 return *this;
Chris@16 876 }
Chris@16 877 BOOST_UBLAS_INLINE
Chris@16 878 const_iterator &operator -= (difference_type n) {
Chris@16 879 it_ -= n;
Chris@16 880 return *this;
Chris@16 881 }
Chris@16 882 BOOST_UBLAS_INLINE
Chris@16 883 difference_type operator - (const const_iterator &it) const {
Chris@16 884 BOOST_UBLAS_CHECK ((*this) ().same_closure (it ()), external_logic ());
Chris@16 885 return it_ - it.it_;
Chris@16 886 }
Chris@16 887
Chris@16 888 // Dereference
Chris@16 889 BOOST_UBLAS_INLINE
Chris@16 890 const_reference operator * () const {
Chris@16 891 // FIXME replace find with at_element
Chris@16 892 BOOST_UBLAS_CHECK (index () < (*this) ().size (), bad_index ());
Chris@16 893 return (*this) ().data_ (*it_);
Chris@16 894 }
Chris@16 895 BOOST_UBLAS_INLINE
Chris@16 896 const_reference operator [] (difference_type n) const {
Chris@16 897 return *(*this + n);
Chris@16 898 }
Chris@16 899
Chris@16 900 // Index
Chris@16 901 BOOST_UBLAS_INLINE
Chris@16 902 size_type index () const {
Chris@16 903 return it_.index ();
Chris@16 904 }
Chris@16 905
Chris@16 906 // Assignment
Chris@16 907 BOOST_UBLAS_INLINE
Chris@16 908 const_iterator &operator = (const const_iterator &it) {
Chris@16 909 container_const_reference<self_type>::assign (&it ());
Chris@16 910 it_ = it.it_;
Chris@16 911 return *this;
Chris@16 912 }
Chris@16 913
Chris@16 914 // Comparison
Chris@16 915 BOOST_UBLAS_INLINE
Chris@16 916 bool operator == (const const_iterator &it) const {
Chris@16 917 BOOST_UBLAS_CHECK ((*this) ().same_closure (it ()), external_logic ());
Chris@16 918 return it_ == it.it_;
Chris@16 919 }
Chris@16 920 BOOST_UBLAS_INLINE
Chris@16 921 bool operator < (const const_iterator &it) const {
Chris@16 922 BOOST_UBLAS_CHECK ((*this) ().same_closure (it ()), external_logic ());
Chris@16 923 return it_ < it.it_;
Chris@16 924 }
Chris@16 925
Chris@16 926 private:
Chris@16 927 const_subiterator_type it_;
Chris@16 928 };
Chris@16 929 #endif
Chris@16 930
Chris@16 931 BOOST_UBLAS_INLINE
Chris@16 932 const_iterator begin () const {
Chris@16 933 return find (0);
Chris@16 934 }
Chris@16 935 BOOST_UBLAS_INLINE
Chris@101 936 const_iterator cbegin () const {
Chris@101 937 return begin ();
Chris@101 938 }
Chris@101 939 BOOST_UBLAS_INLINE
Chris@16 940 const_iterator end () const {
Chris@16 941 return find (size ());
Chris@16 942 }
Chris@101 943 BOOST_UBLAS_INLINE
Chris@101 944 const_iterator cend () const {
Chris@101 945 return end ();
Chris@101 946 }
Chris@16 947
Chris@16 948 #ifndef BOOST_UBLAS_USE_INDEXED_ITERATOR
Chris@16 949 class iterator:
Chris@16 950 public container_reference<vector_slice>,
Chris@16 951 public iterator_base_traits<typename V::iterator::iterator_category>::template
Chris@16 952 iterator_base<iterator, value_type>::type {
Chris@16 953 public:
Chris@16 954 typedef typename V::iterator::difference_type difference_type;
Chris@16 955 typedef typename V::iterator::value_type value_type;
Chris@16 956 typedef typename V::reference reference; //FIXME due to indexing access
Chris@16 957 typedef typename V::iterator::pointer pointer;
Chris@16 958
Chris@16 959 // Construction and destruction
Chris@16 960 BOOST_UBLAS_INLINE
Chris@16 961 iterator ():
Chris@16 962 container_reference<self_type> (), it_ () {}
Chris@16 963 BOOST_UBLAS_INLINE
Chris@16 964 iterator (self_type &vs, const subiterator_type &it):
Chris@16 965 container_reference<self_type> (vs), it_ (it) {}
Chris@16 966
Chris@16 967 // Arithmetic
Chris@16 968 BOOST_UBLAS_INLINE
Chris@16 969 iterator &operator ++ () {
Chris@16 970 ++ it_;
Chris@16 971 return *this;
Chris@16 972 }
Chris@16 973 BOOST_UBLAS_INLINE
Chris@16 974 iterator &operator -- () {
Chris@16 975 -- it_;
Chris@16 976 return *this;
Chris@16 977 }
Chris@16 978 BOOST_UBLAS_INLINE
Chris@16 979 iterator &operator += (difference_type n) {
Chris@16 980 it_ += n;
Chris@16 981 return *this;
Chris@16 982 }
Chris@16 983 BOOST_UBLAS_INLINE
Chris@16 984 iterator &operator -= (difference_type n) {
Chris@16 985 it_ -= n;
Chris@16 986 return *this;
Chris@16 987 }
Chris@16 988 BOOST_UBLAS_INLINE
Chris@16 989 difference_type operator - (const iterator &it) const {
Chris@16 990 BOOST_UBLAS_CHECK ((*this) ().same_closure (it ()), external_logic ());
Chris@16 991 return it_ - it.it_;
Chris@16 992 }
Chris@16 993
Chris@16 994 // Dereference
Chris@16 995 BOOST_UBLAS_INLINE
Chris@16 996 reference operator * () const {
Chris@16 997 // FIXME replace find with at_element
Chris@16 998 BOOST_UBLAS_CHECK (index () < (*this) ().size (), bad_index ());
Chris@16 999 return (*this) ().data_ (*it_);
Chris@16 1000 }
Chris@16 1001 BOOST_UBLAS_INLINE
Chris@16 1002 reference operator [] (difference_type n) const {
Chris@16 1003 return *(*this + n);
Chris@16 1004 }
Chris@16 1005
Chris@16 1006
Chris@16 1007 // Index
Chris@16 1008 BOOST_UBLAS_INLINE
Chris@16 1009 size_type index () const {
Chris@16 1010 return it_.index ();
Chris@16 1011 }
Chris@16 1012
Chris@16 1013 // Assignment
Chris@16 1014 BOOST_UBLAS_INLINE
Chris@16 1015 iterator &operator = (const iterator &it) {
Chris@16 1016 container_reference<self_type>::assign (&it ());
Chris@16 1017 it_ = it.it_;
Chris@16 1018 return *this;
Chris@16 1019 }
Chris@16 1020
Chris@16 1021 // Comparison
Chris@16 1022 BOOST_UBLAS_INLINE
Chris@16 1023 bool operator == (const iterator &it) const {
Chris@16 1024 BOOST_UBLAS_CHECK ((*this) ().same_closure (it ()), external_logic ());
Chris@16 1025 return it_ == it.it_;
Chris@16 1026 }
Chris@16 1027 BOOST_UBLAS_INLINE
Chris@16 1028 bool operator < (const iterator &it) const {
Chris@16 1029 BOOST_UBLAS_CHECK ((*this) ().same_closure (it ()), external_logic ());
Chris@16 1030 return it_ < it.it_;
Chris@16 1031 }
Chris@16 1032
Chris@16 1033 private:
Chris@16 1034 subiterator_type it_;
Chris@16 1035
Chris@16 1036 friend class const_iterator;
Chris@16 1037 };
Chris@16 1038 #endif
Chris@16 1039
Chris@16 1040 BOOST_UBLAS_INLINE
Chris@16 1041 iterator begin () {
Chris@16 1042 return find (0);
Chris@16 1043 }
Chris@16 1044 BOOST_UBLAS_INLINE
Chris@16 1045 iterator end () {
Chris@16 1046 return find (size ());
Chris@16 1047 }
Chris@16 1048
Chris@16 1049 // Reverse iterator
Chris@16 1050 typedef reverse_iterator_base<const_iterator> const_reverse_iterator;
Chris@16 1051 typedef reverse_iterator_base<iterator> reverse_iterator;
Chris@16 1052
Chris@16 1053 BOOST_UBLAS_INLINE
Chris@16 1054 const_reverse_iterator rbegin () const {
Chris@16 1055 return const_reverse_iterator (end ());
Chris@16 1056 }
Chris@16 1057 BOOST_UBLAS_INLINE
Chris@101 1058 const_reverse_iterator crbegin () const {
Chris@101 1059 return rbegin ();
Chris@101 1060 }
Chris@101 1061 BOOST_UBLAS_INLINE
Chris@16 1062 const_reverse_iterator rend () const {
Chris@16 1063 return const_reverse_iterator (begin ());
Chris@16 1064 }
Chris@16 1065 BOOST_UBLAS_INLINE
Chris@101 1066 const_reverse_iterator crend () const {
Chris@101 1067 return rend ();
Chris@101 1068 }
Chris@101 1069 BOOST_UBLAS_INLINE
Chris@16 1070 reverse_iterator rbegin () {
Chris@16 1071 return reverse_iterator (end ());
Chris@16 1072 }
Chris@16 1073 BOOST_UBLAS_INLINE
Chris@16 1074 reverse_iterator rend () {
Chris@16 1075 return reverse_iterator (begin ());
Chris@16 1076 }
Chris@16 1077
Chris@16 1078 private:
Chris@16 1079 vector_closure_type data_;
Chris@16 1080 slice_type s_;
Chris@16 1081 };
Chris@16 1082
Chris@16 1083 // Simple Projections
Chris@16 1084 template<class V>
Chris@16 1085 BOOST_UBLAS_INLINE
Chris@16 1086 vector_slice<V> subslice (V &data, typename V::size_type start, typename V::difference_type stride, typename V::size_type size) {
Chris@16 1087 typedef basic_slice<typename V::size_type, typename V::difference_type> slice_type;
Chris@16 1088 return vector_slice<V> (data, slice_type (start, stride, size));
Chris@16 1089 }
Chris@16 1090 template<class V>
Chris@16 1091 BOOST_UBLAS_INLINE
Chris@16 1092 vector_slice<const V> subslice (const V &data, typename V::size_type start, typename V::difference_type stride, typename V::size_type size) {
Chris@16 1093 typedef basic_slice<typename V::size_type, typename V::difference_type> slice_type;
Chris@16 1094 return vector_slice<const V> (data, slice_type (start, stride, size));
Chris@16 1095 }
Chris@16 1096
Chris@16 1097 // Generic Projections
Chris@16 1098 template<class V>
Chris@16 1099 BOOST_UBLAS_INLINE
Chris@16 1100 vector_slice<V> project (V &data, const typename vector_slice<V>::slice_type &s) {
Chris@16 1101 return vector_slice<V> (data, s);
Chris@16 1102 }
Chris@16 1103 template<class V>
Chris@16 1104 BOOST_UBLAS_INLINE
Chris@16 1105 const vector_slice<const V> project (const V &data, const typename vector_slice<V>::slice_type &s) {
Chris@16 1106 // ISSUE was: return vector_slice<V> (const_cast<V &> (data), s);
Chris@16 1107 return vector_slice<const V> (data, s);
Chris@16 1108 }
Chris@16 1109 template<class V>
Chris@16 1110 BOOST_UBLAS_INLINE
Chris@16 1111 vector_slice<V> project (vector_slice<V> &data, const typename vector_slice<V>::slice_type &s) {
Chris@16 1112 return data.project (s);
Chris@16 1113 }
Chris@16 1114 template<class V>
Chris@16 1115 BOOST_UBLAS_INLINE
Chris@16 1116 const vector_slice<V> project (const vector_slice<V> &data, const typename vector_slice<V>::slice_type &s) {
Chris@16 1117 return data.project (s);
Chris@16 1118 }
Chris@16 1119 // 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
Chris@16 1120 template<class V>
Chris@16 1121 BOOST_UBLAS_INLINE
Chris@16 1122 vector_slice<V> project (vector_slice<V> &data, const typename vector_range<V>::range_type &r) {
Chris@16 1123 return data.project (r);
Chris@16 1124 }
Chris@16 1125 template<class V>
Chris@16 1126 BOOST_UBLAS_INLINE
Chris@16 1127 const vector_slice<V> project (const vector_slice<V> &data, const typename vector_range<V>::range_type &r) {
Chris@16 1128 return data.project (r);
Chris@16 1129 }
Chris@16 1130
Chris@16 1131 // Specialization of temporary_traits
Chris@16 1132 template <class V>
Chris@16 1133 struct vector_temporary_traits< vector_slice<V> >
Chris@16 1134 : vector_temporary_traits< V > {} ;
Chris@16 1135 template <class V>
Chris@16 1136 struct vector_temporary_traits< const vector_slice<V> >
Chris@16 1137 : vector_temporary_traits< V > {} ;
Chris@16 1138
Chris@16 1139
Chris@16 1140 // Vector based indirection class
Chris@16 1141 // Contributed by Toon Knapen.
Chris@16 1142 // Extended and optimized by Kresimir Fresl.
Chris@16 1143
Chris@16 1144 /** \brief A vector referencing a non continuous subvector of elements given another vector of indices.
Chris@16 1145 *
Chris@16 1146 * It is the most general version of any subvectors because it uses another vector of indices to reference
Chris@16 1147 * the subvector.
Chris@16 1148 *
Chris@16 1149 * The vector of indices can be of any type with the restriction that its elements must be
Chris@16 1150 * type-compatible with the size_type \c of the container. In practice, the following are good candidates:
Chris@16 1151 * - \c boost::numeric::ublas::indirect_array<A> where \c A can be \c int, \c size_t, \c long, etc...
Chris@16 1152 * - \c std::vector<A> where \c A can \c int, \c size_t, \c long, etc...
Chris@16 1153 * - \c boost::numeric::ublas::vector<int> can work too (\c int can be replaced by another integer type)
Chris@16 1154 * - etc...
Chris@16 1155 *
Chris@16 1156 * An indirect vector can be used as a normal vector in any expression. If the specified indirect vector
Chris@16 1157 * falls outside that of the indices of the vector, then the \c vector_indirect is not a well formed
Chris@16 1158 * \i Vector \i Expression and access to an element outside of indices of the vector is \b undefined.
Chris@16 1159 *
Chris@16 1160 * \tparam V the type of vector referenced (for example \c vector<double>)
Chris@16 1161 * \tparam IA the type of index vector. Default is \c ublas::indirect_array<>
Chris@16 1162 */
Chris@16 1163 template<class V, class IA>
Chris@16 1164 class vector_indirect:
Chris@16 1165 public vector_expression<vector_indirect<V, IA> > {
Chris@16 1166
Chris@16 1167 typedef vector_indirect<V, IA> self_type;
Chris@16 1168 public:
Chris@16 1169 #ifdef BOOST_UBLAS_ENABLE_PROXY_SHORTCUTS
Chris@16 1170 using vector_expression<self_type>::operator ();
Chris@16 1171 #endif
Chris@16 1172 typedef const V const_vector_type;
Chris@16 1173 typedef V vector_type;
Chris@16 1174 typedef const IA const_indirect_array_type;
Chris@16 1175 typedef IA indirect_array_type;
Chris@16 1176 typedef typename V::size_type size_type;
Chris@16 1177 typedef typename V::difference_type difference_type;
Chris@16 1178 typedef typename V::value_type value_type;
Chris@16 1179 typedef typename V::const_reference const_reference;
Chris@16 1180 typedef typename boost::mpl::if_<boost::is_const<V>,
Chris@16 1181 typename V::const_reference,
Chris@16 1182 typename V::reference>::type reference;
Chris@16 1183 typedef typename boost::mpl::if_<boost::is_const<V>,
Chris@16 1184 typename V::const_closure_type,
Chris@16 1185 typename V::closure_type>::type vector_closure_type;
Chris@16 1186 typedef basic_range<size_type, difference_type> range_type;
Chris@16 1187 typedef basic_slice<size_type, difference_type> slice_type;
Chris@16 1188 typedef const self_type const_closure_type;
Chris@16 1189 typedef self_type closure_type;
Chris@16 1190 typedef typename storage_restrict_traits<typename V::storage_category,
Chris@16 1191 dense_proxy_tag>::storage_category storage_category;
Chris@16 1192
Chris@16 1193 // Construction and destruction
Chris@16 1194 BOOST_UBLAS_INLINE
Chris@16 1195 vector_indirect (vector_type &data, size_type size):
Chris@16 1196 data_ (data), ia_ (size) {}
Chris@16 1197 BOOST_UBLAS_INLINE
Chris@16 1198 vector_indirect (vector_type &data, const indirect_array_type &ia):
Chris@16 1199 data_ (data), ia_ (ia.preprocess (data.size ())) {}
Chris@16 1200 BOOST_UBLAS_INLINE
Chris@16 1201 vector_indirect (const vector_closure_type &data, const indirect_array_type &ia, int):
Chris@16 1202 data_ (data), ia_ (ia.preprocess (data.size ())) {}
Chris@16 1203
Chris@16 1204 // Accessors
Chris@16 1205 BOOST_UBLAS_INLINE
Chris@16 1206 size_type size () const {
Chris@16 1207 return ia_.size ();
Chris@16 1208 }
Chris@16 1209 BOOST_UBLAS_INLINE
Chris@16 1210 const_indirect_array_type &indirect () const {
Chris@16 1211 return ia_;
Chris@16 1212 }
Chris@16 1213 BOOST_UBLAS_INLINE
Chris@16 1214 indirect_array_type &indirect () {
Chris@16 1215 return ia_;
Chris@16 1216 }
Chris@16 1217
Chris@16 1218 // Storage accessors
Chris@16 1219 BOOST_UBLAS_INLINE
Chris@16 1220 const vector_closure_type &data () const {
Chris@16 1221 return data_;
Chris@16 1222 }
Chris@16 1223 BOOST_UBLAS_INLINE
Chris@16 1224 vector_closure_type &data () {
Chris@16 1225 return data_;
Chris@16 1226 }
Chris@16 1227
Chris@16 1228 // Element access
Chris@16 1229 #ifndef BOOST_UBLAS_PROXY_CONST_MEMBER
Chris@16 1230 BOOST_UBLAS_INLINE
Chris@16 1231 const_reference operator () (size_type i) const {
Chris@16 1232 return data_ (ia_ (i));
Chris@16 1233 }
Chris@16 1234 BOOST_UBLAS_INLINE
Chris@16 1235 reference operator () (size_type i) {
Chris@16 1236 return data_ (ia_ (i));
Chris@16 1237 }
Chris@16 1238
Chris@16 1239 BOOST_UBLAS_INLINE
Chris@16 1240 const_reference operator [] (size_type i) const {
Chris@16 1241 return (*this) (i);
Chris@16 1242 }
Chris@16 1243 BOOST_UBLAS_INLINE
Chris@16 1244 reference operator [] (size_type i) {
Chris@16 1245 return (*this) (i);
Chris@16 1246 }
Chris@16 1247 #else
Chris@16 1248 BOOST_UBLAS_INLINE
Chris@16 1249 reference operator () (size_type i) const {
Chris@16 1250 return data_ (ia_ (i));
Chris@16 1251 }
Chris@16 1252
Chris@16 1253 BOOST_UBLAS_INLINE
Chris@16 1254 reference operator [] (size_type i) const {
Chris@16 1255 return (*this) (i);
Chris@16 1256 }
Chris@16 1257 #endif
Chris@16 1258
Chris@16 1259 // ISSUE can this be done in free project function?
Chris@16 1260 // Although a const function can create a non-const proxy to a non-const object
Chris@16 1261 // Critical is that vector_type and data_ (vector_closure_type) are const correct
Chris@16 1262 BOOST_UBLAS_INLINE
Chris@16 1263 vector_indirect<vector_type, indirect_array_type> project (const range_type &r) const {
Chris@16 1264 return vector_indirect<vector_type, indirect_array_type> (data_, ia_.compose (r.preprocess (data_.size ())), 0);
Chris@16 1265 }
Chris@16 1266 BOOST_UBLAS_INLINE
Chris@16 1267 vector_indirect<vector_type, indirect_array_type> project (const slice_type &s) const {
Chris@16 1268 return vector_indirect<vector_type, indirect_array_type> (data_, ia_.compose (s.preprocess (data_.size ())), 0);
Chris@16 1269 }
Chris@16 1270 BOOST_UBLAS_INLINE
Chris@16 1271 vector_indirect<vector_type, indirect_array_type> project (const indirect_array_type &ia) const {
Chris@16 1272 return vector_indirect<vector_type, indirect_array_type> (data_, ia_.compose (ia.preprocess (data_.size ())), 0);
Chris@16 1273 }
Chris@16 1274
Chris@16 1275 // Assignment
Chris@16 1276 BOOST_UBLAS_INLINE
Chris@16 1277 vector_indirect &operator = (const vector_indirect &vi) {
Chris@16 1278 // ISSUE need a temporary, proxy can be overlaping alias
Chris@16 1279 vector_assign<scalar_assign> (*this, typename vector_temporary_traits<V>::type (vi));
Chris@16 1280 return *this;
Chris@16 1281 }
Chris@16 1282 BOOST_UBLAS_INLINE
Chris@16 1283 vector_indirect &assign_temporary (vector_indirect &vi) {
Chris@16 1284 // assign elements, proxied container remains the same
Chris@16 1285 vector_assign<scalar_assign> (*this, vi);
Chris@16 1286 return *this;
Chris@16 1287 }
Chris@16 1288 template<class AE>
Chris@16 1289 BOOST_UBLAS_INLINE
Chris@16 1290 vector_indirect &operator = (const vector_expression<AE> &ae) {
Chris@16 1291 vector_assign<scalar_assign> (*this, typename vector_temporary_traits<V>::type (ae));
Chris@16 1292 return *this;
Chris@16 1293 }
Chris@16 1294 template<class AE>
Chris@16 1295 BOOST_UBLAS_INLINE
Chris@16 1296 vector_indirect &assign (const vector_expression<AE> &ae) {
Chris@16 1297 vector_assign<scalar_assign> (*this, ae);
Chris@16 1298 return *this;
Chris@16 1299 }
Chris@16 1300 template<class AE>
Chris@16 1301 BOOST_UBLAS_INLINE
Chris@16 1302 vector_indirect &operator += (const vector_expression<AE> &ae) {
Chris@16 1303 vector_assign<scalar_assign> (*this, typename vector_temporary_traits<V>::type (*this + ae));
Chris@16 1304 return *this;
Chris@16 1305 }
Chris@16 1306 template<class AE>
Chris@16 1307 BOOST_UBLAS_INLINE
Chris@16 1308 vector_indirect &plus_assign (const vector_expression<AE> &ae) {
Chris@16 1309 vector_assign<scalar_plus_assign> (*this, ae);
Chris@16 1310 return *this;
Chris@16 1311 }
Chris@16 1312 template<class AE>
Chris@16 1313 BOOST_UBLAS_INLINE
Chris@16 1314 vector_indirect &operator -= (const vector_expression<AE> &ae) {
Chris@16 1315 vector_assign<scalar_assign> (*this, typename vector_temporary_traits<V>::type (*this - ae));
Chris@16 1316 return *this;
Chris@16 1317 }
Chris@16 1318 template<class AE>
Chris@16 1319 BOOST_UBLAS_INLINE
Chris@16 1320 vector_indirect &minus_assign (const vector_expression<AE> &ae) {
Chris@16 1321 vector_assign<scalar_minus_assign> (*this, ae);
Chris@16 1322 return *this;
Chris@16 1323 }
Chris@16 1324 template<class AT>
Chris@16 1325 BOOST_UBLAS_INLINE
Chris@16 1326 vector_indirect &operator *= (const AT &at) {
Chris@16 1327 vector_assign_scalar<scalar_multiplies_assign> (*this, at);
Chris@16 1328 return *this;
Chris@16 1329 }
Chris@16 1330 template<class AT>
Chris@16 1331 BOOST_UBLAS_INLINE
Chris@16 1332 vector_indirect &operator /= (const AT &at) {
Chris@16 1333 vector_assign_scalar<scalar_divides_assign> (*this, at);
Chris@16 1334 return *this;
Chris@16 1335 }
Chris@16 1336
Chris@16 1337 // Closure comparison
Chris@16 1338 BOOST_UBLAS_INLINE
Chris@101 1339 bool same_closure (const vector_indirect &/*vr*/) const {
Chris@101 1340 return true;
Chris@16 1341 }
Chris@16 1342
Chris@16 1343 // Comparison
Chris@16 1344 BOOST_UBLAS_INLINE
Chris@16 1345 bool operator == (const vector_indirect &vi) const {
Chris@16 1346 return (*this).data_ == vi.data_ && ia_ == vi.ia_;
Chris@16 1347 }
Chris@16 1348
Chris@16 1349 // Swapping
Chris@16 1350 BOOST_UBLAS_INLINE
Chris@16 1351 void swap (vector_indirect vi) {
Chris@16 1352 if (this != &vi) {
Chris@16 1353 BOOST_UBLAS_CHECK (size () == vi.size (), bad_size ());
Chris@16 1354 // Sparse ranges may be nonconformant now.
Chris@16 1355 // std::swap_ranges (begin (), end (), vi.begin ());
Chris@16 1356 vector_swap<scalar_swap> (*this, vi);
Chris@16 1357 }
Chris@16 1358 }
Chris@16 1359 BOOST_UBLAS_INLINE
Chris@16 1360 friend void swap (vector_indirect vi1, vector_indirect vi2) {
Chris@16 1361 vi1.swap (vi2);
Chris@16 1362 }
Chris@16 1363
Chris@16 1364 // Iterator types
Chris@16 1365 private:
Chris@16 1366 // Use indirect array as an index - FIXME this fails for packed assignment
Chris@16 1367 typedef typename IA::const_iterator const_subiterator_type;
Chris@16 1368 typedef typename IA::const_iterator subiterator_type;
Chris@16 1369
Chris@16 1370 public:
Chris@16 1371 #ifdef BOOST_UBLAS_USE_INDEXED_ITERATOR
Chris@16 1372 typedef indexed_iterator<vector_indirect<vector_type, indirect_array_type>,
Chris@16 1373 typename vector_type::iterator::iterator_category> iterator;
Chris@16 1374 typedef indexed_const_iterator<vector_indirect<vector_type, indirect_array_type>,
Chris@16 1375 typename vector_type::const_iterator::iterator_category> const_iterator;
Chris@16 1376 #else
Chris@16 1377 class const_iterator;
Chris@16 1378 class iterator;
Chris@16 1379 #endif
Chris@16 1380 // Element lookup
Chris@16 1381 BOOST_UBLAS_INLINE
Chris@16 1382 const_iterator find (size_type i) const {
Chris@16 1383 #ifdef BOOST_UBLAS_USE_INDEXED_ITERATOR
Chris@16 1384 return const_iterator (*this, i);
Chris@16 1385 #else
Chris@16 1386 return const_iterator (*this, ia_.begin () + i);
Chris@16 1387 #endif
Chris@16 1388 }
Chris@16 1389 BOOST_UBLAS_INLINE
Chris@16 1390 iterator find (size_type i) {
Chris@16 1391 #ifdef BOOST_UBLAS_USE_INDEXED_ITERATOR
Chris@16 1392 return iterator (*this, i);
Chris@16 1393 #else
Chris@16 1394 return iterator (*this, ia_.begin () + i);
Chris@16 1395 #endif
Chris@16 1396 }
Chris@16 1397
Chris@16 1398 // Iterators simply are indices.
Chris@16 1399
Chris@16 1400 #ifndef BOOST_UBLAS_USE_INDEXED_ITERATOR
Chris@16 1401 class const_iterator:
Chris@16 1402 public container_const_reference<vector_indirect>,
Chris@16 1403 public iterator_base_traits<typename V::const_iterator::iterator_category>::template
Chris@16 1404 iterator_base<const_iterator, value_type>::type {
Chris@16 1405 public:
Chris@16 1406 typedef typename V::const_iterator::difference_type difference_type;
Chris@16 1407 typedef typename V::const_iterator::value_type value_type;
Chris@16 1408 typedef typename V::const_reference reference; //FIXME due to indexing access
Chris@16 1409 typedef typename V::const_iterator::pointer pointer;
Chris@16 1410
Chris@16 1411 // Construction and destruction
Chris@16 1412 BOOST_UBLAS_INLINE
Chris@16 1413 const_iterator ():
Chris@16 1414 container_const_reference<self_type> (), it_ () {}
Chris@16 1415 BOOST_UBLAS_INLINE
Chris@16 1416 const_iterator (const self_type &vi, const const_subiterator_type &it):
Chris@16 1417 container_const_reference<self_type> (vi), it_ (it) {}
Chris@16 1418 BOOST_UBLAS_INLINE
Chris@16 1419 const_iterator (const typename self_type::iterator &it): // ISSUE self_type:: stops VC8 using std::iterator here
Chris@16 1420 container_const_reference<self_type> (it ()), it_ (it.it_) {}
Chris@16 1421
Chris@16 1422 // Arithmetic
Chris@16 1423 BOOST_UBLAS_INLINE
Chris@16 1424 const_iterator &operator ++ () {
Chris@16 1425 ++ it_;
Chris@16 1426 return *this;
Chris@16 1427 }
Chris@16 1428 BOOST_UBLAS_INLINE
Chris@16 1429 const_iterator &operator -- () {
Chris@16 1430 -- it_;
Chris@16 1431 return *this;
Chris@16 1432 }
Chris@16 1433 BOOST_UBLAS_INLINE
Chris@16 1434 const_iterator &operator += (difference_type n) {
Chris@16 1435 it_ += n;
Chris@16 1436 return *this;
Chris@16 1437 }
Chris@16 1438 BOOST_UBLAS_INLINE
Chris@16 1439 const_iterator &operator -= (difference_type n) {
Chris@16 1440 it_ -= n;
Chris@16 1441 return *this;
Chris@16 1442 }
Chris@16 1443 BOOST_UBLAS_INLINE
Chris@16 1444 difference_type operator - (const const_iterator &it) const {
Chris@16 1445 BOOST_UBLAS_CHECK ((*this) ().same_closure (it ()), external_logic ());
Chris@16 1446 return it_ - it.it_;
Chris@16 1447 }
Chris@16 1448
Chris@16 1449 // Dereference
Chris@16 1450 BOOST_UBLAS_INLINE
Chris@16 1451 const_reference operator * () const {
Chris@16 1452 // FIXME replace find with at_element
Chris@16 1453 BOOST_UBLAS_CHECK (index () < (*this) ().size (), bad_index ());
Chris@16 1454 return (*this) ().data_ (*it_);
Chris@16 1455 }
Chris@16 1456 BOOST_UBLAS_INLINE
Chris@16 1457 const_reference operator [] (difference_type n) const {
Chris@16 1458 return *(*this + n);
Chris@16 1459 }
Chris@16 1460
Chris@16 1461 // Index
Chris@16 1462 BOOST_UBLAS_INLINE
Chris@16 1463 size_type index () const {
Chris@16 1464 return it_.index ();
Chris@16 1465 }
Chris@16 1466
Chris@16 1467 // Assignment
Chris@16 1468 BOOST_UBLAS_INLINE
Chris@16 1469 const_iterator &operator = (const const_iterator &it) {
Chris@16 1470 container_const_reference<self_type>::assign (&it ());
Chris@16 1471 it_ = it.it_;
Chris@16 1472 return *this;
Chris@16 1473 }
Chris@16 1474
Chris@16 1475 // Comparison
Chris@16 1476 BOOST_UBLAS_INLINE
Chris@16 1477 bool operator == (const const_iterator &it) const {
Chris@16 1478 BOOST_UBLAS_CHECK ((*this) ().same_closure (it ()), external_logic ());
Chris@16 1479 return it_ == it.it_;
Chris@16 1480 }
Chris@16 1481 BOOST_UBLAS_INLINE
Chris@16 1482 bool operator < (const const_iterator &it) const {
Chris@16 1483 BOOST_UBLAS_CHECK ((*this) ().same_closure (it ()), external_logic ());
Chris@16 1484 return it_ < it.it_;
Chris@16 1485 }
Chris@16 1486
Chris@16 1487 private:
Chris@16 1488 const_subiterator_type it_;
Chris@16 1489 };
Chris@16 1490 #endif
Chris@16 1491
Chris@16 1492 BOOST_UBLAS_INLINE
Chris@16 1493 const_iterator begin () const {
Chris@16 1494 return find (0);
Chris@16 1495 }
Chris@16 1496 BOOST_UBLAS_INLINE
Chris@101 1497 const_iterator cbegin () const {
Chris@101 1498 return begin ();
Chris@101 1499 }
Chris@101 1500 BOOST_UBLAS_INLINE
Chris@16 1501 const_iterator end () const {
Chris@16 1502 return find (size ());
Chris@16 1503 }
Chris@101 1504 BOOST_UBLAS_INLINE
Chris@101 1505 const_iterator cend () const {
Chris@101 1506 return end ();
Chris@101 1507 }
Chris@16 1508
Chris@16 1509 #ifndef BOOST_UBLAS_USE_INDEXED_ITERATOR
Chris@16 1510 class iterator:
Chris@16 1511 public container_reference<vector_indirect>,
Chris@16 1512 public iterator_base_traits<typename V::iterator::iterator_category>::template
Chris@16 1513 iterator_base<iterator, value_type>::type {
Chris@16 1514 public:
Chris@16 1515 typedef typename V::iterator::difference_type difference_type;
Chris@16 1516 typedef typename V::iterator::value_type value_type;
Chris@16 1517 typedef typename V::reference reference; //FIXME due to indexing access
Chris@16 1518 typedef typename V::iterator::pointer pointer;
Chris@16 1519
Chris@16 1520 // Construction and destruction
Chris@16 1521 BOOST_UBLAS_INLINE
Chris@16 1522 iterator ():
Chris@16 1523 container_reference<self_type> (), it_ () {}
Chris@16 1524 BOOST_UBLAS_INLINE
Chris@16 1525 iterator (self_type &vi, const subiterator_type &it):
Chris@16 1526 container_reference<self_type> (vi), it_ (it) {}
Chris@16 1527
Chris@16 1528 // Arithmetic
Chris@16 1529 BOOST_UBLAS_INLINE
Chris@16 1530 iterator &operator ++ () {
Chris@16 1531 ++ it_;
Chris@16 1532 return *this;
Chris@16 1533 }
Chris@16 1534 BOOST_UBLAS_INLINE
Chris@16 1535 iterator &operator -- () {
Chris@16 1536 -- it_;
Chris@16 1537 return *this;
Chris@16 1538 }
Chris@16 1539 BOOST_UBLAS_INLINE
Chris@16 1540 iterator &operator += (difference_type n) {
Chris@16 1541 it_ += n;
Chris@16 1542 return *this;
Chris@16 1543 }
Chris@16 1544 BOOST_UBLAS_INLINE
Chris@16 1545 iterator &operator -= (difference_type n) {
Chris@16 1546 it_ -= n;
Chris@16 1547 return *this;
Chris@16 1548 }
Chris@16 1549 BOOST_UBLAS_INLINE
Chris@16 1550 difference_type operator - (const iterator &it) const {
Chris@16 1551 BOOST_UBLAS_CHECK ((*this) ().same_closure (it ()), external_logic ());
Chris@16 1552 return it_ - it.it_;
Chris@16 1553 }
Chris@16 1554
Chris@16 1555 // Dereference
Chris@16 1556 BOOST_UBLAS_INLINE
Chris@16 1557 reference operator * () const {
Chris@16 1558 // FIXME replace find with at_element
Chris@16 1559 BOOST_UBLAS_CHECK (index () < (*this) ().size (), bad_index ());
Chris@16 1560 return (*this) ().data_ (*it_);
Chris@16 1561 }
Chris@16 1562 BOOST_UBLAS_INLINE
Chris@16 1563 reference operator [] (difference_type n) const {
Chris@16 1564 return *(*this + n);
Chris@16 1565 }
Chris@16 1566
Chris@16 1567 // Index
Chris@16 1568 BOOST_UBLAS_INLINE
Chris@16 1569 size_type index () const {
Chris@16 1570 return it_.index ();
Chris@16 1571 }
Chris@16 1572
Chris@16 1573 // Assignment
Chris@16 1574 BOOST_UBLAS_INLINE
Chris@16 1575 iterator &operator = (const iterator &it) {
Chris@16 1576 container_reference<self_type>::assign (&it ());
Chris@16 1577 it_ = it.it_;
Chris@16 1578 return *this;
Chris@16 1579 }
Chris@16 1580
Chris@16 1581 // Comparison
Chris@16 1582 BOOST_UBLAS_INLINE
Chris@16 1583 bool operator == (const iterator &it) const {
Chris@16 1584 BOOST_UBLAS_CHECK ((*this) ().same_closure (it ()), external_logic ());
Chris@16 1585 return it_ == it.it_;
Chris@16 1586 }
Chris@16 1587 BOOST_UBLAS_INLINE
Chris@16 1588 bool operator < (const iterator &it) const {
Chris@16 1589 BOOST_UBLAS_CHECK ((*this) ().same_closure (it ()), external_logic ());
Chris@16 1590 return it_ < it.it_;
Chris@16 1591 }
Chris@16 1592
Chris@16 1593 private:
Chris@16 1594 subiterator_type it_;
Chris@16 1595
Chris@16 1596 friend class const_iterator;
Chris@16 1597 };
Chris@16 1598 #endif
Chris@16 1599
Chris@16 1600 BOOST_UBLAS_INLINE
Chris@16 1601 iterator begin () {
Chris@16 1602 return find (0);
Chris@16 1603 }
Chris@16 1604 BOOST_UBLAS_INLINE
Chris@16 1605 iterator end () {
Chris@16 1606 return find (size ());
Chris@16 1607 }
Chris@16 1608
Chris@16 1609 // Reverse iterator
Chris@16 1610 typedef reverse_iterator_base<const_iterator> const_reverse_iterator;
Chris@16 1611 typedef reverse_iterator_base<iterator> reverse_iterator;
Chris@16 1612
Chris@16 1613 BOOST_UBLAS_INLINE
Chris@16 1614 const_reverse_iterator rbegin () const {
Chris@16 1615 return const_reverse_iterator (end ());
Chris@16 1616 }
Chris@16 1617 BOOST_UBLAS_INLINE
Chris@101 1618 const_reverse_iterator crbegin () const {
Chris@101 1619 return rbegin ();
Chris@101 1620 }
Chris@101 1621 BOOST_UBLAS_INLINE
Chris@16 1622 const_reverse_iterator rend () const {
Chris@16 1623 return const_reverse_iterator (begin ());
Chris@16 1624 }
Chris@16 1625 BOOST_UBLAS_INLINE
Chris@101 1626 const_reverse_iterator crend () const {
Chris@101 1627 return rend ();
Chris@101 1628 }
Chris@101 1629
Chris@101 1630 BOOST_UBLAS_INLINE
Chris@16 1631 reverse_iterator rbegin () {
Chris@16 1632 return reverse_iterator (end ());
Chris@16 1633 }
Chris@16 1634 BOOST_UBLAS_INLINE
Chris@16 1635 reverse_iterator rend () {
Chris@16 1636 return reverse_iterator (begin ());
Chris@16 1637 }
Chris@16 1638
Chris@16 1639 private:
Chris@16 1640 vector_closure_type data_;
Chris@16 1641 indirect_array_type ia_;
Chris@16 1642 };
Chris@16 1643
Chris@16 1644 // Projections
Chris@16 1645 template<class V, class A>
Chris@16 1646 BOOST_UBLAS_INLINE
Chris@16 1647 vector_indirect<V, indirect_array<A> > project (V &data, const indirect_array<A> &ia) {
Chris@16 1648 return vector_indirect<V, indirect_array<A> > (data, ia);
Chris@16 1649 }
Chris@16 1650 template<class V, class A>
Chris@16 1651 BOOST_UBLAS_INLINE
Chris@16 1652 const vector_indirect<const V, indirect_array<A> > project (const V &data, const indirect_array<A> &ia) {
Chris@16 1653 // ISSUE was: return vector_indirect<V, indirect_array<A> > (const_cast<V &> (data), ia)
Chris@16 1654 return vector_indirect<const V, indirect_array<A> > (data, ia);
Chris@16 1655 }
Chris@16 1656 template<class V, class IA>
Chris@16 1657 BOOST_UBLAS_INLINE
Chris@16 1658 vector_indirect<V, IA> project (vector_indirect<V, IA> &data, const typename vector_indirect<V, IA>::range_type &r) {
Chris@16 1659 return data.project (r);
Chris@16 1660 }
Chris@16 1661 template<class V, class IA>
Chris@16 1662 BOOST_UBLAS_INLINE
Chris@16 1663 const vector_indirect<V, IA> project (const vector_indirect<V, IA> &data, const typename vector_indirect<V, IA>::range_type &r) {
Chris@16 1664 return data.project (r);
Chris@16 1665 }
Chris@16 1666 template<class V, class IA>
Chris@16 1667 BOOST_UBLAS_INLINE
Chris@16 1668 vector_indirect<V, IA> project (vector_indirect<V, IA> &data, const typename vector_indirect<V, IA>::slice_type &s) {
Chris@16 1669 return data.project (s);
Chris@16 1670 }
Chris@16 1671 template<class V, class IA>
Chris@16 1672 BOOST_UBLAS_INLINE
Chris@16 1673 const vector_indirect<V, IA> project (const vector_indirect<V, IA> &data, const typename vector_indirect<V, IA>::slice_type &s) {
Chris@16 1674 return data.project (s);
Chris@16 1675 }
Chris@16 1676 template<class V, class A>
Chris@16 1677 BOOST_UBLAS_INLINE
Chris@16 1678 vector_indirect<V, indirect_array<A> > project (vector_indirect<V, indirect_array<A> > &data, const indirect_array<A> &ia) {
Chris@16 1679 return data.project (ia);
Chris@16 1680 }
Chris@16 1681 template<class V, class A>
Chris@16 1682 BOOST_UBLAS_INLINE
Chris@16 1683 const vector_indirect<V, indirect_array<A> > project (const vector_indirect<V, indirect_array<A> > &data, const indirect_array<A> &ia) {
Chris@16 1684 return data.project (ia);
Chris@16 1685 }
Chris@16 1686
Chris@16 1687 // Specialization of temporary_traits
Chris@16 1688 template <class V>
Chris@16 1689 struct vector_temporary_traits< vector_indirect<V> >
Chris@16 1690 : vector_temporary_traits< V > {} ;
Chris@16 1691 template <class V>
Chris@16 1692 struct vector_temporary_traits< const vector_indirect<V> >
Chris@16 1693 : vector_temporary_traits< V > {} ;
Chris@16 1694
Chris@16 1695 }}}
Chris@16 1696
Chris@16 1697 #endif