sparse_set.cpp 45 KB

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