Răsfoiți Sursa

entity: registry ::remove/::erase entity/range and safe/unsafe versions (close #486)

Michele Caini 4 ani în urmă
părinte
comite
daf72a7c61

+ 7 - 7
docs/md/entity.md

@@ -296,24 +296,24 @@ bool all = registry.all_of<position, velocity>(entity);
 bool any = registry.any_of<position, velocity>(entity);
 ```
 
-If the goal is to delete a component from an entity that owns it, the `remove`
+If the goal is to delete a component from an entity that owns it, the `erase`
 member function template is the way to go:
 
 ```cpp
-registry.remove<position>(entity);
+registry.erase<position>(entity);
 ```
 
-When in doubt whether the entity owns the component, use the `remove_if_exists`
-member function instead. It behaves similarly to `remove` but it discards the
-component if and only if it exists, otherwise it returns safely to the caller:
+When in doubt whether the entity owns the component, use the `remove` member
+function instead. It behaves similarly to `erase` but it erases the component
+if and only if it exists, otherwise it returns safely to the caller:
 
 ```cpp
-registry.remove_if_exists<position>(entity);
+registry.remove<position>(entity);
 ```
 
 The `clear` member function works similarly and can be used to either:
 
-* Remove all instances of the given components from the entities that own them:
+* Erases all instances of the given components from the entities that own them:
 
   ```cpp
   registry.clear<position>();

+ 16 - 8
src/entt/entity/handle.hpp

@@ -30,6 +30,8 @@ struct basic_handle {
     using entity_type = typename registry_type::entity_type;
     /*! @brief Underlying version type. */
     using version_type = typename registry_type::version_type;
+    /*! @brief Unsigned integer type. */
+    using size_type = typename registry_type::size_type;
 
     /*! @brief Constructs an invalid handle. */
     basic_handle() ENTT_NOEXCEPT
@@ -194,21 +196,27 @@ struct basic_handle {
      * @tparam Component Types of components to remove.
      */
     template<typename... Component>
-    void remove() const {
+    size_type remove() const {
         static_assert(sizeof...(Type) == 0 || (type_list_contains_v<type_list<Type...>, Component> && ...), "Invalid type");
-        reg->template remove<Component...>(entt);
+        return reg->template remove<Component...>(entt);
     }
 
     /**
-     * @brief Removes the given components from a handle.
-     * @sa basic_registry::remove_if_exists
-     * @tparam Component Types of components to remove.
-     * @return The number of components actually removed.
+     * @brief Erases the given components from a handle.
+     * @sa basic_registry::erase
+     * @tparam Component Types of components to erase.
      */
     template<typename... Component>
-    decltype(auto) remove_if_exists() const {
+    void erase() const {
         static_assert(sizeof...(Type) == 0 || (type_list_contains_v<type_list<Type...>, Component> && ...), "Invalid type");
-        return reg->template remove_if_exists<Component...>(entt);
+        reg->template erase<Component...>(entt);
+    }
+
+    /*! @copydoc remove */
+    template<typename... Component>
+    [[deprecated("Use ::remove instead")]]
+    size_type remove_if_exists() const {
+        return remove<Component...>();
     }
 
     /**

+ 38 - 20
src/entt/entity/registry.hpp

@@ -662,17 +662,17 @@ public:
      * @brief Removes the given components from an entity.
      *
      * @warning
-     * Attempting to use an invalid entity or to remove a component from an
-     * entity that doesn't own it results in undefined behavior.
+     * Attempting to use an invalid entity results in undefined behavior.
      *
      * @tparam Component Types of components to remove.
      * @param entity A valid entity identifier.
+     * @return The number of components actually removed.
      */
     template<typename... Component>
-    void remove(const entity_type entity) {
+    size_type remove(const entity_type entity) {
         ENTT_ASSERT(valid(entity), "Invalid entity");
         static_assert(sizeof...(Component) > 0, "Provide one or more component types");
-        (assure<Component>()->erase(entity, this), ...);
+        return (assure<Component>()->remove(entity, this) + ... + size_type{});
     }
 
     /**
@@ -684,36 +684,54 @@ 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 The number of components actually removed.
      */
     template<typename... Component, typename It>
-    void remove(It first, It last) {
+    size_type remove(It first, It last) {
         ENTT_ASSERT(std::all_of(first, last, [this](const auto entity) { return valid(entity); }), "Invalid entity");
         static_assert(sizeof...(Component) > 0, "Provide one or more component types");
-        (assure<Component>()->erase(first, last, this), ...);
+        return (assure<Component>()->remove(first, last, this) + ... + size_type{});
     }
 
     /**
-     * @brief Removes the given components from an entity.
-     *
-     * Equivalent to the following snippet (pseudocode):
-     *
-     * @code{.cpp}
-     * if(registry.all_of<Component>(entity)) { registry.remove<Component>(entity) }
-     * @endcode
-     *
-     * Prefer this function anyway because it has slightly better performance.
+     * @brief Erases the given components from an entity.
      *
      * @warning
-     * Attempting to use an invalid entity results in undefined behavior.
+     * Attempting to use an invalid entity or to erase a component from an
+     * entity that doesn't own it results in undefined behavior.
      *
-     * @tparam Component Types of components to remove.
+     * @tparam Component Types of components to erase.
      * @param entity A valid entity identifier.
-     * @return The number of components actually removed.
      */
     template<typename... Component>
-    size_type remove_if_exists(const entity_type entity) {
+    void erase(const entity_type entity) {
         ENTT_ASSERT(valid(entity), "Invalid entity");
-        return (assure<Component>()->remove(entity, this) + ... + size_type{});
+        static_assert(sizeof...(Component) > 0, "Provide one or more component types");
+        (assure<Component>()->erase(entity, this), ...);
+    }
+
+    /**
+     * @brief Erases the given components from all the entities in a range.
+     *
+     * @sa erase
+     *
+     * @tparam Component Types of components to erase.
+     * @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.
+     */
+    template<typename... Component, typename It>
+    void erase(It first, It last) {
+        ENTT_ASSERT(std::all_of(first, last, [this](const auto entity) { return valid(entity); }), "Invalid entity");
+        static_assert(sizeof...(Component) > 0, "Provide one or more component types");
+        (assure<Component>()->erase(first, last, this), ...);
+    }
+
+    /*! @copydoc remove */
+    template<typename... Component>
+    [[deprecated("Use ::remove instead")]]
+    size_type remove_if_exists(const entity_type entity) {
+        return remove<Component...>(entity);
     }
 
     /**

+ 1 - 1
src/entt/entity/snapshot.hpp

@@ -380,7 +380,7 @@ class basic_continuous_loader {
             const auto local = ref.second.first;
 
             if(reg->valid(local)) {
-                reg->template remove_if_exists<Component>(local);
+                reg->template remove<Component>(local);
             }
         }
     }

+ 28 - 10
test/benchmark/benchmark.cpp

@@ -45,9 +45,9 @@ void pathological(Func func) {
 
     for(auto i = 0; i < 10; ++i) {
         registry.each([i = 0, &registry](const auto entity) mutable {
-            if(!(++i % 7)) { registry.remove_if_exists<position>(entity); }
-            if(!(++i % 11)) { registry.remove_if_exists<velocity>(entity); }
-            if(!(++i % 13)) { registry.remove_if_exists<comp<0>>(entity); }
+            if(!(++i % 7)) { registry.remove<position>(entity); }
+            if(!(++i % 11)) { registry.remove<velocity>(entity); }
+            if(!(++i % 13)) { registry.remove<comp<0>>(entity); }
             if(!(++i % 17)) { registry.destroy(entity); }
         });
 
@@ -120,7 +120,7 @@ TEST(Benchmark, CreateManyWithComponents) {
     timer.elapsed();
 }
 
-TEST(Benchmark, Remove) {
+TEST(Benchmark, Erase) {
     entt::registry registry;
     std::vector<entt::entity> entities(1000000);
 
@@ -132,13 +132,13 @@ TEST(Benchmark, Remove) {
     timer timer;
 
     for(auto entity: registry.view<int>()) {
-        registry.remove<int>(entity);
+        registry.erase<int>(entity);
     }
 
     timer.elapsed();
 }
 
-TEST(Benchmark, RemoveMany) {
+TEST(Benchmark, EraseMany) {
     entt::registry registry;
     std::vector<entt::entity> entities(1000000);
 
@@ -149,22 +149,40 @@ TEST(Benchmark, RemoveMany) {
 
     timer timer;
     auto view = registry.view<int>();
-    registry.remove<int>(++view.begin(), view.end());
+    registry.erase<int>(++view.begin(), view.end());
     timer.elapsed();
 }
 
-TEST(Benchmark, RemoveAll) {
+TEST(Benchmark, Remove) {
     entt::registry registry;
     std::vector<entt::entity> entities(1000000);
 
-    std::cout << "Removing 1000000 components from their entities at once" << std::endl;
+    std::cout << "Removing 1000000 components from their entities" << std::endl;
+
+    registry.create(entities.begin(), entities.end());
+    registry.insert<int>(entities.begin(), entities.end());
+
+    timer timer;
+
+    for(auto entity: registry.view<int>()) {
+        registry.remove<int>(entity);
+    }
+
+    timer.elapsed();
+}
+
+TEST(Benchmark, RemoveMany) {
+    entt::registry registry;
+    std::vector<entt::entity> entities(1000000);
+
+    std::cout << "Removing 999999 components from their entities at once" << std::endl;
 
     registry.create(entities.begin(), entities.end());
     registry.insert<int>(entities.begin(), entities.end());
 
     timer timer;
     auto view = registry.view<int>();
-    registry.remove<int>(view.begin(), view.end());
+    registry.remove<int>(++view.begin(), view.end());
     timer.elapsed();
 }
 

+ 14 - 14
test/entt/entity/group.cpp

@@ -43,7 +43,7 @@ TEST(NonOwningGroup, Functionalities) {
 
     ASSERT_EQ(group.size(), 2u);
 
-    registry.remove<int>(e0);
+    registry.erase<int>(e0);
 
     ASSERT_EQ(group.size(), 1u);
 
@@ -55,8 +55,8 @@ TEST(NonOwningGroup, Functionalities) {
 
     ASSERT_EQ(*(group.data() + 0), e1);
 
-    registry.remove<char>(e0);
-    registry.remove<char>(e1);
+    registry.erase<char>(e0);
+    registry.erase<char>(e1);
 
     ASSERT_EQ(group.begin(), group.end());
     ASSERT_EQ(cgroup.begin(), cgroup.end());
@@ -396,7 +396,7 @@ TEST(NonOwningGroup, Find) {
     registry.emplace<int>(e3);
     registry.emplace<char>(e3);
 
-    registry.remove<int>(e1);
+    registry.erase<int>(e1);
 
     ASSERT_NE(group.find(e0), group.end());
     ASSERT_EQ(group.find(e1), group.end());
@@ -455,8 +455,8 @@ TEST(NonOwningGroup, ExcludedComponents) {
 
     ASSERT_TRUE(group.empty());
 
-    registry.remove<char>(e1);
-    registry.remove<char>(e3);
+    registry.erase<char>(e1);
+    registry.erase<char>(e3);
 
     for(const auto entity: group) {
         ASSERT_TRUE(entity == e1 || entity == e3);
@@ -512,7 +512,7 @@ TEST(NonOwningGroup, TrackEntitiesOnComponentDestruction) {
     ASSERT_TRUE(group.empty());
     ASSERT_TRUE(cgroup.empty());
 
-    registry.remove<char>(entity);
+    registry.erase<char>(entity);
 
     ASSERT_FALSE(group.empty());
     ASSERT_FALSE(cgroup.empty());
@@ -661,7 +661,7 @@ TEST(OwningGroup, Functionalities) {
 
     ASSERT_EQ(group.size(), 2u);
 
-    registry.remove<int>(e0);
+    registry.erase<int>(e0);
 
     ASSERT_EQ(group.size(), 1u);
 
@@ -677,8 +677,8 @@ TEST(OwningGroup, Functionalities) {
     ASSERT_EQ(*(group.data() + 0), e1);
     ASSERT_EQ(*(group.raw<int>() + 0), 42);
 
-    registry.remove<char>(e0);
-    registry.remove<char>(e1);
+    registry.erase<char>(e0);
+    registry.erase<char>(e1);
 
     ASSERT_EQ(group.begin(), group.end());
     ASSERT_EQ(cgroup.begin(), cgroup.end());
@@ -1101,7 +1101,7 @@ TEST(OwningGroup, Find) {
     registry.emplace<int>(e3);
     registry.emplace<char>(e3);
 
-    registry.remove<int>(e1);
+    registry.erase<int>(e1);
 
     ASSERT_NE(group.find(e0), group.end());
     ASSERT_EQ(group.find(e1), group.end());
@@ -1160,8 +1160,8 @@ TEST(OwningGroup, ExcludedComponents) {
 
     ASSERT_TRUE(group.empty());
 
-    registry.remove<char>(e1);
-    registry.remove<double>(e3);
+    registry.erase<char>(e1);
+    registry.erase<double>(e3);
 
     for(const auto entity: group) {
         ASSERT_TRUE(entity == e1 || entity == e3);
@@ -1217,7 +1217,7 @@ TEST(OwningGroup, TrackEntitiesOnComponentDestruction) {
     ASSERT_TRUE(group.empty());
     ASSERT_TRUE(cgroup.empty());
 
-    registry.remove<char>(entity);
+    registry.erase<char>(entity);
 
     ASSERT_FALSE(group.empty());
     ASSERT_FALSE(cgroup.empty());

+ 4 - 3
test/entt/entity/handle.cpp

@@ -160,10 +160,10 @@ TEST(BasicHandle, Component) {
     ASSERT_TRUE((handle.all_of<int, char, double>()));
     ASSERT_EQ((std::make_tuple(42, 'a', .3)), (handle.get<int, char, double>()));
 
-    handle.remove<char, double>();
+    handle.erase<char, double>();
 
     ASSERT_TRUE((registry.empty<char, double>()));
-    ASSERT_EQ(0u, (handle.remove_if_exists<char, double>()));
+    ASSERT_EQ(0u, (handle.remove<char, double>()));
 
     handle.visit([](auto info) { ASSERT_EQ(entt::type_id<int>(), info); });
 
@@ -171,7 +171,8 @@ TEST(BasicHandle, Component) {
     ASSERT_FALSE((handle.all_of<int, char, double>()));
     ASSERT_FALSE(handle.orphan());
 
-    handle.remove<int>();
+    ASSERT_EQ(1u, (handle.remove<int>()));
+    ASSERT_DEATH(handle.erase<int>(), "");
 
     ASSERT_TRUE(registry.empty<int>());
     ASSERT_TRUE(handle.orphan());

+ 16 - 16
test/entt/entity/observer.cpp

@@ -31,7 +31,7 @@ TEST(Observer, Functionalities) {
     ASSERT_TRUE(observer.empty());
 
     observer.disconnect();
-    registry.remove<int>(entity);
+    registry.erase<int>(entity);
     registry.emplace<int>(entity);
 
     ASSERT_EQ(observer.size(), 0u);
@@ -60,7 +60,7 @@ TEST(Observer, AllOf) {
 
     ASSERT_FALSE(observer.empty());
 
-    registry.remove<int>(entity);
+    registry.erase<int>(entity);
 
     ASSERT_TRUE(observer.empty());
 
@@ -69,7 +69,7 @@ TEST(Observer, AllOf) {
 
     ASSERT_FALSE(observer.empty());
 
-    registry.remove<double>(entity);
+    registry.erase<double>(entity);
 
     ASSERT_TRUE(observer.empty());
 
@@ -81,7 +81,7 @@ TEST(Observer, AllOf) {
     observer.disconnect();
     registry.emplace_or_replace<int>(entity);
     registry.emplace_or_replace<char>(entity);
-    registry.remove_if_exists<float>(entity);
+    registry.erase<float>(entity);
 
     ASSERT_TRUE(observer.empty());
 }
@@ -102,15 +102,15 @@ TEST(Observer, AllOfFiltered) {
     ASSERT_TRUE(observer.empty());
     ASSERT_EQ(observer.data(), nullptr);
 
-    registry.remove<int>(entity);
+    registry.erase<int>(entity);
     registry.emplace<char>(entity);
     registry.emplace<double>(entity);
     registry.emplace<int>(entity);
 
     ASSERT_TRUE(observer.empty());
 
-    registry.remove<int>(entity);
-    registry.remove<double>(entity);
+    registry.erase<int>(entity);
+    registry.erase<double>(entity);
     registry.emplace<int>(entity);
 
     ASSERT_EQ(observer.size(), 1u);
@@ -121,12 +121,12 @@ TEST(Observer, AllOfFiltered) {
 
     ASSERT_TRUE(observer.empty());
 
-    registry.remove<double>(entity);
+    registry.erase<double>(entity);
 
     ASSERT_TRUE(observer.empty());
 
     observer.disconnect();
-    registry.remove<int>(entity);
+    registry.erase<int>(entity);
     registry.emplace<int>(entity);
 
     ASSERT_TRUE(observer.empty());
@@ -189,7 +189,7 @@ TEST(Observer, ObserveFiltered) {
 
     ASSERT_TRUE(observer.empty());
 
-    registry.remove<double>(entity);
+    registry.erase<double>(entity);
     registry.replace<int>(entity);
 
     ASSERT_EQ(observer.size(), 1u);
@@ -200,7 +200,7 @@ TEST(Observer, ObserveFiltered) {
 
     ASSERT_TRUE(observer.empty());
 
-    registry.remove<double>(entity);
+    registry.erase<double>(entity);
 
     ASSERT_TRUE(observer.empty());
 
@@ -222,13 +222,13 @@ TEST(Observer, AllOfObserve) {
     registry.emplace<int>(entity);
     registry.emplace<char>(entity);
     registry.replace<char>(entity);
-    registry.remove<int>(entity);
+    registry.erase<int>(entity);
 
     ASSERT_EQ(observer.size(), 1u);
     ASSERT_FALSE(observer.empty());
     ASSERT_EQ(*observer.data(), entity);
 
-    registry.remove<char>(entity);
+    registry.erase<char>(entity);
     registry.emplace<char>(entity);
 
     ASSERT_TRUE(observer.empty());
@@ -256,7 +256,7 @@ TEST(Observer, CrossRulesCornerCase) {
     ASSERT_TRUE(observer.empty());
 
     registry.emplace<char>(entity);
-    registry.remove<int>(entity);
+    registry.erase<int>(entity);
 
     ASSERT_FALSE(observer.empty());
 }
@@ -323,7 +323,7 @@ TEST(Observer, MultipleFilters) {
     ASSERT_FALSE(observer.empty());
     ASSERT_EQ(*observer.data(), entity);
 
-    registry.remove<float>(entity);
+    registry.erase<float>(entity);
 
     ASSERT_TRUE(observer.empty());
 
@@ -362,7 +362,7 @@ TEST(Observer, GroupCornerCase) {
     ASSERT_FALSE(remove_observer.empty());
 
     remove_observer.clear();
-    registry.remove<char>(entity);
+    registry.erase<char>(entity);
 
     ASSERT_FALSE(add_observer.empty());
     ASSERT_TRUE(remove_observer.empty());

+ 61 - 23
test/entt/entity/registry.cpp

@@ -192,8 +192,8 @@ TEST(Registry, Functionalities) {
 
     ASSERT_EQ(registry.emplace<int>(e0, 42), 42);
     ASSERT_EQ(registry.emplace<char>(e0, 'c'), 'c');
-    ASSERT_NO_FATAL_FAILURE(registry.remove<int>(e1));
-    ASSERT_NO_FATAL_FAILURE(registry.remove<char>(e1));
+    ASSERT_NO_FATAL_FAILURE(registry.erase<int>(e1));
+    ASSERT_NO_FATAL_FAILURE(registry.erase<char>(e1));
 
     ASSERT_TRUE((registry.all_of<int, char>(e0)));
     ASSERT_FALSE((registry.all_of<int, char>(e1)));
@@ -288,8 +288,8 @@ TEST(Registry, Functionalities) {
 
     registry.emplace<int>(e4);
 
-    ASSERT_EQ(registry.remove_if_exists<int>(e4), 1u);
-    ASSERT_EQ(registry.remove_if_exists<int>(e5), 0u);
+    ASSERT_EQ(registry.remove<int>(e4), 1u);
+    ASSERT_EQ(registry.remove<int>(e5), 0u);
 
     ASSERT_EQ(registry.size<int>(), 0u);
     ASSERT_EQ(registry.size<char>(), 0u);
@@ -319,7 +319,7 @@ TEST(Registry, Move) {
     ASSERT_EQ(test.parent, &registry);
 
     entt::registry other{std::move(registry)};
-    other.remove<int>(entity);
+    other.erase<int>(entity);
     registry.emplace<int>(registry.create(entity));
 
     ASSERT_EQ(test.parent, &other);
@@ -771,7 +771,7 @@ TEST(Registry, CleanViewAfterRemoveAndClear) {
 
     ASSERT_EQ(view.size_hint(), 1u);
 
-    registry.remove<char>(entity);
+    registry.erase<char>(entity);
 
     ASSERT_EQ(view.size_hint(), 1u);
 
@@ -802,7 +802,7 @@ TEST(Registry, CleanNonOwningGroupViewAfterRemoveAndClear) {
 
     ASSERT_EQ(group.size(), 1u);
 
-    registry.remove<char>(entity);
+    registry.erase<char>(entity);
 
     ASSERT_EQ(group.size(), 0u);
 
@@ -833,7 +833,7 @@ TEST(Registry, CleanFullOwningGroupViewAfterRemoveAndClear) {
 
     ASSERT_EQ(group.size(), 1u);
 
-    registry.remove<char>(entity);
+    registry.erase<char>(entity);
 
     ASSERT_EQ(group.size(), 0u);
 
@@ -864,7 +864,7 @@ TEST(Registry, CleanPartialOwningGroupViewAfterRemoveAndClear) {
 
     ASSERT_EQ(group.size(), 1u);
 
-    registry.remove<char>(entity);
+    registry.erase<char>(entity);
 
     ASSERT_EQ(group.size(), 0u);
 
@@ -920,7 +920,7 @@ TEST(Registry, NestedGroups) {
         ASSERT_FALSE(g1.contains(entities[i*2]));
         ASSERT_TRUE(g2.contains(entities[i*2+1]));
         ASSERT_TRUE(g2.contains(entities[i*2]));
-        registry.remove<int>(entities[i*2+1]);
+        registry.erase<int>(entities[i*2+1]);
     }
 
     ASSERT_EQ(g1.size(), 0u);
@@ -965,7 +965,7 @@ TEST(Registry, NestedGroups) {
     ASSERT_EQ(g3.size(), 0u);
 
     for(auto i = 0u; i < 5u; ++i) {
-        registry.remove<double>(entities[i*2]);
+        registry.erase<double>(entities[i*2]);
     }
 
     ASSERT_EQ(g1.size(), 10u);
@@ -979,8 +979,8 @@ TEST(Registry, NestedGroups) {
         ASSERT_TRUE(g2.contains(entities[i*2]));
         ASSERT_FALSE(g3.contains(entities[i*2+1]));
         ASSERT_TRUE(g3.contains(entities[i*2]));
-        registry.remove<int>(entities[i*2+1]);
-        registry.remove<int>(entities[i*2]);
+        registry.erase<int>(entities[i*2+1]);
+        registry.erase<int>(entities[i*2]);
     }
 
     ASSERT_EQ(g1.size(), 0u);
@@ -1095,8 +1095,8 @@ TEST(Registry, Signals) {
     ASSERT_EQ(listener.counter, 4);
     ASSERT_EQ(listener.last, e0);
 
-    registry.remove<empty_type>(e0);
-    registry.remove<int>(e0);
+    registry.erase<empty_type>(e0);
+    registry.erase<int>(e0);
 
     ASSERT_EQ(listener.counter, 2);
     ASSERT_EQ(listener.last, e0);
@@ -1104,8 +1104,8 @@ TEST(Registry, Signals) {
     registry.on_destroy<empty_type>().disconnect<&listener::decr<empty_type>>(listener);
     registry.on_destroy<int>().disconnect<&listener::decr<int>>(listener);
 
-    registry.remove<empty_type>(e1);
-    registry.remove<int>(e1);
+    registry.erase<empty_type>(e1);
+    registry.erase<int>(e1);
 
     ASSERT_EQ(listener.counter, 2);
     ASSERT_EQ(listener.last, e0);
@@ -1123,7 +1123,7 @@ TEST(Registry, Signals) {
     registry.on_destroy<int>().connect<&listener::decr<int>>(listener);
 
     registry.emplace<int>(e0);
-    registry.remove_if_exists<int>(e1);
+    registry.erase<int>(e1);
 
     ASSERT_EQ(listener.counter, 2);
     ASSERT_EQ(listener.last, e1);
@@ -1131,7 +1131,7 @@ TEST(Registry, Signals) {
     registry.on_construct<empty_type>().connect<&listener::incr<empty_type>>(listener);
     registry.on_destroy<empty_type>().connect<&listener::decr<empty_type>>(listener);
 
-    registry.remove_if_exists<empty_type>(e1);
+    registry.erase<empty_type>(e1);
     registry.emplace<empty_type>(e0);
 
     ASSERT_EQ(listener.counter, 2);
@@ -1153,8 +1153,8 @@ TEST(Registry, Signals) {
     ASSERT_EQ(listener.counter, 2);
     ASSERT_EQ(listener.last, e1);
 
-    registry.remove<int>(e0);
-    registry.remove<empty_type>(e0);
+    registry.erase<int>(e0);
+    registry.erase<empty_type>(e0);
     registry.emplace_or_replace<int>(e0);
     registry.emplace_or_replace<empty_type>(e0);
 
@@ -1263,6 +1263,40 @@ TEST(Registry, Insert) {
     ASSERT_EQ(registry.get<float>(e2), 2.f);
 }
 
+TEST(Registry, Erase) {
+    entt::registry registry;
+
+    const auto e0 = registry.create();
+    const auto e1 = registry.create();
+    const auto e2 = registry.create();
+
+    registry.emplace<int>(e0);
+    registry.emplace<char>(e0);
+    registry.emplace<double>(e0);
+
+    registry.emplace<int>(e1);
+    registry.emplace<char>(e1);
+
+    registry.emplace<int>(e2);
+
+    ASSERT_TRUE(registry.all_of<int>(e0));
+    ASSERT_TRUE(registry.all_of<int>(e1));
+    ASSERT_TRUE(registry.all_of<int>(e2));
+
+    const auto view = registry.view<int, char>();
+
+    registry.erase<int>(e0);
+    registry.erase<int>(view.begin(), view.end());
+    registry.erase<int>(view.begin(), view.end());
+
+    ASSERT_DEATH(registry.erase<int>(e0), "");
+    ASSERT_DEATH(registry.erase<int>(e1), "");
+
+    ASSERT_FALSE(registry.all_of<int>(e0));
+    ASSERT_FALSE(registry.all_of<int>(e1));
+    ASSERT_TRUE(registry.all_of<int>(e2));
+}
+
 TEST(Registry, Remove) {
     entt::registry registry;
 
@@ -1284,7 +1318,11 @@ TEST(Registry, Remove) {
     ASSERT_TRUE(registry.all_of<int>(e2));
 
     const auto view = registry.view<int, char>();
-    registry.remove<int>(view.begin(), view.end());
+
+    ASSERT_EQ(registry.remove<int>(e0), 1u);
+    ASSERT_EQ(registry.remove<int>(view.begin(), view.end()), 1u);
+    ASSERT_EQ(registry.remove<int>(view.begin(), view.end()), 0u);
+    ASSERT_EQ(registry.remove<int>(e1), 0u);
 
     ASSERT_FALSE(registry.all_of<int>(e0));
     ASSERT_FALSE(registry.all_of<int>(e1));
@@ -1444,7 +1482,7 @@ TEST(Registry, Dependencies) {
     ASSERT_TRUE(registry.all_of<int>(entity));
     ASSERT_EQ(registry.get<double>(entity), .0);
 
-    registry.remove<int>(entity);
+    registry.erase<int>(entity);
 
     ASSERT_FALSE((registry.any_of<int, double>(entity)));
 

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

@@ -50,8 +50,8 @@ TEST(SingleComponentView, Functionalities) {
     ASSERT_EQ(*(view.raw() + 0), '2');
     ASSERT_EQ(*(cview.raw() + 1), '1');
 
-    registry.remove<char>(e0);
-    registry.remove<char>(e1);
+    registry.erase<char>(e0);
+    registry.erase<char>(e1);
 
     ASSERT_EQ(view.begin(), view.end());
     ASSERT_EQ(view.rbegin(), view.rend());
@@ -296,7 +296,7 @@ TEST(SingleComponentView, Find) {
     const auto e3 = registry.create();
     registry.emplace<int>(e3);
 
-    registry.remove<int>(e1);
+    registry.erase<int>(e1);
 
     ASSERT_NE(view.find(e0), view.end());
     ASSERT_EQ(view.find(e1), view.end());
@@ -760,7 +760,7 @@ TEST(MultiComponentView, Find) {
     registry.emplace<int>(e3);
     registry.emplace<char>(e3);
 
-    registry.remove<int>(e1);
+    registry.erase<int>(e1);
 
     ASSERT_NE(view.find(e0), view.end());
     ASSERT_EQ(view.find(e1), view.end());
@@ -816,8 +816,8 @@ TEST(MultiComponentView, ExcludedComponents) {
 
     registry.emplace<char>(e0);
     registry.emplace<char>(e2);
-    registry.remove<char>(e1);
-    registry.remove<char>(e3);
+    registry.erase<char>(e1);
+    registry.erase<char>(e3);
 
     for(const auto entity: view) {
         ASSERT_TRUE(entity == e1 || entity == e3);

+ 1 - 1
test/example/signal_less.cpp

@@ -35,7 +35,7 @@ TEST(Example, SignalLess) {
 
     // literally a test for storage_adapter_mixin
     registry.emplace<int>(entity[0], 0);
-    registry.remove<int>(entity[0]);
+    registry.erase<int>(entity[0]);
     registry.insert<int>(std::begin(entity), std::end(entity), 3);
     registry.patch<int>(entity[0], [](auto &value) { value = 42; });