Lumiera  0.pre.03
»edityourfreedom«
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
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 
83 #ifndef LIB_DIFF_DIFF_LANGUAGE_H
84 #define LIB_DIFF_DIFF_LANGUAGE_H
85 
86 
87 #include "lib/error.hpp"
88 #include "lib/nocopy.hpp"
89 #include "lib/verb-token.hpp"
90 #include "lib/util.hpp"
91 
92 #include <tuple>
93 
94 
95 
96 namespace lib {
97 namespace diff{
98 
99  namespace error = lumiera::error;
100 
101  LUMIERA_ERROR_DECLARE(DIFF_CONFLICT);
102 
103 
104  template<class I, typename E>
105  using HandlerFun = void (I::*) (E const&); // NOTE: element value taken by const&
106 
107 
109  template<class I>
111  {
112  using Interpreter = I;
113  using Val = typename I::Val;
115  };
116 
117  template<template<typename> class IP, typename E>
118  struct InterpreterScheme<IP<E>>
119  {
120  using Val = E;
121  using Interpreter = IP<E>;
123  };
124 
125  template<class I, typename E>
127  {
128  using Val = E;
129  using Interpreter = I;
131  };
132 
133 
134 
150  template< class I, typename E>
152  {
153 
154  using DiffVerb = VerbToken<I, void(E const&)>; // NOTE: element value taken by const&
155  using DiffToken = std::tuple<DiffVerb, E>;
156  using Interpreter = I;
157 
158  struct DiffStep
159  : DiffToken
160  {
161  DiffVerb& verb() { return std::get<0>(*this); }
162  E const& elm() { return std::get<1>(*this); }
163 
165  : DiffToken(verb,e)
166  { }
167 
168  operator string() const
169  {
170  return string(unConst(this)->verb())
171  + "("+string(unConst(this)->elm())+")";
172  }
173 
174  void
175  applyTo (Interpreter& interpreter)
176  {
177  using util::cStr;
178  TRACE (diff, "verb %4s(%s)", cStr(verb()), cStr(elm()) );
179  verb().applyTo (interpreter, elm());
180  }
181  };
182 
183 
184  static const DiffStep NIL;
185  };
186 
187 
188 
189 
190 
192  template<class I>
194  {
196  using Handler = typename Scheme::Handler;
197  using Val = typename Scheme::Val;
198 
200  using Step = typename Lang::DiffStep;
201  using Verb = typename Lang::DiffVerb;
202 
205 
206  Step
207  operator() (Val elm) const
208  {
209  return { Verb(handler,id), elm };
210  }
211  };
212 
213 
221  template<class H>
222  inline DiffStepBuilder<typename InterpreterScheme<H>::Interpreter>
223  diffTokenBuilder (H handlerFun, Literal id)
224  {
225  return { handlerFun, id };
226  }
227 
238 #define DiffStep_CTOR(_ID_) \
239  const DiffStepBuilder<Interpreter> _ID_ = diffTokenBuilder (&Interpreter::_ID_, STRINGIFY(_ID_));
240 
241 
242 
246  template<class I, typename E>
247  const typename DiffLanguage<I,E>::DiffStep DiffLanguage<I,E>::NIL = DiffStep(DiffVerb(), E());
248 
249 
250 
251 
252 
253 
254 
255 
256 
257  /* ==== Implementation Pattern for Diff Application ==== */
258 
271  template<class TAR, typename SEL =void>
273 
274 
286  template<class TAR>
289  {
291 
293 
294  public:
295  explicit
296  DiffApplicator(TAR& targetStructure)
297  : target_(targetStructure)
298  { }
299 
300  template<class DIFF>
301  void
302  consume (DIFF&& diff)
303  {
304  target_.initDiffApplication();
305  for ( ; diff; ++diff )
306  diff->applyTo(target_);
307  }
308  };
309 
310 
311 
312 }} // namespace lib::diff
313 #endif /*LIB_DIFF_DIFF_LANGUAGE_H*/
typename Scheme::Val Val
LUMIERA_ERROR_DECLARE(DIFF_CONFLICT)
Collision in diff application: contents of target not as expected.
abstract entry, not yet allocated
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
Action token implemented by double dispatch to a handler function, as defined in the "receiver" inter...
Definition: verb-token.hpp:76
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
Extension point: define how a specific diff language can be applied to elements in a concrete contain...
const char * cStr(string const &org)
convenience shortcut: conversion to c-String via string.
Definition: util.hpp:380
Implementation namespace for support and library code.
DiffApplicator(TAR &targetStructure)
TRACE(test,"inserted %d", data)
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).
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
TreeDiffLanguage::DiffStep DiffStep
VerbToken< I, void(E const &)> DiffVerb
HandlerFun< I, Val > Handler
static const DiffStep NIL
fixed "invalid" marker token
typename Lang::DiffVerb Verb
Step operator()(Val elm) const
HandlerFun< Interpreter, Val > Handler
Definition frame for a language to describe differences in data structures.
generic builder to apply a diff description to a given target data structure.