/// \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 namespace ranges { /// \cond namespace detail { // clang-format off CPP_def ( template(typename Rng, typename Fun) concept partial_sum_view_constraints, input_range && constructible_from, range_reference_t> && assignable_from &, range_reference_t> && indirectly_binary_invocable_, iterator_t> && assignable_from< range_value_t &, indirect_result_t, iterator_t>> ); // 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_; } CPP_template(bool Other)( // requires IsConst && (!Other) && 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_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 constexpr auto begin_cursor() const -> CPP_ret(cursor)( // requires detail::partial_sum_view_constraints) { 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_member constexpr auto CPP_fun(size)()(requires sized_range) { return ranges::size(base_); } CPP_member constexpr auto CPP_fun(size)()(const requires sized_range) { return ranges::size(base_); } }; #if RANGES_CXX_DEDUCTION_GUIDES >= RANGES_CXX_DEDUCTION_GUIDES_17 CPP_template(typename Rng, typename Fun)(requires copy_constructible) partial_sum_view(Rng &&, Fun) ->partial_sum_view, Fun>; #endif namespace views { struct partial_sum_fn { private: friend view_access; template static constexpr auto bind(partial_sum_fn partial_sum, Fun fun) { return make_pipeable(bind_back(partial_sum, std::move(fun))); } template RANGES_DEPRECATED( "Use \"ranges::views::partial_sum\" instead of " "\"ranges::views::partial_sum()\".") static constexpr auto bind(partial_sum_fn partial_sum) { return make_pipeable(bind_back(partial_sum, Fun{})); } public: template constexpr auto operator()(Rng && rng, Fun fun = {}) const -> CPP_ret(partial_sum_view, Fun>)( // requires detail::partial_sum_view_constraints, Fun>) { return {all(static_cast(rng)), std::move(fun)}; } }; /// \relates partial_sum_fn /// \ingroup group-views RANGES_INLINE_VARIABLE(view, partial_sum) } // namespace views /// @} } // namespace ranges #include RANGES_SATISFY_BOOST_RANGE(::ranges::partial_sum_view) #endif