From 9bb526b7b92303a54916fd4bc53935b962fc1bb2 Mon Sep 17 00:00:00 2001 From: Michael Stevens Date: Sun, 5 Sep 2004 08:58:29 +0000 Subject: [PATCH] Change to use STL Allocator svn path=/trunk/boost/boost/numeric/ublas/; revision=24910 --- include/boost/numeric/ublas/fwd.hpp | 8 +- .../boost/numeric/ublas/storage_sparse.hpp | 113 ++++++++++++------ 2 files changed, 82 insertions(+), 39 deletions(-) diff --git a/include/boost/numeric/ublas/fwd.hpp b/include/boost/numeric/ublas/fwd.hpp index dabfb264..e5054798 100644 --- a/include/boost/numeric/ublas/fwd.hpp +++ b/include/boost/numeric/ublas/fwd.hpp @@ -39,10 +39,10 @@ namespace boost { namespace numeric { namespace ublas { struct concrete_tag {}; struct abstract_tag {}; - template > + template > class unbounded_array; - template > + template > class bounded_array; class range; @@ -50,9 +50,9 @@ namespace boost { namespace numeric { namespace ublas { template > class indirect_array; - template + template > class map_std; - template + template > class map_array; struct vector_tag {}; diff --git a/include/boost/numeric/ublas/storage_sparse.hpp b/include/boost/numeric/ublas/storage_sparse.hpp index 9361f22c..fecffb4a 100644 --- a/include/boost/numeric/ublas/storage_sparse.hpp +++ b/include/boost/numeric/ublas/storage_sparse.hpp @@ -17,13 +17,9 @@ #ifndef BOOST_UBLAS_STORAGE_SPARSE_H #define BOOST_UBLAS_STORAGE_SPARSE_H -#include #include #include -#include -#include -#include #include namespace boost { namespace numeric { namespace ublas { @@ -245,17 +241,19 @@ namespace boost { namespace numeric { namespace ublas { }; #endif + // Default map type is simply forwarded to std::map - template - class map_std : public std::map { + template + class map_std : public std::map { }; + // Map array - template + template class map_array { public: - typedef std::size_t size_type; - typedef std::ptrdiff_t difference_type; + typedef typename ALLOC::size_type size_type; + typedef typename ALLOC::difference_type difference_type; typedef I index_type; typedef T data_value_type; typedef const T &data_const_reference; @@ -272,46 +270,74 @@ namespace boost { namespace numeric { namespace ublas { // Construction and destruction BOOST_UBLAS_INLINE - map_array (): - capacity_ (0), data_ (new value_type [0]), size_ (0) { + map_array (const ALLOC &a = ALLOC()): + alloc_(a), capacity_ (0), size_ (0) { + data_ = 0; } BOOST_UBLAS_INLINE - map_array (const map_array &a): - capacity_ (a.size_), data_ (new value_type [a.size_]), size_ (a.size_) { - *this = a; + map_array (const map_array &c): + alloc_ (c.alloc_), capacity_ (c.size_), size_ (c.size_) { + if (capacity_) { + data_ = alloc_.allocate (capacity_ BOOST_UBLAS_ALLOCATOR_HINT); + std::uninitialized_copy (data_, data_ + capacity_, c.data_); + // capacity != size_ requires uninitialized_fill (size_ to capacity_) + } + else + data_ = 0; } BOOST_UBLAS_INLINE ~map_array () { - delete [] data_; + if (capacity_) { + std::for_each (data_, data_ + capacity_, static_destroy); + alloc_.deallocate (data_, capacity_); + } } - // Resizing + private: + // Resizing - implicitly exposses uninitialized (but default constructed) data_value_type BOOST_UBLAS_INLINE void resize (size_type size) { BOOST_UBLAS_CHECK (size_ <= capacity_, internal_logic ()); if (size > capacity_) { - pointer data = new value_type [size << 1]; - std::copy (data_, data_ + (std::min) (size, size_), data); - std::fill (data + (std::min) (size, size_), data + size, value_type ()); - delete [] data_; - capacity_ = size << 1; + const size_type capacity = size << 1; + BOOST_UBLAS_CHECK (capacity, internal_logic ()); + pointer data = alloc_.allocate (capacity BOOST_UBLAS_ALLOCATOR_HINT); + std::uninitialized_copy (data_, data_ + (std::min) (size, size_), data); + std::uninitialized_fill (data + (std::min) (size, size_), data + capacity, value_type ()); + + if (capacity_) { + std::for_each (data_, data_ + capacity_, static_destroy); + alloc_.deallocate (data_, capacity_); + } + capacity_ = capacity; data_ = data; } size_ = size; BOOST_UBLAS_CHECK (size_ <= capacity_, internal_logic ()); } + public: // Reserving BOOST_UBLAS_INLINE void reserve (size_type capacity) { BOOST_UBLAS_CHECK (size_ <= capacity_, internal_logic ()); - if (capacity > capacity_) { - pointer data = new value_type [capacity]; - std::copy (data_, data_ + size_, data); - delete [] data_; - capacity_ = capacity; - data_ = data; + // Reduce capacity_ if size_ allows + BOOST_UBLAS_CHECK (capacity >= size_, bad_size ()); + pointer data; + if (capacity) { + data = alloc_.allocate (capacity BOOST_UBLAS_ALLOCATOR_HINT); + std::uninitialized_copy (data_, data_ + size_, data); + std::uninitialized_fill (data + size_, data + capacity, value_type ()); } + else + data = 0; + + if (capacity_) { + std::for_each (data_, data_ + capacity_, static_destroy); + alloc_.deallocate (data_, capacity_); + } + capacity_ = capacity; + data_ = data; BOOST_UBLAS_CHECK (size_ <= capacity_, internal_logic ()); } @@ -319,6 +345,10 @@ namespace boost { namespace numeric { namespace ublas { size_type size () const { return size_; } + BOOST_UBLAS_INLINE + size_type capacity () const { + return capacity_; + } // Element access BOOST_UBLAS_INLINE @@ -326,7 +356,7 @@ namespace boost { namespace numeric { namespace ublas { #ifndef BOOST_UBLAS_STRICT_STORAGE_SPARSE pointer it = find (i); if (it == end ()) - it = insert (end (), value_type (i, data_value_type ())); + it = insert (end (), value_type (i, data_value_type (0))); BOOST_UBLAS_CHECK (it != end (), internal_logic ()); return it->second; #else @@ -410,7 +440,7 @@ namespace boost { namespace numeric { namespace ublas { void erase (pointer it) { BOOST_UBLAS_CHECK (begin () <= it && it < end (), bad_index ()); // Fixed by George Katsirelos. - // (*it).second = data_value_type (); + // (*it).second = data_value_type (0); std::copy (it + 1, end (), it); resize (size () - 1); } @@ -421,7 +451,7 @@ namespace boost { namespace numeric { namespace ublas { // Fixed by George Katsirelos. // while (it1 != it2) { // BOOST_UBLAS_CHECK (begin () <= it1 && it1 < end (), bad_index ()); - // (*it1).second = data_value_type (); + // (*it1).second = data_value_type (0); // ++ it1; // } std::copy (it2, end (), it1); @@ -437,7 +467,7 @@ namespace boost { namespace numeric { namespace ublas { // This function seems to be big. So we do not let the compiler inline it. // BOOST_UBLAS_INLINE const_pointer find (index_type i) const { - const_pointer it (detail::lower_bound (begin (), end (), value_type (i, data_value_type ()), detail::less_pair ())); + const_pointer it (detail::lower_bound (begin (), end (), value_type (i, data_value_type (0)), detail::less_pair ())); if (it == end () || it->first != i) it = end (); return it; @@ -445,7 +475,7 @@ namespace boost { namespace numeric { namespace ublas { // This function seems to be big. So we do not let the compiler inline it. // BOOST_UBLAS_INLINE pointer find (index_type i) { - pointer it (detail::lower_bound (begin (), end (), value_type (i, data_value_type ()), detail::less_pair ())); + pointer it (detail::lower_bound (begin (), end (), value_type (i, data_value_type (0)), detail::less_pair ())); if (it == end () || it->first != i) it = end (); return it; @@ -453,12 +483,12 @@ namespace boost { namespace numeric { namespace ublas { // This function seems to be big. So we do not let the compiler inline it. // BOOST_UBLAS_INLINE const_pointer lower_bound (index_type i) const { - return detail::lower_bound (begin (), end (), value_type (i, data_value_type ()), detail::less_pair ()); + return detail::lower_bound (begin (), end (), value_type (i, data_value_type (0)), detail::less_pair ()); } // This function seems to be big. So we do not let the compiler inline it. // BOOST_UBLAS_INLINE pointer lower_bound (index_type i) { - return detail::lower_bound (begin (), end (), value_type (i, data_value_type ()), detail::less_pair ()); + return detail::lower_bound (begin (), end (), value_type (i, data_value_type (0)), detail::less_pair ()); } // Iterators simply are pointers. @@ -518,6 +548,12 @@ namespace boost { namespace numeric { namespace ublas { } private: + // Provide destroy as a non member function + BOOST_UBLAS_INLINE + void static static_destroy (pointer p) { + p -> ~value_type(); + } + ALLOC alloc_; size_type capacity_; pointer data_; size_type size_; @@ -582,6 +618,12 @@ namespace boost { namespace numeric { namespace ublas { a1.swap (a2); } + +#ifdef BOOST_UBLAS_DEPRACATED +// Depracted due to: +// no allocator interface +// inconsitent value_type zero init + // Set array template class set_array { @@ -617,7 +659,7 @@ namespace boost { namespace numeric { namespace ublas { if (size > capacity_) { pointer data = new value_type [size << 1]; std::copy (data_, data_ + (std::min) (size, size_), data); - std::fill (data + (std::min) (size, size_), data + size, value_type ()); + std::fill (data + (std::min) (size, size_), data + size, value_type (0)); delete [] data_; capacity_ = size << 1; data_ = data; @@ -843,6 +885,7 @@ namespace boost { namespace numeric { namespace ublas { if (&a1 != &a2) a1.swap (a2); } +#endif }}}