Chris@16: // Chris@16: // Copyright (c) 2000-2010 Chris@16: // Joerg Walter, Mathias Koch, David Bellot Chris@101: // Copyright (c) 2014, Athanasios Iliopoulos Chris@16: // Chris@16: // Distributed under the Boost Software License, Version 1.0. (See Chris@16: // accompanying file LICENSE_1_0.txt or copy at Chris@16: // http://www.boost.org/LICENSE_1_0.txt) Chris@16: // Chris@16: // The authors gratefully acknowledge the support of Chris@16: // GeNeSys mbH & Co. KG in producing this work. Chris@16: // Chris@16: // And we acknowledge the support from all contributors. Chris@16: Chris@16: /// \file vector.hpp Definition for the class vector and its derivative Chris@16: Chris@16: #ifndef _BOOST_UBLAS_VECTOR_ Chris@16: #define _BOOST_UBLAS_VECTOR_ Chris@16: Chris@101: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: Chris@101: #ifdef BOOST_UBLAS_CPP_GE_2011 Chris@101: #include Chris@101: #include Chris@101: #if defined(BOOST_MSVC) // For std::forward in fixed_vector Chris@101: #include Chris@101: #endif Chris@101: #endif Chris@16: Chris@16: // Iterators based on ideas of Jeremy Siek Chris@16: Chris@16: namespace boost { namespace numeric { namespace ublas { Chris@16: Chris@16: /** \brief A dense vector of values of type \c T. Chris@16: * Chris@16: * 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 Chris@16: * to the \f$i\f$-th element of the container. A storage type \c A can be specified which defaults to \c unbounded_array. Chris@16: * Elements are constructed by \c A, which need not initialise their value. Chris@16: * Chris@16: * \tparam T type of the objects stored in the vector (like int, double, complex,...) Chris@16: * \tparam A The type of the storage array of the vector. Default is \c unbounded_array. \c and \c std::vector can also be used Chris@16: */ Chris@16: template Chris@16: class vector: Chris@16: public vector_container > { Chris@16: Chris@16: typedef vector self_type; Chris@16: public: Chris@16: #ifdef BOOST_UBLAS_ENABLE_PROXY_SHORTCUTS Chris@16: using vector_container::operator (); Chris@16: #endif Chris@16: Chris@16: typedef typename A::size_type size_type; Chris@16: typedef typename A::difference_type difference_type; Chris@16: typedef T value_type; Chris@16: typedef typename type_traits::const_reference const_reference; Chris@16: typedef T &reference; Chris@16: typedef T *pointer; Chris@16: typedef const T *const_pointer; Chris@16: typedef A array_type; Chris@16: typedef const vector_reference const_closure_type; Chris@16: typedef vector_reference closure_type; Chris@16: typedef self_type vector_temporary_type; Chris@16: typedef dense_tag storage_category; Chris@16: Chris@16: // Construction and destruction Chris@16: Chris@16: /// \brief Constructor of a vector Chris@16: /// By default it is empty, i.e. \c size()==0. Chris@16: BOOST_UBLAS_INLINE Chris@16: vector (): Chris@16: vector_container (), Chris@16: data_ () {} Chris@16: Chris@16: /// \brief Constructor of a vector with a predefined size Chris@16: /// By default, its elements are initialized to 0. Chris@16: /// \param size initial size of the vector Chris@16: explicit BOOST_UBLAS_INLINE Chris@16: vector (size_type size): Chris@16: vector_container (), Chris@16: data_ (size) { Chris@16: } Chris@16: Chris@16: /// \brief Constructor of a vector by copying from another container Chris@16: /// This type has the generic name \c array_typ within the vector definition. Chris@16: /// \param size initial size of the vector \bug this value is not used Chris@16: /// \param data container of type \c A Chris@16: /// \todo remove this definition because \c size is not used Chris@16: BOOST_UBLAS_INLINE Chris@101: vector (size_type /*size*/, const array_type &data): Chris@16: vector_container (), Chris@16: data_ (data) {} Chris@16: Chris@16: /// \brief Constructor of a vector by copying from another container Chris@16: /// This type has the generic name \c array_typ within the vector definition. Chris@16: /// \param data container of type \c A Chris@16: BOOST_UBLAS_INLINE Chris@16: vector (const array_type &data): Chris@16: vector_container (), Chris@16: data_ (data) {} Chris@16: Chris@16: /// \brief Constructor of a vector with a predefined size and a unique initial value Chris@16: /// \param size of the vector Chris@16: /// \param init value to assign to each element of the vector Chris@16: BOOST_UBLAS_INLINE Chris@16: vector (size_type size, const value_type &init): Chris@16: vector_container (), Chris@16: data_ (size, init) {} Chris@16: Chris@16: /// \brief Copy-constructor of a vector Chris@16: /// \param v is the vector to be duplicated Chris@16: BOOST_UBLAS_INLINE Chris@16: vector (const vector &v): Chris@16: vector_container (), Chris@16: data_ (v.data_) {} Chris@16: Chris@16: /// \brief Copy-constructor of a vector from a vector_expression Chris@16: /// Depending on the vector_expression, this constructor can have the cost of the computations Chris@16: /// of the expression (trivial to say it, but it is to take into account in your complexity calculations). Chris@16: /// \param ae the vector_expression which values will be duplicated into the vector Chris@16: template Chris@16: BOOST_UBLAS_INLINE Chris@16: vector (const vector_expression &ae): Chris@16: vector_container (), Chris@16: data_ (ae ().size ()) { Chris@16: vector_assign (*this, ae); Chris@16: } Chris@16: Chris@16: // ----------------------- Chris@16: // Random Access Container Chris@16: // ----------------------- Chris@16: Chris@16: /// \brief Return the maximum size of the data container. Chris@16: /// 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. Chris@16: BOOST_UBLAS_INLINE Chris@16: size_type max_size () const { Chris@16: return data_.max_size (); Chris@16: } Chris@16: Chris@16: /// \brief Return true if the vector is empty (\c size==0) Chris@16: /// \return \c true if empty, \c false otherwise Chris@16: BOOST_UBLAS_INLINE Chris@16: bool empty () const { Chris@16: return data_.size () == 0; Chris@16: } Chris@16: Chris@16: // --------- Chris@16: // Accessors Chris@16: // --------- Chris@16: Chris@16: /// \brief Return the size of the vector Chris@16: BOOST_UBLAS_INLINE Chris@16: size_type size () const { Chris@16: return data_.size (); Chris@16: } Chris@16: Chris@16: // ----------------- Chris@16: // Storage accessors Chris@16: // ----------------- Chris@16: Chris@16: /// \brief Return a \c const reference to the container. Useful to access data directly for specific type of container. Chris@16: BOOST_UBLAS_INLINE Chris@16: const array_type &data () const { Chris@16: return data_; Chris@16: } Chris@16: Chris@16: /// \brief Return a reference to the container. Useful to speed-up write operations to the data in very specific case. Chris@16: BOOST_UBLAS_INLINE Chris@16: array_type &data () { Chris@16: return data_; Chris@16: } Chris@16: Chris@16: // -------- Chris@16: // Resizing Chris@16: // -------- Chris@16: Chris@16: /// \brief Resize the vector Chris@16: /// 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. Chris@16: /// \param size new size of the vector Chris@16: /// \param preserve if true, keep values Chris@16: BOOST_UBLAS_INLINE Chris@16: void resize (size_type size, bool preserve = true) { Chris@16: if (preserve) Chris@16: data ().resize (size, typename A::value_type ()); Chris@16: else Chris@16: data ().resize (size); Chris@16: } Chris@16: Chris@16: // --------------- Chris@16: // Element support Chris@16: // --------------- Chris@16: Chris@16: /// \brief Return a pointer to the element \f$i\f$ Chris@16: /// \param i index of the element Chris@16: // XXX this semantic is not the one expected by the name of this method Chris@16: BOOST_UBLAS_INLINE Chris@16: pointer find_element (size_type i) { Chris@16: return const_cast (const_cast(*this).find_element (i)); Chris@16: } Chris@16: Chris@16: /// \brief Return a const pointer to the element \f$i\f$ Chris@16: /// \param i index of the element Chris@16: // XXX this semantic is not the one expected by the name of this method Chris@16: BOOST_UBLAS_INLINE Chris@16: const_pointer find_element (size_type i) const { Chris@16: return & (data () [i]); Chris@16: } Chris@16: Chris@16: // -------------- Chris@16: // Element access Chris@16: // -------------- Chris@16: Chris@16: /// \brief Return a const reference to the element \f$i\f$ Chris@16: /// Return a const reference to the element \f$i\f$. With some compilers, this notation will be faster than \c[i] Chris@16: /// \param i index of the element Chris@16: BOOST_UBLAS_INLINE Chris@16: const_reference operator () (size_type i) const { Chris@16: return data () [i]; Chris@16: } Chris@16: Chris@16: /// \brief Return a reference to the element \f$i\f$ Chris@16: /// Return a reference to the element \f$i\f$. With some compilers, this notation will be faster than \c[i] Chris@16: /// \param i index of the element Chris@16: BOOST_UBLAS_INLINE Chris@16: reference operator () (size_type i) { Chris@16: return data () [i]; Chris@16: } Chris@16: Chris@16: /// \brief Return a const reference to the element \f$i\f$ Chris@16: /// \param i index of the element Chris@16: BOOST_UBLAS_INLINE Chris@16: const_reference operator [] (size_type i) const { Chris@16: return (*this) (i); Chris@16: } Chris@16: Chris@16: /// \brief Return a reference to the element \f$i\f$ Chris@16: /// \param i index of the element Chris@16: BOOST_UBLAS_INLINE Chris@16: reference operator [] (size_type i) { Chris@16: return (*this) (i); Chris@16: } Chris@16: Chris@16: // ------------------ Chris@16: // Element assignment Chris@16: // ------------------ Chris@16: Chris@16: /// \brief Set element \f$i\f$ to the value \c t Chris@16: /// \param i index of the element Chris@16: /// \param t reference to the value to be set Chris@16: // XXX semantic of this is to insert a new element and therefore size=size+1 ? Chris@16: BOOST_UBLAS_INLINE Chris@16: reference insert_element (size_type i, const_reference t) { Chris@16: return (data () [i] = t); Chris@16: } Chris@16: Chris@16: /// \brief Set element \f$i\f$ to the \e zero value Chris@16: /// \param i index of the element Chris@16: BOOST_UBLAS_INLINE Chris@16: void erase_element (size_type i) { Chris@16: data () [i] = value_type/*zero*/(); Chris@16: } Chris@16: Chris@16: // ------- Chris@16: // Zeroing Chris@16: // ------- Chris@16: Chris@16: /// \brief Clear the vector, i.e. set all values to the \c zero value. Chris@16: BOOST_UBLAS_INLINE Chris@16: void clear () { Chris@16: std::fill (data ().begin (), data ().end (), value_type/*zero*/()); Chris@16: } Chris@16: Chris@16: // Assignment Chris@16: #ifdef BOOST_UBLAS_MOVE_SEMANTICS Chris@16: Chris@16: /// \brief Assign a full vector (\e RHS-vector) to the current vector (\e LHS-vector) Chris@16: /// \param v is the source vector Chris@16: /// \return a reference to a vector (i.e. the destination vector) Chris@16: /*! @note "pass by value" the key idea to enable move semantics */ Chris@16: BOOST_UBLAS_INLINE Chris@16: vector &operator = (vector v) { Chris@16: assign_temporary(v); Chris@16: return *this; Chris@16: } Chris@16: #else Chris@16: /// \brief Assign a full vector (\e RHS-vector) to the current vector (\e LHS-vector) Chris@16: /// \param v is the source vector Chris@16: /// \return a reference to a vector (i.e. the destination vector) Chris@16: BOOST_UBLAS_INLINE Chris@16: vector &operator = (const vector &v) { Chris@16: data () = v.data (); Chris@16: return *this; Chris@16: } Chris@16: #endif Chris@16: Chris@16: /// \brief Assign a full vector (\e RHS-vector) to the current vector (\e LHS-vector) Chris@16: /// Assign a full vector (\e RHS-vector) to the current vector (\e LHS-vector). This method does not create any temporary. Chris@16: /// \param v is the source vector container Chris@16: /// \return a reference to a vector (i.e. the destination vector) Chris@16: template // Container assignment without temporary Chris@16: BOOST_UBLAS_INLINE Chris@16: vector &operator = (const vector_container &v) { Chris@16: resize (v ().size (), false); Chris@16: assign (v); Chris@16: return *this; Chris@16: } Chris@16: Chris@16: /// \brief Assign a full vector (\e RHS-vector) to the current vector (\e LHS-vector) Chris@16: /// \param v is the source vector Chris@16: /// \return a reference to a vector (i.e. the destination vector) Chris@16: BOOST_UBLAS_INLINE Chris@16: vector &assign_temporary (vector &v) { Chris@16: swap (v); Chris@16: return *this; Chris@16: } Chris@16: Chris@16: /// \brief Assign the result of a vector_expression to the vector Chris@16: /// 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. Chris@16: /// \tparam AE is the type of the vector_expression Chris@16: /// \param ae is a const reference to the vector_expression Chris@16: /// \return a reference to the resulting vector Chris@16: template Chris@16: BOOST_UBLAS_INLINE Chris@16: vector &operator = (const vector_expression &ae) { Chris@16: self_type temporary (ae); Chris@16: return assign_temporary (temporary); Chris@16: } Chris@16: Chris@16: /// \brief Assign the result of a vector_expression to the vector Chris@16: /// 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. Chris@16: /// \tparam AE is the type of the vector_expression Chris@16: /// \param ae is a const reference to the vector_expression Chris@16: /// \return a reference to the resulting vector Chris@16: template Chris@16: BOOST_UBLAS_INLINE Chris@16: vector &assign (const vector_expression &ae) { Chris@16: vector_assign (*this, ae); Chris@16: return *this; Chris@16: } Chris@16: Chris@16: // ------------------- Chris@16: // Computed assignment Chris@16: // ------------------- Chris@16: Chris@16: /// \brief Assign the sum of the vector and a vector_expression to the vector Chris@16: /// 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. Chris@16: /// A temporary is created for the computations. Chris@16: /// \tparam AE is the type of the vector_expression Chris@16: /// \param ae is a const reference to the vector_expression Chris@16: /// \return a reference to the resulting vector Chris@16: template Chris@16: BOOST_UBLAS_INLINE Chris@16: vector &operator += (const vector_expression &ae) { Chris@16: self_type temporary (*this + ae); Chris@16: return assign_temporary (temporary); Chris@16: } Chris@16: Chris@16: /// \brief Assign the sum of the vector and a vector_expression to the vector Chris@16: /// 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. Chris@16: /// No temporary is created. Computations are done and stored directly into the resulting vector. Chris@16: /// \tparam AE is the type of the vector_expression Chris@16: /// \param ae is a const reference to the vector_expression Chris@16: /// \return a reference to the resulting vector Chris@16: template // Container assignment without temporary Chris@16: BOOST_UBLAS_INLINE Chris@16: vector &operator += (const vector_container &v) { Chris@16: plus_assign (v); Chris@16: return *this; Chris@16: } Chris@16: Chris@16: /// \brief Assign the sum of the vector and a vector_expression to the vector Chris@16: /// 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. Chris@16: /// No temporary is created. Computations are done and stored directly into the resulting vector. Chris@16: /// \tparam AE is the type of the vector_expression Chris@16: /// \param ae is a const reference to the vector_expression Chris@16: /// \return a reference to the resulting vector Chris@16: template Chris@16: BOOST_UBLAS_INLINE Chris@16: vector &plus_assign (const vector_expression &ae) { Chris@16: vector_assign (*this, ae); Chris@16: return *this; Chris@16: } Chris@16: Chris@16: /// \brief Assign the difference of the vector and a vector_expression to the vector Chris@16: /// 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. Chris@16: /// A temporary is created for the computations. Chris@16: /// \tparam AE is the type of the vector_expression Chris@16: /// \param ae is a const reference to the vector_expression Chris@16: template Chris@16: BOOST_UBLAS_INLINE Chris@16: vector &operator -= (const vector_expression &ae) { Chris@16: self_type temporary (*this - ae); Chris@16: return assign_temporary (temporary); Chris@16: } Chris@16: Chris@16: /// \brief Assign the difference of the vector and a vector_expression to the vector Chris@16: /// 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. Chris@16: /// No temporary is created. Computations are done and stored directly into the resulting vector. Chris@16: /// \tparam AE is the type of the vector_expression Chris@16: /// \param ae is a const reference to the vector_expression Chris@16: /// \return a reference to the resulting vector Chris@16: template // Container assignment without temporary Chris@16: BOOST_UBLAS_INLINE Chris@16: vector &operator -= (const vector_container &v) { Chris@16: minus_assign (v); Chris@16: return *this; Chris@16: } Chris@16: Chris@16: /// \brief Assign the difference of the vector and a vector_expression to the vector Chris@16: /// 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. Chris@16: /// No temporary is created. Computations are done and stored directly into the resulting vector. Chris@16: /// \tparam AE is the type of the vector_expression Chris@16: /// \param ae is a const reference to the vector_expression Chris@16: /// \return a reference to the resulting vector Chris@16: template Chris@16: BOOST_UBLAS_INLINE Chris@16: vector &minus_assign (const vector_expression &ae) { Chris@16: vector_assign (*this, ae); Chris@16: return *this; Chris@16: } Chris@16: Chris@16: /// \brief Assign the product of the vector and a scalar to the vector Chris@16: /// 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. Chris@16: /// No temporary is created. Computations are done and stored directly into the resulting vector. Chris@16: /// \tparam AE is the type of the vector_expression Chris@16: /// \param at is a const reference to the scalar Chris@16: /// \return a reference to the resulting vector Chris@16: template Chris@16: BOOST_UBLAS_INLINE Chris@16: vector &operator *= (const AT &at) { Chris@16: vector_assign_scalar (*this, at); Chris@16: return *this; Chris@16: } Chris@16: Chris@16: /// \brief Assign the division of the vector by a scalar to the vector Chris@16: /// 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. Chris@16: /// No temporary is created. Computations are done and stored directly into the resulting vector. Chris@16: /// \tparam AE is the type of the vector_expression Chris@16: /// \param at is a const reference to the scalar Chris@16: /// \return a reference to the resulting vector Chris@16: template Chris@16: BOOST_UBLAS_INLINE Chris@16: vector &operator /= (const AT &at) { Chris@16: vector_assign_scalar (*this, at); Chris@16: return *this; Chris@16: } Chris@16: Chris@16: // -------- Chris@16: // Swapping Chris@16: // -------- Chris@16: Chris@16: /// \brief Swap the content of the vector with another vector Chris@16: /// \param v is the vector to be swapped with Chris@16: BOOST_UBLAS_INLINE Chris@16: void swap (vector &v) { Chris@16: if (this != &v) { Chris@16: data ().swap (v.data ()); Chris@16: } Chris@16: } Chris@16: Chris@16: /// \brief Swap the content of two vectors Chris@16: /// \param v1 is the first vector. It takes values from v2 Chris@16: /// \param v2 is the second vector It takes values from v1 Chris@16: BOOST_UBLAS_INLINE Chris@16: friend void swap (vector &v1, vector &v2) { Chris@16: v1.swap (v2); Chris@16: } Chris@16: Chris@16: // Iterator types Chris@16: private: Chris@16: // Use the storage array iterator Chris@16: typedef typename A::const_iterator const_subiterator_type; Chris@16: typedef typename A::iterator subiterator_type; Chris@16: Chris@16: public: Chris@16: #ifdef BOOST_UBLAS_USE_INDEXED_ITERATOR Chris@16: typedef indexed_iterator iterator; Chris@16: typedef indexed_const_iterator const_iterator; Chris@16: #else Chris@16: class const_iterator; Chris@16: class iterator; Chris@16: #endif Chris@16: Chris@16: // -------------- Chris@16: // Element lookup Chris@16: // -------------- Chris@16: Chris@16: /// \brief Return a const iterator to the element \e i Chris@16: /// \param i index of the element Chris@16: BOOST_UBLAS_INLINE Chris@16: const_iterator find (size_type i) const { Chris@16: #ifndef BOOST_UBLAS_USE_INDEXED_ITERATOR Chris@16: return const_iterator (*this, data ().begin () + i); Chris@16: #else Chris@16: return const_iterator (*this, i); Chris@16: #endif Chris@16: } Chris@16: Chris@16: /// \brief Return an iterator to the element \e i Chris@16: /// \param i index of the element Chris@16: BOOST_UBLAS_INLINE Chris@16: iterator find (size_type i) { Chris@16: #ifndef BOOST_UBLAS_USE_INDEXED_ITERATOR Chris@16: return iterator (*this, data ().begin () + i); Chris@16: #else Chris@16: return iterator (*this, i); Chris@16: #endif Chris@16: } Chris@16: Chris@16: #ifndef BOOST_UBLAS_USE_INDEXED_ITERATOR Chris@16: class const_iterator: Chris@16: public container_const_reference, Chris@16: public random_access_iterator_base { Chris@16: public: Chris@16: typedef typename vector::difference_type difference_type; Chris@16: typedef typename vector::value_type value_type; Chris@16: typedef typename vector::const_reference reference; Chris@16: typedef const typename vector::pointer pointer; Chris@16: Chris@16: // ---------------------------- Chris@16: // Construction and destruction Chris@16: // ---------------------------- Chris@16: Chris@16: Chris@16: BOOST_UBLAS_INLINE Chris@16: const_iterator (): Chris@16: container_const_reference (), it_ () {} Chris@16: BOOST_UBLAS_INLINE Chris@16: const_iterator (const self_type &v, const const_subiterator_type &it): Chris@16: container_const_reference (v), it_ (it) {} Chris@16: BOOST_UBLAS_INLINE Chris@16: const_iterator (const typename self_type::iterator &it): // ISSUE vector:: stops VC8 using std::iterator here Chris@16: container_const_reference (it ()), it_ (it.it_) {} Chris@16: Chris@16: // ---------- Chris@16: // Arithmetic Chris@16: // ---------- Chris@16: Chris@16: /// \brief Increment by 1 the position of the iterator Chris@16: /// \return a reference to the const iterator Chris@16: BOOST_UBLAS_INLINE Chris@16: const_iterator &operator ++ () { Chris@16: ++ it_; Chris@16: return *this; Chris@16: } Chris@16: Chris@16: /// \brief Decrement by 1 the position of the iterator Chris@16: /// \return a reference to the const iterator Chris@16: BOOST_UBLAS_INLINE Chris@16: const_iterator &operator -- () { Chris@16: -- it_; Chris@16: return *this; Chris@16: } Chris@16: Chris@16: /// \brief Increment by \e n the position of the iterator Chris@16: /// \return a reference to the const iterator Chris@16: BOOST_UBLAS_INLINE Chris@16: const_iterator &operator += (difference_type n) { Chris@16: it_ += n; Chris@16: return *this; Chris@16: } Chris@16: Chris@16: /// \brief Decrement by \e n the position of the iterator Chris@16: /// \return a reference to the const iterator Chris@16: BOOST_UBLAS_INLINE Chris@16: const_iterator &operator -= (difference_type n) { Chris@16: it_ -= n; Chris@16: return *this; Chris@16: } Chris@16: Chris@16: /// \brief Return the different in number of positions between 2 iterators Chris@16: BOOST_UBLAS_INLINE Chris@16: difference_type operator - (const const_iterator &it) const { Chris@16: BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ()); Chris@16: return it_ - it.it_; Chris@16: } Chris@16: Chris@16: /// \brief Dereference an iterator Chris@16: /// Dereference an iterator: a bounds' check is done before returning the value. A bad_index() expection is returned if out of bounds. Chris@16: /// \return a const reference to the value pointed by the iterator Chris@16: BOOST_UBLAS_INLINE Chris@16: const_reference operator * () const { Chris@16: BOOST_UBLAS_CHECK (it_ >= (*this) ().begin ().it_ && it_ < (*this) ().end ().it_, bad_index ()); Chris@16: return *it_; Chris@16: } Chris@16: Chris@16: /// \brief Dereference an iterator at the n-th forward value Chris@16: /// Dereference an iterator at the n-th forward value, that is the value pointed by iterator+n. Chris@16: /// A bounds' check is done before returning the value. A bad_index() expection is returned if out of bounds. Chris@16: /// \return a const reference Chris@16: BOOST_UBLAS_INLINE Chris@16: const_reference operator [] (difference_type n) const { Chris@16: return *(it_ + n); Chris@16: } Chris@16: Chris@16: // Index Chris@16: /// \brief return the index of the element referenced by the iterator Chris@16: BOOST_UBLAS_INLINE Chris@16: size_type index () const { Chris@16: BOOST_UBLAS_CHECK (it_ >= (*this) ().begin ().it_ && it_ < (*this) ().end ().it_, bad_index ()); Chris@16: return it_ - (*this) ().begin ().it_; Chris@16: } Chris@16: Chris@16: // Assignment Chris@16: BOOST_UBLAS_INLINE Chris@16: /// \brief assign the value of an iterator to the iterator Chris@16: const_iterator &operator = (const const_iterator &it) { Chris@16: container_const_reference::assign (&it ()); Chris@16: it_ = it.it_; Chris@16: return *this; Chris@16: } Chris@16: Chris@16: // Comparison Chris@16: /// \brief compare the value of two itetarors Chris@16: /// \return true if they reference the same element Chris@16: BOOST_UBLAS_INLINE Chris@16: bool operator == (const const_iterator &it) const { Chris@16: BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ()); Chris@16: return it_ == it.it_; Chris@16: } Chris@16: Chris@16: Chris@16: /// \brief compare the value of two iterators Chris@16: /// \return return true if the left-hand-side iterator refers to a value placed before the right-hand-side iterator Chris@16: BOOST_UBLAS_INLINE Chris@16: bool operator < (const const_iterator &it) const { Chris@16: BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ()); Chris@16: return it_ < it.it_; Chris@16: } Chris@16: Chris@16: private: Chris@16: const_subiterator_type it_; Chris@16: Chris@16: friend class iterator; Chris@16: }; Chris@16: #endif Chris@16: Chris@16: /// \brief return an iterator on the first element of the vector Chris@16: BOOST_UBLAS_INLINE Chris@16: const_iterator begin () const { Chris@16: return find (0); Chris@16: } Chris@16: Chris@101: /// \brief return an iterator on the first element of the vector Chris@101: BOOST_UBLAS_INLINE Chris@101: const_iterator cbegin () const { Chris@101: return begin (); Chris@101: } Chris@101: Chris@16: /// \brief return an iterator after the last element of the vector Chris@101: BOOST_UBLAS_INLINE Chris@101: const_iterator end () const { Chris@101: return find (data_.size ()); Chris@101: } Chris@101: Chris@101: /// \brief return an iterator after the last element of the vector Chris@101: BOOST_UBLAS_INLINE Chris@101: const_iterator cend () const { Chris@101: return end (); Chris@101: } Chris@16: Chris@16: #ifndef BOOST_UBLAS_USE_INDEXED_ITERATOR Chris@16: class iterator: Chris@16: public container_reference, Chris@16: public random_access_iterator_base { Chris@16: public: Chris@16: typedef typename vector::difference_type difference_type; Chris@16: typedef typename vector::value_type value_type; Chris@16: typedef typename vector::reference reference; Chris@16: typedef typename vector::pointer pointer; Chris@16: Chris@16: Chris@16: // Construction and destruction Chris@16: BOOST_UBLAS_INLINE Chris@16: iterator (): Chris@16: container_reference (), it_ () {} Chris@16: BOOST_UBLAS_INLINE Chris@16: iterator (self_type &v, const subiterator_type &it): Chris@16: container_reference (v), it_ (it) {} Chris@16: Chris@16: // Arithmetic Chris@16: BOOST_UBLAS_INLINE Chris@16: iterator &operator ++ () { Chris@16: ++ it_; Chris@16: return *this; Chris@16: } Chris@16: BOOST_UBLAS_INLINE Chris@16: iterator &operator -- () { Chris@16: -- it_; Chris@16: return *this; Chris@16: } Chris@16: BOOST_UBLAS_INLINE Chris@16: iterator &operator += (difference_type n) { Chris@16: it_ += n; Chris@16: return *this; Chris@16: } Chris@16: BOOST_UBLAS_INLINE Chris@16: iterator &operator -= (difference_type n) { Chris@16: it_ -= n; Chris@16: return *this; Chris@16: } Chris@16: BOOST_UBLAS_INLINE Chris@16: difference_type operator - (const iterator &it) const { Chris@16: BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ()); Chris@16: return it_ - it.it_; Chris@16: } Chris@16: Chris@16: // Dereference Chris@16: BOOST_UBLAS_INLINE Chris@16: reference operator * () const { Chris@16: BOOST_UBLAS_CHECK (it_ >= (*this) ().begin ().it_ && it_ < (*this) ().end ().it_ , bad_index ()); Chris@16: return *it_; Chris@16: } Chris@16: BOOST_UBLAS_INLINE Chris@16: reference operator [] (difference_type n) const { Chris@16: return *(it_ + n); Chris@16: } Chris@16: Chris@16: // Index Chris@16: BOOST_UBLAS_INLINE Chris@16: size_type index () const { Chris@16: BOOST_UBLAS_CHECK (it_ >= (*this) ().begin ().it_ && it_ < (*this) ().end ().it_ , bad_index ()); Chris@16: return it_ - (*this) ().begin ().it_; Chris@16: } Chris@16: Chris@16: // Assignment Chris@16: BOOST_UBLAS_INLINE Chris@16: iterator &operator = (const iterator &it) { Chris@16: container_reference::assign (&it ()); Chris@16: it_ = it.it_; Chris@16: return *this; Chris@16: } Chris@16: Chris@16: // Comparison Chris@16: BOOST_UBLAS_INLINE Chris@16: bool operator == (const iterator &it) const { Chris@16: BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ()); Chris@16: return it_ == it.it_; Chris@16: } Chris@16: BOOST_UBLAS_INLINE Chris@16: bool operator < (const iterator &it) const { Chris@16: BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ()); Chris@16: return it_ < it.it_; Chris@16: } Chris@16: Chris@16: private: Chris@16: subiterator_type it_; Chris@16: Chris@16: friend class const_iterator; Chris@16: }; Chris@16: #endif Chris@16: Chris@16: /// \brief Return an iterator on the first element of the vector Chris@16: BOOST_UBLAS_INLINE Chris@16: iterator begin () { Chris@16: return find (0); Chris@16: } Chris@16: Chris@16: /// \brief Return an iterator at the end of the vector Chris@16: BOOST_UBLAS_INLINE Chris@16: iterator end () { Chris@16: return find (data_.size ()); Chris@16: } Chris@16: Chris@16: // Reverse iterator Chris@16: typedef reverse_iterator_base const_reverse_iterator; Chris@16: typedef reverse_iterator_base reverse_iterator; Chris@16: Chris@16: /// \brief Return a const reverse iterator before the first element of the reversed vector (i.e. end() of normal vector) Chris@16: BOOST_UBLAS_INLINE Chris@16: const_reverse_iterator rbegin () const { Chris@16: return const_reverse_iterator (end ()); Chris@16: } Chris@16: Chris@101: /// \brief Return a const reverse iterator before the first element of the reversed vector (i.e. end() of normal vector) Chris@101: BOOST_UBLAS_INLINE Chris@101: const_reverse_iterator crbegin () const { Chris@101: return rbegin (); Chris@101: } Chris@101: Chris@16: /// \brief Return a const reverse iterator on the end of the reverse vector (i.e. first element of the normal vector) Chris@16: BOOST_UBLAS_INLINE Chris@16: const_reverse_iterator rend () const { Chris@16: return const_reverse_iterator (begin ()); Chris@16: } Chris@16: Chris@101: /// \brief Return a const reverse iterator on the end of the reverse vector (i.e. first element of the normal vector) Chris@101: BOOST_UBLAS_INLINE Chris@101: const_reverse_iterator crend () const { Chris@101: return rend (); Chris@101: } Chris@101: Chris@16: /// \brief Return a const reverse iterator before the first element of the reversed vector (i.e. end() of normal vector) Chris@16: BOOST_UBLAS_INLINE Chris@16: reverse_iterator rbegin () { Chris@16: return reverse_iterator (end ()); Chris@16: } Chris@16: Chris@16: /// \brief Return a const reverse iterator on the end of the reverse vector (i.e. first element of the normal vector) Chris@16: BOOST_UBLAS_INLINE Chris@16: reverse_iterator rend () { Chris@16: return reverse_iterator (begin ()); Chris@16: } Chris@16: Chris@16: // ------------- Chris@16: // Serialization Chris@16: // ------------- Chris@16: Chris@16: /// Serialize a vector into and archive as defined in Boost Chris@16: /// \param ar Archive object. Can be a flat file, an XML file or any other stream Chris@16: /// \param file_version Optional file version (not yet used) Chris@16: template Chris@16: void serialize(Archive & ar, const unsigned int /* file_version */){ Chris@16: ar & serialization::make_nvp("data",data_); Chris@16: } Chris@16: Chris@16: private: Chris@16: array_type data_; Chris@16: }; Chris@16: Chris@16: Chris@101: #ifdef BOOST_UBLAS_CPP_GE_2011 Chris@101: /** \brief A dense vector of values of type \c T. Chris@101: * Chris@101: * 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 Chris@101: * to the \f$i\f$-th element of the container. A storage type \c A can be specified which defaults to \c std::array. Chris@101: * Elements are constructed by \c A, which need not initialise their value. Chris@101: * Chris@101: * \tparam T type of the objects stored in the vector (like int, double, complex,...) Chris@101: * \tparam A The type of the storage array of the vector. Default is \c std::array. Chris@101: */ Chris@101: template Chris@101: class fixed_vector: Chris@101: public vector_container > { Chris@101: Chris@101: typedef fixed_vector self_type; Chris@101: public: Chris@101: #ifdef BOOST_UBLAS_ENABLE_PROXY_SHORTCUTS Chris@101: using vector_container::operator (); Chris@101: #endif Chris@101: Chris@101: typedef typename A::size_type size_type; Chris@101: typedef typename A::difference_type difference_type; Chris@101: typedef T value_type; Chris@101: typedef typename type_traits::const_reference const_reference; Chris@101: typedef T &reference; Chris@101: typedef T *pointer; Chris@101: typedef const T *const_pointer; Chris@101: typedef A array_type; Chris@101: typedef const vector_reference const_closure_type; Chris@101: typedef vector_reference closure_type; Chris@101: typedef self_type vector_temporary_type; Chris@101: typedef dense_tag storage_category; Chris@101: Chris@101: // Construction and destruction Chris@101: Chris@101: /// \brief Constructor of a fixed_vector Chris@101: BOOST_UBLAS_INLINE Chris@101: fixed_vector (): Chris@101: vector_container (), Chris@101: data_ () {} Chris@101: Chris@101: /// \brief Constructor of a fixed_vector by copying from another container Chris@101: /// This type uses the generic name \c array_type within the vector definition. Chris@101: /// \param data container of type \c A Chris@101: BOOST_UBLAS_INLINE Chris@101: fixed_vector (const array_type &data): Chris@101: vector_container (), Chris@101: data_ (data) {} Chris@101: Chris@101: /// \brief Constructor of a fixed_vector with a unique initial value Chris@101: /// \param init value to assign to each element of the vector Chris@101: BOOST_UBLAS_INLINE Chris@101: fixed_vector (const value_type &init): Chris@101: vector_container (), Chris@101: data_ () { Chris@101: data_.fill( init ); Chris@101: } Chris@101: Chris@101: /// \brief Copy-constructor of a fixed_vector Chris@101: /// \param v is the fixed_vector to be duplicated Chris@101: BOOST_UBLAS_INLINE Chris@101: fixed_vector (const fixed_vector &v): Chris@101: vector_container (), Chris@101: data_ (v.data_) {} Chris@101: Chris@101: /// \brief Copy-constructor of a vector from a vector_expression Chris@101: /// Depending on the vector_expression, this constructor can have the cost of the computations Chris@101: /// of the expression (trivial to say it, but take it must be taken into account in your complexity calculations). Chris@101: /// \param ae the vector_expression which values will be duplicated into the vector Chris@101: template Chris@101: BOOST_UBLAS_INLINE Chris@101: fixed_vector (const vector_expression &ae): Chris@101: vector_container (), Chris@101: data_ ( ) { Chris@101: vector_assign (*this, ae); Chris@101: } Chris@101: Chris@101: /// \brief Construct a fixed_vector from a list of values Chris@101: /// This constructor enables initialization by using any of: Chris@101: /// fixed_vector v = { 1, 2, 3 } or fixed_vector v( {1, 2, 3} ) or fixed_vector v( 1, 2, 3 ) Chris@101: #if defined(BOOST_MSVC) Chris@101: // This may or may not work. Maybe use this for all instead only for MSVC Chris@101: template Chris@101: fixed_vector(U&&... values) : Chris@101: vector_container (), Chris@101: data_{{ std::forward(values)... }} {} Chris@101: #else Chris@101: template Chris@101: fixed_vector(value_type v0, Types... vrest) : Chris@101: vector_container (), Chris@101: data_{ { v0, vrest... } } {} Chris@101: #endif Chris@101: Chris@101: // ----------------------- Chris@101: // Random Access Container Chris@101: // ----------------------- Chris@101: Chris@101: /// \brief Return the maximum size of the data container. Chris@101: /// 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. Chris@101: BOOST_UBLAS_INLINE Chris@101: size_type max_size () const { Chris@101: return data_.max_size (); Chris@101: } Chris@101: Chris@101: /// \brief Return true if the vector is empty (\c size==0) Chris@101: /// \return \c true if empty, \c false otherwise Chris@101: BOOST_UBLAS_INLINE Chris@101: const bool &empty () const { Chris@101: return data_.empty(); Chris@101: } Chris@101: Chris@101: // --------- Chris@101: // Accessors Chris@101: // --------- Chris@101: Chris@101: /// \brief Return the size of the vector Chris@101: BOOST_UBLAS_INLINE Chris@101: BOOST_CONSTEXPR size_type size () const{ // should have a const after C++14 Chris@101: return data_.size (); Chris@101: } Chris@101: Chris@101: // ----------------- Chris@101: // Storage accessors Chris@101: // ----------------- Chris@101: Chris@101: /// \brief Return a \c const reference to the container. Useful to access data directly for specific type of container. Chris@101: BOOST_UBLAS_INLINE Chris@101: const array_type &data () const { Chris@101: return data_; Chris@101: } Chris@101: Chris@101: /// \brief Return a reference to the container. Useful to speed-up write operations to the data in very specific case. Chris@101: BOOST_UBLAS_INLINE Chris@101: array_type &data () { Chris@101: return data_; Chris@101: } Chris@101: Chris@101: // --------------- Chris@101: // Element support Chris@101: // --------------- Chris@101: Chris@101: /// \brief Return a pointer to the element \f$i\f$ Chris@101: /// \param i index of the element Chris@101: // XXX this semantic is not the one expected by the name of this method Chris@101: BOOST_UBLAS_INLINE Chris@101: pointer find_element (size_type i) { Chris@101: return const_cast (const_cast(*this).find_element (i)); Chris@101: } Chris@101: Chris@101: /// \brief Return a const pointer to the element \f$i\f$ Chris@101: /// \param i index of the element Chris@101: // XXX this semantic is not the one expected by the name of this method Chris@101: BOOST_UBLAS_INLINE Chris@101: const_pointer find_element (size_type i) const { Chris@101: BOOST_UBLAS_CHECK (i < data_.size(), bad_index() ); // Since std:array doesn't check for bounds Chris@101: return & (data () [i]); Chris@101: } Chris@101: Chris@101: // -------------- Chris@101: // Element access Chris@101: // -------------- Chris@101: Chris@101: /// \brief Return a const reference to the element \f$i\f$ Chris@101: /// Return a const reference to the element \f$i\f$. With some compilers, this notation will be faster than \c[i] Chris@101: /// \param i index of the element Chris@101: BOOST_UBLAS_INLINE Chris@101: const_reference operator () (size_type i) const { Chris@101: BOOST_UBLAS_CHECK (i < data_.size(), bad_index() ); Chris@101: return data () [i]; Chris@101: } Chris@101: Chris@101: /// \brief Return a reference to the element \f$i\f$ Chris@101: /// Return a reference to the element \f$i\f$. With some compilers, this notation will be faster than \c[i] Chris@101: /// \param i index of the element Chris@101: BOOST_UBLAS_INLINE Chris@101: reference operator () (size_type i) { Chris@101: BOOST_UBLAS_CHECK (i < data_.size(), bad_index() ); Chris@101: return data () [i]; Chris@101: } Chris@101: Chris@101: /// \brief Return a const reference to the element \f$i\f$ Chris@101: /// \param i index of the element Chris@101: BOOST_UBLAS_INLINE Chris@101: const_reference operator [] (size_type i) const { Chris@101: BOOST_UBLAS_CHECK (i < data_.size(), bad_index() ); Chris@101: return (*this) (i); Chris@101: } Chris@101: Chris@101: /// \brief Return a reference to the element \f$i\f$ Chris@101: /// \param i index of the element Chris@101: BOOST_UBLAS_INLINE Chris@101: reference operator [] (size_type i) { Chris@101: BOOST_UBLAS_CHECK (i < data_.size(), bad_index() ); Chris@101: return (*this) (i); Chris@101: } Chris@101: Chris@101: // ------------------ Chris@101: // Element assignment Chris@101: // ------------------ Chris@101: Chris@101: /// \brief Set element \f$i\f$ to the value \c t Chris@101: /// \param i index of the element Chris@101: /// \param t reference to the value to be set Chris@101: // XXX semantic of this is to insert a new element and therefore size=size+1 ? Chris@101: BOOST_UBLAS_INLINE Chris@101: reference insert_element (size_type i, const_reference t) { Chris@101: BOOST_UBLAS_CHECK (i < data_.size(), bad_index ()); Chris@101: return (data () [i] = t); Chris@101: } Chris@101: Chris@101: /// \brief Set element \f$i\f$ to the \e zero value Chris@101: /// \param i index of the element Chris@101: BOOST_UBLAS_INLINE Chris@101: void erase_element (size_type i) { Chris@101: BOOST_UBLAS_CHECK (i < data_.size(), bad_index ()); Chris@101: data () [i] = value_type/*zero*/(); Chris@101: } Chris@101: Chris@101: // ------- Chris@101: // Zeroing Chris@101: // ------- Chris@101: Chris@101: /// \brief Clear the vector, i.e. set all values to the \c zero value. Chris@101: BOOST_UBLAS_INLINE Chris@101: void clear () { Chris@101: std::fill (data ().begin (), data ().end (), value_type/*zero*/()); Chris@101: } Chris@101: Chris@101: // Assignment Chris@101: #ifdef BOOST_UBLAS_MOVE_SEMANTICS Chris@101: Chris@101: /// \brief Assign a full fixed_vector (\e RHS-vector) to the current fixed_vector (\e LHS-vector) Chris@101: /// \param v is the source vector Chris@101: /// \return a reference to a fixed_vector (i.e. the destination vector) Chris@101: /*! @note "pass by value" the key idea to enable move semantics */ Chris@101: BOOST_UBLAS_INLINE Chris@101: fixed_vector &operator = (fixed_vector v) { Chris@101: assign_temporary(v); Chris@101: return *this; Chris@101: } Chris@101: #else Chris@101: /// \brief Assign a full fixed_vector (\e RHS-vector) to the current fixed_vector (\e LHS-vector) Chris@101: /// \param v is the source fixed_vector Chris@101: /// \return a reference to a fixed_vector (i.e. the destination vector) Chris@101: BOOST_UBLAS_INLINE Chris@101: fixed_vector &operator = (const fixed_vector &v) { Chris@101: data () = v.data (); Chris@101: return *this; Chris@101: } Chris@101: #endif Chris@101: Chris@101: /// \brief Assign a full vector (\e RHS-vector) to the current fixed_vector (\e LHS-vector) Chris@101: /// Assign a full vector (\e RHS-vector) to the current fixed_vector (\e LHS-vector). This method does not create any temporary. Chris@101: /// \param v is the source vector container Chris@101: /// \return a reference to a vector (i.e. the destination vector) Chris@101: template // Container assignment without temporary Chris@101: BOOST_UBLAS_INLINE Chris@101: fixed_vector &operator = (const vector_container &v) { Chris@101: assign (v); Chris@101: return *this; Chris@101: } Chris@101: Chris@101: /// \brief Assign a full fixed_vector (\e RHS-vector) to the current fixed_vector (\e LHS-vector) Chris@101: /// \param v is the source fixed_vector Chris@101: /// \return a reference to a fixed_vector (i.e. the destination fixed_vector) Chris@101: BOOST_UBLAS_INLINE Chris@101: fixed_vector &assign_temporary (fixed_vector &v) { Chris@101: swap ( v ); Chris@101: return *this; Chris@101: } Chris@101: Chris@101: /// \brief Assign the result of a vector_expression to the fixed_vector Chris@101: /// 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. Chris@101: /// \tparam AE is the type of the vector_expression Chris@101: /// \param ae is a const reference to the vector_expression Chris@101: /// \return a reference to the resulting fixed_vector Chris@101: template Chris@101: BOOST_UBLAS_INLINE Chris@101: fixed_vector &operator = (const vector_expression &ae) { Chris@101: self_type temporary (ae); Chris@101: return assign_temporary (temporary); Chris@101: } Chris@101: Chris@101: /// \brief Assign the result of a vector_expression to the fixed_vector Chris@101: /// 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. Chris@101: /// \tparam AE is the type of the vector_expression Chris@101: /// \param ae is a const reference to the vector_expression Chris@101: /// \return a reference to the resulting fixed_vector Chris@101: template Chris@101: BOOST_UBLAS_INLINE Chris@101: fixed_vector &assign (const vector_expression &ae) { Chris@101: vector_assign (*this, ae); Chris@101: return *this; Chris@101: } Chris@101: Chris@101: // ------------------- Chris@101: // Computed assignment Chris@101: // ------------------- Chris@101: Chris@101: /// \brief Assign the sum of the fixed_vector and a vector_expression to the fixed_vector Chris@101: /// 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. Chris@101: /// A temporary is created for the computations. Chris@101: /// \tparam AE is the type of the vector_expression Chris@101: /// \param ae is a const reference to the vector_expression Chris@101: /// \return a reference to the resulting fixed_vector Chris@101: template Chris@101: BOOST_UBLAS_INLINE Chris@101: fixed_vector &operator += (const vector_expression &ae) { Chris@101: self_type temporary (*this + ae); Chris@101: return assign_temporary (temporary); Chris@101: } Chris@101: Chris@101: /// \brief Assign the sum of the fixed_vector and a vector_expression to the fixed_vector Chris@101: /// 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. Chris@101: /// No temporary is created. Computations are done and stored directly into the resulting vector. Chris@101: /// \tparam AE is the type of the vector_expression Chris@101: /// \param ae is a const reference to the vector_expression Chris@101: /// \return a reference to the resulting vector Chris@101: template // Container assignment without temporary Chris@101: BOOST_UBLAS_INLINE Chris@101: fixed_vector &operator += (const vector_container &v) { Chris@101: plus_assign (v); Chris@101: return *this; Chris@101: } Chris@101: Chris@101: /// \brief Assign the sum of the fixed_vector and a vector_expression to the fixed_vector Chris@101: /// 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. Chris@101: /// No temporary is created. Computations are done and stored directly into the resulting fixed_vector. Chris@101: /// \tparam AE is the type of the vector_expression Chris@101: /// \param ae is a const reference to the vector_expression Chris@101: /// \return a reference to the resulting vector Chris@101: template Chris@101: BOOST_UBLAS_INLINE Chris@101: fixed_vector &plus_assign (const vector_expression &ae) { Chris@101: vector_assign (*this, ae); Chris@101: return *this; Chris@101: } Chris@101: Chris@101: /// \brief Assign the difference of the fixed_vector and a vector_expression to the fixed_vector Chris@101: /// 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. Chris@101: /// A temporary is created for the computations. Chris@101: /// \tparam AE is the type of the vector_expression Chris@101: /// \param ae is a const reference to the vector_expression Chris@101: template Chris@101: BOOST_UBLAS_INLINE Chris@101: fixed_vector &operator -= (const vector_expression &ae) { Chris@101: self_type temporary (*this - ae); Chris@101: return assign_temporary (temporary); Chris@101: } Chris@101: Chris@101: /// \brief Assign the difference of the fixed_vector and a vector_expression to the fixed_vector Chris@101: /// 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. Chris@101: /// No temporary is created. Computations are done and stored directly into the resulting fixed_vector. Chris@101: /// \tparam AE is the type of the vector_expression Chris@101: /// \param ae is a const reference to the vector_expression Chris@101: /// \return a reference to the resulting vector Chris@101: template // Container assignment without temporary Chris@101: BOOST_UBLAS_INLINE Chris@101: fixed_vector &operator -= (const vector_container &v) { Chris@101: minus_assign (v); Chris@101: return *this; Chris@101: } Chris@101: Chris@101: /// \brief Assign the difference of the fixed_vector and a vector_expression to the fixed_vector Chris@101: /// 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. Chris@101: /// No temporary is created. Computations are done and stored directly into the resulting fixed_vector. Chris@101: /// \tparam AE is the type of the vector_expression Chris@101: /// \param ae is a const reference to the vector_expression Chris@101: /// \return a reference to the resulting fixed_vector Chris@101: template Chris@101: BOOST_UBLAS_INLINE Chris@101: fixed_vector &minus_assign (const vector_expression &ae) { Chris@101: vector_assign (*this, ae); Chris@101: return *this; Chris@101: } Chris@101: Chris@101: /// \brief Assign the product of the fixed_vector and a scalar to the fixed_vector Chris@101: /// 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. Chris@101: /// No temporary is created. Computations are done and stored directly into the resulting fixed_vector. Chris@101: /// \tparam AE is the type of the vector_expression Chris@101: /// \param at is a const reference to the scalar Chris@101: /// \return a reference to the resulting fixed_vector Chris@101: template Chris@101: BOOST_UBLAS_INLINE Chris@101: fixed_vector &operator *= (const AT &at) { Chris@101: vector_assign_scalar (*this, at); Chris@101: return *this; Chris@101: } Chris@101: Chris@101: /// \brief Assign the division of the fixed_vector by a scalar to the fixed_vector Chris@101: /// 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. Chris@101: /// No temporary is created. Computations are done and stored directly into the resulting vector. Chris@101: /// \tparam AE is the type of the vector_expression Chris@101: /// \param at is a const reference to the scalar Chris@101: /// \return a reference to the resulting fixed_vector Chris@101: template Chris@101: BOOST_UBLAS_INLINE Chris@101: fixed_vector &operator /= (const AT &at) { Chris@101: vector_assign_scalar (*this, at); Chris@101: return *this; Chris@101: } Chris@101: Chris@101: // -------- Chris@101: // Swapping Chris@101: // -------- Chris@101: Chris@101: /// \brief Swap the content of the fixed_vector with another vector Chris@101: /// \param v is the fixed_vector to be swapped with Chris@101: BOOST_UBLAS_INLINE Chris@101: void swap (fixed_vector &v) { Chris@101: if (this != &v) { Chris@101: data ().swap (v.data ()); Chris@101: } Chris@101: } Chris@101: Chris@101: /// \brief Swap the content of two fixed_vectors Chris@101: /// \param v1 is the first fixed_vector. It takes values from v2 Chris@101: /// \param v2 is the second fixed_vector It takes values from v1 Chris@101: BOOST_UBLAS_INLINE Chris@101: friend void swap (fixed_vector &v1, fixed_vector &v2) { Chris@101: v1.swap (v2); Chris@101: } Chris@101: Chris@101: // Iterator types Chris@101: private: Chris@101: // Use the storage array iterator Chris@101: typedef typename A::const_iterator const_subiterator_type; Chris@101: typedef typename A::iterator subiterator_type; Chris@101: Chris@101: public: Chris@101: #ifdef BOOST_UBLAS_USE_INDEXED_ITERATOR Chris@101: typedef indexed_iterator iterator; Chris@101: typedef indexed_const_iterator const_iterator; Chris@101: #else Chris@101: class const_iterator; Chris@101: class iterator; Chris@101: #endif Chris@101: Chris@101: // -------------- Chris@101: // Element lookup Chris@101: // -------------- Chris@101: Chris@101: /// \brief Return a const iterator to the element \e i Chris@101: /// \param i index of the element Chris@101: BOOST_UBLAS_INLINE Chris@101: const_iterator find (size_type i) const { Chris@101: #ifndef BOOST_UBLAS_USE_INDEXED_ITERATOR Chris@101: return const_iterator (*this, data ().begin () + i); Chris@101: #else Chris@101: return const_iterator (*this, i); Chris@101: #endif Chris@101: } Chris@101: Chris@101: /// \brief Return an iterator to the element \e i Chris@101: /// \param i index of the element Chris@101: BOOST_UBLAS_INLINE Chris@101: iterator find (size_type i) { Chris@101: #ifndef BOOST_UBLAS_USE_INDEXED_ITERATOR Chris@101: return iterator (*this, data ().begin () + i); Chris@101: #else Chris@101: return iterator (*this, i); Chris@101: #endif Chris@101: } Chris@101: Chris@101: #ifndef BOOST_UBLAS_USE_INDEXED_ITERATOR Chris@101: class const_iterator: Chris@101: public container_const_reference, Chris@101: public random_access_iterator_base { Chris@101: public: Chris@101: typedef typename fixed_vector::difference_type difference_type; Chris@101: typedef typename fixed_vector::value_type value_type; Chris@101: typedef typename fixed_vector::const_reference reference; Chris@101: typedef const typename fixed_vector::pointer pointer; Chris@101: Chris@101: // ---------------------------- Chris@101: // Construction and destruction Chris@101: // ---------------------------- Chris@101: Chris@101: Chris@101: BOOST_UBLAS_INLINE Chris@101: const_iterator (): Chris@101: container_const_reference (), it_ () {} Chris@101: BOOST_UBLAS_INLINE Chris@101: const_iterator (const self_type &v, const const_subiterator_type &it): Chris@101: container_const_reference (v), it_ (it) {} Chris@101: BOOST_UBLAS_INLINE Chris@101: const_iterator (const typename self_type::iterator &it): // ISSUE vector:: stops VC8 using std::iterator here Chris@101: container_const_reference (it ()), it_ (it.it_) {} Chris@101: Chris@101: // ---------- Chris@101: // Arithmetic Chris@101: // ---------- Chris@101: Chris@101: /// \brief Increment by 1 the position of the iterator Chris@101: /// \return a reference to the const iterator Chris@101: BOOST_UBLAS_INLINE Chris@101: const_iterator &operator ++ () { Chris@101: ++ it_; Chris@101: return *this; Chris@101: } Chris@101: Chris@101: /// \brief Decrement by 1 the position of the iterator Chris@101: /// \return a reference to the const iterator Chris@101: BOOST_UBLAS_INLINE Chris@101: const_iterator &operator -- () { Chris@101: -- it_; Chris@101: return *this; Chris@101: } Chris@101: Chris@101: /// \brief Increment by \e n the position of the iterator Chris@101: /// \return a reference to the const iterator Chris@101: BOOST_UBLAS_INLINE Chris@101: const_iterator &operator += (difference_type n) { Chris@101: it_ += n; Chris@101: return *this; Chris@101: } Chris@101: Chris@101: /// \brief Decrement by \e n the position of the iterator Chris@101: /// \return a reference to the const iterator Chris@101: BOOST_UBLAS_INLINE Chris@101: const_iterator &operator -= (difference_type n) { Chris@101: it_ -= n; Chris@101: return *this; Chris@101: } Chris@101: Chris@101: /// \brief Return the different in number of positions between 2 iterators Chris@101: BOOST_UBLAS_INLINE Chris@101: difference_type operator - (const const_iterator &it) const { Chris@101: BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ()); Chris@101: return it_ - it.it_; Chris@101: } Chris@101: Chris@101: /// \brief Dereference an iterator Chris@101: /// Dereference an iterator: a bounds' check is done before returning the value. A bad_index() expection is returned if out of bounds. Chris@101: /// \return a const reference to the value pointed by the iterator Chris@101: BOOST_UBLAS_INLINE Chris@101: const_reference operator * () const { Chris@101: BOOST_UBLAS_CHECK (it_ >= (*this) ().begin ().it_ && it_ < (*this) ().end ().it_, bad_index ()); Chris@101: return *it_; Chris@101: } Chris@101: Chris@101: /// \brief Dereference an iterator at the n-th forward value Chris@101: /// Dereference an iterator at the n-th forward value, that is the value pointed by iterator+n. Chris@101: /// A bounds' check is done before returning the value. A bad_index() expection is returned if out of bounds. Chris@101: /// \return a const reference Chris@101: BOOST_UBLAS_INLINE Chris@101: const_reference operator [] (difference_type n) const { Chris@101: return *(it_ + n); Chris@101: } Chris@101: Chris@101: // Index Chris@101: /// \brief return the index of the element referenced by the iterator Chris@101: BOOST_UBLAS_INLINE Chris@101: size_type index () const { Chris@101: BOOST_UBLAS_CHECK (it_ >= (*this) ().begin ().it_ && it_ < (*this) ().end ().it_, bad_index ()); Chris@101: return it_ - (*this) ().begin ().it_; Chris@101: } Chris@101: Chris@101: // Assignment Chris@101: BOOST_UBLAS_INLINE Chris@101: /// \brief assign the value of an iterator to the iterator Chris@101: const_iterator &operator = (const const_iterator &it) { Chris@101: container_const_reference::assign (&it ()); Chris@101: it_ = it.it_; Chris@101: return *this; Chris@101: } Chris@101: Chris@101: // Comparison Chris@101: /// \brief compare the value of two itetarors Chris@101: /// \return true if they reference the same element Chris@101: BOOST_UBLAS_INLINE Chris@101: bool operator == (const const_iterator &it) const { Chris@101: BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ()); Chris@101: return it_ == it.it_; Chris@101: } Chris@101: Chris@101: Chris@101: /// \brief compare the value of two iterators Chris@101: /// \return return true if the left-hand-side iterator refers to a value placed before the right-hand-side iterator Chris@101: BOOST_UBLAS_INLINE Chris@101: bool operator < (const const_iterator &it) const { Chris@101: BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ()); Chris@101: return it_ < it.it_; Chris@101: } Chris@101: Chris@101: private: Chris@101: const_subiterator_type it_; Chris@101: Chris@101: friend class iterator; Chris@101: }; Chris@101: #endif Chris@101: Chris@101: /// \brief return an iterator on the first element of the fixed_vector Chris@101: BOOST_UBLAS_INLINE Chris@101: const_iterator begin () const { Chris@101: return find (0); Chris@101: } Chris@101: Chris@101: /// \brief return an iterator on the first element of the fixed_vector Chris@101: BOOST_UBLAS_INLINE Chris@101: const_iterator cbegin () const { Chris@101: return begin (); Chris@101: } Chris@101: Chris@101: /// \brief return an iterator after the last element of the fixed_vector Chris@101: BOOST_UBLAS_INLINE Chris@101: const_iterator end () const { Chris@101: return find (data_.size ()); Chris@101: } Chris@101: Chris@101: /// \brief return an iterator after the last element of the fixed_vector Chris@101: BOOST_UBLAS_INLINE Chris@101: const_iterator cend () const { Chris@101: return end (); Chris@101: } Chris@101: Chris@101: #ifndef BOOST_UBLAS_USE_INDEXED_ITERATOR Chris@101: class iterator: Chris@101: public container_reference, Chris@101: public random_access_iterator_base { Chris@101: public: Chris@101: typedef typename fixed_vector::difference_type difference_type; Chris@101: typedef typename fixed_vector::value_type value_type; Chris@101: typedef typename fixed_vector::reference reference; Chris@101: typedef typename fixed_vector::pointer pointer; Chris@101: Chris@101: Chris@101: // Construction and destruction Chris@101: BOOST_UBLAS_INLINE Chris@101: iterator (): Chris@101: container_reference (), it_ () {} Chris@101: BOOST_UBLAS_INLINE Chris@101: iterator (self_type &v, const subiterator_type &it): Chris@101: container_reference (v), it_ (it) {} Chris@101: Chris@101: // Arithmetic Chris@101: BOOST_UBLAS_INLINE Chris@101: iterator &operator ++ () { Chris@101: ++ it_; Chris@101: return *this; Chris@101: } Chris@101: BOOST_UBLAS_INLINE Chris@101: iterator &operator -- () { Chris@101: -- it_; Chris@101: return *this; Chris@101: } Chris@101: BOOST_UBLAS_INLINE Chris@101: iterator &operator += (difference_type n) { Chris@101: it_ += n; Chris@101: return *this; Chris@101: } Chris@101: BOOST_UBLAS_INLINE Chris@101: iterator &operator -= (difference_type n) { Chris@101: it_ -= n; Chris@101: return *this; Chris@101: } Chris@101: BOOST_UBLAS_INLINE Chris@101: difference_type operator - (const iterator &it) const { Chris@101: BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ()); Chris@101: return it_ - it.it_; Chris@101: } Chris@101: Chris@101: // Dereference Chris@101: BOOST_UBLAS_INLINE Chris@101: reference operator * () const { Chris@101: BOOST_UBLAS_CHECK (it_ >= (*this) ().begin ().it_ && it_ < (*this) ().end ().it_ , bad_index ()); Chris@101: return *it_; Chris@101: } Chris@101: BOOST_UBLAS_INLINE Chris@101: reference operator [] (difference_type n) const { Chris@101: return *(it_ + n); Chris@101: } Chris@101: Chris@101: // Index Chris@101: BOOST_UBLAS_INLINE Chris@101: size_type index () const { Chris@101: BOOST_UBLAS_CHECK (it_ >= (*this) ().begin ().it_ && it_ < (*this) ().end ().it_ , bad_index ()); Chris@101: return it_ - (*this) ().begin ().it_; Chris@101: } Chris@101: Chris@101: // Assignment Chris@101: BOOST_UBLAS_INLINE Chris@101: iterator &operator = (const iterator &it) { Chris@101: container_reference::assign (&it ()); Chris@101: it_ = it.it_; Chris@101: return *this; Chris@101: } Chris@101: Chris@101: // Comparison Chris@101: BOOST_UBLAS_INLINE Chris@101: bool operator == (const iterator &it) const { Chris@101: BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ()); Chris@101: return it_ == it.it_; Chris@101: } Chris@101: BOOST_UBLAS_INLINE Chris@101: bool operator < (const iterator &it) const { Chris@101: BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ()); Chris@101: return it_ < it.it_; Chris@101: } Chris@101: Chris@101: private: Chris@101: subiterator_type it_; Chris@101: Chris@101: friend class const_iterator; Chris@101: }; Chris@101: #endif Chris@101: Chris@101: /// \brief Return an iterator on the first element of the fixed_vector Chris@101: BOOST_UBLAS_INLINE Chris@101: iterator begin () { Chris@101: return find (0); Chris@101: } Chris@101: Chris@101: /// \brief Return an iterator at the end of the fixed_vector Chris@101: BOOST_UBLAS_INLINE Chris@101: iterator end () { Chris@101: return find (data_.size ()); Chris@101: } Chris@101: Chris@101: // Reverse iterator Chris@101: typedef reverse_iterator_base const_reverse_iterator; Chris@101: typedef reverse_iterator_base reverse_iterator; Chris@101: Chris@101: /// \brief Return a const reverse iterator before the first element of the reversed fixed_vector (i.e. end() of normal fixed_vector) Chris@101: BOOST_UBLAS_INLINE Chris@101: const_reverse_iterator rbegin () const { Chris@101: return const_reverse_iterator (end ()); Chris@101: } Chris@101: Chris@101: /// \brief Return a const reverse iterator before the first element of the reversed fixed_vector (i.e. end() of normal fixed_vector) Chris@101: BOOST_UBLAS_INLINE Chris@101: const_reverse_iterator crbegin () const { Chris@101: return rbegin (); Chris@101: } Chris@101: Chris@101: /// \brief Return a const reverse iterator on the end of the reverse fixed_vector (i.e. first element of the normal fixed_vector) Chris@101: BOOST_UBLAS_INLINE Chris@101: const_reverse_iterator rend () const { Chris@101: return const_reverse_iterator (begin ()); Chris@101: } Chris@101: Chris@101: /// \brief Return a const reverse iterator on the end of the reverse fixed_vector (i.e. first element of the normal fixed_vector) Chris@101: BOOST_UBLAS_INLINE Chris@101: const_reverse_iterator crend () const { Chris@101: return rend (); Chris@101: } Chris@101: Chris@101: /// \brief Return a const reverse iterator before the first element of the reversed fixed_vector (i.e. end() of normal fixed_vector) Chris@101: BOOST_UBLAS_INLINE Chris@101: reverse_iterator rbegin () { Chris@101: return reverse_iterator (end ()); Chris@101: } Chris@101: Chris@101: /// \brief Return a const reverse iterator on the end of the reverse fixed_vector (i.e. first element of the normal fixed_vector) Chris@101: BOOST_UBLAS_INLINE Chris@101: reverse_iterator rend () { Chris@101: return reverse_iterator (begin ()); Chris@101: } Chris@101: Chris@101: // ------------- Chris@101: // Serialization Chris@101: // ------------- Chris@101: Chris@101: /// Serialize a fixed_vector into and archive as defined in Boost Chris@101: /// \param ar Archive object. Can be a flat file, an XML file or any other stream Chris@101: /// \param file_version Optional file version (not yet used) Chris@101: template Chris@101: void serialize(Archive & ar, const unsigned int /* file_version */){ Chris@101: ar & serialization::make_nvp("data",data_); Chris@101: } Chris@101: Chris@101: private: Chris@101: array_type data_; Chris@101: }; Chris@101: Chris@101: #endif // BOOST_UBLAS_CPP_GE_2011 Chris@101: Chris@16: // -------------------- Chris@16: // Bounded vector class Chris@16: // -------------------- Chris@16: Chris@16: /// \brief a dense vector of values of type \c T, of variable size but with maximum \f$N\f$. Chris@16: /// A dense vector of values of type \c T, of variable size but with maximum \f$N\f$. The default constructor Chris@16: /// 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. Chris@16: template Chris@16: class bounded_vector: Chris@16: public vector > { Chris@16: Chris@16: typedef vector > vector_type; Chris@16: public: Chris@16: typedef typename vector_type::size_type size_type; Chris@16: static const size_type max_size = N; Chris@16: Chris@16: // Construction and destruction Chris@16: BOOST_UBLAS_INLINE Chris@16: bounded_vector (): Chris@16: vector_type (N) {} Chris@16: BOOST_UBLAS_INLINE Chris@16: bounded_vector (size_type size): Chris@16: vector_type (size) {} Chris@16: BOOST_UBLAS_INLINE Chris@16: bounded_vector (const bounded_vector &v): Chris@16: vector_type (v) {} Chris@16: template // Allow vector construction Chris@16: BOOST_UBLAS_INLINE Chris@16: bounded_vector (const vector &v): Chris@16: vector_type (v) {} Chris@16: template Chris@16: BOOST_UBLAS_INLINE Chris@16: bounded_vector (const vector_expression &ae): Chris@16: vector_type (ae) {} Chris@16: BOOST_UBLAS_INLINE Chris@16: ~bounded_vector () {} Chris@16: Chris@16: // Assignment Chris@16: #ifdef BOOST_UBLAS_MOVE_SEMANTICS Chris@16: Chris@16: /*! @note "pass by value" the key idea to enable move semantics */ Chris@16: BOOST_UBLAS_INLINE Chris@16: bounded_vector &operator = (bounded_vector v) { Chris@16: vector_type::operator = (v); Chris@16: return *this; Chris@16: } Chris@16: #else Chris@16: BOOST_UBLAS_INLINE Chris@16: bounded_vector &operator = (const bounded_vector &v) { Chris@16: vector_type::operator = (v); Chris@16: return *this; Chris@16: } Chris@16: #endif Chris@16: template // Generic vector assignment Chris@16: BOOST_UBLAS_INLINE Chris@16: bounded_vector &operator = (const vector &v) { Chris@16: vector_type::operator = (v); Chris@16: return *this; Chris@16: } Chris@16: template // Container assignment without temporary Chris@16: BOOST_UBLAS_INLINE Chris@16: bounded_vector &operator = (const vector_container &v) { Chris@16: vector_type::operator = (v); Chris@16: return *this; Chris@16: } Chris@16: template Chris@16: BOOST_UBLAS_INLINE Chris@16: bounded_vector &operator = (const vector_expression &ae) { Chris@16: vector_type::operator = (ae); Chris@16: return *this; Chris@16: } Chris@16: }; Chris@16: Chris@16: Chris@101: Chris@16: // ----------------- Chris@16: // Zero vector class Chris@16: // ----------------- Chris@16: Chris@16: /// \brief A zero vector of type \c T and a given \c size Chris@16: /// 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 Chris@16: /// for storing the zero values: it still acts like any other vector. However assigning values to it will not change the zero Chris@16: /// vector into a normal vector. It must first be assigned to another normal vector by any suitable means. Its memory footprint is constant. Chris@16: template Chris@16: class zero_vector: Chris@16: public vector_container > { Chris@16: Chris@16: typedef const T *const_pointer; Chris@16: typedef zero_vector self_type; Chris@16: public: Chris@16: #ifdef BOOST_UBLAS_ENABLE_PROXY_SHORTCUTS Chris@16: using vector_container::operator (); Chris@16: #endif Chris@16: typedef typename ALLOC::size_type size_type; Chris@16: typedef typename ALLOC::difference_type difference_type; Chris@16: typedef T value_type; Chris@16: typedef const T &const_reference; Chris@16: typedef T &reference; Chris@16: typedef const vector_reference const_closure_type; Chris@16: typedef vector_reference closure_type; Chris@16: typedef sparse_tag storage_category; Chris@16: Chris@16: // Construction and destruction Chris@16: BOOST_UBLAS_INLINE Chris@16: zero_vector (): Chris@16: vector_container (), Chris@16: size_ (0) {} Chris@16: explicit BOOST_UBLAS_INLINE Chris@16: zero_vector (size_type size): Chris@16: vector_container (), Chris@16: size_ (size) {} Chris@16: BOOST_UBLAS_INLINE Chris@16: zero_vector (const zero_vector &v): Chris@16: vector_container (), Chris@16: size_ (v.size_) {} Chris@16: Chris@16: // Accessors Chris@16: BOOST_UBLAS_INLINE Chris@16: size_type size () const { Chris@16: return size_; Chris@16: } Chris@16: Chris@16: // Resizing Chris@16: BOOST_UBLAS_INLINE Chris@16: void resize (size_type size, bool /*preserve*/ = true) { Chris@16: size_ = size; Chris@16: } Chris@16: Chris@16: // Element support Chris@16: BOOST_UBLAS_INLINE Chris@101: const_pointer find_element (size_type /*i*/) const { Chris@16: return & zero_; Chris@16: } Chris@16: Chris@16: // Element access Chris@16: BOOST_UBLAS_INLINE Chris@16: const_reference operator () (size_type /* i */) const { Chris@16: return zero_; Chris@16: } Chris@16: Chris@16: BOOST_UBLAS_INLINE Chris@16: const_reference operator [] (size_type i) const { Chris@16: return (*this) (i); Chris@16: } Chris@16: Chris@16: // Assignment Chris@16: BOOST_UBLAS_INLINE Chris@16: zero_vector &operator = (const zero_vector &v) { Chris@16: size_ = v.size_; Chris@16: return *this; Chris@16: } Chris@16: BOOST_UBLAS_INLINE Chris@16: zero_vector &assign_temporary (zero_vector &v) { Chris@16: swap (v); Chris@16: return *this; Chris@16: } Chris@16: Chris@16: // Swapping Chris@16: BOOST_UBLAS_INLINE Chris@16: void swap (zero_vector &v) { Chris@16: if (this != &v) { Chris@16: std::swap (size_, v.size_); Chris@16: } Chris@16: } Chris@16: BOOST_UBLAS_INLINE Chris@16: friend void swap (zero_vector &v1, zero_vector &v2) { Chris@16: v1.swap (v2); Chris@16: } Chris@16: Chris@16: // Iterator types Chris@16: public: Chris@16: class const_iterator; Chris@16: Chris@16: // Element lookup Chris@16: BOOST_UBLAS_INLINE Chris@16: const_iterator find (size_type /*i*/) const { Chris@16: return const_iterator (*this); Chris@16: } Chris@16: Chris@16: class const_iterator: Chris@16: public container_const_reference, Chris@16: public bidirectional_iterator_base { Chris@16: public: Chris@16: typedef typename zero_vector::difference_type difference_type; Chris@16: typedef typename zero_vector::value_type value_type; Chris@16: typedef typename zero_vector::const_reference reference; Chris@16: typedef typename zero_vector::const_pointer pointer; Chris@16: Chris@16: // Construction and destruction Chris@16: BOOST_UBLAS_INLINE Chris@16: const_iterator (): Chris@16: container_const_reference () {} Chris@16: BOOST_UBLAS_INLINE Chris@16: const_iterator (const self_type &v): Chris@16: container_const_reference (v) {} Chris@16: Chris@16: // Arithmetic Chris@16: BOOST_UBLAS_INLINE Chris@16: const_iterator &operator ++ () { Chris@16: BOOST_UBLAS_CHECK_FALSE (bad_index ()); Chris@16: return *this; Chris@16: } Chris@16: BOOST_UBLAS_INLINE Chris@16: const_iterator &operator -- () { Chris@16: BOOST_UBLAS_CHECK_FALSE (bad_index ()); Chris@16: return *this; Chris@16: } Chris@16: Chris@16: // Dereference Chris@16: BOOST_UBLAS_INLINE Chris@16: const_reference operator * () const { Chris@16: BOOST_UBLAS_CHECK_FALSE (bad_index ()); Chris@16: return zero_; // arbitary return value Chris@16: } Chris@16: Chris@16: // Index Chris@16: BOOST_UBLAS_INLINE Chris@16: size_type index () const { Chris@16: BOOST_UBLAS_CHECK_FALSE (bad_index ()); Chris@16: return 0; // arbitary return value Chris@16: } Chris@16: Chris@16: // Assignment Chris@16: BOOST_UBLAS_INLINE Chris@16: const_iterator &operator = (const const_iterator &it) { Chris@16: container_const_reference::assign (&it ()); Chris@16: return *this; Chris@16: } Chris@16: Chris@16: // Comparison Chris@16: BOOST_UBLAS_INLINE Chris@16: bool operator == (const const_iterator &it) const { Chris@16: BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ()); Chris@16: detail::ignore_unused_variable_warning(it); Chris@16: return true; Chris@16: } Chris@16: }; Chris@16: Chris@16: typedef const_iterator iterator; Chris@16: Chris@16: BOOST_UBLAS_INLINE Chris@16: const_iterator begin () const { Chris@16: return const_iterator (*this); Chris@16: } Chris@101: BOOST_UBLAS_INLINE Chris@101: const_iterator cbegin () const { Chris@101: return begin (); Chris@101: } Chris@16: BOOST_UBLAS_INLINE Chris@16: const_iterator end () const { Chris@16: return const_iterator (*this); Chris@16: } Chris@101: BOOST_UBLAS_INLINE Chris@101: const_iterator cend () const { Chris@101: return end (); Chris@101: } Chris@16: Chris@16: // Reverse iterator Chris@16: typedef reverse_iterator_base const_reverse_iterator; Chris@16: Chris@16: BOOST_UBLAS_INLINE Chris@16: const_reverse_iterator rbegin () const { Chris@16: return const_reverse_iterator (end ()); Chris@16: } Chris@101: BOOST_UBLAS_INLINE Chris@101: const_reverse_iterator crbegin () const { Chris@101: return rbegin (); Chris@101: } Chris@16: BOOST_UBLAS_INLINE Chris@16: const_reverse_iterator rend () const { Chris@16: return const_reverse_iterator (begin ()); Chris@16: } Chris@101: BOOST_UBLAS_INLINE Chris@101: const_reverse_iterator crend () const { Chris@101: return rend (); Chris@101: } Chris@16: Chris@16: // Serialization Chris@16: template Chris@16: void serialize(Archive & ar, const unsigned int /* file_version */){ Chris@16: serialization::collection_size_type s (size_); Chris@16: ar & serialization::make_nvp("size",s); Chris@16: if (Archive::is_loading::value) { Chris@16: size_ = s; Chris@16: } Chris@16: } Chris@16: Chris@16: private: Chris@16: size_type size_; Chris@16: typedef const value_type const_value_type; Chris@16: static const_value_type zero_; Chris@16: }; Chris@16: Chris@16: template Chris@16: typename zero_vector::const_value_type zero_vector::zero_ = T(/*zero*/); Chris@16: Chris@16: Chris@16: // Unit vector class Chris@16: /// \brief unit_vector represents a canonical unit vector Chris@16: /// 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$. Chris@16: /// At construction, the value \e k is given after the dimension of the vector. Chris@16: /// \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. Chris@16: /// \tparam ALLOC a specific allocator can be specified if needed. Most of the time this parameter is omited. Chris@16: template Chris@16: class unit_vector: Chris@16: public vector_container > { Chris@16: Chris@16: typedef const T *const_pointer; Chris@16: typedef unit_vector self_type; Chris@16: public: Chris@16: #ifdef BOOST_UBLAS_ENABLE_PROXY_SHORTCUTS Chris@16: using vector_container::operator (); Chris@16: #endif Chris@16: typedef typename ALLOC::size_type size_type; Chris@16: typedef typename ALLOC::difference_type difference_type; Chris@16: typedef T value_type; Chris@16: typedef const T &const_reference; Chris@16: typedef T &reference; Chris@16: typedef const vector_reference const_closure_type; Chris@16: typedef vector_reference closure_type; Chris@16: typedef sparse_tag storage_category; Chris@16: Chris@16: // Construction and destruction Chris@16: /// \brief Simple constructor with dimension and index 0 Chris@16: BOOST_UBLAS_INLINE Chris@16: unit_vector (): Chris@16: vector_container (), Chris@16: size_ (0), index_ (0) {} Chris@16: Chris@16: /// \brief Constructor of unit_vector Chris@16: /// \param size is the dimension of the vector Chris@16: /// \param index is the order of the vector Chris@16: BOOST_UBLAS_INLINE Chris@16: explicit unit_vector (size_type size, size_type index = 0): Chris@16: vector_container (), Chris@16: size_ (size), index_ (index) {} Chris@16: Chris@16: /// \brief Copy-constructor Chris@16: BOOST_UBLAS_INLINE Chris@16: unit_vector (const unit_vector &v): Chris@16: vector_container (), Chris@16: size_ (v.size_), index_ (v.index_) {} Chris@16: Chris@16: // Accessors Chris@16: //---------- Chris@16: Chris@16: /// \brief Return the size (dimension) of the vector Chris@16: BOOST_UBLAS_INLINE Chris@16: size_type size () const { Chris@16: return size_; Chris@16: } Chris@16: Chris@16: /// \brief Return the order of the unit vector Chris@16: BOOST_UBLAS_INLINE Chris@16: size_type index () const { Chris@16: return index_; Chris@16: } Chris@16: Chris@16: // Resizing Chris@16: // -------- Chris@16: Chris@16: /// \brief Resize the vector. The values are preserved by default (i.e. the index does not change) Chris@16: /// \param size is the new size of the vector Chris@16: BOOST_UBLAS_INLINE Chris@16: void resize (size_type size, bool /*preserve*/ = true) { Chris@16: size_ = size; Chris@16: } Chris@16: Chris@16: // Element support Chris@16: // --------------- Chris@16: Chris@16: /// \brief Return a const pointer to the element of index i Chris@16: BOOST_UBLAS_INLINE Chris@16: const_pointer find_element (size_type i) const { Chris@16: if (i == index_) Chris@16: return & one_; Chris@16: else Chris@16: return & zero_; Chris@16: } Chris@16: Chris@16: // Element access Chris@16: BOOST_UBLAS_INLINE Chris@16: const_reference operator () (size_type i) const { Chris@16: if (i == index_) Chris@16: return one_; Chris@16: else Chris@16: return zero_; Chris@16: } Chris@16: Chris@16: BOOST_UBLAS_INLINE Chris@16: const_reference operator [] (size_type i) const { Chris@16: return (*this) (i); Chris@16: } Chris@16: Chris@16: // Assignment Chris@16: BOOST_UBLAS_INLINE Chris@16: unit_vector &operator = (const unit_vector &v) { Chris@16: size_ = v.size_; Chris@16: index_ = v.index_; Chris@16: return *this; Chris@16: } Chris@16: BOOST_UBLAS_INLINE Chris@16: unit_vector &assign_temporary (unit_vector &v) { Chris@16: swap (v); Chris@16: return *this; Chris@16: } Chris@16: Chris@16: // Swapping Chris@16: BOOST_UBLAS_INLINE Chris@16: void swap (unit_vector &v) { Chris@16: if (this != &v) { Chris@16: std::swap (size_, v.size_); Chris@16: std::swap (index_, v.index_); Chris@16: } Chris@16: } Chris@16: BOOST_UBLAS_INLINE Chris@16: friend void swap (unit_vector &v1, unit_vector &v2) { Chris@16: v1.swap (v2); Chris@16: } Chris@16: Chris@16: // Iterator types Chris@16: private: Chris@16: // Use bool to indicate begin (one_ as value) Chris@16: typedef bool const_subiterator_type; Chris@16: public: Chris@16: class const_iterator; Chris@16: Chris@16: // Element lookup Chris@16: BOOST_UBLAS_INLINE Chris@16: const_iterator find (size_type i) const { Chris@16: return const_iterator (*this, i <= index_); Chris@16: } Chris@16: Chris@16: class const_iterator: Chris@16: public container_const_reference, Chris@16: public bidirectional_iterator_base { Chris@16: public: Chris@16: typedef typename unit_vector::difference_type difference_type; Chris@16: typedef typename unit_vector::value_type value_type; Chris@16: typedef typename unit_vector::const_reference reference; Chris@16: typedef typename unit_vector::const_pointer pointer; Chris@16: Chris@16: // Construction and destruction Chris@16: BOOST_UBLAS_INLINE Chris@16: const_iterator (): Chris@16: container_const_reference (), it_ () {} Chris@16: BOOST_UBLAS_INLINE Chris@16: const_iterator (const unit_vector &v, const const_subiterator_type &it): Chris@16: container_const_reference (v), it_ (it) {} Chris@16: Chris@16: // Arithmetic Chris@16: BOOST_UBLAS_INLINE Chris@16: const_iterator &operator ++ () { Chris@16: BOOST_UBLAS_CHECK (it_, bad_index ()); Chris@16: it_ = !it_; Chris@16: return *this; Chris@16: } Chris@16: BOOST_UBLAS_INLINE Chris@16: const_iterator &operator -- () { Chris@16: BOOST_UBLAS_CHECK (!it_, bad_index ()); Chris@16: it_ = !it_; Chris@16: return *this; Chris@16: } Chris@16: Chris@16: // Dereference Chris@16: BOOST_UBLAS_INLINE Chris@16: const_reference operator * () const { Chris@16: BOOST_UBLAS_CHECK (it_, bad_index ()); Chris@16: return one_; Chris@16: } Chris@16: Chris@16: // Index Chris@16: BOOST_UBLAS_INLINE Chris@16: size_type index () const { Chris@16: BOOST_UBLAS_CHECK (it_, bad_index ()); Chris@16: return (*this) ().index_; Chris@16: } Chris@16: Chris@16: // Assignment Chris@16: BOOST_UBLAS_INLINE Chris@16: const_iterator &operator = (const const_iterator &it) { Chris@16: container_const_reference::assign (&it ()); Chris@16: it_ = it.it_; Chris@16: return *this; Chris@16: } Chris@16: Chris@16: // Comparison Chris@16: BOOST_UBLAS_INLINE Chris@16: bool operator == (const const_iterator &it) const { Chris@16: BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ()); Chris@16: return it_ == it.it_; Chris@16: } Chris@16: Chris@16: private: Chris@16: const_subiterator_type it_; Chris@16: }; Chris@16: Chris@16: typedef const_iterator iterator; Chris@16: Chris@16: BOOST_UBLAS_INLINE Chris@16: const_iterator begin () const { Chris@16: return const_iterator (*this, true); Chris@16: } Chris@101: BOOST_UBLAS_INLINE Chris@101: const_iterator cbegin () const { Chris@101: return begin (); Chris@101: } Chris@16: BOOST_UBLAS_INLINE Chris@16: const_iterator end () const { Chris@16: return const_iterator (*this, false); Chris@16: } Chris@101: BOOST_UBLAS_INLINE Chris@101: const_iterator cend () const { Chris@101: return end (); Chris@101: } Chris@16: Chris@16: // Reverse iterator Chris@16: typedef reverse_iterator_base const_reverse_iterator; Chris@16: Chris@16: BOOST_UBLAS_INLINE Chris@16: const_reverse_iterator rbegin () const { Chris@16: return const_reverse_iterator (end ()); Chris@16: } Chris@101: BOOST_UBLAS_INLINE Chris@101: const_reverse_iterator crbegin () const { Chris@101: return rbegin (); Chris@101: } Chris@16: BOOST_UBLAS_INLINE Chris@16: const_reverse_iterator rend () const { Chris@16: return const_reverse_iterator (begin ()); Chris@16: } Chris@101: BOOST_UBLAS_INLINE Chris@101: const_reverse_iterator crend () const { Chris@101: return rend (); Chris@101: } Chris@16: Chris@16: // Serialization Chris@16: template Chris@16: void serialize(Archive & ar, const unsigned int /* file_version */){ Chris@16: serialization::collection_size_type s (size_); Chris@16: ar & serialization::make_nvp("size",s); Chris@16: if (Archive::is_loading::value) { Chris@16: size_ = s; Chris@16: } Chris@16: ar & serialization::make_nvp("index", index_); Chris@16: } Chris@16: Chris@16: private: Chris@16: size_type size_; Chris@16: size_type index_; Chris@16: typedef const value_type const_value_type; Chris@16: static const_value_type zero_; Chris@16: static const_value_type one_; Chris@16: }; Chris@16: Chris@16: template Chris@16: typename unit_vector::const_value_type unit_vector::zero_ = T(/*zero*/); Chris@16: template Chris@16: typename unit_vector::const_value_type unit_vector::one_ (1); // ISSUE: need 'one'-traits here Chris@16: Chris@16: /// \brief A scalar (i.e. unique value) vector of type \c T and a given \c size Chris@16: /// 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 Chris@16: /// 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. Chris@16: /// vector into a normal vector. It must first be assigned to another normal vector by any suitable means. Its memory footprint is constant. Chris@16: /// \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. Chris@16: template Chris@16: class scalar_vector: Chris@16: public vector_container > { Chris@16: Chris@16: typedef const T *const_pointer; Chris@16: typedef scalar_vector self_type; Chris@16: public: Chris@16: #ifdef BOOST_UBLAS_ENABLE_PROXY_SHORTCUTS Chris@16: using vector_container::operator (); Chris@16: #endif Chris@16: typedef typename ALLOC::size_type size_type; Chris@16: typedef typename ALLOC::difference_type difference_type; Chris@16: typedef T value_type; Chris@16: typedef const T &const_reference; Chris@16: typedef T &reference; Chris@16: typedef const vector_reference const_closure_type; Chris@16: typedef vector_reference closure_type; Chris@16: typedef dense_tag storage_category; Chris@16: Chris@16: // Construction and destruction Chris@16: BOOST_UBLAS_INLINE Chris@16: scalar_vector (): Chris@16: vector_container (), Chris@16: size_ (0), value_ () {} Chris@16: BOOST_UBLAS_INLINE Chris@16: explicit scalar_vector (size_type size, const value_type &value = value_type(1)): Chris@16: vector_container (), Chris@16: size_ (size), value_ (value) {} Chris@16: BOOST_UBLAS_INLINE Chris@16: scalar_vector (const scalar_vector &v): Chris@16: vector_container (), Chris@16: size_ (v.size_), value_ (v.value_) {} Chris@16: Chris@16: // Accessors Chris@16: BOOST_UBLAS_INLINE Chris@16: size_type size () const { Chris@16: return size_; Chris@16: } Chris@16: Chris@16: // Resizing Chris@16: BOOST_UBLAS_INLINE Chris@16: void resize (size_type size, bool /*preserve*/ = true) { Chris@16: size_ = size; Chris@16: } Chris@16: Chris@16: // Element support Chris@16: BOOST_UBLAS_INLINE Chris@16: const_pointer find_element (size_type /*i*/) const { Chris@16: return & value_; Chris@16: } Chris@16: Chris@16: // Element access Chris@16: BOOST_UBLAS_INLINE Chris@16: const_reference operator () (size_type /*i*/) const { Chris@16: return value_; Chris@16: } Chris@16: Chris@16: BOOST_UBLAS_INLINE Chris@16: const_reference operator [] (size_type /*i*/) const { Chris@16: return value_; Chris@16: } Chris@16: Chris@16: // Assignment Chris@16: BOOST_UBLAS_INLINE Chris@16: scalar_vector &operator = (const scalar_vector &v) { Chris@16: size_ = v.size_; Chris@16: value_ = v.value_; Chris@16: return *this; Chris@16: } Chris@16: BOOST_UBLAS_INLINE Chris@16: scalar_vector &assign_temporary (scalar_vector &v) { Chris@16: swap (v); Chris@16: return *this; Chris@16: } Chris@16: Chris@16: // Swapping Chris@16: BOOST_UBLAS_INLINE Chris@16: void swap (scalar_vector &v) { Chris@16: if (this != &v) { Chris@16: std::swap (size_, v.size_); Chris@16: std::swap (value_, v.value_); Chris@16: } Chris@16: } Chris@16: BOOST_UBLAS_INLINE Chris@16: friend void swap (scalar_vector &v1, scalar_vector &v2) { Chris@16: v1.swap (v2); Chris@16: } Chris@16: Chris@16: // Iterator types Chris@16: private: Chris@16: // Use an index Chris@16: typedef size_type const_subiterator_type; Chris@16: Chris@16: public: Chris@16: #ifdef BOOST_UBLAS_USE_INDEXED_ITERATOR Chris@16: typedef indexed_const_iterator iterator; Chris@16: typedef indexed_const_iterator const_iterator; Chris@16: #else Chris@16: class const_iterator; Chris@16: #endif Chris@16: Chris@16: // Element lookup Chris@16: BOOST_UBLAS_INLINE Chris@16: const_iterator find (size_type i) const { Chris@16: return const_iterator (*this, i); Chris@16: } Chris@16: Chris@16: #ifndef BOOST_UBLAS_USE_INDEXED_ITERATOR Chris@16: class const_iterator: Chris@16: public container_const_reference, Chris@16: public random_access_iterator_base { Chris@16: public: Chris@16: typedef typename scalar_vector::difference_type difference_type; Chris@16: typedef typename scalar_vector::value_type value_type; Chris@16: typedef typename scalar_vector::const_reference reference; Chris@16: typedef typename scalar_vector::const_pointer pointer; Chris@16: Chris@16: // Construction and destruction Chris@16: BOOST_UBLAS_INLINE Chris@16: const_iterator (): Chris@16: container_const_reference (), it_ () {} Chris@16: BOOST_UBLAS_INLINE Chris@16: const_iterator (const scalar_vector &v, const const_subiterator_type &it): Chris@16: container_const_reference (v), it_ (it) {} Chris@16: Chris@16: // Arithmetic Chris@16: BOOST_UBLAS_INLINE Chris@16: const_iterator &operator ++ () { Chris@16: ++ it_; Chris@16: return *this; Chris@16: } Chris@16: BOOST_UBLAS_INLINE Chris@16: const_iterator &operator -- () { Chris@16: -- it_; Chris@16: return *this; Chris@16: } Chris@16: BOOST_UBLAS_INLINE Chris@16: const_iterator &operator += (difference_type n) { Chris@16: it_ += n; Chris@16: return *this; Chris@16: } Chris@16: BOOST_UBLAS_INLINE Chris@16: const_iterator &operator -= (difference_type n) { Chris@16: it_ -= n; Chris@16: return *this; Chris@16: } Chris@16: BOOST_UBLAS_INLINE Chris@16: difference_type operator - (const const_iterator &it) const { Chris@16: BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ()); Chris@16: return it_ - it.it_; Chris@16: } Chris@16: Chris@16: // Dereference Chris@16: BOOST_UBLAS_INLINE Chris@16: const_reference operator * () const { Chris@16: BOOST_UBLAS_CHECK (it_ < (*this) ().size (), bad_index ()); Chris@16: return (*this) () (index ()); Chris@16: } Chris@16: BOOST_UBLAS_INLINE Chris@16: const_reference operator [] (difference_type n) const { Chris@16: return *(*this + n); Chris@16: } Chris@16: Chris@16: // Index Chris@16: BOOST_UBLAS_INLINE Chris@16: size_type index () const { Chris@16: BOOST_UBLAS_CHECK (it_ < (*this) ().size (), bad_index ()); Chris@16: return it_; Chris@16: } Chris@16: Chris@16: // Assignment Chris@16: BOOST_UBLAS_INLINE Chris@16: const_iterator &operator = (const const_iterator &it) { Chris@16: container_const_reference::assign (&it ()); Chris@16: it_ = it.it_; Chris@16: return *this; Chris@16: } Chris@16: Chris@16: // Comparison Chris@16: BOOST_UBLAS_INLINE Chris@16: bool operator == (const const_iterator &it) const { Chris@16: BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ()); Chris@16: return it_ == it.it_; Chris@16: } Chris@16: BOOST_UBLAS_INLINE Chris@16: bool operator < (const const_iterator &it) const { Chris@16: BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ()); Chris@16: return it_ < it.it_; Chris@16: } Chris@16: Chris@16: private: Chris@16: const_subiterator_type it_; Chris@16: }; Chris@16: Chris@16: typedef const_iterator iterator; Chris@16: #endif Chris@16: Chris@16: BOOST_UBLAS_INLINE Chris@16: const_iterator begin () const { Chris@16: return find (0); Chris@16: } Chris@101: BOOST_UBLAS_INLINE Chris@101: const_iterator cbegin () const { Chris@101: return begin (); Chris@101: } Chris@16: BOOST_UBLAS_INLINE Chris@16: const_iterator end () const { Chris@16: return find (size_); Chris@16: } Chris@101: BOOST_UBLAS_INLINE Chris@101: const_iterator cend () const { Chris@101: return end (); Chris@101: } Chris@16: Chris@16: // Reverse iterator Chris@16: typedef reverse_iterator_base const_reverse_iterator; Chris@16: Chris@16: BOOST_UBLAS_INLINE Chris@16: const_reverse_iterator rbegin () const { Chris@16: return const_reverse_iterator (end ()); Chris@16: } Chris@101: BOOST_UBLAS_INLINE Chris@101: const_reverse_iterator crbegin () const { Chris@101: return rbegin (); Chris@101: } Chris@16: BOOST_UBLAS_INLINE Chris@16: const_reverse_iterator rend () const { Chris@16: return const_reverse_iterator (begin ()); Chris@16: } Chris@101: BOOST_UBLAS_INLINE Chris@101: const_reverse_iterator crend () const { Chris@101: return rend (); Chris@101: } Chris@16: Chris@16: // Serialization Chris@16: template Chris@16: void serialize(Archive & ar, const unsigned int /* file_version */){ Chris@16: serialization::collection_size_type s (size_); Chris@16: ar & serialization::make_nvp("size",s); Chris@16: if (Archive::is_loading::value) { Chris@16: size_ = s; Chris@16: } Chris@16: ar & serialization::make_nvp("value", value_); Chris@16: } Chris@16: Chris@16: private: Chris@16: size_type size_; Chris@16: value_type value_; Chris@16: }; Chris@16: Chris@16: // ------------------------ Chris@16: // Array based vector class Chris@16: // ------------------------ Chris@16: Chris@16: /// \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] Chris@16: template Chris@16: class c_vector: Chris@16: public vector_container > { Chris@16: Chris@16: typedef c_vector self_type; Chris@16: public: Chris@16: #ifdef BOOST_UBLAS_ENABLE_PROXY_SHORTCUTS Chris@16: using vector_container::operator (); Chris@16: #endif Chris@16: typedef std::size_t size_type; Chris@16: typedef std::ptrdiff_t difference_type; Chris@16: typedef T value_type; Chris@16: typedef const T &const_reference; Chris@16: typedef T &reference; Chris@16: typedef value_type array_type[N]; Chris@16: typedef T *pointer; Chris@16: typedef const T *const_pointer; Chris@16: typedef const vector_reference const_closure_type; Chris@16: typedef vector_reference closure_type; Chris@16: typedef self_type vector_temporary_type; Chris@16: typedef dense_tag storage_category; Chris@16: Chris@16: // Construction and destruction Chris@16: BOOST_UBLAS_INLINE Chris@16: c_vector (): Chris@16: size_ (N) /* , data_ () */ {} Chris@16: explicit BOOST_UBLAS_INLINE Chris@16: c_vector (size_type size): Chris@16: size_ (size) /* , data_ () */ { Chris@16: if (size_ > N) Chris@101: bad_size ().raise (); Chris@16: } Chris@16: BOOST_UBLAS_INLINE Chris@16: c_vector (const c_vector &v): Chris@16: size_ (v.size_) /* , data_ () */ { Chris@16: if (size_ > N) Chris@101: bad_size ().raise (); Chris@16: assign(v); Chris@16: } Chris@16: template Chris@16: BOOST_UBLAS_INLINE Chris@16: c_vector (const vector_expression &ae): Chris@16: size_ (ae ().size ()) /* , data_ () */ { Chris@16: if (size_ > N) Chris@101: bad_size ().raise (); Chris@16: vector_assign (*this, ae); Chris@16: } Chris@16: Chris@16: // Accessors Chris@16: BOOST_UBLAS_INLINE Chris@16: size_type size () const { Chris@16: return size_; Chris@16: } Chris@16: BOOST_UBLAS_INLINE Chris@16: const_pointer data () const { Chris@16: return data_; Chris@16: } Chris@16: BOOST_UBLAS_INLINE Chris@16: pointer data () { Chris@16: return data_; Chris@16: } Chris@16: Chris@16: // Resizing Chris@16: BOOST_UBLAS_INLINE Chris@101: void resize (size_type size, bool /*preserve*/ = true) { Chris@16: if (size > N) Chris@101: bad_size ().raise (); Chris@16: size_ = size; Chris@16: } Chris@16: Chris@16: // Element support Chris@16: BOOST_UBLAS_INLINE Chris@16: pointer find_element (size_type i) { Chris@16: return const_cast (const_cast(*this).find_element (i)); Chris@16: } Chris@16: BOOST_UBLAS_INLINE Chris@16: const_pointer find_element (size_type i) const { Chris@16: return & data_ [i]; Chris@16: } Chris@16: Chris@16: // Element access Chris@16: BOOST_UBLAS_INLINE Chris@16: const_reference operator () (size_type i) const { Chris@16: BOOST_UBLAS_CHECK (i < size_, bad_index ()); Chris@16: return data_ [i]; Chris@16: } Chris@16: BOOST_UBLAS_INLINE Chris@16: reference operator () (size_type i) { Chris@16: BOOST_UBLAS_CHECK (i < size_, bad_index ()); Chris@16: return data_ [i]; Chris@16: } Chris@16: Chris@16: BOOST_UBLAS_INLINE Chris@16: const_reference operator [] (size_type i) const { Chris@16: return (*this) (i); Chris@16: } Chris@16: BOOST_UBLAS_INLINE Chris@16: reference operator [] (size_type i) { Chris@16: return (*this) (i); Chris@16: } Chris@16: Chris@16: // Element assignment Chris@16: BOOST_UBLAS_INLINE Chris@16: reference insert_element (size_type i, const_reference t) { Chris@16: BOOST_UBLAS_CHECK (i < size_, bad_index ()); Chris@16: return (data_ [i] = t); Chris@16: } Chris@16: BOOST_UBLAS_INLINE Chris@16: void erase_element (size_type i) { Chris@16: BOOST_UBLAS_CHECK (i < size_, bad_index ()); Chris@16: data_ [i] = value_type/*zero*/(); Chris@16: } Chris@16: Chris@16: // Zeroing Chris@16: BOOST_UBLAS_INLINE Chris@16: void clear () { Chris@16: std::fill (data_, data_ + size_, value_type/*zero*/()); Chris@16: } Chris@16: Chris@16: // Assignment Chris@16: #ifdef BOOST_UBLAS_MOVE_SEMANTICS Chris@16: Chris@16: /*! @note "pass by value" the key idea to enable move semantics */ Chris@16: BOOST_UBLAS_INLINE Chris@16: c_vector &operator = (c_vector v) { Chris@16: assign_temporary(v); Chris@16: return *this; Chris@16: } Chris@16: #else Chris@16: BOOST_UBLAS_INLINE Chris@16: c_vector &operator = (const c_vector &v) { Chris@16: size_ = v.size_; Chris@16: std::copy (v.data_, v.data_ + v.size_, data_); Chris@16: return *this; Chris@16: } Chris@16: #endif Chris@16: template // Container assignment without temporary Chris@16: BOOST_UBLAS_INLINE Chris@16: c_vector &operator = (const vector_container &v) { Chris@16: resize (v ().size (), false); Chris@16: assign (v); Chris@16: return *this; Chris@16: } Chris@16: BOOST_UBLAS_INLINE Chris@16: c_vector &assign_temporary (c_vector &v) { Chris@16: swap (v); Chris@16: return *this; Chris@16: } Chris@16: template Chris@16: BOOST_UBLAS_INLINE Chris@16: c_vector &operator = (const vector_expression &ae) { Chris@16: self_type temporary (ae); Chris@16: return assign_temporary (temporary); Chris@16: } Chris@16: template Chris@16: BOOST_UBLAS_INLINE Chris@16: c_vector &assign (const vector_expression &ae) { Chris@16: vector_assign (*this, ae); Chris@16: return *this; Chris@16: } Chris@16: Chris@16: // Computed assignment Chris@16: template Chris@16: BOOST_UBLAS_INLINE Chris@16: c_vector &operator += (const vector_expression &ae) { Chris@16: self_type temporary (*this + ae); Chris@16: return assign_temporary (temporary); Chris@16: } Chris@16: template // Container assignment without temporary Chris@16: BOOST_UBLAS_INLINE Chris@16: c_vector &operator += (const vector_container &v) { Chris@16: plus_assign (v); Chris@16: return *this; Chris@16: } Chris@16: template Chris@16: BOOST_UBLAS_INLINE Chris@16: c_vector &plus_assign (const vector_expression &ae) { Chris@16: vector_assign ( *this, ae); Chris@16: return *this; Chris@16: } Chris@16: template Chris@16: BOOST_UBLAS_INLINE Chris@16: c_vector &operator -= (const vector_expression &ae) { Chris@16: self_type temporary (*this - ae); Chris@16: return assign_temporary (temporary); Chris@16: } Chris@16: template // Container assignment without temporary Chris@16: BOOST_UBLAS_INLINE Chris@16: c_vector &operator -= (const vector_container &v) { Chris@16: minus_assign (v); Chris@16: return *this; Chris@16: } Chris@16: template Chris@16: BOOST_UBLAS_INLINE Chris@16: c_vector &minus_assign (const vector_expression &ae) { Chris@16: vector_assign (*this, ae); Chris@16: return *this; Chris@16: } Chris@16: template Chris@16: BOOST_UBLAS_INLINE Chris@16: c_vector &operator *= (const AT &at) { Chris@16: vector_assign_scalar (*this, at); Chris@16: return *this; Chris@16: } Chris@16: template Chris@16: BOOST_UBLAS_INLINE Chris@16: c_vector &operator /= (const AT &at) { Chris@16: vector_assign_scalar (*this, at); Chris@16: return *this; Chris@16: } Chris@16: Chris@16: // Swapping Chris@16: BOOST_UBLAS_INLINE Chris@16: void swap (c_vector &v) { Chris@16: if (this != &v) { Chris@101: BOOST_UBLAS_CHECK (size_ == v.size_, bad_size ()); Chris@16: std::swap (size_, v.size_); Chris@16: std::swap_ranges (data_, data_ + size_, v.data_); Chris@16: } Chris@16: } Chris@16: BOOST_UBLAS_INLINE Chris@16: friend void swap (c_vector &v1, c_vector &v2) { Chris@16: v1.swap (v2); Chris@16: } Chris@16: Chris@16: // Iterator types Chris@16: private: Chris@16: // Use pointers for iterator Chris@16: typedef const_pointer const_subiterator_type; Chris@16: typedef pointer subiterator_type; Chris@16: Chris@16: public: Chris@16: #ifdef BOOST_UBLAS_USE_INDEXED_ITERATOR Chris@16: typedef indexed_iterator iterator; Chris@16: typedef indexed_const_iterator const_iterator; Chris@16: #else Chris@16: class const_iterator; Chris@16: class iterator; Chris@16: #endif Chris@16: Chris@16: // Element lookup Chris@16: BOOST_UBLAS_INLINE Chris@16: const_iterator find (size_type i) const { Chris@16: #ifndef BOOST_UBLAS_USE_INDEXED_ITERATOR Chris@16: return const_iterator (*this, &data_ [i]); Chris@16: #else Chris@16: return const_iterator (*this, i); Chris@16: #endif Chris@16: } Chris@16: BOOST_UBLAS_INLINE Chris@16: iterator find (size_type i) { Chris@16: #ifndef BOOST_UBLAS_USE_INDEXED_ITERATOR Chris@16: return iterator (*this, &data_ [i]); Chris@16: #else Chris@16: return iterator (*this, i); Chris@16: #endif Chris@16: } Chris@16: Chris@16: #ifndef BOOST_UBLAS_USE_INDEXED_ITERATOR Chris@16: class const_iterator: Chris@16: public container_const_reference, Chris@16: public random_access_iterator_base { Chris@16: public: Chris@16: typedef typename c_vector::difference_type difference_type; Chris@16: typedef typename c_vector::value_type value_type; Chris@16: typedef typename c_vector::const_reference reference; Chris@16: typedef typename c_vector::const_pointer pointer; Chris@16: Chris@16: // Construction and destruction Chris@16: BOOST_UBLAS_INLINE Chris@16: const_iterator (): Chris@16: container_const_reference (), it_ () {} Chris@16: BOOST_UBLAS_INLINE Chris@16: const_iterator (const self_type &v, const const_subiterator_type &it): Chris@16: container_const_reference (v), it_ (it) {} Chris@16: BOOST_UBLAS_INLINE Chris@16: const_iterator (const typename self_type::iterator &it): // ISSUE self_type:: stops VC8 using std::iterator here Chris@16: container_const_reference (it ()), it_ (it.it_) {} Chris@16: Chris@16: // Arithmetic Chris@16: BOOST_UBLAS_INLINE Chris@16: const_iterator &operator ++ () { Chris@16: ++ it_; Chris@16: return *this; Chris@16: } Chris@16: BOOST_UBLAS_INLINE Chris@16: const_iterator &operator -- () { Chris@16: -- it_; Chris@16: return *this; Chris@16: } Chris@16: BOOST_UBLAS_INLINE Chris@16: const_iterator &operator += (difference_type n) { Chris@16: it_ += n; Chris@16: return *this; Chris@16: } Chris@16: BOOST_UBLAS_INLINE Chris@16: const_iterator &operator -= (difference_type n) { Chris@16: it_ -= n; Chris@16: return *this; Chris@16: } Chris@16: BOOST_UBLAS_INLINE Chris@16: difference_type operator - (const const_iterator &it) const { Chris@16: BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ()); Chris@16: return it_ - it.it_; Chris@16: } Chris@16: Chris@16: // Dereference Chris@16: BOOST_UBLAS_INLINE Chris@16: const_reference operator * () const { Chris@16: BOOST_UBLAS_CHECK (it_ >= (*this) ().begin ().it_ && it_ < (*this) ().end ().it_, bad_index ()); Chris@16: return *it_; Chris@16: } Chris@16: BOOST_UBLAS_INLINE Chris@16: const_reference operator [] (difference_type n) const { Chris@16: return *(it_ + n); Chris@16: } Chris@16: Chris@16: // Index Chris@16: BOOST_UBLAS_INLINE Chris@16: size_type index () const { Chris@16: BOOST_UBLAS_CHECK (it_ >= (*this) ().begin ().it_ && it_ < (*this) ().end ().it_, bad_index ()); Chris@16: const self_type &v = (*this) (); Chris@16: return it_ - v.begin ().it_; Chris@16: } Chris@16: Chris@16: // Assignment Chris@16: BOOST_UBLAS_INLINE Chris@16: const_iterator &operator = (const const_iterator &it) { Chris@16: container_const_reference::assign (&it ()); Chris@16: it_ = it.it_; Chris@16: return *this; Chris@16: } Chris@16: Chris@16: // Comparison Chris@16: BOOST_UBLAS_INLINE Chris@16: bool operator == (const const_iterator &it) const { Chris@16: BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ()); Chris@16: return it_ == it.it_; Chris@16: } Chris@16: BOOST_UBLAS_INLINE Chris@16: bool operator < (const const_iterator &it) const { Chris@16: BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ()); Chris@16: return it_ < it.it_; Chris@16: } Chris@16: Chris@16: private: Chris@16: const_subiterator_type it_; Chris@16: Chris@16: friend class iterator; Chris@16: }; Chris@16: #endif Chris@16: Chris@16: BOOST_UBLAS_INLINE Chris@16: const_iterator begin () const { Chris@16: return find (0); Chris@16: } Chris@101: BOOST_UBLAS_INLINE Chris@101: const_iterator cbegin () const { Chris@101: return begin (); Chris@101: } Chris@16: BOOST_UBLAS_INLINE Chris@16: const_iterator end () const { Chris@16: return find (size_); Chris@16: } Chris@101: BOOST_UBLAS_INLINE Chris@101: const_iterator cend () const { Chris@101: return end (); Chris@101: } Chris@16: Chris@16: #ifndef BOOST_UBLAS_USE_INDEXED_ITERATOR Chris@16: class iterator: Chris@16: public container_reference, Chris@16: public random_access_iterator_base { Chris@16: public: Chris@16: typedef typename c_vector::difference_type difference_type; Chris@16: typedef typename c_vector::value_type value_type; Chris@16: typedef typename c_vector::reference reference; Chris@16: typedef typename c_vector::pointer pointer; Chris@16: Chris@16: // Construction and destruction Chris@16: BOOST_UBLAS_INLINE Chris@16: iterator (): Chris@16: container_reference (), it_ () {} Chris@16: BOOST_UBLAS_INLINE Chris@16: iterator (self_type &v, const subiterator_type &it): Chris@16: container_reference (v), it_ (it) {} Chris@16: Chris@16: // Arithmetic Chris@16: BOOST_UBLAS_INLINE Chris@16: iterator &operator ++ () { Chris@16: ++ it_; Chris@16: return *this; Chris@16: } Chris@16: BOOST_UBLAS_INLINE Chris@16: iterator &operator -- () { Chris@16: -- it_; Chris@16: return *this; Chris@16: } Chris@16: BOOST_UBLAS_INLINE Chris@16: iterator &operator += (difference_type n) { Chris@16: it_ += n; Chris@16: return *this; Chris@16: } Chris@16: BOOST_UBLAS_INLINE Chris@16: iterator &operator -= (difference_type n) { Chris@16: it_ -= n; Chris@16: return *this; Chris@16: } Chris@16: BOOST_UBLAS_INLINE Chris@16: difference_type operator - (const iterator &it) const { Chris@16: BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ()); Chris@16: return it_ - it.it_; Chris@16: } Chris@16: Chris@16: // Dereference Chris@16: BOOST_UBLAS_INLINE Chris@16: reference operator * () const { Chris@16: BOOST_UBLAS_CHECK (it_ >= (*this) ().begin ().it_ && it_ < (*this) ().end ().it_, bad_index ()); Chris@16: return *it_; Chris@16: } Chris@16: BOOST_UBLAS_INLINE Chris@16: reference operator [] (difference_type n) const { Chris@16: return *(it_ + n); Chris@16: } Chris@16: Chris@16: // Index Chris@16: BOOST_UBLAS_INLINE Chris@16: size_type index () const { Chris@16: BOOST_UBLAS_CHECK (it_ >= (*this) ().begin ().it_ && it_ < (*this) ().end ().it_, bad_index ()); Chris@16: // EDG won't allow const self_type it doesn't allow friend access to it_ Chris@16: self_type &v = (*this) (); Chris@16: return it_ - v.begin ().it_; Chris@16: } Chris@16: Chris@16: // Assignment Chris@16: BOOST_UBLAS_INLINE Chris@16: iterator &operator = (const iterator &it) { Chris@16: container_reference::assign (&it ()); Chris@16: it_ = it.it_; Chris@16: return *this; Chris@16: } Chris@16: Chris@16: // Comparison Chris@16: BOOST_UBLAS_INLINE Chris@16: bool operator == (const iterator &it) const { Chris@16: BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ()); Chris@16: return it_ == it.it_; Chris@16: } Chris@16: BOOST_UBLAS_INLINE Chris@16: bool operator < (const iterator &it) const { Chris@16: BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ()); Chris@16: return it_ < it.it_; Chris@16: } Chris@16: Chris@16: private: Chris@16: subiterator_type it_; Chris@16: Chris@16: friend class const_iterator; Chris@16: }; Chris@16: #endif Chris@16: Chris@16: BOOST_UBLAS_INLINE Chris@16: iterator begin () { Chris@16: return find (0); Chris@16: } Chris@16: BOOST_UBLAS_INLINE Chris@16: iterator end () { Chris@16: return find (size_); Chris@16: } Chris@16: Chris@16: // Reverse iterator Chris@16: typedef reverse_iterator_base const_reverse_iterator; Chris@16: typedef reverse_iterator_base reverse_iterator; Chris@16: Chris@16: BOOST_UBLAS_INLINE Chris@16: const_reverse_iterator rbegin () const { Chris@16: return const_reverse_iterator (end ()); Chris@16: } Chris@101: BOOST_UBLAS_INLINE Chris@101: const_reverse_iterator crbegin () const { Chris@101: return rbegin (); Chris@101: } Chris@16: BOOST_UBLAS_INLINE Chris@16: const_reverse_iterator rend () const { Chris@16: return const_reverse_iterator (begin ()); Chris@16: } Chris@101: BOOST_UBLAS_INLINE Chris@101: const_reverse_iterator crend () const { Chris@101: return rend (); Chris@101: } Chris@16: BOOST_UBLAS_INLINE Chris@16: reverse_iterator rbegin () { Chris@16: return reverse_iterator (end ()); Chris@16: } Chris@16: BOOST_UBLAS_INLINE Chris@16: reverse_iterator rend () { Chris@16: return reverse_iterator (begin ()); Chris@16: } Chris@16: Chris@16: // Serialization Chris@16: template Chris@16: void serialize(Archive & ar, const unsigned int /* file_version */){ Chris@16: serialization::collection_size_type s (size_); Chris@16: ar & serialization::make_nvp("size",s); Chris@16: Chris@16: // copy the value back if loading Chris@16: if (Archive::is_loading::value) { Chris@16: if (s > N) bad_size("too large size in bounded_vector::load()\n").raise(); Chris@16: size_ = s; Chris@16: } Chris@16: // ISSUE: this writes the full array Chris@16: ar & serialization::make_nvp("data",data_); Chris@16: } Chris@16: Chris@16: private: Chris@16: size_type size_; Chris@16: array_type data_; Chris@16: }; Chris@16: Chris@16: }}} Chris@16: Chris@16: #endif