diff --git a/parallel_hashmap/phmap.h b/parallel_hashmap/phmap.h index f2b596f..8ae2ca6 100644 --- a/parallel_hashmap/phmap.h +++ b/parallel_hashmap/phmap.h @@ -3408,6 +3408,16 @@ public: return true; } + template + bool if_contains(const key_arg& key, F&& f) { + typename Lockable::SharedLock m; + auto it = const_cast(this)->find(key, hash(key), m); + if (it == this->end()) + return false; + std::forward(f)(Policy::value(&*it)); + return true; + } + template MappedReference

operator[](key_arg&& key) { return Policy::value(&*try_emplace(std::forward(key)).first); diff --git a/tests/flat_hash_map_test.cc b/tests/flat_hash_map_test.cc index 316c9f7..5f0e57f 100644 --- a/tests/flat_hash_map_test.cc +++ b/tests/flat_hash_map_test.cc @@ -244,6 +244,7 @@ TEST(THIS_TEST_NAME, MergeExtractInsert) { m.insert(std::move(node)); EXPECT_THAT(m, UnorderedElementsAre(Pair(1, 17), Pair(2, 9))); } + #if !defined(__ANDROID__) && !defined(__APPLE__) && !defined(__EMSCRIPTEN__) && defined(PHMAP_HAVE_STD_ANY) TEST(THIS_TEST_NAME, Any) { ThisMap m; diff --git a/tests/parallel_flat_hash_map_test.cc b/tests/parallel_flat_hash_map_test.cc index d1e6288..500bc3c 100644 --- a/tests/parallel_flat_hash_map_test.cc +++ b/tests/parallel_flat_hash_map_test.cc @@ -2,3 +2,4 @@ #define THIS_TEST_NAME ParallelFlatHashMap #include "flat_hash_map_test.cc" +#include "parallel_hash_map_test.cc" diff --git a/tests/parallel_hash_map_test.cc b/tests/parallel_hash_map_test.cc new file mode 100644 index 0000000..b729118 --- /dev/null +++ b/tests/parallel_hash_map_test.cc @@ -0,0 +1,32 @@ +#ifndef THIS_HASH_MAP + #define THIS_HASH_MAP parallel_flat_hash_map + #define THIS_TEST_NAME ParallelFlatHashMap +#endif + +namespace phmap { +namespace container_internal { +namespace { + +TEST(THIS_TEST_NAME, ThreadSafeContains) { + // We can't test mutable keys, or non-copyable keys with ThisMap. + // Test that the nodes have the proper API. + ThisMap m = { {1, 7}, {2, 9} }; + auto val = 0; + EXPECT_TRUE(m.contains(1, val)); + EXPECT_EQ(val, 7); + + EXPECT_FALSE(m.contains(3, val)); + +#if __cplusplus > 199711L + auto func = [&val](int& v) { val = v; }; + EXPECT_TRUE(m.if_contains(2, func)); + EXPECT_EQ(val, 9); + + EXPECT_FALSE(m.if_contains(3, func)); +#endif + +} + +} // namespace +} // namespace container_internal +} // namespace phmap diff --git a/tests/parallel_node_hash_map_test.cc b/tests/parallel_node_hash_map_test.cc index 615a0ba..ea51222 100644 --- a/tests/parallel_node_hash_map_test.cc +++ b/tests/parallel_node_hash_map_test.cc @@ -2,3 +2,4 @@ #define THIS_TEST_NAME ParallelNodeHashMap #include "flat_hash_map_test.cc" +#include "parallel_hash_map_test.cc"