diff options
| author | Dimitry Andric <dim@FreeBSD.org> | 2023-02-11 12:38:04 +0000 | 
|---|---|---|
| committer | Dimitry Andric <dim@FreeBSD.org> | 2023-02-11 12:38:11 +0000 | 
| commit | e3b557809604d036af6e00c60f012c2025b59a5e (patch) | |
| tree | 8a11ba2269a3b669601e2fd41145b174008f4da8 /libcxx/include/__algorithm/unique_copy.h | |
| parent | 08e8dd7b9db7bb4a9de26d44c1cbfd24e869c014 (diff) | |
Diffstat (limited to 'libcxx/include/__algorithm/unique_copy.h')
| -rw-r--r-- | libcxx/include/__algorithm/unique_copy.h | 146 | 
1 files changed, 81 insertions, 65 deletions
| diff --git a/libcxx/include/__algorithm/unique_copy.h b/libcxx/include/__algorithm/unique_copy.h index f58517749f51..81fcd50f011d 100644 --- a/libcxx/include/__algorithm/unique_copy.h +++ b/libcxx/include/__algorithm/unique_copy.h @@ -10,8 +10,14 @@  #define _LIBCPP___ALGORITHM_UNIQUE_COPY_H  #include <__algorithm/comp.h> +#include <__algorithm/iterator_operations.h>  #include <__config>  #include <__iterator/iterator_traits.h> +#include <__type_traits/conditional.h> +#include <__type_traits/is_base_of.h> +#include <__type_traits/is_same.h> +#include <__utility/move.h> +#include <__utility/pair.h>  #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)  #  pragma GCC system_header @@ -19,88 +25,98 @@  _LIBCPP_BEGIN_NAMESPACE_STD -template <class _BinaryPredicate, class _InputIterator, class _OutputIterator> -_LIBCPP_CONSTEXPR_AFTER_CXX17 _OutputIterator -__unique_copy(_InputIterator __first, _InputIterator __last, _OutputIterator __result, _BinaryPredicate __pred, -              input_iterator_tag, output_iterator_tag) -{ -    if (__first != __last) -    { -        typename iterator_traits<_InputIterator>::value_type __t(*__first); +namespace __unique_copy_tags { + +struct __reread_from_input_tag {}; +struct __reread_from_output_tag {}; +struct __read_from_tmp_value_tag {}; + +} // namespace __unique_copy_tags + +template <class _AlgPolicy, class _BinaryPredicate, class _InputIterator, class _Sent, class _OutputIterator> +_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) { +  if (__first != __last) { +    typename _IterOps<_AlgPolicy>::template __value_type<_InputIterator> __t(*__first); +    *__result = __t; +    ++__result; +    while (++__first != __last) { +      if (!__pred(__t, *__first)) { +        __t       = *__first;          *__result = __t;          ++__result; -        while (++__first != __last) -        { -            if (!__pred(__t, *__first)) -            { -                __t = *__first; -                *__result = __t; -                ++__result; -            } -        } +      }      } -    return __result; +  } +  return pair<_InputIterator, _OutputIterator>(std::move(__first), std::move(__result));  } -template <class _BinaryPredicate, class _ForwardIterator, class _OutputIterator> -_LIBCPP_CONSTEXPR_AFTER_CXX17 _OutputIterator -__unique_copy(_ForwardIterator __first, _ForwardIterator __last, _OutputIterator __result, _BinaryPredicate __pred, -              forward_iterator_tag, output_iterator_tag) -{ -    if (__first != __last) -    { -        _ForwardIterator __i = __first; -        *__result = *__i; +template <class _AlgPolicy, class _BinaryPredicate, class _ForwardIterator, class _Sent, class _OutputIterator> +_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) { +  if (__first != __last) { +    _ForwardIterator __i = __first; +    *__result            = *__i; +    ++__result; +    while (++__first != __last) { +      if (!__pred(*__i, *__first)) { +        *__result = *__first;          ++__result; -        while (++__first != __last) -        { -            if (!__pred(*__i, *__first)) -            { -                *__result = *__first; -                ++__result; -                __i = __first; -            } -        } +        __i = __first; +      }      } -    return __result; +  } +  return pair<_ForwardIterator, _OutputIterator>(std::move(__first), std::move(__result));  } -template <class _BinaryPredicate, class _InputIterator, class _ForwardIterator> -_LIBCPP_CONSTEXPR_AFTER_CXX17 _ForwardIterator -__unique_copy(_InputIterator __first, _InputIterator __last, _ForwardIterator __result, _BinaryPredicate __pred, -              input_iterator_tag, forward_iterator_tag) -{ -    if (__first != __last) -    { -        *__result = *__first; -        while (++__first != __last) -            if (!__pred(*__result, *__first)) -                *++__result = *__first; -        ++__result; -    } -    return __result; +template <class _AlgPolicy, class _BinaryPredicate, class _InputIterator, class _Sent, class _InputAndOutputIterator> +_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) { +  if (__first != __last) { +    *__result = *__first; +    while (++__first != __last) +      if (!__pred(*__result, *__first)) +        *++__result = *__first; +    ++__result; +  } +  return pair<_InputIterator, _InputAndOutputIterator>(std::move(__first), std::move(__result));  }  template <class _InputIterator, class _OutputIterator, class _BinaryPredicate> -inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 -_OutputIterator -unique_copy(_InputIterator __first, _InputIterator __last, _OutputIterator __result, _BinaryPredicate __pred) -{ -    return _VSTD::__unique_copy<_BinaryPredicate&>(__first, __last, __result, __pred, -                               typename iterator_traits<_InputIterator>::iterator_category(), -                               typename iterator_traits<_OutputIterator>::iterator_category()); +inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _OutputIterator +unique_copy(_InputIterator __first, _InputIterator __last, _OutputIterator __result, _BinaryPredicate __pred) { +  using __algo_tag = __conditional_t< +      is_base_of<forward_iterator_tag, typename iterator_traits<_InputIterator>::iterator_category>::value, +      __unique_copy_tags::__reread_from_input_tag, +      __conditional_t< +          is_base_of<forward_iterator_tag, typename iterator_traits<_OutputIterator>::iterator_category>::value && +              is_same< typename iterator_traits<_InputIterator>::value_type, +                       typename iterator_traits<_OutputIterator>::value_type>::value, +          __unique_copy_tags::__reread_from_output_tag, +          __unique_copy_tags::__read_from_tmp_value_tag> >; +  return std::__unique_copy<_ClassicAlgPolicy>( +             std::move(__first), std::move(__last), std::move(__result), __pred, __algo_tag()) +      .second;  }  template <class _InputIterator, class _OutputIterator> -inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 -_OutputIterator -unique_copy(_InputIterator __first, _InputIterator __last, _OutputIterator __result) -{ -    typedef typename iterator_traits<_InputIterator>::value_type __v; -    return _VSTD::unique_copy(__first, __last, __result, __equal_to<__v>()); +inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _OutputIterator +unique_copy(_InputIterator __first, _InputIterator __last, _OutputIterator __result) { +  return std::unique_copy(std::move(__first), std::move(__last), std::move(__result), __equal_to());  } -  _LIBCPP_END_NAMESPACE_STD  #endif // _LIBCPP___ALGORITHM_UNIQUE_COPY_H | 
