/// \file // Range v3 library // // Copyright Eric Niebler 2013-present // Copyright Gonzalo Brito Gadeschi 2014 // // Use, modification and distribution is subject to the // Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // Project home: https://github.com/ericniebler/range-v3 // #ifndef RANGES_V3_NUMERIC_PARTIAL_SUM_HPP #define RANGES_V3_NUMERIC_PARTIAL_SUM_HPP #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include namespace ranges { /// \addtogroup group-numerics /// @{ /// \cond namespace detail { // Only needed for type-checking purposes: struct as_lvalue_fn { template constexpr T & operator()(T && t) const noexcept { return t; } }; template using as_value_type_t = composed>>; } // namespace detail /// \endcond // axiom: BOp is associative over values of I. // clang-format off /// \concept indirect_semigroup_ /// \brief The \c indirect_semigroup_ concept template(typename I, typename BOp)( concept (indirect_semigroup_)(I, BOp), copyable> AND indirectly_regular_binary_invocable_< composed>, BOp>, iter_value_t*, I> ); /// \concept indirect_semigroup /// \brief The \c indirect_semigroup concept template CPP_concept indirect_semigroup = indirectly_readable && CPP_concept_ref(ranges::indirect_semigroup_, I, BOp); /// \concept partial_sum_constraints_ /// \brief The \c partial_sum_constraints_ concept template(typename I, typename O, typename BOp, typename P)( concept (partial_sum_constraints_)(I, O, BOp, P), indirect_semigroup< projected>, P>, BOp> AND output_iterator< O, iter_value_t< projected>, P>> const &> ); /// \concept partial_sum_constraints /// \brief The \c partial_sum_constraints concept template CPP_concept partial_sum_constraints = input_iterator && CPP_concept_ref(ranges::partial_sum_constraints_, I, O, BOp, P); // clang-format on template using partial_sum_result = detail::in_out_result; struct partial_sum_fn { template(typename I, typename S1, typename O, typename S2, typename BOp = plus, typename P = identity)( requires sentinel_for AND sentinel_for AND partial_sum_constraints) partial_sum_result operator()(I first, S1 last, O result, S2 end_result, BOp bop = BOp{}, P proj = P{}) const { using X = projected>, P>; coerce> val_i; coerce> val_x; if(first != last && result != end_result) { auto && cur1 = val_i(*first); iter_value_t t(invoke(proj, cur1)); *result = t; for(++first, ++result; first != last && result != end_result; ++first, ++result) { auto && cur2 = val_i(*first); t = val_x(invoke(bop, t, invoke(proj, cur2))); *result = t; } } return {first, result}; } template(typename I, typename S, typename O, typename BOp = plus, typename P = identity)( requires sentinel_for AND partial_sum_constraints) partial_sum_result // operator()(I first, S last, O result, BOp bop = BOp{}, P proj = P{}) const { return (*this)(std::move(first), std::move(last), std::move(result), unreachable, std::move(bop), std::move(proj)); } template(typename Rng, typename ORef, typename BOp = plus, typename P = identity, typename I = iterator_t, typename O = uncvref_t)( requires range AND partial_sum_constraints) partial_sum_result, O> // operator()(Rng && rng, ORef && result, BOp bop = BOp{}, P proj = P{}) const { return (*this)(begin(rng), end(rng), static_cast(result), std::move(bop), std::move(proj)); } template(typename Rng, typename ORng, typename BOp = plus, typename P = identity, typename I = iterator_t, typename O = iterator_t)( requires range AND range AND partial_sum_constraints) partial_sum_result, borrowed_iterator_t> // operator()(Rng && rng, ORng && result, BOp bop = BOp{}, P proj = P{}) const { return (*this)(begin(rng), end(rng), begin(result), end(result), std::move(bop), std::move(proj)); } }; RANGES_INLINE_VARIABLE(partial_sum_fn, partial_sum) /// @} } // namespace ranges #include #endif