dense_set.cpp 31 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048
  1. #include <array>
  2. #include <cmath>
  3. #include <cstddef>
  4. #include <functional>
  5. #include <iterator>
  6. #include <memory>
  7. #include <string>
  8. #include <tuple>
  9. #include <utility>
  10. #include <vector>
  11. #include <gtest/gtest.h>
  12. #include <entt/container/dense_set.hpp>
  13. #include <entt/core/memory.hpp>
  14. #include <entt/core/utility.hpp>
  15. #include "../common/linter.hpp"
  16. #include "../common/throwing_allocator.hpp"
  17. #include "../common/tracked_memory_resource.hpp"
  18. #include "../common/transparent_equal_to.h"
  19. TEST(DenseSet, Functionalities) {
  20. entt::dense_set<int, entt::identity, test::transparent_equal_to> set;
  21. const auto &cset = set;
  22. ASSERT_NO_THROW([[maybe_unused]] auto alloc = set.get_allocator());
  23. ASSERT_TRUE(set.empty());
  24. ASSERT_EQ(set.size(), 0u);
  25. ASSERT_EQ(set.load_factor(), 0.f);
  26. ASSERT_EQ(set.max_load_factor(), .875f);
  27. ASSERT_EQ(set.max_size(), (std::vector<std::pair<std::size_t, int>>{}.max_size()));
  28. set.max_load_factor(.9f);
  29. ASSERT_EQ(set.max_load_factor(), .9f);
  30. ASSERT_EQ(set.begin(), set.end());
  31. ASSERT_EQ(cset.begin(), cset.end());
  32. ASSERT_EQ(set.cbegin(), set.cend());
  33. ASSERT_NE(set.max_bucket_count(), 0u);
  34. ASSERT_EQ(set.bucket_count(), 8u);
  35. ASSERT_EQ(set.bucket_size(3u), 0u);
  36. ASSERT_EQ(set.bucket(0), 0u);
  37. ASSERT_EQ(set.bucket(3), 3u);
  38. ASSERT_EQ(set.bucket(8), 0u);
  39. ASSERT_EQ(set.bucket(10), 2u);
  40. ASSERT_EQ(set.begin(1u), set.end(1u));
  41. ASSERT_EQ(cset.begin(1u), cset.end(1u));
  42. ASSERT_EQ(set.cbegin(1u), set.cend(1u));
  43. ASSERT_FALSE(set.contains(64));
  44. ASSERT_FALSE(set.contains(6.4));
  45. ASSERT_EQ(set.find(64), set.end());
  46. ASSERT_EQ(set.find(6.4), set.end());
  47. ASSERT_EQ(cset.find(64), set.cend());
  48. ASSERT_EQ(cset.find(6.4), set.cend());
  49. ASSERT_EQ(set.hash_function()(64), 64);
  50. ASSERT_TRUE(set.key_eq()(64, 64));
  51. set.emplace(0);
  52. ASSERT_EQ(set.count(0), 1u);
  53. ASSERT_EQ(set.count(6.4), 0u);
  54. ASSERT_EQ(cset.count(0.0), 1u);
  55. ASSERT_EQ(cset.count(64), 0u);
  56. ASSERT_FALSE(set.empty());
  57. ASSERT_EQ(set.size(), 1u);
  58. ASSERT_NE(set.begin(), set.end());
  59. ASSERT_NE(cset.begin(), cset.end());
  60. ASSERT_NE(set.cbegin(), set.cend());
  61. ASSERT_TRUE(set.contains(0));
  62. ASSERT_EQ(set.bucket(0), 0u);
  63. set.clear();
  64. ASSERT_TRUE(set.empty());
  65. ASSERT_EQ(set.size(), 0u);
  66. ASSERT_EQ(set.begin(), set.end());
  67. ASSERT_EQ(cset.begin(), cset.end());
  68. ASSERT_EQ(set.cbegin(), set.cend());
  69. ASSERT_FALSE(set.contains(0));
  70. }
  71. TEST(DenseSet, Constructors) {
  72. constexpr std::size_t minimum_bucket_count = 8u;
  73. entt::dense_set<int> set;
  74. ASSERT_EQ(set.bucket_count(), minimum_bucket_count);
  75. set = entt::dense_set<int>{std::allocator<int>{}};
  76. set = entt::dense_set<int>{2u * minimum_bucket_count, std::allocator<float>{}};
  77. set = entt::dense_set<int>{4u * minimum_bucket_count, std::hash<int>(), std::allocator<double>{}};
  78. set.emplace(3);
  79. entt::dense_set<int> temp{set, set.get_allocator()};
  80. const entt::dense_set<int> other{std::move(temp), set.get_allocator()};
  81. ASSERT_EQ(set.size(), 1u);
  82. ASSERT_EQ(other.size(), 1u);
  83. ASSERT_EQ(set.bucket_count(), 4u * minimum_bucket_count);
  84. ASSERT_EQ(other.bucket_count(), 4u * minimum_bucket_count);
  85. }
  86. TEST(DenseSet, Copy) {
  87. entt::dense_set<std::size_t, entt::identity> set;
  88. const auto max_load_factor = set.max_load_factor() - .05f;
  89. set.max_load_factor(max_load_factor);
  90. set.emplace(3u);
  91. entt::dense_set<std::size_t, entt::identity> other{set};
  92. ASSERT_TRUE(set.contains(3u));
  93. ASSERT_TRUE(other.contains(3u));
  94. ASSERT_EQ(other.max_load_factor(), max_load_factor);
  95. set.emplace(0u);
  96. set.emplace(8u);
  97. other.emplace(1u);
  98. other = set;
  99. ASSERT_TRUE(other.contains(3u));
  100. ASSERT_TRUE(other.contains(0u));
  101. ASSERT_TRUE(other.contains(8u));
  102. ASSERT_FALSE(other.contains(1u));
  103. ASSERT_EQ(other.bucket(0u), set.bucket(8u));
  104. ASSERT_EQ(other.bucket(0u), other.bucket(8u));
  105. ASSERT_EQ(*other.begin(0u), *set.begin(0u));
  106. ASSERT_EQ(*other.begin(0u), 8u);
  107. ASSERT_EQ((*++other.begin(0u)), 0u);
  108. }
  109. TEST(DenseSet, Move) {
  110. entt::dense_set<std::size_t, entt::identity> set;
  111. const auto max_load_factor = set.max_load_factor() - .05f;
  112. set.max_load_factor(max_load_factor);
  113. set.emplace(3u);
  114. entt::dense_set<std::size_t, entt::identity> other{std::move(set)};
  115. test::is_initialized(set);
  116. ASSERT_TRUE(set.empty());
  117. ASSERT_TRUE(other.contains(3u));
  118. ASSERT_EQ(other.max_load_factor(), max_load_factor);
  119. set = other;
  120. set.emplace(0u);
  121. set.emplace(8u);
  122. other.emplace(1u);
  123. other = std::move(set);
  124. test::is_initialized(set);
  125. ASSERT_TRUE(set.empty());
  126. ASSERT_TRUE(other.contains(3u));
  127. ASSERT_TRUE(other.contains(0u));
  128. ASSERT_TRUE(other.contains(8u));
  129. ASSERT_FALSE(other.contains(1u));
  130. ASSERT_EQ(other.bucket(0u), other.bucket(8u));
  131. ASSERT_EQ(*other.begin(0u), 8u);
  132. ASSERT_EQ(*++other.begin(0u), 0u);
  133. }
  134. TEST(DenseSet, Iterator) {
  135. using iterator = typename entt::dense_set<int>::iterator;
  136. testing::StaticAssertTypeEq<iterator::value_type, int>();
  137. testing::StaticAssertTypeEq<iterator::pointer, const int *>();
  138. testing::StaticAssertTypeEq<iterator::reference, const int &>();
  139. entt::dense_set<int> set;
  140. set.emplace(3);
  141. iterator end{set.begin()};
  142. iterator begin{};
  143. begin = set.end();
  144. std::swap(begin, end);
  145. ASSERT_EQ(begin, set.begin());
  146. ASSERT_EQ(end, set.end());
  147. ASSERT_NE(begin, end);
  148. ASSERT_EQ(begin++, set.begin());
  149. ASSERT_EQ(begin--, set.end());
  150. ASSERT_EQ(begin + 1, set.end());
  151. ASSERT_EQ(end - 1, set.begin());
  152. ASSERT_EQ(++begin, set.end());
  153. ASSERT_EQ(--begin, set.begin());
  154. ASSERT_EQ(begin += 1, set.end());
  155. ASSERT_EQ(begin -= 1, set.begin());
  156. ASSERT_EQ(begin + (end - begin), set.end());
  157. ASSERT_EQ(begin - (begin - end), set.end());
  158. ASSERT_EQ(end - (end - begin), set.begin());
  159. ASSERT_EQ(end + (begin - end), set.begin());
  160. ASSERT_EQ(begin[0u], *set.begin().operator->());
  161. ASSERT_EQ(begin[0u], *set.begin());
  162. ASSERT_LT(begin, end);
  163. ASSERT_LE(begin, set.begin());
  164. ASSERT_GT(end, begin);
  165. ASSERT_GE(end, set.end());
  166. set.emplace(1);
  167. begin = set.begin();
  168. ASSERT_EQ(begin[0u], 3);
  169. ASSERT_EQ(begin[1u], 1);
  170. }
  171. TEST(DenseSet, ConstIterator) {
  172. using iterator = typename entt::dense_set<int>::const_iterator;
  173. testing::StaticAssertTypeEq<iterator::value_type, int>();
  174. testing::StaticAssertTypeEq<iterator::pointer, const int *>();
  175. testing::StaticAssertTypeEq<iterator::reference, const int &>();
  176. entt::dense_set<int> set;
  177. set.emplace(3);
  178. iterator cend{set.cbegin()};
  179. iterator cbegin{};
  180. cbegin = set.cend();
  181. std::swap(cbegin, cend);
  182. ASSERT_EQ(cbegin, set.cbegin());
  183. ASSERT_EQ(cend, set.cend());
  184. ASSERT_NE(cbegin, cend);
  185. ASSERT_EQ(cbegin++, set.cbegin());
  186. ASSERT_EQ(cbegin--, set.cend());
  187. ASSERT_EQ(cbegin + 1, set.cend());
  188. ASSERT_EQ(cend - 1, set.cbegin());
  189. ASSERT_EQ(++cbegin, set.cend());
  190. ASSERT_EQ(--cbegin, set.cbegin());
  191. ASSERT_EQ(cbegin += 1, set.cend());
  192. ASSERT_EQ(cbegin -= 1, set.cbegin());
  193. ASSERT_EQ(cbegin + (cend - cbegin), set.cend());
  194. ASSERT_EQ(cbegin - (cbegin - cend), set.cend());
  195. ASSERT_EQ(cend - (cend - cbegin), set.cbegin());
  196. ASSERT_EQ(cend + (cbegin - cend), set.cbegin());
  197. ASSERT_EQ(cbegin[0u], *set.cbegin().operator->());
  198. ASSERT_EQ(cbegin[0u], *set.cbegin());
  199. ASSERT_LT(cbegin, cend);
  200. ASSERT_LE(cbegin, set.cbegin());
  201. ASSERT_GT(cend, cbegin);
  202. ASSERT_GE(cend, set.cend());
  203. set.emplace(1);
  204. cbegin = set.cbegin();
  205. ASSERT_EQ(cbegin[0u], 3);
  206. ASSERT_EQ(cbegin[1u], 1);
  207. }
  208. TEST(DenseSet, ReverseIterator) {
  209. using iterator = typename entt::dense_set<int>::reverse_iterator;
  210. testing::StaticAssertTypeEq<iterator::value_type, int>();
  211. testing::StaticAssertTypeEq<iterator::pointer, const int *>();
  212. testing::StaticAssertTypeEq<iterator::reference, const int &>();
  213. entt::dense_set<int> set;
  214. set.emplace(3);
  215. iterator end{set.rbegin()};
  216. iterator begin{};
  217. begin = set.rend();
  218. std::swap(begin, end);
  219. ASSERT_EQ(begin, set.rbegin());
  220. ASSERT_EQ(end, set.rend());
  221. ASSERT_NE(begin, end);
  222. ASSERT_EQ(begin++, set.rbegin());
  223. ASSERT_EQ(begin--, set.rend());
  224. ASSERT_EQ(begin + 1, set.rend());
  225. ASSERT_EQ(end - 1, set.rbegin());
  226. ASSERT_EQ(++begin, set.rend());
  227. ASSERT_EQ(--begin, set.rbegin());
  228. ASSERT_EQ(begin += 1, set.rend());
  229. ASSERT_EQ(begin -= 1, set.rbegin());
  230. ASSERT_EQ(begin + (end - begin), set.rend());
  231. ASSERT_EQ(begin - (begin - end), set.rend());
  232. ASSERT_EQ(end - (end - begin), set.rbegin());
  233. ASSERT_EQ(end + (begin - end), set.rbegin());
  234. ASSERT_EQ(begin[0u], *set.rbegin().operator->());
  235. ASSERT_EQ(begin[0u], *set.rbegin());
  236. ASSERT_LT(begin, end);
  237. ASSERT_LE(begin, set.rbegin());
  238. ASSERT_GT(end, begin);
  239. ASSERT_GE(end, set.rend());
  240. set.emplace(1);
  241. begin = set.rbegin();
  242. ASSERT_EQ(begin[0u], 1);
  243. ASSERT_EQ(begin[1u], 3);
  244. }
  245. TEST(DenseSet, ConstReverseIterator) {
  246. using iterator = typename entt::dense_set<int>::const_reverse_iterator;
  247. testing::StaticAssertTypeEq<iterator::value_type, int>();
  248. testing::StaticAssertTypeEq<iterator::pointer, const int *>();
  249. testing::StaticAssertTypeEq<iterator::reference, const int &>();
  250. entt::dense_set<int> set;
  251. set.emplace(3);
  252. iterator cend{set.crbegin()};
  253. iterator cbegin{};
  254. cbegin = set.crend();
  255. std::swap(cbegin, cend);
  256. ASSERT_EQ(cbegin, set.crbegin());
  257. ASSERT_EQ(cend, set.crend());
  258. ASSERT_NE(cbegin, cend);
  259. ASSERT_EQ(cbegin++, set.crbegin());
  260. ASSERT_EQ(cbegin--, set.crend());
  261. ASSERT_EQ(cbegin + 1, set.crend());
  262. ASSERT_EQ(cend - 1, set.crbegin());
  263. ASSERT_EQ(++cbegin, set.crend());
  264. ASSERT_EQ(--cbegin, set.crbegin());
  265. ASSERT_EQ(cbegin += 1, set.crend());
  266. ASSERT_EQ(cbegin -= 1, set.crbegin());
  267. ASSERT_EQ(cbegin + (cend - cbegin), set.crend());
  268. ASSERT_EQ(cbegin - (cbegin - cend), set.crend());
  269. ASSERT_EQ(cend - (cend - cbegin), set.crbegin());
  270. ASSERT_EQ(cend + (cbegin - cend), set.crbegin());
  271. ASSERT_EQ(cbegin[0u], *set.crbegin().operator->());
  272. ASSERT_EQ(cbegin[0u], *set.crbegin());
  273. ASSERT_LT(cbegin, cend);
  274. ASSERT_LE(cbegin, set.crbegin());
  275. ASSERT_GT(cend, cbegin);
  276. ASSERT_GE(cend, set.crend());
  277. set.emplace(1);
  278. cbegin = set.crbegin();
  279. ASSERT_EQ(cbegin[0u], 1);
  280. ASSERT_EQ(cbegin[1u], 3);
  281. }
  282. TEST(DenseSet, IteratorConversion) {
  283. entt::dense_set<int> set;
  284. set.emplace(3);
  285. const typename entt::dense_set<int, int>::iterator it = set.begin();
  286. typename entt::dense_set<int, int>::const_iterator cit = it;
  287. testing::StaticAssertTypeEq<decltype(*it), const int &>();
  288. testing::StaticAssertTypeEq<decltype(*cit), const int &>();
  289. ASSERT_EQ(*it, 3);
  290. ASSERT_EQ(*it.operator->(), 3);
  291. ASSERT_EQ(it.operator->(), cit.operator->());
  292. ASSERT_EQ(*it, *cit);
  293. ASSERT_EQ(it - cit, 0);
  294. ASSERT_EQ(cit - it, 0);
  295. ASSERT_LE(it, cit);
  296. ASSERT_LE(cit, it);
  297. ASSERT_GE(it, cit);
  298. ASSERT_GE(cit, it);
  299. ASSERT_EQ(it, cit);
  300. ASSERT_NE(++cit, it);
  301. }
  302. TEST(DenseSet, Insert) {
  303. entt::dense_set<int> set;
  304. typename entt::dense_set<int>::iterator it;
  305. bool result{};
  306. ASSERT_TRUE(set.empty());
  307. ASSERT_EQ(set.size(), 0u);
  308. ASSERT_EQ(set.find(0), set.end());
  309. ASSERT_FALSE(set.contains(0));
  310. int value{1};
  311. std::tie(it, result) = set.insert(std::as_const(value));
  312. ASSERT_TRUE(result);
  313. ASSERT_EQ(set.size(), 1u);
  314. ASSERT_EQ(it, --set.end());
  315. ASSERT_TRUE(set.contains(1));
  316. ASSERT_NE(set.find(1), set.end());
  317. ASSERT_EQ(*it, 1);
  318. std::tie(it, result) = set.insert(value);
  319. ASSERT_FALSE(result);
  320. ASSERT_EQ(set.size(), 1u);
  321. ASSERT_EQ(it, --set.end());
  322. ASSERT_EQ(*it, 1);
  323. std::tie(it, result) = set.insert(3);
  324. ASSERT_TRUE(result);
  325. ASSERT_EQ(set.size(), 2u);
  326. ASSERT_EQ(it, --set.end());
  327. ASSERT_TRUE(set.contains(3));
  328. ASSERT_NE(set.find(3), set.end());
  329. ASSERT_EQ(*it, 3);
  330. std::tie(it, result) = set.insert(3);
  331. ASSERT_FALSE(result);
  332. ASSERT_EQ(set.size(), 2u);
  333. ASSERT_EQ(it, --set.end());
  334. ASSERT_EQ(*it, 3);
  335. std::array range{2, 4};
  336. set.insert(std::begin(range), std::end(range));
  337. ASSERT_EQ(set.size(), 4u);
  338. ASSERT_TRUE(set.contains(2));
  339. ASSERT_NE(set.find(4), set.end());
  340. }
  341. TEST(DenseSet, InsertRehash) {
  342. constexpr std::size_t minimum_bucket_count = 8u;
  343. entt::dense_set<std::size_t, entt::identity> set;
  344. ASSERT_EQ(set.size(), 0u);
  345. ASSERT_EQ(set.bucket_count(), minimum_bucket_count);
  346. for(std::size_t next{}; next < minimum_bucket_count; ++next) {
  347. ASSERT_TRUE(set.insert(next).second);
  348. }
  349. ASSERT_EQ(set.size(), minimum_bucket_count);
  350. ASSERT_GT(set.bucket_count(), minimum_bucket_count);
  351. ASSERT_TRUE(set.contains(minimum_bucket_count / 2u));
  352. ASSERT_EQ(set.bucket(minimum_bucket_count / 2u), minimum_bucket_count / 2u);
  353. ASSERT_FALSE(set.contains(minimum_bucket_count));
  354. ASSERT_TRUE(set.insert(minimum_bucket_count).second);
  355. ASSERT_EQ(set.size(), minimum_bucket_count + 1u);
  356. ASSERT_EQ(set.bucket_count(), minimum_bucket_count * 2u);
  357. ASSERT_TRUE(set.contains(minimum_bucket_count / 2u));
  358. ASSERT_EQ(set.bucket(minimum_bucket_count / 2u), minimum_bucket_count / 2u);
  359. ASSERT_TRUE(set.contains(minimum_bucket_count));
  360. for(std::size_t next{}; next <= minimum_bucket_count; ++next) {
  361. ASSERT_TRUE(set.contains(next));
  362. ASSERT_EQ(set.bucket(next), next);
  363. }
  364. }
  365. TEST(DenseSet, InsertSameBucket) {
  366. constexpr std::size_t minimum_bucket_count = 8u;
  367. entt::dense_set<std::size_t, entt::identity> set;
  368. for(std::size_t next{}; next < minimum_bucket_count; ++next) {
  369. ASSERT_EQ(set.cbegin(next), set.cend(next));
  370. }
  371. ASSERT_TRUE(set.insert(1u).second);
  372. ASSERT_TRUE(set.insert(9u).second);
  373. ASSERT_EQ(set.size(), 2u);
  374. ASSERT_TRUE(set.contains(1u));
  375. ASSERT_NE(set.find(9u), set.end());
  376. ASSERT_EQ(set.bucket(1u), 1u);
  377. ASSERT_EQ(set.bucket(9u), 1u);
  378. ASSERT_EQ(set.bucket_size(1u), 2u);
  379. ASSERT_EQ(set.cbegin(6u), set.cend(6u));
  380. }
  381. TEST(DenseSet, Emplace) {
  382. entt::dense_set<int> set;
  383. typename entt::dense_set<int>::iterator it;
  384. bool result{};
  385. ASSERT_TRUE(set.empty());
  386. ASSERT_EQ(set.size(), 0u);
  387. ASSERT_EQ(set.find(0), set.end());
  388. ASSERT_FALSE(set.contains(0));
  389. std::tie(it, result) = set.emplace();
  390. ASSERT_TRUE(result);
  391. ASSERT_EQ(set.size(), 1u);
  392. ASSERT_EQ(it, --set.end());
  393. ASSERT_TRUE(set.contains(0));
  394. ASSERT_NE(set.find(0), set.end());
  395. ASSERT_EQ(*it, 0);
  396. std::tie(it, result) = set.emplace();
  397. ASSERT_FALSE(result);
  398. ASSERT_EQ(set.size(), 1u);
  399. ASSERT_EQ(it, --set.end());
  400. ASSERT_EQ(*it, 0);
  401. std::tie(it, result) = set.emplace(1);
  402. ASSERT_TRUE(result);
  403. ASSERT_EQ(set.size(), 2u);
  404. ASSERT_EQ(it, --set.end());
  405. ASSERT_TRUE(set.contains(1));
  406. ASSERT_NE(set.find(1), set.end());
  407. ASSERT_EQ(*it, 1);
  408. std::tie(it, result) = set.emplace(1);
  409. ASSERT_FALSE(result);
  410. ASSERT_EQ(set.size(), 2u);
  411. ASSERT_EQ(it, --set.end());
  412. ASSERT_EQ(*it, 1);
  413. }
  414. TEST(DenseSet, EmplaceRehash) {
  415. constexpr std::size_t minimum_bucket_count = 8u;
  416. entt::dense_set<std::size_t, entt::identity> set;
  417. ASSERT_EQ(set.size(), 0u);
  418. ASSERT_EQ(set.bucket_count(), minimum_bucket_count);
  419. for(std::size_t next{}; next < minimum_bucket_count; ++next) {
  420. ASSERT_TRUE(set.emplace(next).second);
  421. ASSERT_LE(set.load_factor(), set.max_load_factor());
  422. }
  423. ASSERT_EQ(set.size(), minimum_bucket_count);
  424. ASSERT_GT(set.bucket_count(), minimum_bucket_count);
  425. ASSERT_TRUE(set.contains(minimum_bucket_count / 2u));
  426. ASSERT_EQ(set.bucket(minimum_bucket_count / 2u), minimum_bucket_count / 2u);
  427. ASSERT_FALSE(set.contains(minimum_bucket_count));
  428. ASSERT_TRUE(set.emplace(minimum_bucket_count).second);
  429. ASSERT_EQ(set.size(), minimum_bucket_count + 1u);
  430. ASSERT_EQ(set.bucket_count(), minimum_bucket_count * 2u);
  431. ASSERT_TRUE(set.contains(minimum_bucket_count / 2u));
  432. ASSERT_EQ(set.bucket(minimum_bucket_count / 2u), minimum_bucket_count / 2u);
  433. ASSERT_TRUE(set.contains(minimum_bucket_count));
  434. for(std::size_t next{}; next <= minimum_bucket_count; ++next) {
  435. ASSERT_TRUE(set.contains(next));
  436. ASSERT_EQ(set.bucket(next), next);
  437. }
  438. }
  439. TEST(DenseSet, EmplaceSameBucket) {
  440. constexpr std::size_t minimum_bucket_count = 8u;
  441. entt::dense_set<std::size_t, entt::identity> set;
  442. for(std::size_t next{}; next < minimum_bucket_count; ++next) {
  443. ASSERT_EQ(set.cbegin(next), set.cend(next));
  444. }
  445. ASSERT_TRUE(set.emplace(1u).second);
  446. ASSERT_TRUE(set.emplace(9u).second);
  447. ASSERT_EQ(set.size(), 2u);
  448. ASSERT_TRUE(set.contains(1u));
  449. ASSERT_NE(set.find(9u), set.end());
  450. ASSERT_EQ(set.bucket(1u), 1u);
  451. ASSERT_EQ(set.bucket(9u), 1u);
  452. ASSERT_EQ(set.bucket_size(1u), 2u);
  453. ASSERT_EQ(set.cbegin(6u), set.cend(6u));
  454. }
  455. TEST(DenseSet, Erase) {
  456. constexpr std::size_t minimum_bucket_count = 8u;
  457. entt::dense_set<std::size_t, entt::identity> set;
  458. for(std::size_t next{}, last = minimum_bucket_count + 1u; next < last; ++next) {
  459. set.emplace(next);
  460. }
  461. ASSERT_EQ(set.bucket_count(), 2 * minimum_bucket_count);
  462. ASSERT_EQ(set.size(), minimum_bucket_count + 1u);
  463. for(std::size_t next{}, last = minimum_bucket_count + 1u; next < last; ++next) {
  464. ASSERT_TRUE(set.contains(next));
  465. }
  466. auto it = set.erase(++set.begin());
  467. it = set.erase(it, it + 1);
  468. ASSERT_EQ(*--set.end(), 6u);
  469. ASSERT_EQ(set.erase(6u), 1u);
  470. ASSERT_EQ(set.erase(6u), 0u);
  471. ASSERT_EQ(set.bucket_count(), 2 * minimum_bucket_count);
  472. ASSERT_EQ(set.size(), minimum_bucket_count + 1u - 3u);
  473. ASSERT_EQ(it, ++set.begin());
  474. ASSERT_EQ(*it, 7u);
  475. ASSERT_EQ(*--set.end(), 5u);
  476. for(std::size_t next{}, last = minimum_bucket_count + 1u; next < last; ++next) {
  477. if(next == 1u || next == 8u || next == 6u) { // NOLINT
  478. ASSERT_FALSE(set.contains(next));
  479. ASSERT_EQ(set.bucket_size(next), 0u);
  480. } else {
  481. ASSERT_TRUE(set.contains(next));
  482. ASSERT_EQ(set.bucket(next), next);
  483. ASSERT_EQ(set.bucket_size(next), 1u);
  484. }
  485. }
  486. set.erase(set.begin(), set.end());
  487. for(std::size_t next{}, last = minimum_bucket_count + 1u; next < last; ++next) {
  488. ASSERT_FALSE(set.contains(next));
  489. }
  490. ASSERT_EQ(set.bucket_count(), 2 * minimum_bucket_count);
  491. ASSERT_EQ(set.size(), 0u);
  492. }
  493. TEST(DenseSet, EraseWithMovableKeyValue) {
  494. constexpr std::size_t minimum_bucket_count = 8u;
  495. entt::dense_set<std::string> set;
  496. set.emplace("0");
  497. set.emplace("1");
  498. ASSERT_EQ(set.bucket_count(), minimum_bucket_count);
  499. ASSERT_EQ(set.size(), 2u);
  500. auto it = set.erase(set.find("0"));
  501. ASSERT_EQ(*it, "1");
  502. ASSERT_EQ(set.size(), 1u);
  503. ASSERT_FALSE(set.contains("0"));
  504. }
  505. TEST(DenseSet, EraseFromBucket) {
  506. constexpr std::size_t minimum_bucket_count = 8u;
  507. entt::dense_set<std::size_t, entt::identity> set;
  508. ASSERT_EQ(set.bucket_count(), minimum_bucket_count);
  509. ASSERT_EQ(set.size(), 0u);
  510. for(std::size_t next{}; next < 4u; ++next) {
  511. ASSERT_TRUE(set.emplace(2u * minimum_bucket_count * next).second);
  512. ASSERT_TRUE(set.emplace(2u * minimum_bucket_count * next + 2u).second);
  513. ASSERT_TRUE(set.emplace(2u * minimum_bucket_count * (next + 1u) - 1u).second);
  514. }
  515. ASSERT_EQ(set.bucket_count(), 2u * minimum_bucket_count);
  516. ASSERT_EQ(set.size(), 12u);
  517. ASSERT_EQ(set.bucket_size(0u), 4u);
  518. ASSERT_EQ(set.bucket_size(2u), 4u);
  519. ASSERT_EQ(set.bucket_size(15u), 4u);
  520. set.erase(set.end() - 3, set.end());
  521. ASSERT_EQ(set.bucket_count(), 2u * minimum_bucket_count);
  522. ASSERT_EQ(set.size(), 9u);
  523. ASSERT_EQ(set.bucket_size(0u), 3u);
  524. ASSERT_EQ(set.bucket_size(2u), 3u);
  525. ASSERT_EQ(set.bucket_size(15u), 3u);
  526. for(std::size_t next{}; next < 3u; ++next) {
  527. ASSERT_TRUE(set.contains(2u * minimum_bucket_count * next));
  528. ASSERT_EQ(set.bucket(2u * minimum_bucket_count * next), 0u);
  529. ASSERT_TRUE(set.contains(2u * minimum_bucket_count * next + 2u));
  530. ASSERT_EQ(set.bucket(2u * minimum_bucket_count * next + 2u), 2u);
  531. ASSERT_TRUE(set.contains(2u * minimum_bucket_count * (next + 1u) - 1u));
  532. ASSERT_EQ(set.bucket(2u * minimum_bucket_count * (next + 1u) - 1u), 15u);
  533. }
  534. ASSERT_FALSE(set.contains(2u * minimum_bucket_count * 3u));
  535. ASSERT_FALSE(set.contains(2u * minimum_bucket_count * 3u + 2u));
  536. ASSERT_FALSE(set.contains(2u * minimum_bucket_count * (3u + 1u) - 1u));
  537. set.erase(*++set.begin(0u));
  538. set.erase(*++set.begin(2u));
  539. set.erase(*++set.begin(15u)); // NOLINT
  540. ASSERT_EQ(set.bucket_count(), 2u * minimum_bucket_count);
  541. ASSERT_EQ(set.size(), 6u);
  542. ASSERT_EQ(set.bucket_size(0u), 2u);
  543. ASSERT_EQ(set.bucket_size(2u), 2u);
  544. ASSERT_EQ(set.bucket_size(15u), 2u);
  545. ASSERT_FALSE(set.contains(2u * minimum_bucket_count * 1u));
  546. ASSERT_FALSE(set.contains(2u * minimum_bucket_count * 1u + 2u));
  547. ASSERT_FALSE(set.contains(2u * minimum_bucket_count * (1u + 1u) - 1u));
  548. while(set.begin(15) != set.end(15u)) { // NOLINT
  549. set.erase(*set.begin(15)); // NOLINT
  550. }
  551. ASSERT_EQ(set.bucket_count(), 2u * minimum_bucket_count);
  552. ASSERT_EQ(set.size(), 4u);
  553. ASSERT_EQ(set.bucket_size(0u), 2u);
  554. ASSERT_EQ(set.bucket_size(2u), 2u);
  555. ASSERT_EQ(set.bucket_size(15u), 0u);
  556. ASSERT_TRUE(set.contains(0u * minimum_bucket_count));
  557. ASSERT_TRUE(set.contains(0u * minimum_bucket_count + 2u));
  558. ASSERT_TRUE(set.contains(4u * minimum_bucket_count));
  559. ASSERT_TRUE(set.contains(4u * minimum_bucket_count + 2u));
  560. set.erase(4u * minimum_bucket_count + 2u);
  561. set.erase(0u * minimum_bucket_count);
  562. ASSERT_EQ(set.bucket_count(), 2u * minimum_bucket_count);
  563. ASSERT_EQ(set.size(), 2u);
  564. ASSERT_EQ(set.bucket_size(0u), 1u);
  565. ASSERT_EQ(set.bucket_size(2u), 1u);
  566. ASSERT_EQ(set.bucket_size(15u), 0u);
  567. ASSERT_FALSE(set.contains(0u * minimum_bucket_count));
  568. ASSERT_TRUE(set.contains(0u * minimum_bucket_count + 2u));
  569. ASSERT_TRUE(set.contains(4u * minimum_bucket_count));
  570. ASSERT_FALSE(set.contains(4u * minimum_bucket_count + 2u));
  571. }
  572. TEST(DenseSet, Swap) {
  573. entt::dense_set<int> set;
  574. entt::dense_set<int> other;
  575. set.emplace(0);
  576. ASSERT_FALSE(set.empty());
  577. ASSERT_TRUE(other.empty());
  578. ASSERT_TRUE(set.contains(0));
  579. ASSERT_FALSE(other.contains(0));
  580. set.swap(other);
  581. ASSERT_TRUE(set.empty());
  582. ASSERT_FALSE(other.empty());
  583. ASSERT_FALSE(set.contains(0));
  584. ASSERT_TRUE(other.contains(0));
  585. }
  586. TEST(DenseSet, EqualRange) {
  587. entt::dense_set<int, entt::identity, test::transparent_equal_to> set;
  588. const auto &cset = set;
  589. set.emplace(1);
  590. ASSERT_EQ(set.equal_range(0).first, set.end());
  591. ASSERT_EQ(set.equal_range(0).second, set.end());
  592. ASSERT_EQ(cset.equal_range(0).first, cset.cend());
  593. ASSERT_EQ(cset.equal_range(0).second, cset.cend());
  594. ASSERT_EQ(set.equal_range(0.0).first, set.end());
  595. ASSERT_EQ(set.equal_range(0.0).second, set.end());
  596. ASSERT_EQ(cset.equal_range(0.0).first, cset.cend());
  597. ASSERT_EQ(cset.equal_range(0.0).second, cset.cend());
  598. ASSERT_NE(set.equal_range(1).first, set.end());
  599. ASSERT_EQ(*set.equal_range(1).first, 1);
  600. ASSERT_EQ(set.equal_range(1).second, set.end());
  601. ASSERT_NE(cset.equal_range(1).first, cset.cend());
  602. ASSERT_EQ(*cset.equal_range(1).first, 1);
  603. ASSERT_EQ(cset.equal_range(1).second, cset.cend());
  604. ASSERT_NE(set.equal_range(1.0).first, set.end());
  605. ASSERT_EQ(*set.equal_range(1.0).first, 1);
  606. ASSERT_EQ(set.equal_range(1.0).second, set.end());
  607. ASSERT_NE(cset.equal_range(1.0).first, cset.cend());
  608. ASSERT_EQ(*cset.equal_range(1.0).first, 1);
  609. ASSERT_EQ(cset.equal_range(1.0).second, cset.cend());
  610. }
  611. TEST(DenseSet, LocalIterator) {
  612. using iterator = typename entt::dense_set<std::size_t, entt::identity>::local_iterator;
  613. testing::StaticAssertTypeEq<iterator::value_type, std::size_t>();
  614. testing::StaticAssertTypeEq<iterator::pointer, const std::size_t *>();
  615. testing::StaticAssertTypeEq<iterator::reference, const std::size_t &>();
  616. constexpr std::size_t minimum_bucket_count = 8u;
  617. entt::dense_set<std::size_t, entt::identity> set;
  618. set.emplace(3u);
  619. set.emplace(3u + minimum_bucket_count);
  620. iterator end{set.begin(3u)};
  621. iterator begin{};
  622. begin = set.end(3u);
  623. std::swap(begin, end);
  624. ASSERT_EQ(begin, set.begin(3u));
  625. ASSERT_EQ(end, set.end(3u));
  626. ASSERT_NE(begin, end);
  627. ASSERT_EQ(*begin.operator->(), 3u + minimum_bucket_count);
  628. ASSERT_EQ(*begin, 3u + minimum_bucket_count);
  629. ASSERT_EQ(begin++, set.begin(3u));
  630. ASSERT_EQ(++begin, set.end(3u));
  631. }
  632. TEST(DenseSet, ConstLocalIterator) {
  633. using iterator = typename entt::dense_set<std::size_t, entt::identity>::const_local_iterator;
  634. testing::StaticAssertTypeEq<iterator::value_type, std::size_t>();
  635. testing::StaticAssertTypeEq<iterator::pointer, const std::size_t *>();
  636. testing::StaticAssertTypeEq<iterator::reference, const std::size_t &>();
  637. constexpr std::size_t minimum_bucket_count = 8u;
  638. entt::dense_set<std::size_t, entt::identity> set;
  639. set.emplace(3u);
  640. set.emplace(3u + minimum_bucket_count);
  641. iterator cend{set.begin(3u)};
  642. iterator cbegin{};
  643. cbegin = set.end(3u);
  644. std::swap(cbegin, cend);
  645. ASSERT_EQ(cbegin, set.begin(3u));
  646. ASSERT_EQ(cend, set.end(3u));
  647. ASSERT_NE(cbegin, cend);
  648. ASSERT_EQ(*cbegin.operator->(), 3u + minimum_bucket_count);
  649. ASSERT_EQ(*cbegin, 3u + minimum_bucket_count);
  650. ASSERT_EQ(cbegin++, set.begin(3u));
  651. ASSERT_EQ(++cbegin, set.end(3u));
  652. }
  653. TEST(DenseSet, LocalIteratorConversion) {
  654. entt::dense_set<int> set;
  655. set.emplace(3);
  656. const typename entt::dense_set<int>::local_iterator it = set.begin(set.bucket(3));
  657. typename entt::dense_set<int>::const_local_iterator cit = it;
  658. testing::StaticAssertTypeEq<decltype(*it), const int &>();
  659. testing::StaticAssertTypeEq<decltype(*cit), const int &>();
  660. ASSERT_EQ(*it, 3);
  661. ASSERT_EQ(*it.operator->(), 3);
  662. ASSERT_EQ(it.operator->(), cit.operator->());
  663. ASSERT_EQ(*it, *cit);
  664. ASSERT_EQ(it, cit);
  665. ASSERT_NE(++cit, it);
  666. }
  667. TEST(DenseSet, Rehash) {
  668. constexpr std::size_t minimum_bucket_count = 8u;
  669. entt::dense_set<std::size_t, entt::identity> set;
  670. set.emplace(32u);
  671. ASSERT_EQ(set.bucket_count(), minimum_bucket_count);
  672. ASSERT_TRUE(set.contains(32u));
  673. ASSERT_EQ(set.bucket(32u), 0u);
  674. set.rehash(minimum_bucket_count + 1u);
  675. ASSERT_EQ(set.bucket_count(), 2u * minimum_bucket_count);
  676. ASSERT_TRUE(set.contains(32u));
  677. ASSERT_EQ(set.bucket(32u), 0u);
  678. set.rehash(4u * minimum_bucket_count + 1u);
  679. ASSERT_EQ(set.bucket_count(), 8u * minimum_bucket_count);
  680. ASSERT_TRUE(set.contains(32u));
  681. ASSERT_EQ(set.bucket(32u), 32u);
  682. set.rehash(0u);
  683. ASSERT_EQ(set.bucket_count(), minimum_bucket_count);
  684. ASSERT_TRUE(set.contains(32u));
  685. ASSERT_EQ(set.bucket(32u), 0u);
  686. for(std::size_t next{}; next < minimum_bucket_count; ++next) {
  687. set.emplace(next);
  688. }
  689. ASSERT_EQ(set.size(), minimum_bucket_count + 1u);
  690. ASSERT_EQ(set.bucket_count(), 2u * minimum_bucket_count);
  691. set.rehash(0u);
  692. ASSERT_EQ(set.bucket_count(), 2u * minimum_bucket_count);
  693. ASSERT_TRUE(set.contains(32u));
  694. set.rehash(4u * minimum_bucket_count + 4u);
  695. ASSERT_EQ(set.bucket_count(), 8u * minimum_bucket_count);
  696. ASSERT_TRUE(set.contains(32u));
  697. set.rehash(2u);
  698. ASSERT_EQ(set.bucket_count(), 2u * minimum_bucket_count);
  699. ASSERT_TRUE(set.contains(32u));
  700. ASSERT_EQ(set.bucket(32u), 0u);
  701. for(std::size_t next{}; next < minimum_bucket_count; ++next) {
  702. ASSERT_TRUE(set.contains(next));
  703. ASSERT_EQ(set.bucket(next), next);
  704. }
  705. ASSERT_EQ(set.bucket_size(0u), 2u);
  706. ASSERT_EQ(set.bucket_size(3u), 1u);
  707. ASSERT_EQ(*set.begin(0u), 0u);
  708. ASSERT_EQ(*++set.begin(0u), 32u);
  709. set.clear();
  710. set.rehash(2u);
  711. ASSERT_EQ(set.bucket_count(), minimum_bucket_count);
  712. ASSERT_FALSE(set.contains(32u));
  713. for(std::size_t next{}; next < minimum_bucket_count; ++next) {
  714. ASSERT_FALSE(set.contains(next));
  715. }
  716. ASSERT_EQ(set.bucket_size(0u), 0u);
  717. ASSERT_EQ(set.bucket_size(3u), 0u);
  718. }
  719. TEST(DenseSet, Reserve) {
  720. constexpr std::size_t minimum_bucket_count = 8u;
  721. entt::dense_set<int> set;
  722. ASSERT_EQ(set.bucket_count(), minimum_bucket_count);
  723. set.reserve(0u);
  724. ASSERT_EQ(set.bucket_count(), minimum_bucket_count);
  725. set.reserve(minimum_bucket_count);
  726. ASSERT_EQ(set.bucket_count(), 2 * minimum_bucket_count);
  727. ASSERT_EQ(set.bucket_count(), entt::next_power_of_two(static_cast<std::size_t>(std::ceil(minimum_bucket_count / set.max_load_factor()))));
  728. }
  729. TEST(DenseSet, ThrowingAllocator) {
  730. constexpr std::size_t minimum_bucket_count = 8u;
  731. using allocator = test::throwing_allocator<std::size_t>;
  732. entt::dense_set<std::size_t, std::hash<std::size_t>, std::equal_to<>, allocator> set{};
  733. set.get_allocator().throw_counter<std::pair<std::size_t, std::size_t>>(0u);
  734. ASSERT_EQ(set.bucket_count(), minimum_bucket_count);
  735. ASSERT_THROW(set.reserve(2u * set.bucket_count()), test::throwing_allocator_exception);
  736. ASSERT_EQ(set.bucket_count(), minimum_bucket_count);
  737. set.get_allocator().throw_counter<std::pair<std::size_t, std::size_t>>(0u);
  738. ASSERT_THROW(set.emplace(), test::throwing_allocator_exception);
  739. ASSERT_FALSE(set.contains(0u));
  740. set.get_allocator().throw_counter<std::pair<std::size_t, std::size_t>>(0u);
  741. ASSERT_THROW(set.emplace(std::size_t{}), test::throwing_allocator_exception);
  742. ASSERT_FALSE(set.contains(0u));
  743. set.get_allocator().throw_counter<std::pair<std::size_t, std::size_t>>(0u);
  744. ASSERT_THROW(set.insert(0u), test::throwing_allocator_exception);
  745. ASSERT_FALSE(set.contains(0u));
  746. }
  747. #if defined(ENTT_HAS_TRACKED_MEMORY_RESOURCE)
  748. # include <memory_resource>
  749. TEST(DenseSet, NoUsesAllocatorConstruction) {
  750. using allocator = std::pmr::polymorphic_allocator<int>;
  751. test::tracked_memory_resource memory_resource{};
  752. entt::dense_set<int, std::hash<int>, std::equal_to<>, allocator> set{&memory_resource};
  753. set.reserve(1u);
  754. memory_resource.reset();
  755. set.emplace(0);
  756. ASSERT_TRUE(set.get_allocator().resource()->is_equal(memory_resource));
  757. ASSERT_EQ(memory_resource.do_allocate_counter(), 0u);
  758. ASSERT_EQ(memory_resource.do_deallocate_counter(), 0u);
  759. }
  760. TEST(DenseSet, UsesAllocatorConstruction) {
  761. using string_type = typename test::tracked_memory_resource::string_type;
  762. using allocator = std::pmr::polymorphic_allocator<string_type>;
  763. test::tracked_memory_resource memory_resource{};
  764. entt::dense_set<string_type, std::hash<string_type>, std::equal_to<>, allocator> set{&memory_resource};
  765. set.reserve(1u);
  766. memory_resource.reset();
  767. set.emplace(test::tracked_memory_resource::default_value);
  768. ASSERT_TRUE(set.get_allocator().resource()->is_equal(memory_resource));
  769. ASSERT_GT(memory_resource.do_allocate_counter(), 0u);
  770. ASSERT_EQ(memory_resource.do_deallocate_counter(), 0u);
  771. }
  772. #endif