Browse Source

storage: ::insert returns an iterator to the range of inserted entities

Michele Caini 3 years ago
parent
commit
3e959007b9
3 changed files with 71 additions and 8 deletions
  1. 16 4
      src/entt/entity/storage.hpp
  2. 17 4
      test/entt/entity/storage.cpp
  3. 38 0
      test/entt/entity/storage_entity.cpp

+ 16 - 4
src/entt/entity/storage.hpp

@@ -711,12 +711,15 @@ public:
      * @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 An instance of the object to construct.
+     * @return Iterator pointing to the first entity inserted, if any.
      */
     template<typename It>
-    void insert(It first, It last, const value_type &value = {}) {
+    typename base_type::iterator insert(It first, It last, const value_type &value = {}) {
         for(; first != last; ++first) {
             emplace_element(*first, true, value);
         }
+
+        return base_type::begin();
     }
 
     /**
@@ -730,12 +733,15 @@ public:
      * @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 from An iterator to the first element of the range of objects.
+     * @return Iterator pointing to the first entity inserted, if any.
      */
     template<typename EIt, typename CIt, typename = std::enable_if_t<std::is_same_v<typename std::iterator_traits<CIt>::value_type, value_type>>>
-    void insert(EIt first, EIt last, CIt from) {
+    typename base_type::iterator insert(EIt first, EIt last, CIt from) {
         for(; first != last; ++first, ++from) {
             emplace_element(*first, true, *from);
         }
+
+        return base_type::begin();
     }
 
     /**
@@ -885,12 +891,15 @@ public:
      * @tparam Args Types of optional arguments.
      * @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.
+     * @return Iterator pointing to the first entity inserted, if any.
      */
     template<typename It, typename... Args>
-    void insert(It first, It last, Args &&...) {
+    typename base_type::iterator insert(It first, It last, Args &&...) {
         for(; first != last; ++first) {
             base_type::try_emplace(*first, true);
         }
+
+        return base_type::begin();
     }
 
     /**
@@ -1112,9 +1121,10 @@ public:
      * @tparam It Type of mutable forward iterator.
      * @param first An iterator to the first element of the range to generate.
      * @param last An iterator past the last element of the range to generate.
+     * @return Iterator pointing to the first entity inserted, if any.
      */
     template<typename It>
-    void insert(It first, It last) {
+    typename base_type::iterator insert(It first, It last) {
         for(const auto sz = base_type::size(); first != last && length != sz; ++first, ++length) {
             *first = base_type::operator[](length);
         }
@@ -1122,6 +1132,8 @@ public:
         for(; first != last; ++first) {
             *first = *base_type::try_emplace(entity_at(length++), true);
         }
+
+        return (base_type::end() - length);
     }
 
     /**

+ 17 - 4
test/entt/entity/storage.cpp

@@ -315,7 +315,12 @@ ENTT_DEBUG_TEST_F(StorageDeathTest, EmptyType) {
 TEST_F(Storage, Insert) {
     entt::storage<stable_type> pool;
     entt::entity entities[2u]{entt::entity{3}, entt::entity{42}};
-    pool.insert(std::begin(entities), std::end(entities), stable_type{99});
+    typename entt::sparse_set::iterator it{};
+    const entt::sparse_set &base = pool;
+
+    it = pool.insert(std::begin(entities), std::end(entities), stable_type{99});
+
+    ASSERT_EQ(it, base.cbegin());
 
     ASSERT_TRUE(pool.contains(entities[0u]));
     ASSERT_TRUE(pool.contains(entities[1u]));
@@ -327,7 +332,9 @@ TEST_F(Storage, Insert) {
 
     pool.erase(std::begin(entities), std::end(entities));
     const stable_type values[2u] = {stable_type{42}, stable_type{3}};
-    pool.insert(std::rbegin(entities), std::rend(entities), std::begin(values));
+    it = pool.insert(std::rbegin(entities), std::rend(entities), std::begin(values));
+
+    ASSERT_EQ(it, base.cbegin());
 
     ASSERT_EQ(pool.size(), 4u);
     ASSERT_EQ(pool.at(2u), entities[1u]);
@@ -341,8 +348,12 @@ TEST_F(Storage, Insert) {
 TEST_F(Storage, InsertEmptyType) {
     entt::storage<empty_stable_type> pool;
     entt::entity entities[2u]{entt::entity{3}, entt::entity{42}};
+    typename entt::sparse_set::iterator it{};
+    const entt::sparse_set &base = pool;
 
-    pool.insert(std::begin(entities), std::end(entities));
+    it = pool.insert(std::begin(entities), std::end(entities));
+
+    ASSERT_EQ(it, base.cbegin());
 
     ASSERT_TRUE(pool.contains(entities[0u]));
     ASSERT_TRUE(pool.contains(entities[1u]));
@@ -352,7 +363,9 @@ TEST_F(Storage, InsertEmptyType) {
 
     pool.erase(std::begin(entities), std::end(entities));
     const empty_stable_type values[2u]{};
-    pool.insert(std::rbegin(entities), std::rend(entities), std::begin(values));
+    it = pool.insert(std::rbegin(entities), std::rend(entities), std::begin(values));
+
+    ASSERT_EQ(it, base.cbegin());
 
     ASSERT_EQ(pool.size(), 4u);
     ASSERT_EQ(pool.at(2u), entities[1u]);

+ 38 - 0
test/entt/entity/storage_entity.cpp

@@ -222,6 +222,44 @@ TEST(StorageEntity, Emplace) {
     ASSERT_EQ(entities[1u], entt::entity{8});
 }
 
+TEST(StorageEntity, Insert) {
+    using traits_type = entt::entt_traits<entt::entity>;
+
+    entt::storage<entt::entity> pool;
+    entt::entity entities[2u]{};
+    typename entt::sparse_set::iterator it{};
+    const entt::sparse_set &base = pool;
+
+    it = pool.insert(std::begin(entities), std::end(entities));
+
+    ASSERT_EQ(it, base.cbegin());
+
+    ASSERT_TRUE(pool.contains(entities[0u]));
+    ASSERT_TRUE(pool.contains(entities[1u]));
+
+    ASSERT_FALSE(pool.empty());
+    ASSERT_EQ(pool.size(), 2u);
+    ASSERT_EQ(pool.in_use(), 2u);
+
+    pool.erase(std::begin(entities), std::end(entities));
+
+    ASSERT_FALSE(pool.empty());
+    ASSERT_EQ(pool.size(), 2u);
+    ASSERT_EQ(pool.in_use(), 0u);
+
+    it = pool.insert(entities, entities + 1u);
+
+    ASSERT_NE(it, base.cbegin());
+    ASSERT_EQ(it, base.cbegin() + 1u);
+
+    ASSERT_TRUE(pool.contains(entities[0u]));
+    ASSERT_FALSE(pool.contains(entities[1u]));
+
+    ASSERT_FALSE(pool.empty());
+    ASSERT_EQ(pool.size(), 2u);
+    ASSERT_EQ(pool.in_use(), 1u);
+}
+
 TEST(StorageEntity, Pack) {
     entt::storage<entt::entity> pool;
     entt::entity entities[3u]{entt::entity{1}, entt::entity{3}, entt::entity{42}};