#include #include #include #include #include #include #include #include struct base_1_t { base_1_t() = default; int value_1{}; }; struct base_2_t { base_2_t() = default; operator int() const { return value_2; } int value_2{}; }; struct base_3_t: base_2_t { base_3_t() = default; int value_3{}; }; struct derived_t: base_1_t, base_3_t { derived_t() = default; int value{}; }; struct MetaBase: ::testing::Test { void SetUp() override { using namespace entt::literals; entt::meta() .data<&base_1_t::value_1>("value_1"_hs); entt::meta() .conv() .data<&base_2_t::value_2>("value_2"_hs); entt::meta() .base() .data<&base_3_t::value_3>("value_3"_hs); entt::meta() .type("derived"_hs) .base() .base() .data<&derived_t::value>("value"_hs); } void TearDown() override { entt::meta_reset(); } }; TEST_F(MetaBase, Functionalities) { auto any = entt::resolve().construct(); any.cast().value_1 = 42; auto as_derived = any.as_ref(); ASSERT_TRUE(any.allow_cast()); ASSERT_FALSE(any.allow_cast()); ASSERT_FALSE(as_derived.allow_cast()); ASSERT_TRUE(any); ASSERT_EQ(any.cast().value_1, as_derived.cast().value_1); any.cast().value_1 = 3; ASSERT_EQ(any.cast().value_1, as_derived.cast().value_1); } TEST_F(MetaBase, SetGetWithMutatingThis) { using namespace entt::literals; derived_t instance; auto any = entt::forward_as_meta(instance); auto as_cref = std::as_const(any).as_ref(); ASSERT_NE(static_cast(static_cast(&instance)), static_cast(static_cast(&instance))); ASSERT_NE(static_cast(static_cast(&instance)), static_cast(static_cast(&instance))); ASSERT_EQ(static_cast(static_cast(&instance)), static_cast(static_cast(&instance))); ASSERT_EQ(static_cast(&instance), static_cast(static_cast(&instance))); ASSERT_TRUE(any.set("value"_hs, 42)); ASSERT_TRUE(any.set("value_1"_hs, 1)); ASSERT_TRUE(any.set("value_2"_hs, 2)); ASSERT_TRUE(any.set("value_3"_hs, 3)); ASSERT_FALSE(as_cref.set("value"_hs, 0)); ASSERT_FALSE(as_cref.set("value_1"_hs, 0)); ASSERT_FALSE(as_cref.set("value_2"_hs, 0)); ASSERT_FALSE(as_cref.set("value_3"_hs, 0)); ASSERT_EQ(any.get("value"_hs).cast(), 42); ASSERT_EQ(any.get("value_1"_hs).cast(), 1); ASSERT_EQ(any.get("value_2"_hs).cast(), 2); ASSERT_EQ(any.get("value_3"_hs).cast(), 3); ASSERT_EQ(as_cref.get("value"_hs).cast(), 42); ASSERT_EQ(as_cref.get("value_1"_hs).cast(), 1); ASSERT_EQ(as_cref.get("value_2"_hs).cast(), 2); ASSERT_EQ(as_cref.get("value_3"_hs).cast(), 3); ASSERT_EQ(instance.value, 42); ASSERT_EQ(instance.value_1, 1); ASSERT_EQ(instance.value_2, 2); ASSERT_EQ(instance.value_3, 3); } TEST_F(MetaBase, ConvWithMutatingThis) { entt::meta_any any{derived_t{}}; auto &&ref = any.cast(); auto as_cref = std::as_const(any).as_ref(); ref.value_2 = 42; auto conv = std::as_const(any).allow_cast(); auto from_cref = std::as_const(as_cref).allow_cast(); ASSERT_TRUE(conv); ASSERT_TRUE(from_cref); ASSERT_EQ(conv.cast(), 42); ASSERT_EQ(from_cref.cast(), 42); ASSERT_TRUE(as_cref.allow_cast()); ASSERT_TRUE(any.allow_cast()); ASSERT_EQ(as_cref.cast(), 42); ASSERT_EQ(any.cast(), 42); } TEST_F(MetaBase, OpaqueConvWithMutatingThis) { entt::meta_any any{derived_t{}}; auto as_cref = std::as_const(any).as_ref(); any.cast().value_2 = 42; auto conv = std::as_const(any).allow_cast(entt::resolve()); auto from_cref = std::as_const(as_cref).allow_cast(entt::resolve()); ASSERT_TRUE(conv); ASSERT_TRUE(from_cref); ASSERT_EQ(conv.cast(), 42); ASSERT_EQ(from_cref.cast(), 42); ASSERT_TRUE(as_cref.allow_cast(entt::resolve())); ASSERT_TRUE(any.allow_cast(entt::resolve())); ASSERT_EQ(as_cref.cast(), 42); ASSERT_EQ(any.cast(), 42); } TEST_F(MetaBase, AssignWithMutatingThis) { using namespace entt::literals; entt::meta_any dst{base_2_t{}}; entt::meta_any src{derived_t{}}; dst.cast().value_2 = 0; src.cast().value_2 = 42; ASSERT_TRUE(dst.assign(src)); ASSERT_EQ(dst.get("value_2"_hs).cast(), 42); } TEST_F(MetaBase, TransferWithMutatingThis) { using namespace entt::literals; entt::meta_any dst{base_2_t{}}; entt::meta_any src{derived_t{}}; dst.cast().value_2 = 0; src.cast().value_2 = 42; ASSERT_TRUE(dst.assign(std::move(src))); ASSERT_EQ(dst.get("value_2"_hs).cast(), 42); } TEST_F(MetaBase, ReRegistration) { SetUp(); auto &&node = entt::internal::resolve(entt::internal::meta_context::from(entt::locator::value_or())); ASSERT_TRUE(node.details); ASSERT_FALSE(node.details->base.empty()); ASSERT_EQ(node.details->base.size(), 2u); }