Horizon
Loading...
Searching...
No Matches
partial_sum.hpp
Go to the documentation of this file.
1
2// Range v3 library
3//
4// Copyright Eric Niebler 2013-present
5// Copyright Gonzalo Brito Gadeschi 2014
6//
7// Use, modification and distribution is subject to the
8// Boost Software License, Version 1.0. (See accompanying
9// file LICENSE_1_0.txt or copy at
10// http://www.boost.org/LICENSE_1_0.txt)
11//
12// Project home: https://github.com/ericniebler/range-v3
13//
14#ifndef RANGES_V3_NUMERIC_PARTIAL_SUM_HPP
15#define RANGES_V3_NUMERIC_PARTIAL_SUM_HPP
16
17#include <meta/meta.hpp>
18
19#include <range/v3/algorithm/result_types.hpp>
31#include <range/v3/utility/static_const.hpp>
32
33#include <range/v3/detail/prologue.hpp>
34
35namespace ranges
36{
39
41 namespace detail
42 {
43 // Only needed for type-checking purposes:
44 struct as_lvalue_fn
45 {
46 template<typename T>
47 constexpr T & operator()(T && t) const noexcept
48 {
49 return t;
50 }
51 };
52 template<typename I>
53 using as_value_type_t = composed<as_lvalue_fn, coerce<iter_value_t<I>>>;
54 } // namespace detail
56
57 // axiom: BOp is associative over values of I.
58 // clang-format off
61 template(typename I, typename BOp)(
62 concept (indirect_semigroup_)(I, BOp),
63 copyable<iter_value_t<I>> AND
64 indirectly_regular_binary_invocable_<
65 composed<coerce<iter_value_t<I>>, BOp>,
66 iter_value_t<I>*, I>
67 );
70 template<typename I, typename BOp>
71 CPP_concept indirect_semigroup =
72 indirectly_readable<I> &&
73 CPP_concept_ref(ranges::indirect_semigroup_, I, BOp);
74
77 template(typename I, typename O, typename BOp, typename P)(
78 concept (partial_sum_constraints_)(I, O, BOp, P),
79 indirect_semigroup<
80 projected<projected<I, detail::as_value_type_t<I>>, P>,
81 BOp> AND
82 output_iterator<
83 O,
84 iter_value_t<
85 projected<projected<I, detail::as_value_type_t<I>>, P>> const &>
86 );
89 template<typename I, typename O, typename BOp = plus, typename P = identity>
90 CPP_concept partial_sum_constraints =
91 input_iterator<I> &&
92 CPP_concept_ref(ranges::partial_sum_constraints_, I, O, BOp, P);
93 // clang-format on
94
95 template<typename I, typename O>
96 using partial_sum_result = detail::in_out_result<I, O>;
97
99 {
100 template(typename I, typename S1, typename O, typename S2, typename BOp = plus,
101 typename P = identity)(
104 partial_sum_result<I, O> operator()(I first,
105 S1 last,
106 O result,
107 S2 end_result,
108 BOp bop = BOp{},
109 P proj = P{}) const
110 {
111 using X = projected<projected<I, detail::as_value_type_t<I>>, P>;
114 if(first != last && result != end_result)
115 {
116 auto && cur1 = val_i(*first);
117 iter_value_t<X> t(invoke(proj, cur1));
118 *result = t;
119 for(++first, ++result; first != last && result != end_result;
120 ++first, ++result)
121 {
122 auto && cur2 = val_i(*first);
123 t = val_x(invoke(bop, t, invoke(proj, cur2)));
124 *result = t;
125 }
126 }
127 return {first, result};
128 }
129
130 template(typename I, typename S, typename O, typename BOp = plus,
131 typename P = identity)(
133 partial_sum_result<I, O> //
134 operator()(I first, S last, O result, BOp bop = BOp{}, P proj = P{}) const
135 {
136 return (*this)(std::move(first),
137 std::move(last),
138 std::move(result),
139 unreachable,
140 std::move(bop),
141 std::move(proj));
142 }
143
144 template(typename Rng, typename ORef, typename BOp = plus, typename P = identity,
145 typename I = iterator_t<Rng>, typename O = uncvref_t<ORef>)(
147 partial_sum_result<borrowed_iterator_t<Rng>, O> //
148 operator()(Rng && rng, ORef && result, BOp bop = BOp{}, P proj = P{}) const
149 {
150 return (*this)(begin(rng),
151 end(rng),
152 static_cast<ORef &&>(result),
153 std::move(bop),
154 std::move(proj));
155 }
156
157 template(typename Rng, typename ORng, typename BOp = plus, typename P = identity,
158 typename I = iterator_t<Rng>, typename O = iterator_t<ORng>)(
160 partial_sum_result<borrowed_iterator_t<Rng>, borrowed_iterator_t<ORng>> //
161 operator()(Rng && rng, ORng && result, BOp bop = BOp{}, P proj = P{}) const
162 {
163 return (*this)(begin(rng),
164 end(rng),
165 begin(result),
166 end(result),
167 std::move(bop),
168 std::move(proj));
169 }
170 };
171
172 RANGES_INLINE_VARIABLE(partial_sum_fn, partial_sum)
174} // namespace ranges
175
176#include <range/v3/detail/epilogue.hpp>
177
178#endif
The indirect_semigroup_ concept.
The partial_sum_constraints_ concept.
The partial_sum_constraints concept.
The range concept.
The sentinel_for concept.
decltype(begin(declval(Rng &))) iterator_t
Definition access.hpp:698
Tiny meta-programming library.
Definition arithmetic.hpp:78
Definition identity.hpp:25
Definition partial_sum.hpp:99
Definition arithmetic.hpp:25