Browse Source

storage: reintroduce support to args for empty types - see #1323

skypjack 15 hours ago
parent
commit
6ca3db7de4

+ 1 - 16
src/entt/entity/registry.hpp

@@ -571,21 +571,6 @@ public:
         return assure<Type>().emplace(entt, std::forward<Args>(args)...);
         return assure<Type>().emplace(entt, std::forward<Args>(args)...);
     }
     }
 
 
-    /**
-     * @brief Assigns each entity in a range the given element.
-     *
-     * @sa emplace
-     *
-     * @tparam Type Type of element to create.
-     * @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.
-     */
-    template<typename Type>
-    void insert(stl::input_iterator auto first, stl::input_iterator auto last) {
-        ENTT_ASSERT(std::all_of(first, last, [this](const auto entt) { return valid(entt); }), "Invalid entity");
-        assure<Type>().insert(std::move(first), std::move(last));
-    }
-
     /**
     /**
      * @brief Assigns each entity in a range the given element.
      * @brief Assigns each entity in a range the given element.
      *
      *
@@ -597,7 +582,7 @@ public:
      * @param value An instance of the element to assign.
      * @param value An instance of the element to assign.
      */
      */
     template<typename Type>
     template<typename Type>
-    void insert(stl::input_iterator auto first, stl::input_iterator auto last, const Type &value) {
+    void insert(stl::input_iterator auto first, stl::input_iterator auto last, const Type &value = {}) {
         ENTT_ASSERT(std::all_of(first, last, [this](const auto entt) { return valid(entt); }), "Invalid entity");
         ENTT_ASSERT(std::all_of(first, last, [this](const auto entt) { return valid(entt); }), "Invalid entity");
         assure<Type>().insert(std::move(first), std::move(last), value);
         assure<Type>().insert(std::move(first), std::move(last), value);
     }
     }

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

@@ -890,9 +890,12 @@ public:
      * Attempting to use an entity that already belongs to the storage results
      * Attempting to use an entity that already belongs to the storage results
      * in undefined behavior.
      * in undefined behavior.
      *
      *
+     * @tparam Args Types of arguments to use to construct the object.
      * @param entt A valid identifier.
      * @param entt A valid identifier.
      */
      */
-    void emplace(const entity_type entt) {
+    template<typename... Args>
+    // NOLINTNEXTLINE(cppcoreguidelines-missing-std-forward)
+    auto emplace(const entity_type entt, Args &&...) {
         base_type::try_emplace(entt, false);
         base_type::try_emplace(entt, false);
     }
     }
 
 
@@ -911,11 +914,13 @@ public:
     /**
     /**
      * @brief Assigns entities to a storage.
      * @brief Assigns entities to a storage.
      * @tparam It Type of input iterator.
      * @tparam It Type of input iterator.
+     * @tparam Args Types of optional arguments.
      * @param first An iterator to the first element of the range of entities.
      * @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 last An iterator past the last element of the range of entities.
      */
      */
-    template<stl::input_iterator It>
-    void insert(It first, It last) {
+    template<typename It, typename... Args>
+    // NOLINTNEXTLINE(cppcoreguidelines-missing-std-forward)
+    void insert(It first, It last, Args &&...) {
         for(; first != last; ++first) {
         for(; first != last; ++first) {
             base_type::try_emplace(*first, true);
             base_type::try_emplace(*first, true);
         }
         }

+ 1 - 1
test/entt/entity/registry.cpp

@@ -977,7 +977,7 @@ TEST_F(Registry, EmplaceEmpty) {
 
 
     ASSERT_FALSE(registry.all_of<test::empty>(entity));
     ASSERT_FALSE(registry.all_of<test::empty>(entity));
 
 
-    registry.emplace<test::empty>(entity);
+    registry.emplace<test::empty>(entity, 4);
 
 
     ASSERT_TRUE(registry.all_of<test::empty>(entity));
     ASSERT_TRUE(registry.all_of<test::empty>(entity));
 }
 }

+ 13 - 4
test/entt/entity/storage_no_instance.cpp

@@ -22,12 +22,21 @@ struct StorageNoInstance: testing::Test {
     using type = Type;
     using type = Type;
 
 
     static auto emplace_instance(entt::storage<type> &pool, const entt::entity entt) {
     static auto emplace_instance(entt::storage<type> &pool, const entt::entity entt) {
-        return pool.emplace(entt);
+        if constexpr(std::is_void_v<type>) {
+            return pool.emplace(entt);
+        } else {
+            return pool.emplace(entt, type{});
+        }
     }
     }
 
 
     template<typename It>
     template<typename It>
     static auto insert_instance(entt::storage<type> &pool, const It from, const It to) {
     static auto insert_instance(entt::storage<type> &pool, const It from, const It to) {
-        return pool.insert(from, to);
+        if constexpr(std::is_void_v<type>) {
+            return pool.insert(from, to);
+        } else {
+            const std::array<type, 2u> value{};
+            return pool.insert(from, to, value.begin());
+        }
     }
     }
 
 
     static auto push_instance(entt::storage<type> &pool, const entt::entity entt) {
     static auto push_instance(entt::storage<type> &pool, const entt::entity entt) {
@@ -106,7 +115,7 @@ TYPED_TEST(StorageNoInstance, Move) {
     ASSERT_EQ(pool.index(entity[0u]), 0u);
     ASSERT_EQ(pool.index(entity[0u]), 0u);
 
 
     other = entt::storage<value_type>{};
     other = entt::storage<value_type>{};
-    other.emplace(entity[1u]);
+    other.emplace(entity[1u], 2);
     other = std::move(pool);
     other = std::move(pool);
     test::is_initialized(pool);
     test::is_initialized(pool);
 
 
@@ -153,7 +162,7 @@ TYPED_TEST(StorageNoInstance, Getters) {
     entt::storage<value_type> pool;
     entt::storage<value_type> pool;
     const entt::entity entity{4};
     const entt::entity entity{4};
 
 
-    pool.emplace(entity);
+    pool.emplace(entity, 3);
 
 
     testing::StaticAssertTypeEq<decltype(pool.get({})), void>();
     testing::StaticAssertTypeEq<decltype(pool.get({})), void>();
     testing::StaticAssertTypeEq<decltype(std::as_const(pool).get({})), void>();
     testing::StaticAssertTypeEq<decltype(std::as_const(pool).get({})), void>();

+ 1 - 1
test/lib/registry/plugin/plugin.cpp

@@ -16,7 +16,7 @@ CR_EXPORT int cr_main(cr_plugin *ctx, cr_op operation) {
         static_cast<void>(registry.storage<test::empty>());
         static_cast<void>(registry.storage<test::empty>());
 
 
         const auto view = registry.view<test::boxed_int>();
         const auto view = registry.view<test::boxed_int>();
-        registry.insert<test::empty>(view.begin(), view.end());
+        registry.insert(view.begin(), view.end(), test::empty{});
 
 
         registry.view<test::boxed_int, test::empty>().each([cnt = count](test::boxed_int &elem) {
         registry.view<test::boxed_int, test::empty>().each([cnt = count](test::boxed_int &elem) {
             elem.value += cnt;
             elem.value += cnt;