Lumiera 0.pre.04~rc.1
»edit your freedom«
Loading...
Searching...
No Matches
Builder< PAR > Struct Template Reference

#include "lib/diff/tree-mutator.hpp"

Description

template<class PAR>
struct lib::diff::anonymous_namespace{tree-mutator.hpp}::Builder< PAR >

Builder-DSL to create and configure a concrete TreeMutator.

Remarks
all generated follow-up builders are chained and derive from the implementation of the preceding "binding layer" and the TreeMutator interface.
Note
on each chained builder call, the compound is moved "inside out" into the next builder.

Definition at line 292 of file tree-mutator.hpp.

Public Member Functions

 Builder (PAR &&par)
 
template<typename BIN , typename... ARGS>
Builder< BIN > chainedBuilder (ARGS &&...args)
 
template<typename CLO >
auto change (Symbol attributeID, CLO setterClosure)
 set up a binding to represent an "attribute" through a data or object field.
 
template<typename CLO >
auto mutateAttrib (Symbol attributeID, CLO mutatorBuilderClosure)
 set up a binding for an object valued "attribute" or named scope.
 
template<typename CLO >
auto mutateAttrib (idi::BareEntryID const &rawID, CLO mutatorBuilderClosure)
 
template<typename BIN >
auto attach (BIN &&collectionBindingSetup)
 set up a binding to a structure of "child objects", implemented through a typical STL container
 
auto attach (Rec::Mutator &targetTree)
 set up binding to a GenNode tree: Special setup to build a concrete TreeMutator.
 
auto attachDummy (TestMutationTarget &dummy)
 set up a diagnostic layer, binding to TestMutationTarget.
 
auto ignoreAllChanges ()
 set up a catch-all and ignore-everything layer
 
template<typename LIS >
auto onSeqChange (LIS changeListener)
 attach a listener function, to be invoked on structural changes.
 
template<typename LIS >
auto onLocalChange (LIS changeListener)
 attach a listener function, to be invoked on any local change.
 
template<typename CLO >
auto change (Symbol attributeID, CLO setterClosure)
 Entry point for DSL builder.
 
template<typename CLO >
auto mutateAttrib (Symbol attributeID, CLO mutatorBuilderClosure)
 Entry point for DSL builder.
 
template<typename CLO >
auto mutateAttrib (idi::BareEntryID const &rawID, CLO mutatorBuilderClosure)
 Entry point for DSL builder; variation to handle an attribute-object with given ID.
 
template<class BIN >
auto attach (BIN &&collectionBindingSetup)
 Entry point for DSL builder.
 
template<class PAR >
auto attach (Rec::Mutator &targetTree)
 Entry point for DSL builder.
 
template<typename LIS >
auto onSeqChange (LIS changeListener)
 Entry point for DSL builder: attach a functor as listener to be notified after structural changes.
 
template<typename LIS >
auto onLocalChange (LIS changeListener)
 Entry point for DSL builder: attach a functor as listener to be notified after either a structural change, or a value assignment within the local scope of this TreeMutator.
 

Constructor & Destructor Documentation

◆ Builder()

template<class PAR >
Builder ( PAR &&  par)
inlineexplicit

Definition at line 296 of file tree-mutator.hpp.

Member Function Documentation

◆ chainedBuilder()

template<class PAR >
template<typename BIN , typename... ARGS>
Builder< BIN > chainedBuilder ( ARGS &&...  args)
inline

Definition at line 302 of file tree-mutator.hpp.

◆ change() [1/2]

template<class PAR >
template<typename CLO >
auto change ( Symbol  attributeID,
CLO  setterClosure 
)

set up a binding to represent an "attribute" through a data or object field.

This binding will allow to apply basic diff operations, but no re-ordering or deletion. Rationale is the fixed nature of a class definition, which does not support any notion of ordering, or adding and removal of members.

Parameters
attributeIDsymbolic key to denote this "attribute"
setterClosurefunctor or lambda to apply a new value
Note
the nominal value type of the "attribute" is picked up from the setterClosure's (single) argument. It must be one of the types supported as payload for GenNode. In case the target data field needs any other value type, it is the closure's responsibility to convert appropriately.
the combination of attributeID and nominal value type is used to build an (EntryID). The hash of this EntryID needs to match the GenNode::ID in any diff verb considered to be "applicable" to this attribute and binding. Similar to GenNode, the provided attributeID is used as-is, without further sanitising.
Returns
a chained builder, which establishes this building and can then be used to define additional binding layers on top

◆ mutateAttrib() [1/4]

template<class PAR >
template<typename CLO >
auto mutateAttrib ( Symbol  attributeID,
CLO  mutatorBuilderClosure 
)

set up a binding for an object valued "attribute" or named scope.

This covers the rather special case, where some relevant sub object is accessed as a (named) property of a managing parent object. On implementation level, this corresponds to using a getter to access a subcomponent or "PImpl". On a formal level, for tree diff handling, such counts as attribute, yet with the special twist that we can not just assign a new "value", but rather have to enter a sub scope and handle a nested diff – similar to how nested child objects are dealt with in general. Thus, all we need here is a way how to build a nested TreeMutator for this sub-scope.

Parameters
attributeIDsymbolic key to denote this "attribute"
mutatorBuilderClosurefunctor or lambda to emplace a custom sub TreeMutator into the given buffer (handle). Such a nested mutator shall be wired internally to the object representation of the attribute in question.
See also
CollectionBindingBuilder::buildChildMutator

◆ mutateAttrib() [2/4]

template<class PAR >
template<typename CLO >
auto mutateAttrib ( idi::BareEntryID const &  rawID,
CLO  mutatorBuilderClosure 
)
Parameters
rawIDthe explicitly given ID of an attribute object, used literally to match the attribute in question

◆ attach() [1/4]

template<class PAR >
template<typename BIN >
auto attach ( BIN &&  collectionBindingSetup)

set up a binding to a structure of "child objects", implemented through a typical STL container

Parameters
collectionBindingSetupas created by invoking a nested DSL, initiated by a builder function collection(implRef), where implRef is a (language) reference to a STL compliant container existing somewhere within the otherwise opaque implementation. The type of the container and thus the type of the elements will be picked up, and the returned builder can be further outfitted with the builder methods, which take lambdas as callback into the implementation.
  • the matcher closure (CollectionBindingBuilder::matchElement) defines how to determine, if an implementation data element "matches" a given diff spec
  • the constructor closure (CollectionBindingBuilder::constructFrom) defines how to build a new implementation data element from the spec of an INS diff verb. Note: the result will be moved (move-constructed) into the target container.
  • the optional selector closure (CollectionBindingBuilder::isApplicableIf) allows to limit applicability of this whole binding (layer) to only some diff specs. E.g., we may set up a binding for elements with value semantics and another binding layer on top to deal with object like children (sub scopes). Please note that this selector also gets to judge upon the Ref::ATTRIBS spec, which indicates if this layer's contents can be considered "attributes".
  • the optional setter closure (CollectionBindingBuilder::assignElement) accepts a diff spec (GenNode) and should assign an equivalent value to the internal data representation of the corresponding element (typically by constructing an implementation data element and then invoking the corresponding setter)
  • the optional mutator closure (CollectionBindingBuilder::buildChildMutator) allows for recursive descent into nested child scopes. On invocation, it has to build a suitable custom TreeMutator implementation into the provided buffer (handle), and this nested TreeMutator should be wired with the internal representation of the nested scope to enter. At this point, the implementation can safely assume that the given target data element has already be checked with the configured matcher closure, and thus can be considered equivalent to the given ID. The code invoking this closure then typically pushes the buffer onto some internal stack and switches then to use this nested mutator until encountering the corresponding EMU bracket verb.
Note
the after(Ref::ATTRIBS) verb can only processed if the selector responds correct to a Ref::ATTRIBS spec. The implicit default selector does so, i.e. it rejects Ref::ATTRIBS. Please be sure to accept this token only if your layer indeed holds something meant to implement "attributes", because in that case, the verb after(Ref::ATTRIBS) will fast forward and accept all the current contents of this layer
Warning
please note the nested DSL. The builder functions used to define the various closures are to be invoked on the argument ("`collection(xyz)`"), not on the top level builder...

Referenced by Builder< PAR >::attach().

+ Here is the caller graph for this function:

◆ attach() [2/4]

template<class PAR >
auto attach ( Rec::Mutator targetTree)

set up binding to a GenNode tree: Special setup to build a concrete TreeMutator.

This decorator is already outfitted with the necessary closures to work on a diff::Record<GenNode> – which is typically used as "meta representation" of object-like structures. Thus this binding allows to apply a MutationMessage onto such a given »External Tree Description«, mutating it into new shape.

Remarks
our meta representation of "objects" is based on Record<GenNode>, which is implemented through two STL collections, one for the attributes and one for the child elements. Thus we'll using two binding layers, based on the ChildCollectionMutator, configured with the necessary lambdas.

◆ attachDummy()

template<class PAR >
auto attachDummy ( TestMutationTarget dummy)

set up a diagnostic layer, binding to TestMutationTarget.

This can be used to monitor the behaviour of the resulting TreeMutator for tests.

Definition at line 530 of file test-mutation-target.hpp.

◆ ignoreAllChanges()

template<class PAR >
auto ignoreAllChanges ( )
inline

set up a catch-all and ignore-everything layer

Entry point for DSL builder: create a binding which consumes any diff without effect.

Warning
must be used as bottom most layer in a custom TreeMutator, since it would otherwise shadow and disable any binding layer below.
Note
however it is possible to add a (typically selective) binding layer on top; any diff verb not handled by such a top layer will fall through and be silently ignored. Such a setup can be used to "fish" for some specific attributes within a diff stream.

Definition at line 102 of file tree-mutator-noop-binding.hpp.

◆ onSeqChange() [1/2]

template<class PAR >
template<typename LIS >
auto onSeqChange ( LIS  changeListener)

attach a listener function, to be invoked on structural changes.

Here, we define any change as "structural", which alters the sequence of child elements, as opposed to their content. In practice, this listener will be invoked after applying a diff with any INS, DEL, FIND, SKIP verb.

Remarks
in theory, one could also drop contents indirectly, by sending only part of the necessary PICK verbs (or using AFTER(...)). However, such a diff is formally not allowed, and will indeed be detected as error when leaving a scope, in ChildCollectionMutator::completeScope()

◆ onLocalChange() [1/2]

template<class PAR >
template<typename LIS >
auto onLocalChange ( LIS  changeListener)

attach a listener function, to be invoked on any local change.

This includes the structural changes, but also value assignments to any attribute or element.

Note
mutation of a nested child scope will not trigger this listener.

◆ change() [2/2]

template<class PAR >
template<typename CLO >
auto change ( Symbol  attributeID,
CLO  setterClosure 
)
inline

Entry point for DSL builder.

Definition at line 346 of file tree-mutator-attribute-binding.hpp.

◆ mutateAttrib() [3/4]

template<class PAR >
template<typename CLO >
auto mutateAttrib ( Symbol  attributeID,
CLO  mutatorBuilderClosure 
)
inline

Entry point for DSL builder.

Definition at line 356 of file tree-mutator-attribute-binding.hpp.

◆ mutateAttrib() [4/4]

template<class PAR >
template<typename CLO >
auto mutateAttrib ( idi::BareEntryID const &  rawID,
CLO  mutatorBuilderClosure 
)
inline

Entry point for DSL builder; variation to handle an attribute-object with given ID.

Definition at line 366 of file tree-mutator-attribute-binding.hpp.

◆ attach() [3/4]

template<class PAR >
template<class BIN >
auto attach ( BIN &&  collectionBindingSetup)
inline

Entry point for DSL builder.

Definition at line 752 of file tree-mutator-collection-binding.hpp.

◆ attach() [4/4]

template<class PAR >
template<class PAR >
auto attach ( Rec::Mutator targetTree)
inline

Entry point for DSL builder.

Definition at line 146 of file tree-mutator-gen-node-binding.hpp.

References Builder< PAR >::attach(), and GenNode::isNamed().

+ Here is the call graph for this function:

◆ onSeqChange() [2/2]

template<class PAR >
template<typename LIS >
auto onSeqChange ( LIS  changeListener)
inline

Entry point for DSL builder: attach a functor as listener to be notified after structural changes.

Definition at line 123 of file tree-mutator-listener-binding.hpp.

References ASSERT_VALID_SIGNATURE.

◆ onLocalChange() [2/2]

template<class PAR >
template<typename LIS >
auto onLocalChange ( LIS  changeListener)
inline

Entry point for DSL builder: attach a functor as listener to be notified after either a structural change, or a value assignment within the local scope of this TreeMutator.

Definition at line 136 of file tree-mutator-listener-binding.hpp.

References ASSERT_VALID_SIGNATURE.

+ Inheritance diagram for Builder< PAR >:
+ Collaboration diagram for Builder< PAR >:

The documentation for this struct was generated from the following files: