Utopia  2
Framework for studying models of complex & adaptive systems.
Classes | Typedefs | Enumerations | Functions
Rules on Entities

Algorithms for conveniently applying function objects on entities. More...

Collaboration diagram for Rules on Entities:

Classes

class  Utopia::rule_invoke_result< State, Rule, Args >
 Helper class for checking rule signatures and return types. More...
 
class  Utopia::StateContainer< StateType, mode >
 Container for states. More...
 
class  Utopia::StateContainer< StateType, Update::manual >
 A very simple, default constructible container with public members. More...
 
class  Utopia::StateContainer< StateType, Update::async >
 State Container specialization for async states. More...
 
class  Utopia::StateContainer< StateType, Update::sync >
 State Container specialization for sync states. More...
 

Typedefs

template<typename State , typename Rule , typename... Args>
using Utopia::rule_invoke_result_t = typename rule_invoke_result< State, Rule, Args... >::type
 Helper definition to query the rule result type. More...
 

Enumerations

enum class  Utopia::Shuffle { Utopia::on , Utopia::off }
 Switch for enabling/disabling shuffling the cells for asynchronous updates. More...
 
enum class  Utopia::Update { Utopia::manual , Utopia::sync , Utopia::async }
 Update modes when applying rules. More...
 

Functions

template<typename State , typename Rule , typename... Args>
constexpr bool Utopia::is_void_rule ()
 Helper function to check if the rule returns void More...
 
template<class Tuple , std::size_t... I>
constexpr decltype(auto) Utopia::make_tuple_from_tuple_impl (Tuple &&t, std::index_sequence< I... >)
 Helper function to create a tuple from a tuple using an index sequence. More...
 
template<class Tuple >
constexpr decltype(auto) Utopia::make_tuple_from_tuple (Tuple &&t)
 Helper function to create a tuple from a tuple. More...
 
template<Update mode, class Rule , class ContTarget , class... ContArgs, typename std::enable_if_t< mode==Update::sync, int > = 0, typename std::enable_if_t< impl::entity_t< ContTarget >::mode==Update::manual, int > = 0>
void Utopia::apply_rule (Rule &&rule, const ContTarget &cont_target, ContArgs &&... cont_args)
 Sequential overload. More...
 
template<Update mode, class Rule , class ContTarget , class... ContArgs, typename std::enable_if_t< mode==Update::sync, int > = 0, typename std::enable_if_t< impl::entity_t< ContTarget >::mode==Update::manual, int > = 0>
void Utopia::apply_rule (const Utopia::ExecPolicy policy, Rule &&rule, const ContTarget &cont_target, ContArgs &&... cont_args)
 Apply a rule synchronously to manually updated states. More...
 
template<Update mode, Shuffle shuffle = Shuffle::on, class Rule , class ContTarget , class... ContArgs, typename std::enable_if_t< mode==Update::async, int > = 0, typename std::enable_if_t< impl::entity_t< ContTarget >::mode==Update::manual, int > = 0, typename std::enable_if_t< shuffle==Shuffle::off, int > = 0>
void Utopia::apply_rule (Rule &&rule, const ContTarget &cont_target, ContArgs &&... cont_args)
 Sequential case overload. More...
 
template<Update mode, Shuffle shuffle = Shuffle::on, class Rule , class ContTarget , class... ContArgs, typename std::enable_if_t< mode==Update::async, int > = 0, typename std::enable_if_t< impl::entity_t< ContTarget >::mode==Update::manual, int > = 0, typename std::enable_if_t< shuffle==Shuffle::off, int > = 0>
void Utopia::apply_rule (const Utopia::ExecPolicy policy, Rule &&rule, const ContTarget &cont_target, ContArgs &&... cont_args)
 Apply a rule asynchronously to manually updated states. More...
 
template<Update mode, Shuffle shuffle = Shuffle::on, class Rule , class ContTarget , class RNG , class... ContArgs, typename std::enable_if_t< mode==Update::async, int > = 0, typename std::enable_if_t< impl::entity_t< ContTarget >::mode==Update::manual, int > = 0, typename std::enable_if_t< shuffle==Shuffle::on, int > = 0>
void Utopia::apply_rule (Rule &&rule, const ContTarget &cont_target, RNG &&rng, ContArgs &&... cont_args)
 Sequential case overload. More...
 
template<Update mode, Shuffle shuffle = Shuffle::on, class Rule , class ContTarget , class RNG , class... ContArgs, typename std::enable_if_t< mode==Update::async, int > = 0, typename std::enable_if_t< impl::entity_t< ContTarget >::mode==Update::manual, int > = 0, typename std::enable_if_t< shuffle==Shuffle::on, int > = 0>
void Utopia::apply_rule (const Utopia::ExecPolicy policy, Rule &&rule, const ContTarget &cont_target, RNG &&rng, ContArgs &&... cont_args)
 Apply a rule asynchronously and shuffled to manually updated states. More...
 
template<class Rule , class Container , bool sync = impl::entity_t<Container>::is_sync()>
std::enable_if_t< sync, void > Utopia::apply_rule (const Rule &rule, const Container &container)
 Apply a rule synchronously on the state of all entities of a container. More...
 
template<bool shuffle = true, class Rule , class Container , bool sync = impl::entity_t<Container>::is_sync()>
std::enable_if_t< not sync &&not shuffle, void > Utopia::apply_rule (const Rule &rule, const Container &container)
 Apply a rule on asynchronous states without prior shuffling. More...
 
template<bool shuffle = true, class Rule , class Container , class RNG , bool sync = impl::entity_t<Container>::is_sync()>
std::enable_if_t< not sync &&shuffle, void > Utopia::apply_rule (const Rule &rule, const Container &container, RNG &&rng)
 Apply a rule on asynchronous states with prior shuffling. More...
 
template<IterateOver iterate_over, Update mode, typename Graph , typename Rule , typename std::enable_if_t< mode==Update::sync, int > = 0>
void Utopia::apply_rule (Rule &&rule, Graph &&g)
 Synchronously apply a rule to graph entities. More...
 
template<IterateOver iterate_over, Update mode, Shuffle shuffle, typename Graph , typename Rule , typename std::enable_if_t< mode==Update::async, int > = 0>
void Utopia::apply_rule (Rule &&rule, Graph &&g)
 Asynchronously apply a rule to graph entities, without shuffling. More...
 
template<IterateOver iterate_over, Update mode, Shuffle shuffle = Shuffle::on, typename Graph , typename Rule , typename RNG , typename std::enable_if_t< mode==Update::async, int > = 0, typename std::enable_if_t< shuffle==Shuffle::on, int > = 0>
void Utopia::apply_rule (Rule &&rule, Graph &&g, RNG &&rng)
 Asynchronously, in shuffled order, apply a rule to graph entities. More...
 
template<IterateOver iterate_over, Update mode, typename Graph , typename Rule , typename VertexDesc = typename boost::graph_traits< std::remove_reference_t<Graph>>::vertex_descriptor, typename std::enable_if_t< mode==Update::sync, int > = 0>
void Utopia::apply_rule (Rule &&rule, const VertexDesc ref_vertex, Graph &&g)
 Synchronously apply a rule to graph entities. More...
 
template<IterateOver iterate_over, Update mode, Shuffle shuffle = Shuffle::on, typename Graph , typename Rule , typename VertexDesc = typename boost::graph_traits< std::remove_reference_t<Graph>>::vertex_descriptor, typename std::enable_if_t< mode==Update::async, int > = 0, typename std::enable_if_t< shuffle==Shuffle::off, int > = 0>
void Utopia::apply_rule (Rule &&rule, const VertexDesc ref_vertex, Graph &&g)
 Asynchronously apply a rule to graph entities, without shuffling. More...
 
template<IterateOver iterate_over, Update mode, Shuffle shuffle = Shuffle::on, typename Graph , typename Rule , typename RNG , typename VertexDesc = typename boost::graph_traits< std::remove_reference_t<Graph>>::vertex_descriptor>
void Utopia::apply_rule (Rule &&rule, const VertexDesc ref_vertex, Graph &&g, RNG &&rng)
 Asynchronously, in shuffled order, apply a rule to graph entities. More...
 

Detailed Description

Algorithms for conveniently applying function objects on entities.

The General Idea

A rule is a function that computes the new state of the entity it is applied to.

Synchronous vs Asynchronous Updates

Applying a rule synchronously means that its result is applied to all entities simultaneously. In practice, one uses a cache for storing the intermediate states of the cells and then copies/moves the cache entries into the respective cell states.

Applying a rule asynchronously means that its result for a single entity is immediately imposed onto this entity. To avoid preferences in execution order, users may choose to use shuffling before iterating over the cells.

Implementation

A rule must be implemented by the programmer as a function (object). The function it represents must take a pointer to the entity as first argument and any number of additional arguments, and may capture arbitrary objects. The function's return value is the new state of the entity it is applied to.

For asynchronously applied rules, no return value is required; the state may be changed directly.

Currently, rules may also alter other members (i.e., tags) of the entity they are applied to, and may even change states of other entities. Notice that this does not make sense if you intend to apply such a rule synchronously!

A rule is applied with the Utopia::apply_rule() function. All overloads of this function take the rule, a container of entities, and optionally additional containers as arguments. The latter two are iterated and their elements are applied to the rule in order of their occurance in the containers. The number of containers the function is called with must match the number of arguments of the rule. All containers must have the same size.

Warning
There will be no runtime check if the inserted containers match in size! The zip iterator will cause undefined behavior in that case.

Defining a rule taking two arguments and passing an additional container with arguments to be applied can look like this:

auto my_rule = [](auto&& cell, auto&& arg){ return cell->state * arg; };
Utopia::Shuffle::off>(my_rule, my_cells, my_args);
void apply_rule(Rule &&rule, const ContTarget &cont_target, ContArgs &&... cont_args)
Sequential overload.
Definition: apply.hh:133
@ off
Immediately apply the rule sequentially.
@ async
Asynchronous update.

Utopia::apply_rule() uses the Zip iteration utilities. The above function call is equivalent to the Python code:

for cell, arg in zip(my_cells, my_args):
cell.state = rule(cell, arg)
Note
Additional argument containers are only available with Utopia::apply_rule() overloads for manual state update (see next section).

Choosing Update Type When Calling <tt>apply_rule</tt>

Previously, the state cache for synchronous updates was implemented in the entity itself. Therefore, users had to opt for either sync or async updates when choosing the state data type. We now encourage the usage of the Utopia::StateContainer with the specialization for the Utopia::Update::manual tag (see Utopia::StateContainer<StateType, Update::manual>). This allows for choosing the update type via the Utopia::Update switch directly when calling Utopia::apply_rule.

CellManager cm = get_cm_from_somewhere();
Utopia::Shuffle::off>(my_rule, cm.cells());
Manages a physical space, its grid discretization, and cells on that grid.
Definition: cell_manager.hh:41
The entity traits struct gathers types to be used for specializing an entity.
Definition: entity.hh:49

Multithreading Rules

Rules can also be applied in parallel, speeding up the entire computation. This requires the optional dependencies to be installed (consult the README.md for further information). Overloads for manual state update of apply_rule() can take a Utopia::ExecPolicy as first argument. Omitting this policy argument has the same effect as using the Utopia::ExecPolicy::seq policy. Parallel execution of Utopia algorithms can be selected at runtime. See Multithreading for details.

// Sequential execution
Utopia::apply_rule<Utopia::Update::async>(my_rule, my_cells, my_args);
// Possibly parallel execution
// NOTE: `my_rule` must avoid data races!
Utopia::apply_rule<Utopia::Update::async>(
my_rule,
my_cells,
my_args
);
@ par
Parallel/multithreaded execution.
Definition: parallel.hh:68

{}

Typedef Documentation

◆ rule_invoke_result_t

template<typename State , typename Rule , typename... Args>
using Utopia::rule_invoke_result_t = typedef typename rule_invoke_result<State, Rule, Args...>::type

Helper definition to query the rule result type.

See also
rule_invoke_result

Enumeration Type Documentation

◆ Shuffle

enum Utopia::Shuffle
strong

Switch for enabling/disabling shuffling the cells for asynchronous updates.

Enumerator
on 

Shuffle the container before applying the rule sequentially.

off 

Immediately apply the rule sequentially.

◆ Update

enum Utopia::Update
strong

Update modes when applying rules.

It is recommended to use Update::manual in the EntityTraits because this gives full flexibility when applying the rules.

Note
To retain compatiblity with older implementations, this switch is used twice: For specializing the StateContainer, and for setting the update type in apply_rule() if said specialization is for Update::manual.
Enumerator
manual 

User chooses update type when calling apply_rule()

sync 

Synchronous update.

async 

Asynchronous update.

Function Documentation

◆ apply_rule() [1/15]

template<class Rule , class Container , bool sync = impl::entity_t<Container>::is_sync()>
std::enable_if_t<sync, void> Utopia::apply_rule ( const Rule &  rule,
const Container &  container 
)

Apply a rule synchronously on the state of all entities of a container.

Applies the rule function to each of the entities' states and stores the result in a buffer. Afterwards, it iterates over all entities again and applies the buffer to the actual state.

Parameters
ruleAn application rule, see rule
ContainerA container with the entities upon whom rule is applied

◆ apply_rule() [2/15]

template<bool shuffle = true, class Rule , class Container , bool sync = impl::entity_t<Container>::is_sync()>
std::enable_if_t<not sync && not shuffle, void> Utopia::apply_rule ( const Rule &  rule,
const Container &  container 
)

Apply a rule on asynchronous states without prior shuffling.

Parameters
ruleAn application rule, see rule
ContainerA container with the entities upon whom rule is applied

◆ apply_rule() [3/15]

template<bool shuffle = true, class Rule , class Container , class RNG , bool sync = impl::entity_t<Container>::is_sync()>
std::enable_if_t<not sync && shuffle, void> Utopia::apply_rule ( const Rule &  rule,
const Container &  container,
RNG &&  rng 
)

Apply a rule on asynchronous states with prior shuffling.

Parameters
ruleAn application rule, see rule
ContainerA container with the entities upon whom rule is applied

◆ apply_rule() [4/15]

template<Update mode, class Rule , class ContTarget , class... ContArgs, typename std::enable_if_t< mode==Update::sync, int > = 0, typename std::enable_if_t< impl::entity_t< ContTarget >::mode==Update::manual, int > = 0>
void Utopia::apply_rule ( const Utopia::ExecPolicy  policy,
Rule &&  rule,
const ContTarget &  cont_target,
ContArgs &&...  cont_args 
)

Apply a rule synchronously to manually updated states.

This creates a cache for new states whose contents are moved into the respective state containers after all rules have been applied.

Template Parameters
modeUpdate mode for this rule. This is the overload for synchronous updates (Update::sync).
RuleThe type of the rule function (object).
ContTargetThe type of entity container.
ContArgsThe types of argument containers.
Parameters
policyUtopia::ExecPolicy for the rule when applied in parallel
ruleThe function (object) to apply to the entities
cont_targetThe container of entities the function will be applied to
cont_argsThe containers of additional argument for the function.

◆ apply_rule() [5/15]

template<Update mode, Shuffle shuffle = Shuffle::on, class Rule , class ContTarget , class... ContArgs, typename std::enable_if_t< mode==Update::async, int > = 0, typename std::enable_if_t< impl::entity_t< ContTarget >::mode==Update::manual, int > = 0, typename std::enable_if_t< shuffle==Shuffle::off, int > = 0>
void Utopia::apply_rule ( const Utopia::ExecPolicy  policy,
Rule &&  rule,
const ContTarget &  cont_target,
ContArgs &&...  cont_args 
)

Apply a rule asynchronously to manually updated states.

Directly overwrite the states of the passed entities, according to the storage order inside the container.

Template Parameters
modeUpdate mode for this rule. This is the overload for asynchronous updates (Update::async).
shuffleSwitch for enabling the shuffling of cells before applying the rule. This is the overload with shuffling disabled (Shuffle::off).
RuleThe type of the rule function (object).
ContainerThe type of entity container.
ContArgsThe types of argument containers.
Parameters
policyUtopia::ExecPolicy for the rule when applied in parallel
ruleThe function (object) to apply to the entities
containerThe container of entities the function will be applied to
cont_argsThe containers of additional argument for the function.

◆ apply_rule() [6/15]

template<Update mode, Shuffle shuffle = Shuffle::on, class Rule , class ContTarget , class RNG , class... ContArgs, typename std::enable_if_t< mode==Update::async, int > = 0, typename std::enable_if_t< impl::entity_t< ContTarget >::mode==Update::manual, int > = 0, typename std::enable_if_t< shuffle==Shuffle::on, int > = 0>
void Utopia::apply_rule ( const Utopia::ExecPolicy  policy,
Rule &&  rule,
const ContTarget &  cont_target,
RNG &&  rng,
ContArgs &&...  cont_args 
)

Apply a rule asynchronously and shuffled to manually updated states.

Copy the container of (pointers to) entities, shuffle it, and apply the rule sequentially to the shuffled container. The original container remains unchanged.

Template Parameters
modeUpdate mode for this rule. This is the overload for asynchronous updates (Update::async).
shuffleSwitch for enabling the shuffling of containers before applying the rule. This is the overload with shuffling enabled (Shuffle::on).
RuleThe type of the rule function (object).
ContainerThe type of entity container.
RNGThe type of the random number generator.
ContArgsThe types of argument containers.
Parameters
policyUtopia::ExecPolicy for the rule when applied in parallel
ruleThe function (object) to apply to the entities
cont_targetThe container of entities the function will be applied to
rngThe random number generator used for shuffling the entities
cont_argsThe containers of additional argument for the function.
Note
Shuffling only changes the order of execution of this function! It occurs on cont_target and all cont_args simultaneously, guaranteeing that entity at index i will be applied with additional arguments at index i for all container indices i. If you want to shuffle argument containers or entities independently from each other, you must do so yourself before applying this function. shuffle the arguments against the entities they are applied on, do so yourself before calling this function!

◆ apply_rule() [7/15]

template<Update mode, class Rule , class ContTarget , class... ContArgs, typename std::enable_if_t< mode==Update::sync, int > = 0, typename std::enable_if_t< impl::entity_t< ContTarget >::mode==Update::manual, int > = 0>
void Utopia::apply_rule ( Rule &&  rule,
const ContTarget &  cont_target,
ContArgs &&...  cont_args 
)

Sequential overload.

◆ apply_rule() [8/15]

template<Update mode, Shuffle shuffle = Shuffle::on, class Rule , class ContTarget , class... ContArgs, typename std::enable_if_t< mode==Update::async, int > = 0, typename std::enable_if_t< impl::entity_t< ContTarget >::mode==Update::manual, int > = 0, typename std::enable_if_t< shuffle==Shuffle::off, int > = 0>
void Utopia::apply_rule ( Rule &&  rule,
const ContTarget &  cont_target,
ContArgs &&...  cont_args 
)

Sequential case overload.

◆ apply_rule() [9/15]

template<Update mode, Shuffle shuffle = Shuffle::on, class Rule , class ContTarget , class RNG , class... ContArgs, typename std::enable_if_t< mode==Update::async, int > = 0, typename std::enable_if_t< impl::entity_t< ContTarget >::mode==Update::manual, int > = 0, typename std::enable_if_t< shuffle==Shuffle::on, int > = 0>
void Utopia::apply_rule ( Rule &&  rule,
const ContTarget &  cont_target,
RNG &&  rng,
ContArgs &&...  cont_args 
)

Sequential case overload.

◆ apply_rule() [10/15]

template<IterateOver iterate_over, Update mode, typename Graph , typename Rule , typename VertexDesc = typename boost::graph_traits< std::remove_reference_t<Graph>>::vertex_descriptor, typename std::enable_if_t< mode==Update::sync, int > = 0>
void Utopia::apply_rule ( Rule &&  rule,
const VertexDesc  ref_vertex,
Graph &&  g 
)

Synchronously apply a rule to graph entities.

This overload specified the apply_rule function for not shuffled entities where getting the correct iterator pair is dependent on a ref_vertex, for example if the rule should be applied to the neighbors, inv_neighbors, in_degree, out_degree or degree wrt. the ref_vertex.

Template Parameters
iterate_overOver which kind of graph entity to iterate over. See IterateOver
modeThe update mode, see UpdateMode
ShuffleWhether to shuffle the container
GraphThe graph type
RuleThe rule type
Parameters
ruleThe rule function, expecting (descriptor, graph) as arguments. For the synchronous update, the rule function needs to return the new state.
ref_vertexReference vertex descriptor to create the iterator from
gThe graph

◆ apply_rule() [11/15]

template<IterateOver iterate_over, Update mode, Shuffle shuffle = Shuffle::on, typename Graph , typename Rule , typename VertexDesc = typename boost::graph_traits< std::remove_reference_t<Graph>>::vertex_descriptor, typename std::enable_if_t< mode==Update::async, int > = 0, typename std::enable_if_t< shuffle==Shuffle::off, int > = 0>
void Utopia::apply_rule ( Rule &&  rule,
const VertexDesc  ref_vertex,
Graph &&  g 
)

Asynchronously apply a rule to graph entities, without shuffling.

This overload specifies the apply_rule function for an asynchronous update.

Warning
Not shuffling a rule often creates unwanted artifacts. Thus, to use this function, the Shuffle::off template argument needs to be given explicitly.
Template Parameters
iterate_overOver which kind of graph entity to iterate over. See IterateOver
modeThe update mode, see UpdateMode
GraphThe graph type
RuleThe rule type
Parameters
ruleThe rule function, expecting (descriptor, graph) as arguments. For an asynchronous update, returning the state is optional.
ref_vertexReference vertex descriptor to create the iterator from
gThe graph

◆ apply_rule() [12/15]

template<IterateOver iterate_over, Update mode, Shuffle shuffle = Shuffle::on, typename Graph , typename Rule , typename RNG , typename VertexDesc = typename boost::graph_traits< std::remove_reference_t<Graph>>::vertex_descriptor>
void Utopia::apply_rule ( Rule &&  rule,
const VertexDesc  ref_vertex,
Graph &&  g,
RNG &&  rng 
)

Asynchronously, in shuffled order, apply a rule to graph entities.

This overload specified the apply_rule function for shuffled entities where getting the correct iterator pair is dependent on a ref_vertex, for example if the rule should be applied to the neighbors, inv_neighbors, in_degree, out_degree or degree wrt. the ref_vertex.

Template Parameters
iterate_overOver which kind of graph entity to iterate over. See IterateOver
modeThe update mode, see UpdateMode
ShuffleWhether to shuffle the iteration
GraphThe graph type
RuleThe rule type
RNGThe random number generator type
Parameters
ruleThe rule function, expecting (descriptor, graph) as arguments. For an asynchronous update, returning the state is optional.
ref_vertexReference vertex descriptor to create the iterator from
gThe graph
rngThe random number generator

◆ apply_rule() [13/15]

template<IterateOver iterate_over, Update mode, typename Graph , typename Rule , typename std::enable_if_t< mode==Update::sync, int > = 0>
void Utopia::apply_rule ( Rule &&  rule,
Graph &&  g 
)

Synchronously apply a rule to graph entities.

This overload specifies the apply_rule function for a synchronous update. In such a case, it makes no sense to shuffle, so the shuffle option is not available here.

Template Parameters
iterate_overOver which kind of graph entity to iterate over. See IterateOver
modeThe update mode, see UpdateMode
GraphThe graph type
RuleThe rule type
Parameters
ruleThe rule function, expecting (descriptor, graph) as arguments. For the synchronous update, the rule function needs to return the new state.
gThe graph

◆ apply_rule() [14/15]

template<IterateOver iterate_over, Update mode, Shuffle shuffle, typename Graph , typename Rule , typename std::enable_if_t< mode==Update::async, int > = 0>
void Utopia::apply_rule ( Rule &&  rule,
Graph &&  g 
)

Asynchronously apply a rule to graph entities, without shuffling.

This overload specifies the apply_rule function for an asynchronous update.

Warning
Not shuffling a rule often creates unwanted artifacts. Thus, to use this function, the Shuffle::off template argument needs to be given explicitly.
Template Parameters
iterate_overOver which kind of graph entity to iterate over. See IterateOver
modeThe update mode, see UpdateMode
GraphThe graph type
RuleThe rule type
Parameters
ruleThe rule function, expecting (descriptor, graph) as arguments. For an asynchronous update, returning the state is optional.
gThe graph

◆ apply_rule() [15/15]

template<IterateOver iterate_over, Update mode, Shuffle shuffle = Shuffle::on, typename Graph , typename Rule , typename RNG , typename std::enable_if_t< mode==Update::async, int > = 0, typename std::enable_if_t< shuffle==Shuffle::on, int > = 0>
void Utopia::apply_rule ( Rule &&  rule,
Graph &&  g,
RNG &&  rng 
)

Asynchronously, in shuffled order, apply a rule to graph entities.

Using the given RNG, the iteration order is shuffled before the rule is applied sequentially to the specified entities.

Template Parameters
iterate_overOver which kind of graph entity to iterate over. See IterateOver
modeThe update mode, see UpdateMode
ShuffleWhether to shuffle the container
GraphThe graph type
RuleThe rule type
RNGThe random number generator type
Parameters
ruleThe rule function, expecting (descriptor, graph) as arguments. For an asynchronous update, returning the state is optional.
gThe graph
rngThe random number generator

◆ is_void_rule()

template<typename State , typename Rule , typename... Args>
constexpr bool Utopia::is_void_rule ( )
constexpr

Helper function to check if the rule returns void

See also
rule_invoke_result

◆ make_tuple_from_tuple()

template<class Tuple >
constexpr decltype(auto) Utopia::make_tuple_from_tuple ( Tuple &&  t)
constexpr

Helper function to create a tuple from a tuple.

This seems silly, but calling std::make_tuple decays objects of std::reference_wrapper<T> toT&`, which is exactly what we use this function for.

This function creates a index sequence for the tuple and calls the implementation helper make_tuple_from_tuple_impl().

Parameters
tTuple to create a tuple from
Returns
Tuple containing the elements of the input tuple

◆ make_tuple_from_tuple_impl()

template<class Tuple , std::size_t... I>
constexpr decltype(auto) Utopia::make_tuple_from_tuple_impl ( Tuple &&  t,
std::index_sequence< I... >   
)
constexpr

Helper function to create a tuple from a tuple using an index sequence.

Template Parameters
IIndex sequence to access the elements of the tuple
Parameters
tTuple to create a tuple from
Returns
Tuple containing the elements of the input tuple