1e78f53d1SNikolas Klauser //===----------------------------------------------------------------------===// 2e78f53d1SNikolas Klauser // 3e78f53d1SNikolas Klauser // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4e78f53d1SNikolas Klauser // See https://llvm.org/LICENSE.txt for license information. 5e78f53d1SNikolas Klauser // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6e78f53d1SNikolas Klauser // 7e78f53d1SNikolas Klauser //===----------------------------------------------------------------------===// 8e78f53d1SNikolas Klauser 9*ce777190SNikolas Klauser #ifndef _LIBCPP___CXX03___ALGORITHM_PARTITION_H 10*ce777190SNikolas Klauser #define _LIBCPP___CXX03___ALGORITHM_PARTITION_H 11e78f53d1SNikolas Klauser 1273fbae83SNikolas Klauser #include <__cxx03/__algorithm/iterator_operations.h> 1373fbae83SNikolas Klauser #include <__cxx03/__config> 1473fbae83SNikolas Klauser #include <__cxx03/__iterator/iterator_traits.h> 1573fbae83SNikolas Klauser #include <__cxx03/__utility/move.h> 1673fbae83SNikolas Klauser #include <__cxx03/__utility/pair.h> 17e78f53d1SNikolas Klauser 18e78f53d1SNikolas Klauser #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) 19e78f53d1SNikolas Klauser # pragma GCC system_header 20e78f53d1SNikolas Klauser #endif 21e78f53d1SNikolas Klauser 22e78f53d1SNikolas Klauser _LIBCPP_PUSH_MACROS 2373fbae83SNikolas Klauser #include <__cxx03/__undef_macros> 24e78f53d1SNikolas Klauser 25e78f53d1SNikolas Klauser _LIBCPP_BEGIN_NAMESPACE_STD 26e78f53d1SNikolas Klauser 27e78f53d1SNikolas Klauser template <class _Predicate, class _AlgPolicy, class _ForwardIterator, class _Sentinel> 28e78f53d1SNikolas Klauser _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 pair<_ForwardIterator, _ForwardIterator> 29e78f53d1SNikolas Klauser __partition_impl(_ForwardIterator __first, _Sentinel __last, _Predicate __pred, forward_iterator_tag) { 30e78f53d1SNikolas Klauser while (true) { 31e78f53d1SNikolas Klauser if (__first == __last) 32e78f53d1SNikolas Klauser return std::make_pair(std::move(__first), std::move(__first)); 33e78f53d1SNikolas Klauser if (!__pred(*__first)) 34e78f53d1SNikolas Klauser break; 35e78f53d1SNikolas Klauser ++__first; 36e78f53d1SNikolas Klauser } 37e78f53d1SNikolas Klauser 38e78f53d1SNikolas Klauser _ForwardIterator __p = __first; 39e78f53d1SNikolas Klauser while (++__p != __last) { 40e78f53d1SNikolas Klauser if (__pred(*__p)) { 41e78f53d1SNikolas Klauser _IterOps<_AlgPolicy>::iter_swap(__first, __p); 42e78f53d1SNikolas Klauser ++__first; 43e78f53d1SNikolas Klauser } 44e78f53d1SNikolas Klauser } 45e78f53d1SNikolas Klauser return std::make_pair(std::move(__first), std::move(__p)); 46e78f53d1SNikolas Klauser } 47e78f53d1SNikolas Klauser 48e78f53d1SNikolas Klauser template <class _Predicate, class _AlgPolicy, class _BidirectionalIterator, class _Sentinel> 49e78f53d1SNikolas Klauser _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 pair<_BidirectionalIterator, _BidirectionalIterator> 50e78f53d1SNikolas Klauser __partition_impl(_BidirectionalIterator __first, _Sentinel __sentinel, _Predicate __pred, bidirectional_iterator_tag) { 51e78f53d1SNikolas Klauser _BidirectionalIterator __original_last = _IterOps<_AlgPolicy>::next(__first, __sentinel); 52e78f53d1SNikolas Klauser _BidirectionalIterator __last = __original_last; 53e78f53d1SNikolas Klauser 54e78f53d1SNikolas Klauser while (true) { 55e78f53d1SNikolas Klauser while (true) { 56e78f53d1SNikolas Klauser if (__first == __last) 57e78f53d1SNikolas Klauser return std::make_pair(std::move(__first), std::move(__original_last)); 58e78f53d1SNikolas Klauser if (!__pred(*__first)) 59e78f53d1SNikolas Klauser break; 60e78f53d1SNikolas Klauser ++__first; 61e78f53d1SNikolas Klauser } 62e78f53d1SNikolas Klauser do { 63e78f53d1SNikolas Klauser if (__first == --__last) 64e78f53d1SNikolas Klauser return std::make_pair(std::move(__first), std::move(__original_last)); 65e78f53d1SNikolas Klauser } while (!__pred(*__last)); 66e78f53d1SNikolas Klauser _IterOps<_AlgPolicy>::iter_swap(__first, __last); 67e78f53d1SNikolas Klauser ++__first; 68e78f53d1SNikolas Klauser } 69e78f53d1SNikolas Klauser } 70e78f53d1SNikolas Klauser 71e78f53d1SNikolas Klauser template <class _AlgPolicy, class _ForwardIterator, class _Sentinel, class _Predicate, class _IterCategory> 72e78f53d1SNikolas Klauser inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 pair<_ForwardIterator, _ForwardIterator> 73e78f53d1SNikolas Klauser __partition(_ForwardIterator __first, _Sentinel __last, _Predicate&& __pred, _IterCategory __iter_category) { 74e78f53d1SNikolas Klauser return std::__partition_impl<__remove_cvref_t<_Predicate>&, _AlgPolicy>( 75e78f53d1SNikolas Klauser std::move(__first), std::move(__last), __pred, __iter_category); 76e78f53d1SNikolas Klauser } 77e78f53d1SNikolas Klauser 78e78f53d1SNikolas Klauser template <class _ForwardIterator, class _Predicate> 79e78f53d1SNikolas Klauser inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _ForwardIterator 80e78f53d1SNikolas Klauser partition(_ForwardIterator __first, _ForwardIterator __last, _Predicate __pred) { 81e78f53d1SNikolas Klauser using _IterCategory = typename iterator_traits<_ForwardIterator>::iterator_category; 82e78f53d1SNikolas Klauser auto __result = std::__partition<_ClassicAlgPolicy>(std::move(__first), std::move(__last), __pred, _IterCategory()); 83e78f53d1SNikolas Klauser return __result.first; 84e78f53d1SNikolas Klauser } 85e78f53d1SNikolas Klauser 86e78f53d1SNikolas Klauser _LIBCPP_END_NAMESPACE_STD 87e78f53d1SNikolas Klauser 88e78f53d1SNikolas Klauser _LIBCPP_POP_MACROS 89e78f53d1SNikolas Klauser 90*ce777190SNikolas Klauser #endif // _LIBCPP___CXX03___ALGORITHM_PARTITION_H 91