llvm.org GIT mirror llvm / 9ece8eb
[ADT] Teach DenseMap to support StringRef keys. While often you want to use something specialized like StringMap, when the strings already have persistent storage a normal densemap over them can be more efficient. This can't go into StringRef.h because of really obnoxious header chains from the hashing code to the endian detection code to CPU feature detection code to StringMap. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@240528 91177308-0d34-0410-b5e6-96231b3b80d8 Chandler Carruth 5 years ago
2 changed file(s) with 52 addition(s) and 0 deletion(s). Raw diff Collapse all Expand all
1313 #ifndef LLVM_ADT_DENSEMAPINFO_H
1414 #define LLVM_ADT_DENSEMAPINFO_H
1515
16 #include "llvm/ADT/Hashing.h"
17 #include "llvm/ADT/StringRef.h"
1618 #include "llvm/Support/PointerLikeTypeTraits.h"
1719 #include "llvm/Support/type_traits.h"
1820
162164 }
163165 };
164166
167 // Provide DenseMapInfo for StringRefs.
168 template <> struct DenseMapInfo {
169 static inline StringRef getEmptyKey() {
170 return StringRef(reinterpret_cast(~static_cast(0)),
171 0);
172 }
173 static inline StringRef getTombstoneKey() {
174 return StringRef(reinterpret_cast(~static_cast(1)),
175 0);
176 }
177 static unsigned getHashValue(StringRef Val) {
178 assert(Val.data() != getEmptyKey().data() && "Cannot hash the empty key!");
179 assert(Val.data() != getTombstoneKey().data() &&
180 "Cannot hash the tombstone key!");
181 return (unsigned)(hash_value(Val));
182 }
183 static bool isEqual(StringRef LHS, StringRef RHS) {
184 if (RHS.data() == getEmptyKey().data())
185 return LHS.data() == getEmptyKey().data();
186 if (RHS.data() == getTombstoneKey().data())
187 return LHS.data() == getTombstoneKey().data();
188 return LHS == RHS;
189 }
190 };
191
165192 } // end namespace llvm
166193
167194 #endif
322322 EXPECT_TRUE(cit == cit2);
323323 }
324324
325 // Make sure DenseMap works with StringRef keys.
326 TEST(DenseMapCustomTest, StringRefTest) {
327 DenseMap M;
328
329 M["a"] = 1;
330 M["b"] = 2;
331 M["c"] = 3;
332
333 EXPECT_EQ(3u, M.size());
334 EXPECT_EQ(1, M.lookup("a"));
335 EXPECT_EQ(2, M.lookup("b"));
336 EXPECT_EQ(3, M.lookup("c"));
337
338 EXPECT_EQ(0, M.lookup("q"));
339
340 // Test the empty string, spelled various ways.
341 EXPECT_EQ(0, M.lookup(""));
342 EXPECT_EQ(0, M.lookup(StringRef()));
343 EXPECT_EQ(0, M.lookup(StringRef("a", 0)));
344 M[""] = 42;
345 EXPECT_EQ(42, M.lookup(""));
346 EXPECT_EQ(42, M.lookup(StringRef()));
347 EXPECT_EQ(42, M.lookup(StringRef("a", 0)));
348 }
349
325350 // Key traits that allows lookup with either an unsigned or char* key;
326351 // In the latter case, "a" == 0, "b" == 1 and so on.
327352 struct TestDenseMapInfo {