sparse_set.cpp 42 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273
  1. #include <algorithm>
  2. #include <cstdint>
  3. #include <functional>
  4. #include <iterator>
  5. #include <type_traits>
  6. #include <utility>
  7. #include <gtest/gtest.h>
  8. #include <entt/entity/entity.hpp>
  9. #include <entt/entity/sparse_set.hpp>
  10. #include "throwing_allocator.hpp"
  11. struct empty_type {};
  12. struct boxed_int {
  13. int value;
  14. };
  15. TEST(SparseSet, Functionalities) {
  16. entt::sparse_set set;
  17. ASSERT_NO_THROW([[maybe_unused]] auto alloc = set.get_allocator());
  18. set.reserve(42);
  19. ASSERT_EQ(set.capacity(), 42u);
  20. ASSERT_TRUE(set.empty());
  21. ASSERT_EQ(set.size(), 0u);
  22. ASSERT_EQ(std::as_const(set).begin(), std::as_const(set).end());
  23. ASSERT_EQ(set.begin(), set.end());
  24. ASSERT_FALSE(set.contains(entt::entity{0}));
  25. ASSERT_FALSE(set.contains(entt::entity{42}));
  26. set.reserve(0);
  27. ASSERT_EQ(set.capacity(), 42u);
  28. ASSERT_TRUE(set.empty());
  29. set.emplace(entt::entity{42});
  30. ASSERT_FALSE(set.empty());
  31. ASSERT_EQ(set.size(), 1u);
  32. ASSERT_NE(std::as_const(set).begin(), std::as_const(set).end());
  33. ASSERT_NE(set.begin(), set.end());
  34. ASSERT_FALSE(set.contains(entt::entity{0}));
  35. ASSERT_TRUE(set.contains(entt::entity{42}));
  36. ASSERT_EQ(set.index(entt::entity{42}), 0u);
  37. ASSERT_EQ(set.at(0u), entt::entity{42});
  38. ASSERT_EQ(set.at(1u), static_cast<entt::entity>(entt::null));
  39. ASSERT_EQ(set[0u], entt::entity{42});
  40. set.erase(entt::entity{42});
  41. ASSERT_TRUE(set.empty());
  42. ASSERT_EQ(set.size(), 0u);
  43. ASSERT_EQ(std::as_const(set).begin(), std::as_const(set).end());
  44. ASSERT_EQ(set.begin(), set.end());
  45. ASSERT_FALSE(set.contains(entt::entity{0}));
  46. ASSERT_FALSE(set.contains(entt::entity{42}));
  47. ASSERT_EQ(set.at(0u), static_cast<entt::entity>(entt::null));
  48. ASSERT_EQ(set.at(1u), static_cast<entt::entity>(entt::null));
  49. set.emplace(entt::entity{42});
  50. ASSERT_FALSE(set.empty());
  51. ASSERT_EQ(set.index(entt::entity{42}), 0u);
  52. ASSERT_EQ(set.at(0u), entt::entity{42});
  53. ASSERT_EQ(set.at(1u), static_cast<entt::entity>(entt::null));
  54. ASSERT_EQ(set[0u], entt::entity{42});
  55. set.clear();
  56. ASSERT_TRUE(set.empty());
  57. ASSERT_EQ(set.size(), 0u);
  58. ASSERT_EQ(std::as_const(set).begin(), std::as_const(set).end());
  59. ASSERT_EQ(set.begin(), set.end());
  60. ASSERT_FALSE(set.contains(entt::entity{0}));
  61. ASSERT_FALSE(set.contains(entt::entity{42}));
  62. }
  63. TEST(SparseSet, Contains) {
  64. using traits_type = entt::entt_traits<entt::entity>;
  65. entt::sparse_set set{entt::deletion_policy::in_place};
  66. set.emplace(entt::entity{0});
  67. set.emplace(entt::entity{3});
  68. set.emplace(entt::entity{42});
  69. set.emplace(entt::entity{99});
  70. set.emplace(traits_type::construct(1, 5));
  71. ASSERT_FALSE(set.contains(entt::null));
  72. ASSERT_FALSE(set.contains(entt::tombstone));
  73. ASSERT_TRUE(set.contains(entt::entity{0}));
  74. ASSERT_TRUE(set.contains(entt::entity{3}));
  75. ASSERT_TRUE(set.contains(entt::entity{42}));
  76. ASSERT_TRUE(set.contains(entt::entity{99}));
  77. ASSERT_FALSE(set.contains(entt::entity{1}));
  78. ASSERT_TRUE(set.contains(traits_type::construct(1, 5)));
  79. ASSERT_TRUE(set.contains(traits_type::construct(3, 0)));
  80. ASSERT_FALSE(set.contains(traits_type::construct(42, 1)));
  81. ASSERT_FALSE(set.contains(traits_type::construct(99, traits_type::to_version(entt::tombstone))));
  82. set.erase(entt::entity{0});
  83. set.erase(entt::entity{3});
  84. set.remove(entt::entity{42});
  85. set.remove(entt::entity{99});
  86. ASSERT_FALSE(set.contains(entt::null));
  87. ASSERT_FALSE(set.contains(entt::tombstone));
  88. ASSERT_FALSE(set.contains(entt::entity{0}));
  89. ASSERT_FALSE(set.contains(entt::entity{3}));
  90. ASSERT_FALSE(set.contains(entt::entity{42}));
  91. ASSERT_FALSE(set.contains(entt::entity{99}));
  92. ASSERT_FALSE(set.contains(entt::entity{1}));
  93. ASSERT_TRUE(set.contains(traits_type::construct(1, 5)));
  94. ASSERT_FALSE(set.contains(traits_type::construct(99, traits_type::to_version(entt::tombstone))));
  95. }
  96. TEST(SparseSet, Current) {
  97. using traits_type = entt::entt_traits<entt::entity>;
  98. entt::sparse_set set{entt::deletion_policy::in_place};
  99. ASSERT_EQ(set.current(traits_type::construct(0, 0)), traits_type::to_version(entt::tombstone));
  100. ASSERT_EQ(set.current(traits_type::construct(3, 3)), traits_type::to_version(entt::tombstone));
  101. set.emplace(traits_type::construct(0, 0));
  102. set.emplace(traits_type::construct(3, 3));
  103. ASSERT_NE(set.current(traits_type::construct(0, 0)), traits_type::to_version(entt::tombstone));
  104. ASSERT_NE(set.current(traits_type::construct(3, 3)), traits_type::to_version(entt::tombstone));
  105. ASSERT_EQ(set.current(traits_type::construct(3, 0)), traits_type::to_version(traits_type::construct(3, 3)));
  106. ASSERT_EQ(set.current(traits_type::construct(42, 1)), traits_type::to_version(entt::tombstone));
  107. ASSERT_EQ(set.current(traits_type::construct(ENTT_SPARSE_PAGE, 1)), traits_type::to_version(entt::tombstone));
  108. set.remove(entt::entity{0});
  109. ASSERT_EQ(set.current(traits_type::construct(0, 0)), traits_type::to_version(entt::tombstone));
  110. ASSERT_EQ(set.current(traits_type::construct(3, 0)), traits_type::to_version(traits_type::construct(3, 3)));
  111. }
  112. TEST(SparseSet, Index) {
  113. using traits_type = entt::entt_traits<entt::entity>;
  114. entt::sparse_set set{};
  115. set.emplace(traits_type::construct(0, 0));
  116. set.emplace(traits_type::construct(3, 3));
  117. ASSERT_EQ(set.index(traits_type::construct(0, 0)), 0u);
  118. ASSERT_EQ(set.index(traits_type::construct(3, 3)), 1u);
  119. set.erase(traits_type::construct(0, 0));
  120. ASSERT_EQ(set.index(traits_type::construct(3, 3)), 0u);
  121. ASSERT_DEATH(static_cast<void>(set.index(traits_type::construct(3, 0))), "");
  122. ASSERT_DEATH(static_cast<void>(set.index(entt::null)), "");
  123. }
  124. TEST(SparseSet, Move) {
  125. entt::sparse_set set;
  126. set.emplace(entt::entity{42});
  127. ASSERT_TRUE(std::is_move_constructible_v<decltype(set)>);
  128. ASSERT_TRUE(std::is_move_assignable_v<decltype(set)>);
  129. entt::sparse_set other{std::move(set)};
  130. ASSERT_TRUE(set.empty());
  131. ASSERT_FALSE(other.empty());
  132. ASSERT_EQ(set.at(0u), static_cast<entt::entity>(entt::null));
  133. ASSERT_EQ(other.at(0u), entt::entity{42});
  134. set = std::move(other);
  135. ASSERT_FALSE(set.empty());
  136. ASSERT_TRUE(other.empty());
  137. ASSERT_EQ(set.at(0u), entt::entity{42});
  138. ASSERT_EQ(other.at(0u), static_cast<entt::entity>(entt::null));
  139. other = entt::sparse_set{};
  140. other.emplace(entt::entity{3});
  141. other = std::move(set);
  142. ASSERT_TRUE(set.empty());
  143. ASSERT_FALSE(other.empty());
  144. ASSERT_EQ(set.at(0u), static_cast<entt::entity>(entt::null));
  145. ASSERT_EQ(other.at(0u), entt::entity{42});
  146. }
  147. TEST(SparseSet, Swap) {
  148. entt::sparse_set set;
  149. entt::sparse_set other{entt::deletion_policy::in_place};
  150. set.emplace(entt::entity{42});
  151. other.emplace(entt::entity{9});
  152. other.emplace(entt::entity{3});
  153. other.erase(entt::entity{9});
  154. ASSERT_EQ(set.size(), 1u);
  155. ASSERT_EQ(other.size(), 2u);
  156. set.swap(other);
  157. ASSERT_EQ(set.size(), 2u);
  158. ASSERT_EQ(other.size(), 1u);
  159. ASSERT_EQ(set.at(1u), entt::entity{3});
  160. ASSERT_EQ(other.at(0u), entt::entity{42});
  161. }
  162. TEST(SparseSet, Pagination) {
  163. entt::sparse_set set;
  164. ASSERT_EQ(set.extent(), 0u);
  165. set.emplace(entt::entity{ENTT_SPARSE_PAGE - 1u});
  166. ASSERT_EQ(set.extent(), ENTT_SPARSE_PAGE);
  167. ASSERT_TRUE(set.contains(entt::entity{ENTT_SPARSE_PAGE - 1u}));
  168. set.emplace(entt::entity{ENTT_SPARSE_PAGE});
  169. ASSERT_EQ(set.extent(), 2 * ENTT_SPARSE_PAGE);
  170. ASSERT_TRUE(set.contains(entt::entity{ENTT_SPARSE_PAGE - 1u}));
  171. ASSERT_TRUE(set.contains(entt::entity{ENTT_SPARSE_PAGE}));
  172. ASSERT_FALSE(set.contains(entt::entity{ENTT_SPARSE_PAGE + 1u}));
  173. set.erase(entt::entity{ENTT_SPARSE_PAGE - 1u});
  174. ASSERT_EQ(set.extent(), 2 * ENTT_SPARSE_PAGE);
  175. ASSERT_FALSE(set.contains(entt::entity{ENTT_SPARSE_PAGE - 1u}));
  176. ASSERT_TRUE(set.contains(entt::entity{ENTT_SPARSE_PAGE}));
  177. set.shrink_to_fit();
  178. set.erase(entt::entity{ENTT_SPARSE_PAGE});
  179. ASSERT_EQ(set.extent(), 2 * ENTT_SPARSE_PAGE);
  180. ASSERT_FALSE(set.contains(entt::entity{ENTT_SPARSE_PAGE - 1u}));
  181. ASSERT_FALSE(set.contains(entt::entity{ENTT_SPARSE_PAGE}));
  182. set.shrink_to_fit();
  183. ASSERT_EQ(set.extent(), 2 * ENTT_SPARSE_PAGE);
  184. }
  185. TEST(SparseSet, Emplace) {
  186. using traits_type = entt::entt_traits<entt::entity>;
  187. entt::sparse_set set{entt::deletion_policy::in_place};
  188. entt::entity entities[2u]{entt::entity{3}, entt::entity{42}};
  189. ASSERT_TRUE(set.empty());
  190. set.emplace(entities[0u]);
  191. set.erase(entities[0u]);
  192. set.emplace(entities[1u]);
  193. set.emplace(entities[0u]);
  194. ASSERT_DEATH(set.emplace(traits_type::combine(3, 1)), "");
  195. ASSERT_DEATH(set.emplace(entities[1u]), "");
  196. ASSERT_EQ(set.at(0u), entities[1u]);
  197. ASSERT_EQ(set.at(1u), entities[0u]);
  198. ASSERT_EQ(set.index(entities[0u]), 1u);
  199. ASSERT_EQ(set.index(entities[1u]), 0u);
  200. set.erase(std::begin(entities), std::end(entities));
  201. set.emplace(entities[1u]);
  202. set.emplace(entities[0u]);
  203. ASSERT_EQ(set.at(0u), entities[1u]);
  204. ASSERT_EQ(set.at(1u), entities[0u]);
  205. ASSERT_EQ(set.index(entities[0u]), 1u);
  206. ASSERT_EQ(set.index(entities[1u]), 0u);
  207. }
  208. TEST(SparseSet, EmplaceOutOfBounds) {
  209. entt::sparse_set set{entt::deletion_policy::in_place};
  210. entt::entity entities[2u]{entt::entity{0}, entt::entity{ENTT_SPARSE_PAGE}};
  211. set.emplace(entities[0u]);
  212. ASSERT_EQ(set.extent(), ENTT_SPARSE_PAGE);
  213. ASSERT_EQ(set.index(entities[0u]), 0u);
  214. set.erase(entities[0u]);
  215. set.emplace(entities[1u]);
  216. ASSERT_EQ(set.extent(), 2u * ENTT_SPARSE_PAGE);
  217. ASSERT_EQ(set.index(entities[1u]), 0u);
  218. }
  219. TEST(SparseSet, Insert) {
  220. entt::sparse_set set{entt::deletion_policy::in_place};
  221. entt::entity entities[2u]{entt::entity{3}, entt::entity{42}};
  222. set.emplace(entt::entity{12});
  223. set.insert(std::end(entities), std::end(entities));
  224. set.insert(std::begin(entities), std::end(entities));
  225. set.emplace(entt::entity{24});
  226. ASSERT_TRUE(set.contains(entities[0u]));
  227. ASSERT_TRUE(set.contains(entities[1u]));
  228. ASSERT_FALSE(set.contains(entt::entity{0}));
  229. ASSERT_FALSE(set.contains(entt::entity{9}));
  230. ASSERT_TRUE(set.contains(entt::entity{12}));
  231. ASSERT_TRUE(set.contains(entt::entity{24}));
  232. ASSERT_FALSE(set.empty());
  233. ASSERT_EQ(set.size(), 4u);
  234. ASSERT_EQ(set.index(entt::entity{12}), 0u);
  235. ASSERT_EQ(set.index(entities[0u]), 1u);
  236. ASSERT_EQ(set.index(entities[1u]), 2u);
  237. ASSERT_EQ(set.index(entt::entity{24}), 3u);
  238. ASSERT_EQ(set.data()[set.index(entt::entity{12})], entt::entity{12});
  239. ASSERT_EQ(set.data()[set.index(entities[0u])], entities[0u]);
  240. ASSERT_EQ(set.data()[set.index(entities[1u])], entities[1u]);
  241. ASSERT_EQ(set.data()[set.index(entt::entity{24})], entt::entity{24});
  242. set.erase(std::begin(entities), std::end(entities));
  243. set.insert(std::rbegin(entities), std::rend(entities));
  244. ASSERT_EQ(set.size(), 4u);
  245. ASSERT_EQ(set.at(1u), entities[0u]);
  246. ASSERT_EQ(set.at(2u), entities[1u]);
  247. ASSERT_EQ(set.index(entities[0u]), 1u);
  248. ASSERT_EQ(set.index(entities[1u]), 2u);
  249. }
  250. TEST(SparseSet, Erase) {
  251. using traits_type = entt::entt_traits<entt::entity>;
  252. entt::sparse_set set;
  253. entt::entity entities[3u]{entt::entity{3}, entt::entity{42}, traits_type::construct(9, 3)};
  254. ASSERT_EQ(set.policy(), entt::deletion_policy::swap_and_pop);
  255. ASSERT_TRUE(set.empty());
  256. ASSERT_DEATH(set.erase(std::begin(entities), std::end(entities)), "");
  257. ASSERT_DEATH(set.erase(entities[1u]), "");
  258. ASSERT_TRUE(set.empty());
  259. set.insert(std::begin(entities), std::end(entities));
  260. set.erase(set.begin(), set.end());
  261. ASSERT_TRUE(set.empty());
  262. ASSERT_EQ(set.current(entities[0u]), traits_type::to_version(entt::tombstone));
  263. ASSERT_EQ(set.current(entities[1u]), traits_type::to_version(entt::tombstone));
  264. ASSERT_EQ(set.current(entities[2u]), traits_type::to_version(entt::tombstone));
  265. set.insert(std::begin(entities), std::end(entities));
  266. set.erase(entities, entities + 2u);
  267. ASSERT_FALSE(set.empty());
  268. ASSERT_EQ(set.current(entities[0u]), traits_type::to_version(entt::tombstone));
  269. ASSERT_EQ(set.current(entities[1u]), traits_type::to_version(entt::tombstone));
  270. ASSERT_EQ(set.current(entities[2u]), traits_type::to_version(entities[2u]));
  271. ASSERT_EQ(*set.begin(), entities[2u]);
  272. set.erase(entities[2u]);
  273. ASSERT_DEATH(set.erase(entities[2u]), "");
  274. ASSERT_TRUE(set.empty());
  275. ASSERT_EQ(set.current(entities[2u]), traits_type::to_version(entt::tombstone));
  276. set.insert(std::begin(entities), std::end(entities));
  277. std::swap(entities[1u], entities[2u]);
  278. set.erase(entities, entities + 2u);
  279. ASSERT_FALSE(set.empty());
  280. ASSERT_EQ(set.current(entities[2u]), traits_type::to_version(entities[2u]));
  281. ASSERT_EQ(*set.begin(), entities[2u]);
  282. ASSERT_DEATH(set.erase(traits_type::construct(9, 0)), "");
  283. ASSERT_DEATH(set.erase(entt::null), "");
  284. }
  285. TEST(SparseSet, StableErase) {
  286. using traits_type = entt::entt_traits<entt::entity>;
  287. entt::sparse_set set{entt::deletion_policy::in_place};
  288. entt::entity entities[3u]{entt::entity{3}, entt::entity{42}, traits_type::construct(9, 3)};
  289. ASSERT_EQ(set.policy(), entt::deletion_policy::in_place);
  290. ASSERT_TRUE(set.empty());
  291. ASSERT_EQ(set.size(), 0u);
  292. ASSERT_DEATH(set.erase(std::begin(entities), std::end(entities)), "");
  293. ASSERT_DEATH(set.erase(entities[1u]), "");
  294. ASSERT_TRUE(set.empty());
  295. ASSERT_EQ(set.size(), 0u);
  296. set.insert(std::begin(entities), std::end(entities));
  297. set.erase(set.begin(), set.end());
  298. ASSERT_FALSE(set.empty());
  299. ASSERT_EQ(set.size(), 3u);
  300. ASSERT_EQ(set.current(entities[0u]), traits_type::to_version(entt::tombstone));
  301. ASSERT_EQ(set.current(entities[1u]), traits_type::to_version(entt::tombstone));
  302. ASSERT_EQ(set.current(entities[2u]), traits_type::to_version(entt::tombstone));
  303. ASSERT_TRUE(set.at(0u) == entt::tombstone);
  304. ASSERT_TRUE(set.at(1u) == entt::tombstone);
  305. ASSERT_TRUE(set.at(2u) == entt::tombstone);
  306. ASSERT_EQ(set.slot(), 0u);
  307. set.insert(std::begin(entities), std::end(entities));
  308. set.erase(entities, entities + 2u);
  309. ASSERT_FALSE(set.empty());
  310. ASSERT_EQ(set.size(), 3u);
  311. ASSERT_EQ(set.current(entities[0u]), traits_type::to_version(entt::tombstone));
  312. ASSERT_EQ(set.current(entities[1u]), traits_type::to_version(entt::tombstone));
  313. ASSERT_EQ(set.current(entities[2u]), traits_type::to_version(entities[2u]));
  314. ASSERT_EQ(*set.begin(), entities[2u]);
  315. ASSERT_TRUE(set.at(0u) == entt::tombstone);
  316. ASSERT_TRUE(set.at(1u) == entt::tombstone);
  317. ASSERT_EQ(set.slot(), 1u);
  318. set.erase(entities[2u]);
  319. ASSERT_DEATH(set.erase(entities[2u]), "");
  320. ASSERT_FALSE(set.empty());
  321. ASSERT_EQ(set.size(), 3u);
  322. ASSERT_EQ(set.current(entities[2u]), traits_type::to_version(entt::tombstone));
  323. ASSERT_EQ(set.slot(), 2u);
  324. set.insert(std::begin(entities), std::end(entities));
  325. std::swap(entities[1u], entities[2u]);
  326. set.erase(entities, entities + 2u);
  327. ASSERT_FALSE(set.empty());
  328. ASSERT_EQ(set.size(), 3u);
  329. ASSERT_EQ(set.current(entities[2u]), traits_type::to_version(entities[2u]));
  330. ASSERT_TRUE(set.at(0u) == entt::tombstone);
  331. ASSERT_EQ(set.at(1u), entities[2u]);
  332. ASSERT_TRUE(set.at(2u) == entt::tombstone);
  333. ASSERT_EQ(*++set.begin(), entities[2u]);
  334. ASSERT_EQ(set.slot(), 0u);
  335. set.compact();
  336. ASSERT_FALSE(set.empty());
  337. ASSERT_EQ(set.size(), 1u);
  338. ASSERT_EQ(set.current(entities[0u]), traits_type::to_version(entt::tombstone));
  339. ASSERT_EQ(set.current(entities[1u]), traits_type::to_version(entt::tombstone));
  340. ASSERT_EQ(set.current(entities[2u]), traits_type::to_version(entities[2u]));
  341. ASSERT_TRUE(set.at(0u) == entities[2u]);
  342. ASSERT_EQ(*set.begin(), entities[2u]);
  343. ASSERT_EQ(set.slot(), 1u);
  344. set.clear();
  345. ASSERT_EQ(set.size(), 1u);
  346. ASSERT_EQ(set.current(entities[2u]), traits_type::to_version(entt::tombstone));
  347. ASSERT_TRUE(set.at(0u) == entt::tombstone);
  348. ASSERT_EQ(set.slot(), 0u);
  349. set.compact();
  350. ASSERT_EQ(set.size(), 0u);
  351. set.insert(std::begin(entities), std::end(entities));
  352. set.erase(entities[2u]);
  353. ASSERT_DEATH(set.erase(entities[2u]), "");
  354. ASSERT_NE(set.current(entities[0u]), traits_type::to_version(entt::tombstone));
  355. ASSERT_NE(set.current(entities[1u]), traits_type::to_version(entt::tombstone));
  356. ASSERT_EQ(set.current(entities[2u]), traits_type::to_version(entt::tombstone));
  357. ASSERT_EQ(set.slot(), 2u);
  358. set.erase(entities[0u]);
  359. set.erase(entities[1u]);
  360. ASSERT_DEATH(set.erase(entities, entities + 2u), "");
  361. ASSERT_EQ(set.size(), 3u);
  362. ASSERT_EQ(set.current(entities[0u]), traits_type::to_version(entt::tombstone));
  363. ASSERT_EQ(set.current(entities[1u]), traits_type::to_version(entt::tombstone));
  364. ASSERT_EQ(set.current(entities[2u]), traits_type::to_version(entt::tombstone));
  365. ASSERT_TRUE(*set.begin() == entt::tombstone);
  366. ASSERT_EQ(set.slot(), 1u);
  367. set.emplace(entities[0u]);
  368. ASSERT_EQ(*++set.begin(), entities[0u]);
  369. set.emplace(entities[1u]);
  370. set.emplace(entities[2u]);
  371. set.emplace(entt::entity{0});
  372. ASSERT_EQ(set.size(), 4u);
  373. ASSERT_EQ(*set.begin(), entt::entity{0});
  374. ASSERT_EQ(set.at(0u), entities[1u]);
  375. ASSERT_EQ(set.at(1u), entities[0u]);
  376. ASSERT_EQ(set.at(2u), entities[2u]);
  377. ASSERT_NE(set.current(entities[0u]), traits_type::to_version(entt::tombstone));
  378. ASSERT_NE(set.current(entities[1u]), traits_type::to_version(entt::tombstone));
  379. ASSERT_NE(set.current(entities[2u]), traits_type::to_version(entt::tombstone));
  380. ASSERT_DEATH(set.erase(traits_type::construct(9, 0)), "");
  381. ASSERT_DEATH(set.erase(entt::null), "");
  382. }
  383. TEST(SparseSet, Remove) {
  384. using traits_type = entt::entt_traits<entt::entity>;
  385. entt::sparse_set set;
  386. entt::entity entities[3u]{entt::entity{3}, entt::entity{42}, traits_type::construct(9, 3)};
  387. ASSERT_EQ(set.policy(), entt::deletion_policy::swap_and_pop);
  388. ASSERT_TRUE(set.empty());
  389. ASSERT_EQ(set.remove(std::begin(entities), std::end(entities)), 0u);
  390. ASSERT_EQ(set.remove(entities[1u]), 0u);
  391. ASSERT_TRUE(set.empty());
  392. set.insert(std::begin(entities), std::end(entities));
  393. ASSERT_EQ(set.remove(set.begin(), set.end()), 3u);
  394. ASSERT_TRUE(set.empty());
  395. ASSERT_EQ(set.current(entities[0u]), traits_type::to_version(entt::tombstone));
  396. ASSERT_EQ(set.current(entities[1u]), traits_type::to_version(entt::tombstone));
  397. ASSERT_EQ(set.current(entities[2u]), traits_type::to_version(entt::tombstone));
  398. set.insert(std::begin(entities), std::end(entities));
  399. ASSERT_EQ(set.remove(entities, entities + 2u), 2u);
  400. ASSERT_FALSE(set.empty());
  401. ASSERT_EQ(set.current(entities[0u]), traits_type::to_version(entt::tombstone));
  402. ASSERT_EQ(set.current(entities[1u]), traits_type::to_version(entt::tombstone));
  403. ASSERT_EQ(set.current(entities[2u]), traits_type::to_version(entities[2u]));
  404. ASSERT_EQ(*set.begin(), entities[2u]);
  405. ASSERT_EQ(set.remove(entities[2u]), 1u);
  406. ASSERT_EQ(set.remove(entities[2u]), 0u);
  407. ASSERT_TRUE(set.empty());
  408. ASSERT_EQ(set.current(entities[2u]), traits_type::to_version(entt::tombstone));
  409. set.insert(entities, entities + 2u);
  410. ASSERT_EQ(set.remove(std::begin(entities), std::end(entities)), 2u);
  411. ASSERT_EQ(set.current(entities[0u]), traits_type::to_version(entt::tombstone));
  412. ASSERT_EQ(set.current(entities[1u]), traits_type::to_version(entt::tombstone));
  413. ASSERT_EQ(set.current(entities[2u]), traits_type::to_version(entt::tombstone));
  414. ASSERT_TRUE(set.empty());
  415. set.insert(std::begin(entities), std::end(entities));
  416. std::swap(entities[1u], entities[2u]);
  417. ASSERT_EQ(set.remove(entities, entities + 2u), 2u);
  418. ASSERT_EQ(set.current(entities[2u]), traits_type::to_version(entities[2u]));
  419. ASSERT_FALSE(set.empty());
  420. ASSERT_EQ(*set.begin(), entities[2u]);
  421. ASSERT_EQ(set.remove(traits_type::construct(9, 0)), 0u);
  422. ASSERT_EQ(set.remove(entt::tombstone), 0u);
  423. ASSERT_EQ(set.remove(entt::null), 0u);
  424. }
  425. TEST(SparseSet, StableRemove) {
  426. using traits_type = entt::entt_traits<entt::entity>;
  427. entt::sparse_set set{entt::deletion_policy::in_place};
  428. entt::entity entities[3u]{entt::entity{3}, entt::entity{42}, traits_type::construct(9, 3)};
  429. ASSERT_EQ(set.policy(), entt::deletion_policy::in_place);
  430. ASSERT_TRUE(set.empty());
  431. ASSERT_EQ(set.size(), 0u);
  432. ASSERT_EQ(set.remove(std::begin(entities), std::end(entities)), 0u);
  433. ASSERT_EQ(set.remove(entities[1u]), 0u);
  434. ASSERT_TRUE(set.empty());
  435. ASSERT_EQ(set.size(), 0u);
  436. set.insert(std::begin(entities), std::end(entities));
  437. ASSERT_EQ(set.remove(set.begin(), set.end()), 3u);
  438. ASSERT_EQ(set.remove(set.begin(), set.end()), 0u);
  439. ASSERT_FALSE(set.empty());
  440. ASSERT_EQ(set.size(), 3u);
  441. ASSERT_EQ(set.current(entities[0u]), traits_type::to_version(entt::tombstone));
  442. ASSERT_EQ(set.current(entities[1u]), traits_type::to_version(entt::tombstone));
  443. ASSERT_EQ(set.current(entities[2u]), traits_type::to_version(entt::tombstone));
  444. ASSERT_TRUE(set.at(0u) == entt::tombstone);
  445. ASSERT_TRUE(set.at(1u) == entt::tombstone);
  446. ASSERT_TRUE(set.at(2u) == entt::tombstone);
  447. ASSERT_EQ(set.slot(), 0u);
  448. set.insert(std::begin(entities), std::end(entities));
  449. ASSERT_EQ(set.remove(entities, entities + 2u), 2u);
  450. ASSERT_EQ(set.remove(entities, entities + 2u), 0u);
  451. ASSERT_FALSE(set.empty());
  452. ASSERT_EQ(set.size(), 3u);
  453. ASSERT_EQ(set.current(entities[0u]), traits_type::to_version(entt::tombstone));
  454. ASSERT_EQ(set.current(entities[1u]), traits_type::to_version(entt::tombstone));
  455. ASSERT_EQ(set.current(entities[2u]), traits_type::to_version(entities[2u]));
  456. ASSERT_EQ(*set.begin(), entities[2u]);
  457. ASSERT_TRUE(set.at(0u) == entt::tombstone);
  458. ASSERT_TRUE(set.at(1u) == entt::tombstone);
  459. ASSERT_EQ(set.slot(), 1u);
  460. ASSERT_EQ(set.remove(entities[2u]), 1u);
  461. ASSERT_EQ(set.remove(entities[2u]), 0u);
  462. ASSERT_FALSE(set.empty());
  463. ASSERT_EQ(set.size(), 3u);
  464. ASSERT_EQ(set.current(entities[2u]), traits_type::to_version(entt::tombstone));
  465. ASSERT_EQ(set.slot(), 2u);
  466. set.insert(std::begin(entities), std::end(entities));
  467. std::swap(entities[1u], entities[2u]);
  468. ASSERT_EQ(set.remove(entities, entities + 2u), 2u);
  469. ASSERT_EQ(set.remove(entities, entities + 2u), 0u);
  470. ASSERT_FALSE(set.empty());
  471. ASSERT_EQ(set.size(), 3u);
  472. ASSERT_EQ(set.current(entities[2u]), traits_type::to_version(entities[2u]));
  473. ASSERT_TRUE(set.at(0u) == entt::tombstone);
  474. ASSERT_EQ(set.at(1u), entities[2u]);
  475. ASSERT_TRUE(set.at(2u) == entt::tombstone);
  476. ASSERT_EQ(*++set.begin(), entities[2u]);
  477. ASSERT_EQ(set.slot(), 0u);
  478. set.compact();
  479. ASSERT_FALSE(set.empty());
  480. ASSERT_EQ(set.size(), 1u);
  481. ASSERT_EQ(set.current(entities[0u]), traits_type::to_version(entt::tombstone));
  482. ASSERT_EQ(set.current(entities[1u]), traits_type::to_version(entt::tombstone));
  483. ASSERT_EQ(set.current(entities[2u]), traits_type::to_version(entities[2u]));
  484. ASSERT_TRUE(set.at(0u) == entities[2u]);
  485. ASSERT_EQ(*set.begin(), entities[2u]);
  486. ASSERT_EQ(set.slot(), 1u);
  487. set.clear();
  488. ASSERT_EQ(set.size(), 1u);
  489. ASSERT_EQ(set.current(entities[2u]), traits_type::to_version(entt::tombstone));
  490. ASSERT_TRUE(set.at(0u) == entt::tombstone);
  491. ASSERT_EQ(set.slot(), 0u);
  492. set.compact();
  493. ASSERT_EQ(set.size(), 0u);
  494. set.insert(std::begin(entities), std::end(entities));
  495. ASSERT_EQ(set.remove(entities[2u]), 1u);
  496. ASSERT_EQ(set.remove(entities[2u]), 0u);
  497. ASSERT_NE(set.current(entities[0u]), traits_type::to_version(entt::tombstone));
  498. ASSERT_NE(set.current(entities[1u]), traits_type::to_version(entt::tombstone));
  499. ASSERT_EQ(set.current(entities[2u]), traits_type::to_version(entt::tombstone));
  500. ASSERT_EQ(set.slot(), 2u);
  501. ASSERT_EQ(set.remove(entities[0u]), 1u);
  502. ASSERT_EQ(set.remove(entities[1u]), 1u);
  503. ASSERT_EQ(set.remove(entities, entities + 2u), 0u);
  504. ASSERT_EQ(set.size(), 3u);
  505. ASSERT_EQ(set.current(entities[0u]), traits_type::to_version(entt::tombstone));
  506. ASSERT_EQ(set.current(entities[1u]), traits_type::to_version(entt::tombstone));
  507. ASSERT_EQ(set.current(entities[2u]), traits_type::to_version(entt::tombstone));
  508. ASSERT_TRUE(*set.begin() == entt::tombstone);
  509. ASSERT_EQ(set.slot(), 1u);
  510. set.emplace(entities[0u]);
  511. ASSERT_EQ(*++set.begin(), entities[0u]);
  512. set.emplace(entities[1u]);
  513. set.emplace(entities[2u]);
  514. set.emplace(entt::entity{0});
  515. ASSERT_EQ(set.size(), 4u);
  516. ASSERT_EQ(*set.begin(), entt::entity{0});
  517. ASSERT_EQ(set.at(0u), entities[1u]);
  518. ASSERT_EQ(set.at(1u), entities[0u]);
  519. ASSERT_EQ(set.at(2u), entities[2u]);
  520. ASSERT_NE(set.current(entities[0u]), traits_type::to_version(entt::tombstone));
  521. ASSERT_NE(set.current(entities[1u]), traits_type::to_version(entt::tombstone));
  522. ASSERT_NE(set.current(entities[2u]), traits_type::to_version(entt::tombstone));
  523. ASSERT_EQ(set.remove(traits_type::construct(9, 0)), 0u);
  524. ASSERT_EQ(set.remove(entt::null), 0u);
  525. }
  526. TEST(SparseSet, Compact) {
  527. entt::sparse_set set{entt::deletion_policy::in_place};
  528. ASSERT_TRUE(set.empty());
  529. ASSERT_EQ(set.size(), 0u);
  530. set.compact();
  531. ASSERT_TRUE(set.empty());
  532. ASSERT_EQ(set.size(), 0u);
  533. set.emplace(entt::entity{0});
  534. set.compact();
  535. ASSERT_FALSE(set.empty());
  536. ASSERT_EQ(set.size(), 1u);
  537. set.emplace(entt::entity{42});
  538. set.erase(entt::entity{0});
  539. ASSERT_EQ(set.size(), 2u);
  540. ASSERT_EQ(set.index(entt::entity{42}), 1u);
  541. set.compact();
  542. ASSERT_EQ(set.size(), 1u);
  543. ASSERT_EQ(set.index(entt::entity{42}), 0u);
  544. set.emplace(entt::entity{0});
  545. set.compact();
  546. ASSERT_EQ(set.size(), 2u);
  547. ASSERT_EQ(set.index(entt::entity{42}), 0u);
  548. ASSERT_EQ(set.index(entt::entity{0}), 1u);
  549. set.erase(entt::entity{0});
  550. set.erase(entt::entity{42});
  551. set.compact();
  552. ASSERT_TRUE(set.empty());
  553. }
  554. TEST(SparseSet, SwapEntity) {
  555. using traits_type = entt::entt_traits<entt::entity>;
  556. entt::sparse_set set;
  557. set.emplace(traits_type::construct(3, 5));
  558. set.emplace(traits_type::construct(42, 99));
  559. ASSERT_EQ(set.index(traits_type::construct(3, 5)), 0u);
  560. ASSERT_EQ(set.index(traits_type::construct(42, 99)), 1u);
  561. ASSERT_DEATH(set.swap_elements(traits_type::construct(3, 5), traits_type::construct(42, 98)), "");
  562. ASSERT_DEATH(set.swap_elements(traits_type::construct(3, 6), traits_type::construct(42, 99)), "");
  563. set.swap_elements(traits_type::construct(3, 5), traits_type::construct(42, 99));
  564. ASSERT_EQ(set.index(traits_type::construct(3, 5)), 1u);
  565. ASSERT_EQ(set.index(traits_type::construct(42, 99)), 0u);
  566. set.swap_elements(traits_type::construct(3, 5), traits_type::construct(42, 99));
  567. ASSERT_EQ(set.index(traits_type::construct(3, 5)), 0u);
  568. ASSERT_EQ(set.index(traits_type::construct(42, 99)), 1u);
  569. }
  570. TEST(SparseSet, Clear) {
  571. entt::sparse_set set;
  572. set.emplace(entt::entity{3});
  573. set.emplace(entt::entity{42});
  574. set.emplace(entt::entity{9});
  575. ASSERT_FALSE(set.empty());
  576. set.clear();
  577. ASSERT_TRUE(set.empty());
  578. }
  579. TEST(SparseSet, Iterator) {
  580. using iterator = typename entt::sparse_set::iterator;
  581. static_assert(std::is_same_v<iterator::value_type, entt::entity>);
  582. static_assert(std::is_same_v<iterator::pointer, const entt::entity *>);
  583. static_assert(std::is_same_v<iterator::reference, const entt::entity &>);
  584. entt::sparse_set set;
  585. set.emplace(entt::entity{3});
  586. iterator end{set.begin()};
  587. iterator begin{};
  588. begin = set.end();
  589. std::swap(begin, end);
  590. ASSERT_EQ(begin, set.begin());
  591. ASSERT_EQ(end, set.end());
  592. ASSERT_NE(begin, end);
  593. ASSERT_EQ(begin++, set.begin());
  594. ASSERT_EQ(begin--, set.end());
  595. ASSERT_EQ(begin + 1, set.end());
  596. ASSERT_EQ(end - 1, set.begin());
  597. ASSERT_EQ(++begin, set.end());
  598. ASSERT_EQ(--begin, set.begin());
  599. ASSERT_EQ(begin += 1, set.end());
  600. ASSERT_EQ(begin -= 1, set.begin());
  601. ASSERT_EQ(begin + (end - begin), set.end());
  602. ASSERT_EQ(begin - (begin - end), set.end());
  603. ASSERT_EQ(end - (end - begin), set.begin());
  604. ASSERT_EQ(end + (begin - end), set.begin());
  605. ASSERT_EQ(begin[0u], *set.begin());
  606. ASSERT_LT(begin, end);
  607. ASSERT_LE(begin, set.begin());
  608. ASSERT_GT(end, begin);
  609. ASSERT_GE(end, set.end());
  610. ASSERT_EQ(*begin, entt::entity{3});
  611. ASSERT_EQ(*begin.operator->(), entt::entity{3});
  612. }
  613. TEST(SparseSet, ReverseIterator) {
  614. using reverse_iterator = typename entt::sparse_set::reverse_iterator;
  615. static_assert(std::is_same_v<reverse_iterator::value_type, entt::entity>);
  616. static_assert(std::is_same_v<reverse_iterator::pointer, const entt::entity *>);
  617. static_assert(std::is_same_v<reverse_iterator::reference, const entt::entity &>);
  618. entt::sparse_set set;
  619. set.emplace(entt::entity{3});
  620. reverse_iterator end{set.rbegin()};
  621. reverse_iterator begin{};
  622. begin = set.rend();
  623. std::swap(begin, end);
  624. ASSERT_EQ(begin, set.rbegin());
  625. ASSERT_EQ(end, set.rend());
  626. ASSERT_NE(begin, end);
  627. ASSERT_EQ(begin++, set.rbegin());
  628. ASSERT_EQ(begin--, set.rend());
  629. ASSERT_EQ(begin + 1, set.rend());
  630. ASSERT_EQ(end - 1, set.rbegin());
  631. ASSERT_EQ(++begin, set.rend());
  632. ASSERT_EQ(--begin, set.rbegin());
  633. ASSERT_EQ(begin += 1, set.rend());
  634. ASSERT_EQ(begin -= 1, set.rbegin());
  635. ASSERT_EQ(begin + (end - begin), set.rend());
  636. ASSERT_EQ(begin - (begin - end), set.rend());
  637. ASSERT_EQ(end - (end - begin), set.rbegin());
  638. ASSERT_EQ(end + (begin - end), set.rbegin());
  639. ASSERT_EQ(begin[0u], *set.rbegin());
  640. ASSERT_LT(begin, end);
  641. ASSERT_LE(begin, set.rbegin());
  642. ASSERT_GT(end, begin);
  643. ASSERT_GE(end, set.rend());
  644. ASSERT_EQ(*begin, entt::entity{3});
  645. }
  646. TEST(SparseSet, Find) {
  647. using traits_type = entt::entt_traits<entt::entity>;
  648. entt::sparse_set set;
  649. set.emplace(entt::entity{3});
  650. set.emplace(entt::entity{42});
  651. set.emplace(traits_type::construct(99, 1));
  652. ASSERT_NE(set.find(entt::entity{3}), set.end());
  653. ASSERT_NE(set.find(entt::entity{42}), set.end());
  654. ASSERT_NE(set.find(traits_type::construct(99, 1)), set.end());
  655. ASSERT_EQ(set.find(traits_type::construct(99, 5)), set.end());
  656. ASSERT_EQ(set.find(entt::entity{0}), set.end());
  657. ASSERT_EQ(set.find(entt::tombstone), set.end());
  658. ASSERT_EQ(set.find(entt::null), set.end());
  659. auto it = set.find(traits_type::construct(99, 1));
  660. ASSERT_EQ(*it, traits_type::construct(99, 1));
  661. ASSERT_EQ(*(++it), entt::entity{42});
  662. ASSERT_EQ(*(++it), entt::entity{3});
  663. ASSERT_EQ(++it, set.end());
  664. ASSERT_EQ(++set.find(entt::entity{3}), set.end());
  665. }
  666. TEST(SparseSet, Data) {
  667. entt::sparse_set set;
  668. set.emplace(entt::entity{3});
  669. set.emplace(entt::entity{12});
  670. set.emplace(entt::entity{42});
  671. ASSERT_EQ(set.index(entt::entity{3}), 0u);
  672. ASSERT_EQ(set.index(entt::entity{12}), 1u);
  673. ASSERT_EQ(set.index(entt::entity{42}), 2u);
  674. ASSERT_EQ(set.data()[0u], entt::entity{3});
  675. ASSERT_EQ(set.data()[1u], entt::entity{12});
  676. ASSERT_EQ(set.data()[2u], entt::entity{42});
  677. }
  678. TEST(SparseSet, SortOrdered) {
  679. entt::sparse_set set;
  680. entt::entity entities[5u]{entt::entity{42}, entt::entity{12}, entt::entity{9}, entt::entity{7}, entt::entity{3}};
  681. set.insert(std::begin(entities), std::end(entities));
  682. set.sort(std::less{});
  683. ASSERT_TRUE(std::equal(std::rbegin(entities), std::rend(entities), set.begin(), set.end()));
  684. }
  685. TEST(SparseSet, SortReverse) {
  686. entt::sparse_set set;
  687. entt::entity entities[5u]{entt::entity{3}, entt::entity{7}, entt::entity{9}, entt::entity{12}, entt::entity{42}};
  688. set.insert(std::begin(entities), std::end(entities));
  689. set.sort(std::less{});
  690. ASSERT_TRUE(std::equal(std::begin(entities), std::end(entities), set.begin(), set.end()));
  691. }
  692. TEST(SparseSet, SortUnordered) {
  693. entt::sparse_set set;
  694. entt::entity entities[5u]{entt::entity{9}, entt::entity{7}, entt::entity{3}, entt::entity{12}, entt::entity{42}};
  695. set.insert(std::begin(entities), std::end(entities));
  696. set.sort(std::less{});
  697. auto begin = set.begin();
  698. auto end = set.end();
  699. ASSERT_EQ(*(begin++), entities[2u]);
  700. ASSERT_EQ(*(begin++), entities[1u]);
  701. ASSERT_EQ(*(begin++), entities[0u]);
  702. ASSERT_EQ(*(begin++), entities[3u]);
  703. ASSERT_EQ(*(begin++), entities[4u]);
  704. ASSERT_EQ(begin, end);
  705. }
  706. TEST(SparseSet, SortRange) {
  707. entt::sparse_set set{entt::deletion_policy::in_place};
  708. entt::entity entities[5u]{entt::entity{7}, entt::entity{9}, entt::entity{3}, entt::entity{12}, entt::entity{42}};
  709. set.insert(std::begin(entities), std::end(entities));
  710. set.erase(entities[0u]);
  711. ASSERT_DEATH(set.sort_n(0u, std::less{});, "");
  712. ASSERT_EQ(set.size(), 5u);
  713. set.sort(std::less{});
  714. ASSERT_EQ(set.size(), 4u);
  715. ASSERT_EQ(set[0u], entities[4u]);
  716. ASSERT_EQ(set[1u], entities[3u]);
  717. ASSERT_EQ(set[2u], entities[1u]);
  718. ASSERT_EQ(set[3u], entities[2u]);
  719. set.clear();
  720. set.insert(std::begin(entities), std::end(entities));
  721. set.sort_n(0u, std::less{});
  722. ASSERT_TRUE(std::equal(std::rbegin(entities), std::rend(entities), set.begin(), set.end()));
  723. set.sort_n(2u, std::less{});
  724. ASSERT_EQ(set.data()[0u], entities[1u]);
  725. ASSERT_EQ(set.data()[1u], entities[0u]);
  726. ASSERT_EQ(set.data()[2u], entities[2u]);
  727. set.sort_n(5u, std::less{});
  728. auto begin = set.begin();
  729. auto end = set.end();
  730. ASSERT_EQ(*(begin++), entities[2u]);
  731. ASSERT_EQ(*(begin++), entities[0u]);
  732. ASSERT_EQ(*(begin++), entities[1u]);
  733. ASSERT_EQ(*(begin++), entities[3u]);
  734. ASSERT_EQ(*(begin++), entities[4u]);
  735. ASSERT_EQ(begin, end);
  736. }
  737. TEST(SparseSet, RespectDisjoint) {
  738. entt::sparse_set lhs;
  739. entt::sparse_set rhs;
  740. entt::entity lhs_entities[3u]{entt::entity{3}, entt::entity{12}, entt::entity{42}};
  741. lhs.insert(std::begin(lhs_entities), std::end(lhs_entities));
  742. ASSERT_TRUE(std::equal(std::rbegin(lhs_entities), std::rend(lhs_entities), lhs.begin(), lhs.end()));
  743. lhs.respect(rhs);
  744. ASSERT_TRUE(std::equal(std::rbegin(lhs_entities), std::rend(lhs_entities), lhs.begin(), lhs.end()));
  745. }
  746. TEST(SparseSet, RespectOverlap) {
  747. entt::sparse_set lhs;
  748. entt::sparse_set rhs;
  749. entt::entity lhs_entities[3u]{entt::entity{3}, entt::entity{12}, entt::entity{42}};
  750. lhs.insert(std::begin(lhs_entities), std::end(lhs_entities));
  751. entt::entity rhs_entities[1u]{entt::entity{12}};
  752. rhs.insert(std::begin(rhs_entities), std::end(rhs_entities));
  753. ASSERT_TRUE(std::equal(std::rbegin(lhs_entities), std::rend(lhs_entities), lhs.begin(), lhs.end()));
  754. ASSERT_TRUE(std::equal(std::rbegin(rhs_entities), std::rend(rhs_entities), rhs.begin(), rhs.end()));
  755. lhs.respect(rhs);
  756. auto begin = lhs.begin();
  757. auto end = lhs.end();
  758. ASSERT_EQ(*(begin++), lhs_entities[1u]);
  759. ASSERT_EQ(*(begin++), lhs_entities[2u]);
  760. ASSERT_EQ(*(begin++), lhs_entities[0u]);
  761. ASSERT_EQ(begin, end);
  762. }
  763. TEST(SparseSet, RespectOrdered) {
  764. entt::sparse_set lhs;
  765. entt::sparse_set rhs;
  766. entt::entity lhs_entities[5u]{entt::entity{1}, entt::entity{2}, entt::entity{3}, entt::entity{4}, entt::entity{5}};
  767. lhs.insert(std::begin(lhs_entities), std::end(lhs_entities));
  768. entt::entity rhs_entities[6u]{entt::entity{6}, entt::entity{1}, entt::entity{2}, entt::entity{3}, entt::entity{4}, entt::entity{5}};
  769. rhs.insert(std::begin(rhs_entities), std::end(rhs_entities));
  770. ASSERT_TRUE(std::equal(std::rbegin(lhs_entities), std::rend(lhs_entities), lhs.begin(), lhs.end()));
  771. ASSERT_TRUE(std::equal(std::rbegin(rhs_entities), std::rend(rhs_entities), rhs.begin(), rhs.end()));
  772. rhs.respect(lhs);
  773. ASSERT_TRUE(std::equal(std::rbegin(rhs_entities), std::rend(rhs_entities), rhs.begin(), rhs.end()));
  774. }
  775. TEST(SparseSet, RespectReverse) {
  776. entt::sparse_set lhs;
  777. entt::sparse_set rhs;
  778. entt::entity lhs_entities[5u]{entt::entity{1}, entt::entity{2}, entt::entity{3}, entt::entity{4}, entt::entity{5}};
  779. lhs.insert(std::begin(lhs_entities), std::end(lhs_entities));
  780. entt::entity rhs_entities[6u]{entt::entity{5}, entt::entity{4}, entt::entity{3}, entt::entity{2}, entt::entity{1}, entt::entity{6}};
  781. rhs.insert(std::begin(rhs_entities), std::end(rhs_entities));
  782. ASSERT_TRUE(std::equal(std::rbegin(lhs_entities), std::rend(lhs_entities), lhs.begin(), lhs.end()));
  783. ASSERT_TRUE(std::equal(std::rbegin(rhs_entities), std::rend(rhs_entities), rhs.begin(), rhs.end()));
  784. rhs.respect(lhs);
  785. auto begin = rhs.begin();
  786. auto end = rhs.end();
  787. ASSERT_EQ(*(begin++), rhs_entities[0u]);
  788. ASSERT_EQ(*(begin++), rhs_entities[1u]);
  789. ASSERT_EQ(*(begin++), rhs_entities[2u]);
  790. ASSERT_EQ(*(begin++), rhs_entities[3u]);
  791. ASSERT_EQ(*(begin++), rhs_entities[4u]);
  792. ASSERT_EQ(*(begin++), rhs_entities[5u]);
  793. ASSERT_EQ(begin, end);
  794. }
  795. TEST(SparseSet, RespectUnordered) {
  796. entt::sparse_set lhs;
  797. entt::sparse_set rhs;
  798. entt::entity lhs_entities[5u]{entt::entity{1}, entt::entity{2}, entt::entity{3}, entt::entity{4}, entt::entity{5}};
  799. lhs.insert(std::begin(lhs_entities), std::end(lhs_entities));
  800. entt::entity rhs_entities[6u]{entt::entity{3}, entt::entity{2}, entt::entity{6}, entt::entity{1}, entt::entity{4}, entt::entity{5}};
  801. rhs.insert(std::begin(rhs_entities), std::end(rhs_entities));
  802. ASSERT_TRUE(std::equal(std::rbegin(lhs_entities), std::rend(lhs_entities), lhs.begin(), lhs.end()));
  803. ASSERT_TRUE(std::equal(std::rbegin(rhs_entities), std::rend(rhs_entities), rhs.begin(), rhs.end()));
  804. rhs.respect(lhs);
  805. auto begin = rhs.begin();
  806. auto end = rhs.end();
  807. ASSERT_EQ(*(begin++), rhs_entities[5u]);
  808. ASSERT_EQ(*(begin++), rhs_entities[4u]);
  809. ASSERT_EQ(*(begin++), rhs_entities[0u]);
  810. ASSERT_EQ(*(begin++), rhs_entities[1u]);
  811. ASSERT_EQ(*(begin++), rhs_entities[3u]);
  812. ASSERT_EQ(*(begin++), rhs_entities[2u]);
  813. ASSERT_EQ(begin, end);
  814. }
  815. TEST(SparseSet, RespectInvalid) {
  816. using traits_type = entt::entt_traits<entt::entity>;
  817. entt::sparse_set lhs;
  818. entt::sparse_set rhs;
  819. entt::entity lhs_entities[3u]{entt::entity{1}, entt::entity{2}, traits_type::construct(3, 1)};
  820. lhs.insert(std::begin(lhs_entities), std::end(lhs_entities));
  821. entt::entity rhs_entities[3u]{entt::entity{2}, entt::entity{1}, traits_type::construct(3, 2)};
  822. rhs.insert(std::begin(rhs_entities), std::end(rhs_entities));
  823. ASSERT_TRUE(std::equal(std::rbegin(lhs_entities), std::rend(lhs_entities), lhs.begin(), lhs.end()));
  824. ASSERT_TRUE(std::equal(std::rbegin(rhs_entities), std::rend(rhs_entities), rhs.begin(), rhs.end()));
  825. rhs.respect(lhs);
  826. auto begin = rhs.begin();
  827. auto end = rhs.end();
  828. ASSERT_EQ(*(begin++), rhs_entities[0u]);
  829. ASSERT_EQ(*(begin++), rhs_entities[1u]);
  830. ASSERT_EQ(*(begin++), rhs_entities[2u]);
  831. ASSERT_EQ(rhs.current(rhs_entities[0u]), 0u);
  832. ASSERT_EQ(rhs.current(rhs_entities[1u]), 0u);
  833. ASSERT_EQ(rhs.current(rhs_entities[2u]), 2u);
  834. ASSERT_EQ(begin, end);
  835. }
  836. TEST(SparseSet, CanModifyDuringIteration) {
  837. entt::sparse_set set;
  838. set.emplace(entt::entity{0});
  839. ASSERT_EQ(set.capacity(), 1u);
  840. const auto it = set.begin();
  841. set.reserve(2u);
  842. ASSERT_EQ(set.capacity(), 2u);
  843. // this should crash with asan enabled if we break the constraint
  844. [[maybe_unused]] const auto entity = *it;
  845. }
  846. TEST(SparseSet, UserData) {
  847. entt::sparse_set set;
  848. int value = 42;
  849. ASSERT_EQ(set.user_data(), nullptr);
  850. set.user_data(&value);
  851. entt::sparse_set other{std::move(set)};
  852. ASSERT_EQ(std::as_const(set).user_data(), nullptr);
  853. ASSERT_EQ(other.user_data(), &value);
  854. std::swap(set, other);
  855. ASSERT_EQ(set.user_data(), &value);
  856. ASSERT_EQ(std::as_const(other).user_data(), nullptr);
  857. other = std::move(set);
  858. ASSERT_EQ(set.user_data(), nullptr);
  859. ASSERT_EQ(other.user_data(), &value);
  860. entt::sparse_set last{std::move(other), std::allocator<entt::entity>{}};
  861. ASSERT_EQ(set.user_data(), nullptr);
  862. ASSERT_EQ(other.user_data(), nullptr);
  863. ASSERT_EQ(last.user_data(), &value);
  864. }
  865. TEST(SparseSet, CustomAllocator) {
  866. test::throwing_allocator<entt::entity> allocator{};
  867. entt::basic_sparse_set<entt::entity, test::throwing_allocator<entt::entity>> set{allocator};
  868. ASSERT_EQ(set.get_allocator(), allocator);
  869. set.reserve(1u);
  870. ASSERT_EQ(set.capacity(), 1u);
  871. set.emplace(entt::entity{0});
  872. set.emplace(entt::entity{1});
  873. entt::basic_sparse_set<entt::entity, test::throwing_allocator<entt::entity>> other{std::move(set), allocator};
  874. ASSERT_TRUE(set.empty());
  875. ASSERT_FALSE(other.empty());
  876. ASSERT_EQ(set.capacity(), 0u);
  877. ASSERT_EQ(other.capacity(), 2u);
  878. ASSERT_EQ(other.size(), 2u);
  879. set = std::move(other);
  880. ASSERT_FALSE(set.empty());
  881. ASSERT_TRUE(other.empty());
  882. ASSERT_EQ(other.capacity(), 0u);
  883. ASSERT_EQ(set.capacity(), 2u);
  884. ASSERT_EQ(set.size(), 2u);
  885. set.swap(other);
  886. set = std::move(other);
  887. ASSERT_FALSE(set.empty());
  888. ASSERT_TRUE(other.empty());
  889. ASSERT_EQ(other.capacity(), 0u);
  890. ASSERT_EQ(set.capacity(), 2u);
  891. ASSERT_EQ(set.size(), 2u);
  892. set.clear();
  893. ASSERT_EQ(set.capacity(), 2u);
  894. ASSERT_EQ(set.size(), 0u);
  895. set.shrink_to_fit();
  896. ASSERT_EQ(set.capacity(), 0u);
  897. }
  898. TEST(SparseSet, ThrowingAllocator) {
  899. entt::basic_sparse_set<entt::entity, test::throwing_allocator<entt::entity>> set{};
  900. test::throwing_allocator<entt::entity>::trigger_on_allocate = true;
  901. ASSERT_THROW(set.reserve(1u), test::throwing_allocator<entt::entity>::exception_type);
  902. ASSERT_EQ(set.capacity(), 0u);
  903. ASSERT_EQ(set.extent(), 0u);
  904. test::throwing_allocator<entt::entity>::trigger_on_allocate = true;
  905. ASSERT_THROW(set.emplace(entt::entity{0}), test::throwing_allocator<entt::entity>::exception_type);
  906. ASSERT_EQ(set.extent(), ENTT_SPARSE_PAGE);
  907. ASSERT_EQ(set.capacity(), 0u);
  908. set.emplace(entt::entity{0});
  909. test::throwing_allocator<entt::entity>::trigger_on_allocate = true;
  910. ASSERT_THROW(set.reserve(2u), test::throwing_allocator<entt::entity>::exception_type);
  911. ASSERT_EQ(set.extent(), ENTT_SPARSE_PAGE);
  912. ASSERT_TRUE(set.contains(entt::entity{0}));
  913. ASSERT_EQ(set.capacity(), 1u);
  914. entt::entity entities[2u]{entt::entity{1}, entt::entity{ENTT_SPARSE_PAGE}};
  915. test::throwing_allocator<entt::entity>::trigger_after_allocate = true;
  916. ASSERT_THROW(set.insert(std::begin(entities), std::end(entities)), test::throwing_allocator<entt::entity>::exception_type);
  917. ASSERT_EQ(set.extent(), 2 * ENTT_SPARSE_PAGE);
  918. ASSERT_TRUE(set.contains(entt::entity{0}));
  919. ASSERT_TRUE(set.contains(entt::entity{1}));
  920. ASSERT_FALSE(set.contains(entt::entity{ENTT_SPARSE_PAGE}));
  921. ASSERT_EQ(set.capacity(), 3u);
  922. ASSERT_EQ(set.size(), 2u);
  923. set.emplace(entities[1u]);
  924. ASSERT_TRUE(set.contains(entt::entity{ENTT_SPARSE_PAGE}));
  925. }