From 609ae6cb4ec742914d8e9f69a1ab5cbd251839fd Mon Sep 17 00:00:00 2001 From: Daniel James Date: Sun, 14 Aug 2016 20:55:40 +0100 Subject: [PATCH] Expand out fill_buckets. --- include/boost/unordered/detail/equivalent.hpp | 59 ++++++++++-- include/boost/unordered/detail/table.hpp | 91 +------------------ include/boost/unordered/detail/unique.hpp | 36 +++++++- 3 files changed, 89 insertions(+), 97 deletions(-) diff --git a/include/boost/unordered/detail/equivalent.hpp b/include/boost/unordered/detail/equivalent.hpp index b7b40f1a..c58108ab 100644 --- a/include/boost/unordered/detail/equivalent.hpp +++ b/include/boost/unordered/detail/equivalent.hpp @@ -628,17 +628,62 @@ namespace boost { namespace unordered { namespace detail { //////////////////////////////////////////////////////////////////////// // fill_buckets - template - void fill_buckets(iterator n, NodeCreator& creator) - { - while (n.node_) { + void copy_buckets(table const& src) { + node_constructor constructor(this->node_alloc()); + this->create_buckets(this->bucket_count_); + + for (iterator n = src.begin(); n.node_;) { std::size_t key_hash = n.node_->hash_; iterator group_end(n.node_->group_prev_->next_); - - iterator pos = this->add_node(creator.create(*n), key_hash, iterator()); + constructor.construct_with_value2(*n); + iterator pos = this->add_node(constructor, key_hash, iterator()); for (++n; n != group_end; ++n) { - this->add_node(creator.create(*n), key_hash, pos); + constructor.construct_with_value2(*n); + this->add_node(constructor, key_hash, pos); + } + } + } + + void move_buckets(table& src) { + node_constructor constructor(this->node_alloc()); + this->create_buckets(this->bucket_count_); + + for (iterator n = src.begin(); n.node_;) { + std::size_t key_hash = n.node_->hash_; + iterator group_end(n.node_->group_prev_->next_); + constructor.construct_with_value2(boost::move(*n)); + iterator pos = this->add_node(constructor, key_hash, iterator()); + for (++n; n != group_end; ++n) + { + constructor.construct_with_value2(boost::move(*n)); + this->add_node(constructor, key_hash, pos); + } + } + } + + void assign_buckets(table const& src) { + node_holder holder(*this); + for (iterator n = src.begin(); n.node_;) { + std::size_t key_hash = n.node_->hash_; + iterator group_end(n.node_->group_prev_->next_); + iterator pos = this->add_node(holder.copy_of(*n), key_hash, iterator()); + for (++n; n != group_end; ++n) + { + this->add_node(holder.copy_of(*n), key_hash, pos); + } + } + } + + void move_assign_buckets(table& src) { + node_holder holder(*this); + for (iterator n = src.begin(); n.node_;) { + std::size_t key_hash = n.node_->hash_; + iterator group_end(n.node_->group_prev_->next_); + iterator pos = this->add_node(holder.move_copy_of(*n), key_hash, iterator()); + for (++n; n != group_end; ++n) + { + this->add_node(holder.move_copy_of(*n), key_hash, pos); } } } diff --git a/include/boost/unordered/detail/table.hpp b/include/boost/unordered/detail/table.hpp index a337f45b..7a0584f7 100644 --- a/include/boost/unordered/detail/table.hpp +++ b/include/boost/unordered/detail/table.hpp @@ -68,70 +68,6 @@ namespace boost { namespace unordered { namespace detail { value_base& operator=(value_base const&); }; - template - struct copy_nodes - { - typedef boost::unordered::detail::allocator_traits - node_allocator_traits; - - node_constructor constructor; - - explicit copy_nodes(NodeAlloc& a) : constructor(a) {} - - typename node_allocator_traits::pointer create( - typename node_allocator_traits::value_type::value_type const& v) - { - constructor.construct_with_value2(v); - return constructor.release(); - } - }; - - template - struct move_nodes - { - typedef boost::unordered::detail::allocator_traits - node_allocator_traits; - - node_constructor constructor; - - explicit move_nodes(NodeAlloc& a) : constructor(a) {} - - typename node_allocator_traits::pointer create( - typename node_allocator_traits::value_type::value_type& v) - { - constructor.construct_with_value2(boost::move(v)); - return constructor.release(); - } - }; - - template - struct assign_nodes - { - node_holder holder; - - explicit assign_nodes(Buckets& b) : holder(b) {} - - typename Buckets::node_pointer create( - typename Buckets::value_type const& v) - { - return holder.copy_of(v); - } - }; - - template - struct move_assign_nodes - { - node_holder holder; - - explicit move_assign_nodes(Buckets& b) : holder(b) {} - - typename Buckets::node_pointer create( - typename Buckets::value_type& v) - { - return holder.move_copy_of(v); - } - }; - template struct table : boost::unordered::detail::functions< @@ -391,9 +327,7 @@ namespace boost { namespace unordered { namespace detail { void init(table const& x) { if (x.size_) { - create_buckets(bucket_count_); - copy_nodes node_creator(node_alloc()); - static_cast(this)->fill_buckets(x.begin(), node_creator); + static_cast(this)->copy_buckets(x); } } @@ -404,11 +338,7 @@ namespace boost { namespace unordered { namespace detail { } else if(x.size_) { // TODO: Could pick new bucket size? - create_buckets(bucket_count_); - - move_nodes node_creator(node_alloc()); - node_holder nodes(x); - static_cast(this)->fill_buckets(nodes.begin(), node_creator); + static_cast(this)->move_buckets(x); } } @@ -650,11 +580,7 @@ namespace boost { namespace unordered { namespace detail { clear_buckets(); } - // assign_nodes takes ownership of the container's elements, - // assigning to them if possible, and deleting any that are - // left over. - assign_nodes node_creator(*this); - static_cast(this)->fill_buckets(x.begin(), node_creator); + static_cast(this)->assign_buckets(x); } void assign(table const& x, true_type) @@ -679,9 +605,7 @@ namespace boost { namespace unordered { namespace detail { // Finally copy the elements. if (x.size_) { - create_buckets(bucket_count_); - copy_nodes node_creator(node_alloc()); - static_cast(this)->fill_buckets(x.begin(), node_creator); + static_cast(this)->copy_buckets(x); } } } @@ -735,12 +659,7 @@ namespace boost { namespace unordered { namespace detail { clear_buckets(); } - // move_assign_nodes takes ownership of the container's - // elements, assigning to them if possible, and deleting - // any that are left over. - move_assign_nodes
node_creator(*this); - node_holder nodes(x); - static_cast(this)->fill_buckets(nodes.begin(), node_creator); + static_cast(this)->move_assign_buckets(x); } } diff --git a/include/boost/unordered/detail/unique.hpp b/include/boost/unordered/detail/unique.hpp index a318d0b3..ef0ce445 100644 --- a/include/boost/unordered/detail/unique.hpp +++ b/include/boost/unordered/detail/unique.hpp @@ -582,11 +582,39 @@ namespace boost { namespace unordered { namespace detail { //////////////////////////////////////////////////////////////////////// // fill_buckets - template - void fill_buckets(iterator n, NodeCreator& creator) + void copy_buckets(table const& src) { + node_constructor constructor(this->node_alloc()); + this->create_buckets(this->bucket_count_); + + for(iterator n = src.begin(); n.node_; ++n) { + constructor.construct_with_value2(*n); + this->add_node(constructor, n.node_->hash_); + } + } + + void move_buckets(table& src) { + node_constructor constructor(this->node_alloc()); + this->create_buckets(this->bucket_count_); + + for(iterator n = src.begin(); n.node_; ++n) { + constructor.construct_with_value2(boost::move(*n)); + this->add_node(constructor, n.node_->hash_); + } + } + + void assign_buckets(table const& src) { - for (; n.node_; ++n) { - this->add_node(creator.create(*n), n.node_->hash_); + node_holder holder(*this); + for(iterator n = src.begin(); n.node_; ++n) { + this->add_node(holder.copy_of(*n), n.node_->hash_); + } + } + + void move_assign_buckets(table& src) + { + node_holder holder(*this); + for(iterator n = src.begin(); n.node_; ++n) { + this->add_node(holder.move_copy_of(*n), n.node_->hash_); } }