any.cpp 44 KB

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