Просмотр исходного кода

meta: further reduce size of symbols

Michele Caini 2 лет назад
Родитель
Сommit
db5ecd2c96
2 измененных файлов с 30 добавлено и 12 удалено
  1. 13 10
      src/entt/meta/container.hpp
  2. 17 2
      src/entt/meta/meta.hpp

+ 13 - 10
src/entt/meta/container.hpp

@@ -157,19 +157,22 @@ struct basic_meta_sequence_container_traits {
      * @brief Assigns one element to a container and constructs its object from
      * a given opaque instance.
      * @param container Opaque pointer to a container of the given type.
-     * @param elem An opaque instance of the object to construct.
+     * @param value Optional opaque instance of the object to construct (as
+     * value type).
+     * @param cref Optional opaque instance of the object to construct (as
+     * decayed const reference type).
      * @param it The meta iterator to rebind the underlying iterator to.
      * @return True in case of success, false otherwise.
      */
-    [[nodiscard]] static bool insert([[maybe_unused]] void *container, [[maybe_unused]] meta_any &elem, [[maybe_unused]] iterator &it) {
+    [[nodiscard]] static bool insert([[maybe_unused]] void *container, [[maybe_unused]] const void *value, [[maybe_unused]] const void *cref, [[maybe_unused]] iterator &it) {
         if constexpr(internal::dynamic_sequence_container_v<Type>) {
-            // this abomination is necessary because only on macos value_type and const_reference are different types for std::vector<bool>
-            if(elem.allow_cast<typename Type::const_reference>() || elem.allow_cast<typename Type::value_type>()) {
-                auto *const non_const = any_cast<typename Type::iterator>(&it.base());
-                const auto *element = elem.try_cast<std::remove_reference_t<typename Type::const_reference>>();
-                it.rebind(static_cast<Type *>(container)->insert(non_const ? *non_const : any_cast<const typename Type::const_iterator &>(it.base()), element ? *element : elem.cast<typename Type::value_type>()));
-                return true;
-            }
+            auto *const non_const = any_cast<typename Type::iterator>(&it.base());
+
+            it.rebind(static_cast<Type *>(container)->insert(
+                non_const ? *non_const : any_cast<const typename Type::const_iterator &>(it.base()),
+                value ? *static_cast<const typename Type::value_type *>(value) : *static_cast<const std::remove_reference_t<typename Type::const_reference> *>(cref)));
+
+            return true;
         }
 
         return false;
@@ -274,7 +277,7 @@ struct basic_meta_associative_container_traits {
      * @brief Inserts an element into a container, if the key does not exist.
      * @param container Opaque pointer to a container of the given type.
      * @param key An opaque key value of an element to insert.
-     * @param value An optional opaque value to insert (key-value containers).
+     * @param value Optional opaque value to insert (key-value containers).
      * @return True if the insertion took place, false otherwise.
      */
     [[nodiscard]] static bool insert(void *container, const void *key, [[maybe_unused]] const void *value) {

+ 17 - 2
src/entt/meta/meta.hpp

@@ -55,6 +55,7 @@ public:
     template<typename Type>
     void rebind(Type &instance) noexcept {
         value_type_node = &internal::resolve<typename Type::value_type>;
+        const_reference_node = &internal::resolve<std::remove_const_t<std::remove_reference_t<typename Type::const_reference>>>;
         size_fn = meta_sequence_container_traits<std::remove_const_t<Type>>::size;
         clear_fn = meta_sequence_container_traits<std::remove_const_t<Type>>::clear;
         reserve_fn = meta_sequence_container_traits<std::remove_const_t<Type>>::reserve;
@@ -81,13 +82,14 @@ public:
 private:
     const meta_ctx *ctx{};
     internal::meta_type_node (*value_type_node)(const internal::meta_context &){};
+    internal::meta_type_node (*const_reference_node)(const internal::meta_context &){};
     size_type (*size_fn)(const void *);
     bool (*clear_fn)(void *);
     bool (*reserve_fn)(void *, const size_type);
     bool (*resize_fn)(void *, const size_type);
     void (*begin_fn)(const void *, const bool, iterator &);
     void (*end_fn)(const void *, const bool, iterator &);
-    bool (*insert_fn)(void *, meta_any &, iterator &);
+    bool (*insert_fn)(void *, const void *, const void *, iterator &);
     bool (*erase_fn)(void *, iterator &);
     any storage{};
 };
@@ -1856,7 +1858,20 @@ inline bool meta_sequence_container::reserve(const size_type sz) {
  * @return A possibly invalid iterator to the inserted element.
  */
 inline meta_sequence_container::iterator meta_sequence_container::insert(iterator it, meta_any value) {
-    return ((storage.policy() != any_policy::cref) && insert_fn(storage.data(), value, it)) ? it : iterator{*ctx};
+    if(storage.policy() != any_policy::cref) {
+        // this abomination is necessary because only on macos value_type and const_reference are different types for std::vector<bool>
+        if(value.allow_cast(meta_type{*ctx, value_type_node(internal::meta_context::from(*ctx))})) {
+            if(insert_fn(storage.data(), std::as_const(value).data(), nullptr, it)) {
+                return it;
+            }
+        } else if(value.allow_cast(meta_type{*ctx, const_reference_node(internal::meta_context::from(*ctx))})) {
+            if(insert_fn(storage.data(), nullptr, std::as_const(value).data(), it)) {
+                return it;
+            }
+        }
+    }
+
+    return iterator{*ctx};
 }
 
 /**