Explicitly expose EraseIf in flat_map/flat_set
Before this CL, EraseIf was defined in flat_tree.h, but that file can
only be included by the flat_map/flat_set implementation, as it's an
internal file with limited visibility.
This CL will move the flat_tree's base EraseIf implementation to the
internal namespace and define specific variants of it in flat_map.h and
flat_set.h
Bug: webrtc:12689
Change-Id: Idf31915f4abe36ad302c1da669b702974a27c647
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/225206
Commit-Queue: Victor Boivie <boivie@webrtc.org>
Reviewed-by: Danil Chapovalov <danilchap@webrtc.org>
Reviewed-by: Mirko Bonadei <mbonadei@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#34431}
diff --git a/rtc_base/containers/flat_map.h b/rtc_base/containers/flat_map.h
index 9fa8056..1dfae51 100644
--- a/rtc_base/containers/flat_map.h
+++ b/rtc_base/containers/flat_map.h
@@ -359,6 +359,16 @@
tree::swap(other);
}
+// Erases all elements that match predicate. It has O(size) complexity.
+//
+// flat_map<int, Timestamp> last_times;
+// ...
+// EraseIf(last_times,
+// [&](const auto& element) { return now - element.second > kLimit; });
+
+// NOLINTNEXTLINE(misc-unused-using-decls)
+using ::webrtc::flat_containers_internal::EraseIf;
+
} // namespace webrtc
#endif // RTC_BASE_CONTAINERS_FLAT_MAP_H_
diff --git a/rtc_base/containers/flat_map_unittest.cc b/rtc_base/containers/flat_map_unittest.cc
index 3ece2ff..8f0b77f 100644
--- a/rtc_base/containers/flat_map_unittest.cc
+++ b/rtc_base/containers/flat_map_unittest.cc
@@ -429,5 +429,26 @@
m.erase(m.cbegin());
}
+TEST(FlatMap, SupportsEraseIf) {
+ flat_map<MoveOnlyInt, MoveOnlyInt> m;
+ m.insert(std::make_pair(MoveOnlyInt(1), MoveOnlyInt(1)));
+ m.insert(std::make_pair(MoveOnlyInt(2), MoveOnlyInt(2)));
+ m.insert(std::make_pair(MoveOnlyInt(3), MoveOnlyInt(3)));
+ m.insert(std::make_pair(MoveOnlyInt(4), MoveOnlyInt(4)));
+ m.insert(std::make_pair(MoveOnlyInt(5), MoveOnlyInt(5)));
+
+ EraseIf(m, [to_be_removed = MoveOnlyInt(2)](
+ const std::pair<MoveOnlyInt, MoveOnlyInt>& e) {
+ return e.first == to_be_removed;
+ });
+
+ EXPECT_EQ(m.size(), 4u);
+ ASSERT_TRUE(m.find(MoveOnlyInt(1)) != m.end());
+ ASSERT_FALSE(m.find(MoveOnlyInt(2)) != m.end());
+ ASSERT_TRUE(m.find(MoveOnlyInt(3)) != m.end());
+ ASSERT_TRUE(m.find(MoveOnlyInt(4)) != m.end());
+ ASSERT_TRUE(m.find(MoveOnlyInt(5)) != m.end());
+}
+
} // namespace
} // namespace webrtc
diff --git a/rtc_base/containers/flat_set.h b/rtc_base/containers/flat_set.h
index 5c43179..e088cc5 100644
--- a/rtc_base/containers/flat_set.h
+++ b/rtc_base/containers/flat_set.h
@@ -161,6 +161,18 @@
using flat_set = typename ::webrtc::flat_containers_internal::
flat_tree<Key, webrtc::identity, Compare, Container>;
+// ----------------------------------------------------------------------------
+// General operations.
+
+// Erases all elements that match predicate. It has O(size) complexity.
+//
+// flat_set<int> numbers;
+// ...
+// EraseIf(numbers, [](int number) { return number % 2 == 1; });
+
+// NOLINTNEXTLINE(misc-unused-using-decls)
+using ::webrtc::flat_containers_internal::EraseIf;
+
} // namespace webrtc
#endif // RTC_BASE_CONTAINERS_FLAT_SET_H_
diff --git a/rtc_base/containers/flat_set_unittest.cc b/rtc_base/containers/flat_set_unittest.cc
index 831afed..617db92 100644
--- a/rtc_base/containers/flat_set_unittest.cc
+++ b/rtc_base/containers/flat_set_unittest.cc
@@ -125,5 +125,25 @@
s.erase(s.begin());
s.erase(s.cbegin());
}
+
+TEST(FlatSet, SupportsEraseIf) {
+ flat_set<MoveOnlyInt> s;
+ s.emplace(MoveOnlyInt(1));
+ s.emplace(MoveOnlyInt(2));
+ s.emplace(MoveOnlyInt(3));
+ s.emplace(MoveOnlyInt(4));
+ s.emplace(MoveOnlyInt(5));
+
+ EraseIf(s, [to_be_removed = MoveOnlyInt(2)](const MoveOnlyInt& elem) {
+ return elem == to_be_removed;
+ });
+
+ EXPECT_EQ(s.size(), 4u);
+ ASSERT_TRUE(s.find(MoveOnlyInt(1)) != s.end());
+ ASSERT_FALSE(s.find(MoveOnlyInt(2)) != s.end());
+ ASSERT_TRUE(s.find(MoveOnlyInt(3)) != s.end());
+ ASSERT_TRUE(s.find(MoveOnlyInt(4)) != s.end());
+ ASSERT_TRUE(s.find(MoveOnlyInt(5)) != s.end());
+}
} // namespace
} // namespace webrtc
diff --git a/rtc_base/containers/flat_tree.h b/rtc_base/containers/flat_tree.h
index 046eef1..1b02cce 100644
--- a/rtc_base/containers/flat_tree.h
+++ b/rtc_base/containers/flat_tree.h
@@ -1076,8 +1076,6 @@
return emplace_key_args(key, std::forward<Args>(args)...);
}
-} // namespace flat_containers_internal
-
// ----------------------------------------------------------------------------
// Free functions.
@@ -1091,12 +1089,14 @@
webrtc::flat_containers_internal::
flat_tree<Key, GetKeyFromValue, KeyCompare, Container>& container,
Predicate pred) {
- auto it = std::remove_if(container.begin(), container.end(), pred);
+ auto it = std::remove_if(container.begin(), container.end(),
+ std::forward<Predicate>(pred));
size_t removed = std::distance(it, container.end());
container.erase(it, container.end());
return removed;
}
+} // namespace flat_containers_internal
} // namespace webrtc
#endif // RTC_BASE_CONTAINERS_FLAT_TREE_H_