Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(3237)

Unified Diff: base/stl_util.h

Issue 2723853002: Implementing erase/erase_if functions from library fundamentals ts: (Closed)
Patch Set: Created 3 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: base/stl_util.h
diff --git a/base/stl_util.h b/base/stl_util.h
index 016bb156450692415d9814f6a011446cf68ca591..6831bc60e4da3ae11fe1e0cda1012c7bc4c27504 100644
--- a/base/stl_util.h
+++ b/base/stl_util.h
@@ -8,9 +8,16 @@
#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"
@@ -126,6 +133,195 @@ bool STLIncludes(const Arg1& a1, const Arg2& a2) {
a2.begin(), a2.end());
}
+// STLErase/STLEraseIf 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.
+// Here we provide overloads for standard containers and general tools to
+// implement this functions for arbitrary containers.
dyaroshev 2017/02/28 23:28:33 Three times the word provide.
Peter Kasting 2017/03/01 03:20:10 Nit: I would make this sentence "The functions her
dyaroshev 2017/03/01 20:05:37 Done.
+// Chromium containers should provide overloads in their own headers (like
+// standard containers).
+
+// Not container specific erasure functions -----------------------------------
+// Most of container specific functions are implemented in terms of
+// STLEraseRemove,STLEraseRemoveIf, STLEraseByOneIf, STLEraseMember,
Peter Kasting 2017/03/01 03:20:11 Nit: Space after comma
dyaroshev 2017/03/01 20:05:37 Done.
+// STLEraseMemberIf - you can use them directly if the necessary
+// overload is not provided here or if you need not default behavior like
Peter Kasting 2017/03/01 03:20:10 Nit: not default -> non-default
dyaroshev 2017/03/01 20:05:37 Done.
+// erase(std::remove) for lists.
+// Note: because there is no std::erase for associative containers, we don't
+// provide STLEraseByOne either.
Peter Kasting 2017/03/01 03:20:11 Nit: I think this note is unnecessary given the si
dyaroshev 2017/03/01 20:05:37 Done.
+
+// erase(std::remove) idiom.
+template <typename Container, typename Value>
+// Requires Container is a ForwardContainer,
+// Requires ValueType<Container> is Movable.
+// ValueType<Container> is equality comparable with Value.
dyaroshev 2017/02/28 23:28:33 @pkasting - I know you don't like describing conce
Peter Kasting 2017/03/01 03:20:11 With respect to the folks writing the C++ Core Gui
dyaroshev 2017/03/01 20:05:37 Done.
+void STLEraseRemove(Container& container, const Value& value) {
+ container.erase(
+ std::remove(std::begin(container), std::end(container), value),
+ std::end(container));
+}
+
+// erase(std::remove) idiom.
+template <typename Container, typename Predicate>
+// Requires Container is a ForwardContainer,
+// ValueType<Container> is Movable
+// Predicate is an UnaryPredicate on ValueType<Container>.
+void STLEraseRemoveIf(Container& container, Predicate pred) {
+ container.erase(
+ std::remove_if(std::begin(container), std::end(container), pred),
+ std::end(container));
+}
+
+// erasing by one element.
Peter Kasting 2017/03/01 03:20:10 Nit: Capitalize start of comment sentences (multip
dyaroshev 2017/03/01 20:05:37 Done.
+template <typename Container, typename Predicate>
+// Requires Predicate is an UnaryPredicate on ValueType<Container>.
+void STLEraseByOneIf(Container& container, Predicate pred) {
+ for (auto it = std::begin(container); it != std::end(container);) {
+ if (pred(*it)) {
Peter Kasting 2017/03/01 03:20:11 Nit: No {}
dyaroshev 2017/03/01 20:05:37 Done.
+ it = container.erase(it);
+ } else {
+ ++it;
+ }
+ }
+}
+
+// calls container's remove_if method.
+template <typename Container, typename Predicate>
+// Requires Container implements remove_if member function,
+// Predicate is an UnaryPredicate on ValueType<Container>.
+void STLEraseMemberIf(Container& container, Predicate pred) {
+ container.remove_if(pred);
+}
+
+// calls container's remove_if method.
+template <typename Container, typename Value>
+// Requires Container implements remove_if member function,
+// ValueType<Container> is equality comparable with Value.
+void STLEraseMember(Container& container, const Value& value) {
+ // Unlike std::*list::remove, this function template accepts heterogenous
+ // types and does not force a conversion to the container's value type before
+ // invoking the == operator.
+ STLEraseMemberIf(container, [&](const typename Container::value_type& cur) {
+ return cur == value;
+ });
+}
+
+// STLErase/STLEraseIf overloaded for standard containers ----------------------
+// Note: there is no std::erase for standard associative containers so we don't
+// have it either.
+
+// http://en.cppreference.com/w/cpp/experimental/basic_string/erase
Peter Kasting 2017/03/01 03:20:11 Nit: I might (not sure) remove all these comments
dyaroshev 2017/03/01 20:05:37 I removed the comments. I don't know about the bla
+template <typename CharT, typename Traits, typename Allocator, typename Value>
+void STLErase(std::basic_string<CharT, Traits, Allocator>& container,
+ const Value& value) {
+ STLEraseRemove(container, value);
+}
+
+// http://en.cppreference.com/w/cpp/experimental/basic_string/erase_if
+template <typename CharT, typename Traits, typename Allocator, class Predicate>
+void STLEraseIf(std::basic_string<CharT, Traits, Allocator>& container,
+ Predicate pred) {
+ STLEraseRemoveIf(container, pred);
+}
+
+// http://en.cppreference.com/w/cpp/experimental/deque/erase
+template <class T, class Allocator, class Value>
+void STLErase(std::deque<T, Allocator>& container, const Value& value) {
+ STLEraseRemove(container, value);
+}
+
+// http://en.cppreference.com/w/cpp/experimental/deque/erase_if
+template <class T, class Allocator, class Predicate>
+void STLEraseIf(std::deque<T, Allocator>& container, Predicate pred) {
+ STLEraseRemoveIf(container, pred);
+}
+
+// http://en.cppreference.com/w/cpp/experimental/vector/erase
+template <class T, class Allocator, class Value>
+void STLErase(std::vector<T, Allocator>& container, const Value& value) {
+ STLEraseRemove(container, value);
+}
+
+// http://en.cppreference.com/w/cpp/experimental/vector/erase_if
+template <class T, class Allocator, class Predicate>
+void STLEraseIf(std::vector<T, Allocator>& container, Predicate pred) {
+ STLEraseRemoveIf(container, pred);
+}
+
+// http://en.cppreference.com/w/cpp/experimental/forward_list/erase
+template <class T, class Allocator, class Value>
+void STLErase(std::forward_list<T, Allocator>& container, const Value& value) {
+ STLEraseMember(container, value);
+}
+
+// http://en.cppreference.com/w/cpp/experimental/forward_list/erase_if
+template <class T, class Allocator, class Predicate>
+void STLEraseIf(std::forward_list<T, Allocator>& container, Predicate pred) {
+ STLEraseMemberIf(container, pred);
+}
+
+// http://en.cppreference.com/w/cpp/experimental/list/erase
+template <class T, class Allocator, class Value>
+void STLErase(std::list<T, Allocator>& container, const Value& value) {
+ STLEraseMember(container, value);
+}
+
+// http://en.cppreference.com/w/cpp/experimental/list/erase_if
+template <class T, class Allocator, class Predicate>
+void STLEraseIf(std::list<T, Allocator>& container, Predicate pred) {
+ STLEraseMemberIf(container, pred);
+}
+
+// http://en.cppreference.com/w/cpp/experimental/map/erase_if
+template <class T, class Allocator, class Predicate>
+void STLEraseIf(std::map<T, Allocator>& container, Predicate pred) {
+ STLEraseByOneIf(container, pred);
+}
+
+// http://en.cppreference.com/w/cpp/experimental/multimap/erase_if
+template <class T, class Allocator, class Predicate>
+void STLEraseIf(std::multimap<T, Allocator>& container, Predicate pred) {
+ STLEraseByOneIf(container, pred);
+}
+
+// http://en.cppreference.com/w/cpp/experimental/set/erase_if
+template <class T, class Allocator, class Predicate>
+void STLEraseIf(std::set<T, Allocator>& container, Predicate pred) {
+ STLEraseByOneIf(container, pred);
+}
+
+// http://en.cppreference.com/w/cpp/experimental/multiset/erase_if
+template <class T, class Allocator, class Predicate>
+void STLEraseIf(std::multiset<T, Allocator>& container, Predicate pred) {
+ STLEraseByOneIf(container, pred);
+}
+
+// http://en.cppreference.com/w/cpp/experimental/unordered_map/erase_if
+template <class T, class Allocator, class Predicate>
+void STLEraseIf(std::unordered_map<T, Allocator>& container, Predicate pred) {
+ STLEraseByOneIf(container, pred);
+}
+
+// http://en.cppreference.com/w/cpp/experimental/unordered_multimap/erase_if
+template <class T, class Allocator, class Predicate>
+void STLEraseIf(std::unordered_multimap<T, Allocator>& container,
+ Predicate pred) {
+ STLEraseByOneIf(container, pred);
+}
+
+// http://en.cppreference.com/w/cpp/experimental/unordered_set/erase_if
+template <class T, class Allocator, class Predicate>
+void STLEraseIf(std::unordered_set<T, Allocator>& container, Predicate pred) {
+ STLEraseByOneIf(container, pred);
+}
+
+// http://en.cppreference.com/w/cpp/experimental/unordered_multiset/erase_if
+template <class T, class Allocator, class Predicate>
+void STLEraseIf(std::unordered_multiset<T, Allocator>& container,
+ Predicate pred) {
+ STLEraseByOneIf(container, pred);
+}
+
} // namespace base
#endif // BASE_STL_UTIL_H_

Powered by Google App Engine
This is Rietveld 408576698