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) 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 namespace lumiera {
98 namespace error {
99  LUMIERA_ERROR_DECLARE(DIFF_STRUCTURE);
100  LUMIERA_ERROR_DECLARE(DIFF_CONFLICT);
101 }}
102 
103 namespace lib {
104 namespace diff{
105 
106  namespace error = lumiera::error;
107 
108 
109  template<class I, typename E>
110  using HandlerFun = void (I::*) (E const&); // NOTE: element value taken by const&
111 
112 
114  template<class I>
116  {
117  using Interpreter = I;
118  using Val = typename I::Val;
119  using Handler = HandlerFun<I,Val>;
120  };
121 
122  template<template<typename> class IP, typename E>
123  struct InterpreterScheme<IP<E>>
124  {
125  using Val = E;
126  using Interpreter = IP<E>;
127  using Handler = HandlerFun<Interpreter,Val>;
128  };
129 
130  template<class I, typename E>
131  struct InterpreterScheme<HandlerFun<I,E>>
132  {
133  using Val = E;
134  using Interpreter = I;
135  using Handler = HandlerFun<I,E>;
136  };
137 
138 
139 
155  template< class I, typename E>
157  {
158 
159  using DiffVerb = VerbToken<I, void(E const&)>; // NOTE: element value taken by const&
160  using DiffToken = std::tuple<DiffVerb, E>;
161  using Interpreter = I;
162 
163  struct DiffStep
164  : DiffToken
165  {
166  DiffVerb& verb() { return std::get<0>(*this); }
167  E const& elm() { return std::get<1>(*this); }
168 
169  DiffStep(DiffVerb verb, E e)
170  : DiffToken(verb,e)
171  { }
172 
173  operator string() const
174  {
175  return string(unConst(this)->verb())
176  + "("+string(unConst(this)->elm())+")";
177  }
178 
179  void
180  applyTo (Interpreter& interpreter)
181  {
182  TRACE (diff, "verb %4s(%s)", cStr(verb()), cStr(elm()) );
183  verb().applyTo (interpreter, elm());
184  }
185  };
186 
187 
188  static const DiffStep NIL;
189  };
190 
191 
192 
193 
194 
196  template<class I>
198  {
200  using Handler = typename Scheme::Handler;
201  using Val = typename Scheme::Val;
202 
203  using Lang = DiffLanguage<I,Val>;
204  using Step = typename Lang::DiffStep;
205  using Verb = typename Lang::DiffVerb;
206 
207  Handler handler;
208  Literal id;
209 
210  Step
211  operator() (Val elm) const
212  {
213  return { Verb(handler,id), elm };
214  }
215  };
216 
217 
225  template<class H>
227  diffTokenBuilder (H handlerFun, Literal id)
228  {
229  return { handlerFun, id };
230  }
231 
242 #define DiffStep_CTOR(_ID_) \
243  const DiffStepBuilder<Interpreter> _ID_ = diffTokenBuilder (&Interpreter::_ID_, STRINGIFY(_ID_));
244 
245 
246 
250  template<class I, typename E>
251  const typename DiffLanguage<I,E>::DiffStep DiffLanguage<I,E>::NIL = DiffStep(DiffVerb(), E());
252 
253 
254 
255 
256 
257 
258 
259 
260 
261  /* ==== Implementation Pattern for Diff Application ==== */
262 
277  template<class TAR, typename SEL =void>
279 
280 
292  template<class TAR>
295  {
297 
298  Interpreter target_;
299 
300  public:
301  explicit
302  DiffApplicator(TAR& targetStructure)
303  : target_(targetStructure)
304  { }
305 
306  template<class DIFF>
307  void
308  consume (DIFF&& diff)
309  {
310  target_.initDiffApplication();
311  for ( ; diff; ++diff )
312  diff->applyTo(target_);
313  target_.completeDiffApplication();
314  }
315  };
316 
317 
318 
319 }} // namespace lib::diff
320 #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:78
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:68
Any copy and copy construction prohibited.
Definition: nocopy.hpp:46
inline string literal This is a marker type to indicate that
Definition: symbol.hpp:85
#define LUMIERA_ERROR_DECLARE(err)
Forward declare an error constant.
Definition: error.h:71
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:113
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.