[compiler-rt] 09256fe - [sanitizer] Add DenseMap::forEach
Vitaly Buka via llvm-commits
llvm-commits at lists.llvm.org
Tue Nov 23 15:23:36 PST 2021
Author: Vitaly Buka
Date: 2021-11-23T15:23:25-08:00
New Revision: 09256fe980ddc46be36ab4460ae1850aa46f094e
URL: https://github.com/llvm/llvm-project/commit/09256fe980ddc46be36ab4460ae1850aa46f094e
DIFF: https://github.com/llvm/llvm-project/commit/09256fe980ddc46be36ab4460ae1850aa46f094e.diff
LOG: [sanitizer] Add DenseMap::forEach
Added:
Modified:
compiler-rt/lib/sanitizer_common/sanitizer_dense_map.h
compiler-rt/lib/sanitizer_common/tests/sanitizer_dense_map_test.cpp
Removed:
################################################################################
diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_dense_map.h b/compiler-rt/lib/sanitizer_common/sanitizer_dense_map.h
index 3fa6af76ce29c..6ddd8b1edc8a3 100644
--- a/compiler-rt/lib/sanitizer_common/sanitizer_dense_map.h
+++ b/compiler-rt/lib/sanitizer_common/sanitizer_dense_map.h
@@ -250,6 +250,22 @@ class DenseMapBase {
return true;
}
+ /// Iterate over active entries of the container.
+ ///
+ /// Function can return fast to stop the process.
+ template <class Fn>
+ void forEach(Fn fn) {
+ const KeyT EmptyKey = getEmptyKey(), TombstoneKey = getTombstoneKey();
+ for (auto *P = getBuckets(), *E = getBucketsEnd(); P != E; ++P) {
+ const KeyT K = P->getFirst();
+ if (!KeyInfoT::isEqual(K, EmptyKey) &&
+ !KeyInfoT::isEqual(K, TombstoneKey)) {
+ if (!fn(*P))
+ return;
+ }
+ }
+ }
+
protected:
DenseMapBase() = default;
diff --git a/compiler-rt/lib/sanitizer_common/tests/sanitizer_dense_map_test.cpp b/compiler-rt/lib/sanitizer_common/tests/sanitizer_dense_map_test.cpp
index c4cf746f35bf7..fcc905ea87b8d 100644
--- a/compiler-rt/lib/sanitizer_common/tests/sanitizer_dense_map_test.cpp
+++ b/compiler-rt/lib/sanitizer_common/tests/sanitizer_dense_map_test.cpp
@@ -299,6 +299,29 @@ TYPED_TEST(DenseMapTest, SwapTest) {
EXPECT_EQ(this->getValue(i), this->Map[this->getKey(i)]);
}
+// A more complex iteration test
+TYPED_TEST(DenseMapTest, IterationTest) {
+ int visited[100];
+ std::map<typename TypeParam::key_type, unsigned> visitedIndex;
+
+ // Insert 100 numbers into the map
+ for (int i = 0; i < 100; ++i) {
+ visited[i] = 0;
+ visitedIndex[this->getKey(i)] = i;
+
+ this->Map[this->getKey(i)] = this->getValue(i);
+ }
+
+ // Iterate over all numbers and mark each one found.
+ this->Map.forEach([&](const typename TypeParam::value_type &kv) {
+ ++visited[visitedIndex[kv.first]];
+ return true;
+ });
+
+ // Ensure every number was visited.
+ for (int i = 0; i < 100; ++i) ASSERT_EQ(1, visited[i]);
+}
+
namespace {
// Simple class that counts how many moves and copy happens when growing a map
struct CountCopyAndMove {
More information about the llvm-commits
mailing list