diff --git a/include/boost/unordered/detail/allocate.hpp b/include/boost/unordered/detail/allocate.hpp index 5574c158..83e650ed 100644 --- a/include/boost/unordered/detail/allocate.hpp +++ b/include/boost/unordered/detail/allocate.hpp @@ -1104,76 +1104,6 @@ namespace boost { namespace unordered { namespace detail { namespace boost { namespace unordered { namespace detail { - //////////////////////////////////////////////////////////////////////////// - // - // construct_node/destroy_node - // - // Construct a node using the best available method. - -#if BOOST_UNORDERED_DETAIL_FULL_CONSTRUCT - - template - inline void construct_node(Alloc& a, T* p, BOOST_UNORDERED_EMPLACE_ARGS) - { - boost::unordered::detail::allocator_traits::construct( - a, p, BOOST_UNORDERED_EMPLACE_FORWARD); - } - - template - inline void destroy_node(Alloc& a, T* p) - { - boost::unordered::detail::allocator_traits::destroy(a, p); - } - -#else - - template - struct value_construct - { - typedef BOOST_DEDUCED_TYPENAME AllocTraits::allocator_type allocator; - - allocator& alloc; - T* ptr; - - value_construct(allocator& a, T* p) : alloc(a), ptr(p) - { - AllocTraits::construct(alloc, ptr, T()); - } - - void release() - { - ptr = 0; - } - - ~value_construct() - { - if (ptr) AllocTraits::destroy(alloc, ptr); - } - - private: - value_construct(value_construct const&); - value_construct& operator=(value_construct const&); - }; - - template - inline void construct_node(Alloc& a, T* p, BOOST_UNORDERED_EMPLACE_ARGS) - { - value_construct, T> - construct_guard(a, p); - boost::unordered::detail::construct_impl( - p->value_ptr(), BOOST_UNORDERED_EMPLACE_FORWARD); - construct_guard.release(); - } - - template - inline void destroy_node(Alloc& a, T* p) - { - boost::unordered::detail::destroy(p->value_ptr()); - boost::unordered::detail::allocator_traits::destroy(a, p); - } - -#endif - //////////////////////////////////////////////////////////////////////////// // // array_constructor diff --git a/include/boost/unordered/detail/buckets.hpp b/include/boost/unordered/detail/buckets.hpp index 85681a68..78ee0a56 100644 --- a/include/boost/unordered/detail/buckets.hpp +++ b/include/boost/unordered/detail/buckets.hpp @@ -53,14 +53,16 @@ namespace boost { namespace unordered { namespace detail { node_allocator& alloc_; node_pointer node_; - bool constructed_; + bool node_constructed_; + bool value_constructed_; public: node_constructor(node_allocator& n) : alloc_(n), node_(), - constructed_(false) + node_constructed_(false), + value_constructed_(false) { } @@ -71,36 +73,27 @@ namespace boost { namespace unordered { namespace detail { template void construct_value(BOOST_UNORDERED_EMPLACE_ARGS) { - BOOST_ASSERT(node_ && !constructed_); - boost::unordered::detail::construct_node(alloc_, - boost::addressof(*node_), BOOST_UNORDERED_EMPLACE_FORWARD); - node_->init(static_cast(node_)); - constructed_ = true; + BOOST_ASSERT(node_ && node_constructed_ && !value_constructed_); + boost::unordered::detail::construct_impl( + node_->value_ptr(), BOOST_UNORDERED_EMPLACE_FORWARD); + value_constructed_ = true; } template void construct_value2(BOOST_FWD_REF(A0) a0) { - BOOST_ASSERT(node_ && !constructed_); - - boost::unordered::detail::construct_node(alloc_, - boost::addressof(*node_), + BOOST_ASSERT(node_ && node_constructed_ && !value_constructed_); + boost::unordered::detail::construct_impl( + node_->value_ptr(), BOOST_UNORDERED_EMPLACE_ARGS1(boost::forward(a0))); - - constructed_ = true; - node_->init(static_cast(node_)); + value_constructed_ = true; } value_type const& value() const { - BOOST_ASSERT(node_ && constructed_); + BOOST_ASSERT(node_ && node_constructed_ && value_constructed_); return node_->value(); } - node_pointer get() - { - return node_; - } - // no throw node_pointer release() { @@ -118,8 +111,12 @@ namespace boost { namespace unordered { namespace detail { node_constructor::~node_constructor() { if (node_) { - if (constructed_) { - boost::unordered::detail::destroy_node(alloc_, + if (value_constructed_) { + boost::unordered::detail::destroy(node_->value_ptr()); + } + + if (node_constructed_) { + node_allocator_traits::destroy(alloc_, boost::addressof(*node_)); } @@ -131,13 +128,24 @@ namespace boost { namespace unordered { namespace detail { void node_constructor::construct_node() { if(!node_) { - constructed_ = false; + node_constructed_ = false; + value_constructed_ = false; + node_ = node_allocator_traits::allocate(alloc_, 1); + + node_allocator_traits::construct(alloc_, + boost::addressof(*node_), node()); + node_->init(static_cast(node_)); + node_constructed_ = true; } - else if (constructed_) { - boost::unordered::detail::destroy_node(alloc_, - boost::addressof(*node_)); - constructed_ = false; + else { + BOOST_ASSERT(node_constructed_); + + if (value_constructed_) + { + boost::unordered::detail::destroy(node_->value_ptr()); + value_constructed_ = false; + } } } @@ -175,16 +183,6 @@ namespace boost { namespace unordered { namespace detail { enum { extra_node = false }; }; - - template - struct node_base - { - typedef LinkPointer link_pointer; - link_pointer next_; - - node_base() : next_() {} - }; - }}} namespace boost { namespace unordered { namespace iterator_detail { @@ -720,14 +718,6 @@ namespace boost { namespace unordered { namespace detail { node_constructor a(this->node_alloc()); a.construct_node(); - // Since this node is just to mark the beginning it doesn't - // contain a value, so just construct node::node_base - // which containers the pointer to the next element. - node_allocator_traits::construct(node_alloc(), - static_cast( - boost::addressof(*a.get())), - typename node::node_base()); - (constructor.get() + static_cast(this->bucket_count_))->next_ = a.release(); @@ -772,8 +762,9 @@ namespace boost { namespace unordered { namespace detail { inline void delete_node(c_iterator n) { - boost::unordered::detail::destroy_node( - node_alloc(), boost::addressof(*n.node_)); + boost::unordered::detail::destroy(n.node_->value_ptr()); + node_allocator_traits::destroy(node_alloc(), + boost::addressof(*n.node_)); node_allocator_traits::deallocate(node_alloc(), n.node_, 1); --size_; } @@ -795,8 +786,7 @@ namespace boost { namespace unordered { namespace detail { inline void delete_extra_node(bucket_pointer) {} inline void delete_extra_node(node_pointer n) { - node_allocator_traits::destroy(node_alloc(), - static_cast(boost::addressof(*n))); + node_allocator_traits::destroy(node_alloc(), boost::addressof(*n)); node_allocator_traits::deallocate(node_alloc(), n, 1); } diff --git a/include/boost/unordered/detail/equivalent.hpp b/include/boost/unordered/detail/equivalent.hpp index 5cbf6a7c..54ace45f 100644 --- a/include/boost/unordered/detail/equivalent.hpp +++ b/include/boost/unordered/detail/equivalent.hpp @@ -22,44 +22,20 @@ namespace boost { namespace unordered { namespace detail { template struct grouped_node : - boost::unordered::detail::node_base< - typename ::boost::unordered::detail::rebind_wrap< - A, grouped_node >::type::pointer - >, boost::unordered::detail::value_base { typedef typename ::boost::unordered::detail::rebind_wrap< A, grouped_node >::type::pointer link_pointer; - typedef boost::unordered::detail::node_base node_base; + link_pointer next_; link_pointer group_prev_; std::size_t hash_; -#if BOOST_UNORDERED_DETAIL_FULL_CONSTRUCT - template - explicit grouped_node(BOOST_UNORDERED_EMPLACE_ARGS) : - node_base(), - group_prev_(), - hash_(0) - { - boost::unordered::detail::construct_impl( - this->value_ptr(), BOOST_UNORDERED_EMPLACE_FORWARD); - } - - ~grouped_node() { - boost::unordered::detail::destroy(this->value_ptr()); - } - - grouped_node(grouped_node const&) { - assert(false); - } -#else grouped_node() : - node_base(), + next_(), group_prev_(), hash_(0) {} -#endif void init(link_pointer self) { @@ -76,37 +52,16 @@ namespace boost { namespace unordered { namespace detail { boost::unordered::detail::ptr_bucket { typedef boost::unordered::detail::ptr_bucket bucket_base; - typedef bucket_base node_base; typedef ptr_bucket* link_pointer; link_pointer group_prev_; std::size_t hash_; -#if BOOST_UNORDERED_DETAIL_FULL_CONSTRUCT - template - explicit grouped_ptr_node(BOOST_UNORDERED_EMPLACE_ARGS) : - bucket_base(), - group_prev_(0), - hash_(0) - { - boost::unordered::detail::construct_impl( - this->value_ptr(), BOOST_UNORDERED_EMPLACE_FORWARD); - } - - ~grouped_ptr_node() { - boost::unordered::detail::destroy(this->value_ptr()); - } - - grouped_ptr_node(grouped_ptr_node const&) { - assert(false); - } -#else grouped_ptr_node() : bucket_base(), group_prev_(0), hash_(0) {} -#endif void init(link_pointer self) { diff --git a/include/boost/unordered/detail/unique.hpp b/include/boost/unordered/detail/unique.hpp index 10db58fa..34cfea25 100644 --- a/include/boost/unordered/detail/unique.hpp +++ b/include/boost/unordered/detail/unique.hpp @@ -24,41 +24,18 @@ namespace boost { namespace unordered { namespace detail { template struct unique_node : - boost::unordered::detail::node_base< - typename ::boost::unordered::detail::rebind_wrap< - A, unique_node >::type::pointer - >, boost::unordered::detail::value_base { typedef typename ::boost::unordered::detail::rebind_wrap< A, unique_node >::type::pointer link_pointer; - typedef boost::unordered::detail::node_base node_base; + link_pointer next_; std::size_t hash_; -#if BOOST_UNORDERED_DETAIL_FULL_CONSTRUCT - template - explicit unique_node(BOOST_UNORDERED_EMPLACE_ARGS) : - node_base(), - hash_(0) - { - boost::unordered::detail::construct_impl( - this->value_ptr(), BOOST_UNORDERED_EMPLACE_FORWARD); - } - - ~unique_node() { - boost::unordered::detail::destroy(this->value_ptr()); - } - - unique_node(unique_node const&) { - BOOST_ASSERT(false); - } -#else unique_node() : - node_base(), + next_(), hash_(0) {} -#endif void init(link_pointer) { @@ -74,34 +51,14 @@ namespace boost { namespace unordered { namespace detail { boost::unordered::detail::ptr_bucket { typedef boost::unordered::detail::ptr_bucket bucket_base; - typedef bucket_base node_base; typedef ptr_bucket* link_pointer; std::size_t hash_; -#if BOOST_UNORDERED_DETAIL_FULL_CONSTRUCT - template - explicit ptr_node(BOOST_UNORDERED_EMPLACE_ARGS) : - bucket_base(), - hash_(0) - { - boost::unordered::detail::construct_impl( - this->value_ptr(), BOOST_UNORDERED_EMPLACE_FORWARD); - } - - ~ptr_node() { - boost::unordered::detail::destroy(this->value_ptr()); - } - - ptr_node(ptr_node const&) { - BOOST_ASSERT(false); - } -#else ptr_node() : bucket_base(), hash_(0) {} -#endif void init(link_pointer) {