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 |