[llvm] 1320036 - [ADT] Add `at` method (assertive lookup) to DenseMap and StringMap

Ryan Guo via llvm-commits llvm-commits at lists.llvm.org
Fri Feb 17 08:32:45 PST 2023


Author: Ryan Guo
Date: 2023-02-17T08:32:29-08:00
New Revision: 132003603ae3453bc385ffd5ed53f5e8057ae1bc

URL: https://github.com/llvm/llvm-project/commit/132003603ae3453bc385ffd5ed53f5e8057ae1bc
DIFF: https://github.com/llvm/llvm-project/commit/132003603ae3453bc385ffd5ed53f5e8057ae1bc.diff

LOG: [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

Added: 
    

Modified: 
    llvm/include/llvm/ADT/DenseMap.h
    llvm/include/llvm/ADT/StringMap.h
    llvm/unittests/ADT/DenseMapTest.cpp
    llvm/unittests/ADT/StringMapTest.cpp

Removed: 
    


################################################################################
diff  --git a/llvm/include/llvm/ADT/DenseMap.h b/llvm/include/llvm/ADT/DenseMap.h
index 9da6f479c427..12a6673cc62c 100644
--- a/llvm/include/llvm/ADT/DenseMap.h
+++ b/llvm/include/llvm/ADT/DenseMap.h
@@ -201,6 +201,14 @@ class DenseMapBase : public DebugEpochBase {
     return ValueT();
   }
 
+  /// at - Return the entry for the specified key, or abort if no such
+  /// entry exists.
+  const ValueT &at(const_arg_type_t<KeyT> Val) const {
+    auto Iter = this->find(std::move(Val));
+    assert(Iter != this->end() && "DenseMap::at failed due to a missing key");
+    return Iter->second;
+  }
+
   // Inserts key,value pair into the map if the key isn't already in the map.
   // If the key is already in the map, it returns false and doesn't update the
   // value.

diff  --git a/llvm/include/llvm/ADT/StringMap.h b/llvm/include/llvm/ADT/StringMap.h
index 0849bef53ba1..443714c02389 100644
--- a/llvm/include/llvm/ADT/StringMap.h
+++ b/llvm/include/llvm/ADT/StringMap.h
@@ -231,12 +231,20 @@ class StringMap : public StringMapImpl,
   /// lookup - Return the entry for the specified key, or a default
   /// constructed value if no such entry exists.
   ValueTy lookup(StringRef Key) const {
-    const_iterator it = find(Key);
-    if (it != end())
-      return it->second;
+    const_iterator Iter = find(Key);
+    if (Iter != end())
+      return Iter->second;
     return ValueTy();
   }
 
+  /// at - Return the entry for the specified key, or abort if no such
+  /// entry exists.
+  const ValueTy &at(StringRef Val) const {
+    auto Iter = this->find(std::move(Val));
+    assert(Iter != this->end() && "StringMap::at failed due to a missing key");
+    return Iter->second;
+  }
+
   /// Lookup the ValueTy for the \p Key, or create a default constructed value
   /// if the key is not in the map.
   ValueTy &operator[](StringRef Key) { return try_emplace(Key).first->second; }

diff  --git a/llvm/unittests/ADT/DenseMapTest.cpp b/llvm/unittests/ADT/DenseMapTest.cpp
index 2d01316e658b..ba4e76424f04 100644
--- a/llvm/unittests/ADT/DenseMapTest.cpp
+++ b/llvm/unittests/ADT/DenseMapTest.cpp
@@ -125,6 +125,10 @@ TYPED_TEST(DenseMapTest, EmptyIntMapTest) {
   EXPECT_TRUE(this->Map.find(this->getKey()) == this->Map.end());
   EXPECT_EQ(typename TypeParam::mapped_type(),
             this->Map.lookup(this->getKey()));
+
+  // LookupOrTrap tests
+  EXPECT_DEATH({ this->Map.at(this->getKey()); },
+               "DenseMap::at failed due to a missing key");
 }
 
 // Constant map tests
@@ -156,6 +160,10 @@ TYPED_TEST(DenseMapTest, SingleEntryMapTest) {
   EXPECT_TRUE(this->Map.find(this->getKey()) == this->Map.begin());
   EXPECT_EQ(this->getValue(), this->Map.lookup(this->getKey()));
   EXPECT_EQ(this->getValue(), this->Map[this->getKey()]);
+
+  // LookupOrTrap tests
+  EXPECT_DEATH({ this->Map.at(this->getKey(1)); },
+               "DenseMap::at failed due to a missing key");
 }
 
 // Test clear() method

diff  --git a/llvm/unittests/ADT/StringMapTest.cpp b/llvm/unittests/ADT/StringMapTest.cpp
index f40f22ad140c..25562d366c42 100644
--- a/llvm/unittests/ADT/StringMapTest.cpp
+++ b/llvm/unittests/ADT/StringMapTest.cpp
@@ -205,6 +205,22 @@ TEST_F(StringMapTest, CopyCtorTest) {
   EXPECT_EQ(5, Map2.lookup("funf"));
 }
 
+TEST_F(StringMapTest, LookupOrTrapTest) {
+  llvm::StringMap<int> Map;
+
+  // key not found on empty map
+  EXPECT_DEATH({ Map.at("a"); }, "StringMap::at failed due to a missing key");
+
+  // keys both found and not found on non-empty map
+  Map["a"] = 1;
+  Map["b"] = 2;
+  Map["c"] = 3;
+  EXPECT_EQ(1, Map.at("a"));
+  EXPECT_EQ(2, Map.at("b"));
+  EXPECT_EQ(3, Map.at("c"));
+  EXPECT_DEATH({ Map.at("d"); }, "StringMap::at failed due to a missing key");
+}
+
 // A more complex iteration test.
 TEST_F(StringMapTest, IterationTest) {
   bool visited[100];


        


More information about the llvm-commits mailing list