meta_data.cpp 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689
  1. #include <cstdlib>
  2. #include <string>
  3. #include <gtest/gtest.h>
  4. #include <entt/core/hashed_string.hpp>
  5. #include <entt/meta/factory.hpp>
  6. #include <entt/meta/meta.hpp>
  7. #include <entt/meta/resolve.hpp>
  8. struct base_t {
  9. virtual ~base_t() = default;
  10. static void destroy(base_t &) {
  11. ++counter;
  12. }
  13. inline static int counter = 0;
  14. int value{3};
  15. };
  16. struct derived_t: base_t {
  17. derived_t() {}
  18. };
  19. struct clazz_t {
  20. clazz_t()
  21. : i{0},
  22. j{1},
  23. base{} {}
  24. operator int() const {
  25. return h;
  26. }
  27. int i{0};
  28. const int j{1};
  29. base_t base{};
  30. inline static int h{2};
  31. inline static const int k{3};
  32. };
  33. struct setter_getter_t {
  34. setter_getter_t()
  35. : value{0} {}
  36. int setter(double val) {
  37. return value = static_cast<int>(val);
  38. }
  39. int getter() {
  40. return value;
  41. }
  42. int setter_with_ref(const int &val) {
  43. return value = val;
  44. }
  45. const int &getter_with_ref() {
  46. return value;
  47. }
  48. static int static_setter(setter_getter_t &type, int value) {
  49. return type.value = value;
  50. }
  51. static int static_getter(const setter_getter_t &type) {
  52. return type.value;
  53. }
  54. int value;
  55. };
  56. struct multi_setter_t {
  57. multi_setter_t()
  58. : value{0} {}
  59. void from_double(double val) {
  60. value = val;
  61. }
  62. void from_string(const char *val) {
  63. value = std::atoi(val);
  64. }
  65. int value;
  66. };
  67. struct array_t {
  68. static inline int global[3];
  69. int local[5];
  70. };
  71. enum class property_t {
  72. random,
  73. value
  74. };
  75. struct MetaData: ::testing::Test {
  76. void SetUp() override {
  77. using namespace entt::literals;
  78. entt::meta<double>()
  79. .type("double"_hs);
  80. entt::meta<base_t>()
  81. .type("base"_hs)
  82. .dtor<base_t::destroy>()
  83. .data<&base_t::value>("value"_hs);
  84. entt::meta<derived_t>()
  85. .type("derived"_hs)
  86. .base<base_t>()
  87. .dtor<derived_t::destroy>()
  88. .data<&base_t::value>("value_from_base"_hs);
  89. entt::meta<clazz_t>()
  90. .type("clazz"_hs)
  91. .data<&clazz_t::i, entt::as_ref_t>("i"_hs)
  92. .prop(3, 0)
  93. .data<&clazz_t::i, entt::as_cref_t>("ci"_hs)
  94. .data<&clazz_t::j>("j"_hs)
  95. .prop(true, 1)
  96. .data<&clazz_t::h>("h"_hs)
  97. .prop(property_t::random, 2)
  98. .data<&clazz_t::k>("k"_hs)
  99. .prop(property_t::value, 3)
  100. .data<&clazz_t::base>("base"_hs)
  101. .data<&clazz_t::i, entt::as_void_t>("void"_hs)
  102. .conv<int>();
  103. entt::meta<setter_getter_t>()
  104. .type("setter_getter"_hs)
  105. .data<&setter_getter_t::static_setter, &setter_getter_t::static_getter>("x"_hs)
  106. .data<&setter_getter_t::setter, &setter_getter_t::getter>("y"_hs)
  107. .data<&setter_getter_t::static_setter, &setter_getter_t::getter>("z"_hs)
  108. .data<&setter_getter_t::setter_with_ref, &setter_getter_t::getter_with_ref>("w"_hs)
  109. .data<nullptr, &setter_getter_t::getter>("z_ro"_hs)
  110. .data<nullptr, &setter_getter_t::value>("value"_hs);
  111. entt::meta<multi_setter_t>()
  112. .type("multi_setter"_hs)
  113. .data<entt::value_list<&multi_setter_t::from_double, &multi_setter_t::from_string>, &multi_setter_t::value>("value"_hs);
  114. entt::meta<array_t>()
  115. .type("array"_hs)
  116. .data<&array_t::global>("global"_hs)
  117. .data<&array_t::local>("local"_hs);
  118. base_t::counter = 0;
  119. }
  120. void TearDown() override {
  121. entt::meta_reset();
  122. }
  123. };
  124. using MetaDataDeathTest = MetaData;
  125. TEST_F(MetaData, Functionalities) {
  126. using namespace entt::literals;
  127. auto data = entt::resolve<clazz_t>().data("i"_hs);
  128. clazz_t instance{};
  129. ASSERT_TRUE(data);
  130. ASSERT_EQ(data.arity(), 1u);
  131. ASSERT_EQ(data.type(), entt::resolve<int>());
  132. ASSERT_EQ(data.arg(0u), entt::resolve<int>());
  133. ASSERT_EQ(data.id(), "i"_hs);
  134. ASSERT_FALSE(data.is_const());
  135. ASSERT_FALSE(data.is_static());
  136. ASSERT_EQ(data.get(instance).cast<int>(), 0);
  137. ASSERT_TRUE(data.set(instance, 42));
  138. ASSERT_EQ(data.get(instance).cast<int>(), 42);
  139. for(auto curr: data.prop()) {
  140. ASSERT_EQ(curr.key(), 3);
  141. ASSERT_EQ(curr.value(), 0);
  142. }
  143. ASSERT_FALSE(data.prop(2));
  144. ASSERT_FALSE(data.prop('c'));
  145. auto prop = data.prop(3);
  146. ASSERT_TRUE(prop);
  147. ASSERT_EQ(prop.key(), 3);
  148. ASSERT_EQ(prop.value(), 0);
  149. }
  150. TEST_F(MetaData, Const) {
  151. using namespace entt::literals;
  152. auto data = entt::resolve<clazz_t>().data("j"_hs);
  153. clazz_t instance{};
  154. ASSERT_TRUE(data);
  155. ASSERT_EQ(data.arity(), 1u);
  156. ASSERT_EQ(data.type(), entt::resolve<int>());
  157. ASSERT_EQ(data.arg(0u), entt::resolve<int>());
  158. ASSERT_EQ(data.id(), "j"_hs);
  159. ASSERT_TRUE(data.is_const());
  160. ASSERT_FALSE(data.is_static());
  161. ASSERT_EQ(data.get(instance).cast<int>(), 1);
  162. ASSERT_FALSE(data.set(instance, 42));
  163. ASSERT_EQ(data.get(instance).cast<int>(), 1);
  164. for(auto curr: data.prop()) {
  165. ASSERT_EQ(curr.key(), true);
  166. ASSERT_EQ(curr.value(), 1);
  167. }
  168. ASSERT_FALSE(data.prop(false));
  169. ASSERT_FALSE(data.prop('c'));
  170. auto prop = data.prop(true);
  171. ASSERT_TRUE(prop);
  172. ASSERT_EQ(prop.key(), true);
  173. ASSERT_EQ(prop.value(), 1);
  174. }
  175. TEST_F(MetaData, Static) {
  176. using namespace entt::literals;
  177. auto data = entt::resolve<clazz_t>().data("h"_hs);
  178. ASSERT_TRUE(data);
  179. ASSERT_EQ(data.arity(), 1u);
  180. ASSERT_EQ(data.type(), entt::resolve<int>());
  181. ASSERT_EQ(data.arg(0u), entt::resolve<int>());
  182. ASSERT_EQ(data.id(), "h"_hs);
  183. ASSERT_FALSE(data.is_const());
  184. ASSERT_TRUE(data.is_static());
  185. ASSERT_EQ(data.get({}).cast<int>(), 2);
  186. ASSERT_TRUE(data.set({}, 42));
  187. ASSERT_EQ(data.get({}).cast<int>(), 42);
  188. for(auto curr: data.prop()) {
  189. ASSERT_EQ(curr.key(), property_t::random);
  190. ASSERT_EQ(curr.value(), 2);
  191. }
  192. ASSERT_FALSE(data.prop(property_t::value));
  193. ASSERT_FALSE(data.prop('c'));
  194. auto prop = data.prop(property_t::random);
  195. ASSERT_TRUE(prop);
  196. ASSERT_EQ(prop.key(), property_t::random);
  197. ASSERT_EQ(prop.value(), 2);
  198. }
  199. TEST_F(MetaData, ConstStatic) {
  200. using namespace entt::literals;
  201. auto data = entt::resolve<clazz_t>().data("k"_hs);
  202. ASSERT_TRUE(data);
  203. ASSERT_EQ(data.arity(), 1u);
  204. ASSERT_EQ(data.type(), entt::resolve<int>());
  205. ASSERT_EQ(data.arg(0u), entt::resolve<int>());
  206. ASSERT_EQ(data.id(), "k"_hs);
  207. ASSERT_TRUE(data.is_const());
  208. ASSERT_TRUE(data.is_static());
  209. ASSERT_EQ(data.get({}).cast<int>(), 3);
  210. ASSERT_FALSE(data.set({}, 42));
  211. ASSERT_EQ(data.get({}).cast<int>(), 3);
  212. for(auto curr: data.prop()) {
  213. ASSERT_EQ(curr.key(), property_t::value);
  214. ASSERT_EQ(curr.value(), 3);
  215. }
  216. ASSERT_FALSE(data.prop(property_t::random));
  217. ASSERT_FALSE(data.prop('c'));
  218. auto prop = data.prop(property_t::value);
  219. ASSERT_TRUE(prop);
  220. ASSERT_EQ(prop.key(), property_t::value);
  221. ASSERT_EQ(prop.value(), 3);
  222. }
  223. TEST_F(MetaData, GetMetaAnyArg) {
  224. using namespace entt::literals;
  225. entt::meta_any any{clazz_t{}};
  226. any.cast<clazz_t &>().i = 99;
  227. const auto value = entt::resolve<clazz_t>().data("i"_hs).get(any);
  228. ASSERT_TRUE(value);
  229. ASSERT_TRUE(static_cast<bool>(value.cast<int>()));
  230. ASSERT_EQ(value.cast<int>(), 99);
  231. }
  232. TEST_F(MetaData, GetInvalidArg) {
  233. using namespace entt::literals;
  234. auto instance = 0;
  235. ASSERT_FALSE(entt::resolve<clazz_t>().data("i"_hs).get(instance));
  236. }
  237. TEST_F(MetaData, SetMetaAnyArg) {
  238. using namespace entt::literals;
  239. entt::meta_any any{clazz_t{}};
  240. entt::meta_any value{42};
  241. ASSERT_EQ(any.cast<clazz_t>().i, 0);
  242. ASSERT_TRUE(entt::resolve<clazz_t>().data("i"_hs).set(any, value));
  243. ASSERT_EQ(any.cast<clazz_t>().i, 42);
  244. }
  245. TEST_F(MetaData, SetInvalidArg) {
  246. using namespace entt::literals;
  247. ASSERT_FALSE(entt::resolve<clazz_t>().data("i"_hs).set({}, 'c'));
  248. }
  249. TEST_F(MetaData, SetCast) {
  250. using namespace entt::literals;
  251. clazz_t instance{};
  252. ASSERT_EQ(base_t::counter, 0);
  253. ASSERT_TRUE(entt::resolve<clazz_t>().data("base"_hs).set(instance, derived_t{}));
  254. ASSERT_EQ(base_t::counter, 1);
  255. }
  256. TEST_F(MetaData, SetConvert) {
  257. using namespace entt::literals;
  258. clazz_t instance{};
  259. instance.h = 42;
  260. ASSERT_EQ(instance.i, 0);
  261. ASSERT_TRUE(entt::resolve<clazz_t>().data("i"_hs).set(instance, instance));
  262. ASSERT_EQ(instance.i, 42);
  263. }
  264. TEST_F(MetaData, SetByRef) {
  265. using namespace entt::literals;
  266. entt::meta_any any{clazz_t{}};
  267. int value{42};
  268. ASSERT_EQ(any.cast<clazz_t>().i, 0);
  269. ASSERT_TRUE(entt::resolve<clazz_t>().data("i"_hs).set(any, entt::make_meta<int &>(value)));
  270. ASSERT_EQ(any.cast<clazz_t>().i, 42);
  271. value = 3;
  272. auto wrapper = entt::make_meta<int &>(value);
  273. ASSERT_TRUE(entt::resolve<clazz_t>().data("i"_hs).set(any, wrapper.as_ref()));
  274. ASSERT_EQ(any.cast<clazz_t>().i, 3);
  275. }
  276. TEST_F(MetaData, SetByConstRef) {
  277. using namespace entt::literals;
  278. entt::meta_any any{clazz_t{}};
  279. int value{42};
  280. ASSERT_EQ(any.cast<clazz_t>().i, 0);
  281. ASSERT_TRUE(entt::resolve<clazz_t>().data("i"_hs).set(any, entt::make_meta<const int &>(value)));
  282. ASSERT_EQ(any.cast<clazz_t>().i, 42);
  283. value = 3;
  284. auto wrapper = entt::make_meta<const int &>(value);
  285. ASSERT_TRUE(entt::resolve<clazz_t>().data("i"_hs).set(any, wrapper.as_ref()));
  286. ASSERT_EQ(any.cast<clazz_t>().i, 3);
  287. }
  288. TEST_F(MetaData, SetterGetterAsFreeFunctions) {
  289. using namespace entt::literals;
  290. auto data = entt::resolve<setter_getter_t>().data("x"_hs);
  291. setter_getter_t instance{};
  292. ASSERT_TRUE(data);
  293. ASSERT_EQ(data.arity(), 1u);
  294. ASSERT_EQ(data.type(), entt::resolve<int>());
  295. ASSERT_EQ(data.arg(0u), entt::resolve<int>());
  296. ASSERT_EQ(data.id(), "x"_hs);
  297. ASSERT_FALSE(data.is_const());
  298. ASSERT_FALSE(data.is_static());
  299. ASSERT_EQ(data.get(instance).cast<int>(), 0);
  300. ASSERT_TRUE(data.set(instance, 42));
  301. ASSERT_EQ(data.get(instance).cast<int>(), 42);
  302. }
  303. TEST_F(MetaData, SetterGetterAsMemberFunctions) {
  304. using namespace entt::literals;
  305. auto data = entt::resolve<setter_getter_t>().data("y"_hs);
  306. setter_getter_t instance{};
  307. ASSERT_TRUE(data);
  308. ASSERT_EQ(data.arity(), 1u);
  309. ASSERT_EQ(data.type(), entt::resolve<int>());
  310. ASSERT_EQ(data.arg(0u), entt::resolve<double>());
  311. ASSERT_EQ(data.id(), "y"_hs);
  312. ASSERT_FALSE(data.is_const());
  313. ASSERT_FALSE(data.is_static());
  314. ASSERT_EQ(data.get(instance).cast<int>(), 0);
  315. ASSERT_TRUE(data.set(instance, 42.));
  316. ASSERT_EQ(data.get(instance).cast<int>(), 42);
  317. ASSERT_TRUE(data.set(instance, 3));
  318. ASSERT_EQ(data.get(instance).cast<int>(), 3);
  319. }
  320. TEST_F(MetaData, SetterGetterWithRefAsMemberFunctions) {
  321. using namespace entt::literals;
  322. auto data = entt::resolve<setter_getter_t>().data("w"_hs);
  323. setter_getter_t instance{};
  324. ASSERT_TRUE(data);
  325. ASSERT_EQ(data.arity(), 1u);
  326. ASSERT_EQ(data.type(), entt::resolve<int>());
  327. ASSERT_EQ(data.arg(0u), entt::resolve<int>());
  328. ASSERT_EQ(data.id(), "w"_hs);
  329. ASSERT_FALSE(data.is_const());
  330. ASSERT_FALSE(data.is_static());
  331. ASSERT_EQ(data.get(instance).cast<int>(), 0);
  332. ASSERT_TRUE(data.set(instance, 42));
  333. ASSERT_EQ(data.get(instance).cast<int>(), 42);
  334. }
  335. TEST_F(MetaData, SetterGetterMixed) {
  336. using namespace entt::literals;
  337. auto data = entt::resolve<setter_getter_t>().data("z"_hs);
  338. setter_getter_t instance{};
  339. ASSERT_TRUE(data);
  340. ASSERT_EQ(data.arity(), 1u);
  341. ASSERT_EQ(data.type(), entt::resolve<int>());
  342. ASSERT_EQ(data.arg(0u), entt::resolve<int>());
  343. ASSERT_EQ(data.id(), "z"_hs);
  344. ASSERT_FALSE(data.is_const());
  345. ASSERT_FALSE(data.is_static());
  346. ASSERT_EQ(data.get(instance).cast<int>(), 0);
  347. ASSERT_TRUE(data.set(instance, 42));
  348. ASSERT_EQ(data.get(instance).cast<int>(), 42);
  349. }
  350. TEST_F(MetaData, SetterGetterReadOnly) {
  351. using namespace entt::literals;
  352. auto data = entt::resolve<setter_getter_t>().data("z_ro"_hs);
  353. setter_getter_t instance{};
  354. ASSERT_TRUE(data);
  355. ASSERT_EQ(data.arity(), 0u);
  356. ASSERT_EQ(data.type(), entt::resolve<int>());
  357. ASSERT_EQ(data.arg(0u), entt::meta_type{});
  358. ASSERT_EQ(data.id(), "z_ro"_hs);
  359. ASSERT_TRUE(data.is_const());
  360. ASSERT_FALSE(data.is_static());
  361. ASSERT_EQ(data.get(instance).cast<int>(), 0);
  362. ASSERT_FALSE(data.set(instance, 42));
  363. ASSERT_EQ(data.get(instance).cast<int>(), 0);
  364. }
  365. TEST_F(MetaData, SetterGetterReadOnlyDataMember) {
  366. using namespace entt::literals;
  367. auto data = entt::resolve<setter_getter_t>().data("value"_hs);
  368. setter_getter_t instance{};
  369. ASSERT_TRUE(data);
  370. ASSERT_EQ(data.arity(), 0u);
  371. ASSERT_EQ(data.type(), entt::resolve<int>());
  372. ASSERT_EQ(data.arg(0u), entt::meta_type{});
  373. ASSERT_EQ(data.id(), "value"_hs);
  374. ASSERT_TRUE(data.is_const());
  375. ASSERT_FALSE(data.is_static());
  376. ASSERT_EQ(data.get(instance).cast<int>(), 0);
  377. ASSERT_FALSE(data.set(instance, 42));
  378. ASSERT_EQ(data.get(instance).cast<int>(), 0);
  379. }
  380. TEST_F(MetaData, MultiSetter) {
  381. using namespace entt::literals;
  382. auto data = entt::resolve<multi_setter_t>().data("value"_hs);
  383. multi_setter_t instance{};
  384. ASSERT_TRUE(data);
  385. ASSERT_EQ(data.arity(), 2u);
  386. ASSERT_EQ(data.type(), entt::resolve<int>());
  387. ASSERT_EQ(data.arg(0u), entt::resolve<double>());
  388. ASSERT_EQ(data.arg(1u), entt::resolve<const char *>());
  389. ASSERT_EQ(data.arg(2u), entt::meta_type{});
  390. ASSERT_EQ(data.id(), "value"_hs);
  391. ASSERT_FALSE(data.is_const());
  392. ASSERT_FALSE(data.is_static());
  393. ASSERT_EQ(data.get(instance).cast<int>(), 0);
  394. ASSERT_TRUE(data.set(instance, 42));
  395. ASSERT_EQ(data.get(instance).cast<int>(), 42);
  396. ASSERT_TRUE(data.set(instance, 3.));
  397. ASSERT_EQ(data.get(instance).cast<int>(), 3);
  398. ASSERT_FALSE(data.set(instance, std::string{"99"}));
  399. ASSERT_TRUE(data.set(instance, std::string{"99"}.c_str()));
  400. ASSERT_EQ(data.get(instance).cast<int>(), 99);
  401. }
  402. TEST_F(MetaData, ConstInstance) {
  403. using namespace entt::literals;
  404. clazz_t instance{};
  405. ASSERT_NE(entt::resolve<clazz_t>().data("i"_hs).get(instance).try_cast<int>(), nullptr);
  406. ASSERT_NE(entt::resolve<clazz_t>().data("i"_hs).get(instance).try_cast<const int>(), nullptr);
  407. ASSERT_EQ(entt::resolve<clazz_t>().data("i"_hs).get(std::as_const(instance)).try_cast<int>(), nullptr);
  408. // as_ref_t adapts to the constness of the passed object and returns const references in case
  409. ASSERT_NE(entt::resolve<clazz_t>().data("i"_hs).get(std::as_const(instance)).try_cast<const int>(), nullptr);
  410. ASSERT_TRUE(entt::resolve<clazz_t>().data("i"_hs).get(instance));
  411. ASSERT_TRUE(entt::resolve<clazz_t>().data("i"_hs).set(instance, 3));
  412. ASSERT_TRUE(entt::resolve<clazz_t>().data("i"_hs).get(std::as_const(instance)));
  413. ASSERT_FALSE(entt::resolve<clazz_t>().data("i"_hs).set(std::as_const(instance), 3));
  414. ASSERT_TRUE(entt::resolve<clazz_t>().data("ci"_hs).get(instance));
  415. ASSERT_TRUE(entt::resolve<clazz_t>().data("ci"_hs).set(instance, 3));
  416. ASSERT_TRUE(entt::resolve<clazz_t>().data("ci"_hs).get(std::as_const(instance)));
  417. ASSERT_FALSE(entt::resolve<clazz_t>().data("ci"_hs).set(std::as_const(instance), 3));
  418. ASSERT_TRUE(entt::resolve<clazz_t>().data("j"_hs).get(instance));
  419. ASSERT_FALSE(entt::resolve<clazz_t>().data("j"_hs).set(instance, 3));
  420. ASSERT_TRUE(entt::resolve<clazz_t>().data("j"_hs).get(std::as_const(instance)));
  421. ASSERT_FALSE(entt::resolve<clazz_t>().data("j"_hs).set(std::as_const(instance), 3));
  422. }
  423. TEST_F(MetaData, ArrayStatic) {
  424. using namespace entt::literals;
  425. auto data = entt::resolve<array_t>().data("global"_hs);
  426. ASSERT_TRUE(data);
  427. ASSERT_EQ(data.arity(), 1u);
  428. ASSERT_EQ(data.type(), entt::resolve<int[3]>());
  429. ASSERT_EQ(data.arg(0u), entt::resolve<int[3]>());
  430. ASSERT_EQ(data.id(), "global"_hs);
  431. ASSERT_FALSE(data.is_const());
  432. ASSERT_TRUE(data.is_static());
  433. ASSERT_TRUE(data.type().is_array());
  434. ASSERT_FALSE(data.get({}));
  435. }
  436. TEST_F(MetaData, Array) {
  437. using namespace entt::literals;
  438. auto data = entt::resolve<array_t>().data("local"_hs);
  439. array_t instance{};
  440. ASSERT_TRUE(data);
  441. ASSERT_EQ(data.arity(), 1u);
  442. ASSERT_EQ(data.type(), entt::resolve<int[5]>());
  443. ASSERT_EQ(data.arg(0u), entt::resolve<int[5]>());
  444. ASSERT_EQ(data.id(), "local"_hs);
  445. ASSERT_FALSE(data.is_const());
  446. ASSERT_FALSE(data.is_static());
  447. ASSERT_TRUE(data.type().is_array());
  448. ASSERT_FALSE(data.get(instance));
  449. }
  450. TEST_F(MetaData, AsVoid) {
  451. using namespace entt::literals;
  452. auto data = entt::resolve<clazz_t>().data("void"_hs);
  453. clazz_t instance{};
  454. ASSERT_TRUE(data);
  455. ASSERT_EQ(data.arity(), 1u);
  456. ASSERT_EQ(data.type(), entt::resolve<int>());
  457. ASSERT_EQ(data.arg(0u), entt::resolve<int>());
  458. ASSERT_TRUE(data.set(instance, 42));
  459. ASSERT_EQ(instance.i, 42);
  460. ASSERT_EQ(data.get(instance), entt::meta_any{std::in_place_type<void>});
  461. }
  462. TEST_F(MetaData, AsRef) {
  463. using namespace entt::literals;
  464. clazz_t instance{};
  465. auto data = entt::resolve<clazz_t>().data("i"_hs);
  466. ASSERT_TRUE(data);
  467. ASSERT_EQ(data.arity(), 1u);
  468. ASSERT_EQ(data.type(), entt::resolve<int>());
  469. ASSERT_EQ(data.arg(0u), entt::resolve<int>());
  470. ASSERT_EQ(instance.i, 0);
  471. data.get(instance).cast<int &>() = 3;
  472. ASSERT_EQ(instance.i, 3);
  473. }
  474. TEST_F(MetaData, AsConstRef) {
  475. using namespace entt::literals;
  476. clazz_t instance{};
  477. auto data = entt::resolve<clazz_t>().data("ci"_hs);
  478. ASSERT_EQ(instance.i, 0);
  479. ASSERT_EQ(data.arity(), 1u);
  480. ASSERT_EQ(data.type(), entt::resolve<int>());
  481. ASSERT_EQ(data.arg(0u), entt::resolve<int>());
  482. ASSERT_EQ(data.get(instance).cast<const int &>(), 0);
  483. ASSERT_EQ(data.get(instance).cast<int>(), 0);
  484. ASSERT_EQ(instance.i, 0);
  485. }
  486. TEST_F(MetaDataDeathTest, AsConstRef) {
  487. using namespace entt::literals;
  488. clazz_t instance{};
  489. auto data = entt::resolve<clazz_t>().data("ci"_hs);
  490. ASSERT_DEATH(data.get(instance).cast<int &>() = 3, "");
  491. }
  492. TEST_F(MetaData, SetGetBaseData) {
  493. using namespace entt::literals;
  494. auto type = entt::resolve<derived_t>();
  495. derived_t instance{};
  496. ASSERT_TRUE(type.data("value"_hs));
  497. ASSERT_EQ(instance.value, 3);
  498. ASSERT_TRUE(type.data("value"_hs).set(instance, 42));
  499. ASSERT_EQ(type.data("value"_hs).get(instance).cast<int>(), 42);
  500. ASSERT_EQ(instance.value, 42);
  501. }
  502. TEST_F(MetaData, SetGetFromBase) {
  503. using namespace entt::literals;
  504. auto type = entt::resolve<derived_t>();
  505. derived_t instance{};
  506. ASSERT_TRUE(type.data("value_from_base"_hs));
  507. ASSERT_EQ(instance.value, 3);
  508. ASSERT_TRUE(type.data("value_from_base"_hs).set(instance, 42));
  509. ASSERT_EQ(type.data("value_from_base"_hs).get(instance).cast<int>(), 42);
  510. ASSERT_EQ(instance.value, 42);
  511. }
  512. TEST_F(MetaData, ReRegistration) {
  513. using namespace entt::literals;
  514. SetUp();
  515. auto *node = entt::internal::meta_node<base_t>::resolve();
  516. auto type = entt::resolve<base_t>();
  517. ASSERT_NE(node->data, nullptr);
  518. ASSERT_EQ(node->data->next, nullptr);
  519. ASSERT_TRUE(type.data("value"_hs));
  520. entt::meta<base_t>().data<&base_t::value>("field"_hs);
  521. ASSERT_NE(node->data, nullptr);
  522. ASSERT_EQ(node->data->next, nullptr);
  523. ASSERT_FALSE(type.data("value"_hs));
  524. ASSERT_TRUE(type.data("field"_hs));
  525. }
  526. TEST_F(MetaData, NameCollision) {
  527. using namespace entt::literals;
  528. ASSERT_NO_FATAL_FAILURE(entt::meta<clazz_t>().data<&clazz_t::j>("j"_hs));
  529. ASSERT_TRUE(entt::resolve<clazz_t>().data("j"_hs));
  530. ASSERT_NO_FATAL_FAILURE(entt::meta<clazz_t>().data<&clazz_t::j>("cj"_hs));
  531. ASSERT_FALSE(entt::resolve<clazz_t>().data("j"_hs));
  532. ASSERT_TRUE(entt::resolve<clazz_t>().data("cj"_hs));
  533. }
  534. TEST_F(MetaDataDeathTest, NameCollision) {
  535. using namespace entt::literals;
  536. ASSERT_DEATH(entt::meta<clazz_t>().data<&clazz_t::j>("i"_hs), "");
  537. }