1#ifndef UTOPIA_CORE_APPLY_HH
2#define UTOPIA_CORE_APPLY_HH
16template<
class Container>
17using entity_t =
typename Container::value_type::element_type;
46template<
typename State,
typename Rule,
typename...
Args>
52 std::is_invocable_v<Rule,
53 typename std::remove_reference_t<Args>::reference...>,
54 "Cannot invoke the Rule with the given container elements as arguments!"
55 " Please check the rule signature!");
59 using type = std::invoke_result_t<
61 typename std::remove_reference_t<Args>::reference...>;
66 std::is_same_v<type, void>
or std::is_convertible_v<type, State>,
67 "Invoking the rule must return a type that can be converted to the "
68 "Entity state type!");
74template<
typename State,
typename Rule,
typename...
Args>
81template<
typename State,
typename Rule,
typename...
Args>
93template<
class Tuple, std::size_t...
I>
94constexpr decltype(
auto)
97 return std::make_tuple(std::get<I>(std::forward<Tuple>(
t))...);
113constexpr decltype(
auto)
117 std::forward<Tuple>(
t),
118 std::make_index_sequence<
119 std::tuple_size_v<std::remove_reference_t<Tuple>>>{});
129 typename std::enable_if_t<mode == Update::sync, int> = 0,
130 typename std::enable_if_t<
131 impl::entity_t<ContTarget>::mode
160 typename std::enable_if_t<mode == Update::sync, int> = 0,
161 typename std::enable_if_t<
162 impl::entity_t<ContTarget>::mode
173 "Cannot apply void rules in a synchronous update!");
182 using std::begin, std::end;
191 return std::apply(
rule,
192 std::forward<
decltype(
args)>(
args));
201 std::get<0>(
tpl)->state = std::move(std::get<1>(
tpl));
211 typename std::enable_if_t<mode == Update::async, int> = 0,
212 typename std::enable_if_t<
213 impl::entity_t<ContTarget>::mode
215 typename std::enable_if_t<shuffle == Shuffle::off, int> = 0>
248 typename std::enable_if_t<mode == Update::async, int> = 0,
249 typename std::enable_if_t<
250 impl::entity_t<ContTarget>::mode
252 typename std::enable_if_t<shuffle == Shuffle::off, int> = 0>
261 using std::begin, std::end;
269 std::forward<
decltype(
args)>(
args));
276 std::forward<
decltype(
args)>(
args));
288 typename std::enable_if_t<mode == Update::async, int> = 0,
289 typename std::enable_if_t<
290 impl::entity_t<ContTarget>::mode
292 typename std::enable_if_t<shuffle == Shuffle::on, int> = 0>
339 typename std::enable_if_t<mode == Update::async, int> = 0,
340 typename std::enable_if_t<
341 impl::entity_t<ContTarget>::mode
343 typename std::enable_if_t<shuffle == Shuffle::on, int> = 0>
353 using std::begin, std::end;
361 using Tuple = std::tuple<
363 std::reference_wrapper<
364 const typename std::remove_reference_t<ContTarget>::value_type>,
368 std::is_const_v<std::remove_reference_t<ContArgs>>,
370 std::reference_wrapper<
371 const typename std::remove_reference_t<ContArgs>::value_type>,
373 std::reference_wrapper<
374 typename std::remove_reference_t<ContArgs>::value_type>>...>;
394 std::forward<
decltype(
args)>(
args)));
406 std::forward<
decltype(
args)>(
args));
428 bool sync=impl::entity_t<Container>::is_sync()>
429std::enable_if_t<sync, void>
434 std::invoke_result_t<Rule, typename Container::value_type>;
436 if constexpr(std::is_same_v<ReturnType, void>) {
467 bool sync=impl::entity_t<Container>::is_sync()>
468std::enable_if_t<not sync && not shuffle, void>
473 std::invoke_result_t<Rule, typename Container::value_type>;
475 if constexpr(std::is_same_v<ReturnType, void>) {
499 bool sync=impl::entity_t<Container>::is_sync()>
500std::enable_if_t<not sync && shuffle, void>
506 std::forward<RNG>(rng));
510 std::invoke_result_t<Rule, typename Container::value_type>;
512 if constexpr(std::is_same_v<ReturnType, void>)
Helper class for checking rule signatures and return types.
Definition apply.hh:48
std::invoke_result_t< Rule, typename std::remove_reference_t< Args >::reference... > type
Report rule invoke result.
Definition apply.hh:61
OutputIt transform(const Utopia::ExecPolicy policy, InputIt first1, InputIt last1, OutputIt d_first, UnaryOperation unary_op)
Apply a unary operator to a range and store the result in a new range.
Definition parallel.hh:368
void for_each(const Utopia::ExecPolicy policy, InputIt first, InputIt last, UnaryFunction f)
Apply a function to a range.
Definition parallel.hh:346
Container select_entities(const Manager &mngr, const DataIO::Config &sel_cfg)
Select entities according to parameters specified in a configuration.
Definition select.hh:213
decltype(auto) range(const Graph &g)
Get the iterator range over selected graph entities.
Definition iterator.hh:149
ExecPolicy
Runtime execution policies.
Definition parallel.hh:60
@ seq
Sequential (i.e., regular) execution.
Definition parallel.hh:66
@ par_unseq
SIMD execution on multiple threads.
Definition parallel.hh:69
constexpr decltype(auto) make_tuple_from_tuple(Tuple &&t)
Helper function to create a tuple from a tuple.
Definition apply.hh:114
constexpr decltype(auto) make_tuple_from_tuple_impl(Tuple &&t, std::index_sequence< I... >)
Helper function to create a tuple from a tuple using an index sequence.
Definition apply.hh:95
Shuffle
Switch for enabling/disabling shuffling the cells for asynchronous updates.
Definition apply.hh:27
constexpr bool is_void_rule()
Helper function to check if the rule returns void
Definition apply.hh:82
Update
Update modes when applying rules.
Definition state.hh:20
typename rule_invoke_result< State, Rule, Args... >::type rule_invoke_result_t
Helper definition to query the rule result type.
Definition apply.hh:76
void apply_rule(Rule &&rule, const ContTarget &cont_target, ContArgs &&... cont_args)
Sequential overload.
Definition apply.hh:133
@ off
Immediately apply the rule sequentially.
@ on
Shuffle the container before applying the rule sequentially.
@ manual
User chooses update type when calling apply_rule()
@ sync
Synchronous update.
typename Container::value_type::element_type entity_t
Return the element type of any container holding pointers to entities.
Definition apply.hh:17