meta_ctor.cpp 5.6 KB

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