xref: /llvm-project/libcxx/include/__algorithm/partition.h (revision ca7926bd79426fbd8b752d6513c77951db35109f)
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_PARTITION_H
10 #define _LIBCPP___ALGORITHM_PARTITION_H
11 
12 #include <__config>
13 #include <__iterator/iterator_traits.h>
14 #include <__utility/swap.h>
15 #include <utility> // pair
16 
17 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
18 #pragma GCC system_header
19 #endif
20 
21 _LIBCPP_PUSH_MACROS
22 #include <__undef_macros>
23 
24 _LIBCPP_BEGIN_NAMESPACE_STD
25 
26 template <class _Predicate, class _ForwardIterator>
27 _LIBCPP_CONSTEXPR_AFTER_CXX17 _ForwardIterator
28 __partition(_ForwardIterator __first, _ForwardIterator __last, _Predicate __pred, forward_iterator_tag)
29 {
30     while (true)
31     {
32         if (__first == __last)
33             return __first;
34         if (!__pred(*__first))
35             break;
36         ++__first;
37     }
38     for (_ForwardIterator __p = __first; ++__p != __last;)
39     {
40         if (__pred(*__p))
41         {
42             swap(*__first, *__p);
43             ++__first;
44         }
45     }
46     return __first;
47 }
48 
49 template <class _Predicate, class _BidirectionalIterator>
50 _LIBCPP_CONSTEXPR_AFTER_CXX17 _BidirectionalIterator
51 __partition(_BidirectionalIterator __first, _BidirectionalIterator __last, _Predicate __pred,
52             bidirectional_iterator_tag)
53 {
54     while (true)
55     {
56         while (true)
57         {
58             if (__first == __last)
59                 return __first;
60             if (!__pred(*__first))
61                 break;
62             ++__first;
63         }
64         do
65         {
66             if (__first == --__last)
67                 return __first;
68         } while (!__pred(*__last));
69         swap(*__first, *__last);
70         ++__first;
71     }
72 }
73 
74 template <class _ForwardIterator, class _Predicate>
75 inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
76 _ForwardIterator
77 partition(_ForwardIterator __first, _ForwardIterator __last, _Predicate __pred)
78 {
79     return _VSTD::__partition<_Predicate&>(
80         __first, __last, __pred, typename iterator_traits<_ForwardIterator>::iterator_category());
81 }
82 
83 _LIBCPP_END_NAMESPACE_STD
84 
85 _LIBCPP_POP_MACROS
86 
87 #endif // _LIBCPP___ALGORITHM_PARTITION_H
88