Index: boost/numeric/ublas/vector.hpp =================================================================== --- boost/numeric/ublas/vector.hpp (revision 64531) +++ boost/numeric/ublas/vector.hpp (working copy) @@ -867,6 +867,80 @@ }; + // -------------------- + // Fixed vector class + // -------------------- + + /// \brief a dense vector of values of type \c T, of fixed size \f$N\f$. + /// A dense vector of values of type \c T, of fixed size \f$N\f$. + /// Elements are constructed by the storage type \c fixed_array, which \b need \b not \b initialise their value. + template + class fixed_vector: + public vector > { + + typedef vector > vector_type; + public: + typedef typename vector_type::size_type size_type; + static const size_type max_size = N; + + // Construction and destruction + BOOST_UBLAS_INLINE + fixed_vector (): + vector_type (N) {} + BOOST_UBLAS_INLINE + fixed_vector (size_type size): + vector_type (size) {} + BOOST_UBLAS_INLINE + fixed_vector (const fixed_vector &v): + vector_type (v) {} + template // Allow vector construction + BOOST_UBLAS_INLINE + fixed_vector (const vector &v): + vector_type (v) {} + template + BOOST_UBLAS_INLINE + fixed_vector (const vector_expression &ae): + vector_type (ae) {} + BOOST_UBLAS_INLINE + ~fixed_vector () {} + + // Assignment +#ifdef BOOST_UBLAS_MOVE_SEMANTICS + + /*! @note "pass by value" the key idea to enable move semantics */ + BOOST_UBLAS_INLINE + fixed_vector &operator = (fixed_vector v) { + vector_type::operator = (v); + return *this; + } +#else + BOOST_UBLAS_INLINE + fixed_vector &operator = (const fixed_vector &v) { + vector_type::operator = (v); + return *this; + } +#endif + template // Generic vector assignment + BOOST_UBLAS_INLINE + fixed_vector &operator = (const vector &v) { + vector_type::operator = (v); + return *this; + } + template // Container assignment without temporary + BOOST_UBLAS_INLINE + fixed_vector &operator = (const vector_container &v) { + vector_type::operator = (v); + return *this; + } + template + BOOST_UBLAS_INLINE + fixed_vector &operator = (const vector_expression &ae) { + vector_type::operator = (ae); + return *this; + } + }; + + // ----------------- // Zero vector class // ----------------- Index: boost/numeric/ublas/storage.hpp =================================================================== --- boost/numeric/ublas/storage.hpp (revision 64531) +++ boost/numeric/ublas/storage.hpp (working copy) @@ -468,6 +468,168 @@ }; + // Fixed array - with allocator for size_type and difference_type + template + class fixed_array: + public storage_array > { + + typedef fixed_array self_type; + public: + // No allocator_type as ALLOC is not used for allocation + typedef typename ALLOC::size_type size_type; + typedef typename ALLOC::difference_type difference_type; + typedef T value_type; + typedef const T &const_reference; + typedef T &reference; + typedef const T *const_pointer; + typedef T *pointer; + typedef const_pointer const_iterator; + typedef pointer iterator; + + // Construction and destruction + BOOST_UBLAS_INLINE + fixed_array () { + } + explicit BOOST_UBLAS_INLINE + fixed_array (size_type size) { + BOOST_UBLAS_CHECK (size == N, bad_size ()); + // data_ (an array) elements are already default constructed + } + BOOST_UBLAS_INLINE + fixed_array (size_type size, const value_type &init) { + BOOST_UBLAS_CHECK (size == N, bad_size ()); + // ISSUE elements should be value constructed here, but we must fill instead as already default constructed + std::fill (begin(), end(), init) ; + } + BOOST_UBLAS_INLINE + fixed_array (const fixed_array &c) { + // ISSUE elements should be copy constructed here, but we must copy instead as already default constructed + std::copy (c.begin(), c.end(), begin()); + } + + // Resizing + BOOST_UBLAS_INLINE + void resize (size_type size) { + BOOST_UBLAS_CHECK (size == N, bad_size ()); + } + BOOST_UBLAS_INLINE + void resize (size_type size, value_type init) { + BOOST_UBLAS_CHECK (size == N, bad_size ()); + } + + // Random Access Container + BOOST_UBLAS_INLINE + size_type max_size () const { + return N; + } + + BOOST_UBLAS_INLINE + bool empty () const { + return N == 0; + } + + BOOST_UBLAS_INLINE + size_type size () const { + return N; + } + + // Element access + BOOST_UBLAS_INLINE + const_reference operator [] (size_type i) const { + BOOST_UBLAS_CHECK (i < N, bad_index ()); + return data_ [i]; + } + BOOST_UBLAS_INLINE + reference operator [] (size_type i) { + BOOST_UBLAS_CHECK (i < N, bad_index ()); + return data_ [i]; + } + + // Assignment + BOOST_UBLAS_INLINE + fixed_array &operator = (const fixed_array &a) { + if (this != &a) { + std::copy (a.data_, a.data_ + N, data_); + } + return *this; + } + BOOST_UBLAS_INLINE + fixed_array &assign_temporary (fixed_array &a) { + *this = a; + return *this; + } + + // Swapping + BOOST_UBLAS_INLINE + void swap (fixed_array &a) { + if (this != &a) { + std::swap_ranges (data_, data_ + N, a.data_); + } + } + BOOST_UBLAS_INLINE + friend void swap (fixed_array &a1, fixed_array &a2) { + a1.swap (a2); + } + + BOOST_UBLAS_INLINE + const_iterator begin () const { + return data_; + } + BOOST_UBLAS_INLINE + const_iterator end () const { + return data_ + N; + } + + BOOST_UBLAS_INLINE + iterator begin () { + return data_; + } + BOOST_UBLAS_INLINE + iterator end () { + return data_ + N; + } + + // Reverse iterators + typedef std::reverse_iterator const_reverse_iterator; + typedef std::reverse_iterator reverse_iterator; + + BOOST_UBLAS_INLINE + const_reverse_iterator rbegin () const { + return const_reverse_iterator (end ()); + } + BOOST_UBLAS_INLINE + const_reverse_iterator rend () const { + return const_reverse_iterator (begin ()); + } + BOOST_UBLAS_INLINE + reverse_iterator rbegin () { + return reverse_iterator (end ()); + } + BOOST_UBLAS_INLINE + reverse_iterator rend () { + return reverse_iterator (begin ()); + } + + private: + // Serialization + friend class boost::serialization::access; + + template + void serialize(Archive & ar, const unsigned int version) + { + serialization::collection_size_type s(N); + ar & serialization::make_nvp("size", s); + if ( Archive::is_loading::value ) { + if (s != N) bad_size("wrong size in fixed_array::load()\n").raise(); + } + ar & serialization::make_array(data_, s); + } + + private: + BOOST_UBLAS_FIXED_ARRAY_ALIGN value_type data_ [N]; + }; + + // Array adaptor with normal deep copy semantics of elements template class array_adaptor: Index: boost/numeric/ublas/detail/config.hpp =================================================================== --- boost/numeric/ublas/detail/config.hpp (revision 64531) +++ boost/numeric/ublas/detail/config.hpp (working copy) @@ -266,6 +266,11 @@ #define BOOST_UBLAS_BOUNDED_ARRAY_ALIGN #endif +// Alignment of fixed_array type +#ifndef BOOST_UBLAS_FIXED_ARRAY_ALIGN +#define BOOST_UBLAS_FIXED_ARRAY_ALIGN +#endif + // Enable different sparse element proxies #ifndef BOOST_UBLAS_NO_ELEMENT_PROXIES // Sparse proxies prevent reference invalidation problems in expressions such as: Index: boost/numeric/ublas/fwd.hpp =================================================================== --- boost/numeric/ublas/fwd.hpp (revision 64531) +++ boost/numeric/ublas/fwd.hpp (working copy) @@ -26,6 +26,9 @@ template > class bounded_array; + template > + class fixed_array; + template class basic_range; template @@ -90,6 +93,8 @@ class vector; template class bounded_vector; + template + class fixed_vector; template > class unit_vector;