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 <vector> | 9 #include <vector> |
| 10 | 10 |
| 11 #include "base/algorithm/sorted_ranges.h" | |
| 12 | |
| 11 namespace base { | 13 namespace base { |
| 12 | 14 |
| 13 enum FlatContainerDupes { | 15 enum FlatContainerDupes { |
| 14 KEEP_FIRST_OF_DUPES, | 16 KEEP_FIRST_OF_DUPES, |
| 15 KEEP_LAST_OF_DUPES, | 17 KEEP_LAST_OF_DUPES, |
| 16 }; | 18 }; |
| 17 | 19 |
| 18 namespace internal { | 20 namespace internal { |
| 19 | 21 |
| 20 // This algorithm is like unique() from the standard library except it | |
| 21 // selects only the last of consecutive values instead of the first. | |
| 22 template <class Iterator, class BinaryPredicate> | |
| 23 Iterator LastUnique(Iterator first, Iterator last, BinaryPredicate compare) { | |
| 24 if (first == last) | |
| 25 return last; | |
| 26 | |
| 27 Iterator dest = first; | |
| 28 Iterator cur = first; | |
| 29 Iterator prev = cur; | |
| 30 while (++cur != last) { | |
| 31 if (!compare(*prev, *cur)) { | |
| 32 // Non-identical one. | |
| 33 if (dest != prev) | |
|
dyaroshev
2017/04/08 16:48:03
I suspect, that the main reason why this way is sl
| |
| 34 *dest = std::move(*prev); | |
| 35 ++dest; | |
| 36 } | |
| 37 prev = cur; | |
| 38 } | |
| 39 | |
| 40 if (dest != prev) | |
| 41 *dest = std::move(*prev); | |
| 42 return ++dest; | |
| 43 } | |
| 44 | |
| 45 // Implementation of a sorted vector for backing flat_set and flat_map. Do not | 22 // Implementation of a sorted vector for backing flat_set and flat_map. Do not |
| 46 // use directly. | 23 // use directly. |
| 47 // | 24 // |
| 48 // The use of "value" in this is like std::map uses, meaning it's the thing | 25 // The use of "value" in this is like std::map uses, meaning it's the thing |
| 49 // contained (in the case of map it's a <Kay, Mapped> pair). The Key is how | 26 // contained (in the case of map it's a <Kay, Mapped> pair). The Key is how |
| 50 // things are looked up. In the case of a set, Key == Value. In the case of | 27 // things are looked up. In the case of a set, Key == Value. In the case of |
| 51 // a map, the Key is a component of a Value. | 28 // a map, the Key is a component of a Value. |
| 52 // | 29 // |
| 53 // The helper class GetKeyFromValue provides the means to extract a key from a | 30 // The helper class GetKeyFromValue provides the means to extract a key from a |
| 54 // value for comparison purposes. It should implement: | 31 // value for comparison purposes. It should implement: |
| (...skipping 267 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 322 // !(lhs < rhs) <=> lhs == rhs. | 299 // !(lhs < rhs) <=> lhs == rhs. |
| 323 return !impl_.get_value_comp()(lhs, rhs); | 300 return !impl_.get_value_comp()(lhs, rhs); |
| 324 }; | 301 }; |
| 325 | 302 |
| 326 iterator erase_after; | 303 iterator erase_after; |
| 327 switch (dupes) { | 304 switch (dupes) { |
| 328 case KEEP_FIRST_OF_DUPES: | 305 case KEEP_FIRST_OF_DUPES: |
| 329 erase_after = std::unique(begin(), end(), comparator); | 306 erase_after = std::unique(begin(), end(), comparator); |
| 330 break; | 307 break; |
| 331 case KEEP_LAST_OF_DUPES: | 308 case KEEP_LAST_OF_DUPES: |
| 332 erase_after = LastUnique(begin(), end(), comparator); | 309 erase_after = UniquePickLast(begin(), end(), comparator); |
| 333 break; | 310 break; |
| 334 } | 311 } |
| 335 erase(erase_after, end()); | 312 erase(erase_after, end()); |
| 336 } | 313 } |
| 337 | 314 |
| 338 // To support comparators that may not be possible to default-construct, we | 315 // To support comparators that may not be possible to default-construct, we |
| 339 // have to store an instance of Compare. Using this to store all internal | 316 // have to store an instance of Compare. Using this to store all internal |
| 340 // state of flat_tree and using private inheritance to store compare lets us | 317 // state of flat_tree and using private inheritance to store compare lets us |
| 341 // take advantage of an empty base class optimization to avoid extra space in | 318 // take advantage of an empty base class optimization to avoid extra space in |
| 342 // the common case when Compare has no state. | 319 // the common case when Compare has no state. |
| (...skipping 422 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 765 void EraseIf(base::internal::flat_tree<Key, Value, GetKeyFromValue, KeyCompare>& | 742 void EraseIf(base::internal::flat_tree<Key, Value, GetKeyFromValue, KeyCompare>& |
| 766 container, | 743 container, |
| 767 Predicate pred) { | 744 Predicate pred) { |
| 768 container.erase(std::remove_if(container.begin(), container.end(), pred), | 745 container.erase(std::remove_if(container.begin(), container.end(), pred), |
| 769 container.end()); | 746 container.end()); |
| 770 } | 747 } |
| 771 | 748 |
| 772 } // namespace base | 749 } // namespace base |
| 773 | 750 |
| 774 #endif // BASE_CONTAINERS_FLAT_TREE_H_ | 751 #endif // BASE_CONTAINERS_FLAT_TREE_H_ |
| OLD | NEW |