storage_entity.cpp 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631
  1. #include <algorithm>
  2. #include <iterator>
  3. #include <tuple>
  4. #include <type_traits>
  5. #include <utility>
  6. #include <gtest/gtest.h>
  7. #include <entt/entity/storage.hpp>
  8. #include "../common/config.h"
  9. #include "../common/throwing_allocator.hpp"
  10. TEST(StorageEntity, TypeAndPolicy) {
  11. entt::storage<entt::entity> pool;
  12. ASSERT_EQ(pool.type(), entt::type_id<entt::entity>());
  13. ASSERT_EQ(pool.policy(), entt::deletion_policy::swap_only);
  14. }
  15. TEST(StorageEntity, Functionalities) {
  16. entt::entity entity[2u]{entt::entity{0}, entt::entity{1}};
  17. entt::storage<entt::entity> pool;
  18. ASSERT_TRUE(pool.empty());
  19. ASSERT_EQ(pool.size(), 0u);
  20. ASSERT_EQ(pool.in_use(), 0u);
  21. ASSERT_EQ(*pool.push(entt::null), entity[0u]);
  22. ASSERT_EQ(*pool.push(entt::tombstone), entity[1u]);
  23. ASSERT_FALSE(pool.empty());
  24. ASSERT_EQ(pool.size(), 2u);
  25. ASSERT_EQ(pool.in_use(), 2u);
  26. pool.in_use(1u);
  27. ASSERT_FALSE(pool.empty());
  28. ASSERT_EQ(pool.size(), 2u);
  29. ASSERT_EQ(pool.in_use(), 1u);
  30. ASSERT_NO_THROW(pool.get(entity[0u]));
  31. ASSERT_EQ(pool.get_as_tuple(entity[0u]), std::tuple<>{});
  32. pool.erase(entity[0u]);
  33. ASSERT_FALSE(pool.empty());
  34. ASSERT_EQ(pool.size(), 2u);
  35. ASSERT_EQ(pool.in_use(), 0u);
  36. }
  37. ENTT_DEBUG_TEST(StorageEntityDeathTest, Get) {
  38. entt::storage<entt::entity> pool;
  39. pool.emplace(entt::entity{99});
  40. ASSERT_DEATH(pool.get(entt::entity{3}), "");
  41. ASSERT_DEATH([[maybe_unused]] auto tup = pool.get_as_tuple(entt::entity{3}), "");
  42. ASSERT_NO_THROW(pool.get(entt::entity{99}));
  43. ASSERT_NO_THROW([[maybe_unused]] auto tup = pool.get_as_tuple(entt::entity{99}));
  44. pool.erase(entt::entity{99});
  45. ASSERT_DEATH(pool.get(entt::entity{99}), "");
  46. ASSERT_DEATH([[maybe_unused]] auto tup = pool.get_as_tuple(entt::entity{99}), "");
  47. }
  48. TEST(StorageEntity, Move) {
  49. entt::storage<entt::entity> pool;
  50. pool.push(entt::entity{1});
  51. ASSERT_EQ(pool.size(), 2u);
  52. ASSERT_EQ(pool.in_use(), 1u);
  53. ASSERT_TRUE(std::is_move_constructible_v<decltype(pool)>);
  54. ASSERT_TRUE(std::is_move_assignable_v<decltype(pool)>);
  55. entt::storage<entt::entity> other{std::move(pool)};
  56. ASSERT_EQ(pool.size(), 0u);
  57. ASSERT_EQ(other.size(), 2u);
  58. ASSERT_EQ(pool.in_use(), 0u);
  59. ASSERT_EQ(other.in_use(), 1u);
  60. ASSERT_EQ(pool.at(0u), static_cast<entt::entity>(entt::null));
  61. ASSERT_EQ(other.at(0u), entt::entity{1});
  62. pool = std::move(other);
  63. ASSERT_EQ(pool.size(), 2u);
  64. ASSERT_EQ(other.size(), 0u);
  65. ASSERT_EQ(pool.in_use(), 1u);
  66. ASSERT_EQ(other.in_use(), 0u);
  67. ASSERT_EQ(pool.at(0u), entt::entity{1});
  68. ASSERT_EQ(other.at(0u), static_cast<entt::entity>(entt::null));
  69. other = entt::storage<entt::entity>{};
  70. other.push(entt::entity{3});
  71. other = std::move(pool);
  72. ASSERT_EQ(pool.size(), 0u);
  73. ASSERT_EQ(other.size(), 2u);
  74. ASSERT_EQ(pool.in_use(), 0u);
  75. ASSERT_EQ(other.in_use(), 1u);
  76. ASSERT_EQ(pool.at(0u), static_cast<entt::entity>(entt::null));
  77. ASSERT_EQ(other.at(0u), entt::entity{1});
  78. other.clear();
  79. ASSERT_EQ(other.size(), 0u);
  80. ASSERT_EQ(other.in_use(), 0u);
  81. ASSERT_EQ(*other.push(entt::null), entt::entity{0});
  82. }
  83. TEST(StorageEntity, Swap) {
  84. entt::storage<entt::entity> pool;
  85. entt::storage<entt::entity> other;
  86. pool.push(entt::entity{1});
  87. other.push(entt::entity{2});
  88. other.push(entt::entity{0});
  89. other.erase(entt::entity{2});
  90. ASSERT_EQ(pool.size(), 2u);
  91. ASSERT_EQ(other.size(), 3u);
  92. ASSERT_EQ(pool.in_use(), 1u);
  93. ASSERT_EQ(other.in_use(), 1u);
  94. pool.swap(other);
  95. ASSERT_EQ(pool.size(), 3u);
  96. ASSERT_EQ(other.size(), 2u);
  97. ASSERT_EQ(pool.in_use(), 1u);
  98. ASSERT_EQ(other.in_use(), 1u);
  99. ASSERT_EQ(pool.at(0u), entt::entity{0});
  100. ASSERT_EQ(other.at(0u), entt::entity{1});
  101. pool.clear();
  102. other.clear();
  103. ASSERT_EQ(pool.size(), 0u);
  104. ASSERT_EQ(other.size(), 0u);
  105. ASSERT_EQ(pool.in_use(), 0u);
  106. ASSERT_EQ(other.in_use(), 0u);
  107. ASSERT_EQ(*other.push(entt::null), entt::entity{0});
  108. }
  109. TEST(StorageEntity, Push) {
  110. using traits_type = entt::entt_traits<entt::entity>;
  111. entt::storage<entt::entity> pool;
  112. ASSERT_EQ(*pool.push(entt::null), entt::entity{0});
  113. ASSERT_EQ(*pool.push(entt::tombstone), entt::entity{1});
  114. ASSERT_EQ(*pool.push(entt::entity{0}), entt::entity{2});
  115. ASSERT_EQ(*pool.push(traits_type::construct(1, 1)), entt::entity{3});
  116. ASSERT_EQ(*pool.push(traits_type::construct(5, 3)), traits_type::construct(5, 3));
  117. ASSERT_LT(pool.index(entt::entity{0}), pool.in_use());
  118. ASSERT_LT(pool.index(entt::entity{1}), pool.in_use());
  119. ASSERT_LT(pool.index(entt::entity{2}), pool.in_use());
  120. ASSERT_LT(pool.index(entt::entity{3}), pool.in_use());
  121. ASSERT_GE(pool.index(entt::entity{4}), pool.in_use());
  122. ASSERT_LT(pool.index(traits_type::construct(5, 3)), pool.in_use());
  123. ASSERT_EQ(*pool.push(traits_type::construct(4, 42)), traits_type::construct(4, 42));
  124. ASSERT_EQ(*pool.push(traits_type::construct(4, 43)), entt::entity{6});
  125. entt::entity entity[2u]{entt::entity{1}, traits_type::construct(5, 3)};
  126. pool.erase(entity, entity + 2u);
  127. pool.erase(entt::entity{2});
  128. ASSERT_EQ(pool.current(entity[0u]), 1);
  129. ASSERT_EQ(pool.current(entity[1u]), 4);
  130. ASSERT_EQ(pool.current(entt::entity{2}), 1);
  131. ASSERT_LT(pool.index(entt::entity{0}), pool.in_use());
  132. ASSERT_GE(pool.index(traits_type::construct(1, 1)), pool.in_use());
  133. ASSERT_GE(pool.index(traits_type::construct(2, 1)), pool.in_use());
  134. ASSERT_LT(pool.index(entt::entity{3}), pool.in_use());
  135. ASSERT_LT(pool.index(traits_type::construct(4, 42)), pool.in_use());
  136. ASSERT_GE(pool.index(traits_type::construct(5, 4)), pool.in_use());
  137. ASSERT_EQ(*pool.push(entt::null), traits_type::construct(2, 1));
  138. ASSERT_EQ(*pool.push(traits_type::construct(1, 3)), traits_type::construct(1, 3));
  139. ASSERT_EQ(*pool.push(entt::null), traits_type::construct(5, 4));
  140. ASSERT_EQ(*pool.push(entt::null), entt::entity{7});
  141. }
  142. TEST(StorageEntity, Emplace) {
  143. using traits_type = entt::entt_traits<entt::entity>;
  144. entt::storage<entt::entity> pool;
  145. entt::entity entity[2u]{};
  146. ASSERT_EQ(pool.emplace(), entt::entity{0});
  147. ASSERT_EQ(pool.emplace(entt::null), entt::entity{1});
  148. ASSERT_EQ(pool.emplace(entt::tombstone), entt::entity{2});
  149. ASSERT_EQ(pool.emplace(entt::entity{0}), entt::entity{3});
  150. ASSERT_EQ(pool.emplace(traits_type::construct(1, 1)), entt::entity{4});
  151. ASSERT_EQ(pool.emplace(traits_type::construct(6, 3)), traits_type::construct(6, 3));
  152. ASSERT_LT(pool.index(entt::entity{0}), pool.in_use());
  153. ASSERT_LT(pool.index(entt::entity{1}), pool.in_use());
  154. ASSERT_LT(pool.index(entt::entity{2}), pool.in_use());
  155. ASSERT_LT(pool.index(entt::entity{3}), pool.in_use());
  156. ASSERT_LT(pool.index(entt::entity{4}), pool.in_use());
  157. ASSERT_GE(pool.index(entt::entity{5}), pool.in_use());
  158. ASSERT_LT(pool.index(traits_type::construct(6, 3)), pool.in_use());
  159. ASSERT_EQ(pool.emplace(traits_type::construct(5, 42)), traits_type::construct(5, 42));
  160. ASSERT_EQ(pool.emplace(traits_type::construct(5, 43)), entt::entity{7});
  161. pool.erase(entt::entity{2});
  162. ASSERT_EQ(pool.emplace(), traits_type::construct(2, 1));
  163. pool.erase(traits_type::construct(2, 1));
  164. pool.insert(entity, entity + 2u);
  165. ASSERT_EQ(entity[0u], traits_type::construct(2, 2));
  166. ASSERT_EQ(entity[1u], entt::entity{8});
  167. }
  168. TEST(StorageEntity, Patch) {
  169. entt::storage<entt::entity> pool;
  170. const auto entity = pool.emplace();
  171. int counter = 0;
  172. auto callback = [&counter]() { ++counter; };
  173. ASSERT_EQ(counter, 0);
  174. pool.patch(entity);
  175. pool.patch(entity, callback);
  176. pool.patch(entity, callback, callback);
  177. ASSERT_EQ(counter, 3);
  178. }
  179. ENTT_DEBUG_TEST(StorageEntityDeathTest, Patch) {
  180. entt::storage<entt::entity> pool;
  181. ASSERT_DEATH(pool.patch(entt::null), "");
  182. }
  183. TEST(StorageEntity, Insert) {
  184. entt::storage<entt::entity> pool;
  185. entt::entity entity[2u]{};
  186. pool.insert(std::begin(entity), std::end(entity));
  187. ASSERT_TRUE(pool.contains(entity[0u]));
  188. ASSERT_TRUE(pool.contains(entity[1u]));
  189. ASSERT_FALSE(pool.empty());
  190. ASSERT_EQ(pool.size(), 2u);
  191. ASSERT_EQ(pool.in_use(), 2u);
  192. pool.erase(std::begin(entity), std::end(entity));
  193. ASSERT_FALSE(pool.empty());
  194. ASSERT_EQ(pool.size(), 2u);
  195. ASSERT_EQ(pool.in_use(), 0u);
  196. pool.insert(entity, entity + 1u);
  197. ASSERT_TRUE(pool.contains(entity[0u]));
  198. ASSERT_FALSE(pool.contains(entity[1u]));
  199. ASSERT_FALSE(pool.empty());
  200. ASSERT_EQ(pool.size(), 2u);
  201. ASSERT_EQ(pool.in_use(), 1u);
  202. }
  203. TEST(StorageEntity, Pack) {
  204. entt::storage<entt::entity> pool;
  205. entt::entity entity[3u]{entt::entity{1}, entt::entity{3}, entt::entity{42}};
  206. pool.push(entity, entity + 3u);
  207. std::swap(entity[0u], entity[1u]);
  208. const auto len = pool.pack(entity + 1u, entity + 3u);
  209. auto it = pool.each().cbegin().base();
  210. ASSERT_NE(it, pool.cbegin());
  211. ASSERT_NE(it, pool.cend());
  212. ASSERT_EQ(len, 2u);
  213. ASSERT_NE(it + len, pool.cend());
  214. ASSERT_EQ(it + len + 1u, pool.cend());
  215. ASSERT_EQ(*it++, entity[1u]);
  216. ASSERT_EQ(*it++, entity[2u]);
  217. ASSERT_NE(it, pool.cend());
  218. ASSERT_EQ(*it++, entity[0u]);
  219. ASSERT_EQ(it, pool.cend());
  220. }
  221. TEST(StorageEntity, Iterable) {
  222. using iterator = typename entt::storage<entt::entity>::iterable::iterator;
  223. testing::StaticAssertTypeEq<iterator::value_type, std::tuple<entt::entity>>();
  224. testing::StaticAssertTypeEq<typename iterator::pointer, entt::input_iterator_pointer<std::tuple<entt::entity>>>();
  225. testing::StaticAssertTypeEq<typename iterator::reference, typename iterator::value_type>();
  226. entt::storage<entt::entity> pool;
  227. pool.emplace(entt::entity{1});
  228. pool.emplace(entt::entity{3});
  229. pool.emplace(entt::entity{42});
  230. pool.erase(entt::entity{3});
  231. auto iterable = pool.each();
  232. iterator end{iterable.begin()};
  233. iterator begin{};
  234. begin = iterable.end();
  235. std::swap(begin, end);
  236. ASSERT_EQ(begin, iterable.begin());
  237. ASSERT_EQ(end, iterable.end());
  238. ASSERT_NE(begin, end);
  239. ASSERT_NE(begin.base(), pool.begin());
  240. ASSERT_EQ(begin.base(), pool.end() - pool.in_use());
  241. ASSERT_EQ(end.base(), pool.end());
  242. ASSERT_EQ(std::get<0>(*begin.operator->().operator->()), entt::entity{42});
  243. ASSERT_EQ(std::get<0>(*begin), entt::entity{42});
  244. ASSERT_EQ(begin++, iterable.begin());
  245. ASSERT_EQ(begin.base(), pool.end() - 1);
  246. ASSERT_EQ(++begin, iterable.end());
  247. ASSERT_EQ(begin.base(), pool.end());
  248. for(auto [entity]: iterable) {
  249. testing::StaticAssertTypeEq<decltype(entity), entt::entity>();
  250. ASSERT_TRUE(entity != entt::entity{3});
  251. }
  252. }
  253. TEST(StorageEntity, ConstIterable) {
  254. using iterator = typename entt::storage<entt::entity>::const_iterable::iterator;
  255. testing::StaticAssertTypeEq<iterator::value_type, std::tuple<entt::entity>>();
  256. testing::StaticAssertTypeEq<typename iterator::pointer, entt::input_iterator_pointer<std::tuple<entt::entity>>>();
  257. testing::StaticAssertTypeEq<typename iterator::reference, typename iterator::value_type>();
  258. entt::storage<entt::entity> pool;
  259. pool.emplace(entt::entity{1});
  260. pool.emplace(entt::entity{3});
  261. pool.emplace(entt::entity{42});
  262. pool.erase(entt::entity{3});
  263. auto iterable = std::as_const(pool).each();
  264. iterator end{iterable.cbegin()};
  265. iterator begin{};
  266. begin = iterable.cend();
  267. std::swap(begin, end);
  268. ASSERT_EQ(begin, iterable.cbegin());
  269. ASSERT_EQ(end, iterable.cend());
  270. ASSERT_NE(begin, end);
  271. ASSERT_NE(begin.base(), pool.begin());
  272. ASSERT_EQ(begin.base(), pool.end() - pool.in_use());
  273. ASSERT_EQ(end.base(), pool.end());
  274. ASSERT_EQ(std::get<0>(*begin.operator->().operator->()), entt::entity{42});
  275. ASSERT_EQ(std::get<0>(*begin), entt::entity{42});
  276. ASSERT_EQ(begin++, iterable.begin());
  277. ASSERT_EQ(begin.base(), pool.end() - 1);
  278. ASSERT_EQ(++begin, iterable.end());
  279. ASSERT_EQ(begin.base(), pool.end());
  280. for(auto [entity]: iterable) {
  281. testing::StaticAssertTypeEq<decltype(entity), entt::entity>();
  282. ASSERT_TRUE(entity != entt::entity{3});
  283. }
  284. }
  285. TEST(StorageEntity, IterableIteratorConversion) {
  286. entt::storage<entt::entity> pool;
  287. pool.emplace(entt::entity{3});
  288. typename entt::storage<entt::entity>::iterable::iterator it = pool.each().begin();
  289. typename entt::storage<entt::entity>::const_iterable::iterator cit = it;
  290. testing::StaticAssertTypeEq<decltype(*it), std::tuple<entt::entity>>();
  291. testing::StaticAssertTypeEq<decltype(*cit), std::tuple<entt::entity>>();
  292. ASSERT_EQ(it, cit);
  293. ASSERT_NE(++cit, it);
  294. }
  295. TEST(StorageEntity, IterableAlgorithmCompatibility) {
  296. entt::storage<entt::entity> pool;
  297. pool.emplace(entt::entity{3});
  298. const auto iterable = pool.each();
  299. const auto it = std::find_if(iterable.begin(), iterable.end(), [](auto args) { return std::get<0>(args) == entt::entity{3}; });
  300. ASSERT_EQ(std::get<0>(*it), entt::entity{3});
  301. }
  302. TEST(StorageEntity, ReverseIterable) {
  303. using iterator = typename entt::storage<entt::entity>::reverse_iterable::iterator;
  304. testing::StaticAssertTypeEq<iterator::value_type, std::tuple<entt::entity>>();
  305. testing::StaticAssertTypeEq<typename iterator::pointer, entt::input_iterator_pointer<std::tuple<entt::entity>>>();
  306. testing::StaticAssertTypeEq<typename iterator::reference, typename iterator::value_type>();
  307. entt::storage<entt::entity> pool;
  308. pool.emplace(entt::entity{1});
  309. pool.emplace(entt::entity{3});
  310. pool.emplace(entt::entity{42});
  311. pool.erase(entt::entity{3});
  312. auto iterable = pool.reach();
  313. iterator end{iterable.begin()};
  314. iterator begin{};
  315. begin = iterable.end();
  316. std::swap(begin, end);
  317. ASSERT_EQ(begin, iterable.begin());
  318. ASSERT_EQ(end, iterable.end());
  319. ASSERT_NE(begin, end);
  320. ASSERT_EQ(begin.base(), pool.rbegin());
  321. ASSERT_EQ(end.base(), pool.rbegin() + pool.in_use());
  322. ASSERT_NE(end.base(), pool.rend());
  323. ASSERT_EQ(std::get<0>(*begin.operator->().operator->()), entt::entity{1});
  324. ASSERT_EQ(std::get<0>(*begin), entt::entity{1});
  325. ASSERT_EQ(begin++, iterable.begin());
  326. ASSERT_EQ(begin.base(), pool.rbegin() + 1);
  327. ASSERT_EQ(++begin, iterable.end());
  328. ASSERT_EQ(begin.base(), pool.rbegin() + 2);
  329. for(auto [entity]: iterable) {
  330. testing::StaticAssertTypeEq<decltype(entity), entt::entity>();
  331. ASSERT_TRUE(entity != entt::entity{3});
  332. }
  333. }
  334. TEST(StorageEntity, ReverseConstIterable) {
  335. using iterator = typename entt::storage<entt::entity>::const_reverse_iterable::iterator;
  336. testing::StaticAssertTypeEq<iterator::value_type, std::tuple<entt::entity>>();
  337. testing::StaticAssertTypeEq<typename iterator::pointer, entt::input_iterator_pointer<std::tuple<entt::entity>>>();
  338. testing::StaticAssertTypeEq<typename iterator::reference, typename iterator::value_type>();
  339. entt::storage<entt::entity> pool;
  340. pool.emplace(entt::entity{1});
  341. pool.emplace(entt::entity{3});
  342. pool.emplace(entt::entity{42});
  343. pool.erase(entt::entity{3});
  344. auto iterable = std::as_const(pool).reach();
  345. iterator end{iterable.cbegin()};
  346. iterator begin{};
  347. begin = iterable.cend();
  348. std::swap(begin, end);
  349. ASSERT_EQ(begin, iterable.cbegin());
  350. ASSERT_EQ(end, iterable.cend());
  351. ASSERT_NE(begin, end);
  352. ASSERT_EQ(begin.base(), pool.rbegin());
  353. ASSERT_EQ(end.base(), pool.rbegin() + pool.in_use());
  354. ASSERT_NE(end.base(), pool.rend());
  355. ASSERT_EQ(std::get<0>(*begin.operator->().operator->()), entt::entity{1});
  356. ASSERT_EQ(std::get<0>(*begin), entt::entity{1});
  357. ASSERT_EQ(begin++, iterable.begin());
  358. ASSERT_EQ(begin.base(), pool.rbegin() + 1);
  359. ASSERT_EQ(++begin, iterable.end());
  360. ASSERT_EQ(begin.base(), pool.rbegin() + 2);
  361. for(auto [entity]: iterable) {
  362. testing::StaticAssertTypeEq<decltype(entity), entt::entity>();
  363. ASSERT_TRUE(entity != entt::entity{3});
  364. }
  365. }
  366. TEST(StorageEntity, ReverseIterableIteratorConversion) {
  367. entt::storage<entt::entity> pool;
  368. pool.emplace(entt::entity{3});
  369. typename entt::storage<entt::entity>::reverse_iterable::iterator it = pool.reach().begin();
  370. typename entt::storage<entt::entity>::const_reverse_iterable::iterator cit = it;
  371. testing::StaticAssertTypeEq<decltype(*it), std::tuple<entt::entity>>();
  372. testing::StaticAssertTypeEq<decltype(*cit), std::tuple<entt::entity>>();
  373. ASSERT_EQ(it, cit);
  374. ASSERT_NE(++cit, it);
  375. }
  376. TEST(StorageEntity, ReverseIterableAlgorithmCompatibility) {
  377. entt::storage<entt::entity> pool;
  378. pool.emplace(entt::entity{3});
  379. const auto iterable = pool.reach();
  380. const auto it = std::find_if(iterable.begin(), iterable.end(), [](auto args) { return std::get<0>(args) == entt::entity{3}; });
  381. ASSERT_EQ(std::get<0>(*it), entt::entity{3});
  382. }
  383. TEST(StorageEntity, SwapElements) {
  384. entt::storage<entt::entity> pool;
  385. pool.push(entt::entity{0});
  386. pool.push(entt::entity{1});
  387. ASSERT_EQ(pool.size(), 2u);
  388. ASSERT_EQ(pool.in_use(), 2u);
  389. ASSERT_TRUE(pool.contains(entt::entity{0}));
  390. ASSERT_TRUE(pool.contains(entt::entity{1}));
  391. ASSERT_EQ(*pool.begin(), entt::entity{1});
  392. ASSERT_EQ(*++pool.begin(), entt::entity{0});
  393. pool.swap_elements(entt::entity{0}, entt::entity{1});
  394. ASSERT_EQ(*pool.begin(), entt::entity{0});
  395. ASSERT_EQ(*++pool.begin(), entt::entity{1});
  396. }
  397. ENTT_DEBUG_TEST(StorageEntityDeathTest, SwapElements) {
  398. entt::storage<entt::entity> pool;
  399. pool.push(entt::entity{1});
  400. ASSERT_EQ(pool.size(), 2u);
  401. ASSERT_EQ(pool.in_use(), 1u);
  402. ASSERT_TRUE(pool.contains(entt::entity{0}));
  403. ASSERT_TRUE(pool.contains(entt::entity{1}));
  404. ASSERT_DEATH(pool.swap_elements(entt::entity{0}, entt::entity{1}), "");
  405. }
  406. ENTT_DEBUG_TEST(StorageEntityDeathTest, InUse) {
  407. entt::storage<entt::entity> pool;
  408. pool.push(entt::entity{0});
  409. pool.push(entt::entity{1});
  410. ASSERT_DEATH(pool.in_use(3u), "");
  411. }
  412. ENTT_DEBUG_TEST(StorageEntityDeathTest, SortAndRespect) {
  413. entt::storage<entt::entity> pool;
  414. entt::storage<entt::entity> other;
  415. pool.push(entt::entity{1});
  416. pool.push(entt::entity{2});
  417. pool.erase(entt::entity{2});
  418. other.push(entt::entity{2});
  419. ASSERT_DEATH(pool.sort([](auto...) { return true; }), "");
  420. ASSERT_DEATH(pool.sort_as(other), "");
  421. }
  422. TEST(StorageEntity, CustomAllocator) {
  423. test::throwing_allocator<entt::entity> allocator{};
  424. entt::basic_storage<entt::entity, entt::entity, test::throwing_allocator<entt::entity>> pool{allocator};
  425. pool.reserve(1u);
  426. ASSERT_EQ(pool.size(), 0u);
  427. ASSERT_EQ(pool.in_use(), 0u);
  428. pool.push(entt::entity{0});
  429. pool.push(entt::entity{1});
  430. ASSERT_EQ(pool.size(), 2u);
  431. ASSERT_EQ(pool.in_use(), 2u);
  432. decltype(pool) other{std::move(pool), allocator};
  433. ASSERT_TRUE(pool.empty());
  434. ASSERT_FALSE(other.empty());
  435. ASSERT_EQ(pool.size(), 0u);
  436. ASSERT_EQ(other.size(), 2u);
  437. ASSERT_EQ(pool.in_use(), 0u);
  438. ASSERT_EQ(other.in_use(), 2u);
  439. pool = std::move(other);
  440. ASSERT_FALSE(pool.empty());
  441. ASSERT_TRUE(other.empty());
  442. ASSERT_EQ(pool.size(), 2u);
  443. ASSERT_EQ(other.size(), 0u);
  444. ASSERT_EQ(pool.in_use(), 2u);
  445. ASSERT_EQ(other.in_use(), 0u);
  446. pool.swap(other);
  447. pool = std::move(other);
  448. ASSERT_FALSE(pool.empty());
  449. ASSERT_TRUE(other.empty());
  450. ASSERT_EQ(pool.size(), 2u);
  451. ASSERT_EQ(other.size(), 0u);
  452. ASSERT_EQ(pool.in_use(), 2u);
  453. ASSERT_EQ(other.in_use(), 0u);
  454. pool.clear();
  455. ASSERT_EQ(pool.size(), 0u);
  456. ASSERT_EQ(pool.in_use(), 0u);
  457. }