comparison DEPENDENCIES/generic/include/boost/numeric/ublas/vector.hpp @ 16:2665513ce2d3

Add boost headers
author Chris Cannam
date Tue, 05 Aug 2014 11:11:38 +0100
parents
children c530137014c0
comparison
equal deleted inserted replaced
15:663ca0da4350 16:2665513ce2d3
1 //
2 // Copyright (c) 2000-2010
3 // Joerg Walter, Mathias Koch, David Bellot
4 //
5 // Distributed under the Boost Software License, Version 1.0. (See
6 // accompanying file LICENSE_1_0.txt or copy at
7 // http://www.boost.org/LICENSE_1_0.txt)
8 //
9 // The authors gratefully acknowledge the support of
10 // GeNeSys mbH & Co. KG in producing this work.
11 //
12 // And we acknowledge the support from all contributors.
13
14 /// \file vector.hpp Definition for the class vector and its derivative
15
16 #ifndef _BOOST_UBLAS_VECTOR_
17 #define _BOOST_UBLAS_VECTOR_
18
19 #include <boost/numeric/ublas/storage.hpp>
20 #include <boost/numeric/ublas/vector_expression.hpp>
21 #include <boost/numeric/ublas/detail/vector_assign.hpp>
22 #include <boost/serialization/collection_size_type.hpp>
23 #include <boost/serialization/nvp.hpp>
24
25
26 // Iterators based on ideas of Jeremy Siek
27
28 namespace boost { namespace numeric { namespace ublas {
29
30 /** \brief A dense vector of values of type \c T.
31 *
32 * 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
33 * to the \f$i\f$-th element of the container. A storage type \c A can be specified which defaults to \c unbounded_array.
34 * Elements are constructed by \c A, which need not initialise their value.
35 *
36 * \tparam T type of the objects stored in the vector (like int, double, complex,...)
37 * \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
38 */
39 template<class T, class A>
40 class vector:
41 public vector_container<vector<T, A> > {
42
43 typedef vector<T, A> self_type;
44 public:
45 #ifdef BOOST_UBLAS_ENABLE_PROXY_SHORTCUTS
46 using vector_container<self_type>::operator ();
47 #endif
48
49 typedef typename A::size_type size_type;
50 typedef typename A::difference_type difference_type;
51 typedef T value_type;
52 typedef typename type_traits<T>::const_reference const_reference;
53 typedef T &reference;
54 typedef T *pointer;
55 typedef const T *const_pointer;
56 typedef A array_type;
57 typedef const vector_reference<const self_type> const_closure_type;
58 typedef vector_reference<self_type> closure_type;
59 typedef self_type vector_temporary_type;
60 typedef dense_tag storage_category;
61
62 // Construction and destruction
63
64 /// \brief Constructor of a vector
65 /// By default it is empty, i.e. \c size()==0.
66 BOOST_UBLAS_INLINE
67 vector ():
68 vector_container<self_type> (),
69 data_ () {}
70
71 /// \brief Constructor of a vector with a predefined size
72 /// By default, its elements are initialized to 0.
73 /// \param size initial size of the vector
74 explicit BOOST_UBLAS_INLINE
75 vector (size_type size):
76 vector_container<self_type> (),
77 data_ (size) {
78 }
79
80 /// \brief Constructor of a vector by copying from another container
81 /// This type has the generic name \c array_typ within the vector definition.
82 /// \param size initial size of the vector \bug this value is not used
83 /// \param data container of type \c A
84 /// \todo remove this definition because \c size is not used
85 BOOST_UBLAS_INLINE
86 vector (size_type size, const array_type &data):
87 vector_container<self_type> (),
88 data_ (data) {}
89
90 /// \brief Constructor of a vector by copying from another container
91 /// This type has the generic name \c array_typ within the vector definition.
92 /// \param data container of type \c A
93 BOOST_UBLAS_INLINE
94 vector (const array_type &data):
95 vector_container<self_type> (),
96 data_ (data) {}
97
98 /// \brief Constructor of a vector with a predefined size and a unique initial value
99 /// \param size of the vector
100 /// \param init value to assign to each element of the vector
101 BOOST_UBLAS_INLINE
102 vector (size_type size, const value_type &init):
103 vector_container<self_type> (),
104 data_ (size, init) {}
105
106 /// \brief Copy-constructor of a vector
107 /// \param v is the vector to be duplicated
108 BOOST_UBLAS_INLINE
109 vector (const vector &v):
110 vector_container<self_type> (),
111 data_ (v.data_) {}
112
113 /// \brief Copy-constructor of a vector from a vector_expression
114 /// Depending on the vector_expression, this constructor can have the cost of the computations
115 /// of the expression (trivial to say it, but it is to take into account in your complexity calculations).
116 /// \param ae the vector_expression which values will be duplicated into the vector
117 template<class AE>
118 BOOST_UBLAS_INLINE
119 vector (const vector_expression<AE> &ae):
120 vector_container<self_type> (),
121 data_ (ae ().size ()) {
122 vector_assign<scalar_assign> (*this, ae);
123 }
124
125 // -----------------------
126 // Random Access Container
127 // -----------------------
128
129 /// \brief Return the maximum size of the data container.
130 /// 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.
131 BOOST_UBLAS_INLINE
132 size_type max_size () const {
133 return data_.max_size ();
134 }
135
136 /// \brief Return true if the vector is empty (\c size==0)
137 /// \return \c true if empty, \c false otherwise
138 BOOST_UBLAS_INLINE
139 bool empty () const {
140 return data_.size () == 0;
141 }
142
143 // ---------
144 // Accessors
145 // ---------
146
147 /// \brief Return the size of the vector
148 BOOST_UBLAS_INLINE
149 size_type size () const {
150 return data_.size ();
151 }
152
153 // -----------------
154 // Storage accessors
155 // -----------------
156
157 /// \brief Return a \c const reference to the container. Useful to access data directly for specific type of container.
158 BOOST_UBLAS_INLINE
159 const array_type &data () const {
160 return data_;
161 }
162
163 /// \brief Return a reference to the container. Useful to speed-up write operations to the data in very specific case.
164 BOOST_UBLAS_INLINE
165 array_type &data () {
166 return data_;
167 }
168
169 // --------
170 // Resizing
171 // --------
172
173 /// \brief Resize the vector
174 /// 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.
175 /// \param size new size of the vector
176 /// \param preserve if true, keep values
177 BOOST_UBLAS_INLINE
178 void resize (size_type size, bool preserve = true) {
179 if (preserve)
180 data ().resize (size, typename A::value_type ());
181 else
182 data ().resize (size);
183 }
184
185 // ---------------
186 // Element support
187 // ---------------
188
189 /// \brief Return a pointer to the element \f$i\f$
190 /// \param i index of the element
191 // XXX this semantic is not the one expected by the name of this method
192 BOOST_UBLAS_INLINE
193 pointer find_element (size_type i) {
194 return const_cast<pointer> (const_cast<const self_type&>(*this).find_element (i));
195 }
196
197 /// \brief Return a const pointer to the element \f$i\f$
198 /// \param i index of the element
199 // XXX this semantic is not the one expected by the name of this method
200 BOOST_UBLAS_INLINE
201 const_pointer find_element (size_type i) const {
202 return & (data () [i]);
203 }
204
205 // --------------
206 // Element access
207 // --------------
208
209 /// \brief Return a const reference to the element \f$i\f$
210 /// Return a const reference to the element \f$i\f$. With some compilers, this notation will be faster than \c[i]
211 /// \param i index of the element
212 BOOST_UBLAS_INLINE
213 const_reference operator () (size_type i) const {
214 return data () [i];
215 }
216
217 /// \brief Return a reference to the element \f$i\f$
218 /// Return a reference to the element \f$i\f$. With some compilers, this notation will be faster than \c[i]
219 /// \param i index of the element
220 BOOST_UBLAS_INLINE
221 reference operator () (size_type i) {
222 return data () [i];
223 }
224
225 /// \brief Return a const reference to the element \f$i\f$
226 /// \param i index of the element
227 BOOST_UBLAS_INLINE
228 const_reference operator [] (size_type i) const {
229 return (*this) (i);
230 }
231
232 /// \brief Return a reference to the element \f$i\f$
233 /// \param i index of the element
234 BOOST_UBLAS_INLINE
235 reference operator [] (size_type i) {
236 return (*this) (i);
237 }
238
239 // ------------------
240 // Element assignment
241 // ------------------
242
243 /// \brief Set element \f$i\f$ to the value \c t
244 /// \param i index of the element
245 /// \param t reference to the value to be set
246 // XXX semantic of this is to insert a new element and therefore size=size+1 ?
247 BOOST_UBLAS_INLINE
248 reference insert_element (size_type i, const_reference t) {
249 return (data () [i] = t);
250 }
251
252 /// \brief Set element \f$i\f$ to the \e zero value
253 /// \param i index of the element
254 BOOST_UBLAS_INLINE
255 void erase_element (size_type i) {
256 data () [i] = value_type/*zero*/();
257 }
258
259 // -------
260 // Zeroing
261 // -------
262
263 /// \brief Clear the vector, i.e. set all values to the \c zero value.
264 BOOST_UBLAS_INLINE
265 void clear () {
266 std::fill (data ().begin (), data ().end (), value_type/*zero*/());
267 }
268
269 // Assignment
270 #ifdef BOOST_UBLAS_MOVE_SEMANTICS
271
272 /// \brief Assign a full vector (\e RHS-vector) to the current vector (\e LHS-vector)
273 /// \param v is the source vector
274 /// \return a reference to a vector (i.e. the destination vector)
275 /*! @note "pass by value" the key idea to enable move semantics */
276 BOOST_UBLAS_INLINE
277 vector &operator = (vector v) {
278 assign_temporary(v);
279 return *this;
280 }
281 #else
282 /// \brief Assign a full vector (\e RHS-vector) to the current vector (\e LHS-vector)
283 /// \param v is the source vector
284 /// \return a reference to a vector (i.e. the destination vector)
285 BOOST_UBLAS_INLINE
286 vector &operator = (const vector &v) {
287 data () = v.data ();
288 return *this;
289 }
290 #endif
291
292 /// \brief Assign a full vector (\e RHS-vector) to the current vector (\e LHS-vector)
293 /// Assign a full vector (\e RHS-vector) to the current vector (\e LHS-vector). This method does not create any temporary.
294 /// \param v is the source vector container
295 /// \return a reference to a vector (i.e. the destination vector)
296 template<class C> // Container assignment without temporary
297 BOOST_UBLAS_INLINE
298 vector &operator = (const vector_container<C> &v) {
299 resize (v ().size (), false);
300 assign (v);
301 return *this;
302 }
303
304 /// \brief Assign a full vector (\e RHS-vector) to the current vector (\e LHS-vector)
305 /// \param v is the source vector
306 /// \return a reference to a vector (i.e. the destination vector)
307 BOOST_UBLAS_INLINE
308 vector &assign_temporary (vector &v) {
309 swap (v);
310 return *this;
311 }
312
313 /// \brief Assign the result of a vector_expression to the vector
314 /// 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.
315 /// \tparam AE is the type of the vector_expression
316 /// \param ae is a const reference to the vector_expression
317 /// \return a reference to the resulting vector
318 template<class AE>
319 BOOST_UBLAS_INLINE
320 vector &operator = (const vector_expression<AE> &ae) {
321 self_type temporary (ae);
322 return assign_temporary (temporary);
323 }
324
325 /// \brief Assign the result of a vector_expression to the vector
326 /// 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.
327 /// \tparam AE is the type of the vector_expression
328 /// \param ae is a const reference to the vector_expression
329 /// \return a reference to the resulting vector
330 template<class AE>
331 BOOST_UBLAS_INLINE
332 vector &assign (const vector_expression<AE> &ae) {
333 vector_assign<scalar_assign> (*this, ae);
334 return *this;
335 }
336
337 // -------------------
338 // Computed assignment
339 // -------------------
340
341 /// \brief Assign the sum of the vector and a vector_expression to the vector
342 /// 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.
343 /// A temporary is created for the computations.
344 /// \tparam AE is the type of the vector_expression
345 /// \param ae is a const reference to the vector_expression
346 /// \return a reference to the resulting vector
347 template<class AE>
348 BOOST_UBLAS_INLINE
349 vector &operator += (const vector_expression<AE> &ae) {
350 self_type temporary (*this + ae);
351 return assign_temporary (temporary);
352 }
353
354 /// \brief Assign the sum of the vector and a vector_expression to the vector
355 /// 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.
356 /// No temporary is created. Computations are done and stored directly into the resulting vector.
357 /// \tparam AE is the type of the vector_expression
358 /// \param ae is a const reference to the vector_expression
359 /// \return a reference to the resulting vector
360 template<class C> // Container assignment without temporary
361 BOOST_UBLAS_INLINE
362 vector &operator += (const vector_container<C> &v) {
363 plus_assign (v);
364 return *this;
365 }
366
367 /// \brief Assign the sum of the vector and a vector_expression to the vector
368 /// 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.
369 /// No temporary is created. Computations are done and stored directly into the resulting vector.
370 /// \tparam AE is the type of the vector_expression
371 /// \param ae is a const reference to the vector_expression
372 /// \return a reference to the resulting vector
373 template<class AE>
374 BOOST_UBLAS_INLINE
375 vector &plus_assign (const vector_expression<AE> &ae) {
376 vector_assign<scalar_plus_assign> (*this, ae);
377 return *this;
378 }
379
380 /// \brief Assign the difference of the vector and a vector_expression to the vector
381 /// 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.
382 /// A temporary is created for the computations.
383 /// \tparam AE is the type of the vector_expression
384 /// \param ae is a const reference to the vector_expression
385 template<class AE>
386 BOOST_UBLAS_INLINE
387 vector &operator -= (const vector_expression<AE> &ae) {
388 self_type temporary (*this - ae);
389 return assign_temporary (temporary);
390 }
391
392 /// \brief Assign the difference of the vector and a vector_expression to the vector
393 /// 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.
394 /// No temporary is created. Computations are done and stored directly into the resulting vector.
395 /// \tparam AE is the type of the vector_expression
396 /// \param ae is a const reference to the vector_expression
397 /// \return a reference to the resulting vector
398 template<class C> // Container assignment without temporary
399 BOOST_UBLAS_INLINE
400 vector &operator -= (const vector_container<C> &v) {
401 minus_assign (v);
402 return *this;
403 }
404
405 /// \brief Assign the difference of the vector and a vector_expression to the vector
406 /// 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.
407 /// No temporary is created. Computations are done and stored directly into the resulting vector.
408 /// \tparam AE is the type of the vector_expression
409 /// \param ae is a const reference to the vector_expression
410 /// \return a reference to the resulting vector
411 template<class AE>
412 BOOST_UBLAS_INLINE
413 vector &minus_assign (const vector_expression<AE> &ae) {
414 vector_assign<scalar_minus_assign> (*this, ae);
415 return *this;
416 }
417
418 /// \brief Assign the product of the vector and a scalar to the vector
419 /// 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.
420 /// No temporary is created. Computations are done and stored directly into the resulting vector.
421 /// \tparam AE is the type of the vector_expression
422 /// \param at is a const reference to the scalar
423 /// \return a reference to the resulting vector
424 template<class AT>
425 BOOST_UBLAS_INLINE
426 vector &operator *= (const AT &at) {
427 vector_assign_scalar<scalar_multiplies_assign> (*this, at);
428 return *this;
429 }
430
431 /// \brief Assign the division of the vector by a scalar to the vector
432 /// 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.
433 /// No temporary is created. Computations are done and stored directly into the resulting vector.
434 /// \tparam AE is the type of the vector_expression
435 /// \param at is a const reference to the scalar
436 /// \return a reference to the resulting vector
437 template<class AT>
438 BOOST_UBLAS_INLINE
439 vector &operator /= (const AT &at) {
440 vector_assign_scalar<scalar_divides_assign> (*this, at);
441 return *this;
442 }
443
444 // --------
445 // Swapping
446 // --------
447
448 /// \brief Swap the content of the vector with another vector
449 /// \param v is the vector to be swapped with
450 BOOST_UBLAS_INLINE
451 void swap (vector &v) {
452 if (this != &v) {
453 data ().swap (v.data ());
454 }
455 }
456
457 /// \brief Swap the content of two vectors
458 /// \param v1 is the first vector. It takes values from v2
459 /// \param v2 is the second vector It takes values from v1
460 BOOST_UBLAS_INLINE
461 friend void swap (vector &v1, vector &v2) {
462 v1.swap (v2);
463 }
464
465 // Iterator types
466 private:
467 // Use the storage array iterator
468 typedef typename A::const_iterator const_subiterator_type;
469 typedef typename A::iterator subiterator_type;
470
471 public:
472 #ifdef BOOST_UBLAS_USE_INDEXED_ITERATOR
473 typedef indexed_iterator<self_type, dense_random_access_iterator_tag> iterator;
474 typedef indexed_const_iterator<self_type, dense_random_access_iterator_tag> const_iterator;
475 #else
476 class const_iterator;
477 class iterator;
478 #endif
479
480 // --------------
481 // Element lookup
482 // --------------
483
484 /// \brief Return a const iterator to the element \e i
485 /// \param i index of the element
486 BOOST_UBLAS_INLINE
487 const_iterator find (size_type i) const {
488 #ifndef BOOST_UBLAS_USE_INDEXED_ITERATOR
489 return const_iterator (*this, data ().begin () + i);
490 #else
491 return const_iterator (*this, i);
492 #endif
493 }
494
495 /// \brief Return an iterator to the element \e i
496 /// \param i index of the element
497 BOOST_UBLAS_INLINE
498 iterator find (size_type i) {
499 #ifndef BOOST_UBLAS_USE_INDEXED_ITERATOR
500 return iterator (*this, data ().begin () + i);
501 #else
502 return iterator (*this, i);
503 #endif
504 }
505
506 #ifndef BOOST_UBLAS_USE_INDEXED_ITERATOR
507 class const_iterator:
508 public container_const_reference<vector>,
509 public random_access_iterator_base<dense_random_access_iterator_tag,
510 const_iterator, value_type, difference_type> {
511 public:
512 typedef typename vector::difference_type difference_type;
513 typedef typename vector::value_type value_type;
514 typedef typename vector::const_reference reference;
515 typedef const typename vector::pointer pointer;
516
517 // ----------------------------
518 // Construction and destruction
519 // ----------------------------
520
521
522 BOOST_UBLAS_INLINE
523 const_iterator ():
524 container_const_reference<self_type> (), it_ () {}
525 BOOST_UBLAS_INLINE
526 const_iterator (const self_type &v, const const_subiterator_type &it):
527 container_const_reference<self_type> (v), it_ (it) {}
528 BOOST_UBLAS_INLINE
529 const_iterator (const typename self_type::iterator &it): // ISSUE vector:: stops VC8 using std::iterator here
530 container_const_reference<self_type> (it ()), it_ (it.it_) {}
531
532 // ----------
533 // Arithmetic
534 // ----------
535
536 /// \brief Increment by 1 the position of the iterator
537 /// \return a reference to the const iterator
538 BOOST_UBLAS_INLINE
539 const_iterator &operator ++ () {
540 ++ it_;
541 return *this;
542 }
543
544 /// \brief Decrement by 1 the position of the iterator
545 /// \return a reference to the const iterator
546 BOOST_UBLAS_INLINE
547 const_iterator &operator -- () {
548 -- it_;
549 return *this;
550 }
551
552 /// \brief Increment by \e n the position of the iterator
553 /// \return a reference to the const iterator
554 BOOST_UBLAS_INLINE
555 const_iterator &operator += (difference_type n) {
556 it_ += n;
557 return *this;
558 }
559
560 /// \brief Decrement by \e n the position of the iterator
561 /// \return a reference to the const iterator
562 BOOST_UBLAS_INLINE
563 const_iterator &operator -= (difference_type n) {
564 it_ -= n;
565 return *this;
566 }
567
568 /// \brief Return the different in number of positions between 2 iterators
569 BOOST_UBLAS_INLINE
570 difference_type operator - (const const_iterator &it) const {
571 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
572 return it_ - it.it_;
573 }
574
575 /// \brief Dereference an iterator
576 /// Dereference an iterator: a bounds' check is done before returning the value. A bad_index() expection is returned if out of bounds.
577 /// \return a const reference to the value pointed by the iterator
578 BOOST_UBLAS_INLINE
579 const_reference operator * () const {
580 BOOST_UBLAS_CHECK (it_ >= (*this) ().begin ().it_ && it_ < (*this) ().end ().it_, bad_index ());
581 return *it_;
582 }
583
584 /// \brief Dereference an iterator at the n-th forward value
585 /// Dereference an iterator at the n-th forward value, that is the value pointed by iterator+n.
586 /// A bounds' check is done before returning the value. A bad_index() expection is returned if out of bounds.
587 /// \return a const reference
588 BOOST_UBLAS_INLINE
589 const_reference operator [] (difference_type n) const {
590 return *(it_ + n);
591 }
592
593 // Index
594 /// \brief return the index of the element referenced by the iterator
595 BOOST_UBLAS_INLINE
596 size_type index () const {
597 BOOST_UBLAS_CHECK (it_ >= (*this) ().begin ().it_ && it_ < (*this) ().end ().it_, bad_index ());
598 return it_ - (*this) ().begin ().it_;
599 }
600
601 // Assignment
602 BOOST_UBLAS_INLINE
603 /// \brief assign the value of an iterator to the iterator
604 const_iterator &operator = (const const_iterator &it) {
605 container_const_reference<self_type>::assign (&it ());
606 it_ = it.it_;
607 return *this;
608 }
609
610 // Comparison
611 /// \brief compare the value of two itetarors
612 /// \return true if they reference the same element
613 BOOST_UBLAS_INLINE
614 bool operator == (const const_iterator &it) const {
615 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
616 return it_ == it.it_;
617 }
618
619
620 /// \brief compare the value of two iterators
621 /// \return return true if the left-hand-side iterator refers to a value placed before the right-hand-side iterator
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 private:
629 const_subiterator_type it_;
630
631 friend class iterator;
632 };
633 #endif
634
635 /// \brief return an iterator on the first element of the vector
636 BOOST_UBLAS_INLINE
637 const_iterator begin () const {
638 return find (0);
639 }
640
641 /// \brief return an iterator after the last element of the vector
642 BOOST_UBLAS_INLINE
643 const_iterator end () const {
644 return find (data_.size ());
645 }
646
647 #ifndef BOOST_UBLAS_USE_INDEXED_ITERATOR
648 class iterator:
649 public container_reference<vector>,
650 public random_access_iterator_base<dense_random_access_iterator_tag,
651 iterator, value_type, difference_type> {
652 public:
653 typedef typename vector::difference_type difference_type;
654 typedef typename vector::value_type value_type;
655 typedef typename vector::reference reference;
656 typedef typename vector::pointer pointer;
657
658
659 // Construction and destruction
660 BOOST_UBLAS_INLINE
661 iterator ():
662 container_reference<self_type> (), it_ () {}
663 BOOST_UBLAS_INLINE
664 iterator (self_type &v, const subiterator_type &it):
665 container_reference<self_type> (v), it_ (it) {}
666
667 // Arithmetic
668 BOOST_UBLAS_INLINE
669 iterator &operator ++ () {
670 ++ it_;
671 return *this;
672 }
673 BOOST_UBLAS_INLINE
674 iterator &operator -- () {
675 -- it_;
676 return *this;
677 }
678 BOOST_UBLAS_INLINE
679 iterator &operator += (difference_type n) {
680 it_ += n;
681 return *this;
682 }
683 BOOST_UBLAS_INLINE
684 iterator &operator -= (difference_type n) {
685 it_ -= n;
686 return *this;
687 }
688 BOOST_UBLAS_INLINE
689 difference_type operator - (const iterator &it) const {
690 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
691 return it_ - it.it_;
692 }
693
694 // Dereference
695 BOOST_UBLAS_INLINE
696 reference operator * () const {
697 BOOST_UBLAS_CHECK (it_ >= (*this) ().begin ().it_ && it_ < (*this) ().end ().it_ , bad_index ());
698 return *it_;
699 }
700 BOOST_UBLAS_INLINE
701 reference operator [] (difference_type n) const {
702 return *(it_ + n);
703 }
704
705 // Index
706 BOOST_UBLAS_INLINE
707 size_type index () const {
708 BOOST_UBLAS_CHECK (it_ >= (*this) ().begin ().it_ && it_ < (*this) ().end ().it_ , bad_index ());
709 return it_ - (*this) ().begin ().it_;
710 }
711
712 // Assignment
713 BOOST_UBLAS_INLINE
714 iterator &operator = (const iterator &it) {
715 container_reference<self_type>::assign (&it ());
716 it_ = it.it_;
717 return *this;
718 }
719
720 // Comparison
721 BOOST_UBLAS_INLINE
722 bool operator == (const iterator &it) const {
723 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
724 return it_ == it.it_;
725 }
726 BOOST_UBLAS_INLINE
727 bool operator < (const iterator &it) const {
728 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
729 return it_ < it.it_;
730 }
731
732 private:
733 subiterator_type it_;
734
735 friend class const_iterator;
736 };
737 #endif
738
739 /// \brief Return an iterator on the first element of the vector
740 BOOST_UBLAS_INLINE
741 iterator begin () {
742 return find (0);
743 }
744
745 /// \brief Return an iterator at the end of the vector
746 BOOST_UBLAS_INLINE
747 iterator end () {
748 return find (data_.size ());
749 }
750
751 // Reverse iterator
752 typedef reverse_iterator_base<const_iterator> const_reverse_iterator;
753 typedef reverse_iterator_base<iterator> reverse_iterator;
754
755 /// \brief Return a const reverse iterator before the first element of the reversed vector (i.e. end() of normal vector)
756 BOOST_UBLAS_INLINE
757 const_reverse_iterator rbegin () const {
758 return const_reverse_iterator (end ());
759 }
760
761 /// \brief Return a const reverse iterator on the end of the reverse vector (i.e. first element of the normal vector)
762 BOOST_UBLAS_INLINE
763 const_reverse_iterator rend () const {
764 return const_reverse_iterator (begin ());
765 }
766
767 /// \brief Return a const reverse iterator before the first element of the reversed vector (i.e. end() of normal vector)
768 BOOST_UBLAS_INLINE
769 reverse_iterator rbegin () {
770 return reverse_iterator (end ());
771 }
772
773 /// \brief Return a const reverse iterator on the end of the reverse vector (i.e. first element of the normal vector)
774 BOOST_UBLAS_INLINE
775 reverse_iterator rend () {
776 return reverse_iterator (begin ());
777 }
778
779 // -------------
780 // Serialization
781 // -------------
782
783 /// Serialize a vector into and archive as defined in Boost
784 /// \param ar Archive object. Can be a flat file, an XML file or any other stream
785 /// \param file_version Optional file version (not yet used)
786 template<class Archive>
787 void serialize(Archive & ar, const unsigned int /* file_version */){
788 ar & serialization::make_nvp("data",data_);
789 }
790
791 private:
792 array_type data_;
793 };
794
795
796 // --------------------
797 // Bounded vector class
798 // --------------------
799
800 /// \brief a dense vector of values of type \c T, of variable size but with maximum \f$N\f$.
801 /// A dense vector of values of type \c T, of variable size but with maximum \f$N\f$. The default constructor
802 /// 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.
803 template<class T, std::size_t N>
804 class bounded_vector:
805 public vector<T, bounded_array<T, N> > {
806
807 typedef vector<T, bounded_array<T, N> > vector_type;
808 public:
809 typedef typename vector_type::size_type size_type;
810 static const size_type max_size = N;
811
812 // Construction and destruction
813 BOOST_UBLAS_INLINE
814 bounded_vector ():
815 vector_type (N) {}
816 BOOST_UBLAS_INLINE
817 bounded_vector (size_type size):
818 vector_type (size) {}
819 BOOST_UBLAS_INLINE
820 bounded_vector (const bounded_vector &v):
821 vector_type (v) {}
822 template<class A2> // Allow vector<T,bounded_array<N> construction
823 BOOST_UBLAS_INLINE
824 bounded_vector (const vector<T, A2> &v):
825 vector_type (v) {}
826 template<class AE>
827 BOOST_UBLAS_INLINE
828 bounded_vector (const vector_expression<AE> &ae):
829 vector_type (ae) {}
830 BOOST_UBLAS_INLINE
831 ~bounded_vector () {}
832
833 // Assignment
834 #ifdef BOOST_UBLAS_MOVE_SEMANTICS
835
836 /*! @note "pass by value" the key idea to enable move semantics */
837 BOOST_UBLAS_INLINE
838 bounded_vector &operator = (bounded_vector v) {
839 vector_type::operator = (v);
840 return *this;
841 }
842 #else
843 BOOST_UBLAS_INLINE
844 bounded_vector &operator = (const bounded_vector &v) {
845 vector_type::operator = (v);
846 return *this;
847 }
848 #endif
849 template<class A2> // Generic vector assignment
850 BOOST_UBLAS_INLINE
851 bounded_vector &operator = (const vector<T, A2> &v) {
852 vector_type::operator = (v);
853 return *this;
854 }
855 template<class C> // Container assignment without temporary
856 BOOST_UBLAS_INLINE
857 bounded_vector &operator = (const vector_container<C> &v) {
858 vector_type::operator = (v);
859 return *this;
860 }
861 template<class AE>
862 BOOST_UBLAS_INLINE
863 bounded_vector &operator = (const vector_expression<AE> &ae) {
864 vector_type::operator = (ae);
865 return *this;
866 }
867 };
868
869
870 // -----------------
871 // Zero vector class
872 // -----------------
873
874 /// \brief A zero vector of type \c T and a given \c size
875 /// 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
876 /// for storing the zero values: it still acts like any other vector. However assigning values to it will not change the zero
877 /// vector into a normal vector. It must first be assigned to another normal vector by any suitable means. Its memory footprint is constant.
878 template<class T, class ALLOC>
879 class zero_vector:
880 public vector_container<zero_vector<T, ALLOC> > {
881
882 typedef const T *const_pointer;
883 typedef zero_vector<T, ALLOC> self_type;
884 public:
885 #ifdef BOOST_UBLAS_ENABLE_PROXY_SHORTCUTS
886 using vector_container<self_type>::operator ();
887 #endif
888 typedef typename ALLOC::size_type size_type;
889 typedef typename ALLOC::difference_type difference_type;
890 typedef T value_type;
891 typedef const T &const_reference;
892 typedef T &reference;
893 typedef const vector_reference<const self_type> const_closure_type;
894 typedef vector_reference<self_type> closure_type;
895 typedef sparse_tag storage_category;
896
897 // Construction and destruction
898 BOOST_UBLAS_INLINE
899 zero_vector ():
900 vector_container<self_type> (),
901 size_ (0) {}
902 explicit BOOST_UBLAS_INLINE
903 zero_vector (size_type size):
904 vector_container<self_type> (),
905 size_ (size) {}
906 BOOST_UBLAS_INLINE
907 zero_vector (const zero_vector &v):
908 vector_container<self_type> (),
909 size_ (v.size_) {}
910
911 // Accessors
912 BOOST_UBLAS_INLINE
913 size_type size () const {
914 return size_;
915 }
916
917 // Resizing
918 BOOST_UBLAS_INLINE
919 void resize (size_type size, bool /*preserve*/ = true) {
920 size_ = size;
921 }
922
923 // Element support
924 BOOST_UBLAS_INLINE
925 const_pointer find_element (size_type i) const {
926 return & zero_;
927 }
928
929 // Element access
930 BOOST_UBLAS_INLINE
931 const_reference operator () (size_type /* i */) const {
932 return zero_;
933 }
934
935 BOOST_UBLAS_INLINE
936 const_reference operator [] (size_type i) const {
937 return (*this) (i);
938 }
939
940 // Assignment
941 BOOST_UBLAS_INLINE
942 zero_vector &operator = (const zero_vector &v) {
943 size_ = v.size_;
944 return *this;
945 }
946 BOOST_UBLAS_INLINE
947 zero_vector &assign_temporary (zero_vector &v) {
948 swap (v);
949 return *this;
950 }
951
952 // Swapping
953 BOOST_UBLAS_INLINE
954 void swap (zero_vector &v) {
955 if (this != &v) {
956 std::swap (size_, v.size_);
957 }
958 }
959 BOOST_UBLAS_INLINE
960 friend void swap (zero_vector &v1, zero_vector &v2) {
961 v1.swap (v2);
962 }
963
964 // Iterator types
965 public:
966 class const_iterator;
967
968 // Element lookup
969 BOOST_UBLAS_INLINE
970 const_iterator find (size_type /*i*/) const {
971 return const_iterator (*this);
972 }
973
974 class const_iterator:
975 public container_const_reference<zero_vector>,
976 public bidirectional_iterator_base<sparse_bidirectional_iterator_tag,
977 const_iterator, value_type> {
978 public:
979 typedef typename zero_vector::difference_type difference_type;
980 typedef typename zero_vector::value_type value_type;
981 typedef typename zero_vector::const_reference reference;
982 typedef typename zero_vector::const_pointer pointer;
983
984 // Construction and destruction
985 BOOST_UBLAS_INLINE
986 const_iterator ():
987 container_const_reference<self_type> () {}
988 BOOST_UBLAS_INLINE
989 const_iterator (const self_type &v):
990 container_const_reference<self_type> (v) {}
991
992 // Arithmetic
993 BOOST_UBLAS_INLINE
994 const_iterator &operator ++ () {
995 BOOST_UBLAS_CHECK_FALSE (bad_index ());
996 return *this;
997 }
998 BOOST_UBLAS_INLINE
999 const_iterator &operator -- () {
1000 BOOST_UBLAS_CHECK_FALSE (bad_index ());
1001 return *this;
1002 }
1003
1004 // Dereference
1005 BOOST_UBLAS_INLINE
1006 const_reference operator * () const {
1007 BOOST_UBLAS_CHECK_FALSE (bad_index ());
1008 return zero_; // arbitary return value
1009 }
1010
1011 // Index
1012 BOOST_UBLAS_INLINE
1013 size_type index () const {
1014 BOOST_UBLAS_CHECK_FALSE (bad_index ());
1015 return 0; // arbitary return value
1016 }
1017
1018 // Assignment
1019 BOOST_UBLAS_INLINE
1020 const_iterator &operator = (const const_iterator &it) {
1021 container_const_reference<self_type>::assign (&it ());
1022 return *this;
1023 }
1024
1025 // Comparison
1026 BOOST_UBLAS_INLINE
1027 bool operator == (const const_iterator &it) const {
1028 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
1029 detail::ignore_unused_variable_warning(it);
1030 return true;
1031 }
1032 };
1033
1034 typedef const_iterator iterator;
1035
1036 BOOST_UBLAS_INLINE
1037 const_iterator begin () const {
1038 return const_iterator (*this);
1039 }
1040 BOOST_UBLAS_INLINE
1041 const_iterator end () const {
1042 return const_iterator (*this);
1043 }
1044
1045 // Reverse iterator
1046 typedef reverse_iterator_base<const_iterator> const_reverse_iterator;
1047
1048 BOOST_UBLAS_INLINE
1049 const_reverse_iterator rbegin () const {
1050 return const_reverse_iterator (end ());
1051 }
1052 BOOST_UBLAS_INLINE
1053 const_reverse_iterator rend () const {
1054 return const_reverse_iterator (begin ());
1055 }
1056
1057 // Serialization
1058 template<class Archive>
1059 void serialize(Archive & ar, const unsigned int /* file_version */){
1060 serialization::collection_size_type s (size_);
1061 ar & serialization::make_nvp("size",s);
1062 if (Archive::is_loading::value) {
1063 size_ = s;
1064 }
1065 }
1066
1067 private:
1068 size_type size_;
1069 typedef const value_type const_value_type;
1070 static const_value_type zero_;
1071 };
1072
1073 template<class T, class ALLOC>
1074 typename zero_vector<T, ALLOC>::const_value_type zero_vector<T, ALLOC>::zero_ = T(/*zero*/);
1075
1076
1077 // Unit vector class
1078 /// \brief unit_vector represents a canonical unit vector
1079 /// 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$.
1080 /// At construction, the value \e k is given after the dimension of the vector.
1081 /// \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.
1082 /// \tparam ALLOC a specific allocator can be specified if needed. Most of the time this parameter is omited.
1083 template<class T, class ALLOC>
1084 class unit_vector:
1085 public vector_container<unit_vector<T, ALLOC> > {
1086
1087 typedef const T *const_pointer;
1088 typedef unit_vector<T, ALLOC> self_type;
1089 public:
1090 #ifdef BOOST_UBLAS_ENABLE_PROXY_SHORTCUTS
1091 using vector_container<self_type>::operator ();
1092 #endif
1093 typedef typename ALLOC::size_type size_type;
1094 typedef typename ALLOC::difference_type difference_type;
1095 typedef T value_type;
1096 typedef const T &const_reference;
1097 typedef T &reference;
1098 typedef const vector_reference<const self_type> const_closure_type;
1099 typedef vector_reference<self_type> closure_type;
1100 typedef sparse_tag storage_category;
1101
1102 // Construction and destruction
1103 /// \brief Simple constructor with dimension and index 0
1104 BOOST_UBLAS_INLINE
1105 unit_vector ():
1106 vector_container<self_type> (),
1107 size_ (0), index_ (0) {}
1108
1109 /// \brief Constructor of unit_vector
1110 /// \param size is the dimension of the vector
1111 /// \param index is the order of the vector
1112 BOOST_UBLAS_INLINE
1113 explicit unit_vector (size_type size, size_type index = 0):
1114 vector_container<self_type> (),
1115 size_ (size), index_ (index) {}
1116
1117 /// \brief Copy-constructor
1118 BOOST_UBLAS_INLINE
1119 unit_vector (const unit_vector &v):
1120 vector_container<self_type> (),
1121 size_ (v.size_), index_ (v.index_) {}
1122
1123 // Accessors
1124 //----------
1125
1126 /// \brief Return the size (dimension) of the vector
1127 BOOST_UBLAS_INLINE
1128 size_type size () const {
1129 return size_;
1130 }
1131
1132 /// \brief Return the order of the unit vector
1133 BOOST_UBLAS_INLINE
1134 size_type index () const {
1135 return index_;
1136 }
1137
1138 // Resizing
1139 // --------
1140
1141 /// \brief Resize the vector. The values are preserved by default (i.e. the index does not change)
1142 /// \param size is the new size of the vector
1143 BOOST_UBLAS_INLINE
1144 void resize (size_type size, bool /*preserve*/ = true) {
1145 size_ = size;
1146 }
1147
1148 // Element support
1149 // ---------------
1150
1151 /// \brief Return a const pointer to the element of index i
1152 BOOST_UBLAS_INLINE
1153 const_pointer find_element (size_type i) const {
1154 if (i == index_)
1155 return & one_;
1156 else
1157 return & zero_;
1158 }
1159
1160 // Element access
1161 BOOST_UBLAS_INLINE
1162 const_reference operator () (size_type i) const {
1163 if (i == index_)
1164 return one_;
1165 else
1166 return zero_;
1167 }
1168
1169 BOOST_UBLAS_INLINE
1170 const_reference operator [] (size_type i) const {
1171 return (*this) (i);
1172 }
1173
1174 // Assignment
1175 BOOST_UBLAS_INLINE
1176 unit_vector &operator = (const unit_vector &v) {
1177 size_ = v.size_;
1178 index_ = v.index_;
1179 return *this;
1180 }
1181 BOOST_UBLAS_INLINE
1182 unit_vector &assign_temporary (unit_vector &v) {
1183 swap (v);
1184 return *this;
1185 }
1186
1187 // Swapping
1188 BOOST_UBLAS_INLINE
1189 void swap (unit_vector &v) {
1190 if (this != &v) {
1191 std::swap (size_, v.size_);
1192 std::swap (index_, v.index_);
1193 }
1194 }
1195 BOOST_UBLAS_INLINE
1196 friend void swap (unit_vector &v1, unit_vector &v2) {
1197 v1.swap (v2);
1198 }
1199
1200 // Iterator types
1201 private:
1202 // Use bool to indicate begin (one_ as value)
1203 typedef bool const_subiterator_type;
1204 public:
1205 class const_iterator;
1206
1207 // Element lookup
1208 BOOST_UBLAS_INLINE
1209 const_iterator find (size_type i) const {
1210 return const_iterator (*this, i <= index_);
1211 }
1212
1213 class const_iterator:
1214 public container_const_reference<unit_vector>,
1215 public bidirectional_iterator_base<sparse_bidirectional_iterator_tag,
1216 const_iterator, value_type> {
1217 public:
1218 typedef typename unit_vector::difference_type difference_type;
1219 typedef typename unit_vector::value_type value_type;
1220 typedef typename unit_vector::const_reference reference;
1221 typedef typename unit_vector::const_pointer pointer;
1222
1223 // Construction and destruction
1224 BOOST_UBLAS_INLINE
1225 const_iterator ():
1226 container_const_reference<unit_vector> (), it_ () {}
1227 BOOST_UBLAS_INLINE
1228 const_iterator (const unit_vector &v, const const_subiterator_type &it):
1229 container_const_reference<unit_vector> (v), it_ (it) {}
1230
1231 // Arithmetic
1232 BOOST_UBLAS_INLINE
1233 const_iterator &operator ++ () {
1234 BOOST_UBLAS_CHECK (it_, bad_index ());
1235 it_ = !it_;
1236 return *this;
1237 }
1238 BOOST_UBLAS_INLINE
1239 const_iterator &operator -- () {
1240 BOOST_UBLAS_CHECK (!it_, bad_index ());
1241 it_ = !it_;
1242 return *this;
1243 }
1244
1245 // Dereference
1246 BOOST_UBLAS_INLINE
1247 const_reference operator * () const {
1248 BOOST_UBLAS_CHECK (it_, bad_index ());
1249 return one_;
1250 }
1251
1252 // Index
1253 BOOST_UBLAS_INLINE
1254 size_type index () const {
1255 BOOST_UBLAS_CHECK (it_, bad_index ());
1256 return (*this) ().index_;
1257 }
1258
1259 // Assignment
1260 BOOST_UBLAS_INLINE
1261 const_iterator &operator = (const const_iterator &it) {
1262 container_const_reference<unit_vector>::assign (&it ());
1263 it_ = it.it_;
1264 return *this;
1265 }
1266
1267 // Comparison
1268 BOOST_UBLAS_INLINE
1269 bool operator == (const const_iterator &it) const {
1270 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
1271 return it_ == it.it_;
1272 }
1273
1274 private:
1275 const_subiterator_type it_;
1276 };
1277
1278 typedef const_iterator iterator;
1279
1280 BOOST_UBLAS_INLINE
1281 const_iterator begin () const {
1282 return const_iterator (*this, true);
1283 }
1284 BOOST_UBLAS_INLINE
1285 const_iterator end () const {
1286 return const_iterator (*this, false);
1287 }
1288
1289 // Reverse iterator
1290 typedef reverse_iterator_base<const_iterator> const_reverse_iterator;
1291
1292 BOOST_UBLAS_INLINE
1293 const_reverse_iterator rbegin () const {
1294 return const_reverse_iterator (end ());
1295 }
1296 BOOST_UBLAS_INLINE
1297 const_reverse_iterator rend () const {
1298 return const_reverse_iterator (begin ());
1299 }
1300
1301 // Serialization
1302 template<class Archive>
1303 void serialize(Archive & ar, const unsigned int /* file_version */){
1304 serialization::collection_size_type s (size_);
1305 ar & serialization::make_nvp("size",s);
1306 if (Archive::is_loading::value) {
1307 size_ = s;
1308 }
1309 ar & serialization::make_nvp("index", index_);
1310 }
1311
1312 private:
1313 size_type size_;
1314 size_type index_;
1315 typedef const value_type const_value_type;
1316 static const_value_type zero_;
1317 static const_value_type one_;
1318 };
1319
1320 template<class T, class ALLOC>
1321 typename unit_vector<T, ALLOC>::const_value_type unit_vector<T, ALLOC>::zero_ = T(/*zero*/);
1322 template<class T, class ALLOC>
1323 typename unit_vector<T, ALLOC>::const_value_type unit_vector<T, ALLOC>::one_ (1); // ISSUE: need 'one'-traits here
1324
1325 /// \brief A scalar (i.e. unique value) vector of type \c T and a given \c size
1326 /// 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
1327 /// 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.
1328 /// vector into a normal vector. It must first be assigned to another normal vector by any suitable means. Its memory footprint is constant.
1329 /// \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.
1330 template<class T, class ALLOC>
1331 class scalar_vector:
1332 public vector_container<scalar_vector<T, ALLOC> > {
1333
1334 typedef const T *const_pointer;
1335 typedef scalar_vector<T, ALLOC> self_type;
1336 public:
1337 #ifdef BOOST_UBLAS_ENABLE_PROXY_SHORTCUTS
1338 using vector_container<self_type>::operator ();
1339 #endif
1340 typedef typename ALLOC::size_type size_type;
1341 typedef typename ALLOC::difference_type difference_type;
1342 typedef T value_type;
1343 typedef const T &const_reference;
1344 typedef T &reference;
1345 typedef const vector_reference<const self_type> const_closure_type;
1346 typedef vector_reference<self_type> closure_type;
1347 typedef dense_tag storage_category;
1348
1349 // Construction and destruction
1350 BOOST_UBLAS_INLINE
1351 scalar_vector ():
1352 vector_container<self_type> (),
1353 size_ (0), value_ () {}
1354 BOOST_UBLAS_INLINE
1355 explicit scalar_vector (size_type size, const value_type &value = value_type(1)):
1356 vector_container<self_type> (),
1357 size_ (size), value_ (value) {}
1358 BOOST_UBLAS_INLINE
1359 scalar_vector (const scalar_vector &v):
1360 vector_container<self_type> (),
1361 size_ (v.size_), value_ (v.value_) {}
1362
1363 // Accessors
1364 BOOST_UBLAS_INLINE
1365 size_type size () const {
1366 return size_;
1367 }
1368
1369 // Resizing
1370 BOOST_UBLAS_INLINE
1371 void resize (size_type size, bool /*preserve*/ = true) {
1372 size_ = size;
1373 }
1374
1375 // Element support
1376 BOOST_UBLAS_INLINE
1377 const_pointer find_element (size_type /*i*/) const {
1378 return & value_;
1379 }
1380
1381 // Element access
1382 BOOST_UBLAS_INLINE
1383 const_reference operator () (size_type /*i*/) const {
1384 return value_;
1385 }
1386
1387 BOOST_UBLAS_INLINE
1388 const_reference operator [] (size_type /*i*/) const {
1389 return value_;
1390 }
1391
1392 // Assignment
1393 BOOST_UBLAS_INLINE
1394 scalar_vector &operator = (const scalar_vector &v) {
1395 size_ = v.size_;
1396 value_ = v.value_;
1397 return *this;
1398 }
1399 BOOST_UBLAS_INLINE
1400 scalar_vector &assign_temporary (scalar_vector &v) {
1401 swap (v);
1402 return *this;
1403 }
1404
1405 // Swapping
1406 BOOST_UBLAS_INLINE
1407 void swap (scalar_vector &v) {
1408 if (this != &v) {
1409 std::swap (size_, v.size_);
1410 std::swap (value_, v.value_);
1411 }
1412 }
1413 BOOST_UBLAS_INLINE
1414 friend void swap (scalar_vector &v1, scalar_vector &v2) {
1415 v1.swap (v2);
1416 }
1417
1418 // Iterator types
1419 private:
1420 // Use an index
1421 typedef size_type const_subiterator_type;
1422
1423 public:
1424 #ifdef BOOST_UBLAS_USE_INDEXED_ITERATOR
1425 typedef indexed_const_iterator<self_type, dense_random_access_iterator_tag> iterator;
1426 typedef indexed_const_iterator<self_type, dense_random_access_iterator_tag> const_iterator;
1427 #else
1428 class const_iterator;
1429 #endif
1430
1431 // Element lookup
1432 BOOST_UBLAS_INLINE
1433 const_iterator find (size_type i) const {
1434 return const_iterator (*this, i);
1435 }
1436
1437 #ifndef BOOST_UBLAS_USE_INDEXED_ITERATOR
1438 class const_iterator:
1439 public container_const_reference<scalar_vector>,
1440 public random_access_iterator_base<dense_random_access_iterator_tag,
1441 const_iterator, value_type> {
1442 public:
1443 typedef typename scalar_vector::difference_type difference_type;
1444 typedef typename scalar_vector::value_type value_type;
1445 typedef typename scalar_vector::const_reference reference;
1446 typedef typename scalar_vector::const_pointer pointer;
1447
1448 // Construction and destruction
1449 BOOST_UBLAS_INLINE
1450 const_iterator ():
1451 container_const_reference<scalar_vector> (), it_ () {}
1452 BOOST_UBLAS_INLINE
1453 const_iterator (const scalar_vector &v, const const_subiterator_type &it):
1454 container_const_reference<scalar_vector> (v), it_ (it) {}
1455
1456 // Arithmetic
1457 BOOST_UBLAS_INLINE
1458 const_iterator &operator ++ () {
1459 ++ it_;
1460 return *this;
1461 }
1462 BOOST_UBLAS_INLINE
1463 const_iterator &operator -- () {
1464 -- it_;
1465 return *this;
1466 }
1467 BOOST_UBLAS_INLINE
1468 const_iterator &operator += (difference_type n) {
1469 it_ += n;
1470 return *this;
1471 }
1472 BOOST_UBLAS_INLINE
1473 const_iterator &operator -= (difference_type n) {
1474 it_ -= n;
1475 return *this;
1476 }
1477 BOOST_UBLAS_INLINE
1478 difference_type operator - (const const_iterator &it) const {
1479 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
1480 return it_ - it.it_;
1481 }
1482
1483 // Dereference
1484 BOOST_UBLAS_INLINE
1485 const_reference operator * () const {
1486 BOOST_UBLAS_CHECK (it_ < (*this) ().size (), bad_index ());
1487 return (*this) () (index ());
1488 }
1489 BOOST_UBLAS_INLINE
1490 const_reference operator [] (difference_type n) const {
1491 return *(*this + n);
1492 }
1493
1494 // Index
1495 BOOST_UBLAS_INLINE
1496 size_type index () const {
1497 BOOST_UBLAS_CHECK (it_ < (*this) ().size (), bad_index ());
1498 return it_;
1499 }
1500
1501 // Assignment
1502 BOOST_UBLAS_INLINE
1503 const_iterator &operator = (const const_iterator &it) {
1504 container_const_reference<scalar_vector>::assign (&it ());
1505 it_ = it.it_;
1506 return *this;
1507 }
1508
1509 // Comparison
1510 BOOST_UBLAS_INLINE
1511 bool operator == (const const_iterator &it) const {
1512 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
1513 return it_ == it.it_;
1514 }
1515 BOOST_UBLAS_INLINE
1516 bool operator < (const const_iterator &it) const {
1517 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
1518 return it_ < it.it_;
1519 }
1520
1521 private:
1522 const_subiterator_type it_;
1523 };
1524
1525 typedef const_iterator iterator;
1526 #endif
1527
1528 BOOST_UBLAS_INLINE
1529 const_iterator begin () const {
1530 return find (0);
1531 }
1532 BOOST_UBLAS_INLINE
1533 const_iterator end () const {
1534 return find (size_);
1535 }
1536
1537 // Reverse iterator
1538 typedef reverse_iterator_base<const_iterator> const_reverse_iterator;
1539
1540 BOOST_UBLAS_INLINE
1541 const_reverse_iterator rbegin () const {
1542 return const_reverse_iterator (end ());
1543 }
1544 BOOST_UBLAS_INLINE
1545 const_reverse_iterator rend () const {
1546 return const_reverse_iterator (begin ());
1547 }
1548
1549 // Serialization
1550 template<class Archive>
1551 void serialize(Archive & ar, const unsigned int /* file_version */){
1552 serialization::collection_size_type s (size_);
1553 ar & serialization::make_nvp("size",s);
1554 if (Archive::is_loading::value) {
1555 size_ = s;
1556 }
1557 ar & serialization::make_nvp("value", value_);
1558 }
1559
1560 private:
1561 size_type size_;
1562 value_type value_;
1563 };
1564
1565 // ------------------------
1566 // Array based vector class
1567 // ------------------------
1568
1569 /// \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]
1570 template<class T, std::size_t N>
1571 class c_vector:
1572 public vector_container<c_vector<T, N> > {
1573
1574 typedef c_vector<T, N> self_type;
1575 public:
1576 #ifdef BOOST_UBLAS_ENABLE_PROXY_SHORTCUTS
1577 using vector_container<self_type>::operator ();
1578 #endif
1579 typedef std::size_t size_type;
1580 typedef std::ptrdiff_t difference_type;
1581 typedef T value_type;
1582 typedef const T &const_reference;
1583 typedef T &reference;
1584 typedef value_type array_type[N];
1585 typedef T *pointer;
1586 typedef const T *const_pointer;
1587 typedef const vector_reference<const self_type> const_closure_type;
1588 typedef vector_reference<self_type> closure_type;
1589 typedef self_type vector_temporary_type;
1590 typedef dense_tag storage_category;
1591
1592 // Construction and destruction
1593 BOOST_UBLAS_INLINE
1594 c_vector ():
1595 size_ (N) /* , data_ () */ {}
1596 explicit BOOST_UBLAS_INLINE
1597 c_vector (size_type size):
1598 size_ (size) /* , data_ () */ {
1599 if (size_ > N)
1600 bad_size ().raise ();
1601 }
1602 BOOST_UBLAS_INLINE
1603 c_vector (const c_vector &v):
1604 size_ (v.size_) /* , data_ () */ {
1605 if (size_ > N)
1606 bad_size ().raise ();
1607 assign(v);
1608 }
1609 template<class AE>
1610 BOOST_UBLAS_INLINE
1611 c_vector (const vector_expression<AE> &ae):
1612 size_ (ae ().size ()) /* , data_ () */ {
1613 if (size_ > N)
1614 bad_size ().raise ();
1615 vector_assign<scalar_assign> (*this, ae);
1616 }
1617
1618 // Accessors
1619 BOOST_UBLAS_INLINE
1620 size_type size () const {
1621 return size_;
1622 }
1623 BOOST_UBLAS_INLINE
1624 const_pointer data () const {
1625 return data_;
1626 }
1627 BOOST_UBLAS_INLINE
1628 pointer data () {
1629 return data_;
1630 }
1631
1632 // Resizing
1633 BOOST_UBLAS_INLINE
1634 void resize (size_type size, bool preserve = true) {
1635 if (size > N)
1636 bad_size ().raise ();
1637 size_ = size;
1638 }
1639
1640 // Element support
1641 BOOST_UBLAS_INLINE
1642 pointer find_element (size_type i) {
1643 return const_cast<pointer> (const_cast<const self_type&>(*this).find_element (i));
1644 }
1645 BOOST_UBLAS_INLINE
1646 const_pointer find_element (size_type i) const {
1647 return & data_ [i];
1648 }
1649
1650 // Element access
1651 BOOST_UBLAS_INLINE
1652 const_reference operator () (size_type i) const {
1653 BOOST_UBLAS_CHECK (i < size_, bad_index ());
1654 return data_ [i];
1655 }
1656 BOOST_UBLAS_INLINE
1657 reference operator () (size_type i) {
1658 BOOST_UBLAS_CHECK (i < size_, bad_index ());
1659 return data_ [i];
1660 }
1661
1662 BOOST_UBLAS_INLINE
1663 const_reference operator [] (size_type i) const {
1664 return (*this) (i);
1665 }
1666 BOOST_UBLAS_INLINE
1667 reference operator [] (size_type i) {
1668 return (*this) (i);
1669 }
1670
1671 // Element assignment
1672 BOOST_UBLAS_INLINE
1673 reference insert_element (size_type i, const_reference t) {
1674 BOOST_UBLAS_CHECK (i < size_, bad_index ());
1675 return (data_ [i] = t);
1676 }
1677 BOOST_UBLAS_INLINE
1678 void erase_element (size_type i) {
1679 BOOST_UBLAS_CHECK (i < size_, bad_index ());
1680 data_ [i] = value_type/*zero*/();
1681 }
1682
1683 // Zeroing
1684 BOOST_UBLAS_INLINE
1685 void clear () {
1686 std::fill (data_, data_ + size_, value_type/*zero*/());
1687 }
1688
1689 // Assignment
1690 #ifdef BOOST_UBLAS_MOVE_SEMANTICS
1691
1692 /*! @note "pass by value" the key idea to enable move semantics */
1693 BOOST_UBLAS_INLINE
1694 c_vector &operator = (c_vector v) {
1695 assign_temporary(v);
1696 return *this;
1697 }
1698 #else
1699 BOOST_UBLAS_INLINE
1700 c_vector &operator = (const c_vector &v) {
1701 size_ = v.size_;
1702 std::copy (v.data_, v.data_ + v.size_, data_);
1703 return *this;
1704 }
1705 #endif
1706 template<class C> // Container assignment without temporary
1707 BOOST_UBLAS_INLINE
1708 c_vector &operator = (const vector_container<C> &v) {
1709 resize (v ().size (), false);
1710 assign (v);
1711 return *this;
1712 }
1713 BOOST_UBLAS_INLINE
1714 c_vector &assign_temporary (c_vector &v) {
1715 swap (v);
1716 return *this;
1717 }
1718 template<class AE>
1719 BOOST_UBLAS_INLINE
1720 c_vector &operator = (const vector_expression<AE> &ae) {
1721 self_type temporary (ae);
1722 return assign_temporary (temporary);
1723 }
1724 template<class AE>
1725 BOOST_UBLAS_INLINE
1726 c_vector &assign (const vector_expression<AE> &ae) {
1727 vector_assign<scalar_assign> (*this, ae);
1728 return *this;
1729 }
1730
1731 // Computed assignment
1732 template<class AE>
1733 BOOST_UBLAS_INLINE
1734 c_vector &operator += (const vector_expression<AE> &ae) {
1735 self_type temporary (*this + ae);
1736 return assign_temporary (temporary);
1737 }
1738 template<class C> // Container assignment without temporary
1739 BOOST_UBLAS_INLINE
1740 c_vector &operator += (const vector_container<C> &v) {
1741 plus_assign (v);
1742 return *this;
1743 }
1744 template<class AE>
1745 BOOST_UBLAS_INLINE
1746 c_vector &plus_assign (const vector_expression<AE> &ae) {
1747 vector_assign<scalar_plus_assign> ( *this, ae);
1748 return *this;
1749 }
1750 template<class AE>
1751 BOOST_UBLAS_INLINE
1752 c_vector &operator -= (const vector_expression<AE> &ae) {
1753 self_type temporary (*this - ae);
1754 return assign_temporary (temporary);
1755 }
1756 template<class C> // Container assignment without temporary
1757 BOOST_UBLAS_INLINE
1758 c_vector &operator -= (const vector_container<C> &v) {
1759 minus_assign (v);
1760 return *this;
1761 }
1762 template<class AE>
1763 BOOST_UBLAS_INLINE
1764 c_vector &minus_assign (const vector_expression<AE> &ae) {
1765 vector_assign<scalar_minus_assign> (*this, ae);
1766 return *this;
1767 }
1768 template<class AT>
1769 BOOST_UBLAS_INLINE
1770 c_vector &operator *= (const AT &at) {
1771 vector_assign_scalar<scalar_multiplies_assign> (*this, at);
1772 return *this;
1773 }
1774 template<class AT>
1775 BOOST_UBLAS_INLINE
1776 c_vector &operator /= (const AT &at) {
1777 vector_assign_scalar<scalar_divides_assign> (*this, at);
1778 return *this;
1779 }
1780
1781 // Swapping
1782 BOOST_UBLAS_INLINE
1783 void swap (c_vector &v) {
1784 if (this != &v) {
1785 BOOST_UBLAS_CHECK (size_ == v.size_, bad_size ());
1786 std::swap (size_, v.size_);
1787 std::swap_ranges (data_, data_ + size_, v.data_);
1788 }
1789 }
1790 BOOST_UBLAS_INLINE
1791 friend void swap (c_vector &v1, c_vector &v2) {
1792 v1.swap (v2);
1793 }
1794
1795 // Iterator types
1796 private:
1797 // Use pointers for iterator
1798 typedef const_pointer const_subiterator_type;
1799 typedef pointer subiterator_type;
1800
1801 public:
1802 #ifdef BOOST_UBLAS_USE_INDEXED_ITERATOR
1803 typedef indexed_iterator<self_type, dense_random_access_iterator_tag> iterator;
1804 typedef indexed_const_iterator<self_type, dense_random_access_iterator_tag> const_iterator;
1805 #else
1806 class const_iterator;
1807 class iterator;
1808 #endif
1809
1810 // Element lookup
1811 BOOST_UBLAS_INLINE
1812 const_iterator find (size_type i) const {
1813 #ifndef BOOST_UBLAS_USE_INDEXED_ITERATOR
1814 return const_iterator (*this, &data_ [i]);
1815 #else
1816 return const_iterator (*this, i);
1817 #endif
1818 }
1819 BOOST_UBLAS_INLINE
1820 iterator find (size_type i) {
1821 #ifndef BOOST_UBLAS_USE_INDEXED_ITERATOR
1822 return iterator (*this, &data_ [i]);
1823 #else
1824 return iterator (*this, i);
1825 #endif
1826 }
1827
1828 #ifndef BOOST_UBLAS_USE_INDEXED_ITERATOR
1829 class const_iterator:
1830 public container_const_reference<c_vector>,
1831 public random_access_iterator_base<dense_random_access_iterator_tag,
1832 const_iterator, value_type> {
1833 public:
1834 typedef typename c_vector::difference_type difference_type;
1835 typedef typename c_vector::value_type value_type;
1836 typedef typename c_vector::const_reference reference;
1837 typedef typename c_vector::const_pointer pointer;
1838
1839 // Construction and destruction
1840 BOOST_UBLAS_INLINE
1841 const_iterator ():
1842 container_const_reference<self_type> (), it_ () {}
1843 BOOST_UBLAS_INLINE
1844 const_iterator (const self_type &v, const const_subiterator_type &it):
1845 container_const_reference<self_type> (v), it_ (it) {}
1846 BOOST_UBLAS_INLINE
1847 const_iterator (const typename self_type::iterator &it): // ISSUE self_type:: stops VC8 using std::iterator here
1848 container_const_reference<self_type> (it ()), it_ (it.it_) {}
1849
1850 // Arithmetic
1851 BOOST_UBLAS_INLINE
1852 const_iterator &operator ++ () {
1853 ++ it_;
1854 return *this;
1855 }
1856 BOOST_UBLAS_INLINE
1857 const_iterator &operator -- () {
1858 -- it_;
1859 return *this;
1860 }
1861 BOOST_UBLAS_INLINE
1862 const_iterator &operator += (difference_type n) {
1863 it_ += n;
1864 return *this;
1865 }
1866 BOOST_UBLAS_INLINE
1867 const_iterator &operator -= (difference_type n) {
1868 it_ -= n;
1869 return *this;
1870 }
1871 BOOST_UBLAS_INLINE
1872 difference_type operator - (const const_iterator &it) const {
1873 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
1874 return it_ - it.it_;
1875 }
1876
1877 // Dereference
1878 BOOST_UBLAS_INLINE
1879 const_reference operator * () const {
1880 BOOST_UBLAS_CHECK (it_ >= (*this) ().begin ().it_ && it_ < (*this) ().end ().it_, bad_index ());
1881 return *it_;
1882 }
1883 BOOST_UBLAS_INLINE
1884 const_reference operator [] (difference_type n) const {
1885 return *(it_ + n);
1886 }
1887
1888 // Index
1889 BOOST_UBLAS_INLINE
1890 size_type index () const {
1891 BOOST_UBLAS_CHECK (it_ >= (*this) ().begin ().it_ && it_ < (*this) ().end ().it_, bad_index ());
1892 const self_type &v = (*this) ();
1893 return it_ - v.begin ().it_;
1894 }
1895
1896 // Assignment
1897 BOOST_UBLAS_INLINE
1898 const_iterator &operator = (const const_iterator &it) {
1899 container_const_reference<self_type>::assign (&it ());
1900 it_ = it.it_;
1901 return *this;
1902 }
1903
1904 // Comparison
1905 BOOST_UBLAS_INLINE
1906 bool operator == (const const_iterator &it) const {
1907 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
1908 return it_ == it.it_;
1909 }
1910 BOOST_UBLAS_INLINE
1911 bool operator < (const const_iterator &it) const {
1912 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
1913 return it_ < it.it_;
1914 }
1915
1916 private:
1917 const_subiterator_type it_;
1918
1919 friend class iterator;
1920 };
1921 #endif
1922
1923 BOOST_UBLAS_INLINE
1924 const_iterator begin () const {
1925 return find (0);
1926 }
1927 BOOST_UBLAS_INLINE
1928 const_iterator end () const {
1929 return find (size_);
1930 }
1931
1932 #ifndef BOOST_UBLAS_USE_INDEXED_ITERATOR
1933 class iterator:
1934 public container_reference<c_vector>,
1935 public random_access_iterator_base<dense_random_access_iterator_tag,
1936 iterator, value_type> {
1937 public:
1938 typedef typename c_vector::difference_type difference_type;
1939 typedef typename c_vector::value_type value_type;
1940 typedef typename c_vector::reference reference;
1941 typedef typename c_vector::pointer pointer;
1942
1943 // Construction and destruction
1944 BOOST_UBLAS_INLINE
1945 iterator ():
1946 container_reference<self_type> (), it_ () {}
1947 BOOST_UBLAS_INLINE
1948 iterator (self_type &v, const subiterator_type &it):
1949 container_reference<self_type> (v), it_ (it) {}
1950
1951 // Arithmetic
1952 BOOST_UBLAS_INLINE
1953 iterator &operator ++ () {
1954 ++ it_;
1955 return *this;
1956 }
1957 BOOST_UBLAS_INLINE
1958 iterator &operator -- () {
1959 -- it_;
1960 return *this;
1961 }
1962 BOOST_UBLAS_INLINE
1963 iterator &operator += (difference_type n) {
1964 it_ += n;
1965 return *this;
1966 }
1967 BOOST_UBLAS_INLINE
1968 iterator &operator -= (difference_type n) {
1969 it_ -= n;
1970 return *this;
1971 }
1972 BOOST_UBLAS_INLINE
1973 difference_type operator - (const iterator &it) const {
1974 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
1975 return it_ - it.it_;
1976 }
1977
1978 // Dereference
1979 BOOST_UBLAS_INLINE
1980 reference operator * () const {
1981 BOOST_UBLAS_CHECK (it_ >= (*this) ().begin ().it_ && it_ < (*this) ().end ().it_, bad_index ());
1982 return *it_;
1983 }
1984 BOOST_UBLAS_INLINE
1985 reference operator [] (difference_type n) const {
1986 return *(it_ + n);
1987 }
1988
1989 // Index
1990 BOOST_UBLAS_INLINE
1991 size_type index () const {
1992 BOOST_UBLAS_CHECK (it_ >= (*this) ().begin ().it_ && it_ < (*this) ().end ().it_, bad_index ());
1993 // EDG won't allow const self_type it doesn't allow friend access to it_
1994 self_type &v = (*this) ();
1995 return it_ - v.begin ().it_;
1996 }
1997
1998 // Assignment
1999 BOOST_UBLAS_INLINE
2000 iterator &operator = (const iterator &it) {
2001 container_reference<self_type>::assign (&it ());
2002 it_ = it.it_;
2003 return *this;
2004 }
2005
2006 // Comparison
2007 BOOST_UBLAS_INLINE
2008 bool operator == (const iterator &it) const {
2009 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
2010 return it_ == it.it_;
2011 }
2012 BOOST_UBLAS_INLINE
2013 bool operator < (const iterator &it) const {
2014 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
2015 return it_ < it.it_;
2016 }
2017
2018 private:
2019 subiterator_type it_;
2020
2021 friend class const_iterator;
2022 };
2023 #endif
2024
2025 BOOST_UBLAS_INLINE
2026 iterator begin () {
2027 return find (0);
2028 }
2029 BOOST_UBLAS_INLINE
2030 iterator end () {
2031 return find (size_);
2032 }
2033
2034 // Reverse iterator
2035 typedef reverse_iterator_base<const_iterator> const_reverse_iterator;
2036 typedef reverse_iterator_base<iterator> reverse_iterator;
2037
2038 BOOST_UBLAS_INLINE
2039 const_reverse_iterator rbegin () const {
2040 return const_reverse_iterator (end ());
2041 }
2042 BOOST_UBLAS_INLINE
2043 const_reverse_iterator rend () const {
2044 return const_reverse_iterator (begin ());
2045 }
2046 BOOST_UBLAS_INLINE
2047 reverse_iterator rbegin () {
2048 return reverse_iterator (end ());
2049 }
2050 BOOST_UBLAS_INLINE
2051 reverse_iterator rend () {
2052 return reverse_iterator (begin ());
2053 }
2054
2055 // Serialization
2056 template<class Archive>
2057 void serialize(Archive & ar, const unsigned int /* file_version */){
2058 serialization::collection_size_type s (size_);
2059 ar & serialization::make_nvp("size",s);
2060
2061 // copy the value back if loading
2062 if (Archive::is_loading::value) {
2063 if (s > N) bad_size("too large size in bounded_vector::load()\n").raise();
2064 size_ = s;
2065 }
2066 // ISSUE: this writes the full array
2067 ar & serialization::make_nvp("data",data_);
2068 }
2069
2070 private:
2071 size_type size_;
2072 array_type data_;
2073 };
2074
2075 }}}
2076
2077 #endif