sparse_set.cpp 51 KB

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