any.cpp 44 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540
  1. #include <array>
  2. #include <cstddef>
  3. #include <cstdint>
  4. #include <cstring>
  5. #include <memory>
  6. #include <unordered_map>
  7. #include <utility>
  8. #include <vector>
  9. #include <gtest/gtest.h>
  10. #include <entt/core/any.hpp>
  11. #include <entt/core/type_info.hpp>
  12. #include "../../common/aggregate.h"
  13. #include "../../common/config.h"
  14. #include "../../common/linter.hpp"
  15. #include "../../common/non_comparable.h"
  16. #include "../../common/non_movable.h"
  17. template<std::size_t Len>
  18. struct tracker {
  19. tracker(int &cnt)
  20. : counter{&cnt} {}
  21. tracker(const tracker &) = default;
  22. tracker &operator=(const tracker &) = delete;
  23. ~tracker() {
  24. ++(*counter);
  25. }
  26. private:
  27. std::array<std::byte, Len> buffer{};
  28. int *counter{};
  29. };
  30. struct fat {
  31. fat(double v1, double v2, double v3, double v4)
  32. : value{v1, v2, v3, v4} {}
  33. [[nodiscard]] bool operator==(const fat &other) const {
  34. return (value == other.value);
  35. }
  36. std::array<double, 4u> value{};
  37. };
  38. struct alignas(64u) over_aligned {};
  39. TEST(Any, SBO) {
  40. entt::any any{'c'};
  41. ASSERT_TRUE(any);
  42. ASSERT_EQ(any.policy(), entt::any_policy::owner);
  43. ASSERT_EQ(any.type(), entt::type_id<char>());
  44. ASSERT_EQ(entt::any_cast<double>(&any), nullptr);
  45. ASSERT_EQ(entt::any_cast<char>(any), 'c');
  46. }
  47. TEST(Any, NoSBO) {
  48. const fat instance{.1, .2, .3, .4};
  49. entt::any any{instance};
  50. ASSERT_TRUE(any);
  51. ASSERT_EQ(any.policy(), entt::any_policy::owner);
  52. ASSERT_EQ(any.type(), entt::type_id<fat>());
  53. ASSERT_EQ(entt::any_cast<double>(&any), nullptr);
  54. ASSERT_EQ(entt::any_cast<fat>(any), instance);
  55. }
  56. TEST(Any, Empty) {
  57. entt::any any{};
  58. ASSERT_FALSE(any);
  59. ASSERT_EQ(any.policy(), entt::any_policy::owner);
  60. ASSERT_EQ(any.type(), entt::type_id<void>());
  61. ASSERT_EQ(entt::any_cast<double>(&any), nullptr);
  62. ASSERT_EQ(any.data(), nullptr);
  63. }
  64. TEST(Any, SBOInPlaceTypeConstruction) {
  65. entt::any any{std::in_place_type<int>, 2};
  66. ASSERT_TRUE(any);
  67. ASSERT_EQ(any.policy(), entt::any_policy::owner);
  68. ASSERT_EQ(any.type(), entt::type_id<int>());
  69. ASSERT_EQ(entt::any_cast<double>(&any), nullptr);
  70. ASSERT_EQ(entt::any_cast<int>(any), 2);
  71. auto other = any.as_ref();
  72. ASSERT_TRUE(other);
  73. ASSERT_EQ(other.policy(), entt::any_policy::ref);
  74. ASSERT_EQ(other.type(), entt::type_id<int>());
  75. ASSERT_EQ(entt::any_cast<int>(other), 2);
  76. ASSERT_EQ(other.data(), any.data());
  77. }
  78. TEST(Any, SBOAsRefConstruction) {
  79. int value = 2;
  80. entt::any any{entt::forward_as_any(value)};
  81. ASSERT_TRUE(any);
  82. ASSERT_EQ(any.policy(), entt::any_policy::ref);
  83. ASSERT_EQ(any.type(), entt::type_id<int>());
  84. ASSERT_EQ(entt::any_cast<double>(&any), nullptr);
  85. ASSERT_EQ(entt::any_cast<const int>(&any), &value);
  86. ASSERT_EQ(entt::any_cast<int>(&any), &value);
  87. ASSERT_EQ(entt::any_cast<const int>(&std::as_const(any)), &value);
  88. ASSERT_EQ(entt::any_cast<int>(&std::as_const(any)), &value);
  89. ASSERT_EQ(entt::any_cast<const int &>(any), 2);
  90. ASSERT_EQ(entt::any_cast<int>(any), 2);
  91. ASSERT_EQ(any.data(), &value);
  92. ASSERT_EQ(std::as_const(any).data(), &value);
  93. any.emplace<int &>(value);
  94. ASSERT_TRUE(any);
  95. ASSERT_EQ(any.policy(), entt::any_policy::ref);
  96. ASSERT_EQ(any.type(), entt::type_id<int>());
  97. ASSERT_EQ(entt::any_cast<int>(&any), &value);
  98. auto other = any.as_ref();
  99. ASSERT_TRUE(other);
  100. ASSERT_EQ(other.policy(), entt::any_policy::ref);
  101. ASSERT_EQ(other.type(), entt::type_id<int>());
  102. ASSERT_EQ(entt::any_cast<int>(other), 2);
  103. ASSERT_EQ(other.data(), any.data());
  104. }
  105. TEST(Any, SBOAsConstRefConstruction) {
  106. const int value = 2;
  107. entt::any any{entt::forward_as_any(value)};
  108. ASSERT_TRUE(any);
  109. ASSERT_EQ(any.policy(), entt::any_policy::cref);
  110. ASSERT_EQ(any.type(), entt::type_id<int>());
  111. ASSERT_EQ(entt::any_cast<double>(&any), nullptr);
  112. ASSERT_EQ(entt::any_cast<const int>(&any), &value);
  113. ASSERT_EQ(entt::any_cast<int>(&any), nullptr);
  114. ASSERT_EQ(entt::any_cast<const int>(&std::as_const(any)), &value);
  115. ASSERT_EQ(entt::any_cast<int>(&std::as_const(any)), &value);
  116. ASSERT_EQ(entt::any_cast<const int &>(any), 2);
  117. ASSERT_EQ(entt::any_cast<int>(any), 2);
  118. ASSERT_EQ(any.data(), nullptr);
  119. ASSERT_EQ(std::as_const(any).data(), &value);
  120. any.emplace<const int &>(value);
  121. ASSERT_TRUE(any);
  122. ASSERT_EQ(any.policy(), entt::any_policy::cref);
  123. ASSERT_EQ(any.type(), entt::type_id<int>());
  124. ASSERT_EQ(entt::any_cast<const int>(&any), &value);
  125. auto other = any.as_ref();
  126. ASSERT_TRUE(other);
  127. ASSERT_EQ(other.policy(), entt::any_policy::cref);
  128. ASSERT_EQ(other.type(), entt::type_id<int>());
  129. ASSERT_EQ(entt::any_cast<int>(other), 2);
  130. ASSERT_EQ(other.data(), any.data());
  131. }
  132. TEST(Any, SBOCopyConstruction) {
  133. const entt::any any{2};
  134. entt::any other{any};
  135. ASSERT_TRUE(any);
  136. ASSERT_TRUE(other);
  137. ASSERT_EQ(other.policy(), entt::any_policy::owner);
  138. ASSERT_EQ(other.type(), entt::type_id<int>());
  139. ASSERT_EQ(entt::any_cast<double>(&other), nullptr);
  140. ASSERT_EQ(entt::any_cast<int>(other), 2);
  141. }
  142. TEST(Any, SBOCopyAssignment) {
  143. const entt::any any{2};
  144. entt::any other{3};
  145. other = any;
  146. ASSERT_TRUE(any);
  147. ASSERT_TRUE(other);
  148. ASSERT_EQ(other.policy(), entt::any_policy::owner);
  149. ASSERT_EQ(other.type(), entt::type_id<int>());
  150. ASSERT_EQ(entt::any_cast<double>(&other), nullptr);
  151. ASSERT_EQ(entt::any_cast<int>(other), 2);
  152. }
  153. TEST(Any, SBOMoveConstruction) {
  154. entt::any any{2};
  155. entt::any other{std::move(any)};
  156. test::is_initialized(any);
  157. ASSERT_TRUE(any);
  158. ASSERT_TRUE(other);
  159. ASSERT_EQ(other.policy(), entt::any_policy::owner);
  160. ASSERT_EQ(other.type(), entt::type_id<int>());
  161. ASSERT_EQ(entt::any_cast<double>(&other), nullptr);
  162. ASSERT_EQ(entt::any_cast<int>(other), 2);
  163. }
  164. TEST(Any, SBOMoveAssignment) {
  165. entt::any any{2};
  166. entt::any other{3};
  167. other = std::move(any);
  168. test::is_initialized(any);
  169. ASSERT_TRUE(any);
  170. ASSERT_TRUE(other);
  171. ASSERT_EQ(other.policy(), entt::any_policy::owner);
  172. ASSERT_EQ(other.type(), entt::type_id<int>());
  173. ASSERT_EQ(entt::any_cast<double>(&other), nullptr);
  174. ASSERT_EQ(entt::any_cast<int>(other), 2);
  175. }
  176. TEST(Any, SBODirectAssignment) {
  177. entt::any any{};
  178. any = 2;
  179. ASSERT_TRUE(any);
  180. ASSERT_EQ(any.policy(), entt::any_policy::owner);
  181. ASSERT_EQ(any.type(), entt::type_id<int>());
  182. ASSERT_EQ(entt::any_cast<double>(&any), nullptr);
  183. ASSERT_EQ(entt::any_cast<int>(any), 2);
  184. }
  185. TEST(Any, SBOAssignValue) {
  186. entt::any any{2};
  187. const entt::any other{3};
  188. const entt::any invalid{'c'};
  189. ASSERT_TRUE(any);
  190. ASSERT_EQ(entt::any_cast<int>(any), 2);
  191. ASSERT_TRUE(any.assign(other));
  192. ASSERT_FALSE(any.assign(invalid));
  193. ASSERT_EQ(entt::any_cast<int>(any), 3);
  194. }
  195. TEST(Any, SBOAsRefAssignValue) {
  196. int value = 2;
  197. entt::any any{entt::forward_as_any(value)};
  198. const entt::any other{3};
  199. const entt::any invalid{'c'};
  200. ASSERT_TRUE(any);
  201. ASSERT_EQ(entt::any_cast<int>(any), 2);
  202. ASSERT_TRUE(any.assign(other));
  203. ASSERT_FALSE(any.assign(invalid));
  204. ASSERT_EQ(entt::any_cast<int>(any), 3);
  205. ASSERT_EQ(value, 3);
  206. }
  207. TEST(Any, SBOAsConstRefAssignValue) {
  208. const int value = 2;
  209. entt::any any{entt::forward_as_any(value)};
  210. const entt::any other{3};
  211. const entt::any invalid{'c'};
  212. ASSERT_TRUE(any);
  213. ASSERT_EQ(entt::any_cast<int>(any), 2);
  214. ASSERT_FALSE(any.assign(other));
  215. ASSERT_FALSE(any.assign(invalid));
  216. ASSERT_EQ(entt::any_cast<int>(any), 2);
  217. ASSERT_EQ(value, 2);
  218. }
  219. TEST(Any, SBOTransferValue) {
  220. entt::any any{2};
  221. ASSERT_TRUE(any);
  222. ASSERT_EQ(entt::any_cast<int>(any), 2);
  223. ASSERT_TRUE(any.assign(3));
  224. ASSERT_FALSE(any.assign('c'));
  225. ASSERT_EQ(entt::any_cast<int>(any), 3);
  226. }
  227. TEST(Any, SBOTransferConstValue) {
  228. const int value = 3;
  229. entt::any any{2};
  230. ASSERT_TRUE(any);
  231. ASSERT_EQ(entt::any_cast<int>(any), 2);
  232. ASSERT_TRUE(any.assign(entt::forward_as_any(value)));
  233. ASSERT_EQ(entt::any_cast<int>(any), 3);
  234. }
  235. TEST(Any, SBOAsRefTransferValue) {
  236. int value = 2;
  237. entt::any any{entt::forward_as_any(value)};
  238. ASSERT_TRUE(any);
  239. ASSERT_EQ(entt::any_cast<int>(any), 2);
  240. ASSERT_TRUE(any.assign(3));
  241. ASSERT_FALSE(any.assign('c'));
  242. ASSERT_EQ(entt::any_cast<int>(any), 3);
  243. ASSERT_EQ(value, 3);
  244. }
  245. TEST(Any, SBOAsConstRefTransferValue) {
  246. const int value = 2;
  247. entt::any any{entt::forward_as_any(value)};
  248. ASSERT_TRUE(any);
  249. ASSERT_EQ(entt::any_cast<int>(any), 2);
  250. ASSERT_FALSE(any.assign(3));
  251. ASSERT_FALSE(any.assign('c'));
  252. ASSERT_EQ(entt::any_cast<int>(any), 2);
  253. ASSERT_EQ(value, 2);
  254. }
  255. TEST(Any, NoSBOInPlaceTypeConstruction) {
  256. const fat instance{.1, .2, .3, .4};
  257. entt::any any{std::in_place_type<fat>, instance};
  258. ASSERT_TRUE(any);
  259. ASSERT_EQ(any.policy(), entt::any_policy::owner);
  260. ASSERT_EQ(any.type(), entt::type_id<fat>());
  261. ASSERT_EQ(entt::any_cast<double>(&any), nullptr);
  262. ASSERT_EQ(entt::any_cast<fat>(any), instance);
  263. auto other = any.as_ref();
  264. ASSERT_TRUE(other);
  265. ASSERT_EQ(other.policy(), entt::any_policy::ref);
  266. ASSERT_EQ(other.type(), entt::type_id<fat>());
  267. ASSERT_EQ(entt::any_cast<fat>(other), (fat{.1, .2, .3, .4}));
  268. ASSERT_EQ(other.data(), any.data());
  269. }
  270. TEST(Any, NoSBOAsRefConstruction) {
  271. fat instance{.1, .2, .3, .4};
  272. entt::any any{entt::forward_as_any(instance)};
  273. ASSERT_TRUE(any);
  274. ASSERT_EQ(any.policy(), entt::any_policy::ref);
  275. ASSERT_EQ(any.policy(), entt::any_policy::ref);
  276. ASSERT_EQ(any.type(), entt::type_id<fat>());
  277. ASSERT_EQ(entt::any_cast<double>(&any), nullptr);
  278. ASSERT_EQ(entt::any_cast<const fat>(&any), &instance);
  279. ASSERT_EQ(entt::any_cast<fat>(&any), &instance);
  280. ASSERT_EQ(entt::any_cast<const fat>(&std::as_const(any)), &instance);
  281. ASSERT_EQ(entt::any_cast<fat>(&std::as_const(any)), &instance);
  282. ASSERT_EQ(entt::any_cast<const fat &>(any), instance);
  283. ASSERT_EQ(entt::any_cast<fat>(any), instance);
  284. ASSERT_EQ(any.data(), &instance);
  285. ASSERT_EQ(std::as_const(any).data(), &instance);
  286. any.emplace<fat &>(instance);
  287. ASSERT_TRUE(any);
  288. ASSERT_EQ(any.policy(), entt::any_policy::ref);
  289. ASSERT_EQ(any.type(), entt::type_id<fat>());
  290. ASSERT_EQ(entt::any_cast<fat>(&any), &instance);
  291. auto other = any.as_ref();
  292. ASSERT_TRUE(other);
  293. ASSERT_EQ(other.policy(), entt::any_policy::ref);
  294. ASSERT_EQ(other.type(), entt::type_id<fat>());
  295. ASSERT_EQ(entt::any_cast<fat>(other), (fat{.1, .2, .3, .4}));
  296. ASSERT_EQ(other.data(), any.data());
  297. }
  298. TEST(Any, NoSBOAsConstRefConstruction) {
  299. const fat instance{.1, .2, .3, .4};
  300. entt::any any{entt::forward_as_any(instance)};
  301. ASSERT_TRUE(any);
  302. ASSERT_EQ(any.policy(), entt::any_policy::cref);
  303. ASSERT_EQ(any.type(), entt::type_id<fat>());
  304. ASSERT_EQ(entt::any_cast<double>(&any), nullptr);
  305. ASSERT_EQ(entt::any_cast<const fat>(&any), &instance);
  306. ASSERT_EQ(entt::any_cast<fat>(&any), nullptr);
  307. ASSERT_EQ(entt::any_cast<const fat>(&std::as_const(any)), &instance);
  308. ASSERT_EQ(entt::any_cast<fat>(&std::as_const(any)), &instance);
  309. ASSERT_EQ(entt::any_cast<const fat &>(any), instance);
  310. ASSERT_EQ(entt::any_cast<fat>(any), instance);
  311. ASSERT_EQ(any.data(), nullptr);
  312. ASSERT_EQ(std::as_const(any).data(), &instance);
  313. any.emplace<const fat &>(instance);
  314. ASSERT_TRUE(any);
  315. ASSERT_EQ(any.policy(), entt::any_policy::cref);
  316. ASSERT_EQ(any.type(), entt::type_id<fat>());
  317. ASSERT_EQ(entt::any_cast<const fat>(&any), &instance);
  318. auto other = any.as_ref();
  319. ASSERT_TRUE(other);
  320. ASSERT_EQ(other.policy(), entt::any_policy::cref);
  321. ASSERT_EQ(other.type(), entt::type_id<fat>());
  322. ASSERT_EQ(entt::any_cast<fat>(other), (fat{.1, .2, .3, .4}));
  323. ASSERT_EQ(other.data(), any.data());
  324. }
  325. TEST(Any, NoSBOCopyConstruction) {
  326. const fat instance{.1, .2, .3, .4};
  327. const entt::any any{instance};
  328. entt::any other{any};
  329. ASSERT_TRUE(any);
  330. ASSERT_TRUE(other);
  331. ASSERT_EQ(other.policy(), entt::any_policy::owner);
  332. ASSERT_EQ(other.type(), entt::type_id<fat>());
  333. ASSERT_EQ(entt::any_cast<double>(&other), nullptr);
  334. ASSERT_EQ(entt::any_cast<fat>(other), instance);
  335. }
  336. TEST(Any, NoSBOCopyAssignment) {
  337. const fat instance{.1, .2, .3, .4};
  338. const entt::any any{instance};
  339. entt::any other{3};
  340. other = any;
  341. ASSERT_TRUE(any);
  342. ASSERT_TRUE(other);
  343. ASSERT_EQ(other.policy(), entt::any_policy::owner);
  344. ASSERT_EQ(other.type(), entt::type_id<fat>());
  345. ASSERT_EQ(entt::any_cast<double>(&other), nullptr);
  346. ASSERT_EQ(entt::any_cast<fat>(other), instance);
  347. }
  348. TEST(Any, NoSBOMoveConstruction) {
  349. const fat instance{.1, .2, .3, .4};
  350. entt::any any{instance};
  351. entt::any other{std::move(any)};
  352. test::is_initialized(any);
  353. ASSERT_TRUE(any);
  354. ASSERT_TRUE(other);
  355. ASSERT_EQ(other.policy(), entt::any_policy::owner);
  356. ASSERT_EQ(other.type(), entt::type_id<fat>());
  357. ASSERT_EQ(entt::any_cast<double>(&other), nullptr);
  358. ASSERT_EQ(entt::any_cast<fat>(other), instance);
  359. }
  360. TEST(Any, NoSBOMoveAssignment) {
  361. const fat instance{.1, .2, .3, .4};
  362. entt::any any{instance};
  363. entt::any other{3};
  364. other = std::move(any);
  365. test::is_initialized(any);
  366. ASSERT_TRUE(any);
  367. ASSERT_TRUE(other);
  368. ASSERT_EQ(other.policy(), entt::any_policy::owner);
  369. ASSERT_EQ(other.type(), entt::type_id<fat>());
  370. ASSERT_EQ(entt::any_cast<double>(&other), nullptr);
  371. ASSERT_EQ(entt::any_cast<fat>(other), instance);
  372. }
  373. TEST(Any, NoSBODirectAssignment) {
  374. const fat instance{.1, .2, .3, .4};
  375. entt::any any{};
  376. any = instance;
  377. ASSERT_TRUE(any);
  378. ASSERT_EQ(any.policy(), entt::any_policy::owner);
  379. ASSERT_EQ(any.type(), entt::type_id<fat>());
  380. ASSERT_EQ(entt::any_cast<double>(&any), nullptr);
  381. ASSERT_EQ(entt::any_cast<fat>(any), instance);
  382. }
  383. TEST(Any, NoSBOAssignValue) {
  384. entt::any any{fat{.1, .2, .3, .4}};
  385. const entt::any other{fat{.0, .1, .2, .3}};
  386. const entt::any invalid{'c'};
  387. const void *addr = std::as_const(any).data();
  388. ASSERT_TRUE(any);
  389. ASSERT_EQ(entt::any_cast<const fat &>(any), (fat{.1, .2, .3, .4}));
  390. ASSERT_TRUE(any.assign(other));
  391. ASSERT_FALSE(any.assign(invalid));
  392. ASSERT_EQ(entt::any_cast<const fat &>(any), (fat{.0, .1, .2, .3}));
  393. ASSERT_EQ(addr, std::as_const(any).data());
  394. }
  395. TEST(Any, NoSBOAsRefAssignValue) {
  396. fat instance{.1, .2, .3, .4};
  397. entt::any any{entt::forward_as_any(instance)};
  398. const entt::any other{fat{.0, .1, .2, .3}};
  399. const entt::any invalid{'c'};
  400. ASSERT_TRUE(any);
  401. ASSERT_EQ(entt::any_cast<const fat &>(any), (fat{.1, .2, .3, .4}));
  402. ASSERT_TRUE(any.assign(other));
  403. ASSERT_FALSE(any.assign(invalid));
  404. ASSERT_EQ(entt::any_cast<const fat &>(any), (fat{.0, .1, .2, .3}));
  405. ASSERT_EQ(instance, (fat{.0, .1, .2, .3}));
  406. }
  407. TEST(Any, NoSBOAsConstRefAssignValue) {
  408. const fat instance{.1, .2, .3, .4};
  409. entt::any any{entt::forward_as_any(instance)};
  410. const entt::any other{fat{.0, .1, .2, .3}};
  411. const entt::any invalid{'c'};
  412. ASSERT_TRUE(any);
  413. ASSERT_EQ(entt::any_cast<const fat &>(any), (fat{.1, .2, .3, .4}));
  414. ASSERT_FALSE(any.assign(other));
  415. ASSERT_FALSE(any.assign(invalid));
  416. ASSERT_EQ(entt::any_cast<const fat &>(any), (fat{.1, .2, .3, .4}));
  417. ASSERT_EQ(instance, (fat{.1, .2, .3, .4}));
  418. }
  419. TEST(Any, NoSBOTransferValue) {
  420. entt::any any{fat{.1, .2, .3, .4}};
  421. const void *addr = std::as_const(any).data();
  422. ASSERT_TRUE(any);
  423. ASSERT_EQ(entt::any_cast<const fat &>(any), (fat{.1, .2, .3, .4}));
  424. ASSERT_TRUE(any.assign(fat{.0, .1, .2, .3}));
  425. ASSERT_FALSE(any.assign('c'));
  426. ASSERT_EQ(entt::any_cast<const fat &>(any), (fat{.0, .1, .2, .3}));
  427. ASSERT_EQ(addr, std::as_const(any).data());
  428. }
  429. TEST(Any, NoSBOTransferConstValue) {
  430. const fat instance{.0, .1, .2, .3};
  431. entt::any any{fat{.1, .2, .3, .4}};
  432. const void *addr = std::as_const(any).data();
  433. ASSERT_TRUE(any);
  434. ASSERT_EQ(entt::any_cast<const fat &>(any), (fat{.1, .2, .3, .4}));
  435. ASSERT_TRUE(any.assign(entt::forward_as_any(instance)));
  436. ASSERT_EQ(entt::any_cast<const fat &>(any), (fat{.0, .1, .2, .3}));
  437. ASSERT_EQ(addr, std::as_const(any).data());
  438. }
  439. TEST(Any, NoSBOAsRefTransferValue) {
  440. fat instance{.1, .2, .3, .4};
  441. entt::any any{entt::forward_as_any(instance)};
  442. const void *addr = std::as_const(any).data();
  443. ASSERT_TRUE(any);
  444. ASSERT_EQ(entt::any_cast<const fat &>(any), (fat{.1, .2, .3, .4}));
  445. ASSERT_TRUE(any.assign(fat{.0, .1, .2, .3}));
  446. ASSERT_FALSE(any.assign('c'));
  447. ASSERT_EQ(entt::any_cast<const fat &>(any), (fat{.0, .1, .2, .3}));
  448. ASSERT_EQ(instance, (fat{.0, .1, .2, .3}));
  449. ASSERT_EQ(addr, std::as_const(any).data());
  450. }
  451. TEST(Any, NoSBOAsConstRefTransferValue) {
  452. const fat instance{.1, .2, .3, .4};
  453. entt::any any{entt::forward_as_any(instance)};
  454. const void *addr = std::as_const(any).data();
  455. ASSERT_TRUE(any);
  456. ASSERT_EQ(entt::any_cast<const fat &>(any), (fat{.1, .2, .3, .4}));
  457. ASSERT_FALSE(any.assign(fat{.0, .1, .2, .3}));
  458. ASSERT_FALSE(any.assign('c'));
  459. ASSERT_EQ(entt::any_cast<const fat &>(any), (fat{.1, .2, .3, .4}));
  460. ASSERT_EQ(instance, (fat{.1, .2, .3, .4}));
  461. ASSERT_EQ(addr, std::as_const(any).data());
  462. }
  463. TEST(Any, VoidInPlaceTypeConstruction) {
  464. entt::any any{std::in_place_type<void>};
  465. ASSERT_FALSE(any);
  466. ASSERT_EQ(any.policy(), entt::any_policy::owner);
  467. ASSERT_EQ(any.type(), entt::type_id<void>());
  468. ASSERT_EQ(entt::any_cast<int>(&any), nullptr);
  469. }
  470. TEST(Any, VoidCopyConstruction) {
  471. entt::any any{std::in_place_type<void>};
  472. entt::any other{any};
  473. ASSERT_FALSE(any);
  474. ASSERT_FALSE(other);
  475. ASSERT_EQ(other.policy(), entt::any_policy::owner);
  476. ASSERT_EQ(other.type(), entt::type_id<void>());
  477. ASSERT_EQ(entt::any_cast<int>(&any), nullptr);
  478. ASSERT_EQ(entt::any_cast<double>(&other), nullptr);
  479. }
  480. TEST(Any, VoidCopyAssignment) {
  481. entt::any any{std::in_place_type<void>};
  482. entt::any other{2};
  483. other = any;
  484. ASSERT_FALSE(any);
  485. ASSERT_FALSE(other);
  486. ASSERT_EQ(other.policy(), entt::any_policy::owner);
  487. ASSERT_EQ(other.type(), entt::type_id<void>());
  488. ASSERT_EQ(entt::any_cast<int>(&any), nullptr);
  489. ASSERT_EQ(entt::any_cast<double>(&other), nullptr);
  490. }
  491. TEST(Any, VoidMoveConstruction) {
  492. entt::any any{std::in_place_type<void>};
  493. entt::any other{std::move(any)};
  494. test::is_initialized(any);
  495. ASSERT_FALSE(any);
  496. ASSERT_FALSE(other);
  497. ASSERT_EQ(other.policy(), entt::any_policy::owner);
  498. ASSERT_EQ(other.type(), entt::type_id<void>());
  499. ASSERT_EQ(entt::any_cast<double>(&other), nullptr);
  500. }
  501. TEST(Any, VoidMoveAssignment) {
  502. entt::any any{std::in_place_type<void>};
  503. entt::any other{2};
  504. other = std::move(any);
  505. test::is_initialized(any);
  506. ASSERT_FALSE(any);
  507. ASSERT_FALSE(other);
  508. ASSERT_EQ(other.policy(), entt::any_policy::owner);
  509. ASSERT_EQ(other.type(), entt::type_id<void>());
  510. ASSERT_EQ(entt::any_cast<double>(&other), nullptr);
  511. }
  512. TEST(Any, SBOMoveValidButUnspecifiedState) {
  513. entt::any any{2};
  514. entt::any other{std::move(any)};
  515. const entt::any valid = std::move(other);
  516. test::is_initialized(any);
  517. test::is_initialized(other);
  518. ASSERT_TRUE(any);
  519. ASSERT_TRUE(other);
  520. ASSERT_TRUE(valid);
  521. }
  522. TEST(Any, NoSBOMoveValidButUnspecifiedState) {
  523. const fat instance{.1, .2, .3, .4};
  524. entt::any any{instance};
  525. entt::any other{std::move(any)};
  526. const entt::any valid = std::move(other);
  527. test::is_initialized(any);
  528. test::is_initialized(other);
  529. ASSERT_TRUE(any);
  530. ASSERT_TRUE(other);
  531. ASSERT_TRUE(valid);
  532. }
  533. TEST(Any, VoidMoveValidButUnspecifiedState) {
  534. entt::any any{std::in_place_type<void>};
  535. entt::any other{std::move(any)};
  536. const entt::any valid = std::move(other);
  537. test::is_initialized(any);
  538. test::is_initialized(other);
  539. ASSERT_FALSE(any);
  540. ASSERT_FALSE(other);
  541. ASSERT_FALSE(valid);
  542. }
  543. TEST(Any, SBODestruction) {
  544. using tracker_type = tracker<0u>;
  545. int counter{};
  546. {
  547. entt::any any{std::in_place_type<tracker_type>, counter};
  548. any.emplace<tracker_type>(counter);
  549. any = tracker_type{counter};
  550. entt::any other{std::move(any)};
  551. any = std::move(other);
  552. }
  553. ASSERT_EQ(counter, 6);
  554. }
  555. TEST(Any, NoSBODestruction) {
  556. using tracker_type = tracker<entt::any::length>;
  557. int counter{};
  558. {
  559. entt::any any{std::in_place_type<tracker_type>, counter};
  560. any.emplace<tracker_type>(counter);
  561. any = tracker_type{counter};
  562. entt::any other{std::move(any)};
  563. any = std::move(other);
  564. }
  565. ASSERT_EQ(counter, 4);
  566. }
  567. TEST(Any, VoidDestruction) {
  568. // just let asan tell us if everything is ok here
  569. [[maybe_unused]] const entt::any any{std::in_place_type<void>};
  570. }
  571. TEST(Any, Emplace) {
  572. entt::any any{};
  573. any.emplace<int>(2);
  574. ASSERT_TRUE(any);
  575. ASSERT_EQ(any.policy(), entt::any_policy::owner);
  576. ASSERT_EQ(any.type(), entt::type_id<int>());
  577. ASSERT_EQ(entt::any_cast<double>(&any), nullptr);
  578. ASSERT_EQ(entt::any_cast<int>(any), 2);
  579. }
  580. TEST(Any, EmplaceVoid) {
  581. entt::any any{};
  582. any.emplace<void>();
  583. ASSERT_FALSE(any);
  584. ASSERT_EQ(any.policy(), entt::any_policy::owner);
  585. ASSERT_EQ(any.type(), entt::type_id<void>());
  586. }
  587. TEST(Any, Reset) {
  588. entt::any any{2};
  589. ASSERT_TRUE(any);
  590. ASSERT_EQ(any.policy(), entt::any_policy::owner);
  591. ASSERT_EQ(any.type(), entt::type_id<int>());
  592. any.reset();
  593. ASSERT_FALSE(any);
  594. ASSERT_EQ(any.policy(), entt::any_policy::owner);
  595. ASSERT_EQ(any.type(), entt::type_id<void>());
  596. int value = 2;
  597. any.emplace<int &>(value);
  598. ASSERT_TRUE(any);
  599. ASSERT_EQ(any.policy(), entt::any_policy::ref);
  600. ASSERT_EQ(any.type(), entt::type_id<int>());
  601. any.reset();
  602. ASSERT_FALSE(any);
  603. ASSERT_EQ(any.policy(), entt::any_policy::owner);
  604. ASSERT_EQ(any.type(), entt::type_id<void>());
  605. }
  606. TEST(Any, SBOSwap) {
  607. entt::any lhs{'c'};
  608. entt::any rhs{2};
  609. std::swap(lhs, rhs);
  610. ASSERT_EQ(lhs.policy(), entt::any_policy::owner);
  611. ASSERT_EQ(rhs.policy(), entt::any_policy::owner);
  612. ASSERT_EQ(lhs.type(), entt::type_id<int>());
  613. ASSERT_EQ(rhs.type(), entt::type_id<char>());
  614. ASSERT_EQ(entt::any_cast<char>(&lhs), nullptr);
  615. ASSERT_EQ(entt::any_cast<int>(&rhs), nullptr);
  616. ASSERT_EQ(entt::any_cast<int>(lhs), 2);
  617. ASSERT_EQ(entt::any_cast<char>(rhs), 'c');
  618. }
  619. TEST(Any, NoSBOSwap) {
  620. entt::any lhs{fat{.1, .2, .3, .4}};
  621. entt::any rhs{fat{.4, .3, .2, .1}};
  622. std::swap(lhs, rhs);
  623. ASSERT_EQ(lhs.policy(), entt::any_policy::owner);
  624. ASSERT_EQ(rhs.policy(), entt::any_policy::owner);
  625. ASSERT_EQ(entt::any_cast<fat>(lhs), (fat{.4, .3, .2, .1}));
  626. ASSERT_EQ(entt::any_cast<fat>(rhs), (fat{.1, .2, .3, .4}));
  627. }
  628. TEST(Any, VoidSwap) {
  629. entt::any lhs{std::in_place_type<void>};
  630. entt::any rhs{std::in_place_type<void>};
  631. const auto *pre = lhs.data();
  632. std::swap(lhs, rhs);
  633. ASSERT_EQ(lhs.policy(), entt::any_policy::owner);
  634. ASSERT_EQ(rhs.policy(), entt::any_policy::owner);
  635. ASSERT_EQ(pre, lhs.data());
  636. }
  637. TEST(Any, SBOWithNoSBOSwap) {
  638. entt::any lhs{fat{.1, .2, .3, .4}};
  639. entt::any rhs{'c'};
  640. std::swap(lhs, rhs);
  641. ASSERT_EQ(lhs.policy(), entt::any_policy::owner);
  642. ASSERT_EQ(rhs.policy(), entt::any_policy::owner);
  643. ASSERT_EQ(lhs.type(), entt::type_id<char>());
  644. ASSERT_EQ(rhs.type(), entt::type_id<fat>());
  645. ASSERT_EQ(entt::any_cast<fat>(&lhs), nullptr);
  646. ASSERT_EQ(entt::any_cast<char>(&rhs), nullptr);
  647. ASSERT_EQ(entt::any_cast<char>(lhs), 'c');
  648. ASSERT_EQ(entt::any_cast<fat>(rhs), (fat{.1, .2, .3, .4}));
  649. }
  650. TEST(Any, SBOWithRefSwap) {
  651. int value = 3;
  652. entt::any lhs{entt::forward_as_any(value)};
  653. entt::any rhs{'c'};
  654. std::swap(lhs, rhs);
  655. ASSERT_EQ(lhs.policy(), entt::any_policy::owner);
  656. ASSERT_EQ(rhs.policy(), entt::any_policy::ref);
  657. ASSERT_EQ(lhs.type(), entt::type_id<char>());
  658. ASSERT_EQ(rhs.type(), entt::type_id<int>());
  659. ASSERT_EQ(entt::any_cast<int>(&lhs), nullptr);
  660. ASSERT_EQ(entt::any_cast<char>(&rhs), nullptr);
  661. ASSERT_EQ(entt::any_cast<char>(lhs), 'c');
  662. ASSERT_EQ(entt::any_cast<int>(rhs), 3);
  663. ASSERT_EQ(rhs.data(), &value);
  664. }
  665. TEST(Any, SBOWithConstRefSwap) {
  666. const int value = 3;
  667. entt::any lhs{entt::forward_as_any(value)};
  668. entt::any rhs{'c'};
  669. std::swap(lhs, rhs);
  670. ASSERT_EQ(lhs.policy(), entt::any_policy::owner);
  671. ASSERT_EQ(rhs.policy(), entt::any_policy::cref);
  672. ASSERT_EQ(lhs.type(), entt::type_id<char>());
  673. ASSERT_EQ(rhs.type(), entt::type_id<int>());
  674. ASSERT_EQ(entt::any_cast<int>(&lhs), nullptr);
  675. ASSERT_EQ(entt::any_cast<char>(&rhs), nullptr);
  676. ASSERT_EQ(entt::any_cast<char>(lhs), 'c');
  677. ASSERT_EQ(entt::any_cast<int>(rhs), 3);
  678. ASSERT_EQ(rhs.data(), nullptr);
  679. ASSERT_EQ(std::as_const(rhs).data(), &value);
  680. }
  681. TEST(Any, SBOWithEmptySwap) {
  682. entt::any lhs{'c'};
  683. entt::any rhs{};
  684. std::swap(lhs, rhs);
  685. ASSERT_FALSE(lhs);
  686. ASSERT_EQ(lhs.policy(), entt::any_policy::owner);
  687. ASSERT_EQ(rhs.type(), entt::type_id<char>());
  688. ASSERT_EQ(entt::any_cast<char>(&lhs), nullptr);
  689. ASSERT_EQ(entt::any_cast<double>(&rhs), nullptr);
  690. ASSERT_EQ(entt::any_cast<char>(rhs), 'c');
  691. std::swap(lhs, rhs);
  692. ASSERT_FALSE(rhs);
  693. ASSERT_EQ(lhs.policy(), entt::any_policy::owner);
  694. ASSERT_EQ(lhs.type(), entt::type_id<char>());
  695. ASSERT_EQ(entt::any_cast<double>(&lhs), nullptr);
  696. ASSERT_EQ(entt::any_cast<char>(&rhs), nullptr);
  697. ASSERT_EQ(entt::any_cast<char>(lhs), 'c');
  698. }
  699. TEST(Any, SBOWithVoidSwap) {
  700. entt::any lhs{'c'};
  701. entt::any rhs{std::in_place_type<void>};
  702. std::swap(lhs, rhs);
  703. ASSERT_FALSE(lhs);
  704. ASSERT_EQ(lhs.policy(), entt::any_policy::owner);
  705. ASSERT_EQ(rhs.type(), entt::type_id<char>());
  706. ASSERT_EQ(entt::any_cast<char>(&lhs), nullptr);
  707. ASSERT_EQ(entt::any_cast<double>(&rhs), nullptr);
  708. ASSERT_EQ(entt::any_cast<char>(rhs), 'c');
  709. std::swap(lhs, rhs);
  710. ASSERT_FALSE(rhs);
  711. ASSERT_EQ(lhs.policy(), entt::any_policy::owner);
  712. ASSERT_EQ(lhs.type(), entt::type_id<char>());
  713. ASSERT_EQ(entt::any_cast<double>(&lhs), nullptr);
  714. ASSERT_EQ(entt::any_cast<char>(&rhs), nullptr);
  715. ASSERT_EQ(entt::any_cast<char>(lhs), 'c');
  716. }
  717. TEST(Any, NoSBOWithRefSwap) {
  718. int value = 3;
  719. entt::any lhs{entt::forward_as_any(value)};
  720. entt::any rhs{fat{.1, .2, .3, .4}};
  721. std::swap(lhs, rhs);
  722. ASSERT_EQ(lhs.policy(), entt::any_policy::owner);
  723. ASSERT_EQ(rhs.policy(), entt::any_policy::ref);
  724. ASSERT_EQ(lhs.type(), entt::type_id<fat>());
  725. ASSERT_EQ(rhs.type(), entt::type_id<int>());
  726. ASSERT_EQ(entt::any_cast<int>(&lhs), nullptr);
  727. ASSERT_EQ(entt::any_cast<fat>(&rhs), nullptr);
  728. ASSERT_EQ(entt::any_cast<fat>(lhs), (fat{.1, .2, .3, .4}));
  729. ASSERT_EQ(entt::any_cast<int>(rhs), 3);
  730. ASSERT_EQ(rhs.data(), &value);
  731. }
  732. TEST(Any, NoSBOWithConstRefSwap) {
  733. const int value = 3;
  734. entt::any lhs{entt::forward_as_any(value)};
  735. entt::any rhs{fat{.1, .2, .3, .4}};
  736. std::swap(lhs, rhs);
  737. ASSERT_EQ(lhs.policy(), entt::any_policy::owner);
  738. ASSERT_EQ(rhs.policy(), entt::any_policy::cref);
  739. ASSERT_EQ(lhs.type(), entt::type_id<fat>());
  740. ASSERT_EQ(rhs.type(), entt::type_id<int>());
  741. ASSERT_EQ(entt::any_cast<int>(&lhs), nullptr);
  742. ASSERT_EQ(entt::any_cast<fat>(&rhs), nullptr);
  743. ASSERT_EQ(entt::any_cast<fat>(lhs), (fat{.1, .2, .3, .4}));
  744. ASSERT_EQ(entt::any_cast<int>(rhs), 3);
  745. ASSERT_EQ(rhs.data(), nullptr);
  746. ASSERT_EQ(std::as_const(rhs).data(), &value);
  747. }
  748. TEST(Any, NoSBOWithEmptySwap) {
  749. entt::any lhs{fat{.1, .2, .3, .4}};
  750. entt::any rhs{};
  751. std::swap(lhs, rhs);
  752. ASSERT_FALSE(lhs);
  753. ASSERT_EQ(lhs.policy(), entt::any_policy::owner);
  754. ASSERT_EQ(rhs.type(), entt::type_id<fat>());
  755. ASSERT_EQ(entt::any_cast<fat>(&lhs), nullptr);
  756. ASSERT_EQ(entt::any_cast<double>(&rhs), nullptr);
  757. ASSERT_EQ(entt::any_cast<fat>(rhs), (fat{.1, .2, .3, .4}));
  758. std::swap(lhs, rhs);
  759. ASSERT_FALSE(rhs);
  760. ASSERT_EQ(lhs.policy(), entt::any_policy::owner);
  761. ASSERT_EQ(lhs.type(), entt::type_id<fat>());
  762. ASSERT_EQ(entt::any_cast<double>(&lhs), nullptr);
  763. ASSERT_EQ(entt::any_cast<fat>(&rhs), nullptr);
  764. ASSERT_EQ(entt::any_cast<fat>(lhs), (fat{.1, .2, .3, .4}));
  765. }
  766. TEST(Any, NoSBOWithVoidSwap) {
  767. entt::any lhs{fat{.1, .2, .3, .4}};
  768. entt::any rhs{std::in_place_type<void>};
  769. std::swap(lhs, rhs);
  770. ASSERT_FALSE(lhs);
  771. ASSERT_EQ(lhs.policy(), entt::any_policy::owner);
  772. ASSERT_EQ(rhs.type(), entt::type_id<fat>());
  773. ASSERT_EQ(entt::any_cast<fat>(&lhs), nullptr);
  774. ASSERT_EQ(entt::any_cast<double>(&rhs), nullptr);
  775. ASSERT_EQ(entt::any_cast<fat>(rhs), (fat{.1, .2, .3, .4}));
  776. std::swap(lhs, rhs);
  777. ASSERT_FALSE(rhs);
  778. ASSERT_EQ(lhs.policy(), entt::any_policy::owner);
  779. ASSERT_EQ(lhs.type(), entt::type_id<fat>());
  780. ASSERT_EQ(entt::any_cast<double>(&lhs), nullptr);
  781. ASSERT_EQ(entt::any_cast<fat>(&rhs), nullptr);
  782. ASSERT_EQ(entt::any_cast<fat>(lhs), (fat{.1, .2, .3, .4}));
  783. }
  784. TEST(Any, AsRef) {
  785. entt::any any{2};
  786. auto ref = any.as_ref();
  787. auto cref = std::as_const(any).as_ref();
  788. ASSERT_EQ(ref.policy(), entt::any_policy::ref);
  789. ASSERT_EQ(cref.policy(), entt::any_policy::cref);
  790. ASSERT_EQ(entt::any_cast<int>(&any), any.data());
  791. ASSERT_EQ(entt::any_cast<int>(&ref), any.data());
  792. ASSERT_EQ(entt::any_cast<int>(&cref), nullptr);
  793. ASSERT_EQ(entt::any_cast<const int>(&any), any.data());
  794. ASSERT_EQ(entt::any_cast<const int>(&ref), any.data());
  795. ASSERT_EQ(entt::any_cast<const int>(&cref), any.data());
  796. ASSERT_EQ(entt::any_cast<int>(any), 2);
  797. ASSERT_EQ(entt::any_cast<int>(ref), 2);
  798. ASSERT_EQ(entt::any_cast<int>(cref), 2);
  799. ASSERT_EQ(entt::any_cast<const int>(any), 2);
  800. ASSERT_EQ(entt::any_cast<const int>(ref), 2);
  801. ASSERT_EQ(entt::any_cast<const int>(cref), 2);
  802. ASSERT_EQ(entt::any_cast<int &>(any), 2);
  803. ASSERT_EQ(entt::any_cast<const int &>(any), 2);
  804. ASSERT_EQ(entt::any_cast<int &>(ref), 2);
  805. ASSERT_EQ(entt::any_cast<const int &>(ref), 2);
  806. ASSERT_EQ(entt::any_cast<int>(&cref), nullptr);
  807. ASSERT_EQ(entt::any_cast<const int &>(cref), 2);
  808. entt::any_cast<int &>(any) = 3;
  809. ASSERT_EQ(entt::any_cast<int>(any), 3);
  810. ASSERT_EQ(entt::any_cast<int>(ref), 3);
  811. ASSERT_EQ(entt::any_cast<int>(cref), 3);
  812. std::swap(ref, cref);
  813. ASSERT_EQ(ref.policy(), entt::any_policy::cref);
  814. ASSERT_EQ(cref.policy(), entt::any_policy::ref);
  815. ASSERT_EQ(entt::any_cast<int>(&ref), nullptr);
  816. ASSERT_EQ(entt::any_cast<int>(&cref), any.data());
  817. ref = ref.as_ref();
  818. cref = std::as_const(cref).as_ref();
  819. ASSERT_EQ(ref.policy(), entt::any_policy::cref);
  820. ASSERT_EQ(cref.policy(), entt::any_policy::cref);
  821. ASSERT_EQ(entt::any_cast<int>(&ref), nullptr);
  822. ASSERT_EQ(entt::any_cast<int>(&cref), nullptr);
  823. ASSERT_EQ(entt::any_cast<const int>(&ref), any.data());
  824. ASSERT_EQ(entt::any_cast<const int>(&cref), any.data());
  825. ASSERT_EQ(entt::any_cast<int>(&ref), nullptr);
  826. ASSERT_EQ(entt::any_cast<int>(&cref), nullptr);
  827. ASSERT_EQ(entt::any_cast<const int &>(ref), 3);
  828. ASSERT_EQ(entt::any_cast<const int &>(cref), 3);
  829. ref = 2;
  830. cref = 2;
  831. ASSERT_EQ(ref.policy(), entt::any_policy::owner);
  832. ASSERT_EQ(cref.policy(), entt::any_policy::owner);
  833. ASSERT_NE(entt::any_cast<int>(&ref), nullptr);
  834. ASSERT_NE(entt::any_cast<int>(&cref), nullptr);
  835. ASSERT_EQ(entt::any_cast<int &>(ref), 2);
  836. ASSERT_EQ(entt::any_cast<int &>(cref), 2);
  837. ASSERT_EQ(entt::any_cast<const int &>(ref), 2);
  838. ASSERT_EQ(entt::any_cast<const int &>(cref), 2);
  839. ASSERT_NE(entt::any_cast<int>(&ref), any.data());
  840. ASSERT_NE(entt::any_cast<int>(&cref), any.data());
  841. }
  842. TEST(Any, Comparable) {
  843. const entt::any any{'c'};
  844. const entt::any other{'a'};
  845. ASSERT_EQ(any, any);
  846. ASSERT_NE(other, any);
  847. ASSERT_NE(any, entt::any{});
  848. ASSERT_TRUE(any == any);
  849. ASSERT_FALSE(other == any);
  850. ASSERT_TRUE(any != other);
  851. ASSERT_TRUE(entt::any{} != any);
  852. }
  853. TEST(Any, NoSBOComparable) {
  854. const entt::any any{fat{.1, .2, .3, .4}};
  855. const entt::any other{fat{.0, .1, .2, .3}};
  856. ASSERT_EQ(any, any);
  857. ASSERT_NE(other, any);
  858. ASSERT_NE(any, entt::any{});
  859. ASSERT_TRUE(any == any);
  860. ASSERT_FALSE(other == any);
  861. ASSERT_TRUE(any != other);
  862. ASSERT_TRUE(entt::any{} != any);
  863. }
  864. TEST(Any, RefComparable) {
  865. int value = 2;
  866. const entt::any any{entt::forward_as_any(value)};
  867. const entt::any other{3};
  868. ASSERT_EQ(any, any);
  869. ASSERT_NE(other, any);
  870. ASSERT_NE(any, entt::any{});
  871. ASSERT_TRUE(any == any);
  872. ASSERT_FALSE(other == any);
  873. ASSERT_TRUE(any != other);
  874. ASSERT_TRUE(entt::any{} != any);
  875. }
  876. TEST(Any, ConstRefComparable) {
  877. int value = 2;
  878. const entt::any any{3};
  879. const entt::any other{entt::make_any<const int &>(value)};
  880. ASSERT_EQ(any, any);
  881. ASSERT_NE(other, any);
  882. ASSERT_NE(any, entt::any{});
  883. ASSERT_TRUE(any == any);
  884. ASSERT_FALSE(other == any);
  885. ASSERT_TRUE(any != other);
  886. ASSERT_TRUE(entt::any{} != any);
  887. }
  888. TEST(Any, UnrelatedComparable) {
  889. const entt::any any{'c'};
  890. const entt::any other{2};
  891. ASSERT_EQ(any, any);
  892. ASSERT_NE(other, any);
  893. ASSERT_NE(any, entt::any{});
  894. ASSERT_TRUE(any == any);
  895. ASSERT_FALSE(other == any);
  896. ASSERT_TRUE(any != other);
  897. ASSERT_TRUE(entt::any{} != any);
  898. }
  899. TEST(Any, NonComparable) {
  900. const test::non_comparable instance{};
  901. auto any = entt::forward_as_any(instance);
  902. ASSERT_EQ(any, any);
  903. ASSERT_NE(any, entt::any{instance});
  904. ASSERT_NE(entt::any{}, any);
  905. ASSERT_TRUE(any == any);
  906. ASSERT_FALSE(any == entt::any{instance});
  907. ASSERT_TRUE(entt::any{} != any);
  908. }
  909. TEST(Any, AssociativeContainerOfNonComparable) {
  910. const std::unordered_map<int, test::non_comparable> instance{};
  911. auto any = entt::forward_as_any(instance);
  912. ASSERT_EQ(any, any);
  913. ASSERT_NE(any, entt::any{instance});
  914. ASSERT_NE(entt::any{}, any);
  915. ASSERT_TRUE(any == any);
  916. ASSERT_FALSE(any == entt::any{instance});
  917. ASSERT_TRUE(entt::any{} != any);
  918. }
  919. TEST(Any, SequenceContainerOfNonComparable) {
  920. const std::vector<test::non_comparable> instance{};
  921. auto any = entt::forward_as_any(instance);
  922. ASSERT_EQ(any, any);
  923. ASSERT_NE(any, entt::any{instance});
  924. ASSERT_NE(entt::any{}, any);
  925. ASSERT_TRUE(any == any);
  926. ASSERT_FALSE(any == entt::any{instance});
  927. ASSERT_TRUE(entt::any{} != any);
  928. }
  929. TEST(Any, CompareVoid) {
  930. const entt::any any{std::in_place_type<void>};
  931. ASSERT_EQ(any, any);
  932. ASSERT_EQ(any, entt::any{std::in_place_type<void>});
  933. ASSERT_NE(entt::any{'a'}, any);
  934. ASSERT_EQ(any, entt::any{});
  935. ASSERT_TRUE(any == any);
  936. ASSERT_TRUE(any == entt::any{std::in_place_type<void>});
  937. ASSERT_FALSE(entt::any{'a'} == any);
  938. ASSERT_TRUE(any != entt::any{'a'});
  939. ASSERT_FALSE(entt::any{} != any);
  940. }
  941. TEST(Any, AnyCast) {
  942. entt::any any{2};
  943. const auto &cany = any;
  944. ASSERT_EQ(entt::any_cast<char>(&any), nullptr);
  945. ASSERT_EQ(entt::any_cast<char>(&cany), nullptr);
  946. ASSERT_EQ(*entt::any_cast<int>(&any), 2);
  947. ASSERT_EQ(*entt::any_cast<int>(&cany), 2);
  948. ASSERT_EQ(entt::any_cast<int &>(any), 2);
  949. ASSERT_EQ(entt::any_cast<const int &>(cany), 2);
  950. auto instance = std::make_unique<double>(2.);
  951. entt::any ref{entt::forward_as_any(instance)};
  952. entt::any cref{entt::forward_as_any(std::as_const(*instance))};
  953. ASSERT_EQ(entt::any_cast<double>(std::move(cref)), 2.);
  954. ASSERT_EQ(*entt::any_cast<std::unique_ptr<double>>(std::move(ref)), 2.);
  955. ASSERT_EQ(entt::any_cast<int>(entt::any{2}), 2);
  956. }
  957. ENTT_DEBUG_TEST(AnyDeathTest, AnyCast) {
  958. entt::any any{2};
  959. const auto &cany = any;
  960. ASSERT_DEATH([[maybe_unused]] auto &elem = entt::any_cast<double &>(any), "");
  961. ASSERT_DEATH([[maybe_unused]] const auto &elem = entt::any_cast<const double &>(cany), "");
  962. auto instance = std::make_unique<double>(2.);
  963. entt::any ref{entt::forward_as_any(instance)};
  964. const entt::any cref{entt::forward_as_any(std::as_const(*instance))};
  965. ASSERT_DEATH([[maybe_unused]] auto elem = entt::any_cast<std::unique_ptr<double>>(std::as_const(ref).as_ref()), "");
  966. ASSERT_DEATH([[maybe_unused]] auto elem = entt::any_cast<double>(entt::any{2}), "");
  967. }
  968. TEST(Any, MakeAny) {
  969. int value = 2;
  970. auto any = entt::make_any<int>(value);
  971. auto ext = entt::make_any<int, sizeof(int), alignof(int)>(value);
  972. auto ref = entt::make_any<int &>(value);
  973. ASSERT_TRUE(any);
  974. ASSERT_TRUE(ext);
  975. ASSERT_TRUE(ref);
  976. ASSERT_EQ(any.policy(), entt::any_policy::owner);
  977. ASSERT_EQ(ext.policy(), entt::any_policy::owner);
  978. ASSERT_EQ(ref.policy(), entt::any_policy::ref);
  979. ASSERT_EQ(entt::any_cast<const int &>(any), 2);
  980. ASSERT_EQ(entt::any_cast<const int &>(ext), 2);
  981. ASSERT_EQ(entt::any_cast<const int &>(ref), 2);
  982. ASSERT_EQ(decltype(any)::length, entt::any::length);
  983. ASSERT_NE(decltype(ext)::length, entt::any::length);
  984. ASSERT_EQ(decltype(ref)::length, entt::any::length);
  985. ASSERT_NE(any.data(), &value);
  986. ASSERT_NE(ext.data(), &value);
  987. ASSERT_EQ(ref.data(), &value);
  988. }
  989. TEST(Any, ForwardAsAny) {
  990. int value = 2;
  991. auto ref = entt::forward_as_any(value);
  992. auto cref = entt::forward_as_any(std::as_const(value));
  993. auto any = entt::forward_as_any(static_cast<int &&>(value));
  994. ASSERT_TRUE(any);
  995. ASSERT_TRUE(ref);
  996. ASSERT_TRUE(cref);
  997. ASSERT_EQ(any.policy(), entt::any_policy::owner);
  998. ASSERT_EQ(ref.policy(), entt::any_policy::ref);
  999. ASSERT_EQ(cref.policy(), entt::any_policy::cref);
  1000. ASSERT_NE(entt::any_cast<int>(&any), nullptr);
  1001. ASSERT_NE(entt::any_cast<int>(&ref), nullptr);
  1002. ASSERT_EQ(entt::any_cast<int>(&cref), nullptr);
  1003. ASSERT_EQ(entt::any_cast<const int &>(any), 2);
  1004. ASSERT_EQ(entt::any_cast<const int &>(ref), 2);
  1005. ASSERT_EQ(entt::any_cast<const int &>(cref), 2);
  1006. ASSERT_NE(any.data(), &value);
  1007. ASSERT_EQ(ref.data(), &value);
  1008. }
  1009. TEST(Any, NonCopyableType) {
  1010. const std::unique_ptr<int> value{};
  1011. entt::any any{std::in_place_type<std::unique_ptr<int>>};
  1012. entt::any other = entt::forward_as_any(value);
  1013. ASSERT_TRUE(any);
  1014. ASSERT_TRUE(other);
  1015. ASSERT_EQ(any.policy(), entt::any_policy::owner);
  1016. ASSERT_EQ(other.policy(), entt::any_policy::cref);
  1017. ASSERT_EQ(any.type(), other.type());
  1018. ASSERT_FALSE(any.assign(other));
  1019. ASSERT_FALSE(any.assign(std::move(other)));
  1020. entt::any copy{any};
  1021. ASSERT_TRUE(any);
  1022. ASSERT_FALSE(copy);
  1023. ASSERT_EQ(any.policy(), entt::any_policy::owner);
  1024. ASSERT_EQ(copy.policy(), entt::any_policy::owner);
  1025. copy = any;
  1026. ASSERT_TRUE(any);
  1027. ASSERT_FALSE(copy);
  1028. ASSERT_EQ(any.policy(), entt::any_policy::owner);
  1029. ASSERT_EQ(copy.policy(), entt::any_policy::owner);
  1030. }
  1031. TEST(Any, NonCopyableValueType) {
  1032. std::vector<entt::any> vec{};
  1033. vec.emplace_back(std::in_place_type<std::unique_ptr<int>>);
  1034. vec.shrink_to_fit();
  1035. ASSERT_EQ(vec.size(), 1u);
  1036. ASSERT_EQ(vec.capacity(), 1u);
  1037. ASSERT_TRUE(vec[0u]);
  1038. // strong exception guarantee due to noexcept move ctor
  1039. vec.emplace_back(std::in_place_type<std::unique_ptr<int>>);
  1040. ASSERT_EQ(vec.size(), 2u);
  1041. ASSERT_TRUE(vec[0u]);
  1042. ASSERT_TRUE(vec[1u]);
  1043. }
  1044. TEST(Any, NonMovableType) {
  1045. entt::any any{std::in_place_type<test::non_movable>};
  1046. entt::any other{std::in_place_type<test::non_movable>};
  1047. ASSERT_TRUE(any);
  1048. ASSERT_TRUE(other);
  1049. ASSERT_EQ(any.policy(), entt::any_policy::owner);
  1050. ASSERT_EQ(other.policy(), entt::any_policy::owner);
  1051. ASSERT_EQ(any.type(), other.type());
  1052. ASSERT_TRUE(any.assign(other));
  1053. ASSERT_TRUE(any.assign(std::move(other)));
  1054. entt::any copy{any};
  1055. ASSERT_TRUE(any);
  1056. ASSERT_TRUE(copy);
  1057. ASSERT_EQ(any.policy(), entt::any_policy::owner);
  1058. ASSERT_EQ(copy.policy(), entt::any_policy::owner);
  1059. copy = any;
  1060. ASSERT_TRUE(any);
  1061. ASSERT_TRUE(copy);
  1062. ASSERT_EQ(any.policy(), entt::any_policy::owner);
  1063. ASSERT_EQ(copy.policy(), entt::any_policy::owner);
  1064. }
  1065. TEST(Any, Array) {
  1066. // NOLINTNEXTLINE(*-avoid-c-arrays)
  1067. entt::any any{std::in_place_type<int[1]>};
  1068. const entt::any copy{any};
  1069. ASSERT_TRUE(any);
  1070. ASSERT_FALSE(copy);
  1071. // NOLINTBEGIN(*-avoid-c-arrays)
  1072. ASSERT_EQ(any.type(), entt::type_id<int[1]>());
  1073. ASSERT_NE(entt::any_cast<int[1]>(&any), nullptr);
  1074. ASSERT_EQ(entt::any_cast<int[2]>(&any), nullptr);
  1075. // NOLINTEND(*-avoid-c-arrays)
  1076. ASSERT_EQ(entt::any_cast<int *>(&any), nullptr);
  1077. // NOLINTNEXTLINE(*-avoid-c-arrays)
  1078. entt::any_cast<int(&)[1]>(any)[0] = 2;
  1079. // NOLINTNEXTLINE(*-avoid-c-arrays)
  1080. ASSERT_EQ(entt::any_cast<const int(&)[1]>(std::as_const(any))[0], 2);
  1081. }
  1082. TEST(Any, CopyMoveReference) {
  1083. int value = 3;
  1084. auto any = entt::forward_as_any(value);
  1085. entt::any move = std::move(any);
  1086. entt::any copy = move;
  1087. test::is_initialized(any);
  1088. ASSERT_TRUE(any);
  1089. ASSERT_TRUE(move);
  1090. ASSERT_TRUE(copy);
  1091. ASSERT_EQ(move.policy(), entt::any_policy::ref);
  1092. ASSERT_EQ(copy.policy(), entt::any_policy::owner);
  1093. ASSERT_EQ(move.type(), entt::type_id<int>());
  1094. ASSERT_EQ(copy.type(), entt::type_id<int>());
  1095. ASSERT_EQ(std::as_const(move).data(), &value);
  1096. ASSERT_NE(std::as_const(copy).data(), &value);
  1097. ASSERT_EQ(entt::any_cast<int>(move), 3);
  1098. ASSERT_EQ(entt::any_cast<int>(copy), 3);
  1099. value = 2;
  1100. ASSERT_EQ(entt::any_cast<int &>(move), 2);
  1101. ASSERT_EQ(entt::any_cast<int &>(copy), 3);
  1102. }
  1103. TEST(Any, CopyMoveConstReference) {
  1104. int value = 3;
  1105. auto any = entt::forward_as_any(std::as_const(value));
  1106. entt::any move = std::move(any);
  1107. entt::any copy = move;
  1108. test::is_initialized(any);
  1109. ASSERT_TRUE(any);
  1110. ASSERT_TRUE(move);
  1111. ASSERT_TRUE(copy);
  1112. ASSERT_EQ(move.policy(), entt::any_policy::cref);
  1113. ASSERT_EQ(copy.policy(), entt::any_policy::owner);
  1114. ASSERT_EQ(move.type(), entt::type_id<int>());
  1115. ASSERT_EQ(copy.type(), entt::type_id<int>());
  1116. ASSERT_EQ(std::as_const(move).data(), &value);
  1117. ASSERT_NE(std::as_const(copy).data(), &value);
  1118. ASSERT_EQ(entt::any_cast<int>(move), 3);
  1119. ASSERT_EQ(entt::any_cast<int>(copy), 3);
  1120. value = 2;
  1121. ASSERT_EQ(entt::any_cast<const int &>(move), 2);
  1122. ASSERT_EQ(entt::any_cast<const int &>(copy), 3);
  1123. }
  1124. TEST(Any, SBOVsZeroedSBOSize) {
  1125. entt::any sbo{2};
  1126. const auto *broken = sbo.data();
  1127. entt::any other = std::move(sbo);
  1128. ASSERT_NE(broken, other.data());
  1129. entt::basic_any<0u> dyn{2};
  1130. const auto *valid = dyn.data();
  1131. entt::basic_any<0u> same = std::move(dyn);
  1132. ASSERT_EQ(valid, same.data());
  1133. }
  1134. TEST(Any, SboAlignment) {
  1135. constexpr auto alignment = alignof(over_aligned);
  1136. using any_type = entt::basic_any<alignment, alignment>;
  1137. std::array<any_type, 2u> sbo = {over_aligned{}, over_aligned{}};
  1138. const auto *data = sbo[0].data();
  1139. // NOLINTBEGIN(*-reinterpret-cast)
  1140. ASSERT_TRUE((reinterpret_cast<std::uintptr_t>(sbo[0u].data()) % alignment) == 0u);
  1141. ASSERT_TRUE((reinterpret_cast<std::uintptr_t>(sbo[1u].data()) % alignment) == 0u);
  1142. // NOLINTEND(*-reinterpret-cast)
  1143. std::swap(sbo[0], sbo[1]);
  1144. // NOLINTBEGIN(*-reinterpret-cast)
  1145. ASSERT_TRUE((reinterpret_cast<std::uintptr_t>(sbo[0u].data()) % alignment) == 0u);
  1146. ASSERT_TRUE((reinterpret_cast<std::uintptr_t>(sbo[1u].data()) % alignment) == 0u);
  1147. // NOLINTEND(*-reinterpret-cast)
  1148. ASSERT_NE(data, sbo[1].data());
  1149. }
  1150. TEST(Any, NoSboAlignment) {
  1151. constexpr auto alignment = alignof(over_aligned);
  1152. using any_type = entt::basic_any<alignment>;
  1153. std::array<any_type, 2u> nosbo = {over_aligned{}, over_aligned{}};
  1154. const auto *data = nosbo[0].data();
  1155. // NOLINTBEGIN(*-reinterpret-cast)
  1156. ASSERT_TRUE((reinterpret_cast<std::uintptr_t>(nosbo[0u].data()) % alignment) == 0u);
  1157. ASSERT_TRUE((reinterpret_cast<std::uintptr_t>(nosbo[1u].data()) % alignment) == 0u);
  1158. // NOLINTEND(*-reinterpret-cast)
  1159. std::swap(nosbo[0], nosbo[1]);
  1160. // NOLINTBEGIN(*-reinterpret-cast)
  1161. ASSERT_TRUE((reinterpret_cast<std::uintptr_t>(nosbo[0u].data()) % alignment) == 0u);
  1162. ASSERT_TRUE((reinterpret_cast<std::uintptr_t>(nosbo[1u].data()) % alignment) == 0u);
  1163. // NOLINTEND(*-reinterpret-cast)
  1164. ASSERT_EQ(data, nosbo[1].data());
  1165. }
  1166. TEST(Any, AggregatesMustWork) {
  1167. // the goal of this test is to enforce the requirements for aggregate types
  1168. entt::any{std::in_place_type<test::aggregate>, 2}.emplace<test::aggregate>(2);
  1169. }
  1170. TEST(Any, DeducedArrayType) {
  1171. entt::any any{"array of char"};
  1172. ASSERT_TRUE(any);
  1173. ASSERT_EQ(any.type(), entt::type_id<const char *>());
  1174. ASSERT_EQ((std::strcmp("array of char", entt::any_cast<const char *>(any))), 0);
  1175. any = "another array of char";
  1176. ASSERT_TRUE(any);
  1177. ASSERT_EQ(any.type(), entt::type_id<const char *>());
  1178. ASSERT_EQ((std::strcmp("another array of char", entt::any_cast<const char *>(any))), 0);
  1179. }