any.cpp 33 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163
  1. #include <algorithm>
  2. #include <string>
  3. #include <type_traits>
  4. #include <unordered_map>
  5. #include <vector>
  6. #include <gtest/gtest.h>
  7. #include <entt/core/any.hpp>
  8. struct empty {
  9. ~empty() { ++counter; }
  10. inline static int counter = 0;
  11. };
  12. struct fat {
  13. fat(double v1, double v2, double v3, double v4)
  14. : value{v1, v2, v3, v4}
  15. {}
  16. ~fat() { ++counter; }
  17. bool operator==(const fat &other) const {
  18. return std::equal(std::begin(value), std::end(value), std::begin(other.value), std::end(other.value));
  19. }
  20. inline static int counter{0};
  21. double value[4];
  22. };
  23. struct not_comparable {
  24. bool operator==(const not_comparable &) const = delete;
  25. };
  26. template<auto Sz>
  27. struct not_copyable {
  28. not_copyable(): payload{} {}
  29. not_copyable(const not_copyable &) = delete;
  30. not_copyable(not_copyable &&) = default;
  31. not_copyable & operator=(const not_copyable &) = delete;
  32. not_copyable & operator=(not_copyable &&) = default;
  33. double payload[Sz];
  34. };
  35. struct alignas(64u) over_aligned {};
  36. struct Any: ::testing::Test {
  37. void SetUp() override {
  38. fat::counter = 0;
  39. empty::counter = 0;
  40. }
  41. };
  42. TEST_F(Any, SBO) {
  43. entt::any any{'c'};
  44. ASSERT_TRUE(any);
  45. ASSERT_TRUE(any.owner());
  46. ASSERT_EQ(any.type(), entt::type_id<char>());
  47. ASSERT_EQ(entt::any_cast<double>(&any), nullptr);
  48. ASSERT_EQ(entt::any_cast<char>(any), 'c');
  49. }
  50. TEST_F(Any, NoSBO) {
  51. fat instance{.1, .2, .3, .4};
  52. entt::any any{instance};
  53. ASSERT_TRUE(any);
  54. ASSERT_TRUE(any.owner());
  55. ASSERT_EQ(any.type(), entt::type_id<fat>());
  56. ASSERT_EQ(entt::any_cast<double>(&any), nullptr);
  57. ASSERT_EQ(entt::any_cast<fat>(any), instance);
  58. }
  59. TEST_F(Any, Empty) {
  60. entt::any any{};
  61. ASSERT_FALSE(any);
  62. ASSERT_TRUE(any.owner());
  63. ASSERT_EQ(any.type(), entt::type_id<void>());
  64. ASSERT_EQ(entt::any_cast<double>(&any), nullptr);
  65. ASSERT_EQ(any.data(), nullptr);
  66. }
  67. TEST_F(Any, SBOInPlaceTypeConstruction) {
  68. entt::any any{std::in_place_type<int>, 42};
  69. ASSERT_TRUE(any);
  70. ASSERT_TRUE(any.owner());
  71. ASSERT_EQ(any.type(), entt::type_id<int>());
  72. ASSERT_EQ(entt::any_cast<double>(&any), nullptr);
  73. ASSERT_EQ(entt::any_cast<int>(any), 42);
  74. auto other = any.as_ref();
  75. ASSERT_TRUE(other);
  76. ASSERT_FALSE(other.owner());
  77. ASSERT_EQ(other.type(), entt::type_id<int>());
  78. ASSERT_EQ(entt::any_cast<int>(other), 42);
  79. ASSERT_EQ(other.data(), any.data());
  80. }
  81. TEST_F(Any, SBOAsRefConstruction) {
  82. int value = 42;
  83. entt::any any{entt::forward_as_any(value)};
  84. ASSERT_TRUE(any);
  85. ASSERT_FALSE(any.owner());
  86. ASSERT_EQ(any.type(), entt::type_id<int>());
  87. ASSERT_EQ(entt::any_cast<double>(&any), nullptr);
  88. ASSERT_EQ(entt::any_cast<const int>(&any), &value);
  89. ASSERT_EQ(entt::any_cast<int>(&any), &value);
  90. ASSERT_EQ(entt::any_cast<const int>(&std::as_const(any)), &value);
  91. ASSERT_EQ(entt::any_cast<int>(&std::as_const(any)), &value);
  92. ASSERT_EQ(entt::any_cast<const int &>(any), 42);
  93. ASSERT_EQ(entt::any_cast<int>(any), 42);
  94. ASSERT_EQ(any.data(), &value);
  95. ASSERT_EQ(std::as_const(any).data(), &value);
  96. any.emplace<int &>(value);
  97. ASSERT_TRUE(any);
  98. ASSERT_FALSE(any.owner());
  99. ASSERT_EQ(any.type(), entt::type_id<int>());
  100. ASSERT_EQ(entt::any_cast<int>(&any), &value);
  101. auto other = any.as_ref();
  102. ASSERT_TRUE(other);
  103. ASSERT_FALSE(other.owner());
  104. ASSERT_EQ(other.type(), entt::type_id<int>());
  105. ASSERT_EQ(entt::any_cast<int>(other), 42);
  106. ASSERT_EQ(other.data(), any.data());
  107. }
  108. TEST_F(Any, SBOAsConstRefConstruction) {
  109. const int value = 42;
  110. entt::any any{entt::forward_as_any(value)};
  111. ASSERT_TRUE(any);
  112. ASSERT_FALSE(any.owner());
  113. ASSERT_EQ(any.type(), entt::type_id<int>());
  114. ASSERT_EQ(entt::any_cast<double>(&any), nullptr);
  115. ASSERT_EQ(entt::any_cast<const int>(&any), &value);
  116. ASSERT_EQ(entt::any_cast<int>(&any), nullptr);
  117. ASSERT_EQ(entt::any_cast<const int>(&std::as_const(any)), &value);
  118. ASSERT_EQ(entt::any_cast<int>(&std::as_const(any)), &value);
  119. ASSERT_EQ(entt::any_cast<const int &>(any), 42);
  120. ASSERT_EQ(entt::any_cast<int>(any), 42);
  121. ASSERT_EQ(any.data(), nullptr);
  122. ASSERT_EQ(std::as_const(any).data(), &value);
  123. any.emplace<const int &>(value);
  124. ASSERT_TRUE(any);
  125. ASSERT_FALSE(any.owner());
  126. ASSERT_EQ(any.type(), entt::type_id<int>());
  127. ASSERT_EQ(entt::any_cast<const int>(&any), &value);
  128. auto other = any.as_ref();
  129. ASSERT_TRUE(other);
  130. ASSERT_FALSE(other.owner());
  131. ASSERT_EQ(other.type(), entt::type_id<int>());
  132. ASSERT_EQ(entt::any_cast<int>(other), 42);
  133. ASSERT_EQ(other.data(), any.data());
  134. }
  135. TEST_F(Any, SBOCopyConstruction) {
  136. entt::any any{42};
  137. entt::any other{any};
  138. ASSERT_TRUE(any);
  139. ASSERT_TRUE(other);
  140. ASSERT_TRUE(any.owner());
  141. ASSERT_TRUE(other.owner());
  142. ASSERT_EQ(any.type(), entt::type_id<int>());
  143. ASSERT_EQ(other.type(), entt::type_id<int>());
  144. ASSERT_EQ(entt::any_cast<double>(&other), nullptr);
  145. ASSERT_EQ(entt::any_cast<int>(other), 42);
  146. }
  147. TEST_F(Any, SBOCopyAssignment) {
  148. entt::any any{42};
  149. entt::any other{3};
  150. other = any;
  151. ASSERT_TRUE(any);
  152. ASSERT_TRUE(other);
  153. ASSERT_TRUE(any.owner());
  154. ASSERT_TRUE(other.owner());
  155. ASSERT_EQ(any.type(), entt::type_id<int>());
  156. ASSERT_EQ(other.type(), entt::type_id<int>());
  157. ASSERT_EQ(entt::any_cast<double>(&other), nullptr);
  158. ASSERT_EQ(entt::any_cast<int>(other), 42);
  159. }
  160. TEST_F(Any, SBOMoveConstruction) {
  161. entt::any any{42};
  162. entt::any other{std::move(any)};
  163. ASSERT_TRUE(any);
  164. ASSERT_TRUE(other);
  165. ASSERT_TRUE(any.owner());
  166. ASSERT_TRUE(other.owner());
  167. ASSERT_NE(any.data(), nullptr);
  168. ASSERT_EQ(any.type(), entt::type_id<int>());
  169. ASSERT_EQ(other.type(), entt::type_id<int>());
  170. ASSERT_EQ(entt::any_cast<double>(&other), nullptr);
  171. ASSERT_EQ(entt::any_cast<int>(other), 42);
  172. }
  173. TEST_F(Any, SBOMoveAssignment) {
  174. entt::any any{42};
  175. entt::any other{3};
  176. other = std::move(any);
  177. ASSERT_TRUE(any);
  178. ASSERT_TRUE(other);
  179. ASSERT_TRUE(any.owner());
  180. ASSERT_TRUE(other.owner());
  181. ASSERT_NE(any.data(), nullptr);
  182. ASSERT_EQ(any.type(), entt::type_id<int>());
  183. ASSERT_EQ(other.type(), entt::type_id<int>());
  184. ASSERT_EQ(entt::any_cast<double>(&other), nullptr);
  185. ASSERT_EQ(entt::any_cast<int>(other), 42);
  186. }
  187. TEST_F(Any, SBODirectAssignment) {
  188. entt::any any{};
  189. any = 42;
  190. ASSERT_TRUE(any);
  191. ASSERT_TRUE(any.owner());
  192. ASSERT_EQ(any.type(), entt::type_id<int>());
  193. ASSERT_EQ(entt::any_cast<double>(&any), nullptr);
  194. ASSERT_EQ(entt::any_cast<int>(any), 42);
  195. }
  196. TEST_F(Any, NoSBOInPlaceTypeConstruction) {
  197. fat instance{.1, .2, .3, .4};
  198. entt::any any{std::in_place_type<fat>, instance};
  199. ASSERT_TRUE(any);
  200. ASSERT_TRUE(any.owner());
  201. ASSERT_EQ(any.type(), entt::type_id<fat>());
  202. ASSERT_EQ(entt::any_cast<double>(&any), nullptr);
  203. ASSERT_EQ(entt::any_cast<fat>(any), instance);
  204. auto other = any.as_ref();
  205. ASSERT_TRUE(other);
  206. ASSERT_FALSE(other.owner());
  207. ASSERT_EQ(other.type(), entt::type_id<fat>());
  208. ASSERT_EQ(entt::any_cast<fat>(other), (fat{.1, .2, .3, .4}));
  209. ASSERT_EQ(other.data(), any.data());
  210. }
  211. TEST_F(Any, NoSBOAsRefConstruction) {
  212. fat instance{.1, .2, .3, .4};
  213. entt::any any{entt::forward_as_any(instance)};
  214. ASSERT_TRUE(any);
  215. ASSERT_FALSE(any.owner());
  216. ASSERT_EQ(any.type(), entt::type_id<fat>());
  217. ASSERT_EQ(entt::any_cast<double>(&any), nullptr);
  218. ASSERT_EQ(entt::any_cast<const fat>(&any), &instance);
  219. ASSERT_EQ(entt::any_cast<fat>(&any), &instance);
  220. ASSERT_EQ(entt::any_cast<const fat>(&std::as_const(any)), &instance);
  221. ASSERT_EQ(entt::any_cast<fat>(&std::as_const(any)), &instance);
  222. ASSERT_EQ(entt::any_cast<const fat &>(any), instance);
  223. ASSERT_EQ(entt::any_cast<fat>(any), instance);
  224. ASSERT_EQ(any.data(), &instance);
  225. ASSERT_EQ(std::as_const(any).data(), &instance);
  226. any.emplace<fat &>(instance);
  227. ASSERT_TRUE(any);
  228. ASSERT_FALSE(any.owner());
  229. ASSERT_EQ(any.type(), entt::type_id<fat>());
  230. ASSERT_EQ(entt::any_cast<fat>(&any), &instance);
  231. auto other = any.as_ref();
  232. ASSERT_TRUE(other);
  233. ASSERT_FALSE(other.owner());
  234. ASSERT_EQ(other.type(), entt::type_id<fat>());
  235. ASSERT_EQ(entt::any_cast<fat>(other), (fat{.1, .2, .3, .4}));
  236. ASSERT_EQ(other.data(), any.data());
  237. }
  238. TEST_F(Any, NoSBOAsConstRefConstruction) {
  239. const fat instance{.1, .2, .3, .4};
  240. entt::any any{entt::forward_as_any(instance)};
  241. ASSERT_TRUE(any);
  242. ASSERT_FALSE(any.owner());
  243. ASSERT_EQ(any.type(), entt::type_id<fat>());
  244. ASSERT_EQ(entt::any_cast<double>(&any), nullptr);
  245. ASSERT_EQ(entt::any_cast<const fat>(&any), &instance);
  246. ASSERT_EQ(entt::any_cast<fat>(&any), nullptr);
  247. ASSERT_EQ(entt::any_cast<const fat>(&std::as_const(any)), &instance);
  248. ASSERT_EQ(entt::any_cast<fat>(&std::as_const(any)), &instance);
  249. ASSERT_EQ(entt::any_cast<const fat &>(any), instance);
  250. ASSERT_EQ(entt::any_cast<fat>(any), instance);
  251. ASSERT_EQ(any.data(), nullptr);
  252. ASSERT_EQ(std::as_const(any).data(), &instance);
  253. any.emplace<const fat &>(instance);
  254. ASSERT_TRUE(any);
  255. ASSERT_FALSE(any.owner());
  256. ASSERT_EQ(any.type(), entt::type_id<fat>());
  257. ASSERT_EQ(entt::any_cast<const fat>(&any), &instance);
  258. auto other = any.as_ref();
  259. ASSERT_TRUE(other);
  260. ASSERT_FALSE(other.owner());
  261. ASSERT_EQ(other.type(), entt::type_id<fat>());
  262. ASSERT_EQ(entt::any_cast<fat>(other), (fat{.1, .2, .3, .4}));
  263. ASSERT_EQ(other.data(), any.data());
  264. }
  265. TEST_F(Any, NoSBOCopyConstruction) {
  266. fat instance{.1, .2, .3, .4};
  267. entt::any any{instance};
  268. entt::any other{any};
  269. ASSERT_TRUE(any);
  270. ASSERT_TRUE(other);
  271. ASSERT_TRUE(any.owner());
  272. ASSERT_TRUE(other.owner());
  273. ASSERT_EQ(any.type(), entt::type_id<fat>());
  274. ASSERT_EQ(other.type(), entt::type_id<fat>());
  275. ASSERT_EQ(entt::any_cast<double>(&other), nullptr);
  276. ASSERT_EQ(entt::any_cast<fat>(other), instance);
  277. }
  278. TEST_F(Any, NoSBOCopyAssignment) {
  279. fat instance{.1, .2, .3, .4};
  280. entt::any any{instance};
  281. entt::any other{3};
  282. other = any;
  283. ASSERT_TRUE(any);
  284. ASSERT_TRUE(other);
  285. ASSERT_TRUE(any.owner());
  286. ASSERT_TRUE(other.owner());
  287. ASSERT_EQ(any.type(), entt::type_id<fat>());
  288. ASSERT_EQ(other.type(), entt::type_id<fat>());
  289. ASSERT_EQ(entt::any_cast<double>(&other), nullptr);
  290. ASSERT_EQ(entt::any_cast<fat>(other), instance);
  291. }
  292. TEST_F(Any, NoSBOMoveConstruction) {
  293. fat instance{.1, .2, .3, .4};
  294. entt::any any{instance};
  295. entt::any other{std::move(any)};
  296. ASSERT_TRUE(any);
  297. ASSERT_TRUE(other);
  298. ASSERT_TRUE(any.owner());
  299. ASSERT_TRUE(other.owner());
  300. ASSERT_EQ(any.data(), nullptr);
  301. ASSERT_EQ(any.type(), entt::type_id<fat>());
  302. ASSERT_EQ(other.type(), entt::type_id<fat>());
  303. ASSERT_EQ(entt::any_cast<double>(&other), nullptr);
  304. ASSERT_EQ(entt::any_cast<fat>(other), instance);
  305. }
  306. TEST_F(Any, NoSBOMoveAssignment) {
  307. fat instance{.1, .2, .3, .4};
  308. entt::any any{instance};
  309. entt::any other{3};
  310. other = std::move(any);
  311. ASSERT_TRUE(any);
  312. ASSERT_TRUE(other);
  313. ASSERT_TRUE(any.owner());
  314. ASSERT_TRUE(other.owner());
  315. ASSERT_EQ(any.data(), nullptr);
  316. ASSERT_EQ(any.type(), entt::type_id<fat>());
  317. ASSERT_EQ(other.type(), entt::type_id<fat>());
  318. ASSERT_EQ(entt::any_cast<double>(&other), nullptr);
  319. ASSERT_EQ(entt::any_cast<fat>(other), instance);
  320. }
  321. TEST_F(Any, NoSBODirectAssignment) {
  322. fat instance{.1, .2, .3, .4};
  323. entt::any any{};
  324. any = instance;
  325. ASSERT_TRUE(any);
  326. ASSERT_TRUE(any.owner());
  327. ASSERT_EQ(any.type(), entt::type_id<fat>());
  328. ASSERT_EQ(entt::any_cast<double>(&any), nullptr);
  329. ASSERT_EQ(entt::any_cast<fat>(any), instance);
  330. }
  331. TEST_F(Any, VoidInPlaceTypeConstruction) {
  332. entt::any any{std::in_place_type<void>};
  333. ASSERT_FALSE(any);
  334. ASSERT_TRUE(any.owner());
  335. ASSERT_EQ(any.type(), entt::type_id<void>());
  336. ASSERT_EQ(entt::any_cast<int>(&any), nullptr);
  337. }
  338. TEST_F(Any, VoidCopyConstruction) {
  339. entt::any any{std::in_place_type<void>};
  340. entt::any other{any};
  341. ASSERT_FALSE(any);
  342. ASSERT_FALSE(other);
  343. ASSERT_TRUE(any.owner());
  344. ASSERT_TRUE(other.owner());
  345. ASSERT_EQ(any.type(), entt::type_id<void>());
  346. ASSERT_EQ(other.type(), entt::type_id<void>());
  347. ASSERT_EQ(entt::any_cast<int>(&any), nullptr);
  348. ASSERT_EQ(entt::any_cast<double>(&other), nullptr);
  349. }
  350. TEST_F(Any, VoidCopyAssignment) {
  351. entt::any any{std::in_place_type<void>};
  352. entt::any other{42};
  353. other = any;
  354. ASSERT_FALSE(any);
  355. ASSERT_FALSE(other);
  356. ASSERT_TRUE(any.owner());
  357. ASSERT_TRUE(other.owner());
  358. ASSERT_EQ(any.type(), entt::type_id<void>());
  359. ASSERT_EQ(other.type(), entt::type_id<void>());
  360. ASSERT_EQ(entt::any_cast<int>(&any), nullptr);
  361. ASSERT_EQ(entt::any_cast<double>(&other), nullptr);
  362. }
  363. TEST_F(Any, VoidMoveConstruction) {
  364. entt::any any{std::in_place_type<void>};
  365. entt::any other{std::move(any)};
  366. ASSERT_FALSE(any);
  367. ASSERT_FALSE(other);
  368. ASSERT_TRUE(any.owner());
  369. ASSERT_TRUE(other.owner());
  370. ASSERT_EQ(any.type(), entt::type_id<void>());
  371. ASSERT_EQ(other.type(), entt::type_id<void>());
  372. ASSERT_EQ(entt::any_cast<int>(&any), nullptr);
  373. ASSERT_EQ(entt::any_cast<double>(&other), nullptr);
  374. }
  375. TEST_F(Any, VoidMoveAssignment) {
  376. entt::any any{std::in_place_type<void>};
  377. entt::any other{42};
  378. other = std::move(any);
  379. ASSERT_FALSE(any);
  380. ASSERT_FALSE(other);
  381. ASSERT_TRUE(any.owner());
  382. ASSERT_TRUE(other.owner());
  383. ASSERT_EQ(any.type(), entt::type_id<void>());
  384. ASSERT_EQ(other.type(), entt::type_id<void>());
  385. ASSERT_EQ(entt::any_cast<int>(&any), nullptr);
  386. ASSERT_EQ(entt::any_cast<double>(&other), nullptr);
  387. }
  388. TEST_F(Any, SBOMoveValidButUnspecifiedState) {
  389. entt::any any{42};
  390. entt::any other{std::move(any)};
  391. entt::any valid = std::move(other);
  392. ASSERT_TRUE(any);
  393. ASSERT_TRUE(other);
  394. ASSERT_TRUE(valid);
  395. }
  396. TEST_F(Any, NoSBOMoveValidButUnspecifiedState) {
  397. fat instance{.1, .2, .3, .4};
  398. entt::any any{instance};
  399. entt::any other{std::move(any)};
  400. entt::any valid = std::move(other);
  401. ASSERT_TRUE(any);
  402. ASSERT_TRUE(other);
  403. ASSERT_TRUE(valid);
  404. }
  405. TEST_F(Any, VoidMoveValidButUnspecifiedState) {
  406. entt::any any{std::in_place_type<void>};
  407. entt::any other{std::move(any)};
  408. entt::any valid = std::move(other);
  409. ASSERT_FALSE(any);
  410. ASSERT_FALSE(other);
  411. ASSERT_FALSE(valid);
  412. }
  413. TEST_F(Any, SBODestruction) {
  414. {
  415. entt::any any{std::in_place_type<empty>};
  416. any.emplace<empty>();
  417. any = empty{};
  418. entt::any other{std::move(any)};
  419. any = std::move(other);
  420. }
  421. ASSERT_EQ(empty::counter, 6);
  422. }
  423. TEST_F(Any, NoSBODestruction) {
  424. {
  425. entt::any any{std::in_place_type<fat>, 1., 2., 3., 4.};
  426. any.emplace<fat>(1., 2., 3., 4.);
  427. any = fat{1., 2., 3., 4.};
  428. entt::any other{std::move(any)};
  429. any = std::move(other);
  430. }
  431. ASSERT_EQ(fat::counter, 4);
  432. }
  433. TEST_F(Any, VoidDestruction) {
  434. // just let asan tell us if everything is ok here
  435. [[maybe_unused]] entt::any any{std::in_place_type<void>};
  436. }
  437. TEST_F(Any, Emplace) {
  438. entt::any any{};
  439. any.emplace<int>(42);
  440. ASSERT_TRUE(any);
  441. ASSERT_TRUE(any.owner());
  442. ASSERT_EQ(any.type(), entt::type_id<int>());
  443. ASSERT_EQ(entt::any_cast<double>(&any), nullptr);
  444. ASSERT_EQ(entt::any_cast<int>(any), 42);
  445. }
  446. TEST_F(Any, EmplaceVoid) {
  447. entt::any any{};
  448. any.emplace<void>();
  449. ASSERT_FALSE(any);
  450. ASSERT_TRUE(any.owner());
  451. ASSERT_EQ(any.type(), entt::type_id<void>());
  452. }
  453. TEST_F(Any, Reset) {
  454. entt::any any{42};
  455. ASSERT_TRUE(any);
  456. ASSERT_TRUE(any.owner());
  457. ASSERT_EQ(any.type(), entt::type_id<int>());
  458. any.reset();
  459. ASSERT_FALSE(any);
  460. ASSERT_TRUE(any.owner());
  461. ASSERT_EQ(any.type(), entt::type_id<void>());
  462. int value = 42;
  463. any.emplace<int &>(value);
  464. ASSERT_TRUE(any);
  465. ASSERT_FALSE(any.owner());
  466. ASSERT_EQ(any.type(), entt::type_id<int>());
  467. any.reset();
  468. ASSERT_FALSE(any);
  469. ASSERT_TRUE(any.owner());
  470. ASSERT_EQ(any.type(), entt::type_id<void>());
  471. }
  472. TEST_F(Any, SBOSwap) {
  473. entt::any lhs{'c'};
  474. entt::any rhs{42};
  475. std::swap(lhs, rhs);
  476. ASSERT_TRUE(lhs.owner());
  477. ASSERT_TRUE(rhs.owner());
  478. ASSERT_EQ(lhs.type(), entt::type_id<int>());
  479. ASSERT_EQ(rhs.type(), entt::type_id<char>());
  480. ASSERT_EQ(entt::any_cast<char>(&lhs), nullptr);
  481. ASSERT_EQ(entt::any_cast<int>(&rhs), nullptr);
  482. ASSERT_EQ(entt::any_cast<int>(lhs), 42);
  483. ASSERT_EQ(entt::any_cast<char>(rhs), 'c');
  484. }
  485. TEST_F(Any, NoSBOSwap) {
  486. entt::any lhs{fat{.1, .2, .3, .4}};
  487. entt::any rhs{fat{.4, .3, .2, .1}};
  488. std::swap(lhs, rhs);
  489. ASSERT_TRUE(lhs.owner());
  490. ASSERT_TRUE(rhs.owner());
  491. ASSERT_EQ(entt::any_cast<fat>(lhs), (fat{.4, .3, .2, .1}));
  492. ASSERT_EQ(entt::any_cast<fat>(rhs), (fat{.1, .2, .3, .4}));
  493. }
  494. TEST_F(Any, VoidSwap) {
  495. entt::any lhs{std::in_place_type<void>};
  496. entt::any rhs{std::in_place_type<void>};
  497. const auto *pre = lhs.data();
  498. std::swap(lhs, rhs);
  499. ASSERT_TRUE(lhs.owner());
  500. ASSERT_TRUE(rhs.owner());
  501. ASSERT_EQ(pre, lhs.data());
  502. }
  503. TEST_F(Any, SBOWithNoSBOSwap) {
  504. entt::any lhs{fat{.1, .2, .3, .4}};
  505. entt::any rhs{'c'};
  506. std::swap(lhs, rhs);
  507. ASSERT_TRUE(lhs.owner());
  508. ASSERT_TRUE(rhs.owner());
  509. ASSERT_EQ(lhs.type(), entt::type_id<char>());
  510. ASSERT_EQ(rhs.type(), entt::type_id<fat>());
  511. ASSERT_EQ(entt::any_cast<fat>(&lhs), nullptr);
  512. ASSERT_EQ(entt::any_cast<char>(&rhs), nullptr);
  513. ASSERT_EQ(entt::any_cast<char>(lhs), 'c');
  514. ASSERT_EQ(entt::any_cast<fat>(rhs), (fat{.1, .2, .3, .4}));
  515. }
  516. TEST_F(Any, SBOWithRefSwap) {
  517. int value = 3;
  518. entt::any lhs{entt::forward_as_any(value)};
  519. entt::any rhs{'c'};
  520. std::swap(lhs, rhs);
  521. ASSERT_TRUE(lhs.owner());
  522. ASSERT_FALSE(rhs.owner());
  523. ASSERT_EQ(lhs.type(), entt::type_id<char>());
  524. ASSERT_EQ(rhs.type(), entt::type_id<int>());
  525. ASSERT_EQ(entt::any_cast<int>(&lhs), nullptr);
  526. ASSERT_EQ(entt::any_cast<char>(&rhs), nullptr);
  527. ASSERT_EQ(entt::any_cast<char>(lhs), 'c');
  528. ASSERT_EQ(entt::any_cast<int>(rhs), 3);
  529. ASSERT_EQ(rhs.data(), &value);
  530. }
  531. TEST_F(Any, SBOWithConstRefSwap) {
  532. const int value = 3;
  533. entt::any lhs{entt::forward_as_any(value)};
  534. entt::any rhs{'c'};
  535. std::swap(lhs, rhs);
  536. ASSERT_TRUE(lhs.owner());
  537. ASSERT_FALSE(rhs.owner());
  538. ASSERT_EQ(lhs.type(), entt::type_id<char>());
  539. ASSERT_EQ(rhs.type(), entt::type_id<int>());
  540. ASSERT_EQ(entt::any_cast<int>(&lhs), nullptr);
  541. ASSERT_EQ(entt::any_cast<char>(&rhs), nullptr);
  542. ASSERT_EQ(entt::any_cast<char>(lhs), 'c');
  543. ASSERT_EQ(entt::any_cast<int>(rhs), 3);
  544. ASSERT_EQ(rhs.data(), nullptr);
  545. ASSERT_EQ(std::as_const(rhs).data(), &value);
  546. }
  547. TEST_F(Any, SBOWithEmptySwap) {
  548. entt::any lhs{'c'};
  549. entt::any rhs{};
  550. std::swap(lhs, rhs);
  551. ASSERT_FALSE(lhs);
  552. ASSERT_TRUE(lhs.owner());
  553. ASSERT_EQ(rhs.type(), entt::type_id<char>());
  554. ASSERT_EQ(entt::any_cast<char>(&lhs), nullptr);
  555. ASSERT_EQ(entt::any_cast<double>(&rhs), nullptr);
  556. ASSERT_EQ(entt::any_cast<char>(rhs), 'c');
  557. std::swap(lhs, rhs);
  558. ASSERT_FALSE(rhs);
  559. ASSERT_TRUE(rhs.owner());
  560. ASSERT_EQ(lhs.type(), entt::type_id<char>());
  561. ASSERT_EQ(entt::any_cast<double>(&lhs), nullptr);
  562. ASSERT_EQ(entt::any_cast<char>(&rhs), nullptr);
  563. ASSERT_EQ(entt::any_cast<char>(lhs), 'c');
  564. }
  565. TEST_F(Any, SBOWithVoidSwap) {
  566. entt::any lhs{'c'};
  567. entt::any rhs{std::in_place_type<void>};
  568. std::swap(lhs, rhs);
  569. ASSERT_FALSE(lhs);
  570. ASSERT_TRUE(lhs.owner());
  571. ASSERT_EQ(rhs.type(), entt::type_id<char>());
  572. ASSERT_EQ(entt::any_cast<char>(&lhs), nullptr);
  573. ASSERT_EQ(entt::any_cast<double>(&rhs), nullptr);
  574. ASSERT_EQ(entt::any_cast<char>(rhs), 'c');
  575. std::swap(lhs, rhs);
  576. ASSERT_FALSE(rhs);
  577. ASSERT_TRUE(rhs.owner());
  578. ASSERT_EQ(lhs.type(), entt::type_id<char>());
  579. ASSERT_EQ(entt::any_cast<double>(&lhs), nullptr);
  580. ASSERT_EQ(entt::any_cast<char>(&rhs), nullptr);
  581. ASSERT_EQ(entt::any_cast<char>(lhs), 'c');
  582. }
  583. TEST_F(Any, NoSBOWithRefSwap) {
  584. int value = 3;
  585. entt::any lhs{entt::forward_as_any(value)};
  586. entt::any rhs{fat{.1, .2, .3, .4}};
  587. std::swap(lhs, rhs);
  588. ASSERT_TRUE(lhs.owner());
  589. ASSERT_FALSE(rhs.owner());
  590. ASSERT_EQ(lhs.type(), entt::type_id<fat>());
  591. ASSERT_EQ(rhs.type(), entt::type_id<int>());
  592. ASSERT_EQ(entt::any_cast<int>(&lhs), nullptr);
  593. ASSERT_EQ(entt::any_cast<fat>(&rhs), nullptr);
  594. ASSERT_EQ(entt::any_cast<fat>(lhs), (fat{.1, .2, .3, .4}));
  595. ASSERT_EQ(entt::any_cast<int>(rhs), 3);
  596. ASSERT_EQ(rhs.data(), &value);
  597. }
  598. TEST_F(Any, NoSBOWithConstRefSwap) {
  599. const int value = 3;
  600. entt::any lhs{entt::forward_as_any(value)};
  601. entt::any rhs{fat{.1, .2, .3, .4}};
  602. std::swap(lhs, rhs);
  603. ASSERT_TRUE(lhs.owner());
  604. ASSERT_FALSE(rhs.owner());
  605. ASSERT_EQ(lhs.type(), entt::type_id<fat>());
  606. ASSERT_EQ(rhs.type(), entt::type_id<int>());
  607. ASSERT_EQ(entt::any_cast<int>(&lhs), nullptr);
  608. ASSERT_EQ(entt::any_cast<fat>(&rhs), nullptr);
  609. ASSERT_EQ(entt::any_cast<fat>(lhs), (fat{.1, .2, .3, .4}));
  610. ASSERT_EQ(entt::any_cast<int>(rhs), 3);
  611. ASSERT_EQ(rhs.data(), nullptr);
  612. ASSERT_EQ(std::as_const(rhs).data(), &value);
  613. }
  614. TEST_F(Any, NoSBOWithEmptySwap) {
  615. entt::any lhs{fat{.1, .2, .3, .4}};
  616. entt::any rhs{};
  617. std::swap(lhs, rhs);
  618. ASSERT_FALSE(lhs);
  619. ASSERT_TRUE(lhs.owner());
  620. ASSERT_EQ(rhs.type(), entt::type_id<fat>());
  621. ASSERT_EQ(entt::any_cast<fat>(&lhs), nullptr);
  622. ASSERT_EQ(entt::any_cast<double>(&rhs), nullptr);
  623. ASSERT_EQ(entt::any_cast<fat>(rhs), (fat{.1, .2, .3, .4}));
  624. std::swap(lhs, rhs);
  625. ASSERT_FALSE(rhs);
  626. ASSERT_TRUE(rhs.owner());
  627. ASSERT_EQ(lhs.type(), entt::type_id<fat>());
  628. ASSERT_EQ(entt::any_cast<double>(&lhs), nullptr);
  629. ASSERT_EQ(entt::any_cast<fat>(&rhs), nullptr);
  630. ASSERT_EQ(entt::any_cast<fat>(lhs), (fat{.1, .2, .3, .4}));
  631. }
  632. TEST_F(Any, NoSBOWithVoidSwap) {
  633. entt::any lhs{fat{.1, .2, .3, .4}};
  634. entt::any rhs{std::in_place_type<void>};
  635. std::swap(lhs, rhs);
  636. ASSERT_FALSE(lhs);
  637. ASSERT_TRUE(lhs.owner());
  638. ASSERT_EQ(rhs.type(), entt::type_id<fat>());
  639. ASSERT_EQ(entt::any_cast<fat>(&lhs), nullptr);
  640. ASSERT_EQ(entt::any_cast<double>(&rhs), nullptr);
  641. ASSERT_EQ(entt::any_cast<fat>(rhs), (fat{.1, .2, .3, .4}));
  642. std::swap(lhs, rhs);
  643. ASSERT_FALSE(rhs);
  644. ASSERT_TRUE(rhs.owner());
  645. ASSERT_EQ(lhs.type(), entt::type_id<fat>());
  646. ASSERT_EQ(entt::any_cast<double>(&lhs), nullptr);
  647. ASSERT_EQ(entt::any_cast<fat>(&rhs), nullptr);
  648. ASSERT_EQ(entt::any_cast<fat>(lhs), (fat{.1, .2, .3, .4}));
  649. }
  650. TEST_F(Any, AsRef) {
  651. entt::any any{42};
  652. auto ref = any.as_ref();
  653. auto cref = std::as_const(any).as_ref();
  654. ASSERT_FALSE(ref.owner());
  655. ASSERT_FALSE(cref.owner());
  656. ASSERT_EQ(entt::any_cast<int>(&any), any.data());
  657. ASSERT_EQ(entt::any_cast<int>(&ref), any.data());
  658. ASSERT_EQ(entt::any_cast<int>(&cref), nullptr);
  659. ASSERT_EQ(entt::any_cast<const int>(&any), any.data());
  660. ASSERT_EQ(entt::any_cast<const int>(&ref), any.data());
  661. ASSERT_EQ(entt::any_cast<const int>(&cref), any.data());
  662. ASSERT_EQ(entt::any_cast<int>(any), 42);
  663. ASSERT_EQ(entt::any_cast<int>(ref), 42);
  664. ASSERT_EQ(entt::any_cast<int>(cref), 42);
  665. ASSERT_EQ(entt::any_cast<const int>(any), 42);
  666. ASSERT_EQ(entt::any_cast<const int>(ref), 42);
  667. ASSERT_EQ(entt::any_cast<const int>(cref), 42);
  668. ASSERT_EQ(entt::any_cast<int &>(any), 42);
  669. ASSERT_EQ(entt::any_cast<const int &>(any), 42);
  670. ASSERT_EQ(entt::any_cast<int &>(ref), 42);
  671. ASSERT_EQ(entt::any_cast<const int &>(ref), 42);
  672. ASSERT_EQ(entt::any_cast<int>(&cref), nullptr);
  673. ASSERT_EQ(entt::any_cast<const int &>(cref), 42);
  674. entt::any_cast<int &>(any) = 3;
  675. ASSERT_EQ(entt::any_cast<int>(any), 3);
  676. ASSERT_EQ(entt::any_cast<int>(ref), 3);
  677. ASSERT_EQ(entt::any_cast<int>(cref), 3);
  678. std::swap(ref, cref);
  679. ASSERT_FALSE(ref.owner());
  680. ASSERT_FALSE(cref.owner());
  681. ASSERT_EQ(entt::any_cast<int>(&ref), nullptr);
  682. ASSERT_EQ(entt::any_cast<int>(&cref), any.data());
  683. ref = ref.as_ref();
  684. cref = std::as_const(cref).as_ref();
  685. ASSERT_FALSE(ref.owner());
  686. ASSERT_FALSE(cref.owner());
  687. ASSERT_EQ(entt::any_cast<int>(&ref), nullptr);
  688. ASSERT_EQ(entt::any_cast<int>(&cref), nullptr);
  689. ASSERT_EQ(entt::any_cast<const int>(&ref), any.data());
  690. ASSERT_EQ(entt::any_cast<const int>(&cref), any.data());
  691. ASSERT_EQ(entt::any_cast<int>(&ref), nullptr);
  692. ASSERT_EQ(entt::any_cast<int>(&cref), nullptr);
  693. ASSERT_EQ(entt::any_cast<const int &>(ref), 3);
  694. ASSERT_EQ(entt::any_cast<const int &>(cref), 3);
  695. ref = 42;
  696. cref = 42;
  697. ASSERT_TRUE(ref.owner());
  698. ASSERT_TRUE(cref.owner());
  699. ASSERT_NE(entt::any_cast<int>(&ref), nullptr);
  700. ASSERT_NE(entt::any_cast<int>(&cref), nullptr);
  701. ASSERT_EQ(entt::any_cast<int &>(ref), 42);
  702. ASSERT_EQ(entt::any_cast<int &>(cref), 42);
  703. ASSERT_EQ(entt::any_cast<const int &>(ref), 42);
  704. ASSERT_EQ(entt::any_cast<const int &>(cref), 42);
  705. ASSERT_NE(entt::any_cast<int>(&ref), any.data());
  706. ASSERT_NE(entt::any_cast<int>(&cref), any.data());
  707. }
  708. TEST_F(Any, Comparable) {
  709. auto test = [](entt::any any, entt::any other) {
  710. ASSERT_EQ(any, any);
  711. ASSERT_NE(other, any);
  712. ASSERT_NE(any, entt::any{});
  713. ASSERT_TRUE(any == any);
  714. ASSERT_FALSE(other == any);
  715. ASSERT_TRUE(any != other);
  716. ASSERT_TRUE(entt::any{} != any);
  717. };
  718. int value = 42;
  719. test('c', 'a');
  720. test(fat{.1, .2, .3, .4}, fat{.0, .1, .2, .3});
  721. test(entt::forward_as_any(value), 3);
  722. test(3, entt::make_any<const int &>(value));
  723. }
  724. TEST_F(Any, NotComparable) {
  725. auto test = [](const auto &instance) {
  726. auto any = entt::forward_as_any(instance);
  727. ASSERT_EQ(any, any);
  728. ASSERT_NE(any, entt::any{instance});
  729. ASSERT_NE(entt::any{}, any);
  730. ASSERT_TRUE(any == any);
  731. ASSERT_FALSE(any == entt::any{instance});
  732. ASSERT_TRUE(entt::any{} != any);
  733. };
  734. test(not_comparable{});
  735. test(std::unordered_map<int, not_comparable>{});
  736. test(std::vector<not_comparable>{});
  737. }
  738. TEST_F(Any, CompareVoid) {
  739. entt::any any{std::in_place_type<void>};
  740. ASSERT_EQ(any, any);
  741. ASSERT_EQ(any, entt::any{std::in_place_type<void>});
  742. ASSERT_NE(entt::any{'a'}, any);
  743. ASSERT_EQ(any, entt::any{});
  744. ASSERT_TRUE(any == any);
  745. ASSERT_TRUE(any == entt::any{std::in_place_type<void>});
  746. ASSERT_FALSE(entt::any{'a'} == any);
  747. ASSERT_TRUE(any != entt::any{'a'});
  748. ASSERT_FALSE(entt::any{} != any);
  749. }
  750. TEST_F(Any, AnyCast) {
  751. entt::any any{42};
  752. const auto &cany = any;
  753. ASSERT_EQ(entt::any_cast<char>(&any), nullptr);
  754. ASSERT_EQ(entt::any_cast<char>(&cany), nullptr);
  755. ASSERT_EQ(*entt::any_cast<int>(&any), 42);
  756. ASSERT_EQ(*entt::any_cast<int>(&cany), 42);
  757. ASSERT_EQ(entt::any_cast<int &>(any), 42);
  758. ASSERT_DEATH(entt::any_cast<double &>(any), "");
  759. ASSERT_EQ(entt::any_cast<const int &>(cany), 42);
  760. ASSERT_DEATH(entt::any_cast<const double &>(cany), "");
  761. not_copyable<1> instance{};
  762. instance.payload[0u] = 42.;
  763. entt::any ref{entt::forward_as_any(instance)};
  764. entt::any cref{entt::forward_as_any(std::as_const(instance).payload[0u])};
  765. ASSERT_EQ(entt::any_cast<not_copyable<1>>(std::move(ref)).payload[0u], 42.);
  766. ASSERT_DEATH(entt::any_cast<not_copyable<1>>(std::as_const(ref).as_ref()), "");
  767. ASSERT_EQ(entt::any_cast<double>(std::move(cref)), 42.);
  768. ASSERT_DEATH(entt::any_cast<double>(entt::any{42}), "");
  769. ASSERT_EQ(entt::any_cast<int>(entt::any{42}), 42);
  770. }
  771. TEST_F(Any, MakeAny) {
  772. int value = 42;
  773. auto any = entt::make_any<int>(value);
  774. auto ext = entt::make_any<int, sizeof(int), alignof(int)>(value);
  775. auto ref = entt::make_any<int &>(value);
  776. ASSERT_TRUE(any);
  777. ASSERT_TRUE(ext);
  778. ASSERT_TRUE(ref);
  779. ASSERT_TRUE(any.owner());
  780. ASSERT_TRUE(ext.owner());
  781. ASSERT_FALSE(ref.owner());
  782. ASSERT_EQ(entt::any_cast<const int &>(any), 42);
  783. ASSERT_EQ(entt::any_cast<const int &>(ext), 42);
  784. ASSERT_EQ(entt::any_cast<const int &>(ref), 42);
  785. ASSERT_EQ(decltype(any)::length, entt::any::length);
  786. ASSERT_NE(decltype(ext)::length, entt::any::length);
  787. ASSERT_EQ(decltype(ref)::length, entt::any::length);
  788. ASSERT_NE(any.data(), &value);
  789. ASSERT_NE(ext.data(), &value);
  790. ASSERT_EQ(ref.data(), &value);
  791. }
  792. TEST_F(Any, ForwardAsAny) {
  793. int value = 42;
  794. auto any = entt::forward_as_any(std::move(value));
  795. auto ref = entt::forward_as_any(value);
  796. auto cref = entt::forward_as_any(std::as_const(value));
  797. ASSERT_TRUE(any);
  798. ASSERT_TRUE(ref);
  799. ASSERT_TRUE(cref);
  800. ASSERT_TRUE(any.owner());
  801. ASSERT_FALSE(ref.owner());
  802. ASSERT_FALSE(cref.owner());
  803. ASSERT_NE(entt::any_cast<int>(&any), nullptr);
  804. ASSERT_NE(entt::any_cast<int>(&ref), nullptr);
  805. ASSERT_EQ(entt::any_cast<int>(&cref), nullptr);
  806. ASSERT_EQ(entt::any_cast<const int &>(any), 42);
  807. ASSERT_EQ(entt::any_cast<const int &>(ref), 42);
  808. ASSERT_EQ(entt::any_cast<const int &>(cref), 42);
  809. ASSERT_NE(any.data(), &value);
  810. ASSERT_EQ(ref.data(), &value);
  811. }
  812. TEST_F(Any, NotCopyableType) {
  813. auto test = [](entt::any any) {
  814. entt::any copy{any};
  815. ASSERT_TRUE(any);
  816. ASSERT_FALSE(copy);
  817. ASSERT_TRUE(any.owner());
  818. ASSERT_TRUE(copy.owner());
  819. copy = any;
  820. ASSERT_TRUE(any);
  821. ASSERT_FALSE(copy);
  822. ASSERT_TRUE(any.owner());
  823. ASSERT_TRUE(copy.owner());
  824. };
  825. test(entt::any{std::in_place_type<not_copyable<1>>});
  826. test(entt::any{std::in_place_type<not_copyable<4>>});
  827. }
  828. TEST_F(Any, Array) {
  829. entt::any any{std::in_place_type<int[1]>};
  830. entt::any copy{any};
  831. ASSERT_TRUE(any);
  832. ASSERT_FALSE(copy);
  833. ASSERT_EQ(any.type(), entt::type_id<int[1]>());
  834. ASSERT_NE(entt::any_cast<int[1]>(&any), nullptr);
  835. ASSERT_EQ(entt::any_cast<int[2]>(&any), nullptr);
  836. ASSERT_EQ(entt::any_cast<int *>(&any), nullptr);
  837. entt::any_cast<int(&)[1]>(any)[0] = 42;
  838. ASSERT_EQ(entt::any_cast<const int(&)[1]>(std::as_const(any))[0], 42);
  839. }
  840. TEST_F(Any, CopyMoveReference) {
  841. int value{};
  842. auto test = [&](auto &&ref) {
  843. value = 3;
  844. auto any = entt::forward_as_any(ref);
  845. entt::any move = std::move(any);
  846. entt::any copy = move;
  847. ASSERT_TRUE(any);
  848. ASSERT_TRUE(move);
  849. ASSERT_TRUE(copy);
  850. ASSERT_FALSE(any.owner());
  851. ASSERT_FALSE(move.owner());
  852. ASSERT_TRUE(copy.owner());
  853. ASSERT_EQ(move.type(), entt::type_id<int>());
  854. ASSERT_EQ(copy.type(), entt::type_id<int>());
  855. ASSERT_EQ(std::as_const(move).data(), &value);
  856. ASSERT_NE(std::as_const(copy).data(), &value);
  857. ASSERT_EQ(entt::any_cast<int>(move), 3);
  858. ASSERT_EQ(entt::any_cast<int>(copy), 3);
  859. value = 42;
  860. ASSERT_EQ(entt::any_cast<const int &>(move), 42);
  861. ASSERT_EQ(entt::any_cast<const int &>(copy), 3);
  862. };
  863. test(value);
  864. test(std::as_const(value));
  865. }
  866. TEST_F(Any, SBOVsZeroedSBOSize) {
  867. entt::any sbo{42};
  868. const auto *broken = sbo.data();
  869. entt::any other = std::move(sbo);
  870. ASSERT_NE(broken, other.data());
  871. entt::basic_any<0u> dyn{42};
  872. const auto *valid = dyn.data();
  873. entt::basic_any<0u> same = std::move(dyn);
  874. ASSERT_EQ(valid, same.data());
  875. }
  876. TEST_F(Any, Alignment) {
  877. static constexpr auto alignment = alignof(over_aligned);
  878. auto test = [](auto *target, auto cb) {
  879. const auto *data = target[0].data();
  880. ASSERT_TRUE((reinterpret_cast<std::uintptr_t>(target[0u].data()) % alignment) == 0u);
  881. ASSERT_TRUE((reinterpret_cast<std::uintptr_t>(target[1u].data()) % alignment) == 0u);
  882. std::swap(target[0], target[1]);
  883. ASSERT_TRUE((reinterpret_cast<std::uintptr_t>(target[0u].data()) % alignment) == 0u);
  884. ASSERT_TRUE((reinterpret_cast<std::uintptr_t>(target[1u].data()) % alignment) == 0u);
  885. cb(data, target[1].data());
  886. };
  887. entt::basic_any<alignment> nosbo[2] = { over_aligned{}, over_aligned{} };
  888. test(nosbo, [](auto *pre, auto *post) { ASSERT_EQ(pre, post); });
  889. entt::basic_any<alignment, alignment> sbo[2] = { over_aligned{}, over_aligned{} };
  890. test(sbo, [](auto *pre, auto *post) { ASSERT_NE(pre, post); });
  891. }
  892. TEST_F(Any, AggregatesMustWork) {
  893. struct aggregate_type { int value; };
  894. // the goal of this test is to enforce the requirements for aggregate types
  895. entt::any{std::in_place_type<aggregate_type>, 42}.emplace<aggregate_type>(42);
  896. }
  897. TEST_F(Any, DeducedArrayType) {
  898. entt::any any{"array of char"};
  899. ASSERT_TRUE(any);
  900. ASSERT_EQ(any.type(), entt::type_id<const char *>());
  901. ASSERT_EQ((strcmp("array of char", entt::any_cast<const char *>(any))), 0);
  902. any = "another array of char";
  903. ASSERT_TRUE(any);
  904. ASSERT_EQ(any.type(), entt::type_id<const char *>());
  905. ASSERT_EQ((strcmp("another array of char", entt::any_cast<const char *>(any))), 0);
  906. }