blob: 3fe35c91edcef9db1eb37933da01c457e36b0d28 [file] [log] [blame]
Misha Brukman8fb520e2009-01-01 02:24:48 +00001//===- llvm/unittest/ADT/DenseMapMap.cpp - DenseMap unit tests --*- C++ -*-===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9
10#include "gtest/gtest.h"
11#include "llvm/ADT/DenseMap.h"
Chandler Carruthe5c7bc62012-06-16 01:31:33 +000012#include <map>
Misha Brukman8fb520e2009-01-01 02:24:48 +000013
14using namespace llvm;
15
16namespace {
17
18// Test fixture
Chandler Carruthe5c7bc62012-06-16 01:31:33 +000019template <typename T>
Misha Brukman8fb520e2009-01-01 02:24:48 +000020class DenseMapTest : public testing::Test {
21protected:
Chandler Carruthe5c7bc62012-06-16 01:31:33 +000022 T Map;
23
24 typename T::key_type getKey(int i = 0);
25 typename T::mapped_type getValue(int i = 0);
Misha Brukman8fb520e2009-01-01 02:24:48 +000026};
27
Chandler Carruthe5c7bc62012-06-16 01:31:33 +000028template <>
29uint32_t DenseMapTest<DenseMap<uint32_t, uint32_t> >::getKey(int i) {
30 return i;
Misha Brukman8fb520e2009-01-01 02:24:48 +000031}
32
Chandler Carruthe5c7bc62012-06-16 01:31:33 +000033template <>
34uint32_t DenseMapTest<DenseMap<uint32_t, uint32_t> >::getValue(int i) {
35 return 42 + i;
36}
37
38template <>
39uint32_t *DenseMapTest<DenseMap<uint32_t *, uint32_t *> >::getKey(int i) {
40 static uint32_t dummy_arr1[8192];
41 assert(i < 8192 && "Only support 8192 dummy keys.");
42 return &dummy_arr1[i];
43}
44
45template <>
46uint32_t *DenseMapTest<DenseMap<uint32_t *, uint32_t *> >::getValue(int i) {
47 static uint32_t dummy_arr2[8192];
48 assert(i < 8192 && "Only support 8192 dummy values.");
49 return &dummy_arr2[i];
50}
51
52// Register these types for testing.
53typedef ::testing::Types<DenseMap<uint32_t, uint32_t>,
54 DenseMap<uint32_t *, uint32_t *> > DenseMapTestTypes;
55TYPED_TEST_CASE(DenseMapTest, DenseMapTestTypes);
56
57// Empty map tests
58TYPED_TEST(DenseMapTest, EmptyIntMapTest) {
Misha Brukman8fb520e2009-01-01 02:24:48 +000059 // Size tests
Chandler Carruthe5c7bc62012-06-16 01:31:33 +000060 EXPECT_EQ(0u, this->Map.size());
61 EXPECT_TRUE(this->Map.empty());
Misha Brukman8fb520e2009-01-01 02:24:48 +000062
63 // Iterator tests
Chandler Carruthe5c7bc62012-06-16 01:31:33 +000064 EXPECT_TRUE(this->Map.begin() == this->Map.end());
Misha Brukman8fb520e2009-01-01 02:24:48 +000065
66 // Lookup tests
Chandler Carruthe5c7bc62012-06-16 01:31:33 +000067 EXPECT_FALSE(this->Map.count(this->getKey()));
68 EXPECT_TRUE(this->Map.find(this->getKey()) == this->Map.end());
Chandler Carruth7027ba92012-06-16 03:54:11 +000069#ifndef _MSC_VER
Chandler Carruthe5c7bc62012-06-16 01:31:33 +000070 EXPECT_EQ(typename TypeParam::mapped_type(),
71 this->Map.lookup(this->getKey()));
Chandler Carruth7027ba92012-06-16 03:54:11 +000072#else
73 // MSVC, at least old versions, cannot parse the typename to disambiguate
74 // TypeParam::mapped_type as a type. However, because MSVC doesn't implement
75 // two-phase name lookup, it also doesn't require the typename. Deal with
76 // this mutual incompatibility through specialized code.
77 EXPECT_EQ(TypeParam::mapped_type(),
78 this->Map.lookup(this->getKey()));
79#endif
Misha Brukman8fb520e2009-01-01 02:24:48 +000080}
81
82// Constant map tests
Chandler Carruthe5c7bc62012-06-16 01:31:33 +000083TYPED_TEST(DenseMapTest, ConstEmptyMapTest) {
84 const TypeParam &ConstMap = this->Map;
85 EXPECT_EQ(0u, ConstMap.size());
86 EXPECT_TRUE(ConstMap.empty());
87 EXPECT_TRUE(ConstMap.begin() == ConstMap.end());
Misha Brukman8fb520e2009-01-01 02:24:48 +000088}
89
90// A map with a single entry
Chandler Carruthe5c7bc62012-06-16 01:31:33 +000091TYPED_TEST(DenseMapTest, SingleEntryMapTest) {
92 this->Map[this->getKey()] = this->getValue();
Misha Brukman8fb520e2009-01-01 02:24:48 +000093
94 // Size tests
Chandler Carruthe5c7bc62012-06-16 01:31:33 +000095 EXPECT_EQ(1u, this->Map.size());
96 EXPECT_FALSE(this->Map.begin() == this->Map.end());
97 EXPECT_FALSE(this->Map.empty());
Misha Brukman8fb520e2009-01-01 02:24:48 +000098
99 // Iterator tests
Chandler Carruthe5c7bc62012-06-16 01:31:33 +0000100 typename TypeParam::iterator it = this->Map.begin();
101 EXPECT_EQ(this->getKey(), it->first);
102 EXPECT_EQ(this->getValue(), it->second);
Misha Brukman8fb520e2009-01-01 02:24:48 +0000103 ++it;
Chandler Carruthe5c7bc62012-06-16 01:31:33 +0000104 EXPECT_TRUE(it == this->Map.end());
Misha Brukman8fb520e2009-01-01 02:24:48 +0000105
106 // Lookup tests
Chandler Carruthe5c7bc62012-06-16 01:31:33 +0000107 EXPECT_TRUE(this->Map.count(this->getKey()));
108 EXPECT_TRUE(this->Map.find(this->getKey()) == this->Map.begin());
109 EXPECT_EQ(this->getValue(), this->Map.lookup(this->getKey()));
110 EXPECT_EQ(this->getValue(), this->Map[this->getKey()]);
Misha Brukman8fb520e2009-01-01 02:24:48 +0000111}
112
113// Test clear() method
Chandler Carruthe5c7bc62012-06-16 01:31:33 +0000114TYPED_TEST(DenseMapTest, ClearTest) {
115 this->Map[this->getKey()] = this->getValue();
116 this->Map.clear();
Misha Brukman8fb520e2009-01-01 02:24:48 +0000117
Chandler Carruthe5c7bc62012-06-16 01:31:33 +0000118 EXPECT_EQ(0u, this->Map.size());
119 EXPECT_TRUE(this->Map.empty());
120 EXPECT_TRUE(this->Map.begin() == this->Map.end());
Misha Brukman8fb520e2009-01-01 02:24:48 +0000121}
122
123// Test erase(iterator) method
Chandler Carruthe5c7bc62012-06-16 01:31:33 +0000124TYPED_TEST(DenseMapTest, EraseTest) {
125 this->Map[this->getKey()] = this->getValue();
126 this->Map.erase(this->Map.begin());
Misha Brukman8fb520e2009-01-01 02:24:48 +0000127
Chandler Carruthe5c7bc62012-06-16 01:31:33 +0000128 EXPECT_EQ(0u, this->Map.size());
129 EXPECT_TRUE(this->Map.empty());
130 EXPECT_TRUE(this->Map.begin() == this->Map.end());
Misha Brukman8fb520e2009-01-01 02:24:48 +0000131}
132
133// Test erase(value) method
Chandler Carruthe5c7bc62012-06-16 01:31:33 +0000134TYPED_TEST(DenseMapTest, EraseTest2) {
135 this->Map[this->getKey()] = this->getValue();
136 this->Map.erase(this->getKey());
Misha Brukman8fb520e2009-01-01 02:24:48 +0000137
Chandler Carruthe5c7bc62012-06-16 01:31:33 +0000138 EXPECT_EQ(0u, this->Map.size());
139 EXPECT_TRUE(this->Map.empty());
140 EXPECT_TRUE(this->Map.begin() == this->Map.end());
Misha Brukman8fb520e2009-01-01 02:24:48 +0000141}
142
143// Test insert() method
Chandler Carruthe5c7bc62012-06-16 01:31:33 +0000144TYPED_TEST(DenseMapTest, InsertTest) {
145 this->Map.insert(std::make_pair(this->getKey(), this->getValue()));
146 EXPECT_EQ(1u, this->Map.size());
147 EXPECT_EQ(this->getValue(), this->Map[this->getKey()]);
Misha Brukman8fb520e2009-01-01 02:24:48 +0000148}
149
150// Test copy constructor method
Chandler Carruthe5c7bc62012-06-16 01:31:33 +0000151TYPED_TEST(DenseMapTest, CopyConstructorTest) {
152 this->Map[this->getKey()] = this->getValue();
153 TypeParam copyMap(this->Map);
Misha Brukman8fb520e2009-01-01 02:24:48 +0000154
155 EXPECT_EQ(1u, copyMap.size());
Chandler Carruthe5c7bc62012-06-16 01:31:33 +0000156 EXPECT_EQ(this->getValue(), copyMap[this->getKey()]);
Misha Brukman8fb520e2009-01-01 02:24:48 +0000157}
158
159// Test assignment operator method
Chandler Carruthe5c7bc62012-06-16 01:31:33 +0000160TYPED_TEST(DenseMapTest, AssignmentTest) {
161 this->Map[this->getKey()] = this->getValue();
162 TypeParam copyMap = this->Map;
Misha Brukman8fb520e2009-01-01 02:24:48 +0000163
164 EXPECT_EQ(1u, copyMap.size());
Chandler Carruthe5c7bc62012-06-16 01:31:33 +0000165 EXPECT_EQ(this->getValue(), copyMap[this->getKey()]);
Misha Brukman8fb520e2009-01-01 02:24:48 +0000166}
167
168// A more complex iteration test
Chandler Carruthe5c7bc62012-06-16 01:31:33 +0000169TYPED_TEST(DenseMapTest, IterationTest) {
Misha Brukman8fb520e2009-01-01 02:24:48 +0000170 bool visited[100];
Chandler Carruthe5c7bc62012-06-16 01:31:33 +0000171 std::map<typename TypeParam::key_type, unsigned> visitedIndex;
Misha Brukman8fb520e2009-01-01 02:24:48 +0000172
173 // Insert 100 numbers into the map
174 for (int i = 0; i < 100; ++i) {
175 visited[i] = false;
Chandler Carruthe5c7bc62012-06-16 01:31:33 +0000176 visitedIndex[this->getKey(i)] = i;
177
178 this->Map[this->getKey(i)] = this->getValue(i);
Misha Brukman8fb520e2009-01-01 02:24:48 +0000179 }
180
181 // Iterate over all numbers and mark each one found.
Chandler Carruthe5c7bc62012-06-16 01:31:33 +0000182 for (typename TypeParam::iterator it = this->Map.begin();
183 it != this->Map.end(); ++it)
184 visited[visitedIndex[it->first]] = true;
Misha Brukman8fb520e2009-01-01 02:24:48 +0000185
186 // Ensure every number was visited.
Chandler Carruthe5c7bc62012-06-16 01:31:33 +0000187 for (int i = 0; i < 100; ++i)
Misha Brukmanc870bb52009-01-07 21:13:53 +0000188 ASSERT_TRUE(visited[i]) << "Entry #" << i << " was never visited";
Misha Brukman8fb520e2009-01-01 02:24:48 +0000189}
190
Jeffrey Yasskin81cf4322009-11-10 01:02:17 +0000191// const_iterator test
Chandler Carruthe5c7bc62012-06-16 01:31:33 +0000192TYPED_TEST(DenseMapTest, ConstIteratorTest) {
Jeffrey Yasskin81cf4322009-11-10 01:02:17 +0000193 // Check conversion from iterator to const_iterator.
Chandler Carruthe5c7bc62012-06-16 01:31:33 +0000194 typename TypeParam::iterator it = this->Map.begin();
195 typename TypeParam::const_iterator cit(it);
Jeffrey Yasskin81cf4322009-11-10 01:02:17 +0000196 EXPECT_TRUE(it == cit);
197
198 // Check copying of const_iterators.
Chandler Carruthe5c7bc62012-06-16 01:31:33 +0000199 typename TypeParam::const_iterator cit2(cit);
Jeffrey Yasskin81cf4322009-11-10 01:02:17 +0000200 EXPECT_TRUE(cit == cit2);
201}
202
Talinbabd5982012-01-30 06:55:43 +0000203// Key traits that allows lookup with either an unsigned or char* key;
204// In the latter case, "a" == 0, "b" == 1 and so on.
205struct TestDenseMapInfo {
206 static inline unsigned getEmptyKey() { return ~0; }
207 static inline unsigned getTombstoneKey() { return ~0U - 1; }
208 static unsigned getHashValue(const unsigned& Val) { return Val * 37U; }
209 static unsigned getHashValue(const char* Val) {
210 return (unsigned)(Val[0] - 'a') * 37U;
211 }
212 static bool isEqual(const unsigned& LHS, const unsigned& RHS) {
213 return LHS == RHS;
214 }
215 static bool isEqual(const char* LHS, const unsigned& RHS) {
216 return (unsigned)(LHS[0] - 'a') == RHS;
217 }
218};
219
220// find_as() tests
Chandler Carruthe5c7bc62012-06-16 01:31:33 +0000221TEST(DenseMapCustomTest, FindAsTest) {
Talinbabd5982012-01-30 06:55:43 +0000222 DenseMap<unsigned, unsigned, TestDenseMapInfo> map;
223 map[0] = 1;
224 map[1] = 2;
225 map[2] = 3;
226
227 // Size tests
228 EXPECT_EQ(3u, map.size());
229
230 // Normal lookup tests
231 EXPECT_EQ(1, map.count(1));
232 EXPECT_EQ(1u, map.find(0)->second);
233 EXPECT_EQ(2u, map.find(1)->second);
234 EXPECT_EQ(3u, map.find(2)->second);
235 EXPECT_TRUE(map.find(3) == map.end());
236
237 // find_as() tests
238 EXPECT_EQ(1u, map.find_as("a")->second);
239 EXPECT_EQ(2u, map.find_as("b")->second);
240 EXPECT_EQ(3u, map.find_as("c")->second);
241 EXPECT_TRUE(map.find_as("d") == map.end());
242}
243
Misha Brukman8fb520e2009-01-01 02:24:48 +0000244}