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