Chromium Code Reviews| 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> |
| 11 #include <deque> | |
|
danakj
2017/03/03 23:51:22
What is including all of these headers together so
dyaroshev
2017/03/04 00:32:49
Good point. I will do the measurements and come ba
dyaroshev
2017/03/05 10:49:59
Doesn't seem to affect build times. Checked on mac
| |
| 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 |
| 27 namespace internal { | |
| 28 | |
| 29 // Calls erase on iterators of matching elements. | |
| 30 template <typename Container, typename Predicate> | |
| 31 void IterateAndEraseIf(Container& container, Predicate pred) { | |
| 32 for (auto it = std::begin(container); it != std::end(container);) { | |
|
danakj
2017/03/03 23:51:22
you could use container.begin()/end() here too rig
dyaroshev
2017/03/04 00:32:49
Done.
| |
| 33 if (pred(*it)) | |
| 34 it = container.erase(it); | |
| 35 else | |
| 36 ++it; | |
| 37 } | |
| 38 } | |
| 39 | |
| 40 } // namespace internal | |
| 41 | |
| 20 // Clears internal memory of an STL object. | 42 // Clears internal memory of an STL object. |
| 21 // STL clear()/reserve(0) does not always free internal memory allocated | 43 // STL clear()/reserve(0) does not always free internal memory allocated |
| 22 // This function uses swap/destructor to ensure the internal memory is freed. | 44 // This function uses swap/destructor to ensure the internal memory is freed. |
| 23 template<class T> | 45 template<class T> |
| 24 void STLClearObject(T* obj) { | 46 void STLClearObject(T* obj) { |
| 25 T tmp; | 47 T tmp; |
| 26 tmp.swap(*obj); | 48 tmp.swap(*obj); |
| 27 // Sometimes "T tmp" allocates objects with memory (arena implementation?). | 49 // Sometimes "T tmp" allocates objects with memory (arena implementation?). |
| 28 // Hence using additional reserve(0) even if it doesn't always work. | 50 // Hence using additional reserve(0) even if it doesn't always work. |
| 29 obj->reserve(0); | 51 obj->reserve(0); |
| (...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 119 // Returns true if the sorted container |a1| contains all elements of the sorted | 141 // Returns true if the sorted container |a1| contains all elements of the sorted |
| 120 // container |a2|. | 142 // container |a2|. |
| 121 template <typename Arg1, typename Arg2> | 143 template <typename Arg1, typename Arg2> |
| 122 bool STLIncludes(const Arg1& a1, const Arg2& a2) { | 144 bool STLIncludes(const Arg1& a1, const Arg2& a2) { |
| 123 DCHECK(STLIsSorted(a1)); | 145 DCHECK(STLIsSorted(a1)); |
| 124 DCHECK(STLIsSorted(a2)); | 146 DCHECK(STLIsSorted(a2)); |
| 125 return std::includes(a1.begin(), a1.end(), | 147 return std::includes(a1.begin(), a1.end(), |
| 126 a2.begin(), a2.end()); | 148 a2.begin(), a2.end()); |
| 127 } | 149 } |
| 128 | 150 |
| 151 // Erase/EraseIf are based on library fundamentals ts v2 erase/erase_if | |
| 152 // http://en.cppreference.com/w/cpp/experimental/lib_extensions_2 | |
| 153 // They provide a generic way to erase elements from a container. | |
| 154 // The functions here implement these for the standard containers until those | |
| 155 // functions are available in the C++ standard. | |
| 156 // For Chromium containers overloads should be defined in their own headers | |
| 157 // (like standard containers). | |
| 158 // Note: there is no std::erase for standard associative containers so we don't | |
| 159 // have it either. | |
| 160 | |
| 161 template <typename CharT, typename Traits, typename Allocator, typename Value> | |
| 162 void Erase(std::basic_string<CharT, Traits, Allocator>& container, | |
| 163 const Value& value) { | |
| 164 container.erase( | |
| 165 std::remove(std::begin(container), std::end(container), value), | |
|
danakj
2017/03/03 23:51:22
same for these, you don't need std::begin/end righ
dyaroshev
2017/03/04 00:32:49
Done.
| |
| 166 std::end(container)); | |
| 167 } | |
| 168 | |
| 169 template <typename CharT, typename Traits, typename Allocator, class Predicate> | |
| 170 void EraseIf(std::basic_string<CharT, Traits, Allocator>& container, | |
| 171 Predicate pred) { | |
| 172 container.erase( | |
| 173 std::remove_if(std::begin(container), std::end(container), pred), | |
| 174 std::end(container)); | |
| 175 } | |
| 176 | |
| 177 template <class T, class Allocator, class Value> | |
| 178 void Erase(std::deque<T, Allocator>& container, const Value& value) { | |
| 179 container.erase( | |
| 180 std::remove(std::begin(container), std::end(container), value), | |
| 181 std::end(container)); | |
| 182 } | |
| 183 | |
| 184 template <class T, class Allocator, class Predicate> | |
| 185 void EraseIf(std::deque<T, Allocator>& container, Predicate pred) { | |
| 186 container.erase( | |
| 187 std::remove_if(std::begin(container), std::end(container), pred), | |
| 188 std::end(container)); | |
| 189 } | |
| 190 | |
| 191 template <class T, class Allocator, class Value> | |
| 192 void Erase(std::vector<T, Allocator>& container, const Value& value) { | |
| 193 container.erase( | |
| 194 std::remove(std::begin(container), std::end(container), value), | |
| 195 std::end(container)); | |
| 196 } | |
| 197 | |
| 198 template <class T, class Allocator, class Predicate> | |
| 199 void EraseIf(std::vector<T, Allocator>& container, Predicate pred) { | |
| 200 container.erase( | |
| 201 std::remove_if(std::begin(container), std::end(container), pred), | |
| 202 std::end(container)); | |
| 203 } | |
| 204 | |
| 205 template <class T, class Allocator, class Value> | |
| 206 void Erase(std::forward_list<T, Allocator>& container, const Value& value) { | |
| 207 // Unlike std::forward_list::remove, this function template accepts | |
| 208 // heterogeneous types and does not force a conversion to the container's | |
| 209 // value type before invoking the == operator. | |
| 210 container.remove_if([&](const T& cur) { return cur == value; }); | |
| 211 } | |
| 212 | |
| 213 template <class T, class Allocator, class Predicate> | |
| 214 void EraseIf(std::forward_list<T, Allocator>& container, Predicate pred) { | |
| 215 container.remove_if(pred); | |
| 216 } | |
| 217 | |
| 218 template <class T, class Allocator, class Value> | |
| 219 void Erase(std::list<T, Allocator>& container, const Value& value) { | |
| 220 // Unlike std::list::remove, this function template accepts heterogeneous | |
| 221 // types and does not force a conversion to the container's value type before | |
| 222 // invoking the == operator. | |
| 223 container.remove_if([&](const T& cur) { return cur == value; }); | |
| 224 } | |
| 225 | |
| 226 template <class T, class Allocator, class Predicate> | |
| 227 void EraseIf(std::list<T, Allocator>& container, Predicate pred) { | |
| 228 container.remove_if(pred); | |
| 229 } | |
| 230 | |
| 231 template <class T, class Allocator, class Predicate> | |
| 232 void EraseIf(std::map<T, Allocator>& container, Predicate pred) { | |
| 233 internal::IterateAndEraseIf(container, pred); | |
| 234 } | |
| 235 | |
| 236 template <class T, class Allocator, class Predicate> | |
| 237 void EraseIf(std::multimap<T, Allocator>& container, Predicate pred) { | |
| 238 internal::IterateAndEraseIf(container, pred); | |
| 239 } | |
| 240 | |
| 241 template <class T, class Allocator, class Predicate> | |
| 242 void EraseIf(std::set<T, Allocator>& container, Predicate pred) { | |
| 243 internal::IterateAndEraseIf(container, pred); | |
| 244 } | |
| 245 | |
| 246 template <class T, class Allocator, class Predicate> | |
| 247 void EraseIf(std::multiset<T, Allocator>& container, Predicate pred) { | |
| 248 internal::IterateAndEraseIf(container, pred); | |
| 249 } | |
| 250 | |
| 251 template <class T, class Allocator, class Predicate> | |
| 252 void EraseIf(std::unordered_map<T, Allocator>& container, Predicate pred) { | |
| 253 internal::IterateAndEraseIf(container, pred); | |
| 254 } | |
| 255 | |
| 256 template <class T, class Allocator, class Predicate> | |
| 257 void EraseIf(std::unordered_multimap<T, Allocator>& container, Predicate pred) { | |
| 258 internal::IterateAndEraseIf(container, pred); | |
| 259 } | |
| 260 | |
| 261 template <class T, class Allocator, class Predicate> | |
| 262 void EraseIf(std::unordered_set<T, Allocator>& container, Predicate pred) { | |
| 263 internal::IterateAndEraseIf(container, pred); | |
| 264 } | |
| 265 | |
| 266 template <class T, class Allocator, class Predicate> | |
| 267 void EraseIf(std::unordered_multiset<T, Allocator>& container, Predicate pred) { | |
| 268 internal::IterateAndEraseIf(container, pred); | |
| 269 } | |
| 270 | |
| 129 } // namespace base | 271 } // namespace base |
| 130 | 272 |
| 131 #endif // BASE_STL_UTIL_H_ | 273 #endif // BASE_STL_UTIL_H_ |
| OLD | NEW |