solution draft for integration of the whole tree diff application machinery

This is the first skeleton to combine all the building blocks,
and it passes compilation, while of course most of the binding
implementation still needs to be filled in...
This commit is contained in:
Fischlurch 2016-07-28 22:58:21 +02:00
parent ed18e1161c
commit 78c9b0835e
7 changed files with 58 additions and 11 deletions

View file

@ -261,10 +261,13 @@ namespace diff{
* @remarks the actual diff fed to the DiffApplicator
* assumes that this DiffApplicationStrategy is
* an Interpreter for the given diff language.
* @remarks the second template parameter allows for
* `std::enable_if` based on the concrete
* target type `TAR` (1st template arg)
* @warning the actual language remains unspecified;
* it is picked from the visible context.
*/
template<class CON>
template<class TAR, typename SEL =void>
class DiffApplicationStrategy;

View file

@ -137,11 +137,50 @@ namespace diff{
class DiffApplicationStrategy<DiffMutable>
: public TreeDiffMutatorBinding
{
public:
void
buildMutator (DiffMutable& targetBinding)
{
UNIMPLEMENTED ("place the mutator into the manager buffer");
// TreeMutator::Handle buffHandle;
// targetBinding.buildMutator (buffHandle);
}
};
/**
* Extended configuration for tree-diff-application to given opaque target data.
* This setup uses the [metaprogramming adapter traits](\ref TreeDiffTraits) to
* pave a way for building the custom TreeMutator implementation internally wired
* to the given opaque target. Moreover, based on the concrete target type, a suitable
* ScopeManager implementation can be provided. Together, these two dynamically created
* adapters allow the generic TreeDiffMutatorBinding to perform all of the actual
* diff application and mutation task.
* @see DiffVirtualisedApplication_test usage example of this combined machinery
*/
template<class TAR>
class DiffApplicationStrategy<TAR, enable_if<TreeDiffTraits<TAR>>>
: public TreeDiffMutatorBinding
{
TAR& subject_;
void
buildMutator (DiffMutable& targetBinding)
{
UNIMPLEMENTED ("place the mutator into the manager buffer");
// TreeMutator::Handle buffHandle;
// targetBinding.buildMutator (buffHandle);
}
public:
explicit
DiffApplicationStrategy<DiffMutable>(DiffMutable& targetBinding)
: TreeDiffMutatorBinding(targetBinding)
{ }
DiffApplicationStrategy(TAR& subject)
: TreeDiffMutatorBinding()
, subject_(subject)
{
auto target = mutatorBinding (subject);
buildMutator (target);
}
};

View file

@ -210,8 +210,7 @@ namespace diff{
public:
explicit
TreeDiffMutatorBinding(DiffMutable& targetBinding)
TreeDiffMutatorBinding()
{
TODO("attach to the given Target");
#if false /////////////////////////////////////////////////////////////////////////////////////////////////////////////UNIMPLEMENTED :: TICKET #992

View file

@ -80,18 +80,21 @@ namespace diff{
template<class TAR, typename SEL =void>
struct TreeDiffTraits
: std::false_type
{
static_assert (!sizeof(TAR), "TreeDiffTraits: Unable to access or build a TreeMutator for this target data.");
};
template<class TAR>
struct TreeDiffTraits<TAR, enable_if<is_same<TAR, DiffMutable>>>
: std::true_type
{
using Ret = DiffMutable&;
};
template<class TAR>
struct TreeDiffTraits<TAR, enable_if<exposes_MutatorBuilder<TAR>>>
: std::true_type
{
class Wrapper
: public DiffMutable

View file

@ -208,8 +208,9 @@ namespace test{
run (Arg)
{
Opaque subject;
auto target = mutatorBinding (subject);
DiffApplicator<DiffMutable> application(target);
// auto target = mutatorBinding (subject);
// DiffApplicator<DiffMutable> application(target);
DiffApplicator<Opaque> application(subject);
//
// TODO verify results
cout << "before..."<<endl << subject<<endl;

View file

@ -8355,7 +8355,7 @@ attached to a clip, or the mixture of clips, effects and labels found within a [
You should note that this entire design is recursive: only after understanding the part, where, for handling a sub-structure, a nested mutator is fabricated and placed into a given buffer, it becomes clear to what effect we're creating a customised mutator: we always need some (relative) parent scope, which happens to know more about the actual data to be treated with a TreeMutator. This scope assists with creating a suitable binding. Obviously, from within that binding, it is known what the sub-structures and children of that local data are all about and what semantics to give to the fundamental operations.
</pre>
</div>
<div title="TreeMutatorEvolution" creator="Ichthyostega" modifier="Ichthyostega" created="201603160255" modified="201606132308" tags="Model Concepts design draft" changecount="21">
<div title="TreeMutatorEvolution" creator="Ichthyostega" modifier="Ichthyostega" created="201603160255" modified="201607282049" tags="Model Concepts design draft" changecount="24">
<pre>The TreeMutator is an intermediary to translate a generic structure pattern into heterogeneous local invocation sequences.
!Motivation
@ -8513,6 +8513,8 @@ Right now it looks sensible to start with the simplistic approach, while keeping
To receive and apply a diff, client code has to build a {{{DiffApplicator&lt;TreeMutator&gt;}}} and somehow attach this to the target data structure. Then, after feeding the diff sequence, the target data structure will be transformed. This leads to kind of a chicken-and-egg problem, since only the target data structure has the ability to know how to fabricate a suitable concrete TreeMutator. Assuming the //size problem// (as detailed above) is already solved one way or the other, we're bound to use an interface where the target structure is prompted to build a suitable mutator into a provided buffer or storage frame. Typically, we'd either use metaprogramming or some ADL extension point to derive a suitable //mutator building closure// from the given target structure. In fact, the same situation repeats itself recursively when it comes to mutating nested scopes, but in that case, the necessary //mutator building closure// is already part of the mutator binding created for the respective parent scope, and thus can just be invoked right away.
The {{{DiffApplicator}}} itself can be made non-copyable; preferably it should be small and cheap to construct. At least we should strive at keeping the number of indirections and heap allocations low. Together with the requirement to separate from the actual TreeMutator implementation, which is built late, just before invocation, we arrive at a ~PImpl structure, with the TreeMutator as ~PImpl and a scope manager hidden within the implementation part; the latter will be responsible for creating a suitable stack, and to use the //mutator building closure// in order to incorporate the concrete TreeMutator into the stack frames.
Pulling all those building blocks together, this architecture finally allows us to offer a (tree) diff-applicator for //»basically anything«:// The ctor respective the init method of {{{DiffAplicator&lt;Something&gt;}}} relies on the metaprogramming or ADL technique embedded within the {{{TreeDiffTraits&lt;Something&gt;}}} to //somehow// get at a {{{DiffMutable&amp;}}} -- the latter offering the crucial method to build a TreeMutator implementation internally wired in a proper way to {{{Something}}}'s internals. This in turn enables us to build a suitalbe {{{ScopeManager}}} implementation with a stack size sufficient to hold this TreeMutator implementation. After this type specific setup, the rest of the diff application works entirely generic and can thus be delegated to the non-templated baseclass TreeDiffMutatorBinding...
</pre>
</div>
<div title="TypedID" modifier="Ichthyostega" created="201003200157" modified="201505310143" tags="Model Types Rules design draft" changecount="12">

View file

@ -4593,7 +4593,7 @@
</node>
</node>
</node>
<node CREATED="1469545080826" HGAP="41" ID="ID_268789302" MODIFIED="1469545140415" VSHIFT="17">
<node CREATED="1469545080826" HGAP="41" ID="ID_268789302" MODIFIED="1469738253120" VSHIFT="17">
<richcontent TYPE="NODE"><html>
<head>
@ -4605,7 +4605,7 @@
</body>
</html>
</richcontent>
<icon BUILTIN="pencil"/>
<icon BUILTIN="button_ok"/>
<node CREATED="1469545168798" ID="ID_511952630" MODIFIED="1469545171905" TEXT="Architektur">
<node CREATED="1469545173893" ID="ID_1815808987" MODIFIED="1469545190599" TEXT="opaque: Kern == TreeMutator"/>
<node CREATED="1469545191899" ID="ID_1298718461" MODIFIED="1469545206853" TEXT="generisch: TreeMutator-Bindung"/>