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
37namespace 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
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
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
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
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
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
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
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
141 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
148 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
158 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
168 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
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
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
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
210 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
222 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
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
237 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
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
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
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
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
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
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
307 vector &operator = (const vector_container<C> &v) {
308 resize (size: v ().size (), preserve: 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
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
329 vector &operator = (const vector_expression<AE> &ae) {
330 self_type temporary (ae);
331 return assign_temporary (v&: 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
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
358 vector &operator += (const vector_expression<AE> &ae) {
359 self_type temporary (*this + ae);
360 return assign_temporary (v&: 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
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
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
396 vector &operator -= (const vector_expression<AE> &ae) {
397 self_type temporary (*this - ae);
398 return assign_temporary (v&: 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
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
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
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
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
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
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
496 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
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
532 const_iterator ():
533 container_const_reference<self_type> (), it_ () {}
534 BOOST_UBLAS_INLINE
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
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
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
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
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
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
579 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
588 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
598 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
605 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
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
623 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
632 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
646 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
652 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
658 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
664 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
682 iterator ():
683 container_reference<self_type> (), it_ () {}
684 BOOST_UBLAS_INLINE
685 iterator (self_type &v, const subiterator_type &it):
686 container_reference<self_type> (v), it_ (it) {}
687
688 // Arithmetic
689 BOOST_UBLAS_INLINE
690 iterator &operator ++ () {
691 ++ it_;
692 return *this;
693 }
694 BOOST_UBLAS_INLINE
695 iterator &operator -- () {
696 -- it_;
697 return *this;
698 }
699 BOOST_UBLAS_INLINE
700 iterator &operator += (difference_type n) {
701 it_ += n;
702 return *this;
703 }
704 BOOST_UBLAS_INLINE
705 iterator &operator -= (difference_type n) {
706 it_ -= n;
707 return *this;
708 }
709 BOOST_UBLAS_INLINE
710 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
717 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
722 reference operator [] (difference_type n) const {
723 return *(it_ + n);
724 }
725
726 // Index
727 BOOST_UBLAS_INLINE
728 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
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
743 bool operator == (const iterator &it) const {
744 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
745 return it_ == it.it_;
746 }
747 BOOST_UBLAS_INLINE
748 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
762 iterator begin () {
763 return find (0);
764 }
765
766 /// \brief Return an iterator at the end of the vector
767 BOOST_UBLAS_INLINE
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
778 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
784 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
790 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
796 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
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
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>
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
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
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
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
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
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
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
922 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
929 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
939 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
949 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
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
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
975 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
988 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
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
1005 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
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
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
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
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
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
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
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
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
1100 fixed_vector &operator = (const vector_expression<AE> &ae) {
1101 self_type temporary (ae);
1102 return assign_temporary (v&: 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
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
1129 fixed_vector &operator += (const vector_expression<AE> &ae) {
1130 self_type temporary (*this + ae);
1131 return assign_temporary (v&: 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
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
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
1167 fixed_vector &operator -= (const vector_expression<AE> &ae) {
1168 self_type temporary (*this - ae);
1169 return assign_temporary (v&: 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
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
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
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
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
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
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
1267 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
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
1303 const_iterator ():
1304 container_const_reference<self_type> (), it_ () {}
1305 BOOST_UBLAS_INLINE
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
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
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
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
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
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
1350 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
1359 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
1369 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
1376 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
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
1394 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
1403 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
1417 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
1423 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
1429 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
1435 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
1453 iterator ():
1454 container_reference<self_type> (), it_ () {}
1455 BOOST_UBLAS_INLINE
1456 iterator (self_type &v, const subiterator_type &it):
1457 container_reference<self_type> (v), it_ (it) {}
1458
1459 // Arithmetic
1460 BOOST_UBLAS_INLINE
1461 iterator &operator ++ () {
1462 ++ it_;
1463 return *this;
1464 }
1465 BOOST_UBLAS_INLINE
1466 iterator &operator -- () {
1467 -- it_;
1468 return *this;
1469 }
1470 BOOST_UBLAS_INLINE
1471 iterator &operator += (difference_type n) {
1472 it_ += n;
1473 return *this;
1474 }
1475 BOOST_UBLAS_INLINE
1476 iterator &operator -= (difference_type n) {
1477 it_ -= n;
1478 return *this;
1479 }
1480 BOOST_UBLAS_INLINE
1481 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
1488 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
1493 reference operator [] (difference_type n) const {
1494 return *(it_ + n);
1495 }
1496
1497 // Index
1498 BOOST_UBLAS_INLINE
1499 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
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
1514 bool operator == (const iterator &it) const {
1515 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
1516 return it_ == it.it_;
1517 }
1518 BOOST_UBLAS_INLINE
1519 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
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
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
1549 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
1555 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
1561 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
1567 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
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
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>
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
1619 bounded_vector ():
1620 vector_type (N) {}
1621 BOOST_UBLAS_INLINE
1622 bounded_vector (size_type size):
1623 vector_type (size) {}
1624 BOOST_UBLAS_INLINE
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
1629 bounded_vector (const vector<T, A2> &v):
1630 vector_type (v) {}
1631 template<class AE>
1632 BOOST_UBLAS_INLINE
1633 bounded_vector (const vector_expression<AE> &ae):
1634 vector_type (ae) {}
1635 BOOST_UBLAS_INLINE
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
1643 bounded_vector &operator = (bounded_vector v) {
1644 vector_type::operator = (v);
1645 return *this;
1646 }
1647#else
1648 BOOST_UBLAS_INLINE
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
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
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
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 boost::allocator_size_type<ALLOC>::type size_type;
1695 typedef typename boost::allocator_difference_type<ALLOC>::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
1705 zero_vector ():
1706 vector_container<self_type> (),
1707 size_ (0) {}
1708 explicit BOOST_UBLAS_INLINE
1709 zero_vector (size_type size):
1710 vector_container<self_type> (),
1711 size_ (size) {}
1712 BOOST_UBLAS_INLINE
1713 zero_vector (const zero_vector &v):
1714 vector_container<self_type> (),
1715 size_ (v.size_) {}
1716
1717 // Accessors
1718 BOOST_UBLAS_INLINE
1719 size_type size () const {
1720 return size_;
1721 }
1722
1723 // Resizing
1724 BOOST_UBLAS_INLINE
1725 void resize (size_type size, bool /*preserve*/ = true) {
1726 size_ = size;
1727 }
1728
1729 // Element support
1730 BOOST_UBLAS_INLINE
1731 const_pointer find_element (size_type /*i*/) const {
1732 return & zero_;
1733 }
1734
1735 // Element access
1736 BOOST_UBLAS_INLINE
1737 const_reference operator () (size_type /* i */) const {
1738 return zero_;
1739 }
1740
1741 BOOST_UBLAS_INLINE
1742 const_reference operator [] (size_type i) const {
1743 return (*this) (i);
1744 }
1745
1746 // Assignment
1747 BOOST_UBLAS_INLINE
1748 zero_vector &operator = (const zero_vector &v) {
1749 size_ = v.size_;
1750 return *this;
1751 }
1752 BOOST_UBLAS_INLINE
1753 zero_vector &assign_temporary (zero_vector &v) {
1754 swap (v);
1755 return *this;
1756 }
1757
1758 // Swapping
1759 BOOST_UBLAS_INLINE
1760 void swap (zero_vector &v) {
1761 if (this != &v) {
1762 std::swap (size_, v.size_);
1763 }
1764 }
1765 BOOST_UBLAS_INLINE
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
1776 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
1792 const_iterator ():
1793 container_const_reference<self_type> () {}
1794 BOOST_UBLAS_INLINE
1795 const_iterator (const self_type &v):
1796 container_const_reference<self_type> (v) {}
1797
1798 // Arithmetic
1799 BOOST_UBLAS_INLINE
1800 const_iterator &operator ++ () {
1801 BOOST_UBLAS_CHECK_FALSE (bad_index ());
1802 return *this;
1803 }
1804 BOOST_UBLAS_INLINE
1805 const_iterator &operator -- () {
1806 BOOST_UBLAS_CHECK_FALSE (bad_index ());
1807 return *this;
1808 }
1809
1810 // Dereference
1811 BOOST_UBLAS_INLINE
1812 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
1819 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
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
1833 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
1843 const_iterator begin () const {
1844 return const_iterator (*this);
1845 }
1846 BOOST_UBLAS_INLINE
1847 const_iterator cbegin () const {
1848 return begin ();
1849 }
1850 BOOST_UBLAS_INLINE
1851 const_iterator end () const {
1852 return const_iterator (*this);
1853 }
1854 BOOST_UBLAS_INLINE
1855 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
1863 const_reverse_iterator rbegin () const {
1864 return const_reverse_iterator (end ());
1865 }
1866 BOOST_UBLAS_INLINE
1867 const_reverse_iterator crbegin () const {
1868 return rbegin ();
1869 }
1870 BOOST_UBLAS_INLINE
1871 const_reverse_iterator rend () const {
1872 return const_reverse_iterator (begin ());
1873 }
1874 BOOST_UBLAS_INLINE
1875 const_reverse_iterator crend () const {
1876 return rend ();
1877 }
1878
1879 // Serialization
1880 template<class Archive>
1881 void serialize(Archive & ar, const unsigned int /* file_version */){
1882 serialization::collection_size_type s (size_);
1883 ar & serialization::make_nvp(n: "size",v&: 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 boost::allocator_size_type<ALLOC>::type size_type;
1916 typedef typename boost::allocator_difference_type<ALLOC>::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
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
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
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
1950 size_type size () const {
1951 return size_;
1952 }
1953
1954 /// \brief Return the order of the unit vector
1955 BOOST_UBLAS_INLINE
1956 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
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
1975 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
1984 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
1992 const_reference operator [] (size_type i) const {
1993 return (*this) (i);
1994 }
1995
1996 // Assignment
1997 BOOST_UBLAS_INLINE
1998 unit_vector &operator = (const unit_vector &v) {
1999 size_ = v.size_;
2000 index_ = v.index_;
2001 return *this;
2002 }
2003 BOOST_UBLAS_INLINE
2004 unit_vector &assign_temporary (unit_vector &v) {
2005 swap (v);
2006 return *this;
2007 }
2008
2009 // Swapping
2010 BOOST_UBLAS_INLINE
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
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
2031 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
2047 const_iterator ():
2048 container_const_reference<unit_vector> (), it_ () {}
2049 BOOST_UBLAS_INLINE
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
2055 const_iterator &operator ++ () {
2056 BOOST_UBLAS_CHECK (it_, bad_index ());
2057 it_ = !it_;
2058 return *this;
2059 }
2060 BOOST_UBLAS_INLINE
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
2069 const_reference operator * () const {
2070 BOOST_UBLAS_CHECK (it_, bad_index ());
2071 return one_;
2072 }
2073
2074 // Index
2075 BOOST_UBLAS_INLINE
2076 size_type index () const {
2077 BOOST_UBLAS_CHECK (it_, bad_index ());
2078 return (*this) ().index_;
2079 }
2080
2081 // Assignment
2082 BOOST_UBLAS_INLINE
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
2091 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
2103 const_iterator begin () const {
2104 return const_iterator (*this, true);
2105 }
2106 BOOST_UBLAS_INLINE
2107 const_iterator cbegin () const {
2108 return begin ();
2109 }
2110 BOOST_UBLAS_INLINE
2111 const_iterator end () const {
2112 return const_iterator (*this, false);
2113 }
2114 BOOST_UBLAS_INLINE
2115 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
2123 const_reverse_iterator rbegin () const {
2124 return const_reverse_iterator (end ());
2125 }
2126 BOOST_UBLAS_INLINE
2127 const_reverse_iterator crbegin () const {
2128 return rbegin ();
2129 }
2130 BOOST_UBLAS_INLINE
2131 const_reverse_iterator rend () const {
2132 return const_reverse_iterator (begin ());
2133 }
2134 BOOST_UBLAS_INLINE
2135 const_reverse_iterator crend () const {
2136 return rend ();
2137 }
2138
2139 // Serialization
2140 template<class Archive>
2141 void serialize(Archive & ar, const unsigned int /* file_version */){
2142 serialization::collection_size_type s (size_);
2143 ar & serialization::make_nvp(n: "size",v&: 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 boost::allocator_size_type<ALLOC>::type size_type;
2179 typedef typename boost::allocator_difference_type<ALLOC>::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
2189 scalar_vector ():
2190 vector_container<self_type> (),
2191 size_ (0), value_ () {}
2192 BOOST_UBLAS_INLINE
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
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
2203 size_type size () const {
2204 return size_;
2205 }
2206
2207 // Resizing
2208 BOOST_UBLAS_INLINE
2209 void resize (size_type size, bool /*preserve*/ = true) {
2210 size_ = size;
2211 }
2212
2213 // Element support
2214 BOOST_UBLAS_INLINE
2215 const_pointer find_element (size_type /*i*/) const {
2216 return & value_;
2217 }
2218
2219 // Element access
2220 BOOST_UBLAS_INLINE
2221 const_reference operator () (size_type /*i*/) const {
2222 return value_;
2223 }
2224
2225 BOOST_UBLAS_INLINE
2226 const_reference operator [] (size_type /*i*/) const {
2227 return value_;
2228 }
2229
2230 // Assignment
2231 BOOST_UBLAS_INLINE
2232 scalar_vector &operator = (const scalar_vector &v) {
2233 size_ = v.size_;
2234 value_ = v.value_;
2235 return *this;
2236 }
2237 BOOST_UBLAS_INLINE
2238 scalar_vector &assign_temporary (scalar_vector &v) {
2239 swap (v);
2240 return *this;
2241 }
2242
2243 // Swapping
2244 BOOST_UBLAS_INLINE
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
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
2271 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
2288 const_iterator ():
2289 container_const_reference<scalar_vector> (), it_ () {}
2290 BOOST_UBLAS_INLINE
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
2296 const_iterator &operator ++ () {
2297 ++ it_;
2298 return *this;
2299 }
2300 BOOST_UBLAS_INLINE
2301 const_iterator &operator -- () {
2302 -- it_;
2303 return *this;
2304 }
2305 BOOST_UBLAS_INLINE
2306 const_iterator &operator += (difference_type n) {
2307 it_ += n;
2308 return *this;
2309 }
2310 BOOST_UBLAS_INLINE
2311 const_iterator &operator -= (difference_type n) {
2312 it_ -= n;
2313 return *this;
2314 }
2315 BOOST_UBLAS_INLINE
2316 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
2323 const_reference operator * () const {
2324 BOOST_UBLAS_CHECK (it_ < (*this) ().size (), bad_index ());
2325 return (*this) () (index ());
2326 }
2327 BOOST_UBLAS_INLINE
2328 const_reference operator [] (difference_type n) const {
2329 return *(*this + n);
2330 }
2331
2332 // Index
2333 BOOST_UBLAS_INLINE
2334 size_type index () const {
2335 BOOST_UBLAS_CHECK (it_ < (*this) ().size (), bad_index ());
2336 return it_;
2337 }
2338
2339 // Assignment
2340 BOOST_UBLAS_INLINE
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
2349 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
2354 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
2367 const_iterator begin () const {
2368 return find (i: 0);
2369 }
2370 BOOST_UBLAS_INLINE
2371 const_iterator cbegin () const {
2372 return begin ();
2373 }
2374 BOOST_UBLAS_INLINE
2375 const_iterator end () const {
2376 return find (i: size_);
2377 }
2378 BOOST_UBLAS_INLINE
2379 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
2387 const_reverse_iterator rbegin () const {
2388 return const_reverse_iterator (end ());
2389 }
2390 BOOST_UBLAS_INLINE
2391 const_reverse_iterator crbegin () const {
2392 return rbegin ();
2393 }
2394 BOOST_UBLAS_INLINE
2395 const_reverse_iterator rend () const {
2396 return const_reverse_iterator (begin ());
2397 }
2398 BOOST_UBLAS_INLINE
2399 const_reverse_iterator crend () const {
2400 return rend ();
2401 }
2402
2403 // Serialization
2404 template<class Archive>
2405 void serialize(Archive & ar, const unsigned int /* file_version */){
2406 serialization::collection_size_type s (size_);
2407 ar & serialization::make_nvp(n: "size",v&: 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
2448 c_vector ():
2449 size_ (N) /* , data_ () */ {}
2450 explicit BOOST_UBLAS_INLINE
2451 c_vector (size_type size):
2452 size_ (size) /* , data_ () */ {
2453 if (size_ > N)
2454 bad_size ().raise ();
2455 }
2456 BOOST_UBLAS_INLINE
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
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
2474 size_type size () const {
2475 return size_;
2476 }
2477 BOOST_UBLAS_INLINE
2478 const_pointer data () const {
2479 return data_;
2480 }
2481 BOOST_UBLAS_INLINE
2482 pointer data () {
2483 return data_;
2484 }
2485
2486 // Resizing
2487 BOOST_UBLAS_INLINE
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
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
2500 const_pointer find_element (size_type i) const {
2501 return & data_ [i];
2502 }
2503
2504 // Element access
2505 BOOST_UBLAS_INLINE
2506 const_reference operator () (size_type i) const {
2507 BOOST_UBLAS_CHECK (i < size_, bad_index ());
2508 return data_ [i];
2509 }
2510 BOOST_UBLAS_INLINE
2511 reference operator () (size_type i) {
2512 BOOST_UBLAS_CHECK (i < size_, bad_index ());
2513 return data_ [i];
2514 }
2515
2516 BOOST_UBLAS_INLINE
2517 const_reference operator [] (size_type i) const {
2518 return (*this) (i);
2519 }
2520 BOOST_UBLAS_INLINE
2521 reference operator [] (size_type i) {
2522 return (*this) (i);
2523 }
2524
2525 // Element assignment
2526 BOOST_UBLAS_INLINE
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
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
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
2548 c_vector &operator = (c_vector v) {
2549 assign_temporary(v);
2550 return *this;
2551 }
2552#else
2553 BOOST_UBLAS_INLINE
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
2562 c_vector &operator = (const vector_container<C> &v) {
2563 resize (size: v ().size (), false);
2564 assign (v);
2565 return *this;
2566 }
2567 BOOST_UBLAS_INLINE
2568 c_vector &assign_temporary (c_vector &v) {
2569 swap (v);
2570 return *this;
2571 }
2572 template<class AE>
2573 BOOST_UBLAS_INLINE
2574 c_vector &operator = (const vector_expression<AE> &ae) {
2575 self_type temporary (ae);
2576 return assign_temporary (v&: temporary);
2577 }
2578 template<class AE>
2579 BOOST_UBLAS_INLINE
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
2588 c_vector &operator += (const vector_expression<AE> &ae) {
2589 self_type temporary (*this + ae);
2590 return assign_temporary (v&: temporary);
2591 }
2592 template<class C> // Container assignment without temporary
2593 BOOST_UBLAS_INLINE
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
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
2606 c_vector &operator -= (const vector_expression<AE> &ae) {
2607 self_type temporary (*this - ae);
2608 return assign_temporary (v&: temporary);
2609 }
2610 template<class C> // Container assignment without temporary
2611 BOOST_UBLAS_INLINE
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
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
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
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
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
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
2666 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
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
2695 const_iterator ():
2696 container_const_reference<self_type> (), it_ () {}
2697 BOOST_UBLAS_INLINE
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
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
2706 const_iterator &operator ++ () {
2707 ++ it_;
2708 return *this;
2709 }
2710 BOOST_UBLAS_INLINE
2711 const_iterator &operator -- () {
2712 -- it_;
2713 return *this;
2714 }
2715 BOOST_UBLAS_INLINE
2716 const_iterator &operator += (difference_type n) {
2717 it_ += n;
2718 return *this;
2719 }
2720 BOOST_UBLAS_INLINE
2721 const_iterator &operator -= (difference_type n) {
2722 it_ -= n;
2723 return *this;
2724 }
2725 BOOST_UBLAS_INLINE
2726 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
2733 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
2738 const_reference operator [] (difference_type n) const {
2739 return *(it_ + n);
2740 }
2741
2742 // Index
2743 BOOST_UBLAS_INLINE
2744 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
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
2760 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
2765 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
2778 const_iterator begin () const {
2779 return find (0);
2780 }
2781 BOOST_UBLAS_INLINE
2782 const_iterator cbegin () const {
2783 return begin ();
2784 }
2785 BOOST_UBLAS_INLINE
2786 const_iterator end () const {
2787 return find (size_);
2788 }
2789 BOOST_UBLAS_INLINE
2790 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
2807 iterator ():
2808 container_reference<self_type> (), it_ () {}
2809 BOOST_UBLAS_INLINE
2810 iterator (self_type &v, const subiterator_type &it):
2811 container_reference<self_type> (v), it_ (it) {}
2812
2813 // Arithmetic
2814 BOOST_UBLAS_INLINE
2815 iterator &operator ++ () {
2816 ++ it_;
2817 return *this;
2818 }
2819 BOOST_UBLAS_INLINE
2820 iterator &operator -- () {
2821 -- it_;
2822 return *this;
2823 }
2824 BOOST_UBLAS_INLINE
2825 iterator &operator += (difference_type n) {
2826 it_ += n;
2827 return *this;
2828 }
2829 BOOST_UBLAS_INLINE
2830 iterator &operator -= (difference_type n) {
2831 it_ -= n;
2832 return *this;
2833 }
2834 BOOST_UBLAS_INLINE
2835 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
2842 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
2847 reference operator [] (difference_type n) const {
2848 return *(it_ + n);
2849 }
2850
2851 // Index
2852 BOOST_UBLAS_INLINE
2853 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
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
2870 bool operator == (const iterator &it) const {
2871 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
2872 return it_ == it.it_;
2873 }
2874 BOOST_UBLAS_INLINE
2875 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
2888 iterator begin () {
2889 return find (0);
2890 }
2891 BOOST_UBLAS_INLINE
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
2901 const_reverse_iterator rbegin () const {
2902 return const_reverse_iterator (end ());
2903 }
2904 BOOST_UBLAS_INLINE
2905 const_reverse_iterator crbegin () const {
2906 return rbegin ();
2907 }
2908 BOOST_UBLAS_INLINE
2909 const_reverse_iterator rend () const {
2910 return const_reverse_iterator (begin ());
2911 }
2912 BOOST_UBLAS_INLINE
2913 const_reverse_iterator crend () const {
2914 return rend ();
2915 }
2916 BOOST_UBLAS_INLINE
2917 reverse_iterator rbegin () {
2918 return reverse_iterator (end ());
2919 }
2920 BOOST_UBLAS_INLINE
2921 reverse_iterator rend () {
2922 return reverse_iterator (begin ());
2923 }
2924
2925 // Serialization
2926 template<class Archive>
2927 void serialize(Archive & ar, const unsigned int /* file_version */){
2928 serialization::collection_size_type s (size_);
2929 ar & serialization::make_nvp(n: "size",v&: 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

source code of boost/libs/numeric/ublas/include/boost/numeric/ublas/vector.hpp