Horizon
partial_sum.hpp
Go to the documentation of this file.
1 // Range v3 library
3 //
4 // Copyright Eric Niebler 2013-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 
14 #ifndef RANGES_V3_VIEW_PARTIAL_SUM_HPP
15 #define RANGES_V3_VIEW_PARTIAL_SUM_HPP
16 
17 #include <iterator>
18 #include <type_traits>
19 #include <utility>
20 
21 #include <meta/meta.hpp>
22 
23 #include <range/v3/range_fwd.hpp>
24 
31 #include <range/v3/utility/addressof.hpp>
33 #include <range/v3/utility/static_const.hpp>
34 #include <range/v3/view/all.hpp>
35 #include <range/v3/view/facade.hpp>
36 #include <range/v3/view/view.hpp>
37 
38 #include <range/v3/detail/prologue.hpp>
39 
40 namespace ranges
41 {
43  namespace detail
44  {
45  // clang-format off
48  template(typename Rng, typename Fun)(
49  concept (partial_sum_view_constraints_)(Rng, Fun),
50  copy_constructible<range_value_t<Rng>> AND
51  constructible_from<range_value_t<Rng>, range_reference_t<Rng>> AND
52  assignable_from<range_value_t<Rng> &, range_reference_t<Rng>> AND
53  indirectly_binary_invocable_<Fun &, iterator_t<Rng>, iterator_t<Rng>> AND
54  assignable_from<
55  range_value_t<Rng> &,
56  indirect_result_t<Fun &, iterator_t<Rng>, iterator_t<Rng>>>
57  );
60  template<typename Rng, typename Fun>
61  CPP_concept partial_sum_view_constraints =
62  input_range<Rng> &&
63  copy_constructible<Fun> &&
64  CPP_concept_ref(detail::partial_sum_view_constraints_, Rng, Fun);
65  // clang-format on
66  } // namespace detail
68 
71  template<typename Rng, typename Fun>
74  {
75  private:
76  friend range_access;
77  CPP_assert(view_<Rng>);
78  CPP_assert(detail::partial_sum_view_constraints<Rng, Fun>);
79 
80  RANGES_NO_UNIQUE_ADDRESS Rng base_{};
81  RANGES_NO_UNIQUE_ADDRESS semiregular_box_t<Fun> fun_;
82 
83  template<bool IsConst>
84  struct cursor
85  {
86  private:
87  friend cursor<true>;
88 
89  using Parent = meta::const_if_c<IsConst, partial_sum_view>;
90  using Base = meta::const_if_c<IsConst, Rng>;
91 
92  Parent * parent_ = nullptr;
93  RANGES_NO_UNIQUE_ADDRESS iterator_t<Base> current_{};
94  RANGES_NO_UNIQUE_ADDRESS semiregular_box_t<range_value_t<Rng>> sum_;
95 
96  public:
98 
99  cursor() = default;
100  constexpr explicit cursor(Parent * rng)
101  : parent_{rng}
102  , current_(ranges::begin(rng->base_))
103  {
104  if(current_ != ranges::end(rng->base_))
105  sum_ = *current_;
106  }
107  template(bool Other)(
108  requires IsConst AND CPP_NOT(Other) AND
109  convertible_to<iterator_t<Rng> const &,
111  constexpr cursor(cursor<Other> const & that)
112  : parent_{that.parent_}
113  , current_(that.current_)
114  , sum_(that.sum_)
115  {}
116  constexpr range_value_t<Rng> read() const
117  {
118  RANGES_EXPECT(current_ != ranges::end(parent_->base_));
119  return sum_;
120  }
121  constexpr void next()
122  {
123  auto last = ranges::end(parent_->base_);
124  RANGES_EXPECT(current_ != last);
125  if(++current_ != last)
126  {
127  auto & sum = static_cast<range_value_t<Rng> &>(sum_);
128  using F = meta::const_if_c<IsConst, Fun>;
129  auto & f = static_cast<F &>(parent_->fun_);
130  sum = invoke(f, sum, *current_);
131  }
132  }
133  constexpr bool equal(default_sentinel_t) const
134  {
135  return current_ == ranges::end(parent_->base_);
136  }
137  CPP_auto_member
138  constexpr bool CPP_fun(equal)(cursor const & that)(const //
139  requires equality_comparable<iterator_t<Base>>)
140  {
141  RANGES_EXPECT(parent_ == that.parent_);
142  return current_ == that.current_;
143  }
144  };
145 
146  constexpr cursor<false> begin_cursor()
147  {
148  return cursor<false>{this};
149  }
150  template(typename CRng = Rng const)(
151  requires detail::partial_sum_view_constraints<CRng, Fun const>)
152  constexpr cursor<true> begin_cursor() const
153  {
154  return cursor<true>{this};
155  }
156 
157  public:
158  partial_sum_view() = default;
159  constexpr partial_sum_view(Rng rng, Fun fun) noexcept(
160  std::is_nothrow_move_constructible<Rng>::value &&
161  std::is_nothrow_move_constructible<Fun>::value)
162  : base_(std::move(rng))
163  , fun_(std::move(fun))
164  {}
165  CPP_auto_member
166  constexpr auto CPP_fun(size)()(
167  requires sized_range<Rng>)
168  {
169  return ranges::size(base_);
170  }
171  CPP_auto_member
172  constexpr auto CPP_fun(size)()(const //
173  requires sized_range<Rng const>)
174  {
175  return ranges::size(base_);
176  }
177  };
178 
179 #if RANGES_CXX_DEDUCTION_GUIDES >= RANGES_CXX_DEDUCTION_GUIDES_17
180  template(typename Rng, typename Fun)(
181  requires copy_constructible<Fun>)
182  partial_sum_view(Rng &&, Fun)
184 #endif
185 
186  namespace views
187  {
189  {
190  template(typename Rng, typename Fun = plus)(
191  requires detail::partial_sum_view_constraints<all_t<Rng>, Fun>)
192  constexpr partial_sum_view<all_t<Rng>, Fun> //
193  operator()(Rng && rng, Fun fun = {}) const
194  {
195  return {all(static_cast<Rng &&>(rng)), std::move(fun)};
196  }
197  };
198 
200  {
201  using partial_sum_base_fn::operator();
202 
203  template(typename Fun)(
204  requires (!range<Fun>))
205  constexpr auto operator()(Fun && fun) const
206  {
207  return make_view_closure(
208  bind_back(partial_sum_base_fn{}, static_cast<Fun &&>(fun)));
209  }
210  template<typename Fun = plus>
211  RANGES_DEPRECATED(
212  "Use \"ranges::views::partial_sum\" instead of "
213  "\"ranges::views::partial_sum()\".")
214  constexpr auto
215  operator()() const
216  {
217  return make_view_closure(bind_back(partial_sum_base_fn{}, Fun{}));
218  }
219  };
220 
224  } // namespace views
226 } // namespace ranges
227 
228 #include <range/v3/detail/epilogue.hpp>
229 
230 #include <range/v3/detail/satisfy_boost_range.hpp>
231 RANGES_SATISFY_BOOST_RANGE(::ranges::partial_sum_view)
232 
233 #endif
decltype(begin(declval(Rng &))) iterator_t
Definition: access.hpp:698
RANGES_INLINE_VARIABLE(detail::to_container_fn< detail::from_range< std::vector >>, to_vector) template< template< typename... > class ContT > auto to(RANGES_HIDDEN_DETAIL(detail
For initializing a container of the specified type with the elements of an Range.
Definition: conversion.hpp:399
std::integral_constant< bool, B > bool_
An integral constant wrapper for bool.
Definition: meta.hpp:168
typename Fn::template invoke< Args... > invoke
Evaluate the invocable Fn with the arguments Args.
Definition: meta.hpp:541
defer< bind_back, Fn, Ts... > bind_back
Definition: meta.hpp:994
meta::size_t< L::size()> size
An integral constant wrapper that is the size of the meta::list L.
Definition: meta.hpp:1696
std::integral_constant< decltype(T::type::value+U::type::value), T::type::value+U::type::value > plus
An integral constant wrapper around the result of adding the two wrapped integers T::type::value and ...
Definition: meta.hpp:197
Tiny meta-programming library.
Definition: default_sentinel.hpp:26
Definition: partial_sum.hpp:74
Definition: traits.hpp:128
A utility for constructing a view from a (derived) type that implements begin and end cursors.
Definition: facade.hpp:66
Definition: partial_sum.hpp:189
Definition: partial_sum.hpp:200
Definition: view.hpp:178