|
|
@@ -19,6 +19,80 @@
|
|
|
|
|
|
namespace entt {
|
|
|
|
|
|
+/**
|
|
|
+ * @cond TURN_OFF_DOXYGEN
|
|
|
+ * Internal details not to be documented.
|
|
|
+ */
|
|
|
+
|
|
|
+namespace internal {
|
|
|
+
|
|
|
+inline void link_prop_if_required(internal::meta_prop_node **ref, internal::meta_prop_node &node) ENTT_NOEXCEPT {
|
|
|
+ if(meta_range<internal::meta_prop_node *, internal::meta_prop_node> range{*ref}; std::find(range.cbegin(), range.cend(), &node) == range.cend()) {
|
|
|
+ ENTT_ASSERT(std::find_if(range.cbegin(), range.cend(), [&node](const auto *curr) { return curr->id == node.id; }) == range.cend(), "Duplicate identifier");
|
|
|
+ node.next = *ref;
|
|
|
+ *ref = &node;
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+inline void link_type_if_required(meta_type_node *owner, const id_type id) ENTT_NOEXCEPT {
|
|
|
+ meta_range<meta_type_node *, meta_type_node> range{*meta_context::global()};
|
|
|
+ ENTT_ASSERT(std::find_if(range.cbegin(), range.cend(), [&](const auto *curr) { return curr != owner && curr->id == id; }) == range.cend(), "Duplicate identifier");
|
|
|
+ owner->id = id;
|
|
|
+
|
|
|
+ if(std::find(range.cbegin(), range.cend(), owner) == range.cend()) {
|
|
|
+ owner->next = *meta_context::global();
|
|
|
+ *meta_context::global() = owner;
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+inline void link_base_if_required(meta_type_node *owner, meta_base_node &node) ENTT_NOEXCEPT {
|
|
|
+ if(meta_range<meta_base_node *, meta_base_node> range{owner->base}; std::find(range.cbegin(), range.cend(), &node) == range.cend()) {
|
|
|
+ node.next = owner->base;
|
|
|
+ owner->base = &node;
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+inline void link_conv_if_required(meta_type_node *owner, meta_conv_node &node) ENTT_NOEXCEPT {
|
|
|
+ if(meta_range<meta_conv_node *, meta_conv_node> range{owner->conv}; std::find(range.cbegin(), range.cend(), &node) == range.cend()) {
|
|
|
+ node.next = owner->conv;
|
|
|
+ owner->conv = &node;
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+inline void link_ctor_if_required(meta_type_node *owner, meta_ctor_node &node) ENTT_NOEXCEPT {
|
|
|
+ if(meta_range<meta_ctor_node *, meta_ctor_node> range{owner->ctor}; std::find(range.cbegin(), range.cend(), &node) == range.cend()) {
|
|
|
+ node.next = owner->ctor;
|
|
|
+ owner->ctor = &node;
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+inline void link_data_if_required(meta_type_node *owner, const id_type id, meta_data_node &node) ENTT_NOEXCEPT {
|
|
|
+ meta_range<meta_data_node *, meta_data_node> range{owner->data};
|
|
|
+ ENTT_ASSERT(std::find_if(range.cbegin(), range.cend(), [id, &node](const auto *curr) { return curr != &node && curr->id == id; }) == range.cend(), "Duplicate identifier");
|
|
|
+ node.id = id;
|
|
|
+
|
|
|
+ if(std::find(range.cbegin(), range.cend(), &node) == range.cend()) {
|
|
|
+ node.next = owner->data;
|
|
|
+ owner->data = &node;
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+inline void link_func_if_required(meta_type_node *owner, const id_type id, meta_func_node &node) ENTT_NOEXCEPT {
|
|
|
+ node.id = id;
|
|
|
+
|
|
|
+ if(meta_range<meta_func_node *, meta_func_node> range{owner->func}; std::find(range.cbegin(), range.cend(), &node) == range.cend()) {
|
|
|
+ node.next = owner->func;
|
|
|
+ owner->func = &node;
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+} // namespace internal
|
|
|
+
|
|
|
+/**
|
|
|
+ * Internal details not to be documented.
|
|
|
+ * @endcond
|
|
|
+ */
|
|
|
+
|
|
|
/**
|
|
|
* @brief Meta factory to be used for reflection purposes.
|
|
|
*
|
|
|
@@ -37,14 +111,6 @@ class meta_factory;
|
|
|
*/
|
|
|
template<typename Type, typename... Spec>
|
|
|
class meta_factory<Type, Spec...>: public meta_factory<Type> {
|
|
|
- void link_prop_if_required(internal::meta_prop_node &node) ENTT_NOEXCEPT {
|
|
|
- if(meta_range<internal::meta_prop_node *, internal::meta_prop_node> range{*ref}; std::find(range.cbegin(), range.cend(), &node) == range.cend()) {
|
|
|
- ENTT_ASSERT(std::find_if(range.cbegin(), range.cend(), [&node](const auto *curr) { return curr->id == node.id; }) == range.cend(), "Duplicate identifier");
|
|
|
- node.next = *ref;
|
|
|
- *ref = &node;
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
template<std::size_t Step = 0, typename... Property, typename... Other>
|
|
|
void unroll(choice_t<2>, std::tuple<Property...> property, Other &&...other) ENTT_NOEXCEPT {
|
|
|
std::apply([this](auto &&...curr) { (this->unroll<Step>(choice<2>, std::forward<Property>(curr)...)); }, property);
|
|
|
@@ -80,7 +146,7 @@ class meta_factory<Type, Spec...>: public meta_factory<Type> {
|
|
|
property[0u] = std::move(key);
|
|
|
property[1u] = std::move(value);
|
|
|
|
|
|
- link_prop_if_required(node);
|
|
|
+ internal::link_prop_if_required(ref, node);
|
|
|
}
|
|
|
|
|
|
public:
|
|
|
@@ -138,47 +204,6 @@ private:
|
|
|
*/
|
|
|
template<typename Type>
|
|
|
class meta_factory<Type> {
|
|
|
- void link_base_if_required(internal::meta_base_node &node) ENTT_NOEXCEPT {
|
|
|
- if(meta_range<internal::meta_base_node *, internal::meta_base_node> range{owner->base}; std::find(range.cbegin(), range.cend(), &node) == range.cend()) {
|
|
|
- node.next = owner->base;
|
|
|
- owner->base = &node;
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- void link_conv_if_required(internal::meta_conv_node &node) ENTT_NOEXCEPT {
|
|
|
- if(meta_range<internal::meta_conv_node *, internal::meta_conv_node> range{owner->conv}; std::find(range.cbegin(), range.cend(), &node) == range.cend()) {
|
|
|
- node.next = owner->conv;
|
|
|
- owner->conv = &node;
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- void link_ctor_if_required(internal::meta_ctor_node &node) ENTT_NOEXCEPT {
|
|
|
- if(meta_range<internal::meta_ctor_node *, internal::meta_ctor_node> range{owner->ctor}; std::find(range.cbegin(), range.cend(), &node) == range.cend()) {
|
|
|
- node.next = owner->ctor;
|
|
|
- owner->ctor = &node;
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- void link_data_if_required(const id_type id, internal::meta_data_node &node) ENTT_NOEXCEPT {
|
|
|
- meta_range<internal::meta_data_node *, internal::meta_data_node> range{owner->data};
|
|
|
- ENTT_ASSERT(std::find_if(range.cbegin(), range.cend(), [id, &node](const auto *curr) { return curr != &node && curr->id == id; }) == range.cend(), "Duplicate identifier");
|
|
|
- node.id = id;
|
|
|
-
|
|
|
- if(std::find(range.cbegin(), range.cend(), &node) == range.cend()) {
|
|
|
- node.next = owner->data;
|
|
|
- owner->data = &node;
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- void link_func_if_required(const id_type id, internal::meta_func_node &node) ENTT_NOEXCEPT {
|
|
|
- node.id = id;
|
|
|
-
|
|
|
- if(meta_range<internal::meta_func_node *, internal::meta_func_node> range{owner->func}; std::find(range.cbegin(), range.cend(), &node) == range.cend()) {
|
|
|
- node.next = owner->func;
|
|
|
- owner->func = &node;
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
template<typename Setter, auto Getter, typename Policy, std::size_t... Index>
|
|
|
auto data(const id_type id, std::index_sequence<Index...>) ENTT_NOEXCEPT {
|
|
|
using data_type = std::invoke_result_t<decltype(Getter), Type &>;
|
|
|
@@ -199,7 +224,7 @@ class meta_factory<Type> {
|
|
|
// tricks clang-format
|
|
|
};
|
|
|
|
|
|
- link_data_if_required(id, node);
|
|
|
+ internal::link_data_if_required(owner, id, node);
|
|
|
return meta_factory<Type, Setter, std::integral_constant<decltype(Getter), Getter>>{&node.prop};
|
|
|
}
|
|
|
|
|
|
@@ -214,15 +239,7 @@ public:
|
|
|
* @return An extended meta factory for the given type.
|
|
|
*/
|
|
|
auto type(const id_type id = type_hash<Type>::value()) ENTT_NOEXCEPT {
|
|
|
- meta_range<internal::meta_type_node *, internal::meta_type_node> range{*internal::meta_context::global()};
|
|
|
- ENTT_ASSERT(std::find_if(range.cbegin(), range.cend(), [id, this](const auto *curr) { return curr != owner && curr->id == id; }) == range.cend(), "Duplicate identifier");
|
|
|
- owner->id = id;
|
|
|
-
|
|
|
- if(std::find(range.cbegin(), range.cend(), owner) == range.cend()) {
|
|
|
- owner->next = *internal::meta_context::global();
|
|
|
- *internal::meta_context::global() = owner;
|
|
|
- }
|
|
|
-
|
|
|
+ internal::link_type_if_required(owner, id);
|
|
|
return meta_factory<Type, Type>{&owner->prop};
|
|
|
}
|
|
|
|
|
|
@@ -251,7 +268,7 @@ public:
|
|
|
// tricks clang-format
|
|
|
};
|
|
|
|
|
|
- link_base_if_required(node);
|
|
|
+ internal::link_base_if_required(owner, node);
|
|
|
return meta_factory<Type>{};
|
|
|
}
|
|
|
|
|
|
@@ -278,7 +295,7 @@ public:
|
|
|
// tricks clang-format
|
|
|
};
|
|
|
|
|
|
- link_conv_if_required(node);
|
|
|
+ internal::link_conv_if_required(owner, node);
|
|
|
return meta_factory<Type>{};
|
|
|
}
|
|
|
|
|
|
@@ -300,7 +317,7 @@ public:
|
|
|
// tricks clang-format
|
|
|
};
|
|
|
|
|
|
- link_conv_if_required(node);
|
|
|
+ internal::link_conv_if_required(owner, node);
|
|
|
return meta_factory<Type>{};
|
|
|
}
|
|
|
|
|
|
@@ -331,7 +348,7 @@ public:
|
|
|
// tricks clang-format
|
|
|
};
|
|
|
|
|
|
- link_ctor_if_required(node);
|
|
|
+ internal::link_ctor_if_required(owner, node);
|
|
|
return meta_factory<Type>{};
|
|
|
}
|
|
|
|
|
|
@@ -357,7 +374,7 @@ public:
|
|
|
// tricks clang-format
|
|
|
};
|
|
|
|
|
|
- link_ctor_if_required(node);
|
|
|
+ internal::link_ctor_if_required(owner, node);
|
|
|
return meta_factory<Type>{};
|
|
|
}
|
|
|
|
|
|
@@ -418,7 +435,7 @@ public:
|
|
|
// tricks clang-format
|
|
|
};
|
|
|
|
|
|
- link_data_if_required(id, node);
|
|
|
+ internal::link_data_if_required(owner, id, node);
|
|
|
return meta_factory<Type, std::integral_constant<decltype(Data), Data>, std::integral_constant<decltype(Data), Data>>{&node.prop};
|
|
|
} else {
|
|
|
using data_type = std::remove_reference_t<std::remove_pointer_t<decltype(Data)>>;
|
|
|
@@ -436,7 +453,7 @@ public:
|
|
|
// tricks clang-format
|
|
|
};
|
|
|
|
|
|
- link_data_if_required(id, node);
|
|
|
+ internal::link_data_if_required(owner, id, node);
|
|
|
return meta_factory<Type, std::integral_constant<decltype(Data), Data>>{&node.prop};
|
|
|
}
|
|
|
}
|
|
|
@@ -481,7 +498,7 @@ public:
|
|
|
// tricks clang-format
|
|
|
};
|
|
|
|
|
|
- link_data_if_required(id, node);
|
|
|
+ internal::link_data_if_required(owner, id, node);
|
|
|
return meta_factory<Type, std::integral_constant<decltype(Setter), Setter>, std::integral_constant<decltype(Getter), Getter>>{&node.prop};
|
|
|
} else {
|
|
|
using args_type = typename meta_function_helper_t<Type, decltype(Setter)>::args_type;
|
|
|
@@ -500,7 +517,7 @@ public:
|
|
|
// tricks clang-format
|
|
|
};
|
|
|
|
|
|
- link_data_if_required(id, node);
|
|
|
+ internal::link_data_if_required(owner, id, node);
|
|
|
return meta_factory<Type, std::integral_constant<decltype(Setter), Setter>, std::integral_constant<decltype(Getter), Getter>>{&node.prop};
|
|
|
}
|
|
|
}
|
|
|
@@ -557,7 +574,7 @@ public:
|
|
|
// tricks clang-format
|
|
|
};
|
|
|
|
|
|
- link_func_if_required(id, node);
|
|
|
+ internal::link_func_if_required(owner, id, node);
|
|
|
return meta_factory<Type, std::integral_constant<decltype(Candidate), Candidate>>{&node.prop};
|
|
|
}
|
|
|
|