Lumiera 0.pre.04
»edit your freedom«
Loading...
Searching...
No Matches
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
88namespace lumiera {
89namespace error {
90 LUMIERA_ERROR_DECLARE(DIFF_STRUCTURE);
91 LUMIERA_ERROR_DECLARE(DIFF_CONFLICT);
92}}
93
94namespace lib {
95namespace 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 = 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>;
119 };
120
121 template<class I, typename E>
123 {
124 using Val = E;
125 using Interpreter = I;
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
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 {
192 using Val = Scheme::Val;
193
195 using Step = Lang::DiffStep;
196 using Verb = Lang::DiffVerb;
197
200
201 Step
202 operator() (Val elm) const
203 {
204 return { Verb(handler,id), elm };
205 }
206 };
207
208
216 template<class H>
217 inline DiffStepBuilder<typename InterpreterScheme<H>::Interpreter>
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 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
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*/
Inline string literal.
Definition symbol.hpp:78
generic builder to apply a diff description to a given target data structure.
DiffApplicationStrategy< TAR > Interpreter
DiffApplicator(TAR &targetStructure)
Any copy and copy construction prohibited.
Definition nocopy.hpp:38
#define LUMIERA_ERROR_DECLARE(err)
Forward declare an error constant.
Definition error.h:62
Lumiera error handling (C++ interface).
TreeDiffLanguage::DiffStep DiffStep
HandlerFun< I, Val > Handler
DiffStepBuilder< typename InterpreterScheme< H >::Interpreter > diffTokenBuilder(H handlerFun, Literal id)
set up a diff language token generator, based on the specific handler function given.
void(I::*)(E const &) HandlerFun
HandlerFun< Interpreter, Val > Handler
Extension point: define how a specific diff language can be applied to elements in a concrete contain...
< base case is to expect typedef I::Val
Implementation namespace for support and library code.
Action token implemented by double dispatch to a handler function, as defined in the "receiver" inter...
Lumiera public interface.
Definition advice.hpp:102
Mix-Ins to allow or prohibit various degrees of copying and cloning.
void applyTo(Interpreter &interpreter)
Definition frame for a language to describe differences in data structures.
VerbToken< I, void(E const &)> DiffVerb
std::tuple< DiffVerb, E > DiffToken
static const DiffStep NIL
fixed "invalid" marker token
generator to produce specific language tokens
InterpreterScheme< I > Scheme
DiffLanguage< I, Val > Lang
Step operator()(Val elm) const
CStr cStr(std::string const &rendered)
convenience shortcut: forced conversion to c-String via string.
Definition symbol.hpp:60
Tiny helper functions and shortcuts to be used everywhere Consider this header to be effectively incl...
Building blocks for a simple DSL using double dispatch to a handler function.