Browse Source

sparse_set: opaque emplace/insert return (eventually invalid) iterators to the inserted elements

Michele Caini 4 years ago
parent
commit
4ba8ac4fa1

+ 14 - 12
src/entt/entity/sparse_set.hpp

@@ -666,11 +666,12 @@ public:
      *
      * @param entt A valid identifier.
      * @param value Optional opaque value to forward to mixins, if any.
-     * @return True in case of success, false otherwise.
+     * @return Iterator pointing to the emplaced element in case of success, the
+     * `end()` iterator otherwise.
      */
-    bool emplace(const entity_type entt, const void *value = nullptr) {
+    iterator emplace(const entity_type entt, const void *value = nullptr) {
         try_emplace(entt, value);
-        return contains(entt);
+        return find(entt);
     }
 
     /**
@@ -683,23 +684,24 @@ public:
      * @tparam It Type of input 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.
-     * @return Number of entities actually assigned to the sparse set.
+     * @return Iterator pointing to the first element inserted in case of
+     * success, the `end()` iterator otherwise.
      */
     template<typename It>
-    size_type insert(It first, It last) {
-        size_type count{};
+    iterator insert(It first, It last) {
+        auto it = first;
 
-        for(; first != last && free_list != null; ++first) {
-            count += emplace(*first);
+        for(; it != last && free_list != null; ++it) {
+            emplace(*it);
         }
 
-        reserve(packed.size() + std::distance(first, last));
+        reserve(packed.size() + std::distance(it, last));
 
-        for(; first != last; ++first) {
-            count += emplace(*first);
+        for(; it != last; ++it) {
+            emplace(*it);
         }
 
-        return count;
+        return first == last ? end() : find(*first);
     }
 
     /**

+ 6 - 6
test/entt/entity/sigh_storage_mixin.cpp

@@ -47,7 +47,7 @@ TEST(SighStorageMixin, GenericType) {
     pool.on_construct().connect<&listener>(on_construct);
     pool.on_destroy().connect<&listener>(on_destroy);
 
-    ASSERT_TRUE(base.emplace(entities[0u]));
+    ASSERT_NE(base.emplace(entities[0u]), base.end());
 
     pool.emplace(entities[1u]);
 
@@ -65,7 +65,7 @@ TEST(SighStorageMixin, GenericType) {
     ASSERT_EQ(on_destroy.value, 2);
     ASSERT_TRUE(pool.empty());
 
-    ASSERT_EQ(base.insert(std::begin(entities), std::end(entities)), 2u);
+    ASSERT_NE(base.insert(std::begin(entities), std::end(entities)), base.end());
 
     ASSERT_EQ(pool.get(entities[0u]), 0);
     ASSERT_EQ(pool.get(entities[1u]), 0);
@@ -113,7 +113,7 @@ TEST(SighStorageMixin, EmptyType) {
     pool.on_construct().connect<&listener>(on_construct);
     pool.on_destroy().connect<&listener>(on_destroy);
 
-    ASSERT_TRUE(base.emplace(entities[0u]));
+    ASSERT_NE(base.emplace(entities[0u]), base.end());
 
     pool.emplace(entities[1u]);
 
@@ -131,7 +131,7 @@ TEST(SighStorageMixin, EmptyType) {
     ASSERT_EQ(on_destroy.value, 2);
     ASSERT_TRUE(pool.empty());
 
-    ASSERT_EQ(base.insert(std::begin(entities), std::end(entities)), 2u);
+    ASSERT_NE(base.insert(std::begin(entities), std::end(entities)), base.end());
 
     ASSERT_TRUE(pool.contains(entities[0u]));
     ASSERT_TRUE(pool.contains(entities[1u]));
@@ -179,7 +179,7 @@ TEST(SighStorageMixin, NonDefaultConstructibleType) {
     pool.on_construct().connect<&listener>(on_construct);
     pool.on_destroy().connect<&listener>(on_destroy);
 
-    ASSERT_FALSE(base.emplace(entities[0u]));
+    ASSERT_EQ(base.emplace(entities[0u]), base.end());
 
     pool.emplace(entities[1u], 3);
 
@@ -196,7 +196,7 @@ TEST(SighStorageMixin, NonDefaultConstructibleType) {
     ASSERT_EQ(on_destroy.value, 1);
     ASSERT_TRUE(pool.empty());
 
-    ASSERT_EQ(base.insert(std::begin(entities), std::end(entities)), 0u);
+    ASSERT_EQ(base.insert(std::begin(entities), std::end(entities)), base.end());
 
     ASSERT_FALSE(pool.contains(entities[0u]));
     ASSERT_FALSE(pool.contains(entities[1u]));

+ 10 - 10
test/entt/entity/sparse_set.cpp

@@ -263,12 +263,12 @@ TEST(SparseSet, Emplace) {
     entt::entity entities[2u]{entt::entity{3}, entt::entity{42}};
 
     ASSERT_TRUE(set.empty());
-    ASSERT_TRUE(set.emplace(entities[0u]));
+    ASSERT_NE(set.emplace(entities[0u]), set.end());
 
     set.erase(entities[0u]);
 
-    ASSERT_TRUE(set.emplace(entities[1u]));
-    ASSERT_TRUE(set.emplace(entities[0u]));
+    ASSERT_NE(set.emplace(entities[1u]), set.end());
+    ASSERT_NE(set.emplace(entities[0u]), set.end());
 
     ASSERT_DEATH(set.emplace(traits_type::combine(3, 1)), "");
     ASSERT_DEATH(set.emplace(entities[1u]), "");
@@ -280,8 +280,8 @@ TEST(SparseSet, Emplace) {
 
     set.erase(std::begin(entities), std::end(entities));
 
-    ASSERT_TRUE(set.emplace(entities[1u]));
-    ASSERT_TRUE(set.emplace(entities[0u]));
+    ASSERT_NE(set.emplace(entities[1u]), set.end());
+    ASSERT_NE(set.emplace(entities[0u]), set.end());
 
     ASSERT_EQ(set.at(0u), entities[1u]);
     ASSERT_EQ(set.at(1u), entities[0u]);
@@ -293,13 +293,13 @@ TEST(SparseSet, EmplaceOutOfBounds) {
     entt::sparse_set set{entt::deletion_policy::in_place};
     entt::entity entities[2u]{entt::entity{0}, entt::entity{ENTT_SPARSE_PAGE}};
 
-    ASSERT_TRUE(set.emplace(entities[0u]));
+    ASSERT_NE(set.emplace(entities[0u]), set.end());
     ASSERT_EQ(set.extent(), ENTT_SPARSE_PAGE);
     ASSERT_EQ(set.index(entities[0u]), 0u);
 
     set.erase(entities[0u]);
 
-    ASSERT_TRUE(set.emplace(entities[1u]));
+    ASSERT_NE(set.emplace(entities[1u]), set.end());
     ASSERT_EQ(set.extent(), 2u * ENTT_SPARSE_PAGE);
     ASSERT_EQ(set.index(entities[1u]), 0u);
 }
@@ -310,8 +310,8 @@ TEST(SparseSet, Insert) {
 
     set.emplace(entt::entity{12});
 
-    ASSERT_EQ(set.insert(std::end(entities), std::end(entities)), 0u);
-    ASSERT_EQ(set.insert(std::begin(entities), std::end(entities)), 2u);
+    ASSERT_EQ(set.insert(std::end(entities), std::end(entities)), set.end());
+    ASSERT_NE(set.insert(std::begin(entities), std::end(entities)), set.end());
 
     set.emplace(entt::entity{24});
 
@@ -335,7 +335,7 @@ TEST(SparseSet, Insert) {
 
     set.erase(std::begin(entities), std::end(entities));
 
-    ASSERT_EQ(set.insert(std::rbegin(entities), std::rend(entities)), 2u);
+    ASSERT_NE(set.insert(std::rbegin(entities), std::rend(entities)), set.end());
 
     ASSERT_EQ(set.size(), 4u);
     ASSERT_EQ(set.at(1u), entities[0u]);

+ 10 - 10
test/entt/entity/storage.cpp

@@ -593,7 +593,7 @@ TEST(Storage, TypeFromBase) {
 
     int instance = 42;
 
-    ASSERT_TRUE(base.emplace(entities[0u], &instance));
+    ASSERT_NE(base.emplace(entities[0u], &instance), base.end());
 
     ASSERT_TRUE(pool.contains(entities[0u]));
     ASSERT_FALSE(pool.contains(entities[1u]));
@@ -602,7 +602,7 @@ TEST(Storage, TypeFromBase) {
 
     base.erase(entities[0u]);
 
-    ASSERT_EQ(base.insert(std::begin(entities), std::end(entities)), 2u);
+    ASSERT_NE(base.insert(std::begin(entities), std::end(entities)), base.end());
 
     ASSERT_TRUE(pool.contains(entities[0u]));
     ASSERT_TRUE(pool.contains(entities[1u]));
@@ -627,7 +627,7 @@ TEST(Storage, EmptyTypeFromBase) {
 
     empty_stable_type instance{};
 
-    ASSERT_TRUE(base.emplace(entities[0u], &instance));
+    ASSERT_NE(base.emplace(entities[0u], &instance), base.end());
 
     ASSERT_TRUE(pool.contains(entities[0u]));
     ASSERT_FALSE(pool.contains(entities[1u]));
@@ -635,7 +635,7 @@ TEST(Storage, EmptyTypeFromBase) {
 
     base.erase(entities[0u]);
 
-    ASSERT_EQ(base.insert(std::begin(entities), std::end(entities)), 2u);
+    ASSERT_NE(base.insert(std::begin(entities), std::end(entities)), base.end());
 
     ASSERT_TRUE(pool.contains(entities[0u]));
     ASSERT_TRUE(pool.contains(entities[1u]));
@@ -659,7 +659,7 @@ TEST(Storage, NonDefaultConstructibleTypeFromBase) {
     ASSERT_FALSE(pool.contains(entities[0u]));
     ASSERT_FALSE(pool.contains(entities[1u]));
 
-    ASSERT_FALSE(base.emplace(entities[0u]));
+    ASSERT_EQ(base.emplace(entities[0u]), base.end());
 
     ASSERT_FALSE(pool.contains(entities[0u]));
     ASSERT_FALSE(pool.contains(entities[1u]));
@@ -668,7 +668,7 @@ TEST(Storage, NonDefaultConstructibleTypeFromBase) {
 
     non_default_constructible instance{3};
 
-    ASSERT_TRUE(base.emplace(entities[0u], &instance));
+    ASSERT_NE(base.emplace(entities[0u], &instance), base.end());
 
     ASSERT_TRUE(pool.contains(entities[0u]));
     ASSERT_FALSE(pool.contains(entities[1u]));
@@ -678,7 +678,7 @@ TEST(Storage, NonDefaultConstructibleTypeFromBase) {
     ASSERT_TRUE(pool.empty());
     ASSERT_FALSE(pool.contains(entities[0u]));
 
-    ASSERT_EQ(base.insert(std::begin(entities), std::end(entities)), 0u);
+    ASSERT_EQ(base.insert(std::begin(entities), std::end(entities)), base.end());
 
     ASSERT_FALSE(pool.contains(entities[0u]));
     ASSERT_FALSE(pool.contains(entities[1u]));
@@ -698,7 +698,7 @@ TEST(Storage, NonCopyConstructibleTypeFromBase) {
     ASSERT_FALSE(pool.contains(entities[0u]));
     ASSERT_FALSE(pool.contains(entities[1u]));
 
-    ASSERT_TRUE(base.emplace(entities[0u]));
+    ASSERT_NE(base.emplace(entities[0u]), base.end());
 
     ASSERT_TRUE(pool.contains(entities[0u]));
     ASSERT_FALSE(pool.contains(entities[1u]));
@@ -707,7 +707,7 @@ TEST(Storage, NonCopyConstructibleTypeFromBase) {
 
     std::unique_ptr<int> instance = std::make_unique<int>(3);
 
-    ASSERT_FALSE(base.emplace(entities[1u], &instance));
+    ASSERT_EQ(base.emplace(entities[1u], &instance), base.end());
 
     ASSERT_TRUE(pool.contains(entities[0u]));
     ASSERT_FALSE(pool.contains(entities[1u]));
@@ -717,7 +717,7 @@ TEST(Storage, NonCopyConstructibleTypeFromBase) {
     ASSERT_TRUE(pool.empty());
     ASSERT_FALSE(pool.contains(entities[0u]));
 
-    ASSERT_EQ(base.insert(std::begin(entities), std::end(entities)), 2u);
+    ASSERT_NE(base.insert(std::begin(entities), std::end(entities)), base.end());
 
     ASSERT_TRUE(pool.contains(entities[0u]));
     ASSERT_TRUE(pool.contains(entities[1u]));