xref: /llvm-project/llvm/unittests/ADT/DenseMapTest.cpp (revision 132003603ae3453bc385ffd5ed53f5e8057ae1bc)
1 //===- llvm/unittest/ADT/DenseMapMap.cpp - DenseMap unit tests --*- C++ -*-===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 
9 #include "llvm/ADT/DenseMap.h"
10 #include "llvm/ADT/DenseMapInfo.h"
11 #include "gmock/gmock.h"
12 #include "gtest/gtest.h"
13 #include <map>
14 #include <set>
15 #include <utility>
16 #include <variant>
17 
18 using namespace llvm;
19 
20 namespace {
21 
22 uint32_t getTestKey(int i, uint32_t *) { return i; }
23 uint32_t getTestValue(int i, uint32_t *) { return 42 + i; }
24 
25 uint32_t *getTestKey(int i, uint32_t **) {
26   static uint32_t dummy_arr1[8192];
27   assert(i < 8192 && "Only support 8192 dummy keys.");
28   return &dummy_arr1[i];
29 }
30 uint32_t *getTestValue(int i, uint32_t **) {
31   static uint32_t dummy_arr1[8192];
32   assert(i < 8192 && "Only support 8192 dummy keys.");
33   return &dummy_arr1[i];
34 }
35 
36 /// A test class that tries to check that construction and destruction
37 /// occur correctly.
38 class CtorTester {
39   static std::set<CtorTester *> Constructed;
40   int Value;
41 
42 public:
43   explicit CtorTester(int Value = 0) : Value(Value) {
44     EXPECT_TRUE(Constructed.insert(this).second);
45   }
46   CtorTester(uint32_t Value) : Value(Value) {
47     EXPECT_TRUE(Constructed.insert(this).second);
48   }
49   CtorTester(const CtorTester &Arg) : Value(Arg.Value) {
50     EXPECT_TRUE(Constructed.insert(this).second);
51   }
52   CtorTester &operator=(const CtorTester &) = default;
53   ~CtorTester() {
54     EXPECT_EQ(1u, Constructed.erase(this));
55   }
56   operator uint32_t() const { return Value; }
57 
58   int getValue() const { return Value; }
59   bool operator==(const CtorTester &RHS) const { return Value == RHS.Value; }
60 };
61 
62 std::set<CtorTester *> CtorTester::Constructed;
63 
64 struct CtorTesterMapInfo {
65   static inline CtorTester getEmptyKey() { return CtorTester(-1); }
66   static inline CtorTester getTombstoneKey() { return CtorTester(-2); }
67   static unsigned getHashValue(const CtorTester &Val) {
68     return Val.getValue() * 37u;
69   }
70   static bool isEqual(const CtorTester &LHS, const CtorTester &RHS) {
71     return LHS == RHS;
72   }
73 };
74 
75 CtorTester getTestKey(int i, CtorTester *) { return CtorTester(i); }
76 CtorTester getTestValue(int i, CtorTester *) { return CtorTester(42 + i); }
77 
78 // Test fixture, with helper functions implemented by forwarding to global
79 // function overloads selected by component types of the type parameter. This
80 // allows all of the map implementations to be tested with shared
81 // implementations of helper routines.
82 template <typename T>
83 class DenseMapTest : public ::testing::Test {
84 protected:
85   T Map;
86 
87   static typename T::key_type *const dummy_key_ptr;
88   static typename T::mapped_type *const dummy_value_ptr;
89 
90   typename T::key_type getKey(int i = 0) {
91     return getTestKey(i, dummy_key_ptr);
92   }
93   typename T::mapped_type getValue(int i = 0) {
94     return getTestValue(i, dummy_value_ptr);
95   }
96 };
97 
98 template <typename T>
99 typename T::key_type *const DenseMapTest<T>::dummy_key_ptr = nullptr;
100 template <typename T>
101 typename T::mapped_type *const DenseMapTest<T>::dummy_value_ptr = nullptr;
102 
103 // Register these types for testing.
104 typedef ::testing::Types<DenseMap<uint32_t, uint32_t>,
105                          DenseMap<uint32_t *, uint32_t *>,
106                          DenseMap<CtorTester, CtorTester, CtorTesterMapInfo>,
107                          SmallDenseMap<uint32_t, uint32_t>,
108                          SmallDenseMap<uint32_t *, uint32_t *>,
109                          SmallDenseMap<CtorTester, CtorTester, 4,
110                                        CtorTesterMapInfo>
111                          > DenseMapTestTypes;
112 TYPED_TEST_SUITE(DenseMapTest, DenseMapTestTypes, );
113 
114 // Empty map tests
115 TYPED_TEST(DenseMapTest, EmptyIntMapTest) {
116   // Size tests
117   EXPECT_EQ(0u, this->Map.size());
118   EXPECT_TRUE(this->Map.empty());
119 
120   // Iterator tests
121   EXPECT_TRUE(this->Map.begin() == this->Map.end());
122 
123   // Lookup tests
124   EXPECT_FALSE(this->Map.count(this->getKey()));
125   EXPECT_TRUE(this->Map.find(this->getKey()) == this->Map.end());
126   EXPECT_EQ(typename TypeParam::mapped_type(),
127             this->Map.lookup(this->getKey()));
128 
129   // LookupOrTrap tests
130   EXPECT_DEATH({ this->Map.at(this->getKey()); },
131                "DenseMap::at failed due to a missing key");
132 }
133 
134 // Constant map tests
135 TYPED_TEST(DenseMapTest, ConstEmptyMapTest) {
136   const TypeParam &ConstMap = this->Map;
137   EXPECT_EQ(0u, ConstMap.size());
138   EXPECT_TRUE(ConstMap.empty());
139   EXPECT_TRUE(ConstMap.begin() == ConstMap.end());
140 }
141 
142 // A map with a single entry
143 TYPED_TEST(DenseMapTest, SingleEntryMapTest) {
144   this->Map[this->getKey()] = this->getValue();
145 
146   // Size tests
147   EXPECT_EQ(1u, this->Map.size());
148   EXPECT_FALSE(this->Map.begin() == this->Map.end());
149   EXPECT_FALSE(this->Map.empty());
150 
151   // Iterator tests
152   typename TypeParam::iterator it = this->Map.begin();
153   EXPECT_EQ(this->getKey(), it->first);
154   EXPECT_EQ(this->getValue(), it->second);
155   ++it;
156   EXPECT_TRUE(it == this->Map.end());
157 
158   // Lookup tests
159   EXPECT_TRUE(this->Map.count(this->getKey()));
160   EXPECT_TRUE(this->Map.find(this->getKey()) == this->Map.begin());
161   EXPECT_EQ(this->getValue(), this->Map.lookup(this->getKey()));
162   EXPECT_EQ(this->getValue(), this->Map[this->getKey()]);
163 
164   // LookupOrTrap tests
165   EXPECT_DEATH({ this->Map.at(this->getKey(1)); },
166                "DenseMap::at failed due to a missing key");
167 }
168 
169 // Test clear() method
170 TYPED_TEST(DenseMapTest, ClearTest) {
171   this->Map[this->getKey()] = this->getValue();
172   this->Map.clear();
173 
174   EXPECT_EQ(0u, this->Map.size());
175   EXPECT_TRUE(this->Map.empty());
176   EXPECT_TRUE(this->Map.begin() == this->Map.end());
177 }
178 
179 // Test erase(iterator) method
180 TYPED_TEST(DenseMapTest, EraseTest) {
181   this->Map[this->getKey()] = this->getValue();
182   this->Map.erase(this->Map.begin());
183 
184   EXPECT_EQ(0u, this->Map.size());
185   EXPECT_TRUE(this->Map.empty());
186   EXPECT_TRUE(this->Map.begin() == this->Map.end());
187 }
188 
189 // Test erase(value) method
190 TYPED_TEST(DenseMapTest, EraseTest2) {
191   this->Map[this->getKey()] = this->getValue();
192   this->Map.erase(this->getKey());
193 
194   EXPECT_EQ(0u, this->Map.size());
195   EXPECT_TRUE(this->Map.empty());
196   EXPECT_TRUE(this->Map.begin() == this->Map.end());
197 }
198 
199 // Test insert() method
200 TYPED_TEST(DenseMapTest, InsertTest) {
201   this->Map.insert(std::make_pair(this->getKey(), this->getValue()));
202   EXPECT_EQ(1u, this->Map.size());
203   EXPECT_EQ(this->getValue(), this->Map[this->getKey()]);
204 }
205 
206 // Test copy constructor method
207 TYPED_TEST(DenseMapTest, CopyConstructorTest) {
208   this->Map[this->getKey()] = this->getValue();
209   TypeParam copyMap(this->Map);
210 
211   EXPECT_EQ(1u, copyMap.size());
212   EXPECT_EQ(this->getValue(), copyMap[this->getKey()]);
213 }
214 
215 // Test copy constructor method where SmallDenseMap isn't small.
216 TYPED_TEST(DenseMapTest, CopyConstructorNotSmallTest) {
217   for (int Key = 0; Key < 5; ++Key)
218     this->Map[this->getKey(Key)] = this->getValue(Key);
219   TypeParam copyMap(this->Map);
220 
221   EXPECT_EQ(5u, copyMap.size());
222   for (int Key = 0; Key < 5; ++Key)
223     EXPECT_EQ(this->getValue(Key), copyMap[this->getKey(Key)]);
224 }
225 
226 // Test copying from a default-constructed map.
227 TYPED_TEST(DenseMapTest, CopyConstructorFromDefaultTest) {
228   TypeParam copyMap(this->Map);
229 
230   EXPECT_TRUE(copyMap.empty());
231 }
232 
233 // Test copying from an empty map where SmallDenseMap isn't small.
234 TYPED_TEST(DenseMapTest, CopyConstructorFromEmptyTest) {
235   for (int Key = 0; Key < 5; ++Key)
236     this->Map[this->getKey(Key)] = this->getValue(Key);
237   this->Map.clear();
238   TypeParam copyMap(this->Map);
239 
240   EXPECT_TRUE(copyMap.empty());
241 }
242 
243 // Test assignment operator method
244 TYPED_TEST(DenseMapTest, AssignmentTest) {
245   this->Map[this->getKey()] = this->getValue();
246   TypeParam copyMap = this->Map;
247 
248   EXPECT_EQ(1u, copyMap.size());
249   EXPECT_EQ(this->getValue(), copyMap[this->getKey()]);
250 
251   // test self-assignment.
252   copyMap = static_cast<TypeParam &>(copyMap);
253   EXPECT_EQ(1u, copyMap.size());
254   EXPECT_EQ(this->getValue(), copyMap[this->getKey()]);
255 }
256 
257 TYPED_TEST(DenseMapTest, AssignmentTestNotSmall) {
258   for (int Key = 0; Key < 5; ++Key)
259     this->Map[this->getKey(Key)] = this->getValue(Key);
260   TypeParam copyMap = this->Map;
261 
262   EXPECT_EQ(5u, copyMap.size());
263   for (int Key = 0; Key < 5; ++Key)
264     EXPECT_EQ(this->getValue(Key), copyMap[this->getKey(Key)]);
265 
266   // test self-assignment.
267   copyMap = static_cast<TypeParam &>(copyMap);
268   EXPECT_EQ(5u, copyMap.size());
269   for (int Key = 0; Key < 5; ++Key)
270     EXPECT_EQ(this->getValue(Key), copyMap[this->getKey(Key)]);
271 }
272 
273 // Test swap method
274 TYPED_TEST(DenseMapTest, SwapTest) {
275   this->Map[this->getKey()] = this->getValue();
276   TypeParam otherMap;
277 
278   this->Map.swap(otherMap);
279   EXPECT_EQ(0u, this->Map.size());
280   EXPECT_TRUE(this->Map.empty());
281   EXPECT_EQ(1u, otherMap.size());
282   EXPECT_EQ(this->getValue(), otherMap[this->getKey()]);
283 
284   this->Map.swap(otherMap);
285   EXPECT_EQ(0u, otherMap.size());
286   EXPECT_TRUE(otherMap.empty());
287   EXPECT_EQ(1u, this->Map.size());
288   EXPECT_EQ(this->getValue(), this->Map[this->getKey()]);
289 
290   // Make this more interesting by inserting 100 numbers into the map.
291   for (int i = 0; i < 100; ++i)
292     this->Map[this->getKey(i)] = this->getValue(i);
293 
294   this->Map.swap(otherMap);
295   EXPECT_EQ(0u, this->Map.size());
296   EXPECT_TRUE(this->Map.empty());
297   EXPECT_EQ(100u, otherMap.size());
298   for (int i = 0; i < 100; ++i)
299     EXPECT_EQ(this->getValue(i), otherMap[this->getKey(i)]);
300 
301   this->Map.swap(otherMap);
302   EXPECT_EQ(0u, otherMap.size());
303   EXPECT_TRUE(otherMap.empty());
304   EXPECT_EQ(100u, this->Map.size());
305   for (int i = 0; i < 100; ++i)
306     EXPECT_EQ(this->getValue(i), this->Map[this->getKey(i)]);
307 }
308 
309 // A more complex iteration test
310 TYPED_TEST(DenseMapTest, IterationTest) {
311   bool visited[100];
312   std::map<typename TypeParam::key_type, unsigned> visitedIndex;
313 
314   // Insert 100 numbers into the map
315   for (int i = 0; i < 100; ++i) {
316     visited[i] = false;
317     visitedIndex[this->getKey(i)] = i;
318 
319     this->Map[this->getKey(i)] = this->getValue(i);
320   }
321 
322   // Iterate over all numbers and mark each one found.
323   for (typename TypeParam::iterator it = this->Map.begin();
324        it != this->Map.end(); ++it)
325     visited[visitedIndex[it->first]] = true;
326 
327   // Ensure every number was visited.
328   for (int i = 0; i < 100; ++i)
329     ASSERT_TRUE(visited[i]) << "Entry #" << i << " was never visited";
330 }
331 
332 // const_iterator test
333 TYPED_TEST(DenseMapTest, ConstIteratorTest) {
334   // Check conversion from iterator to const_iterator.
335   typename TypeParam::iterator it = this->Map.begin();
336   typename TypeParam::const_iterator cit(it);
337   EXPECT_TRUE(it == cit);
338 
339   // Check copying of const_iterators.
340   typename TypeParam::const_iterator cit2(cit);
341   EXPECT_TRUE(cit == cit2);
342 }
343 
344 namespace {
345 // Simple class that counts how many moves and copy happens when growing a map
346 struct CountCopyAndMove {
347   static int Move;
348   static int Copy;
349   CountCopyAndMove() {}
350 
351   CountCopyAndMove(const CountCopyAndMove &) { Copy++; }
352   CountCopyAndMove &operator=(const CountCopyAndMove &) {
353     Copy++;
354     return *this;
355   }
356   CountCopyAndMove(CountCopyAndMove &&) { Move++; }
357   CountCopyAndMove &operator=(const CountCopyAndMove &&) {
358     Move++;
359     return *this;
360   }
361 };
362 int CountCopyAndMove::Copy = 0;
363 int CountCopyAndMove::Move = 0;
364 
365 } // anonymous namespace
366 
367 // Test initializer list construction.
368 TEST(DenseMapCustomTest, InitializerList) {
369   DenseMap<int, int> M({{0, 0}, {0, 1}, {1, 2}});
370   EXPECT_EQ(2u, M.size());
371   EXPECT_EQ(1u, M.count(0));
372   EXPECT_EQ(0, M[0]);
373   EXPECT_EQ(1u, M.count(1));
374   EXPECT_EQ(2, M[1]);
375 }
376 
377 // Test initializer list construction.
378 TEST(DenseMapCustomTest, EqualityComparison) {
379   DenseMap<int, int> M1({{0, 0}, {1, 2}});
380   DenseMap<int, int> M2({{0, 0}, {1, 2}});
381   DenseMap<int, int> M3({{0, 0}, {1, 3}});
382 
383   EXPECT_EQ(M1, M2);
384   EXPECT_NE(M1, M3);
385 }
386 
387 // Test for the default minimum size of a DenseMap
388 TEST(DenseMapCustomTest, DefaultMinReservedSizeTest) {
389   // IF THIS VALUE CHANGE, please update InitialSizeTest, InitFromIterator, and
390   // ReserveTest as well!
391   const int ExpectedInitialBucketCount = 64;
392   // Formula from DenseMap::getMinBucketToReserveForEntries()
393   const int ExpectedMaxInitialEntries = ExpectedInitialBucketCount * 3 / 4 - 1;
394 
395   DenseMap<int, CountCopyAndMove> Map;
396   // Will allocate 64 buckets
397   Map.reserve(1);
398   unsigned MemorySize = Map.getMemorySize();
399   CountCopyAndMove::Copy = 0;
400   CountCopyAndMove::Move = 0;
401   for (int i = 0; i < ExpectedMaxInitialEntries; ++i)
402     Map.insert(std::pair<int, CountCopyAndMove>(std::piecewise_construct,
403                                                 std::forward_as_tuple(i),
404                                                 std::forward_as_tuple()));
405   // Check that we didn't grow
406   EXPECT_EQ(MemorySize, Map.getMemorySize());
407   // Check that move was called the expected number of times
408   EXPECT_EQ(ExpectedMaxInitialEntries, CountCopyAndMove::Move);
409   // Check that no copy occurred
410   EXPECT_EQ(0, CountCopyAndMove::Copy);
411 
412   // Adding one extra element should grow the map
413   Map.insert(std::pair<int, CountCopyAndMove>(
414       std::piecewise_construct,
415       std::forward_as_tuple(ExpectedMaxInitialEntries),
416       std::forward_as_tuple()));
417   // Check that we grew
418   EXPECT_NE(MemorySize, Map.getMemorySize());
419   // Check that move was called the expected number of times
420   //  This relies on move-construction elision, and cannot be reliably tested.
421   //   EXPECT_EQ(ExpectedMaxInitialEntries + 2, CountCopyAndMove::Move);
422   // Check that no copy occurred
423   EXPECT_EQ(0, CountCopyAndMove::Copy);
424 }
425 
426 // Make sure creating the map with an initial size of N actually gives us enough
427 // buckets to insert N items without increasing allocation size.
428 TEST(DenseMapCustomTest, InitialSizeTest) {
429   // Test a few different sizes, 48 is *not* a random choice: we need a value
430   // that is 2/3 of a power of two to stress the grow() condition, and the power
431   // of two has to be at least 64 because of minimum size allocation in the
432   // DenseMap (see DefaultMinReservedSizeTest). 66 is a value just above the
433   // 64 default init.
434   for (auto Size : {1, 2, 48, 66}) {
435     DenseMap<int, CountCopyAndMove> Map(Size);
436     unsigned MemorySize = Map.getMemorySize();
437     CountCopyAndMove::Copy = 0;
438     CountCopyAndMove::Move = 0;
439     for (int i = 0; i < Size; ++i)
440       Map.insert(std::pair<int, CountCopyAndMove>(std::piecewise_construct,
441                                                   std::forward_as_tuple(i),
442                                                   std::forward_as_tuple()));
443     // Check that we didn't grow
444     EXPECT_EQ(MemorySize, Map.getMemorySize());
445     // Check that move was called the expected number of times
446     EXPECT_EQ(Size, CountCopyAndMove::Move);
447     // Check that no copy occurred
448     EXPECT_EQ(0, CountCopyAndMove::Copy);
449   }
450 }
451 
452 // Make sure creating the map with a iterator range does not trigger grow()
453 TEST(DenseMapCustomTest, InitFromIterator) {
454   std::vector<std::pair<int, CountCopyAndMove>> Values;
455   // The size is a random value greater than 64 (hardcoded DenseMap min init)
456   const int Count = 65;
457   Values.reserve(Count);
458   for (int i = 0; i < Count; i++)
459     Values.emplace_back(i, CountCopyAndMove());
460 
461   CountCopyAndMove::Move = 0;
462   CountCopyAndMove::Copy = 0;
463   DenseMap<int, CountCopyAndMove> Map(Values.begin(), Values.end());
464   // Check that no move occurred
465   EXPECT_EQ(0, CountCopyAndMove::Move);
466   // Check that copy was called the expected number of times
467   EXPECT_EQ(Count, CountCopyAndMove::Copy);
468 }
469 
470 // Make sure reserve actually gives us enough buckets to insert N items
471 // without increasing allocation size.
472 TEST(DenseMapCustomTest, ReserveTest) {
473   // Test a few different size, 48 is *not* a random choice: we need a value
474   // that is 2/3 of a power of two to stress the grow() condition, and the power
475   // of two has to be at least 64 because of minimum size allocation in the
476   // DenseMap (see DefaultMinReservedSizeTest). 66 is a value just above the
477   // 64 default init.
478   for (auto Size : {1, 2, 48, 66}) {
479     DenseMap<int, CountCopyAndMove> Map;
480     Map.reserve(Size);
481     unsigned MemorySize = Map.getMemorySize();
482     CountCopyAndMove::Copy = 0;
483     CountCopyAndMove::Move = 0;
484     for (int i = 0; i < Size; ++i)
485       Map.insert(std::pair<int, CountCopyAndMove>(std::piecewise_construct,
486                                                   std::forward_as_tuple(i),
487                                                   std::forward_as_tuple()));
488     // Check that we didn't grow
489     EXPECT_EQ(MemorySize, Map.getMemorySize());
490     // Check that move was called the expected number of times
491     EXPECT_EQ(Size, CountCopyAndMove::Move);
492     // Check that no copy occurred
493     EXPECT_EQ(0, CountCopyAndMove::Copy);
494   }
495 }
496 
497 // Make sure DenseMap works with StringRef keys.
498 TEST(DenseMapCustomTest, StringRefTest) {
499   DenseMap<StringRef, int> M;
500 
501   M["a"] = 1;
502   M["b"] = 2;
503   M["c"] = 3;
504 
505   EXPECT_EQ(3u, M.size());
506   EXPECT_EQ(1, M.lookup("a"));
507   EXPECT_EQ(2, M.lookup("b"));
508   EXPECT_EQ(3, M.lookup("c"));
509 
510   EXPECT_EQ(0, M.lookup("q"));
511 
512   // Test the empty string, spelled various ways.
513   EXPECT_EQ(0, M.lookup(""));
514   EXPECT_EQ(0, M.lookup(StringRef()));
515   EXPECT_EQ(0, M.lookup(StringRef("a", 0)));
516   M[""] = 42;
517   EXPECT_EQ(42, M.lookup(""));
518   EXPECT_EQ(42, M.lookup(StringRef()));
519   EXPECT_EQ(42, M.lookup(StringRef("a", 0)));
520 }
521 
522 // Key traits that allows lookup with either an unsigned or char* key;
523 // In the latter case, "a" == 0, "b" == 1 and so on.
524 struct TestDenseMapInfo {
525   static inline unsigned getEmptyKey() { return ~0; }
526   static inline unsigned getTombstoneKey() { return ~0U - 1; }
527   static unsigned getHashValue(const unsigned& Val) { return Val * 37U; }
528   static unsigned getHashValue(const char* Val) {
529     return (unsigned)(Val[0] - 'a') * 37U;
530   }
531   static bool isEqual(const unsigned& LHS, const unsigned& RHS) {
532     return LHS == RHS;
533   }
534   static bool isEqual(const char* LHS, const unsigned& RHS) {
535     return (unsigned)(LHS[0] - 'a') == RHS;
536   }
537 };
538 
539 // find_as() tests
540 TEST(DenseMapCustomTest, FindAsTest) {
541   DenseMap<unsigned, unsigned, TestDenseMapInfo> map;
542   map[0] = 1;
543   map[1] = 2;
544   map[2] = 3;
545 
546   // Size tests
547   EXPECT_EQ(3u, map.size());
548 
549   // Normal lookup tests
550   EXPECT_EQ(1u, map.count(1));
551   EXPECT_EQ(1u, map.find(0)->second);
552   EXPECT_EQ(2u, map.find(1)->second);
553   EXPECT_EQ(3u, map.find(2)->second);
554   EXPECT_TRUE(map.find(3) == map.end());
555 
556   // find_as() tests
557   EXPECT_EQ(1u, map.find_as("a")->second);
558   EXPECT_EQ(2u, map.find_as("b")->second);
559   EXPECT_EQ(3u, map.find_as("c")->second);
560   EXPECT_TRUE(map.find_as("d") == map.end());
561 }
562 
563 TEST(DenseMapCustomTest, SmallDenseMapInitializerList) {
564   SmallDenseMap<int, int> M = {{0, 0}, {0, 1}, {1, 2}};
565   EXPECT_EQ(2u, M.size());
566   EXPECT_EQ(1u, M.count(0));
567   EXPECT_EQ(0, M[0]);
568   EXPECT_EQ(1u, M.count(1));
569   EXPECT_EQ(2, M[1]);
570 }
571 
572 struct ContiguousDenseMapInfo {
573   static inline unsigned getEmptyKey() { return ~0; }
574   static inline unsigned getTombstoneKey() { return ~0U - 1; }
575   static unsigned getHashValue(const unsigned& Val) { return Val; }
576   static bool isEqual(const unsigned& LHS, const unsigned& RHS) {
577     return LHS == RHS;
578   }
579 };
580 
581 // Test that filling a small dense map with exactly the number of elements in
582 // the map grows to have enough space for an empty bucket.
583 TEST(DenseMapCustomTest, SmallDenseMapGrowTest) {
584   SmallDenseMap<unsigned, unsigned, 32, ContiguousDenseMapInfo> map;
585   // Add some number of elements, then delete a few to leave us some tombstones.
586   // If we just filled the map with 32 elements we'd grow because of not enough
587   // tombstones which masks the issue here.
588   for (unsigned i = 0; i < 20; ++i)
589     map[i] = i + 1;
590   for (unsigned i = 0; i < 10; ++i)
591     map.erase(i);
592   for (unsigned i = 20; i < 32; ++i)
593     map[i] = i + 1;
594 
595   // Size tests
596   EXPECT_EQ(22u, map.size());
597 
598   // Try to find an element which doesn't exist.  There was a bug in
599   // SmallDenseMap which led to a map with num elements == small capacity not
600   // having an empty bucket any more.  Finding an element not in the map would
601   // therefore never terminate.
602   EXPECT_TRUE(map.find(32) == map.end());
603 }
604 
605 TEST(DenseMapCustomTest, LargeSmallDenseMapCompaction) {
606   SmallDenseMap<unsigned, unsigned, 128, ContiguousDenseMapInfo> map;
607   // Fill to < 3/4 load.
608   for (unsigned i = 0; i < 95; ++i)
609     map[i] = i;
610   // And erase, leaving behind tombstones.
611   for (unsigned i = 0; i < 95; ++i)
612     map.erase(i);
613   // Fill further, so that less than 1/8 are empty, but still below 3/4 load.
614   for (unsigned i = 95; i < 128; ++i)
615     map[i] = i;
616 
617   EXPECT_EQ(33u, map.size());
618   // Similar to the previous test, check for a non-existing element, as an
619   // indirect check that tombstones have been removed.
620   EXPECT_TRUE(map.find(0) == map.end());
621 }
622 
623 TEST(DenseMapCustomTest, SmallDenseMapWithNumBucketsNonPowerOf2) {
624   // Is not power of 2.
625   const unsigned NumInitBuckets = 33;
626   // Power of 2 less then NumInitBuckets.
627   constexpr unsigned InlineBuckets = 4;
628   // Constructor should not trigger assert.
629   SmallDenseMap<int, int, InlineBuckets> map(NumInitBuckets);
630 }
631 
632 TEST(DenseMapCustomTest, TryEmplaceTest) {
633   DenseMap<int, std::unique_ptr<int>> Map;
634   std::unique_ptr<int> P(new int(2));
635   auto Try1 = Map.try_emplace(0, new int(1));
636   EXPECT_TRUE(Try1.second);
637   auto Try2 = Map.try_emplace(0, std::move(P));
638   EXPECT_FALSE(Try2.second);
639   EXPECT_EQ(Try1.first, Try2.first);
640   EXPECT_NE(nullptr, P);
641 }
642 
643 TEST(DenseMapCustomTest, ConstTest) {
644   // Test that const pointers work okay for count and find, even when the
645   // underlying map is a non-const pointer.
646   DenseMap<int *, int> Map;
647   int A;
648   int *B = &A;
649   const int *C = &A;
650   Map.insert({B, 0});
651   EXPECT_EQ(Map.count(B), 1u);
652   EXPECT_EQ(Map.count(C), 1u);
653   EXPECT_NE(Map.find(B), Map.end());
654   EXPECT_NE(Map.find(C), Map.end());
655 }
656 
657 struct IncompleteStruct;
658 
659 TEST(DenseMapCustomTest, OpaquePointerKey) {
660   // Test that we can use a pointer to an incomplete type as a DenseMap key.
661   // This is an important build time optimization, since many classes have
662   // DenseMap members.
663   DenseMap<IncompleteStruct *, int> Map;
664   int Keys[3] = {0, 0, 0};
665   IncompleteStruct *K1 = reinterpret_cast<IncompleteStruct *>(&Keys[0]);
666   IncompleteStruct *K2 = reinterpret_cast<IncompleteStruct *>(&Keys[1]);
667   IncompleteStruct *K3 = reinterpret_cast<IncompleteStruct *>(&Keys[2]);
668   Map.insert({K1, 1});
669   Map.insert({K2, 2});
670   Map.insert({K3, 3});
671   EXPECT_EQ(Map.count(K1), 1u);
672   EXPECT_EQ(Map[K1], 1);
673   EXPECT_EQ(Map[K2], 2);
674   EXPECT_EQ(Map[K3], 3);
675   Map.clear();
676   EXPECT_EQ(Map.find(K1), Map.end());
677   EXPECT_EQ(Map.find(K2), Map.end());
678   EXPECT_EQ(Map.find(K3), Map.end());
679 }
680 } // namespace
681 
682 namespace {
683 struct A {
684   A(int value) : value(value) {}
685   int value;
686 };
687 struct B : public A {
688   using A::A;
689 };
690 } // namespace
691 
692 namespace llvm {
693 template <typename T>
694 struct DenseMapInfo<T, std::enable_if_t<std::is_base_of_v<A, T>>> {
695   static inline T getEmptyKey() { return {static_cast<int>(~0)}; }
696   static inline T getTombstoneKey() { return {static_cast<int>(~0U - 1)}; }
697   static unsigned getHashValue(const T &Val) { return Val.value; }
698   static bool isEqual(const T &LHS, const T &RHS) {
699     return LHS.value == RHS.value;
700   }
701 };
702 } // namespace llvm
703 
704 namespace {
705 TEST(DenseMapCustomTest, SFINAEMapInfo) {
706   // Test that we can use a pointer to an incomplete type as a DenseMap key.
707   // This is an important build time optimization, since many classes have
708   // DenseMap members.
709   DenseMap<B, int> Map;
710   B Keys[3] = {{0}, {1}, {2}};
711   Map.insert({Keys[0], 1});
712   Map.insert({Keys[1], 2});
713   Map.insert({Keys[2], 3});
714   EXPECT_EQ(Map.count(Keys[0]), 1u);
715   EXPECT_EQ(Map[Keys[0]], 1);
716   EXPECT_EQ(Map[Keys[1]], 2);
717   EXPECT_EQ(Map[Keys[2]], 3);
718   Map.clear();
719   EXPECT_EQ(Map.find(Keys[0]), Map.end());
720   EXPECT_EQ(Map.find(Keys[1]), Map.end());
721   EXPECT_EQ(Map.find(Keys[2]), Map.end());
722 }
723 
724 TEST(DenseMapCustomTest, VariantSupport) {
725   using variant = std::variant<int, int>;
726   DenseMap<variant, int> Map;
727   variant Keys[] = {
728       variant(std::in_place_index<0>, 1),
729       variant(std::in_place_index<1>, 1),
730   };
731   Map.try_emplace(Keys[0], 0);
732   Map.try_emplace(Keys[1], 1);
733   EXPECT_THAT(Map, testing::SizeIs(2));
734   EXPECT_NE(DenseMapInfo<variant>::getHashValue(Keys[0]),
735             DenseMapInfo<variant>::getHashValue(Keys[1]));
736 }
737 } // namespace
738