From c8f0afb77519413d40475df09150a78edcda5f76 Mon Sep 17 00:00:00 2001 From: Michele Caini Date: Thu, 21 May 2020 23:14:04 +0200 Subject: [PATCH] test: ugly workaround for an ICE of VS2017 that fails to compile valid C++ code when combined with ENTT_API --- src/entt/meta/factory.hpp | 8 ++++---- src/entt/meta/meta.hpp | 21 ++++++++++++++++----- src/entt/meta/resolve.hpp | 4 ++-- test/entt/meta/meta.cpp | 4 ++-- 4 files changed, 24 insertions(+), 13 deletions(-) diff --git a/src/entt/meta/factory.hpp b/src/entt/meta/factory.hpp index 8b1387f6b..4dac226c0 100644 --- a/src/entt/meta/factory.hpp +++ b/src/entt/meta/factory.hpp @@ -393,11 +393,11 @@ public: auto type(const id_type id = type_info::id()) { auto * const node = internal::meta_info::resolve(); - ENTT_ASSERT(!exists(id, *internal::meta_context::global)); - ENTT_ASSERT(!exists(node, *internal::meta_context::global)); + ENTT_ASSERT(!exists(id, *internal::meta_context::global())); + ENTT_ASSERT(!exists(node, *internal::meta_context::global())); node->id = id; - node->next = *internal::meta_context::global; - *internal::meta_context::global = node; + node->next = *internal::meta_context::global(); + *internal::meta_context::global() = node; return meta_factory{&node->prop}; } diff --git a/src/entt/meta/meta.hpp b/src/entt/meta/meta.hpp index 4b535f68b..718d84565 100644 --- a/src/entt/meta/meta.hpp +++ b/src/entt/meta/meta.hpp @@ -192,11 +192,22 @@ bool compare(const void *lhs, const void *rhs) { struct ENTT_API meta_context { - inline static meta_type_node *local = nullptr; - inline static meta_type_node **global = &local; + // 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; + + static meta_type_node * & local() ENTT_NOEXCEPT { + static meta_type_node *chain = nullptr; + return chain; + } + + 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; + auto **it = global(); while(*it && *it != node) { it = &(*it)->next; @@ -261,11 +272,11 @@ struct meta_ctx { * @param other A valid context to which to bind. */ static void bind(meta_ctx other) ENTT_NOEXCEPT { - internal::meta_context::global = other.ctx; + internal::meta_context::global() = other.ctx; } private: - internal::meta_type_node **ctx{&internal::meta_context::local}; + internal::meta_type_node **ctx{&internal::meta_context::local()}; }; diff --git a/src/entt/meta/resolve.hpp b/src/entt/meta/resolve.hpp index be555e03c..52d14f3c5 100644 --- a/src/entt/meta/resolve.hpp +++ b/src/entt/meta/resolve.hpp @@ -27,7 +27,7 @@ inline meta_type resolve() ENTT_NOEXCEPT { */ template void resolve(Op op) { - internal::visit(op, *internal::meta_context::global); + internal::visit(op, *internal::meta_context::global()); } @@ -41,7 +41,7 @@ template inline meta_type resolve_if(Func func) ENTT_NOEXCEPT { return internal::find_if([&func](const auto *curr) { return func(meta_type{curr}); - }, *internal::meta_context::global); + }, *internal::meta_context::global()); } diff --git a/test/entt/meta/meta.cpp b/test/entt/meta/meta.cpp index dc754ad49..7e200c27b 100644 --- a/test/entt/meta/meta.cpp +++ b/test/entt/meta/meta.cpp @@ -1879,7 +1879,7 @@ TEST_F(Meta, PropertiesAndCornerCases) { } TEST_F(Meta, Reset) { - ASSERT_NE(*entt::internal::meta_context::global, nullptr); + ASSERT_NE(*entt::internal::meta_context::global(), nullptr); entt::meta().reset(); entt::meta().reset(); @@ -1909,7 +1909,7 @@ TEST_F(Meta, Reset) { ASSERT_FALSE(entt::resolve_id("another_abstract_type"_hs)); ASSERT_FALSE(entt::resolve_id("concrete"_hs)); - ASSERT_EQ(*entt::internal::meta_context::global, nullptr); + ASSERT_EQ(*entt::internal::meta_context::global(), nullptr); Meta::SetUpAfterUnregistration(); entt::meta_any any{42.};