Browse Source

meta: small review

Michele Caini 5 years ago
parent
commit
c00dcd31d6
5 changed files with 320 additions and 263 deletions
  1. 2 0
      src/entt/entt.hpp
  2. 78 0
      src/entt/meta/ctx.hpp
  3. 1 0
      src/entt/meta/factory.hpp
  4. 237 0
      src/entt/meta/internal.hpp
  5. 2 263
      src/entt/meta/meta.hpp

+ 2 - 0
src/entt/entt.hpp

@@ -20,7 +20,9 @@
 #include "entity/utility.hpp"
 #include "entity/view.hpp"
 #include "locator/locator.hpp"
+#include "meta/ctx.hpp"
 #include "meta/factory.hpp"
+#include "meta/internal.hpp"
 #include "meta/meta.hpp"
 #include "meta/resolve.hpp"
 #include "meta/policy.hpp"

+ 78 - 0
src/entt/meta/ctx.hpp

@@ -0,0 +1,78 @@
+#ifndef ENTT_META_CTX_HPP
+#define ENTT_META_CTX_HPP
+
+
+#include "../core/attribute.h"
+#include "../config/config.h"
+#include "internal.hpp"
+
+
+namespace entt {
+
+
+/**
+ * @cond TURN_OFF_DOXYGEN
+ * Internal details not to be documented.
+ */
+
+
+namespace internal {
+
+
+struct ENTT_API meta_context {
+    // we could use the lines below but VS2017 returns with an ICE if combined with ENTT_API despite the code being valid C++
+    //     inline static meta_type_node *local = nullptr;
+    //     inline static meta_type_node **global = &local;
+
+    [[nodiscard]] static meta_type_node * & local() ENTT_NOEXCEPT {
+        static meta_type_node *chain = nullptr;
+        return chain;
+    }
+
+    [[nodiscard]] static meta_type_node ** & global() ENTT_NOEXCEPT {
+        static meta_type_node **chain = &local();
+        return chain;
+    }
+
+    static void detach(const meta_type_node *node) ENTT_NOEXCEPT {
+        auto **it = global();
+
+        while(*it && *it != node) {
+            it = &(*it)->next;
+        }
+
+        if(*it) {
+            *it = (*it)->next;
+        }
+    }
+};
+
+
+}
+
+
+/**
+ * Internal details not to be documented.
+ * @endcond TURN_OFF_DOXYGEN
+ */
+
+
+/*! @brief Opaque container for a meta context. */
+struct meta_ctx {
+    /**
+     * @brief Binds the meta system to a given context.
+     * @param other A valid context to which to bind.
+     */
+    static void bind(meta_ctx other) ENTT_NOEXCEPT {
+        internal::meta_context::global() = other.ctx;
+    }
+
+private:
+    internal::meta_type_node **ctx{&internal::meta_context::local()};
+};
+
+
+}
+
+
+#endif

+ 1 - 0
src/entt/meta/factory.hpp

@@ -13,6 +13,7 @@
 #include "../core/type_info.hpp"
 #include "../core/type_traits.hpp"
 #include "../core/utility.hpp"
+#include "internal.hpp"
 #include "meta.hpp"
 #include "policy.hpp"
 

+ 237 - 0
src/entt/meta/internal.hpp

@@ -0,0 +1,237 @@
+#ifndef ENTT_META_INTERNAL_HPP
+#define ENTT_META_INTERNAL_HPP
+
+
+#include <cstddef>
+#include <type_traits>
+#include "../core/attribute.h"
+#include "../config/config.h"
+#include "../core/fwd.hpp"
+#include "../core/type_info.hpp"
+#include "../core/type_traits.hpp"
+
+
+namespace entt {
+
+
+class meta_any;
+
+
+/**
+ * @cond TURN_OFF_DOXYGEN
+ * Internal details not to be documented.
+ */
+
+
+namespace internal {
+
+
+struct meta_type_node;
+
+
+struct meta_prop_node {
+    meta_prop_node * next;
+    meta_any(* const key)();
+    meta_any(* const value)();
+};
+
+
+struct meta_base_node {
+    meta_type_node * const parent;
+    meta_base_node * next;
+    meta_type_node *(* const type)() ENTT_NOEXCEPT;
+    void *(* const cast)(void *) ENTT_NOEXCEPT;
+};
+
+
+struct meta_conv_node {
+    meta_type_node * const parent;
+    meta_conv_node * next;
+    meta_type_node *(* const type)() ENTT_NOEXCEPT;
+    meta_any(* const conv)(const void *);
+};
+
+
+struct meta_ctor_node {
+    using size_type = std::size_t;
+    meta_type_node * const parent;
+    meta_ctor_node * next;
+    meta_prop_node * prop;
+    const size_type size;
+    meta_type_node *(* const arg)(size_type) ENTT_NOEXCEPT;
+    meta_any(* const invoke)(meta_any * const);
+};
+
+
+struct meta_dtor_node {
+    meta_type_node * const parent;
+    void(* const invoke)(void *);
+};
+
+
+struct meta_data_node {
+    id_type id;
+    meta_type_node * const parent;
+    meta_data_node * next;
+    meta_prop_node * prop;
+    const bool is_static;
+    meta_type_node *(* const type)() ENTT_NOEXCEPT;
+    bool(* const set)(meta_any, meta_any, meta_any);
+    meta_any(* const get)(meta_any, meta_any);
+};
+
+
+struct meta_func_node {
+    using size_type = std::size_t;
+    id_type id;
+    meta_type_node * const parent;
+    meta_func_node * next;
+    meta_prop_node * prop;
+    const size_type size;
+    const bool is_const;
+    const bool is_static;
+    meta_type_node *(* const ret)() ENTT_NOEXCEPT;
+    meta_type_node *(* const arg)(size_type) ENTT_NOEXCEPT;
+    meta_any(* const invoke)(meta_any, meta_any *);
+};
+
+
+struct meta_type_node {
+    using size_type = std::size_t;
+    const id_type type_id;
+    id_type id;
+    meta_type_node * next;
+    meta_prop_node * prop;
+    const bool is_void;
+    const bool is_integral;
+    const bool is_floating_point;
+    const bool is_array;
+    const bool is_enum;
+    const bool is_union;
+    const bool is_class;
+    const bool is_pointer;
+    const bool is_function_pointer;
+    const bool is_member_object_pointer;
+    const bool is_member_function_pointer;
+    const size_type extent;
+    bool(* const compare)(const void *, const void *);
+    meta_type_node *(* const remove_pointer)() ENTT_NOEXCEPT;
+    meta_type_node *(* const remove_extent)() ENTT_NOEXCEPT;
+    meta_base_node *base{nullptr};
+    meta_conv_node *conv{nullptr};
+    meta_ctor_node *ctor{nullptr};
+    meta_dtor_node *dtor{nullptr};
+    meta_data_node *data{nullptr};
+    meta_func_node *func{nullptr};
+};
+
+
+template<typename Type, typename Op, typename Node>
+void visit(Op &op, Node *node) {
+    while(node) {
+        op(Type{node});
+        node = node->next;
+    }
+}
+
+
+template<auto Member, typename Type, typename Op>
+void visit(Op &op, const internal::meta_type_node *node) {
+    if(node) {
+        internal::visit<Type>(op, node->*Member);
+        auto *next = node->base;
+
+        while(next) {
+            visit<Member, Type>(op, next->type());
+            next = next->next;
+        }
+    }
+}
+
+
+template<typename Op, typename Node>
+auto find_if(const Op &op, Node *node) {
+    while(node && !op(node)) {
+        node = node->next;
+    }
+
+    return node;
+}
+
+
+template<auto Member, typename Op>
+auto find_if(const Op &op, const meta_type_node *node)
+-> decltype(find_if(op, node->*Member)) {
+    decltype(find_if(op, node->*Member)) ret = nullptr;
+
+    if(node) {
+        ret = find_if(op, node->*Member);
+        auto *next = node->base;
+
+        while(next && !ret) {
+            ret = find_if<Member>(op, next->type());
+            next = next->next;
+        }
+    }
+
+    return ret;
+}
+
+
+template<typename Type>
+struct ENTT_API meta_node {
+    static_assert(std::is_same_v<Type, std::remove_cv_t<std::remove_reference_t<Type>>>, "Invalid type");
+
+    [[nodiscard]] static bool compare(const void *lhs, const void *rhs) {
+        if constexpr(!std::is_function_v<Type> && is_equality_comparable_v<Type>) {
+            return *static_cast<const Type *>(lhs) == *static_cast<const Type *>(rhs);
+        } else {
+            return lhs == rhs;
+        }
+    }
+
+    [[nodiscard]] static meta_type_node * resolve() ENTT_NOEXCEPT {
+        static meta_type_node node{
+            type_info<Type>::id(),
+            {},
+            nullptr,
+            nullptr,
+            std::is_void_v<Type>,
+            std::is_integral_v<Type>,
+            std::is_floating_point_v<Type>,
+            std::is_array_v<Type>,
+            std::is_enum_v<Type>,
+            std::is_union_v<Type>,
+            std::is_class_v<Type>,
+            std::is_pointer_v<Type>,
+            std::is_pointer_v<Type> && std::is_function_v<std::remove_pointer_t<Type>>,
+            std::is_member_object_pointer_v<Type>,
+            std::is_member_function_pointer_v<Type>,
+            std::extent_v<Type>,
+            &compare, // workaround for an issue with VS2017
+            &meta_node<std::remove_const_t<std::remove_pointer_t<Type>>>::resolve,
+            &meta_node<std::remove_const_t<std::remove_extent_t<Type>>>::resolve
+        };
+
+        return &node;
+    }
+};
+
+
+template<typename... Type>
+struct meta_info: meta_node<std::remove_cv_t<std::remove_reference_t<Type>>...> {};
+
+
+}
+
+
+/**
+ * Internal details not to be documented.
+ * @endcond TURN_OFF_DOXYGEN
+ */
+
+
+}
+
+
+#endif

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

@@ -8,277 +8,16 @@
 #include <utility>
 #include "../config/config.h"
 #include "../core/fwd.hpp"
-#include "../core/type_info.hpp"
-#include "../core/type_traits.hpp"
+#include "ctx.hpp"
+#include "internal.hpp"
 
 
 namespace entt {
 
 
-class meta_any;
 class meta_type;
 
 
-/**
- * @cond TURN_OFF_DOXYGEN
- * Internal details not to be documented.
- */
-
-
-namespace internal {
-
-
-struct meta_type_node;
-
-
-struct meta_prop_node {
-    meta_prop_node * next;
-    meta_any(* const key)();
-    meta_any(* const value)();
-};
-
-
-struct meta_base_node {
-    meta_type_node * const parent;
-    meta_base_node * next;
-    meta_type_node *(* const type)() ENTT_NOEXCEPT;
-    void *(* const cast)(void *) ENTT_NOEXCEPT;
-};
-
-
-struct meta_conv_node {
-    meta_type_node * const parent;
-    meta_conv_node * next;
-    meta_type_node *(* const type)() ENTT_NOEXCEPT;
-    meta_any(* const conv)(const void *);
-};
-
-
-struct meta_ctor_node {
-    using size_type = std::size_t;
-    meta_type_node * const parent;
-    meta_ctor_node * next;
-    meta_prop_node * prop;
-    const size_type size;
-    meta_type_node *(* const arg)(size_type) ENTT_NOEXCEPT;
-    meta_any(* const invoke)(meta_any * const);
-};
-
-
-struct meta_dtor_node {
-    meta_type_node * const parent;
-    void(* const invoke)(void *);
-};
-
-
-struct meta_data_node {
-    id_type id;
-    meta_type_node * const parent;
-    meta_data_node * next;
-    meta_prop_node * prop;
-    const bool is_static;
-    meta_type_node *(* const type)() ENTT_NOEXCEPT;
-    bool(* const set)(meta_any, meta_any, meta_any);
-    meta_any(* const get)(meta_any, meta_any);
-};
-
-
-struct meta_func_node {
-    using size_type = std::size_t;
-    id_type id;
-    meta_type_node * const parent;
-    meta_func_node * next;
-    meta_prop_node * prop;
-    const size_type size;
-    const bool is_const;
-    const bool is_static;
-    meta_type_node *(* const ret)() ENTT_NOEXCEPT;
-    meta_type_node *(* const arg)(size_type) ENTT_NOEXCEPT;
-    meta_any(* const invoke)(meta_any, meta_any *);
-};
-
-
-struct meta_type_node {
-    using size_type = std::size_t;
-    const id_type type_id;
-    id_type id;
-    meta_type_node * next;
-    meta_prop_node * prop;
-    const bool is_void;
-    const bool is_integral;
-    const bool is_floating_point;
-    const bool is_array;
-    const bool is_enum;
-    const bool is_union;
-    const bool is_class;
-    const bool is_pointer;
-    const bool is_function_pointer;
-    const bool is_member_object_pointer;
-    const bool is_member_function_pointer;
-    const size_type extent;
-    bool(* const compare)(const void *, const void *);
-    meta_type_node *(* const remove_pointer)() ENTT_NOEXCEPT;
-    meta_type_node *(* const remove_extent)() ENTT_NOEXCEPT;
-    meta_base_node *base{nullptr};
-    meta_conv_node *conv{nullptr};
-    meta_ctor_node *ctor{nullptr};
-    meta_dtor_node *dtor{nullptr};
-    meta_data_node *data{nullptr};
-    meta_func_node *func{nullptr};
-};
-
-
-template<typename Type, typename Op, typename Node>
-void visit(Op &op, Node *node) {
-    while(node) {
-        op(Type{node});
-        node = node->next;
-    }
-}
-
-
-template<auto Member, typename Type, typename Op>
-void visit(Op &op, const internal::meta_type_node *node) {
-    if(node) {
-        internal::visit<Type>(op, node->*Member);
-        auto *next = node->base;
-
-        while(next) {
-            visit<Member, Type>(op, next->type());
-            next = next->next;
-        }
-    }
-}
-
-
-template<typename Op, typename Node>
-auto find_if(const Op &op, Node *node) {
-    while(node && !op(node)) {
-        node = node->next;
-    }
-
-    return node;
-}
-
-
-template<auto Member, typename Op>
-auto find_if(const Op &op, const meta_type_node *node)
--> decltype(find_if(op, node->*Member)) {
-    decltype(find_if(op, node->*Member)) ret = nullptr;
-
-    if(node) {
-        ret = find_if(op, node->*Member);
-        auto *next = node->base;
-
-        while(next && !ret) {
-            ret = find_if<Member>(op, next->type());
-            next = next->next;
-        }
-    }
-
-    return ret;
-}
-
-
-template<typename Type>
-[[nodiscard]] bool compare(const void *lhs, const void *rhs) {
-    if constexpr(!std::is_function_v<Type> && is_equality_comparable_v<Type>) {
-        return *static_cast<const Type *>(lhs) == *static_cast<const Type *>(rhs);
-    } else {
-        return lhs == rhs;
-    }
-}
-
-
-struct ENTT_API meta_context {
-    // we could use the lines below but VS2017 returns with an ICE if combined with ENTT_API despite the code being valid C++
-    //     inline static meta_type_node *local = nullptr;
-    //     inline static meta_type_node **global = &local;
-
-    [[nodiscard]] static meta_type_node * & local() ENTT_NOEXCEPT {
-        static meta_type_node *chain = nullptr;
-        return chain;
-    }
-
-    [[nodiscard]] static meta_type_node ** & global() ENTT_NOEXCEPT {
-        static meta_type_node **chain = &local();
-        return chain;
-    }
-
-    static void detach(const meta_type_node *node) ENTT_NOEXCEPT {
-        auto **it = global();
-
-        while(*it && *it != node) {
-            it = &(*it)->next;
-        }
-
-        if(*it) {
-            *it = (*it)->next;
-        }
-    }
-};
-
-
-template<typename Type>
-struct ENTT_API meta_node {
-    static_assert(std::is_same_v<Type, std::remove_cv_t<std::remove_reference_t<Type>>>, "Invalid type");
-
-    [[nodiscard]] static meta_type_node * resolve() ENTT_NOEXCEPT {
-        static meta_type_node node{
-            type_info<Type>::id(),
-            {},
-            nullptr,
-            nullptr,
-            std::is_void_v<Type>,
-            std::is_integral_v<Type>,
-            std::is_floating_point_v<Type>,
-            std::is_array_v<Type>,
-            std::is_enum_v<Type>,
-            std::is_union_v<Type>,
-            std::is_class_v<Type>,
-            std::is_pointer_v<Type>,
-            std::is_pointer_v<Type> && std::is_function_v<std::remove_pointer_t<Type>>,
-            std::is_member_object_pointer_v<Type>,
-            std::is_member_function_pointer_v<Type>,
-            std::extent_v<Type>,
-            &compare<Type>, // workaround for an issue with VS2017
-            &meta_node<std::remove_const_t<std::remove_pointer_t<Type>>>::resolve,
-            &meta_node<std::remove_const_t<std::remove_extent_t<Type>>>::resolve
-        };
-
-        return &node;
-    }
-};
-
-
-template<typename... Type>
-struct meta_info: meta_node<std::remove_cv_t<std::remove_reference_t<Type>>...> {};
-
-
-}
-
-
-/**
- * Internal details not to be documented.
- * @endcond TURN_OFF_DOXYGEN
- */
-
-
-/*! @brief Opaque container for a meta context. */
-struct meta_ctx {
-    /**
-     * @brief Binds the meta system to a given context.
-     * @param other A valid context to which to bind.
-     */
-    static void bind(meta_ctx other) ENTT_NOEXCEPT {
-        internal::meta_context::global() = other.ctx;
-    }
-
-private:
-    internal::meta_type_node **ctx{&internal::meta_context::local()};
-};
-
-
 /**
  * @brief Opaque container for values of any type.
  *