dense_set.cpp 31 KB

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