1fe6060f1SDimitry Andric //===----------------------------------------------------------------------===// 2fe6060f1SDimitry Andric // 3fe6060f1SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4fe6060f1SDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 5fe6060f1SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6fe6060f1SDimitry Andric // 7fe6060f1SDimitry Andric //===----------------------------------------------------------------------===// 8fe6060f1SDimitry Andric 9fe6060f1SDimitry Andric #ifndef _LIBCPP___ALGORITHM_UNIQUE_H 10fe6060f1SDimitry Andric #define _LIBCPP___ALGORITHM_UNIQUE_H 11fe6060f1SDimitry Andric 12fe6060f1SDimitry Andric #include <__algorithm/adjacent_find.h> 1304eeddc0SDimitry Andric #include <__algorithm/comp.h> 1461cfbce3SDimitry Andric #include <__algorithm/iterator_operations.h> 1504eeddc0SDimitry Andric #include <__config> 16fe6060f1SDimitry Andric #include <__iterator/iterator_traits.h> 17fe6060f1SDimitry Andric #include <__utility/move.h> 1861cfbce3SDimitry Andric #include <__utility/pair.h> 19fe6060f1SDimitry Andric 20fe6060f1SDimitry Andric #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) 21fe6060f1SDimitry Andric # pragma GCC system_header 22fe6060f1SDimitry Andric #endif 23fe6060f1SDimitry Andric 24b3edf446SDimitry Andric _LIBCPP_PUSH_MACROS 25b3edf446SDimitry Andric #include <__undef_macros> 26b3edf446SDimitry Andric 27fe6060f1SDimitry Andric _LIBCPP_BEGIN_NAMESPACE_STD 28fe6060f1SDimitry Andric 29fe6060f1SDimitry Andric // unique 30fe6060f1SDimitry Andric 3161cfbce3SDimitry Andric template <class _AlgPolicy, class _Iter, class _Sent, class _BinaryPredicate> 32*0fca6ea1SDimitry Andric _LIBCPP_NODISCARD _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 std::pair<_Iter, _Iter> 3361cfbce3SDimitry Andric __unique(_Iter __first, _Sent __last, _BinaryPredicate&& __pred) { 3461cfbce3SDimitry Andric __first = std::__adjacent_find(__first, __last, __pred); 3561cfbce3SDimitry Andric if (__first != __last) { 36fe6060f1SDimitry Andric // ... a a ? ... 37fe6060f1SDimitry Andric // f i 3861cfbce3SDimitry Andric _Iter __i = __first; 39fe6060f1SDimitry Andric for (++__i; ++__i != __last;) 40fe6060f1SDimitry Andric if (!__pred(*__first, *__i)) 4161cfbce3SDimitry Andric *++__first = _IterOps<_AlgPolicy>::__iter_move(__i); 42fe6060f1SDimitry Andric ++__first; 4361cfbce3SDimitry Andric return std::pair<_Iter, _Iter>(std::move(__first), std::move(__i)); 44fe6060f1SDimitry Andric } 4561cfbce3SDimitry Andric return std::pair<_Iter, _Iter>(__first, __first); 4661cfbce3SDimitry Andric } 4761cfbce3SDimitry Andric 4861cfbce3SDimitry Andric template <class _ForwardIterator, class _BinaryPredicate> 49*0fca6ea1SDimitry Andric _LIBCPP_NODISCARD _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _ForwardIterator 5061cfbce3SDimitry Andric unique(_ForwardIterator __first, _ForwardIterator __last, _BinaryPredicate __pred) { 5161cfbce3SDimitry Andric return std::__unique<_ClassicAlgPolicy>(std::move(__first), std::move(__last), __pred).first; 52fe6060f1SDimitry Andric } 53fe6060f1SDimitry Andric 54fe6060f1SDimitry Andric template <class _ForwardIterator> 55*0fca6ea1SDimitry Andric _LIBCPP_NODISCARD inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _ForwardIterator 5661cfbce3SDimitry Andric unique(_ForwardIterator __first, _ForwardIterator __last) { 57bdd1243dSDimitry Andric return std::unique(__first, __last, __equal_to()); 58fe6060f1SDimitry Andric } 59fe6060f1SDimitry Andric 60fe6060f1SDimitry Andric _LIBCPP_END_NAMESPACE_STD 61fe6060f1SDimitry Andric 62b3edf446SDimitry Andric _LIBCPP_POP_MACROS 63b3edf446SDimitry Andric 64fe6060f1SDimitry Andric #endif // _LIBCPP___ALGORITHM_UNIQUE_H 65