2
0
mirror of https://github.com/boostorg/ublas.git synced 2026-02-26 05:02:16 +00:00

Change to use STL Allocator

svn path=/trunk/boost/boost/numeric/ublas/; revision=24910
This commit is contained in:
Michael Stevens
2004-09-05 08:58:29 +00:00
parent 83f983cb1d
commit 9bb526b7b9
2 changed files with 82 additions and 39 deletions

View File

@@ -39,10 +39,10 @@ namespace boost { namespace numeric { namespace ublas {
struct concrete_tag {};
struct abstract_tag {};
template<class T, class A = std::allocator<T> >
template<class T, class ALLOC = std::allocator<T> >
class unbounded_array;
template<class T, std::size_t N, class A = std::allocator<T> >
template<class T, std::size_t N, class ALLOC = std::allocator<T> >
class bounded_array;
class range;
@@ -50,9 +50,9 @@ namespace boost { namespace numeric { namespace ublas {
template<class A = unbounded_array<std::size_t> >
class indirect_array;
template<class I, class T>
template<class I, class T, class ALLOC = std::allocator<T> >
class map_std;
template<class I, class T>
template<class I, class T, class ALLOC = std::allocator<T> >
class map_array;
struct vector_tag {};

View File

@@ -17,13 +17,9 @@
#ifndef BOOST_UBLAS_STORAGE_SPARSE_H
#define BOOST_UBLAS_STORAGE_SPARSE_H
#include <algorithm>
#include <map>
#include <set>
#include <boost/numeric/ublas/config.hpp>
#include <boost/numeric/ublas/exception.hpp>
#include <boost/numeric/ublas/iterator.hpp>
#include <boost/numeric/ublas/storage.hpp>
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 I, class T>
class map_std : public std::map<I,T> {
template<class I, class T, class ALLOC>
class map_std : public std::map<I, T, ALLOC> {
};
// Map array
template<class I, class T>
template<class I, class T, class ALLOC>
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<value_type> ()));
const_pointer it (detail::lower_bound (begin (), end (), value_type (i, data_value_type (0)), detail::less_pair<value_type> ()));
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<value_type> ()));
pointer it (detail::lower_bound (begin (), end (), value_type (i, data_value_type (0)), detail::less_pair<value_type> ()));
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<value_type> ());
return detail::lower_bound (begin (), end (), value_type (i, data_value_type (0)), detail::less_pair<value_type> ());
}
// 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<value_type> ());
return detail::lower_bound (begin (), end (), value_type (i, data_value_type (0)), detail::less_pair<value_type> ());
}
// 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 I>
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
}}}