/// \file // Range v3 library // // Copyright Eric Niebler 2013-present // // 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_VIEW_PARTIAL_SUM_HPP #define RANGES_V3_VIEW_PARTIAL_SUM_HPP #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include namespace ranges { /// \cond namespace detail { // clang-format off /// \concept partial_sum_view_constraints_ /// \brief The \c partial_sum_view_constraints_ concept template(typename Rng, typename Fun)( concept (partial_sum_view_constraints_)(Rng, Fun), copy_constructible> AND constructible_from, range_reference_t> AND assignable_from &, range_reference_t> AND indirectly_binary_invocable_, iterator_t> AND assignable_from< range_value_t &, indirect_result_t, iterator_t>> ); /// \concept partial_sum_view_constraints /// \brief The \c partial_sum_view_constraints concept template CPP_concept partial_sum_view_constraints = input_range && copy_constructible && CPP_concept_ref(detail::partial_sum_view_constraints_, Rng, Fun); // clang-format on } // namespace detail /// \endcond /// \addtogroup group-views /// @{ template struct partial_sum_view : view_facade, range_cardinality::value> { private: friend range_access; CPP_assert(view_); CPP_assert(detail::partial_sum_view_constraints); RANGES_NO_UNIQUE_ADDRESS Rng base_{}; RANGES_NO_UNIQUE_ADDRESS semiregular_box_t fun_; template struct cursor { private: friend cursor; using Parent = meta::const_if_c; using Base = meta::const_if_c; Parent * parent_ = nullptr; RANGES_NO_UNIQUE_ADDRESS iterator_t current_{}; RANGES_NO_UNIQUE_ADDRESS semiregular_box_t> sum_; public: using single_pass = meta::bool_>>; cursor() = default; constexpr explicit cursor(Parent * rng) : parent_{rng} , current_(ranges::begin(rng->base_)) { if(current_ != ranges::end(rng->base_)) sum_ = *current_; } template(bool Other)( requires IsConst AND CPP_NOT(Other) AND convertible_to const &, iterator_t>) constexpr cursor(cursor const & that) : parent_{that.parent_} , current_(that.current_) , sum_(that.sum_) {} constexpr range_value_t read() const { RANGES_EXPECT(current_ != ranges::end(parent_->base_)); return sum_; } constexpr void next() { auto last = ranges::end(parent_->base_); RANGES_EXPECT(current_ != last); if(++current_ != last) { auto & sum = static_cast &>(sum_); using F = meta::const_if_c; auto & f = static_cast(parent_->fun_); sum = invoke(f, sum, *current_); } } constexpr bool equal(default_sentinel_t) const { return current_ == ranges::end(parent_->base_); } CPP_auto_member constexpr bool CPP_fun(equal)(cursor const & that)(const // requires equality_comparable>) { RANGES_EXPECT(parent_ == that.parent_); return current_ == that.current_; } }; constexpr cursor begin_cursor() { return cursor{this}; } template(typename CRng = Rng const)( requires detail::partial_sum_view_constraints) constexpr cursor begin_cursor() const { return cursor{this}; } public: partial_sum_view() = default; constexpr partial_sum_view(Rng rng, Fun fun) noexcept( std::is_nothrow_move_constructible::value && std::is_nothrow_move_constructible::value) : base_(std::move(rng)) , fun_(std::move(fun)) {} CPP_auto_member constexpr auto CPP_fun(size)()( requires sized_range) { return ranges::size(base_); } CPP_auto_member constexpr auto CPP_fun(size)()(const // requires sized_range) { return ranges::size(base_); } }; #if RANGES_CXX_DEDUCTION_GUIDES >= RANGES_CXX_DEDUCTION_GUIDES_17 template(typename Rng, typename Fun)( requires copy_constructible) partial_sum_view(Rng &&, Fun) -> partial_sum_view, Fun>; #endif namespace views { struct partial_sum_base_fn { template(typename Rng, typename Fun = plus)( requires detail::partial_sum_view_constraints, Fun>) constexpr partial_sum_view, Fun> // operator()(Rng && rng, Fun fun = {}) const { return {all(static_cast(rng)), std::move(fun)}; } }; struct partial_sum_fn : partial_sum_base_fn { using partial_sum_base_fn::operator(); template(typename Fun)( requires (!range)) constexpr auto operator()(Fun && fun) const { return make_view_closure( bind_back(partial_sum_base_fn{}, static_cast(fun))); } template RANGES_DEPRECATED( "Use \"ranges::views::partial_sum\" instead of " "\"ranges::views::partial_sum()\".") constexpr auto operator()() const { return make_view_closure(bind_back(partial_sum_base_fn{}, Fun{})); } }; /// \relates partial_sum_fn /// \ingroup group-views RANGES_INLINE_VARIABLE(view_closure, partial_sum) } // namespace views /// @} } // namespace ranges #include #include RANGES_SATISFY_BOOST_RANGE(::ranges::partial_sum_view) #endif