89 TreeDiffMutatorBinding::__failMismatch (
Literal oper,
GenNode const& spec)
92 "data does not match expectations") % oper % spec
93 , LERR_(DIFF_CONFLICT)};
97 TreeDiffMutatorBinding::__expect_further_elements (
GenNode const& elm)
99 if (not treeMutator_->hasSrc())
100 throw error::State{
_Fmt(
"Premature end of target sequence, still expecting element %s; " 101 "unable to apply diff further.") % elm
102 , LERR_(DIFF_CONFLICT)};
106 TreeDiffMutatorBinding::__fail_not_found (
GenNode const& elm)
109 "element %s in the remainder of the target.") % elm
110 , LERR_(DIFF_CONFLICT)};
114 TreeDiffMutatorBinding::__expect_end_of_scope (
GenNode::ID const& idi)
116 if (not treeMutator_->completeScope())
118 "unexpected extra elements found when diff " 119 "should have settled everything.") % idi.getSym()
120 , LERR_(DIFF_STRUCTURE)};
124 TreeDiffMutatorBinding::__expect_valid_parent_scope (
GenNode::ID const& idi)
126 if (0 == scopeManger_->depth())
127 throw error::Fatal{
_Fmt(
"Diff application floundered after leaving scope %s; " 128 "unbalanced nested scopes, diff attempts to pop root.") % idi.getSym()
129 , LERR_(DIFF_STRUCTURE)};
139 TreeDiffMutatorBinding::ins (
GenNode const& n)
141 bool success = treeMutator_->injectNew(n);
143 __failMismatch (
"insert", n);
147 TreeDiffMutatorBinding::del (
GenNode const& n)
149 __expect_further_elements(n);
150 if (not treeMutator_->matchSrc(n))
151 __failMismatch(
"remove", n);
153 treeMutator_->skipSrc(n);
157 TreeDiffMutatorBinding::pick (
GenNode const& n)
159 bool success = treeMutator_->acceptSrc (n);
161 __failMismatch (
"pick", n);
165 TreeDiffMutatorBinding::skip (
GenNode const& n)
167 __expect_further_elements (n);
168 treeMutator_->skipSrc(n);
172 TreeDiffMutatorBinding::find (
GenNode const& n)
174 __expect_further_elements (n);
176 if (not treeMutator_->findSrc(n))
177 __fail_not_found (n);
191 if (not treeMutator_->accept_until(n))
192 __fail_not_found (n);
199 if (not treeMutator_->assignElm(n))
200 __failMismatch(
"assign", n);
208 if (not treeMutator_->mutateChild(n, buffHandle))
209 __failMismatch(
"enter nested scope", n);
211 TRACE (diff,
"tree-diff: ENTER scope %s",
cStr(n.idi));
212 treeMutator_ = buffHandle.get();
219 TRACE (diff,
"tree-diff: LEAVE scope %s",
cStr(n.idi));
221 __expect_end_of_scope (n.idi);
222 treeMutator_ = &scopeManger_->closeScope();
223 __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