sparse_set.cpp 56 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721
  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.free_list(), 1u);
  419. ASSERT_EQ(set.current(entity[0u]), traits_type::to_version(entt::tombstone));
  420. ASSERT_EQ(set.current(entity[1u]), traits_type::to_version(entt::tombstone));
  421. ASSERT_EQ(set.current(entity[2u]), traits_type::to_version(entt::tombstone));
  422. ASSERT_TRUE(*set.begin() == entt::tombstone);
  423. set.push(entity[0u]);
  424. ASSERT_EQ(*++set.begin(), entity[0u]);
  425. set.push(entity[1u]);
  426. set.push(entity[2u]);
  427. set.push(entt::entity{0});
  428. ASSERT_EQ(set.size(), 4u);
  429. ASSERT_EQ(set.free_list(), traits_type::entity_mask);
  430. ASSERT_EQ(*set.begin(), entt::entity{0});
  431. ASSERT_EQ(set.at(0u), entity[1u]);
  432. ASSERT_EQ(set.at(1u), entity[0u]);
  433. ASSERT_EQ(set.at(2u), entity[2u]);
  434. ASSERT_NE(set.current(entity[0u]), traits_type::to_version(entt::tombstone));
  435. ASSERT_NE(set.current(entity[1u]), traits_type::to_version(entt::tombstone));
  436. ASSERT_NE(set.current(entity[2u]), traits_type::to_version(entt::tombstone));
  437. }
  438. ENTT_DEBUG_TEST(SparseSetDeathTest, StableErase) {
  439. using traits_type = entt::entt_traits<entt::entity>;
  440. entt::sparse_set set{entt::deletion_policy::in_place};
  441. entt::entity entity[2u]{entt::entity{42}, traits_type::construct(9, 3)};
  442. ASSERT_DEATH(set.erase(std::begin(entity), std::end(entity)), "");
  443. ASSERT_DEATH(set.erase(entt::null), "");
  444. }
  445. TEST(SparseSet, CrossStableErase) {
  446. entt::sparse_set set{entt::deletion_policy::in_place};
  447. entt::sparse_set other{entt::deletion_policy::in_place};
  448. entt::entity entity[2u]{entt::entity{3}, entt::entity{42}};
  449. set.push(std::begin(entity), std::end(entity));
  450. other.push(entity[1u]);
  451. set.erase(other.begin(), other.end());
  452. ASSERT_TRUE(set.contains(entity[0u]));
  453. ASSERT_FALSE(set.contains(entity[1u]));
  454. ASSERT_EQ(set.data()[0u], entity[0u]);
  455. }
  456. TEST(SparseSet, SwapOnlyErase) {
  457. using traits_type = entt::entt_traits<entt::entity>;
  458. entt::sparse_set set{entt::deletion_policy::swap_only};
  459. entt::entity entity[3u]{entt::entity{3}, entt::entity{42}, traits_type::construct(9, 3)};
  460. ASSERT_EQ(set.policy(), entt::deletion_policy::swap_only);
  461. ASSERT_EQ(set.free_list(), 0u);
  462. ASSERT_TRUE(set.empty());
  463. set.push(std::begin(entity), std::end(entity));
  464. set.erase(set.begin(), set.end());
  465. ASSERT_FALSE(set.empty());
  466. ASSERT_EQ(set.free_list(), 0u);
  467. entity[0u] = traits_type::next(entity[0u]);
  468. entity[1u] = traits_type::next(entity[1u]);
  469. entity[2u] = traits_type::next(entity[2u]);
  470. ASSERT_EQ(set.current(entity[0u]), traits_type::to_version(entity[0u]));
  471. ASSERT_EQ(set.current(entity[1u]), traits_type::to_version(entity[1u]));
  472. ASSERT_EQ(set.current(entity[2u]), traits_type::to_version(entity[2u]));
  473. set.push(std::begin(entity), std::end(entity));
  474. set.erase(entity, entity + 2u);
  475. ASSERT_FALSE(set.empty());
  476. ASSERT_EQ(set.free_list(), 1u);
  477. entity[0u] = traits_type::next(entity[0u]);
  478. entity[1u] = traits_type::next(entity[1u]);
  479. ASSERT_EQ(set.current(entity[0u]), traits_type::to_version(entity[0u]));
  480. ASSERT_EQ(set.current(entity[1u]), traits_type::to_version(entity[1u]));
  481. ASSERT_EQ(set.current(entity[2u]), traits_type::to_version(entity[2u]));
  482. ASSERT_EQ(*set.begin(), entity[0u]);
  483. set.erase(entity[2u]);
  484. ASSERT_FALSE(set.empty());
  485. ASSERT_EQ(set.free_list(), 0u);
  486. entity[2u] = traits_type::next(entity[2u]);
  487. ASSERT_EQ(set.current(entity[2u]), traits_type::to_version(entity[2u]));
  488. set.push(std::begin(entity), std::end(entity));
  489. std::swap(entity[1u], entity[2u]);
  490. set.erase(entity, entity + 2u);
  491. ASSERT_FALSE(set.empty());
  492. ASSERT_EQ(set.free_list(), 1);
  493. entity[0u] = traits_type::next(entity[0u]);
  494. entity[1u] = traits_type::next(entity[1u]);
  495. ASSERT_EQ(set.current(entity[2u]), traits_type::to_version(entity[2u]));
  496. ASSERT_EQ(*set.begin(), entity[0u]);
  497. }
  498. ENTT_DEBUG_TEST(SparseSetDeathTest, SwapOnlyErase) {
  499. using traits_type = entt::entt_traits<entt::entity>;
  500. entt::sparse_set set{entt::deletion_policy::swap_only};
  501. entt::entity entity[2u]{entt::entity{42}, traits_type::construct(9, 3)};
  502. ASSERT_DEATH(set.erase(std::begin(entity), std::end(entity)), "");
  503. ASSERT_DEATH(set.erase(entt::null), "");
  504. }
  505. TEST(SparseSet, CrossSwapOnlyErase) {
  506. using traits_type = entt::entt_traits<entt::entity>;
  507. entt::sparse_set set{entt::deletion_policy::swap_only};
  508. entt::sparse_set other{entt::deletion_policy::swap_only};
  509. entt::entity entity[2u]{entt::entity{3}, entt::entity{42}};
  510. set.push(std::begin(entity), std::end(entity));
  511. other.push(entity[1u]);
  512. set.erase(other.begin(), other.end());
  513. entity[1u] = traits_type::next(entity[1u]);
  514. ASSERT_TRUE(set.contains(entity[0u]));
  515. ASSERT_TRUE(set.contains(entity[1u]));
  516. ASSERT_EQ(set.data()[0u], entity[0u]);
  517. ASSERT_EQ(set.data()[1u], entity[1u]);
  518. }
  519. TEST(SparseSet, Remove) {
  520. using traits_type = entt::entt_traits<entt::entity>;
  521. entt::sparse_set set;
  522. entt::entity entity[3u]{entt::entity{3}, entt::entity{42}, traits_type::construct(9, 3)};
  523. ASSERT_EQ(set.policy(), entt::deletion_policy::swap_and_pop);
  524. ASSERT_EQ(set.free_list(), traits_type::entity_mask);
  525. ASSERT_TRUE(set.empty());
  526. ASSERT_EQ(set.remove(std::begin(entity), std::end(entity)), 0u);
  527. ASSERT_FALSE(set.remove(entity[1u]));
  528. ASSERT_TRUE(set.empty());
  529. ASSERT_EQ(set.free_list(), traits_type::entity_mask);
  530. set.push(std::begin(entity), std::end(entity));
  531. ASSERT_EQ(set.remove(set.begin(), set.end()), 3u);
  532. ASSERT_TRUE(set.empty());
  533. ASSERT_EQ(set.free_list(), traits_type::entity_mask);
  534. ASSERT_EQ(set.current(entity[0u]), traits_type::to_version(entt::tombstone));
  535. ASSERT_EQ(set.current(entity[1u]), traits_type::to_version(entt::tombstone));
  536. ASSERT_EQ(set.current(entity[2u]), traits_type::to_version(entt::tombstone));
  537. set.push(std::begin(entity), std::end(entity));
  538. ASSERT_EQ(set.remove(entity, entity + 2u), 2u);
  539. ASSERT_FALSE(set.empty());
  540. ASSERT_EQ(set.free_list(), traits_type::entity_mask);
  541. ASSERT_EQ(set.current(entity[0u]), traits_type::to_version(entt::tombstone));
  542. ASSERT_EQ(set.current(entity[1u]), traits_type::to_version(entt::tombstone));
  543. ASSERT_EQ(set.current(entity[2u]), traits_type::to_version(entity[2u]));
  544. ASSERT_EQ(*set.begin(), entity[2u]);
  545. ASSERT_TRUE(set.remove(entity[2u]));
  546. ASSERT_FALSE(set.remove(entity[2u]));
  547. ASSERT_TRUE(set.empty());
  548. ASSERT_EQ(set.current(entity[2u]), traits_type::to_version(entt::tombstone));
  549. set.push(entity, entity + 2u);
  550. ASSERT_EQ(set.remove(std::begin(entity), std::end(entity)), 2u);
  551. ASSERT_EQ(set.current(entity[0u]), traits_type::to_version(entt::tombstone));
  552. ASSERT_EQ(set.current(entity[1u]), traits_type::to_version(entt::tombstone));
  553. ASSERT_EQ(set.current(entity[2u]), traits_type::to_version(entt::tombstone));
  554. ASSERT_TRUE(set.empty());
  555. ASSERT_EQ(set.free_list(), traits_type::entity_mask);
  556. set.push(std::begin(entity), std::end(entity));
  557. std::swap(entity[1u], entity[2u]);
  558. ASSERT_EQ(set.remove(entity, entity + 2u), 2u);
  559. ASSERT_EQ(set.current(entity[2u]), traits_type::to_version(entity[2u]));
  560. ASSERT_FALSE(set.empty());
  561. ASSERT_EQ(set.free_list(), traits_type::entity_mask);
  562. ASSERT_EQ(*set.begin(), entity[2u]);
  563. ASSERT_FALSE(set.remove(traits_type::construct(9, 0)));
  564. ASSERT_FALSE(set.remove(entt::tombstone));
  565. ASSERT_FALSE(set.remove(entt::null));
  566. }
  567. TEST(SparseSet, CrossRemove) {
  568. entt::sparse_set set;
  569. entt::sparse_set other;
  570. entt::entity entity[2u]{entt::entity{3}, entt::entity{42}};
  571. set.push(std::begin(entity), std::end(entity));
  572. other.push(entity[1u]);
  573. set.remove(other.begin(), other.end());
  574. ASSERT_TRUE(set.contains(entity[0u]));
  575. ASSERT_FALSE(set.contains(entity[1u]));
  576. ASSERT_EQ(set.data()[0u], entity[0u]);
  577. }
  578. TEST(SparseSet, StableRemove) {
  579. using traits_type = entt::entt_traits<entt::entity>;
  580. entt::sparse_set set{entt::deletion_policy::in_place};
  581. entt::entity entity[3u]{entt::entity{3}, entt::entity{42}, traits_type::construct(9, 3)};
  582. ASSERT_EQ(set.policy(), entt::deletion_policy::in_place);
  583. ASSERT_EQ(set.free_list(), traits_type::entity_mask);
  584. ASSERT_TRUE(set.empty());
  585. ASSERT_EQ(set.size(), 0u);
  586. ASSERT_EQ(set.remove(std::begin(entity), std::end(entity)), 0u);
  587. ASSERT_FALSE(set.remove(entity[1u]));
  588. ASSERT_TRUE(set.empty());
  589. ASSERT_EQ(set.size(), 0u);
  590. ASSERT_EQ(set.free_list(), traits_type::entity_mask);
  591. set.push(entity[0u]);
  592. set.push(entity[1u]);
  593. set.push(entity[2u]);
  594. ASSERT_EQ(set.remove(set.begin(), set.end()), 3u);
  595. ASSERT_EQ(set.remove(set.begin(), set.end()), 0u);
  596. ASSERT_FALSE(set.empty());
  597. ASSERT_EQ(set.size(), 3u);
  598. ASSERT_EQ(set.free_list(), 0u);
  599. ASSERT_EQ(set.current(entity[0u]), traits_type::to_version(entt::tombstone));
  600. ASSERT_EQ(set.current(entity[1u]), traits_type::to_version(entt::tombstone));
  601. ASSERT_EQ(set.current(entity[2u]), traits_type::to_version(entt::tombstone));
  602. ASSERT_TRUE(set.at(0u) == entt::tombstone);
  603. ASSERT_TRUE(set.at(1u) == entt::tombstone);
  604. ASSERT_TRUE(set.at(2u) == entt::tombstone);
  605. set.push(entity[0u]);
  606. set.push(entity[1u]);
  607. set.push(entity[2u]);
  608. ASSERT_EQ(set.remove(entity, entity + 2u), 2u);
  609. ASSERT_EQ(set.remove(entity, entity + 2u), 0u);
  610. ASSERT_FALSE(set.empty());
  611. ASSERT_EQ(set.size(), 3u);
  612. ASSERT_EQ(set.free_list(), 1u);
  613. ASSERT_EQ(set.current(entity[0u]), traits_type::to_version(entt::tombstone));
  614. ASSERT_EQ(set.current(entity[1u]), traits_type::to_version(entt::tombstone));
  615. ASSERT_EQ(set.current(entity[2u]), traits_type::to_version(entity[2u]));
  616. ASSERT_EQ(*set.begin(), entity[2u]);
  617. ASSERT_TRUE(set.at(0u) == entt::tombstone);
  618. ASSERT_TRUE(set.at(1u) == entt::tombstone);
  619. ASSERT_TRUE(set.remove(entity[2u]));
  620. ASSERT_FALSE(set.remove(entity[2u]));
  621. ASSERT_FALSE(set.empty());
  622. ASSERT_EQ(set.size(), 3u);
  623. ASSERT_EQ(set.free_list(), 2u);
  624. ASSERT_EQ(set.current(entity[2u]), traits_type::to_version(entt::tombstone));
  625. set.push(entity[0u]);
  626. set.push(entity[1u]);
  627. set.push(entity[2u]);
  628. std::swap(entity[1u], entity[2u]);
  629. ASSERT_EQ(set.remove(entity, entity + 2u), 2u);
  630. ASSERT_EQ(set.remove(entity, entity + 2u), 0u);
  631. ASSERT_FALSE(set.empty());
  632. ASSERT_EQ(set.size(), 3u);
  633. ASSERT_EQ(set.free_list(), 0u);
  634. ASSERT_EQ(set.current(entity[2u]), traits_type::to_version(entity[2u]));
  635. ASSERT_TRUE(set.at(0u) == entt::tombstone);
  636. ASSERT_EQ(set.at(1u), entity[2u]);
  637. ASSERT_TRUE(set.at(2u) == entt::tombstone);
  638. ASSERT_EQ(*++set.begin(), entity[2u]);
  639. set.compact();
  640. ASSERT_FALSE(set.empty());
  641. ASSERT_EQ(set.size(), 1u);
  642. ASSERT_EQ(set.free_list(), traits_type::entity_mask);
  643. ASSERT_EQ(set.current(entity[0u]), traits_type::to_version(entt::tombstone));
  644. ASSERT_EQ(set.current(entity[1u]), traits_type::to_version(entt::tombstone));
  645. ASSERT_EQ(set.current(entity[2u]), traits_type::to_version(entity[2u]));
  646. ASSERT_TRUE(set.at(0u) == entity[2u]);
  647. ASSERT_EQ(*set.begin(), entity[2u]);
  648. set.clear();
  649. ASSERT_EQ(set.size(), 0u);
  650. ASSERT_EQ(set.free_list(), traits_type::entity_mask);
  651. ASSERT_EQ(set.current(entity[2u]), traits_type::to_version(entt::tombstone));
  652. set.push(entity[0u]);
  653. set.push(entity[1u]);
  654. set.push(entity[2u]);
  655. ASSERT_TRUE(set.remove(entity[2u]));
  656. ASSERT_FALSE(set.remove(entity[2u]));
  657. ASSERT_NE(set.current(entity[0u]), traits_type::to_version(entt::tombstone));
  658. ASSERT_NE(set.current(entity[1u]), traits_type::to_version(entt::tombstone));
  659. ASSERT_EQ(set.current(entity[2u]), traits_type::to_version(entt::tombstone));
  660. ASSERT_TRUE(set.remove(entity[0u]));
  661. ASSERT_TRUE(set.remove(entity[1u]));
  662. ASSERT_EQ(set.remove(entity, entity + 2u), 0u);
  663. ASSERT_EQ(set.size(), 3u);
  664. ASSERT_EQ(set.free_list(), 1u);
  665. ASSERT_EQ(set.current(entity[0u]), traits_type::to_version(entt::tombstone));
  666. ASSERT_EQ(set.current(entity[1u]), traits_type::to_version(entt::tombstone));
  667. ASSERT_EQ(set.current(entity[2u]), traits_type::to_version(entt::tombstone));
  668. ASSERT_TRUE(*set.begin() == entt::tombstone);
  669. set.push(entity[0u]);
  670. ASSERT_EQ(*++set.begin(), entity[0u]);
  671. set.push(entity[1u]);
  672. set.push(entity[2u]);
  673. set.push(entt::entity{0});
  674. ASSERT_EQ(set.size(), 4u);
  675. ASSERT_EQ(set.free_list(), traits_type::entity_mask);
  676. ASSERT_EQ(*set.begin(), entt::entity{0});
  677. ASSERT_EQ(set.at(0u), entity[1u]);
  678. ASSERT_EQ(set.at(1u), entity[0u]);
  679. ASSERT_EQ(set.at(2u), entity[2u]);
  680. ASSERT_NE(set.current(entity[0u]), traits_type::to_version(entt::tombstone));
  681. ASSERT_NE(set.current(entity[1u]), traits_type::to_version(entt::tombstone));
  682. ASSERT_NE(set.current(entity[2u]), traits_type::to_version(entt::tombstone));
  683. ASSERT_FALSE(set.remove(traits_type::construct(9, 0)));
  684. ASSERT_FALSE(set.remove(entt::null));
  685. }
  686. TEST(SparseSet, CrossStableRemove) {
  687. entt::sparse_set set{entt::deletion_policy::in_place};
  688. entt::sparse_set other{entt::deletion_policy::in_place};
  689. entt::entity entity[2u]{entt::entity{3}, entt::entity{42}};
  690. set.push(std::begin(entity), std::end(entity));
  691. other.push(entity[1u]);
  692. set.remove(other.begin(), other.end());
  693. ASSERT_TRUE(set.contains(entity[0u]));
  694. ASSERT_FALSE(set.contains(entity[1u]));
  695. ASSERT_EQ(set.data()[0u], entity[0u]);
  696. }
  697. TEST(SparseSet, SwapOnlyRemove) {
  698. using traits_type = entt::entt_traits<entt::entity>;
  699. entt::sparse_set set{entt::deletion_policy::swap_only};
  700. entt::entity entity[3u]{entt::entity{3}, entt::entity{42}, traits_type::construct(9, 3)};
  701. ASSERT_EQ(set.policy(), entt::deletion_policy::swap_only);
  702. ASSERT_EQ(set.free_list(), 0u);
  703. ASSERT_TRUE(set.empty());
  704. ASSERT_EQ(set.remove(std::begin(entity), std::end(entity)), 0u);
  705. ASSERT_FALSE(set.remove(entity[1u]));
  706. ASSERT_TRUE(set.empty());
  707. ASSERT_EQ(set.free_list(), 0u);
  708. set.push(std::begin(entity), std::end(entity));
  709. ASSERT_EQ(set.remove(set.begin(), set.end()), 3u);
  710. ASSERT_FALSE(set.empty());
  711. ASSERT_EQ(set.free_list(), 0u);
  712. entity[0u] = traits_type::next(entity[0u]);
  713. entity[1u] = traits_type::next(entity[1u]);
  714. entity[2u] = traits_type::next(entity[2u]);
  715. ASSERT_EQ(set.current(entity[0u]), traits_type::to_version(entity[0u]));
  716. ASSERT_EQ(set.current(entity[1u]), traits_type::to_version(entity[1u]));
  717. ASSERT_EQ(set.current(entity[2u]), traits_type::to_version(entity[2u]));
  718. set.push(std::begin(entity), std::end(entity));
  719. ASSERT_EQ(set.remove(entity, entity + 2u), 2u);
  720. ASSERT_FALSE(set.empty());
  721. ASSERT_EQ(set.free_list(), 1u);
  722. entity[0u] = traits_type::next(entity[0u]);
  723. entity[1u] = traits_type::next(entity[1u]);
  724. ASSERT_EQ(set.current(entity[0u]), traits_type::to_version(entity[0u]));
  725. ASSERT_EQ(set.current(entity[1u]), traits_type::to_version(entity[1u]));
  726. ASSERT_EQ(set.current(entity[2u]), traits_type::to_version(entity[2u]));
  727. ASSERT_EQ(*set.begin(), entity[0u]);
  728. ASSERT_TRUE(set.remove(entity[2u]));
  729. ASSERT_FALSE(set.remove(entity[2u]));
  730. entity[2u] = traits_type::next(entity[2u]);
  731. ASSERT_TRUE(set.remove(entity[2u]));
  732. ASSERT_FALSE(set.remove(entity[2u]));
  733. ASSERT_FALSE(set.empty());
  734. ASSERT_EQ(set.free_list(), 0u);
  735. ASSERT_EQ(set.current(entity[2u]), traits_type::to_version(traits_type::next(entity[2u])));
  736. set.push(entity, entity + 2u);
  737. ASSERT_EQ(set.remove(std::begin(entity), std::end(entity)), 2u);
  738. entity[0u] = traits_type::next(entity[0u]);
  739. entity[1u] = traits_type::next(entity[1u]);
  740. entity[2u] = traits_type::next(entity[2u]);
  741. ASSERT_EQ(set.current(entity[0u]), traits_type::to_version(entity[0u]));
  742. ASSERT_EQ(set.current(entity[1u]), traits_type::to_version(entity[1u]));
  743. ASSERT_EQ(set.current(entity[2u]), traits_type::to_version(entity[2u]));
  744. ASSERT_FALSE(set.empty());
  745. ASSERT_EQ(set.free_list(), 0u);
  746. set.push(std::begin(entity), std::end(entity));
  747. std::swap(entity[1u], entity[2u]);
  748. ASSERT_EQ(set.remove(entity, entity + 2u), 2u);
  749. entity[0u] = traits_type::next(entity[0u]);
  750. entity[1u] = traits_type::next(entity[1u]);
  751. ASSERT_EQ(set.current(entity[2u]), traits_type::to_version(entity[2u]));
  752. ASSERT_FALSE(set.empty());
  753. ASSERT_EQ(set.free_list(), 1u);
  754. ASSERT_EQ(*set.begin(), entity[0u]);
  755. ASSERT_FALSE(set.remove(traits_type::construct(9, 0)));
  756. ASSERT_FALSE(set.remove(entt::tombstone));
  757. ASSERT_FALSE(set.remove(entt::null));
  758. }
  759. TEST(SparseSet, CrossSwapOnlyRemove) {
  760. using traits_type = entt::entt_traits<entt::entity>;
  761. entt::sparse_set set{entt::deletion_policy::swap_only};
  762. entt::sparse_set other{entt::deletion_policy::swap_only};
  763. entt::entity entity[2u]{entt::entity{3}, entt::entity{42}};
  764. set.push(std::begin(entity), std::end(entity));
  765. other.push(entity[1u]);
  766. set.remove(other.begin(), other.end());
  767. entity[1u] = traits_type::next(entity[1u]);
  768. ASSERT_TRUE(set.contains(entity[0u]));
  769. ASSERT_TRUE(set.contains(entity[1u]));
  770. ASSERT_EQ(set.data()[0u], entity[0u]);
  771. ASSERT_EQ(set.data()[1u], entity[1u]);
  772. }
  773. TEST(SparseSet, Compact) {
  774. entt::sparse_set set{entt::deletion_policy::in_place};
  775. ASSERT_TRUE(set.empty());
  776. ASSERT_EQ(set.size(), 0u);
  777. set.compact();
  778. ASSERT_TRUE(set.empty());
  779. ASSERT_EQ(set.size(), 0u);
  780. set.push(entt::entity{0});
  781. set.compact();
  782. ASSERT_FALSE(set.empty());
  783. ASSERT_EQ(set.size(), 1u);
  784. set.push(entt::entity{42});
  785. set.erase(entt::entity{0});
  786. ASSERT_EQ(set.size(), 2u);
  787. ASSERT_EQ(set.index(entt::entity{42}), 1u);
  788. set.compact();
  789. ASSERT_EQ(set.size(), 1u);
  790. ASSERT_EQ(set.index(entt::entity{42}), 0u);
  791. set.push(entt::entity{0});
  792. set.compact();
  793. ASSERT_EQ(set.size(), 2u);
  794. ASSERT_EQ(set.index(entt::entity{42}), 0u);
  795. ASSERT_EQ(set.index(entt::entity{0}), 1u);
  796. set.erase(entt::entity{0});
  797. set.erase(entt::entity{42});
  798. set.compact();
  799. ASSERT_TRUE(set.empty());
  800. }
  801. TEST(SparseSet, SwapEntity) {
  802. using traits_type = entt::entt_traits<entt::entity>;
  803. entt::sparse_set set;
  804. set.push(traits_type::construct(3, 5));
  805. set.push(traits_type::construct(42, 99));
  806. ASSERT_EQ(set.index(traits_type::construct(3, 5)), 0u);
  807. ASSERT_EQ(set.index(traits_type::construct(42, 99)), 1u);
  808. set.swap_elements(traits_type::construct(3, 5), traits_type::construct(42, 99));
  809. ASSERT_EQ(set.index(traits_type::construct(3, 5)), 1u);
  810. ASSERT_EQ(set.index(traits_type::construct(42, 99)), 0u);
  811. set.swap_elements(traits_type::construct(3, 5), traits_type::construct(42, 99));
  812. ASSERT_EQ(set.index(traits_type::construct(3, 5)), 0u);
  813. ASSERT_EQ(set.index(traits_type::construct(42, 99)), 1u);
  814. }
  815. ENTT_DEBUG_TEST(SparseSetDeathTest, SwapEntity) {
  816. entt::sparse_set set;
  817. ASSERT_TRUE(set.empty());
  818. ASSERT_DEATH(set.swap_elements(entt::entity{0}, entt::entity{1}), "");
  819. }
  820. TEST(SparseSet, Clear) {
  821. entt::sparse_set set{entt::deletion_policy::in_place};
  822. set.push(entt::entity{3});
  823. set.push(entt::entity{42});
  824. set.push(entt::entity{9});
  825. set.erase(entt::entity{42});
  826. ASSERT_FALSE(set.empty());
  827. ASSERT_EQ(set.size(), 3u);
  828. ASSERT_EQ(*set.begin(), entt::entity{9});
  829. set.clear();
  830. ASSERT_TRUE(set.empty());
  831. ASSERT_EQ(set.size(), 0u);
  832. ASSERT_EQ(set.find(entt::entity{3}), set.end());
  833. ASSERT_EQ(set.find(entt::entity{9}), set.end());
  834. set.push(entt::entity{3});
  835. set.push(entt::entity{42});
  836. set.push(entt::entity{9});
  837. ASSERT_FALSE(set.empty());
  838. ASSERT_EQ(set.size(), 3u);
  839. ASSERT_EQ(*set.begin(), entt::entity{9});
  840. set.clear();
  841. ASSERT_TRUE(set.empty());
  842. ASSERT_EQ(set.size(), 0u);
  843. ASSERT_EQ(set.find(entt::entity{3}), set.end());
  844. ASSERT_EQ(set.find(entt::entity{42}), set.end());
  845. ASSERT_EQ(set.find(entt::entity{9}), set.end());
  846. }
  847. TEST(SparseSet, Contiguous) {
  848. entt::sparse_set swap_and_pop{entt::deletion_policy::swap_and_pop};
  849. entt::sparse_set in_place{entt::deletion_policy::in_place};
  850. const entt::entity entity{42};
  851. const entt::entity other{3};
  852. ASSERT_TRUE(swap_and_pop.contiguous());
  853. ASSERT_TRUE(in_place.contiguous());
  854. swap_and_pop.push(entity);
  855. in_place.push(entity);
  856. swap_and_pop.push(other);
  857. in_place.push(other);
  858. ASSERT_TRUE(swap_and_pop.contiguous());
  859. ASSERT_TRUE(in_place.contiguous());
  860. swap_and_pop.erase(entity);
  861. in_place.erase(entity);
  862. ASSERT_TRUE(swap_and_pop.contiguous());
  863. ASSERT_FALSE(in_place.contiguous());
  864. swap_and_pop.push(entity);
  865. in_place.push(entity);
  866. ASSERT_TRUE(swap_and_pop.contiguous());
  867. ASSERT_TRUE(in_place.contiguous());
  868. swap_and_pop.erase(other);
  869. in_place.erase(other);
  870. ASSERT_TRUE(swap_and_pop.contiguous());
  871. ASSERT_FALSE(in_place.contiguous());
  872. in_place.compact();
  873. ASSERT_TRUE(swap_and_pop.contiguous());
  874. ASSERT_TRUE(in_place.contiguous());
  875. swap_and_pop.push(other);
  876. in_place.push(other);
  877. swap_and_pop.erase(entity);
  878. in_place.erase(entity);
  879. ASSERT_TRUE(swap_and_pop.contiguous());
  880. ASSERT_FALSE(in_place.contiguous());
  881. swap_and_pop.clear();
  882. in_place.clear();
  883. ASSERT_TRUE(swap_and_pop.contiguous());
  884. ASSERT_TRUE(in_place.contiguous());
  885. }
  886. TEST(SparseSet, Iterator) {
  887. using iterator = typename entt::sparse_set::iterator;
  888. static_assert(std::is_same_v<iterator::value_type, entt::entity>);
  889. static_assert(std::is_same_v<iterator::pointer, const entt::entity *>);
  890. static_assert(std::is_same_v<iterator::reference, const entt::entity &>);
  891. entt::sparse_set set;
  892. set.push(entt::entity{3});
  893. iterator end{set.begin()};
  894. iterator begin{};
  895. ASSERT_EQ(end.data(), set.data());
  896. ASSERT_EQ(begin.data(), nullptr);
  897. begin = set.end();
  898. std::swap(begin, end);
  899. ASSERT_EQ(end.data(), set.data());
  900. ASSERT_EQ(begin.data(), set.data());
  901. ASSERT_EQ(begin, set.cbegin());
  902. ASSERT_EQ(end, set.cend());
  903. ASSERT_NE(begin, end);
  904. ASSERT_EQ(begin.index(), 0);
  905. ASSERT_EQ(end.index(), -1);
  906. ASSERT_EQ(begin++, set.begin());
  907. ASSERT_EQ(begin--, set.end());
  908. ASSERT_EQ(begin + 1, set.end());
  909. ASSERT_EQ(end - 1, set.begin());
  910. ASSERT_EQ(++begin, set.end());
  911. ASSERT_EQ(--begin, set.begin());
  912. ASSERT_EQ(begin += 1, set.end());
  913. ASSERT_EQ(begin -= 1, set.begin());
  914. ASSERT_EQ(begin + (end - begin), set.end());
  915. ASSERT_EQ(begin - (begin - end), set.end());
  916. ASSERT_EQ(end - (end - begin), set.begin());
  917. ASSERT_EQ(end + (begin - end), set.begin());
  918. ASSERT_EQ(begin[0u], *set.begin());
  919. ASSERT_LT(begin, end);
  920. ASSERT_LE(begin, set.begin());
  921. ASSERT_GT(end, begin);
  922. ASSERT_GE(end, set.end());
  923. ASSERT_EQ(*begin, entt::entity{3});
  924. ASSERT_EQ(*begin.operator->(), entt::entity{3});
  925. ASSERT_EQ(begin.index(), 0);
  926. ASSERT_EQ(end.index(), -1);
  927. set.push(entt::entity{42});
  928. begin = set.begin();
  929. ASSERT_EQ(begin.index(), 1);
  930. ASSERT_EQ(end.index(), -1);
  931. ASSERT_EQ(begin[0u], entt::entity{42});
  932. ASSERT_EQ(begin[1u], entt::entity{3});
  933. }
  934. TEST(SparseSet, ReverseIterator) {
  935. using reverse_iterator = typename entt::sparse_set::reverse_iterator;
  936. static_assert(std::is_same_v<reverse_iterator::value_type, entt::entity>);
  937. static_assert(std::is_same_v<reverse_iterator::pointer, const entt::entity *>);
  938. static_assert(std::is_same_v<reverse_iterator::reference, const entt::entity &>);
  939. entt::sparse_set set;
  940. set.push(entt::entity{3});
  941. reverse_iterator end{set.rbegin()};
  942. reverse_iterator begin{};
  943. begin = set.rend();
  944. std::swap(begin, end);
  945. ASSERT_EQ(begin, set.crbegin());
  946. ASSERT_EQ(end, set.crend());
  947. ASSERT_NE(begin, end);
  948. ASSERT_EQ(begin.base().index(), -1);
  949. ASSERT_EQ(end.base().index(), 0);
  950. ASSERT_EQ(begin++, set.rbegin());
  951. ASSERT_EQ(begin--, set.rend());
  952. ASSERT_EQ(begin + 1, set.rend());
  953. ASSERT_EQ(end - 1, set.rbegin());
  954. ASSERT_EQ(++begin, set.rend());
  955. ASSERT_EQ(--begin, set.rbegin());
  956. ASSERT_EQ(begin += 1, set.rend());
  957. ASSERT_EQ(begin -= 1, set.rbegin());
  958. ASSERT_EQ(begin + (end - begin), set.rend());
  959. ASSERT_EQ(begin - (begin - end), set.rend());
  960. ASSERT_EQ(end - (end - begin), set.rbegin());
  961. ASSERT_EQ(end + (begin - end), set.rbegin());
  962. ASSERT_EQ(begin[0u], *set.rbegin());
  963. ASSERT_LT(begin, end);
  964. ASSERT_LE(begin, set.rbegin());
  965. ASSERT_GT(end, begin);
  966. ASSERT_GE(end, set.rend());
  967. ASSERT_EQ(*begin, entt::entity{3});
  968. ASSERT_EQ(*begin.operator->(), entt::entity{3});
  969. ASSERT_EQ(begin.base().index(), -1);
  970. ASSERT_EQ(end.base().index(), 0);
  971. set.push(entt::entity{42});
  972. end = set.rend();
  973. ASSERT_EQ(begin.base().index(), -1);
  974. ASSERT_EQ(end.base().index(), 1);
  975. ASSERT_EQ(begin[0u], entt::entity{3});
  976. ASSERT_EQ(begin[1u], entt::entity{42});
  977. }
  978. TEST(SparseSet, Find) {
  979. using traits_type = entt::entt_traits<entt::entity>;
  980. entt::sparse_set set;
  981. set.push(entt::entity{3});
  982. set.push(entt::entity{42});
  983. set.push(traits_type::construct(99, 1));
  984. ASSERT_NE(set.find(entt::entity{3}), set.end());
  985. ASSERT_NE(set.find(entt::entity{42}), set.end());
  986. ASSERT_NE(set.find(traits_type::construct(99, 1)), set.end());
  987. ASSERT_EQ(set.find(traits_type::construct(99, 5)), set.end());
  988. ASSERT_EQ(set.find(entt::entity{0}), set.end());
  989. ASSERT_EQ(set.find(entt::tombstone), set.end());
  990. ASSERT_EQ(set.find(entt::null), set.end());
  991. auto it = set.find(traits_type::construct(99, 1));
  992. ASSERT_EQ(*it, traits_type::construct(99, 1));
  993. ASSERT_EQ(*(++it), entt::entity{42});
  994. ASSERT_EQ(*(++it), entt::entity{3});
  995. ASSERT_EQ(++it, set.end());
  996. ASSERT_EQ(++set.find(entt::entity{3}), set.end());
  997. }
  998. TEST(SparseSet, Data) {
  999. entt::sparse_set set;
  1000. set.push(entt::entity{3});
  1001. set.push(entt::entity{12});
  1002. set.push(entt::entity{42});
  1003. ASSERT_EQ(set.index(entt::entity{3}), 0u);
  1004. ASSERT_EQ(set.index(entt::entity{12}), 1u);
  1005. ASSERT_EQ(set.index(entt::entity{42}), 2u);
  1006. ASSERT_EQ(set.data()[0u], entt::entity{3});
  1007. ASSERT_EQ(set.data()[1u], entt::entity{12});
  1008. ASSERT_EQ(set.data()[2u], entt::entity{42});
  1009. }
  1010. TEST(SparseSet, SortOrdered) {
  1011. entt::sparse_set set;
  1012. entt::entity entity[5u]{entt::entity{42}, entt::entity{12}, entt::entity{9}, entt::entity{7}, entt::entity{3}};
  1013. set.push(std::begin(entity), std::end(entity));
  1014. set.sort(std::less{});
  1015. ASSERT_TRUE(std::equal(std::rbegin(entity), std::rend(entity), set.begin(), set.end()));
  1016. }
  1017. TEST(SparseSet, SortReverse) {
  1018. entt::sparse_set set;
  1019. entt::entity entity[5u]{entt::entity{3}, entt::entity{7}, entt::entity{9}, entt::entity{12}, entt::entity{42}};
  1020. set.push(std::begin(entity), std::end(entity));
  1021. set.sort(std::less{});
  1022. ASSERT_TRUE(std::equal(std::begin(entity), std::end(entity), set.begin(), set.end()));
  1023. }
  1024. TEST(SparseSet, SortUnordered) {
  1025. entt::sparse_set set;
  1026. entt::entity entity[5u]{entt::entity{9}, entt::entity{7}, entt::entity{3}, entt::entity{12}, entt::entity{42}};
  1027. set.push(std::begin(entity), std::end(entity));
  1028. set.sort(std::less{});
  1029. auto begin = set.begin();
  1030. auto end = set.end();
  1031. ASSERT_EQ(*(begin++), entity[2u]);
  1032. ASSERT_EQ(*(begin++), entity[1u]);
  1033. ASSERT_EQ(*(begin++), entity[0u]);
  1034. ASSERT_EQ(*(begin++), entity[3u]);
  1035. ASSERT_EQ(*(begin++), entity[4u]);
  1036. ASSERT_EQ(begin, end);
  1037. }
  1038. TEST(SparseSet, SortRange) {
  1039. entt::sparse_set set{entt::deletion_policy::in_place};
  1040. entt::entity entity[5u]{entt::entity{7}, entt::entity{9}, entt::entity{3}, entt::entity{12}, entt::entity{42}};
  1041. set.push(std::begin(entity), std::end(entity));
  1042. set.erase(entity[0u]);
  1043. ASSERT_EQ(set.size(), 5u);
  1044. set.sort(std::less{});
  1045. ASSERT_EQ(set.size(), 4u);
  1046. ASSERT_EQ(set[0u], entity[4u]);
  1047. ASSERT_EQ(set[1u], entity[3u]);
  1048. ASSERT_EQ(set[2u], entity[1u]);
  1049. ASSERT_EQ(set[3u], entity[2u]);
  1050. set.clear();
  1051. set.compact();
  1052. set.push(std::begin(entity), std::end(entity));
  1053. set.sort_n(0u, std::less{});
  1054. ASSERT_TRUE(std::equal(std::rbegin(entity), std::rend(entity), set.begin(), set.end()));
  1055. set.sort_n(2u, std::less{});
  1056. ASSERT_EQ(set.data()[0u], entity[1u]);
  1057. ASSERT_EQ(set.data()[1u], entity[0u]);
  1058. ASSERT_EQ(set.data()[2u], entity[2u]);
  1059. set.sort_n(5u, std::less{});
  1060. auto begin = set.begin();
  1061. auto end = set.end();
  1062. ASSERT_EQ(*(begin++), entity[2u]);
  1063. ASSERT_EQ(*(begin++), entity[0u]);
  1064. ASSERT_EQ(*(begin++), entity[1u]);
  1065. ASSERT_EQ(*(begin++), entity[3u]);
  1066. ASSERT_EQ(*(begin++), entity[4u]);
  1067. ASSERT_EQ(begin, end);
  1068. }
  1069. ENTT_DEBUG_TEST(SparseSetDeathTest, SortRange) {
  1070. entt::sparse_set set{entt::deletion_policy::in_place};
  1071. entt::entity entity{42};
  1072. set.push(entity);
  1073. set.erase(entity);
  1074. ASSERT_DEATH(set.sort_n(0u, std::less{});, "");
  1075. ASSERT_DEATH(set.sort_n(3u, std::less{});, "");
  1076. }
  1077. TEST(SparseSet, RespectDisjoint) {
  1078. entt::sparse_set lhs;
  1079. entt::sparse_set rhs;
  1080. entt::entity lhs_entity[3u]{entt::entity{3}, entt::entity{12}, entt::entity{42}};
  1081. lhs.push(std::begin(lhs_entity), std::end(lhs_entity));
  1082. ASSERT_TRUE(std::equal(std::rbegin(lhs_entity), std::rend(lhs_entity), lhs.begin(), lhs.end()));
  1083. lhs.sort_as(rhs);
  1084. ASSERT_TRUE(std::equal(std::rbegin(lhs_entity), std::rend(lhs_entity), lhs.begin(), lhs.end()));
  1085. }
  1086. TEST(SparseSet, RespectOverlap) {
  1087. entt::sparse_set lhs;
  1088. entt::sparse_set rhs;
  1089. entt::entity lhs_entity[3u]{entt::entity{3}, entt::entity{12}, entt::entity{42}};
  1090. lhs.push(std::begin(lhs_entity), std::end(lhs_entity));
  1091. entt::entity rhs_entity[1u]{entt::entity{12}};
  1092. rhs.push(std::begin(rhs_entity), std::end(rhs_entity));
  1093. ASSERT_TRUE(std::equal(std::rbegin(lhs_entity), std::rend(lhs_entity), lhs.begin(), lhs.end()));
  1094. ASSERT_TRUE(std::equal(std::rbegin(rhs_entity), std::rend(rhs_entity), rhs.begin(), rhs.end()));
  1095. lhs.sort_as(rhs);
  1096. auto begin = lhs.begin();
  1097. auto end = lhs.end();
  1098. ASSERT_EQ(*(begin++), lhs_entity[1u]);
  1099. ASSERT_EQ(*(begin++), lhs_entity[2u]);
  1100. ASSERT_EQ(*(begin++), lhs_entity[0u]);
  1101. ASSERT_EQ(begin, end);
  1102. }
  1103. TEST(SparseSet, RespectOrdered) {
  1104. entt::sparse_set lhs;
  1105. entt::sparse_set rhs;
  1106. entt::entity lhs_entity[5u]{entt::entity{1}, entt::entity{2}, entt::entity{3}, entt::entity{4}, entt::entity{5}};
  1107. lhs.push(std::begin(lhs_entity), std::end(lhs_entity));
  1108. entt::entity rhs_entity[6u]{entt::entity{6}, entt::entity{1}, entt::entity{2}, entt::entity{3}, entt::entity{4}, entt::entity{5}};
  1109. rhs.push(std::begin(rhs_entity), std::end(rhs_entity));
  1110. ASSERT_TRUE(std::equal(std::rbegin(lhs_entity), std::rend(lhs_entity), lhs.begin(), lhs.end()));
  1111. ASSERT_TRUE(std::equal(std::rbegin(rhs_entity), std::rend(rhs_entity), rhs.begin(), rhs.end()));
  1112. rhs.sort_as(lhs);
  1113. ASSERT_TRUE(std::equal(std::rbegin(rhs_entity), std::rend(rhs_entity), rhs.begin(), rhs.end()));
  1114. }
  1115. TEST(SparseSet, RespectReverse) {
  1116. entt::sparse_set lhs;
  1117. entt::sparse_set rhs;
  1118. entt::entity lhs_entity[5u]{entt::entity{1}, entt::entity{2}, entt::entity{3}, entt::entity{4}, entt::entity{5}};
  1119. lhs.push(std::begin(lhs_entity), std::end(lhs_entity));
  1120. entt::entity rhs_entity[6u]{entt::entity{5}, entt::entity{4}, entt::entity{3}, entt::entity{2}, entt::entity{1}, entt::entity{6}};
  1121. rhs.push(std::begin(rhs_entity), std::end(rhs_entity));
  1122. ASSERT_TRUE(std::equal(std::rbegin(lhs_entity), std::rend(lhs_entity), lhs.begin(), lhs.end()));
  1123. ASSERT_TRUE(std::equal(std::rbegin(rhs_entity), std::rend(rhs_entity), rhs.begin(), rhs.end()));
  1124. rhs.sort_as(lhs);
  1125. auto begin = rhs.begin();
  1126. auto end = rhs.end();
  1127. ASSERT_EQ(*(begin++), rhs_entity[0u]);
  1128. ASSERT_EQ(*(begin++), rhs_entity[1u]);
  1129. ASSERT_EQ(*(begin++), rhs_entity[2u]);
  1130. ASSERT_EQ(*(begin++), rhs_entity[3u]);
  1131. ASSERT_EQ(*(begin++), rhs_entity[4u]);
  1132. ASSERT_EQ(*(begin++), rhs_entity[5u]);
  1133. ASSERT_EQ(begin, end);
  1134. }
  1135. TEST(SparseSet, RespectUnordered) {
  1136. entt::sparse_set lhs;
  1137. entt::sparse_set rhs;
  1138. entt::entity lhs_entity[5u]{entt::entity{1}, entt::entity{2}, entt::entity{3}, entt::entity{4}, entt::entity{5}};
  1139. lhs.push(std::begin(lhs_entity), std::end(lhs_entity));
  1140. entt::entity rhs_entity[6u]{entt::entity{3}, entt::entity{2}, entt::entity{6}, entt::entity{1}, entt::entity{4}, entt::entity{5}};
  1141. rhs.push(std::begin(rhs_entity), std::end(rhs_entity));
  1142. ASSERT_TRUE(std::equal(std::rbegin(lhs_entity), std::rend(lhs_entity), lhs.begin(), lhs.end()));
  1143. ASSERT_TRUE(std::equal(std::rbegin(rhs_entity), std::rend(rhs_entity), rhs.begin(), rhs.end()));
  1144. rhs.sort_as(lhs);
  1145. auto begin = rhs.begin();
  1146. auto end = rhs.end();
  1147. ASSERT_EQ(*(begin++), rhs_entity[5u]);
  1148. ASSERT_EQ(*(begin++), rhs_entity[4u]);
  1149. ASSERT_EQ(*(begin++), rhs_entity[0u]);
  1150. ASSERT_EQ(*(begin++), rhs_entity[1u]);
  1151. ASSERT_EQ(*(begin++), rhs_entity[3u]);
  1152. ASSERT_EQ(*(begin++), rhs_entity[2u]);
  1153. ASSERT_EQ(begin, end);
  1154. }
  1155. TEST(SparseSet, RespectInvalid) {
  1156. using traits_type = entt::entt_traits<entt::entity>;
  1157. entt::sparse_set lhs;
  1158. entt::sparse_set rhs;
  1159. entt::entity lhs_entity[3u]{entt::entity{1}, entt::entity{2}, traits_type::construct(3, 1)};
  1160. lhs.push(std::begin(lhs_entity), std::end(lhs_entity));
  1161. entt::entity rhs_entity[3u]{entt::entity{2}, entt::entity{1}, traits_type::construct(3, 2)};
  1162. rhs.push(std::begin(rhs_entity), std::end(rhs_entity));
  1163. ASSERT_TRUE(std::equal(std::rbegin(lhs_entity), std::rend(lhs_entity), lhs.begin(), lhs.end()));
  1164. ASSERT_TRUE(std::equal(std::rbegin(rhs_entity), std::rend(rhs_entity), rhs.begin(), rhs.end()));
  1165. rhs.sort_as(lhs);
  1166. auto begin = rhs.begin();
  1167. auto end = rhs.end();
  1168. ASSERT_EQ(*(begin++), rhs_entity[0u]);
  1169. ASSERT_EQ(*(begin++), rhs_entity[1u]);
  1170. ASSERT_EQ(*(begin++), rhs_entity[2u]);
  1171. ASSERT_EQ(rhs.current(rhs_entity[0u]), 0u);
  1172. ASSERT_EQ(rhs.current(rhs_entity[1u]), 0u);
  1173. ASSERT_EQ(rhs.current(rhs_entity[2u]), 2u);
  1174. ASSERT_EQ(begin, end);
  1175. }
  1176. TEST(SparseSet, CanModifyDuringIteration) {
  1177. entt::sparse_set set;
  1178. set.push(entt::entity{0});
  1179. ASSERT_EQ(set.capacity(), 1u);
  1180. const auto it = set.begin();
  1181. set.reserve(2u);
  1182. ASSERT_EQ(set.capacity(), 2u);
  1183. // this should crash with asan enabled if we break the constraint
  1184. [[maybe_unused]] const auto entity = *it;
  1185. }
  1186. TEST(SparseSet, CustomAllocator) {
  1187. test::throwing_allocator<entt::entity> allocator{};
  1188. entt::basic_sparse_set<entt::entity, test::throwing_allocator<entt::entity>> set{allocator};
  1189. ASSERT_EQ(set.get_allocator(), allocator);
  1190. set.reserve(1u);
  1191. ASSERT_EQ(set.capacity(), 1u);
  1192. set.push(entt::entity{0});
  1193. set.push(entt::entity{1});
  1194. entt::basic_sparse_set<entt::entity, test::throwing_allocator<entt::entity>> other{std::move(set), allocator};
  1195. ASSERT_TRUE(set.empty());
  1196. ASSERT_FALSE(other.empty());
  1197. ASSERT_EQ(set.capacity(), 0u);
  1198. ASSERT_EQ(other.capacity(), 2u);
  1199. ASSERT_EQ(other.size(), 2u);
  1200. set = std::move(other);
  1201. ASSERT_FALSE(set.empty());
  1202. ASSERT_TRUE(other.empty());
  1203. ASSERT_EQ(other.capacity(), 0u);
  1204. ASSERT_EQ(set.capacity(), 2u);
  1205. ASSERT_EQ(set.size(), 2u);
  1206. set.swap(other);
  1207. set = std::move(other);
  1208. ASSERT_FALSE(set.empty());
  1209. ASSERT_TRUE(other.empty());
  1210. ASSERT_EQ(other.capacity(), 0u);
  1211. ASSERT_EQ(set.capacity(), 2u);
  1212. ASSERT_EQ(set.size(), 2u);
  1213. set.clear();
  1214. ASSERT_EQ(set.capacity(), 2u);
  1215. ASSERT_EQ(set.size(), 0u);
  1216. set.shrink_to_fit();
  1217. ASSERT_EQ(set.capacity(), 0u);
  1218. }
  1219. TEST(SparseSet, ThrowingAllocator) {
  1220. using traits_type = entt::entt_traits<entt::entity>;
  1221. entt::basic_sparse_set<entt::entity, test::throwing_allocator<entt::entity>> set{};
  1222. test::throwing_allocator<entt::entity>::trigger_on_allocate = true;
  1223. ASSERT_THROW(set.reserve(1u), test::throwing_allocator<entt::entity>::exception_type);
  1224. ASSERT_EQ(set.capacity(), 0u);
  1225. ASSERT_EQ(set.extent(), 0u);
  1226. test::throwing_allocator<entt::entity>::trigger_on_allocate = true;
  1227. ASSERT_THROW(set.push(entt::entity{0}), test::throwing_allocator<entt::entity>::exception_type);
  1228. ASSERT_EQ(set.extent(), traits_type::page_size);
  1229. ASSERT_EQ(set.capacity(), 0u);
  1230. set.push(entt::entity{0});
  1231. test::throwing_allocator<entt::entity>::trigger_on_allocate = true;
  1232. ASSERT_THROW(set.reserve(2u), test::throwing_allocator<entt::entity>::exception_type);
  1233. ASSERT_EQ(set.extent(), traits_type::page_size);
  1234. ASSERT_TRUE(set.contains(entt::entity{0}));
  1235. ASSERT_EQ(set.capacity(), 1u);
  1236. test::throwing_allocator<entt::entity>::trigger_on_allocate = true;
  1237. ASSERT_THROW(set.push(entt::entity{1}), test::throwing_allocator<entt::entity>::exception_type);
  1238. ASSERT_EQ(set.extent(), traits_type::page_size);
  1239. ASSERT_TRUE(set.contains(entt::entity{0}));
  1240. ASSERT_FALSE(set.contains(entt::entity{1}));
  1241. ASSERT_EQ(set.capacity(), 1u);
  1242. entt::entity entity[2u]{entt::entity{1}, entt::entity{traits_type::page_size}};
  1243. test::throwing_allocator<entt::entity>::trigger_after_allocate = true;
  1244. ASSERT_THROW(set.push(std::begin(entity), std::end(entity)), test::throwing_allocator<entt::entity>::exception_type);
  1245. ASSERT_EQ(set.extent(), 2 * traits_type::page_size);
  1246. ASSERT_TRUE(set.contains(entt::entity{0}));
  1247. ASSERT_TRUE(set.contains(entt::entity{1}));
  1248. ASSERT_FALSE(set.contains(entt::entity{traits_type::page_size}));
  1249. ASSERT_EQ(set.capacity(), 2u);
  1250. ASSERT_EQ(set.size(), 2u);
  1251. set.push(entity[1u]);
  1252. ASSERT_TRUE(set.contains(entt::entity{traits_type::page_size}));
  1253. }