From 5900ba0ee8f3f9cef3b29becbb4335b8f440d57d Mon Sep 17 00:00:00 2001 From: Victor Boivie Date: Wed, 7 Jul 2021 10:48:28 +0200 Subject: [PATCH] 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 Reviewed-by: Danil Chapovalov Reviewed-by: Mirko Bonadei Cr-Commit-Position: refs/heads/master@{#34431} --- rtc_base/containers/flat_map.h | 10 ++++++++++ rtc_base/containers/flat_map_unittest.cc | 21 +++++++++++++++++++++ rtc_base/containers/flat_set.h | 12 ++++++++++++ rtc_base/containers/flat_set_unittest.cc | 20 ++++++++++++++++++++ rtc_base/containers/flat_tree.h | 6 +++--- 5 files changed, 66 insertions(+), 3 deletions(-) diff --git a/rtc_base/containers/flat_map.h b/rtc_base/containers/flat_map.h index 9fa80566e2..1dfae51655 100644 --- a/rtc_base/containers/flat_map.h +++ b/rtc_base/containers/flat_map.h @@ -359,6 +359,16 @@ void flat_map::swap(flat_map& other) noexcept { tree::swap(other); } +// Erases all elements that match predicate. It has O(size) complexity. +// +// flat_map 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 3ece2ff30d..8f0b77fc30 100644 --- a/rtc_base/containers/flat_map_unittest.cc +++ b/rtc_base/containers/flat_map_unittest.cc @@ -429,5 +429,26 @@ TEST(FlatMap, UsingTransparentCompare) { m.erase(m.cbegin()); } +TEST(FlatMap, SupportsEraseIf) { + flat_map 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& 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 5c431791be..e088cc5314 100644 --- a/rtc_base/containers/flat_set.h +++ b/rtc_base/containers/flat_set.h @@ -161,6 +161,18 @@ template ; +// ---------------------------------------------------------------------------- +// General operations. + +// Erases all elements that match predicate. It has O(size) complexity. +// +// flat_set 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 831afedcb5..617db92440 100644 --- a/rtc_base/containers/flat_set_unittest.cc +++ b/rtc_base/containers/flat_set_unittest.cc @@ -125,5 +125,25 @@ TEST(FlatSet, UsingTransparentCompare) { s.erase(s.begin()); s.erase(s.cbegin()); } + +TEST(FlatSet, SupportsEraseIf) { + flat_set 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 046eef1508..1b02cce1b4 100644 --- a/rtc_base/containers/flat_tree.h +++ b/rtc_base/containers/flat_tree.h @@ -1076,8 +1076,6 @@ auto flat_tree:: return emplace_key_args(key, std::forward(args)...); } -} // namespace flat_containers_internal - // ---------------------------------------------------------------------------- // Free functions. @@ -1091,12 +1089,14 @@ size_t EraseIf( webrtc::flat_containers_internal:: flat_tree& container, Predicate pred) { - auto it = std::remove_if(container.begin(), container.end(), pred); + auto it = std::remove_if(container.begin(), container.end(), + std::forward(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_