Commit 381a2d39 authored by Joe Loser's avatar Joe Loser Committed by Facebook Github Bot

Implement erase_if for F14 containers (#1069)

Summary:
- For each F14 container, implement `erase_if(F14Container&, Predicate)` similar to C++20 `erase_if(std::unordered_map&, Predicate)`.
- The semantics of `erase_if` are that it erases all elements in the container which satisfy the given predicate.
Pull Request resolved: https://github.com/facebook/folly/pull/1069

Reviewed By: nbronson

Differential Revision: D14588030

Pulled By: yfeldblum

fbshipit-source-id: 87098804b993e9fb742f3a8feed43453aa99c885
parent 379f9548
...@@ -1490,4 +1490,48 @@ void swap( ...@@ -1490,4 +1490,48 @@ void swap(
lhs.swap(rhs); lhs.swap(rhs);
} }
template <
typename K,
typename M,
typename H,
typename E,
typename A,
typename Pred>
void erase_if(F14ValueMap<K, M, H, E, A>& c, Pred pred) {
f14::detail::erase_if_impl(c, pred);
}
template <
typename K,
typename M,
typename H,
typename E,
typename A,
typename Pred>
void erase_if(F14NodeMap<K, M, H, E, A>& c, Pred pred) {
f14::detail::erase_if_impl(c, pred);
}
template <
typename K,
typename M,
typename H,
typename E,
typename A,
typename Pred>
void erase_if(F14VectorMap<K, M, H, E, A>& c, Pred pred) {
f14::detail::erase_if_impl(c, pred);
}
template <
typename K,
typename M,
typename H,
typename E,
typename A,
typename Pred>
void erase_if(F14FastMap<K, M, H, E, A>& c, Pred pred) {
f14::detail::erase_if_impl(c, pred);
}
} // namespace folly } // namespace folly
...@@ -1225,4 +1225,24 @@ void swap(F14FastSet<K, H, E, A>& lhs, F14FastSet<K, H, E, A>& rhs) noexcept( ...@@ -1225,4 +1225,24 @@ void swap(F14FastSet<K, H, E, A>& lhs, F14FastSet<K, H, E, A>& rhs) noexcept(
noexcept(lhs.swap(rhs))) { noexcept(lhs.swap(rhs))) {
lhs.swap(rhs); lhs.swap(rhs);
} }
template <typename K, typename H, typename E, typename A, typename Pred>
void erase_if(F14ValueSet<K, H, E, A>& c, Pred pred) {
f14::detail::erase_if_impl(c, pred);
}
template <typename K, typename H, typename E, typename A, typename Pred>
void erase_if(F14NodeSet<K, H, E, A>& c, Pred pred) {
f14::detail::erase_if_impl(c, pred);
}
template <typename K, typename H, typename E, typename A, typename Pred>
void erase_if(F14VectorSet<K, H, E, A>& c, Pred pred) {
f14::detail::erase_if_impl(c, pred);
}
template <typename K, typename H, typename E, typename A, typename Pred>
void erase_if(F14FastSet<K, H, E, A>& c, Pred pred) {
f14::detail::erase_if_impl(c, pred);
}
} // namespace folly } // namespace folly
...@@ -187,6 +187,16 @@ struct StdNodeReplica< ...@@ -187,6 +187,16 @@ struct StdNodeReplica<
#endif #endif
template <class Container, class Predicate>
void erase_if_impl(Container& c, Predicate& predicate) {
for (auto i = c.begin(), last = c.end(); i != last;) {
auto prev = i++;
if (predicate(*prev)) {
c.erase(prev);
}
}
}
} // namespace detail } // namespace detail
} // namespace f14 } // namespace f14
......
...@@ -1777,6 +1777,23 @@ TEST(F14Map, containsWithPrecomputedHash) { ...@@ -1777,6 +1777,23 @@ TEST(F14Map, containsWithPrecomputedHash) {
testContainsWithPrecomputedHash<F14FastMap>(); testContainsWithPrecomputedHash<F14FastMap>();
} }
template <template <class...> class TMap>
void testEraseIf() {
TMap<int, int> m{{1, 1}, {2, 2}, {3, 3}, {4, 4}};
const auto isEvenKey = [](const auto& p) { return p.first % 2 == 0; };
erase_if(m, isEvenKey);
ASSERT_EQ(2u, m.size());
EXPECT_TRUE(m.contains(1));
EXPECT_TRUE(m.contains(3));
}
TEST(F14Map, eraseIf) {
testEraseIf<F14ValueMap>();
testEraseIf<F14VectorMap>();
testEraseIf<F14NodeMap>();
testEraseIf<F14FastMap>();
}
/////////////////////////////////// ///////////////////////////////////
#endif // FOLLY_F14_VECTOR_INTRINSICS_AVAILABLE #endif // FOLLY_F14_VECTOR_INTRINSICS_AVAILABLE
/////////////////////////////////// ///////////////////////////////////
...@@ -1370,6 +1370,23 @@ TEST(F14Set, containsWithPrecomputedHash) { ...@@ -1370,6 +1370,23 @@ TEST(F14Set, containsWithPrecomputedHash) {
testContainsWithPrecomputedHash<F14FastSet>(); testContainsWithPrecomputedHash<F14FastSet>();
} }
template <template <class...> class TSet>
void testEraseIf() {
TSet<int> s{1, 2, 3, 4};
const auto isEvenKey = [](const auto& key) { return key % 2 == 0; };
erase_if(s, isEvenKey);
ASSERT_EQ(2u, s.size());
EXPECT_TRUE(s.contains(1));
EXPECT_TRUE(s.contains(3));
}
TEST(F14Set, eraseIf) {
testEraseIf<F14ValueSet>();
testEraseIf<F14FastSet>();
testEraseIf<F14VectorSet>();
testEraseIf<F14NodeSet>();
}
/////////////////////////////////// ///////////////////////////////////
#endif // FOLLY_F14_VECTOR_INTRINSICS_AVAILABLE #endif // FOLLY_F14_VECTOR_INTRINSICS_AVAILABLE
/////////////////////////////////// ///////////////////////////////////
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment