Lumiera  0.pre.03
»edityourfreedom«
diff-language.hpp
Go to the documentation of this file.
1 /*
2  DIFF-LANGUAGE.hpp - language to describe differences in linearised form
3 
4  Copyright (C) Lumiera.org
5  2014, Hermann Vosseler <Ichthyostega@web.de>
6 
7  This program is free software; you can redistribute it and/or
8  modify it under the terms of the GNU General Public License as
9  published by the Free Software Foundation; either version 2 of
10  the License, or (at your option) any later version.
11 
12  This program is distributed in the hope that it will be useful,
13  but WITHOUT ANY WARRANTY; without even the implied warranty of
14  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15  GNU General Public License for more details.
16 
17  You should have received a copy of the GNU General Public License
18  along with this program; if not, write to the Free Software
19  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20 
21 */
22 
23 
85 #ifndef LIB_DIFF_DIFF_LANGUAGE_H
86 #define LIB_DIFF_DIFF_LANGUAGE_H
87 
88 
89 #include "lib/error.hpp"
90 #include "lib/nocopy.hpp"
91 #include "lib/verb-token.hpp"
92 #include "lib/util.hpp"
93 
94 #include <tuple>
95 
96 
97 
98 namespace lib {
99 namespace diff{
100 
101  namespace error = lumiera::error;
102 
103  LUMIERA_ERROR_DECLARE(DIFF_STRUCTURE);
104  LUMIERA_ERROR_DECLARE(DIFF_CONFLICT);
105 
106 
107  template<class I, typename E>
108  using HandlerFun = void (I::*) (E const&); // NOTE: element value taken by const&
109 
110 
112  template<class I>
114  {
115  using Interpreter = I;
116  using Val = typename I::Val;
118  };
119 
120  template<template<typename> class IP, typename E>
121  struct InterpreterScheme<IP<E>>
122  {
123  using Val = E;
124  using Interpreter = IP<E>;
126  };
127 
128  template<class I, typename E>
130  {
131  using Val = E;
132  using Interpreter = I;
134  };
135 
136 
137 
153  template< class I, typename E>
155  {
156 
157  using DiffVerb = VerbToken<I, void(E const&)>; // NOTE: element value taken by const&
158  using DiffToken = std::tuple<DiffVerb, E>;
159  using Interpreter = I;
160 
161  struct DiffStep
162  : DiffToken
163  {
164  DiffVerb& verb() { return std::get<0>(*this); }
165  E const& elm() { return std::get<1>(*this); }
166 
167  DiffStep(DiffVerb verb, E e)
168  : DiffToken(verb,e)
169  { }
170 
171  operator string() const
172  {
173  return string(unConst(this)->verb())
174  + "("+string(unConst(this)->elm())+")";
175  }
176 
177  void
178  applyTo (Interpreter& interpreter)
179  {
180  using util::cStr;
181  TRACE (diff, "verb %4s(%s)", cStr(verb()), cStr(elm()) );
182  verb().applyTo (interpreter, elm());
183  }
184  };
185 
186 
187  static const DiffStep NIL;
188  };
189 
190 
191 
192 
193 
195  template<class I>
197  {
199  using Handler = typename Scheme::Handler;
200  using Val = typename Scheme::Val;
201 
203  using Step = typename Lang::DiffStep;
204  using Verb = typename Lang::DiffVerb;
205 
208 
209  Step
210  operator() (Val elm) const
211  {
212  return { Verb(handler,id), elm };
213  }
214  };
215 
216 
224  template<class H>
226  diffTokenBuilder (H handlerFun, Literal id)
227  {
228  return { handlerFun, id };
229  }
230 
241 #define DiffStep_CTOR(_ID_) \
242  const DiffStepBuilder<Interpreter> _ID_ = diffTokenBuilder (&Interpreter::_ID_, STRINGIFY(_ID_));
243 
244 
245 
249  template<class I, typename E>
250  const typename DiffLanguage<I,E>::DiffStep DiffLanguage<I,E>::NIL = DiffStep(DiffVerb(), E());
251 
252 
253 
254 
255 
256 
257 
258 
259 
260  /* ==== Implementation Pattern for Diff Application ==== */
261 
274  template<class TAR, typename SEL =void>
276 
277 
289  template<class TAR>
292  {
294 
296 
297  public:
298  explicit
299  DiffApplicator(TAR& targetStructure)
300  : target_(targetStructure)
301  { }
302 
303  template<class DIFF>
304  void
305  consume (DIFF&& diff)
306  {
307  target_.initDiffApplication();
308  for ( ; diff; ++diff )
309  diff->applyTo(target_);
310  }
311  };
312 
313 
314 
315 }} // namespace lib::diff
316 #endif /*LIB_DIFF_DIFF_LANGUAGE_H*/
Action token implemented by double dispatch to a handler function, as defined in the "receiver" inter...
Definition: verb-token.hpp:76
typename Scheme::Val Val
void applyTo(Interpreter &interpreter)
< base case is to expect typedef I::Val
Building blocks for a simple DSL using double dispatch to a handler function.
typename Scheme::Handler Handler
void consume(DIFF &&diff)
Interpreter interface to define the operations ("verbs"), which describe differences or changes in a ...
Definition: list-diff.hpp:72
Any copy and copy construction prohibited.
Definition: nocopy.hpp:46
inline string literal This is a marker type to indicate that
Definition: symbol.hpp:75
typename Lang::DiffStep Step
const char * cStr(string const &org)
convenience shortcut: conversion to c-String via string.
Definition: util.hpp:397
Implementation namespace for support and library code.
DiffApplicator(TAR &targetStructure)
Mix-Ins to allow or prohibit various degrees of copying and cloning.
DiffStepBuilder< typename InterpreterScheme< H >::Interpreter > diffTokenBuilder(H handlerFun, Literal id)
set up a diff language token generator, based on the specific handler function given.
Tiny helper functions and shortcuts to be used everywhere Consider this header to be effectively incl...
void(I::*)(E const &) HandlerFun
Lumiera error handling (C++ interface).
TRACE(test, "inserted %d", data)
OBJ * unConst(const OBJ *o)
shortcut to save some typing when having to define const and non-const variants of member functions ...
Definition: util.hpp:319
generator to produce specific language tokens
LUMIERA_ERROR_DECLARE(DIFF_STRUCTURE)
Invalid diff structure: implicit rules and assumptions violated.
TreeDiffLanguage::DiffStep DiffStep
HandlerFun< I, Val > Handler
static const DiffStep NIL
fixed "invalid" marker token
typename Lang::DiffVerb Verb
HandlerFun< Interpreter, Val > Handler
Extension point: define how a specific diff language can be applied to elements in a concrete contain...
Definition frame for a language to describe differences in data structures.
generic builder to apply a diff description to a given target data structure.