107 lines · c
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-exception6//7//===----------------------------------------------------------------------===//8 9#ifndef _LIBCPP___ALGORITHM_RANGES_PARTITION_COPY_H10#define _LIBCPP___ALGORITHM_RANGES_PARTITION_COPY_H11 12#include <__algorithm/in_out_out_result.h>13#include <__config>14#include <__functional/identity.h>15#include <__functional/invoke.h>16#include <__iterator/concepts.h>17#include <__iterator/iterator_traits.h>18#include <__iterator/projected.h>19#include <__ranges/access.h>20#include <__ranges/concepts.h>21#include <__ranges/dangling.h>22#include <__type_traits/remove_cvref.h>23#include <__utility/move.h>24 25#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)26# pragma GCC system_header27#endif28 29_LIBCPP_PUSH_MACROS30#include <__undef_macros>31 32#if _LIBCPP_STD_VER >= 2033 34_LIBCPP_BEGIN_NAMESPACE_STD35 36namespace ranges {37 38template <class _InIter, class _OutIter1, class _OutIter2>39using partition_copy_result = in_out_out_result<_InIter, _OutIter1, _OutIter2>;40 41struct __partition_copy {42 // TODO(ranges): delegate to the classic algorithm.43 template <class _InIter, class _Sent, class _OutIter1, class _OutIter2, class _Proj, class _Pred>44 _LIBCPP_HIDE_FROM_ABI constexpr static partition_copy_result<__remove_cvref_t<_InIter>,45 __remove_cvref_t<_OutIter1>,46 __remove_cvref_t<_OutIter2> >47 __partition_copy_fn_impl(48 _InIter&& __first,49 _Sent&& __last,50 _OutIter1&& __out_true,51 _OutIter2&& __out_false,52 _Pred& __pred,53 _Proj& __proj) {54 for (; __first != __last; ++__first) {55 if (std::invoke(__pred, std::invoke(__proj, *__first))) {56 *__out_true = *__first;57 ++__out_true;58 59 } else {60 *__out_false = *__first;61 ++__out_false;62 }63 }64 65 return {std::move(__first), std::move(__out_true), std::move(__out_false)};66 }67 68 template <input_iterator _InIter,69 sentinel_for<_InIter> _Sent,70 weakly_incrementable _OutIter1,71 weakly_incrementable _OutIter2,72 class _Proj = identity,73 indirect_unary_predicate<projected<_InIter, _Proj>> _Pred>74 requires indirectly_copyable<_InIter, _OutIter1> && indirectly_copyable<_InIter, _OutIter2>75 _LIBCPP_HIDE_FROM_ABI constexpr partition_copy_result<_InIter, _OutIter1, _OutIter2> operator()(76 _InIter __first, _Sent __last, _OutIter1 __out_true, _OutIter2 __out_false, _Pred __pred, _Proj __proj = {})77 const {78 return __partition_copy_fn_impl(79 std::move(__first), std::move(__last), std::move(__out_true), std::move(__out_false), __pred, __proj);80 }81 82 template <input_range _Range,83 weakly_incrementable _OutIter1,84 weakly_incrementable _OutIter2,85 class _Proj = identity,86 indirect_unary_predicate<projected<iterator_t<_Range>, _Proj>> _Pred>87 requires indirectly_copyable<iterator_t<_Range>, _OutIter1> && indirectly_copyable<iterator_t<_Range>, _OutIter2>88 _LIBCPP_HIDE_FROM_ABI constexpr partition_copy_result<borrowed_iterator_t<_Range>, _OutIter1, _OutIter2>89 operator()(_Range&& __range, _OutIter1 __out_true, _OutIter2 __out_false, _Pred __pred, _Proj __proj = {}) const {90 return __partition_copy_fn_impl(91 ranges::begin(__range), ranges::end(__range), std::move(__out_true), std::move(__out_false), __pred, __proj);92 }93};94 95inline namespace __cpo {96inline constexpr auto partition_copy = __partition_copy{};97} // namespace __cpo98} // namespace ranges99 100_LIBCPP_END_NAMESPACE_STD101 102#endif // _LIBCPP_STD_VER >= 20103 104_LIBCPP_POP_MACROS105 106#endif // _LIBCPP___ALGORITHM_RANGES_PARTITION_COPY_H107