File indexing completed on 2025-01-18 10:09:51
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014 #ifndef RANGES_V3_NUMERIC_PARTIAL_SUM_HPP
0015 #define RANGES_V3_NUMERIC_PARTIAL_SUM_HPP
0016
0017 #include <meta/meta.hpp>
0018
0019 #include <range/v3/algorithm/result_types.hpp>
0020 #include <range/v3/functional/arithmetic.hpp>
0021 #include <range/v3/functional/compose.hpp>
0022 #include <range/v3/functional/identity.hpp>
0023 #include <range/v3/functional/invoke.hpp>
0024 #include <range/v3/iterator/concepts.hpp>
0025 #include <range/v3/iterator/traits.hpp>
0026 #include <range/v3/iterator/unreachable_sentinel.hpp>
0027 #include <range/v3/range/access.hpp>
0028 #include <range/v3/range/concepts.hpp>
0029 #include <range/v3/range/dangling.hpp>
0030 #include <range/v3/range/traits.hpp>
0031 #include <range/v3/utility/static_const.hpp>
0032
0033 #include <range/v3/detail/prologue.hpp>
0034
0035 namespace ranges
0036 {
0037
0038
0039
0040
0041 namespace detail
0042 {
0043
0044 struct as_lvalue_fn
0045 {
0046 template<typename T>
0047 constexpr T & operator()(T && t) const noexcept
0048 {
0049 return t;
0050 }
0051 };
0052 template<typename I>
0053 using as_value_type_t = composed<as_lvalue_fn, coerce<iter_value_t<I>>>;
0054 }
0055
0056
0057
0058
0059
0060
0061 template(typename I, typename BOp)(
0062 concept (indirect_semigroup_)(I, BOp),
0063 copyable<iter_value_t<I>> AND
0064 indirectly_regular_binary_invocable_<
0065 composed<coerce<iter_value_t<I>>, BOp>,
0066 iter_value_t<I>*, I>
0067 );
0068
0069
0070 template<typename I, typename BOp>
0071 CPP_concept indirect_semigroup =
0072 indirectly_readable<I> &&
0073 CPP_concept_ref(ranges::indirect_semigroup_, I, BOp);
0074
0075
0076
0077 template(typename I, typename O, typename BOp, typename P)(
0078 concept (partial_sum_constraints_)(I, O, BOp, P),
0079 indirect_semigroup<
0080 projected<projected<I, detail::as_value_type_t<I>>, P>,
0081 BOp> AND
0082 output_iterator<
0083 O,
0084 iter_value_t<
0085 projected<projected<I, detail::as_value_type_t<I>>, P>> const &>
0086 );
0087
0088
0089 template<typename I, typename O, typename BOp = plus, typename P = identity>
0090 CPP_concept partial_sum_constraints =
0091 input_iterator<I> &&
0092 CPP_concept_ref(ranges::partial_sum_constraints_, I, O, BOp, P);
0093
0094
0095 template<typename I, typename O>
0096 using partial_sum_result = detail::in_out_result<I, O>;
0097
0098 struct partial_sum_fn
0099 {
0100 template(typename I, typename S1, typename O, typename S2, typename BOp = plus,
0101 typename P = identity)(
0102 requires sentinel_for<S1, I> AND sentinel_for<S2, O> AND
0103 partial_sum_constraints<I, O, BOp, P>)
0104 partial_sum_result<I, O> operator()(I first,
0105 S1 last,
0106 O result,
0107 S2 end_result,
0108 BOp bop = BOp{},
0109 P proj = P{}) const
0110 {
0111 using X = projected<projected<I, detail::as_value_type_t<I>>, P>;
0112 coerce<iter_value_t<I>> val_i;
0113 coerce<iter_value_t<X>> val_x;
0114 if(first != last && result != end_result)
0115 {
0116 auto && cur1 = val_i(*first);
0117 iter_value_t<X> t(invoke(proj, cur1));
0118 *result = t;
0119 for(++first, ++result; first != last && result != end_result;
0120 ++first, ++result)
0121 {
0122 auto && cur2 = val_i(*first);
0123 t = val_x(invoke(bop, t, invoke(proj, cur2)));
0124 *result = t;
0125 }
0126 }
0127 return {first, result};
0128 }
0129
0130 template(typename I, typename S, typename O, typename BOp = plus,
0131 typename P = identity)(
0132 requires sentinel_for<S, I> AND partial_sum_constraints<I, O, BOp, P>)
0133 partial_sum_result<I, O>
0134 operator()(I first, S last, O result, BOp bop = BOp{}, P proj = P{}) const
0135 {
0136 return (*this)(std::move(first),
0137 std::move(last),
0138 std::move(result),
0139 unreachable,
0140 std::move(bop),
0141 std::move(proj));
0142 }
0143
0144 template(typename Rng, typename ORef, typename BOp = plus, typename P = identity,
0145 typename I = iterator_t<Rng>, typename O = uncvref_t<ORef>)(
0146 requires range<Rng> AND partial_sum_constraints<I, O, BOp, P>)
0147 partial_sum_result<borrowed_iterator_t<Rng>, O>
0148 operator()(Rng && rng, ORef && result, BOp bop = BOp{}, P proj = P{}) const
0149 {
0150 return (*this)(begin(rng),
0151 end(rng),
0152 static_cast<ORef &&>(result),
0153 std::move(bop),
0154 std::move(proj));
0155 }
0156
0157 template(typename Rng, typename ORng, typename BOp = plus, typename P = identity,
0158 typename I = iterator_t<Rng>, typename O = iterator_t<ORng>)(
0159 requires range<Rng> AND range<ORng> AND partial_sum_constraints<I, O, BOp, P>)
0160 partial_sum_result<borrowed_iterator_t<Rng>, borrowed_iterator_t<ORng>>
0161 operator()(Rng && rng, ORng && result, BOp bop = BOp{}, P proj = P{}) const
0162 {
0163 return (*this)(begin(rng),
0164 end(rng),
0165 begin(result),
0166 end(result),
0167 std::move(bop),
0168 std::move(proj));
0169 }
0170 };
0171
0172 RANGES_INLINE_VARIABLE(partial_sum_fn, partial_sum)
0173
0174 }
0175
0176 #include <range/v3/detail/epilogue.hpp>
0177
0178 #endif