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

Side by Side Diff: base/stl_util.h

Issue 2723853002: Implementing erase/erase_if functions from library fundamentals ts: (Closed)
Patch Set: Created 3 years, 9 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 unified diff | Download patch
OLDNEW
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 // Derived from google3/util/gtl/stl_util.h 5 // Derived from google3/util/gtl/stl_util.h
6 6
7 #ifndef BASE_STL_UTIL_H_ 7 #ifndef BASE_STL_UTIL_H_
8 #define BASE_STL_UTIL_H_ 8 #define BASE_STL_UTIL_H_
9 9
10 #include <algorithm> 10 #include <algorithm>
11 #include <deque>
12 #include <forward_list>
11 #include <functional> 13 #include <functional>
12 #include <iterator> 14 #include <iterator>
15 #include <list>
16 #include <map>
17 #include <set>
13 #include <string> 18 #include <string>
19 #include <unordered_map>
20 #include <unordered_set>
14 #include <vector> 21 #include <vector>
15 22
16 #include "base/logging.h" 23 #include "base/logging.h"
17 24
18 namespace base { 25 namespace base {
19 26
20 // Clears internal memory of an STL object. 27 // Clears internal memory of an STL object.
21 // STL clear()/reserve(0) does not always free internal memory allocated 28 // STL clear()/reserve(0) does not always free internal memory allocated
22 // This function uses swap/destructor to ensure the internal memory is freed. 29 // This function uses swap/destructor to ensure the internal memory is freed.
23 template<class T> 30 template<class T>
(...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after
119 // Returns true if the sorted container |a1| contains all elements of the sorted 126 // Returns true if the sorted container |a1| contains all elements of the sorted
120 // container |a2|. 127 // container |a2|.
121 template <typename Arg1, typename Arg2> 128 template <typename Arg1, typename Arg2>
122 bool STLIncludes(const Arg1& a1, const Arg2& a2) { 129 bool STLIncludes(const Arg1& a1, const Arg2& a2) {
123 DCHECK(STLIsSorted(a1)); 130 DCHECK(STLIsSorted(a1));
124 DCHECK(STLIsSorted(a2)); 131 DCHECK(STLIsSorted(a2));
125 return std::includes(a1.begin(), a1.end(), 132 return std::includes(a1.begin(), a1.end(),
126 a2.begin(), a2.end()); 133 a2.begin(), a2.end());
127 } 134 }
128 135
136 // STLErase/STLEraseIf are based on library fundamentals ts v2 erase/erase_if
137 // http://en.cppreference.com/w/cpp/experimental/lib_extensions_2
138 // They provide a generic way to erase elements from a container.
139 // Here we provide overloads for standard containers and general tools to
140 // 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.
141 // Chromium containers should provide overloads in their own headers (like
142 // standard containers).
143
144 // Not container specific erasure functions -----------------------------------
145 // Most of container specific functions are implemented in terms of
146 // STLEraseRemove,STLEraseRemoveIf, STLEraseByOneIf, STLEraseMember,
Peter Kasting 2017/03/01 03:20:11 Nit: Space after comma
dyaroshev 2017/03/01 20:05:37 Done.
147 // STLEraseMemberIf - you can use them directly if the necessary
148 // 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.
149 // erase(std::remove) for lists.
150 // Note: because there is no std::erase for associative containers, we don't
151 // 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.
152
153 // erase(std::remove) idiom.
154 template <typename Container, typename Value>
155 // Requires Container is a ForwardContainer,
156 // Requires ValueType<Container> is Movable.
157 // 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.
158 void STLEraseRemove(Container& container, const Value& value) {
159 container.erase(
160 std::remove(std::begin(container), std::end(container), value),
161 std::end(container));
162 }
163
164 // erase(std::remove) idiom.
165 template <typename Container, typename Predicate>
166 // Requires Container is a ForwardContainer,
167 // ValueType<Container> is Movable
168 // Predicate is an UnaryPredicate on ValueType<Container>.
169 void STLEraseRemoveIf(Container& container, Predicate pred) {
170 container.erase(
171 std::remove_if(std::begin(container), std::end(container), pred),
172 std::end(container));
173 }
174
175 // 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.
176 template <typename Container, typename Predicate>
177 // Requires Predicate is an UnaryPredicate on ValueType<Container>.
178 void STLEraseByOneIf(Container& container, Predicate pred) {
179 for (auto it = std::begin(container); it != std::end(container);) {
180 if (pred(*it)) {
Peter Kasting 2017/03/01 03:20:11 Nit: No {}
dyaroshev 2017/03/01 20:05:37 Done.
181 it = container.erase(it);
182 } else {
183 ++it;
184 }
185 }
186 }
187
188 // calls container's remove_if method.
189 template <typename Container, typename Predicate>
190 // Requires Container implements remove_if member function,
191 // Predicate is an UnaryPredicate on ValueType<Container>.
192 void STLEraseMemberIf(Container& container, Predicate pred) {
193 container.remove_if(pred);
194 }
195
196 // calls container's remove_if method.
197 template <typename Container, typename Value>
198 // Requires Container implements remove_if member function,
199 // ValueType<Container> is equality comparable with Value.
200 void STLEraseMember(Container& container, const Value& value) {
201 // Unlike std::*list::remove, this function template accepts heterogenous
202 // types and does not force a conversion to the container's value type before
203 // invoking the == operator.
204 STLEraseMemberIf(container, [&](const typename Container::value_type& cur) {
205 return cur == value;
206 });
207 }
208
209 // STLErase/STLEraseIf overloaded for standard containers ----------------------
210 // Note: there is no std::erase for standard associative containers so we don't
211 // have it either.
212
213 // 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
214 template <typename CharT, typename Traits, typename Allocator, typename Value>
215 void STLErase(std::basic_string<CharT, Traits, Allocator>& container,
216 const Value& value) {
217 STLEraseRemove(container, value);
218 }
219
220 // http://en.cppreference.com/w/cpp/experimental/basic_string/erase_if
221 template <typename CharT, typename Traits, typename Allocator, class Predicate>
222 void STLEraseIf(std::basic_string<CharT, Traits, Allocator>& container,
223 Predicate pred) {
224 STLEraseRemoveIf(container, pred);
225 }
226
227 // http://en.cppreference.com/w/cpp/experimental/deque/erase
228 template <class T, class Allocator, class Value>
229 void STLErase(std::deque<T, Allocator>& container, const Value& value) {
230 STLEraseRemove(container, value);
231 }
232
233 // http://en.cppreference.com/w/cpp/experimental/deque/erase_if
234 template <class T, class Allocator, class Predicate>
235 void STLEraseIf(std::deque<T, Allocator>& container, Predicate pred) {
236 STLEraseRemoveIf(container, pred);
237 }
238
239 // http://en.cppreference.com/w/cpp/experimental/vector/erase
240 template <class T, class Allocator, class Value>
241 void STLErase(std::vector<T, Allocator>& container, const Value& value) {
242 STLEraseRemove(container, value);
243 }
244
245 // http://en.cppreference.com/w/cpp/experimental/vector/erase_if
246 template <class T, class Allocator, class Predicate>
247 void STLEraseIf(std::vector<T, Allocator>& container, Predicate pred) {
248 STLEraseRemoveIf(container, pred);
249 }
250
251 // http://en.cppreference.com/w/cpp/experimental/forward_list/erase
252 template <class T, class Allocator, class Value>
253 void STLErase(std::forward_list<T, Allocator>& container, const Value& value) {
254 STLEraseMember(container, value);
255 }
256
257 // http://en.cppreference.com/w/cpp/experimental/forward_list/erase_if
258 template <class T, class Allocator, class Predicate>
259 void STLEraseIf(std::forward_list<T, Allocator>& container, Predicate pred) {
260 STLEraseMemberIf(container, pred);
261 }
262
263 // http://en.cppreference.com/w/cpp/experimental/list/erase
264 template <class T, class Allocator, class Value>
265 void STLErase(std::list<T, Allocator>& container, const Value& value) {
266 STLEraseMember(container, value);
267 }
268
269 // http://en.cppreference.com/w/cpp/experimental/list/erase_if
270 template <class T, class Allocator, class Predicate>
271 void STLEraseIf(std::list<T, Allocator>& container, Predicate pred) {
272 STLEraseMemberIf(container, pred);
273 }
274
275 // http://en.cppreference.com/w/cpp/experimental/map/erase_if
276 template <class T, class Allocator, class Predicate>
277 void STLEraseIf(std::map<T, Allocator>& container, Predicate pred) {
278 STLEraseByOneIf(container, pred);
279 }
280
281 // http://en.cppreference.com/w/cpp/experimental/multimap/erase_if
282 template <class T, class Allocator, class Predicate>
283 void STLEraseIf(std::multimap<T, Allocator>& container, Predicate pred) {
284 STLEraseByOneIf(container, pred);
285 }
286
287 // http://en.cppreference.com/w/cpp/experimental/set/erase_if
288 template <class T, class Allocator, class Predicate>
289 void STLEraseIf(std::set<T, Allocator>& container, Predicate pred) {
290 STLEraseByOneIf(container, pred);
291 }
292
293 // http://en.cppreference.com/w/cpp/experimental/multiset/erase_if
294 template <class T, class Allocator, class Predicate>
295 void STLEraseIf(std::multiset<T, Allocator>& container, Predicate pred) {
296 STLEraseByOneIf(container, pred);
297 }
298
299 // http://en.cppreference.com/w/cpp/experimental/unordered_map/erase_if
300 template <class T, class Allocator, class Predicate>
301 void STLEraseIf(std::unordered_map<T, Allocator>& container, Predicate pred) {
302 STLEraseByOneIf(container, pred);
303 }
304
305 // http://en.cppreference.com/w/cpp/experimental/unordered_multimap/erase_if
306 template <class T, class Allocator, class Predicate>
307 void STLEraseIf(std::unordered_multimap<T, Allocator>& container,
308 Predicate pred) {
309 STLEraseByOneIf(container, pred);
310 }
311
312 // http://en.cppreference.com/w/cpp/experimental/unordered_set/erase_if
313 template <class T, class Allocator, class Predicate>
314 void STLEraseIf(std::unordered_set<T, Allocator>& container, Predicate pred) {
315 STLEraseByOneIf(container, pred);
316 }
317
318 // http://en.cppreference.com/w/cpp/experimental/unordered_multiset/erase_if
319 template <class T, class Allocator, class Predicate>
320 void STLEraseIf(std::unordered_multiset<T, Allocator>& container,
321 Predicate pred) {
322 STLEraseByOneIf(container, pred);
323 }
324
129 } // namespace base 325 } // namespace base
130 326
131 #endif // BASE_STL_UTIL_H_ 327 #endif // BASE_STL_UTIL_H_
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698