1 /// \file 2 // Range v3 library 3 // 4 // Copyright Eric Niebler 2014-present 5 // 6 // Use, modification and distribution is subject to the 7 // Boost Software License, Version 1.0. (See accompanying 8 // file LICENSE_1_0.txt or copy at 9 // http://www.boost.org/LICENSE_1_0.txt) 10 // 11 // Project home: https://github.com/ericniebler/range-v3 12 // 13 #ifndef RANGES_V3_ALGORITHM_PARTITION_COPY_HPP 14 #define RANGES_V3_ALGORITHM_PARTITION_COPY_HPP 15 16 #include <tuple> 17 18 #include <meta/meta.hpp> 19 20 #include <range/v3/range_fwd.hpp> 21 22 #include <range/v3/algorithm/result_types.hpp> 23 #include <range/v3/functional/identity.hpp> 24 #include <range/v3/functional/invoke.hpp> 25 #include <range/v3/iterator/concepts.hpp> 26 #include <range/v3/iterator/operations.hpp> 27 #include <range/v3/iterator/traits.hpp> 28 #include <range/v3/range/access.hpp> 29 #include <range/v3/range/concepts.hpp> 30 #include <range/v3/range/dangling.hpp> 31 #include <range/v3/range/traits.hpp> 32 #include <range/v3/utility/static_const.hpp> 33 34 #include <range/v3/detail/prologue.hpp> 35 36 namespace ranges 37 { 38 /// \addtogroup group-algorithms 39 /// @{ 40 template<typename I, typename O0, typename O1> 41 using partition_copy_result = detail::in_out1_out2_result<I, O0, O1>; 42 RANGES_FUNC_BEGIN(partition_copy)43 RANGES_FUNC_BEGIN(partition_copy) 44 45 /// \brief function template \c partition_copy 46 template(typename I, 47 typename S, 48 typename O0, 49 typename O1, 50 typename C, 51 typename P = identity)( 52 /// \pre 53 requires input_iterator<I> AND sentinel_for<S, I> AND 54 weakly_incrementable<O0> AND weakly_incrementable<O1> AND 55 indirectly_copyable<I, O0> AND indirectly_copyable<I, O1> AND 56 indirect_unary_predicate<C, projected<I, P>>) 57 partition_copy_result<I, O0, O1> RANGES_FUNC(partition_copy)( 58 I first, S last, O0 o0, O1 o1, C pred, P proj = P{}) 59 { 60 for(; first != last; ++first) 61 { 62 auto && x = *first; 63 if(invoke(pred, invoke(proj, x))) 64 { 65 *o0 = (decltype(x) &&)x; 66 ++o0; 67 } 68 else 69 { 70 *o1 = (decltype(x) &&)x; 71 ++o1; 72 } 73 } 74 return {first, o0, o1}; 75 } 76 77 /// \overload 78 template(typename Rng, 79 typename O0, 80 typename O1, 81 typename C, 82 typename P = identity)( 83 /// \pre 84 requires input_range<Rng> AND weakly_incrementable<O0> AND 85 weakly_incrementable<O1> AND indirectly_copyable<iterator_t<Rng>, O0> AND 86 indirectly_copyable<iterator_t<Rng>, O1> AND 87 indirect_unary_predicate<C, projected<iterator_t<Rng>, P>>) 88 partition_copy_result<borrowed_iterator_t<Rng>, O0, O1> // RANGES_FUNC(partition_copy)89 RANGES_FUNC(partition_copy)(Rng && rng, O0 o0, O1 o1, C pred, P proj = P{}) 90 { 91 return (*this)(begin(rng), 92 end(rng), 93 std::move(o0), 94 std::move(o1), 95 std::move(pred), 96 std::move(proj)); 97 } 98 99 RANGES_FUNC_END(partition_copy) 100 101 namespace cpp20 102 { 103 using ranges::partition_copy; 104 using ranges::partition_copy_result; 105 } // namespace cpp20 106 /// @} 107 } // namespace ranges 108 109 #include <range/v3/detail/epilogue.hpp> 110 111 #endif 112