6namespace probfd::views {
8#ifndef __cpp_lib_ranges_fold
18 template <
typename Tp,
typename Up>
19 requires std::invocable<Fp&, Up, Tp>
20 std::invoke_result_t<Fp&, Up, Tp>
21 operator()(Tp&&, Up&&);
24template <
typename Fp,
typename Tp,
typename Iter,
typename Up>
25concept indirectly_binary_left_foldable_impl =
26 std::movable<Tp> && std::movable<Up> && std::convertible_to<Tp, Up> &&
27 std::invocable<Fp&, Up, std::iter_reference_t<Iter>> &&
30 std::invoke_result_t<Fp&, Up, std::iter_reference_t<Iter>>>;
32template <
typename Fp,
typename Tp,
typename Iter>
33concept indirectly_binary_left_foldable =
34 std::copy_constructible<Fp> && std::indirectly_readable<Iter> &&
35 std::invocable<Fp&, Tp, std::iter_reference_t<Iter>> &&
37 std::invoke_result_t<Fp&, Tp, std::iter_reference_t<Iter>>,
39 std::invoke_result_t<Fp&, Tp, std::iter_reference_t<Iter>>>> &&
40 indirectly_binary_left_foldable_impl<
45 std::invoke_result_t<Fp&, Tp, std::iter_reference_t<Iter>>>>;
47template <
typename Fp,
typename Tp,
typename Iter>
48concept indirectly_binary_right_foldable =
49 indirectly_binary_left_foldable<flipped<Fp>, Tp, Iter>;
54 std::input_iterator I,
55 std::sentinel_for<I> S,
56 class T = std::iter_value_t<I>,
57 detail::indirectly_binary_left_foldable<T, I> F>
58 constexpr auto operator()(I first, S last, T init, F f)
const
61 std::decay_t<std::invoke_result_t<F&, T, std::iter_reference_t<I>>>;
62 if (first == last)
return U(std::move(init));
63 U accum = std::invoke(f, std::move(init), *first);
64 for (++first; first != last; ++first)
65 accum = std::invoke(f, std::move(accum), *first);
66 return std::move(accum);
70 std::ranges::input_range R,
71 class T = std::ranges::range_value_t<R>,
72 detail::indirectly_binary_left_foldable<T, std::ranges::iterator_t<R>>
74 constexpr auto operator()(R&& r, T init, F f)
const
77 std::ranges::begin(r),
84inline constexpr fold_left_fn fold_left;
88inline constexpr auto fold_left = std::ranges::fold_left;