Trivial fix for empty ranges in node_alloc_holder

[SVN r84902]
This commit is contained in:
Ion Gaztañaga
2013-06-24 19:13:16 +00:00
parent b556fead74
commit e7b1fde968
2 changed files with 43 additions and 40 deletions

View File

@@ -698,7 +698,8 @@ use [*Boost.Container]? There are several reasons for that:
[@https://svn.boost.org/trac/boost/ticket/7969 #7969],
[@https://svn.boost.org/trac/boost/ticket/8118 #8118],
[@https://svn.boost.org/trac/boost/ticket/8294 #8294],
[@https://svn.boost.org/trac/boost/ticket/8553 #8553].
[@https://svn.boost.org/trac/boost/ticket/8553 #8553],
[@https://svn.boost.org/trac/boost/ticket/8724 #8724].
[endsect]

View File

@@ -229,48 +229,50 @@ struct node_alloc_holder
void allocate_many_and_construct
(FwdIterator beg, difference_type n, Inserter inserter)
{
/*
NodePtr p = this->allocate_one();
Deallocator node_deallocator(p, this->node_alloc());
::boost::container::construct_in_place(this->node_alloc(), container_detail::addressof(p->m_data), it);
node_deallocator.release();
//This does not throw
typedef typename Node::hook_type hook_type;
::new(static_cast<hook_type*>(container_detail::to_raw_pointer(p))) hook_type;
return (p);
*/
typedef typename NodeAlloc::multiallocation_chain multiallocation_chain;
if(n){
/*
NodePtr p = this->allocate_one();
Deallocator node_deallocator(p, this->node_alloc());
::boost::container::construct_in_place(this->node_alloc(), container_detail::addressof(p->m_data), it);
node_deallocator.release();
//This does not throw
typedef typename Node::hook_type hook_type;
::new(static_cast<hook_type*>(container_detail::to_raw_pointer(p))) hook_type;
return (p);
*/
typedef typename NodeAlloc::multiallocation_chain multiallocation_chain;
//Try to allocate memory in a single block
typedef typename multiallocation_chain::iterator multialloc_iterator;
multiallocation_chain mem;
this->node_alloc().allocate_individual(n, mem);
multialloc_iterator itbeg(mem.begin()), itlast(mem.last());
mem.clear();
Node *p = 0;
NodeAlloc &nalloc = this->node_alloc();
BOOST_TRY{
while(n--){
p = container_detail::to_raw_pointer(&*itbeg);
++itbeg;
//This can throw
Deallocator node_deallocator(p, nalloc);
boost::container::construct_in_place(nalloc, container_detail::addressof(p->m_data), beg);
++beg;
node_deallocator.release();
//This does not throw
typedef typename Node::hook_type hook_type;
::new(static_cast<hook_type*>(p)) hook_type;
//This can throw in some containers (predicate might throw)
inserter(*p);
//Try to allocate memory in a single block
typedef typename multiallocation_chain::iterator multialloc_iterator;
multiallocation_chain mem;
this->node_alloc().allocate_individual(n, mem);
multialloc_iterator itbeg(mem.begin()), itlast(mem.last());
mem.clear();
Node *p = 0;
NodeAlloc &nalloc = this->node_alloc();
BOOST_TRY{
while(n--){
p = container_detail::to_raw_pointer(&*itbeg);
++itbeg;
//This can throw
Deallocator node_deallocator(p, nalloc);
boost::container::construct_in_place(nalloc, container_detail::addressof(p->m_data), beg);
++beg;
node_deallocator.release();
//This does not throw
typedef typename Node::hook_type hook_type;
::new(static_cast<hook_type*>(p)) hook_type;
//This can throw in some containers (predicate might throw)
inserter(*p);
}
}
BOOST_CATCH(...){
mem.incorporate_after(mem.last(), &*itbeg, &*itlast, n);
this->node_alloc().deallocate_individual(mem);
BOOST_RETHROW
}
BOOST_CATCH_END
}
BOOST_CATCH(...){
mem.incorporate_after(mem.last(), &*itbeg, &*itlast, n);
this->node_alloc().deallocate_individual(mem);
BOOST_RETHROW
}
BOOST_CATCH_END
}
void clear(allocator_v1)