meta: avoid risk of name clashing on meta types and meta data members

This commit is contained in:
Michele Caini
2021-08-10 16:07:17 +02:00
parent d1ff491010
commit a9cefcb823
3 changed files with 35 additions and 6 deletions

View File

@@ -159,10 +159,11 @@ struct meta_factory<Type> {
auto type(const id_type id = type_hash<Type>::value()) {
auto * const node = internal::meta_info<Type>::resolve();
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, node](const auto *curr) { return curr != node && curr->id == id; }) == range.cend(), "Duplicate identifier");
node->id = id;
if(meta_range<internal::meta_type_node *, internal::meta_type_node> range{*internal::meta_context::global()}; std::find(range.cbegin(), range.cend(), node) == range.cend()) {
ENTT_ASSERT(std::find_if(range.cbegin(), range.cend(), [id](const auto *curr) { return curr->id == id; }) == range.cend(), "Duplicate identifier");
if(std::find(range.cbegin(), range.cend(), node) == range.cend()) {
node->next = *internal::meta_context::global();
*internal::meta_context::global() = node;
}
@@ -411,10 +412,11 @@ struct meta_factory<Type> {
&meta_getter<Type, Data, Policy>
};
meta_range<internal::meta_data_node *, internal::meta_data_node> range{type->data};
ENTT_ASSERT(std::find_if(range.cbegin(), range.cend(), [id](const auto *curr) { return curr != &node && curr->id == id; }) == range.cend(), "Duplicate identifier");
node.id = id;
if(meta_range<internal::meta_data_node *, internal::meta_data_node> range{type->data}; std::find(range.cbegin(), range.cend(), &node) == range.cend()) {
ENTT_ASSERT(std::find_if(range.cbegin(), range.cend(), [id](const auto *curr) { return curr->id == id; }) == range.cend(), "Duplicate identifier");
if(std::find(range.cbegin(), range.cend(), &node) == range.cend()) {
node.next = type->data;
type->data = &node;
}
@@ -460,10 +462,11 @@ struct meta_factory<Type> {
&meta_getter<Type, Getter, Policy>
};
meta_range<internal::meta_data_node *, internal::meta_data_node> range{type->data};
ENTT_ASSERT(std::find_if(range.cbegin(), range.cend(), [id](const auto *curr) { return curr != &node && curr->id == id; }) == range.cend(), "Duplicate identifier");
node.id = id;
if(meta_range<internal::meta_data_node *, internal::meta_data_node> range{type->data}; std::find(range.cbegin(), range.cend(), &node) == range.cend()) {
ENTT_ASSERT(std::find_if(range.cbegin(), range.cend(), [id](const auto *curr) { return curr->id == id; }) == range.cend(), "Duplicate identifier");
if(std::find(range.cbegin(), range.cend(), &node) == range.cend()) {
node.next = type->data;
type->data = &node;
}

View File

@@ -515,3 +515,16 @@ TEST_F(MetaData, ReRegistration) {
ASSERT_FALSE(type.data("value"_hs));
ASSERT_TRUE(type.data("field"_hs));
}
TEST_F(MetaData, NameCollision) {
using namespace entt::literals;
ASSERT_NO_FATAL_FAILURE(entt::meta<clazz_t>().data<&clazz_t::j>("j"_hs));
ASSERT_TRUE(entt::resolve<clazz_t>().data("j"_hs));
ASSERT_NO_FATAL_FAILURE(entt::meta<clazz_t>().data<&clazz_t::j>("cj"_hs));
ASSERT_FALSE(entt::resolve<clazz_t>().data("j"_hs));
ASSERT_TRUE(entt::resolve<clazz_t>().data("cj"_hs));
ASSERT_DEATH(entt::meta<clazz_t>().data<&clazz_t::j>("i"_hs), "");
}

View File

@@ -640,3 +640,16 @@ TEST_F(MetaType, ReRegistration) {
ASSERT_TRUE(entt::resolve("real"_hs));
ASSERT_TRUE(entt::resolve("real"_hs).data("var"_hs));
}
TEST_F(MetaType, NameCollision) {
using namespace entt::literals;
ASSERT_NO_FATAL_FAILURE(entt::meta<clazz_t>().type("clazz"_hs));
ASSERT_TRUE(entt::resolve("clazz"_hs));
ASSERT_NO_FATAL_FAILURE(entt::meta<clazz_t>().type("quux"_hs));
ASSERT_FALSE(entt::resolve("clazz"_hs));
ASSERT_TRUE(entt::resolve("quux"_hs));
ASSERT_DEATH(entt::meta<clazz_t>().type("abstract"_hs), "");
}