Lumiera  0.pre.03
»edit your freedom«
tree-diff-application.hpp
Go to the documentation of this file.
1 /*
2  TREE-DIFF-APPLICATION.hpp - consume and apply a tree diff
3 
4  Copyright (C)
5  2016, Hermann Vosseler <Ichthyostega@web.de>
6 
7   **Lumiera** is free software; you can redistribute it and/or modify it
8   under the terms of the GNU General Public License as published by the
9   Free Software Foundation; either version 2 of the License, or (at your
10   option) any later version. See the file COPYING for further details.
11 
12 */
13 
14 
124 #ifndef LIB_DIFF_TREE_DIFF_APPLICATION_H
125 #define LIB_DIFF_TREE_DIFF_APPLICATION_H
126 
127 
128 #include "lib/diff/tree-diff.hpp"
129 #include "lib/diff/tree-mutator.hpp"
130 #include "lib/diff/diff-mutable.hpp"
132 #include "lib/diff/gen-node.hpp"
133 #include "lib/format-string.hpp"
134 #include "lib/util.hpp"
135 
136 #include <utility>
137 #include <stack>
138 
139 namespace lib {
140 namespace diff{
141 
148  {
149  public:
150  virtual ~ScopeManager();
151 
152  virtual TreeMutator::Handle openScope() =0;
153  virtual TreeMutator& closeScope() =0;
154  virtual void clear() =0;
155 
156  virtual size_t depth() const =0;
157  };
158 
159 
160 
169  template<size_t buffSiz>
171  : public ScopeManager
172  {
174  using MutatorStack = std::stack<MutatorBuffer>;
175 
177  MutatorStack scopes_;
178 
179 
180  public:
182  : scopes_()
183  { }
184 
185  TreeMutator&
186  currentScope() const
187  {
188  if (0 == depth())
189  throw error::Logic("Attempt to access the current scope "
190  "without establishing a root scope beforehand."
191  , error::LUMIERA_ERROR_LIFECYCLE);
192  return *scopes_.top();
193  }
194 
195 
196  /* ==== ScopeManager interface ==== */
197 
198  virtual TreeMutator::Handle
200  {
201  scopes_.emplace();
202  TreeMutator::Handle placementHandle (scopes_.top());
203  return placementHandle;
204  }
205 
206  virtual TreeMutator&
207  closeScope()
208  {
209  scopes_.pop();
210  REQUIRE (0 < depth(), "attempt to return beyond root scope");
211  return *scopes_.top();
212  }
213 
214  virtual void
215  clear()
216  {
217  while (0 < scopes_.size())
218  scopes_.pop();
219 
220  ENSURE (scopes_.empty());
221  }
222 
223 
224  virtual size_t
225  depth() const
226  {
227  return scopes_.size();
228  }
229  };
230 
231 
232 
233 
234 
235  /* ======= Implementation of Tree Diff Application via TreeMutator ======= */
236 
237  using util::unConst;
238  using util::_Fmt;
239  using std::move;
240  using std::swap;
241 
242 
264  : public TreeDiffInterpreter
265  {
266  protected:
267  TreeMutator* treeMutator_;
268  ScopeManager* scopeManger_;
269 
270  private:
271 
272  /* == error handling helpers == */
273 
274  void __failMismatch (Literal oper, GenNode const& spec);
275  void __expect_further_elements (GenNode const& elm);
276  void __fail_not_found (GenNode const& elm);
277  void __expect_end_of_scope (GenNode::ID const& idi);
278  void __expect_valid_parent_scope (GenNode::ID const& idi);
279 
280 
281 
282 
283  /* == Implementation of the list diff application primitives == */
284 
285  virtual void ins (GenNode const& n) override;
286  virtual void del (GenNode const& n) override;
287  virtual void pick (GenNode const& n) override;
288  virtual void skip (GenNode const& n) override;
289  virtual void find (GenNode const& n) override;
290 
291 
292  /* == Implementation of the tree diff application primitives == */
293 
294  virtual void after(GenNode const& n) override;
295  virtual void set (GenNode const& n) override;
296  virtual void mut (GenNode const& n) override;
297  virtual void emu (GenNode const& n) override;
298 
299 
300  public:
302  : treeMutator_(nullptr)
303  , scopeManger_(nullptr)
304  { }
305  };
306 
307 
308 
309 
310 
311 
336  template<class TAR>
337  class DiffApplicationStrategy<TAR, enable_if<TreeDiffTraits<TAR>>>
338  : public TreeDiffMutatorBinding
339  {
341 
342 
343  TAR& subject_;
344  Scopes scopes_;
345 
346 
347  TreeMutator*
348  buildMutator (DiffMutable& targetBinding)
349  {
350  scopes_.clear();
351  TreeMutator::Handle buffHandle = scopes_.openScope();
352  targetBinding.buildMutator (buffHandle);
353  return buffHandle.get();
354  }
355 
356  public:
357  explicit
358  DiffApplicationStrategy(TAR& subject)
360  , subject_(subject)
361  , scopes_()
362  { }
363 
364  void
365  initDiffApplication()
366  {
367  using Target = typename TreeDiffTraits<TAR>::Ret;
368 
369  Target target = mutatorBinding (subject_);
370  buildMutator(target)->init();
371  TreeDiffMutatorBinding::scopeManger_ = &scopes_;
372  TreeDiffMutatorBinding::treeMutator_ = &scopes_.currentScope();
373  REQUIRE (this->treeMutator_);
374  }
375 
376  void
377  completeDiffApplication()
378  {
379  if (not treeMutator_->completeScope())
380  throw error::State(_Fmt("Unsettled content remains after diff application. "
381  "Top level == %s") % subject_
382  , LERR_(DIFF_STRUCTURE));
383  // discard storage
384  treeMutator_ = nullptr;
385  scopes_.clear();
386  }
387  };
388 
389 
390 
391 }} // namespace lib::diff
392 #endif /*LIB_DIFF_TREE_DIFF_APPLICATION_H*/
Interpreter interface to define the operations ("verbs"), which describe differences or changes in hi...
Definition: tree-diff.hpp:125
Abstraction or descriptor interface for a data structure exposing the ability for mutation by receivi...
virtual TreeMutator::Handle openScope()
virtual void buildMutator(TreeMutator::Handle buffer)=0
build a custom implementation of the TreeMutator interface, suitably wired to cause appropriate chang...
virtual TreeMutator::Handle openScope()=0
virtual ~ScopeManager()
this is an interface
Definition: tree-diff.cpp:44
Any copy and copy construction prohibited.
Definition: nocopy.hpp:37
inline string literal This is a marker type to indicate that
Definition: symbol.hpp:76
Front-end for printf-style string template interpolation.
A front-end for using printf-style formatting.
Implementation namespace for support and library code.
Definitions and Properties to guide automated tree mutator binding.
Derived specific exceptions within Lumiera&#39;s exception hierarchy.
Definition: error.hpp:190
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...
Definition: record.hpp:104
Typical standard implementation of the ScopeManager.
Tiny helper functions and shortcuts to be used everywhere Consider this header to be effectively incl...
MutatorStack scopes_
Allocate Heap Storage for nested TreeMutator(s)
Generic building block for tree shaped (meta)data structures.
Extension point: define how a specific diff language can be applied to elements in a concrete contain...
Management interface to deal with storage for TreeMutators dedicated to nested scopes.
A token language to represent structural changes in a tree like hierarchical data structure...
Customisable intermediary to abstract generic tree mutation operations.
Buffer to place and maintain an object instance privately within another object.
TreeDiffTraits< TAR >::Ret mutatorBinding(TAR &subject)
public access point to this configuration machinery
generic data element node within a tree
Definition: gen-node.hpp:222
Marker or capability interface: an otherwise not further disclosed data structure, which can be transformed through "tree diff messages".
Customisable intermediary to abstract mutating operations on arbitrary, hierarchical object-like data...
Implementation of the tree-diff-language to work on arbitrary tree-like data.