From 78c9b0835e629b5c6b41860fb061020fd01205bb Mon Sep 17 00:00:00 2001 From: Ichthyostega Date: Thu, 28 Jul 2016 22:58:21 +0200 Subject: [PATCH] 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... --- src/lib/diff/diff-language.hpp | 5 ++- src/lib/diff/tree-diff-application.hpp | 45 +++++++++++++++++-- src/lib/diff/tree-diff-mutator-binding.hpp | 3 +- src/lib/diff/tree-diff-traits.hpp | 3 ++ .../diff-virtualised-application-test.cpp | 5 ++- wiki/renderengine.html | 4 +- wiki/thinkPad.ichthyo.mm | 4 +- 7 files changed, 58 insertions(+), 11 deletions(-) diff --git a/src/lib/diff/diff-language.hpp b/src/lib/diff/diff-language.hpp index 482279747..4f8587939 100644 --- a/src/lib/diff/diff-language.hpp +++ b/src/lib/diff/diff-language.hpp @@ -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 + template class DiffApplicationStrategy; diff --git a/src/lib/diff/tree-diff-application.hpp b/src/lib/diff/tree-diff-application.hpp index 387564742..2d372611b 100644 --- a/src/lib/diff/tree-diff-application.hpp +++ b/src/lib/diff/tree-diff-application.hpp @@ -137,11 +137,50 @@ namespace diff{ class DiffApplicationStrategy : 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 DiffApplicationStrategy>> + : 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& targetBinding) - : TreeDiffMutatorBinding(targetBinding) - { } + DiffApplicationStrategy(TAR& subject) + : TreeDiffMutatorBinding() + , subject_(subject) + { + auto target = mutatorBinding (subject); + buildMutator (target); + } }; diff --git a/src/lib/diff/tree-diff-mutator-binding.hpp b/src/lib/diff/tree-diff-mutator-binding.hpp index 670f3f84f..1c302dcd1 100644 --- a/src/lib/diff/tree-diff-mutator-binding.hpp +++ b/src/lib/diff/tree-diff-mutator-binding.hpp @@ -210,8 +210,7 @@ namespace diff{ public: - explicit - TreeDiffMutatorBinding(DiffMutable& targetBinding) + TreeDiffMutatorBinding() { TODO("attach to the given Target"); #if false /////////////////////////////////////////////////////////////////////////////////////////////////////////////UNIMPLEMENTED :: TICKET #992 diff --git a/src/lib/diff/tree-diff-traits.hpp b/src/lib/diff/tree-diff-traits.hpp index 3e8223f42..48e5bf6f8 100644 --- a/src/lib/diff/tree-diff-traits.hpp +++ b/src/lib/diff/tree-diff-traits.hpp @@ -80,18 +80,21 @@ namespace diff{ template struct TreeDiffTraits + : std::false_type { static_assert (!sizeof(TAR), "TreeDiffTraits: Unable to access or build a TreeMutator for this target data."); }; template struct TreeDiffTraits>> + : std::true_type { using Ret = DiffMutable&; }; template struct TreeDiffTraits>> + : std::true_type { class Wrapper : public DiffMutable diff --git a/tests/library/diff/diff-virtualised-application-test.cpp b/tests/library/diff/diff-virtualised-application-test.cpp index 29b262a8c..491d2e318 100644 --- a/tests/library/diff/diff-virtualised-application-test.cpp +++ b/tests/library/diff/diff-virtualised-application-test.cpp @@ -208,8 +208,9 @@ namespace test{ run (Arg) { Opaque subject; - auto target = mutatorBinding (subject); - DiffApplicator application(target); +// auto target = mutatorBinding (subject); +// DiffApplicator application(target); + DiffApplicator application(subject); // // TODO verify results cout << "before..."< -
+
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<TreeMutator>}}} 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<Something>}}} relies on the metaprogramming or ADL technique embedded within the {{{TreeDiffTraits<Something>}}} to //somehow// get at a {{{DiffMutable&}}} -- 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...
 
diff --git a/wiki/thinkPad.ichthyo.mm b/wiki/thinkPad.ichthyo.mm index 2925f65ae..7668ccf7f 100644 --- a/wiki/thinkPad.ichthyo.mm +++ b/wiki/thinkPad.ichthyo.mm @@ -4593,7 +4593,7 @@ - + @@ -4605,7 +4605,7 @@ - +