OLD | NEW |
---|---|
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> |
(...skipping 11 matching lines...) Expand all Loading... | |
22 // This function uses swap/destructor to ensure the internal memory is freed. | 22 // This function uses swap/destructor to ensure the internal memory is freed. |
23 template<class T> | 23 template<class T> |
24 void STLClearObject(T* obj) { | 24 void STLClearObject(T* obj) { |
25 T tmp; | 25 T tmp; |
26 tmp.swap(*obj); | 26 tmp.swap(*obj); |
27 // Sometimes "T tmp" allocates objects with memory (arena implementation?). | 27 // Sometimes "T tmp" allocates objects with memory (arena implementation?). |
28 // Hence using additional reserve(0) even if it doesn't always work. | 28 // Hence using additional reserve(0) even if it doesn't always work. |
29 obj->reserve(0); | 29 obj->reserve(0); |
30 } | 30 } |
31 | 31 |
32 // For a range within a container of pointers, calls delete (non-array version) | |
33 // on these pointers. | |
34 // NOTE: for these three functions, we could just implement a DeleteObject | |
35 // functor and then call for_each() on the range and functor, but this | |
36 // requires us to pull in all of algorithm.h, which seems expensive. | |
37 // For hash_[multi]set, it is important that this deletes behind the iterator | |
38 // because the hash_set may call the hash function on the iterator when it is | |
39 // advanced, which could result in the hash function trying to deference a | |
40 // stale pointer. | |
41 template <class ForwardIterator> | |
42 void STLDeleteContainerPointers(ForwardIterator begin, ForwardIterator end) { | |
43 while (begin != end) { | |
44 ForwardIterator temp = begin; | |
45 ++begin; | |
46 delete *temp; | |
47 } | |
48 } | |
49 | |
50 // Counts the number of instances of val in a container. | 32 // Counts the number of instances of val in a container. |
51 template <typename Container, typename T> | 33 template <typename Container, typename T> |
52 typename std::iterator_traits< | 34 typename std::iterator_traits< |
53 typename Container::const_iterator>::difference_type | 35 typename Container::const_iterator>::difference_type |
54 STLCount(const Container& container, const T& val) { | 36 STLCount(const Container& container, const T& val) { |
55 return std::count(container.begin(), container.end(), val); | 37 return std::count(container.begin(), container.end(), val); |
56 } | 38 } |
57 | 39 |
58 // Return a mutable char* pointing to a string's internal buffer, | 40 // Return a mutable char* pointing to a string's internal buffer, |
59 // which may not be null-terminated. Writing through this pointer will | 41 // which may not be null-terminated. Writing through this pointer will |
(...skipping 18 matching lines...) Expand all Loading... | |
78 // STLDeleteElements() deletes all the elements in an STL container and clears | 60 // STLDeleteElements() deletes all the elements in an STL container and clears |
79 // the container. This function is suitable for use with a vector, set, | 61 // the container. This function is suitable for use with a vector, set, |
80 // hash_set, or any other STL container which defines sensible begin(), end(), | 62 // hash_set, or any other STL container which defines sensible begin(), end(), |
81 // and clear() methods. | 63 // and clear() methods. |
82 // | 64 // |
83 // If container is NULL, this function is a no-op. | 65 // If container is NULL, this function is a no-op. |
84 template <class T> | 66 template <class T> |
85 void STLDeleteElements(T* container) { | 67 void STLDeleteElements(T* container) { |
86 if (!container) | 68 if (!container) |
87 return; | 69 return; |
88 STLDeleteContainerPointers(container->begin(), container->end()); | 70 |
71 auto it = container->begin(); | |
72 while (it != container->end()) { | |
Mark Mentovai
2016/10/31 19:52:02
for would be more concise by one line.
Avi (use Gerrit)
2016/10/31 21:17:40
Is the issue of not being able to advance the iter
| |
73 auto temp = it; | |
74 ++it; | |
75 delete *temp; | |
76 } | |
77 | |
89 container->clear(); | 78 container->clear(); |
90 } | 79 } |
91 | 80 |
92 // Given an STL container consisting of (key, value) pairs, STLDeleteValues | 81 // Given an STL container consisting of (key, value) pairs, STLDeleteValues |
93 // deletes all the "value" components and clears the container. Does nothing | 82 // deletes all the "value" components and clears the container. Does nothing |
94 // in the case it's given a NULL pointer. | 83 // in the case it's given a NULL pointer. |
95 template <class T> | 84 template <class T> |
96 void STLDeleteValues(T* container) { | 85 void STLDeleteValues(T* container) { |
97 if (!container) | 86 if (!container) |
98 return; | 87 return; |
(...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
175 bool STLIncludes(const Arg1& a1, const Arg2& a2) { | 164 bool STLIncludes(const Arg1& a1, const Arg2& a2) { |
176 DCHECK(STLIsSorted(a1)); | 165 DCHECK(STLIsSorted(a1)); |
177 DCHECK(STLIsSorted(a2)); | 166 DCHECK(STLIsSorted(a2)); |
178 return std::includes(a1.begin(), a1.end(), | 167 return std::includes(a1.begin(), a1.end(), |
179 a2.begin(), a2.end()); | 168 a2.begin(), a2.end()); |
180 } | 169 } |
181 | 170 |
182 } // namespace base | 171 } // namespace base |
183 | 172 |
184 #endif // BASE_STL_UTIL_H_ | 173 #endif // BASE_STL_UTIL_H_ |
OLD | NEW |