//===----------------------------------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//

#ifndef _LIBCPP___ALGORITHM_UNIQUE_COPY_H
#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
#endif

_LIBCPP_BEGIN_NAMESPACE_STD

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;
      }
    }
  }
  return pair<_InputIterator, _OutputIterator>(std::move(__first), std::move(__result));
}

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;
        __i = __first;
      }
    }
  }
  return pair<_ForwardIterator, _OutputIterator>(std::move(__first), std::move(__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_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_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
