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