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