Explorar el Código

dense_set: strong exception guarantee (emplace/insert)

Michele Caini hace 3 años
padre
commit
b63aebfdaf
Se han modificado 2 ficheros con 17 adiciones y 2 borrados
  1. 2 2
      src/entt/container/dense_set.hpp
  2. 15 0
      test/entt/container/dense_set.cpp

+ 2 - 2
src/entt/container/dense_set.hpp

@@ -275,8 +275,8 @@ class dense_set {
             return std::make_pair(it, false);
             return std::make_pair(it, false);
         }
         }
 
 
-        const auto next = std::exchange(sparse.first()[index], packed.first().size());
-        packed.first().emplace_back(next, std::forward<Other>(value));
+        packed.first().emplace_back(sparse.first()[index], std::forward<Other>(value));
+        sparse.first()[index] = packed.first().size() - 1u;
         rehash_if_required();
         rehash_if_required();
 
 
         return std::make_pair(--end(), true);
         return std::make_pair(--end(), true);

+ 15 - 0
test/entt/container/dense_set.cpp

@@ -832,6 +832,21 @@ TEST(DenseSet, ThrowingAllocator) {
     ASSERT_EQ(set.bucket_count(), minimum_bucket_count);
     ASSERT_EQ(set.bucket_count(), minimum_bucket_count);
     ASSERT_THROW(set.reserve(2u * set.bucket_count()), packed_exception);
     ASSERT_THROW(set.reserve(2u * set.bucket_count()), packed_exception);
     ASSERT_EQ(set.bucket_count(), minimum_bucket_count);
     ASSERT_EQ(set.bucket_count(), minimum_bucket_count);
+
+    packed_allocator::trigger_on_allocate = true;
+
+    ASSERT_THROW(set.emplace(), packed_exception);
+    ASSERT_FALSE(set.contains(0u));
+
+    packed_allocator::trigger_on_allocate = true;
+
+    ASSERT_THROW(set.emplace(std::size_t{}), packed_exception);
+    ASSERT_FALSE(set.contains(0u));
+
+    packed_allocator::trigger_on_allocate = true;
+
+    ASSERT_THROW(set.insert(0u), packed_exception);
+    ASSERT_FALSE(set.contains(0u));
 }
 }
 
 
 #if defined(ENTT_HAS_TRACKED_MEMORY_RESOURCE)
 #if defined(ENTT_HAS_TRACKED_MEMORY_RESOURCE)