diff --git a/include/boost/unordered/detail/fca.hpp b/include/boost/unordered/detail/fca.hpp index a1d14d95..174ff4be 100644 --- a/include/boost/unordered/detail/fca.hpp +++ b/include/boost/unordered/detail/fca.hpp @@ -494,11 +494,25 @@ namespace boost { group_pointer groups; public: + grouped_bucket_array() + : empty_value( + empty_init_t(), node_allocator_type()), + size_index_(0), size_(0), buckets(), groups() + { + } + grouped_bucket_array(size_type n, const Allocator& al) : empty_value(empty_init_t(), al), - size_index_(size_policy::size_index(n)), - size_(size_policy::size(size_index_)), buckets(), groups() + size_index_(0), + size_(0), buckets(), groups() { + if (n == 0) { + return; + } + + size_index_ = size_policy::size_index(n); + size_ = size_policy::size(size_index_); + bucket_allocator_type bucket_alloc = this->get_bucket_allocator(); group_allocator_type group_alloc = this->get_group_allocator(); diff --git a/include/boost/unordered/detail/implementation.hpp b/include/boost/unordered/detail/implementation.hpp index c81cf960..fad51a64 100644 --- a/include/boost/unordered/detail/implementation.hpp +++ b/include/boost/unordered/detail/implementation.hpp @@ -2075,9 +2075,16 @@ namespace boost { // From 6.3.1/13: // Only resize when size >= mlf_ * count - max_load_ = boost::unordered::detail::double_to_size( - floor(static_cast(mlf_) * - static_cast(buckets_.bucket_count()))); + std::size_t const bc = buckets_.bucket_count(); + + // it's important we do the `bc == 0` check here because the `mlf_` + // can be specified to be infinity. The operation `n * INF` is `INF` + // for all `n > 0` but NaN for `n == 0`. + // + max_load_ = + bc == 0 ? 0 + : boost::unordered::detail::double_to_size(floor( + static_cast(mlf_) * static_cast(bc))); } void max_load_factor(float z) @@ -2090,6 +2097,12 @@ namespace boost { //////////////////////////////////////////////////////////////////////// // Constructors + table() + : functions(hasher(), key_equal()), size_(0), mlf_(1.0f), + max_load_(0) + { + } + table(std::size_t num_buckets, hasher const& hf, key_equal const& eq, node_allocator_type const& a) : functions(hf, eq), size_(0), mlf_(1.0f), max_load_(0), @@ -2361,7 +2374,10 @@ namespace boost { template void move_assign(table& x, UniqueType is_unique, false_type) { - reserve(x.size_); + if (x.size_ > 0) { + reserve(x.size_); + } + if (node_alloc() == x.node_alloc()) { move_assign_equal_alloc(x); } else { @@ -2390,7 +2406,9 @@ namespace boost { { mlf_ = x.mlf_; recalculate_max_load(); - this->reserve_for_insert(x.size_); + if (x.size_ > 0) { + this->reserve_for_insert(x.size_); + } this->clear_impl(); } BOOST_CATCH(...) diff --git a/include/boost/unordered/unordered_map.hpp b/include/boost/unordered/unordered_map.hpp index 3e25a28a..d66c5394 100644 --- a/include/boost/unordered/unordered_map.hpp +++ b/include/boost/unordered/unordered_map.hpp @@ -1664,8 +1664,6 @@ namespace boost { template unordered_map::unordered_map() - : table_(boost::unordered::detail::default_bucket_count, hasher(), - key_equal(), allocator_type()) { } @@ -2147,8 +2145,6 @@ namespace boost { template unordered_multimap::unordered_multimap() - : table_(boost::unordered::detail::default_bucket_count, hasher(), - key_equal(), allocator_type()) { } diff --git a/include/boost/unordered/unordered_set.hpp b/include/boost/unordered/unordered_set.hpp index 82d323c6..ed736c21 100644 --- a/include/boost/unordered/unordered_set.hpp +++ b/include/boost/unordered/unordered_set.hpp @@ -1266,8 +1266,6 @@ namespace boost { //////////////////////////////////////////////////////////////////////////// template unordered_set::unordered_set() - : table_(boost::unordered::detail::default_bucket_count, hasher(), - key_equal(), allocator_type()) { } @@ -1664,8 +1662,6 @@ namespace boost { template unordered_multiset::unordered_multiset() - : table_(boost::unordered::detail::default_bucket_count, hasher(), - key_equal(), allocator_type()) { }