meta.cpp 58 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952
  1. #include <utility>
  2. #include <functional>
  3. #include <type_traits>
  4. #include <gtest/gtest.h>
  5. #include <entt/core/hashed_string.hpp>
  6. #include <entt/core/type_info.hpp>
  7. #include <entt/core/utility.hpp>
  8. #include <entt/meta/factory.hpp>
  9. #include <entt/meta/meta.hpp>
  10. #include <entt/meta/resolve.hpp>
  11. template<typename Type>
  12. void set(Type &prop, Type value) {
  13. prop = value;
  14. }
  15. template<typename Type>
  16. Type get(Type &prop) {
  17. return prop;
  18. }
  19. enum class props {
  20. prop_int,
  21. prop_value,
  22. prop_bool,
  23. key_only,
  24. prop_list
  25. };
  26. struct empty_type {
  27. virtual ~empty_type() = default;
  28. static void destroy(empty_type &) {
  29. ++counter;
  30. }
  31. inline static int counter = 0;
  32. };
  33. struct fat_type: empty_type {
  34. fat_type() = default;
  35. fat_type(int *value)
  36. : foo{value}, bar{value}
  37. {}
  38. int *foo{nullptr};
  39. int *bar{nullptr};
  40. bool operator==(const fat_type &other) const {
  41. return foo == other.foo && bar == other.bar;
  42. }
  43. };
  44. union union_type {
  45. int i;
  46. double d;
  47. };
  48. struct base_type {
  49. virtual ~base_type() = default;
  50. };
  51. struct derived_type: base_type {
  52. derived_type() = default;
  53. derived_type(const base_type &, int value, char character)
  54. : i{value}, c{character}
  55. {}
  56. int f() const { return i; }
  57. static char g(const derived_type &type) { return type.c; }
  58. const int i{};
  59. const char c{};
  60. };
  61. derived_type derived_factory(const base_type &, int value) {
  62. return {derived_type{}, value, 'c'};
  63. }
  64. struct data_type {
  65. int i{0};
  66. const int j{1};
  67. inline static int h{2};
  68. inline static const int k{3};
  69. empty_type empty{};
  70. int v{0};
  71. };
  72. struct array_type {
  73. static inline int global[3];
  74. int local[3];
  75. };
  76. struct func_type {
  77. int f(const base_type &, int a, int b) { return f(a, b); }
  78. int f(int a, int b) { value = a; return b*b; }
  79. int f(int v) const { return v*v; }
  80. void g(int v) { value = v*v; }
  81. static int h(int &v) { return (v *= value); }
  82. static void k(int v) { value = v; }
  83. int v(int v) const { return (value = v); }
  84. int & a() const { return value; }
  85. inline static int value = 0;
  86. };
  87. struct setter_getter_type {
  88. int value{};
  89. int setter(int val) { return value = val; }
  90. int getter() { return value; }
  91. int setter_with_ref(const int &val) { return value = val; }
  92. const int & getter_with_ref() { return value; }
  93. static int static_setter(setter_getter_type &type, int value) { return type.value = value; }
  94. static int static_getter(const setter_getter_type &type) { return type.value; }
  95. };
  96. struct not_comparable_type {
  97. bool operator==(const not_comparable_type &) const = delete;
  98. };
  99. struct unmanageable_type {
  100. unmanageable_type() = default;
  101. unmanageable_type(const unmanageable_type &) = delete;
  102. unmanageable_type(unmanageable_type &&) = delete;
  103. unmanageable_type & operator=(const unmanageable_type &) = delete;
  104. unmanageable_type & operator=(unmanageable_type &&) = delete;
  105. };
  106. bool operator!=(const not_comparable_type &, const not_comparable_type &) = delete;
  107. struct an_abstract_type {
  108. virtual ~an_abstract_type() = default;
  109. void f(int v) { i = v; }
  110. virtual void g(int) = 0;
  111. int i{};
  112. };
  113. struct another_abstract_type {
  114. virtual ~another_abstract_type() = default;
  115. virtual void h(char) = 0;
  116. char j{};
  117. };
  118. struct concrete_type: an_abstract_type, another_abstract_type {
  119. void f(int v) { i = v*v; } // hide, it's ok :-)
  120. void g(int v) override { i = -v; }
  121. void h(char c) override { j = c; }
  122. };
  123. struct Meta: ::testing::Test {
  124. static void SetUpTestCase() {
  125. entt::meta<double>().conv<int>();
  126. entt::meta<char>()
  127. .alias("char"_hs)
  128. .prop(props::prop_int, 42)
  129. .data<&set<char>, &get<char>>("value"_hs);
  130. entt::meta<props>()
  131. .data<props::prop_bool>("prop_bool"_hs)
  132. .prop(props::prop_int, 0)
  133. .prop(props::prop_value, 3)
  134. .data<props::prop_int>("prop_int"_hs)
  135. .prop(std::make_tuple(std::make_pair(props::prop_bool, true), std::make_pair(props::prop_int, 0), std::make_pair(props::prop_value, 3)))
  136. .prop(props::key_only)
  137. .data<props::key_only>("key_only"_hs)
  138. .prop([]() { return props::key_only; })
  139. .data<&set<props>, &get<props>>("value"_hs)
  140. .data<props::prop_list>("prop_list"_hs)
  141. .props(std::make_pair(props::prop_bool, false), std::make_pair(props::prop_int, 0), std::make_pair(props::prop_value, 3), props::key_only);
  142. entt::meta<unsigned int>().data<0u>("min"_hs).data<100u>("max"_hs);
  143. entt::meta<base_type>()
  144. .alias("base"_hs);
  145. entt::meta<derived_type>()
  146. .alias("derived"_hs)
  147. .prop(props::prop_int, 99)
  148. .base<base_type>()
  149. .ctor<const base_type &, int, char>()
  150. .prop(props::prop_bool, false)
  151. .ctor<&derived_factory>()
  152. .prop(props::prop_int, 42)
  153. .conv<&derived_type::f>()
  154. .conv<&derived_type::g>();
  155. entt::meta<empty_type>()
  156. .ctor<>()
  157. .alias("empty"_hs)
  158. .dtor<&empty_type::destroy>();
  159. entt::meta<fat_type>()
  160. .alias("fat"_hs)
  161. .base<empty_type>()
  162. .dtor<&fat_type::destroy>();
  163. entt::meta<data_type>()
  164. .alias("data"_hs)
  165. .data<&data_type::i, entt::as_alias_t>("i"_hs)
  166. .prop(props::prop_int, 0)
  167. .data<&data_type::j>("j"_hs)
  168. .prop(props::prop_int, 1)
  169. .data<&data_type::h>("h"_hs)
  170. .prop(props::prop_int, 2)
  171. .data<&data_type::k>("k"_hs)
  172. .prop(props::prop_int, 3)
  173. .data<&data_type::empty>("empty"_hs)
  174. .data<&data_type::v, entt::as_void_t>("v"_hs);
  175. entt::meta<array_type>()
  176. .alias("array"_hs)
  177. .data<&array_type::global>("global"_hs)
  178. .data<&array_type::local>("local"_hs);
  179. entt::meta<func_type>()
  180. .alias("func"_hs)
  181. .func<entt::overload<int(const base_type &, int, int)>(&func_type::f)>("f3"_hs)
  182. .func<entt::overload<int(int, int)>(&func_type::f)>("f2"_hs)
  183. .prop(props::prop_bool, false)
  184. .func<entt::overload<int(int) const>(&func_type::f)>("f1"_hs)
  185. .prop(props::prop_bool, false)
  186. .func<&func_type::g>("g"_hs)
  187. .prop(props::prop_bool, false)
  188. .func<&func_type::h>("h"_hs)
  189. .prop(props::prop_bool, false)
  190. .func<&func_type::k>("k"_hs)
  191. .prop(props::prop_bool, false)
  192. .func<&func_type::v, entt::as_void_t>("v"_hs)
  193. .func<&func_type::a, entt::as_alias_t>("a"_hs);
  194. entt::meta<setter_getter_type>()
  195. .alias("setter_getter"_hs)
  196. .data<&setter_getter_type::static_setter, &setter_getter_type::static_getter>("x"_hs)
  197. .data<&setter_getter_type::setter, &setter_getter_type::getter>("y"_hs)
  198. .data<&setter_getter_type::static_setter, &setter_getter_type::getter>("z"_hs)
  199. .data<&setter_getter_type::setter_with_ref, &setter_getter_type::getter_with_ref>("w"_hs);
  200. entt::meta<an_abstract_type>()
  201. .alias("an_abstract_type"_hs)
  202. .prop(props::prop_bool, false)
  203. .data<&an_abstract_type::i>("i"_hs)
  204. .func<&an_abstract_type::f>("f"_hs)
  205. .func<&an_abstract_type::g>("g"_hs);
  206. entt::meta<another_abstract_type>()
  207. .alias("another_abstract_type"_hs)
  208. .prop(props::prop_int, 42)
  209. .data<&another_abstract_type::j>("j"_hs)
  210. .func<&another_abstract_type::h>("h"_hs);
  211. entt::meta<concrete_type>()
  212. .alias("concrete"_hs)
  213. .base<an_abstract_type>()
  214. .base<another_abstract_type>()
  215. .func<&concrete_type::f>("f"_hs);
  216. }
  217. static void SetUpAfterUnregistration() {
  218. entt::meta<double>().conv<float>();
  219. entt::meta<props>()
  220. .data<props::prop_bool>("prop_bool"_hs)
  221. .prop(props::prop_int, 0)
  222. .prop(props::prop_value, 3);
  223. entt::meta<derived_type>()
  224. .alias("my_type"_hs)
  225. .prop(props::prop_bool, false)
  226. .ctor<>();
  227. entt::meta<another_abstract_type>()
  228. .alias("your_type"_hs)
  229. .data<&another_abstract_type::j>("a_data_member"_hs)
  230. .func<&another_abstract_type::h>("a_member_function"_hs);
  231. }
  232. void SetUp() override {
  233. empty_type::counter = 0;
  234. func_type::value = 0;
  235. }
  236. };
  237. TEST_F(Meta, Resolve) {
  238. ASSERT_EQ(entt::resolve<derived_type>(), entt::resolve_id("derived"_hs));
  239. ASSERT_EQ(entt::resolve<derived_type>(), entt::resolve_type(entt::type_info<derived_type>::id()));
  240. // it could be "char"_hs rather than entt::hashed_string::value("char") if it weren't for a bug in VS2017
  241. ASSERT_EQ(entt::resolve_if([](auto type) { return type.id() == entt::hashed_string::value("char"); }), entt::resolve<char>());
  242. bool found = false;
  243. entt::resolve([&found](auto type) {
  244. found = found || type == entt::resolve<derived_type>();
  245. });
  246. ASSERT_TRUE(found);
  247. }
  248. TEST_F(Meta, MetaAnySBO) {
  249. entt::meta_any any{'c'};
  250. ASSERT_TRUE(any);
  251. ASSERT_FALSE(any.try_cast<std::size_t>());
  252. ASSERT_EQ(any.cast<char>(), 'c');
  253. ASSERT_NE(any.data(), nullptr);
  254. ASSERT_EQ(any, entt::meta_any{'c'});
  255. ASSERT_NE(entt::meta_any{'h'}, any);
  256. }
  257. TEST_F(Meta, MetaAnyNoSBO) {
  258. int value = 42;
  259. fat_type instance{&value};
  260. entt::meta_any any{instance};
  261. ASSERT_TRUE(any);
  262. ASSERT_FALSE(any.try_cast<std::size_t>());
  263. ASSERT_EQ(any.cast<fat_type>(), instance);
  264. ASSERT_NE(any.data(), nullptr);
  265. ASSERT_EQ(any, entt::meta_any{instance});
  266. ASSERT_NE(fat_type{}, any);
  267. }
  268. TEST_F(Meta, MetaAnyEmpty) {
  269. entt::meta_any any{};
  270. ASSERT_FALSE(any);
  271. ASSERT_FALSE(any.type());
  272. ASSERT_FALSE(any.try_cast<std::size_t>());
  273. ASSERT_EQ(any.data(), nullptr);
  274. ASSERT_EQ(any, entt::meta_any{});
  275. ASSERT_NE(entt::meta_any{'c'}, any);
  276. }
  277. TEST_F(Meta, MetaAnySBOInPlaceTypeConstruction) {
  278. entt::meta_any any{std::in_place_type<int>, 42};
  279. ASSERT_TRUE(any);
  280. ASSERT_FALSE(any.try_cast<std::size_t>());
  281. ASSERT_EQ(any.cast<int>(), 42);
  282. ASSERT_NE(any.data(), nullptr);
  283. ASSERT_EQ(any, (entt::meta_any{std::in_place_type<int>, 42}));
  284. ASSERT_EQ(any, entt::meta_any{42});
  285. ASSERT_NE(entt::meta_any{3}, any);
  286. }
  287. TEST_F(Meta, MetaAnySBOAsAliasConstruction) {
  288. int value = 3;
  289. int other = 42;
  290. entt::meta_any any{std::ref(value)};
  291. ASSERT_TRUE(any);
  292. ASSERT_FALSE(any.try_cast<std::size_t>());
  293. ASSERT_EQ(any.cast<int>(), 3);
  294. ASSERT_NE(any.data(), nullptr);
  295. ASSERT_EQ(any, (entt::meta_any{std::ref(value)}));
  296. ASSERT_NE(any, (entt::meta_any{std::ref(other)}));
  297. ASSERT_NE(any, entt::meta_any{42});
  298. ASSERT_EQ(entt::meta_any{3}, any);
  299. }
  300. TEST_F(Meta, MetaAnySBOCopyConstruction) {
  301. entt::meta_any any{42};
  302. entt::meta_any other{any};
  303. ASSERT_TRUE(any);
  304. ASSERT_TRUE(other);
  305. ASSERT_FALSE(other.try_cast<std::size_t>());
  306. ASSERT_EQ(other.cast<int>(), 42);
  307. ASSERT_EQ(other, entt::meta_any{42});
  308. ASSERT_NE(other, entt::meta_any{0});
  309. }
  310. TEST_F(Meta, MetaAnySBOCopyAssignment) {
  311. entt::meta_any any{42};
  312. entt::meta_any other{3};
  313. other = any;
  314. ASSERT_TRUE(any);
  315. ASSERT_TRUE(other);
  316. ASSERT_FALSE(other.try_cast<std::size_t>());
  317. ASSERT_EQ(other.cast<int>(), 42);
  318. ASSERT_EQ(other, entt::meta_any{42});
  319. ASSERT_NE(other, entt::meta_any{0});
  320. }
  321. TEST_F(Meta, MetaAnySBOMoveConstruction) {
  322. entt::meta_any any{42};
  323. entt::meta_any other{std::move(any)};
  324. ASSERT_FALSE(any);
  325. ASSERT_TRUE(other);
  326. ASSERT_FALSE(other.try_cast<std::size_t>());
  327. ASSERT_EQ(other.cast<int>(), 42);
  328. ASSERT_EQ(other, entt::meta_any{42});
  329. ASSERT_NE(other, entt::meta_any{0});
  330. }
  331. TEST_F(Meta, MetaAnySBOMoveAssignment) {
  332. entt::meta_any any{42};
  333. entt::meta_any other{3};
  334. other = std::move(any);
  335. ASSERT_FALSE(any);
  336. ASSERT_TRUE(other);
  337. ASSERT_FALSE(other.try_cast<std::size_t>());
  338. ASSERT_EQ(other.cast<int>(), 42);
  339. ASSERT_EQ(other, entt::meta_any{42});
  340. ASSERT_NE(other, entt::meta_any{0});
  341. }
  342. TEST_F(Meta, MetaAnySBODirectAssignment) {
  343. entt::meta_any any{};
  344. any = 42;
  345. ASSERT_FALSE(any.try_cast<std::size_t>());
  346. ASSERT_EQ(any.cast<int>(), 42);
  347. ASSERT_EQ(any, entt::meta_any{42});
  348. ASSERT_NE(entt::meta_any{0}, any);
  349. }
  350. TEST_F(Meta, MetaAnyNoSBOInPlaceTypeConstruction) {
  351. int value = 42;
  352. fat_type instance{&value};
  353. entt::meta_any any{std::in_place_type<fat_type>, instance};
  354. ASSERT_TRUE(any);
  355. ASSERT_FALSE(any.try_cast<std::size_t>());
  356. ASSERT_EQ(any.cast<fat_type>(), instance);
  357. ASSERT_NE(any.data(), nullptr);
  358. ASSERT_EQ(any, (entt::meta_any{std::in_place_type<fat_type>, instance}));
  359. ASSERT_EQ(any, entt::meta_any{instance});
  360. ASSERT_NE(entt::meta_any{fat_type{}}, any);
  361. }
  362. TEST_F(Meta, MetaAnyNoSBOAsAliasConstruction) {
  363. int value = 3;
  364. fat_type instance{&value};
  365. entt::meta_any any{std::ref(instance)};
  366. ASSERT_TRUE(any);
  367. ASSERT_FALSE(any.try_cast<std::size_t>());
  368. ASSERT_EQ(any.cast<fat_type>(), instance);
  369. ASSERT_NE(any.data(), nullptr);
  370. ASSERT_EQ(any, (entt::meta_any{std::ref(instance)}));
  371. ASSERT_EQ(any, entt::meta_any{instance});
  372. ASSERT_NE(entt::meta_any{fat_type{}}, any);
  373. }
  374. TEST_F(Meta, MetaAnyNoSBOCopyConstruction) {
  375. int value = 42;
  376. fat_type instance{&value};
  377. entt::meta_any any{instance};
  378. entt::meta_any other{any};
  379. ASSERT_TRUE(any);
  380. ASSERT_TRUE(other);
  381. ASSERT_FALSE(other.try_cast<std::size_t>());
  382. ASSERT_EQ(other.cast<fat_type>(), instance);
  383. ASSERT_EQ(other, entt::meta_any{instance});
  384. ASSERT_NE(other, fat_type{});
  385. }
  386. TEST_F(Meta, MetaAnyNoSBOCopyAssignment) {
  387. int value = 42;
  388. fat_type instance{&value};
  389. entt::meta_any any{instance};
  390. entt::meta_any other{3};
  391. other = any;
  392. ASSERT_TRUE(any);
  393. ASSERT_TRUE(other);
  394. ASSERT_FALSE(other.try_cast<std::size_t>());
  395. ASSERT_EQ(other.cast<fat_type>(), instance);
  396. ASSERT_EQ(other, entt::meta_any{instance});
  397. ASSERT_NE(other, fat_type{});
  398. }
  399. TEST_F(Meta, MetaAnyNoSBOMoveConstruction) {
  400. int value = 42;
  401. fat_type instance{&value};
  402. entt::meta_any any{instance};
  403. entt::meta_any other{std::move(any)};
  404. ASSERT_FALSE(any);
  405. ASSERT_TRUE(other);
  406. ASSERT_FALSE(other.try_cast<std::size_t>());
  407. ASSERT_EQ(other.cast<fat_type>(), instance);
  408. ASSERT_EQ(other, entt::meta_any{instance});
  409. ASSERT_NE(other, fat_type{});
  410. }
  411. TEST_F(Meta, MetaAnyNoSBOMoveAssignment) {
  412. int value = 42;
  413. fat_type instance{&value};
  414. entt::meta_any any{instance};
  415. entt::meta_any other{3};
  416. other = std::move(any);
  417. ASSERT_FALSE(any);
  418. ASSERT_TRUE(other);
  419. ASSERT_FALSE(other.try_cast<std::size_t>());
  420. ASSERT_EQ(other.cast<fat_type>(), instance);
  421. ASSERT_EQ(other, entt::meta_any{instance});
  422. ASSERT_NE(other, fat_type{});
  423. }
  424. TEST_F(Meta, MetaAnyNoSBODirectAssignment) {
  425. int value = 42;
  426. entt::meta_any any{};
  427. any = fat_type{&value};
  428. ASSERT_FALSE(any.try_cast<std::size_t>());
  429. ASSERT_EQ(any.cast<fat_type>(), fat_type{&value});
  430. ASSERT_EQ(any, entt::meta_any{fat_type{&value}});
  431. ASSERT_NE(fat_type{}, any);
  432. }
  433. TEST_F(Meta, MetaAnyVoidInPlaceTypeConstruction) {
  434. entt::meta_any any{std::in_place_type<void>};
  435. ASSERT_TRUE(any);
  436. ASSERT_FALSE(any.try_cast<char>());
  437. ASSERT_EQ(any.data(), nullptr);
  438. ASSERT_EQ(any.type(), entt::resolve<void>());
  439. ASSERT_EQ(any, entt::meta_any{std::in_place_type<void>});
  440. ASSERT_NE(entt::meta_any{3}, any);
  441. }
  442. TEST_F(Meta, MetaAnyVoidCopyConstruction) {
  443. entt::meta_any any{std::in_place_type<void>};
  444. entt::meta_any other{any};
  445. ASSERT_TRUE(any);
  446. ASSERT_TRUE(other);
  447. ASSERT_EQ(any.type(), entt::resolve<void>());
  448. ASSERT_EQ(other, entt::meta_any{std::in_place_type<void>});
  449. }
  450. TEST_F(Meta, MetaAnyVoidCopyAssignment) {
  451. entt::meta_any any{std::in_place_type<void>};
  452. entt::meta_any other{std::in_place_type<void>};
  453. other = any;
  454. ASSERT_TRUE(any);
  455. ASSERT_TRUE(other);
  456. ASSERT_EQ(any.type(), entt::resolve<void>());
  457. ASSERT_EQ(other, entt::meta_any{std::in_place_type<void>});
  458. }
  459. TEST_F(Meta, MetaAnyVoidMoveConstruction) {
  460. entt::meta_any any{std::in_place_type<void>};
  461. entt::meta_any other{std::move(any)};
  462. ASSERT_FALSE(any);
  463. ASSERT_TRUE(other);
  464. ASSERT_EQ(other.type(), entt::resolve<void>());
  465. ASSERT_EQ(other, entt::meta_any{std::in_place_type<void>});
  466. }
  467. TEST_F(Meta, MetaAnyVoidMoveAssignment) {
  468. entt::meta_any any{std::in_place_type<void>};
  469. entt::meta_any other{std::in_place_type<void>};
  470. other = std::move(any);
  471. ASSERT_FALSE(any);
  472. ASSERT_TRUE(other);
  473. ASSERT_EQ(other.type(), entt::resolve<void>());
  474. ASSERT_EQ(other, entt::meta_any{std::in_place_type<void>});
  475. }
  476. TEST_F(Meta, MetaAnySBOMoveInvalidate) {
  477. entt::meta_any any{42};
  478. entt::meta_any other{std::move(any)};
  479. entt::meta_any valid = std::move(other);
  480. ASSERT_FALSE(any);
  481. ASSERT_FALSE(other);
  482. ASSERT_TRUE(valid);
  483. }
  484. TEST_F(Meta, MetaAnyNoSBOMoveInvalidate) {
  485. int value = 42;
  486. fat_type instance{&value};
  487. entt::meta_any any{instance};
  488. entt::meta_any other{std::move(any)};
  489. entt::meta_any valid = std::move(other);
  490. ASSERT_FALSE(any);
  491. ASSERT_FALSE(other);
  492. ASSERT_TRUE(valid);
  493. }
  494. TEST_F(Meta, MetaAnyVoidMoveInvalidate) {
  495. entt::meta_any any{std::in_place_type<void>};
  496. entt::meta_any other{std::move(any)};
  497. entt::meta_any valid = std::move(other);
  498. ASSERT_FALSE(any);
  499. ASSERT_FALSE(other);
  500. ASSERT_TRUE(valid);
  501. }
  502. TEST_F(Meta, MetaAnySBODestruction) {
  503. ASSERT_EQ(empty_type::counter, 0);
  504. { entt::meta_any any{empty_type{}}; }
  505. ASSERT_EQ(empty_type::counter, 1);
  506. }
  507. TEST_F(Meta, MetaAnyNoSBODestruction) {
  508. ASSERT_EQ(fat_type::counter, 0);
  509. { entt::meta_any any{fat_type{}}; }
  510. ASSERT_EQ(fat_type::counter, 1);
  511. }
  512. TEST_F(Meta, MetaAnyVoidDestruction) {
  513. // just let asan tell us if everything is ok here
  514. [[maybe_unused]] entt::meta_any any{std::in_place_type<void>};
  515. }
  516. TEST_F(Meta, MetaAnyEmplace) {
  517. entt::meta_any any{};
  518. any.emplace<int>(42);
  519. ASSERT_TRUE(any);
  520. ASSERT_FALSE(any.try_cast<std::size_t>());
  521. ASSERT_EQ(any.cast<int>(), 42);
  522. ASSERT_NE(any.data(), nullptr);
  523. ASSERT_EQ(any, (entt::meta_any{std::in_place_type<int>, 42}));
  524. ASSERT_EQ(any, entt::meta_any{42});
  525. ASSERT_NE(entt::meta_any{3}, any);
  526. }
  527. TEST_F(Meta, MetaAnyEmplaceVoid) {
  528. entt::meta_any any{};
  529. any.emplace<void>();
  530. ASSERT_TRUE(any);
  531. ASSERT_EQ(any.data(), nullptr);
  532. ASSERT_EQ(any.type(), entt::resolve<void>());
  533. ASSERT_EQ(any, (entt::meta_any{std::in_place_type<void>}));
  534. }
  535. TEST_F(Meta, MetaAnySBOSwap) {
  536. entt::meta_any lhs{'c'};
  537. entt::meta_any rhs{42};
  538. std::swap(lhs, rhs);
  539. ASSERT_FALSE(lhs.try_cast<char>());
  540. ASSERT_EQ(lhs.cast<int>(), 42);
  541. ASSERT_FALSE(rhs.try_cast<int>());
  542. ASSERT_EQ(rhs.cast<char>(), 'c');
  543. }
  544. TEST_F(Meta, MetaAnyNoSBOSwap) {
  545. int i, j;
  546. entt::meta_any lhs{fat_type{&i}};
  547. entt::meta_any rhs{fat_type{&j}};
  548. std::swap(lhs, rhs);
  549. ASSERT_EQ(lhs.cast<fat_type>().foo, &j);
  550. ASSERT_EQ(rhs.cast<fat_type>().bar, &i);
  551. }
  552. TEST_F(Meta, MetaAnyVoidSwap) {
  553. entt::meta_any lhs{std::in_place_type<void>};
  554. entt::meta_any rhs{std::in_place_type<void>};
  555. const auto *pre = lhs.data();
  556. std::swap(lhs, rhs);
  557. ASSERT_EQ(pre, lhs.data());
  558. }
  559. TEST_F(Meta, MetaAnySBOWithNoSBOSwap) {
  560. int value = 42;
  561. entt::meta_any lhs{fat_type{&value}};
  562. entt::meta_any rhs{'c'};
  563. std::swap(lhs, rhs);
  564. ASSERT_FALSE(lhs.try_cast<fat_type>());
  565. ASSERT_EQ(lhs.cast<char>(), 'c');
  566. ASSERT_FALSE(rhs.try_cast<char>());
  567. ASSERT_EQ(rhs.cast<fat_type>().foo, &value);
  568. ASSERT_EQ(rhs.cast<fat_type>().bar, &value);
  569. }
  570. TEST_F(Meta, MetaAnySBOWithEmptySwap) {
  571. entt::meta_any lhs{'c'};
  572. entt::meta_any rhs{};
  573. std::swap(lhs, rhs);
  574. ASSERT_FALSE(lhs);
  575. ASSERT_EQ(rhs.cast<char>(), 'c');
  576. std::swap(lhs, rhs);
  577. ASSERT_FALSE(rhs);
  578. ASSERT_EQ(lhs.cast<char>(), 'c');
  579. }
  580. TEST_F(Meta, MetaAnySBOWithVoidSwap) {
  581. entt::meta_any lhs{'c'};
  582. entt::meta_any rhs{std::in_place_type<void>};
  583. std::swap(lhs, rhs);
  584. ASSERT_EQ(lhs.type(), entt::resolve<void>());
  585. ASSERT_EQ(rhs.cast<char>(), 'c');
  586. }
  587. TEST_F(Meta, MetaAnyNoSBOWithEmptySwap) {
  588. int i;
  589. entt::meta_any lhs{fat_type{&i}};
  590. entt::meta_any rhs{};
  591. std::swap(lhs, rhs);
  592. ASSERT_EQ(rhs.cast<fat_type>().bar, &i);
  593. std::swap(lhs, rhs);
  594. ASSERT_EQ(lhs.cast<fat_type>().bar, &i);
  595. }
  596. TEST_F(Meta, MetaAnyNoSBOWithVoidSwap) {
  597. int i;
  598. entt::meta_any lhs{fat_type{&i}};
  599. entt::meta_any rhs{std::in_place_type<void>};
  600. std::swap(lhs, rhs);
  601. ASSERT_EQ(rhs.cast<fat_type>().bar, &i);
  602. std::swap(lhs, rhs);
  603. ASSERT_EQ(lhs.cast<fat_type>().bar, &i);
  604. }
  605. TEST_F(Meta, MetaAnyComparable) {
  606. entt::meta_any any{'c'};
  607. ASSERT_EQ(any, any);
  608. ASSERT_EQ(any, entt::meta_any{'c'});
  609. ASSERT_NE(entt::meta_any{'a'}, any);
  610. ASSERT_NE(any, entt::meta_any{});
  611. ASSERT_TRUE(any == any);
  612. ASSERT_TRUE(any == entt::meta_any{'c'});
  613. ASSERT_FALSE(entt::meta_any{'a'} == any);
  614. ASSERT_TRUE(any != entt::meta_any{'a'});
  615. ASSERT_TRUE(entt::meta_any{} != any);
  616. }
  617. TEST_F(Meta, MetaAnyNotComparable) {
  618. entt::meta_any any{not_comparable_type{}};
  619. ASSERT_EQ(any, any);
  620. ASSERT_NE(any, entt::meta_any{not_comparable_type{}});
  621. ASSERT_NE(entt::meta_any{}, any);
  622. ASSERT_TRUE(any == any);
  623. ASSERT_FALSE(any == entt::meta_any{not_comparable_type{}});
  624. ASSERT_TRUE(entt::meta_any{} != any);
  625. }
  626. TEST_F(Meta, MetaAnyCompareVoid) {
  627. entt::meta_any any{std::in_place_type<void>};
  628. ASSERT_EQ(any, any);
  629. ASSERT_EQ(any, entt::meta_any{std::in_place_type<void>});
  630. ASSERT_NE(entt::meta_any{'a'}, any);
  631. ASSERT_NE(any, entt::meta_any{});
  632. ASSERT_TRUE(any == any);
  633. ASSERT_TRUE(any == entt::meta_any{std::in_place_type<void>});
  634. ASSERT_FALSE(entt::meta_any{'a'} == any);
  635. ASSERT_TRUE(any != entt::meta_any{'a'});
  636. ASSERT_TRUE(entt::meta_any{} != any);
  637. }
  638. TEST_F(Meta, MetaAnyTryCast) {
  639. entt::meta_any any{derived_type{}};
  640. ASSERT_TRUE(any);
  641. ASSERT_EQ(any.type(), entt::resolve<derived_type>());
  642. ASSERT_EQ(any.try_cast<void>(), nullptr);
  643. ASSERT_NE(any.try_cast<base_type>(), nullptr);
  644. ASSERT_EQ(any.try_cast<derived_type>(), any.data());
  645. ASSERT_EQ(std::as_const(any).try_cast<base_type>(), any.try_cast<base_type>());
  646. ASSERT_EQ(std::as_const(any).try_cast<derived_type>(), any.data());
  647. }
  648. TEST_F(Meta, MetaAnyCast) {
  649. entt::meta_any any{derived_type{}};
  650. ASSERT_TRUE(any);
  651. ASSERT_EQ(any.type(), entt::resolve<derived_type>());
  652. ASSERT_EQ(any.try_cast<std::size_t>(), nullptr);
  653. ASSERT_NE(any.try_cast<base_type>(), nullptr);
  654. ASSERT_EQ(any.try_cast<derived_type>(), any.data());
  655. ASSERT_EQ(std::as_const(any).try_cast<base_type>(), any.try_cast<base_type>());
  656. ASSERT_EQ(std::as_const(any).try_cast<derived_type>(), any.data());
  657. }
  658. TEST_F(Meta, MetaAnyConvert) {
  659. entt::meta_any any{42.};
  660. ASSERT_TRUE(any);
  661. ASSERT_EQ(any.type(), entt::resolve<double>());
  662. ASSERT_TRUE(any.convert<double>());
  663. ASSERT_FALSE(any.convert<char>());
  664. ASSERT_EQ(any.type(), entt::resolve<double>());
  665. ASSERT_EQ(any.cast<double>(), 42.);
  666. ASSERT_TRUE(any.convert<int>());
  667. ASSERT_EQ(any.type(), entt::resolve<int>());
  668. ASSERT_EQ(any.cast<int>(), 42);
  669. }
  670. TEST_F(Meta, MetaAnyConstConvert) {
  671. const entt::meta_any any{42.};
  672. ASSERT_TRUE(any);
  673. ASSERT_EQ(any.type(), entt::resolve<double>());
  674. ASSERT_TRUE(any.convert<double>());
  675. ASSERT_FALSE(any.convert<char>());
  676. ASSERT_EQ(any.type(), entt::resolve<double>());
  677. ASSERT_EQ(any.cast<double>(), 42.);
  678. auto other = any.convert<int>();
  679. ASSERT_EQ(any.type(), entt::resolve<double>());
  680. ASSERT_EQ(any.cast<double>(), 42.);
  681. ASSERT_EQ(other.type(), entt::resolve<int>());
  682. ASSERT_EQ(other.cast<int>(), 42);
  683. }
  684. TEST_F(Meta, MetaAnyUnmanageableType) {
  685. unmanageable_type instance;
  686. entt::meta_any any{std::ref(instance)};
  687. entt::meta_any other = any;
  688. std::swap(any, other);
  689. ASSERT_TRUE(any);
  690. ASSERT_TRUE(other);
  691. ASSERT_EQ(any.type(), entt::resolve<unmanageable_type>());
  692. ASSERT_NE(any.data(), nullptr);
  693. ASSERT_EQ(any.try_cast<int>(), nullptr);
  694. ASSERT_NE(any.try_cast<unmanageable_type>(), nullptr);
  695. ASSERT_TRUE(any.convert<unmanageable_type>());
  696. ASSERT_FALSE(any.convert<int>());
  697. ASSERT_TRUE(std::as_const(any).convert<unmanageable_type>());
  698. ASSERT_FALSE(std::as_const(any).convert<int>());
  699. }
  700. TEST_F(Meta, MetaProp) {
  701. auto prop = entt::resolve<char>().prop(props::prop_int);
  702. ASSERT_TRUE(prop);
  703. ASSERT_EQ(prop.key(), props::prop_int);
  704. ASSERT_EQ(prop.value(), 42);
  705. }
  706. TEST_F(Meta, MetaBase) {
  707. auto base = entt::resolve<derived_type>().base("base"_hs);
  708. derived_type derived{};
  709. ASSERT_TRUE(base);
  710. ASSERT_EQ(base.parent(), entt::resolve("derived"_hs));
  711. ASSERT_EQ(base.type(), entt::resolve<base_type>());
  712. ASSERT_EQ(base.cast(&derived), static_cast<base_type *>(&derived));
  713. }
  714. TEST_F(Meta, MetaConv) {
  715. auto conv = entt::resolve<double>().conv<int>();
  716. double value = 3.;
  717. ASSERT_TRUE(conv);
  718. ASSERT_EQ(conv.parent(), entt::resolve<double>());
  719. ASSERT_EQ(conv.type(), entt::resolve<int>());
  720. auto any = conv.convert(&value);
  721. ASSERT_TRUE(any);
  722. ASSERT_EQ(any.type(), entt::resolve<int>());
  723. ASSERT_EQ(any.cast<int>(), 3);
  724. }
  725. TEST_F(Meta, MetaConvAsFreeFunctions) {
  726. auto conv = entt::resolve<derived_type>().conv<int>();
  727. derived_type derived{derived_type{}, 42, 'c'};
  728. ASSERT_TRUE(conv);
  729. ASSERT_EQ(conv.parent(), entt::resolve<derived_type>());
  730. ASSERT_EQ(conv.type(), entt::resolve<int>());
  731. auto any = conv.convert(&derived);
  732. ASSERT_TRUE(any);
  733. ASSERT_EQ(any.type(), entt::resolve<int>());
  734. ASSERT_EQ(any.cast<int>(), 42);
  735. }
  736. TEST_F(Meta, MetaConvAsMemberFunctions) {
  737. auto conv = entt::resolve<derived_type>().conv<char>();
  738. derived_type derived{derived_type{}, 42, 'c'};
  739. ASSERT_TRUE(conv);
  740. ASSERT_EQ(conv.parent(), entt::resolve<derived_type>());
  741. ASSERT_EQ(conv.type(), entt::resolve<char>());
  742. auto any = conv.convert(&derived);
  743. ASSERT_TRUE(any);
  744. ASSERT_EQ(any.type(), entt::resolve<char>());
  745. ASSERT_EQ(any.cast<char>(), 'c');
  746. }
  747. TEST_F(Meta, MetaCtor) {
  748. auto ctor = entt::resolve<derived_type>().ctor<const base_type &, int, char>();
  749. ASSERT_TRUE(ctor);
  750. ASSERT_EQ(ctor.parent(), entt::resolve("derived"_hs));
  751. ASSERT_EQ(ctor.size(), 3u);
  752. ASSERT_EQ(ctor.arg(0u), entt::resolve<base_type>());
  753. ASSERT_EQ(ctor.arg(1u), entt::resolve<int>());
  754. ASSERT_EQ(ctor.arg(2u), entt::resolve<char>());
  755. ASSERT_FALSE(ctor.arg(3u));
  756. auto any = ctor.invoke(base_type{}, 42, 'c');
  757. auto empty = ctor.invoke();
  758. ASSERT_FALSE(empty);
  759. ASSERT_TRUE(any);
  760. ASSERT_EQ(any.cast<derived_type>().i, 42);
  761. ASSERT_EQ(any.cast<derived_type>().c, 'c');
  762. ctor.prop([](auto prop) {
  763. ASSERT_EQ(prop.key(), props::prop_bool);
  764. ASSERT_FALSE(prop.value().template cast<bool>());
  765. });
  766. ASSERT_FALSE(ctor.prop(props::prop_int));
  767. auto prop = ctor.prop(props::prop_bool);
  768. ASSERT_TRUE(prop);
  769. ASSERT_EQ(prop.key(), props::prop_bool);
  770. ASSERT_FALSE(prop.value().template cast<bool>());
  771. }
  772. TEST_F(Meta, MetaCtorFunc) {
  773. auto ctor = entt::resolve<derived_type>().ctor<const base_type &, int>();
  774. ASSERT_TRUE(ctor);
  775. ASSERT_EQ(ctor.parent(), entt::resolve("derived"_hs));
  776. ASSERT_EQ(ctor.size(), 2u);
  777. ASSERT_EQ(ctor.arg(0u), entt::resolve<base_type>());
  778. ASSERT_EQ(ctor.arg(1u), entt::resolve<int>());
  779. ASSERT_FALSE(ctor.arg(2u));
  780. auto any = ctor.invoke(derived_type{}, 42);
  781. auto empty = ctor.invoke(3, 'c');
  782. ASSERT_FALSE(empty);
  783. ASSERT_TRUE(any);
  784. ASSERT_EQ(any.cast<derived_type>().i, 42);
  785. ASSERT_EQ(any.cast<derived_type>().c, 'c');
  786. ctor.prop([](auto prop) {
  787. ASSERT_EQ(prop.key(), props::prop_int);
  788. ASSERT_EQ(prop.value(), 42);
  789. });
  790. ASSERT_FALSE(ctor.prop(props::prop_bool));
  791. auto prop = ctor.prop(props::prop_int);
  792. ASSERT_TRUE(prop);
  793. ASSERT_EQ(prop.key(), props::prop_int);
  794. ASSERT_EQ(prop.value(), 42);
  795. }
  796. TEST_F(Meta, MetaCtorMetaAnyArgs) {
  797. auto any = entt::resolve<derived_type>().ctor<const base_type &, int, char>().invoke(base_type{}, 42, 'c');
  798. ASSERT_TRUE(any);
  799. ASSERT_EQ(any.cast<derived_type>().i, 42);
  800. ASSERT_EQ(any.cast<derived_type>().c, 'c');
  801. }
  802. TEST_F(Meta, MetaCtorInvalidArgs) {
  803. auto ctor = entt::resolve<derived_type>().ctor<const base_type &, int, char>();
  804. ASSERT_FALSE(ctor.invoke(base_type{}, 'c', 42));
  805. }
  806. TEST_F(Meta, MetaCtorCastAndConvert) {
  807. auto any = entt::resolve<derived_type>().ctor<const base_type &, int, char>().invoke(derived_type{}, 42., 'c');
  808. ASSERT_TRUE(any);
  809. ASSERT_EQ(any.cast<derived_type>().i, 42);
  810. ASSERT_EQ(any.cast<derived_type>().c, 'c');
  811. }
  812. TEST_F(Meta, MetaCtorFuncMetaAnyArgs) {
  813. auto any = entt::resolve<derived_type>().ctor<const base_type &, int>().invoke(base_type{}, 42);
  814. ASSERT_TRUE(any);
  815. ASSERT_EQ(any.cast<derived_type>().i, 42);
  816. ASSERT_EQ(any.cast<derived_type>().c, 'c');
  817. }
  818. TEST_F(Meta, MetaCtorFuncInvalidArgs) {
  819. auto ctor = entt::resolve<derived_type>().ctor<const base_type &, int>();
  820. ASSERT_FALSE(ctor.invoke(base_type{}, 'c'));
  821. }
  822. TEST_F(Meta, MetaCtorFuncCastAndConvert) {
  823. auto any = entt::resolve<derived_type>().ctor<const base_type &, int>().invoke(derived_type{}, 42.);
  824. ASSERT_TRUE(any);
  825. ASSERT_EQ(any.cast<derived_type>().i, 42);
  826. ASSERT_EQ(any.cast<derived_type>().c, 'c');
  827. }
  828. TEST_F(Meta, MetaData) {
  829. auto data = entt::resolve<data_type>().data("i"_hs);
  830. data_type instance{};
  831. ASSERT_TRUE(data);
  832. ASSERT_EQ(data.parent(), entt::resolve("data"_hs));
  833. ASSERT_EQ(data.type(), entt::resolve<int>());
  834. ASSERT_EQ(data.alias(), "i"_hs);
  835. ASSERT_FALSE(data.is_const());
  836. ASSERT_FALSE(data.is_static());
  837. ASSERT_EQ(data.get(instance).cast<int>(), 0);
  838. ASSERT_TRUE(data.set(instance, 42));
  839. ASSERT_EQ(data.get(instance).cast<int>(), 42);
  840. data.prop([](auto prop) {
  841. ASSERT_EQ(prop.key(), props::prop_int);
  842. ASSERT_EQ(prop.value(), 0);
  843. });
  844. ASSERT_FALSE(data.prop(props::prop_bool));
  845. auto prop = data.prop(props::prop_int);
  846. ASSERT_TRUE(prop);
  847. ASSERT_EQ(prop.key(), props::prop_int);
  848. ASSERT_EQ(prop.value(), 0);
  849. }
  850. TEST_F(Meta, MetaDataConst) {
  851. auto data = entt::resolve<data_type>().data("j"_hs);
  852. data_type instance{};
  853. ASSERT_TRUE(data);
  854. ASSERT_EQ(data.parent(), entt::resolve("data"_hs));
  855. ASSERT_EQ(data.type(), entt::resolve<int>());
  856. ASSERT_EQ(data.alias(), "j"_hs);
  857. ASSERT_TRUE(data.is_const());
  858. ASSERT_FALSE(data.is_static());
  859. ASSERT_EQ(data.get(instance).cast<int>(), 1);
  860. ASSERT_FALSE(data.set(instance, 42));
  861. ASSERT_EQ(data.get(instance).cast<int>(), 1);
  862. data.prop([](auto prop) {
  863. ASSERT_EQ(prop.key(), props::prop_int);
  864. ASSERT_EQ(prop.value(), 1);
  865. });
  866. ASSERT_FALSE(data.prop(props::prop_bool));
  867. auto prop = data.prop(props::prop_int);
  868. ASSERT_TRUE(prop);
  869. ASSERT_EQ(prop.key(), props::prop_int);
  870. ASSERT_EQ(prop.value(), 1);
  871. }
  872. TEST_F(Meta, MetaDataStatic) {
  873. auto data = entt::resolve<data_type>().data("h"_hs);
  874. ASSERT_TRUE(data);
  875. ASSERT_EQ(data.parent(), entt::resolve("data"_hs));
  876. ASSERT_EQ(data.type(), entt::resolve<int>());
  877. ASSERT_EQ(data.alias(), "h"_hs);
  878. ASSERT_FALSE(data.is_const());
  879. ASSERT_TRUE(data.is_static());
  880. ASSERT_EQ(data.get({}).cast<int>(), 2);
  881. ASSERT_TRUE(data.set({}, 42));
  882. ASSERT_EQ(data.get({}).cast<int>(), 42);
  883. data.prop([](auto prop) {
  884. ASSERT_EQ(prop.key(), props::prop_int);
  885. ASSERT_EQ(prop.value(), 2);
  886. });
  887. ASSERT_FALSE(data.prop(props::prop_bool));
  888. auto prop = data.prop(props::prop_int);
  889. ASSERT_TRUE(prop);
  890. ASSERT_EQ(prop.key(), props::prop_int);
  891. ASSERT_EQ(prop.value(), 2);
  892. }
  893. TEST_F(Meta, MetaDataConstStatic) {
  894. auto data = entt::resolve<data_type>().data("k"_hs);
  895. ASSERT_TRUE(data);
  896. ASSERT_EQ(data.parent(), entt::resolve("data"_hs));
  897. ASSERT_EQ(data.type(), entt::resolve<int>());
  898. ASSERT_EQ(data.alias(), "k"_hs);
  899. ASSERT_TRUE(data.is_const());
  900. ASSERT_TRUE(data.is_static());
  901. ASSERT_EQ(data.get({}).cast<int>(), 3);
  902. ASSERT_FALSE(data.set({}, 42));
  903. ASSERT_EQ(data.get({}).cast<int>(), 3);
  904. data.prop([](auto prop) {
  905. ASSERT_EQ(prop.key(), props::prop_int);
  906. ASSERT_EQ(prop.value(), 3);
  907. });
  908. ASSERT_FALSE(data.prop(props::prop_bool));
  909. auto prop = data.prop(props::prop_int);
  910. ASSERT_TRUE(prop);
  911. ASSERT_EQ(prop.key(), props::prop_int);
  912. ASSERT_EQ(prop.value(), 3);
  913. }
  914. TEST_F(Meta, MetaDataGetMetaAnyArg) {
  915. entt::meta_any any{data_type{}};
  916. any.cast<data_type>().i = 99;
  917. const auto value = entt::resolve<data_type>().data("i"_hs).get(any);
  918. ASSERT_TRUE(value);
  919. ASSERT_TRUE(value.cast<int>());
  920. ASSERT_EQ(value.cast<int>(), 99);
  921. }
  922. TEST_F(Meta, MetaDataGetInvalidArg) {
  923. auto instance = 0;
  924. ASSERT_FALSE(entt::resolve<data_type>().data("i"_hs).get(instance));
  925. }
  926. TEST_F(Meta, MetaDataSetMetaAnyArg) {
  927. entt::meta_any any{data_type{}};
  928. entt::meta_any value{42};
  929. ASSERT_EQ(any.cast<data_type>().i, 0);
  930. ASSERT_TRUE(entt::resolve<data_type>().data("i"_hs).set(any, value));
  931. ASSERT_EQ(any.cast<data_type>().i, 42);
  932. }
  933. TEST_F(Meta, MetaDataSetInvalidArg) {
  934. ASSERT_FALSE(entt::resolve<data_type>().data("i"_hs).set({}, 'c'));
  935. }
  936. TEST_F(Meta, MetaDataSetCast) {
  937. data_type instance{};
  938. ASSERT_EQ(empty_type::counter, 0);
  939. ASSERT_TRUE(entt::resolve<data_type>().data("empty"_hs).set(instance, fat_type{}));
  940. ASSERT_EQ(empty_type::counter, 1);
  941. }
  942. TEST_F(Meta, MetaDataSetConvert) {
  943. data_type instance{};
  944. ASSERT_EQ(instance.i, 0);
  945. ASSERT_TRUE(entt::resolve<data_type>().data("i"_hs).set(instance, 3.));
  946. ASSERT_EQ(instance.i, 3);
  947. }
  948. TEST_F(Meta, MetaDataSetterGetterAsFreeFunctions) {
  949. auto data = entt::resolve<setter_getter_type>().data("x"_hs);
  950. setter_getter_type instance{};
  951. ASSERT_TRUE(data);
  952. ASSERT_EQ(data.parent(), entt::resolve("setter_getter"_hs));
  953. ASSERT_EQ(data.type(), entt::resolve<int>());
  954. ASSERT_EQ(data.alias(), "x"_hs);
  955. ASSERT_FALSE(data.is_const());
  956. ASSERT_FALSE(data.is_static());
  957. ASSERT_EQ(data.get(instance).cast<int>(), 0);
  958. ASSERT_TRUE(data.set(instance, 42));
  959. ASSERT_EQ(data.get(instance).cast<int>(), 42);
  960. }
  961. TEST_F(Meta, MetaDataSetterGetterAsMemberFunctions) {
  962. auto data = entt::resolve<setter_getter_type>().data("y"_hs);
  963. setter_getter_type instance{};
  964. ASSERT_TRUE(data);
  965. ASSERT_EQ(data.parent(), entt::resolve("setter_getter"_hs));
  966. ASSERT_EQ(data.type(), entt::resolve<int>());
  967. ASSERT_EQ(data.alias(), "y"_hs);
  968. ASSERT_FALSE(data.is_const());
  969. ASSERT_FALSE(data.is_static());
  970. ASSERT_EQ(data.get(instance).cast<int>(), 0);
  971. ASSERT_TRUE(data.set(instance, 42));
  972. ASSERT_EQ(data.get(instance).cast<int>(), 42);
  973. }
  974. TEST_F(Meta, MetaDataSetterGetterWithRefAsMemberFunctions) {
  975. auto data = entt::resolve<setter_getter_type>().data("w"_hs);
  976. setter_getter_type instance{};
  977. ASSERT_TRUE(data);
  978. ASSERT_EQ(data.parent(), entt::resolve("setter_getter"_hs));
  979. ASSERT_EQ(data.type(), entt::resolve<int>());
  980. ASSERT_EQ(data.alias(), "w"_hs);
  981. ASSERT_FALSE(data.is_const());
  982. ASSERT_FALSE(data.is_static());
  983. ASSERT_EQ(data.get(instance).cast<int>(), 0);
  984. ASSERT_TRUE(data.set(instance, 42));
  985. ASSERT_EQ(data.get(instance).cast<int>(), 42);
  986. }
  987. TEST_F(Meta, MetaDataSetterGetterMixed) {
  988. auto data = entt::resolve<setter_getter_type>().data("z"_hs);
  989. setter_getter_type instance{};
  990. ASSERT_TRUE(data);
  991. ASSERT_EQ(data.parent(), entt::resolve("setter_getter"_hs));
  992. ASSERT_EQ(data.type(), entt::resolve<int>());
  993. ASSERT_EQ(data.alias(), "z"_hs);
  994. ASSERT_FALSE(data.is_const());
  995. ASSERT_FALSE(data.is_static());
  996. ASSERT_EQ(data.get(instance).cast<int>(), 0);
  997. ASSERT_TRUE(data.set(instance, 42));
  998. ASSERT_EQ(data.get(instance).cast<int>(), 42);
  999. }
  1000. TEST_F(Meta, MetaDataArrayStatic) {
  1001. auto data = entt::resolve<array_type>().data("global"_hs);
  1002. array_type::global[0] = 3;
  1003. array_type::global[1] = 5;
  1004. array_type::global[2] = 7;
  1005. ASSERT_TRUE(data);
  1006. ASSERT_EQ(data.parent(), entt::resolve("array"_hs));
  1007. ASSERT_EQ(data.type(), entt::resolve<int[3]>());
  1008. ASSERT_EQ(data.alias(), "global"_hs);
  1009. ASSERT_FALSE(data.is_const());
  1010. ASSERT_TRUE(data.is_static());
  1011. ASSERT_TRUE(data.type().is_array());
  1012. ASSERT_EQ(data.type().extent(), 3);
  1013. ASSERT_EQ(data.get({}, 0).cast<int>(), 3);
  1014. ASSERT_EQ(data.get({}, 1).cast<int>(), 5);
  1015. ASSERT_EQ(data.get({}, 2).cast<int>(), 7);
  1016. ASSERT_FALSE(data.set({}, 0, 'c'));
  1017. ASSERT_EQ(data.get({}, 0).cast<int>(), 3);
  1018. ASSERT_TRUE(data.set({}, 0, data.get({}, 0).cast<int>()+2));
  1019. ASSERT_TRUE(data.set({}, 1, data.get({}, 1).cast<int>()+2));
  1020. ASSERT_TRUE(data.set({}, 2, data.get({}, 2).cast<int>()+2));
  1021. ASSERT_EQ(data.get({}, 0).cast<int>(), 5);
  1022. ASSERT_EQ(data.get({}, 1).cast<int>(), 7);
  1023. ASSERT_EQ(data.get({}, 2).cast<int>(), 9);
  1024. }
  1025. TEST_F(Meta, MetaDataArray) {
  1026. auto data = entt::resolve<array_type>().data("local"_hs);
  1027. array_type instance;
  1028. instance.local[0] = 3;
  1029. instance.local[1] = 5;
  1030. instance.local[2] = 7;
  1031. ASSERT_TRUE(data);
  1032. ASSERT_EQ(data.parent(), entt::resolve("array"_hs));
  1033. ASSERT_EQ(data.type(), entt::resolve<int[3]>());
  1034. ASSERT_EQ(data.alias(), "local"_hs);
  1035. ASSERT_FALSE(data.is_const());
  1036. ASSERT_FALSE(data.is_static());
  1037. ASSERT_TRUE(data.type().is_array());
  1038. ASSERT_EQ(data.type().extent(), 3);
  1039. ASSERT_EQ(data.get(instance, 0).cast<int>(), 3);
  1040. ASSERT_EQ(data.get(instance, 1).cast<int>(), 5);
  1041. ASSERT_EQ(data.get(instance, 2).cast<int>(), 7);
  1042. ASSERT_FALSE(data.set(instance, 0, 'c'));
  1043. ASSERT_EQ(data.get(instance, 0).cast<int>(), 3);
  1044. ASSERT_TRUE(data.set(instance, 0, data.get(instance, 0).cast<int>()+2));
  1045. ASSERT_TRUE(data.set(instance, 1, data.get(instance, 1).cast<int>()+2));
  1046. ASSERT_TRUE(data.set(instance, 2, data.get(instance, 2).cast<int>()+2));
  1047. ASSERT_EQ(data.get(instance, 0).cast<int>(), 5);
  1048. ASSERT_EQ(data.get(instance, 1).cast<int>(), 7);
  1049. ASSERT_EQ(data.get(instance, 2).cast<int>(), 9);
  1050. }
  1051. TEST_F(Meta, MetaDataAsVoid) {
  1052. auto data = entt::resolve<data_type>().data("v"_hs);
  1053. data_type instance{};
  1054. ASSERT_TRUE(data.set(instance, 42));
  1055. ASSERT_EQ(instance.v, 42);
  1056. ASSERT_EQ(data.get(instance), entt::meta_any{std::in_place_type<void>});
  1057. }
  1058. TEST_F(Meta, MetaDataAsAlias) {
  1059. data_type instance{};
  1060. auto h_data = entt::resolve<data_type>().data("h"_hs);
  1061. auto i_data = entt::resolve<data_type>().data("i"_hs);
  1062. h_data.get(instance).cast<int>() = 3;
  1063. i_data.get(instance).cast<int>() = 3;
  1064. ASSERT_EQ(h_data.type(), entt::resolve<int>());
  1065. ASSERT_EQ(i_data.type(), entt::resolve<int>());
  1066. ASSERT_NE(instance.h, 3);
  1067. ASSERT_EQ(instance.i, 3);
  1068. }
  1069. TEST_F(Meta, MetaFunc) {
  1070. auto func = entt::resolve<func_type>().func("f2"_hs);
  1071. func_type instance{};
  1072. ASSERT_TRUE(func);
  1073. ASSERT_EQ(func.parent(), entt::resolve("func"_hs));
  1074. ASSERT_EQ(func.alias(), "f2"_hs);
  1075. ASSERT_EQ(func.size(), 2u);
  1076. ASSERT_FALSE(func.is_const());
  1077. ASSERT_FALSE(func.is_static());
  1078. ASSERT_EQ(func.ret(), entt::resolve<int>());
  1079. ASSERT_EQ(func.arg(0u), entt::resolve<int>());
  1080. ASSERT_EQ(func.arg(1u), entt::resolve<int>());
  1081. ASSERT_FALSE(func.arg(2u));
  1082. auto any = func.invoke(instance, 3, 2);
  1083. auto empty = func.invoke(instance);
  1084. ASSERT_FALSE(empty);
  1085. ASSERT_TRUE(any);
  1086. ASSERT_EQ(any.type(), entt::resolve<int>());
  1087. ASSERT_EQ(any.cast<int>(), 4);
  1088. ASSERT_EQ(func_type::value, 3);
  1089. func.prop([](auto prop) {
  1090. ASSERT_EQ(prop.key(), props::prop_bool);
  1091. ASSERT_FALSE(prop.value().template cast<bool>());
  1092. });
  1093. ASSERT_FALSE(func.prop(props::prop_int));
  1094. auto prop = func.prop(props::prop_bool);
  1095. ASSERT_TRUE(prop);
  1096. ASSERT_EQ(prop.key(), props::prop_bool);
  1097. ASSERT_FALSE(prop.value().cast<bool>());
  1098. }
  1099. TEST_F(Meta, MetaFuncConst) {
  1100. auto func = entt::resolve<func_type>().func("f1"_hs);
  1101. func_type instance{};
  1102. ASSERT_TRUE(func);
  1103. ASSERT_EQ(func.parent(), entt::resolve("func"_hs));
  1104. ASSERT_EQ(func.alias(), "f1"_hs);
  1105. ASSERT_EQ(func.size(), 1u);
  1106. ASSERT_TRUE(func.is_const());
  1107. ASSERT_FALSE(func.is_static());
  1108. ASSERT_EQ(func.ret(), entt::resolve<int>());
  1109. ASSERT_EQ(func.arg(0u), entt::resolve<int>());
  1110. ASSERT_FALSE(func.arg(1u));
  1111. auto any = func.invoke(instance, 4);
  1112. auto empty = func.invoke(instance, 'c');
  1113. ASSERT_FALSE(empty);
  1114. ASSERT_TRUE(any);
  1115. ASSERT_EQ(any.type(), entt::resolve<int>());
  1116. ASSERT_EQ(any.cast<int>(), 16);
  1117. func.prop([](auto prop) {
  1118. ASSERT_EQ(prop.key(), props::prop_bool);
  1119. ASSERT_FALSE(prop.value().template cast<bool>());
  1120. });
  1121. ASSERT_FALSE(func.prop(props::prop_int));
  1122. auto prop = func.prop(props::prop_bool);
  1123. ASSERT_TRUE(prop);
  1124. ASSERT_EQ(prop.key(), props::prop_bool);
  1125. ASSERT_FALSE(prop.value().cast<bool>());
  1126. }
  1127. TEST_F(Meta, MetaFuncRetVoid) {
  1128. auto func = entt::resolve<func_type>().func("g"_hs);
  1129. func_type instance{};
  1130. ASSERT_TRUE(func);
  1131. ASSERT_EQ(func.parent(), entt::resolve("func"_hs));
  1132. ASSERT_EQ(func.alias(), "g"_hs);
  1133. ASSERT_EQ(func.size(), 1u);
  1134. ASSERT_FALSE(func.is_const());
  1135. ASSERT_FALSE(func.is_static());
  1136. ASSERT_EQ(func.ret(), entt::resolve<void>());
  1137. ASSERT_EQ(func.arg(0u), entt::resolve<int>());
  1138. ASSERT_FALSE(func.arg(1u));
  1139. auto any = func.invoke(instance, 5);
  1140. ASSERT_TRUE(any);
  1141. ASSERT_EQ(any.type(), entt::resolve<void>());
  1142. ASSERT_EQ(func_type::value, 25);
  1143. func.prop([](auto prop) {
  1144. ASSERT_EQ(prop.key(), props::prop_bool);
  1145. ASSERT_FALSE(prop.value().template cast<bool>());
  1146. });
  1147. ASSERT_FALSE(func.prop(props::prop_int));
  1148. auto prop = func.prop(props::prop_bool);
  1149. ASSERT_TRUE(prop);
  1150. ASSERT_EQ(prop.key(), props::prop_bool);
  1151. ASSERT_FALSE(prop.value().cast<bool>());
  1152. }
  1153. TEST_F(Meta, MetaFuncStatic) {
  1154. auto func = entt::resolve<func_type>().func("h"_hs);
  1155. func_type::value = 2;
  1156. ASSERT_TRUE(func);
  1157. ASSERT_EQ(func.parent(), entt::resolve("func"_hs));
  1158. ASSERT_EQ(func.alias(), "h"_hs);
  1159. ASSERT_EQ(func.size(), 1u);
  1160. ASSERT_FALSE(func.is_const());
  1161. ASSERT_TRUE(func.is_static());
  1162. ASSERT_EQ(func.ret(), entt::resolve<int>());
  1163. ASSERT_EQ(func.arg(0u), entt::resolve<int>());
  1164. ASSERT_FALSE(func.arg(1u));
  1165. auto any = func.invoke({}, 3);
  1166. auto empty = func.invoke({}, 'c');
  1167. ASSERT_FALSE(empty);
  1168. ASSERT_TRUE(any);
  1169. ASSERT_EQ(any.type(), entt::resolve<int>());
  1170. ASSERT_EQ(any.cast<int>(), 6);
  1171. func.prop([](auto prop) {
  1172. ASSERT_EQ(prop.key(), props::prop_bool);
  1173. ASSERT_FALSE(prop.value().template cast<bool>());
  1174. });
  1175. ASSERT_FALSE(func.prop(props::prop_int));
  1176. auto prop = func.prop(props::prop_bool);
  1177. ASSERT_TRUE(prop);
  1178. ASSERT_EQ(prop.key(), props::prop_bool);
  1179. ASSERT_FALSE(prop.value().cast<bool>());
  1180. }
  1181. TEST_F(Meta, MetaFuncStaticRetVoid) {
  1182. auto func = entt::resolve<func_type>().func("k"_hs);
  1183. ASSERT_TRUE(func);
  1184. ASSERT_EQ(func.parent(), entt::resolve("func"_hs));
  1185. ASSERT_EQ(func.alias(), "k"_hs);
  1186. ASSERT_EQ(func.size(), 1u);
  1187. ASSERT_FALSE(func.is_const());
  1188. ASSERT_TRUE(func.is_static());
  1189. ASSERT_EQ(func.ret(), entt::resolve<void>());
  1190. ASSERT_EQ(func.arg(0u), entt::resolve<int>());
  1191. ASSERT_FALSE(func.arg(1u));
  1192. auto any = func.invoke({}, 42);
  1193. ASSERT_TRUE(any);
  1194. ASSERT_EQ(any.type(), entt::resolve<void>());
  1195. ASSERT_EQ(func_type::value, 42);
  1196. func.prop([](auto *prop) {
  1197. ASSERT_TRUE(prop);
  1198. ASSERT_EQ(prop->key(), props::prop_bool);
  1199. ASSERT_FALSE(prop->value().template cast<bool>());
  1200. });
  1201. ASSERT_FALSE(func.prop(props::prop_int));
  1202. auto prop = func.prop(props::prop_bool);
  1203. ASSERT_TRUE(prop);
  1204. ASSERT_EQ(prop.key(), props::prop_bool);
  1205. ASSERT_FALSE(prop.value().cast<bool>());
  1206. }
  1207. TEST_F(Meta, MetaFuncMetaAnyArgs) {
  1208. func_type instance;
  1209. auto any = entt::resolve<func_type>().func("f1"_hs).invoke(instance, 3);
  1210. ASSERT_TRUE(any);
  1211. ASSERT_EQ(any.type(), entt::resolve<int>());
  1212. ASSERT_EQ(any.cast<int>(), 9);
  1213. }
  1214. TEST_F(Meta, MetaFuncInvalidArgs) {
  1215. empty_type instance;
  1216. ASSERT_FALSE(entt::resolve<func_type>().func("f1"_hs).invoke(instance, 'c'));
  1217. }
  1218. TEST_F(Meta, MetaFuncCastAndConvert) {
  1219. func_type instance;
  1220. auto any = entt::resolve<func_type>().func("f3"_hs).invoke(instance, derived_type{}, 0, 3.);
  1221. ASSERT_TRUE(any);
  1222. ASSERT_EQ(any.type(), entt::resolve<int>());
  1223. ASSERT_EQ(any.cast<int>(), 9);
  1224. }
  1225. TEST_F(Meta, MetaFuncAsVoid) {
  1226. auto func = entt::resolve<func_type>().func("v"_hs);
  1227. func_type instance{};
  1228. ASSERT_EQ(func.invoke(instance, 42), entt::meta_any{std::in_place_type<void>});
  1229. ASSERT_EQ(func.ret(), entt::resolve<void>());
  1230. ASSERT_EQ(instance.value, 42);
  1231. }
  1232. TEST_F(Meta, MetaFuncAsAlias) {
  1233. func_type instance{};
  1234. auto func = entt::resolve<func_type>().func("a"_hs);
  1235. func.invoke(instance).cast<int>() = 3;
  1236. ASSERT_EQ(func.ret(), entt::resolve<int>());
  1237. ASSERT_EQ(instance.value, 3);
  1238. }
  1239. TEST_F(Meta, MetaFuncByReference) {
  1240. auto func = entt::resolve<func_type>().func("h"_hs);
  1241. func_type::value = 2;
  1242. entt::meta_any any{3};
  1243. int value = 4;
  1244. ASSERT_EQ(func.invoke({}, std::ref(value)).cast<int>(), 8);
  1245. ASSERT_EQ(func.invoke({}, *any).cast<int>(), 6);
  1246. ASSERT_EQ(any.cast<int>(), 6);
  1247. ASSERT_EQ(value, 8);
  1248. }
  1249. TEST_F(Meta, MetaType) {
  1250. auto type = entt::resolve<derived_type>();
  1251. ASSERT_TRUE(type);
  1252. ASSERT_NE(type, entt::meta_type{});
  1253. ASSERT_EQ(type.alias(), "derived"_hs);
  1254. ASSERT_EQ(type.type_id(), entt::type_info<derived_type>::id());
  1255. type.prop([](auto prop) {
  1256. ASSERT_EQ(prop.key(), props::prop_int);
  1257. ASSERT_EQ(prop.value(), 99);
  1258. });
  1259. ASSERT_FALSE(type.prop(props::prop_bool));
  1260. auto prop = type.prop(props::prop_int);
  1261. ASSERT_TRUE(prop);
  1262. ASSERT_EQ(prop.key(), props::prop_int);
  1263. ASSERT_EQ(prop.value(), 99);
  1264. }
  1265. TEST_F(Meta, MetaTypeTraits) {
  1266. ASSERT_TRUE(entt::resolve<void>().is_void());
  1267. ASSERT_TRUE(entt::resolve<bool>().is_integral());
  1268. ASSERT_TRUE(entt::resolve<double>().is_floating_point());
  1269. ASSERT_TRUE(entt::resolve<props>().is_enum());
  1270. ASSERT_TRUE(entt::resolve<union_type>().is_union());
  1271. ASSERT_TRUE(entt::resolve<derived_type>().is_class());
  1272. ASSERT_TRUE(entt::resolve<int *>().is_pointer());
  1273. ASSERT_TRUE(entt::resolve<decltype(&empty_type::destroy)>().is_function_pointer());
  1274. ASSERT_TRUE(entt::resolve<decltype(&data_type::i)>().is_member_object_pointer());
  1275. ASSERT_TRUE(entt::resolve<decltype(&func_type::g)>().is_member_function_pointer());
  1276. }
  1277. TEST_F(Meta, MetaTypeRemovePointer) {
  1278. ASSERT_EQ(entt::resolve<void *>().remove_pointer(), entt::resolve<void>());
  1279. ASSERT_EQ(entt::resolve<int(*)(char, double)>().remove_pointer(), entt::resolve<int(char, double)>());
  1280. ASSERT_EQ(entt::resolve<derived_type>().remove_pointer(), entt::resolve<derived_type>());
  1281. }
  1282. TEST_F(Meta, MetaTypeRemoveExtent) {
  1283. ASSERT_EQ(entt::resolve<int[3]>().remove_extent(), entt::resolve<int>());
  1284. ASSERT_EQ(entt::resolve<int[3][3]>().remove_extent(), entt::resolve<int[3]>());
  1285. ASSERT_EQ(entt::resolve<derived_type>().remove_extent(), entt::resolve<derived_type>());
  1286. }
  1287. TEST_F(Meta, MetaTypeBase) {
  1288. auto type = entt::resolve<derived_type>();
  1289. bool iterate = false;
  1290. type.base([&iterate](auto base) {
  1291. ASSERT_EQ(base.type(), entt::resolve<base_type>());
  1292. iterate = true;
  1293. });
  1294. ASSERT_TRUE(iterate);
  1295. ASSERT_EQ(type.base("base"_hs).type(), entt::resolve<base_type>());
  1296. }
  1297. TEST_F(Meta, MetaTypeConv) {
  1298. auto type = entt::resolve<double>();
  1299. bool iterate = false;
  1300. type.conv([&iterate](auto conv) {
  1301. ASSERT_EQ(conv.type(), entt::resolve<int>());
  1302. iterate = true;
  1303. });
  1304. ASSERT_TRUE(iterate);
  1305. auto conv = type.conv<int>();
  1306. ASSERT_EQ(conv.type(), entt::resolve<int>());
  1307. ASSERT_FALSE(type.conv<char>());
  1308. }
  1309. TEST_F(Meta, MetaTypeCtor) {
  1310. auto type = entt::resolve<derived_type>();
  1311. int counter{};
  1312. type.ctor([&counter](auto) {
  1313. ++counter;
  1314. });
  1315. ASSERT_EQ(counter, 2);
  1316. ASSERT_TRUE((type.ctor<const base_type &, int>()));
  1317. ASSERT_TRUE((type.ctor<const derived_type &, double>()));
  1318. }
  1319. TEST_F(Meta, MetaTypeData) {
  1320. auto type = entt::resolve<data_type>();
  1321. int counter{};
  1322. type.data([&counter](auto) {
  1323. ++counter;
  1324. });
  1325. ASSERT_EQ(counter, 6);
  1326. ASSERT_TRUE(type.data("i"_hs));
  1327. }
  1328. TEST_F(Meta, MetaTypeFunc) {
  1329. auto type = entt::resolve<func_type>();
  1330. int counter{};
  1331. type.func([&counter](auto) {
  1332. ++counter;
  1333. });
  1334. ASSERT_EQ(counter, 8);
  1335. ASSERT_TRUE(type.func("f1"_hs));
  1336. }
  1337. TEST_F(Meta, MetaTypeConstruct) {
  1338. auto any = entt::resolve<derived_type>().construct(base_type{}, 42, 'c');
  1339. ASSERT_TRUE(any);
  1340. ASSERT_EQ(any.cast<derived_type>().i, 42);
  1341. ASSERT_EQ(any.cast<derived_type>().c, 'c');
  1342. }
  1343. TEST_F(Meta, MetaTypeConstructNoArgs) {
  1344. // this should work, no other tests required
  1345. auto any = entt::resolve<empty_type>().construct();
  1346. ASSERT_TRUE(any);
  1347. }
  1348. TEST_F(Meta, MetaTypeConstructMetaAnyArgs) {
  1349. auto any = entt::resolve<derived_type>().construct(base_type{}, 42, 'c');
  1350. ASSERT_TRUE(any);
  1351. ASSERT_EQ(any.cast<derived_type>().i, 42);
  1352. ASSERT_EQ(any.cast<derived_type>().c, 'c');
  1353. }
  1354. TEST_F(Meta, MetaTypeConstructInvalidArgs) {
  1355. ASSERT_FALSE(entt::resolve<derived_type>().construct(base_type{}, 'c', 42));
  1356. }
  1357. TEST_F(Meta, MetaTypeLessArgs) {
  1358. ASSERT_FALSE(entt::resolve<derived_type>().construct(base_type{}));
  1359. }
  1360. TEST_F(Meta, MetaTypeConstructCastAndConvert) {
  1361. auto any = entt::resolve<derived_type>().construct(derived_type{}, 42., 'c');
  1362. ASSERT_TRUE(any);
  1363. ASSERT_EQ(any.cast<derived_type>().i, 42);
  1364. ASSERT_EQ(any.cast<derived_type>().c, 'c');
  1365. }
  1366. TEST_F(Meta, MetaTypeDetach) {
  1367. ASSERT_TRUE(entt::resolve("char"_hs));
  1368. entt::resolve([](auto type) {
  1369. if(type.alias() == "char"_hs) {
  1370. type.detach();
  1371. }
  1372. });
  1373. ASSERT_FALSE(entt::resolve("char"_hs));
  1374. ASSERT_EQ(entt::resolve<char>().alias(), "char"_hs);
  1375. ASSERT_EQ(entt::resolve<char>().prop(props::prop_int).value().cast<int>(), 42);
  1376. ASSERT_TRUE(entt::resolve<char>().data("value"_hs));
  1377. entt::meta_factory<char>().alias("char"_hs);
  1378. ASSERT_TRUE(entt::resolve("char"_hs));
  1379. }
  1380. TEST_F(Meta, MetaDataFromBase) {
  1381. auto type = entt::resolve<concrete_type>();
  1382. concrete_type instance;
  1383. ASSERT_TRUE(type.data("i"_hs));
  1384. ASSERT_TRUE(type.data("j"_hs));
  1385. ASSERT_EQ(instance.i, 0);
  1386. ASSERT_EQ(instance.j, char{});
  1387. ASSERT_TRUE(type.data("i"_hs).set(instance, 3));
  1388. ASSERT_TRUE(type.data("j"_hs).set(instance, 'c'));
  1389. ASSERT_EQ(instance.i, 3);
  1390. ASSERT_EQ(instance.j, 'c');
  1391. }
  1392. TEST_F(Meta, MetaFuncFromBase) {
  1393. auto type = entt::resolve<concrete_type>();
  1394. auto base = entt::resolve<an_abstract_type>();
  1395. concrete_type instance;
  1396. ASSERT_TRUE(type.func("f"_hs));
  1397. ASSERT_TRUE(type.func("g"_hs));
  1398. ASSERT_TRUE(type.func("h"_hs));
  1399. ASSERT_EQ(type.func("f"_hs).parent(), entt::resolve<concrete_type>());
  1400. ASSERT_EQ(type.func("g"_hs).parent(), entt::resolve<an_abstract_type>());
  1401. ASSERT_EQ(type.func("h"_hs).parent(), entt::resolve<another_abstract_type>());
  1402. ASSERT_EQ(instance.i, 0);
  1403. ASSERT_EQ(instance.j, char{});
  1404. type.func("f"_hs).invoke(instance, 3);
  1405. type.func("h"_hs).invoke(instance, 'c');
  1406. ASSERT_EQ(instance.i, 9);
  1407. ASSERT_EQ(instance.j, 'c');
  1408. base.func("g"_hs).invoke(instance, 3);
  1409. ASSERT_EQ(instance.i, -3);
  1410. }
  1411. TEST_F(Meta, MetaPropFromBase) {
  1412. auto type = entt::resolve<concrete_type>();
  1413. auto prop_bool = type.prop(props::prop_bool);
  1414. auto prop_int = type.prop(props::prop_int);
  1415. ASSERT_TRUE(prop_bool);
  1416. ASSERT_TRUE(prop_int);
  1417. ASSERT_FALSE(prop_bool.value().cast<bool>());
  1418. ASSERT_EQ(prop_int.value().cast<int>(), 42);
  1419. }
  1420. TEST_F(Meta, AbstractClass) {
  1421. auto type = entt::resolve<an_abstract_type>();
  1422. concrete_type instance;
  1423. ASSERT_EQ(type.type_id(), entt::type_info<an_abstract_type>::id());
  1424. ASSERT_EQ(instance.i, 0);
  1425. type.func("f"_hs).invoke(instance, 3);
  1426. ASSERT_EQ(instance.i, 3);
  1427. type.func("g"_hs).invoke(instance, 3);
  1428. ASSERT_EQ(instance.i, -3);
  1429. }
  1430. TEST_F(Meta, EnumAndNamedConstants) {
  1431. auto type = entt::resolve<props>();
  1432. ASSERT_TRUE(type.data("prop_bool"_hs));
  1433. ASSERT_TRUE(type.data("prop_int"_hs));
  1434. ASSERT_EQ(type.data("prop_bool"_hs).type(), type);
  1435. ASSERT_EQ(type.data("prop_int"_hs).type(), type);
  1436. ASSERT_FALSE(type.data("prop_bool"_hs).set({}, props::prop_int));
  1437. ASSERT_FALSE(type.data("prop_int"_hs).set({}, props::prop_bool));
  1438. ASSERT_EQ(type.data("prop_bool"_hs).get({}).cast<props>(), props::prop_bool);
  1439. ASSERT_EQ(type.data("prop_int"_hs).get({}).cast<props>(), props::prop_int);
  1440. }
  1441. TEST_F(Meta, ArithmeticTypeAndNamedConstants) {
  1442. auto type = entt::resolve<unsigned int>();
  1443. ASSERT_TRUE(type.data("min"_hs));
  1444. ASSERT_TRUE(type.data("max"_hs));
  1445. ASSERT_EQ(type.data("min"_hs).type(), type);
  1446. ASSERT_EQ(type.data("max"_hs).type(), type);
  1447. ASSERT_FALSE(type.data("min"_hs).set({}, 100u));
  1448. ASSERT_FALSE(type.data("max"_hs).set({}, 0u));
  1449. ASSERT_EQ(type.data("min"_hs).get({}).cast<unsigned int>(), 0u);
  1450. ASSERT_EQ(type.data("max"_hs).get({}).cast<unsigned int>(), 100u);
  1451. }
  1452. TEST_F(Meta, Variables) {
  1453. auto p_data = entt::resolve<props>().data("value"_hs);
  1454. auto c_data = entt::resolve("char"_hs).data("value"_hs);
  1455. props prop{props::prop_int};
  1456. char c = 'c';
  1457. p_data.set(prop, props::prop_bool);
  1458. c_data.set(c, 'x');
  1459. ASSERT_EQ(p_data.get(prop).cast<props>(), props::prop_bool);
  1460. ASSERT_EQ(c_data.get(c).cast<char>(), 'x');
  1461. ASSERT_EQ(prop, props::prop_bool);
  1462. ASSERT_EQ(c, 'x');
  1463. }
  1464. TEST_F(Meta, PropertiesAndCornerCases) {
  1465. auto type = entt::resolve<props>();
  1466. ASSERT_EQ(type.data("prop_bool"_hs).prop(props::prop_int).value().cast<int>(), 0);
  1467. ASSERT_EQ(type.data("prop_bool"_hs).prop(props::prop_value).value().cast<int>(), 3);
  1468. ASSERT_EQ(type.data("prop_int"_hs).prop(props::prop_bool).value().cast<bool>(), true);
  1469. ASSERT_EQ(type.data("prop_int"_hs).prop(props::prop_int).value().cast<int>(), 0);
  1470. ASSERT_EQ(type.data("prop_int"_hs).prop(props::prop_value).value().cast<int>(), 3);
  1471. ASSERT_TRUE(type.data("prop_int"_hs).prop(props::key_only));
  1472. ASSERT_FALSE(type.data("prop_int"_hs).prop(props::key_only).value());
  1473. ASSERT_EQ(type.data("prop_list"_hs).prop(props::prop_bool).value().cast<bool>(), false);
  1474. ASSERT_EQ(type.data("prop_list"_hs).prop(props::prop_int).value().cast<int>(), 0);
  1475. ASSERT_EQ(type.data("prop_list"_hs).prop(props::prop_value).value().cast<int>(), 3);
  1476. ASSERT_TRUE(type.data("prop_list"_hs).prop(props::key_only));
  1477. ASSERT_FALSE(type.data("prop_list"_hs).prop(props::key_only).value());
  1478. }
  1479. TEST_F(Meta, Reset) {
  1480. ASSERT_NE(*entt::internal::meta_context::global, nullptr);
  1481. entt::meta<char>().reset();
  1482. entt::meta<concrete_type>().reset();
  1483. entt::meta<setter_getter_type>().reset();
  1484. entt::meta<fat_type>().reset();
  1485. entt::meta<data_type>().reset();
  1486. entt::meta<func_type>().reset();
  1487. entt::meta<array_type>().reset();
  1488. entt::meta<double>().reset();
  1489. entt::meta<props>().reset();
  1490. entt::meta<base_type>().reset();
  1491. entt::meta<derived_type>().reset();
  1492. entt::meta<empty_type>().reset();
  1493. entt::meta<an_abstract_type>().reset();
  1494. entt::meta<another_abstract_type>().reset();
  1495. entt::meta<unsigned int>().reset();
  1496. ASSERT_FALSE(entt::resolve("char"_hs));
  1497. ASSERT_FALSE(entt::resolve("base"_hs));
  1498. ASSERT_FALSE(entt::resolve("derived"_hs));
  1499. ASSERT_FALSE(entt::resolve("empty"_hs));
  1500. ASSERT_FALSE(entt::resolve("fat"_hs));
  1501. ASSERT_FALSE(entt::resolve("data"_hs));
  1502. ASSERT_FALSE(entt::resolve("func"_hs));
  1503. ASSERT_FALSE(entt::resolve("setter_getter"_hs));
  1504. ASSERT_FALSE(entt::resolve("an_abstract_type"_hs));
  1505. ASSERT_FALSE(entt::resolve("another_abstract_type"_hs));
  1506. ASSERT_FALSE(entt::resolve("concrete"_hs));
  1507. ASSERT_EQ(*entt::internal::meta_context::global, nullptr);
  1508. Meta::SetUpAfterUnregistration();
  1509. entt::meta_any any{42.};
  1510. ASSERT_TRUE(any);
  1511. ASSERT_FALSE(any.convert<int>());
  1512. ASSERT_TRUE(any.convert<float>());
  1513. ASSERT_FALSE(entt::resolve("derived"_hs));
  1514. ASSERT_TRUE(entt::resolve("my_type"_hs));
  1515. entt::resolve<derived_type>().prop([](auto prop) {
  1516. ASSERT_EQ(prop.key(), props::prop_bool);
  1517. ASSERT_FALSE(prop.value().template cast<bool>());
  1518. });
  1519. ASSERT_FALSE((entt::resolve<derived_type>().ctor<const base_type &, int, char>()));
  1520. ASSERT_TRUE((entt::resolve<derived_type>().ctor<>()));
  1521. ASSERT_TRUE(entt::resolve("your_type"_hs).data("a_data_member"_hs));
  1522. ASSERT_FALSE(entt::resolve("your_type"_hs).data("another_data_member"_hs));
  1523. ASSERT_TRUE(entt::resolve("your_type"_hs).func("a_member_function"_hs));
  1524. ASSERT_FALSE(entt::resolve("your_type"_hs).func("another_member_function"_hs));
  1525. }
  1526. TEST_F(Meta, ReRegistrationAfterReset) {
  1527. ASSERT_TRUE(entt::resolve<props>().data("prop_bool"_hs).prop(props::prop_int));
  1528. ASSERT_TRUE(entt::resolve<props>().data("prop_bool"_hs).prop(props::prop_value));
  1529. entt::meta<double>().reset();
  1530. entt::meta<props>().reset();
  1531. entt::meta<derived_type>().reset();
  1532. entt::meta<another_abstract_type>().reset();
  1533. Meta::SetUpAfterUnregistration();
  1534. ASSERT_TRUE(entt::resolve<props>().data("prop_bool"_hs).prop(props::prop_int));
  1535. ASSERT_TRUE(entt::resolve<props>().data("prop_bool"_hs).prop(props::prop_value));
  1536. }