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