xref: /aosp_15_r20/external/llvm/unittests/ADT/DenseMapTest.cpp (revision 9880d6810fe72a1726cb53787c6711e909410d58)
1*9880d681SAndroid Build Coastguard Worker //===- llvm/unittest/ADT/DenseMapMap.cpp - DenseMap unit tests --*- C++ -*-===//
2*9880d681SAndroid Build Coastguard Worker //
3*9880d681SAndroid Build Coastguard Worker //                     The LLVM Compiler Infrastructure
4*9880d681SAndroid Build Coastguard Worker //
5*9880d681SAndroid Build Coastguard Worker // This file is distributed under the University of Illinois Open Source
6*9880d681SAndroid Build Coastguard Worker // License. See LICENSE.TXT for details.
7*9880d681SAndroid Build Coastguard Worker //
8*9880d681SAndroid Build Coastguard Worker //===----------------------------------------------------------------------===//
9*9880d681SAndroid Build Coastguard Worker 
10*9880d681SAndroid Build Coastguard Worker #include "gtest/gtest.h"
11*9880d681SAndroid Build Coastguard Worker #include "llvm/ADT/DenseMap.h"
12*9880d681SAndroid Build Coastguard Worker #include <map>
13*9880d681SAndroid Build Coastguard Worker #include <set>
14*9880d681SAndroid Build Coastguard Worker 
15*9880d681SAndroid Build Coastguard Worker using namespace llvm;
16*9880d681SAndroid Build Coastguard Worker 
17*9880d681SAndroid Build Coastguard Worker namespace {
18*9880d681SAndroid Build Coastguard Worker 
getTestKey(int i,uint32_t *)19*9880d681SAndroid Build Coastguard Worker uint32_t getTestKey(int i, uint32_t *) { return i; }
getTestValue(int i,uint32_t *)20*9880d681SAndroid Build Coastguard Worker uint32_t getTestValue(int i, uint32_t *) { return 42 + i; }
21*9880d681SAndroid Build Coastguard Worker 
getTestKey(int i,uint32_t **)22*9880d681SAndroid Build Coastguard Worker uint32_t *getTestKey(int i, uint32_t **) {
23*9880d681SAndroid Build Coastguard Worker   static uint32_t dummy_arr1[8192];
24*9880d681SAndroid Build Coastguard Worker   assert(i < 8192 && "Only support 8192 dummy keys.");
25*9880d681SAndroid Build Coastguard Worker   return &dummy_arr1[i];
26*9880d681SAndroid Build Coastguard Worker }
getTestValue(int i,uint32_t **)27*9880d681SAndroid Build Coastguard Worker uint32_t *getTestValue(int i, uint32_t **) {
28*9880d681SAndroid Build Coastguard Worker   static uint32_t dummy_arr1[8192];
29*9880d681SAndroid Build Coastguard Worker   assert(i < 8192 && "Only support 8192 dummy keys.");
30*9880d681SAndroid Build Coastguard Worker   return &dummy_arr1[i];
31*9880d681SAndroid Build Coastguard Worker }
32*9880d681SAndroid Build Coastguard Worker 
33*9880d681SAndroid Build Coastguard Worker /// \brief A test class that tries to check that construction and destruction
34*9880d681SAndroid Build Coastguard Worker /// occur correctly.
35*9880d681SAndroid Build Coastguard Worker class CtorTester {
36*9880d681SAndroid Build Coastguard Worker   static std::set<CtorTester *> Constructed;
37*9880d681SAndroid Build Coastguard Worker   int Value;
38*9880d681SAndroid Build Coastguard Worker 
39*9880d681SAndroid Build Coastguard Worker public:
CtorTester(int Value=0)40*9880d681SAndroid Build Coastguard Worker   explicit CtorTester(int Value = 0) : Value(Value) {
41*9880d681SAndroid Build Coastguard Worker     EXPECT_TRUE(Constructed.insert(this).second);
42*9880d681SAndroid Build Coastguard Worker   }
CtorTester(uint32_t Value)43*9880d681SAndroid Build Coastguard Worker   CtorTester(uint32_t Value) : Value(Value) {
44*9880d681SAndroid Build Coastguard Worker     EXPECT_TRUE(Constructed.insert(this).second);
45*9880d681SAndroid Build Coastguard Worker   }
CtorTester(const CtorTester & Arg)46*9880d681SAndroid Build Coastguard Worker   CtorTester(const CtorTester &Arg) : Value(Arg.Value) {
47*9880d681SAndroid Build Coastguard Worker     EXPECT_TRUE(Constructed.insert(this).second);
48*9880d681SAndroid Build Coastguard Worker   }
49*9880d681SAndroid Build Coastguard Worker   CtorTester &operator=(const CtorTester &) = default;
~CtorTester()50*9880d681SAndroid Build Coastguard Worker   ~CtorTester() {
51*9880d681SAndroid Build Coastguard Worker     EXPECT_EQ(1u, Constructed.erase(this));
52*9880d681SAndroid Build Coastguard Worker   }
operator uint32_t() const53*9880d681SAndroid Build Coastguard Worker   operator uint32_t() const { return Value; }
54*9880d681SAndroid Build Coastguard Worker 
getValue() const55*9880d681SAndroid Build Coastguard Worker   int getValue() const { return Value; }
operator ==(const CtorTester & RHS) const56*9880d681SAndroid Build Coastguard Worker   bool operator==(const CtorTester &RHS) const { return Value == RHS.Value; }
57*9880d681SAndroid Build Coastguard Worker };
58*9880d681SAndroid Build Coastguard Worker 
59*9880d681SAndroid Build Coastguard Worker std::set<CtorTester *> CtorTester::Constructed;
60*9880d681SAndroid Build Coastguard Worker 
61*9880d681SAndroid Build Coastguard Worker struct CtorTesterMapInfo {
getEmptyKey__anon91ff75790111::CtorTesterMapInfo62*9880d681SAndroid Build Coastguard Worker   static inline CtorTester getEmptyKey() { return CtorTester(-1); }
getTombstoneKey__anon91ff75790111::CtorTesterMapInfo63*9880d681SAndroid Build Coastguard Worker   static inline CtorTester getTombstoneKey() { return CtorTester(-2); }
getHashValue__anon91ff75790111::CtorTesterMapInfo64*9880d681SAndroid Build Coastguard Worker   static unsigned getHashValue(const CtorTester &Val) {
65*9880d681SAndroid Build Coastguard Worker     return Val.getValue() * 37u;
66*9880d681SAndroid Build Coastguard Worker   }
isEqual__anon91ff75790111::CtorTesterMapInfo67*9880d681SAndroid Build Coastguard Worker   static bool isEqual(const CtorTester &LHS, const CtorTester &RHS) {
68*9880d681SAndroid Build Coastguard Worker     return LHS == RHS;
69*9880d681SAndroid Build Coastguard Worker   }
70*9880d681SAndroid Build Coastguard Worker };
71*9880d681SAndroid Build Coastguard Worker 
getTestKey(int i,CtorTester *)72*9880d681SAndroid Build Coastguard Worker CtorTester getTestKey(int i, CtorTester *) { return CtorTester(i); }
getTestValue(int i,CtorTester *)73*9880d681SAndroid Build Coastguard Worker CtorTester getTestValue(int i, CtorTester *) { return CtorTester(42 + i); }
74*9880d681SAndroid Build Coastguard Worker 
75*9880d681SAndroid Build Coastguard Worker // Test fixture, with helper functions implemented by forwarding to global
76*9880d681SAndroid Build Coastguard Worker // function overloads selected by component types of the type parameter. This
77*9880d681SAndroid Build Coastguard Worker // allows all of the map implementations to be tested with shared
78*9880d681SAndroid Build Coastguard Worker // implementations of helper routines.
79*9880d681SAndroid Build Coastguard Worker template <typename T>
80*9880d681SAndroid Build Coastguard Worker class DenseMapTest : public ::testing::Test {
81*9880d681SAndroid Build Coastguard Worker protected:
82*9880d681SAndroid Build Coastguard Worker   T Map;
83*9880d681SAndroid Build Coastguard Worker 
84*9880d681SAndroid Build Coastguard Worker   static typename T::key_type *const dummy_key_ptr;
85*9880d681SAndroid Build Coastguard Worker   static typename T::mapped_type *const dummy_value_ptr;
86*9880d681SAndroid Build Coastguard Worker 
getKey(int i=0)87*9880d681SAndroid Build Coastguard Worker   typename T::key_type getKey(int i = 0) {
88*9880d681SAndroid Build Coastguard Worker     return getTestKey(i, dummy_key_ptr);
89*9880d681SAndroid Build Coastguard Worker   }
getValue(int i=0)90*9880d681SAndroid Build Coastguard Worker   typename T::mapped_type getValue(int i = 0) {
91*9880d681SAndroid Build Coastguard Worker     return getTestValue(i, dummy_value_ptr);
92*9880d681SAndroid Build Coastguard Worker   }
93*9880d681SAndroid Build Coastguard Worker };
94*9880d681SAndroid Build Coastguard Worker 
95*9880d681SAndroid Build Coastguard Worker template <typename T>
96*9880d681SAndroid Build Coastguard Worker typename T::key_type *const DenseMapTest<T>::dummy_key_ptr = nullptr;
97*9880d681SAndroid Build Coastguard Worker template <typename T>
98*9880d681SAndroid Build Coastguard Worker typename T::mapped_type *const DenseMapTest<T>::dummy_value_ptr = nullptr;
99*9880d681SAndroid Build Coastguard Worker 
100*9880d681SAndroid Build Coastguard Worker // Register these types for testing.
101*9880d681SAndroid Build Coastguard Worker typedef ::testing::Types<DenseMap<uint32_t, uint32_t>,
102*9880d681SAndroid Build Coastguard Worker                          DenseMap<uint32_t *, uint32_t *>,
103*9880d681SAndroid Build Coastguard Worker                          DenseMap<CtorTester, CtorTester, CtorTesterMapInfo>,
104*9880d681SAndroid Build Coastguard Worker                          SmallDenseMap<uint32_t, uint32_t>,
105*9880d681SAndroid Build Coastguard Worker                          SmallDenseMap<uint32_t *, uint32_t *>,
106*9880d681SAndroid Build Coastguard Worker                          SmallDenseMap<CtorTester, CtorTester, 4,
107*9880d681SAndroid Build Coastguard Worker                                        CtorTesterMapInfo>
108*9880d681SAndroid Build Coastguard Worker                          > DenseMapTestTypes;
109*9880d681SAndroid Build Coastguard Worker TYPED_TEST_CASE(DenseMapTest, DenseMapTestTypes);
110*9880d681SAndroid Build Coastguard Worker 
111*9880d681SAndroid Build Coastguard Worker // Empty map tests
TYPED_TEST(DenseMapTest,EmptyIntMapTest)112*9880d681SAndroid Build Coastguard Worker TYPED_TEST(DenseMapTest, EmptyIntMapTest) {
113*9880d681SAndroid Build Coastguard Worker   // Size tests
114*9880d681SAndroid Build Coastguard Worker   EXPECT_EQ(0u, this->Map.size());
115*9880d681SAndroid Build Coastguard Worker   EXPECT_TRUE(this->Map.empty());
116*9880d681SAndroid Build Coastguard Worker 
117*9880d681SAndroid Build Coastguard Worker   // Iterator tests
118*9880d681SAndroid Build Coastguard Worker   EXPECT_TRUE(this->Map.begin() == this->Map.end());
119*9880d681SAndroid Build Coastguard Worker 
120*9880d681SAndroid Build Coastguard Worker   // Lookup tests
121*9880d681SAndroid Build Coastguard Worker   EXPECT_FALSE(this->Map.count(this->getKey()));
122*9880d681SAndroid Build Coastguard Worker   EXPECT_TRUE(this->Map.find(this->getKey()) == this->Map.end());
123*9880d681SAndroid Build Coastguard Worker #if !defined(_MSC_VER) || defined(__clang__)
124*9880d681SAndroid Build Coastguard Worker   EXPECT_EQ(typename TypeParam::mapped_type(),
125*9880d681SAndroid Build Coastguard Worker             this->Map.lookup(this->getKey()));
126*9880d681SAndroid Build Coastguard Worker #else
127*9880d681SAndroid Build Coastguard Worker   // MSVC, at least old versions, cannot parse the typename to disambiguate
128*9880d681SAndroid Build Coastguard Worker   // TypeParam::mapped_type as a type. However, because MSVC doesn't implement
129*9880d681SAndroid Build Coastguard Worker   // two-phase name lookup, it also doesn't require the typename. Deal with
130*9880d681SAndroid Build Coastguard Worker   // this mutual incompatibility through specialized code.
131*9880d681SAndroid Build Coastguard Worker   EXPECT_EQ(TypeParam::mapped_type(),
132*9880d681SAndroid Build Coastguard Worker             this->Map.lookup(this->getKey()));
133*9880d681SAndroid Build Coastguard Worker #endif
134*9880d681SAndroid Build Coastguard Worker }
135*9880d681SAndroid Build Coastguard Worker 
136*9880d681SAndroid Build Coastguard Worker // Constant map tests
TYPED_TEST(DenseMapTest,ConstEmptyMapTest)137*9880d681SAndroid Build Coastguard Worker TYPED_TEST(DenseMapTest, ConstEmptyMapTest) {
138*9880d681SAndroid Build Coastguard Worker   const TypeParam &ConstMap = this->Map;
139*9880d681SAndroid Build Coastguard Worker   EXPECT_EQ(0u, ConstMap.size());
140*9880d681SAndroid Build Coastguard Worker   EXPECT_TRUE(ConstMap.empty());
141*9880d681SAndroid Build Coastguard Worker   EXPECT_TRUE(ConstMap.begin() == ConstMap.end());
142*9880d681SAndroid Build Coastguard Worker }
143*9880d681SAndroid Build Coastguard Worker 
144*9880d681SAndroid Build Coastguard Worker // A map with a single entry
TYPED_TEST(DenseMapTest,SingleEntryMapTest)145*9880d681SAndroid Build Coastguard Worker TYPED_TEST(DenseMapTest, SingleEntryMapTest) {
146*9880d681SAndroid Build Coastguard Worker   this->Map[this->getKey()] = this->getValue();
147*9880d681SAndroid Build Coastguard Worker 
148*9880d681SAndroid Build Coastguard Worker   // Size tests
149*9880d681SAndroid Build Coastguard Worker   EXPECT_EQ(1u, this->Map.size());
150*9880d681SAndroid Build Coastguard Worker   EXPECT_FALSE(this->Map.begin() == this->Map.end());
151*9880d681SAndroid Build Coastguard Worker   EXPECT_FALSE(this->Map.empty());
152*9880d681SAndroid Build Coastguard Worker 
153*9880d681SAndroid Build Coastguard Worker   // Iterator tests
154*9880d681SAndroid Build Coastguard Worker   typename TypeParam::iterator it = this->Map.begin();
155*9880d681SAndroid Build Coastguard Worker   EXPECT_EQ(this->getKey(), it->first);
156*9880d681SAndroid Build Coastguard Worker   EXPECT_EQ(this->getValue(), it->second);
157*9880d681SAndroid Build Coastguard Worker   ++it;
158*9880d681SAndroid Build Coastguard Worker   EXPECT_TRUE(it == this->Map.end());
159*9880d681SAndroid Build Coastguard Worker 
160*9880d681SAndroid Build Coastguard Worker   // Lookup tests
161*9880d681SAndroid Build Coastguard Worker   EXPECT_TRUE(this->Map.count(this->getKey()));
162*9880d681SAndroid Build Coastguard Worker   EXPECT_TRUE(this->Map.find(this->getKey()) == this->Map.begin());
163*9880d681SAndroid Build Coastguard Worker   EXPECT_EQ(this->getValue(), this->Map.lookup(this->getKey()));
164*9880d681SAndroid Build Coastguard Worker   EXPECT_EQ(this->getValue(), this->Map[this->getKey()]);
165*9880d681SAndroid Build Coastguard Worker }
166*9880d681SAndroid Build Coastguard Worker 
167*9880d681SAndroid Build Coastguard Worker // Test clear() method
TYPED_TEST(DenseMapTest,ClearTest)168*9880d681SAndroid Build Coastguard Worker TYPED_TEST(DenseMapTest, ClearTest) {
169*9880d681SAndroid Build Coastguard Worker   this->Map[this->getKey()] = this->getValue();
170*9880d681SAndroid Build Coastguard Worker   this->Map.clear();
171*9880d681SAndroid Build Coastguard Worker 
172*9880d681SAndroid Build Coastguard Worker   EXPECT_EQ(0u, this->Map.size());
173*9880d681SAndroid Build Coastguard Worker   EXPECT_TRUE(this->Map.empty());
174*9880d681SAndroid Build Coastguard Worker   EXPECT_TRUE(this->Map.begin() == this->Map.end());
175*9880d681SAndroid Build Coastguard Worker }
176*9880d681SAndroid Build Coastguard Worker 
177*9880d681SAndroid Build Coastguard Worker // Test erase(iterator) method
TYPED_TEST(DenseMapTest,EraseTest)178*9880d681SAndroid Build Coastguard Worker TYPED_TEST(DenseMapTest, EraseTest) {
179*9880d681SAndroid Build Coastguard Worker   this->Map[this->getKey()] = this->getValue();
180*9880d681SAndroid Build Coastguard Worker   this->Map.erase(this->Map.begin());
181*9880d681SAndroid Build Coastguard Worker 
182*9880d681SAndroid Build Coastguard Worker   EXPECT_EQ(0u, this->Map.size());
183*9880d681SAndroid Build Coastguard Worker   EXPECT_TRUE(this->Map.empty());
184*9880d681SAndroid Build Coastguard Worker   EXPECT_TRUE(this->Map.begin() == this->Map.end());
185*9880d681SAndroid Build Coastguard Worker }
186*9880d681SAndroid Build Coastguard Worker 
187*9880d681SAndroid Build Coastguard Worker // Test erase(value) method
TYPED_TEST(DenseMapTest,EraseTest2)188*9880d681SAndroid Build Coastguard Worker TYPED_TEST(DenseMapTest, EraseTest2) {
189*9880d681SAndroid Build Coastguard Worker   this->Map[this->getKey()] = this->getValue();
190*9880d681SAndroid Build Coastguard Worker   this->Map.erase(this->getKey());
191*9880d681SAndroid Build Coastguard Worker 
192*9880d681SAndroid Build Coastguard Worker   EXPECT_EQ(0u, this->Map.size());
193*9880d681SAndroid Build Coastguard Worker   EXPECT_TRUE(this->Map.empty());
194*9880d681SAndroid Build Coastguard Worker   EXPECT_TRUE(this->Map.begin() == this->Map.end());
195*9880d681SAndroid Build Coastguard Worker }
196*9880d681SAndroid Build Coastguard Worker 
197*9880d681SAndroid Build Coastguard Worker // Test insert() method
TYPED_TEST(DenseMapTest,InsertTest)198*9880d681SAndroid Build Coastguard Worker TYPED_TEST(DenseMapTest, InsertTest) {
199*9880d681SAndroid Build Coastguard Worker   this->Map.insert(std::make_pair(this->getKey(), this->getValue()));
200*9880d681SAndroid Build Coastguard Worker   EXPECT_EQ(1u, this->Map.size());
201*9880d681SAndroid Build Coastguard Worker   EXPECT_EQ(this->getValue(), this->Map[this->getKey()]);
202*9880d681SAndroid Build Coastguard Worker }
203*9880d681SAndroid Build Coastguard Worker 
204*9880d681SAndroid Build Coastguard Worker // Test copy constructor method
TYPED_TEST(DenseMapTest,CopyConstructorTest)205*9880d681SAndroid Build Coastguard Worker TYPED_TEST(DenseMapTest, CopyConstructorTest) {
206*9880d681SAndroid Build Coastguard Worker   this->Map[this->getKey()] = this->getValue();
207*9880d681SAndroid Build Coastguard Worker   TypeParam copyMap(this->Map);
208*9880d681SAndroid Build Coastguard Worker 
209*9880d681SAndroid Build Coastguard Worker   EXPECT_EQ(1u, copyMap.size());
210*9880d681SAndroid Build Coastguard Worker   EXPECT_EQ(this->getValue(), copyMap[this->getKey()]);
211*9880d681SAndroid Build Coastguard Worker }
212*9880d681SAndroid Build Coastguard Worker 
213*9880d681SAndroid Build Coastguard Worker // Test copy constructor method where SmallDenseMap isn't small.
TYPED_TEST(DenseMapTest,CopyConstructorNotSmallTest)214*9880d681SAndroid Build Coastguard Worker TYPED_TEST(DenseMapTest, CopyConstructorNotSmallTest) {
215*9880d681SAndroid Build Coastguard Worker   for (int Key = 0; Key < 5; ++Key)
216*9880d681SAndroid Build Coastguard Worker     this->Map[this->getKey(Key)] = this->getValue(Key);
217*9880d681SAndroid Build Coastguard Worker   TypeParam copyMap(this->Map);
218*9880d681SAndroid Build Coastguard Worker 
219*9880d681SAndroid Build Coastguard Worker   EXPECT_EQ(5u, copyMap.size());
220*9880d681SAndroid Build Coastguard Worker   for (int Key = 0; Key < 5; ++Key)
221*9880d681SAndroid Build Coastguard Worker     EXPECT_EQ(this->getValue(Key), copyMap[this->getKey(Key)]);
222*9880d681SAndroid Build Coastguard Worker }
223*9880d681SAndroid Build Coastguard Worker 
224*9880d681SAndroid Build Coastguard Worker // Test copying from a default-constructed map.
TYPED_TEST(DenseMapTest,CopyConstructorFromDefaultTest)225*9880d681SAndroid Build Coastguard Worker TYPED_TEST(DenseMapTest, CopyConstructorFromDefaultTest) {
226*9880d681SAndroid Build Coastguard Worker   TypeParam copyMap(this->Map);
227*9880d681SAndroid Build Coastguard Worker 
228*9880d681SAndroid Build Coastguard Worker   EXPECT_TRUE(copyMap.empty());
229*9880d681SAndroid Build Coastguard Worker }
230*9880d681SAndroid Build Coastguard Worker 
231*9880d681SAndroid Build Coastguard Worker // Test copying from an empty map where SmallDenseMap isn't small.
TYPED_TEST(DenseMapTest,CopyConstructorFromEmptyTest)232*9880d681SAndroid Build Coastguard Worker TYPED_TEST(DenseMapTest, CopyConstructorFromEmptyTest) {
233*9880d681SAndroid Build Coastguard Worker   for (int Key = 0; Key < 5; ++Key)
234*9880d681SAndroid Build Coastguard Worker     this->Map[this->getKey(Key)] = this->getValue(Key);
235*9880d681SAndroid Build Coastguard Worker   this->Map.clear();
236*9880d681SAndroid Build Coastguard Worker   TypeParam copyMap(this->Map);
237*9880d681SAndroid Build Coastguard Worker 
238*9880d681SAndroid Build Coastguard Worker   EXPECT_TRUE(copyMap.empty());
239*9880d681SAndroid Build Coastguard Worker }
240*9880d681SAndroid Build Coastguard Worker 
241*9880d681SAndroid Build Coastguard Worker // Test assignment operator method
TYPED_TEST(DenseMapTest,AssignmentTest)242*9880d681SAndroid Build Coastguard Worker TYPED_TEST(DenseMapTest, AssignmentTest) {
243*9880d681SAndroid Build Coastguard Worker   this->Map[this->getKey()] = this->getValue();
244*9880d681SAndroid Build Coastguard Worker   TypeParam copyMap = this->Map;
245*9880d681SAndroid Build Coastguard Worker 
246*9880d681SAndroid Build Coastguard Worker   EXPECT_EQ(1u, copyMap.size());
247*9880d681SAndroid Build Coastguard Worker   EXPECT_EQ(this->getValue(), copyMap[this->getKey()]);
248*9880d681SAndroid Build Coastguard Worker 
249*9880d681SAndroid Build Coastguard Worker   // test self-assignment.
250*9880d681SAndroid Build Coastguard Worker   copyMap = copyMap;
251*9880d681SAndroid Build Coastguard Worker   EXPECT_EQ(1u, copyMap.size());
252*9880d681SAndroid Build Coastguard Worker   EXPECT_EQ(this->getValue(), copyMap[this->getKey()]);
253*9880d681SAndroid Build Coastguard Worker }
254*9880d681SAndroid Build Coastguard Worker 
TYPED_TEST(DenseMapTest,AssignmentTestNotSmall)255*9880d681SAndroid Build Coastguard Worker TYPED_TEST(DenseMapTest, AssignmentTestNotSmall) {
256*9880d681SAndroid Build Coastguard Worker   for (int Key = 0; Key < 5; ++Key)
257*9880d681SAndroid Build Coastguard Worker     this->Map[this->getKey(Key)] = this->getValue(Key);
258*9880d681SAndroid Build Coastguard Worker   TypeParam copyMap = this->Map;
259*9880d681SAndroid Build Coastguard Worker 
260*9880d681SAndroid Build Coastguard Worker   EXPECT_EQ(5u, copyMap.size());
261*9880d681SAndroid Build Coastguard Worker   for (int Key = 0; Key < 5; ++Key)
262*9880d681SAndroid Build Coastguard Worker     EXPECT_EQ(this->getValue(Key), copyMap[this->getKey(Key)]);
263*9880d681SAndroid Build Coastguard Worker 
264*9880d681SAndroid Build Coastguard Worker   // test self-assignment.
265*9880d681SAndroid Build Coastguard Worker   copyMap = copyMap;
266*9880d681SAndroid Build Coastguard Worker   EXPECT_EQ(5u, copyMap.size());
267*9880d681SAndroid Build Coastguard Worker   for (int Key = 0; Key < 5; ++Key)
268*9880d681SAndroid Build Coastguard Worker     EXPECT_EQ(this->getValue(Key), copyMap[this->getKey(Key)]);
269*9880d681SAndroid Build Coastguard Worker }
270*9880d681SAndroid Build Coastguard Worker 
271*9880d681SAndroid Build Coastguard Worker // Test swap method
TYPED_TEST(DenseMapTest,SwapTest)272*9880d681SAndroid Build Coastguard Worker TYPED_TEST(DenseMapTest, SwapTest) {
273*9880d681SAndroid Build Coastguard Worker   this->Map[this->getKey()] = this->getValue();
274*9880d681SAndroid Build Coastguard Worker   TypeParam otherMap;
275*9880d681SAndroid Build Coastguard Worker 
276*9880d681SAndroid Build Coastguard Worker   this->Map.swap(otherMap);
277*9880d681SAndroid Build Coastguard Worker   EXPECT_EQ(0u, this->Map.size());
278*9880d681SAndroid Build Coastguard Worker   EXPECT_TRUE(this->Map.empty());
279*9880d681SAndroid Build Coastguard Worker   EXPECT_EQ(1u, otherMap.size());
280*9880d681SAndroid Build Coastguard Worker   EXPECT_EQ(this->getValue(), otherMap[this->getKey()]);
281*9880d681SAndroid Build Coastguard Worker 
282*9880d681SAndroid Build Coastguard Worker   this->Map.swap(otherMap);
283*9880d681SAndroid Build Coastguard Worker   EXPECT_EQ(0u, otherMap.size());
284*9880d681SAndroid Build Coastguard Worker   EXPECT_TRUE(otherMap.empty());
285*9880d681SAndroid Build Coastguard Worker   EXPECT_EQ(1u, this->Map.size());
286*9880d681SAndroid Build Coastguard Worker   EXPECT_EQ(this->getValue(), this->Map[this->getKey()]);
287*9880d681SAndroid Build Coastguard Worker 
288*9880d681SAndroid Build Coastguard Worker   // Make this more interesting by inserting 100 numbers into the map.
289*9880d681SAndroid Build Coastguard Worker   for (int i = 0; i < 100; ++i)
290*9880d681SAndroid Build Coastguard Worker     this->Map[this->getKey(i)] = this->getValue(i);
291*9880d681SAndroid Build Coastguard Worker 
292*9880d681SAndroid Build Coastguard Worker   this->Map.swap(otherMap);
293*9880d681SAndroid Build Coastguard Worker   EXPECT_EQ(0u, this->Map.size());
294*9880d681SAndroid Build Coastguard Worker   EXPECT_TRUE(this->Map.empty());
295*9880d681SAndroid Build Coastguard Worker   EXPECT_EQ(100u, otherMap.size());
296*9880d681SAndroid Build Coastguard Worker   for (int i = 0; i < 100; ++i)
297*9880d681SAndroid Build Coastguard Worker     EXPECT_EQ(this->getValue(i), otherMap[this->getKey(i)]);
298*9880d681SAndroid Build Coastguard Worker 
299*9880d681SAndroid Build Coastguard Worker   this->Map.swap(otherMap);
300*9880d681SAndroid Build Coastguard Worker   EXPECT_EQ(0u, otherMap.size());
301*9880d681SAndroid Build Coastguard Worker   EXPECT_TRUE(otherMap.empty());
302*9880d681SAndroid Build Coastguard Worker   EXPECT_EQ(100u, this->Map.size());
303*9880d681SAndroid Build Coastguard Worker   for (int i = 0; i < 100; ++i)
304*9880d681SAndroid Build Coastguard Worker     EXPECT_EQ(this->getValue(i), this->Map[this->getKey(i)]);
305*9880d681SAndroid Build Coastguard Worker }
306*9880d681SAndroid Build Coastguard Worker 
307*9880d681SAndroid Build Coastguard Worker // A more complex iteration test
TYPED_TEST(DenseMapTest,IterationTest)308*9880d681SAndroid Build Coastguard Worker TYPED_TEST(DenseMapTest, IterationTest) {
309*9880d681SAndroid Build Coastguard Worker   bool visited[100];
310*9880d681SAndroid Build Coastguard Worker   std::map<typename TypeParam::key_type, unsigned> visitedIndex;
311*9880d681SAndroid Build Coastguard Worker 
312*9880d681SAndroid Build Coastguard Worker   // Insert 100 numbers into the map
313*9880d681SAndroid Build Coastguard Worker   for (int i = 0; i < 100; ++i) {
314*9880d681SAndroid Build Coastguard Worker     visited[i] = false;
315*9880d681SAndroid Build Coastguard Worker     visitedIndex[this->getKey(i)] = i;
316*9880d681SAndroid Build Coastguard Worker 
317*9880d681SAndroid Build Coastguard Worker     this->Map[this->getKey(i)] = this->getValue(i);
318*9880d681SAndroid Build Coastguard Worker   }
319*9880d681SAndroid Build Coastguard Worker 
320*9880d681SAndroid Build Coastguard Worker   // Iterate over all numbers and mark each one found.
321*9880d681SAndroid Build Coastguard Worker   for (typename TypeParam::iterator it = this->Map.begin();
322*9880d681SAndroid Build Coastguard Worker        it != this->Map.end(); ++it)
323*9880d681SAndroid Build Coastguard Worker     visited[visitedIndex[it->first]] = true;
324*9880d681SAndroid Build Coastguard Worker 
325*9880d681SAndroid Build Coastguard Worker   // Ensure every number was visited.
326*9880d681SAndroid Build Coastguard Worker   for (int i = 0; i < 100; ++i)
327*9880d681SAndroid Build Coastguard Worker     ASSERT_TRUE(visited[i]) << "Entry #" << i << " was never visited";
328*9880d681SAndroid Build Coastguard Worker }
329*9880d681SAndroid Build Coastguard Worker 
330*9880d681SAndroid Build Coastguard Worker // const_iterator test
TYPED_TEST(DenseMapTest,ConstIteratorTest)331*9880d681SAndroid Build Coastguard Worker TYPED_TEST(DenseMapTest, ConstIteratorTest) {
332*9880d681SAndroid Build Coastguard Worker   // Check conversion from iterator to const_iterator.
333*9880d681SAndroid Build Coastguard Worker   typename TypeParam::iterator it = this->Map.begin();
334*9880d681SAndroid Build Coastguard Worker   typename TypeParam::const_iterator cit(it);
335*9880d681SAndroid Build Coastguard Worker   EXPECT_TRUE(it == cit);
336*9880d681SAndroid Build Coastguard Worker 
337*9880d681SAndroid Build Coastguard Worker   // Check copying of const_iterators.
338*9880d681SAndroid Build Coastguard Worker   typename TypeParam::const_iterator cit2(cit);
339*9880d681SAndroid Build Coastguard Worker   EXPECT_TRUE(cit == cit2);
340*9880d681SAndroid Build Coastguard Worker }
341*9880d681SAndroid Build Coastguard Worker 
342*9880d681SAndroid Build Coastguard Worker namespace {
343*9880d681SAndroid Build Coastguard Worker // Simple class that counts how many moves and copy happens when growing a map
344*9880d681SAndroid Build Coastguard Worker struct CountCopyAndMove {
345*9880d681SAndroid Build Coastguard Worker   static int Move;
346*9880d681SAndroid Build Coastguard Worker   static int Copy;
CountCopyAndMove__anon91ff75790111::__anon91ff75790211::CountCopyAndMove347*9880d681SAndroid Build Coastguard Worker   CountCopyAndMove() {}
348*9880d681SAndroid Build Coastguard Worker 
CountCopyAndMove__anon91ff75790111::__anon91ff75790211::CountCopyAndMove349*9880d681SAndroid Build Coastguard Worker   CountCopyAndMove(const CountCopyAndMove &) { Copy++; }
operator =__anon91ff75790111::__anon91ff75790211::CountCopyAndMove350*9880d681SAndroid Build Coastguard Worker   CountCopyAndMove &operator=(const CountCopyAndMove &) {
351*9880d681SAndroid Build Coastguard Worker     Copy++;
352*9880d681SAndroid Build Coastguard Worker     return *this;
353*9880d681SAndroid Build Coastguard Worker   }
CountCopyAndMove__anon91ff75790111::__anon91ff75790211::CountCopyAndMove354*9880d681SAndroid Build Coastguard Worker   CountCopyAndMove(CountCopyAndMove &&) { Move++; }
operator =__anon91ff75790111::__anon91ff75790211::CountCopyAndMove355*9880d681SAndroid Build Coastguard Worker   CountCopyAndMove &operator=(const CountCopyAndMove &&) {
356*9880d681SAndroid Build Coastguard Worker     Move++;
357*9880d681SAndroid Build Coastguard Worker     return *this;
358*9880d681SAndroid Build Coastguard Worker   }
359*9880d681SAndroid Build Coastguard Worker };
360*9880d681SAndroid Build Coastguard Worker int CountCopyAndMove::Copy = 0;
361*9880d681SAndroid Build Coastguard Worker int CountCopyAndMove::Move = 0;
362*9880d681SAndroid Build Coastguard Worker 
363*9880d681SAndroid Build Coastguard Worker } // anonymous namespace
364*9880d681SAndroid Build Coastguard Worker 
365*9880d681SAndroid Build Coastguard Worker // Test for the default minimum size of a DenseMap
TEST(DenseMapCustomTest,DefaultMinReservedSizeTest)366*9880d681SAndroid Build Coastguard Worker TEST(DenseMapCustomTest, DefaultMinReservedSizeTest) {
367*9880d681SAndroid Build Coastguard Worker   // IF THIS VALUE CHANGE, please update InitialSizeTest, InitFromIterator, and
368*9880d681SAndroid Build Coastguard Worker   // ReserveTest as well!
369*9880d681SAndroid Build Coastguard Worker   const int ExpectedInitialBucketCount = 64;
370*9880d681SAndroid Build Coastguard Worker   // Formula from DenseMap::getMinBucketToReserveForEntries()
371*9880d681SAndroid Build Coastguard Worker   const int ExpectedMaxInitialEntries = ExpectedInitialBucketCount * 3 / 4 - 1;
372*9880d681SAndroid Build Coastguard Worker 
373*9880d681SAndroid Build Coastguard Worker   DenseMap<int, CountCopyAndMove> Map;
374*9880d681SAndroid Build Coastguard Worker   // Will allocate 64 buckets
375*9880d681SAndroid Build Coastguard Worker   Map.reserve(1);
376*9880d681SAndroid Build Coastguard Worker   unsigned MemorySize = Map.getMemorySize();
377*9880d681SAndroid Build Coastguard Worker   CountCopyAndMove::Copy = 0;
378*9880d681SAndroid Build Coastguard Worker   CountCopyAndMove::Move = 0;
379*9880d681SAndroid Build Coastguard Worker   for (int i = 0; i < ExpectedMaxInitialEntries; ++i)
380*9880d681SAndroid Build Coastguard Worker     Map.insert(std::pair<int, CountCopyAndMove>(std::piecewise_construct,
381*9880d681SAndroid Build Coastguard Worker                                                 std::forward_as_tuple(i),
382*9880d681SAndroid Build Coastguard Worker                                                 std::forward_as_tuple()));
383*9880d681SAndroid Build Coastguard Worker   // Check that we didn't grow
384*9880d681SAndroid Build Coastguard Worker   EXPECT_EQ(MemorySize, Map.getMemorySize());
385*9880d681SAndroid Build Coastguard Worker   // Check that move was called the expected number of times
386*9880d681SAndroid Build Coastguard Worker   EXPECT_EQ(ExpectedMaxInitialEntries, CountCopyAndMove::Move);
387*9880d681SAndroid Build Coastguard Worker   // Check that no copy occured
388*9880d681SAndroid Build Coastguard Worker   EXPECT_EQ(0, CountCopyAndMove::Copy);
389*9880d681SAndroid Build Coastguard Worker 
390*9880d681SAndroid Build Coastguard Worker   // Adding one extra element should grow the map
391*9880d681SAndroid Build Coastguard Worker   Map.insert(std::pair<int, CountCopyAndMove>(
392*9880d681SAndroid Build Coastguard Worker       std::piecewise_construct,
393*9880d681SAndroid Build Coastguard Worker       std::forward_as_tuple(ExpectedMaxInitialEntries),
394*9880d681SAndroid Build Coastguard Worker       std::forward_as_tuple()));
395*9880d681SAndroid Build Coastguard Worker   // Check that we grew
396*9880d681SAndroid Build Coastguard Worker   EXPECT_NE(MemorySize, Map.getMemorySize());
397*9880d681SAndroid Build Coastguard Worker   // Check that move was called the expected number of times
398*9880d681SAndroid Build Coastguard Worker   //  This relies on move-construction elision, and cannot be reliably tested.
399*9880d681SAndroid Build Coastguard Worker   //   EXPECT_EQ(ExpectedMaxInitialEntries + 2, CountCopyAndMove::Move);
400*9880d681SAndroid Build Coastguard Worker   // Check that no copy occured
401*9880d681SAndroid Build Coastguard Worker   EXPECT_EQ(0, CountCopyAndMove::Copy);
402*9880d681SAndroid Build Coastguard Worker }
403*9880d681SAndroid Build Coastguard Worker 
404*9880d681SAndroid Build Coastguard Worker // Make sure creating the map with an initial size of N actually gives us enough
405*9880d681SAndroid Build Coastguard Worker // buckets to insert N items without increasing allocation size.
TEST(DenseMapCustomTest,InitialSizeTest)406*9880d681SAndroid Build Coastguard Worker TEST(DenseMapCustomTest, InitialSizeTest) {
407*9880d681SAndroid Build Coastguard Worker   // Test a few different sizes, 48 is *not* a random choice: we need a value
408*9880d681SAndroid Build Coastguard Worker   // that is 2/3 of a power of two to stress the grow() condition, and the power
409*9880d681SAndroid Build Coastguard Worker   // of two has to be at least 64 because of minimum size allocation in the
410*9880d681SAndroid Build Coastguard Worker   // DenseMap (see DefaultMinReservedSizeTest). 66 is a value just above the
411*9880d681SAndroid Build Coastguard Worker   // 64 default init.
412*9880d681SAndroid Build Coastguard Worker   for (auto Size : {1, 2, 48, 66}) {
413*9880d681SAndroid Build Coastguard Worker     DenseMap<int, CountCopyAndMove> Map(Size);
414*9880d681SAndroid Build Coastguard Worker     unsigned MemorySize = Map.getMemorySize();
415*9880d681SAndroid Build Coastguard Worker     CountCopyAndMove::Copy = 0;
416*9880d681SAndroid Build Coastguard Worker     CountCopyAndMove::Move = 0;
417*9880d681SAndroid Build Coastguard Worker     for (int i = 0; i < Size; ++i)
418*9880d681SAndroid Build Coastguard Worker       Map.insert(std::pair<int, CountCopyAndMove>(std::piecewise_construct,
419*9880d681SAndroid Build Coastguard Worker                                                   std::forward_as_tuple(i),
420*9880d681SAndroid Build Coastguard Worker                                                   std::forward_as_tuple()));
421*9880d681SAndroid Build Coastguard Worker     // Check that we didn't grow
422*9880d681SAndroid Build Coastguard Worker     EXPECT_EQ(MemorySize, Map.getMemorySize());
423*9880d681SAndroid Build Coastguard Worker     // Check that move was called the expected number of times
424*9880d681SAndroid Build Coastguard Worker     EXPECT_EQ(Size, CountCopyAndMove::Move);
425*9880d681SAndroid Build Coastguard Worker     // Check that no copy occured
426*9880d681SAndroid Build Coastguard Worker     EXPECT_EQ(0, CountCopyAndMove::Copy);
427*9880d681SAndroid Build Coastguard Worker   }
428*9880d681SAndroid Build Coastguard Worker }
429*9880d681SAndroid Build Coastguard Worker 
430*9880d681SAndroid Build Coastguard Worker // Make sure creating the map with a iterator range does not trigger grow()
TEST(DenseMapCustomTest,InitFromIterator)431*9880d681SAndroid Build Coastguard Worker TEST(DenseMapCustomTest, InitFromIterator) {
432*9880d681SAndroid Build Coastguard Worker   std::vector<std::pair<int, CountCopyAndMove>> Values;
433*9880d681SAndroid Build Coastguard Worker   // The size is a random value greater than 64 (hardcoded DenseMap min init)
434*9880d681SAndroid Build Coastguard Worker   const int Count = 65;
435*9880d681SAndroid Build Coastguard Worker   for (int i = 0; i < Count; i++)
436*9880d681SAndroid Build Coastguard Worker     Values.emplace_back(i, CountCopyAndMove());
437*9880d681SAndroid Build Coastguard Worker 
438*9880d681SAndroid Build Coastguard Worker   CountCopyAndMove::Move = 0;
439*9880d681SAndroid Build Coastguard Worker   CountCopyAndMove::Copy = 0;
440*9880d681SAndroid Build Coastguard Worker   DenseMap<int, CountCopyAndMove> Map(Values.begin(), Values.end());
441*9880d681SAndroid Build Coastguard Worker   // Check that no move occured
442*9880d681SAndroid Build Coastguard Worker   EXPECT_EQ(0, CountCopyAndMove::Move);
443*9880d681SAndroid Build Coastguard Worker   // Check that copy was called the expected number of times
444*9880d681SAndroid Build Coastguard Worker   EXPECT_EQ(Count, CountCopyAndMove::Copy);
445*9880d681SAndroid Build Coastguard Worker }
446*9880d681SAndroid Build Coastguard Worker 
447*9880d681SAndroid Build Coastguard Worker // Make sure reserve actually gives us enough buckets to insert N items
448*9880d681SAndroid Build Coastguard Worker // without increasing allocation size.
TEST(DenseMapCustomTest,ReserveTest)449*9880d681SAndroid Build Coastguard Worker TEST(DenseMapCustomTest, ReserveTest) {
450*9880d681SAndroid Build Coastguard Worker   // Test a few different size, 48 is *not* a random choice: we need a value
451*9880d681SAndroid Build Coastguard Worker   // that is 2/3 of a power of two to stress the grow() condition, and the power
452*9880d681SAndroid Build Coastguard Worker   // of two has to be at least 64 because of minimum size allocation in the
453*9880d681SAndroid Build Coastguard Worker   // DenseMap (see DefaultMinReservedSizeTest). 66 is a value just above the
454*9880d681SAndroid Build Coastguard Worker   // 64 default init.
455*9880d681SAndroid Build Coastguard Worker   for (auto Size : {1, 2, 48, 66}) {
456*9880d681SAndroid Build Coastguard Worker     DenseMap<int, CountCopyAndMove> Map;
457*9880d681SAndroid Build Coastguard Worker     Map.reserve(Size);
458*9880d681SAndroid Build Coastguard Worker     unsigned MemorySize = Map.getMemorySize();
459*9880d681SAndroid Build Coastguard Worker     CountCopyAndMove::Copy = 0;
460*9880d681SAndroid Build Coastguard Worker     CountCopyAndMove::Move = 0;
461*9880d681SAndroid Build Coastguard Worker     for (int i = 0; i < Size; ++i)
462*9880d681SAndroid Build Coastguard Worker       Map.insert(std::pair<int, CountCopyAndMove>(std::piecewise_construct,
463*9880d681SAndroid Build Coastguard Worker                                                   std::forward_as_tuple(i),
464*9880d681SAndroid Build Coastguard Worker                                                   std::forward_as_tuple()));
465*9880d681SAndroid Build Coastguard Worker     // Check that we didn't grow
466*9880d681SAndroid Build Coastguard Worker     EXPECT_EQ(MemorySize, Map.getMemorySize());
467*9880d681SAndroid Build Coastguard Worker     // Check that move was called the expected number of times
468*9880d681SAndroid Build Coastguard Worker     EXPECT_EQ(Size, CountCopyAndMove::Move);
469*9880d681SAndroid Build Coastguard Worker     // Check that no copy occured
470*9880d681SAndroid Build Coastguard Worker     EXPECT_EQ(0, CountCopyAndMove::Copy);
471*9880d681SAndroid Build Coastguard Worker   }
472*9880d681SAndroid Build Coastguard Worker }
473*9880d681SAndroid Build Coastguard Worker 
474*9880d681SAndroid Build Coastguard Worker // Make sure DenseMap works with StringRef keys.
TEST(DenseMapCustomTest,StringRefTest)475*9880d681SAndroid Build Coastguard Worker TEST(DenseMapCustomTest, StringRefTest) {
476*9880d681SAndroid Build Coastguard Worker   DenseMap<StringRef, int> M;
477*9880d681SAndroid Build Coastguard Worker 
478*9880d681SAndroid Build Coastguard Worker   M["a"] = 1;
479*9880d681SAndroid Build Coastguard Worker   M["b"] = 2;
480*9880d681SAndroid Build Coastguard Worker   M["c"] = 3;
481*9880d681SAndroid Build Coastguard Worker 
482*9880d681SAndroid Build Coastguard Worker   EXPECT_EQ(3u, M.size());
483*9880d681SAndroid Build Coastguard Worker   EXPECT_EQ(1, M.lookup("a"));
484*9880d681SAndroid Build Coastguard Worker   EXPECT_EQ(2, M.lookup("b"));
485*9880d681SAndroid Build Coastguard Worker   EXPECT_EQ(3, M.lookup("c"));
486*9880d681SAndroid Build Coastguard Worker 
487*9880d681SAndroid Build Coastguard Worker   EXPECT_EQ(0, M.lookup("q"));
488*9880d681SAndroid Build Coastguard Worker 
489*9880d681SAndroid Build Coastguard Worker   // Test the empty string, spelled various ways.
490*9880d681SAndroid Build Coastguard Worker   EXPECT_EQ(0, M.lookup(""));
491*9880d681SAndroid Build Coastguard Worker   EXPECT_EQ(0, M.lookup(StringRef()));
492*9880d681SAndroid Build Coastguard Worker   EXPECT_EQ(0, M.lookup(StringRef("a", 0)));
493*9880d681SAndroid Build Coastguard Worker   M[""] = 42;
494*9880d681SAndroid Build Coastguard Worker   EXPECT_EQ(42, M.lookup(""));
495*9880d681SAndroid Build Coastguard Worker   EXPECT_EQ(42, M.lookup(StringRef()));
496*9880d681SAndroid Build Coastguard Worker   EXPECT_EQ(42, M.lookup(StringRef("a", 0)));
497*9880d681SAndroid Build Coastguard Worker }
498*9880d681SAndroid Build Coastguard Worker 
499*9880d681SAndroid Build Coastguard Worker struct CachedHashTest {
500*9880d681SAndroid Build Coastguard Worker   unsigned Val;
501*9880d681SAndroid Build Coastguard Worker   unsigned *Counter = nullptr;
CachedHashTest__anon91ff75790111::CachedHashTest502*9880d681SAndroid Build Coastguard Worker   CachedHashTest(unsigned Val) : Val(Val) {}
CachedHashTest__anon91ff75790111::CachedHashTest503*9880d681SAndroid Build Coastguard Worker   CachedHashTest(unsigned Val, unsigned *Counter)
504*9880d681SAndroid Build Coastguard Worker       : Val(Val), Counter(Counter) {}
505*9880d681SAndroid Build Coastguard Worker };
506*9880d681SAndroid Build Coastguard Worker }
507*9880d681SAndroid Build Coastguard Worker namespace llvm {
508*9880d681SAndroid Build Coastguard Worker template <> struct DenseMapInfo<CachedHashTest> {
getEmptyKeyllvm::DenseMapInfo509*9880d681SAndroid Build Coastguard Worker   static CachedHashTest getEmptyKey() { return ~0; }
getTombstoneKeyllvm::DenseMapInfo510*9880d681SAndroid Build Coastguard Worker   static CachedHashTest getTombstoneKey() { return ~0U - 1; }
getHashValuellvm::DenseMapInfo511*9880d681SAndroid Build Coastguard Worker   static unsigned getHashValue(const CachedHashTest &X) {
512*9880d681SAndroid Build Coastguard Worker     ++*X.Counter;
513*9880d681SAndroid Build Coastguard Worker     return X.Val;
514*9880d681SAndroid Build Coastguard Worker   }
isEqualllvm::DenseMapInfo515*9880d681SAndroid Build Coastguard Worker   static bool isEqual(const CachedHashTest &LHS, const CachedHashTest &RHS) {
516*9880d681SAndroid Build Coastguard Worker     return LHS.Val == RHS.Val;
517*9880d681SAndroid Build Coastguard Worker   }
518*9880d681SAndroid Build Coastguard Worker };
519*9880d681SAndroid Build Coastguard Worker }
520*9880d681SAndroid Build Coastguard Worker namespace {
521*9880d681SAndroid Build Coastguard Worker 
TEST(DenseMapCustomTest,CachedHashTest)522*9880d681SAndroid Build Coastguard Worker TEST(DenseMapCustomTest, CachedHashTest) {
523*9880d681SAndroid Build Coastguard Worker   unsigned Counter = 0;
524*9880d681SAndroid Build Coastguard Worker   CachedHashTest Val(0, &Counter);
525*9880d681SAndroid Build Coastguard Worker   DenseMap<CachedHashTest, int> Map;
526*9880d681SAndroid Build Coastguard Worker 
527*9880d681SAndroid Build Coastguard Worker   Map[Val] = 0;
528*9880d681SAndroid Build Coastguard Worker   ASSERT_EQ(1u, Counter);
529*9880d681SAndroid Build Coastguard Worker 
530*9880d681SAndroid Build Coastguard Worker   Map.reserve(64);
531*9880d681SAndroid Build Coastguard Worker   ASSERT_EQ(2u, Counter);
532*9880d681SAndroid Build Coastguard Worker }
533*9880d681SAndroid Build Coastguard Worker 
534*9880d681SAndroid Build Coastguard Worker // Like above, but now cache the hash.
TEST(DenseMapCustomTest,CachedHashTest2)535*9880d681SAndroid Build Coastguard Worker TEST(DenseMapCustomTest, CachedHashTest2) {
536*9880d681SAndroid Build Coastguard Worker   unsigned Counter = 0;
537*9880d681SAndroid Build Coastguard Worker   CachedHashTest Val(0, &Counter);
538*9880d681SAndroid Build Coastguard Worker   typedef CachedHash<CachedHashTest> Cached;
539*9880d681SAndroid Build Coastguard Worker   DenseMap<Cached, int> Map;
540*9880d681SAndroid Build Coastguard Worker 
541*9880d681SAndroid Build Coastguard Worker   Map[Val] = 0;
542*9880d681SAndroid Build Coastguard Worker   ASSERT_EQ(1u, Counter);
543*9880d681SAndroid Build Coastguard Worker 
544*9880d681SAndroid Build Coastguard Worker   Map.reserve(64);
545*9880d681SAndroid Build Coastguard Worker   ASSERT_EQ(1u, Counter);
546*9880d681SAndroid Build Coastguard Worker }
547*9880d681SAndroid Build Coastguard Worker 
548*9880d681SAndroid Build Coastguard Worker // Key traits that allows lookup with either an unsigned or char* key;
549*9880d681SAndroid Build Coastguard Worker // In the latter case, "a" == 0, "b" == 1 and so on.
550*9880d681SAndroid Build Coastguard Worker struct TestDenseMapInfo {
getEmptyKey__anon91ff75790311::TestDenseMapInfo551*9880d681SAndroid Build Coastguard Worker   static inline unsigned getEmptyKey() { return ~0; }
getTombstoneKey__anon91ff75790311::TestDenseMapInfo552*9880d681SAndroid Build Coastguard Worker   static inline unsigned getTombstoneKey() { return ~0U - 1; }
getHashValue__anon91ff75790311::TestDenseMapInfo553*9880d681SAndroid Build Coastguard Worker   static unsigned getHashValue(const unsigned& Val) { return Val * 37U; }
getHashValue__anon91ff75790311::TestDenseMapInfo554*9880d681SAndroid Build Coastguard Worker   static unsigned getHashValue(const char* Val) {
555*9880d681SAndroid Build Coastguard Worker     return (unsigned)(Val[0] - 'a') * 37U;
556*9880d681SAndroid Build Coastguard Worker   }
isEqual__anon91ff75790311::TestDenseMapInfo557*9880d681SAndroid Build Coastguard Worker   static bool isEqual(const unsigned& LHS, const unsigned& RHS) {
558*9880d681SAndroid Build Coastguard Worker     return LHS == RHS;
559*9880d681SAndroid Build Coastguard Worker   }
isEqual__anon91ff75790311::TestDenseMapInfo560*9880d681SAndroid Build Coastguard Worker   static bool isEqual(const char* LHS, const unsigned& RHS) {
561*9880d681SAndroid Build Coastguard Worker     return (unsigned)(LHS[0] - 'a') == RHS;
562*9880d681SAndroid Build Coastguard Worker   }
563*9880d681SAndroid Build Coastguard Worker };
564*9880d681SAndroid Build Coastguard Worker 
565*9880d681SAndroid Build Coastguard Worker // find_as() tests
TEST(DenseMapCustomTest,FindAsTest)566*9880d681SAndroid Build Coastguard Worker TEST(DenseMapCustomTest, FindAsTest) {
567*9880d681SAndroid Build Coastguard Worker   DenseMap<unsigned, unsigned, TestDenseMapInfo> map;
568*9880d681SAndroid Build Coastguard Worker   map[0] = 1;
569*9880d681SAndroid Build Coastguard Worker   map[1] = 2;
570*9880d681SAndroid Build Coastguard Worker   map[2] = 3;
571*9880d681SAndroid Build Coastguard Worker 
572*9880d681SAndroid Build Coastguard Worker   // Size tests
573*9880d681SAndroid Build Coastguard Worker   EXPECT_EQ(3u, map.size());
574*9880d681SAndroid Build Coastguard Worker 
575*9880d681SAndroid Build Coastguard Worker   // Normal lookup tests
576*9880d681SAndroid Build Coastguard Worker   EXPECT_EQ(1u, map.count(1));
577*9880d681SAndroid Build Coastguard Worker   EXPECT_EQ(1u, map.find(0)->second);
578*9880d681SAndroid Build Coastguard Worker   EXPECT_EQ(2u, map.find(1)->second);
579*9880d681SAndroid Build Coastguard Worker   EXPECT_EQ(3u, map.find(2)->second);
580*9880d681SAndroid Build Coastguard Worker   EXPECT_TRUE(map.find(3) == map.end());
581*9880d681SAndroid Build Coastguard Worker 
582*9880d681SAndroid Build Coastguard Worker   // find_as() tests
583*9880d681SAndroid Build Coastguard Worker   EXPECT_EQ(1u, map.find_as("a")->second);
584*9880d681SAndroid Build Coastguard Worker   EXPECT_EQ(2u, map.find_as("b")->second);
585*9880d681SAndroid Build Coastguard Worker   EXPECT_EQ(3u, map.find_as("c")->second);
586*9880d681SAndroid Build Coastguard Worker   EXPECT_TRUE(map.find_as("d") == map.end());
587*9880d681SAndroid Build Coastguard Worker }
588*9880d681SAndroid Build Coastguard Worker 
589*9880d681SAndroid Build Coastguard Worker struct ContiguousDenseMapInfo {
getEmptyKey__anon91ff75790311::ContiguousDenseMapInfo590*9880d681SAndroid Build Coastguard Worker   static inline unsigned getEmptyKey() { return ~0; }
getTombstoneKey__anon91ff75790311::ContiguousDenseMapInfo591*9880d681SAndroid Build Coastguard Worker   static inline unsigned getTombstoneKey() { return ~0U - 1; }
getHashValue__anon91ff75790311::ContiguousDenseMapInfo592*9880d681SAndroid Build Coastguard Worker   static unsigned getHashValue(const unsigned& Val) { return Val; }
isEqual__anon91ff75790311::ContiguousDenseMapInfo593*9880d681SAndroid Build Coastguard Worker   static bool isEqual(const unsigned& LHS, const unsigned& RHS) {
594*9880d681SAndroid Build Coastguard Worker     return LHS == RHS;
595*9880d681SAndroid Build Coastguard Worker   }
596*9880d681SAndroid Build Coastguard Worker };
597*9880d681SAndroid Build Coastguard Worker 
598*9880d681SAndroid Build Coastguard Worker // Test that filling a small dense map with exactly the number of elements in
599*9880d681SAndroid Build Coastguard Worker // the map grows to have enough space for an empty bucket.
TEST(DenseMapCustomTest,SmallDenseMapGrowTest)600*9880d681SAndroid Build Coastguard Worker TEST(DenseMapCustomTest, SmallDenseMapGrowTest) {
601*9880d681SAndroid Build Coastguard Worker   SmallDenseMap<unsigned, unsigned, 32, ContiguousDenseMapInfo> map;
602*9880d681SAndroid Build Coastguard Worker   // Add some number of elements, then delete a few to leave us some tombstones.
603*9880d681SAndroid Build Coastguard Worker   // If we just filled the map with 32 elements we'd grow because of not enough
604*9880d681SAndroid Build Coastguard Worker   // tombstones which masks the issue here.
605*9880d681SAndroid Build Coastguard Worker   for (unsigned i = 0; i < 20; ++i)
606*9880d681SAndroid Build Coastguard Worker     map[i] = i + 1;
607*9880d681SAndroid Build Coastguard Worker   for (unsigned i = 0; i < 10; ++i)
608*9880d681SAndroid Build Coastguard Worker     map.erase(i);
609*9880d681SAndroid Build Coastguard Worker   for (unsigned i = 20; i < 32; ++i)
610*9880d681SAndroid Build Coastguard Worker     map[i] = i + 1;
611*9880d681SAndroid Build Coastguard Worker 
612*9880d681SAndroid Build Coastguard Worker   // Size tests
613*9880d681SAndroid Build Coastguard Worker   EXPECT_EQ(22u, map.size());
614*9880d681SAndroid Build Coastguard Worker 
615*9880d681SAndroid Build Coastguard Worker   // Try to find an element which doesn't exist.  There was a bug in
616*9880d681SAndroid Build Coastguard Worker   // SmallDenseMap which led to a map with num elements == small capacity not
617*9880d681SAndroid Build Coastguard Worker   // having an empty bucket any more.  Finding an element not in the map would
618*9880d681SAndroid Build Coastguard Worker   // therefore never terminate.
619*9880d681SAndroid Build Coastguard Worker   EXPECT_TRUE(map.find(32) == map.end());
620*9880d681SAndroid Build Coastguard Worker }
621*9880d681SAndroid Build Coastguard Worker 
622*9880d681SAndroid Build Coastguard Worker }
623