Просмотр исходного кода

dense_map: fix an issue when erasing movable keys

Michele Caini 3 лет назад
Родитель
Сommit
c26558cd6d
2 измененных файлов с 20 добавлено и 1 удалено
  1. 1 1
      src/entt/container/dense_map.hpp
  2. 19 0
      test/entt/container/dense_map.cpp

+ 1 - 1
src/entt/container/dense_map.hpp

@@ -331,8 +331,8 @@ class dense_map {
 
 
     void move_and_pop(const std::size_t pos) {
     void move_and_pop(const std::size_t pos) {
         if(const auto last = size() - 1u; pos != last) {
         if(const auto last = size() - 1u; pos != last) {
-            packed.first()[pos] = std::move(packed.first().back());
             size_type *curr = sparse.first().data() + key_to_bucket(packed.first().back().element.first);
             size_type *curr = sparse.first().data() + key_to_bucket(packed.first().back().element.first);
+            packed.first()[pos] = std::move(packed.first().back());
             for(; *curr != last; curr = &packed.first()[*curr].next) {}
             for(; *curr != last; curr = &packed.first()[*curr].next) {}
             *curr = pos;
             *curr = pos;
         }
         }

+ 19 - 0
test/entt/container/dense_map.cpp

@@ -2,6 +2,7 @@
 #include <functional>
 #include <functional>
 #include <iterator>
 #include <iterator>
 #include <memory>
 #include <memory>
+#include <string>
 #include <tuple>
 #include <tuple>
 #include <type_traits>
 #include <type_traits>
 #include <utility>
 #include <utility>
@@ -788,6 +789,24 @@ TEST(DenseMap, Erase) {
     ASSERT_EQ(map.size(), 0u);
     ASSERT_EQ(map.size(), 0u);
 }
 }
 
 
+TEST(DenseMap, EraseWithMovableKeyValue) {
+    static constexpr std::size_t minimum_bucket_count = 8u;
+    entt::dense_map<std::string, std::size_t> map;
+
+    map.emplace("0", 0u);
+    map.emplace("1", 1u);
+
+    ASSERT_EQ(map.bucket_count(), minimum_bucket_count);
+    ASSERT_EQ(map.size(), 2u);
+
+    auto it = map.erase(map.find("0"));
+
+    ASSERT_EQ(it->first, "1");
+    ASSERT_EQ(it->second, 1u);
+    ASSERT_EQ(map.size(), 1u);
+    ASSERT_FALSE(map.contains("0"));
+}
+
 TEST(DenseMap, EraseFromBucket) {
 TEST(DenseMap, EraseFromBucket) {
     static constexpr std::size_t minimum_bucket_count = 8u;
     static constexpr std::size_t minimum_bucket_count = 8u;
     entt::dense_map<std::size_t, std::size_t, entt::identity> map;
     entt::dense_map<std::size_t, std::size_t, entt::identity> map;