diff --git a/include/boost/unordered/detail/implementation.hpp b/include/boost/unordered/detail/implementation.hpp index 7db2d341..d25026fe 100644 --- a/include/boost/unordered/detail/implementation.hpp +++ b/include/boost/unordered/detail/implementation.hpp @@ -3197,6 +3197,31 @@ namespace boost { other.max_load_ = 0; } + // For use in the constructor when allocators might be different. + void move_construct_buckets(table& src) + { + if (this->node_alloc() == src.node_alloc()) { + move_buckets_from(src); + } else { + this->create_buckets(this->bucket_count_); + link_pointer prev = this->get_previous_start(); + std::size_t last_bucket = this->bucket_count_; + for (node_pointer n = src.begin(); n; n = next_node(n)) { + std::size_t bucket = n->get_bucket(); + if (bucket != last_bucket) { + this->get_bucket(bucket)->next_ = prev; + } + node_pointer n2 = boost::unordered::detail::func::construct_node( + this->node_alloc(), boost::move(n->value())); + n2->bucket_info_ = n->bucket_info_; + prev->next_ = n2; + ++size_; + prev = n2; + last_bucket = bucket; + } + } + } + //////////////////////////////////////////////////////////////////////// // Delete/destruct @@ -3921,20 +3946,6 @@ namespace boost { } } - // TODO: Should be move_buckets_uniq - void move_buckets(table const& src) - { - this->create_buckets(this->bucket_count_); - - for (node_pointer n = src.begin(); n; n = next_node(n)) { - std::size_t key_hash = this->hash(this->get_key(n)); - this->add_node_unique( - boost::unordered::detail::func::construct_node( - this->node_alloc(), boost::move(n->value())), - key_hash); - } - } - void assign_buckets(table const& src, true_type) { node_holder holder(*this); @@ -4327,26 +4338,6 @@ namespace boost { } } - void move_buckets_equiv(table const& src) - { - this->create_buckets(this->bucket_count_); - - for (node_pointer n = src.begin(); n;) { - std::size_t key_hash = this->hash(this->get_key(n)); - node_pointer group_end(next_group(n)); - node_pointer pos = this->add_node_equiv( - boost::unordered::detail::func::construct_node( - this->node_alloc(), boost::move(n->value())), - key_hash, node_pointer()); - for (n = next_node(n); n != group_end; n = next_node(n)) { - this->add_node_equiv( - boost::unordered::detail::func::construct_node( - this->node_alloc(), boost::move(n->value())), - key_hash, pos); - } - } - } - void assign_buckets(table const& src, false_type) { node_holder holder(*this); diff --git a/include/boost/unordered/unordered_map.hpp b/include/boost/unordered/unordered_map.hpp index 345685a6..bae3aa2f 100644 --- a/include/boost/unordered/unordered_map.hpp +++ b/include/boost/unordered/unordered_map.hpp @@ -1424,12 +1424,7 @@ namespace boost { BOOST_RV_REF(unordered_map) other, allocator_type const& a) : table_(other.table_, a, boost::unordered::detail::move_tag()) { - if (table_.node_alloc() == other.table_.node_alloc()) { - table_.move_buckets_from(other.table_); - } else if (other.table_.size_) { - // TODO: Could pick new bucket size? - table_.move_buckets(other.table_); - } + table_.move_construct_buckets(other.table_); } #if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST) @@ -1908,12 +1903,7 @@ namespace boost { BOOST_RV_REF(unordered_multimap) other, allocator_type const& a) : table_(other.table_, a, boost::unordered::detail::move_tag()) { - if (table_.node_alloc() == other.table_.node_alloc()) { - table_.move_buckets_from(other.table_); - } else if (other.table_.size_) { - // TODO: Could pick new bucket size? - table_.move_buckets_equiv(other.table_); - } + table_.move_construct_buckets(other.table_); } #if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST) diff --git a/include/boost/unordered/unordered_set.hpp b/include/boost/unordered/unordered_set.hpp index b32607fb..e01c5586 100644 --- a/include/boost/unordered/unordered_set.hpp +++ b/include/boost/unordered/unordered_set.hpp @@ -1108,12 +1108,7 @@ namespace boost { BOOST_RV_REF(unordered_set) other, allocator_type const& a) : table_(other.table_, a, boost::unordered::detail::move_tag()) { - if (table_.node_alloc() == other.table_.node_alloc()) { - table_.move_buckets_from(other.table_); - } else if (other.table_.size_) { - // TODO: Could pick new bucket size? - table_.move_buckets(other.table_); - } + table_.move_construct_buckets(other.table_); } #if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST) @@ -1510,12 +1505,7 @@ namespace boost { BOOST_RV_REF(unordered_multiset) other, allocator_type const& a) : table_(other.table_, a, boost::unordered::detail::move_tag()) { - if (table_.node_alloc() == other.table_.node_alloc()) { - table_.move_buckets_from(other.table_); - } else if (other.table_.size_) { - // TODO: Could pick new bucket size? - table_.move_buckets_equiv(other.table_); - } + table_.move_construct_buckets(other.table_); } #if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)