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