From 299cbf53d9234bcf09c2f9b8fcaa1a87147ff5bb Mon Sep 17 00:00:00 2001 From: Michael Stevens Date: Sun, 19 Sep 2004 05:14:26 +0000 Subject: [PATCH] Storage array: removed insert,erase,clear they requires value_type(0) and semantics are not STL resize(n,init) is element preserving resize_new is not --- doc/storage.htm | 62 ++--- include/boost/numeric/ublas/banded.hpp | 17 ++ include/boost/numeric/ublas/concepts.hpp | 21 +- include/boost/numeric/ublas/hermitian.hpp | 19 +- include/boost/numeric/ublas/matrix.hpp | 28 +++ include/boost/numeric/ublas/storage.hpp | 279 ++++++++-------------- include/boost/numeric/ublas/symmetric.hpp | 19 +- include/boost/numeric/ublas/vector.hpp | 35 +-- 8 files changed, 222 insertions(+), 258 deletions(-) diff --git a/doc/storage.htm b/doc/storage.htm index be4cdfb4..2a7319d5 100644 --- a/doc/storage.htm +++ b/doc/storage.htm @@ -96,11 +96,18 @@ holds at most size elements, using a specified allocator. Deallocates the unbounded_array itself. -void resize (size_type size, bool preserve = -true) -Reallocates an unbounded_array to hold at most -size elements. When preserve == false the -elements values after resize are undefined. +void resize (size_type size, value_type init) +Resizes an unbounded_array to hold at most +size elements.
+The unbounded_array is reallocated only if the size changes. +Element values are preserved, additional elements are assigned the value of init. + + +void resize_new (size_type size) +Resizes an unbounded_array to hold at most +size elements.
+The unbounded_array is reallocated only if the size changes. +The elements values are undefined. size_type size () const @@ -131,19 +138,6 @@ const Swaps the contents of the arrays. -pointer insert (pointer it, const value_type -&t) -Inserts the value t at it. - - -void erase (pointer it) -Erases the value at it. - - -void clear () -Clears the array. - - const_iterator begin () const Returns a const_iterator pointing to the beginning of the unbounded_array. @@ -269,10 +263,17 @@ holds at most size elements. Deallocates the bounded_array itself. -void resize (size_type size) -Reallocates a bounded_array to hold at most -size elements. When preserve == false the -elements values after resize are undefined. +void resize (size_type size, value_type init) +Resizes a bounded_array to hold at most +size elements. Element values are preserved, additional +elements are assigned the value of init. Throws a bad_size exception +if the size exeeds the bound. + + +void resize_new (size_type size) +Resizes a bounded_array to hold at most +size elements. The elements values are undefined. Throws a bad_size exception +if the size exeeds the bound. size_type size () const @@ -299,23 +300,6 @@ const Assigns a temporary. May change the array a. -void swap (bounded_array &a) -Swaps the contents of the arrays. - - -pointer insert (pointer it, const value_type -&t) -Inserts the value t at it. - - -void erase (pointer it) -Erases the value at it. - - -void clear () -Clears the array. - - const_iterator begin () const Returns a const_iterator pointing to the beginning of the bounded_array. diff --git a/include/boost/numeric/ublas/banded.hpp b/include/boost/numeric/ublas/banded.hpp index ff342c06..def348fd 100644 --- a/include/boost/numeric/ublas/banded.hpp +++ b/include/boost/numeric/ublas/banded.hpp @@ -119,9 +119,26 @@ namespace boost { namespace numeric { namespace ublas { size2_ = size2; lower_ = lower; upper_ = upper; + if (preserve) { + self_type temporary (size1, size2, lower, upper); + // FIXME use matrix_resize_preserve on conformant compilers + // detail::matrix_resize_reserve (*this, temporary, size_, size_); + assign_temporary (temporary); + } + else + detail::resize (data (), (std::max) (size1, size2) * (lower + 1 + upper), preserve); detail::resize (data (), (std::max) (size1, size2) * (lower + 1 + upper), preserve); } + BOOST_UBLAS_INLINE + void resize_packed_preserve (size_type size1, size_type size2, size_type lower = 0, size_type upper = 0) { + size1_ = size1; + size2_ = size2; + lower_ = lower; + upper_ = upper; + detail::resize (data (), (std::max) (size1, size2) * (lower + 1 + upper), true); + } + // Element access BOOST_UBLAS_INLINE const_reference operator () (size_type i, size_type j) const { diff --git a/include/boost/numeric/ublas/concepts.hpp b/include/boost/numeric/ublas/concepts.hpp index ea61fb74..0d74a6bd 100644 --- a/include/boost/numeric/ublas/concepts.hpp +++ b/include/boost/numeric/ublas/concepts.hpp @@ -456,12 +456,15 @@ namespace boost { namespace numeric { namespace ublas { struct StorageContainerConcept { typedef C container_type; typedef typename C::size_type size_type; + typedef typename C::value_type value_type; static void constraints () { RandomAccessContainerConcept::constraints (); size_type n (0); // Sizing constructor container_type c = container_type (n); + // Initialised sizing constructor + container_type (n, value_type (5)); ignore_unused_variable_warning (c); } }; @@ -478,20 +481,12 @@ namespace boost { namespace numeric { namespace ublas { size_type n (0); // Sizing constructor container_type c = container_type (n); - value_type t = value_type (); - iterator_type it = iterator_type (), it1 = iterator_type (), it2 = iterator_type (); - // Insert - c.insert (it, t); - // Range insert - c.insert (it, it1, it2); - // Erase - c.erase (it); - // Range erase - c.erase (it1, it2); - // Clear - c.clear (); + // Initialised sizing constructor + c = container_type (n, value_type (3)); // Resize - c.resize (n); + c.resize (n, value_type (5)); + // Resize - none preserving + detail::resize (c, n, false); } }; diff --git a/include/boost/numeric/ublas/hermitian.hpp b/include/boost/numeric/ublas/hermitian.hpp index a6ab38c3..8359121e 100644 --- a/include/boost/numeric/ublas/hermitian.hpp +++ b/include/boost/numeric/ublas/hermitian.hpp @@ -323,13 +323,24 @@ namespace boost { namespace numeric { namespace ublas { // Resizing BOOST_UBLAS_INLINE void resize (size_type size, bool preserve = true) { - size_ = BOOST_UBLAS_SAME (size, size); - detail::resize (data (), functor1_type::packed_size (size, size), preserve); + size_ = size; + if (preserve) { + self_type temporary (size_, size_); + // FIXME use matrix_resize_preserve on conformant compilers + // detail::matrix_resize_reserve (*this, temporary, size_, size_); + assign_temporary (temporary); + } + else + detail::resize (data (), functor1_type::packed_size (size_, size_), preserve); } BOOST_UBLAS_INLINE void resize (size_type size1, size_type size2, bool preserve = true) { - size_ = BOOST_UBLAS_SAME (size1, size2); - detail::resize (data (), functor1_type::packed_size (size1, size2), preserve); + resize (BOOST_UBLAS_SAME (size1, size2), preserve); + } + BOOST_UBLAS_INLINE + void resize_packed_preserve (size_type size) { + size_ = BOOST_UBLAS_SAME (size, size); + detail::resize (data (), functor1_type::packed_size (size_, size_), false); } // Element access diff --git a/include/boost/numeric/ublas/matrix.hpp b/include/boost/numeric/ublas/matrix.hpp index 9dd0d65b..636d0431 100644 --- a/include/boost/numeric/ublas/matrix.hpp +++ b/include/boost/numeric/ublas/matrix.hpp @@ -28,6 +28,32 @@ namespace boost { namespace numeric { namespace ublas { + namespace detail { + using namespace boost::numeric::ublas; + + // Matrix resizing algorithm + template + BOOST_UBLAS_INLINE + void matrix_resize_preserve (M& m, M& temporary, BOOST_UBLAS_TYPENAME M::size_type size1, BOOST_UBLAS_TYPENAME M::size_type size2) { + typedef F functor_type; + typedef BOOST_UBLAS_TYPENAME M::size_type size_type; + // Common elements to preserve + const size_type size1_min = (std::min) (size1, m.size1_); + const size_type size2_min = (std::min) (size2, m.size2_); + // Order loop for i-major and j-minor sizes + const size_type i_size = functor_type::size1 (size1_min, size2_min); + const size_type j_size = functor_type::size2 (size1_min, size2_min); + for (size_type i = 0; i != i_size; ++i) { // indexing copy over major + for (size_type j = 0; j != j_size; ++j) { + temporary.data () [functor_type::element (functor_type::element1(i,i_size, j,j_size), size1, functor_type::element2(i,i_size, j,j_size), size2)] = + m.data() [functor_type::element (functor_type::element1(i,i_size, j,j_size), m.size1_, functor_type::element2(i,i_size, j,j_size), m.size2_)]; + } + } + assign_temporary (temporary); + } + } + + // Array based matrix class template class matrix: @@ -110,6 +136,8 @@ namespace boost { namespace numeric { namespace ublas { void resize (size_type size1, size_type size2, bool preserve = true) { if (preserve) { self_type temporary (size1, size2); + // FIXME use matrix_resize_preserve on conformant compilers + // detail::matrix_resize_reserve (*this, temporary, size1, size2); // Common elements to preserve const size_type size1_min = (std::min) (size1, size1_); const size_type size2_min = (std::min) (size2, size2_); diff --git a/include/boost/numeric/ublas/storage.hpp b/include/boost/numeric/ublas/storage.hpp index 89c67513..4f082baa 100644 --- a/include/boost/numeric/ublas/storage.hpp +++ b/include/boost/numeric/ublas/storage.hpp @@ -93,12 +93,13 @@ namespace boost { namespace numeric { namespace ublas { alloc_(a), size_ (size) { if (size_) { data_ = alloc_.allocate (size_ BOOST_UBLAS_ALLOCATOR_HINT); + // ISSUE some compilers zero POD here new (data_) value_type[size_]; } } // No value initialised, but still be default constructed BOOST_UBLAS_INLINE - unbounded_array (size_type size, const T& init, const ALLOC &a = ALLOC()): + unbounded_array (size_type size, const value_type &init, const ALLOC &a = ALLOC()): alloc_ (a), size_ (size) { if (size_) { data_ = alloc_.allocate (size_ BOOST_UBLAS_ALLOCATOR_HINT); @@ -127,8 +128,9 @@ namespace boost { namespace numeric { namespace ublas { } // Resizing + private: BOOST_UBLAS_INLINE - void resize (size_type size, bool preserve = true) { + void resize_internal (size_type size, value_type init, bool preserve) { if (size != size_) { pointer data; if (size) { @@ -147,12 +149,15 @@ namespace boost { namespace numeric { namespace ublas { alloc_.construct (di, *si); ++di; } - const value_type zero (0); for (; di != data + size; ++di) { - alloc_.construct (di, zero); + alloc_.construct (di, init); } } - } + } + else { + // ISSUE some compilers zero POD here + new (data) value_type[size]; + } } else data = 0; @@ -167,7 +172,16 @@ namespace boost { namespace numeric { namespace ublas { data_ = data; } } - + public: + BOOST_UBLAS_INLINE + void resize_new (size_type size) { + resize_internal (size, value_type (), false); + } + BOOST_UBLAS_INLINE + void resize (size_type size, value_type init) { + resize_internal (size, init, true); + } + BOOST_UBLAS_INLINE size_type size () const { return size_; @@ -189,7 +203,7 @@ namespace boost { namespace numeric { namespace ublas { BOOST_UBLAS_INLINE unbounded_array &operator = (const unbounded_array &a) { if (this != &a) { - resize (a.size_, false); + resize_new (a.size_); std::copy (a.data_, a.data_ + a.size_, data_); } return *this; @@ -215,41 +229,6 @@ namespace boost { namespace numeric { namespace ublas { } #endif - // Element insertion and deletion - BOOST_UBLAS_INLINE - iterator insert (iterator it, const value_type &t) { - BOOST_UBLAS_CHECK (begin () <= it && it < end (), bad_index ()); - BOOST_UBLAS_CHECK (*it == value_type (0), external_logic ()); - *it = t; - return it; - } - BOOST_UBLAS_INLINE - void insert (iterator it, iterator it1, iterator it2) { - while (it1 != it2) { - BOOST_UBLAS_CHECK (begin () <= it && it < end (), bad_index ()); - BOOST_UBLAS_CHECK (*it == value_type (0), external_logic ()); - *it = *it1; - ++ it, ++ it1; - } - } - BOOST_UBLAS_INLINE - void erase (pointer it) { - BOOST_UBLAS_CHECK (begin () <= it && it < end (), bad_index ()); - *it = value_type (0); - } - BOOST_UBLAS_INLINE - void erase (pointer it1, pointer it2) { - while (it1 != it2) { - BOOST_UBLAS_CHECK (begin () <= it1 && it1 < end (), bad_index ()); - *it1 = value_type (0); - ++ it1; - } - } - BOOST_UBLAS_INLINE - void clear () { - erase (begin (), end ()); - } - BOOST_UBLAS_INLINE const_iterator begin () const { return data_; @@ -301,10 +280,10 @@ namespace boost { namespace numeric { namespace ublas { } private: - // Handle explict destroy on a (possibily indexed) iterator + // Handle explict destroy on a (possibly indexed) iterator BOOST_UBLAS_INLINE static void iterator_destroy (iterator &i) { - (&(*i)) -> ~value_type(); + (&(*i)) -> ~value_type (); } ALLOC alloc_; size_type size_; @@ -338,9 +317,8 @@ namespace boost { namespace numeric { namespace ublas { bad_size ().raise (); // data_ (an array) elements are already default constructed } - // No value initialised, but still be default constructed BOOST_UBLAS_INLINE - bounded_array (size_type size, const T& init): + bounded_array (size_type size, const value_type &init): size_ (size) /*, data_ ()*/ { if (size_ > N) bad_size ().raise (); @@ -350,17 +328,23 @@ namespace boost { namespace numeric { namespace ublas { BOOST_UBLAS_INLINE bounded_array (const bounded_array &c): size_ (c.size_) { - // ISSUE elements should be copy constructed here, but we must copy instead as already constructed + // ISSUE elements should be copy constructed here, but we must copy instead as already default constructed std::copy (c.data_, c.data_ + c.size_, data_); } // Resizing BOOST_UBLAS_INLINE - void resize (size_type size, bool preserve = true) { + void resize_new (size_type size) { if (size > N) bad_size ().raise (); - if (preserve && size > size_) - std::fill (data_ + size_, data_ + size, value_type (0)); + size_ = size; + } + BOOST_UBLAS_INLINE + void resize (size_type size, value_type init) { + if (size > N) + bad_size ().raise (); + if (size > size_) + std::fill (data_ + size_, data_ + size, init); size_ = size; } @@ -385,7 +369,7 @@ namespace boost { namespace numeric { namespace ublas { BOOST_UBLAS_INLINE bounded_array &operator = (const bounded_array &a) { if (this != &a) { - resize (a.size_, false); + resize_new (a.size_); std::copy (a.data_, a.data_ + a.size_, data_); } return *this; @@ -411,41 +395,6 @@ namespace boost { namespace numeric { namespace ublas { } #endif - // Element insertion and deletion - BOOST_UBLAS_INLINE - iterator insert (iterator it, const value_type &t) { - BOOST_UBLAS_CHECK (begin () <= it && it < end (), bad_index ()); - BOOST_UBLAS_CHECK (*it == value_type (0), external_logic ()); - *it = t; - return it; - } - BOOST_UBLAS_INLINE - void insert (iterator it, iterator it1, iterator it2) { - while (it1 != it2) { - BOOST_UBLAS_CHECK (begin () <= it && it < end (), bad_index ()); - BOOST_UBLAS_CHECK (*it == value_type (0), external_logic ()); - *it = *it1; - ++ it, ++ it1; - } - } - BOOST_UBLAS_INLINE - void erase (iterator it) { - BOOST_UBLAS_CHECK (begin () <= it && it < end (), bad_index ()); - *it = value_type (0); - } - BOOST_UBLAS_INLINE - void erase (iterator it1, iterator it2) { - while (it1 != it2) { - BOOST_UBLAS_CHECK (begin () <= it1 && it1 < end (), bad_index ()); - *it1 = value_type (0); - ++ it1; - } - } - BOOST_UBLAS_INLINE - void clear () { - erase (begin (), end ()); - } - BOOST_UBLAS_INLINE const_iterator begin () const { return data_; @@ -502,9 +451,6 @@ namespace boost { namespace numeric { namespace ublas { }; - // No initialise - tag parameter specified to disable construction of array value_types's - struct no_init {}; - // Array adaptor with normal deep copy semantics of elements template class array_adaptor { @@ -523,16 +469,13 @@ namespace boost { namespace numeric { namespace ublas { size_ (0), own_ (true), data_ (new value_type [0]) { } explicit BOOST_UBLAS_INLINE - array_adaptor (no_init): - size_ (0), own_ (true), data_ (new value_type [0]) {} - explicit BOOST_UBLAS_INLINE array_adaptor (size_type size): size_ (size), own_ (true), data_ (new value_type [size]) { - std::fill (data_, data_ + size_, value_type (0)); } BOOST_UBLAS_INLINE - array_adaptor (size_type size, no_init): + array_adaptor (size_type size, const value_type &init): size_ (size), own_ (true), data_ (new value_type [size]) { + std::fill (data_, data_ + size_, init); } BOOST_UBLAS_INLINE array_adaptor (size_type size, pointer data): @@ -550,13 +493,14 @@ namespace boost { namespace numeric { namespace ublas { } // Resizing + private: BOOST_UBLAS_INLINE - void resize (size_type size, bool preserve = true) { + void resize_internal (size_type size, value_type init, bool preserve = true) { if (size != size_) { pointer data = new value_type [size]; if (preserve) { std::copy (data_, data_ + (std::min) (size, size_), data); - std::fill (data + (std::min) (size, size_), data + size, value_type (0)); + std::fill (data + (std::min) (size, size_), data + size, init); } if (own_) delete [] data_; @@ -566,16 +510,38 @@ namespace boost { namespace numeric { namespace ublas { } } BOOST_UBLAS_INLINE - void resize (size_type size, pointer data, bool preserve = true) { - if (preserve) { - std::copy (data_, data_ + (std::min) (size, size_), data); + void resize_internal (size_type size, pointer data, value_type init, bool preserve = true) { + if (data != data_) { + if (preserve) { + std::copy (data_, data_ + (std::min) (size, size_), data); + std::fill (data + (std::min) (size, size_), data + size, value_type (0)); + } + if (own_) + delete [] data_; + own_ = false; + data_ = data; + } + else { std::fill (data + (std::min) (size, size_), data + size, value_type (0)); } - if (own_) - delete [] data_; size_ = size; - own_ = false; - data_ = data; + } + public: + BOOST_UBLAS_INLINE + void resize_new (size_type size) { + resize_internal (size, value_type (), false); + } + BOOST_UBLAS_INLINE + void resize (size_type size, value_type init) { + resize_internal (size, init, true); + } + BOOST_UBLAS_INLINE + void resize_new (size_type size, pointer data) { + resize_internal (size, data, value_type (), false); + } + BOOST_UBLAS_INLINE + void resize (size_type size, pointer data, value_type init) { + resize_internal (size, data, init, true); } BOOST_UBLAS_INLINE @@ -599,7 +565,7 @@ namespace boost { namespace numeric { namespace ublas { BOOST_UBLAS_INLINE array_adaptor &operator = (const array_adaptor &a) { if (this != &a) { - resize (a.size_, false); + resize_new (a.size_); std::copy (a.data_, a.data_ + a.size_, data_); } return *this; @@ -629,41 +595,6 @@ namespace boost { namespace numeric { namespace ublas { } #endif - // Element insertion and deletion - BOOST_UBLAS_INLINE - pointer insert (pointer it, const value_type &t) { - BOOST_UBLAS_CHECK (begin () <= it && it < end (), bad_index ()); - BOOST_UBLAS_CHECK (*it == value_type (0), external_logic ()); - *it = t; - return it; - } - BOOST_UBLAS_INLINE - void insert (pointer it, pointer it1, pointer it2) { - while (it1 != it2) { - BOOST_UBLAS_CHECK (begin () <= it && it < end (), bad_index ()); - BOOST_UBLAS_CHECK (*it == value_type (0), external_logic ()); - *it = *it1; - ++ it, ++ it1; - } - } - BOOST_UBLAS_INLINE - void erase (pointer it) { - BOOST_UBLAS_CHECK (begin () <= it && it < end (), bad_index ()); - *it = value_type (0); - } - BOOST_UBLAS_INLINE - void erase (pointer it1, pointer it2) { - while (it1 != it2) { - BOOST_UBLAS_CHECK (begin () <= it1 && it1 < end (), bad_index ()); - *it1 = value_type (0); - ++ it1; - } - } - BOOST_UBLAS_INLINE - void clear () { - erase (begin (), end ()); - } - // Iterators simply are pointers. typedef const_pointer const_iterator; @@ -757,16 +688,13 @@ namespace boost { namespace numeric { namespace ublas { size_ (0), own_ (true), data_ (new value_type [0]) { } explicit BOOST_UBLAS_INLINE - shallow_array_adaptor (no_init): - size_ (0), own_ (true), data_ (new value_type [0]) {} - explicit BOOST_UBLAS_INLINE shallow_array_adaptor (size_type size): size_ (size), own_ (true), data_ (new value_type [size]) { - std::fill (data_.get (), data_.get () + size_, value_type (0)); } BOOST_UBLAS_INLINE - shallow_array_adaptor (size_type size, no_init): + shallow_array_adaptor (size_type size, const value_type &init): size_ (size), own_ (true), data_ (new value_type [size]) { + std::fill (data_.get (), data_.get () + size_, init); } BOOST_UBLAS_INLINE shallow_array_adaptor (size_type size, pointer data): @@ -781,27 +709,45 @@ namespace boost { namespace numeric { namespace ublas { } // Resizing + private: BOOST_UBLAS_INLINE - void resize (size_type size, bool preserve = true) { + void resize_internal (size_type size, value_type init, bool preserve = true) { if (size != size_) { shared_array data (new value_type [size]); if (preserve) { std::copy (data_.get (), data_.get () + (std::min) (size, size_), data.get ()); - std::fill (data.get () + (std::min) (size, size_), data.get () + size, value_type (0)); + std::fill (data.get () + (std::min) (size, size_), data.get () + size, init); } size_ = size; data_ = data; } } BOOST_UBLAS_INLINE - void resize (size_type size, pointer data, bool preserve = true) { + void resize_internal (size_type size, pointer data, value_type init, bool preserve = true) { if (preserve) { std::copy (data_.get (), data_.get () + (std::min) (size, size_), data); - std::fill (data + (std::min) (size, size_), data + size, value_type (0)); + std::fill (data + (std::min) (size, size_), data + size, init); } size_ = size; data_ = data; } + public: + BOOST_UBLAS_INLINE + void resize_new (size_type size) { + resize_internal (size, value_type (), false); + } + BOOST_UBLAS_INLINE + void resize (size_type size, value_type init) { + resize_internal (size, init, true); + } + BOOST_UBLAS_INLINE + void resize_new (size_type size, pointer data) { + resize_internal (size, data, value_type (), false); + } + BOOST_UBLAS_INLINE + void resize (size_type size, pointer data, value_type init) { + resize_internal (size, data, init, true); + } BOOST_UBLAS_INLINE size_type size () const { @@ -824,7 +770,7 @@ namespace boost { namespace numeric { namespace ublas { BOOST_UBLAS_INLINE shallow_array_adaptor &operator = (const shallow_array_adaptor &a) { if (this != &a) { - resize (a.size_, false); + resize_new (a.size_); std::copy (a.data_.get (), a.data_.get () + a.size_, data_.get ()); } return *this; @@ -854,41 +800,6 @@ namespace boost { namespace numeric { namespace ublas { } #endif - // Element insertion and deletion - BOOST_UBLAS_INLINE - pointer insert (pointer it, const value_type &t) { - BOOST_UBLAS_CHECK (begin () <= it && it < end (), bad_index ()); - BOOST_UBLAS_CHECK (*it == value_type (0), external_logic ()); - *it = t; - return it; - } - BOOST_UBLAS_INLINE - void insert (pointer it, pointer it1, pointer it2) { - while (it1 != it2) { - BOOST_UBLAS_CHECK (begin () <= it && it < end (), bad_index ()); - BOOST_UBLAS_CHECK (*it == value_type (0), external_logic ()); - *it = *it1; - ++ it, ++ it1; - } - } - BOOST_UBLAS_INLINE - void erase (pointer it) { - BOOST_UBLAS_CHECK (begin () <= it && it < end (), bad_index ()); - *it = value_type (0); - } - BOOST_UBLAS_INLINE - void erase (pointer it1, pointer it2) { - while (it1 != it2) { - BOOST_UBLAS_CHECK (begin () <= it1 && it1 < end (), bad_index ()); - *it1 = value_type (0); - ++ it1; - } - } - BOOST_UBLAS_INLINE - void clear () { - erase (begin (), end ()); - } - // Iterators simply are pointers. typedef const_pointer const_iterator; diff --git a/include/boost/numeric/ublas/symmetric.hpp b/include/boost/numeric/ublas/symmetric.hpp index 4205891d..7c073b66 100644 --- a/include/boost/numeric/ublas/symmetric.hpp +++ b/include/boost/numeric/ublas/symmetric.hpp @@ -126,13 +126,24 @@ namespace boost { namespace numeric { namespace ublas { // Resizing BOOST_UBLAS_INLINE void resize (size_type size, bool preserve = true) { - size_ = BOOST_UBLAS_SAME (size, size); - detail::resize (data (), functor1_type::packed_size (size, size), preserve); + size_ = size; + if (preserve) { + self_type temporary (size_, size_); + // FIXME use matrix_resize_preserve on conformant compilers + // detail::matrix_resize_reserve (*this, temporary, size_, size_); + assign_temporary (temporary); + } + else + detail::resize (data (), functor1_type::packed_size (size_, size_), preserve); } BOOST_UBLAS_INLINE void resize (size_type size1, size_type size2, bool preserve = true) { - size_ = BOOST_UBLAS_SAME (size1, size2); - detail::resize (data (), functor1_type::packed_size (size1, size2), preserve); + resize (BOOST_UBLAS_SAME (size1, size2), preserve); + } + BOOST_UBLAS_INLINE + void resize_packed_preserve (size_type size) { + size_ = BOOST_UBLAS_SAME (size, size); + detail::resize (data (), functor1_type::packed_size (size_, size_), false); } // Element access diff --git a/include/boost/numeric/ublas/vector.hpp b/include/boost/numeric/ublas/vector.hpp index ddbf32cf..65ba99c1 100644 --- a/include/boost/numeric/ublas/vector.hpp +++ b/include/boost/numeric/ublas/vector.hpp @@ -37,31 +37,37 @@ namespace boost { namespace numeric { namespace ublas { #ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION // ISSUE Overloaded free function templates fail on some compilers! // Thanks to Karl Meerbergen for the functor workaround which we use by default - template + template struct resize_functor { - void operator() (T& a, typename T::size_type size, bool preserve) const { - a.resize (size, preserve); - } + void operator() (A& a, typename A::size_type size, bool preserve) const { + if (preserve) + a.resize (size, typename A::value_type (0)); + else + a.resize_new (size); + } }; // Specialise for std::vector template struct resize_functor > { - void operator() (std::vector& a, typename std::vector::size_type size, bool ) const { - a.resize (size); - } + void operator() (std::vector& a, typename std::vector::size_type size, bool ) const { + a.resize (size); + } }; - template + template BOOST_UBLAS_INLINE - void resize (T& a, typename T::size_type size, bool preserve) { - resize_functor() (a, size, preserve); + void resize (A& a, typename A::size_type size, bool preserve) { + resize_functor() (a, size, preserve); } #else - template + template BOOST_UBLAS_INLINE - void resize (T& a, typename T::size_type size, bool preserve) { - a.resize (size, preserve); + void resize (A& a, typename A::size_type size, bool preserve) { + if (preserve) + a.resize (size, BOOST_UBLAS_TYPENAME A::value_type (0)); + else + a.resize_new (size); } /* ISSUE Specialise for std::vector * however some (MSVC-6/7) compilers without template partial specialization @@ -69,12 +75,13 @@ namespace boost { namespace numeric { namespace ublas { */ template BOOST_UBLAS_INLINE - void resize (std::vector &a, typename std::vector::size_type size, bool /* preserve */) { + void resize (std::vector &a, typename std::vector::size_type size, bool ) { a.resize (size); } #endif } + // Array based vector class template class vector: