meta.cpp 52 KB

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