176d0caaeSpatrick //===----------------------------------------------------------------------===//
276d0caaeSpatrick //
376d0caaeSpatrick // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
476d0caaeSpatrick // See https://llvm.org/LICENSE.txt for license information.
576d0caaeSpatrick // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
676d0caaeSpatrick //
776d0caaeSpatrick //===----------------------------------------------------------------------===//
876d0caaeSpatrick
976d0caaeSpatrick #ifndef _LIBCPP___ALGORITHM_PARTITION_H
1076d0caaeSpatrick #define _LIBCPP___ALGORITHM_PARTITION_H
1176d0caaeSpatrick
12*4bdff4beSrobert #include <__algorithm/iterator_operations.h>
1376d0caaeSpatrick #include <__config>
1476d0caaeSpatrick #include <__iterator/iterator_traits.h>
15*4bdff4beSrobert #include <__utility/move.h>
16*4bdff4beSrobert #include <__utility/pair.h>
1776d0caaeSpatrick #include <type_traits>
1876d0caaeSpatrick
1976d0caaeSpatrick #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
2076d0caaeSpatrick # pragma GCC system_header
2176d0caaeSpatrick #endif
2276d0caaeSpatrick
2376d0caaeSpatrick _LIBCPP_BEGIN_NAMESPACE_STD
2476d0caaeSpatrick
25*4bdff4beSrobert template <class _Predicate, class _AlgPolicy, class _ForwardIterator, class _Sentinel>
26*4bdff4beSrobert _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 pair<_ForwardIterator, _ForwardIterator>
__partition_impl(_ForwardIterator __first,_Sentinel __last,_Predicate __pred,forward_iterator_tag)27*4bdff4beSrobert __partition_impl(_ForwardIterator __first, _Sentinel __last, _Predicate __pred, forward_iterator_tag)
2876d0caaeSpatrick {
2976d0caaeSpatrick while (true)
3076d0caaeSpatrick {
3176d0caaeSpatrick if (__first == __last)
32*4bdff4beSrobert return std::make_pair(std::move(__first), std::move(__first));
3376d0caaeSpatrick if (!__pred(*__first))
3476d0caaeSpatrick break;
3576d0caaeSpatrick ++__first;
3676d0caaeSpatrick }
37*4bdff4beSrobert
38*4bdff4beSrobert _ForwardIterator __p = __first;
39*4bdff4beSrobert while (++__p != __last)
4076d0caaeSpatrick {
4176d0caaeSpatrick if (__pred(*__p))
4276d0caaeSpatrick {
43*4bdff4beSrobert _IterOps<_AlgPolicy>::iter_swap(__first, __p);
4476d0caaeSpatrick ++__first;
4576d0caaeSpatrick }
4676d0caaeSpatrick }
47*4bdff4beSrobert return std::make_pair(std::move(__first), std::move(__p));
4876d0caaeSpatrick }
4976d0caaeSpatrick
50*4bdff4beSrobert template <class _Predicate, class _AlgPolicy, class _BidirectionalIterator, class _Sentinel>
51*4bdff4beSrobert _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 pair<_BidirectionalIterator, _BidirectionalIterator>
__partition_impl(_BidirectionalIterator __first,_Sentinel __sentinel,_Predicate __pred,bidirectional_iterator_tag)52*4bdff4beSrobert __partition_impl(_BidirectionalIterator __first, _Sentinel __sentinel, _Predicate __pred,
5376d0caaeSpatrick bidirectional_iterator_tag)
5476d0caaeSpatrick {
55*4bdff4beSrobert _BidirectionalIterator __original_last = _IterOps<_AlgPolicy>::next(__first, __sentinel);
56*4bdff4beSrobert _BidirectionalIterator __last = __original_last;
57*4bdff4beSrobert
5876d0caaeSpatrick while (true)
5976d0caaeSpatrick {
6076d0caaeSpatrick while (true)
6176d0caaeSpatrick {
6276d0caaeSpatrick if (__first == __last)
63*4bdff4beSrobert return std::make_pair(std::move(__first), std::move(__original_last));
6476d0caaeSpatrick if (!__pred(*__first))
6576d0caaeSpatrick break;
6676d0caaeSpatrick ++__first;
6776d0caaeSpatrick }
6876d0caaeSpatrick do
6976d0caaeSpatrick {
7076d0caaeSpatrick if (__first == --__last)
71*4bdff4beSrobert return std::make_pair(std::move(__first), std::move(__original_last));
7276d0caaeSpatrick } while (!__pred(*__last));
73*4bdff4beSrobert _IterOps<_AlgPolicy>::iter_swap(__first, __last);
7476d0caaeSpatrick ++__first;
7576d0caaeSpatrick }
7676d0caaeSpatrick }
7776d0caaeSpatrick
78*4bdff4beSrobert template <class _AlgPolicy, class _ForwardIterator, class _Sentinel, class _Predicate, class _IterCategory>
79*4bdff4beSrobert inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
__partition(_ForwardIterator __first,_Sentinel __last,_Predicate && __pred,_IterCategory __iter_category)80*4bdff4beSrobert pair<_ForwardIterator, _ForwardIterator> __partition(
81*4bdff4beSrobert _ForwardIterator __first, _Sentinel __last, _Predicate&& __pred, _IterCategory __iter_category) {
82*4bdff4beSrobert return std::__partition_impl<__remove_cvref_t<_Predicate>&, _AlgPolicy>(
83*4bdff4beSrobert std::move(__first), std::move(__last), __pred, __iter_category);
84*4bdff4beSrobert }
85*4bdff4beSrobert
8676d0caaeSpatrick template <class _ForwardIterator, class _Predicate>
87*4bdff4beSrobert inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20
8876d0caaeSpatrick _ForwardIterator
partition(_ForwardIterator __first,_ForwardIterator __last,_Predicate __pred)8976d0caaeSpatrick partition(_ForwardIterator __first, _ForwardIterator __last, _Predicate __pred)
9076d0caaeSpatrick {
91*4bdff4beSrobert using _IterCategory = typename iterator_traits<_ForwardIterator>::iterator_category;
92*4bdff4beSrobert auto __result = std::__partition<_ClassicAlgPolicy>(std::move(__first), std::move(__last), __pred, _IterCategory());
93*4bdff4beSrobert return __result.first;
9476d0caaeSpatrick }
9576d0caaeSpatrick
9676d0caaeSpatrick _LIBCPP_END_NAMESPACE_STD
9776d0caaeSpatrick
9876d0caaeSpatrick #endif // _LIBCPP___ALGORITHM_PARTITION_H
99