xref: /openbsd-src/gnu/llvm/libcxx/include/__algorithm/partition.h (revision 4bdff4bed0e3d54e55670334c7d0077db4170f86)
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