Skip to content

Commit 1320036

Browse files
committed
[ADT] Add at method (assertive lookup) to DenseMap and StringMap
This patch makes it easier for users when they want to use validated lookup on DenseMap/StringMap as a composable C++ expression. For instance: ``` // instead of if (auto val = map.lookup(key)) return val; assert("..."); // we can write return map.at(key); ``` Differential Revision: https://reviews.llvm.org/D143976
1 parent 2b51c8c commit 1320036

File tree

4 files changed

+43
-3
lines changed

4 files changed

+43
-3
lines changed

llvm/include/llvm/ADT/DenseMap.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -201,6 +201,14 @@ class DenseMapBase : public DebugEpochBase {
201201
return ValueT();
202202
}
203203

204+
/// at - Return the entry for the specified key, or abort if no such
205+
/// entry exists.
206+
const ValueT &at(const_arg_type_t<KeyT> Val) const {
207+
auto Iter = this->find(std::move(Val));
208+
assert(Iter != this->end() && "DenseMap::at failed due to a missing key");
209+
return Iter->second;
210+
}
211+
204212
// Inserts key,value pair into the map if the key isn't already in the map.
205213
// If the key is already in the map, it returns false and doesn't update the
206214
// value.

llvm/include/llvm/ADT/StringMap.h

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -231,12 +231,20 @@ class StringMap : public StringMapImpl,
231231
/// lookup - Return the entry for the specified key, or a default
232232
/// constructed value if no such entry exists.
233233
ValueTy lookup(StringRef Key) const {
234-
const_iterator it = find(Key);
235-
if (it != end())
236-
return it->second;
234+
const_iterator Iter = find(Key);
235+
if (Iter != end())
236+
return Iter->second;
237237
return ValueTy();
238238
}
239239

240+
/// at - Return the entry for the specified key, or abort if no such
241+
/// entry exists.
242+
const ValueTy &at(StringRef Val) const {
243+
auto Iter = this->find(std::move(Val));
244+
assert(Iter != this->end() && "StringMap::at failed due to a missing key");
245+
return Iter->second;
246+
}
247+
240248
/// Lookup the ValueTy for the \p Key, or create a default constructed value
241249
/// if the key is not in the map.
242250
ValueTy &operator[](StringRef Key) { return try_emplace(Key).first->second; }

llvm/unittests/ADT/DenseMapTest.cpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -125,6 +125,10 @@ TYPED_TEST(DenseMapTest, EmptyIntMapTest) {
125125
EXPECT_TRUE(this->Map.find(this->getKey()) == this->Map.end());
126126
EXPECT_EQ(typename TypeParam::mapped_type(),
127127
this->Map.lookup(this->getKey()));
128+
129+
// LookupOrTrap tests
130+
EXPECT_DEATH({ this->Map.at(this->getKey()); },
131+
"DenseMap::at failed due to a missing key");
128132
}
129133

130134
// Constant map tests
@@ -156,6 +160,10 @@ TYPED_TEST(DenseMapTest, SingleEntryMapTest) {
156160
EXPECT_TRUE(this->Map.find(this->getKey()) == this->Map.begin());
157161
EXPECT_EQ(this->getValue(), this->Map.lookup(this->getKey()));
158162
EXPECT_EQ(this->getValue(), this->Map[this->getKey()]);
163+
164+
// LookupOrTrap tests
165+
EXPECT_DEATH({ this->Map.at(this->getKey(1)); },
166+
"DenseMap::at failed due to a missing key");
159167
}
160168

161169
// Test clear() method

llvm/unittests/ADT/StringMapTest.cpp

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -205,6 +205,22 @@ TEST_F(StringMapTest, CopyCtorTest) {
205205
EXPECT_EQ(5, Map2.lookup("funf"));
206206
}
207207

208+
TEST_F(StringMapTest, LookupOrTrapTest) {
209+
llvm::StringMap<int> Map;
210+
211+
// key not found on empty map
212+
EXPECT_DEATH({ Map.at("a"); }, "StringMap::at failed due to a missing key");
213+
214+
// keys both found and not found on non-empty map
215+
Map["a"] = 1;
216+
Map["b"] = 2;
217+
Map["c"] = 3;
218+
EXPECT_EQ(1, Map.at("a"));
219+
EXPECT_EQ(2, Map.at("b"));
220+
EXPECT_EQ(3, Map.at("c"));
221+
EXPECT_DEATH({ Map.at("d"); }, "StringMap::at failed due to a missing key");
222+
}
223+
208224
// A more complex iteration test.
209225
TEST_F(StringMapTest, IterationTest) {
210226
bool visited[100];

0 commit comments

Comments
 (0)