xref: /llvm-project/libcxx/include/__algorithm/unique_copy.h (revision 7b4622514d232ce5f7110dd8b20d90e81127c467)
1134723edSLouis Dionne //===----------------------------------------------------------------------===//
2134723edSLouis Dionne //
3134723edSLouis Dionne // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4134723edSLouis Dionne // See https://llvm.org/LICENSE.txt for license information.
5134723edSLouis Dionne // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6134723edSLouis Dionne //
7134723edSLouis Dionne //===----------------------------------------------------------------------===//
8134723edSLouis Dionne 
9134723edSLouis Dionne #ifndef _LIBCPP___ALGORITHM_UNIQUE_COPY_H
10134723edSLouis Dionne #define _LIBCPP___ALGORITHM_UNIQUE_COPY_H
11134723edSLouis Dionne 
12134723edSLouis Dionne #include <__algorithm/comp.h>
1372f57e3aSHui Xie #include <__algorithm/iterator_operations.h>
144d81a46fSArthur O'Dwyer #include <__config>
15134723edSLouis Dionne #include <__iterator/iterator_traits.h>
1672f57e3aSHui Xie #include <__type_traits/conditional.h>
1772f57e3aSHui Xie #include <__type_traits/is_base_of.h>
1872f57e3aSHui Xie #include <__type_traits/is_same.h>
1972f57e3aSHui Xie #include <__utility/move.h>
2072f57e3aSHui Xie #include <__utility/pair.h>
21134723edSLouis Dionne 
22134723edSLouis Dionne #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
23134723edSLouis Dionne #  pragma GCC system_header
24134723edSLouis Dionne #endif
25134723edSLouis Dionne 
26*7b462251SLouis Dionne _LIBCPP_PUSH_MACROS
27*7b462251SLouis Dionne #include <__undef_macros>
28*7b462251SLouis Dionne 
29134723edSLouis Dionne _LIBCPP_BEGIN_NAMESPACE_STD
30134723edSLouis Dionne 
3172f57e3aSHui Xie namespace __unique_copy_tags {
3272f57e3aSHui Xie 
3372f57e3aSHui Xie struct __reread_from_input_tag {};
3472f57e3aSHui Xie struct __reread_from_output_tag {};
3572f57e3aSHui Xie struct __read_from_tmp_value_tag {};
3672f57e3aSHui Xie 
3772f57e3aSHui Xie } // namespace __unique_copy_tags
3872f57e3aSHui Xie 
3972f57e3aSHui Xie template <class _AlgPolicy, class _BinaryPredicate, class _InputIterator, class _Sent, class _OutputIterator>
405146b57bSNikolas Klauser _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI pair<_InputIterator, _OutputIterator>
__unique_copy(_InputIterator __first,_Sent __last,_OutputIterator __result,_BinaryPredicate && __pred,__unique_copy_tags::__read_from_tmp_value_tag)4172f57e3aSHui Xie __unique_copy(_InputIterator __first,
4272f57e3aSHui Xie               _Sent __last,
4372f57e3aSHui Xie               _OutputIterator __result,
4472f57e3aSHui Xie               _BinaryPredicate&& __pred,
4572f57e3aSHui Xie               __unique_copy_tags::__read_from_tmp_value_tag) {
4672f57e3aSHui Xie   if (__first != __last) {
4772f57e3aSHui Xie     typename _IterOps<_AlgPolicy>::template __value_type<_InputIterator> __t(*__first);
48134723edSLouis Dionne     *__result = __t;
49134723edSLouis Dionne     ++__result;
5072f57e3aSHui Xie     while (++__first != __last) {
5172f57e3aSHui Xie       if (!__pred(__t, *__first)) {
52134723edSLouis Dionne         __t       = *__first;
53134723edSLouis Dionne         *__result = __t;
54134723edSLouis Dionne         ++__result;
55134723edSLouis Dionne       }
56134723edSLouis Dionne     }
57134723edSLouis Dionne   }
5872f57e3aSHui Xie   return pair<_InputIterator, _OutputIterator>(std::move(__first), std::move(__result));
59134723edSLouis Dionne }
60134723edSLouis Dionne 
6172f57e3aSHui Xie template <class _AlgPolicy, class _BinaryPredicate, class _ForwardIterator, class _Sent, class _OutputIterator>
625146b57bSNikolas Klauser _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI pair<_ForwardIterator, _OutputIterator>
__unique_copy(_ForwardIterator __first,_Sent __last,_OutputIterator __result,_BinaryPredicate && __pred,__unique_copy_tags::__reread_from_input_tag)6372f57e3aSHui Xie __unique_copy(_ForwardIterator __first,
6472f57e3aSHui Xie               _Sent __last,
6572f57e3aSHui Xie               _OutputIterator __result,
6672f57e3aSHui Xie               _BinaryPredicate&& __pred,
6772f57e3aSHui Xie               __unique_copy_tags::__reread_from_input_tag) {
6872f57e3aSHui Xie   if (__first != __last) {
69134723edSLouis Dionne     _ForwardIterator __i = __first;
70134723edSLouis Dionne     *__result            = *__i;
71134723edSLouis Dionne     ++__result;
7272f57e3aSHui Xie     while (++__first != __last) {
7372f57e3aSHui Xie       if (!__pred(*__i, *__first)) {
74134723edSLouis Dionne         *__result = *__first;
75134723edSLouis Dionne         ++__result;
76134723edSLouis Dionne         __i = __first;
77134723edSLouis Dionne       }
78134723edSLouis Dionne     }
79134723edSLouis Dionne   }
8072f57e3aSHui Xie   return pair<_ForwardIterator, _OutputIterator>(std::move(__first), std::move(__result));
81134723edSLouis Dionne }
82134723edSLouis Dionne 
8372f57e3aSHui Xie template <class _AlgPolicy, class _BinaryPredicate, class _InputIterator, class _Sent, class _InputAndOutputIterator>
845146b57bSNikolas Klauser _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI pair<_InputIterator, _InputAndOutputIterator>
__unique_copy(_InputIterator __first,_Sent __last,_InputAndOutputIterator __result,_BinaryPredicate && __pred,__unique_copy_tags::__reread_from_output_tag)8572f57e3aSHui Xie __unique_copy(_InputIterator __first,
8672f57e3aSHui Xie               _Sent __last,
8772f57e3aSHui Xie               _InputAndOutputIterator __result,
8872f57e3aSHui Xie               _BinaryPredicate&& __pred,
8972f57e3aSHui Xie               __unique_copy_tags::__reread_from_output_tag) {
9072f57e3aSHui Xie   if (__first != __last) {
91134723edSLouis Dionne     *__result = *__first;
92134723edSLouis Dionne     while (++__first != __last)
93134723edSLouis Dionne       if (!__pred(*__result, *__first))
94134723edSLouis Dionne         *++__result = *__first;
95134723edSLouis Dionne     ++__result;
96134723edSLouis Dionne   }
9772f57e3aSHui Xie   return pair<_InputIterator, _InputAndOutputIterator>(std::move(__first), std::move(__result));
98134723edSLouis Dionne }
99134723edSLouis Dionne 
100134723edSLouis Dionne template <class _InputIterator, class _OutputIterator, class _BinaryPredicate>
1015146b57bSNikolas Klauser inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _OutputIterator
unique_copy(_InputIterator __first,_InputIterator __last,_OutputIterator __result,_BinaryPredicate __pred)10272f57e3aSHui Xie unique_copy(_InputIterator __first, _InputIterator __last, _OutputIterator __result, _BinaryPredicate __pred) {
103ed2d3644SNikolas Klauser   using __algo_tag = __conditional_t<
10472f57e3aSHui Xie       is_base_of<forward_iterator_tag, typename iterator_traits<_InputIterator>::iterator_category>::value,
10572f57e3aSHui Xie       __unique_copy_tags::__reread_from_input_tag,
106ed2d3644SNikolas Klauser       __conditional_t<
10772f57e3aSHui Xie           is_base_of<forward_iterator_tag, typename iterator_traits<_OutputIterator>::iterator_category>::value &&
10872f57e3aSHui Xie               is_same< typename iterator_traits<_InputIterator>::value_type,
10972f57e3aSHui Xie                        typename iterator_traits<_OutputIterator>::value_type>::value,
11072f57e3aSHui Xie           __unique_copy_tags::__reread_from_output_tag,
111ed2d3644SNikolas Klauser           __unique_copy_tags::__read_from_tmp_value_tag> >;
11272f57e3aSHui Xie   return std::__unique_copy<_ClassicAlgPolicy>(
11372f57e3aSHui Xie              std::move(__first), std::move(__last), std::move(__result), __pred, __algo_tag())
11472f57e3aSHui Xie       .second;
115134723edSLouis Dionne }
116134723edSLouis Dionne 
117134723edSLouis Dionne template <class _InputIterator, class _OutputIterator>
1185146b57bSNikolas Klauser inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _OutputIterator
unique_copy(_InputIterator __first,_InputIterator __last,_OutputIterator __result)11972f57e3aSHui Xie unique_copy(_InputIterator __first, _InputIterator __last, _OutputIterator __result) {
120e07ca2aeSAlvin Wong   return std::unique_copy(std::move(__first), std::move(__last), std::move(__result), __equal_to());
121134723edSLouis Dionne }
122134723edSLouis Dionne 
123134723edSLouis Dionne _LIBCPP_END_NAMESPACE_STD
124134723edSLouis Dionne 
125*7b462251SLouis Dionne _LIBCPP_POP_MACROS
126*7b462251SLouis Dionne 
127134723edSLouis Dionne #endif // _LIBCPP___ALGORITHM_UNIQUE_COPY_H
128