| Index: base/stl_util.h
|
| diff --git a/base/stl_util.h b/base/stl_util.h
|
| index 016bb156450692415d9814f6a011446cf68ca591..2cec11b2e6c9069af85f3e1e7f4a600d5c4b2337 100644
|
| --- a/base/stl_util.h
|
| +++ b/base/stl_util.h
|
| @@ -8,15 +8,37 @@
|
| #define BASE_STL_UTIL_H_
|
|
|
| #include <algorithm>
|
| +#include <deque>
|
| +#include <forward_list>
|
| #include <functional>
|
| #include <iterator>
|
| +#include <list>
|
| +#include <map>
|
| +#include <set>
|
| #include <string>
|
| +#include <unordered_map>
|
| +#include <unordered_set>
|
| #include <vector>
|
|
|
| #include "base/logging.h"
|
|
|
| namespace base {
|
|
|
| +namespace internal {
|
| +
|
| +// Calls erase on iterators of matching elements.
|
| +template <typename Container, typename Predicate>
|
| +void IterateAndEraseIf(Container& container, Predicate pred) {
|
| + for (auto it = container.begin(); it != container.end();) {
|
| + if (pred(*it))
|
| + it = container.erase(it);
|
| + else
|
| + ++it;
|
| + }
|
| +}
|
| +
|
| +} // namespace internal
|
| +
|
| // Clears internal memory of an STL object.
|
| // STL clear()/reserve(0) does not always free internal memory allocated
|
| // This function uses swap/destructor to ensure the internal memory is freed.
|
| @@ -126,6 +148,120 @@ bool STLIncludes(const Arg1& a1, const Arg2& a2) {
|
| a2.begin(), a2.end());
|
| }
|
|
|
| +// Erase/EraseIf are based on library fundamentals ts v2 erase/erase_if
|
| +// http://en.cppreference.com/w/cpp/experimental/lib_extensions_2
|
| +// They provide a generic way to erase elements from a container.
|
| +// The functions here implement these for the standard containers until those
|
| +// functions are available in the C++ standard.
|
| +// For Chromium containers overloads should be defined in their own headers
|
| +// (like standard containers).
|
| +// Note: there is no std::erase for standard associative containers so we don't
|
| +// have it either.
|
| +
|
| +template <typename CharT, typename Traits, typename Allocator, typename Value>
|
| +void Erase(std::basic_string<CharT, Traits, Allocator>& container,
|
| + const Value& value) {
|
| + container.erase(std::remove(container.begin(), container.end(), value),
|
| + container.end());
|
| +}
|
| +
|
| +template <typename CharT, typename Traits, typename Allocator, class Predicate>
|
| +void EraseIf(std::basic_string<CharT, Traits, Allocator>& container,
|
| + Predicate pred) {
|
| + container.erase(std::remove_if(container.begin(), container.end(), pred),
|
| + container.end());
|
| +}
|
| +
|
| +template <class T, class Allocator, class Value>
|
| +void Erase(std::deque<T, Allocator>& container, const Value& value) {
|
| + container.erase(std::remove(container.begin(), container.end(), value),
|
| + container.end());
|
| +}
|
| +
|
| +template <class T, class Allocator, class Predicate>
|
| +void EraseIf(std::deque<T, Allocator>& container, Predicate pred) {
|
| + container.erase(std::remove_if(container.begin(), container.end(), pred),
|
| + container.end());
|
| +}
|
| +
|
| +template <class T, class Allocator, class Value>
|
| +void Erase(std::vector<T, Allocator>& container, const Value& value) {
|
| + container.erase(std::remove(container.begin(), container.end(), value),
|
| + container.end());
|
| +}
|
| +
|
| +template <class T, class Allocator, class Predicate>
|
| +void EraseIf(std::vector<T, Allocator>& container, Predicate pred) {
|
| + container.erase(std::remove_if(container.begin(), container.end(), pred),
|
| + container.end());
|
| +}
|
| +
|
| +template <class T, class Allocator, class Value>
|
| +void Erase(std::forward_list<T, Allocator>& container, const Value& value) {
|
| + // Unlike std::forward_list::remove, this function template accepts
|
| + // heterogeneous types and does not force a conversion to the container's
|
| + // value type before invoking the == operator.
|
| + container.remove_if([&](const T& cur) { return cur == value; });
|
| +}
|
| +
|
| +template <class T, class Allocator, class Predicate>
|
| +void EraseIf(std::forward_list<T, Allocator>& container, Predicate pred) {
|
| + container.remove_if(pred);
|
| +}
|
| +
|
| +template <class T, class Allocator, class Value>
|
| +void Erase(std::list<T, Allocator>& container, const Value& value) {
|
| + // Unlike std::list::remove, this function template accepts heterogeneous
|
| + // types and does not force a conversion to the container's value type before
|
| + // invoking the == operator.
|
| + container.remove_if([&](const T& cur) { return cur == value; });
|
| +}
|
| +
|
| +template <class T, class Allocator, class Predicate>
|
| +void EraseIf(std::list<T, Allocator>& container, Predicate pred) {
|
| + container.remove_if(pred);
|
| +}
|
| +
|
| +template <class T, class Allocator, class Predicate>
|
| +void EraseIf(std::map<T, Allocator>& container, Predicate pred) {
|
| + internal::IterateAndEraseIf(container, pred);
|
| +}
|
| +
|
| +template <class T, class Allocator, class Predicate>
|
| +void EraseIf(std::multimap<T, Allocator>& container, Predicate pred) {
|
| + internal::IterateAndEraseIf(container, pred);
|
| +}
|
| +
|
| +template <class T, class Allocator, class Predicate>
|
| +void EraseIf(std::set<T, Allocator>& container, Predicate pred) {
|
| + internal::IterateAndEraseIf(container, pred);
|
| +}
|
| +
|
| +template <class T, class Allocator, class Predicate>
|
| +void EraseIf(std::multiset<T, Allocator>& container, Predicate pred) {
|
| + internal::IterateAndEraseIf(container, pred);
|
| +}
|
| +
|
| +template <class T, class Allocator, class Predicate>
|
| +void EraseIf(std::unordered_map<T, Allocator>& container, Predicate pred) {
|
| + internal::IterateAndEraseIf(container, pred);
|
| +}
|
| +
|
| +template <class T, class Allocator, class Predicate>
|
| +void EraseIf(std::unordered_multimap<T, Allocator>& container, Predicate pred) {
|
| + internal::IterateAndEraseIf(container, pred);
|
| +}
|
| +
|
| +template <class T, class Allocator, class Predicate>
|
| +void EraseIf(std::unordered_set<T, Allocator>& container, Predicate pred) {
|
| + internal::IterateAndEraseIf(container, pred);
|
| +}
|
| +
|
| +template <class T, class Allocator, class Predicate>
|
| +void EraseIf(std::unordered_multiset<T, Allocator>& container, Predicate pred) {
|
| + internal::IterateAndEraseIf(container, pred);
|
| +}
|
| +
|
| } // namespace base
|
|
|
| #endif // BASE_STL_UTIL_H_
|
|
|