/// \file // Range v3 library // // Copyright Eric Niebler 2021-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_ALGORITHM_FOLD_LEFT_HPP #define RANGES_V3_ALGORITHM_FOLD_LEFT_HPP #include #include #include #include #include #include #include namespace ranges { // clang-format off /// \concept indirectly_binary_left_foldable_impl /// \brief The \c indirectly_binary_left_foldable_impl concept template CPP_concept indirectly_binary_left_foldable_impl = movable && movable && convertible_to && invocable> && assignable_from>>; /// \concept indirectly_binary_left_foldable /// \brief The \c indirectly_binary_left_foldable concept template CPP_concept indirectly_binary_left_foldable = copy_constructible && indirectly_readable && invocable> && convertible_to>, std::decay_t>>> && indirectly_binary_left_foldable_impl>>>; // clang-format on /// \addtogroup group-algorithms /// @{ RANGES_FUNC_BEGIN(fold_left) template(typename I, typename S, typename T, typename Op)( requires sentinel_for AND input_iterator AND indirectly_binary_left_foldable) // constexpr auto RANGES_FUNC(fold_left)(I first, S last, T init, Op op) { using U = std::decay_t>>; if(first == last) { return U(std::move(init)); } U accum = invoke(op, std::move(init), *first); for(++first; first != last; ++first) { accum = invoke(op, std::move(accum), *first); } return accum; } template(typename Rng, typename T, typename Op)( requires input_range AND indirectly_binary_left_foldable>) // constexpr auto RANGES_FUNC(fold_left)(Rng && rng, T init, Op op) { return (*this)(begin(rng), end(rng), std::move(init), std::move(op)); } RANGES_FUNC_END(fold_left) RANGES_FUNC_BEGIN(fold_left_first) template(typename I, typename S, typename Op)( requires sentinel_for AND input_iterator AND indirectly_binary_left_foldable, I> AND constructible_from, iter_reference_t>) // constexpr auto RANGES_FUNC(fold_left_first)(I first, S last, Op op) { using U = invoke_result_t, Op>; if(first == last) { return optional(); } iter_value_t init = *first; ++first; return optional( in_place, fold_left_fn{}(std::move(first), std::move(last), std::move(init), op)); } template(typename R, typename Op)( requires input_range AND indirectly_binary_left_foldable, iterator_t> AND constructible_from, range_reference_t>) // constexpr auto RANGES_FUNC(fold_left_first)(R && rng, Op op) { return (*this)(begin(rng), end(rng), std::move(op)); } RANGES_FUNC_END(fold_left_first) /// @} } // namespace ranges #include #endif