any.cpp 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797
  1. #include <algorithm>
  2. #include <memory>
  3. #include <unordered_map>
  4. #include <vector>
  5. #include <gtest/gtest.h>
  6. #include <entt/core/any.hpp>
  7. struct fat {
  8. double value[4];
  9. inline static int counter = 0;
  10. ~fat() { ++counter; }
  11. bool operator==(const fat &other) const {
  12. return std::equal(std::begin(value), std::end(value), std::begin(other.value), std::end(other.value));
  13. }
  14. };
  15. struct empty {
  16. inline static int counter = 0;
  17. ~empty() { ++counter; }
  18. };
  19. struct not_comparable {
  20. bool operator==(const not_comparable &) const = delete;
  21. };
  22. TEST(Any, SBO) {
  23. entt::any any{'c'};
  24. ASSERT_TRUE(any);
  25. ASSERT_EQ(any.type(), entt::type_id<char>());
  26. ASSERT_EQ(entt::any_cast<double>(&any), nullptr);
  27. ASSERT_EQ(entt::any_cast<char>(any), 'c');
  28. }
  29. TEST(Any, NoSBO) {
  30. fat instance{{.1, .2, .3, .4}};
  31. entt::any any{instance};
  32. ASSERT_TRUE(any);
  33. ASSERT_EQ(any.type(), entt::type_id<fat>());
  34. ASSERT_EQ(entt::any_cast<double>(&any), nullptr);
  35. ASSERT_EQ(entt::any_cast<fat>(any), instance);
  36. }
  37. TEST(Any, Empty) {
  38. entt::any any{};
  39. ASSERT_FALSE(any);
  40. ASSERT_FALSE(any.type());
  41. ASSERT_EQ(entt::any_cast<double>(&any), nullptr);
  42. ASSERT_EQ(any.data(), nullptr);
  43. }
  44. TEST(Any, SBOInPlaceTypeConstruction) {
  45. entt::any any{std::in_place_type<int>, 42};
  46. ASSERT_TRUE(any);
  47. ASSERT_EQ(any.type(), entt::type_id<int>());
  48. ASSERT_EQ(entt::any_cast<double>(&any), nullptr);
  49. ASSERT_EQ(entt::any_cast<int>(any), 42);
  50. auto other = as_ref(any);
  51. ASSERT_TRUE(other);
  52. ASSERT_EQ(other.type(), entt::type_id<int>());
  53. ASSERT_EQ(entt::any_cast<int>(other), 42);
  54. ASSERT_EQ(other.data(), any.data());
  55. }
  56. TEST(Any, SBOAsRefConstruction) {
  57. int value = 42;
  58. entt::any any{std::ref(value)};
  59. ASSERT_TRUE(any);
  60. ASSERT_EQ(any.type(), entt::type_id<int>());
  61. ASSERT_EQ(entt::any_cast<double>(&any), nullptr);
  62. ASSERT_EQ(entt::any_cast<const int>(&any), &value);
  63. ASSERT_EQ(entt::any_cast<int>(&any), &value);
  64. ASSERT_EQ(entt::any_cast<const int>(&std::as_const(any)), &value);
  65. ASSERT_EQ(entt::any_cast<int>(&std::as_const(any)), &value);
  66. ASSERT_EQ(entt::any_cast<const int &>(any), 42);
  67. ASSERT_EQ(entt::any_cast<int>(any), 42);
  68. ASSERT_EQ(any.data(), &value);
  69. ASSERT_EQ(std::as_const(any).data(), &value);
  70. auto other = as_ref(any);
  71. ASSERT_TRUE(other);
  72. ASSERT_EQ(other.type(), entt::type_id<int>());
  73. ASSERT_EQ(entt::any_cast<int>(other), 42);
  74. ASSERT_EQ(other.data(), any.data());
  75. }
  76. TEST(Any, SBOAsConstRefConstruction) {
  77. int value = 42;
  78. entt::any any{std::cref(value)};
  79. ASSERT_TRUE(any);
  80. ASSERT_EQ(any.type(), entt::type_id<int>());
  81. ASSERT_EQ(entt::any_cast<double>(&any), nullptr);
  82. ASSERT_EQ(entt::any_cast<const int>(&any), &value);
  83. ASSERT_EQ(entt::any_cast<int>(&any), nullptr);
  84. ASSERT_EQ(entt::any_cast<const int>(&std::as_const(any)), &value);
  85. ASSERT_EQ(entt::any_cast<int>(&std::as_const(any)), &value);
  86. ASSERT_EQ(entt::any_cast<const int &>(any), 42);
  87. ASSERT_EQ(entt::any_cast<int>(any), 42);
  88. ASSERT_EQ(any.data(), nullptr);
  89. ASSERT_EQ(std::as_const(any).data(), &value);
  90. auto other = as_ref(any);
  91. ASSERT_TRUE(other);
  92. ASSERT_EQ(other.type(), entt::type_id<int>());
  93. ASSERT_EQ(entt::any_cast<int>(other), 42);
  94. ASSERT_EQ(other.data(), any.data());
  95. }
  96. TEST(Any, SBOCopyConstruction) {
  97. entt::any any{42};
  98. entt::any other{any};
  99. ASSERT_TRUE(any);
  100. ASSERT_TRUE(other);
  101. ASSERT_EQ(any.type(), entt::type_id<int>());
  102. ASSERT_EQ(other.type(), entt::type_id<int>());
  103. ASSERT_EQ(entt::any_cast<double>(&other), nullptr);
  104. ASSERT_EQ(entt::any_cast<int>(other), 42);
  105. }
  106. TEST(Any, SBOCopyAssignment) {
  107. entt::any any{42};
  108. entt::any other{3};
  109. other = any;
  110. ASSERT_TRUE(any);
  111. ASSERT_TRUE(other);
  112. ASSERT_EQ(any.type(), entt::type_id<int>());
  113. ASSERT_EQ(other.type(), entt::type_id<int>());
  114. ASSERT_EQ(entt::any_cast<double>(&other), nullptr);
  115. ASSERT_EQ(entt::any_cast<int>(other), 42);
  116. }
  117. TEST(Any, SBOMoveConstruction) {
  118. entt::any any{42};
  119. entt::any other{std::move(any)};
  120. ASSERT_FALSE(any);
  121. ASSERT_TRUE(other);
  122. ASSERT_FALSE(any.type());
  123. ASSERT_EQ(other.type(), entt::type_id<int>());
  124. ASSERT_EQ(entt::any_cast<double>(&other), nullptr);
  125. ASSERT_EQ(entt::any_cast<int>(other), 42);
  126. }
  127. TEST(Any, SBOMoveAssignment) {
  128. entt::any any{42};
  129. entt::any other{3};
  130. other = std::move(any);
  131. ASSERT_FALSE(any);
  132. ASSERT_TRUE(other);
  133. ASSERT_FALSE(any.type());
  134. ASSERT_EQ(other.type(), entt::type_id<int>());
  135. ASSERT_EQ(entt::any_cast<double>(&other), nullptr);
  136. ASSERT_EQ(entt::any_cast<int>(other), 42);
  137. }
  138. TEST(Any, SBODirectAssignment) {
  139. entt::any any{};
  140. any = 42;
  141. ASSERT_TRUE(any);
  142. ASSERT_EQ(any.type(), entt::type_id<int>());
  143. ASSERT_EQ(entt::any_cast<double>(&any), nullptr);
  144. ASSERT_EQ(entt::any_cast<int>(any), 42);
  145. }
  146. TEST(Any, NoSBOInPlaceTypeConstruction) {
  147. fat instance{{.1, .2, .3, .4}};
  148. entt::any any{std::in_place_type<fat>, instance};
  149. ASSERT_TRUE(any);
  150. ASSERT_EQ(any.type(), entt::type_id<fat>());
  151. ASSERT_EQ(entt::any_cast<double>(&any), nullptr);
  152. ASSERT_EQ(entt::any_cast<fat>(any), instance);
  153. auto other = as_ref(any);
  154. ASSERT_TRUE(other);
  155. ASSERT_EQ(other.type(), entt::type_id<fat>());
  156. ASSERT_EQ(entt::any_cast<fat>(other), (fat{{.1, .2, .3, .4}}));
  157. ASSERT_EQ(other.data(), any.data());
  158. }
  159. TEST(Any, NoSBOAsRefConstruction) {
  160. fat instance{{.1, .2, .3, .4}};
  161. entt::any any{std::ref(instance)};
  162. ASSERT_TRUE(any);
  163. ASSERT_EQ(any.type(), entt::type_id<fat>());
  164. ASSERT_EQ(entt::any_cast<double>(&any), nullptr);
  165. ASSERT_EQ(entt::any_cast<const fat>(&any), &instance);
  166. ASSERT_EQ(entt::any_cast<fat>(&any), &instance);
  167. ASSERT_EQ(entt::any_cast<const fat>(&std::as_const(any)), &instance);
  168. ASSERT_EQ(entt::any_cast<fat>(&std::as_const(any)), &instance);
  169. ASSERT_EQ(entt::any_cast<const fat &>(any), instance);
  170. ASSERT_EQ(entt::any_cast<fat>(any), instance);
  171. ASSERT_EQ(any.data(), &instance);
  172. ASSERT_EQ(std::as_const(any).data(), &instance);
  173. auto other = as_ref(any);
  174. ASSERT_TRUE(other);
  175. ASSERT_EQ(other.type(), entt::type_id<fat>());
  176. ASSERT_EQ(entt::any_cast<fat>(other), (fat{{.1, .2, .3, .4}}));
  177. ASSERT_EQ(other.data(), any.data());
  178. }
  179. TEST(Any, NoSBOAsConstRefConstruction) {
  180. fat instance{{.1, .2, .3, .4}};
  181. entt::any any{std::cref(instance)};
  182. ASSERT_TRUE(any);
  183. ASSERT_EQ(any.type(), entt::type_id<fat>());
  184. ASSERT_EQ(entt::any_cast<double>(&any), nullptr);
  185. ASSERT_EQ(entt::any_cast<const fat>(&any), &instance);
  186. ASSERT_EQ(entt::any_cast<fat>(&any), nullptr);
  187. ASSERT_EQ(entt::any_cast<const fat>(&std::as_const(any)), &instance);
  188. ASSERT_EQ(entt::any_cast<fat>(&std::as_const(any)), &instance);
  189. ASSERT_EQ(entt::any_cast<const fat &>(any), instance);
  190. ASSERT_EQ(entt::any_cast<fat>(any), instance);
  191. ASSERT_EQ(any.data(), nullptr);
  192. ASSERT_EQ(std::as_const(any).data(), &instance);
  193. auto other = as_ref(any);
  194. ASSERT_TRUE(other);
  195. ASSERT_EQ(other.type(), entt::type_id<fat>());
  196. ASSERT_EQ(entt::any_cast<fat>(other), (fat{{.1, .2, .3, .4}}));
  197. ASSERT_EQ(other.data(), any.data());
  198. }
  199. TEST(Any, NoSBOCopyConstruction) {
  200. fat instance{{.1, .2, .3, .4}};
  201. entt::any any{instance};
  202. entt::any other{any};
  203. ASSERT_TRUE(any);
  204. ASSERT_TRUE(other);
  205. ASSERT_EQ(any.type(), entt::type_id<fat>());
  206. ASSERT_EQ(other.type(), entt::type_id<fat>());
  207. ASSERT_EQ(entt::any_cast<double>(&other), nullptr);
  208. ASSERT_EQ(entt::any_cast<fat>(other), instance);
  209. }
  210. TEST(Any, NoSBOCopyAssignment) {
  211. fat instance{{.1, .2, .3, .4}};
  212. entt::any any{instance};
  213. entt::any other{3};
  214. other = any;
  215. ASSERT_TRUE(any);
  216. ASSERT_TRUE(other);
  217. ASSERT_EQ(any.type(), entt::type_id<fat>());
  218. ASSERT_EQ(other.type(), entt::type_id<fat>());
  219. ASSERT_EQ(entt::any_cast<double>(&other), nullptr);
  220. ASSERT_EQ(entt::any_cast<fat>(other), instance);
  221. }
  222. TEST(Any, NoSBOMoveConstruction) {
  223. fat instance{{.1, .2, .3, .4}};
  224. entt::any any{instance};
  225. entt::any other{std::move(any)};
  226. ASSERT_FALSE(any);
  227. ASSERT_TRUE(other);
  228. ASSERT_EQ(other.type(), entt::type_id<fat>());
  229. ASSERT_EQ(entt::any_cast<double>(&other), nullptr);
  230. ASSERT_EQ(entt::any_cast<fat>(other), instance);
  231. }
  232. TEST(Any, NoSBOMoveAssignment) {
  233. fat instance{{.1, .2, .3, .4}};
  234. entt::any any{instance};
  235. entt::any other{3};
  236. other = std::move(any);
  237. ASSERT_FALSE(any);
  238. ASSERT_TRUE(other);
  239. ASSERT_EQ(other.type(), entt::type_id<fat>());
  240. ASSERT_EQ(entt::any_cast<double>(&other), nullptr);
  241. ASSERT_EQ(entt::any_cast<fat>(other), instance);
  242. }
  243. TEST(Any, NoSBODirectAssignment) {
  244. fat instance{{.1, .2, .3, .4}};
  245. entt::any any{};
  246. any = instance;
  247. ASSERT_TRUE(any);
  248. ASSERT_EQ(any.type(), entt::type_id<fat>());
  249. ASSERT_EQ(entt::any_cast<double>(&any), nullptr);
  250. ASSERT_EQ(entt::any_cast<fat>(any), instance);
  251. }
  252. TEST(Any, VoidInPlaceTypeConstruction) {
  253. entt::any any{std::in_place_type<void>};
  254. ASSERT_FALSE(any);
  255. ASSERT_FALSE(any.type());
  256. ASSERT_EQ(entt::any_cast<int>(&any), nullptr);
  257. }
  258. TEST(Any, VoidCopyConstruction) {
  259. entt::any any{std::in_place_type<void>};
  260. entt::any other{any};
  261. ASSERT_FALSE(any);
  262. ASSERT_FALSE(other);
  263. ASSERT_FALSE(any.type());
  264. ASSERT_FALSE(other.type());
  265. ASSERT_EQ(entt::any_cast<int>(&any), nullptr);
  266. ASSERT_EQ(entt::any_cast<double>(&other), nullptr);
  267. }
  268. TEST(Any, VoidCopyAssignment) {
  269. entt::any any{std::in_place_type<void>};
  270. entt::any other{std::in_place_type<void>};
  271. other = any;
  272. ASSERT_FALSE(any);
  273. ASSERT_FALSE(other);
  274. ASSERT_FALSE(any.type());
  275. ASSERT_FALSE(other.type());
  276. ASSERT_EQ(entt::any_cast<int>(&any), nullptr);
  277. ASSERT_EQ(entt::any_cast<double>(&other), nullptr);
  278. }
  279. TEST(Any, VoidMoveConstruction) {
  280. entt::any any{std::in_place_type<void>};
  281. entt::any other{std::move(any)};
  282. ASSERT_FALSE(any);
  283. ASSERT_FALSE(other);
  284. ASSERT_FALSE(any.type());
  285. ASSERT_FALSE(other.type());
  286. ASSERT_EQ(entt::any_cast<int>(&any), nullptr);
  287. ASSERT_EQ(entt::any_cast<double>(&other), nullptr);
  288. }
  289. TEST(Any, VoidMoveAssignment) {
  290. entt::any any{std::in_place_type<void>};
  291. entt::any other{std::in_place_type<void>};
  292. other = std::move(any);
  293. ASSERT_FALSE(any);
  294. ASSERT_FALSE(other);
  295. ASSERT_FALSE(any.type());
  296. ASSERT_FALSE(other.type());
  297. ASSERT_EQ(entt::any_cast<int>(&any), nullptr);
  298. ASSERT_EQ(entt::any_cast<double>(&other), nullptr);
  299. }
  300. TEST(Any, SBOMoveInvalidate) {
  301. entt::any any{42};
  302. entt::any other{std::move(any)};
  303. entt::any valid = std::move(other);
  304. ASSERT_FALSE(any);
  305. ASSERT_FALSE(other);
  306. ASSERT_TRUE(valid);
  307. }
  308. TEST(Any, NoSBOMoveInvalidate) {
  309. fat instance{{.1, .2, .3, .4}};
  310. entt::any any{instance};
  311. entt::any other{std::move(any)};
  312. entt::any valid = std::move(other);
  313. ASSERT_FALSE(any);
  314. ASSERT_FALSE(other);
  315. ASSERT_TRUE(valid);
  316. }
  317. TEST(Any, VoidMoveInvalidate) {
  318. entt::any any{std::in_place_type<void>};
  319. entt::any other{std::move(any)};
  320. entt::any valid = std::move(other);
  321. ASSERT_FALSE(any);
  322. ASSERT_FALSE(other);
  323. ASSERT_FALSE(valid);
  324. }
  325. TEST(Any, SBODestruction) {
  326. {
  327. entt::any any{empty{}};
  328. empty::counter = 0;
  329. }
  330. ASSERT_EQ(empty::counter, 1);
  331. }
  332. TEST(Any, NoSBODestruction) {
  333. {
  334. entt::any any{fat{}};
  335. fat::counter = 0;
  336. }
  337. ASSERT_EQ(fat::counter, 1);
  338. }
  339. TEST(Any, VoidDestruction) {
  340. // just let asan tell us if everything is ok here
  341. [[maybe_unused]] entt::any any{std::in_place_type<void>};
  342. }
  343. TEST(Any, Emplace) {
  344. entt::any any{};
  345. any.emplace<int>(42);
  346. ASSERT_TRUE(any);
  347. ASSERT_EQ(any.type(), entt::type_id<int>());
  348. ASSERT_EQ(entt::any_cast<double>(&any), nullptr);
  349. ASSERT_EQ(entt::any_cast<int>(any), 42);
  350. }
  351. TEST(Any, EmplaceVoid) {
  352. entt::any any{};
  353. any.emplace<void>();
  354. ASSERT_FALSE(any);
  355. ASSERT_FALSE(any.type());
  356. }
  357. TEST(Any, SBOSwap) {
  358. entt::any lhs{'c'};
  359. entt::any rhs{42};
  360. std::swap(lhs, rhs);
  361. ASSERT_EQ(lhs.type(), entt::type_id<int>());
  362. ASSERT_EQ(rhs.type(), entt::type_id<char>());
  363. ASSERT_EQ(entt::any_cast<char>(&lhs), nullptr);
  364. ASSERT_EQ(entt::any_cast<int>(&rhs), nullptr);
  365. ASSERT_EQ(entt::any_cast<int>(lhs), 42);
  366. ASSERT_EQ(entt::any_cast<char>(rhs), 'c');
  367. }
  368. TEST(Any, NoSBOSwap) {
  369. entt::any lhs{fat{{.1, .2, .3, .4}}};
  370. entt::any rhs{fat{{.4, .3, .2, .1}}};
  371. std::swap(lhs, rhs);
  372. ASSERT_EQ(entt::any_cast<fat>(lhs), (fat{{.4, .3, .2, .1}}));
  373. ASSERT_EQ(entt::any_cast<fat>(rhs), (fat{{.1, .2, .3, .4}}));
  374. }
  375. TEST(Any, VoidSwap) {
  376. entt::any lhs{std::in_place_type<void>};
  377. entt::any rhs{std::in_place_type<void>};
  378. const auto *pre = lhs.data();
  379. std::swap(lhs, rhs);
  380. ASSERT_EQ(pre, lhs.data());
  381. }
  382. TEST(Any, SBOWithNoSBOSwap) {
  383. entt::any lhs{fat{{.1, .2, .3, .4}}};
  384. entt::any rhs{'c'};
  385. std::swap(lhs, rhs);
  386. ASSERT_EQ(lhs.type(), entt::type_id<char>());
  387. ASSERT_EQ(rhs.type(), entt::type_id<fat>());
  388. ASSERT_EQ(entt::any_cast<fat>(&lhs), nullptr);
  389. ASSERT_EQ(entt::any_cast<char>(&rhs), nullptr);
  390. ASSERT_EQ(entt::any_cast<char>(lhs), 'c');
  391. ASSERT_EQ(entt::any_cast<fat>(rhs), (fat{{.1, .2, .3, .4}}));
  392. }
  393. TEST(Any, SBOWithRefSwap) {
  394. int value = 3;
  395. entt::any lhs{std::ref(value)};
  396. entt::any rhs{'c'};
  397. std::swap(lhs, rhs);
  398. ASSERT_EQ(lhs.type(), entt::type_id<char>());
  399. ASSERT_EQ(rhs.type(), entt::type_id<int>());
  400. ASSERT_EQ(entt::any_cast<int>(&lhs), nullptr);
  401. ASSERT_EQ(entt::any_cast<char>(&rhs), nullptr);
  402. ASSERT_EQ(entt::any_cast<char>(lhs), 'c');
  403. ASSERT_EQ(entt::any_cast<int>(rhs), 3);
  404. ASSERT_EQ(rhs.data(), &value);
  405. }
  406. TEST(Any, SBOWithConstRefSwap) {
  407. int value = 3;
  408. entt::any lhs{std::cref(value)};
  409. entt::any rhs{'c'};
  410. std::swap(lhs, rhs);
  411. ASSERT_EQ(lhs.type(), entt::type_id<char>());
  412. ASSERT_EQ(rhs.type(), entt::type_id<int>());
  413. ASSERT_EQ(entt::any_cast<int>(&lhs), nullptr);
  414. ASSERT_EQ(entt::any_cast<char>(&rhs), nullptr);
  415. ASSERT_EQ(entt::any_cast<char>(lhs), 'c');
  416. ASSERT_EQ(entt::any_cast<int>(rhs), 3);
  417. ASSERT_EQ(rhs.data(), nullptr);
  418. ASSERT_EQ(std::as_const(rhs).data(), &value);
  419. }
  420. TEST(Any, SBOWithEmptySwap) {
  421. entt::any lhs{'c'};
  422. entt::any rhs{};
  423. std::swap(lhs, rhs);
  424. ASSERT_FALSE(lhs);
  425. ASSERT_EQ(rhs.type(), entt::type_id<char>());
  426. ASSERT_EQ(entt::any_cast<char>(&lhs), nullptr);
  427. ASSERT_EQ(entt::any_cast<double>(&rhs), nullptr);
  428. ASSERT_EQ(entt::any_cast<char>(rhs), 'c');
  429. std::swap(lhs, rhs);
  430. ASSERT_FALSE(rhs);
  431. ASSERT_EQ(lhs.type(), entt::type_id<char>());
  432. ASSERT_EQ(entt::any_cast<double>(&lhs), nullptr);
  433. ASSERT_EQ(entt::any_cast<char>(&rhs), nullptr);
  434. ASSERT_EQ(entt::any_cast<char>(lhs), 'c');
  435. }
  436. TEST(Any, SBOWithVoidSwap) {
  437. entt::any lhs{'c'};
  438. entt::any rhs{std::in_place_type<void>};
  439. std::swap(lhs, rhs);
  440. ASSERT_FALSE(lhs);
  441. ASSERT_EQ(rhs.type(), entt::type_id<char>());
  442. ASSERT_EQ(entt::any_cast<char>(&lhs), nullptr);
  443. ASSERT_EQ(entt::any_cast<double>(&rhs), nullptr);
  444. ASSERT_EQ(entt::any_cast<char>(rhs), 'c');
  445. std::swap(lhs, rhs);
  446. ASSERT_FALSE(rhs);
  447. ASSERT_EQ(lhs.type(), entt::type_id<char>());
  448. ASSERT_EQ(entt::any_cast<double>(&lhs), nullptr);
  449. ASSERT_EQ(entt::any_cast<char>(&rhs), nullptr);
  450. ASSERT_EQ(entt::any_cast<char>(lhs), 'c');
  451. }
  452. TEST(Any, NoSBOWithRefSwap) {
  453. int value = 3;
  454. entt::any lhs{std::ref(value)};
  455. entt::any rhs{fat{{.1, .2, .3, .4}}};
  456. std::swap(lhs, rhs);
  457. ASSERT_EQ(lhs.type(), entt::type_id<fat>());
  458. ASSERT_EQ(rhs.type(), entt::type_id<int>());
  459. ASSERT_EQ(entt::any_cast<int>(&lhs), nullptr);
  460. ASSERT_EQ(entt::any_cast<fat>(&rhs), nullptr);
  461. ASSERT_EQ(entt::any_cast<fat>(lhs), (fat{{.1, .2, .3, .4}}));
  462. ASSERT_EQ(entt::any_cast<int>(rhs), 3);
  463. ASSERT_EQ(rhs.data(), &value);
  464. }
  465. TEST(Any, NoSBOWithConstRefSwap) {
  466. int value = 3;
  467. entt::any lhs{std::cref(value)};
  468. entt::any rhs{fat{{.1, .2, .3, .4}}};
  469. std::swap(lhs, rhs);
  470. ASSERT_EQ(lhs.type(), entt::type_id<fat>());
  471. ASSERT_EQ(rhs.type(), entt::type_id<int>());
  472. ASSERT_EQ(entt::any_cast<int>(&lhs), nullptr);
  473. ASSERT_EQ(entt::any_cast<fat>(&rhs), nullptr);
  474. ASSERT_EQ(entt::any_cast<fat>(lhs), (fat{{.1, .2, .3, .4}}));
  475. ASSERT_EQ(entt::any_cast<int>(rhs), 3);
  476. ASSERT_EQ(rhs.data(), nullptr);
  477. ASSERT_EQ(std::as_const(rhs).data(), &value);
  478. }
  479. TEST(Any, NoSBOWithEmptySwap) {
  480. entt::any lhs{fat{{.1, .2, .3, .4}}};
  481. entt::any rhs{};
  482. std::swap(lhs, rhs);
  483. ASSERT_FALSE(lhs);
  484. ASSERT_EQ(rhs.type(), entt::type_id<fat>());
  485. ASSERT_EQ(entt::any_cast<fat>(&lhs), nullptr);
  486. ASSERT_EQ(entt::any_cast<double>(&rhs), nullptr);
  487. ASSERT_EQ(entt::any_cast<fat>(rhs), (fat{{.1, .2, .3, .4}}));
  488. std::swap(lhs, rhs);
  489. ASSERT_FALSE(rhs);
  490. ASSERT_EQ(lhs.type(), entt::type_id<fat>());
  491. ASSERT_EQ(entt::any_cast<double>(&lhs), nullptr);
  492. ASSERT_EQ(entt::any_cast<fat>(&rhs), nullptr);
  493. ASSERT_EQ(entt::any_cast<fat>(lhs), (fat{{.1, .2, .3, .4}}));
  494. }
  495. TEST(Any, NoSBOWithVoidSwap) {
  496. entt::any lhs{fat{{.1, .2, .3, .4}}};
  497. entt::any rhs{std::in_place_type<void>};
  498. std::swap(lhs, rhs);
  499. ASSERT_FALSE(lhs);
  500. ASSERT_EQ(rhs.type(), entt::type_id<fat>());
  501. ASSERT_EQ(entt::any_cast<fat>(&lhs), nullptr);
  502. ASSERT_EQ(entt::any_cast<double>(&rhs), nullptr);
  503. ASSERT_EQ(entt::any_cast<fat>(rhs), (fat{{.1, .2, .3, .4}}));
  504. std::swap(lhs, rhs);
  505. ASSERT_FALSE(rhs);
  506. ASSERT_EQ(lhs.type(), entt::type_id<fat>());
  507. ASSERT_EQ(entt::any_cast<double>(&lhs), nullptr);
  508. ASSERT_EQ(entt::any_cast<fat>(&rhs), nullptr);
  509. ASSERT_EQ(entt::any_cast<fat>(lhs), (fat{{.1, .2, .3, .4}}));
  510. }
  511. TEST(Any, AsRef) {
  512. entt::any any{42};
  513. auto ref = as_ref(any);
  514. auto cref = as_ref(std::as_const(any));
  515. ASSERT_EQ(entt::any_cast<int>(&any), any.data());
  516. ASSERT_EQ(entt::any_cast<int>(&ref), any.data());
  517. ASSERT_EQ(entt::any_cast<int>(&cref), nullptr);
  518. ASSERT_EQ(entt::any_cast<const int>(&any), any.data());
  519. ASSERT_EQ(entt::any_cast<const int>(&ref), any.data());
  520. ASSERT_EQ(entt::any_cast<const int>(&cref), any.data());
  521. ASSERT_EQ(entt::any_cast<int>(any), 42);
  522. ASSERT_EQ(entt::any_cast<int>(ref), 42);
  523. ASSERT_EQ(entt::any_cast<int>(cref), 42);
  524. ASSERT_EQ(entt::any_cast<const int>(any), 42);
  525. ASSERT_EQ(entt::any_cast<const int>(ref), 42);
  526. ASSERT_EQ(entt::any_cast<const int>(cref), 42);
  527. ASSERT_EQ(entt::any_cast<int &>(any), 42);
  528. ASSERT_EQ(entt::any_cast<const int &>(any), 42);
  529. ASSERT_EQ(entt::any_cast<int &>(ref), 42);
  530. ASSERT_EQ(entt::any_cast<const int &>(ref), 42);
  531. ASSERT_DEATH(entt::any_cast<int &>(cref), ".*");
  532. ASSERT_EQ(entt::any_cast<const int &>(cref), 42);
  533. entt::any_cast<int &>(any) = 3;
  534. ASSERT_EQ(entt::any_cast<int>(any), 3);
  535. ASSERT_EQ(entt::any_cast<int>(ref), 3);
  536. ASSERT_EQ(entt::any_cast<int>(cref), 3);
  537. std::swap(ref, cref);
  538. ASSERT_EQ(entt::any_cast<int>(&ref), nullptr);
  539. ASSERT_EQ(entt::any_cast<int>(&cref), any.data());
  540. ref = as_ref(ref);
  541. cref = as_ref(std::as_const(cref));
  542. ASSERT_EQ(entt::any_cast<int>(&ref), nullptr);
  543. ASSERT_EQ(entt::any_cast<int>(&cref), nullptr);
  544. ASSERT_EQ(entt::any_cast<const int>(&ref), any.data());
  545. ASSERT_EQ(entt::any_cast<const int>(&cref), any.data());
  546. ASSERT_DEATH(entt::any_cast<int &>(ref), ".*");
  547. ASSERT_DEATH(entt::any_cast<int &>(cref), ".*");
  548. ASSERT_EQ(entt::any_cast<const int &>(ref), 3);
  549. ASSERT_EQ(entt::any_cast<const int &>(cref), 3);
  550. ref = 42;
  551. cref = 42;
  552. ASSERT_NE(entt::any_cast<int>(&ref), nullptr);
  553. ASSERT_NE(entt::any_cast<int>(&cref), nullptr);
  554. ASSERT_EQ(entt::any_cast<int &>(ref), 42);
  555. ASSERT_EQ(entt::any_cast<int &>(cref), 42);
  556. ASSERT_EQ(entt::any_cast<const int &>(ref), 42);
  557. ASSERT_EQ(entt::any_cast<const int &>(cref), 42);
  558. ASSERT_NE(entt::any_cast<int>(&ref), any.data());
  559. ASSERT_NE(entt::any_cast<int>(&cref), any.data());
  560. }
  561. TEST(Any, Comparable) {
  562. auto test = [](entt::any any, entt::any other) {
  563. ASSERT_EQ(any, any);
  564. ASSERT_NE(other, any);
  565. ASSERT_NE(any, entt::any{});
  566. ASSERT_TRUE(any == any);
  567. ASSERT_FALSE(other == any);
  568. ASSERT_TRUE(any != other);
  569. ASSERT_TRUE(entt::any{} != any);
  570. };
  571. int value = 42;
  572. test('c', 'a');
  573. test(fat{{.1, .2, .3, .4}}, fat{{.0, .1, .2, .3}});
  574. test(std::ref(value), 3);
  575. test(3, std::cref(value));
  576. }
  577. TEST(Any, NotComparable) {
  578. auto test = [](const auto &instance) {
  579. entt::any any{std::cref(instance)};
  580. ASSERT_EQ(any, any);
  581. ASSERT_NE(any, entt::any{instance});
  582. ASSERT_NE(entt::any{}, any);
  583. ASSERT_TRUE(any == any);
  584. ASSERT_FALSE(any == entt::any{instance});
  585. ASSERT_TRUE(entt::any{} != any);
  586. };
  587. test(not_comparable{});
  588. test(std::unordered_map<int, not_comparable>{});
  589. test(std::vector<not_comparable>{});
  590. }
  591. TEST(Any, CompareVoid) {
  592. entt::any any{std::in_place_type<void>};
  593. ASSERT_EQ(any, any);
  594. ASSERT_EQ(any, entt::any{std::in_place_type<void>});
  595. ASSERT_NE(entt::any{'a'}, any);
  596. ASSERT_EQ(any, entt::any{});
  597. ASSERT_TRUE(any == any);
  598. ASSERT_TRUE(any == entt::any{std::in_place_type<void>});
  599. ASSERT_FALSE(entt::any{'a'} == any);
  600. ASSERT_TRUE(any != entt::any{'a'});
  601. ASSERT_FALSE(entt::any{} != any);
  602. }
  603. TEST(Any, AnyCast) {
  604. entt::any any{42};
  605. const auto &cany = any;
  606. ASSERT_EQ(entt::any_cast<char>(&any), nullptr);
  607. ASSERT_EQ(entt::any_cast<char>(&cany), nullptr);
  608. ASSERT_EQ(*entt::any_cast<int>(&any), 42);
  609. ASSERT_EQ(*entt::any_cast<int>(&cany), 42);
  610. ASSERT_EQ(entt::any_cast<int &>(any), 42);
  611. ASSERT_EQ(entt::any_cast<const int &>(cany), 42);
  612. ASSERT_EQ(entt::any_cast<int>(42), 42);
  613. }
  614. TEST(Any, NonCopyableType) {
  615. entt::any any{std::in_place_type<std::unique_ptr<int>>, new int{42}};
  616. entt::any copy{any};
  617. ASSERT_TRUE(any);
  618. ASSERT_FALSE(copy);
  619. copy = any;
  620. ASSERT_TRUE(any);
  621. ASSERT_FALSE(copy);
  622. }