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_