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 // 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_ |
| OLD | NEW |