Lumiera  0.pre.03
»edit your freedom«
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)
5  2014, 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 
76 #ifndef LIB_DIFF_DIFF_LANGUAGE_H
77 #define LIB_DIFF_DIFF_LANGUAGE_H
78 
79 
80 #include "lib/error.hpp"
81 #include "lib/nocopy.hpp"
82 #include "lib/verb-token.hpp"
83 #include "lib/util.hpp"
84 
85 #include <tuple>
86 
87 
88 namespace lumiera {
89 namespace error {
90  LUMIERA_ERROR_DECLARE(DIFF_STRUCTURE);
91  LUMIERA_ERROR_DECLARE(DIFF_CONFLICT);
92 }}
93 
94 namespace lib {
95 namespace diff{
96 
97  namespace error = lumiera::error;
98 
99 
100  template<class I, typename E>
101  using HandlerFun = void (I::*) (E const&); // NOTE: element value taken by const&
102 
103 
105  template<class I>
107  {
108  using Interpreter = I;
109  using Val = typename I::Val;
110  using Handler = HandlerFun<I,Val>;
111  };
112 
113  template<template<typename> class IP, typename E>
114  struct InterpreterScheme<IP<E>>
115  {
116  using Val = E;
117  using Interpreter = IP<E>;
118  using Handler = HandlerFun<Interpreter,Val>;
119  };
120 
121  template<class I, typename E>
122  struct InterpreterScheme<HandlerFun<I,E>>
123  {
124  using Val = E;
125  using Interpreter = I;
126  using Handler = HandlerFun<I,E>;
127  };
128 
129 
130 
146  template< class I, typename E>
148  {
149 
150  using DiffVerb = VerbToken<I, void(E const&)>; // NOTE: element value taken by const&
151  using DiffToken = std::tuple<DiffVerb, E>;
152  using Interpreter = I;
153 
154  struct DiffStep
155  : DiffToken
156  {
157  DiffVerb& verb() { return std::get<0>(*this); }
158  E const& elm() { return std::get<1>(*this); }
159 
160  DiffStep(DiffVerb verb, E e)
161  : DiffToken(verb,e)
162  { }
163 
164  operator string() const
165  {
166  return string(unConst(this)->verb())
167  + "("+string(unConst(this)->elm())+")";
168  }
169 
170  void
171  applyTo (Interpreter& interpreter)
172  {
173  TRACE (diff, "verb %4s(%s)", cStr(verb()), cStr(elm()) );
174  verb().applyTo (interpreter, elm());
175  }
176  };
177 
178 
179  static const DiffStep NIL;
180  };
181 
182 
183 
184 
185 
187  template<class I>
189  {
191  using Handler = typename Scheme::Handler;
192  using Val = typename Scheme::Val;
193 
194  using Lang = DiffLanguage<I,Val>;
195  using Step = typename Lang::DiffStep;
196  using Verb = typename Lang::DiffVerb;
197 
198  Handler handler;
199  Literal id;
200 
201  Step
202  operator() (Val elm) const
203  {
204  return { Verb(handler,id), elm };
205  }
206  };
207 
208 
216  template<class H>
218  diffTokenBuilder (H handlerFun, Literal id)
219  {
220  return { handlerFun, id };
221  }
222 
233 #define DiffStep_CTOR(_ID_) \
234  const DiffStepBuilder<Interpreter> _ID_ = diffTokenBuilder (&Interpreter::_ID_, STRINGIFY(_ID_));
235 
236 
237 
241  template<class I, typename E>
242  const typename DiffLanguage<I,E>::DiffStep DiffLanguage<I,E>::NIL = DiffStep(DiffVerb(), E());
243 
244 
245 
246 
247 
248 
249 
250 
251 
252  /* ==== Implementation Pattern for Diff Application ==== */
253 
268  template<class TAR, typename SEL =void>
270 
271 
283  template<class TAR>
286  {
288 
289  Interpreter target_;
290 
291  public:
292  explicit
293  DiffApplicator(TAR& targetStructure)
294  : target_(targetStructure)
295  { }
296 
297  template<class DIFF>
298  void
299  consume (DIFF&& diff)
300  {
301  target_.initDiffApplication();
302  for ( ; diff; ++diff )
303  diff->applyTo(target_);
304  target_.completeDiffApplication();
305  }
306  };
307 
308 
309 
310 }} // namespace lib::diff
311 #endif /*LIB_DIFF_DIFF_LANGUAGE_H*/
< base case is to expect typedef I::Val
Action token implemented by double dispatch to a handler function, as defined in the "receiver" inter...
Definition: verb-token.hpp:69
Building blocks for a simple DSL using double dispatch to a handler function.
CStr cStr(std::string const &rendered)
convenience shortcut: forced conversion to c-String via string.
Definition: symbol.hpp:59
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
#define LUMIERA_ERROR_DECLARE(err)
Forward declare an error constant.
Definition: error.h:62
Implementation namespace for support and library code.
Mix-Ins to allow or prohibit various degrees of copying and cloning.
Tiny helper functions and shortcuts to be used everywhere Consider this header to be effectively incl...
Extension point: define how a specific diff language can be applied to elements in a concrete contain...
Lumiera error handling (C++ interface).
generator to produce specific language tokens
Lumiera public interface.
Definition: advice.cpp:104
abstract entry, not yet allocated
static const DiffStep NIL
fixed "invalid" marker token
DiffStepBuilder< typename InterpreterScheme< H >::Interpreter > diffTokenBuilder(H handlerFun, Literal id)
set up a diff language token generator, based on the specific handler function given.
Definition frame for a language to describe differences in data structures.
generic builder to apply a diff description to a given target data structure.