Browse Source

meta: split begin/cbegin and end/cend for meta seq containers, review vtable

Michele Caini 2 years ago
parent
commit
5aeae3a452
3 changed files with 26 additions and 30 deletions
  1. 16 20
      src/entt/meta/container.hpp
  2. 8 10
      src/entt/meta/meta.hpp
  3. 2 0
      src/entt/meta/type_traits.hpp

+ 16 - 20
src/entt/meta/container.hpp

@@ -64,46 +64,42 @@ class basic_meta_sequence_container_traits {
     using size_type = typename meta_sequence_container::size_type;
     using iterator = typename meta_sequence_container::iterator;
 
-    static size_type basic_vtable(const operation op, const void *cvalue, void *value, iterator *it) {
+    static size_type basic_vtable(const operation op, const void *container, const void *value, iterator *it) {
         switch(op) {
         case operation::size:
-            return static_cast<const Type *>(cvalue)->size();
+            return static_cast<const Type *>(container)->size();
         case operation::clear:
             if constexpr(internal::dynamic_sequence_container<Type>::value) {
-                static_cast<Type *>(value)->clear();
+                static_cast<Type *>(const_cast<void *>(container))->clear();
                 return true;
             } else {
                 break;
             }
         case operation::reserve:
             if constexpr(internal::reserve_aware_container<Type>::value) {
-                static_cast<Type *>(value)->reserve(*static_cast<const size_type *>(cvalue));
+                static_cast<Type *>(const_cast<void *>(container))->reserve(*static_cast<const size_type *>(value));
                 return true;
             } else {
                 break;
             }
         case operation::resize:
             if constexpr(internal::dynamic_sequence_container<Type>::value) {
-                static_cast<Type *>(value)->resize(*static_cast<const size_type *>(cvalue));
+                static_cast<Type *>(const_cast<void *>(container))->resize(*static_cast<const size_type *>(value));
                 return true;
             } else {
                 break;
             }
         case operation::begin:
-            if(value) {
-                it->rebind(static_cast<Type *>(value)->begin());
-            } else {
-                it->rebind(static_cast<const Type *>(cvalue)->begin());
-            }
-
+            it->rebind(static_cast<Type *>(const_cast<void *>(container))->begin());
+            return true;
+        case operation::cbegin:
+            it->rebind(static_cast<const Type *>(container)->begin());
             return true;
         case operation::end:
-            if(value) {
-                it->rebind(static_cast<Type *>(value)->end());
-            } else {
-                it->rebind(static_cast<const Type *>(cvalue)->end());
-            }
-
+            it->rebind(static_cast<Type *>(const_cast<void *>(container))->end());
+            return true;
+        case operation::cend:
+            it->rebind(static_cast<const Type *>(container)->end());
             return true;
         case operation::insert:
             if constexpr(internal::dynamic_sequence_container<Type>::value) {
@@ -111,9 +107,9 @@ class basic_meta_sequence_container_traits {
                 typename Type::const_iterator underlying{non_const ? *non_const : any_cast<const typename Type::const_iterator &>(it->base())};
 
                 // this abomination is necessary because only on macos value_type and const_reference are different types for std::vector<bool>
-                if(auto &as_any = *static_cast<meta_any *>(const_cast<void *>(cvalue)); as_any.allow_cast<typename Type::const_reference>() || as_any.allow_cast<typename Type::value_type>()) {
+                if(auto &as_any = *static_cast<meta_any *>(const_cast<void *>(value)); as_any.allow_cast<typename Type::const_reference>() || as_any.allow_cast<typename Type::value_type>()) {
                     const auto *element = as_any.try_cast<std::remove_reference_t<typename Type::const_reference>>();
-                    it->rebind(static_cast<Type *>(value)->insert(underlying, element ? *element : as_any.cast<typename Type::value_type>()));
+                    it->rebind(static_cast<Type *>(const_cast<void *>(container))->insert(underlying, element ? *element : as_any.cast<typename Type::value_type>()));
                     return true;
                 }
             }
@@ -123,7 +119,7 @@ class basic_meta_sequence_container_traits {
             if constexpr(internal::dynamic_sequence_container<Type>::value) {
                 auto *const non_const = any_cast<typename Type::iterator>(&it->base());
                 typename Type::const_iterator underlying{non_const ? *non_const : any_cast<const typename Type::const_iterator &>(it->base())};
-                it->rebind(static_cast<Type *>(value)->erase(underlying));
+                it->rebind(static_cast<Type *>(const_cast<void *>(container))->erase(underlying));
                 return true;
             } else {
                 break;

+ 8 - 10
src/entt/meta/meta.hpp

@@ -75,7 +75,7 @@ public:
 private:
     const meta_ctx *ctx{};
     internal::meta_type_node (*value_type_node)(const internal::meta_context &){};
-    size_type (*vtable)(const operation, const void *, void *, iterator *){};
+    size_type (*vtable)(const operation, const void *, const void *, iterator *){};
     any storage{};
 };
 
@@ -1782,7 +1782,7 @@ private:
  * @return True in case of success, false otherwise.
  */
 inline bool meta_sequence_container::resize(const size_type sz) {
-    return (storage.policy() != any_policy::cref) && vtable(operation::resize, &sz, storage.data(), nullptr);
+    return (storage.policy() != any_policy::cref) && vtable(operation::resize, storage.data(), &sz, nullptr);
 }
 
 /**
@@ -1790,7 +1790,7 @@ inline bool meta_sequence_container::resize(const size_type sz) {
  * @return True in case of success, false otherwise.
  */
 inline bool meta_sequence_container::clear() {
-    return (storage.policy() != any_policy::cref) && vtable(operation::clear, nullptr, storage.data(), nullptr);
+    return (storage.policy() != any_policy::cref) && vtable(operation::clear, storage.data(), nullptr, nullptr);
 }
 
 /**
@@ -1799,7 +1799,7 @@ inline bool meta_sequence_container::clear() {
  * @return True in case of success, false otherwise.
  */
 inline bool meta_sequence_container::reserve(const size_type sz) {
-    return (storage.policy() != any_policy::cref) && vtable(operation::reserve, &sz, storage.data(), nullptr);
+    return (storage.policy() != any_policy::cref) && vtable(operation::reserve, storage.data(), &sz, nullptr);
 }
 
 /**
@@ -1808,8 +1808,7 @@ inline bool meta_sequence_container::reserve(const size_type sz) {
  */
 [[nodiscard]] inline meta_sequence_container::iterator meta_sequence_container::begin() {
     iterator it{*ctx};
-    const void *data = std::as_const(storage).data();
-    vtable(operation::begin, data, storage.policy() == any_policy::cref ? nullptr : const_cast<void *>(data), &it);
+    vtable(storage.policy() == any_policy::cref ? operation::cbegin : operation::begin, std::as_const(storage).data(), nullptr, &it);
     return it;
 }
 
@@ -1819,8 +1818,7 @@ inline bool meta_sequence_container::reserve(const size_type sz) {
  */
 [[nodiscard]] inline meta_sequence_container::iterator meta_sequence_container::end() {
     iterator it{*ctx};
-    const void *data = std::as_const(storage).data();
-    vtable(operation::end, data, storage.policy() == any_policy::cref ? nullptr : const_cast<void *>(data), &it);
+    vtable(storage.policy() == any_policy::cref ? operation::cend : operation::end, std::as_const(storage).data(), nullptr, &it);
     return it;
 }
 
@@ -1831,7 +1829,7 @@ 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) && vtable(operation::insert, &value, storage.data(), &it)) ? it : iterator{*ctx};
+    return ((storage.policy() != any_policy::cref) && vtable(operation::insert, storage.data(), &value, &it)) ? it : iterator{*ctx};
 }
 
 /**
@@ -1840,7 +1838,7 @@ inline meta_sequence_container::iterator meta_sequence_container::insert(iterato
  * @return A possibly invalid iterator following the last removed element.
  */
 inline meta_sequence_container::iterator meta_sequence_container::erase(iterator it) {
-    return ((storage.policy() != any_policy::cref) && vtable(operation::erase, nullptr, storage.data(), &it)) ? it : iterator{*ctx};
+    return ((storage.policy() != any_policy::cref) && vtable(operation::erase, storage.data(), nullptr, &it)) ? it : iterator{*ctx};
 }
 
 /**

+ 2 - 0
src/entt/meta/type_traits.hpp

@@ -19,7 +19,9 @@ enum class meta_sequence_container_operation {
     reserve,
     resize,
     begin,
+    cbegin,
     end,
+    cend,
     insert,
     erase
 };