@@ -1214,21 +1214,30 @@ class table : public std::conditional_t<is_map_v<T>, base_table_type_map<T>, bas
12141214 if (&other != this ) {
12151215 deallocate_buckets (); // deallocate before m_values is set (might have another allocator)
12161216 m_values = std::move (other.m_values );
1217+ other.m_values .clear ();
12171218
1218- // we can only reuse m_buckets over when both maps have the same allocator!
1219+ // we can only reuse m_buckets when both maps have the same allocator!
12191220 if (get_allocator () == other.get_allocator ()) {
12201221 m_buckets = std::exchange (other.m_buckets , nullptr );
1222+ m_num_buckets = std::exchange (other.m_num_buckets , 0 );
1223+ m_max_bucket_capacity = std::exchange (other.m_max_bucket_capacity , 0 );
1224+ m_shifts = std::exchange (other.m_shifts , initial_shifts);
1225+ m_max_load_factor = std::exchange (other.m_max_load_factor , default_max_load_factor);
1226+ m_hash = std::exchange (other.m_hash , {});
1227+ m_equal = std::exchange (other.m_equal , {});
12211228 } else {
1229+ // set max_load_factor *before* copying the other's buckets, so we have the same
1230+ // behavior
1231+ m_max_load_factor = other.m_max_load_factor ;
1232+
1233+ // copy_buckets sets m_buckets, m_num_buckets, m_max_bucket_capacity, m_shifts
12221234 copy_buckets (other);
1235+ // clear's the other's buckets so other is now already usable.
1236+ other.clear_buckets ();
1237+ m_hash = other.m_hash ;
1238+ m_equal = other.m_equal ;
12231239 }
1224-
1225- m_num_buckets = std::exchange (other.m_num_buckets , 0 );
1226- m_max_bucket_capacity = std::exchange (other.m_max_bucket_capacity , 0 );
1227- m_max_load_factor = std::exchange (other.m_max_load_factor , default_max_load_factor);
1228- m_hash = std::exchange (other.m_hash , {});
1229- m_equal = std::exchange (other.m_equal , {});
1230- m_shifts = std::exchange (other.m_shifts , initial_shifts);
1231- other.m_values .clear ();
1240+ // map "other" is now already usable, it's empty.
12321241 }
12331242 return *this ;
12341243 }
0 commit comments