Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2017 The Chromium Authors. All rights reserved. | 1 // Copyright 2017 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 #ifndef BASE_CONTAINERS_FLAT_TREE_H_ | 5 #ifndef BASE_CONTAINERS_FLAT_TREE_H_ |
| 6 #define BASE_CONTAINERS_FLAT_TREE_H_ | 6 #define BASE_CONTAINERS_FLAT_TREE_H_ |
| 7 | 7 |
| 8 #include <algorithm> | 8 #include <algorithm> |
| 9 #include <iterator> | 9 #include <iterator> |
| 10 #include <vector> | 10 #include <vector> |
| 11 | 11 |
| 12 #include "base/template_util.h" | |
| 13 | |
| 12 namespace base { | 14 namespace base { |
| 13 | 15 |
| 14 enum FlatContainerDupes { | 16 enum FlatContainerDupes { |
| 15 KEEP_FIRST_OF_DUPES, | 17 KEEP_FIRST_OF_DUPES, |
| 16 KEEP_LAST_OF_DUPES, | 18 KEEP_LAST_OF_DUPES, |
| 17 }; | 19 }; |
| 18 | 20 |
| 19 namespace internal { | 21 namespace internal { |
| 20 | 22 |
| 21 // This is a convenience method returning true if Iterator is at least a | 23 // This is a convenience method returning true if Iterator is at least a |
| (...skipping 26 matching lines...) Expand all Loading... | |
| 48 for (Iterator next = std::next(first); next != last; ++next, ++first) { | 50 for (Iterator next = std::next(first); next != last; ++next, ++first) { |
| 49 if (!compare(*first, *next)) | 51 if (!compare(*first, *next)) |
| 50 *replacable++ = std::move(*first); | 52 *replacable++ = std::move(*first); |
| 51 } | 53 } |
| 52 | 54 |
| 53 // Last element should be copied unconditionally. | 55 // Last element should be copied unconditionally. |
| 54 *replacable++ = std::move(*first); | 56 *replacable++ = std::move(*first); |
| 55 return replacable; | 57 return replacable; |
| 56 } | 58 } |
| 57 | 59 |
| 60 // Uses SFINAE to detect whether type has is_transparent member. | |
| 61 template <typename T, typename = void> | |
| 62 struct IsTransparentCompare : std::false_type {}; | |
| 63 template <typename T> | |
| 64 struct IsTransparentCompare<T, void_t<typename T::is_transparent>> | |
| 65 : std::true_type {}; | |
| 66 | |
| 67 // Implementation ------------------------------------------------------------- | |
| 68 | |
| 58 // Implementation of a sorted vector for backing flat_set and flat_map. Do not | 69 // Implementation of a sorted vector for backing flat_set and flat_map. Do not |
| 59 // use directly. | 70 // use directly. |
| 60 // | 71 // |
| 61 // The use of "value" in this is like std::map uses, meaning it's the thing | 72 // The use of "value" in this is like std::map uses, meaning it's the thing |
| 62 // contained (in the case of map it's a <Kay, Mapped> pair). The Key is how | 73 // contained (in the case of map it's a <Kay, Mapped> pair). The Key is how |
| 63 // things are looked up. In the case of a set, Key == Value. In the case of | 74 // things are looked up. In the case of a set, Key == Value. In the case of |
| 64 // a map, the Key is a component of a Value. | 75 // a map, the Key is a component of a Value. |
| 65 // | 76 // |
| 66 // The helper class GetKeyFromValue provides the means to extract a key from a | 77 // The helper class GetKeyFromValue provides the means to extract a key from a |
| 67 // value for comparison purposes. It should implement: | 78 // value for comparison purposes. It should implement: |
| (...skipping 159 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 227 // Erase operations. | 238 // Erase operations. |
| 228 // | 239 // |
| 229 // Assume that every operation invalidates iterators and references. | 240 // Assume that every operation invalidates iterators and references. |
| 230 // | 241 // |
| 231 // erase(position), erase(first, last) can take O(size). | 242 // erase(position), erase(first, last) can take O(size). |
| 232 // erase(key) may take O(size) + O(log(size)). | 243 // erase(key) may take O(size) + O(log(size)). |
| 233 // | 244 // |
| 234 // Prefer base::EraseIf() or some other variation on erase(remove(), end()) | 245 // Prefer base::EraseIf() or some other variation on erase(remove(), end()) |
| 235 // idiom when deleting multiple non-consecutive elements. | 246 // idiom when deleting multiple non-consecutive elements. |
| 236 | 247 |
| 248 iterator erase(iterator position); | |
| 237 iterator erase(const_iterator position); | 249 iterator erase(const_iterator position); |
| 238 iterator erase(const_iterator first, const_iterator last); | 250 iterator erase(const_iterator first, const_iterator last); |
| 239 size_type erase(const key_type& key); | 251 template <typename K> |
| 252 size_type erase(const K& key); | |
| 240 | 253 |
| 241 // -------------------------------------------------------------------------- | 254 // -------------------------------------------------------------------------- |
| 242 // Comparators. | 255 // Comparators. |
| 243 | 256 |
| 244 key_compare key_comp() const; | 257 key_compare key_comp() const; |
| 245 value_compare value_comp() const; | 258 value_compare value_comp() const; |
| 246 | 259 |
| 247 // -------------------------------------------------------------------------- | 260 // -------------------------------------------------------------------------- |
| 248 // Search operations. | 261 // Search operations. |
| 249 // | 262 // |
| 250 // Search operations have O(log(size)) complexity. | 263 // Search operations have O(log(size)) complexity. |
| 251 | 264 |
| 252 size_type count(const key_type& key) const; | 265 template <typename K> |
| 266 size_type count(const K& key) const; | |
| 253 | 267 |
| 254 iterator find(const key_type& key); | 268 template <typename K> |
| 255 const_iterator find(const key_type& key) const; | 269 iterator find(const K& key); |
| 256 | 270 |
| 257 std::pair<iterator, iterator> equal_range(const key_type& ket); | 271 template <typename K> |
| 258 std::pair<const_iterator, const_iterator> equal_range( | 272 const_iterator find(const K& key) const; |
| 259 const key_type& key) const; | |
| 260 | 273 |
| 261 iterator lower_bound(const key_type& key); | 274 template <typename K> |
| 262 const_iterator lower_bound(const key_type& key) const; | 275 std::pair<iterator, iterator> equal_range(const K& key); |
| 263 | 276 |
| 264 iterator upper_bound(const key_type& key); | 277 template <typename K> |
| 265 const_iterator upper_bound(const key_type& key) const; | 278 std::pair<const_iterator, const_iterator> equal_range(const K& key) const; |
| 279 | |
| 280 template <typename K> | |
| 281 iterator lower_bound(const K& key); | |
| 282 | |
| 283 template <typename K> | |
| 284 const_iterator lower_bound(const K& key) const; | |
| 285 | |
| 286 template <typename K> | |
| 287 iterator upper_bound(const K& key); | |
| 288 | |
| 289 template <typename K> | |
| 290 const_iterator upper_bound(const K& key) const; | |
| 266 | 291 |
| 267 // -------------------------------------------------------------------------- | 292 // -------------------------------------------------------------------------- |
| 268 // General operations. | 293 // General operations. |
| 269 // | 294 // |
| 270 // Assume that swap invalidates iterators and references. | 295 // Assume that swap invalidates iterators and references. |
| 271 // | 296 // |
| 272 // Implementation note: currently we use operator==() and operator<() on | 297 // Implementation note: currently we use operator==() and operator<() on |
| 273 // std::vector, because they have the same contract we need, so we use them | 298 // std::vector, because they have the same contract we need, so we use them |
| 274 // directly for brevity and in case it is more optimal than calling equal() | 299 // directly for brevity and in case it is more optimal than calling equal() |
| 275 // and lexicograhpical_compare(). If the underlying container type is changed, | 300 // and lexicograhpical_compare(). If the underlying container type is changed, |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 310 iterator unsafe_emplace(const_iterator position, Args&&... args); | 335 iterator unsafe_emplace(const_iterator position, Args&&... args); |
| 311 | 336 |
| 312 private: | 337 private: |
| 313 // Helper class for e.g. lower_bound that can compare a value on the left | 338 // Helper class for e.g. lower_bound that can compare a value on the left |
| 314 // to a key on the right. | 339 // to a key on the right. |
| 315 struct KeyValueCompare { | 340 struct KeyValueCompare { |
| 316 // The key comparison object must outlive this class. | 341 // The key comparison object must outlive this class. |
| 317 explicit KeyValueCompare(const key_compare& key_comp) | 342 explicit KeyValueCompare(const key_compare& key_comp) |
| 318 : key_comp_(key_comp) {} | 343 : key_comp_(key_comp) {} |
| 319 | 344 |
| 320 bool operator()(const value_type& left, const key_type& right) const { | 345 template <typename T, typename U> |
| 321 GetKeyFromValue extractor; | 346 bool operator()(const T& lhs, const U& rhs) const { |
| 322 return key_comp_(extractor(left), right); | 347 return key_comp_(extract_if_value_type(lhs), extract_if_value_type(rhs)); |
| 323 } | 348 } |
| 324 | 349 |
| 325 private: | 350 private: |
| 351 const key_type& extract_if_value_type(const value_type& v) const { | |
| 352 GetKeyFromValue extractor; | |
| 353 return extractor(v); | |
| 354 } | |
| 355 | |
| 356 template <typename K> | |
| 357 const K& extract_if_value_type(const K& k) const { | |
| 358 return k; | |
| 359 } | |
| 360 | |
| 326 const key_compare& key_comp_; | 361 const key_compare& key_comp_; |
| 327 }; | 362 }; |
| 328 | 363 |
| 329 const flat_tree& as_const() { return *this; } | 364 const flat_tree& as_const() { return *this; } |
| 330 | 365 |
| 331 iterator const_cast_it(const_iterator c_it) { | 366 iterator const_cast_it(const_iterator c_it) { |
| 332 auto distance = std::distance(cbegin(), c_it); | 367 auto distance = std::distance(cbegin(), c_it); |
| 333 return std::next(begin(), distance); | 368 return std::next(begin(), distance); |
| 334 } | 369 } |
| 335 | 370 |
| (...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 429 template <class Cmp, class... Body> | 464 template <class Cmp, class... Body> |
| 430 explicit Impl(Cmp&& compare_arg, Body&&... underlying_type_args) | 465 explicit Impl(Cmp&& compare_arg, Body&&... underlying_type_args) |
| 431 : value_compare(std::forward<Cmp>(compare_arg)), | 466 : value_compare(std::forward<Cmp>(compare_arg)), |
| 432 body_(std::forward<Body>(underlying_type_args)...) {} | 467 body_(std::forward<Body>(underlying_type_args)...) {} |
| 433 | 468 |
| 434 const value_compare& get_value_comp() const { return *this; } | 469 const value_compare& get_value_comp() const { return *this; } |
| 435 const key_compare& get_key_comp() const { return *this; } | 470 const key_compare& get_key_comp() const { return *this; } |
| 436 | 471 |
| 437 underlying_type body_; | 472 underlying_type body_; |
| 438 } impl_; | 473 } impl_; |
| 474 | |
| 475 // If the compare is not transparent we want to construct key_type once. | |
| 476 template <typename K> | |
| 477 using PickConstReferenceTypeT = | |
|
vmpstr
2017/06/26 15:35:53
nit: Maybe KeyTypeOrT? I'd still weakly prefer thi
dyaroshev
2017/06/26 16:19:28
Done.
| |
| 478 typename std::conditional<IsTransparentCompare<key_compare>::value, | |
| 479 const K&, | |
| 480 const key_type&>::type; | |
| 439 }; | 481 }; |
| 440 | 482 |
| 441 // ---------------------------------------------------------------------------- | 483 // ---------------------------------------------------------------------------- |
| 442 // Lifetime. | 484 // Lifetime. |
| 443 | 485 |
| 444 template <class Key, class Value, class GetKeyFromValue, class KeyCompare> | 486 template <class Key, class Value, class GetKeyFromValue, class KeyCompare> |
| 445 flat_tree<Key, Value, GetKeyFromValue, KeyCompare>::flat_tree() = default; | 487 flat_tree<Key, Value, GetKeyFromValue, KeyCompare>::flat_tree() = default; |
| 446 | 488 |
| 447 template <class Key, class Value, class GetKeyFromValue, class KeyCompare> | 489 template <class Key, class Value, class GetKeyFromValue, class KeyCompare> |
| 448 flat_tree<Key, Value, GetKeyFromValue, KeyCompare>::flat_tree( | 490 flat_tree<Key, Value, GetKeyFromValue, KeyCompare>::flat_tree( |
| (...skipping 311 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 760 const_iterator position_hint, | 802 const_iterator position_hint, |
| 761 Args&&... args) -> iterator { | 803 Args&&... args) -> iterator { |
| 762 return insert(position_hint, value_type(std::forward<Args>(args)...)); | 804 return insert(position_hint, value_type(std::forward<Args>(args)...)); |
| 763 } | 805 } |
| 764 | 806 |
| 765 // ---------------------------------------------------------------------------- | 807 // ---------------------------------------------------------------------------- |
| 766 // Erase operations. | 808 // Erase operations. |
| 767 | 809 |
| 768 template <class Key, class Value, class GetKeyFromValue, class KeyCompare> | 810 template <class Key, class Value, class GetKeyFromValue, class KeyCompare> |
| 769 auto flat_tree<Key, Value, GetKeyFromValue, KeyCompare>::erase( | 811 auto flat_tree<Key, Value, GetKeyFromValue, KeyCompare>::erase( |
| 812 iterator position) -> iterator { | |
| 813 return impl_.body_.erase(position); | |
| 814 } | |
| 815 | |
| 816 template <class Key, class Value, class GetKeyFromValue, class KeyCompare> | |
| 817 auto flat_tree<Key, Value, GetKeyFromValue, KeyCompare>::erase( | |
| 770 const_iterator position) -> iterator { | 818 const_iterator position) -> iterator { |
| 771 // We have to cast away const because of crbug.com/677044. | 819 // We have to cast away const because of crbug.com/677044. |
| 772 return impl_.body_.erase(const_cast_it(position)); | 820 return erase(const_cast_it(position)); |
| 773 } | 821 } |
| 774 | 822 |
| 775 template <class Key, class Value, class GetKeyFromValue, class KeyCompare> | 823 template <class Key, class Value, class GetKeyFromValue, class KeyCompare> |
| 776 auto flat_tree<Key, Value, GetKeyFromValue, KeyCompare>::erase( | 824 template <typename K> |
| 777 const key_type& val) -> size_type { | 825 auto flat_tree<Key, Value, GetKeyFromValue, KeyCompare>::erase(const K& val) |
| 826 -> size_type { | |
| 778 auto eq_range = equal_range(val); | 827 auto eq_range = equal_range(val); |
| 779 auto res = std::distance(eq_range.first, eq_range.second); | 828 auto res = std::distance(eq_range.first, eq_range.second); |
| 780 // We have to cast away const because of crbug.com/677044. | 829 // We have to cast away const because of crbug.com/677044. |
| 781 erase(const_cast_it(eq_range.first), const_cast_it(eq_range.second)); | 830 erase(const_cast_it(eq_range.first), const_cast_it(eq_range.second)); |
| 782 return res; | 831 return res; |
| 783 } | 832 } |
| 784 | 833 |
| 785 template <class Key, class Value, class GetKeyFromValue, class KeyCompare> | 834 template <class Key, class Value, class GetKeyFromValue, class KeyCompare> |
| 786 auto flat_tree<Key, Value, GetKeyFromValue, KeyCompare>::erase( | 835 auto flat_tree<Key, Value, GetKeyFromValue, KeyCompare>::erase( |
| 787 const_iterator first, | 836 const_iterator first, |
| (...skipping 14 matching lines...) Expand all Loading... | |
| 802 template <class Key, class Value, class GetKeyFromValue, class KeyCompare> | 851 template <class Key, class Value, class GetKeyFromValue, class KeyCompare> |
| 803 auto flat_tree<Key, Value, GetKeyFromValue, KeyCompare>::value_comp() const | 852 auto flat_tree<Key, Value, GetKeyFromValue, KeyCompare>::value_comp() const |
| 804 -> value_compare { | 853 -> value_compare { |
| 805 return impl_.get_value_comp(); | 854 return impl_.get_value_comp(); |
| 806 } | 855 } |
| 807 | 856 |
| 808 // ---------------------------------------------------------------------------- | 857 // ---------------------------------------------------------------------------- |
| 809 // Search operations. | 858 // Search operations. |
| 810 | 859 |
| 811 template <class Key, class Value, class GetKeyFromValue, class KeyCompare> | 860 template <class Key, class Value, class GetKeyFromValue, class KeyCompare> |
| 861 template <typename K> | |
| 812 auto flat_tree<Key, Value, GetKeyFromValue, KeyCompare>::count( | 862 auto flat_tree<Key, Value, GetKeyFromValue, KeyCompare>::count( |
| 813 const key_type& key) const -> size_type { | 863 const K& key) const -> size_type { |
| 814 auto eq_range = equal_range(key); | 864 auto eq_range = equal_range(key); |
| 815 return std::distance(eq_range.first, eq_range.second); | 865 return std::distance(eq_range.first, eq_range.second); |
| 816 } | 866 } |
| 817 | 867 |
| 818 template <class Key, class Value, class GetKeyFromValue, class KeyCompare> | 868 template <class Key, class Value, class GetKeyFromValue, class KeyCompare> |
| 819 auto flat_tree<Key, Value, GetKeyFromValue, KeyCompare>::find( | 869 template <typename K> |
| 820 const key_type& key) -> iterator { | 870 auto flat_tree<Key, Value, GetKeyFromValue, KeyCompare>::find(const K& key) |
| 871 -> iterator { | |
| 821 return const_cast_it(as_const().find(key)); | 872 return const_cast_it(as_const().find(key)); |
| 822 } | 873 } |
| 823 | 874 |
| 824 template <class Key, class Value, class GetKeyFromValue, class KeyCompare> | 875 template <class Key, class Value, class GetKeyFromValue, class KeyCompare> |
| 876 template <typename K> | |
| 825 auto flat_tree<Key, Value, GetKeyFromValue, KeyCompare>::find( | 877 auto flat_tree<Key, Value, GetKeyFromValue, KeyCompare>::find( |
| 826 const key_type& key) const -> const_iterator { | 878 const K& key) const -> const_iterator { |
| 827 auto eq_range = equal_range(key); | 879 auto eq_range = equal_range(key); |
| 828 return (eq_range.first == eq_range.second) ? end() : eq_range.first; | 880 return (eq_range.first == eq_range.second) ? end() : eq_range.first; |
| 829 } | 881 } |
| 830 | 882 |
| 831 template <class Key, class Value, class GetKeyFromValue, class KeyCompare> | 883 template <class Key, class Value, class GetKeyFromValue, class KeyCompare> |
| 884 template <typename K> | |
| 832 auto flat_tree<Key, Value, GetKeyFromValue, KeyCompare>::equal_range( | 885 auto flat_tree<Key, Value, GetKeyFromValue, KeyCompare>::equal_range( |
| 833 const key_type& key) -> std::pair<iterator, iterator> { | 886 const K& key) -> std::pair<iterator, iterator> { |
| 834 auto res = as_const().equal_range(key); | 887 auto res = as_const().equal_range(key); |
| 835 return {const_cast_it(res.first), const_cast_it(res.second)}; | 888 return {const_cast_it(res.first), const_cast_it(res.second)}; |
| 836 } | 889 } |
| 837 | 890 |
| 838 template <class Key, class Value, class GetKeyFromValue, class KeyCompare> | 891 template <class Key, class Value, class GetKeyFromValue, class KeyCompare> |
| 892 template <typename K> | |
| 839 auto flat_tree<Key, Value, GetKeyFromValue, KeyCompare>::equal_range( | 893 auto flat_tree<Key, Value, GetKeyFromValue, KeyCompare>::equal_range( |
| 840 const key_type& key) const -> std::pair<const_iterator, const_iterator> { | 894 const K& key) const -> std::pair<const_iterator, const_iterator> { |
| 841 auto lower = lower_bound(key); | 895 auto lower = lower_bound(key); |
| 842 | 896 |
| 843 GetKeyFromValue extractor; | 897 GetKeyFromValue extractor; |
| 844 if (lower == end() || impl_.get_key_comp()(key, extractor(*lower))) | 898 if (lower == end() || impl_.get_key_comp()(key, extractor(*lower))) |
| 845 return {lower, lower}; | 899 return {lower, lower}; |
| 846 | 900 |
| 847 return {lower, std::next(lower)}; | 901 return {lower, std::next(lower)}; |
| 848 } | 902 } |
| 849 | 903 |
| 850 template <class Key, class Value, class GetKeyFromValue, class KeyCompare> | 904 template <class Key, class Value, class GetKeyFromValue, class KeyCompare> |
| 905 template <typename K> | |
| 851 auto flat_tree<Key, Value, GetKeyFromValue, KeyCompare>::lower_bound( | 906 auto flat_tree<Key, Value, GetKeyFromValue, KeyCompare>::lower_bound( |
| 852 const key_type& key) -> iterator { | 907 const K& key) -> iterator { |
| 853 return const_cast_it(as_const().lower_bound(key)); | 908 return const_cast_it(as_const().lower_bound(key)); |
| 854 } | 909 } |
| 855 | 910 |
| 856 template <class Key, class Value, class GetKeyFromValue, class KeyCompare> | 911 template <class Key, class Value, class GetKeyFromValue, class KeyCompare> |
| 912 template <typename K> | |
| 857 auto flat_tree<Key, Value, GetKeyFromValue, KeyCompare>::lower_bound( | 913 auto flat_tree<Key, Value, GetKeyFromValue, KeyCompare>::lower_bound( |
| 858 const key_type& key) const -> const_iterator { | 914 const K& key) const -> const_iterator { |
| 915 // Only compile when conversion is implicit. | |
|
vmpstr
2017/06/26 15:35:53
I'm not sure what this comment is referring to. Th
dyaroshev
2017/06/26 16:19:28
This is about using assignment over operator().
T
| |
| 916 PickConstReferenceTypeT<K> key_ref = key; | |
| 917 | |
| 859 KeyValueCompare key_value(impl_.get_key_comp()); | 918 KeyValueCompare key_value(impl_.get_key_comp()); |
| 860 return std::lower_bound(begin(), end(), key, key_value); | 919 return std::lower_bound(begin(), end(), key_ref, key_value); |
| 861 } | 920 } |
| 862 | 921 |
| 863 template <class Key, class Value, class GetKeyFromValue, class KeyCompare> | 922 template <class Key, class Value, class GetKeyFromValue, class KeyCompare> |
| 923 template <typename K> | |
| 864 auto flat_tree<Key, Value, GetKeyFromValue, KeyCompare>::upper_bound( | 924 auto flat_tree<Key, Value, GetKeyFromValue, KeyCompare>::upper_bound( |
| 865 const key_type& key) -> iterator { | 925 const K& key) -> iterator { |
| 866 return const_cast_it(as_const().upper_bound(key)); | 926 return const_cast_it(as_const().upper_bound(key)); |
| 867 } | 927 } |
| 868 | 928 |
| 869 template <class Key, class Value, class GetKeyFromValue, class KeyCompare> | 929 template <class Key, class Value, class GetKeyFromValue, class KeyCompare> |
| 930 template <typename K> | |
| 870 auto flat_tree<Key, Value, GetKeyFromValue, KeyCompare>::upper_bound( | 931 auto flat_tree<Key, Value, GetKeyFromValue, KeyCompare>::upper_bound( |
| 871 const key_type& key) const -> const_iterator { | 932 const K& key) const -> const_iterator { |
| 872 KeyValueCompare key_value(impl_.get_key_comp()); | 933 KeyValueCompare key_value(impl_.get_key_comp()); |
| 873 return std::upper_bound(begin(), end(), key, key_value); | 934 |
| 935 // Only compile when conversion is implicit. | |
| 936 PickConstReferenceTypeT<K> key_ref = key; | |
| 937 return std::upper_bound(begin(), end(), key_ref, key_value); | |
| 874 } | 938 } |
| 875 | 939 |
| 876 // ---------------------------------------------------------------------------- | 940 // ---------------------------------------------------------------------------- |
| 877 // General operations. | 941 // General operations. |
| 878 | 942 |
| 879 template <class Key, class Value, class GetKeyFromValue, class KeyCompare> | 943 template <class Key, class Value, class GetKeyFromValue, class KeyCompare> |
| 880 void flat_tree<Key, Value, GetKeyFromValue, KeyCompare>::swap( | 944 void flat_tree<Key, Value, GetKeyFromValue, KeyCompare>::swap( |
| 881 flat_tree& other) { | 945 flat_tree& other) { |
| 882 std::swap(impl_, other.impl_); | 946 std::swap(impl_, other.impl_); |
| 883 } | 947 } |
| (...skipping 29 matching lines...) Expand all Loading... | |
| 913 void EraseIf(base::internal::flat_tree<Key, Value, GetKeyFromValue, KeyCompare>& | 977 void EraseIf(base::internal::flat_tree<Key, Value, GetKeyFromValue, KeyCompare>& |
| 914 container, | 978 container, |
| 915 Predicate pred) { | 979 Predicate pred) { |
| 916 container.erase(std::remove_if(container.begin(), container.end(), pred), | 980 container.erase(std::remove_if(container.begin(), container.end(), pred), |
| 917 container.end()); | 981 container.end()); |
| 918 } | 982 } |
| 919 | 983 |
| 920 } // namespace base | 984 } // namespace base |
| 921 | 985 |
| 922 #endif // BASE_CONTAINERS_FLAT_TREE_H_ | 986 #endif // BASE_CONTAINERS_FLAT_TREE_H_ |
| OLD | NEW |