فهرست منبع

meta: meta containers support to ::reserve

skypjack 2 سال پیش
والد
کامیت
378d98096d
3فایلهای تغییر یافته به همراه58 افزوده شده و 2 حذف شده
  1. 25 1
      src/entt/meta/container.hpp
  2. 21 1
      src/entt/meta/meta.hpp
  3. 12 0
      test/entt/meta/meta_container.cpp

+ 25 - 1
src/entt/meta/container.hpp

@@ -38,6 +38,12 @@ struct key_only_associative_container: std::true_type {};
 template<typename Type>
 struct key_only_associative_container<Type, std::void_t<typename Type::mapped_type>>: std::false_type {};
 
+template<typename, typename = void>
+struct reserve_aware_container: std::false_type {};
+
+template<typename Type>
+struct reserve_aware_container<Type, std::void_t<decltype(&Type::reserve)>>: std::true_type {};
+
 template<typename Type>
 struct basic_meta_sequence_container_traits {
     static_assert(std::is_same_v<Type, std::remove_cv_t<std::remove_reference_t<Type>>>, "Unexpected type");
@@ -58,7 +64,16 @@ struct basic_meta_sequence_container_traits {
         }
     }
 
-    [[nodiscard]] static bool resize([[maybe_unused]] void *container, [[maybe_unused]] size_type sz) {
+    [[nodiscard]] static bool reserve([[maybe_unused]] void *container, [[maybe_unused]] const size_type sz) {
+        if constexpr(reserve_aware_container<Type>::value) {
+            static_cast<Type *>(container)->reserve(sz);
+            return true;
+        } else {
+            return false;
+        }
+    }
+
+    [[nodiscard]] static bool resize([[maybe_unused]] void *container, [[maybe_unused]] const size_type sz) {
         if constexpr(dynamic_sequence_container<Type>::value) {
             static_cast<Type *>(container)->resize(sz);
             return true;
@@ -120,6 +135,15 @@ struct basic_meta_associative_container_traits {
         return true;
     }
 
+    [[nodiscard]] static bool reserve([[maybe_unused]] void *container, [[maybe_unused]] const size_type sz) {
+        if constexpr(reserve_aware_container<Type>::value) {
+            static_cast<Type *>(container)->reserve(sz);
+            return true;
+        } else {
+            return false;
+        }
+    }
+
     [[nodiscard]] static iterator iter(const meta_ctx &ctx, const void *container, const bool as_const, const bool as_end) {
         if(as_const) {
             const auto it = as_end ? static_cast<const Type *>(container)->end() : static_cast<const Type *>(container)->begin();

+ 21 - 1
src/entt/meta/meta.hpp

@@ -54,6 +54,7 @@ public:
         value_type_node = &internal::resolve<typename Type::value_type>;
         size_fn = &meta_sequence_container_traits<Type>::size;
         clear_fn = &meta_sequence_container_traits<Type>::clear;
+        reserve_fn = &meta_sequence_container_traits<Type>::reserve;
         resize_fn = &meta_sequence_container_traits<Type>::resize;
         iter_fn = &meta_sequence_container_traits<Type>::iter;
         insert_or_erase_fn = &meta_sequence_container_traits<Type>::insert_or_erase;
@@ -64,6 +65,7 @@ public:
     [[nodiscard]] inline size_type size() const noexcept;
     inline bool resize(const size_type);
     inline bool clear();
+    inline bool reserve(const size_type);
     [[nodiscard]] inline iterator begin();
     [[nodiscard]] inline iterator end();
     inline iterator insert(iterator, meta_any);
@@ -76,7 +78,8 @@ private:
     internal::meta_type_node (*value_type_node)(const internal::meta_context &){};
     size_type (*size_fn)(const void *) noexcept {};
     bool (*clear_fn)(void *){};
-    bool (*resize_fn)(void *, size_type){};
+    bool (*reserve_fn)(void *, const size_type){};
+    bool (*resize_fn)(void *, const size_type){};
     iterator (*iter_fn)(const meta_ctx &, const void *, const bool, const bool){};
     iterator (*insert_or_erase_fn)(const meta_ctx &, void *, const any &, meta_any &){};
     any storage{};
@@ -117,6 +120,7 @@ public:
         value_type_node = &internal::resolve<typename Type::value_type>;
         size_fn = &meta_associative_container_traits<Type>::size;
         clear_fn = &meta_associative_container_traits<Type>::clear;
+        reserve_fn = &meta_associative_container_traits<Type>::reserve;
         iter_fn = &meta_associative_container_traits<Type>::iter;
         insert_or_erase_fn = &meta_associative_container_traits<Type>::insert_or_erase;
         find_fn = &meta_associative_container_traits<Type>::find;
@@ -129,6 +133,7 @@ public:
     [[nodiscard]] inline meta_type value_type() const noexcept;
     [[nodiscard]] inline size_type size() const noexcept;
     inline bool clear();
+    inline bool reserve(const size_type);
     [[nodiscard]] inline iterator begin();
     [[nodiscard]] inline iterator end();
     inline bool insert(meta_any);
@@ -145,6 +150,7 @@ private:
     internal::meta_type_node (*value_type_node)(const internal::meta_context &){};
     size_type (*size_fn)(const void *) noexcept {};
     bool (*clear_fn)(void *){};
+    bool (*reserve_fn)(void *, const size_type){};
     iterator (*iter_fn)(const meta_ctx &, const void *, const bool, const bool){};
     size_type (*insert_or_erase_fn)(void *, meta_any &, meta_any &){};
     iterator (*find_fn)(const meta_ctx &, const void *, const bool, meta_any &){};
@@ -1861,6 +1867,15 @@ inline bool meta_sequence_container::clear() {
     return (storage.policy() != any_policy::cref) && clear_fn(storage.data());
 }
 
+/**
+ * @brief Reserves storage for at least the given number of elements.
+ * @param sz The new capacity of the container.
+ * @return True in case of success, false otherwise.
+ */
+inline bool meta_sequence_container::reserve(const size_type sz) {
+    return (storage.policy() != any_policy::cref) && reserve_fn(storage.data(), sz);
+}
+
 /**
  * @brief Returns an iterator to the first element of a container.
  * @return An iterator to the first element of the container.
@@ -1955,6 +1970,11 @@ inline bool meta_associative_container::clear() {
     return (storage.policy() != any_policy::cref) && clear_fn(storage.data());
 }
 
+/*! @copydoc meta_sequence_container::reserve */
+inline bool meta_associative_container::reserve(const size_type sz) {
+    return (storage.policy() != any_policy::cref) && reserve_fn(storage.data(), sz);
+}
+
 /*! @copydoc meta_sequence_container::begin */
 [[nodiscard]] inline meta_associative_container::iterator meta_associative_container::begin() {
     return iter_fn(*ctx, std::as_const(storage).data(), (storage.policy() == any_policy::cref), false);

+ 12 - 0
test/entt/meta/meta_container.cpp

@@ -152,6 +152,7 @@ TEST(MetaContainer, StdVector) {
     ASSERT_EQ(ret->cast<int>(), 2);
 
     ASSERT_TRUE(view.clear());
+    ASSERT_TRUE(view.reserve(42u));
     ASSERT_EQ(view.size(), 0u);
 }
 
@@ -193,6 +194,7 @@ TEST(MetaContainer, StdArray) {
     ASSERT_EQ(it->cast<int>(), 2);
 
     ASSERT_FALSE(view.clear());
+    ASSERT_FALSE(view.reserve(42u));
     ASSERT_EQ(view.size(), 3u);
 }
 
@@ -247,6 +249,7 @@ TEST(MetaContainer, StdList) {
     ASSERT_EQ(ret->cast<int>(), 2);
 
     ASSERT_TRUE(view.clear());
+    ASSERT_FALSE(view.reserve(42u));
     ASSERT_EQ(view.size(), 0u);
 }
 
@@ -301,6 +304,7 @@ TEST(MetaContainer, StdDeque) {
     ASSERT_EQ(ret->cast<int>(), 2);
 
     ASSERT_TRUE(view.clear());
+    ASSERT_FALSE(view.reserve(42u));
     ASSERT_EQ(view.size(), 0u);
 }
 
@@ -344,6 +348,7 @@ TEST(MetaContainer, StdMap) {
 
     ASSERT_EQ(view.erase(1.), 1u);
     ASSERT_TRUE(view.clear());
+    ASSERT_FALSE(view.reserve(42u));
     ASSERT_EQ(view.size(), 0u);
 }
 
@@ -386,6 +391,7 @@ TEST(MetaContainer, StdSet) {
 
     ASSERT_EQ(view.erase(1.), 1u);
     ASSERT_TRUE(view.clear());
+    ASSERT_FALSE(view.reserve(42u));
     ASSERT_EQ(view.size(), 0u);
 }
 
@@ -433,6 +439,7 @@ TEST(MetaContainer, DenseMap) {
 
     ASSERT_EQ(view.erase(1.), 1u);
     ASSERT_TRUE(view.clear());
+    ASSERT_TRUE(view.reserve(42u));
     ASSERT_EQ(view.size(), 0u);
 }
 
@@ -479,6 +486,7 @@ TEST(MetaContainer, DenseSet) {
 
     ASSERT_EQ(view.erase(1.), 1u);
     ASSERT_TRUE(view.clear());
+    ASSERT_TRUE(view.reserve(42u));
     ASSERT_EQ(view.size(), 0u);
 }
 
@@ -517,6 +525,7 @@ TEST(MetaContainer, ConstSequenceContainer) {
     ASSERT_EQ(view.size(), 1u);
 
     ASSERT_FALSE(view.clear());
+    ASSERT_FALSE(view.reserve(42u));
     ASSERT_EQ(view.size(), 1u);
 }
 
@@ -559,6 +568,7 @@ TEST(MetaContainer, ConstKeyValueAssociativeContainer) {
     ASSERT_NE(view.find(2), view.end());
 
     ASSERT_FALSE(view.clear());
+    ASSERT_FALSE(view.reserve(42u));
     ASSERT_EQ(view.size(), 1u);
 }
 
@@ -605,6 +615,7 @@ TEST(MetaContainer, ConstKeyOnlyAssociativeContainer) {
     ASSERT_NE(view.find(2), view.end());
 
     ASSERT_FALSE(view.clear());
+    ASSERT_FALSE(view.reserve(42u));
     ASSERT_EQ(view.size(), 1u);
 }
 
@@ -735,5 +746,6 @@ TEST(MetaContainer, StdVectorBool) {
     ASSERT_EQ(ret->cast<proxy_type>(), false);
 
     ASSERT_TRUE(view.clear());
+    ASSERT_TRUE(view.reserve(42u));
     ASSERT_EQ(cview.size(), 0u);
 }