1 // 2 // Copyright (c) 2000-2010 3 // Joerg Walter, Mathias Koch, David Bellot 4 // Copyright (c) 2014, Athanasios Iliopoulos 5 // 6 // Distributed under the Boost Software License, Version 1.0. (See 7 // accompanying file LICENSE_1_0.txt or copy at 8 // http://www.boost.org/LICENSE_1_0.txt) 9 // 10 // The authors gratefully acknowledge the support of 11 // GeNeSys mbH & Co. KG in producing this work. 12 // 13 // And we acknowledge the support from all contributors. 14 15 /// \file vector.hpp Definition for the class vector and its derivative 16 17 #ifndef _BOOST_UBLAS_VECTOR_ 18 #define _BOOST_UBLAS_VECTOR_ 19 20 #include <boost/config.hpp> 21 #include <boost/numeric/ublas/storage.hpp> 22 #include <boost/numeric/ublas/vector_expression.hpp> 23 #include <boost/numeric/ublas/detail/vector_assign.hpp> 24 #include <boost/serialization/collection_size_type.hpp> 25 #include <boost/serialization/nvp.hpp> 26 27 #ifdef BOOST_UBLAS_CPP_GE_2011 28 #include <array> 29 #include <initializer_list> 30 #if defined(BOOST_MSVC) // For std::forward in fixed_vector 31 #include <utility> 32 #endif 33 #endif 34 35 // Iterators based on ideas of Jeremy Siek 36 37 namespace boost { namespace numeric { namespace ublas { 38 39 /** \brief A dense vector of values of type \c T. 40 * 41 * For a \f$n\f$-dimensional vector \f$v\f$ and \f$0\leq i < n\f$ every element \f$v_i\f$ is mapped 42 * to the \f$i\f$-th element of the container. A storage type \c A can be specified which defaults to \c unbounded_array. 43 * Elements are constructed by \c A, which need not initialise their value. 44 * 45 * \tparam T type of the objects stored in the vector (like int, double, complex,...) 46 * \tparam A The type of the storage array of the vector. Default is \c unbounded_array<T>. \c <bounded_array<T> and \c std::vector<T> can also be used 47 */ 48 template<class T, class A> 49 class vector: 50 public vector_container<vector<T, A> > { 51 52 typedef vector<T, A> self_type; 53 public: 54 #ifdef BOOST_UBLAS_ENABLE_PROXY_SHORTCUTS 55 using vector_container<self_type>::operator (); 56 #endif 57 58 typedef typename A::size_type size_type; 59 typedef typename A::difference_type difference_type; 60 typedef T value_type; 61 typedef typename type_traits<T>::const_reference const_reference; 62 typedef T &reference; 63 typedef T *pointer; 64 typedef const T *const_pointer; 65 typedef A array_type; 66 typedef const vector_reference<const self_type> const_closure_type; 67 typedef vector_reference<self_type> closure_type; 68 typedef self_type vector_temporary_type; 69 typedef dense_tag storage_category; 70 71 // Construction and destruction 72 73 /// \brief Constructor of a vector 74 /// By default it is empty, i.e. \c size()==0. 75 BOOST_UBLAS_INLINE vector()76 vector (): 77 vector_container<self_type> (), 78 data_ () {} 79 80 /// \brief Constructor of a vector with a predefined size 81 /// By default, its elements are initialized to 0. 82 /// \param size initial size of the vector 83 explicit BOOST_UBLAS_INLINE vector(size_type size)84 vector (size_type size): 85 vector_container<self_type> (), 86 data_ (size) { 87 } 88 89 /// \brief Constructor of a vector by copying from another container 90 /// This type has the generic name \c array_typ within the vector definition. 91 /// \param size initial size of the vector \bug this value is not used 92 /// \param data container of type \c A 93 /// \todo remove this definition because \c size is not used 94 BOOST_UBLAS_INLINE vector(size_type,const array_type & data)95 vector (size_type /*size*/, const array_type &data): 96 vector_container<self_type> (), 97 data_ (data) {} 98 99 /// \brief Constructor of a vector by copying from another container 100 /// This type has the generic name \c array_typ within the vector definition. 101 /// \param data container of type \c A 102 BOOST_UBLAS_INLINE vector(const array_type & data)103 vector (const array_type &data): 104 vector_container<self_type> (), 105 data_ (data) {} 106 107 /// \brief Constructor of a vector with a predefined size and a unique initial value 108 /// \param size of the vector 109 /// \param init value to assign to each element of the vector 110 BOOST_UBLAS_INLINE vector(size_type size,const value_type & init)111 vector (size_type size, const value_type &init): 112 vector_container<self_type> (), 113 data_ (size, init) {} 114 115 /// \brief Copy-constructor of a vector 116 /// \param v is the vector to be duplicated 117 BOOST_UBLAS_INLINE vector(const vector & v)118 vector (const vector &v): 119 vector_container<self_type> (), 120 data_ (v.data_) {} 121 122 /// \brief Copy-constructor of a vector from a vector_expression 123 /// Depending on the vector_expression, this constructor can have the cost of the computations 124 /// of the expression (trivial to say it, but it is to take into account in your complexity calculations). 125 /// \param ae the vector_expression which values will be duplicated into the vector 126 template<class AE> 127 BOOST_UBLAS_INLINE vector(const vector_expression<AE> & ae)128 vector (const vector_expression<AE> &ae): 129 vector_container<self_type> (), 130 data_ (ae ().size ()) { 131 vector_assign<scalar_assign> (*this, ae); 132 } 133 134 // ----------------------- 135 // Random Access Container 136 // ----------------------- 137 138 /// \brief Return the maximum size of the data container. 139 /// Return the upper bound (maximum size) on the data container. Depending on the container, it can be bigger than the current size of the vector. 140 BOOST_UBLAS_INLINE max_size() const141 size_type max_size () const { 142 return data_.max_size (); 143 } 144 145 /// \brief Return true if the vector is empty (\c size==0) 146 /// \return \c true if empty, \c false otherwise 147 BOOST_UBLAS_INLINE empty() const148 bool empty () const { 149 return data_.size () == 0; 150 } 151 152 // --------- 153 // Accessors 154 // --------- 155 156 /// \brief Return the size of the vector 157 BOOST_UBLAS_INLINE size() const158 size_type size () const { 159 return data_.size (); 160 } 161 162 // ----------------- 163 // Storage accessors 164 // ----------------- 165 166 /// \brief Return a \c const reference to the container. Useful to access data directly for specific type of container. 167 BOOST_UBLAS_INLINE data() const168 const array_type &data () const { 169 return data_; 170 } 171 172 /// \brief Return a reference to the container. Useful to speed-up write operations to the data in very specific case. 173 BOOST_UBLAS_INLINE data()174 array_type &data () { 175 return data_; 176 } 177 178 // -------- 179 // Resizing 180 // -------- 181 182 /// \brief Resize the vector 183 /// Resize the vector to a new size. If \c preserve is true, data are copied otherwise data are lost. If the new size is bigger, the remaining values are filled in with the initial value (0 by default) in the case of \c unbounded_array, which is the container by default. If the new size is smaller, last values are lost. This behaviour can be different if you explicitely specify another type of container. 184 /// \param size new size of the vector 185 /// \param preserve if true, keep values 186 BOOST_UBLAS_INLINE resize(size_type size,bool preserve=true)187 void resize (size_type size, bool preserve = true) { 188 if (preserve) 189 data ().resize (size, typename A::value_type ()); 190 else 191 data ().resize (size); 192 } 193 194 // --------------- 195 // Element support 196 // --------------- 197 198 /// \brief Return a pointer to the element \f$i\f$ 199 /// \param i index of the element 200 // XXX this semantic is not the one expected by the name of this method 201 BOOST_UBLAS_INLINE find_element(size_type i)202 pointer find_element (size_type i) { 203 return const_cast<pointer> (const_cast<const self_type&>(*this).find_element (i)); 204 } 205 206 /// \brief Return a const pointer to the element \f$i\f$ 207 /// \param i index of the element 208 // XXX this semantic is not the one expected by the name of this method 209 BOOST_UBLAS_INLINE find_element(size_type i) const210 const_pointer find_element (size_type i) const { 211 return & (data () [i]); 212 } 213 214 // -------------- 215 // Element access 216 // -------------- 217 218 /// \brief Return a const reference to the element \f$i\f$ 219 /// Return a const reference to the element \f$i\f$. With some compilers, this notation will be faster than \c[i] 220 /// \param i index of the element 221 BOOST_UBLAS_INLINE operator ()(size_type i) const222 const_reference operator () (size_type i) const { 223 return data () [i]; 224 } 225 226 /// \brief Return a reference to the element \f$i\f$ 227 /// Return a reference to the element \f$i\f$. With some compilers, this notation will be faster than \c[i] 228 /// \param i index of the element 229 BOOST_UBLAS_INLINE operator ()(size_type i)230 reference operator () (size_type i) { 231 return data () [i]; 232 } 233 234 /// \brief Return a const reference to the element \f$i\f$ 235 /// \param i index of the element 236 BOOST_UBLAS_INLINE operator [](size_type i) const237 const_reference operator [] (size_type i) const { 238 return (*this) (i); 239 } 240 241 /// \brief Return a reference to the element \f$i\f$ 242 /// \param i index of the element 243 BOOST_UBLAS_INLINE operator [](size_type i)244 reference operator [] (size_type i) { 245 return (*this) (i); 246 } 247 248 // ------------------ 249 // Element assignment 250 // ------------------ 251 252 /// \brief Set element \f$i\f$ to the value \c t 253 /// \param i index of the element 254 /// \param t reference to the value to be set 255 // XXX semantic of this is to insert a new element and therefore size=size+1 ? 256 BOOST_UBLAS_INLINE insert_element(size_type i,const_reference t)257 reference insert_element (size_type i, const_reference t) { 258 return (data () [i] = t); 259 } 260 261 /// \brief Set element \f$i\f$ to the \e zero value 262 /// \param i index of the element 263 BOOST_UBLAS_INLINE erase_element(size_type i)264 void erase_element (size_type i) { 265 data () [i] = value_type/*zero*/(); 266 } 267 268 // ------- 269 // Zeroing 270 // ------- 271 272 /// \brief Clear the vector, i.e. set all values to the \c zero value. 273 BOOST_UBLAS_INLINE clear()274 void clear () { 275 std::fill (data ().begin (), data ().end (), value_type/*zero*/()); 276 } 277 278 // Assignment 279 #ifdef BOOST_UBLAS_MOVE_SEMANTICS 280 281 /// \brief Assign a full vector (\e RHS-vector) to the current vector (\e LHS-vector) 282 /// \param v is the source vector 283 /// \return a reference to a vector (i.e. the destination vector) 284 /*! @note "pass by value" the key idea to enable move semantics */ 285 BOOST_UBLAS_INLINE operator =(vector v)286 vector &operator = (vector v) { 287 assign_temporary(v); 288 return *this; 289 } 290 #else 291 /// \brief Assign a full vector (\e RHS-vector) to the current vector (\e LHS-vector) 292 /// \param v is the source vector 293 /// \return a reference to a vector (i.e. the destination vector) 294 BOOST_UBLAS_INLINE operator =(const vector & v)295 vector &operator = (const vector &v) { 296 data () = v.data (); 297 return *this; 298 } 299 #endif 300 301 /// \brief Assign a full vector (\e RHS-vector) to the current vector (\e LHS-vector) 302 /// Assign a full vector (\e RHS-vector) to the current vector (\e LHS-vector). This method does not create any temporary. 303 /// \param v is the source vector container 304 /// \return a reference to a vector (i.e. the destination vector) 305 template<class C> // Container assignment without temporary 306 BOOST_UBLAS_INLINE operator =(const vector_container<C> & v)307 vector &operator = (const vector_container<C> &v) { 308 resize (v ().size (), false); 309 assign (v); 310 return *this; 311 } 312 313 /// \brief Assign a full vector (\e RHS-vector) to the current vector (\e LHS-vector) 314 /// \param v is the source vector 315 /// \return a reference to a vector (i.e. the destination vector) 316 BOOST_UBLAS_INLINE assign_temporary(vector & v)317 vector &assign_temporary (vector &v) { 318 swap (v); 319 return *this; 320 } 321 322 /// \brief Assign the result of a vector_expression to the vector 323 /// Assign the result of a vector_expression to the vector. This is lazy-compiled and will be optimized out by the compiler on any type of expression. 324 /// \tparam AE is the type of the vector_expression 325 /// \param ae is a const reference to the vector_expression 326 /// \return a reference to the resulting vector 327 template<class AE> 328 BOOST_UBLAS_INLINE operator =(const vector_expression<AE> & ae)329 vector &operator = (const vector_expression<AE> &ae) { 330 self_type temporary (ae); 331 return assign_temporary (temporary); 332 } 333 334 /// \brief Assign the result of a vector_expression to the vector 335 /// Assign the result of a vector_expression to the vector. This is lazy-compiled and will be optimized out by the compiler on any type of expression. 336 /// \tparam AE is the type of the vector_expression 337 /// \param ae is a const reference to the vector_expression 338 /// \return a reference to the resulting vector 339 template<class AE> 340 BOOST_UBLAS_INLINE assign(const vector_expression<AE> & ae)341 vector &assign (const vector_expression<AE> &ae) { 342 vector_assign<scalar_assign> (*this, ae); 343 return *this; 344 } 345 346 // ------------------- 347 // Computed assignment 348 // ------------------- 349 350 /// \brief Assign the sum of the vector and a vector_expression to the vector 351 /// Assign the sum of the vector and a vector_expression to the vector. This is lazy-compiled and will be optimized out by the compiler on any type of expression. 352 /// A temporary is created for the computations. 353 /// \tparam AE is the type of the vector_expression 354 /// \param ae is a const reference to the vector_expression 355 /// \return a reference to the resulting vector 356 template<class AE> 357 BOOST_UBLAS_INLINE operator +=(const vector_expression<AE> & ae)358 vector &operator += (const vector_expression<AE> &ae) { 359 self_type temporary (*this + ae); 360 return assign_temporary (temporary); 361 } 362 363 /// \brief Assign the sum of the vector and a vector_expression to the vector 364 /// Assign the sum of the vector and a vector_expression to the vector. This is lazy-compiled and will be optimized out by the compiler on any type of expression. 365 /// No temporary is created. Computations are done and stored directly into the resulting vector. 366 /// \tparam AE is the type of the vector_expression 367 /// \param ae is a const reference to the vector_expression 368 /// \return a reference to the resulting vector 369 template<class C> // Container assignment without temporary 370 BOOST_UBLAS_INLINE operator +=(const vector_container<C> & v)371 vector &operator += (const vector_container<C> &v) { 372 plus_assign (v); 373 return *this; 374 } 375 376 /// \brief Assign the sum of the vector and a vector_expression to the vector 377 /// Assign the sum of the vector and a vector_expression to the vector. This is lazy-compiled and will be optimized out by the compiler on any type of expression. 378 /// No temporary is created. Computations are done and stored directly into the resulting vector. 379 /// \tparam AE is the type of the vector_expression 380 /// \param ae is a const reference to the vector_expression 381 /// \return a reference to the resulting vector 382 template<class AE> 383 BOOST_UBLAS_INLINE plus_assign(const vector_expression<AE> & ae)384 vector &plus_assign (const vector_expression<AE> &ae) { 385 vector_assign<scalar_plus_assign> (*this, ae); 386 return *this; 387 } 388 389 /// \brief Assign the difference of the vector and a vector_expression to the vector 390 /// Assign the difference of the vector and a vector_expression to the vector. This is lazy-compiled and will be optimized out by the compiler on any type of expression. 391 /// A temporary is created for the computations. 392 /// \tparam AE is the type of the vector_expression 393 /// \param ae is a const reference to the vector_expression 394 template<class AE> 395 BOOST_UBLAS_INLINE operator -=(const vector_expression<AE> & ae)396 vector &operator -= (const vector_expression<AE> &ae) { 397 self_type temporary (*this - ae); 398 return assign_temporary (temporary); 399 } 400 401 /// \brief Assign the difference of the vector and a vector_expression to the vector 402 /// Assign the difference of the vector and a vector_expression to the vector. This is lazy-compiled and will be optimized out by the compiler on any type of expression. 403 /// No temporary is created. Computations are done and stored directly into the resulting vector. 404 /// \tparam AE is the type of the vector_expression 405 /// \param ae is a const reference to the vector_expression 406 /// \return a reference to the resulting vector 407 template<class C> // Container assignment without temporary 408 BOOST_UBLAS_INLINE operator -=(const vector_container<C> & v)409 vector &operator -= (const vector_container<C> &v) { 410 minus_assign (v); 411 return *this; 412 } 413 414 /// \brief Assign the difference of the vector and a vector_expression to the vector 415 /// Assign the difference of the vector and a vector_expression to the vector. This is lazy-compiled and will be optimized out by the compiler on any type of expression. 416 /// No temporary is created. Computations are done and stored directly into the resulting vector. 417 /// \tparam AE is the type of the vector_expression 418 /// \param ae is a const reference to the vector_expression 419 /// \return a reference to the resulting vector 420 template<class AE> 421 BOOST_UBLAS_INLINE minus_assign(const vector_expression<AE> & ae)422 vector &minus_assign (const vector_expression<AE> &ae) { 423 vector_assign<scalar_minus_assign> (*this, ae); 424 return *this; 425 } 426 427 /// \brief Assign the product of the vector and a scalar to the vector 428 /// Assign the product of the vector and a scalar to the vector. This is lazy-compiled and will be optimized out by the compiler on any type of expression. 429 /// No temporary is created. Computations are done and stored directly into the resulting vector. 430 /// \tparam AE is the type of the vector_expression 431 /// \param at is a const reference to the scalar 432 /// \return a reference to the resulting vector 433 template<class AT> 434 BOOST_UBLAS_INLINE operator *=(const AT & at)435 vector &operator *= (const AT &at) { 436 vector_assign_scalar<scalar_multiplies_assign> (*this, at); 437 return *this; 438 } 439 440 /// \brief Assign the division of the vector by a scalar to the vector 441 /// Assign the division of the vector by a scalar to the vector. This is lazy-compiled and will be optimized out by the compiler on any type of expression. 442 /// No temporary is created. Computations are done and stored directly into the resulting vector. 443 /// \tparam AE is the type of the vector_expression 444 /// \param at is a const reference to the scalar 445 /// \return a reference to the resulting vector 446 template<class AT> 447 BOOST_UBLAS_INLINE operator /=(const AT & at)448 vector &operator /= (const AT &at) { 449 vector_assign_scalar<scalar_divides_assign> (*this, at); 450 return *this; 451 } 452 453 // -------- 454 // Swapping 455 // -------- 456 457 /// \brief Swap the content of the vector with another vector 458 /// \param v is the vector to be swapped with 459 BOOST_UBLAS_INLINE swap(vector & v)460 void swap (vector &v) { 461 if (this != &v) { 462 data ().swap (v.data ()); 463 } 464 } 465 466 /// \brief Swap the content of two vectors 467 /// \param v1 is the first vector. It takes values from v2 468 /// \param v2 is the second vector It takes values from v1 469 BOOST_UBLAS_INLINE swap(vector & v1,vector & v2)470 friend void swap (vector &v1, vector &v2) { 471 v1.swap (v2); 472 } 473 474 // Iterator types 475 private: 476 // Use the storage array iterator 477 typedef typename A::const_iterator const_subiterator_type; 478 typedef typename A::iterator subiterator_type; 479 480 public: 481 #ifdef BOOST_UBLAS_USE_INDEXED_ITERATOR 482 typedef indexed_iterator<self_type, dense_random_access_iterator_tag> iterator; 483 typedef indexed_const_iterator<self_type, dense_random_access_iterator_tag> const_iterator; 484 #else 485 class const_iterator; 486 class iterator; 487 #endif 488 489 // -------------- 490 // Element lookup 491 // -------------- 492 493 /// \brief Return a const iterator to the element \e i 494 /// \param i index of the element 495 BOOST_UBLAS_INLINE find(size_type i) const496 const_iterator find (size_type i) const { 497 #ifndef BOOST_UBLAS_USE_INDEXED_ITERATOR 498 return const_iterator (*this, data ().begin () + i); 499 #else 500 return const_iterator (*this, i); 501 #endif 502 } 503 504 /// \brief Return an iterator to the element \e i 505 /// \param i index of the element 506 BOOST_UBLAS_INLINE find(size_type i)507 iterator find (size_type i) { 508 #ifndef BOOST_UBLAS_USE_INDEXED_ITERATOR 509 return iterator (*this, data ().begin () + i); 510 #else 511 return iterator (*this, i); 512 #endif 513 } 514 515 #ifndef BOOST_UBLAS_USE_INDEXED_ITERATOR 516 class const_iterator: 517 public container_const_reference<vector>, 518 public random_access_iterator_base<dense_random_access_iterator_tag, 519 const_iterator, value_type, difference_type> { 520 public: 521 typedef typename vector::difference_type difference_type; 522 typedef typename vector::value_type value_type; 523 typedef typename vector::const_reference reference; 524 typedef const typename vector::pointer pointer; 525 526 // ---------------------------- 527 // Construction and destruction 528 // ---------------------------- 529 530 531 BOOST_UBLAS_INLINE const_iterator()532 const_iterator (): 533 container_const_reference<self_type> (), it_ () {} 534 BOOST_UBLAS_INLINE const_iterator(const self_type & v,const const_subiterator_type & it)535 const_iterator (const self_type &v, const const_subiterator_type &it): 536 container_const_reference<self_type> (v), it_ (it) {} 537 BOOST_UBLAS_INLINE const_iterator(const typename self_type::iterator & it)538 const_iterator (const typename self_type::iterator &it): // ISSUE vector:: stops VC8 using std::iterator here 539 container_const_reference<self_type> (it ()), it_ (it.it_) {} 540 541 // ---------- 542 // Arithmetic 543 // ---------- 544 545 /// \brief Increment by 1 the position of the iterator 546 /// \return a reference to the const iterator 547 BOOST_UBLAS_INLINE operator ++()548 const_iterator &operator ++ () { 549 ++ it_; 550 return *this; 551 } 552 553 /// \brief Decrement by 1 the position of the iterator 554 /// \return a reference to the const iterator 555 BOOST_UBLAS_INLINE operator --()556 const_iterator &operator -- () { 557 -- it_; 558 return *this; 559 } 560 561 /// \brief Increment by \e n the position of the iterator 562 /// \return a reference to the const iterator 563 BOOST_UBLAS_INLINE operator +=(difference_type n)564 const_iterator &operator += (difference_type n) { 565 it_ += n; 566 return *this; 567 } 568 569 /// \brief Decrement by \e n the position of the iterator 570 /// \return a reference to the const iterator 571 BOOST_UBLAS_INLINE operator -=(difference_type n)572 const_iterator &operator -= (difference_type n) { 573 it_ -= n; 574 return *this; 575 } 576 577 /// \brief Return the different in number of positions between 2 iterators 578 BOOST_UBLAS_INLINE operator -(const const_iterator & it) const579 difference_type operator - (const const_iterator &it) const { 580 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ()); 581 return it_ - it.it_; 582 } 583 584 /// \brief Dereference an iterator 585 /// Dereference an iterator: a bounds' check is done before returning the value. A bad_index() expection is returned if out of bounds. 586 /// \return a const reference to the value pointed by the iterator 587 BOOST_UBLAS_INLINE operator *() const588 const_reference operator * () const { 589 BOOST_UBLAS_CHECK (it_ >= (*this) ().begin ().it_ && it_ < (*this) ().end ().it_, bad_index ()); 590 return *it_; 591 } 592 593 /// \brief Dereference an iterator at the n-th forward value 594 /// Dereference an iterator at the n-th forward value, that is the value pointed by iterator+n. 595 /// A bounds' check is done before returning the value. A bad_index() expection is returned if out of bounds. 596 /// \return a const reference 597 BOOST_UBLAS_INLINE operator [](difference_type n) const598 const_reference operator [] (difference_type n) const { 599 return *(it_ + n); 600 } 601 602 // Index 603 /// \brief return the index of the element referenced by the iterator 604 BOOST_UBLAS_INLINE index() const605 size_type index () const { 606 BOOST_UBLAS_CHECK (it_ >= (*this) ().begin ().it_ && it_ < (*this) ().end ().it_, bad_index ()); 607 return it_ - (*this) ().begin ().it_; 608 } 609 610 // Assignment 611 BOOST_UBLAS_INLINE 612 /// \brief assign the value of an iterator to the iterator operator =(const const_iterator & it)613 const_iterator &operator = (const const_iterator &it) { 614 container_const_reference<self_type>::assign (&it ()); 615 it_ = it.it_; 616 return *this; 617 } 618 619 // Comparison 620 /// \brief compare the value of two itetarors 621 /// \return true if they reference the same element 622 BOOST_UBLAS_INLINE operator ==(const const_iterator & it) const623 bool operator == (const const_iterator &it) const { 624 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ()); 625 return it_ == it.it_; 626 } 627 628 629 /// \brief compare the value of two iterators 630 /// \return return true if the left-hand-side iterator refers to a value placed before the right-hand-side iterator 631 BOOST_UBLAS_INLINE operator <(const const_iterator & it) const632 bool operator < (const const_iterator &it) const { 633 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ()); 634 return it_ < it.it_; 635 } 636 637 private: 638 const_subiterator_type it_; 639 640 friend class iterator; 641 }; 642 #endif 643 644 /// \brief return an iterator on the first element of the vector 645 BOOST_UBLAS_INLINE begin() const646 const_iterator begin () const { 647 return find (0); 648 } 649 650 /// \brief return an iterator on the first element of the vector 651 BOOST_UBLAS_INLINE cbegin() const652 const_iterator cbegin () const { 653 return begin (); 654 } 655 656 /// \brief return an iterator after the last element of the vector 657 BOOST_UBLAS_INLINE end() const658 const_iterator end () const { 659 return find (data_.size ()); 660 } 661 662 /// \brief return an iterator after the last element of the vector 663 BOOST_UBLAS_INLINE cend() const664 const_iterator cend () const { 665 return end (); 666 } 667 668 #ifndef BOOST_UBLAS_USE_INDEXED_ITERATOR 669 class iterator: 670 public container_reference<vector>, 671 public random_access_iterator_base<dense_random_access_iterator_tag, 672 iterator, value_type, difference_type> { 673 public: 674 typedef typename vector::difference_type difference_type; 675 typedef typename vector::value_type value_type; 676 typedef typename vector::reference reference; 677 typedef typename vector::pointer pointer; 678 679 680 // Construction and destruction 681 BOOST_UBLAS_INLINE iterator()682 iterator (): 683 container_reference<self_type> (), it_ () {} 684 BOOST_UBLAS_INLINE iterator(self_type & v,const subiterator_type & it)685 iterator (self_type &v, const subiterator_type &it): 686 container_reference<self_type> (v), it_ (it) {} 687 688 // Arithmetic 689 BOOST_UBLAS_INLINE operator ++()690 iterator &operator ++ () { 691 ++ it_; 692 return *this; 693 } 694 BOOST_UBLAS_INLINE operator --()695 iterator &operator -- () { 696 -- it_; 697 return *this; 698 } 699 BOOST_UBLAS_INLINE operator +=(difference_type n)700 iterator &operator += (difference_type n) { 701 it_ += n; 702 return *this; 703 } 704 BOOST_UBLAS_INLINE operator -=(difference_type n)705 iterator &operator -= (difference_type n) { 706 it_ -= n; 707 return *this; 708 } 709 BOOST_UBLAS_INLINE operator -(const iterator & it) const710 difference_type operator - (const iterator &it) const { 711 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ()); 712 return it_ - it.it_; 713 } 714 715 // Dereference 716 BOOST_UBLAS_INLINE operator *() const717 reference operator * () const { 718 BOOST_UBLAS_CHECK (it_ >= (*this) ().begin ().it_ && it_ < (*this) ().end ().it_ , bad_index ()); 719 return *it_; 720 } 721 BOOST_UBLAS_INLINE operator [](difference_type n) const722 reference operator [] (difference_type n) const { 723 return *(it_ + n); 724 } 725 726 // Index 727 BOOST_UBLAS_INLINE index() const728 size_type index () const { 729 BOOST_UBLAS_CHECK (it_ >= (*this) ().begin ().it_ && it_ < (*this) ().end ().it_ , bad_index ()); 730 return it_ - (*this) ().begin ().it_; 731 } 732 733 // Assignment 734 BOOST_UBLAS_INLINE operator =(const iterator & it)735 iterator &operator = (const iterator &it) { 736 container_reference<self_type>::assign (&it ()); 737 it_ = it.it_; 738 return *this; 739 } 740 741 // Comparison 742 BOOST_UBLAS_INLINE operator ==(const iterator & it) const743 bool operator == (const iterator &it) const { 744 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ()); 745 return it_ == it.it_; 746 } 747 BOOST_UBLAS_INLINE operator <(const iterator & it) const748 bool operator < (const iterator &it) const { 749 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ()); 750 return it_ < it.it_; 751 } 752 753 private: 754 subiterator_type it_; 755 756 friend class const_iterator; 757 }; 758 #endif 759 760 /// \brief Return an iterator on the first element of the vector 761 BOOST_UBLAS_INLINE begin()762 iterator begin () { 763 return find (0); 764 } 765 766 /// \brief Return an iterator at the end of the vector 767 BOOST_UBLAS_INLINE end()768 iterator end () { 769 return find (data_.size ()); 770 } 771 772 // Reverse iterator 773 typedef reverse_iterator_base<const_iterator> const_reverse_iterator; 774 typedef reverse_iterator_base<iterator> reverse_iterator; 775 776 /// \brief Return a const reverse iterator before the first element of the reversed vector (i.e. end() of normal vector) 777 BOOST_UBLAS_INLINE rbegin() const778 const_reverse_iterator rbegin () const { 779 return const_reverse_iterator (end ()); 780 } 781 782 /// \brief Return a const reverse iterator before the first element of the reversed vector (i.e. end() of normal vector) 783 BOOST_UBLAS_INLINE crbegin() const784 const_reverse_iterator crbegin () const { 785 return rbegin (); 786 } 787 788 /// \brief Return a const reverse iterator on the end of the reverse vector (i.e. first element of the normal vector) 789 BOOST_UBLAS_INLINE rend() const790 const_reverse_iterator rend () const { 791 return const_reverse_iterator (begin ()); 792 } 793 794 /// \brief Return a const reverse iterator on the end of the reverse vector (i.e. first element of the normal vector) 795 BOOST_UBLAS_INLINE crend() const796 const_reverse_iterator crend () const { 797 return rend (); 798 } 799 800 /// \brief Return a const reverse iterator before the first element of the reversed vector (i.e. end() of normal vector) 801 BOOST_UBLAS_INLINE rbegin()802 reverse_iterator rbegin () { 803 return reverse_iterator (end ()); 804 } 805 806 /// \brief Return a const reverse iterator on the end of the reverse vector (i.e. first element of the normal vector) 807 BOOST_UBLAS_INLINE rend()808 reverse_iterator rend () { 809 return reverse_iterator (begin ()); 810 } 811 812 // ------------- 813 // Serialization 814 // ------------- 815 816 /// Serialize a vector into and archive as defined in Boost 817 /// \param ar Archive object. Can be a flat file, an XML file or any other stream 818 /// \param file_version Optional file version (not yet used) 819 template<class Archive> serialize(Archive & ar,const unsigned int)820 void serialize(Archive & ar, const unsigned int /* file_version */){ 821 ar & serialization::make_nvp("data",data_); 822 } 823 824 private: 825 array_type data_; 826 }; 827 828 829 #ifdef BOOST_UBLAS_CPP_GE_2011 830 /** \brief A dense vector of values of type \c T. 831 * 832 * For a \f$n\f$-dimensional vector \f$v\f$ and \f$0\leq i < n\f$ every element \f$v_i\f$ is mapped 833 * to the \f$i\f$-th element of the container. A storage type \c A can be specified which defaults to \c std::array. 834 * Elements are constructed by \c A, which need not initialise their value. 835 * 836 * \tparam T type of the objects stored in the vector (like int, double, complex,...) 837 * \tparam A The type of the storage array of the vector. Default is \c std::array<T>. 838 */ 839 template<class T, std::size_t N, class A> 840 class fixed_vector: 841 public vector_container<fixed_vector<T, N, A> > { 842 843 typedef fixed_vector<T, N, A> self_type; 844 public: 845 #ifdef BOOST_UBLAS_ENABLE_PROXY_SHORTCUTS 846 using vector_container<self_type>::operator (); 847 #endif 848 849 typedef typename A::size_type size_type; 850 typedef typename A::difference_type difference_type; 851 typedef T value_type; 852 typedef typename type_traits<T>::const_reference const_reference; 853 typedef T &reference; 854 typedef T *pointer; 855 typedef const T *const_pointer; 856 typedef A array_type; 857 typedef const vector_reference<const self_type> const_closure_type; 858 typedef vector_reference<self_type> closure_type; 859 typedef self_type vector_temporary_type; 860 typedef dense_tag storage_category; 861 862 // Construction and destruction 863 864 /// \brief Constructor of a fixed_vector 865 BOOST_UBLAS_INLINE fixed_vector()866 fixed_vector (): 867 vector_container<self_type> (), 868 data_ () {} 869 870 /// \brief Constructor of a fixed_vector by copying from another container 871 /// This type uses the generic name \c array_type within the vector definition. 872 /// \param data container of type \c A 873 BOOST_UBLAS_INLINE fixed_vector(const array_type & data)874 fixed_vector (const array_type &data): 875 vector_container<self_type> (), 876 data_ (data) {} 877 878 /// \brief Constructor of a fixed_vector with a unique initial value 879 /// \param init value to assign to each element of the vector 880 BOOST_UBLAS_INLINE fixed_vector(const value_type & init)881 fixed_vector (const value_type &init): 882 vector_container<self_type> (), 883 data_ () { 884 data_.fill( init ); 885 } 886 887 /// \brief Copy-constructor of a fixed_vector 888 /// \param v is the fixed_vector to be duplicated 889 BOOST_UBLAS_INLINE fixed_vector(const fixed_vector & v)890 fixed_vector (const fixed_vector &v): 891 vector_container<self_type> (), 892 data_ (v.data_) {} 893 894 /// \brief Copy-constructor of a vector from a vector_expression 895 /// Depending on the vector_expression, this constructor can have the cost of the computations 896 /// of the expression (trivial to say it, but take it must be taken into account in your complexity calculations). 897 /// \param ae the vector_expression which values will be duplicated into the vector 898 template<class AE> 899 BOOST_UBLAS_INLINE fixed_vector(const vector_expression<AE> & ae)900 fixed_vector (const vector_expression<AE> &ae): 901 vector_container<self_type> (), 902 data_ ( ) { 903 vector_assign<scalar_assign> (*this, ae); 904 } 905 906 /// \brief Construct a fixed_vector from a list of values 907 /// This constructor enables initialization by using any of: 908 /// fixed_vector<double, 3> v = { 1, 2, 3 } or fixed_vector<double,3> v( {1, 2, 3} ) or fixed_vector<double,3> v( 1, 2, 3 ) 909 #if defined(BOOST_MSVC) 910 // This may or may not work. Maybe use this for all instead only for MSVC 911 template <typename... U> fixed_vector(U &&...values)912 fixed_vector(U&&... values) : 913 vector_container<self_type> (), 914 data_{{ std::forward<U>(values)... }} {} 915 #else 916 template <typename... Types> fixed_vector(value_type v0,Types...vrest)917 fixed_vector(value_type v0, Types... vrest) : 918 vector_container<self_type> (), 919 data_{ { v0, vrest... } } {} 920 #endif 921 922 // ----------------------- 923 // Random Access Container 924 // ----------------------- 925 926 /// \brief Return the maximum size of the data container. 927 /// Return the upper bound (maximum size) on the data container. Depending on the container, it can be bigger than the current size of the vector. 928 BOOST_UBLAS_INLINE max_size() const929 size_type max_size () const { 930 return data_.max_size (); 931 } 932 933 /// \brief Return true if the vector is empty (\c size==0) 934 /// \return \c true if empty, \c false otherwise 935 BOOST_UBLAS_INLINE empty() const936 const bool &empty () const { 937 return data_.empty(); 938 } 939 940 // --------- 941 // Accessors 942 // --------- 943 944 /// \brief Return the size of the vector 945 BOOST_UBLAS_INLINE size() const946 BOOST_CONSTEXPR size_type size () const{ // should have a const after C++14 947 return data_.size (); 948 } 949 950 // ----------------- 951 // Storage accessors 952 // ----------------- 953 954 /// \brief Return a \c const reference to the container. Useful to access data directly for specific type of container. 955 BOOST_UBLAS_INLINE data() const956 const array_type &data () const { 957 return data_; 958 } 959 960 /// \brief Return a reference to the container. Useful to speed-up write operations to the data in very specific case. 961 BOOST_UBLAS_INLINE data()962 array_type &data () { 963 return data_; 964 } 965 966 // --------------- 967 // Element support 968 // --------------- 969 970 /// \brief Return a pointer to the element \f$i\f$ 971 /// \param i index of the element 972 // XXX this semantic is not the one expected by the name of this method 973 BOOST_UBLAS_INLINE find_element(size_type i)974 pointer find_element (size_type i) { 975 return const_cast<pointer> (const_cast<const self_type&>(*this).find_element (i)); 976 } 977 978 /// \brief Return a const pointer to the element \f$i\f$ 979 /// \param i index of the element 980 // XXX this semantic is not the one expected by the name of this method 981 BOOST_UBLAS_INLINE find_element(size_type i) const982 const_pointer find_element (size_type i) const { 983 BOOST_UBLAS_CHECK (i < data_.size(), bad_index() ); // Since std:array doesn't check for bounds 984 return & (data () [i]); 985 } 986 987 // -------------- 988 // Element access 989 // -------------- 990 991 /// \brief Return a const reference to the element \f$i\f$ 992 /// Return a const reference to the element \f$i\f$. With some compilers, this notation will be faster than \c[i] 993 /// \param i index of the element 994 BOOST_UBLAS_INLINE operator ()(size_type i) const995 const_reference operator () (size_type i) const { 996 BOOST_UBLAS_CHECK (i < data_.size(), bad_index() ); 997 return data () [i]; 998 } 999 1000 /// \brief Return a reference to the element \f$i\f$ 1001 /// Return a reference to the element \f$i\f$. With some compilers, this notation will be faster than \c[i] 1002 /// \param i index of the element 1003 BOOST_UBLAS_INLINE operator ()(size_type i)1004 reference operator () (size_type i) { 1005 BOOST_UBLAS_CHECK (i < data_.size(), bad_index() ); 1006 return data () [i]; 1007 } 1008 1009 /// \brief Return a const reference to the element \f$i\f$ 1010 /// \param i index of the element 1011 BOOST_UBLAS_INLINE operator [](size_type i) const1012 const_reference operator [] (size_type i) const { 1013 BOOST_UBLAS_CHECK (i < data_.size(), bad_index() ); 1014 return (*this) (i); 1015 } 1016 1017 /// \brief Return a reference to the element \f$i\f$ 1018 /// \param i index of the element 1019 BOOST_UBLAS_INLINE operator [](size_type i)1020 reference operator [] (size_type i) { 1021 BOOST_UBLAS_CHECK (i < data_.size(), bad_index() ); 1022 return (*this) (i); 1023 } 1024 1025 // ------------------ 1026 // Element assignment 1027 // ------------------ 1028 1029 /// \brief Set element \f$i\f$ to the value \c t 1030 /// \param i index of the element 1031 /// \param t reference to the value to be set 1032 // XXX semantic of this is to insert a new element and therefore size=size+1 ? 1033 BOOST_UBLAS_INLINE insert_element(size_type i,const_reference t)1034 reference insert_element (size_type i, const_reference t) { 1035 BOOST_UBLAS_CHECK (i < data_.size(), bad_index ()); 1036 return (data () [i] = t); 1037 } 1038 1039 /// \brief Set element \f$i\f$ to the \e zero value 1040 /// \param i index of the element 1041 BOOST_UBLAS_INLINE erase_element(size_type i)1042 void erase_element (size_type i) { 1043 BOOST_UBLAS_CHECK (i < data_.size(), bad_index ()); 1044 data () [i] = value_type/*zero*/(); 1045 } 1046 1047 // ------- 1048 // Zeroing 1049 // ------- 1050 1051 /// \brief Clear the vector, i.e. set all values to the \c zero value. 1052 BOOST_UBLAS_INLINE clear()1053 void clear () { 1054 std::fill (data ().begin (), data ().end (), value_type/*zero*/()); 1055 } 1056 1057 // Assignment 1058 #ifdef BOOST_UBLAS_MOVE_SEMANTICS 1059 1060 /// \brief Assign a full fixed_vector (\e RHS-vector) to the current fixed_vector (\e LHS-vector) 1061 /// \param v is the source vector 1062 /// \return a reference to a fixed_vector (i.e. the destination vector) 1063 /*! @note "pass by value" the key idea to enable move semantics */ 1064 BOOST_UBLAS_INLINE operator =(fixed_vector v)1065 fixed_vector &operator = (fixed_vector v) { 1066 assign_temporary(v); 1067 return *this; 1068 } 1069 #else 1070 /// \brief Assign a full fixed_vector (\e RHS-vector) to the current fixed_vector (\e LHS-vector) 1071 /// \param v is the source fixed_vector 1072 /// \return a reference to a fixed_vector (i.e. the destination vector) 1073 BOOST_UBLAS_INLINE operator =(const fixed_vector & v)1074 fixed_vector &operator = (const fixed_vector &v) { 1075 data () = v.data (); 1076 return *this; 1077 } 1078 #endif 1079 1080 /// \brief Assign a full vector (\e RHS-vector) to the current fixed_vector (\e LHS-vector) 1081 /// Assign a full vector (\e RHS-vector) to the current fixed_vector (\e LHS-vector). This method does not create any temporary. 1082 /// \param v is the source vector container 1083 /// \return a reference to a vector (i.e. the destination vector) 1084 template<class C> // Container assignment without temporary 1085 BOOST_UBLAS_INLINE operator =(const vector_container<C> & v)1086 fixed_vector &operator = (const vector_container<C> &v) { 1087 assign (v); 1088 return *this; 1089 } 1090 1091 /// \brief Assign a full fixed_vector (\e RHS-vector) to the current fixed_vector (\e LHS-vector) 1092 /// \param v is the source fixed_vector 1093 /// \return a reference to a fixed_vector (i.e. the destination fixed_vector) 1094 BOOST_UBLAS_INLINE assign_temporary(fixed_vector & v)1095 fixed_vector &assign_temporary (fixed_vector &v) { 1096 swap ( v ); 1097 return *this; 1098 } 1099 1100 /// \brief Assign the result of a vector_expression to the fixed_vector 1101 /// Assign the result of a vector_expression to the vector. This is lazy-compiled and will be optimized out by the compiler on any type of expression. 1102 /// \tparam AE is the type of the vector_expression 1103 /// \param ae is a const reference to the vector_expression 1104 /// \return a reference to the resulting fixed_vector 1105 template<class AE> 1106 BOOST_UBLAS_INLINE operator =(const vector_expression<AE> & ae)1107 fixed_vector &operator = (const vector_expression<AE> &ae) { 1108 self_type temporary (ae); 1109 return assign_temporary (temporary); 1110 } 1111 1112 /// \brief Assign the result of a vector_expression to the fixed_vector 1113 /// Assign the result of a vector_expression to the vector. This is lazy-compiled and will be optimized out by the compiler on any type of expression. 1114 /// \tparam AE is the type of the vector_expression 1115 /// \param ae is a const reference to the vector_expression 1116 /// \return a reference to the resulting fixed_vector 1117 template<class AE> 1118 BOOST_UBLAS_INLINE assign(const vector_expression<AE> & ae)1119 fixed_vector &assign (const vector_expression<AE> &ae) { 1120 vector_assign<scalar_assign> (*this, ae); 1121 return *this; 1122 } 1123 1124 // ------------------- 1125 // Computed assignment 1126 // ------------------- 1127 1128 /// \brief Assign the sum of the fixed_vector and a vector_expression to the fixed_vector 1129 /// Assign the sum of the fixed_vector and a vector_expression to the fixed_vector. This is lazy-compiled and will be optimized out by the compiler on any type of expression. 1130 /// A temporary is created for the computations. 1131 /// \tparam AE is the type of the vector_expression 1132 /// \param ae is a const reference to the vector_expression 1133 /// \return a reference to the resulting fixed_vector 1134 template<class AE> 1135 BOOST_UBLAS_INLINE operator +=(const vector_expression<AE> & ae)1136 fixed_vector &operator += (const vector_expression<AE> &ae) { 1137 self_type temporary (*this + ae); 1138 return assign_temporary (temporary); 1139 } 1140 1141 /// \brief Assign the sum of the fixed_vector and a vector_expression to the fixed_vector 1142 /// Assign the sum of the fixed_vector and a vector_expression to the fixed_vector. This is lazy-compiled and will be optimized out by the compiler on any type of expression. 1143 /// No temporary is created. Computations are done and stored directly into the resulting vector. 1144 /// \tparam AE is the type of the vector_expression 1145 /// \param ae is a const reference to the vector_expression 1146 /// \return a reference to the resulting vector 1147 template<class C> // Container assignment without temporary 1148 BOOST_UBLAS_INLINE operator +=(const vector_container<C> & v)1149 fixed_vector &operator += (const vector_container<C> &v) { 1150 plus_assign (v); 1151 return *this; 1152 } 1153 1154 /// \brief Assign the sum of the fixed_vector and a vector_expression to the fixed_vector 1155 /// Assign the sum of the fixed_vector and a vector_expression to the fixed_vector. This is lazy-compiled and will be optimized out by the compiler on any type of expression. 1156 /// No temporary is created. Computations are done and stored directly into the resulting fixed_vector. 1157 /// \tparam AE is the type of the vector_expression 1158 /// \param ae is a const reference to the vector_expression 1159 /// \return a reference to the resulting vector 1160 template<class AE> 1161 BOOST_UBLAS_INLINE plus_assign(const vector_expression<AE> & ae)1162 fixed_vector &plus_assign (const vector_expression<AE> &ae) { 1163 vector_assign<scalar_plus_assign> (*this, ae); 1164 return *this; 1165 } 1166 1167 /// \brief Assign the difference of the fixed_vector and a vector_expression to the fixed_vector 1168 /// Assign the difference of the fixed_vector and a vector_expression to the fixed_vector. This is lazy-compiled and will be optimized out by the compiler on any type of expression. 1169 /// A temporary is created for the computations. 1170 /// \tparam AE is the type of the vector_expression 1171 /// \param ae is a const reference to the vector_expression 1172 template<class AE> 1173 BOOST_UBLAS_INLINE operator -=(const vector_expression<AE> & ae)1174 fixed_vector &operator -= (const vector_expression<AE> &ae) { 1175 self_type temporary (*this - ae); 1176 return assign_temporary (temporary); 1177 } 1178 1179 /// \brief Assign the difference of the fixed_vector and a vector_expression to the fixed_vector 1180 /// Assign the difference of the fixed_vector and a vector_expression to the fixed_vector. This is lazy-compiled and will be optimized out by the compiler on any type of expression. 1181 /// No temporary is created. Computations are done and stored directly into the resulting fixed_vector. 1182 /// \tparam AE is the type of the vector_expression 1183 /// \param ae is a const reference to the vector_expression 1184 /// \return a reference to the resulting vector 1185 template<class C> // Container assignment without temporary 1186 BOOST_UBLAS_INLINE operator -=(const vector_container<C> & v)1187 fixed_vector &operator -= (const vector_container<C> &v) { 1188 minus_assign (v); 1189 return *this; 1190 } 1191 1192 /// \brief Assign the difference of the fixed_vector and a vector_expression to the fixed_vector 1193 /// Assign the difference of the fixed_vector and a vector_expression to the fixed_vector. This is lazy-compiled and will be optimized out by the compiler on any type of expression. 1194 /// No temporary is created. Computations are done and stored directly into the resulting fixed_vector. 1195 /// \tparam AE is the type of the vector_expression 1196 /// \param ae is a const reference to the vector_expression 1197 /// \return a reference to the resulting fixed_vector 1198 template<class AE> 1199 BOOST_UBLAS_INLINE minus_assign(const vector_expression<AE> & ae)1200 fixed_vector &minus_assign (const vector_expression<AE> &ae) { 1201 vector_assign<scalar_minus_assign> (*this, ae); 1202 return *this; 1203 } 1204 1205 /// \brief Assign the product of the fixed_vector and a scalar to the fixed_vector 1206 /// Assign the product of the fixed_vector and a scalar to the fixed_vector. This is lazy-compiled and will be optimized out by the compiler on any type of expression. 1207 /// No temporary is created. Computations are done and stored directly into the resulting fixed_vector. 1208 /// \tparam AE is the type of the vector_expression 1209 /// \param at is a const reference to the scalar 1210 /// \return a reference to the resulting fixed_vector 1211 template<class AT> 1212 BOOST_UBLAS_INLINE operator *=(const AT & at)1213 fixed_vector &operator *= (const AT &at) { 1214 vector_assign_scalar<scalar_multiplies_assign> (*this, at); 1215 return *this; 1216 } 1217 1218 /// \brief Assign the division of the fixed_vector by a scalar to the fixed_vector 1219 /// Assign the division of the fixed_vector by a scalar to the vector. This is lazy-compiled and will be optimized out by the compiler on any type of expression. 1220 /// No temporary is created. Computations are done and stored directly into the resulting vector. 1221 /// \tparam AE is the type of the vector_expression 1222 /// \param at is a const reference to the scalar 1223 /// \return a reference to the resulting fixed_vector 1224 template<class AT> 1225 BOOST_UBLAS_INLINE operator /=(const AT & at)1226 fixed_vector &operator /= (const AT &at) { 1227 vector_assign_scalar<scalar_divides_assign> (*this, at); 1228 return *this; 1229 } 1230 1231 // -------- 1232 // Swapping 1233 // -------- 1234 1235 /// \brief Swap the content of the fixed_vector with another vector 1236 /// \param v is the fixed_vector to be swapped with 1237 BOOST_UBLAS_INLINE swap(fixed_vector & v)1238 void swap (fixed_vector &v) { 1239 if (this != &v) { 1240 data ().swap (v.data ()); 1241 } 1242 } 1243 1244 /// \brief Swap the content of two fixed_vectors 1245 /// \param v1 is the first fixed_vector. It takes values from v2 1246 /// \param v2 is the second fixed_vector It takes values from v1 1247 BOOST_UBLAS_INLINE swap(fixed_vector & v1,fixed_vector & v2)1248 friend void swap (fixed_vector &v1, fixed_vector &v2) { 1249 v1.swap (v2); 1250 } 1251 1252 // Iterator types 1253 private: 1254 // Use the storage array iterator 1255 typedef typename A::const_iterator const_subiterator_type; 1256 typedef typename A::iterator subiterator_type; 1257 1258 public: 1259 #ifdef BOOST_UBLAS_USE_INDEXED_ITERATOR 1260 typedef indexed_iterator<self_type, dense_random_access_iterator_tag> iterator; 1261 typedef indexed_const_iterator<self_type, dense_random_access_iterator_tag> const_iterator; 1262 #else 1263 class const_iterator; 1264 class iterator; 1265 #endif 1266 1267 // -------------- 1268 // Element lookup 1269 // -------------- 1270 1271 /// \brief Return a const iterator to the element \e i 1272 /// \param i index of the element 1273 BOOST_UBLAS_INLINE find(size_type i) const1274 const_iterator find (size_type i) const { 1275 #ifndef BOOST_UBLAS_USE_INDEXED_ITERATOR 1276 return const_iterator (*this, data ().begin () + i); 1277 #else 1278 return const_iterator (*this, i); 1279 #endif 1280 } 1281 1282 /// \brief Return an iterator to the element \e i 1283 /// \param i index of the element 1284 BOOST_UBLAS_INLINE find(size_type i)1285 iterator find (size_type i) { 1286 #ifndef BOOST_UBLAS_USE_INDEXED_ITERATOR 1287 return iterator (*this, data ().begin () + i); 1288 #else 1289 return iterator (*this, i); 1290 #endif 1291 } 1292 1293 #ifndef BOOST_UBLAS_USE_INDEXED_ITERATOR 1294 class const_iterator: 1295 public container_const_reference<fixed_vector>, 1296 public random_access_iterator_base<dense_random_access_iterator_tag, 1297 const_iterator, value_type, difference_type> { 1298 public: 1299 typedef typename fixed_vector::difference_type difference_type; 1300 typedef typename fixed_vector::value_type value_type; 1301 typedef typename fixed_vector::const_reference reference; 1302 typedef const typename fixed_vector::pointer pointer; 1303 1304 // ---------------------------- 1305 // Construction and destruction 1306 // ---------------------------- 1307 1308 1309 BOOST_UBLAS_INLINE const_iterator()1310 const_iterator (): 1311 container_const_reference<self_type> (), it_ () {} 1312 BOOST_UBLAS_INLINE const_iterator(const self_type & v,const const_subiterator_type & it)1313 const_iterator (const self_type &v, const const_subiterator_type &it): 1314 container_const_reference<self_type> (v), it_ (it) {} 1315 BOOST_UBLAS_INLINE const_iterator(const typename self_type::iterator & it)1316 const_iterator (const typename self_type::iterator &it): // ISSUE vector:: stops VC8 using std::iterator here 1317 container_const_reference<self_type> (it ()), it_ (it.it_) {} 1318 1319 // ---------- 1320 // Arithmetic 1321 // ---------- 1322 1323 /// \brief Increment by 1 the position of the iterator 1324 /// \return a reference to the const iterator 1325 BOOST_UBLAS_INLINE operator ++()1326 const_iterator &operator ++ () { 1327 ++ it_; 1328 return *this; 1329 } 1330 1331 /// \brief Decrement by 1 the position of the iterator 1332 /// \return a reference to the const iterator 1333 BOOST_UBLAS_INLINE operator --()1334 const_iterator &operator -- () { 1335 -- it_; 1336 return *this; 1337 } 1338 1339 /// \brief Increment by \e n the position of the iterator 1340 /// \return a reference to the const iterator 1341 BOOST_UBLAS_INLINE operator +=(difference_type n)1342 const_iterator &operator += (difference_type n) { 1343 it_ += n; 1344 return *this; 1345 } 1346 1347 /// \brief Decrement by \e n the position of the iterator 1348 /// \return a reference to the const iterator 1349 BOOST_UBLAS_INLINE operator -=(difference_type n)1350 const_iterator &operator -= (difference_type n) { 1351 it_ -= n; 1352 return *this; 1353 } 1354 1355 /// \brief Return the different in number of positions between 2 iterators 1356 BOOST_UBLAS_INLINE operator -(const const_iterator & it) const1357 difference_type operator - (const const_iterator &it) const { 1358 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ()); 1359 return it_ - it.it_; 1360 } 1361 1362 /// \brief Dereference an iterator 1363 /// Dereference an iterator: a bounds' check is done before returning the value. A bad_index() expection is returned if out of bounds. 1364 /// \return a const reference to the value pointed by the iterator 1365 BOOST_UBLAS_INLINE operator *() const1366 const_reference operator * () const { 1367 BOOST_UBLAS_CHECK (it_ >= (*this) ().begin ().it_ && it_ < (*this) ().end ().it_, bad_index ()); 1368 return *it_; 1369 } 1370 1371 /// \brief Dereference an iterator at the n-th forward value 1372 /// Dereference an iterator at the n-th forward value, that is the value pointed by iterator+n. 1373 /// A bounds' check is done before returning the value. A bad_index() expection is returned if out of bounds. 1374 /// \return a const reference 1375 BOOST_UBLAS_INLINE operator [](difference_type n) const1376 const_reference operator [] (difference_type n) const { 1377 return *(it_ + n); 1378 } 1379 1380 // Index 1381 /// \brief return the index of the element referenced by the iterator 1382 BOOST_UBLAS_INLINE index() const1383 size_type index () const { 1384 BOOST_UBLAS_CHECK (it_ >= (*this) ().begin ().it_ && it_ < (*this) ().end ().it_, bad_index ()); 1385 return it_ - (*this) ().begin ().it_; 1386 } 1387 1388 // Assignment 1389 BOOST_UBLAS_INLINE 1390 /// \brief assign the value of an iterator to the iterator operator =(const const_iterator & it)1391 const_iterator &operator = (const const_iterator &it) { 1392 container_const_reference<self_type>::assign (&it ()); 1393 it_ = it.it_; 1394 return *this; 1395 } 1396 1397 // Comparison 1398 /// \brief compare the value of two itetarors 1399 /// \return true if they reference the same element 1400 BOOST_UBLAS_INLINE operator ==(const const_iterator & it) const1401 bool operator == (const const_iterator &it) const { 1402 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ()); 1403 return it_ == it.it_; 1404 } 1405 1406 1407 /// \brief compare the value of two iterators 1408 /// \return return true if the left-hand-side iterator refers to a value placed before the right-hand-side iterator 1409 BOOST_UBLAS_INLINE operator <(const const_iterator & it) const1410 bool operator < (const const_iterator &it) const { 1411 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ()); 1412 return it_ < it.it_; 1413 } 1414 1415 private: 1416 const_subiterator_type it_; 1417 1418 friend class iterator; 1419 }; 1420 #endif 1421 1422 /// \brief return an iterator on the first element of the fixed_vector 1423 BOOST_UBLAS_INLINE begin() const1424 const_iterator begin () const { 1425 return find (0); 1426 } 1427 1428 /// \brief return an iterator on the first element of the fixed_vector 1429 BOOST_UBLAS_INLINE cbegin() const1430 const_iterator cbegin () const { 1431 return begin (); 1432 } 1433 1434 /// \brief return an iterator after the last element of the fixed_vector 1435 BOOST_UBLAS_INLINE end() const1436 const_iterator end () const { 1437 return find (data_.size ()); 1438 } 1439 1440 /// \brief return an iterator after the last element of the fixed_vector 1441 BOOST_UBLAS_INLINE cend() const1442 const_iterator cend () const { 1443 return end (); 1444 } 1445 1446 #ifndef BOOST_UBLAS_USE_INDEXED_ITERATOR 1447 class iterator: 1448 public container_reference<fixed_vector>, 1449 public random_access_iterator_base<dense_random_access_iterator_tag, 1450 iterator, value_type, difference_type> { 1451 public: 1452 typedef typename fixed_vector::difference_type difference_type; 1453 typedef typename fixed_vector::value_type value_type; 1454 typedef typename fixed_vector::reference reference; 1455 typedef typename fixed_vector::pointer pointer; 1456 1457 1458 // Construction and destruction 1459 BOOST_UBLAS_INLINE iterator()1460 iterator (): 1461 container_reference<self_type> (), it_ () {} 1462 BOOST_UBLAS_INLINE iterator(self_type & v,const subiterator_type & it)1463 iterator (self_type &v, const subiterator_type &it): 1464 container_reference<self_type> (v), it_ (it) {} 1465 1466 // Arithmetic 1467 BOOST_UBLAS_INLINE operator ++()1468 iterator &operator ++ () { 1469 ++ it_; 1470 return *this; 1471 } 1472 BOOST_UBLAS_INLINE operator --()1473 iterator &operator -- () { 1474 -- it_; 1475 return *this; 1476 } 1477 BOOST_UBLAS_INLINE operator +=(difference_type n)1478 iterator &operator += (difference_type n) { 1479 it_ += n; 1480 return *this; 1481 } 1482 BOOST_UBLAS_INLINE operator -=(difference_type n)1483 iterator &operator -= (difference_type n) { 1484 it_ -= n; 1485 return *this; 1486 } 1487 BOOST_UBLAS_INLINE operator -(const iterator & it) const1488 difference_type operator - (const iterator &it) const { 1489 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ()); 1490 return it_ - it.it_; 1491 } 1492 1493 // Dereference 1494 BOOST_UBLAS_INLINE operator *() const1495 reference operator * () const { 1496 BOOST_UBLAS_CHECK (it_ >= (*this) ().begin ().it_ && it_ < (*this) ().end ().it_ , bad_index ()); 1497 return *it_; 1498 } 1499 BOOST_UBLAS_INLINE operator [](difference_type n) const1500 reference operator [] (difference_type n) const { 1501 return *(it_ + n); 1502 } 1503 1504 // Index 1505 BOOST_UBLAS_INLINE index() const1506 size_type index () const { 1507 BOOST_UBLAS_CHECK (it_ >= (*this) ().begin ().it_ && it_ < (*this) ().end ().it_ , bad_index ()); 1508 return it_ - (*this) ().begin ().it_; 1509 } 1510 1511 // Assignment 1512 BOOST_UBLAS_INLINE operator =(const iterator & it)1513 iterator &operator = (const iterator &it) { 1514 container_reference<self_type>::assign (&it ()); 1515 it_ = it.it_; 1516 return *this; 1517 } 1518 1519 // Comparison 1520 BOOST_UBLAS_INLINE operator ==(const iterator & it) const1521 bool operator == (const iterator &it) const { 1522 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ()); 1523 return it_ == it.it_; 1524 } 1525 BOOST_UBLAS_INLINE operator <(const iterator & it) const1526 bool operator < (const iterator &it) const { 1527 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ()); 1528 return it_ < it.it_; 1529 } 1530 1531 private: 1532 subiterator_type it_; 1533 1534 friend class const_iterator; 1535 }; 1536 #endif 1537 1538 /// \brief Return an iterator on the first element of the fixed_vector 1539 BOOST_UBLAS_INLINE begin()1540 iterator begin () { 1541 return find (0); 1542 } 1543 1544 /// \brief Return an iterator at the end of the fixed_vector 1545 BOOST_UBLAS_INLINE end()1546 iterator end () { 1547 return find (data_.size ()); 1548 } 1549 1550 // Reverse iterator 1551 typedef reverse_iterator_base<const_iterator> const_reverse_iterator; 1552 typedef reverse_iterator_base<iterator> reverse_iterator; 1553 1554 /// \brief Return a const reverse iterator before the first element of the reversed fixed_vector (i.e. end() of normal fixed_vector) 1555 BOOST_UBLAS_INLINE rbegin() const1556 const_reverse_iterator rbegin () const { 1557 return const_reverse_iterator (end ()); 1558 } 1559 1560 /// \brief Return a const reverse iterator before the first element of the reversed fixed_vector (i.e. end() of normal fixed_vector) 1561 BOOST_UBLAS_INLINE crbegin() const1562 const_reverse_iterator crbegin () const { 1563 return rbegin (); 1564 } 1565 1566 /// \brief Return a const reverse iterator on the end of the reverse fixed_vector (i.e. first element of the normal fixed_vector) 1567 BOOST_UBLAS_INLINE rend() const1568 const_reverse_iterator rend () const { 1569 return const_reverse_iterator (begin ()); 1570 } 1571 1572 /// \brief Return a const reverse iterator on the end of the reverse fixed_vector (i.e. first element of the normal fixed_vector) 1573 BOOST_UBLAS_INLINE crend() const1574 const_reverse_iterator crend () const { 1575 return rend (); 1576 } 1577 1578 /// \brief Return a const reverse iterator before the first element of the reversed fixed_vector (i.e. end() of normal fixed_vector) 1579 BOOST_UBLAS_INLINE rbegin()1580 reverse_iterator rbegin () { 1581 return reverse_iterator (end ()); 1582 } 1583 1584 /// \brief Return a const reverse iterator on the end of the reverse fixed_vector (i.e. first element of the normal fixed_vector) 1585 BOOST_UBLAS_INLINE rend()1586 reverse_iterator rend () { 1587 return reverse_iterator (begin ()); 1588 } 1589 1590 // ------------- 1591 // Serialization 1592 // ------------- 1593 1594 /// Serialize a fixed_vector into and archive as defined in Boost 1595 /// \param ar Archive object. Can be a flat file, an XML file or any other stream 1596 /// \param file_version Optional file version (not yet used) 1597 template<class Archive> serialize(Archive & ar,const unsigned int)1598 void serialize(Archive & ar, const unsigned int /* file_version */){ 1599 ar & serialization::make_nvp("data",data_); 1600 } 1601 1602 private: 1603 array_type data_; 1604 }; 1605 1606 #endif // BOOST_UBLAS_CPP_GE_2011 1607 1608 // -------------------- 1609 // Bounded vector class 1610 // -------------------- 1611 1612 /// \brief a dense vector of values of type \c T, of variable size but with maximum \f$N\f$. 1613 /// A dense vector of values of type \c T, of variable size but with maximum \f$N\f$. The default constructor 1614 /// creates the vector with size \f$N\f$. Elements are constructed by the storage type \c bounded_array, which \b need \b not \b initialise their value. 1615 template<class T, std::size_t N> 1616 class bounded_vector: 1617 public vector<T, bounded_array<T, N> > { 1618 1619 typedef vector<T, bounded_array<T, N> > vector_type; 1620 public: 1621 typedef typename vector_type::size_type size_type; 1622 static const size_type max_size = N; 1623 1624 // Construction and destruction 1625 BOOST_UBLAS_INLINE bounded_vector()1626 bounded_vector (): 1627 vector_type (N) {} 1628 BOOST_UBLAS_INLINE bounded_vector(size_type size)1629 bounded_vector (size_type size): 1630 vector_type (size) {} 1631 BOOST_UBLAS_INLINE bounded_vector(const bounded_vector & v)1632 bounded_vector (const bounded_vector &v): 1633 vector_type (v) {} 1634 template<class A2> // Allow vector<T,bounded_array<N> construction 1635 BOOST_UBLAS_INLINE bounded_vector(const vector<T,A2> & v)1636 bounded_vector (const vector<T, A2> &v): 1637 vector_type (v) {} 1638 template<class AE> 1639 BOOST_UBLAS_INLINE bounded_vector(const vector_expression<AE> & ae)1640 bounded_vector (const vector_expression<AE> &ae): 1641 vector_type (ae) {} 1642 BOOST_UBLAS_INLINE ~bounded_vector()1643 ~bounded_vector () {} 1644 1645 // Assignment 1646 #ifdef BOOST_UBLAS_MOVE_SEMANTICS 1647 1648 /*! @note "pass by value" the key idea to enable move semantics */ 1649 BOOST_UBLAS_INLINE operator =(bounded_vector v)1650 bounded_vector &operator = (bounded_vector v) { 1651 vector_type::operator = (v); 1652 return *this; 1653 } 1654 #else 1655 BOOST_UBLAS_INLINE operator =(const bounded_vector & v)1656 bounded_vector &operator = (const bounded_vector &v) { 1657 vector_type::operator = (v); 1658 return *this; 1659 } 1660 #endif 1661 template<class A2> // Generic vector assignment 1662 BOOST_UBLAS_INLINE operator =(const vector<T,A2> & v)1663 bounded_vector &operator = (const vector<T, A2> &v) { 1664 vector_type::operator = (v); 1665 return *this; 1666 } 1667 template<class C> // Container assignment without temporary 1668 BOOST_UBLAS_INLINE operator =(const vector_container<C> & v)1669 bounded_vector &operator = (const vector_container<C> &v) { 1670 vector_type::operator = (v); 1671 return *this; 1672 } 1673 template<class AE> 1674 BOOST_UBLAS_INLINE operator =(const vector_expression<AE> & ae)1675 bounded_vector &operator = (const vector_expression<AE> &ae) { 1676 vector_type::operator = (ae); 1677 return *this; 1678 } 1679 }; 1680 1681 1682 1683 // ----------------- 1684 // Zero vector class 1685 // ----------------- 1686 1687 /// \brief A zero vector of type \c T and a given \c size 1688 /// A zero vector of type \c T and a given \c size. This is a virtual vector in the sense that no memory is allocated 1689 /// for storing the zero values: it still acts like any other vector. However assigning values to it will not change the zero 1690 /// vector into a normal vector. It must first be assigned to another normal vector by any suitable means. Its memory footprint is constant. 1691 template<class T, class ALLOC> 1692 class zero_vector: 1693 public vector_container<zero_vector<T, ALLOC> > { 1694 1695 typedef const T *const_pointer; 1696 typedef zero_vector<T, ALLOC> self_type; 1697 public: 1698 #ifdef BOOST_UBLAS_ENABLE_PROXY_SHORTCUTS 1699 using vector_container<self_type>::operator (); 1700 #endif 1701 typedef typename ALLOC::size_type size_type; 1702 typedef typename ALLOC::difference_type difference_type; 1703 typedef T value_type; 1704 typedef const T &const_reference; 1705 typedef T &reference; 1706 typedef const vector_reference<const self_type> const_closure_type; 1707 typedef vector_reference<self_type> closure_type; 1708 typedef sparse_tag storage_category; 1709 1710 // Construction and destruction 1711 BOOST_UBLAS_INLINE zero_vector()1712 zero_vector (): 1713 vector_container<self_type> (), 1714 size_ (0) {} 1715 explicit BOOST_UBLAS_INLINE zero_vector(size_type size)1716 zero_vector (size_type size): 1717 vector_container<self_type> (), 1718 size_ (size) {} 1719 BOOST_UBLAS_INLINE zero_vector(const zero_vector & v)1720 zero_vector (const zero_vector &v): 1721 vector_container<self_type> (), 1722 size_ (v.size_) {} 1723 1724 // Accessors 1725 BOOST_UBLAS_INLINE size() const1726 size_type size () const { 1727 return size_; 1728 } 1729 1730 // Resizing 1731 BOOST_UBLAS_INLINE resize(size_type size,bool=true)1732 void resize (size_type size, bool /*preserve*/ = true) { 1733 size_ = size; 1734 } 1735 1736 // Element support 1737 BOOST_UBLAS_INLINE find_element(size_type) const1738 const_pointer find_element (size_type /*i*/) const { 1739 return & zero_; 1740 } 1741 1742 // Element access 1743 BOOST_UBLAS_INLINE operator ()(size_type) const1744 const_reference operator () (size_type /* i */) const { 1745 return zero_; 1746 } 1747 1748 BOOST_UBLAS_INLINE operator [](size_type i) const1749 const_reference operator [] (size_type i) const { 1750 return (*this) (i); 1751 } 1752 1753 // Assignment 1754 BOOST_UBLAS_INLINE operator =(const zero_vector & v)1755 zero_vector &operator = (const zero_vector &v) { 1756 size_ = v.size_; 1757 return *this; 1758 } 1759 BOOST_UBLAS_INLINE assign_temporary(zero_vector & v)1760 zero_vector &assign_temporary (zero_vector &v) { 1761 swap (v); 1762 return *this; 1763 } 1764 1765 // Swapping 1766 BOOST_UBLAS_INLINE swap(zero_vector & v)1767 void swap (zero_vector &v) { 1768 if (this != &v) { 1769 std::swap (size_, v.size_); 1770 } 1771 } 1772 BOOST_UBLAS_INLINE swap(zero_vector & v1,zero_vector & v2)1773 friend void swap (zero_vector &v1, zero_vector &v2) { 1774 v1.swap (v2); 1775 } 1776 1777 // Iterator types 1778 public: 1779 class const_iterator; 1780 1781 // Element lookup 1782 BOOST_UBLAS_INLINE find(size_type) const1783 const_iterator find (size_type /*i*/) const { 1784 return const_iterator (*this); 1785 } 1786 1787 class const_iterator: 1788 public container_const_reference<zero_vector>, 1789 public bidirectional_iterator_base<sparse_bidirectional_iterator_tag, 1790 const_iterator, value_type> { 1791 public: 1792 typedef typename zero_vector::difference_type difference_type; 1793 typedef typename zero_vector::value_type value_type; 1794 typedef typename zero_vector::const_reference reference; 1795 typedef typename zero_vector::const_pointer pointer; 1796 1797 // Construction and destruction 1798 BOOST_UBLAS_INLINE const_iterator()1799 const_iterator (): 1800 container_const_reference<self_type> () {} 1801 BOOST_UBLAS_INLINE const_iterator(const self_type & v)1802 const_iterator (const self_type &v): 1803 container_const_reference<self_type> (v) {} 1804 1805 // Arithmetic 1806 BOOST_UBLAS_INLINE operator ++()1807 const_iterator &operator ++ () { 1808 BOOST_UBLAS_CHECK_FALSE (bad_index ()); 1809 return *this; 1810 } 1811 BOOST_UBLAS_INLINE operator --()1812 const_iterator &operator -- () { 1813 BOOST_UBLAS_CHECK_FALSE (bad_index ()); 1814 return *this; 1815 } 1816 1817 // Dereference 1818 BOOST_UBLAS_INLINE operator *() const1819 const_reference operator * () const { 1820 BOOST_UBLAS_CHECK_FALSE (bad_index ()); 1821 return zero_; // arbitary return value 1822 } 1823 1824 // Index 1825 BOOST_UBLAS_INLINE index() const1826 size_type index () const { 1827 BOOST_UBLAS_CHECK_FALSE (bad_index ()); 1828 return 0; // arbitary return value 1829 } 1830 1831 // Assignment 1832 BOOST_UBLAS_INLINE operator =(const const_iterator & it)1833 const_iterator &operator = (const const_iterator &it) { 1834 container_const_reference<self_type>::assign (&it ()); 1835 return *this; 1836 } 1837 1838 // Comparison 1839 BOOST_UBLAS_INLINE operator ==(const const_iterator & it) const1840 bool operator == (const const_iterator &it) const { 1841 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ()); 1842 detail::ignore_unused_variable_warning(it); 1843 return true; 1844 } 1845 }; 1846 1847 typedef const_iterator iterator; 1848 1849 BOOST_UBLAS_INLINE begin() const1850 const_iterator begin () const { 1851 return const_iterator (*this); 1852 } 1853 BOOST_UBLAS_INLINE cbegin() const1854 const_iterator cbegin () const { 1855 return begin (); 1856 } 1857 BOOST_UBLAS_INLINE end() const1858 const_iterator end () const { 1859 return const_iterator (*this); 1860 } 1861 BOOST_UBLAS_INLINE cend() const1862 const_iterator cend () const { 1863 return end (); 1864 } 1865 1866 // Reverse iterator 1867 typedef reverse_iterator_base<const_iterator> const_reverse_iterator; 1868 1869 BOOST_UBLAS_INLINE rbegin() const1870 const_reverse_iterator rbegin () const { 1871 return const_reverse_iterator (end ()); 1872 } 1873 BOOST_UBLAS_INLINE crbegin() const1874 const_reverse_iterator crbegin () const { 1875 return rbegin (); 1876 } 1877 BOOST_UBLAS_INLINE rend() const1878 const_reverse_iterator rend () const { 1879 return const_reverse_iterator (begin ()); 1880 } 1881 BOOST_UBLAS_INLINE crend() const1882 const_reverse_iterator crend () const { 1883 return rend (); 1884 } 1885 1886 // Serialization 1887 template<class Archive> serialize(Archive & ar,const unsigned int)1888 void serialize(Archive & ar, const unsigned int /* file_version */){ 1889 serialization::collection_size_type s (size_); 1890 ar & serialization::make_nvp("size",s); 1891 if (Archive::is_loading::value) { 1892 size_ = s; 1893 } 1894 } 1895 1896 private: 1897 size_type size_; 1898 typedef const value_type const_value_type; 1899 static const_value_type zero_; 1900 }; 1901 1902 template<class T, class ALLOC> 1903 typename zero_vector<T, ALLOC>::const_value_type zero_vector<T, ALLOC>::zero_ = T(/*zero*/); 1904 1905 1906 // Unit vector class 1907 /// \brief unit_vector represents a canonical unit vector 1908 /// unit_vector represents a canonical unit vector. The \e k-th unit vector of dimension \f$n\f$ holds 0 for every value \f$u_i\f$ s.t. \f$i \neq k\f$ and 1 when \f$i=k\f$. 1909 /// At construction, the value \e k is given after the dimension of the vector. 1910 /// \tparam T is the type of elements in the vector. They must be 0 and 1 assignable in order for the vector to have its unit-vector semantic. 1911 /// \tparam ALLOC a specific allocator can be specified if needed. Most of the time this parameter is omited. 1912 template<class T, class ALLOC> 1913 class unit_vector: 1914 public vector_container<unit_vector<T, ALLOC> > { 1915 1916 typedef const T *const_pointer; 1917 typedef unit_vector<T, ALLOC> self_type; 1918 public: 1919 #ifdef BOOST_UBLAS_ENABLE_PROXY_SHORTCUTS 1920 using vector_container<self_type>::operator (); 1921 #endif 1922 typedef typename ALLOC::size_type size_type; 1923 typedef typename ALLOC::difference_type difference_type; 1924 typedef T value_type; 1925 typedef const T &const_reference; 1926 typedef T &reference; 1927 typedef const vector_reference<const self_type> const_closure_type; 1928 typedef vector_reference<self_type> closure_type; 1929 typedef sparse_tag storage_category; 1930 1931 // Construction and destruction 1932 /// \brief Simple constructor with dimension and index 0 1933 BOOST_UBLAS_INLINE unit_vector()1934 unit_vector (): 1935 vector_container<self_type> (), 1936 size_ (0), index_ (0) {} 1937 1938 /// \brief Constructor of unit_vector 1939 /// \param size is the dimension of the vector 1940 /// \param index is the order of the vector 1941 BOOST_UBLAS_INLINE unit_vector(size_type size,size_type index=0)1942 explicit unit_vector (size_type size, size_type index = 0): 1943 vector_container<self_type> (), 1944 size_ (size), index_ (index) {} 1945 1946 /// \brief Copy-constructor 1947 BOOST_UBLAS_INLINE unit_vector(const unit_vector & v)1948 unit_vector (const unit_vector &v): 1949 vector_container<self_type> (), 1950 size_ (v.size_), index_ (v.index_) {} 1951 1952 // Accessors 1953 //---------- 1954 1955 /// \brief Return the size (dimension) of the vector 1956 BOOST_UBLAS_INLINE size() const1957 size_type size () const { 1958 return size_; 1959 } 1960 1961 /// \brief Return the order of the unit vector 1962 BOOST_UBLAS_INLINE index() const1963 size_type index () const { 1964 return index_; 1965 } 1966 1967 // Resizing 1968 // -------- 1969 1970 /// \brief Resize the vector. The values are preserved by default (i.e. the index does not change) 1971 /// \param size is the new size of the vector 1972 BOOST_UBLAS_INLINE resize(size_type size,bool=true)1973 void resize (size_type size, bool /*preserve*/ = true) { 1974 size_ = size; 1975 } 1976 1977 // Element support 1978 // --------------- 1979 1980 /// \brief Return a const pointer to the element of index i 1981 BOOST_UBLAS_INLINE find_element(size_type i) const1982 const_pointer find_element (size_type i) const { 1983 if (i == index_) 1984 return & one_; 1985 else 1986 return & zero_; 1987 } 1988 1989 // Element access 1990 BOOST_UBLAS_INLINE operator ()(size_type i) const1991 const_reference operator () (size_type i) const { 1992 if (i == index_) 1993 return one_; 1994 else 1995 return zero_; 1996 } 1997 1998 BOOST_UBLAS_INLINE operator [](size_type i) const1999 const_reference operator [] (size_type i) const { 2000 return (*this) (i); 2001 } 2002 2003 // Assignment 2004 BOOST_UBLAS_INLINE operator =(const unit_vector & v)2005 unit_vector &operator = (const unit_vector &v) { 2006 size_ = v.size_; 2007 index_ = v.index_; 2008 return *this; 2009 } 2010 BOOST_UBLAS_INLINE assign_temporary(unit_vector & v)2011 unit_vector &assign_temporary (unit_vector &v) { 2012 swap (v); 2013 return *this; 2014 } 2015 2016 // Swapping 2017 BOOST_UBLAS_INLINE swap(unit_vector & v)2018 void swap (unit_vector &v) { 2019 if (this != &v) { 2020 std::swap (size_, v.size_); 2021 std::swap (index_, v.index_); 2022 } 2023 } 2024 BOOST_UBLAS_INLINE swap(unit_vector & v1,unit_vector & v2)2025 friend void swap (unit_vector &v1, unit_vector &v2) { 2026 v1.swap (v2); 2027 } 2028 2029 // Iterator types 2030 private: 2031 // Use bool to indicate begin (one_ as value) 2032 typedef bool const_subiterator_type; 2033 public: 2034 class const_iterator; 2035 2036 // Element lookup 2037 BOOST_UBLAS_INLINE find(size_type i) const2038 const_iterator find (size_type i) const { 2039 return const_iterator (*this, i <= index_); 2040 } 2041 2042 class const_iterator: 2043 public container_const_reference<unit_vector>, 2044 public bidirectional_iterator_base<sparse_bidirectional_iterator_tag, 2045 const_iterator, value_type> { 2046 public: 2047 typedef typename unit_vector::difference_type difference_type; 2048 typedef typename unit_vector::value_type value_type; 2049 typedef typename unit_vector::const_reference reference; 2050 typedef typename unit_vector::const_pointer pointer; 2051 2052 // Construction and destruction 2053 BOOST_UBLAS_INLINE const_iterator()2054 const_iterator (): 2055 container_const_reference<unit_vector> (), it_ () {} 2056 BOOST_UBLAS_INLINE const_iterator(const unit_vector & v,const const_subiterator_type & it)2057 const_iterator (const unit_vector &v, const const_subiterator_type &it): 2058 container_const_reference<unit_vector> (v), it_ (it) {} 2059 2060 // Arithmetic 2061 BOOST_UBLAS_INLINE operator ++()2062 const_iterator &operator ++ () { 2063 BOOST_UBLAS_CHECK (it_, bad_index ()); 2064 it_ = !it_; 2065 return *this; 2066 } 2067 BOOST_UBLAS_INLINE operator --()2068 const_iterator &operator -- () { 2069 BOOST_UBLAS_CHECK (!it_, bad_index ()); 2070 it_ = !it_; 2071 return *this; 2072 } 2073 2074 // Dereference 2075 BOOST_UBLAS_INLINE operator *() const2076 const_reference operator * () const { 2077 BOOST_UBLAS_CHECK (it_, bad_index ()); 2078 return one_; 2079 } 2080 2081 // Index 2082 BOOST_UBLAS_INLINE index() const2083 size_type index () const { 2084 BOOST_UBLAS_CHECK (it_, bad_index ()); 2085 return (*this) ().index_; 2086 } 2087 2088 // Assignment 2089 BOOST_UBLAS_INLINE operator =(const const_iterator & it)2090 const_iterator &operator = (const const_iterator &it) { 2091 container_const_reference<unit_vector>::assign (&it ()); 2092 it_ = it.it_; 2093 return *this; 2094 } 2095 2096 // Comparison 2097 BOOST_UBLAS_INLINE operator ==(const const_iterator & it) const2098 bool operator == (const const_iterator &it) const { 2099 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ()); 2100 return it_ == it.it_; 2101 } 2102 2103 private: 2104 const_subiterator_type it_; 2105 }; 2106 2107 typedef const_iterator iterator; 2108 2109 BOOST_UBLAS_INLINE begin() const2110 const_iterator begin () const { 2111 return const_iterator (*this, true); 2112 } 2113 BOOST_UBLAS_INLINE cbegin() const2114 const_iterator cbegin () const { 2115 return begin (); 2116 } 2117 BOOST_UBLAS_INLINE end() const2118 const_iterator end () const { 2119 return const_iterator (*this, false); 2120 } 2121 BOOST_UBLAS_INLINE cend() const2122 const_iterator cend () const { 2123 return end (); 2124 } 2125 2126 // Reverse iterator 2127 typedef reverse_iterator_base<const_iterator> const_reverse_iterator; 2128 2129 BOOST_UBLAS_INLINE rbegin() const2130 const_reverse_iterator rbegin () const { 2131 return const_reverse_iterator (end ()); 2132 } 2133 BOOST_UBLAS_INLINE crbegin() const2134 const_reverse_iterator crbegin () const { 2135 return rbegin (); 2136 } 2137 BOOST_UBLAS_INLINE rend() const2138 const_reverse_iterator rend () const { 2139 return const_reverse_iterator (begin ()); 2140 } 2141 BOOST_UBLAS_INLINE crend() const2142 const_reverse_iterator crend () const { 2143 return rend (); 2144 } 2145 2146 // Serialization 2147 template<class Archive> serialize(Archive & ar,const unsigned int)2148 void serialize(Archive & ar, const unsigned int /* file_version */){ 2149 serialization::collection_size_type s (size_); 2150 ar & serialization::make_nvp("size",s); 2151 if (Archive::is_loading::value) { 2152 size_ = s; 2153 } 2154 ar & serialization::make_nvp("index", index_); 2155 } 2156 2157 private: 2158 size_type size_; 2159 size_type index_; 2160 typedef const value_type const_value_type; 2161 static const_value_type zero_; 2162 static const_value_type one_; 2163 }; 2164 2165 template<class T, class ALLOC> 2166 typename unit_vector<T, ALLOC>::const_value_type unit_vector<T, ALLOC>::zero_ = T(/*zero*/); 2167 template<class T, class ALLOC> 2168 typename unit_vector<T, ALLOC>::const_value_type unit_vector<T, ALLOC>::one_ (1); // ISSUE: need 'one'-traits here 2169 2170 /// \brief A scalar (i.e. unique value) vector of type \c T and a given \c size 2171 /// A scalar (i.e. unique value) vector of type \c T and a given \c size. This is a virtual vector in the sense that no memory is allocated 2172 /// for storing the unique value more than once: it still acts like any other vector. However assigning a new value will change all the value at once. 2173 /// vector into a normal vector. It must first be assigned to another normal vector by any suitable means. Its memory footprint is constant. 2174 /// \tparam T type of the objects stored in the vector: it can be anything even if most of the time, scalar types will be used like \c double or \c int. Complex types can be used, or even classes like boost::interval. 2175 template<class T, class ALLOC> 2176 class scalar_vector: 2177 public vector_container<scalar_vector<T, ALLOC> > { 2178 2179 typedef const T *const_pointer; 2180 typedef scalar_vector<T, ALLOC> self_type; 2181 public: 2182 #ifdef BOOST_UBLAS_ENABLE_PROXY_SHORTCUTS 2183 using vector_container<self_type>::operator (); 2184 #endif 2185 typedef typename ALLOC::size_type size_type; 2186 typedef typename ALLOC::difference_type difference_type; 2187 typedef T value_type; 2188 typedef const T &const_reference; 2189 typedef T &reference; 2190 typedef const vector_reference<const self_type> const_closure_type; 2191 typedef vector_reference<self_type> closure_type; 2192 typedef dense_tag storage_category; 2193 2194 // Construction and destruction 2195 BOOST_UBLAS_INLINE scalar_vector()2196 scalar_vector (): 2197 vector_container<self_type> (), 2198 size_ (0), value_ () {} 2199 BOOST_UBLAS_INLINE scalar_vector(size_type size,const value_type & value=value_type (1))2200 explicit scalar_vector (size_type size, const value_type &value = value_type(1)): 2201 vector_container<self_type> (), 2202 size_ (size), value_ (value) {} 2203 BOOST_UBLAS_INLINE scalar_vector(const scalar_vector & v)2204 scalar_vector (const scalar_vector &v): 2205 vector_container<self_type> (), 2206 size_ (v.size_), value_ (v.value_) {} 2207 2208 // Accessors 2209 BOOST_UBLAS_INLINE size() const2210 size_type size () const { 2211 return size_; 2212 } 2213 2214 // Resizing 2215 BOOST_UBLAS_INLINE resize(size_type size,bool=true)2216 void resize (size_type size, bool /*preserve*/ = true) { 2217 size_ = size; 2218 } 2219 2220 // Element support 2221 BOOST_UBLAS_INLINE find_element(size_type) const2222 const_pointer find_element (size_type /*i*/) const { 2223 return & value_; 2224 } 2225 2226 // Element access 2227 BOOST_UBLAS_INLINE operator ()(size_type) const2228 const_reference operator () (size_type /*i*/) const { 2229 return value_; 2230 } 2231 2232 BOOST_UBLAS_INLINE operator [](size_type) const2233 const_reference operator [] (size_type /*i*/) const { 2234 return value_; 2235 } 2236 2237 // Assignment 2238 BOOST_UBLAS_INLINE operator =(const scalar_vector & v)2239 scalar_vector &operator = (const scalar_vector &v) { 2240 size_ = v.size_; 2241 value_ = v.value_; 2242 return *this; 2243 } 2244 BOOST_UBLAS_INLINE assign_temporary(scalar_vector & v)2245 scalar_vector &assign_temporary (scalar_vector &v) { 2246 swap (v); 2247 return *this; 2248 } 2249 2250 // Swapping 2251 BOOST_UBLAS_INLINE swap(scalar_vector & v)2252 void swap (scalar_vector &v) { 2253 if (this != &v) { 2254 std::swap (size_, v.size_); 2255 std::swap (value_, v.value_); 2256 } 2257 } 2258 BOOST_UBLAS_INLINE swap(scalar_vector & v1,scalar_vector & v2)2259 friend void swap (scalar_vector &v1, scalar_vector &v2) { 2260 v1.swap (v2); 2261 } 2262 2263 // Iterator types 2264 private: 2265 // Use an index 2266 typedef size_type const_subiterator_type; 2267 2268 public: 2269 #ifdef BOOST_UBLAS_USE_INDEXED_ITERATOR 2270 typedef indexed_const_iterator<self_type, dense_random_access_iterator_tag> iterator; 2271 typedef indexed_const_iterator<self_type, dense_random_access_iterator_tag> const_iterator; 2272 #else 2273 class const_iterator; 2274 #endif 2275 2276 // Element lookup 2277 BOOST_UBLAS_INLINE find(size_type i) const2278 const_iterator find (size_type i) const { 2279 return const_iterator (*this, i); 2280 } 2281 2282 #ifndef BOOST_UBLAS_USE_INDEXED_ITERATOR 2283 class const_iterator: 2284 public container_const_reference<scalar_vector>, 2285 public random_access_iterator_base<dense_random_access_iterator_tag, 2286 const_iterator, value_type> { 2287 public: 2288 typedef typename scalar_vector::difference_type difference_type; 2289 typedef typename scalar_vector::value_type value_type; 2290 typedef typename scalar_vector::const_reference reference; 2291 typedef typename scalar_vector::const_pointer pointer; 2292 2293 // Construction and destruction 2294 BOOST_UBLAS_INLINE const_iterator()2295 const_iterator (): 2296 container_const_reference<scalar_vector> (), it_ () {} 2297 BOOST_UBLAS_INLINE const_iterator(const scalar_vector & v,const const_subiterator_type & it)2298 const_iterator (const scalar_vector &v, const const_subiterator_type &it): 2299 container_const_reference<scalar_vector> (v), it_ (it) {} 2300 2301 // Arithmetic 2302 BOOST_UBLAS_INLINE operator ++()2303 const_iterator &operator ++ () { 2304 ++ it_; 2305 return *this; 2306 } 2307 BOOST_UBLAS_INLINE operator --()2308 const_iterator &operator -- () { 2309 -- it_; 2310 return *this; 2311 } 2312 BOOST_UBLAS_INLINE operator +=(difference_type n)2313 const_iterator &operator += (difference_type n) { 2314 it_ += n; 2315 return *this; 2316 } 2317 BOOST_UBLAS_INLINE operator -=(difference_type n)2318 const_iterator &operator -= (difference_type n) { 2319 it_ -= n; 2320 return *this; 2321 } 2322 BOOST_UBLAS_INLINE operator -(const const_iterator & it) const2323 difference_type operator - (const const_iterator &it) const { 2324 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ()); 2325 return it_ - it.it_; 2326 } 2327 2328 // Dereference 2329 BOOST_UBLAS_INLINE operator *() const2330 const_reference operator * () const { 2331 BOOST_UBLAS_CHECK (it_ < (*this) ().size (), bad_index ()); 2332 return (*this) () (index ()); 2333 } 2334 BOOST_UBLAS_INLINE operator [](difference_type n) const2335 const_reference operator [] (difference_type n) const { 2336 return *(*this + n); 2337 } 2338 2339 // Index 2340 BOOST_UBLAS_INLINE index() const2341 size_type index () const { 2342 BOOST_UBLAS_CHECK (it_ < (*this) ().size (), bad_index ()); 2343 return it_; 2344 } 2345 2346 // Assignment 2347 BOOST_UBLAS_INLINE operator =(const const_iterator & it)2348 const_iterator &operator = (const const_iterator &it) { 2349 container_const_reference<scalar_vector>::assign (&it ()); 2350 it_ = it.it_; 2351 return *this; 2352 } 2353 2354 // Comparison 2355 BOOST_UBLAS_INLINE operator ==(const const_iterator & it) const2356 bool operator == (const const_iterator &it) const { 2357 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ()); 2358 return it_ == it.it_; 2359 } 2360 BOOST_UBLAS_INLINE operator <(const const_iterator & it) const2361 bool operator < (const const_iterator &it) const { 2362 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ()); 2363 return it_ < it.it_; 2364 } 2365 2366 private: 2367 const_subiterator_type it_; 2368 }; 2369 2370 typedef const_iterator iterator; 2371 #endif 2372 2373 BOOST_UBLAS_INLINE begin() const2374 const_iterator begin () const { 2375 return find (0); 2376 } 2377 BOOST_UBLAS_INLINE cbegin() const2378 const_iterator cbegin () const { 2379 return begin (); 2380 } 2381 BOOST_UBLAS_INLINE end() const2382 const_iterator end () const { 2383 return find (size_); 2384 } 2385 BOOST_UBLAS_INLINE cend() const2386 const_iterator cend () const { 2387 return end (); 2388 } 2389 2390 // Reverse iterator 2391 typedef reverse_iterator_base<const_iterator> const_reverse_iterator; 2392 2393 BOOST_UBLAS_INLINE rbegin() const2394 const_reverse_iterator rbegin () const { 2395 return const_reverse_iterator (end ()); 2396 } 2397 BOOST_UBLAS_INLINE crbegin() const2398 const_reverse_iterator crbegin () const { 2399 return rbegin (); 2400 } 2401 BOOST_UBLAS_INLINE rend() const2402 const_reverse_iterator rend () const { 2403 return const_reverse_iterator (begin ()); 2404 } 2405 BOOST_UBLAS_INLINE crend() const2406 const_reverse_iterator crend () const { 2407 return rend (); 2408 } 2409 2410 // Serialization 2411 template<class Archive> serialize(Archive & ar,const unsigned int)2412 void serialize(Archive & ar, const unsigned int /* file_version */){ 2413 serialization::collection_size_type s (size_); 2414 ar & serialization::make_nvp("size",s); 2415 if (Archive::is_loading::value) { 2416 size_ = s; 2417 } 2418 ar & serialization::make_nvp("value", value_); 2419 } 2420 2421 private: 2422 size_type size_; 2423 value_type value_; 2424 }; 2425 2426 // ------------------------ 2427 // Array based vector class 2428 // ------------------------ 2429 2430 /// \brief A dense vector of values of type \c T with the given \c size. The data is stored as an ordinary C++ array \c T \c data_[M] 2431 template<class T, std::size_t N> 2432 class c_vector: 2433 public vector_container<c_vector<T, N> > { 2434 2435 typedef c_vector<T, N> self_type; 2436 public: 2437 #ifdef BOOST_UBLAS_ENABLE_PROXY_SHORTCUTS 2438 using vector_container<self_type>::operator (); 2439 #endif 2440 typedef std::size_t size_type; 2441 typedef std::ptrdiff_t difference_type; 2442 typedef T value_type; 2443 typedef const T &const_reference; 2444 typedef T &reference; 2445 typedef value_type array_type[N]; 2446 typedef T *pointer; 2447 typedef const T *const_pointer; 2448 typedef const vector_reference<const self_type> const_closure_type; 2449 typedef vector_reference<self_type> closure_type; 2450 typedef self_type vector_temporary_type; 2451 typedef dense_tag storage_category; 2452 2453 // Construction and destruction 2454 BOOST_UBLAS_INLINE c_vector()2455 c_vector (): 2456 size_ (N) /* , data_ () */ {} 2457 explicit BOOST_UBLAS_INLINE c_vector(size_type size)2458 c_vector (size_type size): 2459 size_ (size) /* , data_ () */ { 2460 if (size_ > N) 2461 bad_size ().raise (); 2462 } 2463 BOOST_UBLAS_INLINE c_vector(const c_vector & v)2464 c_vector (const c_vector &v): 2465 size_ (v.size_) /* , data_ () */ { 2466 if (size_ > N) 2467 bad_size ().raise (); 2468 assign(v); 2469 } 2470 template<class AE> 2471 BOOST_UBLAS_INLINE c_vector(const vector_expression<AE> & ae)2472 c_vector (const vector_expression<AE> &ae): 2473 size_ (ae ().size ()) /* , data_ () */ { 2474 if (size_ > N) 2475 bad_size ().raise (); 2476 vector_assign<scalar_assign> (*this, ae); 2477 } 2478 2479 // Accessors 2480 BOOST_UBLAS_INLINE size() const2481 size_type size () const { 2482 return size_; 2483 } 2484 BOOST_UBLAS_INLINE data() const2485 const_pointer data () const { 2486 return data_; 2487 } 2488 BOOST_UBLAS_INLINE data()2489 pointer data () { 2490 return data_; 2491 } 2492 2493 // Resizing 2494 BOOST_UBLAS_INLINE resize(size_type size,bool=true)2495 void resize (size_type size, bool /*preserve*/ = true) { 2496 if (size > N) 2497 bad_size ().raise (); 2498 size_ = size; 2499 } 2500 2501 // Element support 2502 BOOST_UBLAS_INLINE find_element(size_type i)2503 pointer find_element (size_type i) { 2504 return const_cast<pointer> (const_cast<const self_type&>(*this).find_element (i)); 2505 } 2506 BOOST_UBLAS_INLINE find_element(size_type i) const2507 const_pointer find_element (size_type i) const { 2508 return & data_ [i]; 2509 } 2510 2511 // Element access 2512 BOOST_UBLAS_INLINE operator ()(size_type i) const2513 const_reference operator () (size_type i) const { 2514 BOOST_UBLAS_CHECK (i < size_, bad_index ()); 2515 return data_ [i]; 2516 } 2517 BOOST_UBLAS_INLINE operator ()(size_type i)2518 reference operator () (size_type i) { 2519 BOOST_UBLAS_CHECK (i < size_, bad_index ()); 2520 return data_ [i]; 2521 } 2522 2523 BOOST_UBLAS_INLINE operator [](size_type i) const2524 const_reference operator [] (size_type i) const { 2525 return (*this) (i); 2526 } 2527 BOOST_UBLAS_INLINE operator [](size_type i)2528 reference operator [] (size_type i) { 2529 return (*this) (i); 2530 } 2531 2532 // Element assignment 2533 BOOST_UBLAS_INLINE insert_element(size_type i,const_reference t)2534 reference insert_element (size_type i, const_reference t) { 2535 BOOST_UBLAS_CHECK (i < size_, bad_index ()); 2536 return (data_ [i] = t); 2537 } 2538 BOOST_UBLAS_INLINE erase_element(size_type i)2539 void erase_element (size_type i) { 2540 BOOST_UBLAS_CHECK (i < size_, bad_index ()); 2541 data_ [i] = value_type/*zero*/(); 2542 } 2543 2544 // Zeroing 2545 BOOST_UBLAS_INLINE clear()2546 void clear () { 2547 std::fill (data_, data_ + size_, value_type/*zero*/()); 2548 } 2549 2550 // Assignment 2551 #ifdef BOOST_UBLAS_MOVE_SEMANTICS 2552 2553 /*! @note "pass by value" the key idea to enable move semantics */ 2554 BOOST_UBLAS_INLINE operator =(c_vector v)2555 c_vector &operator = (c_vector v) { 2556 assign_temporary(v); 2557 return *this; 2558 } 2559 #else 2560 BOOST_UBLAS_INLINE operator =(const c_vector & v)2561 c_vector &operator = (const c_vector &v) { 2562 size_ = v.size_; 2563 std::copy (v.data_, v.data_ + v.size_, data_); 2564 return *this; 2565 } 2566 #endif 2567 template<class C> // Container assignment without temporary 2568 BOOST_UBLAS_INLINE operator =(const vector_container<C> & v)2569 c_vector &operator = (const vector_container<C> &v) { 2570 resize (v ().size (), false); 2571 assign (v); 2572 return *this; 2573 } 2574 BOOST_UBLAS_INLINE assign_temporary(c_vector & v)2575 c_vector &assign_temporary (c_vector &v) { 2576 swap (v); 2577 return *this; 2578 } 2579 template<class AE> 2580 BOOST_UBLAS_INLINE operator =(const vector_expression<AE> & ae)2581 c_vector &operator = (const vector_expression<AE> &ae) { 2582 self_type temporary (ae); 2583 return assign_temporary (temporary); 2584 } 2585 template<class AE> 2586 BOOST_UBLAS_INLINE assign(const vector_expression<AE> & ae)2587 c_vector &assign (const vector_expression<AE> &ae) { 2588 vector_assign<scalar_assign> (*this, ae); 2589 return *this; 2590 } 2591 2592 // Computed assignment 2593 template<class AE> 2594 BOOST_UBLAS_INLINE operator +=(const vector_expression<AE> & ae)2595 c_vector &operator += (const vector_expression<AE> &ae) { 2596 self_type temporary (*this + ae); 2597 return assign_temporary (temporary); 2598 } 2599 template<class C> // Container assignment without temporary 2600 BOOST_UBLAS_INLINE operator +=(const vector_container<C> & v)2601 c_vector &operator += (const vector_container<C> &v) { 2602 plus_assign (v); 2603 return *this; 2604 } 2605 template<class AE> 2606 BOOST_UBLAS_INLINE plus_assign(const vector_expression<AE> & ae)2607 c_vector &plus_assign (const vector_expression<AE> &ae) { 2608 vector_assign<scalar_plus_assign> ( *this, ae); 2609 return *this; 2610 } 2611 template<class AE> 2612 BOOST_UBLAS_INLINE operator -=(const vector_expression<AE> & ae)2613 c_vector &operator -= (const vector_expression<AE> &ae) { 2614 self_type temporary (*this - ae); 2615 return assign_temporary (temporary); 2616 } 2617 template<class C> // Container assignment without temporary 2618 BOOST_UBLAS_INLINE operator -=(const vector_container<C> & v)2619 c_vector &operator -= (const vector_container<C> &v) { 2620 minus_assign (v); 2621 return *this; 2622 } 2623 template<class AE> 2624 BOOST_UBLAS_INLINE minus_assign(const vector_expression<AE> & ae)2625 c_vector &minus_assign (const vector_expression<AE> &ae) { 2626 vector_assign<scalar_minus_assign> (*this, ae); 2627 return *this; 2628 } 2629 template<class AT> 2630 BOOST_UBLAS_INLINE operator *=(const AT & at)2631 c_vector &operator *= (const AT &at) { 2632 vector_assign_scalar<scalar_multiplies_assign> (*this, at); 2633 return *this; 2634 } 2635 template<class AT> 2636 BOOST_UBLAS_INLINE operator /=(const AT & at)2637 c_vector &operator /= (const AT &at) { 2638 vector_assign_scalar<scalar_divides_assign> (*this, at); 2639 return *this; 2640 } 2641 2642 // Swapping 2643 BOOST_UBLAS_INLINE swap(c_vector & v)2644 void swap (c_vector &v) { 2645 if (this != &v) { 2646 BOOST_UBLAS_CHECK (size_ == v.size_, bad_size ()); 2647 std::swap (size_, v.size_); 2648 std::swap_ranges (data_, data_ + size_, v.data_); 2649 } 2650 } 2651 BOOST_UBLAS_INLINE swap(c_vector & v1,c_vector & v2)2652 friend void swap (c_vector &v1, c_vector &v2) { 2653 v1.swap (v2); 2654 } 2655 2656 // Iterator types 2657 private: 2658 // Use pointers for iterator 2659 typedef const_pointer const_subiterator_type; 2660 typedef pointer subiterator_type; 2661 2662 public: 2663 #ifdef BOOST_UBLAS_USE_INDEXED_ITERATOR 2664 typedef indexed_iterator<self_type, dense_random_access_iterator_tag> iterator; 2665 typedef indexed_const_iterator<self_type, dense_random_access_iterator_tag> const_iterator; 2666 #else 2667 class const_iterator; 2668 class iterator; 2669 #endif 2670 2671 // Element lookup 2672 BOOST_UBLAS_INLINE find(size_type i) const2673 const_iterator find (size_type i) const { 2674 #ifndef BOOST_UBLAS_USE_INDEXED_ITERATOR 2675 return const_iterator (*this, &data_ [i]); 2676 #else 2677 return const_iterator (*this, i); 2678 #endif 2679 } 2680 BOOST_UBLAS_INLINE find(size_type i)2681 iterator find (size_type i) { 2682 #ifndef BOOST_UBLAS_USE_INDEXED_ITERATOR 2683 return iterator (*this, &data_ [i]); 2684 #else 2685 return iterator (*this, i); 2686 #endif 2687 } 2688 2689 #ifndef BOOST_UBLAS_USE_INDEXED_ITERATOR 2690 class const_iterator: 2691 public container_const_reference<c_vector>, 2692 public random_access_iterator_base<dense_random_access_iterator_tag, 2693 const_iterator, value_type> { 2694 public: 2695 typedef typename c_vector::difference_type difference_type; 2696 typedef typename c_vector::value_type value_type; 2697 typedef typename c_vector::const_reference reference; 2698 typedef typename c_vector::const_pointer pointer; 2699 2700 // Construction and destruction 2701 BOOST_UBLAS_INLINE const_iterator()2702 const_iterator (): 2703 container_const_reference<self_type> (), it_ () {} 2704 BOOST_UBLAS_INLINE const_iterator(const self_type & v,const const_subiterator_type & it)2705 const_iterator (const self_type &v, const const_subiterator_type &it): 2706 container_const_reference<self_type> (v), it_ (it) {} 2707 BOOST_UBLAS_INLINE const_iterator(const typename self_type::iterator & it)2708 const_iterator (const typename self_type::iterator &it): // ISSUE self_type:: stops VC8 using std::iterator here 2709 container_const_reference<self_type> (it ()), it_ (it.it_) {} 2710 2711 // Arithmetic 2712 BOOST_UBLAS_INLINE operator ++()2713 const_iterator &operator ++ () { 2714 ++ it_; 2715 return *this; 2716 } 2717 BOOST_UBLAS_INLINE operator --()2718 const_iterator &operator -- () { 2719 -- it_; 2720 return *this; 2721 } 2722 BOOST_UBLAS_INLINE operator +=(difference_type n)2723 const_iterator &operator += (difference_type n) { 2724 it_ += n; 2725 return *this; 2726 } 2727 BOOST_UBLAS_INLINE operator -=(difference_type n)2728 const_iterator &operator -= (difference_type n) { 2729 it_ -= n; 2730 return *this; 2731 } 2732 BOOST_UBLAS_INLINE operator -(const const_iterator & it) const2733 difference_type operator - (const const_iterator &it) const { 2734 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ()); 2735 return it_ - it.it_; 2736 } 2737 2738 // Dereference 2739 BOOST_UBLAS_INLINE operator *() const2740 const_reference operator * () const { 2741 BOOST_UBLAS_CHECK (it_ >= (*this) ().begin ().it_ && it_ < (*this) ().end ().it_, bad_index ()); 2742 return *it_; 2743 } 2744 BOOST_UBLAS_INLINE operator [](difference_type n) const2745 const_reference operator [] (difference_type n) const { 2746 return *(it_ + n); 2747 } 2748 2749 // Index 2750 BOOST_UBLAS_INLINE index() const2751 size_type index () const { 2752 BOOST_UBLAS_CHECK (it_ >= (*this) ().begin ().it_ && it_ < (*this) ().end ().it_, bad_index ()); 2753 const self_type &v = (*this) (); 2754 return it_ - v.begin ().it_; 2755 } 2756 2757 // Assignment 2758 BOOST_UBLAS_INLINE operator =(const const_iterator & it)2759 const_iterator &operator = (const const_iterator &it) { 2760 container_const_reference<self_type>::assign (&it ()); 2761 it_ = it.it_; 2762 return *this; 2763 } 2764 2765 // Comparison 2766 BOOST_UBLAS_INLINE operator ==(const const_iterator & it) const2767 bool operator == (const const_iterator &it) const { 2768 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ()); 2769 return it_ == it.it_; 2770 } 2771 BOOST_UBLAS_INLINE operator <(const const_iterator & it) const2772 bool operator < (const const_iterator &it) const { 2773 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ()); 2774 return it_ < it.it_; 2775 } 2776 2777 private: 2778 const_subiterator_type it_; 2779 2780 friend class iterator; 2781 }; 2782 #endif 2783 2784 BOOST_UBLAS_INLINE begin() const2785 const_iterator begin () const { 2786 return find (0); 2787 } 2788 BOOST_UBLAS_INLINE cbegin() const2789 const_iterator cbegin () const { 2790 return begin (); 2791 } 2792 BOOST_UBLAS_INLINE end() const2793 const_iterator end () const { 2794 return find (size_); 2795 } 2796 BOOST_UBLAS_INLINE cend() const2797 const_iterator cend () const { 2798 return end (); 2799 } 2800 2801 #ifndef BOOST_UBLAS_USE_INDEXED_ITERATOR 2802 class iterator: 2803 public container_reference<c_vector>, 2804 public random_access_iterator_base<dense_random_access_iterator_tag, 2805 iterator, value_type> { 2806 public: 2807 typedef typename c_vector::difference_type difference_type; 2808 typedef typename c_vector::value_type value_type; 2809 typedef typename c_vector::reference reference; 2810 typedef typename c_vector::pointer pointer; 2811 2812 // Construction and destruction 2813 BOOST_UBLAS_INLINE iterator()2814 iterator (): 2815 container_reference<self_type> (), it_ () {} 2816 BOOST_UBLAS_INLINE iterator(self_type & v,const subiterator_type & it)2817 iterator (self_type &v, const subiterator_type &it): 2818 container_reference<self_type> (v), it_ (it) {} 2819 2820 // Arithmetic 2821 BOOST_UBLAS_INLINE operator ++()2822 iterator &operator ++ () { 2823 ++ it_; 2824 return *this; 2825 } 2826 BOOST_UBLAS_INLINE operator --()2827 iterator &operator -- () { 2828 -- it_; 2829 return *this; 2830 } 2831 BOOST_UBLAS_INLINE operator +=(difference_type n)2832 iterator &operator += (difference_type n) { 2833 it_ += n; 2834 return *this; 2835 } 2836 BOOST_UBLAS_INLINE operator -=(difference_type n)2837 iterator &operator -= (difference_type n) { 2838 it_ -= n; 2839 return *this; 2840 } 2841 BOOST_UBLAS_INLINE operator -(const iterator & it) const2842 difference_type operator - (const iterator &it) const { 2843 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ()); 2844 return it_ - it.it_; 2845 } 2846 2847 // Dereference 2848 BOOST_UBLAS_INLINE operator *() const2849 reference operator * () const { 2850 BOOST_UBLAS_CHECK (it_ >= (*this) ().begin ().it_ && it_ < (*this) ().end ().it_, bad_index ()); 2851 return *it_; 2852 } 2853 BOOST_UBLAS_INLINE operator [](difference_type n) const2854 reference operator [] (difference_type n) const { 2855 return *(it_ + n); 2856 } 2857 2858 // Index 2859 BOOST_UBLAS_INLINE index() const2860 size_type index () const { 2861 BOOST_UBLAS_CHECK (it_ >= (*this) ().begin ().it_ && it_ < (*this) ().end ().it_, bad_index ()); 2862 // EDG won't allow const self_type it doesn't allow friend access to it_ 2863 self_type &v = (*this) (); 2864 return it_ - v.begin ().it_; 2865 } 2866 2867 // Assignment 2868 BOOST_UBLAS_INLINE operator =(const iterator & it)2869 iterator &operator = (const iterator &it) { 2870 container_reference<self_type>::assign (&it ()); 2871 it_ = it.it_; 2872 return *this; 2873 } 2874 2875 // Comparison 2876 BOOST_UBLAS_INLINE operator ==(const iterator & it) const2877 bool operator == (const iterator &it) const { 2878 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ()); 2879 return it_ == it.it_; 2880 } 2881 BOOST_UBLAS_INLINE operator <(const iterator & it) const2882 bool operator < (const iterator &it) const { 2883 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ()); 2884 return it_ < it.it_; 2885 } 2886 2887 private: 2888 subiterator_type it_; 2889 2890 friend class const_iterator; 2891 }; 2892 #endif 2893 2894 BOOST_UBLAS_INLINE begin()2895 iterator begin () { 2896 return find (0); 2897 } 2898 BOOST_UBLAS_INLINE end()2899 iterator end () { 2900 return find (size_); 2901 } 2902 2903 // Reverse iterator 2904 typedef reverse_iterator_base<const_iterator> const_reverse_iterator; 2905 typedef reverse_iterator_base<iterator> reverse_iterator; 2906 2907 BOOST_UBLAS_INLINE rbegin() const2908 const_reverse_iterator rbegin () const { 2909 return const_reverse_iterator (end ()); 2910 } 2911 BOOST_UBLAS_INLINE crbegin() const2912 const_reverse_iterator crbegin () const { 2913 return rbegin (); 2914 } 2915 BOOST_UBLAS_INLINE rend() const2916 const_reverse_iterator rend () const { 2917 return const_reverse_iterator (begin ()); 2918 } 2919 BOOST_UBLAS_INLINE crend() const2920 const_reverse_iterator crend () const { 2921 return rend (); 2922 } 2923 BOOST_UBLAS_INLINE rbegin()2924 reverse_iterator rbegin () { 2925 return reverse_iterator (end ()); 2926 } 2927 BOOST_UBLAS_INLINE rend()2928 reverse_iterator rend () { 2929 return reverse_iterator (begin ()); 2930 } 2931 2932 // Serialization 2933 template<class Archive> serialize(Archive & ar,const unsigned int)2934 void serialize(Archive & ar, const unsigned int /* file_version */){ 2935 serialization::collection_size_type s (size_); 2936 ar & serialization::make_nvp("size",s); 2937 2938 // copy the value back if loading 2939 if (Archive::is_loading::value) { 2940 if (s > N) bad_size("too large size in bounded_vector::load()\n").raise(); 2941 size_ = s; 2942 } 2943 // ISSUE: this writes the full array 2944 ar & serialization::make_nvp("data",data_); 2945 } 2946 2947 private: 2948 size_type size_; 2949 array_type data_; 2950 }; 2951 2952 }}} 2953 2954 #endif 2955