xref: /freebsd-src/contrib/llvm-project/libcxx/include/__algorithm/ranges_partition_copy.h (revision b3edf4467982447620505a28fc82e38a414c07dc)
1753f127fSDimitry Andric //===----------------------------------------------------------------------===//
2753f127fSDimitry Andric //
3753f127fSDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4753f127fSDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
5753f127fSDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6753f127fSDimitry Andric //
7753f127fSDimitry Andric //===----------------------------------------------------------------------===//
8753f127fSDimitry Andric 
9753f127fSDimitry Andric #ifndef _LIBCPP___ALGORITHM_RANGES_PARTITION_COPY_H
10753f127fSDimitry Andric #define _LIBCPP___ALGORITHM_RANGES_PARTITION_COPY_H
11753f127fSDimitry Andric 
12753f127fSDimitry Andric #include <__algorithm/in_out_out_result.h>
13753f127fSDimitry Andric #include <__config>
14753f127fSDimitry Andric #include <__functional/identity.h>
15753f127fSDimitry Andric #include <__functional/invoke.h>
16753f127fSDimitry Andric #include <__iterator/concepts.h>
17753f127fSDimitry Andric #include <__iterator/iterator_traits.h>
18753f127fSDimitry Andric #include <__iterator/projected.h>
19753f127fSDimitry Andric #include <__ranges/access.h>
20753f127fSDimitry Andric #include <__ranges/concepts.h>
21753f127fSDimitry Andric #include <__ranges/dangling.h>
2206c3fb27SDimitry Andric #include <__type_traits/remove_cvref.h>
23753f127fSDimitry Andric #include <__utility/move.h>
24753f127fSDimitry Andric 
25753f127fSDimitry Andric #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
26753f127fSDimitry Andric #  pragma GCC system_header
27753f127fSDimitry Andric #endif
28753f127fSDimitry Andric 
29*b3edf446SDimitry Andric _LIBCPP_PUSH_MACROS
30*b3edf446SDimitry Andric #include <__undef_macros>
31*b3edf446SDimitry Andric 
3206c3fb27SDimitry Andric #if _LIBCPP_STD_VER >= 20
33753f127fSDimitry Andric 
34753f127fSDimitry Andric _LIBCPP_BEGIN_NAMESPACE_STD
35753f127fSDimitry Andric 
36753f127fSDimitry Andric namespace ranges {
37753f127fSDimitry Andric 
38753f127fSDimitry Andric template <class _InIter, class _OutIter1, class _OutIter2>
39753f127fSDimitry Andric using partition_copy_result = in_out_out_result<_InIter, _OutIter1, _OutIter2>;
40753f127fSDimitry Andric 
41753f127fSDimitry Andric namespace __partition_copy {
42753f127fSDimitry Andric 
43753f127fSDimitry Andric struct __fn {
44fcaf7f86SDimitry Andric   // TODO(ranges): delegate to the classic algorithm.
45fcaf7f86SDimitry Andric   template <class _InIter, class _Sent, class _OutIter1, class _OutIter2, class _Proj, class _Pred>
4606c3fb27SDimitry Andric   _LIBCPP_HIDE_FROM_ABI constexpr static partition_copy_result<__remove_cvref_t<_InIter>,
4706c3fb27SDimitry Andric                                                                __remove_cvref_t<_OutIter1>,
4806c3fb27SDimitry Andric                                                                __remove_cvref_t<_OutIter2> >
__partition_copy_fn_impl__fn4906c3fb27SDimitry Andric   __partition_copy_fn_impl(
5006c3fb27SDimitry Andric       _InIter&& __first,
5106c3fb27SDimitry Andric       _Sent&& __last,
5206c3fb27SDimitry Andric       _OutIter1&& __out_true,
5306c3fb27SDimitry Andric       _OutIter2&& __out_false,
5406c3fb27SDimitry Andric       _Pred& __pred,
5506c3fb27SDimitry Andric       _Proj& __proj) {
56fcaf7f86SDimitry Andric     for (; __first != __last; ++__first) {
57fcaf7f86SDimitry Andric       if (std::invoke(__pred, std::invoke(__proj, *__first))) {
58fcaf7f86SDimitry Andric         *__out_true = *__first;
59fcaf7f86SDimitry Andric         ++__out_true;
60fcaf7f86SDimitry Andric 
61fcaf7f86SDimitry Andric       } else {
62fcaf7f86SDimitry Andric         *__out_false = *__first;
63fcaf7f86SDimitry Andric         ++__out_false;
64fcaf7f86SDimitry Andric       }
65fcaf7f86SDimitry Andric     }
66fcaf7f86SDimitry Andric 
67fcaf7f86SDimitry Andric     return {std::move(__first), std::move(__out_true), std::move(__out_false)};
68fcaf7f86SDimitry Andric   }
69fcaf7f86SDimitry Andric 
7006c3fb27SDimitry Andric   template <input_iterator _InIter,
7106c3fb27SDimitry Andric             sentinel_for<_InIter> _Sent,
7206c3fb27SDimitry Andric             weakly_incrementable _OutIter1,
7306c3fb27SDimitry Andric             weakly_incrementable _OutIter2,
7406c3fb27SDimitry Andric             class _Proj = identity,
7506c3fb27SDimitry Andric             indirect_unary_predicate<projected<_InIter, _Proj>> _Pred>
76753f127fSDimitry Andric     requires indirectly_copyable<_InIter, _OutIter1> && indirectly_copyable<_InIter, _OutIter2>
operator__fn7706c3fb27SDimitry Andric   _LIBCPP_HIDE_FROM_ABI constexpr partition_copy_result<_InIter, _OutIter1, _OutIter2> operator()(
7806c3fb27SDimitry Andric       _InIter __first, _Sent __last, _OutIter1 __out_true, _OutIter2 __out_false, _Pred __pred, _Proj __proj = {})
7906c3fb27SDimitry Andric       const {
80fcaf7f86SDimitry Andric     return __partition_copy_fn_impl(
81fcaf7f86SDimitry Andric         std::move(__first), std::move(__last), std::move(__out_true), std::move(__out_false), __pred, __proj);
82753f127fSDimitry Andric   }
83753f127fSDimitry Andric 
8406c3fb27SDimitry Andric   template <input_range _Range,
8506c3fb27SDimitry Andric             weakly_incrementable _OutIter1,
8606c3fb27SDimitry Andric             weakly_incrementable _OutIter2,
8706c3fb27SDimitry Andric             class _Proj = identity,
8806c3fb27SDimitry Andric             indirect_unary_predicate<projected<iterator_t<_Range>, _Proj>> _Pred>
89753f127fSDimitry Andric     requires indirectly_copyable<iterator_t<_Range>, _OutIter1> && indirectly_copyable<iterator_t<_Range>, _OutIter2>
9006c3fb27SDimitry Andric   _LIBCPP_HIDE_FROM_ABI constexpr partition_copy_result<borrowed_iterator_t<_Range>, _OutIter1, _OutIter2>
operator__fn91753f127fSDimitry Andric   operator()(_Range&& __range, _OutIter1 __out_true, _OutIter2 __out_false, _Pred __pred, _Proj __proj = {}) const {
92fcaf7f86SDimitry Andric     return __partition_copy_fn_impl(
93fcaf7f86SDimitry Andric         ranges::begin(__range), ranges::end(__range), std::move(__out_true), std::move(__out_false), __pred, __proj);
94753f127fSDimitry Andric   }
95753f127fSDimitry Andric };
96753f127fSDimitry Andric 
97753f127fSDimitry Andric } // namespace __partition_copy
98753f127fSDimitry Andric 
99753f127fSDimitry Andric inline namespace __cpo {
100753f127fSDimitry Andric inline constexpr auto partition_copy = __partition_copy::__fn{};
101753f127fSDimitry Andric } // namespace __cpo
102753f127fSDimitry Andric } // namespace ranges
103753f127fSDimitry Andric 
104753f127fSDimitry Andric _LIBCPP_END_NAMESPACE_STD
105753f127fSDimitry Andric 
10606c3fb27SDimitry Andric #endif // _LIBCPP_STD_VER >= 20
107753f127fSDimitry Andric 
108*b3edf446SDimitry Andric _LIBCPP_POP_MACROS
109*b3edf446SDimitry Andric 
110753f127fSDimitry Andric #endif // _LIBCPP___ALGORITHM_RANGES_PARTITION_COPY_H
111