xref: /openbsd-src/gnu/llvm/libcxx/include/__algorithm/unique_copy.h (revision 4bdff4bed0e3d54e55670334c7d0077db4170f86)
176d0caaeSpatrick //===----------------------------------------------------------------------===//
276d0caaeSpatrick //
376d0caaeSpatrick // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
476d0caaeSpatrick // See https://llvm.org/LICENSE.txt for license information.
576d0caaeSpatrick // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
676d0caaeSpatrick //
776d0caaeSpatrick //===----------------------------------------------------------------------===//
876d0caaeSpatrick 
976d0caaeSpatrick #ifndef _LIBCPP___ALGORITHM_UNIQUE_COPY_H
1076d0caaeSpatrick #define _LIBCPP___ALGORITHM_UNIQUE_COPY_H
1176d0caaeSpatrick 
1276d0caaeSpatrick #include <__algorithm/comp.h>
13*4bdff4beSrobert #include <__algorithm/iterator_operations.h>
14*4bdff4beSrobert #include <__config>
1576d0caaeSpatrick #include <__iterator/iterator_traits.h>
16*4bdff4beSrobert #include <__type_traits/conditional.h>
17*4bdff4beSrobert #include <__type_traits/is_base_of.h>
18*4bdff4beSrobert #include <__type_traits/is_same.h>
19*4bdff4beSrobert #include <__utility/move.h>
20*4bdff4beSrobert #include <__utility/pair.h>
2176d0caaeSpatrick 
2276d0caaeSpatrick #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
2376d0caaeSpatrick #  pragma GCC system_header
2476d0caaeSpatrick #endif
2576d0caaeSpatrick 
2676d0caaeSpatrick _LIBCPP_BEGIN_NAMESPACE_STD
2776d0caaeSpatrick 
28*4bdff4beSrobert namespace __unique_copy_tags {
29*4bdff4beSrobert 
30*4bdff4beSrobert struct __reread_from_input_tag {};
31*4bdff4beSrobert struct __reread_from_output_tag {};
32*4bdff4beSrobert struct __read_from_tmp_value_tag {};
33*4bdff4beSrobert 
34*4bdff4beSrobert } // namespace __unique_copy_tags
35*4bdff4beSrobert 
36*4bdff4beSrobert template <class _AlgPolicy, class _BinaryPredicate, class _InputIterator, class _Sent, class _OutputIterator>
37*4bdff4beSrobert _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)38*4bdff4beSrobert __unique_copy(_InputIterator __first,
39*4bdff4beSrobert               _Sent __last,
40*4bdff4beSrobert               _OutputIterator __result,
41*4bdff4beSrobert               _BinaryPredicate&& __pred,
42*4bdff4beSrobert               __unique_copy_tags::__read_from_tmp_value_tag) {
43*4bdff4beSrobert   if (__first != __last) {
44*4bdff4beSrobert     typename _IterOps<_AlgPolicy>::template __value_type<_InputIterator> __t(*__first);
4576d0caaeSpatrick     *__result = __t;
4676d0caaeSpatrick     ++__result;
47*4bdff4beSrobert     while (++__first != __last) {
48*4bdff4beSrobert       if (!__pred(__t, *__first)) {
4976d0caaeSpatrick         __t       = *__first;
5076d0caaeSpatrick         *__result = __t;
5176d0caaeSpatrick         ++__result;
5276d0caaeSpatrick       }
5376d0caaeSpatrick     }
5476d0caaeSpatrick   }
55*4bdff4beSrobert   return pair<_InputIterator, _OutputIterator>(std::move(__first), std::move(__result));
5676d0caaeSpatrick }
5776d0caaeSpatrick 
58*4bdff4beSrobert template <class _AlgPolicy, class _BinaryPredicate, class _ForwardIterator, class _Sent, class _OutputIterator>
59*4bdff4beSrobert _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)60*4bdff4beSrobert __unique_copy(_ForwardIterator __first,
61*4bdff4beSrobert               _Sent __last,
62*4bdff4beSrobert               _OutputIterator __result,
63*4bdff4beSrobert               _BinaryPredicate&& __pred,
64*4bdff4beSrobert               __unique_copy_tags::__reread_from_input_tag) {
65*4bdff4beSrobert   if (__first != __last) {
6676d0caaeSpatrick     _ForwardIterator __i = __first;
6776d0caaeSpatrick     *__result            = *__i;
6876d0caaeSpatrick     ++__result;
69*4bdff4beSrobert     while (++__first != __last) {
70*4bdff4beSrobert       if (!__pred(*__i, *__first)) {
7176d0caaeSpatrick         *__result = *__first;
7276d0caaeSpatrick         ++__result;
7376d0caaeSpatrick         __i = __first;
7476d0caaeSpatrick       }
7576d0caaeSpatrick     }
7676d0caaeSpatrick   }
77*4bdff4beSrobert   return pair<_ForwardIterator, _OutputIterator>(std::move(__first), std::move(__result));
7876d0caaeSpatrick }
7976d0caaeSpatrick 
80*4bdff4beSrobert template <class _AlgPolicy, class _BinaryPredicate, class _InputIterator, class _Sent, class _InputAndOutputIterator>
81*4bdff4beSrobert _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)82*4bdff4beSrobert __unique_copy(_InputIterator __first,
83*4bdff4beSrobert               _Sent __last,
84*4bdff4beSrobert               _InputAndOutputIterator __result,
85*4bdff4beSrobert               _BinaryPredicate&& __pred,
86*4bdff4beSrobert               __unique_copy_tags::__reread_from_output_tag) {
87*4bdff4beSrobert   if (__first != __last) {
8876d0caaeSpatrick     *__result = *__first;
8976d0caaeSpatrick     while (++__first != __last)
9076d0caaeSpatrick       if (!__pred(*__result, *__first))
9176d0caaeSpatrick         *++__result = *__first;
9276d0caaeSpatrick     ++__result;
9376d0caaeSpatrick   }
94*4bdff4beSrobert   return pair<_InputIterator, _InputAndOutputIterator>(std::move(__first), std::move(__result));
9576d0caaeSpatrick }
9676d0caaeSpatrick 
9776d0caaeSpatrick template <class _InputIterator, class _OutputIterator, class _BinaryPredicate>
98*4bdff4beSrobert inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _OutputIterator
unique_copy(_InputIterator __first,_InputIterator __last,_OutputIterator __result,_BinaryPredicate __pred)99*4bdff4beSrobert unique_copy(_InputIterator __first, _InputIterator __last, _OutputIterator __result, _BinaryPredicate __pred) {
100*4bdff4beSrobert   using __algo_tag = __conditional_t<
101*4bdff4beSrobert       is_base_of<forward_iterator_tag, typename iterator_traits<_InputIterator>::iterator_category>::value,
102*4bdff4beSrobert       __unique_copy_tags::__reread_from_input_tag,
103*4bdff4beSrobert       __conditional_t<
104*4bdff4beSrobert           is_base_of<forward_iterator_tag, typename iterator_traits<_OutputIterator>::iterator_category>::value &&
105*4bdff4beSrobert               is_same< typename iterator_traits<_InputIterator>::value_type,
106*4bdff4beSrobert                        typename iterator_traits<_OutputIterator>::value_type>::value,
107*4bdff4beSrobert           __unique_copy_tags::__reread_from_output_tag,
108*4bdff4beSrobert           __unique_copy_tags::__read_from_tmp_value_tag> >;
109*4bdff4beSrobert   return std::__unique_copy<_ClassicAlgPolicy>(
110*4bdff4beSrobert              std::move(__first), std::move(__last), std::move(__result), __pred, __algo_tag())
111*4bdff4beSrobert       .second;
11276d0caaeSpatrick }
11376d0caaeSpatrick 
11476d0caaeSpatrick template <class _InputIterator, class _OutputIterator>
115*4bdff4beSrobert inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _OutputIterator
unique_copy(_InputIterator __first,_InputIterator __last,_OutputIterator __result)116*4bdff4beSrobert unique_copy(_InputIterator __first, _InputIterator __last, _OutputIterator __result) {
117*4bdff4beSrobert   return std::unique_copy(std::move(__first), std::move(__last), std::move(__result), __equal_to());
11876d0caaeSpatrick }
11976d0caaeSpatrick 
12076d0caaeSpatrick _LIBCPP_END_NAMESPACE_STD
12176d0caaeSpatrick 
12276d0caaeSpatrick #endif // _LIBCPP___ALGORITHM_UNIQUE_COPY_H
123