meta_ctor.cpp 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215
  1. #include <utility>
  2. #include <gtest/gtest.h>
  3. #include <entt/core/hashed_string.hpp>
  4. #include <entt/core/utility.hpp>
  5. #include <entt/entity/registry.hpp>
  6. #include <entt/locator/locator.hpp>
  7. #include <entt/meta/factory.hpp>
  8. #include <entt/meta/meta.hpp>
  9. #include <entt/meta/resolve.hpp>
  10. struct base_t {
  11. base_t()
  12. : value{'c'} {}
  13. char value;
  14. };
  15. struct derived_t: base_t {
  16. derived_t()
  17. : base_t{} {}
  18. };
  19. struct clazz_t {
  20. clazz_t(const base_t &other, int &iv)
  21. : clazz_t{iv, other.value} {}
  22. clazz_t(const int &iv, char cv)
  23. : i{iv}, c{cv} {}
  24. operator int() const {
  25. return i;
  26. }
  27. static clazz_t factory(int value) {
  28. return {value, 'c'};
  29. }
  30. static clazz_t factory(base_t other, int value, int mul) {
  31. return {value * mul, other.value};
  32. }
  33. int i{};
  34. char c{};
  35. };
  36. double double_factory() {
  37. return 42.;
  38. }
  39. struct MetaCtor: ::testing::Test {
  40. void SetUp() override {
  41. using namespace entt::literals;
  42. entt::meta<double>()
  43. .type("double"_hs)
  44. .ctor<double_factory>();
  45. entt::meta<derived_t>()
  46. .type("derived"_hs)
  47. .base<base_t>();
  48. entt::meta<clazz_t>()
  49. .type("clazz"_hs)
  50. .ctor<&entt::registry::emplace_or_replace<clazz_t, const int &, const char &>, entt::as_ref_t>()
  51. .ctor<const base_t &, int &>()
  52. .ctor<const int &, char>()
  53. .ctor<entt::overload<clazz_t(int)>(clazz_t::factory)>()
  54. .ctor<entt::overload<clazz_t(base_t, int, int)>(clazz_t::factory)>()
  55. .conv<int>();
  56. }
  57. void TearDown() override {
  58. entt::meta_reset();
  59. }
  60. };
  61. TEST_F(MetaCtor, Functionalities) {
  62. auto any = entt::resolve<clazz_t>().construct(42, 'c');
  63. ASSERT_TRUE(any);
  64. ASSERT_EQ(any.cast<clazz_t>().i, 42);
  65. ASSERT_EQ(any.cast<clazz_t>().c, 'c');
  66. }
  67. TEST_F(MetaCtor, Func) {
  68. auto any = entt::resolve<clazz_t>().construct(42);
  69. ASSERT_TRUE(any);
  70. ASSERT_EQ(any.cast<clazz_t>().i, 42);
  71. ASSERT_EQ(any.cast<clazz_t>().c, 'c');
  72. }
  73. TEST_F(MetaCtor, MetaAnyArgs) {
  74. auto any = entt::resolve<clazz_t>().construct(entt::meta_any{42}, entt::meta_any{'c'});
  75. ASSERT_TRUE(any);
  76. ASSERT_EQ(any.cast<clazz_t>().i, 42);
  77. ASSERT_EQ(any.cast<clazz_t>().c, 'c');
  78. }
  79. TEST_F(MetaCtor, InvalidArgs) {
  80. ASSERT_FALSE(entt::resolve<clazz_t>().construct(entt::meta_any{}, derived_t{}));
  81. }
  82. TEST_F(MetaCtor, CastAndConvert) {
  83. auto any = entt::resolve<clazz_t>().construct(derived_t{}, clazz_t{42, 'd'});
  84. ASSERT_TRUE(any);
  85. ASSERT_EQ(any.cast<clazz_t>().i, 42);
  86. ASSERT_EQ(any.cast<clazz_t>().c, 'c');
  87. }
  88. TEST_F(MetaCtor, ArithmeticConversion) {
  89. auto any = entt::resolve<clazz_t>().construct(true, 4.2);
  90. ASSERT_TRUE(any);
  91. ASSERT_EQ(any.cast<clazz_t>().i, 1);
  92. ASSERT_EQ(any.cast<clazz_t>().c, char{4});
  93. }
  94. TEST_F(MetaCtor, ConstNonConstRefArgs) {
  95. int ivalue = 42;
  96. const char cvalue = 'c';
  97. auto any = entt::resolve<clazz_t>().construct(entt::forward_as_meta(ivalue), entt::forward_as_meta(cvalue));
  98. ASSERT_TRUE(any);
  99. ASSERT_EQ(any.cast<clazz_t>().i, 42);
  100. ASSERT_EQ(any.cast<clazz_t>().c, 'c');
  101. }
  102. TEST_F(MetaCtor, WrongConstness) {
  103. int value = 42;
  104. auto any = entt::resolve<clazz_t>().construct(derived_t{}, entt::forward_as_meta(value));
  105. auto other = entt::resolve<clazz_t>().construct(derived_t{}, entt::forward_as_meta(std::as_const(value)));
  106. ASSERT_TRUE(any);
  107. ASSERT_FALSE(other);
  108. ASSERT_EQ(any.cast<clazz_t>().i, 42);
  109. ASSERT_EQ(any.cast<clazz_t>().c, 'c');
  110. }
  111. TEST_F(MetaCtor, FuncMetaAnyArgs) {
  112. auto any = entt::resolve<clazz_t>().construct(entt::meta_any{42});
  113. ASSERT_TRUE(any);
  114. ASSERT_EQ(any.cast<clazz_t>().i, 42);
  115. ASSERT_EQ(any.cast<clazz_t>().c, 'c');
  116. }
  117. TEST_F(MetaCtor, FuncCastAndConvert) {
  118. auto any = entt::resolve<clazz_t>().construct(derived_t{}, 3., clazz_t{3, 'd'});
  119. ASSERT_TRUE(any);
  120. ASSERT_EQ(any.cast<clazz_t>().i, 9);
  121. ASSERT_EQ(any.cast<clazz_t>().c, 'c');
  122. }
  123. TEST_F(MetaCtor, FuncArithmeticConversion) {
  124. auto any = entt::resolve<clazz_t>().construct(4.2);
  125. ASSERT_TRUE(any);
  126. ASSERT_EQ(any.cast<clazz_t>().i, 4);
  127. ASSERT_EQ(any.cast<clazz_t>().c, 'c');
  128. }
  129. TEST_F(MetaCtor, FuncConstNonConstRefArgs) {
  130. int ivalue = 42;
  131. auto any = entt::resolve<clazz_t>().construct(entt::forward_as_meta(ivalue));
  132. auto other = entt::resolve<clazz_t>().construct(entt::make_meta<const int &>(ivalue));
  133. ASSERT_TRUE(any);
  134. ASSERT_TRUE(other);
  135. ASSERT_EQ(any.cast<clazz_t>().i, 42);
  136. ASSERT_EQ(other.cast<clazz_t>().i, 42);
  137. }
  138. TEST_F(MetaCtor, ExternalMemberFunction) {
  139. entt::registry registry;
  140. const auto entity = registry.create();
  141. ASSERT_FALSE(registry.all_of<clazz_t>(entity));
  142. const auto any = entt::resolve<clazz_t>().construct(entt::forward_as_meta(registry), entity, 3, 'c');
  143. ASSERT_TRUE(any);
  144. ASSERT_TRUE(registry.all_of<clazz_t>(entity));
  145. ASSERT_EQ(registry.get<clazz_t>(entity).i, 3);
  146. ASSERT_EQ(registry.get<clazz_t>(entity).c, 'c');
  147. }
  148. TEST_F(MetaCtor, OverrideImplicitlyGeneratedDefaultConstructor) {
  149. auto type = entt::resolve<double>();
  150. auto any = type.construct();
  151. ASSERT_TRUE(any);
  152. ASSERT_EQ(any.type(), entt::resolve<double>());
  153. ASSERT_EQ(any.cast<double>(), 42.);
  154. }
  155. TEST_F(MetaCtor, NonDefaultConstructibleType) {
  156. auto type = entt::resolve<clazz_t>();
  157. // no implicitly generated default constructor
  158. ASSERT_FALSE(type.construct());
  159. }
  160. TEST_F(MetaCtor, ReRegistration) {
  161. SetUp();
  162. auto &&node = entt::internal::resolve<double>(entt::internal::meta_context::from(entt::locator<entt::meta_ctx>::value_or()));
  163. ASSERT_TRUE(node.details);
  164. ASSERT_FALSE(node.details->ctor.empty());
  165. // implicitly generated default constructor is not cleared
  166. ASSERT_NE(node.default_constructor, nullptr);
  167. }