Reduced template code bloat making stable_vector's index independent from value_type.

[SVN r80478]
This commit is contained in:
Ion Gaztañaga
2012-09-09 21:47:32 +00:00
parent a8d20305dc
commit 22a18c25fb
6 changed files with 700 additions and 587 deletions

View File

@@ -27,6 +27,68 @@ namespace boost {
namespace container {
namespace container_detail {
//!A deleter for scoped_ptr that deallocates the memory
//!allocated for an object using a STL allocator.
template <class A>
struct scoped_deallocator
{
typedef allocator_traits<A> allocator_traits_type;
typedef typename allocator_traits_type::pointer pointer;
typedef container_detail::integral_constant<unsigned,
boost::container::container_detail::
version<A>::value> alloc_version;
typedef container_detail::integral_constant<unsigned, 1> allocator_v1;
typedef container_detail::integral_constant<unsigned, 2> allocator_v2;
private:
void priv_deallocate(allocator_v1)
{ m_alloc.deallocate(m_ptr, 1); }
void priv_deallocate(allocator_v2)
{ m_alloc.deallocate_one(m_ptr); }
BOOST_MOVABLE_BUT_NOT_COPYABLE(scoped_deallocator)
public:
pointer m_ptr;
A& m_alloc;
scoped_deallocator(pointer p, A& a)
: m_ptr(p), m_alloc(a)
{}
~scoped_deallocator()
{ if (m_ptr)priv_deallocate(alloc_version()); }
scoped_deallocator(BOOST_RV_REF(scoped_deallocator) o)
: m_ptr(o.m_ptr), m_alloc(o.m_alloc)
{ o.release(); }
pointer get() const
{ return m_ptr; }
void release()
{ m_ptr = 0; }
};
template <class Allocator>
struct null_scoped_deallocator
{
typedef boost::container::allocator_traits<Allocator> AllocTraits;
typedef typename AllocTraits::pointer pointer;
typedef typename AllocTraits::size_type size_type;
null_scoped_deallocator(pointer, Allocator&, size_type)
{}
void release()
{}
pointer get() const
{ return pointer(); }
};
//!A deleter for scoped_ptr that deallocates the memory
//!allocated for an array of objects using a STL allocator.
template <class Allocator>
@@ -239,10 +301,57 @@ class allocator_destroyer
void operator()(const pointer &p)
{
AllocTraits::destroy(a_, container_detail::to_raw_pointer(p));
priv_deallocate(p, alloc_version());
this->priv_deallocate(p, alloc_version());
}
};
template <class A>
class allocator_destroyer_and_chain_builder
{
typedef allocator_traits<A> allocator_traits_type;
typedef typename allocator_traits_type::value_type value_type;
typedef typename A::multiallocation_chain multiallocation_chain;
A & a_;
multiallocation_chain &c_;
public:
allocator_destroyer_and_chain_builder(A &a, multiallocation_chain &c)
: a_(a), c_(c)
{}
void operator()(const typename A::pointer &p)
{
allocator_traits<A>::destroy(a_, container_detail::to_raw_pointer(p));
c_.push_front(p);
}
};
template <class A>
class allocator_multialloc_chain_node_deallocator
{
typedef allocator_traits<A> allocator_traits_type;
typedef typename allocator_traits_type::value_type value_type;
typedef typename A::multiallocation_chain multiallocation_chain;
typedef allocator_destroyer_and_chain_builder<A> chain_builder;
A & a_;
multiallocation_chain c_;
public:
allocator_multialloc_chain_node_deallocator(A &a)
: a_(a), c_()
{}
chain_builder get_chain_builder()
{ return chain_builder(a_, c_); }
~allocator_multialloc_chain_node_deallocator()
{
if(!c_.empty())
a_.deallocate_individual(boost::move(c_));
}
};
} //namespace container_detail {
} //namespace container {

View File

@@ -200,7 +200,7 @@ class transform_multiallocation_chain
void splice_after(iterator after_this, transform_multiallocation_chain &x, iterator before_begin, iterator before_end, size_type n)
{ holder_.splice_after(after_this.base(), x.holder_, before_begin.base(), before_end.base(), n); }
void incorporate_after(iterator after_this, void_pointer begin, void_pointer before_end, size_type n)
void incorporate_after(iterator after_this, pointer begin, pointer before_end, size_type n)
{ holder_.incorporate_after(after_this.base(), begin, before_end, n); }
void pop_front()

View File

@@ -43,99 +43,6 @@ namespace boost {
namespace container {
namespace container_detail {
//!A deleter for scoped_ptr that deallocates the memory
//!allocated for an object using a STL allocator.
template <class A>
struct scoped_deallocator
{
typedef allocator_traits<A> allocator_traits_type;
typedef typename allocator_traits_type::pointer pointer;
typedef container_detail::integral_constant<unsigned,
boost::container::container_detail::
version<A>::value> alloc_version;
typedef container_detail::integral_constant<unsigned, 1> allocator_v1;
typedef container_detail::integral_constant<unsigned, 2> allocator_v2;
private:
void priv_deallocate(allocator_v1)
{ m_alloc.deallocate(m_ptr, 1); }
void priv_deallocate(allocator_v2)
{ m_alloc.deallocate_one(m_ptr); }
BOOST_MOVABLE_BUT_NOT_COPYABLE(scoped_deallocator)
public:
pointer m_ptr;
A& m_alloc;
scoped_deallocator(pointer p, A& a)
: m_ptr(p), m_alloc(a)
{}
~scoped_deallocator()
{ if (m_ptr)priv_deallocate(alloc_version()); }
scoped_deallocator(BOOST_RV_REF(scoped_deallocator) o)
: m_ptr(o.m_ptr), m_alloc(o.m_alloc)
{ o.release(); }
pointer get() const
{ return m_ptr; }
void release()
{ m_ptr = 0; }
};
template <class A>
class allocator_destroyer_and_chain_builder
{
typedef allocator_traits<A> allocator_traits_type;
typedef typename allocator_traits_type::value_type value_type;
typedef typename A::multiallocation_chain multiallocation_chain;
A & a_;
multiallocation_chain &c_;
public:
allocator_destroyer_and_chain_builder(A &a, multiallocation_chain &c)
: a_(a), c_(c)
{}
void operator()(const typename A::pointer &p)
{
allocator_traits<A>::destroy(a_, container_detail::to_raw_pointer(p));
c_.push_front(p);
}
};
template <class A>
class allocator_multialloc_chain_node_deallocator
{
typedef allocator_traits<A> allocator_traits_type;
typedef typename allocator_traits_type::value_type value_type;
typedef typename A::multiallocation_chain multiallocation_chain;
typedef allocator_destroyer_and_chain_builder<A> chain_builder;
A & a_;
multiallocation_chain c_;
public:
allocator_multialloc_chain_node_deallocator(A &a)
: a_(a), c_()
{}
chain_builder get_chain_builder()
{ return chain_builder(a_, c_); }
~allocator_multialloc_chain_node_deallocator()
{
if(!c_.empty())
a_.deallocate_individual(boost::move(c_));
}
};
template<class ValueCompare, class Node>
struct node_compare
: private ValueCompare

File diff suppressed because it is too large Load Diff

View File

@@ -1521,7 +1521,7 @@ class vector : private container_detail::vector_alloc_holder<A>
container_detail::is_same<AllocVersion, allocator_v1>::value >::type * = 0)
{
if(this->members_.m_capacity){
if(!size()){
if(!this->size()){
this->prot_deallocate();
}
else{