Index: base/algorithm/sorted_ranges.h |
diff --git a/base/algorithm/sorted_ranges.h b/base/algorithm/sorted_ranges.h |
new file mode 100644 |
index 0000000000000000000000000000000000000000..97bed02a3d97fe284b35221e490f21c3361e6769 |
--- /dev/null |
+++ b/base/algorithm/sorted_ranges.h |
@@ -0,0 +1,70 @@ |
+// Copyright 2017 The Chromium Authors. All rights reserved. |
+// Use of this source code is governed by a BSD-style license that can be |
+// found in the LICENSE file. |
+ |
+#ifndef BASE_ALGORITHM_SORTED_RANGES_H_ |
+#define BASE_ALGORITHM_SORTED_RANGES_H_ |
+ |
+#include <algorithm> |
+#include <functional> |
+#include <iterator> |
+ |
+namespace base { |
+ |
+//---------------------------------------------------------------------------- |
+// UniquePickLast/UniqueCopyPickLast are algorithms modeled after |
+// std::unique/std::unique_copy but instead of choosing first equal element in |
+// the equal group, they choose last. |
dyaroshev
2017/04/08 17:03:12
but they keep the last element in the group of equ
|
+ |
+template <typename InputIterator, |
+ typename OutputIterator, |
+ typename BinaryPredicate> |
+OutputIterator UniqueCopyPickLast(InputIterator first, |
+ InputIterator last, |
+ OutputIterator out, |
+ BinaryPredicate pred) { |
+ if (first == last) |
+ return out; |
+ |
+ // adjacent_find will force us to use BidirectionalIterator. |
+ // to get the previous element. |
+ for (InputIterator next = std::next(first); next != last; ++next, ++first) |
+ if (!pred(*first, *next)) |
+ *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
|
+ |
+ // last element should be copied unconditionally. |
+ *out++ = *first; |
+ |
+ return out; |
+} |
+ |
+template <typename InputIterator, typename OutputIterator> |
+OutputIterator UniqueCopyPickLast(InputIterator first, |
+ InputIterator last, |
+ OutputIterator out) { |
+ using ValueType = typename std::iterator_traits<InputIterator>::value_type; |
+ return UniqueCopyPickLast(first, last, out, std::equal_to<ValueType>{}); |
+} |
+ |
+template <typename ForwardIterator, typename BinaryPredicate> |
+ForwardIterator UniquePickLast(ForwardIterator first, |
+ ForwardIterator last, |
+ BinaryPredicate pred) { |
+ ForwardIterator replacable = std::adjacent_find(first, last, pred); |
+ return (replacable == last) |
+ ? last |
+ : UniqueCopyPickLast( |
+ std::next(std::make_move_iterator(replacable)), |
+ std::make_move_iterator(last), replacable, pred); |
+} |
+ |
+template <typename ForwardIterator> |
+ForwardIterator UniquePickLast(ForwardIterator first, ForwardIterator last) { |
+ using ValueType = typename std::iterator_traits<ForwardIterator>::value_type; |
+ |
+ return UniquePickLast(first, last, std::equal_to<ValueType>{}); |
+} |
+ |
+} // namespace base |
+ |
+#endif // BASE_ALGORITHM_SORTED_RANGES_H_ |