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