Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 09:43:17

0001 //
0002 //  Copyright (c) 2000-2010
0003 //  Joerg Walter, Mathias Koch, David Bellot
0004 //  Copyright (c) 2014, Athanasios Iliopoulos
0005 //
0006 //  Distributed under the Boost Software License, Version 1.0. (See
0007 //  accompanying file LICENSE_1_0.txt or copy at
0008 //  http://www.boost.org/LICENSE_1_0.txt)
0009 //
0010 //  The authors gratefully acknowledge the support of
0011 //  GeNeSys mbH & Co. KG in producing this work.
0012 //
0013 //  And we acknowledge the support from all contributors.
0014 
0015 /// \file vector.hpp Definition for the class vector and its derivative
0016 
0017 #ifndef _BOOST_UBLAS_VECTOR_
0018 #define _BOOST_UBLAS_VECTOR_
0019 
0020 #include <boost/config.hpp>
0021 #include <boost/numeric/ublas/storage.hpp>
0022 #include <boost/numeric/ublas/vector_expression.hpp>
0023 #include <boost/numeric/ublas/detail/vector_assign.hpp>
0024 #include <boost/serialization/collection_size_type.hpp>
0025 #include <boost/serialization/nvp.hpp>
0026 
0027 #ifdef BOOST_UBLAS_CPP_GE_2011
0028 #include <array>
0029 #include <initializer_list>
0030 #if defined(BOOST_MSVC) // For std::forward in fixed_vector
0031 #include <utility>
0032 #endif
0033 #endif
0034 
0035 // Iterators based on ideas of Jeremy Siek
0036 
0037 namespace boost { namespace numeric { namespace ublas {
0038 
0039      /** \brief A dense vector of values of type \c T.
0040       *
0041       * 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 
0042       * to the \f$i\f$-th element of the container. A storage type \c A can be specified which defaults to \c unbounded_array. 
0043       * Elements are constructed by \c A, which need not initialise their value.
0044       *
0045       * \tparam T type of the objects stored in the vector (like int, double, complex,...)
0046       * \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
0047       */
0048      template<class T, class A>
0049      class vector:
0050          public vector_container<vector<T, A> > {
0051 
0052          typedef vector<T, A> self_type;
0053      public:
0054 #ifdef BOOST_UBLAS_ENABLE_PROXY_SHORTCUTS
0055          using vector_container<self_type>::operator ();
0056 #endif
0057 
0058     typedef typename A::size_type size_type;
0059         typedef typename A::difference_type difference_type;
0060         typedef T value_type;
0061         typedef typename type_traits<T>::const_reference const_reference;
0062         typedef T &reference;
0063         typedef T *pointer;
0064         typedef const T *const_pointer;
0065         typedef A array_type;
0066         typedef const vector_reference<const self_type> const_closure_type;
0067         typedef vector_reference<self_type> closure_type;
0068         typedef self_type vector_temporary_type;
0069         typedef dense_tag storage_category;
0070 
0071         // Construction and destruction
0072     
0073     /// \brief Constructor of a vector
0074     /// By default it is empty, i.e. \c size()==0.
0075         BOOST_UBLAS_INLINE
0076         vector ():
0077             vector_container<self_type> (),
0078             data_ () {}
0079 
0080     /// \brief Constructor of a vector with a predefined size
0081     /// By default, its elements are initialized to 0.
0082     /// \param size initial size of the vector
0083         explicit BOOST_UBLAS_INLINE
0084         vector (size_type size):
0085             vector_container<self_type> (),
0086             data_ (size) {
0087         }
0088 
0089     /// \brief Constructor of a vector by copying from another container
0090     /// This type has the generic name \c array_typ within the vector definition.
0091     /// \param size initial size of the vector \bug this value is not used
0092     /// \param data container of type \c A
0093     /// \todo remove this definition because \c size is not used
0094         BOOST_UBLAS_INLINE
0095         vector (size_type /*size*/, const array_type &data):
0096             vector_container<self_type> (),
0097             data_ (data) {}
0098 
0099     /// \brief Constructor of a vector by copying from another container
0100     /// This type has the generic name \c array_typ within the vector definition.
0101     /// \param data container of type \c A
0102          BOOST_UBLAS_INLINE
0103          vector (const array_type &data):
0104              vector_container<self_type> (),
0105              data_ (data) {}
0106 
0107     /// \brief Constructor of a vector with a predefined size and a unique initial value
0108     /// \param size of the vector
0109     /// \param init value to assign to each element of the vector
0110         BOOST_UBLAS_INLINE
0111         vector (size_type size, const value_type &init):
0112             vector_container<self_type> (),
0113             data_ (size, init) {}
0114 
0115     /// \brief Copy-constructor of a vector
0116     /// \param v is the vector to be duplicated
0117         BOOST_UBLAS_INLINE
0118         vector (const vector &v):
0119             vector_container<self_type> (),
0120             data_ (v.data_) {}
0121 
0122     /// \brief Copy-constructor of a vector from a vector_expression
0123     /// Depending on the vector_expression, this constructor can have the cost of the computations 
0124     /// of the expression (trivial to say it, but it is to take into account in your complexity calculations).
0125     /// \param ae the vector_expression which values will be duplicated into the vector
0126         template<class AE>
0127         BOOST_UBLAS_INLINE
0128         vector (const vector_expression<AE> &ae):
0129             vector_container<self_type> (),
0130             data_ (ae ().size ()) {
0131             vector_assign<scalar_assign> (*this, ae);
0132         }
0133 
0134     // -----------------------
0135     // Random Access Container
0136     // -----------------------
0137     
0138     /// \brief Return the maximum size of the data container.
0139     /// 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.
0140         BOOST_UBLAS_INLINE
0141         size_type max_size () const {
0142             return data_.max_size ();
0143         }
0144         
0145     /// \brief Return true if the vector is empty (\c size==0)
0146     /// \return \c true if empty, \c false otherwise
0147         BOOST_UBLAS_INLINE
0148         bool empty () const {
0149             return data_.size () == 0;
0150         }
0151 
0152     // ---------
0153     // Accessors
0154     // ---------
0155     
0156     /// \brief Return the size of the vector
0157          BOOST_UBLAS_INLINE
0158          size_type size () const {
0159              return data_.size ();
0160          }
0161 
0162     // -----------------
0163     // Storage accessors
0164     // -----------------
0165     
0166     /// \brief Return a \c const reference to the container. Useful to access data directly for specific type of container.
0167          BOOST_UBLAS_INLINE
0168          const array_type &data () const {
0169              return data_;
0170          }
0171 
0172     /// \brief Return a reference to the container. Useful to speed-up write operations to the data in very specific case.
0173          BOOST_UBLAS_INLINE
0174          array_type &data () {
0175              return data_;
0176          }
0177 
0178     // --------
0179          // Resizing
0180     // --------
0181     
0182     /// \brief Resize the vector
0183     /// 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.
0184     /// \param size new size of the vector
0185     /// \param preserve if true, keep values
0186          BOOST_UBLAS_INLINE
0187          void resize (size_type size, bool preserve = true) {
0188              if (preserve)
0189                  data ().resize (size, typename A::value_type ());
0190              else
0191                  data ().resize (size);
0192          }
0193 
0194     // ---------------
0195          // Element support
0196     // ---------------
0197     
0198     /// \brief Return a pointer to the element \f$i\f$
0199     /// \param i index of the element
0200     // XXX this semantic is not the one expected by the name of this method
0201          BOOST_UBLAS_INLINE
0202          pointer find_element (size_type i) {
0203              return const_cast<pointer> (const_cast<const self_type&>(*this).find_element (i));
0204          }
0205 
0206     /// \brief Return a const pointer to the element \f$i\f$
0207     /// \param i index of the element
0208     // XXX  this semantic is not the one expected by the name of this method
0209          BOOST_UBLAS_INLINE
0210          const_pointer find_element (size_type i) const {
0211              return & (data () [i]);
0212          }
0213 
0214     // --------------
0215          // Element access
0216     // --------------
0217 
0218     /// \brief Return a const reference to the element \f$i\f$
0219     /// Return a const reference to the element \f$i\f$. With some compilers, this notation will be faster than \c[i]
0220     /// \param i index of the element
0221          BOOST_UBLAS_INLINE
0222          const_reference operator () (size_type i) const {
0223              return data () [i];
0224          }
0225     
0226     /// \brief Return a reference to the element \f$i\f$
0227     /// Return a reference to the element \f$i\f$. With some compilers, this notation will be faster than \c[i]
0228     /// \param i index of the element
0229          BOOST_UBLAS_INLINE
0230          reference operator () (size_type i) {
0231              return data () [i];
0232          }
0233 
0234     /// \brief Return a const reference to the element \f$i\f$
0235     /// \param i index of the element
0236          BOOST_UBLAS_INLINE
0237          const_reference operator [] (size_type i) const {
0238              return (*this) (i);
0239          }
0240     
0241     /// \brief Return a reference to the element \f$i\f$
0242     /// \param i index of the element
0243          BOOST_UBLAS_INLINE
0244          reference operator [] (size_type i) {
0245              return (*this) (i);
0246          }
0247 
0248     // ------------------
0249          // Element assignment
0250     // ------------------
0251     
0252     /// \brief Set element \f$i\f$ to the value \c t
0253     /// \param i index of the element
0254     /// \param t reference to the value to be set
0255     // XXX semantic of this is to insert a new element and therefore size=size+1 ?
0256          BOOST_UBLAS_INLINE
0257          reference insert_element (size_type i, const_reference t) {
0258              return (data () [i] = t);
0259          }
0260 
0261     /// \brief Set element \f$i\f$ to the \e zero value
0262     /// \param i index of the element
0263          BOOST_UBLAS_INLINE
0264          void erase_element (size_type i) {
0265              data () [i] = value_type/*zero*/();
0266          }
0267          
0268     // -------
0269          // Zeroing
0270     // -------
0271     
0272     /// \brief Clear the vector, i.e. set all values to the \c zero value.
0273          BOOST_UBLAS_INLINE
0274          void clear () {
0275              std::fill (data ().begin (), data ().end (), value_type/*zero*/());
0276          }
0277 
0278          // Assignment
0279 #ifdef BOOST_UBLAS_MOVE_SEMANTICS
0280 
0281     /// \brief Assign a full vector (\e RHS-vector) to the current vector (\e LHS-vector)
0282     /// \param v is the source vector
0283     /// \return a reference to a vector (i.e. the destination vector)
0284          /*! @note "pass by value" the key idea to enable move semantics */
0285          BOOST_UBLAS_INLINE
0286          vector &operator = (vector v) {
0287              assign_temporary(v);
0288              return *this;
0289          }
0290 #else
0291     /// \brief Assign a full vector (\e RHS-vector) to the current vector (\e LHS-vector)
0292     /// \param v is the source vector
0293     /// \return a reference to a vector (i.e. the destination vector)
0294          BOOST_UBLAS_INLINE
0295          vector &operator = (const vector &v) {
0296              data () = v.data ();
0297              return *this;
0298          }
0299 #endif
0300 
0301     /// \brief Assign a full vector (\e RHS-vector) to the current vector (\e LHS-vector)
0302     /// Assign a full vector (\e RHS-vector) to the current vector (\e LHS-vector). This method does not create any temporary.
0303     /// \param v is the source vector container
0304     /// \return a reference to a vector (i.e. the destination vector)
0305          template<class C>          // Container assignment without temporary
0306          BOOST_UBLAS_INLINE
0307          vector &operator = (const vector_container<C> &v) {
0308              resize (v ().size (), false);
0309              assign (v);
0310              return *this;
0311          }
0312 
0313     /// \brief Assign a full vector (\e RHS-vector) to the current vector (\e LHS-vector)
0314     /// \param v is the source vector
0315     /// \return a reference to a vector (i.e. the destination vector)
0316          BOOST_UBLAS_INLINE
0317          vector &assign_temporary (vector &v) {
0318              swap (v);
0319              return *this;
0320          }
0321 
0322     /// \brief Assign the result of a vector_expression to the vector
0323     /// 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.
0324     /// \tparam AE is the type of the vector_expression
0325     /// \param ae is a const reference to the vector_expression
0326     /// \return a reference to the resulting vector
0327          template<class AE>
0328          BOOST_UBLAS_INLINE
0329          vector &operator = (const vector_expression<AE> &ae) {
0330              self_type temporary (ae);
0331              return assign_temporary (temporary);
0332          }
0333 
0334     /// \brief Assign the result of a vector_expression to the vector
0335     /// 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.
0336     /// \tparam AE is the type of the vector_expression
0337     /// \param ae is a const reference to the vector_expression
0338     /// \return a reference to the resulting vector
0339          template<class AE>
0340          BOOST_UBLAS_INLINE
0341          vector &assign (const vector_expression<AE> &ae) {
0342              vector_assign<scalar_assign> (*this, ae);
0343              return *this;
0344          }
0345 
0346     // -------------------
0347          // Computed assignment
0348     // -------------------
0349     
0350     /// \brief Assign the sum of the vector and a vector_expression to the vector
0351     /// 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.
0352     /// A temporary is created for the computations.
0353     /// \tparam AE is the type of the vector_expression
0354     /// \param ae is a const reference to the vector_expression
0355     /// \return a reference to the resulting vector
0356          template<class AE>
0357          BOOST_UBLAS_INLINE
0358          vector &operator += (const vector_expression<AE> &ae) {
0359              self_type temporary (*this + ae);
0360              return assign_temporary (temporary);
0361          }
0362 
0363     /// \brief Assign the sum of the vector and a vector_expression to the vector
0364     /// 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.
0365     /// No temporary is created. Computations are done and stored directly into the resulting vector.
0366     /// \tparam AE is the type of the vector_expression
0367     /// \param ae is a const reference to the vector_expression
0368     /// \return a reference to the resulting vector
0369          template<class C>          // Container assignment without temporary
0370          BOOST_UBLAS_INLINE
0371          vector &operator += (const vector_container<C> &v) {
0372              plus_assign (v);
0373              return *this;
0374          }
0375 
0376     /// \brief Assign the sum of the vector and a vector_expression to the vector
0377     /// 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.
0378     /// No temporary is created. Computations are done and stored directly into the resulting vector.
0379     /// \tparam AE is the type of the vector_expression
0380     /// \param ae is a const reference to the vector_expression
0381     /// \return a reference to the resulting vector
0382          template<class AE>
0383          BOOST_UBLAS_INLINE
0384          vector &plus_assign (const vector_expression<AE> &ae) {
0385              vector_assign<scalar_plus_assign> (*this, ae);
0386              return *this;
0387          }
0388     
0389     /// \brief Assign the difference of the vector and a vector_expression to the vector
0390     /// 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.
0391     /// A temporary is created for the computations.
0392     /// \tparam AE is the type of the vector_expression
0393     /// \param ae is a const reference to the vector_expression
0394          template<class AE>
0395          BOOST_UBLAS_INLINE
0396          vector &operator -= (const vector_expression<AE> &ae) {
0397              self_type temporary (*this - ae);
0398              return assign_temporary (temporary);
0399          }
0400 
0401     /// \brief Assign the difference of the vector and a vector_expression to the vector
0402     /// 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.
0403     /// No temporary is created. Computations are done and stored directly into the resulting vector.
0404     /// \tparam AE is the type of the vector_expression
0405     /// \param ae is a const reference to the vector_expression
0406     /// \return a reference to the resulting vector
0407          template<class C>          // Container assignment without temporary
0408          BOOST_UBLAS_INLINE
0409          vector &operator -= (const vector_container<C> &v) {
0410              minus_assign (v);
0411              return *this;
0412          }
0413 
0414     /// \brief Assign the difference of the vector and a vector_expression to the vector
0415     /// 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.
0416     /// No temporary is created. Computations are done and stored directly into the resulting vector.
0417     /// \tparam AE is the type of the vector_expression
0418     /// \param ae is a const reference to the vector_expression
0419     /// \return a reference to the resulting vector
0420          template<class AE>
0421          BOOST_UBLAS_INLINE
0422          vector &minus_assign (const vector_expression<AE> &ae) {
0423              vector_assign<scalar_minus_assign> (*this, ae);
0424              return *this;
0425          }
0426 
0427     /// \brief Assign the product of the vector and a scalar to the vector
0428     /// 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.
0429     /// No temporary is created. Computations are done and stored directly into the resulting vector.
0430     /// \tparam AE is the type of the vector_expression
0431     /// \param at is a const reference to the scalar
0432     /// \return a reference to the resulting vector
0433          template<class AT>
0434          BOOST_UBLAS_INLINE
0435          vector &operator *= (const AT &at) {
0436              vector_assign_scalar<scalar_multiplies_assign> (*this, at);
0437              return *this;
0438          }
0439 
0440     /// \brief Assign the division of the vector by a scalar to the vector
0441     /// 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.
0442     /// No temporary is created. Computations are done and stored directly into the resulting vector.
0443     /// \tparam AE is the type of the vector_expression
0444     /// \param at is a const reference to the scalar
0445     /// \return a reference to the resulting vector
0446         template<class AT>
0447         BOOST_UBLAS_INLINE
0448         vector &operator /= (const AT &at) {
0449             vector_assign_scalar<scalar_divides_assign> (*this, at);
0450             return *this;
0451         }
0452     
0453     // --------
0454         // Swapping
0455     // --------
0456     
0457     /// \brief Swap the content of the vector with another vector
0458     /// \param v is the vector to be swapped with
0459         BOOST_UBLAS_INLINE
0460         void swap (vector &v) {
0461             if (this != &v) {
0462                 data ().swap (v.data ());
0463             }
0464         }
0465 
0466     /// \brief Swap the content of two vectors
0467     /// \param v1 is the first vector. It takes values from v2
0468     /// \param v2 is the second vector It takes values from v1
0469          BOOST_UBLAS_INLINE
0470          friend void swap (vector &v1, vector &v2) {
0471              v1.swap (v2);
0472          }
0473 
0474          // Iterator types
0475      private:
0476          // Use the storage array iterator
0477          typedef typename A::const_iterator const_subiterator_type;
0478          typedef typename A::iterator subiterator_type;
0479 
0480      public:
0481 #ifdef BOOST_UBLAS_USE_INDEXED_ITERATOR
0482          typedef indexed_iterator<self_type, dense_random_access_iterator_tag> iterator;
0483          typedef indexed_const_iterator<self_type, dense_random_access_iterator_tag> const_iterator;
0484 #else
0485          class const_iterator;
0486          class iterator;
0487 #endif
0488 
0489     // --------------
0490         // Element lookup
0491     // --------------
0492     
0493     /// \brief Return a const iterator to the element \e i
0494     /// \param i index of the element
0495          BOOST_UBLAS_INLINE
0496          const_iterator find (size_type i) const {
0497 #ifndef BOOST_UBLAS_USE_INDEXED_ITERATOR
0498              return const_iterator (*this, data ().begin () + i);
0499 #else
0500              return const_iterator (*this, i);
0501 #endif
0502          }
0503 
0504     /// \brief Return an iterator to the element \e i
0505     /// \param i index of the element
0506          BOOST_UBLAS_INLINE
0507          iterator find (size_type i) {
0508 #ifndef BOOST_UBLAS_USE_INDEXED_ITERATOR
0509              return iterator (*this, data ().begin () + i);
0510 #else
0511              return iterator (*this, i);
0512 #endif
0513          }
0514 
0515 #ifndef BOOST_UBLAS_USE_INDEXED_ITERATOR
0516          class const_iterator:
0517              public container_const_reference<vector>,
0518              public random_access_iterator_base<dense_random_access_iterator_tag,
0519                    const_iterator, value_type, difference_type> {
0520          public:
0521              typedef typename vector::difference_type difference_type;
0522              typedef typename vector::value_type value_type;
0523              typedef typename vector::const_reference reference;
0524              typedef const typename vector::pointer pointer;
0525 
0526         // ----------------------------
0527             // Construction and destruction
0528         // ----------------------------
0529     
0530     
0531             BOOST_UBLAS_INLINE
0532             const_iterator ():
0533                 container_const_reference<self_type> (), it_ () {}
0534             BOOST_UBLAS_INLINE
0535             const_iterator (const self_type &v, const const_subiterator_type &it):
0536                 container_const_reference<self_type> (v), it_ (it) {}
0537             BOOST_UBLAS_INLINE
0538             const_iterator (const typename self_type::iterator &it):  // ISSUE vector:: stops VC8 using std::iterator here
0539                 container_const_reference<self_type> (it ()), it_ (it.it_) {}
0540     
0541         // ----------
0542             // Arithmetic
0543         // ----------
0544     
0545         /// \brief Increment by 1 the position of the iterator
0546         /// \return a reference to the const iterator
0547             BOOST_UBLAS_INLINE
0548             const_iterator &operator ++ () {
0549                 ++ it_;
0550                 return *this;
0551             }
0552 
0553         /// \brief Decrement by 1 the position of the iterator
0554         /// \return a reference to the const iterator
0555             BOOST_UBLAS_INLINE
0556             const_iterator &operator -- () {
0557                 -- it_;
0558                 return *this;
0559             }
0560       
0561         /// \brief Increment by \e n the position of the iterator 
0562         /// \return a reference to the const iterator
0563             BOOST_UBLAS_INLINE
0564             const_iterator &operator += (difference_type n) {
0565                 it_ += n;
0566                 return *this;
0567             }
0568     
0569         /// \brief Decrement by \e n the position of the iterator 
0570         /// \return a reference to the const iterator
0571             BOOST_UBLAS_INLINE
0572             const_iterator &operator -= (difference_type n) {
0573                 it_ -= n;
0574                 return *this;
0575             }
0576     
0577         /// \brief Return the different in number of positions between 2 iterators
0578             BOOST_UBLAS_INLINE
0579             difference_type operator - (const const_iterator &it) const {
0580                 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
0581                 return it_ - it.it_;
0582             }
0583     
0584             /// \brief Dereference an iterator
0585             /// Dereference an iterator: a bounds' check is done before returning the value. A bad_index() expection is returned if out of bounds.
0586         /// \return a const reference to the value pointed by the iterator
0587             BOOST_UBLAS_INLINE
0588             const_reference operator * () const {
0589                 BOOST_UBLAS_CHECK (it_ >= (*this) ().begin ().it_ && it_ < (*this) ().end ().it_, bad_index ());
0590                 return *it_;
0591             }
0592     
0593         /// \brief Dereference an iterator at the n-th forward value
0594         /// Dereference an iterator at the n-th forward value, that is the value pointed by iterator+n.
0595             /// A bounds' check is done before returning the value. A bad_index() expection is returned if out of bounds.
0596         /// \return a const reference
0597             BOOST_UBLAS_INLINE
0598             const_reference operator [] (difference_type n) const {
0599                 return *(it_ + n);
0600             }
0601     
0602             // Index
0603         /// \brief return the index of the element referenced by the iterator
0604              BOOST_UBLAS_INLINE
0605              size_type index () const {
0606                  BOOST_UBLAS_CHECK (it_ >= (*this) ().begin ().it_ && it_ < (*this) ().end ().it_, bad_index ());
0607                  return it_ - (*this) ().begin ().it_;
0608              }
0609 
0610              // Assignment
0611              BOOST_UBLAS_INLINE
0612         /// \brief assign the value of an iterator to the iterator     
0613              const_iterator &operator = (const const_iterator &it) {
0614                  container_const_reference<self_type>::assign (&it ());
0615                  it_ = it.it_;
0616                  return *this;
0617              }
0618 
0619              // Comparison
0620         /// \brief compare the value of two itetarors
0621         /// \return true if they reference the same element
0622             BOOST_UBLAS_INLINE
0623             bool operator == (const const_iterator &it) const {
0624                 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
0625                 return it_ == it.it_;
0626             }
0627 
0628     
0629         /// \brief compare the value of two iterators
0630         /// \return return true if the left-hand-side iterator refers to a value placed before the right-hand-side iterator
0631              BOOST_UBLAS_INLINE
0632              bool operator < (const const_iterator &it) const {
0633                  BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
0634                  return it_ < it.it_;
0635              }
0636 
0637          private:
0638              const_subiterator_type it_;
0639 
0640              friend class iterator;
0641          };
0642 #endif
0643 
0644     /// \brief return an iterator on the first element of the vector
0645         BOOST_UBLAS_INLINE
0646         const_iterator begin () const {
0647             return find (0);
0648         }
0649 
0650     /// \brief return an iterator on the first element of the vector
0651         BOOST_UBLAS_INLINE
0652         const_iterator cbegin () const {
0653             return begin ();
0654         }
0655 
0656     /// \brief return an iterator after the last element of the vector
0657         BOOST_UBLAS_INLINE
0658         const_iterator end () const {
0659             return find (data_.size ());
0660         }
0661 
0662     /// \brief return an iterator after the last element of the vector
0663          BOOST_UBLAS_INLINE
0664          const_iterator cend () const {
0665              return end ();
0666          }
0667 
0668 #ifndef BOOST_UBLAS_USE_INDEXED_ITERATOR
0669          class iterator:
0670              public container_reference<vector>,
0671              public random_access_iterator_base<dense_random_access_iterator_tag,
0672                                                 iterator, value_type, difference_type> {
0673          public:
0674              typedef typename vector::difference_type difference_type;
0675              typedef typename vector::value_type value_type;
0676              typedef typename vector::reference reference;
0677              typedef typename vector::pointer pointer;
0678 
0679 
0680              // Construction and destruction
0681              BOOST_UBLAS_INLINE
0682              iterator ():
0683                  container_reference<self_type> (), it_ () {}
0684              BOOST_UBLAS_INLINE
0685              iterator (self_type &v, const subiterator_type &it):
0686                  container_reference<self_type> (v), it_ (it) {}
0687 
0688              // Arithmetic
0689              BOOST_UBLAS_INLINE
0690              iterator &operator ++ () {
0691                  ++ it_;
0692                  return *this;
0693              }
0694              BOOST_UBLAS_INLINE
0695              iterator &operator -- () {
0696                  -- it_;
0697                  return *this;
0698              }
0699              BOOST_UBLAS_INLINE
0700              iterator &operator += (difference_type n) {
0701                  it_ += n;
0702                  return *this;
0703              }
0704              BOOST_UBLAS_INLINE
0705              iterator &operator -= (difference_type n) {
0706                  it_ -= n;
0707                  return *this;
0708              }
0709              BOOST_UBLAS_INLINE
0710              difference_type operator - (const iterator &it) const {
0711                  BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
0712                  return it_ - it.it_;
0713              }
0714 
0715              // Dereference
0716              BOOST_UBLAS_INLINE
0717              reference operator * () const {
0718                  BOOST_UBLAS_CHECK (it_ >= (*this) ().begin ().it_ && it_ < (*this) ().end ().it_ , bad_index ());
0719                  return *it_;
0720              }
0721              BOOST_UBLAS_INLINE
0722              reference operator [] (difference_type n) const {
0723                  return *(it_ + n);
0724              }
0725 
0726              // Index
0727              BOOST_UBLAS_INLINE
0728              size_type index () const {
0729                  BOOST_UBLAS_CHECK (it_ >= (*this) ().begin ().it_ && it_ < (*this) ().end ().it_ , bad_index ());
0730                  return it_ - (*this) ().begin ().it_;
0731              }
0732 
0733              // Assignment
0734              BOOST_UBLAS_INLINE
0735              iterator &operator = (const iterator &it) {
0736                  container_reference<self_type>::assign (&it ());
0737                  it_ = it.it_;
0738                  return *this;
0739              }
0740 
0741              // Comparison
0742              BOOST_UBLAS_INLINE
0743              bool operator == (const iterator &it) const {
0744                  BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
0745                  return it_ == it.it_;
0746              }
0747              BOOST_UBLAS_INLINE
0748              bool operator < (const iterator &it) const {
0749                  BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
0750                  return it_ < it.it_;
0751              }
0752 
0753          private:
0754              subiterator_type it_;
0755 
0756              friend class const_iterator;
0757          };
0758 #endif
0759 
0760     /// \brief Return an iterator on the first element of the vector
0761         BOOST_UBLAS_INLINE
0762         iterator begin () {
0763             return find (0);
0764         }
0765     
0766     /// \brief Return an iterator at the end of the vector
0767         BOOST_UBLAS_INLINE
0768         iterator end () {
0769             return find (data_.size ());
0770         }
0771     
0772         // Reverse iterator
0773         typedef reverse_iterator_base<const_iterator> const_reverse_iterator;
0774         typedef reverse_iterator_base<iterator> reverse_iterator;
0775     
0776     /// \brief Return a const reverse iterator before the first element of the reversed vector (i.e. end() of normal vector)
0777         BOOST_UBLAS_INLINE
0778         const_reverse_iterator rbegin () const {
0779             return const_reverse_iterator (end ());
0780         }
0781     
0782     /// \brief Return a const reverse iterator before the first element of the reversed vector (i.e. end() of normal vector)
0783         BOOST_UBLAS_INLINE
0784         const_reverse_iterator crbegin () const {
0785             return rbegin ();
0786         }
0787 
0788     /// \brief Return a const reverse iterator on the end of the reverse vector (i.e. first element of the normal vector) 
0789         BOOST_UBLAS_INLINE
0790         const_reverse_iterator rend () const {
0791             return const_reverse_iterator (begin ());
0792         }
0793     
0794     /// \brief Return a const reverse iterator on the end of the reverse vector (i.e. first element of the normal vector)
0795         BOOST_UBLAS_INLINE
0796         const_reverse_iterator crend () const {
0797             return rend ();
0798         }
0799 
0800     /// \brief Return a const reverse iterator before the first element of the reversed vector (i.e. end() of normal vector)
0801         BOOST_UBLAS_INLINE
0802         reverse_iterator rbegin () {
0803             return reverse_iterator (end ());
0804         }
0805     
0806     /// \brief Return a const reverse iterator on the end of the reverse vector (i.e. first element of the normal vector) 
0807         BOOST_UBLAS_INLINE
0808         reverse_iterator rend () {
0809             return reverse_iterator (begin ());
0810         }
0811     
0812     // -------------
0813         // Serialization
0814     // -------------
0815     
0816     /// Serialize a vector into and archive as defined in Boost
0817     /// \param ar Archive object. Can be a flat file, an XML file or any other stream
0818     /// \param file_version Optional file version (not yet used)
0819          template<class Archive>
0820          void serialize(Archive & ar, const unsigned int /* file_version */){
0821              ar & serialization::make_nvp("data",data_);
0822          }
0823 
0824      private:
0825          array_type data_;
0826      };
0827 
0828 
0829 #ifdef BOOST_UBLAS_CPP_GE_2011
0830      /** \brief A dense vector of values of type \c T.
0831       *
0832       * 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
0833       * to the \f$i\f$-th element of the container. A storage type \c A can be specified which defaults to \c std::array.
0834       * Elements are constructed by \c A, which need not initialise their value.
0835       *
0836       * \tparam T type of the objects stored in the vector (like int, double, complex,...)
0837       * \tparam A The type of the storage array of the vector. Default is \c std::array<T>.
0838       */
0839      template<class T, std::size_t N, class A>
0840      class fixed_vector:
0841          public vector_container<fixed_vector<T, N, A> > {
0842 
0843          typedef fixed_vector<T, N, A> self_type;
0844      public:
0845 #ifdef BOOST_UBLAS_ENABLE_PROXY_SHORTCUTS
0846          using vector_container<self_type>::operator ();
0847 #endif
0848 
0849         typedef typename A::size_type       size_type;
0850         typedef typename A::difference_type difference_type;
0851         typedef T value_type;
0852         typedef typename type_traits<T>::const_reference const_reference;
0853         typedef T &reference;
0854         typedef T *pointer;
0855         typedef const T *const_pointer;
0856         typedef A array_type;
0857         typedef const vector_reference<const self_type> const_closure_type;
0858         typedef vector_reference<self_type> closure_type;
0859         typedef self_type vector_temporary_type;
0860         typedef dense_tag storage_category;
0861 
0862         // Construction and destruction
0863 
0864     /// \brief Constructor of a fixed_vector
0865         BOOST_UBLAS_INLINE
0866         fixed_vector ():
0867             vector_container<self_type> (),
0868             data_ () {}
0869 
0870     /// \brief Constructor of a fixed_vector by copying from another container
0871     /// This type uses the generic name \c array_type within the vector definition.
0872     /// \param data container of type \c A
0873          BOOST_UBLAS_INLINE
0874          fixed_vector (const array_type &data):
0875              vector_container<self_type> (),
0876              data_ (data) {}
0877 
0878     /// \brief Constructor of a fixed_vector with a unique initial value
0879     /// \param init value to assign to each element of the vector
0880          BOOST_UBLAS_INLINE
0881          fixed_vector (const value_type &init):
0882              vector_container<self_type> (),
0883              data_ () {
0884              data_.fill( init );
0885          }
0886 
0887     /// \brief Copy-constructor of a fixed_vector
0888     /// \param v is the fixed_vector to be duplicated
0889         BOOST_UBLAS_INLINE
0890         fixed_vector (const fixed_vector &v):
0891             vector_container<self_type> (),
0892             data_ (v.data_) {}
0893 
0894     /// \brief Copy-constructor of a vector from a vector_expression
0895     /// Depending on the vector_expression, this constructor can have the cost of the computations
0896     /// of the expression (trivial to say it, but take it must be taken into account in your complexity calculations).
0897     /// \param ae the vector_expression which values will be duplicated into the vector
0898         template<class AE>
0899         BOOST_UBLAS_INLINE
0900         fixed_vector (const vector_expression<AE> &ae):
0901             vector_container<self_type> (),
0902             data_ ( ) {
0903             vector_assign<scalar_assign> (*this, ae);
0904         }
0905 
0906     /// \brief Construct a fixed_vector from a list of values
0907     /// This constructor enables initialization by using any of:
0908     /// 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 )
0909         template <typename... Types>
0910         BOOST_UBLAS_INLINE
0911         fixed_vector(value_type v0, Types... vrest) :
0912             vector_container<self_type> (),
0913             data_( array_type{ v0, vrest... } ) {}
0914 
0915     // -----------------------
0916     // Random Access Container
0917     // -----------------------
0918 
0919     /// \brief Return the maximum size of the data container.
0920     /// 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.
0921         BOOST_UBLAS_INLINE
0922         size_type max_size () const {
0923             return data_.max_size ();
0924         }
0925 
0926     /// \brief Return true if the vector is empty (\c size==0)
0927     /// \return \c true if empty, \c false otherwise
0928         BOOST_UBLAS_INLINE
0929         const bool &empty () const {
0930             return data_.empty();
0931         }
0932 
0933     // ---------
0934     // Accessors
0935     // ---------
0936 
0937     /// \brief Return the size of the vector
0938          BOOST_UBLAS_INLINE
0939          BOOST_CONSTEXPR size_type size () const{ // should have a const after C++14
0940              return data_.size ();
0941          }
0942 
0943     // -----------------
0944     // Storage accessors
0945     // -----------------
0946 
0947     /// \brief Return a \c const reference to the container. Useful to access data directly for specific type of container.
0948          BOOST_UBLAS_INLINE
0949          const array_type &data () const {
0950              return data_;
0951          }
0952 
0953     /// \brief Return a reference to the container. Useful to speed-up write operations to the data in very specific case.
0954          BOOST_UBLAS_INLINE
0955          array_type &data () {
0956              return data_;
0957          }
0958 
0959     // ---------------
0960          // Element support
0961     // ---------------
0962 
0963     /// \brief Return a pointer to the element \f$i\f$
0964     /// \param i index of the element
0965     // XXX this semantic is not the one expected by the name of this method
0966          BOOST_UBLAS_INLINE
0967          pointer find_element (size_type i) {
0968              return const_cast<pointer> (const_cast<const self_type&>(*this).find_element (i));
0969          }
0970 
0971     /// \brief Return a const pointer to the element \f$i\f$
0972     /// \param i index of the element
0973     // XXX  this semantic is not the one expected by the name of this method
0974          BOOST_UBLAS_INLINE
0975          const_pointer find_element (size_type i) const {
0976              BOOST_UBLAS_CHECK (i < data_.size(), bad_index() ); // Since std:array doesn't check for bounds
0977              return & (data () [i]);
0978          }
0979 
0980     // --------------
0981          // Element access
0982     // --------------
0983 
0984     /// \brief Return a const reference to the element \f$i\f$
0985     /// Return a const reference to the element \f$i\f$. With some compilers, this notation will be faster than \c[i]
0986     /// \param i index of the element
0987          BOOST_UBLAS_INLINE
0988          const_reference operator () (size_type i) const {
0989              BOOST_UBLAS_CHECK (i < data_.size(), bad_index() );
0990              return data () [i];
0991          }
0992 
0993     /// \brief Return a reference to the element \f$i\f$
0994     /// Return a reference to the element \f$i\f$. With some compilers, this notation will be faster than \c[i]
0995     /// \param i index of the element
0996          BOOST_UBLAS_INLINE
0997          reference operator () (size_type i) {
0998              BOOST_UBLAS_CHECK (i < data_.size(), bad_index() );
0999              return data () [i];
1000          }
1001 
1002     /// \brief Return a const reference to the element \f$i\f$
1003     /// \param i index of the element
1004          BOOST_UBLAS_INLINE
1005          const_reference operator [] (size_type i) const {
1006              BOOST_UBLAS_CHECK (i < data_.size(), bad_index() );
1007              return (*this) (i);
1008          }
1009 
1010     /// \brief Return a reference to the element \f$i\f$
1011     /// \param i index of the element
1012          BOOST_UBLAS_INLINE
1013          reference operator [] (size_type i) {
1014              BOOST_UBLAS_CHECK (i < data_.size(), bad_index() );
1015              return (*this) (i);
1016          }
1017 
1018     // ------------------
1019          // Element assignment
1020     // ------------------
1021 
1022     /// \brief Set element \f$i\f$ to the value \c t
1023     /// \param i index of the element
1024     /// \param t reference to the value to be set
1025     // XXX semantic of this is to insert a new element and therefore size=size+1 ?
1026          BOOST_UBLAS_INLINE
1027          reference insert_element (size_type i, const_reference t) {
1028              BOOST_UBLAS_CHECK (i < data_.size(), bad_index ());
1029              return (data () [i] = t);
1030          }
1031 
1032     /// \brief Set element \f$i\f$ to the \e zero value
1033     /// \param i index of the element
1034          BOOST_UBLAS_INLINE
1035          void erase_element (size_type i) {
1036              BOOST_UBLAS_CHECK (i < data_.size(), bad_index ());
1037              data () [i] = value_type/*zero*/();
1038          }
1039 
1040     // -------
1041          // Zeroing
1042     // -------
1043 
1044     /// \brief Clear the vector, i.e. set all values to the \c zero value.
1045          BOOST_UBLAS_INLINE
1046          void clear () {
1047              std::fill (data ().begin (), data ().end (), value_type/*zero*/());
1048          }
1049 
1050          // Assignment
1051 #ifdef BOOST_UBLAS_MOVE_SEMANTICS
1052 
1053     /// \brief Assign a full fixed_vector (\e RHS-vector) to the current fixed_vector (\e LHS-vector)
1054     /// \param v is the source vector
1055     /// \return a reference to a fixed_vector (i.e. the destination vector)
1056          /*! @note "pass by value" the key idea to enable move semantics */
1057          BOOST_UBLAS_INLINE
1058          fixed_vector &operator = (fixed_vector v) {
1059              assign_temporary(v);
1060              return *this;
1061          }
1062 #else
1063     /// \brief Assign a full fixed_vector (\e RHS-vector) to the current fixed_vector (\e LHS-vector)
1064     /// \param v is the source fixed_vector
1065     /// \return a reference to a fixed_vector (i.e. the destination vector)
1066          BOOST_UBLAS_INLINE
1067          fixed_vector &operator = (const fixed_vector &v) {
1068              data () = v.data ();
1069              return *this;
1070          }
1071 #endif
1072 
1073     /// \brief Assign a full vector (\e RHS-vector) to the current fixed_vector (\e LHS-vector)
1074     /// Assign a full vector (\e RHS-vector) to the current fixed_vector (\e LHS-vector). This method does not create any temporary.
1075     /// \param v is the source vector container
1076     /// \return a reference to a vector (i.e. the destination vector)
1077          template<class C>          // Container assignment without temporary
1078          BOOST_UBLAS_INLINE
1079          fixed_vector &operator = (const vector_container<C> &v) {
1080              assign (v);
1081              return *this;
1082          }
1083 
1084     /// \brief Assign a full fixed_vector (\e RHS-vector) to the current fixed_vector (\e LHS-vector)
1085     /// \param v is the source fixed_vector
1086     /// \return a reference to a fixed_vector (i.e. the destination fixed_vector)
1087          BOOST_UBLAS_INLINE
1088          fixed_vector &assign_temporary (fixed_vector &v) {
1089              swap ( v );
1090              return *this;
1091          }
1092 
1093     /// \brief Assign the result of a vector_expression to the fixed_vector
1094     /// Assign the result of a vector_expression to the vector. This is lazy-compiled and will be optimized out by the compiler on any type of expression.
1095     /// \tparam AE is the type of the vector_expression
1096     /// \param ae is a const reference to the vector_expression
1097     /// \return a reference to the resulting fixed_vector
1098          template<class AE>
1099          BOOST_UBLAS_INLINE
1100          fixed_vector &operator = (const vector_expression<AE> &ae) {
1101              self_type temporary (ae);
1102              return assign_temporary (temporary);
1103          }
1104 
1105     /// \brief Assign the result of a vector_expression to the fixed_vector
1106     /// Assign the result of a vector_expression to the vector. This is lazy-compiled and will be optimized out by the compiler on any type of expression.
1107     /// \tparam AE is the type of the vector_expression
1108     /// \param ae is a const reference to the vector_expression
1109     /// \return a reference to the resulting fixed_vector
1110          template<class AE>
1111          BOOST_UBLAS_INLINE
1112          fixed_vector &assign (const vector_expression<AE> &ae) {
1113              vector_assign<scalar_assign> (*this, ae);
1114              return *this;
1115          }
1116 
1117     // -------------------
1118          // Computed assignment
1119     // -------------------
1120 
1121     /// \brief Assign the sum of the fixed_vector and a vector_expression to the fixed_vector
1122     /// Assign the sum of the fixed_vector and a vector_expression to the fixed_vector. This is lazy-compiled and will be optimized out by the compiler on any type of expression.
1123     /// A temporary is created for the computations.
1124     /// \tparam AE is the type of the vector_expression
1125     /// \param ae is a const reference to the vector_expression
1126     /// \return a reference to the resulting fixed_vector
1127          template<class AE>
1128          BOOST_UBLAS_INLINE
1129          fixed_vector &operator += (const vector_expression<AE> &ae) {
1130              self_type temporary (*this + ae);
1131              return assign_temporary (temporary);
1132          }
1133 
1134     /// \brief Assign the sum of the fixed_vector and a vector_expression to the fixed_vector
1135     /// Assign the sum of the fixed_vector and a vector_expression to the fixed_vector. This is lazy-compiled and will be optimized out by the compiler on any type of expression.
1136     /// No temporary is created. Computations are done and stored directly into the resulting vector.
1137     /// \tparam AE is the type of the vector_expression
1138     /// \param ae is a const reference to the vector_expression
1139     /// \return a reference to the resulting vector
1140          template<class C>          // Container assignment without temporary
1141          BOOST_UBLAS_INLINE
1142          fixed_vector &operator += (const vector_container<C> &v) {
1143              plus_assign (v);
1144              return *this;
1145          }
1146 
1147     /// \brief Assign the sum of the fixed_vector and a vector_expression to the fixed_vector
1148     /// Assign the sum of the fixed_vector and a vector_expression to the fixed_vector. This is lazy-compiled and will be optimized out by the compiler on any type of expression.
1149     /// No temporary is created. Computations are done and stored directly into the resulting fixed_vector.
1150     /// \tparam AE is the type of the vector_expression
1151     /// \param ae is a const reference to the vector_expression
1152     /// \return a reference to the resulting vector
1153          template<class AE>
1154          BOOST_UBLAS_INLINE
1155          fixed_vector &plus_assign (const vector_expression<AE> &ae) {
1156              vector_assign<scalar_plus_assign> (*this, ae);
1157              return *this;
1158          }
1159 
1160     /// \brief Assign the difference of the fixed_vector and a vector_expression to the fixed_vector
1161     /// Assign the difference of the fixed_vector and a vector_expression to the fixed_vector. This is lazy-compiled and will be optimized out by the compiler on any type of expression.
1162     /// A temporary is created for the computations.
1163     /// \tparam AE is the type of the vector_expression
1164     /// \param ae is a const reference to the vector_expression
1165          template<class AE>
1166          BOOST_UBLAS_INLINE
1167          fixed_vector &operator -= (const vector_expression<AE> &ae) {
1168              self_type temporary (*this - ae);
1169              return assign_temporary (temporary);
1170          }
1171 
1172     /// \brief Assign the difference of the fixed_vector and a vector_expression to the fixed_vector
1173     /// Assign the difference of the fixed_vector and a vector_expression to the fixed_vector. This is lazy-compiled and will be optimized out by the compiler on any type of expression.
1174     /// No temporary is created. Computations are done and stored directly into the resulting fixed_vector.
1175     /// \tparam AE is the type of the vector_expression
1176     /// \param ae is a const reference to the vector_expression
1177     /// \return a reference to the resulting vector
1178          template<class C>          // Container assignment without temporary
1179          BOOST_UBLAS_INLINE
1180          fixed_vector &operator -= (const vector_container<C> &v) {
1181              minus_assign (v);
1182              return *this;
1183          }
1184 
1185     /// \brief Assign the difference of the fixed_vector and a vector_expression to the fixed_vector
1186     /// Assign the difference of the fixed_vector and a vector_expression to the fixed_vector. This is lazy-compiled and will be optimized out by the compiler on any type of expression.
1187     /// No temporary is created. Computations are done and stored directly into the resulting fixed_vector.
1188     /// \tparam AE is the type of the vector_expression
1189     /// \param ae is a const reference to the vector_expression
1190     /// \return a reference to the resulting fixed_vector
1191          template<class AE>
1192          BOOST_UBLAS_INLINE
1193          fixed_vector &minus_assign (const vector_expression<AE> &ae) {
1194              vector_assign<scalar_minus_assign> (*this, ae);
1195              return *this;
1196          }
1197 
1198     /// \brief Assign the product of the fixed_vector and a scalar to the fixed_vector
1199     /// Assign the product of the fixed_vector and a scalar to the fixed_vector. This is lazy-compiled and will be optimized out by the compiler on any type of expression.
1200     /// No temporary is created. Computations are done and stored directly into the resulting fixed_vector.
1201     /// \tparam AE is the type of the vector_expression
1202     /// \param at is a const reference to the scalar
1203     /// \return a reference to the resulting fixed_vector
1204          template<class AT>
1205          BOOST_UBLAS_INLINE
1206          fixed_vector &operator *= (const AT &at) {
1207              vector_assign_scalar<scalar_multiplies_assign> (*this, at);
1208              return *this;
1209          }
1210 
1211     /// \brief Assign the division of the fixed_vector by a scalar to the fixed_vector
1212     /// Assign the division of the fixed_vector by a scalar to the vector. This is lazy-compiled and will be optimized out by the compiler on any type of expression.
1213     /// No temporary is created. Computations are done and stored directly into the resulting vector.
1214     /// \tparam AE is the type of the vector_expression
1215     /// \param at is a const reference to the scalar
1216     /// \return a reference to the resulting fixed_vector
1217         template<class AT>
1218         BOOST_UBLAS_INLINE
1219         fixed_vector &operator /= (const AT &at) {
1220             vector_assign_scalar<scalar_divides_assign> (*this, at);
1221             return *this;
1222         }
1223 
1224     // --------
1225         // Swapping
1226     // --------
1227 
1228     /// \brief Swap the content of the fixed_vector with another vector
1229     /// \param v is the fixed_vector to be swapped with
1230         BOOST_UBLAS_INLINE
1231         void swap (fixed_vector &v) {
1232             if (this != &v) {
1233                 data ().swap (v.data ());
1234             }
1235         }
1236 
1237     /// \brief Swap the content of two fixed_vectors
1238     /// \param v1 is the first fixed_vector. It takes values from v2
1239     /// \param v2 is the second fixed_vector It takes values from v1
1240          BOOST_UBLAS_INLINE
1241          friend void swap (fixed_vector &v1, fixed_vector &v2) {
1242              v1.swap (v2);
1243          }
1244 
1245          // Iterator types
1246      private:
1247          // Use the storage array iterator
1248          typedef typename A::const_iterator const_subiterator_type;
1249          typedef typename A::iterator subiterator_type;
1250 
1251      public:
1252 #ifdef BOOST_UBLAS_USE_INDEXED_ITERATOR
1253          typedef indexed_iterator<self_type, dense_random_access_iterator_tag> iterator;
1254          typedef indexed_const_iterator<self_type, dense_random_access_iterator_tag> const_iterator;
1255 #else
1256          class const_iterator;
1257          class iterator;
1258 #endif
1259 
1260     // --------------
1261         // Element lookup
1262     // --------------
1263 
1264     /// \brief Return a const iterator to the element \e i
1265     /// \param i index of the element
1266          BOOST_UBLAS_INLINE
1267          const_iterator find (size_type i) const {
1268 #ifndef BOOST_UBLAS_USE_INDEXED_ITERATOR
1269              return const_iterator (*this, data ().begin () + i);
1270 #else
1271              return const_iterator (*this, i);
1272 #endif
1273          }
1274 
1275     /// \brief Return an iterator to the element \e i
1276     /// \param i index of the element
1277          BOOST_UBLAS_INLINE
1278          iterator find (size_type i) {
1279 #ifndef BOOST_UBLAS_USE_INDEXED_ITERATOR
1280              return iterator (*this, data ().begin () + i);
1281 #else
1282              return iterator (*this, i);
1283 #endif
1284          }
1285 
1286 #ifndef BOOST_UBLAS_USE_INDEXED_ITERATOR
1287          class const_iterator:
1288              public container_const_reference<fixed_vector>,
1289              public random_access_iterator_base<dense_random_access_iterator_tag,
1290                    const_iterator, value_type, difference_type> {
1291          public:
1292              typedef typename fixed_vector::difference_type difference_type;
1293              typedef typename fixed_vector::value_type value_type;
1294              typedef typename fixed_vector::const_reference reference;
1295              typedef const typename fixed_vector::pointer pointer;
1296 
1297         // ----------------------------
1298             // Construction and destruction
1299         // ----------------------------
1300 
1301 
1302             BOOST_UBLAS_INLINE
1303             const_iterator ():
1304                 container_const_reference<self_type> (), it_ () {}
1305             BOOST_UBLAS_INLINE
1306             const_iterator (const self_type &v, const const_subiterator_type &it):
1307                 container_const_reference<self_type> (v), it_ (it) {}
1308             BOOST_UBLAS_INLINE
1309             const_iterator (const typename self_type::iterator &it):  // ISSUE vector:: stops VC8 using std::iterator here
1310                 container_const_reference<self_type> (it ()), it_ (it.it_) {}
1311 
1312         // ----------
1313             // Arithmetic
1314         // ----------
1315 
1316         /// \brief Increment by 1 the position of the iterator
1317         /// \return a reference to the const iterator
1318             BOOST_UBLAS_INLINE
1319             const_iterator &operator ++ () {
1320                 ++ it_;
1321                 return *this;
1322             }
1323 
1324         /// \brief Decrement by 1 the position of the iterator
1325         /// \return a reference to the const iterator
1326             BOOST_UBLAS_INLINE
1327             const_iterator &operator -- () {
1328                 -- it_;
1329                 return *this;
1330             }
1331 
1332         /// \brief Increment by \e n the position of the iterator
1333         /// \return a reference to the const iterator
1334             BOOST_UBLAS_INLINE
1335             const_iterator &operator += (difference_type n) {
1336                 it_ += n;
1337                 return *this;
1338             }
1339 
1340         /// \brief Decrement by \e n the position of the iterator
1341         /// \return a reference to the const iterator
1342             BOOST_UBLAS_INLINE
1343             const_iterator &operator -= (difference_type n) {
1344                 it_ -= n;
1345                 return *this;
1346             }
1347 
1348         /// \brief Return the different in number of positions between 2 iterators
1349             BOOST_UBLAS_INLINE
1350             difference_type operator - (const const_iterator &it) const {
1351                 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
1352                 return it_ - it.it_;
1353             }
1354 
1355             /// \brief Dereference an iterator
1356             /// Dereference an iterator: a bounds' check is done before returning the value. A bad_index() expection is returned if out of bounds.
1357         /// \return a const reference to the value pointed by the iterator
1358             BOOST_UBLAS_INLINE
1359             const_reference operator * () const {
1360                 BOOST_UBLAS_CHECK (it_ >= (*this) ().begin ().it_ && it_ < (*this) ().end ().it_, bad_index ());
1361                 return *it_;
1362             }
1363 
1364         /// \brief Dereference an iterator at the n-th forward value
1365         /// Dereference an iterator at the n-th forward value, that is the value pointed by iterator+n.
1366             /// A bounds' check is done before returning the value. A bad_index() expection is returned if out of bounds.
1367         /// \return a const reference
1368             BOOST_UBLAS_INLINE
1369             const_reference operator [] (difference_type n) const {
1370                 return *(it_ + n);
1371             }
1372 
1373             // Index
1374         /// \brief return the index of the element referenced by the iterator
1375              BOOST_UBLAS_INLINE
1376              size_type index () const {
1377                  BOOST_UBLAS_CHECK (it_ >= (*this) ().begin ().it_ && it_ < (*this) ().end ().it_, bad_index ());
1378                  return it_ - (*this) ().begin ().it_;
1379              }
1380 
1381              // Assignment
1382              BOOST_UBLAS_INLINE
1383         /// \brief assign the value of an iterator to the iterator
1384              const_iterator &operator = (const const_iterator &it) {
1385                  container_const_reference<self_type>::assign (&it ());
1386                  it_ = it.it_;
1387                  return *this;
1388              }
1389 
1390              // Comparison
1391         /// \brief compare the value of two itetarors
1392         /// \return true if they reference the same element
1393             BOOST_UBLAS_INLINE
1394             bool operator == (const const_iterator &it) const {
1395                 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
1396                 return it_ == it.it_;
1397             }
1398 
1399 
1400         /// \brief compare the value of two iterators
1401         /// \return return true if the left-hand-side iterator refers to a value placed before the right-hand-side iterator
1402              BOOST_UBLAS_INLINE
1403              bool operator < (const const_iterator &it) const {
1404                  BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
1405                  return it_ < it.it_;
1406              }
1407 
1408          private:
1409              const_subiterator_type it_;
1410 
1411              friend class iterator;
1412          };
1413 #endif
1414 
1415     /// \brief return an iterator on the first element of the fixed_vector
1416         BOOST_UBLAS_INLINE
1417         const_iterator begin () const {
1418             return find (0);
1419         }
1420 
1421     /// \brief return an iterator on the first element of the fixed_vector
1422         BOOST_UBLAS_INLINE
1423         const_iterator cbegin () const {
1424             return begin ();
1425         }
1426 
1427     /// \brief return an iterator after the last element of the fixed_vector
1428          BOOST_UBLAS_INLINE
1429          const_iterator end () const {
1430              return find (data_.size ());
1431          }
1432 
1433     /// \brief return an iterator after the last element of the fixed_vector
1434          BOOST_UBLAS_INLINE
1435          const_iterator cend () const {
1436              return end ();
1437          }
1438 
1439 #ifndef BOOST_UBLAS_USE_INDEXED_ITERATOR
1440          class iterator:
1441              public container_reference<fixed_vector>,
1442              public random_access_iterator_base<dense_random_access_iterator_tag,
1443                                                 iterator, value_type, difference_type> {
1444          public:
1445              typedef typename fixed_vector::difference_type difference_type;
1446              typedef typename fixed_vector::value_type value_type;
1447              typedef typename fixed_vector::reference reference;
1448              typedef typename fixed_vector::pointer pointer;
1449 
1450 
1451              // Construction and destruction
1452              BOOST_UBLAS_INLINE
1453              iterator ():
1454                  container_reference<self_type> (), it_ () {}
1455              BOOST_UBLAS_INLINE
1456              iterator (self_type &v, const subiterator_type &it):
1457                  container_reference<self_type> (v), it_ (it) {}
1458 
1459              // Arithmetic
1460              BOOST_UBLAS_INLINE
1461              iterator &operator ++ () {
1462                  ++ it_;
1463                  return *this;
1464              }
1465              BOOST_UBLAS_INLINE
1466              iterator &operator -- () {
1467                  -- it_;
1468                  return *this;
1469              }
1470              BOOST_UBLAS_INLINE
1471              iterator &operator += (difference_type n) {
1472                  it_ += n;
1473                  return *this;
1474              }
1475              BOOST_UBLAS_INLINE
1476              iterator &operator -= (difference_type n) {
1477                  it_ -= n;
1478                  return *this;
1479              }
1480              BOOST_UBLAS_INLINE
1481              difference_type operator - (const iterator &it) const {
1482                  BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
1483                  return it_ - it.it_;
1484              }
1485 
1486              // Dereference
1487              BOOST_UBLAS_INLINE
1488              reference operator * () const {
1489                  BOOST_UBLAS_CHECK (it_ >= (*this) ().begin ().it_ && it_ < (*this) ().end ().it_ , bad_index ());
1490                  return *it_;
1491              }
1492              BOOST_UBLAS_INLINE
1493              reference operator [] (difference_type n) const {
1494                  return *(it_ + n);
1495              }
1496 
1497              // Index
1498              BOOST_UBLAS_INLINE
1499              size_type index () const {
1500                  BOOST_UBLAS_CHECK (it_ >= (*this) ().begin ().it_ && it_ < (*this) ().end ().it_ , bad_index ());
1501                  return it_ - (*this) ().begin ().it_;
1502              }
1503 
1504              // Assignment
1505              BOOST_UBLAS_INLINE
1506              iterator &operator = (const iterator &it) {
1507                  container_reference<self_type>::assign (&it ());
1508                  it_ = it.it_;
1509                  return *this;
1510              }
1511 
1512              // Comparison
1513              BOOST_UBLAS_INLINE
1514              bool operator == (const iterator &it) const {
1515                  BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
1516                  return it_ == it.it_;
1517              }
1518              BOOST_UBLAS_INLINE
1519              bool operator < (const iterator &it) const {
1520                  BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
1521                  return it_ < it.it_;
1522              }
1523 
1524          private:
1525              subiterator_type it_;
1526 
1527              friend class const_iterator;
1528          };
1529 #endif
1530 
1531     /// \brief Return an iterator on the first element of the fixed_vector
1532         BOOST_UBLAS_INLINE
1533         iterator begin () {
1534             return find (0);
1535         }
1536 
1537     /// \brief Return an iterator at the end of the fixed_vector
1538         BOOST_UBLAS_INLINE
1539         iterator end () {
1540             return find (data_.size ());
1541         }
1542 
1543         // Reverse iterator
1544         typedef reverse_iterator_base<const_iterator> const_reverse_iterator;
1545         typedef reverse_iterator_base<iterator> reverse_iterator;
1546 
1547     /// \brief Return a const reverse iterator before the first element of the reversed fixed_vector (i.e. end() of normal fixed_vector)
1548         BOOST_UBLAS_INLINE
1549         const_reverse_iterator rbegin () const {
1550             return const_reverse_iterator (end ());
1551         }
1552 
1553     /// \brief Return a const reverse iterator before the first element of the reversed fixed_vector (i.e. end() of normal fixed_vector)
1554         BOOST_UBLAS_INLINE
1555         const_reverse_iterator crbegin () const {
1556             return rbegin ();
1557         }
1558 
1559     /// \brief Return a const reverse iterator on the end of the reverse fixed_vector (i.e. first element of the normal fixed_vector)
1560         BOOST_UBLAS_INLINE
1561         const_reverse_iterator rend () const {
1562             return const_reverse_iterator (begin ());
1563         }
1564 
1565     /// \brief Return a const reverse iterator on the end of the reverse fixed_vector (i.e. first element of the normal fixed_vector)
1566         BOOST_UBLAS_INLINE
1567         const_reverse_iterator crend () const {
1568             return rend ();
1569         }
1570 
1571     /// \brief Return a const reverse iterator before the first element of the reversed fixed_vector (i.e. end() of normal fixed_vector)
1572         BOOST_UBLAS_INLINE
1573         reverse_iterator rbegin () {
1574             return reverse_iterator (end ());
1575         }
1576 
1577     /// \brief Return a const reverse iterator on the end of the reverse fixed_vector (i.e. first element of the normal fixed_vector)
1578         BOOST_UBLAS_INLINE
1579         reverse_iterator rend () {
1580             return reverse_iterator (begin ());
1581         }
1582 
1583     // -------------
1584         // Serialization
1585     // -------------
1586 
1587     /// Serialize a fixed_vector into and archive as defined in Boost
1588     /// \param ar Archive object. Can be a flat file, an XML file or any other stream
1589     /// \param file_version Optional file version (not yet used)
1590          template<class Archive>
1591          void serialize(Archive & ar, const unsigned int /* file_version */){
1592              ar & serialization::make_nvp("data",data_);
1593          }
1594 
1595      private:
1596          array_type data_;
1597      };
1598 
1599 #endif // BOOST_UBLAS_CPP_GE_2011
1600 
1601      // --------------------
1602      // Bounded vector class
1603      // --------------------
1604 
1605      /// \brief a dense vector of values of type \c T, of variable size but with maximum \f$N\f$.
1606      /// A dense vector of values of type \c T, of variable size but with maximum \f$N\f$.  The default constructor 
1607      /// creates the vector with size \f$N\f$. Elements are constructed by the storage type \c bounded_array, which \b need \b not \b initialise their value.
1608      template<class T, std::size_t N>
1609      class bounded_vector:
1610          public vector<T, bounded_array<T, N> > {
1611 
1612          typedef vector<T, bounded_array<T, N> > vector_type;
1613      public:
1614          typedef typename vector_type::size_type size_type;
1615          static const size_type max_size = N;
1616 
1617          // Construction and destruction
1618          BOOST_UBLAS_INLINE
1619          bounded_vector ():
1620              vector_type (N) {}
1621          BOOST_UBLAS_INLINE
1622          bounded_vector (size_type size):
1623              vector_type (size) {}
1624          BOOST_UBLAS_INLINE
1625          bounded_vector (const bounded_vector &v):
1626              vector_type (v) {}
1627          template<class A2>              // Allow vector<T,bounded_array<N> construction
1628          BOOST_UBLAS_INLINE
1629          bounded_vector (const vector<T, A2> &v):
1630              vector_type (v) {}
1631          template<class AE>
1632          BOOST_UBLAS_INLINE
1633          bounded_vector (const vector_expression<AE> &ae):
1634              vector_type (ae) {}
1635          BOOST_UBLAS_INLINE
1636          ~bounded_vector () {}
1637 
1638          // Assignment
1639 #ifdef BOOST_UBLAS_MOVE_SEMANTICS
1640 
1641          /*! @note "pass by value" the key idea to enable move semantics */
1642          BOOST_UBLAS_INLINE
1643          bounded_vector &operator = (bounded_vector v) {
1644              vector_type::operator = (v);
1645              return *this;
1646          }
1647 #else
1648          BOOST_UBLAS_INLINE
1649          bounded_vector &operator = (const bounded_vector &v) {
1650              vector_type::operator = (v);
1651              return *this;
1652          }
1653 #endif
1654          template<class A2>         // Generic vector assignment
1655          BOOST_UBLAS_INLINE
1656          bounded_vector &operator = (const vector<T, A2> &v) {
1657              vector_type::operator = (v);
1658              return *this;
1659          }
1660          template<class C>          // Container assignment without temporary
1661          BOOST_UBLAS_INLINE
1662          bounded_vector &operator = (const vector_container<C> &v) {
1663              vector_type::operator = (v);
1664              return *this;
1665          }
1666          template<class AE>
1667          BOOST_UBLAS_INLINE
1668          bounded_vector &operator = (const vector_expression<AE> &ae) {
1669              vector_type::operator = (ae);
1670              return *this;
1671          }
1672      };
1673 
1674 
1675 
1676      // -----------------
1677      // Zero vector class
1678      // -----------------
1679      
1680      /// \brief A zero vector of type \c T and a given \c size
1681      /// A zero vector of type \c T and a given \c size. This is a virtual vector in the sense that no memory is allocated 
1682      /// for storing the zero values: it still acts like any other vector. However assigning values to it will not change the zero
1683      /// vector into a normal vector. It must first be assigned to another normal vector by any suitable means. Its memory footprint is constant.
1684      template<class T, class ALLOC>
1685      class zero_vector:
1686          public vector_container<zero_vector<T, ALLOC> > {
1687 
1688          typedef const T *const_pointer;
1689          typedef zero_vector<T, ALLOC> self_type;
1690      public:
1691 #ifdef BOOST_UBLAS_ENABLE_PROXY_SHORTCUTS
1692          using vector_container<self_type>::operator ();
1693 #endif
1694          typedef typename boost::allocator_size_type<ALLOC>::type size_type;
1695          typedef typename boost::allocator_difference_type<ALLOC>::type difference_type;
1696          typedef T value_type;
1697          typedef const T &const_reference;
1698          typedef T &reference;
1699          typedef const vector_reference<const self_type> const_closure_type;
1700          typedef vector_reference<self_type> closure_type;
1701          typedef sparse_tag storage_category;
1702 
1703          // Construction and destruction
1704          BOOST_UBLAS_INLINE
1705          zero_vector ():
1706              vector_container<self_type> (),
1707              size_ (0) {}
1708          explicit BOOST_UBLAS_INLINE
1709          zero_vector (size_type size):
1710              vector_container<self_type> (),
1711              size_ (size) {}
1712          BOOST_UBLAS_INLINE
1713          zero_vector (const zero_vector &v):
1714              vector_container<self_type> (),
1715              size_ (v.size_) {}
1716 
1717          // Accessors
1718          BOOST_UBLAS_INLINE
1719          size_type size () const {
1720              return size_;
1721          }
1722 
1723          // Resizing
1724          BOOST_UBLAS_INLINE
1725          void resize (size_type size, bool /*preserve*/ = true) {
1726              size_ = size;
1727          }
1728 
1729          // Element support
1730          BOOST_UBLAS_INLINE
1731          const_pointer find_element (size_type /*i*/) const {
1732              return & zero_;
1733          }
1734 
1735          // Element access
1736          BOOST_UBLAS_INLINE
1737          const_reference operator () (size_type /* i */) const {
1738              return zero_;
1739          }
1740 
1741          BOOST_UBLAS_INLINE
1742          const_reference operator [] (size_type i) const {
1743              return (*this) (i);
1744          }
1745 
1746          // Assignment
1747          BOOST_UBLAS_INLINE
1748          zero_vector &operator = (const zero_vector &v) {
1749              size_ = v.size_;
1750              return *this;
1751          }
1752          BOOST_UBLAS_INLINE
1753          zero_vector &assign_temporary (zero_vector &v) {
1754              swap (v);
1755              return *this;
1756          }
1757 
1758          // Swapping
1759          BOOST_UBLAS_INLINE
1760          void swap (zero_vector &v) {
1761              if (this != &v) {
1762                  std::swap (size_, v.size_);
1763              }
1764          }
1765          BOOST_UBLAS_INLINE
1766          friend void swap (zero_vector &v1, zero_vector &v2) {
1767              v1.swap (v2);
1768          }
1769 
1770          // Iterator types
1771      public:
1772          class const_iterator;
1773 
1774          // Element lookup
1775          BOOST_UBLAS_INLINE
1776          const_iterator find (size_type /*i*/) const {
1777              return const_iterator (*this);
1778          }
1779 
1780          class const_iterator:
1781              public container_const_reference<zero_vector>,
1782              public bidirectional_iterator_base<sparse_bidirectional_iterator_tag,
1783                                                 const_iterator, value_type> {
1784          public:
1785              typedef typename zero_vector::difference_type difference_type;
1786              typedef typename zero_vector::value_type value_type;
1787              typedef typename zero_vector::const_reference reference;
1788              typedef typename zero_vector::const_pointer pointer;
1789 
1790              // Construction and destruction
1791              BOOST_UBLAS_INLINE
1792              const_iterator ():
1793                  container_const_reference<self_type> () {}
1794              BOOST_UBLAS_INLINE
1795              const_iterator (const self_type &v):
1796                  container_const_reference<self_type> (v) {}
1797 
1798              // Arithmetic
1799              BOOST_UBLAS_INLINE
1800              const_iterator &operator ++ () {
1801                  BOOST_UBLAS_CHECK_FALSE (bad_index ());
1802                  return *this;
1803              }
1804              BOOST_UBLAS_INLINE
1805              const_iterator &operator -- () {
1806                  BOOST_UBLAS_CHECK_FALSE (bad_index ());
1807                  return *this;
1808              }
1809 
1810              // Dereference
1811              BOOST_UBLAS_INLINE
1812              const_reference operator * () const {
1813                  BOOST_UBLAS_CHECK_FALSE (bad_index ());
1814                  return zero_;   // arbitary return value
1815              }
1816 
1817              // Index
1818              BOOST_UBLAS_INLINE
1819              size_type index () const {
1820                  BOOST_UBLAS_CHECK_FALSE (bad_index ());
1821                  return 0;   // arbitary return value
1822              }
1823 
1824              // Assignment
1825              BOOST_UBLAS_INLINE
1826              const_iterator &operator = (const const_iterator &it) {
1827                  container_const_reference<self_type>::assign (&it ());
1828                  return *this;
1829              }
1830 
1831              // Comparison
1832              BOOST_UBLAS_INLINE
1833              bool operator == (const const_iterator &it) const {
1834                  BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
1835                  detail::ignore_unused_variable_warning(it);
1836                  return true;
1837              }
1838          };
1839 
1840          typedef const_iterator iterator;
1841 
1842          BOOST_UBLAS_INLINE
1843          const_iterator begin () const {
1844              return const_iterator (*this);
1845          }
1846          BOOST_UBLAS_INLINE
1847          const_iterator cbegin () const {
1848              return begin ();
1849          }
1850          BOOST_UBLAS_INLINE
1851          const_iterator end () const {
1852              return const_iterator (*this);
1853          }
1854          BOOST_UBLAS_INLINE
1855          const_iterator cend () const {
1856              return end ();
1857          }
1858 
1859          // Reverse iterator
1860          typedef reverse_iterator_base<const_iterator> const_reverse_iterator;
1861 
1862          BOOST_UBLAS_INLINE
1863          const_reverse_iterator rbegin () const {
1864              return const_reverse_iterator (end ());
1865          }
1866          BOOST_UBLAS_INLINE
1867          const_reverse_iterator crbegin () const {
1868              return rbegin ();
1869          }
1870          BOOST_UBLAS_INLINE
1871          const_reverse_iterator rend () const {
1872              return const_reverse_iterator (begin ());
1873          }
1874          BOOST_UBLAS_INLINE
1875          const_reverse_iterator crend () const {
1876              return rend ();
1877          }
1878 
1879           // Serialization
1880          template<class Archive>
1881          void serialize(Archive & ar, const unsigned int /* file_version */){
1882              serialization::collection_size_type s (size_);
1883              ar & serialization::make_nvp("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 boost::allocator_size_type<ALLOC>::type size_type;
1916          typedef typename boost::allocator_difference_type<ALLOC>::type difference_type;
1917          typedef T value_type;
1918          typedef const T &const_reference;
1919          typedef T &reference;
1920          typedef const vector_reference<const self_type> const_closure_type;
1921          typedef vector_reference<self_type> closure_type;
1922          typedef sparse_tag storage_category;
1923 
1924          // Construction and destruction
1925     /// \brief Simple constructor with dimension and index 0
1926         BOOST_UBLAS_INLINE
1927         unit_vector ():
1928             vector_container<self_type> (),
1929             size_ (0), index_ (0) {}
1930     
1931     /// \brief Constructor of unit_vector
1932     /// \param size is the dimension of the vector
1933     /// \param index is the order of the vector
1934         BOOST_UBLAS_INLINE
1935         explicit unit_vector (size_type size, size_type index = 0):
1936             vector_container<self_type> (),
1937             size_ (size), index_ (index) {}
1938     
1939     /// \brief Copy-constructor
1940         BOOST_UBLAS_INLINE
1941         unit_vector (const unit_vector &v):
1942             vector_container<self_type> (),
1943             size_ (v.size_), index_ (v.index_) {}
1944     
1945         // Accessors
1946     //----------
1947     
1948     /// \brief Return the size (dimension) of the vector
1949         BOOST_UBLAS_INLINE
1950         size_type size () const {
1951             return size_;
1952         }
1953     
1954     /// \brief Return the order of the unit vector
1955         BOOST_UBLAS_INLINE
1956         size_type index () const {
1957             return index_;
1958         }
1959     
1960         // Resizing
1961     // --------
1962     
1963     /// \brief Resize the vector. The values are preserved by default (i.e. the index does not change)
1964     /// \param size is the new size of the vector
1965         BOOST_UBLAS_INLINE
1966         void resize (size_type size, bool /*preserve*/ = true) {
1967             size_ = size;
1968         }
1969     
1970         // Element support
1971     // ---------------
1972     
1973     /// \brief Return a const pointer to the element of index i
1974          BOOST_UBLAS_INLINE
1975          const_pointer find_element (size_type i) const {
1976              if (i == index_)
1977                  return & one_;
1978              else
1979                  return & zero_;
1980          }
1981 
1982          // Element access
1983          BOOST_UBLAS_INLINE
1984          const_reference operator () (size_type i) const {
1985              if (i == index_)
1986                  return one_;
1987              else
1988                  return zero_;
1989          }
1990 
1991          BOOST_UBLAS_INLINE
1992          const_reference operator [] (size_type i) const {
1993              return (*this) (i);
1994          }
1995 
1996          // Assignment
1997          BOOST_UBLAS_INLINE
1998          unit_vector &operator = (const unit_vector &v) {
1999              size_ = v.size_;
2000              index_ = v.index_;
2001              return *this;
2002          }
2003          BOOST_UBLAS_INLINE
2004          unit_vector &assign_temporary (unit_vector &v) {
2005              swap (v);
2006              return *this;
2007          }
2008 
2009          // Swapping
2010          BOOST_UBLAS_INLINE
2011          void swap (unit_vector &v) {
2012              if (this != &v) {
2013                  std::swap (size_, v.size_);
2014                  std::swap (index_, v.index_);
2015              }
2016          }
2017          BOOST_UBLAS_INLINE
2018          friend void swap (unit_vector &v1, unit_vector &v2) {
2019              v1.swap (v2);
2020          }
2021 
2022          // Iterator types
2023      private:
2024          // Use bool to indicate begin (one_ as value)
2025          typedef bool const_subiterator_type;
2026      public:
2027          class const_iterator;
2028 
2029          // Element lookup
2030          BOOST_UBLAS_INLINE
2031          const_iterator find (size_type i) const {
2032              return const_iterator (*this, i <= index_);
2033          }
2034 
2035          class const_iterator:
2036              public container_const_reference<unit_vector>,
2037              public bidirectional_iterator_base<sparse_bidirectional_iterator_tag,
2038                                                 const_iterator, value_type> {
2039          public:
2040              typedef typename unit_vector::difference_type difference_type;
2041              typedef typename unit_vector::value_type value_type;
2042              typedef typename unit_vector::const_reference reference;
2043              typedef typename unit_vector::const_pointer pointer;
2044 
2045              // Construction and destruction
2046              BOOST_UBLAS_INLINE
2047              const_iterator ():
2048                  container_const_reference<unit_vector> (), it_ () {}
2049              BOOST_UBLAS_INLINE
2050              const_iterator (const unit_vector &v, const const_subiterator_type &it):
2051                  container_const_reference<unit_vector> (v), it_ (it) {}
2052 
2053              // Arithmetic
2054              BOOST_UBLAS_INLINE
2055              const_iterator &operator ++ () {
2056                  BOOST_UBLAS_CHECK (it_, bad_index ());
2057                  it_ = !it_;
2058                  return *this;
2059              }
2060              BOOST_UBLAS_INLINE
2061              const_iterator &operator -- () {
2062                  BOOST_UBLAS_CHECK (!it_, bad_index ());
2063                  it_ = !it_;
2064                  return *this;
2065              }
2066 
2067              // Dereference
2068              BOOST_UBLAS_INLINE
2069              const_reference operator * () const {
2070                  BOOST_UBLAS_CHECK (it_, bad_index ());
2071                  return one_;
2072              }
2073 
2074              // Index
2075              BOOST_UBLAS_INLINE
2076              size_type index () const {
2077                  BOOST_UBLAS_CHECK (it_, bad_index ());
2078                  return (*this) ().index_;
2079              }
2080 
2081              // Assignment
2082              BOOST_UBLAS_INLINE
2083              const_iterator &operator = (const const_iterator &it) {
2084                  container_const_reference<unit_vector>::assign (&it ());
2085                  it_ = it.it_;
2086                  return *this;
2087              }
2088 
2089              // Comparison
2090              BOOST_UBLAS_INLINE
2091              bool operator == (const const_iterator &it) const {
2092                  BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
2093                  return it_ == it.it_;
2094              }
2095 
2096          private:
2097              const_subiterator_type it_;
2098          };
2099 
2100          typedef const_iterator iterator;
2101 
2102          BOOST_UBLAS_INLINE
2103          const_iterator begin () const {
2104              return const_iterator (*this, true);
2105          }
2106          BOOST_UBLAS_INLINE
2107          const_iterator cbegin () const {
2108              return begin ();
2109          }
2110          BOOST_UBLAS_INLINE
2111          const_iterator end () const {
2112              return const_iterator (*this, false);
2113          }
2114          BOOST_UBLAS_INLINE
2115          const_iterator cend () const {
2116              return end ();
2117          }
2118 
2119          // Reverse iterator
2120          typedef reverse_iterator_base<const_iterator> const_reverse_iterator;
2121 
2122          BOOST_UBLAS_INLINE
2123          const_reverse_iterator rbegin () const {
2124              return const_reverse_iterator (end ());
2125          }
2126          BOOST_UBLAS_INLINE
2127          const_reverse_iterator crbegin () const {
2128              return rbegin ();
2129          }
2130          BOOST_UBLAS_INLINE
2131          const_reverse_iterator rend () const {
2132              return const_reverse_iterator (begin ());
2133          }
2134          BOOST_UBLAS_INLINE
2135          const_reverse_iterator crend () const {
2136              return rend ();
2137          }
2138 
2139           // Serialization
2140          template<class Archive>
2141          void serialize(Archive & ar, const unsigned int /* file_version */){
2142              serialization::collection_size_type s (size_);
2143              ar & serialization::make_nvp("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 boost::allocator_size_type<ALLOC>::type size_type;
2179          typedef typename boost::allocator_difference_type<ALLOC>::type difference_type;
2180          typedef T value_type;
2181          typedef const T &const_reference;
2182          typedef T &reference;
2183          typedef const vector_reference<const self_type> const_closure_type;
2184          typedef vector_reference<self_type> closure_type;
2185          typedef dense_tag storage_category;
2186 
2187          // Construction and destruction
2188          BOOST_UBLAS_INLINE
2189          scalar_vector ():
2190              vector_container<self_type> (),
2191              size_ (0), value_ () {}
2192          BOOST_UBLAS_INLINE
2193          explicit scalar_vector (size_type size, const value_type &value = value_type(1)):
2194              vector_container<self_type> (),
2195              size_ (size), value_ (value) {}
2196          BOOST_UBLAS_INLINE
2197          scalar_vector (const scalar_vector &v):
2198              vector_container<self_type> (),
2199              size_ (v.size_), value_ (v.value_) {}
2200 
2201          // Accessors
2202          BOOST_UBLAS_INLINE
2203          size_type size () const {
2204              return size_;
2205          }
2206 
2207          // Resizing
2208          BOOST_UBLAS_INLINE
2209          void resize (size_type size, bool /*preserve*/ = true) {
2210              size_ = size;
2211          }
2212 
2213          // Element support
2214          BOOST_UBLAS_INLINE
2215          const_pointer find_element (size_type /*i*/) const {
2216              return & value_;
2217          }
2218 
2219          // Element access
2220          BOOST_UBLAS_INLINE
2221          const_reference operator () (size_type /*i*/) const {
2222              return value_;
2223          }
2224 
2225          BOOST_UBLAS_INLINE
2226          const_reference operator [] (size_type /*i*/) const {
2227              return value_;
2228          }
2229 
2230          // Assignment
2231          BOOST_UBLAS_INLINE
2232          scalar_vector &operator = (const scalar_vector &v) {
2233              size_ = v.size_;
2234              value_ = v.value_;
2235              return *this;
2236          }
2237          BOOST_UBLAS_INLINE
2238          scalar_vector &assign_temporary (scalar_vector &v) {
2239              swap (v);
2240              return *this;
2241          }
2242 
2243          // Swapping
2244          BOOST_UBLAS_INLINE
2245          void swap (scalar_vector &v) {
2246              if (this != &v) {
2247                  std::swap (size_, v.size_);
2248                  std::swap (value_, v.value_);
2249              }
2250          }
2251          BOOST_UBLAS_INLINE
2252          friend void swap (scalar_vector &v1, scalar_vector &v2) {
2253              v1.swap (v2);
2254          }
2255 
2256          // Iterator types
2257      private:
2258          // Use an index
2259          typedef size_type const_subiterator_type;
2260 
2261      public:
2262 #ifdef BOOST_UBLAS_USE_INDEXED_ITERATOR
2263          typedef indexed_const_iterator<self_type, dense_random_access_iterator_tag> iterator;
2264          typedef indexed_const_iterator<self_type, dense_random_access_iterator_tag> const_iterator;
2265 #else
2266          class const_iterator;
2267 #endif
2268 
2269          // Element lookup
2270          BOOST_UBLAS_INLINE
2271          const_iterator find (size_type i) const {
2272              return const_iterator (*this, i);
2273          }
2274 
2275 #ifndef BOOST_UBLAS_USE_INDEXED_ITERATOR
2276          class const_iterator:
2277              public container_const_reference<scalar_vector>,
2278              public random_access_iterator_base<dense_random_access_iterator_tag,
2279                                                 const_iterator, value_type> {
2280          public:
2281              typedef typename scalar_vector::difference_type difference_type;
2282              typedef typename scalar_vector::value_type value_type;
2283              typedef typename scalar_vector::const_reference reference;
2284              typedef typename scalar_vector::const_pointer pointer;
2285 
2286              // Construction and destruction
2287              BOOST_UBLAS_INLINE
2288              const_iterator ():
2289                  container_const_reference<scalar_vector> (), it_ () {}
2290              BOOST_UBLAS_INLINE
2291              const_iterator (const scalar_vector &v, const const_subiterator_type &it):
2292                  container_const_reference<scalar_vector> (v), it_ (it) {}
2293 
2294              // Arithmetic
2295              BOOST_UBLAS_INLINE
2296              const_iterator &operator ++ () {
2297                  ++ it_;
2298                  return *this;
2299              }
2300              BOOST_UBLAS_INLINE
2301              const_iterator &operator -- () {
2302                  -- it_;
2303                  return *this;
2304              }
2305              BOOST_UBLAS_INLINE
2306              const_iterator &operator += (difference_type n) {
2307                  it_ += n;
2308                  return *this;
2309              }
2310              BOOST_UBLAS_INLINE
2311              const_iterator &operator -= (difference_type n) {
2312                  it_ -= n;
2313                  return *this;
2314              }
2315              BOOST_UBLAS_INLINE
2316              difference_type operator - (const const_iterator &it) const {
2317                  BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
2318                  return it_ - it.it_;
2319              }
2320 
2321              // Dereference
2322              BOOST_UBLAS_INLINE
2323              const_reference operator * () const {
2324                  BOOST_UBLAS_CHECK (it_ < (*this) ().size (), bad_index ());
2325                  return (*this) () (index ());
2326              }
2327              BOOST_UBLAS_INLINE
2328              const_reference operator [] (difference_type n) const {
2329                  return *(*this + n);
2330              }
2331 
2332              // Index
2333              BOOST_UBLAS_INLINE
2334              size_type index () const {
2335                  BOOST_UBLAS_CHECK (it_ < (*this) ().size (), bad_index ());
2336                  return it_;
2337              }
2338 
2339              // Assignment
2340              BOOST_UBLAS_INLINE
2341              const_iterator &operator = (const const_iterator &it) {
2342                  container_const_reference<scalar_vector>::assign (&it ());
2343                  it_ = it.it_;
2344                  return *this;
2345              }
2346 
2347              // Comparison
2348              BOOST_UBLAS_INLINE
2349              bool operator == (const const_iterator &it) const {
2350                  BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
2351                  return it_ == it.it_;
2352              }
2353              BOOST_UBLAS_INLINE
2354              bool operator < (const const_iterator &it) const {
2355                  BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
2356                  return it_ < it.it_;
2357              }
2358 
2359          private:
2360              const_subiterator_type it_;
2361          };
2362 
2363          typedef const_iterator iterator;
2364 #endif
2365 
2366          BOOST_UBLAS_INLINE
2367          const_iterator begin () const {
2368              return find (0);
2369          }
2370          BOOST_UBLAS_INLINE
2371          const_iterator cbegin () const {
2372              return begin ();
2373          }
2374          BOOST_UBLAS_INLINE
2375          const_iterator end () const {
2376              return find (size_);
2377          }
2378          BOOST_UBLAS_INLINE
2379          const_iterator cend () const {
2380              return end ();
2381          }
2382 
2383          // Reverse iterator
2384          typedef reverse_iterator_base<const_iterator> const_reverse_iterator;
2385 
2386          BOOST_UBLAS_INLINE
2387          const_reverse_iterator rbegin () const {
2388              return const_reverse_iterator (end ());
2389          }
2390          BOOST_UBLAS_INLINE
2391          const_reverse_iterator crbegin () const {
2392              return rbegin ();
2393          }
2394          BOOST_UBLAS_INLINE
2395          const_reverse_iterator rend () const {
2396              return const_reverse_iterator (begin ());
2397          }
2398          BOOST_UBLAS_INLINE
2399          const_reverse_iterator crend () const {
2400              return rend ();
2401          }
2402 
2403           // Serialization
2404          template<class Archive>
2405          void serialize(Archive & ar, const unsigned int /* file_version */){
2406              serialization::collection_size_type s (size_);
2407              ar & serialization::make_nvp("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
2448          c_vector ():
2449              size_ (N) /* , data_ () */ {}
2450          explicit BOOST_UBLAS_INLINE
2451          c_vector (size_type size):
2452              size_ (size) /* , data_ () */ {
2453              if (size_ > N)
2454                  bad_size ().raise ();
2455          }
2456          BOOST_UBLAS_INLINE
2457          c_vector (const c_vector &v):
2458              size_ (v.size_) /* , data_ () */ {
2459              if (size_ > N)
2460                  bad_size ().raise ();
2461              assign(v);
2462          }
2463          template<class AE>
2464          BOOST_UBLAS_INLINE
2465          c_vector (const vector_expression<AE> &ae):
2466              size_ (ae ().size ()) /* , data_ () */ {
2467              if (size_ > N)
2468                  bad_size ().raise ();
2469              vector_assign<scalar_assign> (*this, ae);
2470          }
2471 
2472          // Accessors
2473          BOOST_UBLAS_INLINE
2474          size_type size () const {
2475              return size_;
2476          }
2477          BOOST_UBLAS_INLINE
2478          const_pointer data () const {
2479              return data_;
2480          }
2481          BOOST_UBLAS_INLINE
2482          pointer data () {
2483              return data_;
2484          }
2485 
2486          // Resizing
2487          BOOST_UBLAS_INLINE
2488          void resize (size_type size, bool /*preserve*/ = true) {
2489              if (size > N)
2490                  bad_size ().raise ();
2491              size_ = size;
2492          }
2493 
2494          // Element support
2495          BOOST_UBLAS_INLINE
2496          pointer find_element (size_type i) {
2497              return const_cast<pointer> (const_cast<const self_type&>(*this).find_element (i));
2498          }
2499          BOOST_UBLAS_INLINE
2500          const_pointer find_element (size_type i) const {
2501              return & data_ [i];
2502          }
2503 
2504          // Element access
2505          BOOST_UBLAS_INLINE
2506          const_reference operator () (size_type i) const {
2507              BOOST_UBLAS_CHECK (i < size_,  bad_index ());
2508              return data_ [i];
2509          }
2510          BOOST_UBLAS_INLINE
2511          reference operator () (size_type i) {
2512              BOOST_UBLAS_CHECK (i < size_, bad_index ());
2513              return data_ [i];
2514          }
2515 
2516          BOOST_UBLAS_INLINE
2517          const_reference operator [] (size_type i) const {
2518              return (*this) (i);
2519          }
2520          BOOST_UBLAS_INLINE
2521          reference operator [] (size_type i) {
2522              return (*this) (i);
2523          }
2524 
2525          // Element assignment
2526          BOOST_UBLAS_INLINE
2527          reference insert_element (size_type i, const_reference t) {
2528              BOOST_UBLAS_CHECK (i < size_, bad_index ());
2529              return (data_ [i] = t);
2530          }
2531          BOOST_UBLAS_INLINE
2532          void erase_element (size_type i) {
2533              BOOST_UBLAS_CHECK (i < size_, bad_index ());
2534              data_ [i] = value_type/*zero*/();
2535          }
2536          
2537          // Zeroing
2538          BOOST_UBLAS_INLINE
2539          void clear () {
2540              std::fill (data_, data_ + size_, value_type/*zero*/());
2541          }
2542 
2543          // Assignment
2544 #ifdef BOOST_UBLAS_MOVE_SEMANTICS
2545 
2546          /*! @note "pass by value" the key idea to enable move semantics */
2547          BOOST_UBLAS_INLINE
2548          c_vector &operator = (c_vector v) {
2549              assign_temporary(v);
2550              return *this;
2551          }
2552 #else
2553          BOOST_UBLAS_INLINE
2554          c_vector &operator = (const c_vector &v) {
2555              size_ = v.size_;
2556              std::copy (v.data_, v.data_ + v.size_, data_);
2557              return *this;
2558          }
2559 #endif
2560          template<class C>          // Container assignment without temporary
2561          BOOST_UBLAS_INLINE
2562          c_vector &operator = (const vector_container<C> &v) {
2563              resize (v ().size (), false);
2564              assign (v);
2565              return *this;
2566          }
2567          BOOST_UBLAS_INLINE
2568          c_vector &assign_temporary (c_vector &v) {
2569              swap (v);
2570              return *this;
2571          }
2572          template<class AE>
2573          BOOST_UBLAS_INLINE
2574          c_vector &operator = (const vector_expression<AE> &ae) {
2575              self_type temporary (ae);
2576              return assign_temporary (temporary);
2577          }
2578          template<class AE>
2579          BOOST_UBLAS_INLINE
2580          c_vector &assign (const vector_expression<AE> &ae) {
2581              vector_assign<scalar_assign> (*this, ae);
2582              return *this;
2583          }
2584 
2585          // Computed assignment
2586          template<class AE>
2587          BOOST_UBLAS_INLINE
2588          c_vector &operator += (const vector_expression<AE> &ae) {
2589              self_type temporary (*this + ae);
2590              return assign_temporary (temporary);
2591          }
2592          template<class C>          // Container assignment without temporary
2593          BOOST_UBLAS_INLINE
2594          c_vector &operator += (const vector_container<C> &v) {
2595              plus_assign (v);
2596              return *this;
2597          }
2598          template<class AE>
2599          BOOST_UBLAS_INLINE
2600          c_vector &plus_assign (const vector_expression<AE> &ae) {
2601              vector_assign<scalar_plus_assign> ( *this, ae);
2602              return *this;
2603          }
2604          template<class AE>
2605          BOOST_UBLAS_INLINE
2606          c_vector &operator -= (const vector_expression<AE> &ae) {
2607              self_type temporary (*this - ae);
2608              return assign_temporary (temporary);
2609          }
2610          template<class C>          // Container assignment without temporary
2611          BOOST_UBLAS_INLINE
2612          c_vector &operator -= (const vector_container<C> &v) {
2613              minus_assign (v);
2614              return *this;
2615          }
2616          template<class AE>
2617          BOOST_UBLAS_INLINE
2618          c_vector &minus_assign (const vector_expression<AE> &ae) {
2619              vector_assign<scalar_minus_assign> (*this, ae);
2620              return *this;
2621          }
2622          template<class AT>
2623          BOOST_UBLAS_INLINE
2624          c_vector &operator *= (const AT &at) {
2625              vector_assign_scalar<scalar_multiplies_assign> (*this, at);
2626              return *this;
2627          }
2628          template<class AT>
2629          BOOST_UBLAS_INLINE
2630          c_vector &operator /= (const AT &at) {
2631              vector_assign_scalar<scalar_divides_assign> (*this, at);
2632              return *this;
2633          }
2634 
2635          // Swapping
2636          BOOST_UBLAS_INLINE
2637          void swap (c_vector &v) {
2638              if (this != &v) {
2639                  BOOST_UBLAS_CHECK (size_ == v.size_, bad_size ());
2640                  std::swap (size_, v.size_);
2641                  std::swap_ranges (data_, data_ + size_, v.data_);
2642              }
2643          }
2644          BOOST_UBLAS_INLINE
2645          friend void swap (c_vector &v1, c_vector &v2) {
2646              v1.swap (v2);
2647          }
2648 
2649          // Iterator types
2650      private:
2651          // Use pointers for iterator
2652          typedef const_pointer const_subiterator_type;
2653          typedef pointer subiterator_type;
2654 
2655      public:
2656 #ifdef BOOST_UBLAS_USE_INDEXED_ITERATOR
2657          typedef indexed_iterator<self_type, dense_random_access_iterator_tag> iterator;
2658          typedef indexed_const_iterator<self_type, dense_random_access_iterator_tag> const_iterator;
2659 #else
2660          class const_iterator;
2661          class iterator;
2662 #endif
2663 
2664          // Element lookup
2665          BOOST_UBLAS_INLINE
2666          const_iterator find (size_type i) const {
2667 #ifndef BOOST_UBLAS_USE_INDEXED_ITERATOR
2668              return const_iterator (*this, &data_ [i]);
2669 #else
2670              return const_iterator (*this, i);
2671 #endif
2672          }
2673          BOOST_UBLAS_INLINE
2674          iterator find (size_type i) {
2675 #ifndef BOOST_UBLAS_USE_INDEXED_ITERATOR
2676              return iterator (*this, &data_ [i]);
2677 #else
2678              return iterator (*this, i);
2679 #endif
2680          }
2681 
2682 #ifndef BOOST_UBLAS_USE_INDEXED_ITERATOR
2683          class const_iterator:
2684              public container_const_reference<c_vector>,
2685              public random_access_iterator_base<dense_random_access_iterator_tag,
2686                                                 const_iterator, value_type> {
2687          public:
2688              typedef typename c_vector::difference_type difference_type;
2689              typedef typename c_vector::value_type value_type;
2690              typedef typename c_vector::const_reference reference;
2691              typedef typename c_vector::const_pointer pointer;
2692 
2693              // Construction and destruction
2694              BOOST_UBLAS_INLINE
2695              const_iterator ():
2696                  container_const_reference<self_type> (), it_ () {}
2697              BOOST_UBLAS_INLINE
2698              const_iterator (const self_type &v, const const_subiterator_type &it):
2699                  container_const_reference<self_type> (v), it_ (it) {}
2700              BOOST_UBLAS_INLINE
2701              const_iterator (const typename self_type::iterator &it):  // ISSUE self_type:: stops VC8 using std::iterator here
2702                  container_const_reference<self_type> (it ()), it_ (it.it_) {}
2703 
2704              // Arithmetic
2705              BOOST_UBLAS_INLINE
2706              const_iterator &operator ++ () {
2707                  ++ it_;
2708                  return *this;
2709              }
2710              BOOST_UBLAS_INLINE
2711              const_iterator &operator -- () {
2712                  -- it_;
2713                  return *this;
2714              }
2715              BOOST_UBLAS_INLINE
2716              const_iterator &operator += (difference_type n) {
2717                  it_ += n;
2718                  return *this;
2719              }
2720              BOOST_UBLAS_INLINE
2721              const_iterator &operator -= (difference_type n) {
2722                  it_ -= n;
2723                  return *this;
2724              }
2725              BOOST_UBLAS_INLINE
2726              difference_type operator - (const const_iterator &it) const {
2727                  BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
2728                  return it_ - it.it_;
2729              }
2730 
2731              // Dereference
2732              BOOST_UBLAS_INLINE
2733              const_reference operator * () const {
2734                  BOOST_UBLAS_CHECK (it_ >= (*this) ().begin ().it_ && it_ < (*this) ().end ().it_, bad_index ());
2735                  return *it_;
2736              }
2737              BOOST_UBLAS_INLINE
2738              const_reference operator [] (difference_type n) const {
2739                  return *(it_ + n);
2740              }
2741 
2742              // Index
2743              BOOST_UBLAS_INLINE
2744              size_type index () const {
2745                  BOOST_UBLAS_CHECK (it_ >= (*this) ().begin ().it_ && it_ < (*this) ().end ().it_, bad_index ());
2746                  const self_type &v = (*this) ();
2747                  return it_ - v.begin ().it_;
2748              }
2749 
2750              // Assignment
2751              BOOST_UBLAS_INLINE
2752              const_iterator &operator = (const const_iterator &it) {
2753                  container_const_reference<self_type>::assign (&it ());
2754                  it_ = it.it_;
2755                  return *this;
2756              }
2757 
2758              // Comparison
2759              BOOST_UBLAS_INLINE
2760              bool operator == (const const_iterator &it) const {
2761                  BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
2762                  return it_ == it.it_;
2763              }
2764              BOOST_UBLAS_INLINE
2765              bool operator < (const const_iterator &it) const {
2766                  BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
2767                  return it_ < it.it_;
2768              }
2769 
2770          private:
2771              const_subiterator_type it_;
2772 
2773              friend class iterator;
2774          };
2775 #endif
2776 
2777          BOOST_UBLAS_INLINE
2778          const_iterator begin () const {
2779              return find (0);
2780          }
2781          BOOST_UBLAS_INLINE
2782          const_iterator cbegin () const {
2783              return begin ();
2784          }
2785          BOOST_UBLAS_INLINE
2786          const_iterator end () const {
2787              return find (size_);
2788          }
2789          BOOST_UBLAS_INLINE
2790          const_iterator cend () const {
2791              return end ();
2792          }
2793 
2794 #ifndef BOOST_UBLAS_USE_INDEXED_ITERATOR
2795          class iterator:
2796              public container_reference<c_vector>,
2797              public random_access_iterator_base<dense_random_access_iterator_tag,
2798                                                 iterator, value_type> {
2799          public:
2800              typedef typename c_vector::difference_type difference_type;
2801              typedef typename c_vector::value_type value_type;
2802              typedef typename c_vector::reference reference;
2803              typedef typename c_vector::pointer pointer;
2804 
2805              // Construction and destruction
2806              BOOST_UBLAS_INLINE
2807              iterator ():
2808                  container_reference<self_type> (), it_ () {}
2809              BOOST_UBLAS_INLINE
2810              iterator (self_type &v, const subiterator_type &it):
2811                  container_reference<self_type> (v), it_ (it) {}
2812 
2813              // Arithmetic
2814              BOOST_UBLAS_INLINE
2815              iterator &operator ++ () {
2816                  ++ it_;
2817                  return *this;
2818              }
2819              BOOST_UBLAS_INLINE
2820              iterator &operator -- () {
2821                  -- it_;
2822                  return *this;
2823              }
2824              BOOST_UBLAS_INLINE
2825              iterator &operator += (difference_type n) {
2826                  it_ += n;
2827                  return *this;
2828              }
2829              BOOST_UBLAS_INLINE
2830              iterator &operator -= (difference_type n) {
2831                  it_ -= n;
2832                  return *this;
2833              }
2834              BOOST_UBLAS_INLINE
2835              difference_type operator - (const iterator &it) const {
2836                  BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
2837                  return it_ - it.it_;
2838              }
2839 
2840              // Dereference
2841              BOOST_UBLAS_INLINE
2842              reference operator * () const {
2843                  BOOST_UBLAS_CHECK (it_ >= (*this) ().begin ().it_ && it_ < (*this) ().end ().it_, bad_index ());
2844                  return *it_;
2845              }
2846              BOOST_UBLAS_INLINE
2847              reference operator [] (difference_type n) const {
2848                  return *(it_ + n);
2849              }
2850 
2851              // Index
2852              BOOST_UBLAS_INLINE
2853              size_type index () const {
2854                  BOOST_UBLAS_CHECK (it_ >= (*this) ().begin ().it_ && it_ < (*this) ().end ().it_, bad_index ());
2855                  // EDG won't allow const self_type it doesn't allow friend access to it_
2856                  self_type &v = (*this) ();
2857                  return it_ - v.begin ().it_;
2858              }
2859 
2860              // Assignment
2861              BOOST_UBLAS_INLINE
2862              iterator &operator = (const iterator &it) {
2863                  container_reference<self_type>::assign (&it ());
2864                  it_ = it.it_;
2865                  return *this;
2866              }
2867 
2868              // Comparison
2869              BOOST_UBLAS_INLINE
2870              bool operator == (const iterator &it) const {
2871                  BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
2872                  return it_ == it.it_;
2873              }
2874              BOOST_UBLAS_INLINE
2875              bool operator < (const iterator &it) const {
2876                  BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
2877                  return it_ < it.it_;
2878              }
2879 
2880          private:
2881              subiterator_type it_;
2882 
2883              friend class const_iterator;
2884          };
2885 #endif
2886 
2887          BOOST_UBLAS_INLINE
2888          iterator begin () {
2889              return find (0);
2890          }
2891          BOOST_UBLAS_INLINE
2892          iterator end () {
2893              return find (size_);
2894          }
2895 
2896          // Reverse iterator
2897          typedef reverse_iterator_base<const_iterator> const_reverse_iterator;
2898          typedef reverse_iterator_base<iterator> reverse_iterator;
2899 
2900          BOOST_UBLAS_INLINE
2901          const_reverse_iterator rbegin () const {
2902              return const_reverse_iterator (end ());
2903          }
2904          BOOST_UBLAS_INLINE
2905          const_reverse_iterator crbegin () const {
2906              return rbegin ();
2907          }
2908          BOOST_UBLAS_INLINE
2909          const_reverse_iterator rend () const {
2910              return const_reverse_iterator (begin ());
2911          }
2912          BOOST_UBLAS_INLINE
2913          const_reverse_iterator crend () const {
2914              return rend ();
2915          }
2916          BOOST_UBLAS_INLINE
2917          reverse_iterator rbegin () {
2918              return reverse_iterator (end ());
2919          }
2920          BOOST_UBLAS_INLINE
2921          reverse_iterator rend () {
2922              return reverse_iterator (begin ());
2923          }
2924 
2925          // Serialization
2926          template<class Archive>
2927          void serialize(Archive & ar, const unsigned int /* file_version */){
2928              serialization::collection_size_type s (size_);
2929              ar & serialization::make_nvp("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