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 template <typename... Types> 910 BOOST_UBLAS_INLINE fixed_vector(value_type v0,Types...vrest)911 fixed_vector(value_type v0, Types... vrest) : 912 vector_container<self_type> (), 913 data_( array_type{ v0, vrest... } ) {} 914 915 // ----------------------- 916 // Random Access Container 917 // ----------------------- 918 919 /// \brief Return the maximum size of the data container. 920 /// 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. 921 BOOST_UBLAS_INLINE max_size() const922 size_type max_size () const { 923 return data_.max_size (); 924 } 925 926 /// \brief Return true if the vector is empty (\c size==0) 927 /// \return \c true if empty, \c false otherwise 928 BOOST_UBLAS_INLINE empty() const929 const bool &empty () const { 930 return data_.empty(); 931 } 932 933 // --------- 934 // Accessors 935 // --------- 936 937 /// \brief Return the size of the vector 938 BOOST_UBLAS_INLINE size() const939 BOOST_CONSTEXPR size_type size () const{ // should have a const after C++14 940 return data_.size (); 941 } 942 943 // ----------------- 944 // Storage accessors 945 // ----------------- 946 947 /// \brief Return a \c const reference to the container. Useful to access data directly for specific type of container. 948 BOOST_UBLAS_INLINE data() const949 const array_type &data () const { 950 return data_; 951 } 952 953 /// \brief Return a reference to the container. Useful to speed-up write operations to the data in very specific case. 954 BOOST_UBLAS_INLINE data()955 array_type &data () { 956 return data_; 957 } 958 959 // --------------- 960 // Element support 961 // --------------- 962 963 /// \brief Return a pointer to the element \f$i\f$ 964 /// \param i index of the element 965 // XXX this semantic is not the one expected by the name of this method 966 BOOST_UBLAS_INLINE find_element(size_type i)967 pointer find_element (size_type i) { 968 return const_cast<pointer> (const_cast<const self_type&>(*this).find_element (i)); 969 } 970 971 /// \brief Return a const pointer to the element \f$i\f$ 972 /// \param i index of the element 973 // XXX this semantic is not the one expected by the name of this method 974 BOOST_UBLAS_INLINE find_element(size_type i) const975 const_pointer find_element (size_type i) const { 976 BOOST_UBLAS_CHECK (i < data_.size(), bad_index() ); // Since std:array doesn't check for bounds 977 return & (data () [i]); 978 } 979 980 // -------------- 981 // Element access 982 // -------------- 983 984 /// \brief Return a const reference to the element \f$i\f$ 985 /// Return a const reference to the element \f$i\f$. With some compilers, this notation will be faster than \c[i] 986 /// \param i index of the element 987 BOOST_UBLAS_INLINE operator ()(size_type i) const988 const_reference operator () (size_type i) const { 989 BOOST_UBLAS_CHECK (i < data_.size(), bad_index() ); 990 return data () [i]; 991 } 992 993 /// \brief Return a reference to the element \f$i\f$ 994 /// Return a reference to the element \f$i\f$. With some compilers, this notation will be faster than \c[i] 995 /// \param i index of the element 996 BOOST_UBLAS_INLINE operator ()(size_type i)997 reference operator () (size_type i) { 998 BOOST_UBLAS_CHECK (i < data_.size(), bad_index() ); 999 return data () [i]; 1000 } 1001 1002 /// \brief Return a const reference to the element \f$i\f$ 1003 /// \param i index of the element 1004 BOOST_UBLAS_INLINE operator [](size_type i) const1005 const_reference operator [] (size_type i) const { 1006 BOOST_UBLAS_CHECK (i < data_.size(), bad_index() ); 1007 return (*this) (i); 1008 } 1009 1010 /// \brief Return a reference to the element \f$i\f$ 1011 /// \param i index of the element 1012 BOOST_UBLAS_INLINE operator [](size_type i)1013 reference operator [] (size_type i) { 1014 BOOST_UBLAS_CHECK (i < data_.size(), bad_index() ); 1015 return (*this) (i); 1016 } 1017 1018 // ------------------ 1019 // Element assignment 1020 // ------------------ 1021 1022 /// \brief Set element \f$i\f$ to the value \c t 1023 /// \param i index of the element 1024 /// \param t reference to the value to be set 1025 // XXX semantic of this is to insert a new element and therefore size=size+1 ? 1026 BOOST_UBLAS_INLINE insert_element(size_type i,const_reference t)1027 reference insert_element (size_type i, const_reference t) { 1028 BOOST_UBLAS_CHECK (i < data_.size(), bad_index ()); 1029 return (data () [i] = t); 1030 } 1031 1032 /// \brief Set element \f$i\f$ to the \e zero value 1033 /// \param i index of the element 1034 BOOST_UBLAS_INLINE erase_element(size_type i)1035 void erase_element (size_type i) { 1036 BOOST_UBLAS_CHECK (i < data_.size(), bad_index ()); 1037 data () [i] = value_type/*zero*/(); 1038 } 1039 1040 // ------- 1041 // Zeroing 1042 // ------- 1043 1044 /// \brief Clear the vector, i.e. set all values to the \c zero value. 1045 BOOST_UBLAS_INLINE clear()1046 void clear () { 1047 std::fill (data ().begin (), data ().end (), value_type/*zero*/()); 1048 } 1049 1050 // Assignment 1051 #ifdef BOOST_UBLAS_MOVE_SEMANTICS 1052 1053 /// \brief Assign a full fixed_vector (\e RHS-vector) to the current fixed_vector (\e LHS-vector) 1054 /// \param v is the source vector 1055 /// \return a reference to a fixed_vector (i.e. the destination vector) 1056 /*! @note "pass by value" the key idea to enable move semantics */ 1057 BOOST_UBLAS_INLINE operator =(fixed_vector v)1058 fixed_vector &operator = (fixed_vector v) { 1059 assign_temporary(v); 1060 return *this; 1061 } 1062 #else 1063 /// \brief Assign a full fixed_vector (\e RHS-vector) to the current fixed_vector (\e LHS-vector) 1064 /// \param v is the source fixed_vector 1065 /// \return a reference to a fixed_vector (i.e. the destination vector) 1066 BOOST_UBLAS_INLINE operator =(const fixed_vector & v)1067 fixed_vector &operator = (const fixed_vector &v) { 1068 data () = v.data (); 1069 return *this; 1070 } 1071 #endif 1072 1073 /// \brief Assign a full vector (\e RHS-vector) to the current fixed_vector (\e LHS-vector) 1074 /// Assign a full vector (\e RHS-vector) to the current fixed_vector (\e LHS-vector). This method does not create any temporary. 1075 /// \param v is the source vector container 1076 /// \return a reference to a vector (i.e. the destination vector) 1077 template<class C> // Container assignment without temporary 1078 BOOST_UBLAS_INLINE operator =(const vector_container<C> & v)1079 fixed_vector &operator = (const vector_container<C> &v) { 1080 assign (v); 1081 return *this; 1082 } 1083 1084 /// \brief Assign a full fixed_vector (\e RHS-vector) to the current fixed_vector (\e LHS-vector) 1085 /// \param v is the source fixed_vector 1086 /// \return a reference to a fixed_vector (i.e. the destination fixed_vector) 1087 BOOST_UBLAS_INLINE assign_temporary(fixed_vector & v)1088 fixed_vector &assign_temporary (fixed_vector &v) { 1089 swap ( v ); 1090 return *this; 1091 } 1092 1093 /// \brief Assign the result of a vector_expression to the fixed_vector 1094 /// 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. 1095 /// \tparam AE is the type of the vector_expression 1096 /// \param ae is a const reference to the vector_expression 1097 /// \return a reference to the resulting fixed_vector 1098 template<class AE> 1099 BOOST_UBLAS_INLINE operator =(const vector_expression<AE> & ae)1100 fixed_vector &operator = (const vector_expression<AE> &ae) { 1101 self_type temporary (ae); 1102 return assign_temporary (temporary); 1103 } 1104 1105 /// \brief Assign the result of a vector_expression to the fixed_vector 1106 /// 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. 1107 /// \tparam AE is the type of the vector_expression 1108 /// \param ae is a const reference to the vector_expression 1109 /// \return a reference to the resulting fixed_vector 1110 template<class AE> 1111 BOOST_UBLAS_INLINE assign(const vector_expression<AE> & ae)1112 fixed_vector &assign (const vector_expression<AE> &ae) { 1113 vector_assign<scalar_assign> (*this, ae); 1114 return *this; 1115 } 1116 1117 // ------------------- 1118 // Computed assignment 1119 // ------------------- 1120 1121 /// \brief Assign the sum of the fixed_vector and a vector_expression to the fixed_vector 1122 /// 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. 1123 /// A temporary is created for the computations. 1124 /// \tparam AE is the type of the vector_expression 1125 /// \param ae is a const reference to the vector_expression 1126 /// \return a reference to the resulting fixed_vector 1127 template<class AE> 1128 BOOST_UBLAS_INLINE operator +=(const vector_expression<AE> & ae)1129 fixed_vector &operator += (const vector_expression<AE> &ae) { 1130 self_type temporary (*this + ae); 1131 return assign_temporary (temporary); 1132 } 1133 1134 /// \brief Assign the sum of the fixed_vector and a vector_expression to the fixed_vector 1135 /// 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. 1136 /// No temporary is created. Computations are done and stored directly into the resulting vector. 1137 /// \tparam AE is the type of the vector_expression 1138 /// \param ae is a const reference to the vector_expression 1139 /// \return a reference to the resulting vector 1140 template<class C> // Container assignment without temporary 1141 BOOST_UBLAS_INLINE operator +=(const vector_container<C> & v)1142 fixed_vector &operator += (const vector_container<C> &v) { 1143 plus_assign (v); 1144 return *this; 1145 } 1146 1147 /// \brief Assign the sum of the fixed_vector and a vector_expression to the fixed_vector 1148 /// 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. 1149 /// No temporary is created. Computations are done and stored directly into the resulting fixed_vector. 1150 /// \tparam AE is the type of the vector_expression 1151 /// \param ae is a const reference to the vector_expression 1152 /// \return a reference to the resulting vector 1153 template<class AE> 1154 BOOST_UBLAS_INLINE plus_assign(const vector_expression<AE> & ae)1155 fixed_vector &plus_assign (const vector_expression<AE> &ae) { 1156 vector_assign<scalar_plus_assign> (*this, ae); 1157 return *this; 1158 } 1159 1160 /// \brief Assign the difference of the fixed_vector and a vector_expression to the fixed_vector 1161 /// 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. 1162 /// A temporary is created for the computations. 1163 /// \tparam AE is the type of the vector_expression 1164 /// \param ae is a const reference to the vector_expression 1165 template<class AE> 1166 BOOST_UBLAS_INLINE operator -=(const vector_expression<AE> & ae)1167 fixed_vector &operator -= (const vector_expression<AE> &ae) { 1168 self_type temporary (*this - ae); 1169 return assign_temporary (temporary); 1170 } 1171 1172 /// \brief Assign the difference of the fixed_vector and a vector_expression to the fixed_vector 1173 /// 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. 1174 /// No temporary is created. Computations are done and stored directly into the resulting fixed_vector. 1175 /// \tparam AE is the type of the vector_expression 1176 /// \param ae is a const reference to the vector_expression 1177 /// \return a reference to the resulting vector 1178 template<class C> // Container assignment without temporary 1179 BOOST_UBLAS_INLINE operator -=(const vector_container<C> & v)1180 fixed_vector &operator -= (const vector_container<C> &v) { 1181 minus_assign (v); 1182 return *this; 1183 } 1184 1185 /// \brief Assign the difference of the fixed_vector and a vector_expression to the fixed_vector 1186 /// 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. 1187 /// No temporary is created. Computations are done and stored directly into the resulting fixed_vector. 1188 /// \tparam AE is the type of the vector_expression 1189 /// \param ae is a const reference to the vector_expression 1190 /// \return a reference to the resulting fixed_vector 1191 template<class AE> 1192 BOOST_UBLAS_INLINE minus_assign(const vector_expression<AE> & ae)1193 fixed_vector &minus_assign (const vector_expression<AE> &ae) { 1194 vector_assign<scalar_minus_assign> (*this, ae); 1195 return *this; 1196 } 1197 1198 /// \brief Assign the product of the fixed_vector and a scalar to the fixed_vector 1199 /// 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. 1200 /// No temporary is created. Computations are done and stored directly into the resulting fixed_vector. 1201 /// \tparam AE is the type of the vector_expression 1202 /// \param at is a const reference to the scalar 1203 /// \return a reference to the resulting fixed_vector 1204 template<class AT> 1205 BOOST_UBLAS_INLINE operator *=(const AT & at)1206 fixed_vector &operator *= (const AT &at) { 1207 vector_assign_scalar<scalar_multiplies_assign> (*this, at); 1208 return *this; 1209 } 1210 1211 /// \brief Assign the division of the fixed_vector by a scalar to the fixed_vector 1212 /// 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. 1213 /// No temporary is created. Computations are done and stored directly into the resulting vector. 1214 /// \tparam AE is the type of the vector_expression 1215 /// \param at is a const reference to the scalar 1216 /// \return a reference to the resulting fixed_vector 1217 template<class AT> 1218 BOOST_UBLAS_INLINE operator /=(const AT & at)1219 fixed_vector &operator /= (const AT &at) { 1220 vector_assign_scalar<scalar_divides_assign> (*this, at); 1221 return *this; 1222 } 1223 1224 // -------- 1225 // Swapping 1226 // -------- 1227 1228 /// \brief Swap the content of the fixed_vector with another vector 1229 /// \param v is the fixed_vector to be swapped with 1230 BOOST_UBLAS_INLINE swap(fixed_vector & v)1231 void swap (fixed_vector &v) { 1232 if (this != &v) { 1233 data ().swap (v.data ()); 1234 } 1235 } 1236 1237 /// \brief Swap the content of two fixed_vectors 1238 /// \param v1 is the first fixed_vector. It takes values from v2 1239 /// \param v2 is the second fixed_vector It takes values from v1 1240 BOOST_UBLAS_INLINE swap(fixed_vector & v1,fixed_vector & v2)1241 friend void swap (fixed_vector &v1, fixed_vector &v2) { 1242 v1.swap (v2); 1243 } 1244 1245 // Iterator types 1246 private: 1247 // Use the storage array iterator 1248 typedef typename A::const_iterator const_subiterator_type; 1249 typedef typename A::iterator subiterator_type; 1250 1251 public: 1252 #ifdef BOOST_UBLAS_USE_INDEXED_ITERATOR 1253 typedef indexed_iterator<self_type, dense_random_access_iterator_tag> iterator; 1254 typedef indexed_const_iterator<self_type, dense_random_access_iterator_tag> const_iterator; 1255 #else 1256 class const_iterator; 1257 class iterator; 1258 #endif 1259 1260 // -------------- 1261 // Element lookup 1262 // -------------- 1263 1264 /// \brief Return a const iterator to the element \e i 1265 /// \param i index of the element 1266 BOOST_UBLAS_INLINE find(size_type i) const1267 const_iterator find (size_type i) const { 1268 #ifndef BOOST_UBLAS_USE_INDEXED_ITERATOR 1269 return const_iterator (*this, data ().begin () + i); 1270 #else 1271 return const_iterator (*this, i); 1272 #endif 1273 } 1274 1275 /// \brief Return an iterator to the element \e i 1276 /// \param i index of the element 1277 BOOST_UBLAS_INLINE find(size_type i)1278 iterator find (size_type i) { 1279 #ifndef BOOST_UBLAS_USE_INDEXED_ITERATOR 1280 return iterator (*this, data ().begin () + i); 1281 #else 1282 return iterator (*this, i); 1283 #endif 1284 } 1285 1286 #ifndef BOOST_UBLAS_USE_INDEXED_ITERATOR 1287 class const_iterator: 1288 public container_const_reference<fixed_vector>, 1289 public random_access_iterator_base<dense_random_access_iterator_tag, 1290 const_iterator, value_type, difference_type> { 1291 public: 1292 typedef typename fixed_vector::difference_type difference_type; 1293 typedef typename fixed_vector::value_type value_type; 1294 typedef typename fixed_vector::const_reference reference; 1295 typedef const typename fixed_vector::pointer pointer; 1296 1297 // ---------------------------- 1298 // Construction and destruction 1299 // ---------------------------- 1300 1301 1302 BOOST_UBLAS_INLINE const_iterator()1303 const_iterator (): 1304 container_const_reference<self_type> (), it_ () {} 1305 BOOST_UBLAS_INLINE const_iterator(const self_type & v,const const_subiterator_type & it)1306 const_iterator (const self_type &v, const const_subiterator_type &it): 1307 container_const_reference<self_type> (v), it_ (it) {} 1308 BOOST_UBLAS_INLINE const_iterator(const typename self_type::iterator & it)1309 const_iterator (const typename self_type::iterator &it): // ISSUE vector:: stops VC8 using std::iterator here 1310 container_const_reference<self_type> (it ()), it_ (it.it_) {} 1311 1312 // ---------- 1313 // Arithmetic 1314 // ---------- 1315 1316 /// \brief Increment by 1 the position of the iterator 1317 /// \return a reference to the const iterator 1318 BOOST_UBLAS_INLINE operator ++()1319 const_iterator &operator ++ () { 1320 ++ it_; 1321 return *this; 1322 } 1323 1324 /// \brief Decrement by 1 the position of the iterator 1325 /// \return a reference to the const iterator 1326 BOOST_UBLAS_INLINE operator --()1327 const_iterator &operator -- () { 1328 -- it_; 1329 return *this; 1330 } 1331 1332 /// \brief Increment by \e n the position of the iterator 1333 /// \return a reference to the const iterator 1334 BOOST_UBLAS_INLINE operator +=(difference_type n)1335 const_iterator &operator += (difference_type n) { 1336 it_ += n; 1337 return *this; 1338 } 1339 1340 /// \brief Decrement by \e n the position of the iterator 1341 /// \return a reference to the const iterator 1342 BOOST_UBLAS_INLINE operator -=(difference_type n)1343 const_iterator &operator -= (difference_type n) { 1344 it_ -= n; 1345 return *this; 1346 } 1347 1348 /// \brief Return the different in number of positions between 2 iterators 1349 BOOST_UBLAS_INLINE operator -(const const_iterator & it) const1350 difference_type operator - (const const_iterator &it) const { 1351 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ()); 1352 return it_ - it.it_; 1353 } 1354 1355 /// \brief Dereference an iterator 1356 /// Dereference an iterator: a bounds' check is done before returning the value. A bad_index() expection is returned if out of bounds. 1357 /// \return a const reference to the value pointed by the iterator 1358 BOOST_UBLAS_INLINE operator *() const1359 const_reference operator * () const { 1360 BOOST_UBLAS_CHECK (it_ >= (*this) ().begin ().it_ && it_ < (*this) ().end ().it_, bad_index ()); 1361 return *it_; 1362 } 1363 1364 /// \brief Dereference an iterator at the n-th forward value 1365 /// Dereference an iterator at the n-th forward value, that is the value pointed by iterator+n. 1366 /// A bounds' check is done before returning the value. A bad_index() expection is returned if out of bounds. 1367 /// \return a const reference 1368 BOOST_UBLAS_INLINE operator [](difference_type n) const1369 const_reference operator [] (difference_type n) const { 1370 return *(it_ + n); 1371 } 1372 1373 // Index 1374 /// \brief return the index of the element referenced by the iterator 1375 BOOST_UBLAS_INLINE index() const1376 size_type index () const { 1377 BOOST_UBLAS_CHECK (it_ >= (*this) ().begin ().it_ && it_ < (*this) ().end ().it_, bad_index ()); 1378 return it_ - (*this) ().begin ().it_; 1379 } 1380 1381 // Assignment 1382 BOOST_UBLAS_INLINE 1383 /// \brief assign the value of an iterator to the iterator operator =(const const_iterator & it)1384 const_iterator &operator = (const const_iterator &it) { 1385 container_const_reference<self_type>::assign (&it ()); 1386 it_ = it.it_; 1387 return *this; 1388 } 1389 1390 // Comparison 1391 /// \brief compare the value of two itetarors 1392 /// \return true if they reference the same element 1393 BOOST_UBLAS_INLINE operator ==(const const_iterator & it) const1394 bool operator == (const const_iterator &it) const { 1395 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ()); 1396 return it_ == it.it_; 1397 } 1398 1399 1400 /// \brief compare the value of two iterators 1401 /// \return return true if the left-hand-side iterator refers to a value placed before the right-hand-side iterator 1402 BOOST_UBLAS_INLINE operator <(const const_iterator & it) const1403 bool operator < (const const_iterator &it) const { 1404 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ()); 1405 return it_ < it.it_; 1406 } 1407 1408 private: 1409 const_subiterator_type it_; 1410 1411 friend class iterator; 1412 }; 1413 #endif 1414 1415 /// \brief return an iterator on the first element of the fixed_vector 1416 BOOST_UBLAS_INLINE begin() const1417 const_iterator begin () const { 1418 return find (0); 1419 } 1420 1421 /// \brief return an iterator on the first element of the fixed_vector 1422 BOOST_UBLAS_INLINE cbegin() const1423 const_iterator cbegin () const { 1424 return begin (); 1425 } 1426 1427 /// \brief return an iterator after the last element of the fixed_vector 1428 BOOST_UBLAS_INLINE end() const1429 const_iterator end () const { 1430 return find (data_.size ()); 1431 } 1432 1433 /// \brief return an iterator after the last element of the fixed_vector 1434 BOOST_UBLAS_INLINE cend() const1435 const_iterator cend () const { 1436 return end (); 1437 } 1438 1439 #ifndef BOOST_UBLAS_USE_INDEXED_ITERATOR 1440 class iterator: 1441 public container_reference<fixed_vector>, 1442 public random_access_iterator_base<dense_random_access_iterator_tag, 1443 iterator, value_type, difference_type> { 1444 public: 1445 typedef typename fixed_vector::difference_type difference_type; 1446 typedef typename fixed_vector::value_type value_type; 1447 typedef typename fixed_vector::reference reference; 1448 typedef typename fixed_vector::pointer pointer; 1449 1450 1451 // Construction and destruction 1452 BOOST_UBLAS_INLINE iterator()1453 iterator (): 1454 container_reference<self_type> (), it_ () {} 1455 BOOST_UBLAS_INLINE iterator(self_type & v,const subiterator_type & it)1456 iterator (self_type &v, const subiterator_type &it): 1457 container_reference<self_type> (v), it_ (it) {} 1458 1459 // Arithmetic 1460 BOOST_UBLAS_INLINE operator ++()1461 iterator &operator ++ () { 1462 ++ it_; 1463 return *this; 1464 } 1465 BOOST_UBLAS_INLINE operator --()1466 iterator &operator -- () { 1467 -- it_; 1468 return *this; 1469 } 1470 BOOST_UBLAS_INLINE operator +=(difference_type n)1471 iterator &operator += (difference_type n) { 1472 it_ += n; 1473 return *this; 1474 } 1475 BOOST_UBLAS_INLINE operator -=(difference_type n)1476 iterator &operator -= (difference_type n) { 1477 it_ -= n; 1478 return *this; 1479 } 1480 BOOST_UBLAS_INLINE operator -(const iterator & it) const1481 difference_type operator - (const iterator &it) const { 1482 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ()); 1483 return it_ - it.it_; 1484 } 1485 1486 // Dereference 1487 BOOST_UBLAS_INLINE operator *() const1488 reference operator * () const { 1489 BOOST_UBLAS_CHECK (it_ >= (*this) ().begin ().it_ && it_ < (*this) ().end ().it_ , bad_index ()); 1490 return *it_; 1491 } 1492 BOOST_UBLAS_INLINE operator [](difference_type n) const1493 reference operator [] (difference_type n) const { 1494 return *(it_ + n); 1495 } 1496 1497 // Index 1498 BOOST_UBLAS_INLINE index() const1499 size_type index () const { 1500 BOOST_UBLAS_CHECK (it_ >= (*this) ().begin ().it_ && it_ < (*this) ().end ().it_ , bad_index ()); 1501 return it_ - (*this) ().begin ().it_; 1502 } 1503 1504 // Assignment 1505 BOOST_UBLAS_INLINE operator =(const iterator & it)1506 iterator &operator = (const iterator &it) { 1507 container_reference<self_type>::assign (&it ()); 1508 it_ = it.it_; 1509 return *this; 1510 } 1511 1512 // Comparison 1513 BOOST_UBLAS_INLINE operator ==(const iterator & it) const1514 bool operator == (const iterator &it) const { 1515 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ()); 1516 return it_ == it.it_; 1517 } 1518 BOOST_UBLAS_INLINE operator <(const iterator & it) const1519 bool operator < (const iterator &it) const { 1520 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ()); 1521 return it_ < it.it_; 1522 } 1523 1524 private: 1525 subiterator_type it_; 1526 1527 friend class const_iterator; 1528 }; 1529 #endif 1530 1531 /// \brief Return an iterator on the first element of the fixed_vector 1532 BOOST_UBLAS_INLINE begin()1533 iterator begin () { 1534 return find (0); 1535 } 1536 1537 /// \brief Return an iterator at the end of the fixed_vector 1538 BOOST_UBLAS_INLINE end()1539 iterator end () { 1540 return find (data_.size ()); 1541 } 1542 1543 // Reverse iterator 1544 typedef reverse_iterator_base<const_iterator> const_reverse_iterator; 1545 typedef reverse_iterator_base<iterator> reverse_iterator; 1546 1547 /// \brief Return a const reverse iterator before the first element of the reversed fixed_vector (i.e. end() of normal fixed_vector) 1548 BOOST_UBLAS_INLINE rbegin() const1549 const_reverse_iterator rbegin () const { 1550 return const_reverse_iterator (end ()); 1551 } 1552 1553 /// \brief Return a const reverse iterator before the first element of the reversed fixed_vector (i.e. end() of normal fixed_vector) 1554 BOOST_UBLAS_INLINE crbegin() const1555 const_reverse_iterator crbegin () const { 1556 return rbegin (); 1557 } 1558 1559 /// \brief Return a const reverse iterator on the end of the reverse fixed_vector (i.e. first element of the normal fixed_vector) 1560 BOOST_UBLAS_INLINE rend() const1561 const_reverse_iterator rend () const { 1562 return const_reverse_iterator (begin ()); 1563 } 1564 1565 /// \brief Return a const reverse iterator on the end of the reverse fixed_vector (i.e. first element of the normal fixed_vector) 1566 BOOST_UBLAS_INLINE crend() const1567 const_reverse_iterator crend () const { 1568 return rend (); 1569 } 1570 1571 /// \brief Return a const reverse iterator before the first element of the reversed fixed_vector (i.e. end() of normal fixed_vector) 1572 BOOST_UBLAS_INLINE rbegin()1573 reverse_iterator rbegin () { 1574 return reverse_iterator (end ()); 1575 } 1576 1577 /// \brief Return a const reverse iterator on the end of the reverse fixed_vector (i.e. first element of the normal fixed_vector) 1578 BOOST_UBLAS_INLINE rend()1579 reverse_iterator rend () { 1580 return reverse_iterator (begin ()); 1581 } 1582 1583 // ------------- 1584 // Serialization 1585 // ------------- 1586 1587 /// Serialize a fixed_vector into and archive as defined in Boost 1588 /// \param ar Archive object. Can be a flat file, an XML file or any other stream 1589 /// \param file_version Optional file version (not yet used) 1590 template<class Archive> serialize(Archive & ar,const unsigned int)1591 void serialize(Archive & ar, const unsigned int /* file_version */){ 1592 ar & serialization::make_nvp("data",data_); 1593 } 1594 1595 private: 1596 array_type data_; 1597 }; 1598 1599 #endif // BOOST_UBLAS_CPP_GE_2011 1600 1601 // -------------------- 1602 // Bounded vector class 1603 // -------------------- 1604 1605 /// \brief a dense vector of values of type \c T, of variable size but with maximum \f$N\f$. 1606 /// A dense vector of values of type \c T, of variable size but with maximum \f$N\f$. The default constructor 1607 /// 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. 1608 template<class T, std::size_t N> 1609 class bounded_vector: 1610 public vector<T, bounded_array<T, N> > { 1611 1612 typedef vector<T, bounded_array<T, N> > vector_type; 1613 public: 1614 typedef typename vector_type::size_type size_type; 1615 static const size_type max_size = N; 1616 1617 // Construction and destruction 1618 BOOST_UBLAS_INLINE bounded_vector()1619 bounded_vector (): 1620 vector_type (N) {} 1621 BOOST_UBLAS_INLINE bounded_vector(size_type size)1622 bounded_vector (size_type size): 1623 vector_type (size) {} 1624 BOOST_UBLAS_INLINE bounded_vector(const bounded_vector & v)1625 bounded_vector (const bounded_vector &v): 1626 vector_type (v) {} 1627 template<class A2> // Allow vector<T,bounded_array<N> construction 1628 BOOST_UBLAS_INLINE bounded_vector(const vector<T,A2> & v)1629 bounded_vector (const vector<T, A2> &v): 1630 vector_type (v) {} 1631 template<class AE> 1632 BOOST_UBLAS_INLINE bounded_vector(const vector_expression<AE> & ae)1633 bounded_vector (const vector_expression<AE> &ae): 1634 vector_type (ae) {} 1635 BOOST_UBLAS_INLINE ~bounded_vector()1636 ~bounded_vector () {} 1637 1638 // Assignment 1639 #ifdef BOOST_UBLAS_MOVE_SEMANTICS 1640 1641 /*! @note "pass by value" the key idea to enable move semantics */ 1642 BOOST_UBLAS_INLINE operator =(bounded_vector v)1643 bounded_vector &operator = (bounded_vector v) { 1644 vector_type::operator = (v); 1645 return *this; 1646 } 1647 #else 1648 BOOST_UBLAS_INLINE operator =(const bounded_vector & v)1649 bounded_vector &operator = (const bounded_vector &v) { 1650 vector_type::operator = (v); 1651 return *this; 1652 } 1653 #endif 1654 template<class A2> // Generic vector assignment 1655 BOOST_UBLAS_INLINE operator =(const vector<T,A2> & v)1656 bounded_vector &operator = (const vector<T, A2> &v) { 1657 vector_type::operator = (v); 1658 return *this; 1659 } 1660 template<class C> // Container assignment without temporary 1661 BOOST_UBLAS_INLINE operator =(const vector_container<C> & v)1662 bounded_vector &operator = (const vector_container<C> &v) { 1663 vector_type::operator = (v); 1664 return *this; 1665 } 1666 template<class AE> 1667 BOOST_UBLAS_INLINE operator =(const vector_expression<AE> & ae)1668 bounded_vector &operator = (const vector_expression<AE> &ae) { 1669 vector_type::operator = (ae); 1670 return *this; 1671 } 1672 }; 1673 1674 1675 1676 // ----------------- 1677 // Zero vector class 1678 // ----------------- 1679 1680 /// \brief A zero vector of type \c T and a given \c size 1681 /// 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 1682 /// for storing the zero values: it still acts like any other vector. However assigning values to it will not change the zero 1683 /// vector into a normal vector. It must first be assigned to another normal vector by any suitable means. Its memory footprint is constant. 1684 template<class T, class ALLOC> 1685 class zero_vector: 1686 public vector_container<zero_vector<T, ALLOC> > { 1687 1688 typedef const T *const_pointer; 1689 typedef zero_vector<T, ALLOC> self_type; 1690 public: 1691 #ifdef BOOST_UBLAS_ENABLE_PROXY_SHORTCUTS 1692 using vector_container<self_type>::operator (); 1693 #endif 1694 typedef typename ALLOC::size_type size_type; 1695 typedef typename ALLOC::difference_type difference_type; 1696 typedef T value_type; 1697 typedef const T &const_reference; 1698 typedef T &reference; 1699 typedef const vector_reference<const self_type> const_closure_type; 1700 typedef vector_reference<self_type> closure_type; 1701 typedef sparse_tag storage_category; 1702 1703 // Construction and destruction 1704 BOOST_UBLAS_INLINE zero_vector()1705 zero_vector (): 1706 vector_container<self_type> (), 1707 size_ (0) {} 1708 explicit BOOST_UBLAS_INLINE zero_vector(size_type size)1709 zero_vector (size_type size): 1710 vector_container<self_type> (), 1711 size_ (size) {} 1712 BOOST_UBLAS_INLINE zero_vector(const zero_vector & v)1713 zero_vector (const zero_vector &v): 1714 vector_container<self_type> (), 1715 size_ (v.size_) {} 1716 1717 // Accessors 1718 BOOST_UBLAS_INLINE size() const1719 size_type size () const { 1720 return size_; 1721 } 1722 1723 // Resizing 1724 BOOST_UBLAS_INLINE resize(size_type size,bool=true)1725 void resize (size_type size, bool /*preserve*/ = true) { 1726 size_ = size; 1727 } 1728 1729 // Element support 1730 BOOST_UBLAS_INLINE find_element(size_type) const1731 const_pointer find_element (size_type /*i*/) const { 1732 return & zero_; 1733 } 1734 1735 // Element access 1736 BOOST_UBLAS_INLINE operator ()(size_type) const1737 const_reference operator () (size_type /* i */) const { 1738 return zero_; 1739 } 1740 1741 BOOST_UBLAS_INLINE operator [](size_type i) const1742 const_reference operator [] (size_type i) const { 1743 return (*this) (i); 1744 } 1745 1746 // Assignment 1747 BOOST_UBLAS_INLINE operator =(const zero_vector & v)1748 zero_vector &operator = (const zero_vector &v) { 1749 size_ = v.size_; 1750 return *this; 1751 } 1752 BOOST_UBLAS_INLINE assign_temporary(zero_vector & v)1753 zero_vector &assign_temporary (zero_vector &v) { 1754 swap (v); 1755 return *this; 1756 } 1757 1758 // Swapping 1759 BOOST_UBLAS_INLINE swap(zero_vector & v)1760 void swap (zero_vector &v) { 1761 if (this != &v) { 1762 std::swap (size_, v.size_); 1763 } 1764 } 1765 BOOST_UBLAS_INLINE swap(zero_vector & v1,zero_vector & v2)1766 friend void swap (zero_vector &v1, zero_vector &v2) { 1767 v1.swap (v2); 1768 } 1769 1770 // Iterator types 1771 public: 1772 class const_iterator; 1773 1774 // Element lookup 1775 BOOST_UBLAS_INLINE find(size_type) const1776 const_iterator find (size_type /*i*/) const { 1777 return const_iterator (*this); 1778 } 1779 1780 class const_iterator: 1781 public container_const_reference<zero_vector>, 1782 public bidirectional_iterator_base<sparse_bidirectional_iterator_tag, 1783 const_iterator, value_type> { 1784 public: 1785 typedef typename zero_vector::difference_type difference_type; 1786 typedef typename zero_vector::value_type value_type; 1787 typedef typename zero_vector::const_reference reference; 1788 typedef typename zero_vector::const_pointer pointer; 1789 1790 // Construction and destruction 1791 BOOST_UBLAS_INLINE const_iterator()1792 const_iterator (): 1793 container_const_reference<self_type> () {} 1794 BOOST_UBLAS_INLINE const_iterator(const self_type & v)1795 const_iterator (const self_type &v): 1796 container_const_reference<self_type> (v) {} 1797 1798 // Arithmetic 1799 BOOST_UBLAS_INLINE operator ++()1800 const_iterator &operator ++ () { 1801 BOOST_UBLAS_CHECK_FALSE (bad_index ()); 1802 return *this; 1803 } 1804 BOOST_UBLAS_INLINE operator --()1805 const_iterator &operator -- () { 1806 BOOST_UBLAS_CHECK_FALSE (bad_index ()); 1807 return *this; 1808 } 1809 1810 // Dereference 1811 BOOST_UBLAS_INLINE operator *() const1812 const_reference operator * () const { 1813 BOOST_UBLAS_CHECK_FALSE (bad_index ()); 1814 return zero_; // arbitary return value 1815 } 1816 1817 // Index 1818 BOOST_UBLAS_INLINE index() const1819 size_type index () const { 1820 BOOST_UBLAS_CHECK_FALSE (bad_index ()); 1821 return 0; // arbitary return value 1822 } 1823 1824 // Assignment 1825 BOOST_UBLAS_INLINE operator =(const const_iterator & it)1826 const_iterator &operator = (const const_iterator &it) { 1827 container_const_reference<self_type>::assign (&it ()); 1828 return *this; 1829 } 1830 1831 // Comparison 1832 BOOST_UBLAS_INLINE operator ==(const const_iterator & it) const1833 bool operator == (const const_iterator &it) const { 1834 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ()); 1835 detail::ignore_unused_variable_warning(it); 1836 return true; 1837 } 1838 }; 1839 1840 typedef const_iterator iterator; 1841 1842 BOOST_UBLAS_INLINE begin() const1843 const_iterator begin () const { 1844 return const_iterator (*this); 1845 } 1846 BOOST_UBLAS_INLINE cbegin() const1847 const_iterator cbegin () const { 1848 return begin (); 1849 } 1850 BOOST_UBLAS_INLINE end() const1851 const_iterator end () const { 1852 return const_iterator (*this); 1853 } 1854 BOOST_UBLAS_INLINE cend() const1855 const_iterator cend () const { 1856 return end (); 1857 } 1858 1859 // Reverse iterator 1860 typedef reverse_iterator_base<const_iterator> const_reverse_iterator; 1861 1862 BOOST_UBLAS_INLINE rbegin() const1863 const_reverse_iterator rbegin () const { 1864 return const_reverse_iterator (end ()); 1865 } 1866 BOOST_UBLAS_INLINE crbegin() const1867 const_reverse_iterator crbegin () const { 1868 return rbegin (); 1869 } 1870 BOOST_UBLAS_INLINE rend() const1871 const_reverse_iterator rend () const { 1872 return const_reverse_iterator (begin ()); 1873 } 1874 BOOST_UBLAS_INLINE crend() const1875 const_reverse_iterator crend () const { 1876 return rend (); 1877 } 1878 1879 // Serialization 1880 template<class Archive> serialize(Archive & ar,const unsigned int)1881 void serialize(Archive & ar, const unsigned int /* file_version */){ 1882 serialization::collection_size_type s (size_); 1883 ar & serialization::make_nvp("size",s); 1884 if (Archive::is_loading::value) { 1885 size_ = s; 1886 } 1887 } 1888 1889 private: 1890 size_type size_; 1891 typedef const value_type const_value_type; 1892 static const_value_type zero_; 1893 }; 1894 1895 template<class T, class ALLOC> 1896 typename zero_vector<T, ALLOC>::const_value_type zero_vector<T, ALLOC>::zero_ = T(/*zero*/); 1897 1898 1899 // Unit vector class 1900 /// \brief unit_vector represents a canonical unit vector 1901 /// 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$. 1902 /// At construction, the value \e k is given after the dimension of the vector. 1903 /// \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. 1904 /// \tparam ALLOC a specific allocator can be specified if needed. Most of the time this parameter is omited. 1905 template<class T, class ALLOC> 1906 class unit_vector: 1907 public vector_container<unit_vector<T, ALLOC> > { 1908 1909 typedef const T *const_pointer; 1910 typedef unit_vector<T, ALLOC> self_type; 1911 public: 1912 #ifdef BOOST_UBLAS_ENABLE_PROXY_SHORTCUTS 1913 using vector_container<self_type>::operator (); 1914 #endif 1915 typedef typename ALLOC::size_type size_type; 1916 typedef typename ALLOC::difference_type difference_type; 1917 typedef T value_type; 1918 typedef const T &const_reference; 1919 typedef T &reference; 1920 typedef const vector_reference<const self_type> const_closure_type; 1921 typedef vector_reference<self_type> closure_type; 1922 typedef sparse_tag storage_category; 1923 1924 // Construction and destruction 1925 /// \brief Simple constructor with dimension and index 0 1926 BOOST_UBLAS_INLINE unit_vector()1927 unit_vector (): 1928 vector_container<self_type> (), 1929 size_ (0), index_ (0) {} 1930 1931 /// \brief Constructor of unit_vector 1932 /// \param size is the dimension of the vector 1933 /// \param index is the order of the vector 1934 BOOST_UBLAS_INLINE unit_vector(size_type size,size_type index=0)1935 explicit unit_vector (size_type size, size_type index = 0): 1936 vector_container<self_type> (), 1937 size_ (size), index_ (index) {} 1938 1939 /// \brief Copy-constructor 1940 BOOST_UBLAS_INLINE unit_vector(const unit_vector & v)1941 unit_vector (const unit_vector &v): 1942 vector_container<self_type> (), 1943 size_ (v.size_), index_ (v.index_) {} 1944 1945 // Accessors 1946 //---------- 1947 1948 /// \brief Return the size (dimension) of the vector 1949 BOOST_UBLAS_INLINE size() const1950 size_type size () const { 1951 return size_; 1952 } 1953 1954 /// \brief Return the order of the unit vector 1955 BOOST_UBLAS_INLINE index() const1956 size_type index () const { 1957 return index_; 1958 } 1959 1960 // Resizing 1961 // -------- 1962 1963 /// \brief Resize the vector. The values are preserved by default (i.e. the index does not change) 1964 /// \param size is the new size of the vector 1965 BOOST_UBLAS_INLINE resize(size_type size,bool=true)1966 void resize (size_type size, bool /*preserve*/ = true) { 1967 size_ = size; 1968 } 1969 1970 // Element support 1971 // --------------- 1972 1973 /// \brief Return a const pointer to the element of index i 1974 BOOST_UBLAS_INLINE find_element(size_type i) const1975 const_pointer find_element (size_type i) const { 1976 if (i == index_) 1977 return & one_; 1978 else 1979 return & zero_; 1980 } 1981 1982 // Element access 1983 BOOST_UBLAS_INLINE operator ()(size_type i) const1984 const_reference operator () (size_type i) const { 1985 if (i == index_) 1986 return one_; 1987 else 1988 return zero_; 1989 } 1990 1991 BOOST_UBLAS_INLINE operator [](size_type i) const1992 const_reference operator [] (size_type i) const { 1993 return (*this) (i); 1994 } 1995 1996 // Assignment 1997 BOOST_UBLAS_INLINE operator =(const unit_vector & v)1998 unit_vector &operator = (const unit_vector &v) { 1999 size_ = v.size_; 2000 index_ = v.index_; 2001 return *this; 2002 } 2003 BOOST_UBLAS_INLINE assign_temporary(unit_vector & v)2004 unit_vector &assign_temporary (unit_vector &v) { 2005 swap (v); 2006 return *this; 2007 } 2008 2009 // Swapping 2010 BOOST_UBLAS_INLINE swap(unit_vector & v)2011 void swap (unit_vector &v) { 2012 if (this != &v) { 2013 std::swap (size_, v.size_); 2014 std::swap (index_, v.index_); 2015 } 2016 } 2017 BOOST_UBLAS_INLINE swap(unit_vector & v1,unit_vector & v2)2018 friend void swap (unit_vector &v1, unit_vector &v2) { 2019 v1.swap (v2); 2020 } 2021 2022 // Iterator types 2023 private: 2024 // Use bool to indicate begin (one_ as value) 2025 typedef bool const_subiterator_type; 2026 public: 2027 class const_iterator; 2028 2029 // Element lookup 2030 BOOST_UBLAS_INLINE find(size_type i) const2031 const_iterator find (size_type i) const { 2032 return const_iterator (*this, i <= index_); 2033 } 2034 2035 class const_iterator: 2036 public container_const_reference<unit_vector>, 2037 public bidirectional_iterator_base<sparse_bidirectional_iterator_tag, 2038 const_iterator, value_type> { 2039 public: 2040 typedef typename unit_vector::difference_type difference_type; 2041 typedef typename unit_vector::value_type value_type; 2042 typedef typename unit_vector::const_reference reference; 2043 typedef typename unit_vector::const_pointer pointer; 2044 2045 // Construction and destruction 2046 BOOST_UBLAS_INLINE const_iterator()2047 const_iterator (): 2048 container_const_reference<unit_vector> (), it_ () {} 2049 BOOST_UBLAS_INLINE const_iterator(const unit_vector & v,const const_subiterator_type & it)2050 const_iterator (const unit_vector &v, const const_subiterator_type &it): 2051 container_const_reference<unit_vector> (v), it_ (it) {} 2052 2053 // Arithmetic 2054 BOOST_UBLAS_INLINE operator ++()2055 const_iterator &operator ++ () { 2056 BOOST_UBLAS_CHECK (it_, bad_index ()); 2057 it_ = !it_; 2058 return *this; 2059 } 2060 BOOST_UBLAS_INLINE operator --()2061 const_iterator &operator -- () { 2062 BOOST_UBLAS_CHECK (!it_, bad_index ()); 2063 it_ = !it_; 2064 return *this; 2065 } 2066 2067 // Dereference 2068 BOOST_UBLAS_INLINE operator *() const2069 const_reference operator * () const { 2070 BOOST_UBLAS_CHECK (it_, bad_index ()); 2071 return one_; 2072 } 2073 2074 // Index 2075 BOOST_UBLAS_INLINE index() const2076 size_type index () const { 2077 BOOST_UBLAS_CHECK (it_, bad_index ()); 2078 return (*this) ().index_; 2079 } 2080 2081 // Assignment 2082 BOOST_UBLAS_INLINE operator =(const const_iterator & it)2083 const_iterator &operator = (const const_iterator &it) { 2084 container_const_reference<unit_vector>::assign (&it ()); 2085 it_ = it.it_; 2086 return *this; 2087 } 2088 2089 // Comparison 2090 BOOST_UBLAS_INLINE operator ==(const const_iterator & it) const2091 bool operator == (const const_iterator &it) const { 2092 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ()); 2093 return it_ == it.it_; 2094 } 2095 2096 private: 2097 const_subiterator_type it_; 2098 }; 2099 2100 typedef const_iterator iterator; 2101 2102 BOOST_UBLAS_INLINE begin() const2103 const_iterator begin () const { 2104 return const_iterator (*this, true); 2105 } 2106 BOOST_UBLAS_INLINE cbegin() const2107 const_iterator cbegin () const { 2108 return begin (); 2109 } 2110 BOOST_UBLAS_INLINE end() const2111 const_iterator end () const { 2112 return const_iterator (*this, false); 2113 } 2114 BOOST_UBLAS_INLINE cend() const2115 const_iterator cend () const { 2116 return end (); 2117 } 2118 2119 // Reverse iterator 2120 typedef reverse_iterator_base<const_iterator> const_reverse_iterator; 2121 2122 BOOST_UBLAS_INLINE rbegin() const2123 const_reverse_iterator rbegin () const { 2124 return const_reverse_iterator (end ()); 2125 } 2126 BOOST_UBLAS_INLINE crbegin() const2127 const_reverse_iterator crbegin () const { 2128 return rbegin (); 2129 } 2130 BOOST_UBLAS_INLINE rend() const2131 const_reverse_iterator rend () const { 2132 return const_reverse_iterator (begin ()); 2133 } 2134 BOOST_UBLAS_INLINE crend() const2135 const_reverse_iterator crend () const { 2136 return rend (); 2137 } 2138 2139 // Serialization 2140 template<class Archive> serialize(Archive & ar,const unsigned int)2141 void serialize(Archive & ar, const unsigned int /* file_version */){ 2142 serialization::collection_size_type s (size_); 2143 ar & serialization::make_nvp("size",s); 2144 if (Archive::is_loading::value) { 2145 size_ = s; 2146 } 2147 ar & serialization::make_nvp("index", index_); 2148 } 2149 2150 private: 2151 size_type size_; 2152 size_type index_; 2153 typedef const value_type const_value_type; 2154 static const_value_type zero_; 2155 static const_value_type one_; 2156 }; 2157 2158 template<class T, class ALLOC> 2159 typename unit_vector<T, ALLOC>::const_value_type unit_vector<T, ALLOC>::zero_ = T(/*zero*/); 2160 template<class T, class ALLOC> 2161 typename unit_vector<T, ALLOC>::const_value_type unit_vector<T, ALLOC>::one_ (1); // ISSUE: need 'one'-traits here 2162 2163 /// \brief A scalar (i.e. unique value) vector of type \c T and a given \c size 2164 /// 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 2165 /// 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. 2166 /// vector into a normal vector. It must first be assigned to another normal vector by any suitable means. Its memory footprint is constant. 2167 /// \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. 2168 template<class T, class ALLOC> 2169 class scalar_vector: 2170 public vector_container<scalar_vector<T, ALLOC> > { 2171 2172 typedef const T *const_pointer; 2173 typedef scalar_vector<T, ALLOC> self_type; 2174 public: 2175 #ifdef BOOST_UBLAS_ENABLE_PROXY_SHORTCUTS 2176 using vector_container<self_type>::operator (); 2177 #endif 2178 typedef typename ALLOC::size_type size_type; 2179 typedef typename ALLOC::difference_type difference_type; 2180 typedef T value_type; 2181 typedef const T &const_reference; 2182 typedef T &reference; 2183 typedef const vector_reference<const self_type> const_closure_type; 2184 typedef vector_reference<self_type> closure_type; 2185 typedef dense_tag storage_category; 2186 2187 // Construction and destruction 2188 BOOST_UBLAS_INLINE scalar_vector()2189 scalar_vector (): 2190 vector_container<self_type> (), 2191 size_ (0), value_ () {} 2192 BOOST_UBLAS_INLINE scalar_vector(size_type size,const value_type & value=value_type (1))2193 explicit scalar_vector (size_type size, const value_type &value = value_type(1)): 2194 vector_container<self_type> (), 2195 size_ (size), value_ (value) {} 2196 BOOST_UBLAS_INLINE scalar_vector(const scalar_vector & v)2197 scalar_vector (const scalar_vector &v): 2198 vector_container<self_type> (), 2199 size_ (v.size_), value_ (v.value_) {} 2200 2201 // Accessors 2202 BOOST_UBLAS_INLINE size() const2203 size_type size () const { 2204 return size_; 2205 } 2206 2207 // Resizing 2208 BOOST_UBLAS_INLINE resize(size_type size,bool=true)2209 void resize (size_type size, bool /*preserve*/ = true) { 2210 size_ = size; 2211 } 2212 2213 // Element support 2214 BOOST_UBLAS_INLINE find_element(size_type) const2215 const_pointer find_element (size_type /*i*/) const { 2216 return & value_; 2217 } 2218 2219 // Element access 2220 BOOST_UBLAS_INLINE operator ()(size_type) const2221 const_reference operator () (size_type /*i*/) const { 2222 return value_; 2223 } 2224 2225 BOOST_UBLAS_INLINE operator [](size_type) const2226 const_reference operator [] (size_type /*i*/) const { 2227 return value_; 2228 } 2229 2230 // Assignment 2231 BOOST_UBLAS_INLINE operator =(const scalar_vector & v)2232 scalar_vector &operator = (const scalar_vector &v) { 2233 size_ = v.size_; 2234 value_ = v.value_; 2235 return *this; 2236 } 2237 BOOST_UBLAS_INLINE assign_temporary(scalar_vector & v)2238 scalar_vector &assign_temporary (scalar_vector &v) { 2239 swap (v); 2240 return *this; 2241 } 2242 2243 // Swapping 2244 BOOST_UBLAS_INLINE swap(scalar_vector & v)2245 void swap (scalar_vector &v) { 2246 if (this != &v) { 2247 std::swap (size_, v.size_); 2248 std::swap (value_, v.value_); 2249 } 2250 } 2251 BOOST_UBLAS_INLINE swap(scalar_vector & v1,scalar_vector & v2)2252 friend void swap (scalar_vector &v1, scalar_vector &v2) { 2253 v1.swap (v2); 2254 } 2255 2256 // Iterator types 2257 private: 2258 // Use an index 2259 typedef size_type const_subiterator_type; 2260 2261 public: 2262 #ifdef BOOST_UBLAS_USE_INDEXED_ITERATOR 2263 typedef indexed_const_iterator<self_type, dense_random_access_iterator_tag> iterator; 2264 typedef indexed_const_iterator<self_type, dense_random_access_iterator_tag> const_iterator; 2265 #else 2266 class const_iterator; 2267 #endif 2268 2269 // Element lookup 2270 BOOST_UBLAS_INLINE find(size_type i) const2271 const_iterator find (size_type i) const { 2272 return const_iterator (*this, i); 2273 } 2274 2275 #ifndef BOOST_UBLAS_USE_INDEXED_ITERATOR 2276 class const_iterator: 2277 public container_const_reference<scalar_vector>, 2278 public random_access_iterator_base<dense_random_access_iterator_tag, 2279 const_iterator, value_type> { 2280 public: 2281 typedef typename scalar_vector::difference_type difference_type; 2282 typedef typename scalar_vector::value_type value_type; 2283 typedef typename scalar_vector::const_reference reference; 2284 typedef typename scalar_vector::const_pointer pointer; 2285 2286 // Construction and destruction 2287 BOOST_UBLAS_INLINE const_iterator()2288 const_iterator (): 2289 container_const_reference<scalar_vector> (), it_ () {} 2290 BOOST_UBLAS_INLINE const_iterator(const scalar_vector & v,const const_subiterator_type & it)2291 const_iterator (const scalar_vector &v, const const_subiterator_type &it): 2292 container_const_reference<scalar_vector> (v), it_ (it) {} 2293 2294 // Arithmetic 2295 BOOST_UBLAS_INLINE operator ++()2296 const_iterator &operator ++ () { 2297 ++ it_; 2298 return *this; 2299 } 2300 BOOST_UBLAS_INLINE operator --()2301 const_iterator &operator -- () { 2302 -- it_; 2303 return *this; 2304 } 2305 BOOST_UBLAS_INLINE operator +=(difference_type n)2306 const_iterator &operator += (difference_type n) { 2307 it_ += n; 2308 return *this; 2309 } 2310 BOOST_UBLAS_INLINE operator -=(difference_type n)2311 const_iterator &operator -= (difference_type n) { 2312 it_ -= n; 2313 return *this; 2314 } 2315 BOOST_UBLAS_INLINE operator -(const const_iterator & it) const2316 difference_type operator - (const const_iterator &it) const { 2317 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ()); 2318 return it_ - it.it_; 2319 } 2320 2321 // Dereference 2322 BOOST_UBLAS_INLINE operator *() const2323 const_reference operator * () const { 2324 BOOST_UBLAS_CHECK (it_ < (*this) ().size (), bad_index ()); 2325 return (*this) () (index ()); 2326 } 2327 BOOST_UBLAS_INLINE operator [](difference_type n) const2328 const_reference operator [] (difference_type n) const { 2329 return *(*this + n); 2330 } 2331 2332 // Index 2333 BOOST_UBLAS_INLINE index() const2334 size_type index () const { 2335 BOOST_UBLAS_CHECK (it_ < (*this) ().size (), bad_index ()); 2336 return it_; 2337 } 2338 2339 // Assignment 2340 BOOST_UBLAS_INLINE operator =(const const_iterator & it)2341 const_iterator &operator = (const const_iterator &it) { 2342 container_const_reference<scalar_vector>::assign (&it ()); 2343 it_ = it.it_; 2344 return *this; 2345 } 2346 2347 // Comparison 2348 BOOST_UBLAS_INLINE operator ==(const const_iterator & it) const2349 bool operator == (const const_iterator &it) const { 2350 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ()); 2351 return it_ == it.it_; 2352 } 2353 BOOST_UBLAS_INLINE operator <(const const_iterator & it) const2354 bool operator < (const const_iterator &it) const { 2355 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ()); 2356 return it_ < it.it_; 2357 } 2358 2359 private: 2360 const_subiterator_type it_; 2361 }; 2362 2363 typedef const_iterator iterator; 2364 #endif 2365 2366 BOOST_UBLAS_INLINE begin() const2367 const_iterator begin () const { 2368 return find (0); 2369 } 2370 BOOST_UBLAS_INLINE cbegin() const2371 const_iterator cbegin () const { 2372 return begin (); 2373 } 2374 BOOST_UBLAS_INLINE end() const2375 const_iterator end () const { 2376 return find (size_); 2377 } 2378 BOOST_UBLAS_INLINE cend() const2379 const_iterator cend () const { 2380 return end (); 2381 } 2382 2383 // Reverse iterator 2384 typedef reverse_iterator_base<const_iterator> const_reverse_iterator; 2385 2386 BOOST_UBLAS_INLINE rbegin() const2387 const_reverse_iterator rbegin () const { 2388 return const_reverse_iterator (end ()); 2389 } 2390 BOOST_UBLAS_INLINE crbegin() const2391 const_reverse_iterator crbegin () const { 2392 return rbegin (); 2393 } 2394 BOOST_UBLAS_INLINE rend() const2395 const_reverse_iterator rend () const { 2396 return const_reverse_iterator (begin ()); 2397 } 2398 BOOST_UBLAS_INLINE crend() const2399 const_reverse_iterator crend () const { 2400 return rend (); 2401 } 2402 2403 // Serialization 2404 template<class Archive> serialize(Archive & ar,const unsigned int)2405 void serialize(Archive & ar, const unsigned int /* file_version */){ 2406 serialization::collection_size_type s (size_); 2407 ar & serialization::make_nvp("size",s); 2408 if (Archive::is_loading::value) { 2409 size_ = s; 2410 } 2411 ar & serialization::make_nvp("value", value_); 2412 } 2413 2414 private: 2415 size_type size_; 2416 value_type value_; 2417 }; 2418 2419 // ------------------------ 2420 // Array based vector class 2421 // ------------------------ 2422 2423 /// \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] 2424 template<class T, std::size_t N> 2425 class c_vector: 2426 public vector_container<c_vector<T, N> > { 2427 2428 typedef c_vector<T, N> self_type; 2429 public: 2430 #ifdef BOOST_UBLAS_ENABLE_PROXY_SHORTCUTS 2431 using vector_container<self_type>::operator (); 2432 #endif 2433 typedef std::size_t size_type; 2434 typedef std::ptrdiff_t difference_type; 2435 typedef T value_type; 2436 typedef const T &const_reference; 2437 typedef T &reference; 2438 typedef value_type array_type[N]; 2439 typedef T *pointer; 2440 typedef const T *const_pointer; 2441 typedef const vector_reference<const self_type> const_closure_type; 2442 typedef vector_reference<self_type> closure_type; 2443 typedef self_type vector_temporary_type; 2444 typedef dense_tag storage_category; 2445 2446 // Construction and destruction 2447 BOOST_UBLAS_INLINE c_vector()2448 c_vector (): 2449 size_ (N) /* , data_ () */ {} 2450 explicit BOOST_UBLAS_INLINE c_vector(size_type size)2451 c_vector (size_type size): 2452 size_ (size) /* , data_ () */ { 2453 if (size_ > N) 2454 bad_size ().raise (); 2455 } 2456 BOOST_UBLAS_INLINE c_vector(const c_vector & v)2457 c_vector (const c_vector &v): 2458 size_ (v.size_) /* , data_ () */ { 2459 if (size_ > N) 2460 bad_size ().raise (); 2461 assign(v); 2462 } 2463 template<class AE> 2464 BOOST_UBLAS_INLINE c_vector(const vector_expression<AE> & ae)2465 c_vector (const vector_expression<AE> &ae): 2466 size_ (ae ().size ()) /* , data_ () */ { 2467 if (size_ > N) 2468 bad_size ().raise (); 2469 vector_assign<scalar_assign> (*this, ae); 2470 } 2471 2472 // Accessors 2473 BOOST_UBLAS_INLINE size() const2474 size_type size () const { 2475 return size_; 2476 } 2477 BOOST_UBLAS_INLINE data() const2478 const_pointer data () const { 2479 return data_; 2480 } 2481 BOOST_UBLAS_INLINE data()2482 pointer data () { 2483 return data_; 2484 } 2485 2486 // Resizing 2487 BOOST_UBLAS_INLINE resize(size_type size,bool=true)2488 void resize (size_type size, bool /*preserve*/ = true) { 2489 if (size > N) 2490 bad_size ().raise (); 2491 size_ = size; 2492 } 2493 2494 // Element support 2495 BOOST_UBLAS_INLINE find_element(size_type i)2496 pointer find_element (size_type i) { 2497 return const_cast<pointer> (const_cast<const self_type&>(*this).find_element (i)); 2498 } 2499 BOOST_UBLAS_INLINE find_element(size_type i) const2500 const_pointer find_element (size_type i) const { 2501 return & data_ [i]; 2502 } 2503 2504 // Element access 2505 BOOST_UBLAS_INLINE operator ()(size_type i) const2506 const_reference operator () (size_type i) const { 2507 BOOST_UBLAS_CHECK (i < size_, bad_index ()); 2508 return data_ [i]; 2509 } 2510 BOOST_UBLAS_INLINE operator ()(size_type i)2511 reference operator () (size_type i) { 2512 BOOST_UBLAS_CHECK (i < size_, bad_index ()); 2513 return data_ [i]; 2514 } 2515 2516 BOOST_UBLAS_INLINE operator [](size_type i) const2517 const_reference operator [] (size_type i) const { 2518 return (*this) (i); 2519 } 2520 BOOST_UBLAS_INLINE operator [](size_type i)2521 reference operator [] (size_type i) { 2522 return (*this) (i); 2523 } 2524 2525 // Element assignment 2526 BOOST_UBLAS_INLINE insert_element(size_type i,const_reference t)2527 reference insert_element (size_type i, const_reference t) { 2528 BOOST_UBLAS_CHECK (i < size_, bad_index ()); 2529 return (data_ [i] = t); 2530 } 2531 BOOST_UBLAS_INLINE erase_element(size_type i)2532 void erase_element (size_type i) { 2533 BOOST_UBLAS_CHECK (i < size_, bad_index ()); 2534 data_ [i] = value_type/*zero*/(); 2535 } 2536 2537 // Zeroing 2538 BOOST_UBLAS_INLINE clear()2539 void clear () { 2540 std::fill (data_, data_ + size_, value_type/*zero*/()); 2541 } 2542 2543 // Assignment 2544 #ifdef BOOST_UBLAS_MOVE_SEMANTICS 2545 2546 /*! @note "pass by value" the key idea to enable move semantics */ 2547 BOOST_UBLAS_INLINE operator =(c_vector v)2548 c_vector &operator = (c_vector v) { 2549 assign_temporary(v); 2550 return *this; 2551 } 2552 #else 2553 BOOST_UBLAS_INLINE operator =(const c_vector & v)2554 c_vector &operator = (const c_vector &v) { 2555 size_ = v.size_; 2556 std::copy (v.data_, v.data_ + v.size_, data_); 2557 return *this; 2558 } 2559 #endif 2560 template<class C> // Container assignment without temporary 2561 BOOST_UBLAS_INLINE operator =(const vector_container<C> & v)2562 c_vector &operator = (const vector_container<C> &v) { 2563 resize (v ().size (), false); 2564 assign (v); 2565 return *this; 2566 } 2567 BOOST_UBLAS_INLINE assign_temporary(c_vector & v)2568 c_vector &assign_temporary (c_vector &v) { 2569 swap (v); 2570 return *this; 2571 } 2572 template<class AE> 2573 BOOST_UBLAS_INLINE operator =(const vector_expression<AE> & ae)2574 c_vector &operator = (const vector_expression<AE> &ae) { 2575 self_type temporary (ae); 2576 return assign_temporary (temporary); 2577 } 2578 template<class AE> 2579 BOOST_UBLAS_INLINE assign(const vector_expression<AE> & ae)2580 c_vector &assign (const vector_expression<AE> &ae) { 2581 vector_assign<scalar_assign> (*this, ae); 2582 return *this; 2583 } 2584 2585 // Computed assignment 2586 template<class AE> 2587 BOOST_UBLAS_INLINE operator +=(const vector_expression<AE> & ae)2588 c_vector &operator += (const vector_expression<AE> &ae) { 2589 self_type temporary (*this + ae); 2590 return assign_temporary (temporary); 2591 } 2592 template<class C> // Container assignment without temporary 2593 BOOST_UBLAS_INLINE operator +=(const vector_container<C> & v)2594 c_vector &operator += (const vector_container<C> &v) { 2595 plus_assign (v); 2596 return *this; 2597 } 2598 template<class AE> 2599 BOOST_UBLAS_INLINE plus_assign(const vector_expression<AE> & ae)2600 c_vector &plus_assign (const vector_expression<AE> &ae) { 2601 vector_assign<scalar_plus_assign> ( *this, ae); 2602 return *this; 2603 } 2604 template<class AE> 2605 BOOST_UBLAS_INLINE operator -=(const vector_expression<AE> & ae)2606 c_vector &operator -= (const vector_expression<AE> &ae) { 2607 self_type temporary (*this - ae); 2608 return assign_temporary (temporary); 2609 } 2610 template<class C> // Container assignment without temporary 2611 BOOST_UBLAS_INLINE operator -=(const vector_container<C> & v)2612 c_vector &operator -= (const vector_container<C> &v) { 2613 minus_assign (v); 2614 return *this; 2615 } 2616 template<class AE> 2617 BOOST_UBLAS_INLINE minus_assign(const vector_expression<AE> & ae)2618 c_vector &minus_assign (const vector_expression<AE> &ae) { 2619 vector_assign<scalar_minus_assign> (*this, ae); 2620 return *this; 2621 } 2622 template<class AT> 2623 BOOST_UBLAS_INLINE operator *=(const AT & at)2624 c_vector &operator *= (const AT &at) { 2625 vector_assign_scalar<scalar_multiplies_assign> (*this, at); 2626 return *this; 2627 } 2628 template<class AT> 2629 BOOST_UBLAS_INLINE operator /=(const AT & at)2630 c_vector &operator /= (const AT &at) { 2631 vector_assign_scalar<scalar_divides_assign> (*this, at); 2632 return *this; 2633 } 2634 2635 // Swapping 2636 BOOST_UBLAS_INLINE swap(c_vector & v)2637 void swap (c_vector &v) { 2638 if (this != &v) { 2639 BOOST_UBLAS_CHECK (size_ == v.size_, bad_size ()); 2640 std::swap (size_, v.size_); 2641 std::swap_ranges (data_, data_ + size_, v.data_); 2642 } 2643 } 2644 BOOST_UBLAS_INLINE swap(c_vector & v1,c_vector & v2)2645 friend void swap (c_vector &v1, c_vector &v2) { 2646 v1.swap (v2); 2647 } 2648 2649 // Iterator types 2650 private: 2651 // Use pointers for iterator 2652 typedef const_pointer const_subiterator_type; 2653 typedef pointer subiterator_type; 2654 2655 public: 2656 #ifdef BOOST_UBLAS_USE_INDEXED_ITERATOR 2657 typedef indexed_iterator<self_type, dense_random_access_iterator_tag> iterator; 2658 typedef indexed_const_iterator<self_type, dense_random_access_iterator_tag> const_iterator; 2659 #else 2660 class const_iterator; 2661 class iterator; 2662 #endif 2663 2664 // Element lookup 2665 BOOST_UBLAS_INLINE find(size_type i) const2666 const_iterator find (size_type i) const { 2667 #ifndef BOOST_UBLAS_USE_INDEXED_ITERATOR 2668 return const_iterator (*this, &data_ [i]); 2669 #else 2670 return const_iterator (*this, i); 2671 #endif 2672 } 2673 BOOST_UBLAS_INLINE find(size_type i)2674 iterator find (size_type i) { 2675 #ifndef BOOST_UBLAS_USE_INDEXED_ITERATOR 2676 return iterator (*this, &data_ [i]); 2677 #else 2678 return iterator (*this, i); 2679 #endif 2680 } 2681 2682 #ifndef BOOST_UBLAS_USE_INDEXED_ITERATOR 2683 class const_iterator: 2684 public container_const_reference<c_vector>, 2685 public random_access_iterator_base<dense_random_access_iterator_tag, 2686 const_iterator, value_type> { 2687 public: 2688 typedef typename c_vector::difference_type difference_type; 2689 typedef typename c_vector::value_type value_type; 2690 typedef typename c_vector::const_reference reference; 2691 typedef typename c_vector::const_pointer pointer; 2692 2693 // Construction and destruction 2694 BOOST_UBLAS_INLINE const_iterator()2695 const_iterator (): 2696 container_const_reference<self_type> (), it_ () {} 2697 BOOST_UBLAS_INLINE const_iterator(const self_type & v,const const_subiterator_type & it)2698 const_iterator (const self_type &v, const const_subiterator_type &it): 2699 container_const_reference<self_type> (v), it_ (it) {} 2700 BOOST_UBLAS_INLINE const_iterator(const typename self_type::iterator & it)2701 const_iterator (const typename self_type::iterator &it): // ISSUE self_type:: stops VC8 using std::iterator here 2702 container_const_reference<self_type> (it ()), it_ (it.it_) {} 2703 2704 // Arithmetic 2705 BOOST_UBLAS_INLINE operator ++()2706 const_iterator &operator ++ () { 2707 ++ it_; 2708 return *this; 2709 } 2710 BOOST_UBLAS_INLINE operator --()2711 const_iterator &operator -- () { 2712 -- it_; 2713 return *this; 2714 } 2715 BOOST_UBLAS_INLINE operator +=(difference_type n)2716 const_iterator &operator += (difference_type n) { 2717 it_ += n; 2718 return *this; 2719 } 2720 BOOST_UBLAS_INLINE operator -=(difference_type n)2721 const_iterator &operator -= (difference_type n) { 2722 it_ -= n; 2723 return *this; 2724 } 2725 BOOST_UBLAS_INLINE operator -(const const_iterator & it) const2726 difference_type operator - (const const_iterator &it) const { 2727 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ()); 2728 return it_ - it.it_; 2729 } 2730 2731 // Dereference 2732 BOOST_UBLAS_INLINE operator *() const2733 const_reference operator * () const { 2734 BOOST_UBLAS_CHECK (it_ >= (*this) ().begin ().it_ && it_ < (*this) ().end ().it_, bad_index ()); 2735 return *it_; 2736 } 2737 BOOST_UBLAS_INLINE operator [](difference_type n) const2738 const_reference operator [] (difference_type n) const { 2739 return *(it_ + n); 2740 } 2741 2742 // Index 2743 BOOST_UBLAS_INLINE index() const2744 size_type index () const { 2745 BOOST_UBLAS_CHECK (it_ >= (*this) ().begin ().it_ && it_ < (*this) ().end ().it_, bad_index ()); 2746 const self_type &v = (*this) (); 2747 return it_ - v.begin ().it_; 2748 } 2749 2750 // Assignment 2751 BOOST_UBLAS_INLINE operator =(const const_iterator & it)2752 const_iterator &operator = (const const_iterator &it) { 2753 container_const_reference<self_type>::assign (&it ()); 2754 it_ = it.it_; 2755 return *this; 2756 } 2757 2758 // Comparison 2759 BOOST_UBLAS_INLINE operator ==(const const_iterator & it) const2760 bool operator == (const const_iterator &it) const { 2761 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ()); 2762 return it_ == it.it_; 2763 } 2764 BOOST_UBLAS_INLINE operator <(const const_iterator & it) const2765 bool operator < (const const_iterator &it) const { 2766 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ()); 2767 return it_ < it.it_; 2768 } 2769 2770 private: 2771 const_subiterator_type it_; 2772 2773 friend class iterator; 2774 }; 2775 #endif 2776 2777 BOOST_UBLAS_INLINE begin() const2778 const_iterator begin () const { 2779 return find (0); 2780 } 2781 BOOST_UBLAS_INLINE cbegin() const2782 const_iterator cbegin () const { 2783 return begin (); 2784 } 2785 BOOST_UBLAS_INLINE end() const2786 const_iterator end () const { 2787 return find (size_); 2788 } 2789 BOOST_UBLAS_INLINE cend() const2790 const_iterator cend () const { 2791 return end (); 2792 } 2793 2794 #ifndef BOOST_UBLAS_USE_INDEXED_ITERATOR 2795 class iterator: 2796 public container_reference<c_vector>, 2797 public random_access_iterator_base<dense_random_access_iterator_tag, 2798 iterator, value_type> { 2799 public: 2800 typedef typename c_vector::difference_type difference_type; 2801 typedef typename c_vector::value_type value_type; 2802 typedef typename c_vector::reference reference; 2803 typedef typename c_vector::pointer pointer; 2804 2805 // Construction and destruction 2806 BOOST_UBLAS_INLINE iterator()2807 iterator (): 2808 container_reference<self_type> (), it_ () {} 2809 BOOST_UBLAS_INLINE iterator(self_type & v,const subiterator_type & it)2810 iterator (self_type &v, const subiterator_type &it): 2811 container_reference<self_type> (v), it_ (it) {} 2812 2813 // Arithmetic 2814 BOOST_UBLAS_INLINE operator ++()2815 iterator &operator ++ () { 2816 ++ it_; 2817 return *this; 2818 } 2819 BOOST_UBLAS_INLINE operator --()2820 iterator &operator -- () { 2821 -- it_; 2822 return *this; 2823 } 2824 BOOST_UBLAS_INLINE operator +=(difference_type n)2825 iterator &operator += (difference_type n) { 2826 it_ += n; 2827 return *this; 2828 } 2829 BOOST_UBLAS_INLINE operator -=(difference_type n)2830 iterator &operator -= (difference_type n) { 2831 it_ -= n; 2832 return *this; 2833 } 2834 BOOST_UBLAS_INLINE operator -(const iterator & it) const2835 difference_type operator - (const iterator &it) const { 2836 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ()); 2837 return it_ - it.it_; 2838 } 2839 2840 // Dereference 2841 BOOST_UBLAS_INLINE operator *() const2842 reference operator * () const { 2843 BOOST_UBLAS_CHECK (it_ >= (*this) ().begin ().it_ && it_ < (*this) ().end ().it_, bad_index ()); 2844 return *it_; 2845 } 2846 BOOST_UBLAS_INLINE operator [](difference_type n) const2847 reference operator [] (difference_type n) const { 2848 return *(it_ + n); 2849 } 2850 2851 // Index 2852 BOOST_UBLAS_INLINE index() const2853 size_type index () const { 2854 BOOST_UBLAS_CHECK (it_ >= (*this) ().begin ().it_ && it_ < (*this) ().end ().it_, bad_index ()); 2855 // EDG won't allow const self_type it doesn't allow friend access to it_ 2856 self_type &v = (*this) (); 2857 return it_ - v.begin ().it_; 2858 } 2859 2860 // Assignment 2861 BOOST_UBLAS_INLINE operator =(const iterator & it)2862 iterator &operator = (const iterator &it) { 2863 container_reference<self_type>::assign (&it ()); 2864 it_ = it.it_; 2865 return *this; 2866 } 2867 2868 // Comparison 2869 BOOST_UBLAS_INLINE operator ==(const iterator & it) const2870 bool operator == (const iterator &it) const { 2871 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ()); 2872 return it_ == it.it_; 2873 } 2874 BOOST_UBLAS_INLINE operator <(const iterator & it) const2875 bool operator < (const iterator &it) const { 2876 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ()); 2877 return it_ < it.it_; 2878 } 2879 2880 private: 2881 subiterator_type it_; 2882 2883 friend class const_iterator; 2884 }; 2885 #endif 2886 2887 BOOST_UBLAS_INLINE begin()2888 iterator begin () { 2889 return find (0); 2890 } 2891 BOOST_UBLAS_INLINE end()2892 iterator end () { 2893 return find (size_); 2894 } 2895 2896 // Reverse iterator 2897 typedef reverse_iterator_base<const_iterator> const_reverse_iterator; 2898 typedef reverse_iterator_base<iterator> reverse_iterator; 2899 2900 BOOST_UBLAS_INLINE rbegin() const2901 const_reverse_iterator rbegin () const { 2902 return const_reverse_iterator (end ()); 2903 } 2904 BOOST_UBLAS_INLINE crbegin() const2905 const_reverse_iterator crbegin () const { 2906 return rbegin (); 2907 } 2908 BOOST_UBLAS_INLINE rend() const2909 const_reverse_iterator rend () const { 2910 return const_reverse_iterator (begin ()); 2911 } 2912 BOOST_UBLAS_INLINE crend() const2913 const_reverse_iterator crend () const { 2914 return rend (); 2915 } 2916 BOOST_UBLAS_INLINE rbegin()2917 reverse_iterator rbegin () { 2918 return reverse_iterator (end ()); 2919 } 2920 BOOST_UBLAS_INLINE rend()2921 reverse_iterator rend () { 2922 return reverse_iterator (begin ()); 2923 } 2924 2925 // Serialization 2926 template<class Archive> serialize(Archive & ar,const unsigned int)2927 void serialize(Archive & ar, const unsigned int /* file_version */){ 2928 serialization::collection_size_type s (size_); 2929 ar & serialization::make_nvp("size",s); 2930 2931 // copy the value back if loading 2932 if (Archive::is_loading::value) { 2933 if (s > N) bad_size("too large size in bounded_vector::load()\n").raise(); 2934 size_ = s; 2935 } 2936 // ISSUE: this writes the full array 2937 ar & serialization::make_nvp("data",data_); 2938 } 2939 2940 private: 2941 size_type size_; 2942 array_type data_; 2943 }; 2944 2945 }}} 2946 2947 #endif 2948