meta_any.cpp 38 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378
  1. #include <algorithm>
  2. #include <cstddef>
  3. #include <iterator>
  4. #include <type_traits>
  5. #include <utility>
  6. #include <gtest/gtest.h>
  7. #include <entt/core/hashed_string.hpp>
  8. #include <entt/meta/factory.hpp>
  9. #include <entt/meta/meta.hpp>
  10. #include <entt/meta/resolve.hpp>
  11. #include "../common/config.h"
  12. struct clazz_t {
  13. clazz_t()
  14. : value{0} {}
  15. void member(int i) {
  16. value = i;
  17. }
  18. static void func() {
  19. c = 'd';
  20. }
  21. operator int() const {
  22. return value;
  23. }
  24. static inline char c = 'c';
  25. int value;
  26. };
  27. struct empty_t {
  28. virtual ~empty_t() {
  29. ++destructor_counter;
  30. }
  31. static void destroy(empty_t &) {
  32. ++destroy_counter;
  33. }
  34. inline static int destroy_counter = 0;
  35. inline static int destructor_counter = 0;
  36. };
  37. struct fat_t: empty_t {
  38. fat_t()
  39. : value{.0, .0, .0, .0} {}
  40. fat_t(double v1, double v2, double v3, double v4)
  41. : value{v1, v2, v3, v4} {}
  42. bool operator==(const fat_t &other) const {
  43. return std::equal(std::begin(value), std::end(value), std::begin(other.value), std::end(other.value));
  44. }
  45. double value[4];
  46. };
  47. enum class enum_class : unsigned short int {
  48. foo = 0u,
  49. bar = 42u
  50. };
  51. struct not_comparable_t {
  52. bool operator==(const not_comparable_t &) const = delete;
  53. };
  54. struct unmanageable_t {
  55. unmanageable_t() = default;
  56. unmanageable_t(const unmanageable_t &) = delete;
  57. unmanageable_t(unmanageable_t &&) = delete;
  58. unmanageable_t &operator=(const unmanageable_t &) = delete;
  59. unmanageable_t &operator=(unmanageable_t &&) = delete;
  60. };
  61. struct MetaAny: ::testing::Test {
  62. void SetUp() override {
  63. using namespace entt::literals;
  64. entt::meta<empty_t>()
  65. .type("empty"_hs)
  66. .dtor<empty_t::destroy>();
  67. entt::meta<fat_t>()
  68. .type("fat"_hs)
  69. .base<empty_t>()
  70. .dtor<fat_t::destroy>();
  71. entt::meta<clazz_t>()
  72. .type("clazz"_hs)
  73. .data<&clazz_t::value>("value"_hs)
  74. .func<&clazz_t::member>("member"_hs)
  75. .func<clazz_t::func>("func"_hs)
  76. .conv<int>();
  77. empty_t::destroy_counter = 0;
  78. empty_t::destructor_counter = 0;
  79. }
  80. void TearDown() override {
  81. entt::meta_reset();
  82. }
  83. };
  84. using MetaAnyDeathTest = MetaAny;
  85. TEST_F(MetaAny, SBO) {
  86. entt::meta_any any{'c'};
  87. ASSERT_TRUE(any);
  88. ASSERT_TRUE(any.owner());
  89. ASSERT_EQ(any.policy(), entt::meta_any_policy::owner);
  90. ASSERT_FALSE(any.try_cast<std::size_t>());
  91. ASSERT_EQ(any.cast<char>(), 'c');
  92. ASSERT_NE(any.data(), nullptr);
  93. ASSERT_EQ(any, entt::meta_any{'c'});
  94. ASSERT_NE(entt::meta_any{'h'}, any);
  95. }
  96. TEST_F(MetaAny, NoSBO) {
  97. fat_t instance{.1, .2, .3, .4};
  98. entt::meta_any any{instance};
  99. ASSERT_TRUE(any);
  100. ASSERT_TRUE(any.owner());
  101. ASSERT_EQ(any.policy(), entt::meta_any_policy::owner);
  102. ASSERT_FALSE(any.try_cast<std::size_t>());
  103. ASSERT_EQ(any.cast<fat_t>(), instance);
  104. ASSERT_NE(any.data(), nullptr);
  105. ASSERT_EQ(any, entt::meta_any{instance});
  106. ASSERT_NE(any, fat_t{});
  107. }
  108. TEST_F(MetaAny, Empty) {
  109. entt::meta_any any{};
  110. ASSERT_FALSE(any);
  111. ASSERT_FALSE(any.type());
  112. ASSERT_FALSE(any.try_cast<std::size_t>());
  113. ASSERT_EQ(any.data(), nullptr);
  114. ASSERT_EQ(any, entt::meta_any{});
  115. ASSERT_NE(entt::meta_any{'c'}, any);
  116. ASSERT_FALSE(any.as_ref());
  117. ASSERT_FALSE(any.as_sequence_container());
  118. ASSERT_FALSE(any.as_associative_container());
  119. ASSERT_FALSE(std::as_const(any).as_ref());
  120. ASSERT_FALSE(std::as_const(any).as_sequence_container());
  121. ASSERT_FALSE(std::as_const(any).as_associative_container());
  122. }
  123. TEST_F(MetaAny, SBOInPlaceTypeConstruction) {
  124. entt::meta_any any{std::in_place_type<int>, 42};
  125. ASSERT_TRUE(any);
  126. ASSERT_FALSE(any.try_cast<std::size_t>());
  127. ASSERT_EQ(any.cast<int>(), 42);
  128. ASSERT_NE(any.data(), nullptr);
  129. ASSERT_EQ(any, (entt::meta_any{std::in_place_type<int>, 42}));
  130. ASSERT_EQ(any, entt::meta_any{42});
  131. ASSERT_NE(entt::meta_any{3}, any);
  132. }
  133. TEST_F(MetaAny, SBOAsRefConstruction) {
  134. int value = 3;
  135. int compare = 42;
  136. auto any = entt::forward_as_meta(value);
  137. ASSERT_TRUE(any);
  138. ASSERT_FALSE(any.owner());
  139. ASSERT_EQ(any.policy(), entt::meta_any_policy::ref);
  140. ASSERT_EQ(any.type(), entt::resolve<int>());
  141. ASSERT_FALSE(any.try_cast<std::size_t>());
  142. ASSERT_EQ(any.cast<int &>(), 3);
  143. ASSERT_EQ(any.cast<const int &>(), 3);
  144. ASSERT_EQ(any.cast<int>(), 3);
  145. ASSERT_EQ(any.data(), &value);
  146. ASSERT_EQ(std::as_const(any).data(), &value);
  147. ASSERT_EQ(any, entt::forward_as_meta(value));
  148. ASSERT_NE(any, entt::forward_as_meta(compare));
  149. ASSERT_NE(any, entt::meta_any{42});
  150. ASSERT_EQ(entt::meta_any{3}, any);
  151. any = entt::forward_as_meta(value);
  152. ASSERT_TRUE(any);
  153. ASSERT_EQ(any.type(), entt::resolve<int>());
  154. ASSERT_EQ(std::as_const(any).data(), &value);
  155. auto other = any.as_ref();
  156. ASSERT_TRUE(other);
  157. ASSERT_EQ(any.type(), entt::resolve<int>());
  158. ASSERT_EQ(any.cast<int>(), 3);
  159. ASSERT_EQ(other.data(), any.data());
  160. }
  161. TEST_F(MetaAny, SBOAsConstRefConstruction) {
  162. const int value = 3;
  163. int compare = 42;
  164. auto any = entt::forward_as_meta(value);
  165. ASSERT_TRUE(any);
  166. ASSERT_FALSE(any.owner());
  167. ASSERT_EQ(any.policy(), entt::meta_any_policy::cref);
  168. ASSERT_EQ(any.type(), entt::resolve<int>());
  169. ASSERT_FALSE(any.try_cast<std::size_t>());
  170. ASSERT_EQ(any.cast<const int &>(), 3);
  171. ASSERT_EQ(any.cast<int>(), 3);
  172. ASSERT_EQ(any.data(), nullptr);
  173. ASSERT_EQ(std::as_const(any).data(), &value);
  174. ASSERT_EQ(any, entt::forward_as_meta(value));
  175. ASSERT_NE(any, entt::forward_as_meta(compare));
  176. ASSERT_NE(any, entt::meta_any{42});
  177. ASSERT_EQ(entt::meta_any{3}, any);
  178. any = entt::forward_as_meta(std::as_const(value));
  179. ASSERT_TRUE(any);
  180. ASSERT_EQ(any.type(), entt::resolve<int>());
  181. ASSERT_EQ(std::as_const(any).data(), &value);
  182. auto other = any.as_ref();
  183. ASSERT_TRUE(other);
  184. ASSERT_EQ(any.type(), entt::resolve<int>());
  185. ASSERT_EQ(any.cast<int>(), 3);
  186. ASSERT_EQ(other.data(), any.data());
  187. }
  188. ENTT_DEBUG_TEST_F(MetaAnyDeathTest, SBOAsConstRefConstruction) {
  189. const int value = 3;
  190. auto any = entt::forward_as_meta(value);
  191. ASSERT_TRUE(any);
  192. ASSERT_DEATH(any.cast<int &>() = 3, "");
  193. }
  194. TEST_F(MetaAny, SBOCopyConstruction) {
  195. entt::meta_any any{42};
  196. entt::meta_any other{any};
  197. ASSERT_TRUE(any);
  198. ASSERT_TRUE(other);
  199. ASSERT_FALSE(other.try_cast<std::size_t>());
  200. ASSERT_EQ(other.cast<int>(), 42);
  201. ASSERT_EQ(other, entt::meta_any{42});
  202. ASSERT_NE(other, entt::meta_any{0});
  203. }
  204. TEST_F(MetaAny, SBOCopyAssignment) {
  205. entt::meta_any any{42};
  206. entt::meta_any other{3};
  207. other = any;
  208. ASSERT_TRUE(any);
  209. ASSERT_TRUE(other);
  210. ASSERT_FALSE(other.try_cast<std::size_t>());
  211. ASSERT_EQ(other.cast<int>(), 42);
  212. ASSERT_EQ(other, entt::meta_any{42});
  213. ASSERT_NE(other, entt::meta_any{0});
  214. }
  215. TEST_F(MetaAny, SBOMoveConstruction) {
  216. entt::meta_any any{42};
  217. entt::meta_any other{std::move(any)};
  218. ASSERT_FALSE(any);
  219. ASSERT_TRUE(other);
  220. ASSERT_FALSE(other.try_cast<std::size_t>());
  221. ASSERT_EQ(other.cast<int>(), 42);
  222. ASSERT_EQ(other, entt::meta_any{42});
  223. ASSERT_NE(other, entt::meta_any{0});
  224. }
  225. TEST_F(MetaAny, SBOMoveAssignment) {
  226. entt::meta_any any{42};
  227. entt::meta_any other{3};
  228. other = std::move(any);
  229. ASSERT_FALSE(any);
  230. ASSERT_TRUE(other);
  231. ASSERT_FALSE(other.try_cast<std::size_t>());
  232. ASSERT_EQ(other.cast<int>(), 42);
  233. ASSERT_EQ(other, entt::meta_any{42});
  234. ASSERT_NE(other, entt::meta_any{0});
  235. }
  236. TEST_F(MetaAny, SBODirectAssignment) {
  237. entt::meta_any any{};
  238. any = 42;
  239. ASSERT_FALSE(any.try_cast<std::size_t>());
  240. ASSERT_EQ(any.cast<int>(), 42);
  241. ASSERT_EQ(any, entt::meta_any{42});
  242. ASSERT_NE(entt::meta_any{0}, any);
  243. }
  244. TEST_F(MetaAny, SBOAssignValue) {
  245. entt::meta_any any{42};
  246. entt::meta_any other{3};
  247. entt::meta_any invalid{empty_t{}};
  248. ASSERT_TRUE(any);
  249. ASSERT_EQ(any.cast<int>(), 42);
  250. ASSERT_TRUE(any.assign(other));
  251. ASSERT_FALSE(any.assign(invalid));
  252. ASSERT_EQ(any.cast<int>(), 3);
  253. }
  254. TEST_F(MetaAny, SBOConvertAssignValue) {
  255. entt::meta_any any{42};
  256. entt::meta_any other{3.5};
  257. entt::meta_any invalid{empty_t{}};
  258. ASSERT_TRUE(any);
  259. ASSERT_EQ(any.cast<int>(), 42);
  260. ASSERT_TRUE(any.assign(other));
  261. ASSERT_FALSE(any.assign(invalid));
  262. ASSERT_EQ(any.cast<int>(), 3);
  263. }
  264. TEST_F(MetaAny, SBOAsRefAssignValue) {
  265. int value = 42;
  266. entt::meta_any any{entt::forward_as_meta(value)};
  267. entt::meta_any other{3};
  268. entt::meta_any invalid{empty_t{}};
  269. ASSERT_TRUE(any);
  270. ASSERT_EQ(any.cast<int>(), 42);
  271. ASSERT_TRUE(any.assign(other));
  272. ASSERT_FALSE(any.assign(invalid));
  273. ASSERT_EQ(any.cast<int>(), 3);
  274. ASSERT_EQ(value, 3);
  275. }
  276. TEST_F(MetaAny, SBOAsConstRefAssignValue) {
  277. const int value = 42;
  278. entt::meta_any any{entt::forward_as_meta(value)};
  279. entt::meta_any other{3};
  280. entt::meta_any invalid{empty_t{}};
  281. ASSERT_TRUE(any);
  282. ASSERT_EQ(any.cast<int>(), 42);
  283. ASSERT_FALSE(any.assign(other));
  284. ASSERT_FALSE(any.assign(invalid));
  285. ASSERT_EQ(any.cast<int>(), 42);
  286. ASSERT_EQ(value, 42);
  287. }
  288. TEST_F(MetaAny, SBOTransferValue) {
  289. entt::meta_any any{42};
  290. ASSERT_TRUE(any);
  291. ASSERT_EQ(any.cast<int>(), 42);
  292. ASSERT_TRUE(any.assign(3));
  293. ASSERT_FALSE(any.assign(empty_t{}));
  294. ASSERT_EQ(any.cast<int>(), 3);
  295. }
  296. TEST_F(MetaAny, SBOTransferConstValue) {
  297. const int value = 3;
  298. entt::meta_any any{42};
  299. ASSERT_TRUE(any);
  300. ASSERT_EQ(any.cast<int>(), 42);
  301. ASSERT_TRUE(any.assign(entt::forward_as_meta(value)));
  302. ASSERT_EQ(any.cast<int>(), 3);
  303. }
  304. TEST_F(MetaAny, SBOConvertTransferValue) {
  305. entt::meta_any any{42};
  306. ASSERT_TRUE(any);
  307. ASSERT_EQ(any.cast<int>(), 42);
  308. ASSERT_TRUE(any.assign(3.5));
  309. ASSERT_FALSE(any.assign(empty_t{}));
  310. ASSERT_EQ(any.cast<int>(), 3);
  311. }
  312. TEST_F(MetaAny, SBOAsRefTransferValue) {
  313. int value = 42;
  314. entt::meta_any any{entt::forward_as_meta(value)};
  315. ASSERT_TRUE(any);
  316. ASSERT_EQ(any.cast<int>(), 42);
  317. ASSERT_TRUE(any.assign(3));
  318. ASSERT_FALSE(any.assign(empty_t{}));
  319. ASSERT_EQ(any.cast<int>(), 3);
  320. ASSERT_EQ(value, 3);
  321. }
  322. TEST_F(MetaAny, SBOAsConstRefTransferValue) {
  323. const int value = 42;
  324. entt::meta_any any{entt::forward_as_meta(value)};
  325. ASSERT_TRUE(any);
  326. ASSERT_EQ(any.cast<int>(), 42);
  327. ASSERT_FALSE(any.assign(3));
  328. ASSERT_FALSE(any.assign(empty_t{}));
  329. ASSERT_EQ(any.cast<int>(), 42);
  330. ASSERT_EQ(value, 42);
  331. }
  332. TEST_F(MetaAny, NoSBOInPlaceTypeConstruction) {
  333. fat_t instance{.1, .2, .3, .4};
  334. entt::meta_any any{std::in_place_type<fat_t>, instance};
  335. ASSERT_TRUE(any);
  336. ASSERT_FALSE(any.try_cast<std::size_t>());
  337. ASSERT_EQ(any.cast<fat_t>(), instance);
  338. ASSERT_NE(any.data(), nullptr);
  339. ASSERT_EQ(any, (entt::meta_any{std::in_place_type<fat_t>, instance}));
  340. ASSERT_EQ(any, entt::meta_any{instance});
  341. ASSERT_NE(entt::meta_any{fat_t{}}, any);
  342. }
  343. TEST_F(MetaAny, NoSBOAsRefConstruction) {
  344. fat_t instance{.1, .2, .3, .4};
  345. auto any = entt::forward_as_meta(instance);
  346. ASSERT_TRUE(any);
  347. ASSERT_FALSE(any.owner());
  348. ASSERT_EQ(any.policy(), entt::meta_any_policy::ref);
  349. ASSERT_EQ(any.type(), entt::resolve<fat_t>());
  350. ASSERT_FALSE(any.try_cast<std::size_t>());
  351. ASSERT_EQ(any.cast<fat_t &>(), instance);
  352. ASSERT_EQ(any.cast<const fat_t &>(), instance);
  353. ASSERT_EQ(any.cast<fat_t>(), instance);
  354. ASSERT_EQ(any.data(), &instance);
  355. ASSERT_EQ(std::as_const(any).data(), &instance);
  356. ASSERT_EQ(any, entt::forward_as_meta(instance));
  357. ASSERT_EQ(any, entt::meta_any{instance});
  358. ASSERT_NE(entt::meta_any{fat_t{}}, any);
  359. any = entt::forward_as_meta(instance);
  360. ASSERT_TRUE(any);
  361. ASSERT_EQ(any.type(), entt::resolve<fat_t>());
  362. ASSERT_EQ(std::as_const(any).data(), &instance);
  363. auto other = any.as_ref();
  364. ASSERT_TRUE(other);
  365. ASSERT_EQ(any.type(), entt::resolve<fat_t>());
  366. ASSERT_EQ(any, entt::meta_any{instance});
  367. ASSERT_EQ(other.data(), any.data());
  368. }
  369. TEST_F(MetaAny, NoSBOAsConstRefConstruction) {
  370. const fat_t instance{.1, .2, .3, .4};
  371. auto any = entt::forward_as_meta(instance);
  372. ASSERT_TRUE(any);
  373. ASSERT_FALSE(any.owner());
  374. ASSERT_EQ(any.policy(), entt::meta_any_policy::cref);
  375. ASSERT_EQ(any.type(), entt::resolve<fat_t>());
  376. ASSERT_FALSE(any.try_cast<std::size_t>());
  377. ASSERT_EQ(any.cast<const fat_t &>(), instance);
  378. ASSERT_EQ(any.cast<fat_t>(), instance);
  379. ASSERT_EQ(any.data(), nullptr);
  380. ASSERT_EQ(std::as_const(any).data(), &instance);
  381. ASSERT_EQ(any, entt::forward_as_meta(instance));
  382. ASSERT_EQ(any, entt::meta_any{instance});
  383. ASSERT_NE(entt::meta_any{fat_t{}}, any);
  384. any = entt::forward_as_meta(std::as_const(instance));
  385. ASSERT_TRUE(any);
  386. ASSERT_EQ(any.type(), entt::resolve<fat_t>());
  387. ASSERT_EQ(std::as_const(any).data(), &instance);
  388. auto other = any.as_ref();
  389. ASSERT_TRUE(other);
  390. ASSERT_EQ(any.type(), entt::resolve<fat_t>());
  391. ASSERT_EQ(any, entt::meta_any{instance});
  392. ASSERT_EQ(other.data(), any.data());
  393. }
  394. ENTT_DEBUG_TEST_F(MetaAnyDeathTest, NoSBOAsConstRefConstruction) {
  395. const fat_t instance{.1, .2, .3, .4};
  396. auto any = entt::forward_as_meta(instance);
  397. ASSERT_TRUE(any);
  398. ASSERT_DEATH(any.cast<fat_t &>() = {}, "");
  399. }
  400. TEST_F(MetaAny, NoSBOCopyConstruction) {
  401. fat_t instance{.1, .2, .3, .4};
  402. entt::meta_any any{instance};
  403. entt::meta_any other{any};
  404. ASSERT_TRUE(any);
  405. ASSERT_TRUE(other);
  406. ASSERT_FALSE(other.try_cast<std::size_t>());
  407. ASSERT_EQ(other.cast<fat_t>(), instance);
  408. ASSERT_EQ(other, entt::meta_any{instance});
  409. ASSERT_NE(other, fat_t{});
  410. }
  411. TEST_F(MetaAny, NoSBOCopyAssignment) {
  412. fat_t instance{.1, .2, .3, .4};
  413. entt::meta_any any{instance};
  414. entt::meta_any other{3};
  415. other = any;
  416. ASSERT_TRUE(any);
  417. ASSERT_TRUE(other);
  418. ASSERT_FALSE(other.try_cast<std::size_t>());
  419. ASSERT_EQ(other.cast<fat_t>(), instance);
  420. ASSERT_EQ(other, entt::meta_any{instance});
  421. ASSERT_NE(other, fat_t{});
  422. }
  423. TEST_F(MetaAny, NoSBOMoveConstruction) {
  424. fat_t instance{.1, .2, .3, .4};
  425. entt::meta_any any{instance};
  426. entt::meta_any other{std::move(any)};
  427. ASSERT_FALSE(any);
  428. ASSERT_TRUE(other);
  429. ASSERT_FALSE(other.try_cast<std::size_t>());
  430. ASSERT_EQ(other.cast<fat_t>(), instance);
  431. ASSERT_EQ(other, entt::meta_any{instance});
  432. ASSERT_NE(other, fat_t{});
  433. }
  434. TEST_F(MetaAny, NoSBOMoveAssignment) {
  435. fat_t instance{.1, .2, .3, .4};
  436. entt::meta_any any{instance};
  437. entt::meta_any other{3};
  438. other = std::move(any);
  439. ASSERT_FALSE(any);
  440. ASSERT_TRUE(other);
  441. ASSERT_FALSE(other.try_cast<std::size_t>());
  442. ASSERT_EQ(other.cast<fat_t>(), instance);
  443. ASSERT_EQ(other, entt::meta_any{instance});
  444. ASSERT_NE(other, fat_t{});
  445. }
  446. TEST_F(MetaAny, NoSBODirectAssignment) {
  447. fat_t instance{.1, .2, .3, .4};
  448. entt::meta_any any{};
  449. any = instance;
  450. ASSERT_FALSE(any.try_cast<std::size_t>());
  451. ASSERT_EQ(any.cast<fat_t>(), instance);
  452. ASSERT_EQ(any, (entt::meta_any{fat_t{.1, .2, .3, .4}}));
  453. ASSERT_NE(any, fat_t{});
  454. }
  455. TEST_F(MetaAny, NoSBOAssignValue) {
  456. entt::meta_any any{fat_t{.1, .2, .3, .4}};
  457. entt::meta_any other{fat_t{.0, .1, .2, .3}};
  458. entt::meta_any invalid{'c'};
  459. const void *addr = std::as_const(any).data();
  460. ASSERT_TRUE(any);
  461. ASSERT_EQ(any.cast<const fat_t &>(), (fat_t{.1, .2, .3, .4}));
  462. ASSERT_TRUE(any.assign(other));
  463. ASSERT_FALSE(any.assign(invalid));
  464. ASSERT_EQ(any.cast<const fat_t &>(), (fat_t{.0, .1, .2, .3}));
  465. ASSERT_EQ(addr, std::as_const(any).data());
  466. }
  467. TEST_F(MetaAny, NoSBOConvertAssignValue) {
  468. entt::meta_any any{empty_t{}};
  469. entt::meta_any other{fat_t{.0, .1, .2, .3}};
  470. entt::meta_any invalid{'c'};
  471. const void *addr = std::as_const(any).data();
  472. ASSERT_TRUE(any);
  473. ASSERT_TRUE(any.assign(other));
  474. ASSERT_FALSE(any.assign(invalid));
  475. ASSERT_EQ(addr, std::as_const(any).data());
  476. }
  477. TEST_F(MetaAny, NoSBOAsRefAssignValue) {
  478. fat_t instance{.1, .2, .3, .4};
  479. entt::meta_any any{entt::forward_as_meta(instance)};
  480. entt::meta_any other{fat_t{.0, .1, .2, .3}};
  481. entt::meta_any invalid{'c'};
  482. ASSERT_TRUE(any);
  483. ASSERT_EQ(any.cast<const fat_t &>(), (fat_t{.1, .2, .3, .4}));
  484. ASSERT_TRUE(any.assign(other));
  485. ASSERT_FALSE(any.assign(invalid));
  486. ASSERT_EQ(any.cast<const fat_t &>(), (fat_t{.0, .1, .2, .3}));
  487. ASSERT_EQ(instance, (fat_t{.0, .1, .2, .3}));
  488. }
  489. TEST_F(MetaAny, NoSBOAsConstRefAssignValue) {
  490. const fat_t instance{.1, .2, .3, .4};
  491. entt::meta_any any{entt::forward_as_meta(instance)};
  492. entt::meta_any other{fat_t{.0, .1, .2, .3}};
  493. entt::meta_any invalid{'c'};
  494. ASSERT_TRUE(any);
  495. ASSERT_EQ(any.cast<const fat_t &>(), (fat_t{.1, .2, .3, .4}));
  496. ASSERT_FALSE(any.assign(other));
  497. ASSERT_FALSE(any.assign(invalid));
  498. ASSERT_EQ(any.cast<const fat_t &>(), (fat_t{.1, .2, .3, .4}));
  499. ASSERT_EQ(instance, (fat_t{.1, .2, .3, .4}));
  500. }
  501. TEST_F(MetaAny, NoSBOTransferValue) {
  502. entt::meta_any any{fat_t{.1, .2, .3, .4}};
  503. const void *addr = std::as_const(any).data();
  504. ASSERT_TRUE(any);
  505. ASSERT_EQ(any.cast<const fat_t &>(), (fat_t{.1, .2, .3, .4}));
  506. ASSERT_TRUE(any.assign(fat_t{.0, .1, .2, .3}));
  507. ASSERT_FALSE(any.assign('c'));
  508. ASSERT_EQ(any.cast<const fat_t &>(), (fat_t{.0, .1, .2, .3}));
  509. ASSERT_EQ(addr, std::as_const(any).data());
  510. }
  511. TEST_F(MetaAny, NoSBOTransferConstValue) {
  512. const fat_t instance{.0, .1, .2, .3};
  513. entt::meta_any any{fat_t{.1, .2, .3, .4}};
  514. const void *addr = std::as_const(any).data();
  515. ASSERT_TRUE(any);
  516. ASSERT_EQ(any.cast<const fat_t &>(), (fat_t{.1, .2, .3, .4}));
  517. ASSERT_TRUE(any.assign(entt::forward_as_meta(instance)));
  518. ASSERT_EQ(any.cast<const fat_t &>(), (fat_t{.0, .1, .2, .3}));
  519. ASSERT_EQ(addr, std::as_const(any).data());
  520. }
  521. TEST_F(MetaAny, NoSBOConvertTransferValue) {
  522. entt::meta_any any{empty_t{}};
  523. const void *addr = std::as_const(any).data();
  524. ASSERT_TRUE(any);
  525. ASSERT_TRUE(any.assign(fat_t{.0, .1, .2, .3}));
  526. ASSERT_FALSE(any.assign('c'));
  527. ASSERT_EQ(addr, std::as_const(any).data());
  528. }
  529. TEST_F(MetaAny, NoSBOAsRefTransferValue) {
  530. fat_t instance{.1, .2, .3, .4};
  531. entt::meta_any any{entt::forward_as_meta(instance)};
  532. const void *addr = std::as_const(any).data();
  533. ASSERT_TRUE(any);
  534. ASSERT_EQ(any.cast<const fat_t &>(), (fat_t{.1, .2, .3, .4}));
  535. ASSERT_TRUE(any.assign(fat_t{.0, .1, .2, .3}));
  536. ASSERT_FALSE(any.assign('c'));
  537. ASSERT_EQ(any.cast<const fat_t &>(), (fat_t{.0, .1, .2, .3}));
  538. ASSERT_EQ(instance, (fat_t{.0, .1, .2, .3}));
  539. ASSERT_EQ(addr, std::as_const(any).data());
  540. }
  541. TEST_F(MetaAny, NoSBOAsConstRefTransferValue) {
  542. const fat_t instance{.1, .2, .3, .4};
  543. entt::meta_any any{entt::forward_as_meta(instance)};
  544. const void *addr = std::as_const(any).data();
  545. ASSERT_TRUE(any);
  546. ASSERT_EQ(any.cast<const fat_t &>(), (fat_t{.1, .2, .3, .4}));
  547. ASSERT_FALSE(any.assign(fat_t{.0, .1, .2, .3}));
  548. ASSERT_FALSE(any.assign('c'));
  549. ASSERT_EQ(any.cast<const fat_t &>(), (fat_t{.1, .2, .3, .4}));
  550. ASSERT_EQ(instance, (fat_t{.1, .2, .3, .4}));
  551. ASSERT_EQ(addr, std::as_const(any).data());
  552. }
  553. TEST_F(MetaAny, VoidInPlaceTypeConstruction) {
  554. entt::meta_any any{std::in_place_type<void>};
  555. ASSERT_TRUE(any);
  556. ASSERT_TRUE(any.owner());
  557. ASSERT_EQ(any.policy(), entt::meta_any_policy::owner);
  558. ASSERT_FALSE(any.try_cast<char>());
  559. ASSERT_EQ(any.data(), nullptr);
  560. ASSERT_EQ(any.type(), entt::resolve<void>());
  561. ASSERT_EQ(any, entt::meta_any{std::in_place_type<void>});
  562. ASSERT_NE(entt::meta_any{3}, any);
  563. }
  564. TEST_F(MetaAny, VoidCopyConstruction) {
  565. entt::meta_any any{std::in_place_type<void>};
  566. entt::meta_any other{any};
  567. ASSERT_TRUE(any);
  568. ASSERT_TRUE(other);
  569. ASSERT_EQ(any.type(), entt::resolve<void>());
  570. ASSERT_EQ(other, entt::meta_any{std::in_place_type<void>});
  571. }
  572. TEST_F(MetaAny, VoidCopyAssignment) {
  573. entt::meta_any any{std::in_place_type<void>};
  574. entt::meta_any other{std::in_place_type<void>};
  575. other = any;
  576. ASSERT_TRUE(any);
  577. ASSERT_TRUE(other);
  578. ASSERT_EQ(any.type(), entt::resolve<void>());
  579. ASSERT_EQ(other, entt::meta_any{std::in_place_type<void>});
  580. }
  581. TEST_F(MetaAny, VoidMoveConstruction) {
  582. entt::meta_any any{std::in_place_type<void>};
  583. entt::meta_any other{std::move(any)};
  584. ASSERT_FALSE(any);
  585. ASSERT_TRUE(other);
  586. ASSERT_EQ(other.type(), entt::resolve<void>());
  587. ASSERT_EQ(other, entt::meta_any{std::in_place_type<void>});
  588. }
  589. TEST_F(MetaAny, VoidMoveAssignment) {
  590. entt::meta_any any{std::in_place_type<void>};
  591. entt::meta_any other{std::in_place_type<void>};
  592. other = std::move(any);
  593. ASSERT_FALSE(any);
  594. ASSERT_TRUE(other);
  595. ASSERT_EQ(other.type(), entt::resolve<void>());
  596. ASSERT_EQ(other, entt::meta_any{std::in_place_type<void>});
  597. }
  598. TEST_F(MetaAny, SBOMoveInvalidate) {
  599. entt::meta_any any{42};
  600. entt::meta_any other{std::move(any)};
  601. entt::meta_any valid = std::move(other);
  602. ASSERT_FALSE(any);
  603. ASSERT_FALSE(other);
  604. ASSERT_TRUE(valid);
  605. }
  606. TEST_F(MetaAny, NoSBOMoveInvalidate) {
  607. fat_t instance{.1, .2, .3, .4};
  608. entt::meta_any any{instance};
  609. entt::meta_any other{std::move(any)};
  610. entt::meta_any valid = std::move(other);
  611. ASSERT_FALSE(any);
  612. ASSERT_FALSE(other);
  613. ASSERT_TRUE(valid);
  614. }
  615. TEST_F(MetaAny, VoidMoveInvalidate) {
  616. entt::meta_any any{std::in_place_type<void>};
  617. entt::meta_any other{std::move(any)};
  618. entt::meta_any valid = std::move(other);
  619. ASSERT_FALSE(any);
  620. ASSERT_FALSE(other);
  621. ASSERT_TRUE(valid);
  622. }
  623. TEST_F(MetaAny, SBODestruction) {
  624. {
  625. entt::meta_any any{std::in_place_type<empty_t>};
  626. any.emplace<empty_t>();
  627. any = empty_t{};
  628. entt::meta_any other{std::move(any)};
  629. any = std::move(other);
  630. }
  631. ASSERT_EQ(empty_t::destroy_counter, 3);
  632. ASSERT_EQ(empty_t::destructor_counter, 6);
  633. }
  634. TEST_F(MetaAny, NoSBODestruction) {
  635. {
  636. entt::meta_any any{std::in_place_type<fat_t>, 1., 2., 3., 4.};
  637. any.emplace<fat_t>(1., 2., 3., 4.);
  638. any = fat_t{1., 2., 3., 4.};
  639. entt::meta_any other{std::move(any)};
  640. any = std::move(other);
  641. }
  642. ASSERT_EQ(fat_t::destroy_counter, 3);
  643. ASSERT_EQ(empty_t::destructor_counter, 4);
  644. }
  645. TEST_F(MetaAny, VoidDestruction) {
  646. // just let asan tell us if everything is ok here
  647. [[maybe_unused]] entt::meta_any any{std::in_place_type<void>};
  648. }
  649. TEST_F(MetaAny, Emplace) {
  650. entt::meta_any any{};
  651. any.emplace<int>(42);
  652. ASSERT_TRUE(any);
  653. ASSERT_FALSE(any.try_cast<std::size_t>());
  654. ASSERT_EQ(any.cast<int>(), 42);
  655. ASSERT_NE(any.data(), nullptr);
  656. ASSERT_EQ(any, (entt::meta_any{std::in_place_type<int>, 42}));
  657. ASSERT_EQ(any, entt::meta_any{42});
  658. ASSERT_NE(entt::meta_any{3}, any);
  659. }
  660. TEST_F(MetaAny, EmplaceVoid) {
  661. entt::meta_any any{};
  662. any.emplace<void>();
  663. ASSERT_TRUE(any);
  664. ASSERT_EQ(any.data(), nullptr);
  665. ASSERT_EQ(any.type(), entt::resolve<void>());
  666. ASSERT_EQ(any, (entt::meta_any{std::in_place_type<void>}));
  667. }
  668. TEST_F(MetaAny, Reset) {
  669. entt::meta_any any{42};
  670. ASSERT_TRUE(any);
  671. ASSERT_EQ(any.type(), entt::resolve<int>());
  672. any.reset();
  673. ASSERT_FALSE(any);
  674. ASSERT_EQ(any.type(), entt::meta_type{});
  675. }
  676. TEST_F(MetaAny, SBOSwap) {
  677. entt::meta_any lhs{'c'};
  678. entt::meta_any rhs{42};
  679. std::swap(lhs, rhs);
  680. ASSERT_FALSE(lhs.try_cast<char>());
  681. ASSERT_EQ(lhs.cast<int>(), 42);
  682. ASSERT_FALSE(rhs.try_cast<int>());
  683. ASSERT_EQ(rhs.cast<char>(), 'c');
  684. }
  685. TEST_F(MetaAny, NoSBOSwap) {
  686. entt::meta_any lhs{fat_t{.1, .2, .3, .4}};
  687. entt::meta_any rhs{fat_t{.4, .3, .2, .1}};
  688. std::swap(lhs, rhs);
  689. ASSERT_EQ(lhs.cast<fat_t>(), (fat_t{.4, .3, .2, .1}));
  690. ASSERT_EQ(rhs.cast<fat_t>(), (fat_t{.1, .2, .3, .4}));
  691. }
  692. TEST_F(MetaAny, VoidSwap) {
  693. entt::meta_any lhs{std::in_place_type<void>};
  694. entt::meta_any rhs{std::in_place_type<void>};
  695. const auto *pre = lhs.data();
  696. std::swap(lhs, rhs);
  697. ASSERT_EQ(pre, lhs.data());
  698. }
  699. TEST_F(MetaAny, SBOWithNoSBOSwap) {
  700. entt::meta_any lhs{fat_t{.1, .2, .3, .4}};
  701. entt::meta_any rhs{'c'};
  702. std::swap(lhs, rhs);
  703. ASSERT_FALSE(lhs.try_cast<fat_t>());
  704. ASSERT_EQ(lhs.cast<char>(), 'c');
  705. ASSERT_FALSE(rhs.try_cast<char>());
  706. ASSERT_EQ(rhs.cast<fat_t>(), (fat_t{.1, .2, .3, .4}));
  707. }
  708. TEST_F(MetaAny, SBOWithEmptySwap) {
  709. entt::meta_any lhs{'c'};
  710. entt::meta_any rhs{};
  711. std::swap(lhs, rhs);
  712. ASSERT_FALSE(lhs);
  713. ASSERT_EQ(rhs.cast<char>(), 'c');
  714. std::swap(lhs, rhs);
  715. ASSERT_FALSE(rhs);
  716. ASSERT_EQ(lhs.cast<char>(), 'c');
  717. }
  718. TEST_F(MetaAny, SBOWithVoidSwap) {
  719. entt::meta_any lhs{'c'};
  720. entt::meta_any rhs{std::in_place_type<void>};
  721. std::swap(lhs, rhs);
  722. ASSERT_EQ(lhs.type(), entt::resolve<void>());
  723. ASSERT_EQ(rhs.cast<char>(), 'c');
  724. }
  725. TEST_F(MetaAny, NoSBOWithEmptySwap) {
  726. entt::meta_any lhs{fat_t{.1, .2, .3, .4}};
  727. entt::meta_any rhs{};
  728. std::swap(lhs, rhs);
  729. ASSERT_FALSE(lhs);
  730. ASSERT_EQ(rhs.cast<fat_t>(), (fat_t{.1, .2, .3, .4}));
  731. std::swap(lhs, rhs);
  732. ASSERT_FALSE(rhs);
  733. ASSERT_EQ(lhs.cast<fat_t>(), (fat_t{.1, .2, .3, .4}));
  734. }
  735. TEST_F(MetaAny, NoSBOWithVoidSwap) {
  736. entt::meta_any lhs{fat_t{.1, .2, .3, .4}};
  737. entt::meta_any rhs{std::in_place_type<void>};
  738. std::swap(lhs, rhs);
  739. ASSERT_EQ(lhs.type(), entt::resolve<void>());
  740. ASSERT_EQ(rhs.cast<fat_t>(), (fat_t{.1, .2, .3, .4}));
  741. std::swap(lhs, rhs);
  742. ASSERT_EQ(rhs.type(), entt::resolve<void>());
  743. ASSERT_EQ(lhs.cast<fat_t>(), (fat_t{.1, .2, .3, .4}));
  744. }
  745. TEST_F(MetaAny, AsRef) {
  746. entt::meta_any any{42};
  747. auto ref = any.as_ref();
  748. auto cref = std::as_const(any).as_ref();
  749. ASSERT_EQ(any.try_cast<int>(), any.data());
  750. ASSERT_EQ(ref.try_cast<int>(), any.data());
  751. ASSERT_EQ(cref.try_cast<int>(), nullptr);
  752. ASSERT_EQ(any.try_cast<const int>(), any.data());
  753. ASSERT_EQ(ref.try_cast<const int>(), any.data());
  754. ASSERT_EQ(cref.try_cast<const int>(), any.data());
  755. ASSERT_EQ(any.cast<int>(), 42);
  756. ASSERT_EQ(ref.cast<int>(), 42);
  757. ASSERT_EQ(cref.cast<int>(), 42);
  758. ASSERT_EQ(any.cast<const int>(), 42);
  759. ASSERT_EQ(ref.cast<const int>(), 42);
  760. ASSERT_EQ(cref.cast<const int>(), 42);
  761. ASSERT_EQ(any.cast<int &>(), 42);
  762. ASSERT_EQ(any.cast<const int &>(), 42);
  763. ASSERT_EQ(ref.cast<int &>(), 42);
  764. ASSERT_EQ(ref.cast<const int &>(), 42);
  765. ASSERT_EQ(cref.cast<const int &>(), 42);
  766. any.cast<int &>() = 3;
  767. ASSERT_EQ(any.cast<int>(), 3);
  768. ASSERT_EQ(ref.cast<int>(), 3);
  769. ASSERT_EQ(cref.cast<int>(), 3);
  770. std::swap(ref, cref);
  771. ASSERT_EQ(ref.try_cast<int>(), nullptr);
  772. ASSERT_EQ(cref.try_cast<int>(), any.data());
  773. ref = ref.as_ref();
  774. cref = std::as_const(cref).as_ref();
  775. ASSERT_EQ(ref.try_cast<int>(), nullptr);
  776. ASSERT_EQ(cref.try_cast<int>(), nullptr);
  777. ASSERT_EQ(ref.try_cast<const int>(), any.data());
  778. ASSERT_EQ(cref.try_cast<const int>(), any.data());
  779. ASSERT_EQ(ref.cast<const int &>(), 3);
  780. ASSERT_EQ(cref.cast<const int &>(), 3);
  781. ref = 42;
  782. cref = 42;
  783. ASSERT_NE(ref.try_cast<int>(), nullptr);
  784. ASSERT_NE(cref.try_cast<int>(), nullptr);
  785. ASSERT_EQ(ref.cast<int &>(), 42);
  786. ASSERT_EQ(cref.cast<int &>(), 42);
  787. ASSERT_EQ(ref.cast<const int &>(), 42);
  788. ASSERT_EQ(cref.cast<const int &>(), 42);
  789. ASSERT_NE(ref.try_cast<int>(), any.data());
  790. ASSERT_NE(cref.try_cast<int>(), any.data());
  791. any.emplace<void>();
  792. ref = any.as_ref();
  793. cref = std::as_const(any).as_ref();
  794. ASSERT_TRUE(any);
  795. ASSERT_FALSE(ref);
  796. ASSERT_FALSE(cref);
  797. }
  798. ENTT_DEBUG_TEST_F(MetaAnyDeathTest, AsRef) {
  799. entt::meta_any any{42};
  800. auto cref = std::as_const(any).as_ref();
  801. ASSERT_TRUE(any);
  802. ASSERT_DEATH(cref.cast<int &>() = 3, "");
  803. }
  804. TEST_F(MetaAny, Comparable) {
  805. entt::meta_any any{'c'};
  806. ASSERT_EQ(any, any);
  807. ASSERT_EQ(any, entt::meta_any{'c'});
  808. ASSERT_NE(entt::meta_any{'a'}, any);
  809. ASSERT_NE(any, entt::meta_any{});
  810. ASSERT_TRUE(any == any);
  811. ASSERT_TRUE(any == entt::meta_any{'c'});
  812. ASSERT_FALSE(entt::meta_any{'a'} == any);
  813. ASSERT_TRUE(any != entt::meta_any{'a'});
  814. ASSERT_TRUE(entt::meta_any{} != any);
  815. }
  816. TEST_F(MetaAny, NotComparable) {
  817. entt::meta_any any{not_comparable_t{}};
  818. ASSERT_EQ(any, any);
  819. ASSERT_NE(any, entt::meta_any{not_comparable_t{}});
  820. ASSERT_NE(entt::meta_any{}, any);
  821. ASSERT_TRUE(any == any);
  822. ASSERT_FALSE(any == entt::meta_any{not_comparable_t{}});
  823. ASSERT_TRUE(entt::meta_any{} != any);
  824. }
  825. TEST_F(MetaAny, CompareVoid) {
  826. entt::meta_any any{std::in_place_type<void>};
  827. ASSERT_EQ(any, any);
  828. ASSERT_EQ(any, entt::meta_any{std::in_place_type<void>});
  829. ASSERT_NE(entt::meta_any{'a'}, any);
  830. ASSERT_NE(any, entt::meta_any{});
  831. ASSERT_TRUE(any == any);
  832. ASSERT_TRUE(any == entt::meta_any{std::in_place_type<void>});
  833. ASSERT_FALSE(entt::meta_any{'a'} == any);
  834. ASSERT_TRUE(any != entt::meta_any{'a'});
  835. ASSERT_TRUE(entt::meta_any{} != any);
  836. }
  837. TEST_F(MetaAny, TryCast) {
  838. entt::meta_any any{fat_t{}};
  839. ASSERT_TRUE(any);
  840. ASSERT_EQ(any.type(), entt::resolve<fat_t>());
  841. ASSERT_EQ(any.try_cast<void>(), nullptr);
  842. ASSERT_NE(any.try_cast<empty_t>(), nullptr);
  843. ASSERT_EQ(any.try_cast<fat_t>(), any.data());
  844. ASSERT_EQ(std::as_const(any).try_cast<empty_t>(), any.try_cast<empty_t>());
  845. ASSERT_EQ(std::as_const(any).try_cast<fat_t>(), any.data());
  846. ASSERT_EQ(std::as_const(any).try_cast<int>(), nullptr);
  847. }
  848. TEST_F(MetaAny, Cast) {
  849. entt::meta_any any{fat_t{}};
  850. ASSERT_TRUE(any);
  851. ASSERT_EQ(any.type(), entt::resolve<fat_t>());
  852. ASSERT_EQ(std::as_const(any).cast<const fat_t &>(), fat_t{});
  853. ASSERT_EQ(any.cast<const fat_t>(), fat_t{});
  854. ASSERT_EQ(any.cast<fat_t &>(), fat_t{});
  855. ASSERT_EQ(any.cast<fat_t>(), fat_t{});
  856. ASSERT_EQ(any.cast<fat_t>().value[0u], 0.);
  857. any.cast<fat_t &>().value[0u] = 3.;
  858. ASSERT_EQ(any.cast<fat_t>().value[0u], 3.);
  859. }
  860. TEST_F(MetaAny, AllowCast) {
  861. entt::meta_any clazz{clazz_t{}};
  862. entt::meta_any fat{fat_t{}};
  863. entt::meta_any arithmetic{42};
  864. auto as_cref = entt::forward_as_meta(arithmetic.cast<const int &>());
  865. ASSERT_TRUE(clazz);
  866. ASSERT_TRUE(fat);
  867. ASSERT_TRUE(arithmetic);
  868. ASSERT_TRUE(as_cref);
  869. ASSERT_TRUE(clazz.allow_cast<clazz_t>());
  870. ASSERT_TRUE(clazz.allow_cast<clazz_t &>());
  871. ASSERT_TRUE(clazz.allow_cast<const clazz_t &>());
  872. ASSERT_EQ(clazz.type(), entt::resolve<clazz_t>());
  873. ASSERT_TRUE(clazz.allow_cast<const int &>());
  874. ASSERT_EQ(clazz.type(), entt::resolve<int>());
  875. ASSERT_TRUE(clazz.allow_cast<int>());
  876. ASSERT_TRUE(clazz.allow_cast<int &>());
  877. ASSERT_TRUE(clazz.allow_cast<const int &>());
  878. ASSERT_TRUE(fat.allow_cast<fat_t>());
  879. ASSERT_TRUE(fat.allow_cast<fat_t &>());
  880. ASSERT_TRUE(fat.allow_cast<const empty_t &>());
  881. ASSERT_EQ(fat.type(), entt::resolve<fat_t>());
  882. ASSERT_FALSE(fat.allow_cast<int>());
  883. ASSERT_TRUE(std::as_const(fat).allow_cast<fat_t>());
  884. ASSERT_FALSE(std::as_const(fat).allow_cast<fat_t &>());
  885. ASSERT_TRUE(std::as_const(fat).allow_cast<const empty_t &>());
  886. ASSERT_EQ(fat.type(), entt::resolve<fat_t>());
  887. ASSERT_FALSE(fat.allow_cast<int>());
  888. ASSERT_TRUE(arithmetic.allow_cast<int>());
  889. ASSERT_TRUE(arithmetic.allow_cast<int &>());
  890. ASSERT_TRUE(arithmetic.allow_cast<const int &>());
  891. ASSERT_EQ(arithmetic.type(), entt::resolve<int>());
  892. ASSERT_FALSE(arithmetic.allow_cast<fat_t>());
  893. ASSERT_TRUE(arithmetic.allow_cast<double &>());
  894. ASSERT_EQ(arithmetic.type(), entt::resolve<double>());
  895. ASSERT_EQ(arithmetic.cast<double &>(), 42.);
  896. ASSERT_TRUE(arithmetic.allow_cast<const float &>());
  897. ASSERT_EQ(arithmetic.type(), entt::resolve<float>());
  898. ASSERT_EQ(arithmetic.cast<float &>(), 42.f);
  899. ASSERT_TRUE(as_cref.allow_cast<int>());
  900. ASSERT_FALSE(as_cref.allow_cast<int &>());
  901. ASSERT_TRUE(as_cref.allow_cast<const int &>());
  902. ASSERT_EQ(as_cref.type(), entt::resolve<int>());
  903. ASSERT_FALSE(as_cref.allow_cast<fat_t>());
  904. ASSERT_TRUE(as_cref.allow_cast<double &>());
  905. ASSERT_EQ(as_cref.type(), entt::resolve<double>());
  906. }
  907. TEST_F(MetaAny, OpaqueAllowCast) {
  908. entt::meta_any clazz{clazz_t{}};
  909. entt::meta_any fat{fat_t{}};
  910. entt::meta_any arithmetic{42};
  911. auto as_cref = entt::forward_as_meta(arithmetic.cast<const int &>());
  912. ASSERT_TRUE(clazz);
  913. ASSERT_TRUE(fat);
  914. ASSERT_TRUE(arithmetic);
  915. ASSERT_TRUE(as_cref);
  916. ASSERT_TRUE(clazz.allow_cast(entt::resolve<clazz_t>()));
  917. ASSERT_EQ(clazz.type(), entt::resolve<clazz_t>());
  918. ASSERT_TRUE(clazz.allow_cast(entt::resolve<int>()));
  919. ASSERT_EQ(clazz.type(), entt::resolve<int>());
  920. ASSERT_TRUE(clazz.allow_cast(entt::resolve<int>()));
  921. ASSERT_TRUE(fat.allow_cast(entt::resolve<fat_t>()));
  922. ASSERT_TRUE(fat.allow_cast(entt::resolve<empty_t>()));
  923. ASSERT_EQ(fat.type(), entt::resolve<fat_t>());
  924. ASSERT_FALSE(fat.allow_cast(entt::resolve<int>()));
  925. ASSERT_TRUE(std::as_const(fat).allow_cast(entt::resolve<fat_t>()));
  926. ASSERT_TRUE(std::as_const(fat).allow_cast(entt::resolve<empty_t>()));
  927. ASSERT_EQ(fat.type(), entt::resolve<fat_t>());
  928. ASSERT_FALSE(fat.allow_cast(entt::resolve<int>()));
  929. ASSERT_TRUE(arithmetic.allow_cast(entt::resolve<int>()));
  930. ASSERT_EQ(arithmetic.type(), entt::resolve<int>());
  931. ASSERT_FALSE(arithmetic.allow_cast(entt::resolve<fat_t>()));
  932. ASSERT_TRUE(arithmetic.allow_cast(entt::resolve<double>()));
  933. ASSERT_EQ(arithmetic.type(), entt::resolve<double>());
  934. ASSERT_EQ(arithmetic.cast<double &>(), 42.);
  935. ASSERT_TRUE(arithmetic.allow_cast(entt::resolve<float>()));
  936. ASSERT_EQ(arithmetic.type(), entt::resolve<float>());
  937. ASSERT_EQ(arithmetic.cast<float &>(), 42.f);
  938. ASSERT_TRUE(as_cref.allow_cast(entt::resolve<int>()));
  939. ASSERT_EQ(as_cref.type(), entt::resolve<int>());
  940. ASSERT_FALSE(as_cref.allow_cast(entt::resolve<fat_t>()));
  941. ASSERT_TRUE(as_cref.allow_cast(entt::resolve<double>()));
  942. ASSERT_EQ(as_cref.type(), entt::resolve<double>());
  943. ASSERT_TRUE(as_cref.allow_cast(entt::resolve<float>()));
  944. ASSERT_EQ(as_cref.type(), entt::resolve<float>());
  945. }
  946. TEST_F(MetaAny, Convert) {
  947. entt::meta_any any{clazz_t{}};
  948. any.cast<clazz_t &>().value = 42;
  949. auto as_int = std::as_const(any).allow_cast<int>();
  950. ASSERT_TRUE(any);
  951. ASSERT_EQ(any.type(), entt::resolve<clazz_t>());
  952. ASSERT_TRUE(any.allow_cast<clazz_t>());
  953. ASSERT_EQ(any.type(), entt::resolve<clazz_t>());
  954. ASSERT_TRUE(any.allow_cast<int>());
  955. ASSERT_EQ(any.type(), entt::resolve<int>());
  956. ASSERT_EQ(any.cast<int>(), 42);
  957. ASSERT_TRUE(as_int);
  958. ASSERT_EQ(as_int.type(), entt::resolve<int>());
  959. ASSERT_EQ(as_int.cast<int>(), 42);
  960. ASSERT_TRUE(as_int.allow_cast<char>());
  961. ASSERT_EQ(as_int.type(), entt::resolve<char>());
  962. ASSERT_EQ(as_int.cast<char>(), char{42});
  963. }
  964. TEST_F(MetaAny, ArithmeticConversion) {
  965. entt::meta_any any{'c'};
  966. ASSERT_EQ(any.type(), entt::resolve<char>());
  967. ASSERT_EQ(any.cast<char>(), 'c');
  968. ASSERT_TRUE(any.allow_cast<double>());
  969. ASSERT_EQ(any.type(), entt::resolve<double>());
  970. ASSERT_EQ(any.cast<double>(), static_cast<double>('c'));
  971. any = 3.1;
  972. ASSERT_TRUE(any.allow_cast(entt::resolve<int>()));
  973. ASSERT_EQ(any.type(), entt::resolve<int>());
  974. ASSERT_EQ(any.cast<int>(), 3);
  975. ASSERT_TRUE(any.allow_cast<float>());
  976. ASSERT_EQ(any.type(), entt::resolve<float>());
  977. ASSERT_EQ(any.cast<float>(), 3.f);
  978. any = static_cast<float>('c');
  979. ASSERT_TRUE(any.allow_cast<char>());
  980. ASSERT_EQ(any.type(), entt::resolve<char>());
  981. ASSERT_EQ(any.cast<char>(), 'c');
  982. }
  983. TEST_F(MetaAny, EnumConversion) {
  984. entt::meta_any any{enum_class::foo};
  985. ASSERT_EQ(any.type(), entt::resolve<enum_class>());
  986. ASSERT_EQ(any.cast<enum_class>(), enum_class::foo);
  987. ASSERT_TRUE(any.allow_cast<double>());
  988. ASSERT_EQ(any.type(), entt::resolve<double>());
  989. ASSERT_EQ(any.cast<double>(), 0.);
  990. any = enum_class::bar;
  991. ASSERT_TRUE(any.allow_cast(entt::resolve<int>()));
  992. ASSERT_EQ(any.type(), entt::resolve<int>());
  993. ASSERT_EQ(any.cast<int>(), 42);
  994. ASSERT_TRUE(any.allow_cast<enum_class>());
  995. ASSERT_EQ(any.type(), entt::resolve<enum_class>());
  996. ASSERT_EQ(any.cast<enum_class>(), enum_class::bar);
  997. any = 0;
  998. ASSERT_TRUE(any.allow_cast(entt::resolve<enum_class>()));
  999. ASSERT_EQ(any.type(), entt::resolve<enum_class>());
  1000. ASSERT_EQ(any.cast<enum_class>(), enum_class::foo);
  1001. }
  1002. TEST_F(MetaAny, UnmanageableType) {
  1003. unmanageable_t instance;
  1004. auto any = entt::forward_as_meta(instance);
  1005. entt::meta_any other = any.as_ref();
  1006. std::swap(any, other);
  1007. ASSERT_TRUE(any);
  1008. ASSERT_TRUE(other);
  1009. ASSERT_EQ(any.type(), entt::resolve<unmanageable_t>());
  1010. ASSERT_NE(any.data(), nullptr);
  1011. ASSERT_EQ(any.try_cast<int>(), nullptr);
  1012. ASSERT_NE(any.try_cast<unmanageable_t>(), nullptr);
  1013. ASSERT_TRUE(any.allow_cast<unmanageable_t>());
  1014. ASSERT_FALSE(any.allow_cast<int>());
  1015. ASSERT_TRUE(std::as_const(any).allow_cast<unmanageable_t>());
  1016. ASSERT_FALSE(std::as_const(any).allow_cast<int>());
  1017. }
  1018. TEST_F(MetaAny, Invoke) {
  1019. using namespace entt::literals;
  1020. clazz_t instance;
  1021. auto any = entt::forward_as_meta(instance);
  1022. ASSERT_TRUE(any.invoke("func"_hs));
  1023. ASSERT_TRUE(any.invoke("member"_hs, 42));
  1024. ASSERT_FALSE(std::as_const(any).invoke("member"_hs, 42));
  1025. ASSERT_FALSE(std::as_const(any).as_ref().invoke("member"_hs, 42));
  1026. ASSERT_FALSE(any.invoke("non_existent"_hs, 42));
  1027. ASSERT_EQ(clazz_t::c, 'd');
  1028. ASSERT_EQ(instance.value, 42);
  1029. }
  1030. TEST_F(MetaAny, SetGet) {
  1031. using namespace entt::literals;
  1032. clazz_t instance;
  1033. auto any = entt::forward_as_meta(instance);
  1034. ASSERT_TRUE(any.set("value"_hs, 42));
  1035. const auto value = std::as_const(any).get("value"_hs);
  1036. ASSERT_TRUE(value);
  1037. ASSERT_EQ(value, any.get("value"_hs));
  1038. ASSERT_EQ(value, std::as_const(any).as_ref().get("value"_hs));
  1039. ASSERT_NE(value.try_cast<int>(), nullptr);
  1040. ASSERT_EQ(value.cast<int>(), 42);
  1041. ASSERT_EQ(instance.value, 42);
  1042. ASSERT_FALSE(any.set("non_existent"_hs, 42));
  1043. ASSERT_FALSE(any.get("non_existent"_hs));
  1044. }
  1045. TEST_F(MetaAny, ForwardAsMeta) {
  1046. int value = 42;
  1047. auto ref = entt::forward_as_meta(value);
  1048. auto cref = entt::forward_as_meta(std::as_const(value));
  1049. auto any = entt::forward_as_meta(std::move(value));
  1050. ASSERT_TRUE(any);
  1051. ASSERT_TRUE(ref);
  1052. ASSERT_TRUE(cref);
  1053. ASSERT_NE(any.try_cast<int>(), nullptr);
  1054. ASSERT_NE(ref.try_cast<int>(), nullptr);
  1055. ASSERT_EQ(cref.try_cast<int>(), nullptr);
  1056. ASSERT_EQ(any.cast<const int &>(), 42);
  1057. ASSERT_EQ(ref.cast<const int &>(), 42);
  1058. ASSERT_EQ(cref.cast<const int &>(), 42);
  1059. ASSERT_NE(any.data(), &value);
  1060. ASSERT_EQ(ref.data(), &value);
  1061. }