15 #ifndef BELUGA_ACTIONS_PROPAGATE_HPP
16 #define BELUGA_ACTIONS_PROPAGATE_HPP
20 #include <type_traits>
25 #include <range/v3/action/action.hpp>
26 #include <range/v3/utility/random.hpp>
27 #include <range/v3/view/common.hpp>
52 class ExecutionPolicy,
54 class StateSamplingFunction,
55 std::enable_if_t<std::is_execution_policy_v<std::decay_t<ExecutionPolicy>>,
int> = 0,
56 std::enable_if_t<ranges::range<Range>,
int> = 0>
57 constexpr
auto operator()(ExecutionPolicy&&
policy, Range& range, StateSamplingFunction fn)
const -> Range& {
58 static_assert(beluga::is_particle_range_v<Range>);
61 auto unary_fn = [&]() {
62 using States = decltype(
states);
63 using State = ranges::range_value_t<States>;
64 using Generator = decltype(ranges::detail::get_random_engine());
65 if constexpr (std::is_invocable_v<StateSamplingFunction, State, Generator>) {
66 return [fn = std::move(fn)](
const State&
state) {
return fn(
state, ranges::detail::get_random_engine()); };
84 class StateSamplingFunction,
85 class ExecutionPolicy,
86 std::enable_if_t<ranges::range<Range>,
int> = 0,
87 std::enable_if_t<std::is_execution_policy_v<ExecutionPolicy>,
int> = 0>
88 constexpr
auto operator()(Range&& range, StateSamplingFunction fn, ExecutionPolicy
policy)
const -> Range& {
89 return (*
this)(std::move(
policy), std::forward<Range>(range), std::move(fn));
94 class ExecutionPolicy,
95 class StateSamplingFunction,
96 std::enable_if_t<std::is_execution_policy_v<ExecutionPolicy>,
int> = 0>
104 using propagate_base_fn::operator();
109 class StateSamplingFunction,
110 std::enable_if_t<ranges::range<Range>,
int> = 0>
111 constexpr
auto operator()(Range&& range, StateSamplingFunction fn)
const -> Range& {
112 return (*
this)(std::execution::seq, std::forward<Range>(range), std::move(fn));
116 template <
class StateSamplingFunction>
118 return ranges::make_action_closure(ranges::bind_back(
propagate_fn{}, std::move(fn)));