Lumiera  0.pre.03
»edit your freedom«
gen-node.cpp
Go to the documentation of this file.
1 /*
2  GenNode - generic node element for tree like data representation
3 
4  Copyright (C)
5  2015, 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 
35 #include "lib/error.hpp"
37 #include "lib/diff/gen-node.hpp"
38 #include "lib/util-quant.hpp"
39 #include "lib/variant.hpp"
40 
41 #include <boost/lexical_cast.hpp>
42 
43 
44 using util::join;
45 using boost::lexical_cast;
48 using util::almostEqual;
49 using lib::hash::LuidH;
50 
51 
52 namespace lib {
53 namespace diff{
54 
55  /* symbolic marker ID references
56  * used within the tree diff language
57  * to mark specific scopes and situations
58  */
59  const Ref Ref::I ("_I_");
60  const Ref Ref::NO ("_NO_");
61  const Ref Ref::END ("_END_");
62  const Ref Ref::THIS ("_THIS_");
63  const Ref Ref::CHILD ("_CHILD_");
64  const Ref Ref::ATTRIBS("_ATTRIBS_");
65 
66 
67 
68 
77  bool
78  DataCap::matchData (DataCap const& o) const
79  {
80  class EqualityTest
81  : public Variant<DataValues>::Predicate
82  {
83  DataCap const& o_;
84 
85 #define DERIVE_EQUALITY(_TY_) \
86  virtual bool handle (_TY_ const& val) override { return (o_.get<_TY_>() == val); }
87 
88  DERIVE_EQUALITY (int)
89  DERIVE_EQUALITY (int64_t)
90  DERIVE_EQUALITY (short)
91  DERIVE_EQUALITY (char)
92  DERIVE_EQUALITY (bool)
93  DERIVE_EQUALITY (double)
94  DERIVE_EQUALITY (string)
95  DERIVE_EQUALITY (time::Time)
96  DERIVE_EQUALITY (time::Offset)
97  DERIVE_EQUALITY (time::Duration)
98  DERIVE_EQUALITY (time::TimeSpan)
99  DERIVE_EQUALITY (hash::LuidH)
100  DERIVE_EQUALITY (Rec)
101 
102 
104  virtual bool
105  handle (RecRef const& val) override
106  {
107  return o_.matchRec(val);
108  }
109 
110  public:
111  EqualityTest(DataCap const& o)
112  : o_(o)
113  { }
114  };
115 
116  EqualityTest visitor(o);
117  return accept(visitor);
118  }
119 
120 
121  bool
122  DataCap::matchNum (int64_t num) const
123  {
124  class MatchNumber
125  : public Variant<DataValues>::Predicate
126  {
127  int64_t num_;
128 
129 #define MATCH_NUMBER(_TY_) \
130  virtual bool handle (_TY_ const& val) override { return val == num_; }
131 
132  MATCH_NUMBER (int)
133  MATCH_NUMBER (int64_t)
134  MATCH_NUMBER (short)
135  MATCH_NUMBER (char)
136  MATCH_NUMBER (double)
137 
138  public:
139  MatchNumber(int64_t num)
140  : num_(num)
141  { }
142  };
143 
144  MatchNumber visitor(num);
145  return accept(visitor);
146  }
147 
148 
149  bool
150  DataCap::matchDbl (double d) const
151  {
152  class MatchDouble
153  : public Variant<DataValues>::Predicate
154  {
155  double num_;
156 
157 #define MATCH_DOUBLE(_TY_) \
158  virtual bool handle (_TY_ const& val) override { return almostEqual (double(val), num_); }
159 
160  MATCH_DOUBLE (int)
161  MATCH_DOUBLE (int64_t)
162  MATCH_DOUBLE (short)
163  MATCH_DOUBLE (char)
164  MATCH_DOUBLE (double)
165 
166  public:
167  MatchDouble(double d)
168  : num_(d)
169  { }
170  };
171 
172  MatchDouble visitor(d);
173  return accept(visitor);
174  }
175 
176 
177  bool
178  DataCap::matchTxt (string const& text) const
179  {
180  class MatchString
181  : public Variant<DataValues>::Predicate
182  {
183  string const& txt_;
184 
185 #define MATCH_STRING(_TY_) \
186  virtual bool handle (_TY_ const& val) override { return lexical_cast<string>(val) == txt_; }
187 
188  MATCH_STRING (int)
189  MATCH_STRING (int64_t)
190  MATCH_STRING (short)
191  MATCH_STRING (double)
192  MATCH_STRING (bool)
193 
194  virtual bool handle (string const& str) override { return str == txt_; }
195  virtual bool handle (char const& c ) override { return 1 == txt_.length() && txt_.front() == c; }
196 
197  public:
198  MatchString(string const& text)
199  : txt_(text)
200  { }
201  };
202 
203  MatchString visitor(text);
204  return accept(visitor);
205  }
206 
207 
208  bool
209  DataCap::matchTime (TimeValue time) const
210  {
211  class MatchTime
212  : public Variant<DataValues>::Predicate
213  {
214  TimeValue& t_;
215 
216 #define MATCH_TIME(_TY_) \
217  virtual bool handle (_TY_ const& val) override { return val == t_; }
218 
219  MATCH_TIME (time::Time)
220  MATCH_TIME (time::Offset)
221  MATCH_TIME (time::Duration)
222  MATCH_TIME (time::TimeSpan)
223  MATCH_TIME (hash::LuidH)
224 
225  public:
226  MatchTime(TimeValue& t)
227  : t_(t)
228  { }
229  };
230 
231  MatchTime visitor(time);
232  return accept(visitor);
233  }
234 
235 
236  bool
237  DataCap::matchBool (bool b) const
238  {
239  bool* val = unConst(this)->maybeGet<bool>();
240  return val && (b == *val);
241  }
242 
243 
244  bool
245  DataCap::matchLuid (LuidH hash) const
246  {
247  LuidH* val = unConst(this)->maybeGet<LuidH>();
248  return val && (hash == *val);
249  }
250 
251 
252  bool
253  DataCap::matchRec (RecRef const& ref) const
254  {
255  if (ref)
256  return matchRec (*ref.get());
257  else
258  {
259  RecRef* val = unConst(this)->maybeGet<RecRef>();
260  return val && val->empty();
261  }
262  }
263 
264 
265  bool
266  DataCap::matchRec (Rec const& rec) const
267  {
268  Rec* val = unConst(this)->maybeGet<Rec>();
269  if (!val)
270  {
271  RecRef* r = unConst(this)->maybeGet<RecRef>();
272  if (r) val = r->get();
273  }
274  return val && (rec == *val);
275  }
276 
277 
278 
279 
280  DataCap::operator string() const
281  {
282  return "DataCap|"+string(this->buffer());
283  }
284 
285 
286 
287 
288 
290  string renderCompact (Rec const& rec)
291  {
292  auto renderChild = [](diff::GenNode const& n){ return renderCompact(n); };
293  auto renderAttrib = [](diff::GenNode const& n){
294  return (n.isNamed()? n.idi.getSym()+"=" : "")
295  + renderCompact(n);
296  };
297 
298  return (Rec::TYPE_NIL==rec.getType()? "" : rec.getType())
299  + "{"
300  + join (transformIterator (rec.attribs(), renderAttrib))
301  + (isnil(rec.scope())? "" : "|")
302  + join (transformIterator (rec.scope() , renderChild))
303  + "}"
304  ;
305  }
306 
307  string
308  renderCompact (RecRef const& ref)
309  {
310  return "Ref->" + (ref.empty()? util::BOTTOM_INDICATOR
311  : renderCompact (*ref.get()));
312  }
313 
320  string
321  renderCompact (GenNode const& node)
322  {
323  class Renderer
324  : public Variant<diff::DataValues>::Renderer
325  {
326  #define RENDER_CONTENT(_TY_) \
327  virtual string handle (_TY_ const& val) override { return util::toString(val); }
328 
329  RENDER_CONTENT (int)
330  RENDER_CONTENT (int64_t)
331  RENDER_CONTENT (short)
332  RENDER_CONTENT (char)
333  RENDER_CONTENT (double)
334  RENDER_CONTENT (bool)
335  RENDER_CONTENT (time::Time)
336  RENDER_CONTENT (time::Offset)
337  RENDER_CONTENT (time::Duration)
338  RENDER_CONTENT (time::TimeSpan)
339  #undef RENDER_CONTENT
340 
341  virtual string handle (string const& val) override { return val; }
342  virtual string handle (LuidH const& val) override { return util::showHash(val, 2);}
343  virtual string handle (RecRef const& ref) override { return renderCompact(ref); }
344  virtual string handle (Rec const& rec) override { return renderCompact(rec); }
345  };
346 
347  Renderer visitor;
348  return node.data.accept (visitor);
349  }
350 
351 
352 }} // namespace lib::diff
static const Ref I
symbolic ID ref "_I_"
Definition: gen-node.hpp:860
Fundamental definitions for a representation of changes.
Typesafe union record.
Definition: variant.hpp:215
static const Ref CHILD
symbolic ID ref "_CHILD_"
Definition: gen-node.hpp:864
string renderCompact(Rec const &rec)
compact textual representation of a Record<GenNode> (»object«).
Definition: gen-node.cpp:290
Implementation namespace for support and library code.
Lumiera&#39;s internal time value datatype.
Definition: timevalue.hpp:299
static const Ref END
symbolic ID ref "_END_"
Definition: gen-node.hpp:862
bool matchData(DataCap const &) const
Implementation of content equality test, delgating to content.
Definition: gen-node.cpp:78
A typesafe union record to carry embedded values of unrelated type.
wrapped record reference.
Definition: record.hpp:612
Utilities for quantisation (grid alignment) and comparisons.
Generic building block for tree shaped (meta)data structures.
static const Ref NO
symbolic ID ref "_NO_"
Definition: gen-node.hpp:861
Lumiera error handling (C++ interface).
Hash implementation based on a lumiera unique object id (LUID) When invoking the default ctor...
static const Ref ATTRIBS
symbolic ID ref "_ATTRIBS_"
Definition: gen-node.hpp:865
Offset measures a distance in time.
Definition: timevalue.hpp:358
Duration is the internal Lumiera time metric.
Definition: timevalue.hpp:468
bool almostEqual(double d1, double d2, unsigned int ulp=2)
epsilon comparison of doubles.
Definition: util-quant.hpp:150
A time interval anchored at a specific point in time.
Definition: timevalue.hpp:573
auto transformIterator(IT const &src, FUN processingFunc)
Build a TransformIter: convenience free function shortcut, picking up the involved types automaticall...
Definition: itertools.hpp:788
object-like record of data.
Definition: record.hpp:141
static const Ref THIS
symbolic ID ref "_THIS_"
Definition: gen-node.hpp:863
basic constant internal time value.
Definition: timevalue.hpp:133
generic data element node within a tree
Definition: gen-node.hpp:222