any.cpp 40 KB

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