5 Commits 4d7fce0edc ... ca9a5f22d0

Auteur SHA1 Bericht Datum
  skypjack ca9a5f22d0 test: empty_mixin 2 dagen geleden
  skypjack b7e8bb265f test: use the mixin design a little more 2 dagen geleden
  skypjack b5797912d3 test: use the mixin design a little more 2 dagen geleden
  skypjack c113dfe082 test: use the mixin design a little more 2 dagen geleden
  skypjack 24a7cc0deb sparse_set: review internal functions (perf) 2 dagen geleden

+ 0 - 2
TODO

@@ -34,8 +34,6 @@ TODO:
 * organizer: view/storage only based model, no registry
 * introduce a way to inject stl from outside too
 * redesign snapshot as a whole
-* use the value type mixin more in the test suite to reduce the number of utility types
 * explore "runtime" mode for hashed string where the source is copied internally
-* swap_only/swap_and_pop/in_place_pop can (should?) accept the entity
 * storage: shrink_to_fit does not work with reentrant destructor?
 * test trivially_destructible optimization

+ 16 - 16
src/entt/entity/sparse_set.hpp

@@ -230,25 +230,25 @@ protected:
 
     /**
      * @brief Erases an entity from a sparse set.
-     * @param it An iterator to the element to pop.
+     * @param entt A valid identifier for the element to pop.
      */
-    void swap_only(const basic_iterator it) {
+    void swap_only(const Entity entt) {
         ENTT_ASSERT(mode == deletion_policy::swap_only, "Deletion policy mismatch");
-        const auto pos = index(*it);
-        bump(traits_type::next(*it));
+        const auto pos = index(entt);
+        bump(traits_type::next(entt));
         swap_at(pos, head -= (pos < head));
     }
 
     /**
      * @brief Erases an entity from a sparse set.
-     * @param it An iterator to the element to pop.
+     * @param entt A valid identifier for the element to pop.
      */
-    void swap_and_pop(const basic_iterator it) {
+    void swap_and_pop(const Entity entt) {
         ENTT_ASSERT(mode == deletion_policy::swap_and_pop, "Deletion policy mismatch");
-        auto &self = sparse_ref(*it);
-        const auto entt = traits_type::to_entity(self);
-        sparse_ref(packed.back()) = traits_type::combine(entt, traits_type::to_integral(packed.back()));
-        packed[static_cast<size_type>(entt)] = packed.back();
+        auto &self = sparse_ref(entt);
+        const auto pos = traits_type::to_entity(self);
+        sparse_ref(packed.back()) = traits_type::combine(pos, traits_type::to_integral(packed.back()));
+        packed[static_cast<size_type>(pos)] = packed.back();
         // unnecessary but it helps to detect nasty bugs
         // NOLINTNEXTLINE(bugprone-assert-side-effect)
         ENTT_ASSERT((packed.back() = null, true), "");
@@ -259,11 +259,11 @@ protected:
 
     /**
      * @brief Erases an entity from a sparse set.
-     * @param it An iterator to the element to pop.
+     * @param entt A valid identifier for the element to pop.
      */
-    void in_place_pop(const basic_iterator it) {
+    void in_place_pop(const Entity entt) {
         ENTT_ASSERT(mode == deletion_policy::in_place, "Deletion policy mismatch");
-        const auto pos = entity_to_pos(std::exchange(sparse_ref(*it), null));
+        const auto pos = entity_to_pos(std::exchange(sparse_ref(entt), null));
         packed[pos] = traits_type::combine(static_cast<traits_type::entity_type>(std::exchange(head, pos)), tombstone);
     }
 
@@ -276,17 +276,17 @@ protected:
         switch(mode) {
         case deletion_policy::swap_and_pop:
             for(; first != last; ++first) {
-                swap_and_pop(first);
+                swap_and_pop(*first);
             }
             break;
         case deletion_policy::in_place:
             for(; first != last; ++first) {
-                in_place_pop(first);
+                in_place_pop(*first);
             }
             break;
         case deletion_policy::swap_only:
             for(; first != last; ++first) {
-                swap_only(first);
+                swap_only(*first);
             }
             break;
         }

+ 5 - 5
src/entt/entity/storage.hpp

@@ -324,17 +324,17 @@ protected:
             auto &elem = element_at(base_type::index(*first));
 
             if constexpr(traits_type::in_place_delete) {
-                base_type::in_place_pop(first);
+                base_type::in_place_pop(*first);
                 alloc_traits::destroy(allocator, std::addressof(elem));
             } else if constexpr(std::is_trivially_destructible_v<element_type>) {
                 elem = std::move(element_at(base_type::size() - 1u));
-                base_type::swap_and_pop(first);
+                base_type::swap_and_pop(*first);
             } else {
                 auto &other = element_at(base_type::size() - 1u);
                 // destroying on exit allows reentrant destructors
                 [[maybe_unused]] auto unused = std::exchange(elem, std::move(other));
                 alloc_traits::destroy(allocator, std::addressof(other));
-                base_type::swap_and_pop(first);
+                base_type::swap_and_pop(*first);
             }
         }
     }
@@ -349,11 +349,11 @@ protected:
             for(auto first = base_type::begin(); !(first.index() < 0); ++first) {
                 if constexpr(traits_type::in_place_delete) {
                     if(*first != tombstone) {
-                        base_type::in_place_pop(first);
+                        base_type::in_place_pop(*first);
                         alloc_traits::destroy(allocator, std::addressof(element_at(static_cast<size_type>(first.index()))));
                     }
                 } else {
-                    base_type::swap_and_pop(first);
+                    base_type::swap_and_pop(*first);
                     alloc_traits::destroy(allocator, std::addressof(element_at(static_cast<size_type>(first.index()))));
                 }
             }

+ 0 - 12
test/common/non_comparable.h

@@ -1,12 +0,0 @@
-#ifndef ENTT_COMMON_NON_COMPARABLE_H
-#define ENTT_COMMON_NON_COMPARABLE_H
-
-namespace test {
-
-struct non_comparable {
-    bool operator==(const non_comparable &) const noexcept = delete;
-};
-
-} // namespace test
-
-#endif

+ 0 - 17
test/common/non_default_constructible.h

@@ -1,17 +0,0 @@
-#ifndef ENTT_COMMON_NON_DEFAULT_CONSTRUCTIBLE_H
-#define ENTT_COMMON_NON_DEFAULT_CONSTRUCTIBLE_H
-
-namespace test {
-
-struct non_default_constructible {
-    non_default_constructible() = delete;
-
-    non_default_constructible(int v)
-        : value{v} {}
-
-    int value;
-};
-
-} // namespace test
-
-#endif

+ 0 - 20
test/common/non_movable.h

@@ -1,20 +0,0 @@
-#ifndef ENTT_COMMON_NON_MOVABLE_H
-#define ENTT_COMMON_NON_MOVABLE_H
-
-namespace test {
-
-struct non_movable {
-    non_movable() = default;
-
-    non_movable(const non_movable &) = default;
-    non_movable(non_movable &&) = delete;
-
-    non_movable &operator=(const non_movable &) = default;
-    non_movable &operator=(non_movable &&) = delete;
-
-    int value{};
-};
-
-} // namespace test
-
-#endif

+ 46 - 14
test/common/value_type.h

@@ -6,22 +6,48 @@
 
 namespace test {
 
-template<typename... Type>
-struct pointer_stable_mixin: Type... {
+namespace internal {
+
+template<typename Type>
+struct pointer_stable_mixin: Type {
     static constexpr auto in_place_delete = true;
-    [[nodiscard]] constexpr bool operator==(const pointer_stable_mixin &) const noexcept = default;
-    [[nodiscard]] constexpr auto operator<=>(const pointer_stable_mixin &) const noexcept = default;
+    using Type::Type;
+    using Type::operator=;
+};
+
+template<typename Type>
+struct non_default_constructible_mixin: Type {
+    using Type::Type;
+    using Type::operator=;
+    non_default_constructible_mixin() = delete;
+};
+
+template<typename Type>
+struct non_trivially_destructible_mixin: Type {
+    using Type::Type;
+    using Type::operator=;
+    virtual ~non_trivially_destructible_mixin() noexcept = default;
 };
 
-template<typename... Type>
-struct non_trivially_destructible_mixin: Type... {
-    [[nodiscard]] constexpr bool operator==(const non_trivially_destructible_mixin &) const noexcept = default;
-    [[nodiscard]] constexpr auto operator<=>(const non_trivially_destructible_mixin &) const noexcept = default;
-    virtual ~non_trivially_destructible_mixin() = default;
+template<typename Type>
+struct non_comparable_mixin: Type {
+    using Type::Type;
+    using Type::operator=;
+    bool operator==(const non_comparable_mixin &) const noexcept = delete;
 };
 
-template<typename... Type>
-struct value_type final: Type... {
+template<typename Type>
+struct non_movable_mixin: Type {
+    using Type::Type;
+    non_movable_mixin(non_movable_mixin &&) noexcept = delete;
+    non_movable_mixin(const non_movable_mixin &) noexcept = default;
+    non_movable_mixin &operator=(non_movable_mixin &&) noexcept = delete;
+    non_movable_mixin &operator=(const non_movable_mixin &) noexcept = default;
+};
+
+struct empty_mixin {};
+
+struct value_type {
     constexpr value_type() = default;
     constexpr value_type(int elem): value{elem} {}
     [[nodiscard]] constexpr bool operator==(const value_type &) const noexcept = default;
@@ -29,13 +55,19 @@ struct value_type final: Type... {
     int value{};
 };
 
-using pointer_stable = value_type<pointer_stable_mixin<>>;
-using non_trivially_destructible = value_type<non_trivially_destructible_mixin<>>;
-using pointer_stable_non_trivially_destructible = value_type<pointer_stable_mixin<non_trivially_destructible_mixin<>>>;
+} // namespace internal
+
+using pointer_stable = internal::pointer_stable_mixin<internal::value_type>;
+using non_default_constructible = internal::non_default_constructible_mixin<internal::value_type>;
+using non_trivially_destructible = internal::non_trivially_destructible_mixin<internal::value_type>;
+using pointer_stable_non_trivially_destructible = internal::pointer_stable_mixin<internal::non_trivially_destructible_mixin<internal::value_type>>;
+using non_comparable = internal::non_comparable_mixin<internal::empty_mixin>;
+using non_movable = internal::non_movable_mixin<internal::value_type>;
 
 static_assert(std::is_trivially_destructible_v<test::pointer_stable>, "Not a trivially destructible type");
 static_assert(!std::is_trivially_destructible_v<test::non_trivially_destructible>, "Trivially destructible type");
 static_assert(!std::is_trivially_destructible_v<test::pointer_stable_non_trivially_destructible>, "Trivially destructible type");
+static_assert(!std::is_move_constructible_v<test::non_movable> && !std::is_move_assignable_v<test::non_movable>, "Movable type");
 
 } // namespace test
 

+ 1 - 2
test/entt/core/any.cpp

@@ -13,8 +13,7 @@
 #include "../../common/config.h"
 #include "../../common/linter.hpp"
 #include "../../common/new_delete.h"
-#include "../../common/non_comparable.h"
-#include "../../common/non_movable.h"
+#include "../../common/value_type.h"
 
 template<std::size_t Len>
 struct tracker {

+ 1 - 1
test/entt/core/compressed_pair.cpp

@@ -7,7 +7,7 @@
 #include <gtest/gtest.h>
 #include <entt/core/compressed_pair.hpp>
 #include "../../common/empty.h"
-#include "../../common/non_default_constructible.h"
+#include "../../common/value_type.h"
 
 TEST(CompressedPair, Size) {
     struct local {

+ 1 - 1
test/entt/core/type_traits.cpp

@@ -8,7 +8,7 @@
 #include <gtest/gtest.h>
 #include <entt/core/hashed_string.hpp>
 #include <entt/core/type_traits.hpp>
-#include "../../common/non_comparable.h"
+#include "../../common/value_type.h"
 
 struct nlohmann_json_like final {
     using value_type = nlohmann_json_like;

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

@@ -4,7 +4,7 @@
 #include <entt/entity/component.hpp>
 #include "../../common/boxed_type.h"
 #include "../../common/empty.h"
-#include "../../common/non_movable.h"
+#include "../../common/value_type.h"
 
 struct ComponentBase: testing::Test {
     enum class my_entity : std::uint32_t {};

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

@@ -23,7 +23,6 @@
 #include "../../common/config.h"
 #include "../../common/empty.h"
 #include "../../common/mixin.hpp"
-#include "../../common/non_default_constructible.h"
 #include "../../common/value_type.h"
 
 struct Registry: testing::Test {

+ 0 - 1
test/entt/entity/sigh_mixin.cpp

@@ -13,7 +13,6 @@
 #include <entt/signal/sigh.hpp>
 #include "../../common/config.h"
 #include "../../common/linter.hpp"
-#include "../../common/non_default_constructible.h"
 #include "../../common/registry.h"
 #include "../../common/throwing_allocator.hpp"
 #include "../../common/throwing_type.hpp"

+ 1 - 1
test/entt/meta/meta_any.cpp

@@ -14,7 +14,7 @@
 #include <entt/meta/resolve.hpp>
 #include "../../common/config.h"
 #include "../../common/linter.hpp"
-#include "../../common/non_comparable.h"
+#include "../../common/value_type.h"
 
 struct MetaAny: ::testing::Test {
     struct clazz {

+ 1 - 1
test/entt/meta/meta_container.cpp

@@ -15,7 +15,7 @@
 #include <entt/meta/resolve.hpp>
 #include "../../common/config.h"
 #include "../../common/empty.h"
-#include "../../common/non_default_constructible.h"
+#include "../../common/value_type.h"
 
 TEST(MetaContainer, Invalid) {
     ASSERT_FALSE(entt::meta_any{0}.as_sequence_container());