meta_base.cpp 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194
  1. #include <utility>
  2. #include <gtest/gtest.h>
  3. #include <entt/core/hashed_string.hpp>
  4. #include <entt/locator/locator.hpp>
  5. #include <entt/meta/context.hpp>
  6. #include <entt/meta/factory.hpp>
  7. #include <entt/meta/meta.hpp>
  8. #include <entt/meta/node.hpp>
  9. #include <entt/meta/resolve.hpp>
  10. struct base_1 {
  11. base_1() = default;
  12. int value_1{};
  13. };
  14. struct base_2 {
  15. base_2() = default;
  16. operator int() const {
  17. return value_2;
  18. }
  19. int value_2{};
  20. };
  21. struct base_3: base_2 {
  22. base_3() = default;
  23. int value_3{};
  24. };
  25. struct derived: base_1, base_3 {
  26. derived() = default;
  27. int value{};
  28. };
  29. struct MetaBase: ::testing::Test {
  30. void SetUp() override {
  31. using namespace entt::literals;
  32. entt::meta<base_1>()
  33. .data<&base_1::value_1>("value_1"_hs);
  34. entt::meta<base_2>()
  35. .conv<int>()
  36. .data<&base_2::value_2>("value_2"_hs);
  37. entt::meta<base_3>()
  38. .base<base_2>()
  39. .data<&base_3::value_3>("value_3"_hs);
  40. entt::meta<derived>()
  41. .type("derived"_hs)
  42. .base<base_1>()
  43. .base<base_3>()
  44. .data<&derived::value>("value"_hs);
  45. }
  46. void TearDown() override {
  47. entt::meta_reset();
  48. }
  49. };
  50. TEST_F(MetaBase, Functionalities) {
  51. auto any = entt::resolve<derived>().construct();
  52. any.cast<derived &>().value_1 = 2;
  53. auto as_derived = any.as_ref();
  54. ASSERT_TRUE(any.allow_cast<base_1 &>());
  55. ASSERT_FALSE(any.allow_cast<char>());
  56. ASSERT_FALSE(as_derived.allow_cast<char>());
  57. ASSERT_TRUE(any);
  58. ASSERT_EQ(any.cast<base_1 &>().value_1, as_derived.cast<derived &>().value_1);
  59. any.cast<base_1 &>().value_1 = 3;
  60. ASSERT_EQ(any.cast<const base_1 &>().value_1, as_derived.cast<const derived &>().value_1);
  61. }
  62. TEST_F(MetaBase, SetGetWithMutatingThis) {
  63. using namespace entt::literals;
  64. derived instance;
  65. auto any = entt::forward_as_meta(instance);
  66. auto as_cref = std::as_const(any).as_ref();
  67. ASSERT_NE(static_cast<const void *>(static_cast<const base_1 *>(&instance)), static_cast<const void *>(static_cast<const base_2 *>(&instance)));
  68. ASSERT_NE(static_cast<const void *>(static_cast<const base_1 *>(&instance)), static_cast<const void *>(static_cast<const base_3 *>(&instance)));
  69. ASSERT_EQ(static_cast<const void *>(static_cast<const base_2 *>(&instance)), static_cast<const void *>(static_cast<const base_3 *>(&instance)));
  70. ASSERT_EQ(static_cast<const void *>(&instance), static_cast<const void *>(static_cast<const base_1 *>(&instance)));
  71. ASSERT_TRUE(any.set("value"_hs, 0));
  72. ASSERT_TRUE(any.set("value_1"_hs, 1));
  73. ASSERT_TRUE(any.set("value_2"_hs, 2));
  74. ASSERT_TRUE(any.set("value_3"_hs, 3));
  75. ASSERT_FALSE(as_cref.set("value"_hs, 4));
  76. ASSERT_FALSE(as_cref.set("value_1"_hs, 4));
  77. ASSERT_FALSE(as_cref.set("value_2"_hs, 4));
  78. ASSERT_FALSE(as_cref.set("value_3"_hs, 4));
  79. ASSERT_EQ(any.get("value"_hs).cast<int>(), 0);
  80. ASSERT_EQ(any.get("value_1"_hs).cast<const int>(), 1);
  81. ASSERT_EQ(any.get("value_2"_hs).cast<int>(), 2);
  82. ASSERT_EQ(any.get("value_3"_hs).cast<const int>(), 3);
  83. ASSERT_EQ(as_cref.get("value"_hs).cast<const int>(), 0);
  84. ASSERT_EQ(as_cref.get("value_1"_hs).cast<int>(), 1);
  85. ASSERT_EQ(as_cref.get("value_2"_hs).cast<const int>(), 2);
  86. ASSERT_EQ(as_cref.get("value_3"_hs).cast<int>(), 3);
  87. ASSERT_EQ(instance.value, 0);
  88. ASSERT_EQ(instance.value_1, 1);
  89. ASSERT_EQ(instance.value_2, 2);
  90. ASSERT_EQ(instance.value_3, 3);
  91. }
  92. TEST_F(MetaBase, ConvWithMutatingThis) {
  93. entt::meta_any any{derived{}};
  94. auto &&ref = any.cast<derived &>();
  95. auto as_cref = std::as_const(any).as_ref();
  96. ref.value_2 = 2;
  97. auto conv = std::as_const(any).allow_cast<int>();
  98. auto from_cref = std::as_const(as_cref).allow_cast<int>();
  99. ASSERT_TRUE(conv);
  100. ASSERT_TRUE(from_cref);
  101. ASSERT_EQ(conv.cast<int>(), 2);
  102. ASSERT_EQ(from_cref.cast<int>(), 2);
  103. ASSERT_TRUE(as_cref.allow_cast<int>());
  104. ASSERT_TRUE(any.allow_cast<int>());
  105. ASSERT_EQ(as_cref.cast<int>(), 2);
  106. ASSERT_EQ(any.cast<int>(), 2);
  107. }
  108. TEST_F(MetaBase, OpaqueConvWithMutatingThis) {
  109. entt::meta_any any{derived{}};
  110. auto as_cref = std::as_const(any).as_ref();
  111. any.cast<derived &>().value_2 = 2;
  112. auto conv = std::as_const(any).allow_cast(entt::resolve<int>());
  113. auto from_cref = std::as_const(as_cref).allow_cast(entt::resolve<int>());
  114. ASSERT_TRUE(conv);
  115. ASSERT_TRUE(from_cref);
  116. ASSERT_EQ(conv.cast<int>(), 2);
  117. ASSERT_EQ(from_cref.cast<int>(), 2);
  118. ASSERT_TRUE(as_cref.allow_cast(entt::resolve<int>()));
  119. ASSERT_TRUE(any.allow_cast(entt::resolve<int>()));
  120. ASSERT_EQ(as_cref.cast<int>(), 2);
  121. ASSERT_EQ(any.cast<int>(), 2);
  122. }
  123. TEST_F(MetaBase, AssignWithMutatingThis) {
  124. using namespace entt::literals;
  125. entt::meta_any dst{base_2{}};
  126. entt::meta_any src{derived{}};
  127. dst.cast<base_2 &>().value_2 = 0;
  128. src.cast<derived &>().value_2 = 1;
  129. ASSERT_TRUE(dst.assign(src));
  130. ASSERT_EQ(dst.get("value_2"_hs).cast<int>(), 1);
  131. }
  132. TEST_F(MetaBase, TransferWithMutatingThis) {
  133. using namespace entt::literals;
  134. entt::meta_any dst{base_2{}};
  135. entt::meta_any src{derived{}};
  136. dst.cast<base_2 &>().value_2 = 0;
  137. src.cast<derived &>().value_2 = 1;
  138. ASSERT_TRUE(dst.assign(std::move(src)));
  139. ASSERT_EQ(dst.get("value_2"_hs).cast<int>(), 1);
  140. }
  141. TEST_F(MetaBase, ReRegistration) {
  142. SetUp();
  143. auto &&node = entt::internal::resolve<derived>(entt::internal::meta_context::from(entt::locator<entt::meta_ctx>::value_or()));
  144. ASSERT_TRUE(node.details);
  145. ASSERT_FALSE(node.details->base.empty());
  146. ASSERT_EQ(node.details->base.size(), 2u);
  147. }