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> | |
| 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 Loading... | |
| 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 // The functions here implement these for the standard containers until those | |
| 140 // functions are available in the C++ standard. | |
| 141 // For Chromium containers overloads should be defined in their own headers | |
| 142 // (like 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, | |
| 147 // STLEraseMemberIf - you can use them directly if the necessary | |
| 148 // overload is not available or if you need non-default behavior, for example | |
| 149 // erase(std::remove) for lists. | |
| 150 | |
| 151 // Uses erase(std::remove) idiom. | |
| 152 template <typename Container, typename Value> | |
| 153 void STLEraseRemove(Container& container, const Value& value) { | |
|
danakj
2017/03/03 20:11:49
These should be in the base::internal namespace, b
dyaroshev
2017/03/03 23:16:54
Done.
| |
| 154 container.erase( | |
| 155 std::remove(std::begin(container), std::end(container), value), | |
| 156 std::end(container)); | |
| 157 } | |
| 158 | |
| 159 // Uses erase(std::remove) idiom. | |
| 160 template <typename Container, typename Predicate> | |
| 161 void STLEraseRemoveIf(Container& container, Predicate pred) { | |
| 162 container.erase( | |
| 163 std::remove_if(std::begin(container), std::end(container), pred), | |
| 164 std::end(container)); | |
| 165 } | |
| 166 | |
| 167 // Calls erase on iterators of matching elements. | |
| 168 template <typename Container, typename Predicate> | |
| 169 void STLEraseByOneIf(Container& container, Predicate pred) { | |
|
danakj
2017/03/03 20:11:49
This maybe justifies a helper method in the intern
dyaroshev
2017/03/03 23:16:54
Done.
| |
| 170 for (auto it = std::begin(container); it != std::end(container);) { | |
| 171 if (pred(*it)) | |
| 172 it = container.erase(it); | |
| 173 else | |
| 174 ++it; | |
| 175 } | |
| 176 } | |
| 177 | |
| 178 // Calls container's remove_if method. | |
| 179 template <typename Container, typename Predicate> | |
| 180 void STLEraseMemberIf(Container& container, Predicate pred) { | |
| 181 container.remove_if(pred); | |
|
danakj
2017/03/03 20:11:49
can't see why the caller wouldn't just call contai
dyaroshev
2017/03/03 23:16:54
Done.
| |
| 182 } | |
| 183 | |
| 184 // Calls container's remove_if method. | |
| 185 template <typename Container, typename Value> | |
| 186 void STLEraseMember(Container& container, const Value& value) { | |
| 187 // Unlike std::*list::remove, this function template accepts heterogeneous | |
| 188 // types and does not force a conversion to the container's value type before | |
| 189 // invoking the == operator. | |
| 190 STLEraseMemberIf(container, [&](const typename Container::value_type& cur) { | |
| 191 return cur == value; | |
| 192 }); | |
| 193 } | |
| 194 | |
| 195 // STLErase/STLEraseIf overloaded for standard containers ---------------------- | |
| 196 // Note: there is no std::erase for standard associative containers so we don't | |
| 197 // have it either. | |
| 198 | |
| 199 template <typename CharT, typename Traits, typename Allocator, typename Value> | |
| 200 void STLErase(std::basic_string<CharT, Traits, Allocator>& container, | |
|
danakj
2017/03/03 20:11:49
I'm not sure where the whole STL prefix thing star
dyaroshev
2017/03/03 23:16:54
Done.
| |
| 201 const Value& value) { | |
| 202 STLEraseRemove(container, value); | |
| 203 } | |
| 204 | |
| 205 template <typename CharT, typename Traits, typename Allocator, class Predicate> | |
| 206 void STLEraseIf(std::basic_string<CharT, Traits, Allocator>& container, | |
| 207 Predicate pred) { | |
| 208 STLEraseRemoveIf(container, pred); | |
| 209 } | |
| 210 | |
| 211 template <class T, class Allocator, class Value> | |
| 212 void STLErase(std::deque<T, Allocator>& container, const Value& value) { | |
| 213 STLEraseRemove(container, value); | |
| 214 } | |
| 215 | |
| 216 template <class T, class Allocator, class Predicate> | |
| 217 void STLEraseIf(std::deque<T, Allocator>& container, Predicate pred) { | |
| 218 STLEraseRemoveIf(container, pred); | |
| 219 } | |
| 220 | |
| 221 template <class T, class Allocator, class Value> | |
| 222 void STLErase(std::vector<T, Allocator>& container, const Value& value) { | |
| 223 STLEraseRemove(container, value); | |
| 224 } | |
| 225 | |
| 226 template <class T, class Allocator, class Predicate> | |
| 227 void STLEraseIf(std::vector<T, Allocator>& container, Predicate pred) { | |
| 228 STLEraseRemoveIf(container, pred); | |
| 229 } | |
| 230 | |
| 231 template <class T, class Allocator, class Value> | |
| 232 void STLErase(std::forward_list<T, Allocator>& container, const Value& value) { | |
| 233 STLEraseMember(container, value); | |
| 234 } | |
| 235 | |
| 236 template <class T, class Allocator, class Predicate> | |
| 237 void STLEraseIf(std::forward_list<T, Allocator>& container, Predicate pred) { | |
| 238 STLEraseMemberIf(container, pred); | |
| 239 } | |
| 240 | |
| 241 template <class T, class Allocator, class Value> | |
| 242 void STLErase(std::list<T, Allocator>& container, const Value& value) { | |
| 243 STLEraseMember(container, value); | |
| 244 } | |
| 245 | |
| 246 template <class T, class Allocator, class Predicate> | |
| 247 void STLEraseIf(std::list<T, Allocator>& container, Predicate pred) { | |
| 248 STLEraseMemberIf(container, pred); | |
| 249 } | |
| 250 | |
| 251 template <class T, class Allocator, class Predicate> | |
| 252 void STLEraseIf(std::map<T, Allocator>& container, Predicate pred) { | |
| 253 STLEraseByOneIf(container, pred); | |
| 254 } | |
| 255 | |
| 256 template <class T, class Allocator, class Predicate> | |
| 257 void STLEraseIf(std::multimap<T, Allocator>& container, Predicate pred) { | |
| 258 STLEraseByOneIf(container, pred); | |
| 259 } | |
| 260 | |
| 261 template <class T, class Allocator, class Predicate> | |
| 262 void STLEraseIf(std::set<T, Allocator>& container, Predicate pred) { | |
| 263 STLEraseByOneIf(container, pred); | |
| 264 } | |
| 265 | |
| 266 template <class T, class Allocator, class Predicate> | |
| 267 void STLEraseIf(std::multiset<T, Allocator>& container, Predicate pred) { | |
| 268 STLEraseByOneIf(container, pred); | |
| 269 } | |
| 270 | |
| 271 template <class T, class Allocator, class Predicate> | |
| 272 void STLEraseIf(std::unordered_map<T, Allocator>& container, Predicate pred) { | |
| 273 STLEraseByOneIf(container, pred); | |
| 274 } | |
| 275 | |
| 276 template <class T, class Allocator, class Predicate> | |
| 277 void STLEraseIf(std::unordered_multimap<T, Allocator>& container, | |
| 278 Predicate pred) { | |
| 279 STLEraseByOneIf(container, pred); | |
| 280 } | |
| 281 | |
| 282 template <class T, class Allocator, class Predicate> | |
| 283 void STLEraseIf(std::unordered_set<T, Allocator>& container, Predicate pred) { | |
| 284 STLEraseByOneIf(container, pred); | |
| 285 } | |
| 286 | |
| 287 template <class T, class Allocator, class Predicate> | |
| 288 void STLEraseIf(std::unordered_multiset<T, Allocator>& container, | |
| 289 Predicate pred) { | |
| 290 STLEraseByOneIf(container, pred); | |
| 291 } | |
| 292 | |
| 129 } // namespace base | 293 } // namespace base |
| 130 | 294 |
| 131 #endif // BASE_STL_UTIL_H_ | 295 #endif // BASE_STL_UTIL_H_ |
| OLD | NEW |