OLD | NEW |
---|---|
(Empty) | |
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 | |
3 // found in the LICENSE file. | |
4 | |
5 #ifndef BASE_ALGORITHM_SORTED_RANGES_H_ | |
6 #define BASE_ALGORITHM_SORTED_RANGES_H_ | |
7 | |
8 #include <algorithm> | |
9 #include <functional> | |
10 #include <iterator> | |
11 | |
12 namespace base { | |
13 | |
14 //---------------------------------------------------------------------------- | |
15 // UniquePickLast/UniqueCopyPickLast are algorithms modeled after | |
16 // std::unique/std::unique_copy but instead of choosing first equal element in | |
17 // the equal group, they choose last. | |
dyaroshev
2017/04/08 17:03:12
but they keep the last element in the group of equ
| |
18 | |
19 template <typename InputIterator, | |
20 typename OutputIterator, | |
21 typename BinaryPredicate> | |
22 OutputIterator UniqueCopyPickLast(InputIterator first, | |
23 InputIterator last, | |
24 OutputIterator out, | |
25 BinaryPredicate pred) { | |
26 if (first == last) | |
27 return out; | |
28 | |
29 // adjacent_find will force us to use BidirectionalIterator. | |
30 // to get the previous element. | |
31 for (InputIterator next = std::next(first); next != last; ++next, ++first) | |
32 if (!pred(*first, *next)) | |
33 *out++ = *first; | |
danakj
2017/04/12 15:54:48
Wouldn't this preclude the container from holding
dyaroshev
2017/04/12 16:00:01
This algorithm should not move elements - it's a c
| |
34 | |
35 // last element should be copied unconditionally. | |
36 *out++ = *first; | |
37 | |
38 return out; | |
39 } | |
40 | |
41 template <typename InputIterator, typename OutputIterator> | |
42 OutputIterator UniqueCopyPickLast(InputIterator first, | |
43 InputIterator last, | |
44 OutputIterator out) { | |
45 using ValueType = typename std::iterator_traits<InputIterator>::value_type; | |
46 return UniqueCopyPickLast(first, last, out, std::equal_to<ValueType>{}); | |
47 } | |
48 | |
49 template <typename ForwardIterator, typename BinaryPredicate> | |
50 ForwardIterator UniquePickLast(ForwardIterator first, | |
51 ForwardIterator last, | |
52 BinaryPredicate pred) { | |
53 ForwardIterator replacable = std::adjacent_find(first, last, pred); | |
54 return (replacable == last) | |
55 ? last | |
56 : UniqueCopyPickLast( | |
57 std::next(std::make_move_iterator(replacable)), | |
58 std::make_move_iterator(last), replacable, pred); | |
59 } | |
60 | |
61 template <typename ForwardIterator> | |
62 ForwardIterator UniquePickLast(ForwardIterator first, ForwardIterator last) { | |
63 using ValueType = typename std::iterator_traits<ForwardIterator>::value_type; | |
64 | |
65 return UniquePickLast(first, last, std::equal_to<ValueType>{}); | |
66 } | |
67 | |
68 } // namespace base | |
69 | |
70 #endif // BASE_ALGORITHM_SORTED_RANGES_H_ | |
OLD | NEW |