1 #ifndef UTOPIA_CORE_GRAPH_APPLY_HH
2 #define UTOPIA_CORE_GRAPH_APPLY_HH
5 #include <boost/graph/graph_traits.hpp>
10 #include "../state.hh"
38 template<
typename Graph,
typename Iter,
typename Rule>
39 void apply_async(Iter it_begin, Iter it_end, Graph&& g, Rule&& rule)
44 using Desc =
typename std::iterator_traits<Iter>::value_type;
45 using ReturnType =
typename std::invoke_result_t<Rule, Desc, Graph>;
46 constexpr
bool lambda_returns_void = std::is_same_v<ReturnType, void>;
49 if constexpr (lambda_returns_void){
51 [&rule, &g](
auto g_entity){
57 g[g_entity].state = rule(g_entity, g);
84 template<
typename Iter,
typename Graph,
typename Rule>
85 void apply_sync(Iter it_begin, Iter it_end, Graph&& g, Rule&& rule)
88 std::vector<decltype(g[*it_begin].state)> state_cache;
89 state_cache.reserve(std::distance(it_begin, it_end));
92 for (
auto entity : boost::make_iterator_range(it_begin, it_end)){
93 state_cache.push_back(rule(entity, g));
98 for (
auto entity : boost::make_iterator_range(it_begin, it_end)){
99 g[entity].state = std::move(state_cache[counter]);
132 typename std::enable_if_t<mode == Update::sync, int> = 0>
135 using namespace GraphUtils;
136 auto [it, it_end] = iterator_pair<iterate_over>(g);
164 typename std::enable_if_t<mode == Update::async, int> = 0>
168 "Refusing to asynchronously apply a rule without shuffling. Either "
169 "explicitly specify Shuffle::off or pass an RNG to apply_rule to "
172 using namespace GraphUtils;
173 auto [it, it_end] = iterator_pair<iterate_over>(g);
202 typename std::enable_if_t<mode == Update::async, int> = 0,
203 typename std::enable_if_t<shuffle == Shuffle::on, int> = 0>
206 using namespace GraphUtils;
210 auto [it, it_end] = Utopia::GraphUtils::iterator_pair<iterate_over>(g);
211 using Desc =
typename std::iterator_traits<decltype(it)>::value_type;
212 std::vector<Desc> it_shuffled(it, it_end);
216 std::forward<RNG>(
rng));
251 typename VertexDesc =
252 typename boost::graph_traits<
253 std::remove_reference_t<Graph>>::vertex_descriptor,
254 typename std::enable_if_t<mode == Update::sync, int> = 0>
256 const VertexDesc ref_vertex,
259 using namespace GraphUtils;
260 auto [it, it_end] = iterator_pair<iterate_over>(ref_vertex, g);
289 typename VertexDesc =
290 typename boost::graph_traits<
291 std::remove_reference_t<Graph>>::vertex_descriptor,
292 typename std::enable_if_t<mode == Update::async, int> = 0,
293 typename std::enable_if_t<shuffle == Shuffle::off, int> = 0>
295 const VertexDesc ref_vertex,
298 using namespace GraphUtils;
299 auto [it, it_end] = iterator_pair<iterate_over>(ref_vertex, g);
331 typename VertexDesc =
332 typename boost::graph_traits<
333 std::remove_reference_t<Graph>>::vertex_descriptor>
335 const VertexDesc ref_vertex,
340 "Shuffled apply_rule is only possible for Update::async!");
342 using namespace GraphUtils;
346 auto [it, it_end] = iterator_pair<iterate_over>(ref_vertex, g);
347 std::vector<VertexDesc> it_shuffled(it, it_end);
void for_each(const Utopia::ExecPolicy policy, InputIt first, InputIt last, UnaryFunction f)
Apply a function to a range.
Definition: parallel.hh:346
IterateOver
Over which graph entity to iterate.
Definition: iterator.hh:19
Shuffle
Switch for enabling/disabling shuffling the cells for asynchronous updates.
Definition: apply.hh:27
Update
Update modes when applying rules.
Definition: state.hh:20
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.
@ async
Asynchronous update.
void apply_sync(Iter it_begin, Iter it_end, Graph &&g, Rule &&rule)
Apply a rule synchronously.
Definition: apply.hh:85
void apply_async(Iter it_begin, Iter it_end, Graph &&g, Rule &&rule)
Apply a rule asynchronously.
Definition: apply.hh:39
std::mt19937 rng
– Type definitions ----------------------------------------------------—
Definition: test_revision.cc:17