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

added storage::batch overload for copy construction

Michele Caini 6 лет назад
Родитель
Сommit
d6911337f3
2 измененных файлов с 54 добавлено и 22 удалено
  1. 29 3
      src/entt/entity/storage.hpp
  2. 25 19
      test/entt/entity/storage.cpp

+ 29 - 3
src/entt/entity/storage.hpp

@@ -332,8 +332,8 @@ public:
     }
 
     /**
-     * @brief Assigns one or more entities to a storage and constructs their
-     * objects.
+     * @brief Assigns one or more entities to a storage and default constructs
+     * their objects.
      *
      * The object type must be at least move and default insertable.
      *
@@ -358,6 +358,30 @@ public:
         return begin();
     }
 
+    /**
+     * @brief Assigns one or more entities to a storage and copy constructs
+     * their objects.
+     *
+     * The object type must be at least move and copy insertable.
+     *
+     * @sa batch
+     *
+     * @tparam It Type of forward iterator.
+     * @param first An iterator to the first element of the range of entities.
+     * @param last An iterator past the last element of the range of entities.
+     * @param value The value to initialize the new objects with.
+     * @return An iterator to the list of instances just created and sorted the
+     * same of the entities.
+     */
+    template<typename It>
+    iterator_type batch(It first, It last, const object_type &value) {
+        const auto length = last - first;
+        instances.resize(instances.size() + length, value);
+        // entity goes after component in case constructor throws
+        underlying_type::batch(first, last);
+        return begin();
+    }
+
     /**
      * @brief Removes an entity from a storage and destroys its object.
      *
@@ -650,6 +674,8 @@ public:
     /**
      * @brief Assigns one or more entities to a storage.
      *
+     * The object type must be at least default constructible.
+     *
      * @warning
      * Attempting to assign an entity that already belongs to the storage
      * results in undefined behavior.<br/>
@@ -663,7 +689,7 @@ public:
      * same of the entities.
      */
     template<typename It>
-    iterator_type batch(It first, It last) {
+    iterator_type batch(It first, It last, const object_type & = {}) {
         underlying_type::batch(first, last);
         return begin();
     }

+ 25 - 19
test/entt/entity/storage.cpp

@@ -100,25 +100,38 @@ TEST(Storage, BatchAdd) {
 
     entities[0] = entt::entity{3};
     entities[1] = entt::entity{42};
-
-    pool.reserve(4);
-    pool.construct(entt::entity{12}, 21);
     auto it = pool.batch(std::begin(entities), std::end(entities));
-    pool.construct(entt::entity{24}, 42);
 
     ASSERT_TRUE(pool.has(entities[0]));
     ASSERT_TRUE(pool.has(entities[1]));
-    ASSERT_FALSE(pool.has(entt::entity{0}));
-    ASSERT_FALSE(pool.has(entt::entity{9}));
-    ASSERT_TRUE(pool.has(entt::entity{12}));
-    ASSERT_TRUE(pool.has(entt::entity{24}));
 
     ASSERT_FALSE(pool.empty());
-    ASSERT_EQ(pool.size(), 4u);
-    ASSERT_EQ(pool.get(entt::entity{12}), 21);
+    ASSERT_EQ(pool.size(), 2u);
     ASSERT_EQ(pool.get(entities[0]), 0);
     ASSERT_EQ(pool.get(entities[1]), 0);
-    ASSERT_EQ(pool.get(entt::entity{24}), 42);
+
+    it[0] = 1;
+    it[1] = 2;
+
+    ASSERT_EQ(pool.get(entities[0]), 1);
+    ASSERT_EQ(pool.get(entities[1]), 2);
+}
+
+TEST(Storage, BatchAddByCopy) {
+    entt::storage<entt::entity, int> pool;
+    entt::entity entities[2];
+
+    entities[0] = entt::entity{3};
+    entities[1] = entt::entity{42};
+    auto it = pool.batch(std::begin(entities), std::end(entities), 3);
+
+    ASSERT_TRUE(pool.has(entities[0]));
+    ASSERT_TRUE(pool.has(entities[1]));
+
+    ASSERT_FALSE(pool.empty());
+    ASSERT_EQ(pool.size(), 2u);
+    ASSERT_EQ(pool.get(entities[0]), 3);
+    ASSERT_EQ(pool.get(entities[1]), 3);
 
     it[0] = 1;
     it[1] = 2;
@@ -134,20 +147,13 @@ TEST(Storage, BatchAddEmptyType) {
     entities[0] = entt::entity{3};
     entities[1] = entt::entity{42};
 
-    pool.reserve(4);
-    pool.construct(entt::entity{12});
     pool.batch(std::begin(entities), std::end(entities));
-    pool.construct(entt::entity{24});
 
     ASSERT_TRUE(pool.has(entities[0]));
     ASSERT_TRUE(pool.has(entities[1]));
-    ASSERT_FALSE(pool.has(entt::entity{0}));
-    ASSERT_FALSE(pool.has(entt::entity{9}));
-    ASSERT_TRUE(pool.has(entt::entity{12}));
-    ASSERT_TRUE(pool.has(entt::entity{24}));
 
     ASSERT_FALSE(pool.empty());
-    ASSERT_EQ(pool.size(), 4u);
+    ASSERT_EQ(pool.size(), 2u);
 
     auto &&component = pool.get(entities[0]);