mirror of
https://github.com/greg7mdp/parallel-hashmap.git
synced 2026-08-29 08:34:39 +08:00
add support for std::erase_if for hash containers - issue #141
This commit is contained in:
Vendored
+3
@@ -112,6 +112,9 @@ if (PHMAP_BUILD_TESTS)
|
||||
phmap_cc_test(NAME dump_load SRCS "tests/dump_load_test.cc"
|
||||
COPTS "-DUNORDERED_MAP_CXX17" DEPS gmock_main)
|
||||
|
||||
phmap_cc_test(NAME erase_if SRCS "tests/erase_if_test.cc"
|
||||
COPTS "-DUNORDERED_MAP_CXX17" DEPS gmock_main)
|
||||
|
||||
## --------------- btree -----------------------------------------------
|
||||
phmap_cc_test(NAME btree SRCS "tests/btree_test.cc"
|
||||
CLOPTS "-w" DEPS gmock_main)
|
||||
|
||||
Vendored
+64
@@ -4939,6 +4939,70 @@ public:
|
||||
|
||||
} // namespace phmap
|
||||
|
||||
|
||||
namespace phmap {
|
||||
namespace priv {
|
||||
template <class C, class Pred>
|
||||
std::size_t erase_if(C &c, Pred pred) {
|
||||
auto old_size = c.size();
|
||||
for (auto i = c.begin(), last = c.end(); i != last; ) {
|
||||
if (pred(*i)) {
|
||||
i = c.erase(i);
|
||||
} else {
|
||||
++i;
|
||||
}
|
||||
}
|
||||
return old_size - c.size();
|
||||
}
|
||||
} // priv
|
||||
} // phmap
|
||||
|
||||
namespace std {
|
||||
|
||||
// ======== erase_if for phmap set containers ==================================
|
||||
template <class T, class Hash, class Eq, class Alloc, class Pred>
|
||||
std::size_t erase_if(phmap::flat_hash_set<T, Hash, Eq, Alloc>& c, Pred pred) {
|
||||
return phmap::priv::erase_if(c, std::move(pred));
|
||||
}
|
||||
|
||||
template <class T, class Hash, class Eq, class Alloc, class Pred>
|
||||
std::size_t erase_if(phmap::node_hash_set<T, Hash, Eq, Alloc>& c, Pred pred) {
|
||||
return phmap::priv::erase_if(c, std::move(pred));
|
||||
}
|
||||
|
||||
template <class T, class Hash, class Eq, class Alloc, size_t N, class Mtx_, class Pred>
|
||||
std::size_t erase_if(phmap::parallel_flat_hash_set<T, Hash, Eq, Alloc, N, Mtx_>& c, Pred pred) {
|
||||
return phmap::priv::erase_if(c, std::move(pred));
|
||||
}
|
||||
|
||||
template <class T, class Hash, class Eq, class Alloc, size_t N, class Mtx_, class Pred>
|
||||
std::size_t erase_if(phmap::parallel_node_hash_set<T, Hash, Eq, Alloc, N, Mtx_>& c, Pred pred) {
|
||||
return phmap::priv::erase_if(c, std::move(pred));
|
||||
}
|
||||
|
||||
// ======== erase_if for phmap map containers ==================================
|
||||
template <class K, class V, class Hash, class Eq, class Alloc, class Pred>
|
||||
std::size_t erase_if(phmap::flat_hash_map<K, V, Hash, Eq, Alloc>& c, Pred pred) {
|
||||
return phmap::priv::erase_if(c, std::move(pred));
|
||||
}
|
||||
|
||||
template <class K, class V, class Hash, class Eq, class Alloc, class Pred>
|
||||
std::size_t erase_if(phmap::node_hash_map<K, V, Hash, Eq, Alloc>& c, Pred pred) {
|
||||
return phmap::priv::erase_if(c, std::move(pred));
|
||||
}
|
||||
|
||||
template <class K, class V, class Hash, class Eq, class Alloc, size_t N, class Mtx_, class Pred>
|
||||
std::size_t erase_if(phmap::parallel_flat_hash_map<K, V, Hash, Eq, Alloc, N, Mtx_>& c, Pred pred) {
|
||||
return phmap::priv::erase_if(c, std::move(pred));
|
||||
}
|
||||
|
||||
template <class K, class V, class Hash, class Eq, class Alloc, size_t N, class Mtx_, class Pred>
|
||||
std::size_t erase_if(phmap::parallel_node_hash_map<K, V, Hash, Eq, Alloc, N, Mtx_>& c, Pred pred) {
|
||||
return phmap::priv::erase_if(c, std::move(pred));
|
||||
}
|
||||
|
||||
} // std
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#pragma warning(pop)
|
||||
#endif
|
||||
|
||||
@@ -8,7 +8,7 @@ namespace phmap {
|
||||
namespace priv {
|
||||
namespace {
|
||||
|
||||
TEST(DumpLoad, FlatHashSet_uin32) {
|
||||
TEST(DumpLoad, FlatHashSet_uint32) {
|
||||
phmap::flat_hash_set<uint32_t> st1 = { 1991, 1202 };
|
||||
|
||||
{
|
||||
|
||||
@@ -0,0 +1,52 @@
|
||||
#include <vector>
|
||||
|
||||
#include "gtest/gtest.h"
|
||||
|
||||
#include "parallel_hashmap/phmap.h"
|
||||
|
||||
namespace phmap {
|
||||
namespace priv {
|
||||
namespace {
|
||||
|
||||
TEST(EraseIf, FlatHashSet_uint32) {
|
||||
phmap::flat_hash_set<uint32_t> st1 = { 3, 6, 7, 9 };
|
||||
auto num_erased = std::erase_if(st1, [](const uint32_t& v) { return v >= 7; });
|
||||
EXPECT_TRUE(num_erased == 2);
|
||||
|
||||
phmap::flat_hash_set<uint32_t> st2 = { 0, 2, 3, 6 };
|
||||
num_erased = std::erase_if(st2, [](const uint32_t& v) { return v <= 2; });
|
||||
EXPECT_TRUE(num_erased == 2);
|
||||
|
||||
EXPECT_TRUE(st1 == st2);
|
||||
}
|
||||
|
||||
TEST(EraseIf, FlatHashMap_uint64_uint32) {
|
||||
using map = phmap::flat_hash_map<uint32_t, uint32_t>;
|
||||
map st1 = { {3, 0}, {6, 0}, {7, 0}, {9, 0} };
|
||||
auto num_erased = std::erase_if(st1, [](const map::value_type& v) { return v.first >= 7; });
|
||||
EXPECT_TRUE(num_erased == 2);
|
||||
|
||||
map st2 = { {0, 0}, {2, 0}, {3, 0}, {6, 0} };
|
||||
num_erased = std::erase_if(st2, [](const map::value_type& v) { return v.first <= 2; });
|
||||
EXPECT_TRUE(num_erased == 2);
|
||||
|
||||
EXPECT_TRUE(st1 == st2);
|
||||
}
|
||||
|
||||
TEST(EraseIf, ParallelFlatHashMap_uint64_uint32) {
|
||||
using map = phmap::parallel_flat_hash_map<uint32_t, uint32_t>;
|
||||
map st1 = { {3, 0}, {6, 0}, {7, 0}, {9, 0} };
|
||||
auto num_erased = std::erase_if(st1, [](const map::value_type& v) { return v.first >= 7; });
|
||||
EXPECT_TRUE(num_erased == 2);
|
||||
|
||||
map st2 = { {0, 0}, {2, 0}, {3, 0}, {6, 0} };
|
||||
num_erased = std::erase_if(st2, [](const map::value_type& v) { return v.first <= 2; });
|
||||
EXPECT_TRUE(num_erased == 2);
|
||||
|
||||
EXPECT_TRUE(st1 == st2);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user