xref: /aosp_15_r20/external/llvm/unittests/ADT/StringMapTest.cpp (revision 9880d6810fe72a1726cb53787c6711e909410d58)
1*9880d681SAndroid Build Coastguard Worker //===- llvm/unittest/ADT/StringMapMap.cpp - StringMap unit tests ----------===//
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 "llvm/ADT/StringMap.h"
11*9880d681SAndroid Build Coastguard Worker #include "llvm/ADT/Twine.h"
12*9880d681SAndroid Build Coastguard Worker #include "llvm/Support/DataTypes.h"
13*9880d681SAndroid Build Coastguard Worker #include "gtest/gtest.h"
14*9880d681SAndroid Build Coastguard Worker #include <tuple>
15*9880d681SAndroid Build Coastguard Worker using namespace llvm;
16*9880d681SAndroid Build Coastguard Worker 
17*9880d681SAndroid Build Coastguard Worker namespace {
18*9880d681SAndroid Build Coastguard Worker 
19*9880d681SAndroid Build Coastguard Worker // Test fixture
20*9880d681SAndroid Build Coastguard Worker class StringMapTest : public testing::Test {
21*9880d681SAndroid Build Coastguard Worker protected:
22*9880d681SAndroid Build Coastguard Worker   StringMap<uint32_t> testMap;
23*9880d681SAndroid Build Coastguard Worker 
24*9880d681SAndroid Build Coastguard Worker   static const char testKey[];
25*9880d681SAndroid Build Coastguard Worker   static const uint32_t testValue;
26*9880d681SAndroid Build Coastguard Worker   static const char* testKeyFirst;
27*9880d681SAndroid Build Coastguard Worker   static size_t testKeyLength;
28*9880d681SAndroid Build Coastguard Worker   static const std::string testKeyStr;
29*9880d681SAndroid Build Coastguard Worker 
assertEmptyMap()30*9880d681SAndroid Build Coastguard Worker   void assertEmptyMap() {
31*9880d681SAndroid Build Coastguard Worker     // Size tests
32*9880d681SAndroid Build Coastguard Worker     EXPECT_EQ(0u, testMap.size());
33*9880d681SAndroid Build Coastguard Worker     EXPECT_TRUE(testMap.empty());
34*9880d681SAndroid Build Coastguard Worker 
35*9880d681SAndroid Build Coastguard Worker     // Iterator tests
36*9880d681SAndroid Build Coastguard Worker     EXPECT_TRUE(testMap.begin() == testMap.end());
37*9880d681SAndroid Build Coastguard Worker 
38*9880d681SAndroid Build Coastguard Worker     // Lookup tests
39*9880d681SAndroid Build Coastguard Worker     EXPECT_EQ(0u, testMap.count(testKey));
40*9880d681SAndroid Build Coastguard Worker     EXPECT_EQ(0u, testMap.count(StringRef(testKeyFirst, testKeyLength)));
41*9880d681SAndroid Build Coastguard Worker     EXPECT_EQ(0u, testMap.count(testKeyStr));
42*9880d681SAndroid Build Coastguard Worker     EXPECT_TRUE(testMap.find(testKey) == testMap.end());
43*9880d681SAndroid Build Coastguard Worker     EXPECT_TRUE(testMap.find(StringRef(testKeyFirst, testKeyLength)) ==
44*9880d681SAndroid Build Coastguard Worker                 testMap.end());
45*9880d681SAndroid Build Coastguard Worker     EXPECT_TRUE(testMap.find(testKeyStr) == testMap.end());
46*9880d681SAndroid Build Coastguard Worker   }
47*9880d681SAndroid Build Coastguard Worker 
assertSingleItemMap()48*9880d681SAndroid Build Coastguard Worker   void assertSingleItemMap() {
49*9880d681SAndroid Build Coastguard Worker     // Size tests
50*9880d681SAndroid Build Coastguard Worker     EXPECT_EQ(1u, testMap.size());
51*9880d681SAndroid Build Coastguard Worker     EXPECT_FALSE(testMap.begin() == testMap.end());
52*9880d681SAndroid Build Coastguard Worker     EXPECT_FALSE(testMap.empty());
53*9880d681SAndroid Build Coastguard Worker 
54*9880d681SAndroid Build Coastguard Worker     // Iterator tests
55*9880d681SAndroid Build Coastguard Worker     StringMap<uint32_t>::iterator it = testMap.begin();
56*9880d681SAndroid Build Coastguard Worker     EXPECT_STREQ(testKey, it->first().data());
57*9880d681SAndroid Build Coastguard Worker     EXPECT_EQ(testValue, it->second);
58*9880d681SAndroid Build Coastguard Worker     ++it;
59*9880d681SAndroid Build Coastguard Worker     EXPECT_TRUE(it == testMap.end());
60*9880d681SAndroid Build Coastguard Worker 
61*9880d681SAndroid Build Coastguard Worker     // Lookup tests
62*9880d681SAndroid Build Coastguard Worker     EXPECT_EQ(1u, testMap.count(testKey));
63*9880d681SAndroid Build Coastguard Worker     EXPECT_EQ(1u, testMap.count(StringRef(testKeyFirst, testKeyLength)));
64*9880d681SAndroid Build Coastguard Worker     EXPECT_EQ(1u, testMap.count(testKeyStr));
65*9880d681SAndroid Build Coastguard Worker     EXPECT_TRUE(testMap.find(testKey) == testMap.begin());
66*9880d681SAndroid Build Coastguard Worker     EXPECT_TRUE(testMap.find(StringRef(testKeyFirst, testKeyLength)) ==
67*9880d681SAndroid Build Coastguard Worker                 testMap.begin());
68*9880d681SAndroid Build Coastguard Worker     EXPECT_TRUE(testMap.find(testKeyStr) == testMap.begin());
69*9880d681SAndroid Build Coastguard Worker   }
70*9880d681SAndroid Build Coastguard Worker };
71*9880d681SAndroid Build Coastguard Worker 
72*9880d681SAndroid Build Coastguard Worker const char StringMapTest::testKey[] = "key";
73*9880d681SAndroid Build Coastguard Worker const uint32_t StringMapTest::testValue = 1u;
74*9880d681SAndroid Build Coastguard Worker const char* StringMapTest::testKeyFirst = testKey;
75*9880d681SAndroid Build Coastguard Worker size_t StringMapTest::testKeyLength = sizeof(testKey) - 1;
76*9880d681SAndroid Build Coastguard Worker const std::string StringMapTest::testKeyStr(testKey);
77*9880d681SAndroid Build Coastguard Worker 
78*9880d681SAndroid Build Coastguard Worker // Empty map tests.
TEST_F(StringMapTest,EmptyMapTest)79*9880d681SAndroid Build Coastguard Worker TEST_F(StringMapTest, EmptyMapTest) {
80*9880d681SAndroid Build Coastguard Worker   assertEmptyMap();
81*9880d681SAndroid Build Coastguard Worker }
82*9880d681SAndroid Build Coastguard Worker 
83*9880d681SAndroid Build Coastguard Worker // Constant map tests.
TEST_F(StringMapTest,ConstEmptyMapTest)84*9880d681SAndroid Build Coastguard Worker TEST_F(StringMapTest, ConstEmptyMapTest) {
85*9880d681SAndroid Build Coastguard Worker   const StringMap<uint32_t>& constTestMap = testMap;
86*9880d681SAndroid Build Coastguard Worker 
87*9880d681SAndroid Build Coastguard Worker   // Size tests
88*9880d681SAndroid Build Coastguard Worker   EXPECT_EQ(0u, constTestMap.size());
89*9880d681SAndroid Build Coastguard Worker   EXPECT_TRUE(constTestMap.empty());
90*9880d681SAndroid Build Coastguard Worker 
91*9880d681SAndroid Build Coastguard Worker   // Iterator tests
92*9880d681SAndroid Build Coastguard Worker   EXPECT_TRUE(constTestMap.begin() == constTestMap.end());
93*9880d681SAndroid Build Coastguard Worker 
94*9880d681SAndroid Build Coastguard Worker   // Lookup tests
95*9880d681SAndroid Build Coastguard Worker   EXPECT_EQ(0u, constTestMap.count(testKey));
96*9880d681SAndroid Build Coastguard Worker   EXPECT_EQ(0u, constTestMap.count(StringRef(testKeyFirst, testKeyLength)));
97*9880d681SAndroid Build Coastguard Worker   EXPECT_EQ(0u, constTestMap.count(testKeyStr));
98*9880d681SAndroid Build Coastguard Worker   EXPECT_TRUE(constTestMap.find(testKey) == constTestMap.end());
99*9880d681SAndroid Build Coastguard Worker   EXPECT_TRUE(constTestMap.find(StringRef(testKeyFirst, testKeyLength)) ==
100*9880d681SAndroid Build Coastguard Worker               constTestMap.end());
101*9880d681SAndroid Build Coastguard Worker   EXPECT_TRUE(constTestMap.find(testKeyStr) == constTestMap.end());
102*9880d681SAndroid Build Coastguard Worker }
103*9880d681SAndroid Build Coastguard Worker 
104*9880d681SAndroid Build Coastguard Worker // A map with a single entry.
TEST_F(StringMapTest,SingleEntryMapTest)105*9880d681SAndroid Build Coastguard Worker TEST_F(StringMapTest, SingleEntryMapTest) {
106*9880d681SAndroid Build Coastguard Worker   testMap[testKey] = testValue;
107*9880d681SAndroid Build Coastguard Worker   assertSingleItemMap();
108*9880d681SAndroid Build Coastguard Worker }
109*9880d681SAndroid Build Coastguard Worker 
110*9880d681SAndroid Build Coastguard Worker // Test clear() method.
TEST_F(StringMapTest,ClearTest)111*9880d681SAndroid Build Coastguard Worker TEST_F(StringMapTest, ClearTest) {
112*9880d681SAndroid Build Coastguard Worker   testMap[testKey] = testValue;
113*9880d681SAndroid Build Coastguard Worker   testMap.clear();
114*9880d681SAndroid Build Coastguard Worker   assertEmptyMap();
115*9880d681SAndroid Build Coastguard Worker }
116*9880d681SAndroid Build Coastguard Worker 
117*9880d681SAndroid Build Coastguard Worker // Test erase(iterator) method.
TEST_F(StringMapTest,EraseIteratorTest)118*9880d681SAndroid Build Coastguard Worker TEST_F(StringMapTest, EraseIteratorTest) {
119*9880d681SAndroid Build Coastguard Worker   testMap[testKey] = testValue;
120*9880d681SAndroid Build Coastguard Worker   testMap.erase(testMap.begin());
121*9880d681SAndroid Build Coastguard Worker   assertEmptyMap();
122*9880d681SAndroid Build Coastguard Worker }
123*9880d681SAndroid Build Coastguard Worker 
124*9880d681SAndroid Build Coastguard Worker // Test erase(value) method.
TEST_F(StringMapTest,EraseValueTest)125*9880d681SAndroid Build Coastguard Worker TEST_F(StringMapTest, EraseValueTest) {
126*9880d681SAndroid Build Coastguard Worker   testMap[testKey] = testValue;
127*9880d681SAndroid Build Coastguard Worker   testMap.erase(testKey);
128*9880d681SAndroid Build Coastguard Worker   assertEmptyMap();
129*9880d681SAndroid Build Coastguard Worker }
130*9880d681SAndroid Build Coastguard Worker 
131*9880d681SAndroid Build Coastguard Worker // Test inserting two values and erasing one.
TEST_F(StringMapTest,InsertAndEraseTest)132*9880d681SAndroid Build Coastguard Worker TEST_F(StringMapTest, InsertAndEraseTest) {
133*9880d681SAndroid Build Coastguard Worker   testMap[testKey] = testValue;
134*9880d681SAndroid Build Coastguard Worker   testMap["otherKey"] = 2;
135*9880d681SAndroid Build Coastguard Worker   testMap.erase("otherKey");
136*9880d681SAndroid Build Coastguard Worker   assertSingleItemMap();
137*9880d681SAndroid Build Coastguard Worker }
138*9880d681SAndroid Build Coastguard Worker 
TEST_F(StringMapTest,SmallFullMapTest)139*9880d681SAndroid Build Coastguard Worker TEST_F(StringMapTest, SmallFullMapTest) {
140*9880d681SAndroid Build Coastguard Worker   // StringMap has a tricky corner case when the map is small (<8 buckets) and
141*9880d681SAndroid Build Coastguard Worker   // it fills up through a balanced pattern of inserts and erases. This can
142*9880d681SAndroid Build Coastguard Worker   // lead to inf-loops in some cases (PR13148) so we test it explicitly here.
143*9880d681SAndroid Build Coastguard Worker   llvm::StringMap<int> Map(2);
144*9880d681SAndroid Build Coastguard Worker 
145*9880d681SAndroid Build Coastguard Worker   Map["eins"] = 1;
146*9880d681SAndroid Build Coastguard Worker   Map["zwei"] = 2;
147*9880d681SAndroid Build Coastguard Worker   Map["drei"] = 3;
148*9880d681SAndroid Build Coastguard Worker   Map.erase("drei");
149*9880d681SAndroid Build Coastguard Worker   Map.erase("eins");
150*9880d681SAndroid Build Coastguard Worker   Map["veir"] = 4;
151*9880d681SAndroid Build Coastguard Worker   Map["funf"] = 5;
152*9880d681SAndroid Build Coastguard Worker 
153*9880d681SAndroid Build Coastguard Worker   EXPECT_EQ(3u, Map.size());
154*9880d681SAndroid Build Coastguard Worker   EXPECT_EQ(0, Map.lookup("eins"));
155*9880d681SAndroid Build Coastguard Worker   EXPECT_EQ(2, Map.lookup("zwei"));
156*9880d681SAndroid Build Coastguard Worker   EXPECT_EQ(0, Map.lookup("drei"));
157*9880d681SAndroid Build Coastguard Worker   EXPECT_EQ(4, Map.lookup("veir"));
158*9880d681SAndroid Build Coastguard Worker   EXPECT_EQ(5, Map.lookup("funf"));
159*9880d681SAndroid Build Coastguard Worker }
160*9880d681SAndroid Build Coastguard Worker 
TEST_F(StringMapTest,CopyCtorTest)161*9880d681SAndroid Build Coastguard Worker TEST_F(StringMapTest, CopyCtorTest) {
162*9880d681SAndroid Build Coastguard Worker   llvm::StringMap<int> Map;
163*9880d681SAndroid Build Coastguard Worker 
164*9880d681SAndroid Build Coastguard Worker   Map["eins"] = 1;
165*9880d681SAndroid Build Coastguard Worker   Map["zwei"] = 2;
166*9880d681SAndroid Build Coastguard Worker   Map["drei"] = 3;
167*9880d681SAndroid Build Coastguard Worker   Map.erase("drei");
168*9880d681SAndroid Build Coastguard Worker   Map.erase("eins");
169*9880d681SAndroid Build Coastguard Worker   Map["veir"] = 4;
170*9880d681SAndroid Build Coastguard Worker   Map["funf"] = 5;
171*9880d681SAndroid Build Coastguard Worker 
172*9880d681SAndroid Build Coastguard Worker   EXPECT_EQ(3u, Map.size());
173*9880d681SAndroid Build Coastguard Worker   EXPECT_EQ(0, Map.lookup("eins"));
174*9880d681SAndroid Build Coastguard Worker   EXPECT_EQ(2, Map.lookup("zwei"));
175*9880d681SAndroid Build Coastguard Worker   EXPECT_EQ(0, Map.lookup("drei"));
176*9880d681SAndroid Build Coastguard Worker   EXPECT_EQ(4, Map.lookup("veir"));
177*9880d681SAndroid Build Coastguard Worker   EXPECT_EQ(5, Map.lookup("funf"));
178*9880d681SAndroid Build Coastguard Worker 
179*9880d681SAndroid Build Coastguard Worker   llvm::StringMap<int> Map2(Map);
180*9880d681SAndroid Build Coastguard Worker   EXPECT_EQ(3u, Map2.size());
181*9880d681SAndroid Build Coastguard Worker   EXPECT_EQ(0, Map2.lookup("eins"));
182*9880d681SAndroid Build Coastguard Worker   EXPECT_EQ(2, Map2.lookup("zwei"));
183*9880d681SAndroid Build Coastguard Worker   EXPECT_EQ(0, Map2.lookup("drei"));
184*9880d681SAndroid Build Coastguard Worker   EXPECT_EQ(4, Map2.lookup("veir"));
185*9880d681SAndroid Build Coastguard Worker   EXPECT_EQ(5, Map2.lookup("funf"));
186*9880d681SAndroid Build Coastguard Worker }
187*9880d681SAndroid Build Coastguard Worker 
188*9880d681SAndroid Build Coastguard Worker // A more complex iteration test.
TEST_F(StringMapTest,IterationTest)189*9880d681SAndroid Build Coastguard Worker TEST_F(StringMapTest, IterationTest) {
190*9880d681SAndroid Build Coastguard Worker   bool visited[100];
191*9880d681SAndroid Build Coastguard Worker 
192*9880d681SAndroid Build Coastguard Worker   // Insert 100 numbers into the map
193*9880d681SAndroid Build Coastguard Worker   for (int i = 0; i < 100; ++i) {
194*9880d681SAndroid Build Coastguard Worker     std::stringstream ss;
195*9880d681SAndroid Build Coastguard Worker     ss << "key_" << i;
196*9880d681SAndroid Build Coastguard Worker     testMap[ss.str()] = i;
197*9880d681SAndroid Build Coastguard Worker     visited[i] = false;
198*9880d681SAndroid Build Coastguard Worker   }
199*9880d681SAndroid Build Coastguard Worker 
200*9880d681SAndroid Build Coastguard Worker   // Iterate over all numbers and mark each one found.
201*9880d681SAndroid Build Coastguard Worker   for (StringMap<uint32_t>::iterator it = testMap.begin();
202*9880d681SAndroid Build Coastguard Worker       it != testMap.end(); ++it) {
203*9880d681SAndroid Build Coastguard Worker     std::stringstream ss;
204*9880d681SAndroid Build Coastguard Worker     ss << "key_" << it->second;
205*9880d681SAndroid Build Coastguard Worker     ASSERT_STREQ(ss.str().c_str(), it->first().data());
206*9880d681SAndroid Build Coastguard Worker     visited[it->second] = true;
207*9880d681SAndroid Build Coastguard Worker   }
208*9880d681SAndroid Build Coastguard Worker 
209*9880d681SAndroid Build Coastguard Worker   // Ensure every number was visited.
210*9880d681SAndroid Build Coastguard Worker   for (int i = 0; i < 100; ++i) {
211*9880d681SAndroid Build Coastguard Worker     ASSERT_TRUE(visited[i]) << "Entry #" << i << " was never visited";
212*9880d681SAndroid Build Coastguard Worker   }
213*9880d681SAndroid Build Coastguard Worker }
214*9880d681SAndroid Build Coastguard Worker 
215*9880d681SAndroid Build Coastguard Worker // Test StringMapEntry::Create() method.
TEST_F(StringMapTest,StringMapEntryTest)216*9880d681SAndroid Build Coastguard Worker TEST_F(StringMapTest, StringMapEntryTest) {
217*9880d681SAndroid Build Coastguard Worker   StringMap<uint32_t>::value_type* entry =
218*9880d681SAndroid Build Coastguard Worker       StringMap<uint32_t>::value_type::Create(
219*9880d681SAndroid Build Coastguard Worker           StringRef(testKeyFirst, testKeyLength), 1u);
220*9880d681SAndroid Build Coastguard Worker   EXPECT_STREQ(testKey, entry->first().data());
221*9880d681SAndroid Build Coastguard Worker   EXPECT_EQ(1u, entry->second);
222*9880d681SAndroid Build Coastguard Worker   free(entry);
223*9880d681SAndroid Build Coastguard Worker }
224*9880d681SAndroid Build Coastguard Worker 
225*9880d681SAndroid Build Coastguard Worker // Test insert() method.
TEST_F(StringMapTest,InsertTest)226*9880d681SAndroid Build Coastguard Worker TEST_F(StringMapTest, InsertTest) {
227*9880d681SAndroid Build Coastguard Worker   SCOPED_TRACE("InsertTest");
228*9880d681SAndroid Build Coastguard Worker   testMap.insert(
229*9880d681SAndroid Build Coastguard Worker       StringMap<uint32_t>::value_type::Create(
230*9880d681SAndroid Build Coastguard Worker           StringRef(testKeyFirst, testKeyLength),
231*9880d681SAndroid Build Coastguard Worker           testMap.getAllocator(), 1u));
232*9880d681SAndroid Build Coastguard Worker   assertSingleItemMap();
233*9880d681SAndroid Build Coastguard Worker }
234*9880d681SAndroid Build Coastguard Worker 
235*9880d681SAndroid Build Coastguard Worker // Test insert(pair<K, V>) method
TEST_F(StringMapTest,InsertPairTest)236*9880d681SAndroid Build Coastguard Worker TEST_F(StringMapTest, InsertPairTest) {
237*9880d681SAndroid Build Coastguard Worker   bool Inserted;
238*9880d681SAndroid Build Coastguard Worker   StringMap<uint32_t>::iterator NewIt;
239*9880d681SAndroid Build Coastguard Worker   std::tie(NewIt, Inserted) =
240*9880d681SAndroid Build Coastguard Worker       testMap.insert(std::make_pair(testKeyFirst, testValue));
241*9880d681SAndroid Build Coastguard Worker   EXPECT_EQ(1u, testMap.size());
242*9880d681SAndroid Build Coastguard Worker   EXPECT_EQ(testValue, testMap[testKeyFirst]);
243*9880d681SAndroid Build Coastguard Worker   EXPECT_EQ(testKeyFirst, NewIt->first());
244*9880d681SAndroid Build Coastguard Worker   EXPECT_EQ(testValue, NewIt->second);
245*9880d681SAndroid Build Coastguard Worker   EXPECT_TRUE(Inserted);
246*9880d681SAndroid Build Coastguard Worker 
247*9880d681SAndroid Build Coastguard Worker   StringMap<uint32_t>::iterator ExistingIt;
248*9880d681SAndroid Build Coastguard Worker   std::tie(ExistingIt, Inserted) =
249*9880d681SAndroid Build Coastguard Worker       testMap.insert(std::make_pair(testKeyFirst, testValue + 1));
250*9880d681SAndroid Build Coastguard Worker   EXPECT_EQ(1u, testMap.size());
251*9880d681SAndroid Build Coastguard Worker   EXPECT_EQ(testValue, testMap[testKeyFirst]);
252*9880d681SAndroid Build Coastguard Worker   EXPECT_FALSE(Inserted);
253*9880d681SAndroid Build Coastguard Worker   EXPECT_EQ(NewIt, ExistingIt);
254*9880d681SAndroid Build Coastguard Worker }
255*9880d681SAndroid Build Coastguard Worker 
256*9880d681SAndroid Build Coastguard Worker // Test insert(pair<K, V>) method when rehashing occurs
TEST_F(StringMapTest,InsertRehashingPairTest)257*9880d681SAndroid Build Coastguard Worker TEST_F(StringMapTest, InsertRehashingPairTest) {
258*9880d681SAndroid Build Coastguard Worker   // Check that the correct iterator is returned when the inserted element is
259*9880d681SAndroid Build Coastguard Worker   // moved to a different bucket during internal rehashing. This depends on
260*9880d681SAndroid Build Coastguard Worker   // the particular key, and the implementation of StringMap and HashString.
261*9880d681SAndroid Build Coastguard Worker   // Changes to those might result in this test not actually checking that.
262*9880d681SAndroid Build Coastguard Worker   StringMap<uint32_t> t(0);
263*9880d681SAndroid Build Coastguard Worker   EXPECT_EQ(0u, t.getNumBuckets());
264*9880d681SAndroid Build Coastguard Worker 
265*9880d681SAndroid Build Coastguard Worker   StringMap<uint32_t>::iterator It =
266*9880d681SAndroid Build Coastguard Worker     t.insert(std::make_pair("abcdef", 42)).first;
267*9880d681SAndroid Build Coastguard Worker   EXPECT_EQ(16u, t.getNumBuckets());
268*9880d681SAndroid Build Coastguard Worker   EXPECT_EQ("abcdef", It->first());
269*9880d681SAndroid Build Coastguard Worker   EXPECT_EQ(42u, It->second);
270*9880d681SAndroid Build Coastguard Worker }
271*9880d681SAndroid Build Coastguard Worker 
272*9880d681SAndroid Build Coastguard Worker // Create a non-default constructable value
273*9880d681SAndroid Build Coastguard Worker struct StringMapTestStruct {
StringMapTestStruct__anon55ab63410111::StringMapTestStruct274*9880d681SAndroid Build Coastguard Worker   StringMapTestStruct(int i) : i(i) {}
275*9880d681SAndroid Build Coastguard Worker   StringMapTestStruct() = delete;
276*9880d681SAndroid Build Coastguard Worker   int i;
277*9880d681SAndroid Build Coastguard Worker };
278*9880d681SAndroid Build Coastguard Worker 
TEST_F(StringMapTest,NonDefaultConstructable)279*9880d681SAndroid Build Coastguard Worker TEST_F(StringMapTest, NonDefaultConstructable) {
280*9880d681SAndroid Build Coastguard Worker   StringMap<StringMapTestStruct> t;
281*9880d681SAndroid Build Coastguard Worker   t.insert(std::make_pair("Test", StringMapTestStruct(123)));
282*9880d681SAndroid Build Coastguard Worker   StringMap<StringMapTestStruct>::iterator iter = t.find("Test");
283*9880d681SAndroid Build Coastguard Worker   ASSERT_NE(iter, t.end());
284*9880d681SAndroid Build Coastguard Worker   ASSERT_EQ(iter->second.i, 123);
285*9880d681SAndroid Build Coastguard Worker }
286*9880d681SAndroid Build Coastguard Worker 
287*9880d681SAndroid Build Coastguard Worker struct Immovable {
Immovable__anon55ab63410111::Immovable288*9880d681SAndroid Build Coastguard Worker   Immovable() {}
289*9880d681SAndroid Build Coastguard Worker   Immovable(Immovable&&) = delete; // will disable the other special members
290*9880d681SAndroid Build Coastguard Worker };
291*9880d681SAndroid Build Coastguard Worker 
292*9880d681SAndroid Build Coastguard Worker struct MoveOnly {
293*9880d681SAndroid Build Coastguard Worker   int i;
MoveOnly__anon55ab63410111::MoveOnly294*9880d681SAndroid Build Coastguard Worker   MoveOnly(int i) : i(i) {}
MoveOnly__anon55ab63410111::MoveOnly295*9880d681SAndroid Build Coastguard Worker   MoveOnly(const Immovable&) : i(0) {}
MoveOnly__anon55ab63410111::MoveOnly296*9880d681SAndroid Build Coastguard Worker   MoveOnly(MoveOnly &&RHS) : i(RHS.i) {}
operator =__anon55ab63410111::MoveOnly297*9880d681SAndroid Build Coastguard Worker   MoveOnly &operator=(MoveOnly &&RHS) {
298*9880d681SAndroid Build Coastguard Worker     i = RHS.i;
299*9880d681SAndroid Build Coastguard Worker     return *this;
300*9880d681SAndroid Build Coastguard Worker   }
301*9880d681SAndroid Build Coastguard Worker 
302*9880d681SAndroid Build Coastguard Worker private:
303*9880d681SAndroid Build Coastguard Worker   MoveOnly(const MoveOnly &) = delete;
304*9880d681SAndroid Build Coastguard Worker   MoveOnly &operator=(const MoveOnly &) = delete;
305*9880d681SAndroid Build Coastguard Worker };
306*9880d681SAndroid Build Coastguard Worker 
TEST_F(StringMapTest,MoveOnly)307*9880d681SAndroid Build Coastguard Worker TEST_F(StringMapTest, MoveOnly) {
308*9880d681SAndroid Build Coastguard Worker   StringMap<MoveOnly> t;
309*9880d681SAndroid Build Coastguard Worker   t.insert(std::make_pair("Test", MoveOnly(42)));
310*9880d681SAndroid Build Coastguard Worker   StringRef Key = "Test";
311*9880d681SAndroid Build Coastguard Worker   StringMapEntry<MoveOnly>::Create(Key, MoveOnly(42))
312*9880d681SAndroid Build Coastguard Worker       ->Destroy();
313*9880d681SAndroid Build Coastguard Worker }
314*9880d681SAndroid Build Coastguard Worker 
TEST_F(StringMapTest,CtorArg)315*9880d681SAndroid Build Coastguard Worker TEST_F(StringMapTest, CtorArg) {
316*9880d681SAndroid Build Coastguard Worker   StringRef Key = "Test";
317*9880d681SAndroid Build Coastguard Worker   StringMapEntry<MoveOnly>::Create(Key, Immovable())
318*9880d681SAndroid Build Coastguard Worker       ->Destroy();
319*9880d681SAndroid Build Coastguard Worker }
320*9880d681SAndroid Build Coastguard Worker 
TEST_F(StringMapTest,MoveConstruct)321*9880d681SAndroid Build Coastguard Worker TEST_F(StringMapTest, MoveConstruct) {
322*9880d681SAndroid Build Coastguard Worker   StringMap<int> A;
323*9880d681SAndroid Build Coastguard Worker   A["x"] = 42;
324*9880d681SAndroid Build Coastguard Worker   StringMap<int> B = std::move(A);
325*9880d681SAndroid Build Coastguard Worker   ASSERT_EQ(A.size(), 0u);
326*9880d681SAndroid Build Coastguard Worker   ASSERT_EQ(B.size(), 1u);
327*9880d681SAndroid Build Coastguard Worker   ASSERT_EQ(B["x"], 42);
328*9880d681SAndroid Build Coastguard Worker   ASSERT_EQ(B.count("y"), 0u);
329*9880d681SAndroid Build Coastguard Worker }
330*9880d681SAndroid Build Coastguard Worker 
TEST_F(StringMapTest,MoveAssignment)331*9880d681SAndroid Build Coastguard Worker TEST_F(StringMapTest, MoveAssignment) {
332*9880d681SAndroid Build Coastguard Worker   StringMap<int> A;
333*9880d681SAndroid Build Coastguard Worker   A["x"] = 42;
334*9880d681SAndroid Build Coastguard Worker   StringMap<int> B;
335*9880d681SAndroid Build Coastguard Worker   B["y"] = 117;
336*9880d681SAndroid Build Coastguard Worker   A = std::move(B);
337*9880d681SAndroid Build Coastguard Worker   ASSERT_EQ(A.size(), 1u);
338*9880d681SAndroid Build Coastguard Worker   ASSERT_EQ(B.size(), 0u);
339*9880d681SAndroid Build Coastguard Worker   ASSERT_EQ(A["y"], 117);
340*9880d681SAndroid Build Coastguard Worker   ASSERT_EQ(B.count("x"), 0u);
341*9880d681SAndroid Build Coastguard Worker }
342*9880d681SAndroid Build Coastguard Worker 
343*9880d681SAndroid Build Coastguard Worker struct Countable {
344*9880d681SAndroid Build Coastguard Worker   int &InstanceCount;
345*9880d681SAndroid Build Coastguard Worker   int Number;
Countable__anon55ab63410111::Countable346*9880d681SAndroid Build Coastguard Worker   Countable(int Number, int &InstanceCount)
347*9880d681SAndroid Build Coastguard Worker       : InstanceCount(InstanceCount), Number(Number) {
348*9880d681SAndroid Build Coastguard Worker     ++InstanceCount;
349*9880d681SAndroid Build Coastguard Worker   }
Countable__anon55ab63410111::Countable350*9880d681SAndroid Build Coastguard Worker   Countable(Countable &&C) : InstanceCount(C.InstanceCount), Number(C.Number) {
351*9880d681SAndroid Build Coastguard Worker     ++InstanceCount;
352*9880d681SAndroid Build Coastguard Worker     C.Number = -1;
353*9880d681SAndroid Build Coastguard Worker   }
Countable__anon55ab63410111::Countable354*9880d681SAndroid Build Coastguard Worker   Countable(const Countable &C)
355*9880d681SAndroid Build Coastguard Worker       : InstanceCount(C.InstanceCount), Number(C.Number) {
356*9880d681SAndroid Build Coastguard Worker     ++InstanceCount;
357*9880d681SAndroid Build Coastguard Worker   }
operator =__anon55ab63410111::Countable358*9880d681SAndroid Build Coastguard Worker   Countable &operator=(Countable C) {
359*9880d681SAndroid Build Coastguard Worker     Number = C.Number;
360*9880d681SAndroid Build Coastguard Worker     return *this;
361*9880d681SAndroid Build Coastguard Worker   }
~Countable__anon55ab63410111::Countable362*9880d681SAndroid Build Coastguard Worker   ~Countable() { --InstanceCount; }
363*9880d681SAndroid Build Coastguard Worker };
364*9880d681SAndroid Build Coastguard Worker 
TEST_F(StringMapTest,MoveDtor)365*9880d681SAndroid Build Coastguard Worker TEST_F(StringMapTest, MoveDtor) {
366*9880d681SAndroid Build Coastguard Worker   int InstanceCount = 0;
367*9880d681SAndroid Build Coastguard Worker   StringMap<Countable> A;
368*9880d681SAndroid Build Coastguard Worker   A.insert(std::make_pair("x", Countable(42, InstanceCount)));
369*9880d681SAndroid Build Coastguard Worker   ASSERT_EQ(InstanceCount, 1);
370*9880d681SAndroid Build Coastguard Worker   auto I = A.find("x");
371*9880d681SAndroid Build Coastguard Worker   ASSERT_NE(I, A.end());
372*9880d681SAndroid Build Coastguard Worker   ASSERT_EQ(I->second.Number, 42);
373*9880d681SAndroid Build Coastguard Worker 
374*9880d681SAndroid Build Coastguard Worker   StringMap<Countable> B;
375*9880d681SAndroid Build Coastguard Worker   B = std::move(A);
376*9880d681SAndroid Build Coastguard Worker   ASSERT_EQ(InstanceCount, 1);
377*9880d681SAndroid Build Coastguard Worker   ASSERT_TRUE(A.empty());
378*9880d681SAndroid Build Coastguard Worker   I = B.find("x");
379*9880d681SAndroid Build Coastguard Worker   ASSERT_NE(I, B.end());
380*9880d681SAndroid Build Coastguard Worker   ASSERT_EQ(I->second.Number, 42);
381*9880d681SAndroid Build Coastguard Worker 
382*9880d681SAndroid Build Coastguard Worker   B = StringMap<Countable>();
383*9880d681SAndroid Build Coastguard Worker   ASSERT_EQ(InstanceCount, 0);
384*9880d681SAndroid Build Coastguard Worker   ASSERT_TRUE(B.empty());
385*9880d681SAndroid Build Coastguard Worker }
386*9880d681SAndroid Build Coastguard Worker 
387*9880d681SAndroid Build Coastguard Worker namespace {
388*9880d681SAndroid Build Coastguard Worker // Simple class that counts how many moves and copy happens when growing a map
389*9880d681SAndroid Build Coastguard Worker struct CountCtorCopyAndMove {
390*9880d681SAndroid Build Coastguard Worker   static unsigned Ctor;
391*9880d681SAndroid Build Coastguard Worker   static unsigned Move;
392*9880d681SAndroid Build Coastguard Worker   static unsigned Copy;
393*9880d681SAndroid Build Coastguard Worker   int Data = 0;
CountCtorCopyAndMove__anon55ab63410111::__anon55ab63410211::CountCtorCopyAndMove394*9880d681SAndroid Build Coastguard Worker   CountCtorCopyAndMove(int Data) : Data(Data) { Ctor++; }
CountCtorCopyAndMove__anon55ab63410111::__anon55ab63410211::CountCtorCopyAndMove395*9880d681SAndroid Build Coastguard Worker   CountCtorCopyAndMove() { Ctor++; }
396*9880d681SAndroid Build Coastguard Worker 
CountCtorCopyAndMove__anon55ab63410111::__anon55ab63410211::CountCtorCopyAndMove397*9880d681SAndroid Build Coastguard Worker   CountCtorCopyAndMove(const CountCtorCopyAndMove &) { Copy++; }
operator =__anon55ab63410111::__anon55ab63410211::CountCtorCopyAndMove398*9880d681SAndroid Build Coastguard Worker   CountCtorCopyAndMove &operator=(const CountCtorCopyAndMove &) {
399*9880d681SAndroid Build Coastguard Worker     Copy++;
400*9880d681SAndroid Build Coastguard Worker     return *this;
401*9880d681SAndroid Build Coastguard Worker   }
CountCtorCopyAndMove__anon55ab63410111::__anon55ab63410211::CountCtorCopyAndMove402*9880d681SAndroid Build Coastguard Worker   CountCtorCopyAndMove(CountCtorCopyAndMove &&) { Move++; }
operator =__anon55ab63410111::__anon55ab63410211::CountCtorCopyAndMove403*9880d681SAndroid Build Coastguard Worker   CountCtorCopyAndMove &operator=(const CountCtorCopyAndMove &&) {
404*9880d681SAndroid Build Coastguard Worker     Move++;
405*9880d681SAndroid Build Coastguard Worker     return *this;
406*9880d681SAndroid Build Coastguard Worker   }
407*9880d681SAndroid Build Coastguard Worker };
408*9880d681SAndroid Build Coastguard Worker unsigned CountCtorCopyAndMove::Copy = 0;
409*9880d681SAndroid Build Coastguard Worker unsigned CountCtorCopyAndMove::Move = 0;
410*9880d681SAndroid Build Coastguard Worker unsigned CountCtorCopyAndMove::Ctor = 0;
411*9880d681SAndroid Build Coastguard Worker 
412*9880d681SAndroid Build Coastguard Worker } // anonymous namespace
413*9880d681SAndroid Build Coastguard Worker 
414*9880d681SAndroid Build Coastguard Worker // Make sure creating the map with an initial size of N actually gives us enough
415*9880d681SAndroid Build Coastguard Worker // buckets to insert N items without increasing allocation size.
TEST(StringMapCustomTest,InitialSizeTest)416*9880d681SAndroid Build Coastguard Worker TEST(StringMapCustomTest, InitialSizeTest) {
417*9880d681SAndroid Build Coastguard Worker   // 1 is an "edge value", 32 is an arbitrary power of two, and 67 is an
418*9880d681SAndroid Build Coastguard Worker   // arbitrary prime, picked without any good reason.
419*9880d681SAndroid Build Coastguard Worker   for (auto Size : {1, 32, 67}) {
420*9880d681SAndroid Build Coastguard Worker     StringMap<CountCtorCopyAndMove> Map(Size);
421*9880d681SAndroid Build Coastguard Worker     auto NumBuckets = Map.getNumBuckets();
422*9880d681SAndroid Build Coastguard Worker     CountCtorCopyAndMove::Move = 0;
423*9880d681SAndroid Build Coastguard Worker     CountCtorCopyAndMove::Copy = 0;
424*9880d681SAndroid Build Coastguard Worker     for (int i = 0; i < Size; ++i)
425*9880d681SAndroid Build Coastguard Worker       Map.insert(std::pair<std::string, CountCtorCopyAndMove>(
426*9880d681SAndroid Build Coastguard Worker           std::piecewise_construct, std::forward_as_tuple(Twine(i).str()),
427*9880d681SAndroid Build Coastguard Worker           std::forward_as_tuple(i)));
428*9880d681SAndroid Build Coastguard Worker     // After the inital move, the map will move the Elts in the Entry.
429*9880d681SAndroid Build Coastguard Worker     EXPECT_EQ((unsigned)Size * 2, CountCtorCopyAndMove::Move);
430*9880d681SAndroid Build Coastguard Worker     // We copy once the pair from the Elts vector
431*9880d681SAndroid Build Coastguard Worker     EXPECT_EQ(0u, CountCtorCopyAndMove::Copy);
432*9880d681SAndroid Build Coastguard Worker     // Check that the map didn't grow
433*9880d681SAndroid Build Coastguard Worker     EXPECT_EQ(Map.getNumBuckets(), NumBuckets);
434*9880d681SAndroid Build Coastguard Worker   }
435*9880d681SAndroid Build Coastguard Worker }
436*9880d681SAndroid Build Coastguard Worker 
TEST(StringMapCustomTest,BracketOperatorCtor)437*9880d681SAndroid Build Coastguard Worker TEST(StringMapCustomTest, BracketOperatorCtor) {
438*9880d681SAndroid Build Coastguard Worker   StringMap<CountCtorCopyAndMove> Map;
439*9880d681SAndroid Build Coastguard Worker   CountCtorCopyAndMove::Ctor = 0;
440*9880d681SAndroid Build Coastguard Worker   Map["abcd"];
441*9880d681SAndroid Build Coastguard Worker   EXPECT_EQ(1u, CountCtorCopyAndMove::Ctor);
442*9880d681SAndroid Build Coastguard Worker   // Test that operator[] does not create a value when it is already in the map
443*9880d681SAndroid Build Coastguard Worker   CountCtorCopyAndMove::Ctor = 0;
444*9880d681SAndroid Build Coastguard Worker   Map["abcd"];
445*9880d681SAndroid Build Coastguard Worker   EXPECT_EQ(0u, CountCtorCopyAndMove::Ctor);
446*9880d681SAndroid Build Coastguard Worker }
447*9880d681SAndroid Build Coastguard Worker 
448*9880d681SAndroid Build Coastguard Worker namespace {
449*9880d681SAndroid Build Coastguard Worker struct NonMoveableNonCopyableType {
450*9880d681SAndroid Build Coastguard Worker   int Data = 0;
451*9880d681SAndroid Build Coastguard Worker   NonMoveableNonCopyableType() = default;
NonMoveableNonCopyableType__anon55ab63410111::__anon55ab63410311::NonMoveableNonCopyableType452*9880d681SAndroid Build Coastguard Worker   NonMoveableNonCopyableType(int Data) : Data(Data) {}
453*9880d681SAndroid Build Coastguard Worker   NonMoveableNonCopyableType(const NonMoveableNonCopyableType &) = delete;
454*9880d681SAndroid Build Coastguard Worker   NonMoveableNonCopyableType(NonMoveableNonCopyableType &&) = delete;
455*9880d681SAndroid Build Coastguard Worker };
456*9880d681SAndroid Build Coastguard Worker }
457*9880d681SAndroid Build Coastguard Worker 
458*9880d681SAndroid Build Coastguard Worker // Test that we can "emplace" an element in the map without involving map/move
TEST(StringMapCustomTest,EmplaceTest)459*9880d681SAndroid Build Coastguard Worker TEST(StringMapCustomTest, EmplaceTest) {
460*9880d681SAndroid Build Coastguard Worker   StringMap<NonMoveableNonCopyableType> Map;
461*9880d681SAndroid Build Coastguard Worker   Map.emplace_second("abcd", 42);
462*9880d681SAndroid Build Coastguard Worker   EXPECT_EQ(1u, Map.count("abcd"));
463*9880d681SAndroid Build Coastguard Worker   EXPECT_EQ(42, Map["abcd"].Data);
464*9880d681SAndroid Build Coastguard Worker }
465*9880d681SAndroid Build Coastguard Worker 
466*9880d681SAndroid Build Coastguard Worker } // end anonymous namespace
467