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/7969 #7969],
[@https://svn.boost.org/trac/boost/ticket/8118 #8118], [@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/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] [endsect]

View File

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