80 TreeDiffMutatorBinding::__failMismatch (
Literal oper,
GenNode const& spec)
83 "data does not match expectations") % oper % spec
84 , LERR_(DIFF_CONFLICT)};
88 TreeDiffMutatorBinding::__expect_further_elements (
GenNode const& elm)
90 if (not treeMutator_->hasSrc())
91 throw error::State{
_Fmt(
"Premature end of target sequence, still expecting element %s; " 92 "unable to apply diff further.") % elm
93 , LERR_(DIFF_CONFLICT)};
97 TreeDiffMutatorBinding::__fail_not_found (
GenNode const& elm)
100 "element %s in the remainder of the target.") % elm
101 , LERR_(DIFF_CONFLICT)};
105 TreeDiffMutatorBinding::__expect_end_of_scope (
GenNode::ID const& idi)
107 if (not treeMutator_->completeScope())
109 "unexpected extra elements found when diff " 110 "should have settled everything.") % idi.getSym()
111 , LERR_(DIFF_STRUCTURE)};
115 TreeDiffMutatorBinding::__expect_valid_parent_scope (
GenNode::ID const& idi)
117 if (0 == scopeManger_->depth())
118 throw error::Fatal{
_Fmt(
"Diff application floundered after leaving scope %s; " 119 "unbalanced nested scopes, diff attempts to pop root.") % idi.getSym()
120 , LERR_(DIFF_STRUCTURE)};
130 TreeDiffMutatorBinding::ins (
GenNode const& n)
132 bool success = treeMutator_->injectNew(n);
134 __failMismatch (
"insert", n);
138 TreeDiffMutatorBinding::del (
GenNode const& n)
140 __expect_further_elements(n);
141 if (not treeMutator_->matchSrc(n))
142 __failMismatch(
"remove", n);
144 treeMutator_->skipSrc(n);
148 TreeDiffMutatorBinding::pick (
GenNode const& n)
150 bool success = treeMutator_->acceptSrc (n);
152 __failMismatch (
"pick", n);
156 TreeDiffMutatorBinding::skip (
GenNode const& n)
158 __expect_further_elements (n);
159 treeMutator_->skipSrc(n);
163 TreeDiffMutatorBinding::find (
GenNode const& n)
165 __expect_further_elements (n);
167 if (not treeMutator_->findSrc(n))
168 __fail_not_found (n);
182 if (not treeMutator_->accept_until(n))
183 __fail_not_found (n);
190 if (not treeMutator_->assignElm(n))
191 __failMismatch(
"assign", n);
199 if (not treeMutator_->mutateChild(n, buffHandle))
200 __failMismatch(
"enter nested scope", n);
202 TRACE (diff,
"tree-diff: ENTER scope %s",
cStr(n.idi));
203 treeMutator_ = buffHandle.get();
210 TRACE (diff,
"tree-diff: LEAVE scope %s",
cStr(n.idi));
212 __expect_end_of_scope (n.idi);
213 treeMutator_ = &scopeManger_->closeScope();
214 __expect_valid_parent_scope (n.idi);
Concrete implementation to apply structural changes to hierarchical data structures.
CStr cStr(std::string const &rendered)
convenience shortcut: forced conversion to c-String via string.
virtual ~ScopeManager()
this is an interface
inline string literal This is a marker type to indicate that
virtual ~TreeMutator()
this is an interface
virtual void after(GenNode const &n) override
cue to a position behind the named node, thereby picking (accepting) all traversed elements into the ...
A front-end for using printf-style formatting.
virtual void emu(GenNode const &n) override
finish and leave child object scope, return to parent
Implementation namespace for support and library code.
static Builder< TreeMutator > build()
DSL: start building a custom adapted tree mutator, where the operations are tied by closures or wrapp...
Derived specific exceptions within Lumiera's exception hierarchy.
SUB & emplace(SUB &&implementation)
move-construct an instance of a subclass into the opaque buffer
A handle to allow for safe »remote implantation« of an unknown subclass into a given opaque InPlaceBu...
virtual void set(GenNode const &n) override
assignment of changed value in one step
void buildMutator(BufferHandle)
attachment point to receive and apply tree-diff changes.
virtual void mut(GenNode const &n) override
open nested scope to apply diff to child object
Lumiera error handling (C++ interface).
generic data element node within a tree