From e92f7d86c1599dde290ac5c70f8ca44bbcd0c96f Mon Sep 17 00:00:00 2001 From: Daniel James Date: Sun, 14 Aug 2016 20:55:40 +0100 Subject: [PATCH] Remove array_constructor. I was using SFINAE for everything because some old compilers had issues. But that's hopefully in the distant past now. --- include/boost/unordered/detail/allocate.hpp | 71 +-------------------- include/boost/unordered/detail/table.hpp | 65 ++++++++++++------- 2 files changed, 43 insertions(+), 93 deletions(-) diff --git a/include/boost/unordered/detail/allocate.hpp b/include/boost/unordered/detail/allocate.hpp index d56bcaa0..a83edad2 100644 --- a/include/boost/unordered/detail/allocate.hpp +++ b/include/boost/unordered/detail/allocate.hpp @@ -31,6 +31,7 @@ #include #include #include +#include #include #include #include @@ -1248,76 +1249,6 @@ namespace boost { namespace unordered { namespace detail { namespace func { } }}}} -namespace boost { namespace unordered { namespace detail { - - //////////////////////////////////////////////////////////////////////////// - // - // array_constructor - // - // Allocate and construct an array in an exception safe manner, and - // clean up if an exception is thrown before the container takes charge - // of it. - - template - struct array_constructor - { - typedef boost::unordered::detail::allocator_traits traits; - typedef typename traits::pointer pointer; - - Allocator& alloc_; - pointer ptr_; - pointer constructed_; - std::size_t length_; - - array_constructor(Allocator& a) - : alloc_(a), ptr_(), constructed_(), length_(0) - { - constructed_ = pointer(); - ptr_ = pointer(); - } - - ~array_constructor() { - if (ptr_) { - for(pointer p = ptr_; p != constructed_; ++p) { - boost::unordered::detail::func::destroy( - boost::addressof(*p)); - } - - traits::deallocate(alloc_, ptr_, length_); - } - } - - template - void construct(V const& v, std::size_t l) - { - BOOST_ASSERT(!ptr_); - length_ = l; - ptr_ = traits::allocate(alloc_, length_); - pointer end = ptr_ + static_cast(length_); - for(constructed_ = ptr_; constructed_ != end; ++constructed_) { - new ((void*) boost::addressof(*constructed_)) V(v); - } - } - - pointer get() const - { - return ptr_; - } - - pointer release() - { - pointer p(ptr_); - ptr_ = pointer(); - return p; - } - - private: - - array_constructor(array_constructor const&); - array_constructor& operator=(array_constructor const&); - }; -}}} - #if defined(BOOST_MSVC) #pragma warning(pop) #endif diff --git a/include/boost/unordered/detail/table.hpp b/include/boost/unordered/detail/table.hpp index de7baa57..ab4000b4 100644 --- a/include/boost/unordered/detail/table.hpp +++ b/include/boost/unordered/detail/table.hpp @@ -345,34 +345,53 @@ namespace boost { namespace unordered { namespace detail { void create_buckets(std::size_t new_count) { - boost::unordered::detail::array_constructor - constructor(bucket_alloc()); - - // Creates an extra bucket to act as the start node. - constructor.construct(bucket(), new_count + 1); + std::size_t length = new_count + 1; + bucket_pointer new_buckets = bucket_allocator_traits::allocate( + bucket_alloc(), length); + bucket_pointer constructed = new_buckets; - if (buckets_) - { - // Copy the nodes to the new buckets, including the dummy - // node if there is one. - (constructor.get() + - static_cast(new_count))->next_ = - (buckets_ + static_cast( - bucket_count_))->next_; - destroy_buckets(); - } - else if (bucket::extra_node) - { - node_constructor a(node_alloc()); - a.create_node(); + BOOST_TRY { + bucket_pointer end = new_buckets + + static_cast(length); + for(; constructed != end; ++constructed) { + new ((void*) boost::addressof(*constructed)) bucket(); + } - (constructor.get() + - static_cast(new_count))->next_ = - a.release(); + if (buckets_) + { + // Copy the nodes to the new buckets, including the dummy + // node if there is one. + (new_buckets + + static_cast(new_count))->next_ = + (buckets_ + static_cast( + bucket_count_))->next_; + destroy_buckets(); + } + else if (bucket::extra_node) + { + node_constructor a(node_alloc()); + a.create_node(); + + (new_buckets + + static_cast(new_count))->next_ = + a.release(); + } } + BOOST_CATCH(...) { + for(bucket_pointer p = new_buckets; p != constructed; ++p) { + boost::unordered::detail::func::destroy( + boost::addressof(*p)); + } + + bucket_allocator_traits::deallocate(bucket_alloc(), + new_buckets, length); + + BOOST_RETHROW; + } + BOOST_CATCH_END bucket_count_ = new_count; - buckets_ = constructor.release(); + buckets_ = new_buckets; recalculate_max_load(); }