1 //===----------------------------------------------------------------------===// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===----------------------------------------------------------------------===// 8 9 #ifndef _LIBCPP___ALGORITHM_UNIQUE_COPY_H 10 #define _LIBCPP___ALGORITHM_UNIQUE_COPY_H 11 12 #include <__config> 13 #include <__algorithm/comp.h> 14 #include <__iterator/iterator_traits.h> 15 #include <utility> 16 #include <type_traits> 17 18 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) 19 #pragma GCC system_header 20 #endif 21 22 _LIBCPP_PUSH_MACROS 23 #include <__undef_macros> 24 25 _LIBCPP_BEGIN_NAMESPACE_STD 26 27 template <class _BinaryPredicate, class _InputIterator, class _OutputIterator> 28 _LIBCPP_CONSTEXPR_AFTER_CXX17 _OutputIterator 29 __unique_copy(_InputIterator __first, _InputIterator __last, _OutputIterator __result, _BinaryPredicate __pred, 30 input_iterator_tag, output_iterator_tag) 31 { 32 if (__first != __last) 33 { 34 typename iterator_traits<_InputIterator>::value_type __t(*__first); 35 *__result = __t; 36 ++__result; 37 while (++__first != __last) 38 { 39 if (!__pred(__t, *__first)) 40 { 41 __t = *__first; 42 *__result = __t; 43 ++__result; 44 } 45 } 46 } 47 return __result; 48 } 49 50 template <class _BinaryPredicate, class _ForwardIterator, class _OutputIterator> 51 _LIBCPP_CONSTEXPR_AFTER_CXX17 _OutputIterator 52 __unique_copy(_ForwardIterator __first, _ForwardIterator __last, _OutputIterator __result, _BinaryPredicate __pred, 53 forward_iterator_tag, output_iterator_tag) 54 { 55 if (__first != __last) 56 { 57 _ForwardIterator __i = __first; 58 *__result = *__i; 59 ++__result; 60 while (++__first != __last) 61 { 62 if (!__pred(*__i, *__first)) 63 { 64 *__result = *__first; 65 ++__result; 66 __i = __first; 67 } 68 } 69 } 70 return __result; 71 } 72 73 template <class _BinaryPredicate, class _InputIterator, class _ForwardIterator> 74 _LIBCPP_CONSTEXPR_AFTER_CXX17 _ForwardIterator 75 __unique_copy(_InputIterator __first, _InputIterator __last, _ForwardIterator __result, _BinaryPredicate __pred, 76 input_iterator_tag, forward_iterator_tag) 77 { 78 if (__first != __last) 79 { 80 *__result = *__first; 81 while (++__first != __last) 82 if (!__pred(*__result, *__first)) 83 *++__result = *__first; 84 ++__result; 85 } 86 return __result; 87 } 88 89 template <class _InputIterator, class _OutputIterator, class _BinaryPredicate> 90 inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 91 _OutputIterator 92 unique_copy(_InputIterator __first, _InputIterator __last, _OutputIterator __result, _BinaryPredicate __pred) 93 { 94 return _VSTD::__unique_copy<typename add_lvalue_reference<_BinaryPredicate>::type> 95 (__first, __last, __result, __pred, 96 typename iterator_traits<_InputIterator>::iterator_category(), 97 typename iterator_traits<_OutputIterator>::iterator_category()); 98 } 99 100 template <class _InputIterator, class _OutputIterator> 101 inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 102 _OutputIterator 103 unique_copy(_InputIterator __first, _InputIterator __last, _OutputIterator __result) 104 { 105 typedef typename iterator_traits<_InputIterator>::value_type __v; 106 return _VSTD::unique_copy(__first, __last, __result, __equal_to<__v>()); 107 } 108 109 110 _LIBCPP_END_NAMESPACE_STD 111 112 _LIBCPP_POP_MACROS 113 114 #endif // _LIBCPP___ALGORITHM_UNIQUE_COPY_H 115