WIP: code organisation - double layered architecture

This commit is contained in:
Fischlurch 2016-07-28 01:17:50 +02:00
parent 40b032c9c2
commit ed18e1161c
6 changed files with 446 additions and 127 deletions

View file

@ -103,6 +103,8 @@
#include "lib/diff/tree-diff.hpp"
#include "lib/diff/tree-diff-traits.hpp"
#include "lib/diff/tree-diff-mutator-binding.hpp"
#include "lib/diff/gen-node.hpp"
#include "lib/format-string.hpp"
#include "lib/util.hpp"
@ -120,6 +122,29 @@ namespace diff{
using std::swap;
/**
* Interpreter for the tree-diff-language to work on arbitrary
* opaque target data structures. A concrete strategy to apply a structural diff
* to otherwise undisclosed, recursive, tree-like target data. The only requirement
* is for this target structure to expose a hook for building a customised
* TreeMutator able to work on and transform the private target data.
* @throws lumiera::error::State when diff application fails due to the
* target sequence being different than assumed by the given diff.
* @see #TreeDiffInterpreter explanation of the verbs
*/
template<>
class DiffApplicationStrategy<DiffMutable>
: public TreeDiffMutatorBinding
{
public:
explicit
DiffApplicationStrategy<DiffMutable>(DiffMutable& targetBinding)
: TreeDiffMutatorBinding(targetBinding)
{ }
};
/**
* Interpreter for the tree-diff-language to work on GenNode elements
* A concrete strategy to apply a structural diff to a target data structure

View file

@ -64,7 +64,7 @@ namespace diff{
using Iter = Content::Iter;
template<>
struct DiffApplicationStrategy<DiffMutable>::ScopeFrame
struct TreeDiffMutatorBinding::ScopeFrame
{
Mutator& target;
Content content;
@ -94,7 +94,7 @@ namespace diff{
void
DiffApplicationStrategy<DiffMutable>::__expect_in_target (GenNode const& elm, Literal oper)
TreeDiffMutatorBinding::__expect_in_target (GenNode const& elm, Literal oper)
{
if (endOfData())
throw error::State(_Fmt("Unable to %s element %s from target as demanded; "
@ -112,7 +112,7 @@ namespace diff{
}
void
DiffApplicationStrategy<DiffMutable>::__expect_further_elements (GenNode const& elm)
TreeDiffMutatorBinding::__expect_further_elements (GenNode const& elm)
{
if (endOfData())
throw error::State(_Fmt("Premature end of target sequence, still expecting element %s; "
@ -121,7 +121,7 @@ namespace diff{
}
void
DiffApplicationStrategy<DiffMutable>::__expect_found (GenNode const& elm, Iter const& targetPos)
TreeDiffMutatorBinding::__expect_found (GenNode const& elm, Iter const& targetPos)
{
if (targetPos == src().end())
throw error::State(_Fmt("Premature end of sequence; unable to locate "
@ -130,7 +130,7 @@ namespace diff{
}
void
DiffApplicationStrategy<DiffMutable>::__expect_successful_location (GenNode const& elm)
TreeDiffMutatorBinding::__expect_successful_location (GenNode const& elm)
{
if (endOfData()
and not ( elm.matches(Ref::END) // after(_END_) -> its OK we hit the end
@ -140,7 +140,7 @@ namespace diff{
}
void
DiffApplicationStrategy<DiffMutable>::__expect_valid_parent_scope (GenNode::ID const& idi)
TreeDiffMutatorBinding::__expect_valid_parent_scope (GenNode::ID const& idi)
{
if (scopes_.empty())
throw error::State(_Fmt("Unbalanced child scope bracketing tokens in diff; "
@ -154,7 +154,7 @@ namespace diff{
}
void
DiffApplicationStrategy<DiffMutable>::__expect_end_of_scope (GenNode::ID const& idi)
TreeDiffMutatorBinding::__expect_end_of_scope (GenNode::ID const& idi)
{
if (not endOfData())
throw error::State(_Fmt("Incomplete diff: when about to leave scope %s, "
@ -165,7 +165,7 @@ namespace diff{
Iter
DiffApplicationStrategy<DiffMutable>::find_in_current_scope (GenNode const& elm)
TreeDiffMutatorBinding::find_in_current_scope (GenNode const& elm)
{
Iter end_of_scope = src().currIsAttrib()? src().attribs.end()
: src().children.end();
@ -178,7 +178,7 @@ namespace diff{
}
GenNode const&
DiffApplicationStrategy<DiffMutable>::find_child (GenNode::ID const& idi)
TreeDiffMutatorBinding::find_child (GenNode::ID const& idi)
{
if (alteredRec().empty())
throw error::State(_Fmt("Attempt to mutate element %s, but current target data scope is empty. "
@ -204,7 +204,7 @@ namespace diff{
}
void
DiffApplicationStrategy<DiffMutable>::move_into_new_sequence (Iter pos)
TreeDiffMutatorBinding::move_into_new_sequence (Iter pos)
{
if (src().currIsAttrib())
out().appendAttrib (move(*pos)); //////////////TICKET #969 was it a good idea to allow adding attributes "after the fact"?
@ -216,31 +216,31 @@ namespace diff{
/* == Forwarding: error handling == */
void
DiffApplicationStrategy<DiffMutable>::__expect_in_target (GenNode const& elm, Literal oper)
TreeDiffMutatorBinding::__expect_in_target (GenNode const& elm, Literal oper)
{
}
void
DiffApplicationStrategy<DiffMutable>::__expect_further_elements (GenNode const& elm)
TreeDiffMutatorBinding::__expect_further_elements (GenNode const& elm)
{
}
void
DiffApplicationStrategy<DiffMutable>::__fail_not_found (GenNode const& elm)
TreeDiffMutatorBinding::__fail_not_found (GenNode const& elm)
{
}
void
DiffApplicationStrategy<DiffMutable>::__expect_end_of_scope (GenNode::ID const& idi)
TreeDiffMutatorBinding::__expect_end_of_scope (GenNode::ID const& idi)
{
}
void
DiffApplicationStrategy<DiffMutable>::__expect_valid_parent_scope (GenNode::ID const& idi)
TreeDiffMutatorBinding::__expect_valid_parent_scope (GenNode::ID const& idi)
{
}
@ -249,55 +249,55 @@ namespace diff{
/* == Forwarding: mutation primitives == */
void
DiffApplicationStrategy<DiffMutable>::skipSrc()
TreeDiffMutatorBinding::skipSrc()
{
UNIMPLEMENTED("skip next src element and advance abstract source position");
}
void
DiffApplicationStrategy<DiffMutable>::injectNew (GenNode const& n)
TreeDiffMutatorBinding::injectNew (GenNode const& n)
{
UNIMPLEMENTED("inject a new element at current abstract position");
}
bool
DiffApplicationStrategy<DiffMutable>::matchSrc (GenNode const& n)
TreeDiffMutatorBinding::matchSrc (GenNode const& n)
{
UNIMPLEMENTED("ensure the next source element matches with given spec");
}
bool
DiffApplicationStrategy<DiffMutable>::acceptSrc (GenNode const& n)
TreeDiffMutatorBinding::acceptSrc (GenNode const& n)
{
UNIMPLEMENTED("accept existing element, when matching the given spec");
}
bool
DiffApplicationStrategy<DiffMutable>::findSrc (GenNode const& n)
TreeDiffMutatorBinding::findSrc (GenNode const& n)
{
UNIMPLEMENTED("locate designated element and accept it at current position");
}
bool
DiffApplicationStrategy<DiffMutable>::accept_until (GenNode const& refMark)
TreeDiffMutatorBinding::accept_until (GenNode const& refMark)
{
UNIMPLEMENTED("repeatedly accept until encountering the mark");
}
void
DiffApplicationStrategy<DiffMutable>::assignElm (GenNode const& n)
TreeDiffMutatorBinding::assignElm (GenNode const& n)
{
UNIMPLEMENTED("locate already accepted element and assign given new payload");
}
void
DiffApplicationStrategy<DiffMutable>::open_subScope (GenNode const& n)
TreeDiffMutatorBinding::open_subScope (GenNode const& n)
{
UNIMPLEMENTED("locate already accepted element and open recursive sub-scope for mutation");
}
void
DiffApplicationStrategy<DiffMutable>::close_subScope()
TreeDiffMutatorBinding::close_subScope()
{
UNIMPLEMENTED("finish and leave sub scope and return to invoking parent scope");
}
@ -307,38 +307,38 @@ namespace diff{
/* == Implementation of the list diff application primitives == */
void
DiffApplicationStrategy<DiffMutable>::ins (GenNode const& n)
TreeDiffMutatorBinding::ins (GenNode const& n)
{
injectNew (n);
}
void
DiffApplicationStrategy<DiffMutable>::del (GenNode const& n)
TreeDiffMutatorBinding::del (GenNode const& n)
{
__expect_in_target(n, "remove");
skipSrc();
}
void
DiffApplicationStrategy<DiffMutable>::pick (GenNode const& n)
TreeDiffMutatorBinding::pick (GenNode const& n)
{
__expect_in_target(n, "pick");
acceptSrc (n);
}
void
DiffApplicationStrategy<DiffMutable>::skip (GenNode const& n)
TreeDiffMutatorBinding::skip (GenNode const& n)
{
__expect_further_elements (n);
skipSrc();
} // assume the actual content has been moved away by a previous find()
void
DiffApplicationStrategy<DiffMutable>::find (GenNode const& n)
TreeDiffMutatorBinding::find (GenNode const& n)
{
__expect_further_elements (n);
// consume and leave waste, expected to be cleaned-up by skip() later
if (not findSrc(n));
if (not this->findSrc(n));
__fail_not_found (n);
}
@ -349,7 +349,7 @@ namespace diff{
* thereby picking (accepting) all traversed elements
* into the reshaped new data structure as-is */
void
DiffApplicationStrategy<DiffMutable>::after (GenNode const& n)
TreeDiffMutatorBinding::after (GenNode const& n)
{
if (not accept_until(n))
__fail_not_found (n);
@ -357,14 +357,14 @@ namespace diff{
/** assignment of changed value in one step */
void
DiffApplicationStrategy<DiffMutable>::set (GenNode const& n)
TreeDiffMutatorBinding::set (GenNode const& n)
{
assignElm (n);
}
/** open nested scope to apply diff to child object */
void
DiffApplicationStrategy<DiffMutable>::mut (GenNode const& n)
TreeDiffMutatorBinding::mut (GenNode const& n)
{
open_subScope (n);
@ -376,7 +376,7 @@ namespace diff{
/** finish and leave child object scope, return to parent */
void
DiffApplicationStrategy<DiffMutable>::emu (GenNode const& n)
TreeDiffMutatorBinding::emu (GenNode const& n)
{
#if false /////////////////////////////////////////////////////////////////////////////////////////////////////////////UNIMPLEMENTED :: TICKET #992
TRACE (diff, "tree-diff: LEAVE scope %s", cStr(describeScope()));
@ -390,7 +390,7 @@ namespace diff{
void
DiffApplicationStrategy<DiffMutable>::initDiffApplication()
TreeDiffMutatorBinding::initDiffApplication()
{
TODO("(re)initialise the diff application machinery");
#if false /////////////////////////////////////////////////////////////////////////////////////////////////////////////UNIMPLEMENTED :: TICKET #992
@ -401,14 +401,6 @@ namespace diff{
/* ==== trigger code generation of the generic part ==== */
/************************************************************************/
/* explicit template instantiation DiffApplicationStrategy<DiffMutable> */
/************************************************************************/
template class DiffApplicationStrategy<DiffMutable>;
}} // namespace lib::diff

View file

@ -94,80 +94,6 @@
namespace lib {
namespace diff{
/* ======= derive a TreeMutator binding for a given opaque data structure ======= */
using meta::enable_if;
using meta::Yes_t;
using meta::No_t;
using std::is_same;
/**
* helper to detect presence of a
* TreeMutator builder function
*/
template<typename T>
class exposes_MutatorBuilder
{
META_DETECT_FUNCTION (void, buildMutator, (TreeMutator::Handle));
public:
enum{ value = HasFunSig_buildMutator<T>::value
};
};
template<class TAR, typename SEL =void>
struct MutatorBinding
{
static_assert (!sizeof(TAR), "MutatorBinding: Unable to access or build a TreeMutator for this target data.");
};
template<class TAR>
struct MutatorBinding<TAR, enable_if<is_same<TAR, DiffMutable>>>
{
using Ret = DiffMutable&;
};
template<class TAR>
struct MutatorBinding<TAR, enable_if<exposes_MutatorBuilder<TAR>>>
{
class Wrapper
: public DiffMutable
{
TAR& subject_;
/** implement the TreeMutator interface,
* by forwarding to a known implementation function
* on the wrapped target data type */
virtual void
buildMutator (TreeMutator::Handle handle)
{
subject_.buildMutator (handle);
}
public:
Wrapper(TAR& subj)
: subject_(subj)
{ }
};
using Ret = Wrapper;
};
template<class TAR>
auto
mutatorBinding (TAR& subject) -> typename MutatorBinding<TAR>::Ret
{
using Wrapper = typename MutatorBinding<TAR>::Ret;
return Wrapper{subject};
}
/* ======= Implementation of Tree Diff Application via TreeMutator ======= */
@ -190,8 +116,7 @@ namespace diff{
* @see TreeDiffInterpreter explanation of the verbs
* @see DiffVirtualisedApplication_test demonstration of usage
*/
template<>
class DiffApplicationStrategy<DiffMutable>
class TreeDiffMutatorBinding
: public TreeDiffInterpreter
{
#if false /////////////////////////////////////////////////////////////////////////////////////////////////////////////UNIMPLEMENTED :: TICKET #992
@ -286,7 +211,7 @@ namespace diff{
public:
explicit
DiffApplicationStrategy(DiffMutable& targetBinding)
TreeDiffMutatorBinding(DiffMutable& targetBinding)
{
TODO("attach to the given Target");
#if false /////////////////////////////////////////////////////////////////////////////////////////////////////////////UNIMPLEMENTED :: TICKET #992
@ -299,9 +224,5 @@ namespace diff{
/** use the explicit instantiation provided in library module */
extern template class DiffApplicationStrategy<DiffMutable>;
}} // namespace lib::diff
#endif /*LIB_DIFF_TREE_DIFF_MUTATOR_BINDING_H*/

View file

@ -0,0 +1,131 @@
/*
TREE-DIFF-TRAITS.hpp - definitions to control tree mutator binding
Copyright (C) Lumiera.org
2016, Hermann Vosseler <Ichthyostega@web.de>
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License as
published by the Free Software Foundation; either version 2 of
the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
/** @file tree-diff-traits.hpp
** Definitions and Properties to guide automated tree mutator binding.
** Decision how to access the target structure and how to construct
** a suitable TreeMutator as attached to this opaque target data.
**
** @todo this is WIP as of 8/2016
**
** @see DiffVirtualisedApplication_test
** @see DiffTreeApplication_test
** @see DiffListApplication_test
** @see GenNodeBasic_test
** @see tree-diff.hpp
**
*/
#ifndef LIB_DIFF_TREE_DIFF_TRAITS_H
#define LIB_DIFF_TREE_DIFF_TRAITS_H
#include "lib/diff/tree-mutator.hpp"
#include "lib/diff/diff-mutable.hpp"
#include "lib/util.hpp"
#include <utility>
#include <stack>
namespace lib {
namespace diff{
/* ======= derive a TreeMutator binding for a given opaque data structure ======= */
using meta::enable_if;
using meta::Yes_t;
using meta::No_t;
using std::is_same;
/**
* helper to detect presence of a
* TreeMutator builder function
*/
template<typename T>
class exposes_MutatorBuilder
{
META_DETECT_FUNCTION (void, buildMutator, (TreeMutator::Handle));
public:
enum{ value = HasFunSig_buildMutator<T>::value
};
};
template<class TAR, typename SEL =void>
struct TreeDiffTraits
{
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>>>
{
using Ret = DiffMutable&;
};
template<class TAR>
struct TreeDiffTraits<TAR, enable_if<exposes_MutatorBuilder<TAR>>>
{
class Wrapper
: public DiffMutable
{
TAR& subject_;
/** implement the TreeMutator interface,
* by forwarding to a known implementation function
* on the wrapped target data type */
virtual void
buildMutator (TreeMutator::Handle handle)
{
subject_.buildMutator (handle);
}
public:
Wrapper(TAR& subj)
: subject_(subj)
{ }
};
using Ret = Wrapper;
};
template<class TAR>
auto
mutatorBinding (TAR& subject) -> typename TreeDiffTraits<TAR>::Ret
{
using Wrapper = typename TreeDiffTraits<TAR>::Ret;
return Wrapper{subject};
}
}} // namespace lib::diff
#endif /*LIB_DIFF_TREE_DIFF_TRAITS_H*/

View file

@ -23,7 +23,7 @@
#include "lib/test/run.hpp"
#include "lib/format-util.hpp"
#include "lib/diff/tree-diff-mutator-binding.hpp"
#include "lib/diff/tree-diff-application.hpp"
#include "lib/iter-adapter-stl.hpp"
#include "lib/time/timevalue.hpp"
#include "lib/format-cout.hpp" //////////TODO necessary?

View file

@ -4378,8 +4378,8 @@
<node CREATED="1468761997202" ID="ID_1870085622" MODIFIED="1468762006291" TEXT="kombinierte L&#xf6;sung">
<icon BUILTIN="idea"/>
<node CREATED="1468762009304" ID="ID_1554371522" MODIFIED="1468762018314" TEXT="Interface DiffMutable"/>
<node CREATED="1468762031701" ID="ID_48737788" MODIFIED="1468762250072" TEXT="Meta-Adapter">
<icon BUILTIN="pencil"/>
<node CREATED="1468762031701" ID="ID_48737788" MODIFIED="1469544261716" TEXT="Meta-Adapter">
<linktarget COLOR="#503382" DESTINATION="ID_48737788" ENDARROW="Default" ENDINCLINATION="8;131;" ID="Arrow_ID_579805576" SOURCE="ID_887400042" STARTARROW="None" STARTINCLINATION="535;0;"/>
<node CREATED="1468762052858" ID="ID_494010261" MODIFIED="1468762066764" TEXT="synthetisiert dieses Interface"/>
<node CREATED="1468762067383" ID="ID_484867304" MODIFIED="1468762075059" TEXT="erkennt passende Methoden"/>
<node CREATED="1468762075671" ID="ID_52899390" MODIFIED="1468762081293" TEXT="Problem: Storage">
@ -4442,6 +4442,252 @@
</node>
</node>
</node>
<node CREATED="1469544027620" HGAP="38" ID="ID_1475348824" MODIFIED="1469544049582" TEXT="Storage-Probleme" VSHIFT="11">
<icon BUILTIN="messagebox_warning"/>
<node CREATED="1469544055624" ID="ID_390940604" MODIFIED="1469544066153" TEXT="Beobachtung: Template-bloat">
<icon BUILTIN="stop-sign"/>
<node CREATED="1469544072709" ID="ID_16055877" MODIFIED="1469544083016" TEXT="Ursache: wir generieren die Klasse jedesmal neu"/>
<node CREATED="1469544084220" ID="ID_1247343007" MODIFIED="1469544104909" TEXT="...obwohl keinerlei Bezug zum Target-Typ vorliegt">
<icon BUILTIN="idea"/>
</node>
<node CREATED="1469544123271" ID="ID_1703312587" MODIFIED="1469544133675" TEXT="Funktionalit&#xe4;t ist zu 90% generisch">
<icon BUILTIN="info"/>
</node>
<node CREATED="1469544171176" ID="ID_887400042" MODIFIED="1469544253263">
<richcontent TYPE="NODE"><html>
<head>
</head>
<body>
<p>
<i>nicht</i>&#160;generisch: <b><font color="#923977">mutatorBinding</font></b>
</p>
</body>
</html>
</richcontent>
<arrowlink COLOR="#503382" DESTINATION="ID_48737788" ENDARROW="Default" ENDINCLINATION="8;131;" ID="Arrow_ID_579805576" STARTARROW="None" STARTINCLINATION="535;0;"/>
</node>
</node>
<node CREATED="1469544264955" HGAP="35" ID="ID_366424331" MODIFIED="1469544292540" VSHIFT="16">
<richcontent TYPE="NODE"><html>
<head>
</head>
<body>
<p>
L&#246;sungsversuch: <b>extern template</b>
</p>
</body>
</html>
</richcontent>
<icon BUILTIN="button_cancel"/>
<node CREATED="1469544293574" ID="ID_947583528" MODIFIED="1469544318455" TEXT="Template bereits in Lumiera-Lib vor-generieren">
<icon BUILTIN="info"/>
</node>
<node CREATED="1469544337408" ID="ID_1646108569" MODIFIED="1469544349252" TEXT="nur ctor ist nochmals ge-Templated">
<icon BUILTIN="idea"/>
</node>
<node CREATED="1469544323331" ID="ID_1924059831" MODIFIED="1469544362933" TEXT="flexibler Teil verbleibt in ctor">
<icon BUILTIN="forward"/>
<node CREATED="1469544368180" ID="ID_989521105" MODIFIED="1469544377687" TEXT="hier kann das mutatorBinding stattfinden"/>
<node CREATED="1469544385882" ID="ID_82786122" MODIFIED="1469544397396" TEXT="...in Abh&#xe4;ngigkeit vom konkreten Zieltyp"/>
<node CREATED="1469544400544" ID="ID_1789924824" MODIFIED="1469544413058" TEXT="Resultat ist ein TreeMutator im internen Puffer"/>
</node>
<node CREATED="1469544471294" ID="ID_1306807662" MODIFIED="1469544482058" TEXT="Problem-1: Puffer-Gr&#xf6;&#xdf;e">
<icon BUILTIN="messagebox_warning"/>
<node CREATED="1469544519439" ID="ID_1173588510" MODIFIED="1469544535057" TEXT="Plan: Heuristik + Traits"/>
<node CREATED="1469544536309" ID="ID_579318822" MODIFIED="1469544546951" TEXT="h&#xe4;ngt von konkretem Zieltyp ab"/>
<node CREATED="1469544547731" ID="ID_1296389584" MODIFIED="1469544596453" TEXT="kann nicht im generischen Teil stecken">
<icon BUILTIN="stop-sign"/>
</node>
<node CREATED="1469544575808" ID="ID_259226539" MODIFIED="1469544599880" TEXT="Problem: vom generischen Teil ansprechen">
<icon BUILTIN="messagebox_warning"/>
</node>
<node CREATED="1469544601444" ID="ID_1593190605" MODIFIED="1469544616515" TEXT="L&#xf6;sung: weitere Indirektion">
<icon BUILTIN="yes"/>
</node>
<node CREATED="1469544618738" ID="ID_324293110" MODIFIED="1469544754834" TEXT="vertretbar, da nur beim Scope-Wechsel....">
<richcontent TYPE="NOTE"><html>
<head>
</head>
<body>
<p>
...im Klartext: diesen Zugriff von der generischen Implementierung
</p>
<p>
auf den eingebauten Stack-Mechanismus ben&#246;tigen wir nur...
</p>
<ul>
<li>
einmal zu Beginn, bei der Konstruktion
</li>
<li>
wenn wir in einen geschachtelten Scope eintreten
</li>
</ul>
<p>
Zwar sind indirekte Calls aufwendiger, aber letzten Endes auch wieder nicht soooo aufwendig,
</p>
<p>
da&#223; sie uns im gegebenen Kontext umbringen
</p>
<ul>
<li>
wenn wir einen Solchen verlassen
</li>
</ul>
</body>
</html>
</richcontent>
<icon BUILTIN="idea"/>
</node>
</node>
<node CREATED="1469544496907" ID="ID_447935464" MODIFIED="1469544506440" TEXT="Problem-2: re-Initialisierung">
<icon BUILTIN="messagebox_warning"/>
<node CREATED="1469544831244" ID="ID_756911810" MODIFIED="1469544838662" TEXT="bestehendes Protokoll">
<font ITALIC="true" NAME="SansSerif" SIZE="12"/>
</node>
<node CREATED="1469544839795" ID="ID_1308746305" MODIFIED="1469544858420" TEXT="Diff-Applikator kan beliebige Folge von Diffs akzeptieren"/>
<node CREATED="1469544859392" ID="ID_325998286" MODIFIED="1469544964778">
<richcontent TYPE="NODE"><html>
<head>
</head>
<body>
<p>
<i>intern:</i>&#160;eingebaute <b>initDiffApplication()</b>
</p>
</body>
</html>
</richcontent>
<richcontent TYPE="NOTE"><html>
<head>
</head>
<body>
<p>
...wird automatisch vor Konsumieren eines Diff aufgerufen
</p>
</body>
</html>
</richcontent>
</node>
<node CREATED="1469544965890" ID="ID_443152890" MODIFIED="1469545023179">
<richcontent TYPE="NODE"><html>
<head>
</head>
<body>
<p>
<i>Widerspruch:</i>&#160;TreeMutator ist <b>Wegwerf</b>-Objekt
</p>
</body>
</html>
</richcontent>
<icon BUILTIN="broken-line"/>
</node>
<node COLOR="#f61b01" CREATED="1469545033584" ID="ID_578930155" MODIFIED="1469545058652" TEXT="Abbruch">
<icon BUILTIN="button_cancel"/>
<icon BUILTIN="stop-sign"/>
</node>
</node>
</node>
<node CREATED="1469545080826" HGAP="41" ID="ID_268789302" MODIFIED="1469545140415" VSHIFT="17">
<richcontent TYPE="NODE"><html>
<head>
</head>
<body>
<p>
L&#246;sungsversuch: <b>doppelte H&#252;lle</b>
</p>
</body>
</html>
</richcontent>
<icon BUILTIN="pencil"/>
<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"/>
<node CREATED="1469545208440" ID="ID_796164740" MODIFIED="1469545246870" TEXT="dediziert: Typ-Adapter"/>
</node>
<node CREATED="1469545401582" ID="ID_1145081121" MODIFIED="1469545407769" TEXT="konkrete Folgen...">
<node CREATED="1469545417579" ID="ID_474776082" MODIFIED="1469545427486" TEXT="alle virtuellen Methoden im generischen Teil"/>
<node CREATED="1469545428289" ID="ID_1077900797" MODIFIED="1469545450730" TEXT="generischer Teil verwendet nur Interfaces">
<node CREATED="1469545452406" ID="ID_369878659" MODIFIED="1469545455778" TEXT="TreeMutator"/>
<node CREATED="1469545456549" ID="ID_676404790" MODIFIED="1469545459401" TEXT="ScopeManager"/>
</node>
<node CREATED="1469545522445" ID="ID_1752356251" MODIFIED="1469545525384" TEXT="ScopeManager">
<node CREATED="1469545526380" ID="ID_141570709" MODIFIED="1469545535550" TEXT="Imp. wird per Zieltyp generiert"/>
<node CREATED="1469545536139" ID="ID_423387515" MODIFIED="1469545543750" TEXT="lebt in opaquem Buffer"/>
<node CREATED="1469545546209" ID="ID_229490952" MODIFIED="1469545561067" TEXT="enth&#xe4;lt Stack,"/>
<node CREATED="1469545562151" ID="ID_1390916085" MODIFIED="1469545568130" TEXT="mit passender Puffergr&#xf6;&#xdf;e"/>
</node>
<node CREATED="1469545592171" ID="ID_1826413238" MODIFIED="1469545710185" TEXT="dedizierter Applikator">
<icon BUILTIN="idea"/>
<node CREATED="1469545598922" ID="ID_815414440" MODIFIED="1469545609733" TEXT="h&#xe4;llt Referenz auf Zielobjekt"/>
<node CREATED="1469545611177" ID="ID_410214862" MODIFIED="1469545670672">
<richcontent TYPE="NODE"><html>
<head>
</head>
<body>
<p>
kann daher <b>TreeMutator</b>&#160;konstruieren
</p>
</body>
</html>
</richcontent>
</node>
<node CREATED="1469545641644" ID="ID_1811640827" MODIFIED="1469545662506">
<richcontent TYPE="NODE"><html>
<head>
</head>
<body>
<p>
...und zwar per <b>mutatorBinding</b>
</p>
</body>
</html>
</richcontent>
</node>
<node CREATED="1469545691349" ID="ID_239269579" MODIFIED="1469545705980">
<richcontent TYPE="NODE"><html>
<head>
</head>
<body>
<p>
implementiert somit <b>initDiffApplication()</b>
</p>
</body>
</html>
</richcontent>
</node>
</node>
</node>
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1469545778873" HGAP="37" ID="ID_263708712" MODIFIED="1469546023805" VSHIFT="53">
<richcontent TYPE="NODE"><html>
<head>
</head>
<body>
<p>
TODO: <font color="#010101">Namensgebung</font>
</p>
</body>
</html>
</richcontent>
<linktarget COLOR="#7c4b8e" DESTINATION="ID_263708712" ENDARROW="Default" ENDINCLINATION="-438;877;" ID="Arrow_ID_774958535" SOURCE="ID_660087752" STARTARROW="Default" STARTINCLINATION="2134;135;"/>
<icon BUILTIN="flag-yellow"/>
<node CREATED="1469545959160" ID="ID_826999251" MODIFIED="1469545961076" TEXT="DiffApplicationStrategy&lt;DiffMutable&gt;"/>
<node CREATED="1469545962192" ID="ID_1539721850" MODIFIED="1469545971051" TEXT="feste explizite Spezialisierung"/>
<node CREATED="1469545972470" ID="ID_996523023" MODIFIED="1469545983800" TEXT="in non-Template-Basisklasse verwandeln"/>
<node CREATED="1469545990956" ID="ID_543764775" MODIFIED="1469546010389" TEXT="oder zumindest in Trait-Template + enable_if"/>
</node>
</node>
</node>
</node>
</node>
</node>
@ -4604,6 +4850,10 @@
<node CREATED="1465428236860" ID="ID_339833424" MODIFIED="1465428248614" TEXT="speziell Attribut-Binding unterst&#xfc;tzt zur generische Variante"/>
</node>
</node>
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1469545751885" ID="ID_660087752" MODIFIED="1469545906061" TEXT="Namensgebung f&#xfc;r generisches Mutator-Binding">
<arrowlink COLOR="#7c4b8e" DESTINATION="ID_263708712" ENDARROW="Default" ENDINCLINATION="-438;877;" ID="Arrow_ID_774958535" STARTARROW="Default" STARTINCLINATION="2134;135;"/>
<icon BUILTIN="flag-yellow"/>
</node>
<node CREATED="1458850387823" ID="ID_415691337" MODIFIED="1458850394506" TEXT="allgemein">
<node CREATED="1458850397158" ID="ID_1336568549" MODIFIED="1458850405665" TEXT="GenNode">
<node CREATED="1458850406396" ID="ID_1837583550" MODIFIED="1458850420054" TEXT="string-Repr&#xe4;sentation der Payload"/>