Please see the sample code below. =========================== sample code =========================== #include <iostream> #include <unordered_set> template<typename S> void print(const S& s, typename S::const_iterator& it) { std::cout << "size = " << s.size() << '\n'; std::cout << "bucket_count = " << s.bucket_count() << '\n'; std::cout << "load_factor = " << s.load_factor() << '\n'; std::cout << "max_load_factor = " << s.max_load_factor() << '\n'; std::cout << "size limit = " << s.bucket_count() * s.max_load_factor() << "\n\n"; for (std::size_t i = 0; it != s.end() && i < s.size() / 2; ++i, ++it) { std::cout << *it << ' '; } std::cout << "\n\n"; } int main() { std::unordered_set<int> s; const auto max = 10; s.reserve(max); for (int i = 0; i < max; ++i) { s.insert(i); } auto it = s.cbegin(); print(s, it); s.insert(max); print(s, it); } =========================== sample code =========================== =========================== output =========================== size = 10 bucket_count = 11 load_factor = 0.909091 max_load_factor = 1 size limit = 11 9 8 7 6 5 size = 11 bucket_count = 23 load_factor = 0.478261 max_load_factor = 1 size limit = 23 4 5 6 7 8 =========================== output =========================== cf. https://wandbox.org/permlink/QhPfL6787GV8RYXV The C++17 standard 26.2.7[unord.req]/p.15 says, The insert and emplace members shall not affect the validity of iterators if (N+n) <= z * B, where N is the number of elements in the container prior to the insert operation, n is the number of elements inserted, B is the container's bucket count, and z is the container’s maximum load factor. So, I think that the sample code above should never rehash.
This changed with https://wg21.link/lwg2156
Author: fdumont Date: Tue Sep 18 20:36:16 2018 New Revision: 264413 URL: https://gcc.gnu.org/viewcvs?rev=264413&root=gcc&view=rev Log: 2018-09-18 François Dumont <fdumont@gcc.gnu.org> PR libstdc++/87135 * src/c++11/hashtable_c++0x.cc: (_Prime_rehash_policy::_M_next_bkt): Return a prime no smaller than requested size, but not necessarily greater. (_Prime_rehash_policy::_M_need_rehash): Rehash only if target size is strictly greater than next resize threshold. * testsuite/23_containers/unordered_map/modifiers/reserve.cc: Adapt test to validate that there is no rehash as long as number of insertion is lower or equal to the reserved number of elements. Modified: trunk/libstdc++-v3/ChangeLog trunk/libstdc++-v3/src/c++11/hashtable_c++0x.cc trunk/libstdc++-v3/testsuite/23_containers/unordered_map/modifiers/reserve.cc
Rehash policy has been reviewed, rehash will take place only when reserved size is overwhelmed.
Author: fdumont Date: Fri Sep 21 20:39:07 2018 New Revision: 264494 URL: https://gcc.gnu.org/viewcvs?rev=264494&root=gcc&view=rev Log: 2018-09-21 François Dumont <fdumont@gcc.gnu.org> PR libstdc++/87135 * src/c++11/hashtable_c++0x.cc (_Prime_rehash_policy::_M_next_bkt): Use __builtin_floor to compute _M_next_resize. * testsuite/23_containers/unordered_set/hash_policy/71181.cc: Adapt. * testsuite/23_containers/unordered_set/hash_policy/prime_rehash.cc: Adapt. Modified: trunk/libstdc++-v3/ChangeLog trunk/libstdc++-v3/src/c++11/hashtable_c++0x.cc trunk/libstdc++-v3/testsuite/23_containers/unordered_set/hash_policy/71181.cc trunk/libstdc++-v3/testsuite/23_containers/unordered_set/hash_policy/prime_rehash.cc