diff --git a/include/tsl/robin_hash.h b/include/tsl/robin_hash.h index ed61f86..0ed0f74 100644 --- a/include/tsl/robin_hash.h +++ b/include/tsl/robin_hash.h @@ -623,14 +623,7 @@ public: m_min_load_factor(other.m_min_load_factor), m_try_skrink_on_next_insert(other.m_try_skrink_on_next_insert) { - other.GrowthPolicy::clear(); - other.m_buckets_data.clear(); - other.m_buckets = static_empty_bucket_ptr(); - other.m_bucket_count = 0; - other.m_nb_elements = 0; - other.m_load_threshold = 0; - other.m_grow_on_next_insert = false; - other.m_try_skrink_on_next_insert = false; + other.clear_and_shrink(); } robin_hash& operator=(const robin_hash& other) { @@ -725,12 +718,17 @@ public: * Modifiers */ void clear() noexcept { - for(auto& bucket: m_buckets_data) { - bucket.clear(); + if(m_min_load_factor > 0.0f) { + clear_and_shrink(); + } + else { + for(auto& bucket: m_buckets_data) { + bucket.clear(); + } + + m_nb_elements = 0; + m_grow_on_next_insert = false; } - - m_nb_elements = 0; - m_grow_on_next_insert = false; } @@ -1322,6 +1320,18 @@ private: new_table.swap(*this); } + // Same as rehash(0) but noexcept and faster. + void clear_and_shrink() noexcept { + GrowthPolicy::clear(); + m_buckets_data.clear(); + m_buckets = static_empty_bucket_ptr(); + m_bucket_count = 0; + m_nb_elements = 0; + m_load_threshold = 0; + m_grow_on_next_insert = false; + m_try_skrink_on_next_insert = false; + } + void insert_value_on_rehash(std::size_t ibucket, distance_type dist_from_ideal_bucket, truncated_hash_type hash, value_type&& value) { diff --git a/tests/robin_map_tests.cpp b/tests/robin_map_tests.cpp index a3dcd89..15fccf2 100644 --- a/tests/robin_map_tests.cpp +++ b/tests/robin_map_tests.cpp @@ -646,6 +646,25 @@ BOOST_AUTO_TEST_CASE(test_clear) { BOOST_CHECK(map == (HMap({{5, -5}, {1, -1}, {2, -1}, {4, -4}, {3, -3}}))); } +BOOST_AUTO_TEST_CASE(test_clear_with_min_load_factor) { + // insert x values, clear map, test insert + using HMap = tsl::robin_map; + + const std::size_t nb_values = 1000; + auto map = utils::get_filled_hash_map(nb_values); + map.min_load_factor(0.1f); + + map.clear(); + BOOST_CHECK_EQUAL(map.bucket_count(), 0); + BOOST_CHECK_EQUAL(map.size(), 0); + BOOST_CHECK_EQUAL(std::distance(map.begin(), map.end()), 0); + + map.insert({5, -5}); + map.insert({{1, -1}, {2, -1}, {4, -4}, {3, -3}}); + + BOOST_CHECK(map == (HMap({{5, -5}, {1, -1}, {2, -1}, {4, -4}, {3, -3}}))); +} + /** * iterator.value()