storage_no_instance.cpp 25 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719
  1. #include <algorithm>
  2. #include <functional>
  3. #include <iterator>
  4. #include <memory>
  5. #include <tuple>
  6. #include <type_traits>
  7. #include <utility>
  8. #include <gtest/gtest.h>
  9. #include <entt/core/iterator.hpp>
  10. #include <entt/core/type_info.hpp>
  11. #include <entt/entity/entity.hpp>
  12. #include <entt/entity/storage.hpp>
  13. #include "../common/config.h"
  14. #include "../common/empty.h"
  15. template<typename Type>
  16. struct StorageNoInstance: testing::Test {
  17. using type = Type;
  18. static auto emplace_instance(entt::storage<type> &pool, const entt::entity entt) {
  19. if constexpr(std::is_void_v<type>) {
  20. return pool.emplace(entt);
  21. } else {
  22. return pool.emplace(entt, type{});
  23. }
  24. }
  25. template<typename It>
  26. static auto insert_instance(entt::storage<type> &pool, const It from, const It to) {
  27. if constexpr(std::is_void_v<type>) {
  28. return pool.insert(from, to);
  29. } else {
  30. const type values[2u]{};
  31. return pool.insert(from, to, std::begin(values));
  32. }
  33. }
  34. static auto push_instance(entt::storage<type> &pool, const entt::entity entt) {
  35. if constexpr(std::is_void_v<type>) {
  36. return pool.push(entt, nullptr);
  37. } else {
  38. type instance{};
  39. return pool.push(entt, &instance);
  40. }
  41. }
  42. };
  43. template<typename Type>
  44. using StorageNoInstanceDeathTest = StorageNoInstance<Type>;
  45. using StorageNoInstanceTypes = ::testing::Types<test::empty, void>;
  46. TYPED_TEST_SUITE(StorageNoInstance, StorageNoInstanceTypes, );
  47. TYPED_TEST_SUITE(StorageNoInstanceDeathTest, StorageNoInstanceTypes, );
  48. TYPED_TEST(StorageNoInstance, Constructors) {
  49. using value_type = typename TestFixture::type;
  50. entt::storage<value_type> pool;
  51. ASSERT_EQ(pool.policy(), entt::deletion_policy::swap_and_pop);
  52. ASSERT_NO_FATAL_FAILURE([[maybe_unused]] auto alloc = pool.get_allocator());
  53. ASSERT_EQ(pool.type(), entt::type_id<value_type>());
  54. pool = entt::storage<value_type>{std::allocator<value_type>{}};
  55. ASSERT_EQ(pool.policy(), entt::deletion_policy::swap_and_pop);
  56. ASSERT_NO_FATAL_FAILURE([[maybe_unused]] auto alloc = pool.get_allocator());
  57. ASSERT_EQ(pool.type(), entt::type_id<value_type>());
  58. }
  59. TYPED_TEST(StorageNoInstance, Move) {
  60. using value_type = typename TestFixture::type;
  61. entt::storage<value_type> pool;
  62. pool.emplace(entt::entity{3});
  63. static_assert(std::is_move_constructible_v<decltype(pool)>, "Move constructible type required");
  64. static_assert(std::is_move_assignable_v<decltype(pool)>, "Move assignable type required");
  65. entt::storage<value_type> other{std::move(pool)};
  66. ASSERT_TRUE(pool.empty()); // NOLINT
  67. ASSERT_FALSE(other.empty());
  68. ASSERT_EQ(pool.type(), entt::type_id<value_type>()); // NOLINT
  69. ASSERT_EQ(other.type(), entt::type_id<value_type>());
  70. ASSERT_EQ(pool.at(0u), static_cast<entt::entity>(entt::null)); // NOLINT
  71. ASSERT_EQ(other.at(0u), entt::entity{3}); // NOLINT
  72. entt::storage<value_type> extended{std::move(other), std::allocator<value_type>{}};
  73. ASSERT_TRUE(other.empty()); // NOLINT
  74. ASSERT_FALSE(extended.empty());
  75. ASSERT_EQ(other.type(), entt::type_id<value_type>()); // NOLINT
  76. ASSERT_EQ(extended.type(), entt::type_id<value_type>());
  77. ASSERT_EQ(other.at(0u), static_cast<entt::entity>(entt::null)); // NOLINT
  78. ASSERT_EQ(extended.at(0u), entt::entity{3}); // NOLINT
  79. pool = std::move(extended);
  80. ASSERT_FALSE(pool.empty());
  81. ASSERT_TRUE(other.empty()); // NOLINT
  82. ASSERT_TRUE(extended.empty()); // NOLINT
  83. ASSERT_EQ(pool.type(), entt::type_id<value_type>());
  84. ASSERT_EQ(other.type(), entt::type_id<value_type>()); // NOLINT
  85. ASSERT_EQ(extended.type(), entt::type_id<value_type>()); // NOLINT
  86. ASSERT_EQ(pool.at(0u), entt::entity{3}); // NOLINT
  87. ASSERT_EQ(other.at(0u), static_cast<entt::entity>(entt::null)); // NOLINT
  88. ASSERT_EQ(extended.at(0u), static_cast<entt::entity>(entt::null)); // NOLINT
  89. other = entt::storage<value_type>{};
  90. other.emplace(entt::entity{42}, 42);
  91. other = std::move(pool);
  92. ASSERT_TRUE(pool.empty()); // NOLINT
  93. ASSERT_FALSE(other.empty());
  94. ASSERT_EQ(pool.type(), entt::type_id<value_type>()); // NOLINT
  95. ASSERT_EQ(other.type(), entt::type_id<value_type>());
  96. ASSERT_EQ(pool.at(0u), static_cast<entt::entity>(entt::null)); // NOLINT
  97. ASSERT_EQ(other.at(0u), entt::entity{3}); // NOLINT
  98. }
  99. TYPED_TEST(StorageNoInstance, Swap) {
  100. using value_type = typename TestFixture::type;
  101. entt::storage<value_type> pool;
  102. entt::storage<value_type> other;
  103. ASSERT_EQ(pool.type(), entt::type_id<value_type>());
  104. ASSERT_EQ(other.type(), entt::type_id<value_type>());
  105. pool.emplace(entt::entity{42});
  106. other.emplace(entt::entity{9});
  107. other.emplace(entt::entity{3});
  108. other.erase(entt::entity{9});
  109. ASSERT_EQ(pool.size(), 1u);
  110. ASSERT_EQ(other.size(), 1u);
  111. pool.swap(other);
  112. ASSERT_EQ(pool.type(), entt::type_id<value_type>());
  113. ASSERT_EQ(other.type(), entt::type_id<value_type>());
  114. ASSERT_EQ(pool.size(), 1u);
  115. ASSERT_EQ(other.size(), 1u);
  116. ASSERT_EQ(pool.index(entt::entity{3}), 0u);
  117. ASSERT_EQ(other.index(entt::entity{42}), 0u);
  118. }
  119. TYPED_TEST(StorageNoInstance, Getters) {
  120. using value_type = typename TestFixture::type;
  121. entt::storage<value_type> pool;
  122. pool.emplace(entt::entity{41}, 3);
  123. testing::StaticAssertTypeEq<decltype(pool.get({})), void>();
  124. testing::StaticAssertTypeEq<decltype(std::as_const(pool).get({})), void>();
  125. testing::StaticAssertTypeEq<decltype(pool.get_as_tuple({})), std::tuple<>>();
  126. testing::StaticAssertTypeEq<decltype(std::as_const(pool).get_as_tuple({})), std::tuple<>>();
  127. ASSERT_NO_FATAL_FAILURE(pool.get(entt::entity{41}));
  128. ASSERT_NO_FATAL_FAILURE(std::as_const(pool).get(entt::entity{41}));
  129. ASSERT_EQ(pool.get_as_tuple(entt::entity{41}), std::make_tuple());
  130. ASSERT_EQ(std::as_const(pool).get_as_tuple(entt::entity{41}), std::make_tuple());
  131. }
  132. ENTT_DEBUG_TYPED_TEST(StorageNoInstanceDeathTest, Getters) {
  133. using value_type = typename TestFixture::type;
  134. entt::storage<value_type> pool;
  135. ASSERT_DEATH(pool.get(entt::entity{41}), "");
  136. ASSERT_DEATH(std::as_const(pool).get(entt::entity{41}), "");
  137. ASSERT_DEATH([[maybe_unused]] const auto value = pool.get_as_tuple(entt::entity{41}), "");
  138. ASSERT_DEATH([[maybe_unused]] const auto value = std::as_const(pool).get_as_tuple(entt::entity{41}), "");
  139. }
  140. TYPED_TEST(StorageNoInstance, Value) {
  141. using value_type = typename TestFixture::type;
  142. entt::storage<value_type> pool;
  143. pool.emplace(entt::entity{42});
  144. ASSERT_EQ(pool.value(entt::entity{42}), nullptr);
  145. }
  146. ENTT_DEBUG_TYPED_TEST(StorageNoInstanceDeathTest, Value) {
  147. using value_type = typename TestFixture::type;
  148. entt::storage<value_type> pool;
  149. ASSERT_DEATH([[maybe_unused]] const void *value = pool.value(entt::entity{42}), "");
  150. }
  151. TYPED_TEST(StorageNoInstance, Emplace) {
  152. using value_type = typename TestFixture::type;
  153. entt::storage<value_type> pool;
  154. const entt::entity entity[2u]{entt::entity{3}, entt::entity{42}};
  155. testing::StaticAssertTypeEq<decltype(pool.emplace({})), void>();
  156. ASSERT_NO_FATAL_FAILURE(pool.emplace(entity[0u]));
  157. ASSERT_NO_FATAL_FAILURE(this->emplace_instance(pool, entity[1u]));
  158. }
  159. ENTT_DEBUG_TYPED_TEST(StorageNoInstanceDeathTest, Emplace) {
  160. using value_type = typename TestFixture::type;
  161. entt::storage<value_type> pool;
  162. const entt::entity entity{42};
  163. testing::StaticAssertTypeEq<decltype(pool.emplace({})), void>();
  164. pool.emplace(entity);
  165. ASSERT_DEATH(pool.emplace(entity), "");
  166. ASSERT_DEATH(this->emplace_instance(pool, entity), "");
  167. }
  168. TYPED_TEST(StorageNoInstance, TryEmplace) {
  169. using value_type = typename TestFixture::type;
  170. entt::storage<value_type> pool;
  171. entt::sparse_set &base = pool;
  172. const entt::entity entity[2u]{entt::entity{3}, entt::entity{42}};
  173. ASSERT_NE(this->push_instance(pool, entity[0u]), base.end());
  174. ASSERT_EQ(pool.size(), 1u);
  175. ASSERT_EQ(base.index(entity[0u]), 0u);
  176. base.erase(entity[0u]);
  177. ASSERT_NE(base.push(std::begin(entity), std::end(entity)), base.end());
  178. ASSERT_EQ(pool.size(), 2u);
  179. ASSERT_EQ(base.index(entity[0u]), 0u);
  180. ASSERT_EQ(base.index(entity[1u]), 1u);
  181. base.erase(std::begin(entity), std::end(entity));
  182. ASSERT_NE(base.push(std::rbegin(entity), std::rend(entity)), base.end());
  183. ASSERT_EQ(pool.size(), 2u);
  184. ASSERT_EQ(base.index(entity[0u]), 1u);
  185. ASSERT_EQ(base.index(entity[1u]), 0u);
  186. }
  187. TYPED_TEST(StorageNoInstance, Patch) {
  188. using value_type = typename TestFixture::type;
  189. entt::storage<value_type> pool;
  190. const entt::entity entity{42};
  191. int counter = 0;
  192. auto callback = [&counter]() { ++counter; };
  193. pool.emplace(entity);
  194. ASSERT_EQ(counter, 0);
  195. pool.patch(entity);
  196. pool.patch(entity, callback);
  197. pool.patch(entity, callback, callback);
  198. ASSERT_EQ(counter, 3);
  199. }
  200. ENTT_DEBUG_TYPED_TEST(StorageNoInstanceDeathTest, Patch) {
  201. using value_type = typename TestFixture::type;
  202. entt::storage<value_type> pool;
  203. ASSERT_DEATH(pool.patch(entt::null), "");
  204. }
  205. TYPED_TEST(StorageNoInstance, Insert) {
  206. using value_type = typename TestFixture::type;
  207. entt::storage<value_type> pool;
  208. const entt::entity entity[2u]{entt::entity{3}, entt::entity{42}};
  209. pool.insert(std::begin(entity), std::end(entity));
  210. ASSERT_EQ(pool.size(), 2u);
  211. ASSERT_EQ(pool.index(entity[0u]), 0u);
  212. ASSERT_EQ(pool.index(entity[1u]), 1u);
  213. pool.erase(std::begin(entity), std::end(entity));
  214. this->insert_instance(pool, std::rbegin(entity), std::rend(entity));
  215. ASSERT_EQ(pool.size(), 2u);
  216. ASSERT_EQ(pool.index(entity[0u]), 1u);
  217. ASSERT_EQ(pool.index(entity[1u]), 0u);
  218. }
  219. ENTT_DEBUG_TYPED_TEST(StorageNoInstanceDeathTest, Insert) {
  220. using value_type = typename TestFixture::type;
  221. entt::storage<value_type> pool;
  222. const entt::entity entity[2u]{entt::entity{3}, entt::entity{42}};
  223. pool.insert(std::begin(entity), std::end(entity));
  224. ASSERT_DEATH(pool.insert(std::begin(entity), std::end(entity)), "");
  225. ASSERT_DEATH(this->insert_instance(pool, std::begin(entity), std::end(entity)), "");
  226. }
  227. TYPED_TEST(StorageNoInstance, Iterable) {
  228. using value_type = typename TestFixture::type;
  229. using iterator = typename entt::storage<value_type>::iterable::iterator;
  230. testing::StaticAssertTypeEq<typename iterator::value_type, std::tuple<entt::entity>>();
  231. testing::StaticAssertTypeEq<typename iterator::value_type, std::tuple<entt::entity>>();
  232. testing::StaticAssertTypeEq<typename iterator::pointer, entt::input_iterator_pointer<std::tuple<entt::entity>>>();
  233. testing::StaticAssertTypeEq<typename iterator::reference, typename iterator::value_type>();
  234. entt::storage<value_type> pool;
  235. const entt::sparse_set &base = pool;
  236. pool.emplace(entt::entity{1});
  237. pool.emplace(entt::entity{3});
  238. auto iterable = pool.each();
  239. iterator end{iterable.begin()};
  240. iterator begin{};
  241. begin = iterable.end();
  242. std::swap(begin, end);
  243. ASSERT_EQ(begin, iterable.begin());
  244. ASSERT_EQ(end, iterable.end());
  245. ASSERT_NE(begin, end);
  246. ASSERT_EQ(begin.base(), base.begin());
  247. ASSERT_EQ(end.base(), base.end());
  248. ASSERT_EQ(std::get<0>(*begin.operator->().operator->()), entt::entity{3});
  249. ASSERT_EQ(std::get<0>(*begin), entt::entity{3});
  250. ASSERT_EQ(begin++, iterable.begin());
  251. ASSERT_EQ(begin.base(), ++base.begin());
  252. ASSERT_EQ(++begin, iterable.end());
  253. ASSERT_EQ(begin.base(), base.end());
  254. for(auto [entity]: iterable) {
  255. testing::StaticAssertTypeEq<decltype(entity), entt::entity>();
  256. ASSERT_TRUE(entity == entt::entity{1} || entity == entt::entity{3});
  257. }
  258. }
  259. TYPED_TEST(StorageNoInstance, ConstIterable) {
  260. using value_type = typename TestFixture::type;
  261. using iterator = typename entt::storage<value_type>::const_iterable::iterator;
  262. testing::StaticAssertTypeEq<typename iterator::value_type, std::tuple<entt::entity>>();
  263. testing::StaticAssertTypeEq<typename iterator::value_type, std::tuple<entt::entity>>();
  264. testing::StaticAssertTypeEq<typename iterator::pointer, entt::input_iterator_pointer<std::tuple<entt::entity>>>();
  265. testing::StaticAssertTypeEq<typename iterator::reference, typename iterator::value_type>();
  266. entt::storage<value_type> pool;
  267. const entt::sparse_set &base = pool;
  268. pool.emplace(entt::entity{1});
  269. pool.emplace(entt::entity{3});
  270. auto iterable = std::as_const(pool).each();
  271. iterator end{iterable.begin()};
  272. iterator begin{};
  273. begin = iterable.end();
  274. std::swap(begin, end);
  275. ASSERT_EQ(begin, iterable.begin());
  276. ASSERT_EQ(end, iterable.end());
  277. ASSERT_NE(begin, end);
  278. ASSERT_EQ(begin.base(), base.begin());
  279. ASSERT_EQ(end.base(), base.end());
  280. ASSERT_EQ(std::get<0>(*begin.operator->().operator->()), entt::entity{3});
  281. ASSERT_EQ(std::get<0>(*begin), entt::entity{3});
  282. ASSERT_EQ(begin++, iterable.begin());
  283. ASSERT_EQ(begin.base(), ++base.begin());
  284. ASSERT_EQ(++begin, iterable.end());
  285. ASSERT_EQ(begin.base(), base.end());
  286. for(auto [entity]: iterable) {
  287. testing::StaticAssertTypeEq<decltype(entity), entt::entity>();
  288. ASSERT_TRUE(entity == entt::entity{1} || entity == entt::entity{3});
  289. }
  290. }
  291. TYPED_TEST(StorageNoInstance, IterableIteratorConversion) {
  292. using value_type = typename TestFixture::type;
  293. entt::storage<value_type> pool;
  294. pool.emplace(entt::entity{3});
  295. const typename entt::storage<value_type>::iterable::iterator it = pool.each().begin();
  296. typename entt::storage<value_type>::const_iterable::iterator cit = it;
  297. testing::StaticAssertTypeEq<decltype(*it), std::tuple<entt::entity>>();
  298. testing::StaticAssertTypeEq<decltype(*cit), std::tuple<entt::entity>>();
  299. ASSERT_EQ(it, cit);
  300. ASSERT_NE(++cit, it);
  301. }
  302. TYPED_TEST(StorageNoInstance, IterableAlgorithmCompatibility) {
  303. using value_type = typename TestFixture::type;
  304. entt::storage<value_type> pool;
  305. pool.emplace(entt::entity{3});
  306. const auto iterable = pool.each();
  307. const auto it = std::find_if(iterable.begin(), iterable.end(), [](auto args) { return std::get<0>(args) == entt::entity{3}; });
  308. ASSERT_EQ(std::get<0>(*it), entt::entity{3});
  309. }
  310. TYPED_TEST(StorageNoInstance, ReverseIterable) {
  311. using value_type = typename TestFixture::type;
  312. using iterator = typename entt::storage<value_type>::reverse_iterable::iterator;
  313. testing::StaticAssertTypeEq<typename iterator::value_type, std::tuple<entt::entity>>();
  314. testing::StaticAssertTypeEq<typename iterator::value_type, std::tuple<entt::entity>>();
  315. testing::StaticAssertTypeEq<typename iterator::pointer, entt::input_iterator_pointer<std::tuple<entt::entity>>>();
  316. testing::StaticAssertTypeEq<typename iterator::reference, typename iterator::value_type>();
  317. entt::storage<value_type> pool;
  318. const entt::sparse_set &base = pool;
  319. pool.emplace(entt::entity{1});
  320. pool.emplace(entt::entity{3});
  321. auto iterable = pool.reach();
  322. iterator end{iterable.begin()};
  323. iterator begin{};
  324. begin = iterable.end();
  325. std::swap(begin, end);
  326. ASSERT_EQ(begin, iterable.begin());
  327. ASSERT_EQ(end, iterable.end());
  328. ASSERT_NE(begin, end);
  329. ASSERT_EQ(begin.base(), base.rbegin());
  330. ASSERT_EQ(end.base(), base.rend());
  331. ASSERT_EQ(std::get<0>(*begin.operator->().operator->()), entt::entity{1});
  332. ASSERT_EQ(std::get<0>(*begin), entt::entity{1});
  333. ASSERT_EQ(begin++, iterable.begin());
  334. ASSERT_EQ(begin.base(), ++base.rbegin());
  335. ASSERT_EQ(++begin, iterable.end());
  336. ASSERT_EQ(begin.base(), base.rend());
  337. for(auto [entity]: iterable) {
  338. testing::StaticAssertTypeEq<decltype(entity), entt::entity>();
  339. ASSERT_TRUE(entity == entt::entity{1} || entity == entt::entity{3});
  340. }
  341. }
  342. TYPED_TEST(StorageNoInstance, ConstReverseIterable) {
  343. using value_type = typename TestFixture::type;
  344. using iterator = typename entt::storage<value_type>::const_reverse_iterable::iterator;
  345. testing::StaticAssertTypeEq<typename iterator::value_type, std::tuple<entt::entity>>();
  346. testing::StaticAssertTypeEq<typename iterator::value_type, std::tuple<entt::entity>>();
  347. testing::StaticAssertTypeEq<typename iterator::pointer, entt::input_iterator_pointer<std::tuple<entt::entity>>>();
  348. testing::StaticAssertTypeEq<typename iterator::reference, typename iterator::value_type>();
  349. entt::storage<value_type> pool;
  350. const entt::sparse_set &base = pool;
  351. pool.emplace(entt::entity{1});
  352. pool.emplace(entt::entity{3});
  353. auto iterable = std::as_const(pool).reach();
  354. iterator end{iterable.begin()};
  355. iterator begin{};
  356. begin = iterable.end();
  357. std::swap(begin, end);
  358. ASSERT_EQ(begin, iterable.begin());
  359. ASSERT_EQ(end, iterable.end());
  360. ASSERT_NE(begin, end);
  361. ASSERT_EQ(begin.base(), base.rbegin());
  362. ASSERT_EQ(end.base(), base.rend());
  363. ASSERT_EQ(std::get<0>(*begin.operator->().operator->()), entt::entity{1});
  364. ASSERT_EQ(std::get<0>(*begin), entt::entity{1});
  365. ASSERT_EQ(begin++, iterable.begin());
  366. ASSERT_EQ(begin.base(), ++base.rbegin());
  367. ASSERT_EQ(++begin, iterable.end());
  368. ASSERT_EQ(begin.base(), base.rend());
  369. for(auto [entity]: iterable) {
  370. testing::StaticAssertTypeEq<decltype(entity), entt::entity>();
  371. ASSERT_TRUE(entity == entt::entity{1} || entity == entt::entity{3});
  372. }
  373. }
  374. TYPED_TEST(StorageNoInstance, ReverseIterableIteratorConversion) {
  375. using value_type = typename TestFixture::type;
  376. entt::storage<value_type> pool;
  377. pool.emplace(entt::entity{3});
  378. const typename entt::storage<value_type>::reverse_iterable::iterator it = pool.reach().begin();
  379. typename entt::storage<value_type>::const_reverse_iterable::iterator cit = it;
  380. testing::StaticAssertTypeEq<decltype(*it), std::tuple<entt::entity>>();
  381. testing::StaticAssertTypeEq<decltype(*cit), std::tuple<entt::entity>>();
  382. ASSERT_EQ(it, cit);
  383. ASSERT_NE(++cit, it);
  384. }
  385. TYPED_TEST(StorageNoInstance, ReverseIterableAlgorithmCompatibility) {
  386. using value_type = typename TestFixture::type;
  387. entt::storage<value_type> pool;
  388. pool.emplace(entt::entity{3});
  389. const auto iterable = pool.reach();
  390. const auto it = std::find_if(iterable.begin(), iterable.end(), [](auto args) { return std::get<0>(args) == entt::entity{3}; });
  391. ASSERT_EQ(std::get<0>(*it), entt::entity{3});
  392. }
  393. TYPED_TEST(StorageNoInstance, SortOrdered) {
  394. using value_type = typename TestFixture::type;
  395. entt::storage<value_type> pool;
  396. entt::entity entity[5u]{entt::entity{42}, entt::entity{12}, entt::entity{9}, entt::entity{7}, entt::entity{3}};
  397. pool.insert(std::begin(entity), std::end(entity));
  398. pool.sort(std::less{});
  399. ASSERT_TRUE(std::equal(std::rbegin(entity), std::rend(entity), pool.begin(), pool.end()));
  400. }
  401. TYPED_TEST(StorageNoInstance, SortReverse) {
  402. using value_type = typename TestFixture::type;
  403. entt::storage<value_type> pool;
  404. entt::entity entity[5u]{entt::entity{3}, entt::entity{7}, entt::entity{9}, entt::entity{12}, entt::entity{42}};
  405. pool.insert(std::begin(entity), std::end(entity));
  406. pool.sort(std::less{});
  407. ASSERT_TRUE(std::equal(std::begin(entity), std::end(entity), pool.begin(), pool.end()));
  408. }
  409. TYPED_TEST(StorageNoInstance, SortUnordered) {
  410. using value_type = typename TestFixture::type;
  411. entt::storage<value_type> pool;
  412. entt::entity entity[5u]{entt::entity{9}, entt::entity{7}, entt::entity{3}, entt::entity{12}, entt::entity{42}};
  413. pool.insert(std::begin(entity), std::end(entity));
  414. pool.sort(std::less{});
  415. ASSERT_EQ(pool.data()[0u], entity[4u]);
  416. ASSERT_EQ(pool.data()[1u], entity[3u]);
  417. ASSERT_EQ(pool.data()[2u], entity[0u]);
  418. ASSERT_EQ(pool.data()[3u], entity[1u]);
  419. ASSERT_EQ(pool.data()[4u], entity[2u]);
  420. }
  421. TYPED_TEST(StorageNoInstance, SortN) {
  422. using value_type = typename TestFixture::type;
  423. entt::storage<value_type> pool;
  424. entt::entity entity[5u]{entt::entity{7}, entt::entity{9}, entt::entity{3}, entt::entity{12}, entt::entity{42}};
  425. pool.insert(std::begin(entity), std::end(entity));
  426. pool.sort_n(0u, std::less{});
  427. ASSERT_TRUE(std::equal(std::rbegin(entity), std::rend(entity), pool.begin(), pool.end()));
  428. pool.sort_n(2u, std::less{});
  429. ASSERT_EQ(pool.data()[0u], entity[1u]);
  430. ASSERT_EQ(pool.data()[1u], entity[0u]);
  431. ASSERT_EQ(pool.data()[2u], entity[2u]);
  432. pool.sort_n(5u, std::less{});
  433. ASSERT_EQ(pool.data()[0u], entity[4u]);
  434. ASSERT_EQ(pool.data()[1u], entity[3u]);
  435. ASSERT_EQ(pool.data()[2u], entity[1u]);
  436. ASSERT_EQ(pool.data()[3u], entity[0u]);
  437. ASSERT_EQ(pool.data()[4u], entity[2u]);
  438. }
  439. TYPED_TEST(StorageNoInstance, SortAsDisjoint) {
  440. using value_type = typename TestFixture::type;
  441. entt::storage<value_type> lhs;
  442. const entt::storage<value_type> rhs;
  443. entt::entity lhs_entity[3u]{entt::entity{3}, entt::entity{12}, entt::entity{42}};
  444. lhs.insert(std::begin(lhs_entity), std::end(lhs_entity));
  445. ASSERT_TRUE(std::equal(std::rbegin(lhs_entity), std::rend(lhs_entity), lhs.begin(), lhs.end()));
  446. lhs.sort_as(rhs.begin(), rhs.end());
  447. ASSERT_TRUE(std::equal(std::rbegin(lhs_entity), std::rend(lhs_entity), lhs.begin(), lhs.end()));
  448. }
  449. TYPED_TEST(StorageNoInstance, SortAsOverlap) {
  450. using value_type = typename TestFixture::type;
  451. entt::storage<value_type> lhs;
  452. entt::storage<value_type> rhs;
  453. entt::entity lhs_entity[3u]{entt::entity{3}, entt::entity{12}, entt::entity{42}};
  454. entt::entity rhs_entity[1u]{entt::entity{12}};
  455. lhs.insert(std::begin(lhs_entity), std::end(lhs_entity));
  456. rhs.insert(std::begin(rhs_entity), std::end(rhs_entity));
  457. ASSERT_TRUE(std::equal(std::rbegin(lhs_entity), std::rend(lhs_entity), lhs.begin(), lhs.end()));
  458. ASSERT_TRUE(std::equal(std::rbegin(rhs_entity), std::rend(rhs_entity), rhs.begin(), rhs.end()));
  459. lhs.sort_as(rhs.begin(), rhs.end());
  460. ASSERT_EQ(lhs.data()[0u], lhs_entity[0u]);
  461. ASSERT_EQ(lhs.data()[1u], lhs_entity[2u]);
  462. ASSERT_EQ(lhs.data()[2u], lhs_entity[1u]);
  463. }
  464. TYPED_TEST(StorageNoInstance, SortAsOrdered) {
  465. using value_type = typename TestFixture::type;
  466. entt::storage<value_type> lhs;
  467. entt::storage<value_type> rhs;
  468. entt::entity lhs_entity[5u]{entt::entity{1}, entt::entity{2}, entt::entity{3}, entt::entity{4}, entt::entity{5}};
  469. entt::entity rhs_entity[6u]{entt::entity{6}, entt::entity{1}, entt::entity{2}, entt::entity{3}, entt::entity{4}, entt::entity{5}};
  470. lhs.insert(std::begin(lhs_entity), std::end(lhs_entity));
  471. rhs.insert(std::begin(rhs_entity), std::end(rhs_entity));
  472. ASSERT_TRUE(std::equal(std::rbegin(lhs_entity), std::rend(lhs_entity), lhs.begin(), lhs.end()));
  473. ASSERT_TRUE(std::equal(std::rbegin(rhs_entity), std::rend(rhs_entity), rhs.begin(), rhs.end()));
  474. rhs.sort_as(lhs.begin(), lhs.end());
  475. ASSERT_TRUE(std::equal(std::rbegin(rhs_entity), std::rend(rhs_entity), rhs.begin(), rhs.end()));
  476. }
  477. TYPED_TEST(StorageNoInstance, SortAsReverse) {
  478. using value_type = typename TestFixture::type;
  479. entt::storage<value_type> lhs;
  480. entt::storage<value_type> rhs;
  481. entt::entity lhs_entity[5u]{entt::entity{1}, entt::entity{2}, entt::entity{3}, entt::entity{4}, entt::entity{5}};
  482. entt::entity rhs_entity[6u]{entt::entity{5}, entt::entity{4}, entt::entity{3}, entt::entity{2}, entt::entity{1}, entt::entity{6}};
  483. lhs.insert(std::begin(lhs_entity), std::end(lhs_entity));
  484. rhs.insert(std::begin(rhs_entity), std::end(rhs_entity));
  485. ASSERT_TRUE(std::equal(std::rbegin(lhs_entity), std::rend(lhs_entity), lhs.begin(), lhs.end()));
  486. ASSERT_TRUE(std::equal(std::rbegin(rhs_entity), std::rend(rhs_entity), rhs.begin(), rhs.end()));
  487. rhs.sort_as(lhs.begin(), lhs.end());
  488. ASSERT_EQ(rhs.data()[0u], rhs_entity[5u]);
  489. ASSERT_EQ(rhs.data()[1u], rhs_entity[4u]);
  490. ASSERT_EQ(rhs.data()[2u], rhs_entity[3u]);
  491. ASSERT_EQ(rhs.data()[3u], rhs_entity[2u]);
  492. ASSERT_EQ(rhs.data()[4u], rhs_entity[1u]);
  493. ASSERT_EQ(rhs.data()[5u], rhs_entity[0u]);
  494. }
  495. TYPED_TEST(StorageNoInstance, SortAsUnordered) {
  496. using value_type = typename TestFixture::type;
  497. entt::storage<value_type> lhs;
  498. entt::storage<value_type> rhs;
  499. entt::entity lhs_entity[5u]{entt::entity{1}, entt::entity{2}, entt::entity{3}, entt::entity{4}, entt::entity{5}};
  500. entt::entity rhs_entity[6u]{entt::entity{3}, entt::entity{2}, entt::entity{6}, entt::entity{1}, entt::entity{4}, entt::entity{5}};
  501. lhs.insert(std::begin(lhs_entity), std::end(lhs_entity));
  502. rhs.insert(std::begin(rhs_entity), std::end(rhs_entity));
  503. ASSERT_TRUE(std::equal(std::rbegin(lhs_entity), std::rend(lhs_entity), lhs.begin(), lhs.end()));
  504. ASSERT_TRUE(std::equal(std::rbegin(rhs_entity), std::rend(rhs_entity), rhs.begin(), rhs.end()));
  505. rhs.sort_as(lhs.begin(), lhs.end());
  506. ASSERT_EQ(rhs.data()[0u], rhs_entity[2u]);
  507. ASSERT_EQ(rhs.data()[1u], rhs_entity[3u]);
  508. ASSERT_EQ(rhs.data()[2u], rhs_entity[1u]);
  509. ASSERT_EQ(rhs.data()[3u], rhs_entity[0u]);
  510. ASSERT_EQ(rhs.data()[4u], rhs_entity[4u]);
  511. ASSERT_EQ(rhs.data()[5u], rhs_entity[5u]);
  512. }