Chromium Code Reviews| 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 |