From 29235139149790f5afc430c11cec8f1eb1677607 Mon Sep 17 00:00:00 2001 From: Abseil Team Date: Wed, 18 Dec 2019 11:46:26 -0800 Subject: Export of internal Abseil changes -- a7e789be4687681b98060fddbf8bd1c64a8f5908 by Abseil Team : Support C++20 erase_if API in btree. See the reference here: https://en.cppreference.com/w/cpp/container/set/erase_if. PiperOrigin-RevId: 286235196 -- 952dd2fdd8435dd293e2186c97e14ef3f29a1aa6 by Derek Mauro : Avoids accessing an out-of-bounds value during flag parsing PiperOrigin-RevId: 286206167 -- ba24591ade579fc4446a09bb3f23bf3602908c04 by Abseil Team : Change null term* (and nul term*) to NUL-term* in comments. PiperOrigin-RevId: 286066376 -- d770baecf36f3d7a8214ca2033d90696ba353d00 by Andy Soffer : cmake: Fix x86_64 check on Windows for random copts Import of https://github.com/abseil/abseil-cpp/pull/518 PiperOrigin-RevId: 286056395 -- 9ed007e284ecf6ec79547437dbed9ce3023204b9 by Greg Falcon : Manual re-import of CCTZ from GitHub. filegroup() moved as a side effect of an internal change. PiperOrigin-RevId: 286015866 -- 25441cc5cb7ee906177f8dac0dcd524df0e6e305 by Derek Mauro : Fix implicit cycle in debugging build rules due to .inc files PiperOrigin-RevId: 285873346 GitOrigin-RevId: a7e789be4687681b98060fddbf8bd1c64a8f5908 Change-Id: Idef8cce4e723fccae6bdd749e94e11e655908214 --- absl/container/btree_map.h | 28 ++++++++++++++++++++++++++++ absl/container/btree_set.h | 28 ++++++++++++++++++++++++++++ absl/container/btree_test.cc | 42 ++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 98 insertions(+) (limited to 'absl/container') diff --git a/absl/container/btree_map.h b/absl/container/btree_map.h index 470e319..cbfcb58 100644 --- a/absl/container/btree_map.h +++ b/absl/container/btree_map.h @@ -412,6 +412,20 @@ void swap(btree_map &x, btree_map &y) { return x.swap(y); } +// absl::erase_if(absl::btree_map<>, Pred) +// +// Erases all elements that satisfy the predicate pred from the container. +template +void erase_if(btree_map &map, Pred pred) { + for (auto it = map.begin(); it != map.end();) { + if (pred(*it)) { + it = map.erase(it); + } else { + ++it; + } + } +} + // absl::btree_multimap // // An `absl::btree_multimap` is an ordered associative container of @@ -701,6 +715,20 @@ void swap(btree_multimap &x, btree_multimap &y) { return x.swap(y); } +// absl::erase_if(absl::btree_multimap<>, Pred) +// +// Erases all elements that satisfy the predicate pred from the container. +template +void erase_if(btree_multimap &map, Pred pred) { + for (auto it = map.begin(); it != map.end();) { + if (pred(*it)) { + it = map.erase(it); + } else { + ++it; + } + } +} + ABSL_NAMESPACE_END } // namespace absl diff --git a/absl/container/btree_set.h b/absl/container/btree_set.h index 2a4d0ac..127fb94 100644 --- a/absl/container/btree_set.h +++ b/absl/container/btree_set.h @@ -360,6 +360,20 @@ void swap(btree_set &x, btree_set &y) { return x.swap(y); } +// absl::erase_if(absl::btree_set<>, Pred) +// +// Erases all elements that satisfy the predicate pred from the container. +template +void erase_if(btree_set &set, Pred pred) { + for (auto it = set.begin(); it != set.end();) { + if (pred(*it)) { + it = set.erase(it); + } else { + ++it; + } + } +} + // absl::btree_multiset<> // // An `absl::btree_multiset` is an ordered associative container of @@ -649,6 +663,20 @@ void swap(btree_multiset &x, btree_multiset &y) { return x.swap(y); } +// absl::erase_if(absl::btree_multiset<>, Pred) +// +// Erases all elements that satisfy the predicate pred from the container. +template +void erase_if(btree_multiset &set, Pred pred) { + for (auto it = set.begin(); it != set.end();) { + if (pred(*it)) { + it = set.erase(it); + } else { + ++it; + } + } +} + ABSL_NAMESPACE_END } // namespace absl diff --git a/absl/container/btree_test.cc b/absl/container/btree_test.cc index f8aadd6..8692b9c 100644 --- a/absl/container/btree_test.cc +++ b/absl/container/btree_test.cc @@ -51,6 +51,7 @@ using ::absl::test_internal::InstanceTracker; using ::absl::test_internal::MovableOnlyInstance; using ::testing::ElementsAre; using ::testing::ElementsAreArray; +using ::testing::IsEmpty; using ::testing::Pair; template @@ -2303,6 +2304,47 @@ TEST(Btree, EmptyTree) { EXPECT_GT(s.max_size(), 0); } +bool IsEven(int k) { return k % 2 == 0; } + +TEST(Btree, EraseIf) { + // Test that erase_if works with all the container types and supports lambdas. + { + absl::btree_set s = {1, 3, 5, 6, 100}; + erase_if(s, [](int k) { return k > 3; }); + EXPECT_THAT(s, ElementsAre(1, 3)); + } + { + absl::btree_multiset s = {1, 3, 3, 5, 6, 6, 100}; + erase_if(s, [](int k) { return k <= 3; }); + EXPECT_THAT(s, ElementsAre(5, 6, 6, 100)); + } + { + absl::btree_map m = {{1, 1}, {3, 3}, {6, 6}, {100, 100}}; + erase_if(m, [](std::pair kv) { return kv.first > 3; }); + EXPECT_THAT(m, ElementsAre(Pair(1, 1), Pair(3, 3))); + } + { + absl::btree_multimap m = {{1, 1}, {3, 3}, {3, 6}, + {6, 6}, {6, 7}, {100, 6}}; + erase_if(m, [](std::pair kv) { return kv.second == 6; }); + EXPECT_THAT(m, ElementsAre(Pair(1, 1), Pair(3, 3), Pair(6, 7))); + } + // Test that erasing all elements from a large set works and test support for + // function pointers. + { + absl::btree_set s; + for (int i = 0; i < 1000; ++i) s.insert(2 * i); + erase_if(s, IsEven); + EXPECT_THAT(s, IsEmpty()); + } + // Test that erase_if supports other format of function pointers. + { + absl::btree_set s = {1, 3, 5, 6, 100}; + erase_if(s, &IsEven); + EXPECT_THAT(s, ElementsAre(1, 3, 5)); + } +} + } // namespace } // namespace container_internal ABSL_NAMESPACE_END -- cgit v1.2.3