From e7b1fde9684e5571ce1af110c30376affd18e912 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ion=20Gazta=C3=B1aga?= Date: Mon, 24 Jun 2013 19:13:16 +0000 Subject: [PATCH] Trivial fix for empty ranges in node_alloc_holder [SVN r84902] --- doc/container.qbk | 3 +- .../container/detail/node_alloc_holder.hpp | 80 ++++++++++--------- 2 files changed, 43 insertions(+), 40 deletions(-) diff --git a/doc/container.qbk b/doc/container.qbk index 2018ed5..ff18ba4 100644 --- a/doc/container.qbk +++ b/doc/container.qbk @@ -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] diff --git a/include/boost/container/detail/node_alloc_holder.hpp b/include/boost/container/detail/node_alloc_holder.hpp index 7d851c0..5a94a68 100644 --- a/include/boost/container/detail/node_alloc_holder.hpp +++ b/include/boost/container/detail/node_alloc_holder.hpp @@ -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(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(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(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(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)