| 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> |
| 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 = container.begin(); it != container.end();) { |
| 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(std::remove(container.begin(), container.end(), value), |
| 165 container.end()); |
| 166 } |
| 167 |
| 168 template <typename CharT, typename Traits, typename Allocator, class Predicate> |
| 169 void EraseIf(std::basic_string<CharT, Traits, Allocator>& container, |
| 170 Predicate pred) { |
| 171 container.erase(std::remove_if(container.begin(), container.end(), pred), |
| 172 container.end()); |
| 173 } |
| 174 |
| 175 template <class T, class Allocator, class Value> |
| 176 void Erase(std::deque<T, Allocator>& container, const Value& value) { |
| 177 container.erase(std::remove(container.begin(), container.end(), value), |
| 178 container.end()); |
| 179 } |
| 180 |
| 181 template <class T, class Allocator, class Predicate> |
| 182 void EraseIf(std::deque<T, Allocator>& container, Predicate pred) { |
| 183 container.erase(std::remove_if(container.begin(), container.end(), pred), |
| 184 container.end()); |
| 185 } |
| 186 |
| 187 template <class T, class Allocator, class Value> |
| 188 void Erase(std::vector<T, Allocator>& container, const Value& value) { |
| 189 container.erase(std::remove(container.begin(), container.end(), value), |
| 190 container.end()); |
| 191 } |
| 192 |
| 193 template <class T, class Allocator, class Predicate> |
| 194 void EraseIf(std::vector<T, Allocator>& container, Predicate pred) { |
| 195 container.erase(std::remove_if(container.begin(), container.end(), pred), |
| 196 container.end()); |
| 197 } |
| 198 |
| 199 template <class T, class Allocator, class Value> |
| 200 void Erase(std::forward_list<T, Allocator>& container, const Value& value) { |
| 201 // Unlike std::forward_list::remove, this function template accepts |
| 202 // heterogeneous types and does not force a conversion to the container's |
| 203 // value type before invoking the == operator. |
| 204 container.remove_if([&](const T& cur) { return cur == value; }); |
| 205 } |
| 206 |
| 207 template <class T, class Allocator, class Predicate> |
| 208 void EraseIf(std::forward_list<T, Allocator>& container, Predicate pred) { |
| 209 container.remove_if(pred); |
| 210 } |
| 211 |
| 212 template <class T, class Allocator, class Value> |
| 213 void Erase(std::list<T, Allocator>& container, const Value& value) { |
| 214 // Unlike std::list::remove, this function template accepts heterogeneous |
| 215 // types and does not force a conversion to the container's value type before |
| 216 // invoking the == operator. |
| 217 container.remove_if([&](const T& cur) { return cur == value; }); |
| 218 } |
| 219 |
| 220 template <class T, class Allocator, class Predicate> |
| 221 void EraseIf(std::list<T, Allocator>& container, Predicate pred) { |
| 222 container.remove_if(pred); |
| 223 } |
| 224 |
| 225 template <class T, class Allocator, class Predicate> |
| 226 void EraseIf(std::map<T, Allocator>& container, Predicate pred) { |
| 227 internal::IterateAndEraseIf(container, pred); |
| 228 } |
| 229 |
| 230 template <class T, class Allocator, class Predicate> |
| 231 void EraseIf(std::multimap<T, Allocator>& container, Predicate pred) { |
| 232 internal::IterateAndEraseIf(container, pred); |
| 233 } |
| 234 |
| 235 template <class T, class Allocator, class Predicate> |
| 236 void EraseIf(std::set<T, Allocator>& container, Predicate pred) { |
| 237 internal::IterateAndEraseIf(container, pred); |
| 238 } |
| 239 |
| 240 template <class T, class Allocator, class Predicate> |
| 241 void EraseIf(std::multiset<T, Allocator>& container, Predicate pred) { |
| 242 internal::IterateAndEraseIf(container, pred); |
| 243 } |
| 244 |
| 245 template <class T, class Allocator, class Predicate> |
| 246 void EraseIf(std::unordered_map<T, Allocator>& container, Predicate pred) { |
| 247 internal::IterateAndEraseIf(container, pred); |
| 248 } |
| 249 |
| 250 template <class T, class Allocator, class Predicate> |
| 251 void EraseIf(std::unordered_multimap<T, Allocator>& container, Predicate pred) { |
| 252 internal::IterateAndEraseIf(container, pred); |
| 253 } |
| 254 |
| 255 template <class T, class Allocator, class Predicate> |
| 256 void EraseIf(std::unordered_set<T, Allocator>& container, Predicate pred) { |
| 257 internal::IterateAndEraseIf(container, pred); |
| 258 } |
| 259 |
| 260 template <class T, class Allocator, class Predicate> |
| 261 void EraseIf(std::unordered_multiset<T, Allocator>& container, Predicate pred) { |
| 262 internal::IterateAndEraseIf(container, pred); |
| 263 } |
| 264 |
| 129 } // namespace base | 265 } // namespace base |
| 130 | 266 |
| 131 #endif // BASE_STL_UTIL_H_ | 267 #endif // BASE_STL_UTIL_H_ |
| OLD | NEW |