Lumiera  0.pre.03
»edit your freedom«
digxel.hpp
Go to the documentation of this file.
1 /*
2  DIGXEL.hpp - grid aligned and fixed format time specifications
3 
4  Copyright (C)
5  2010, 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 
56 #ifndef LIB_TIME_DIGXEL_H
57 #define LIB_TIME_DIGXEL_H
58 
59 #include "lib/error.hpp"
60 #include "lib/symbol.hpp"
61 #include "lib/util.hpp"
62 
63 #include <boost/operators.hpp>
64 #include <boost/lexical_cast.hpp>
65 #include <functional>
66 #include <string>
67 #include <cstdio>
68 #include <cmath>
69 
70 using std::string;
71 
72 
73 namespace lib {
74 namespace time {
75 
76  namespace digxel {
77 
78  using lib::Literal;
79  using boost::lexical_cast;
80 
81  using CBuf = CStr;
82 
83 
89  template<typename NUM, size_t len>
91  {
92  enum{ bufsiz = len+1 };
93 
94  char printbuffer_[bufsiz];
95  Literal formatSpec_;
96 
97  public:
99  : printbuffer_()
100  , formatSpec_(fmt)
101  {
102  clear();
103  }
104 
105  void clear() { printbuffer_[0] = '\0'; }
106  bool empty() { return '\0' == *printbuffer_; }
107 
108  size_t
109  maxlen() const
110  {
111  return len;
112  }
113 
114  CBuf
115  show (NUM val)
116  {
117  if (empty())
118  {
119  size_t space = std::snprintf (printbuffer_, bufsiz, formatSpec_, val);
120  REQUIRE (space < bufsiz, "Digxel value exceeded available buffer size. "
121  "For showing %s, %zu+1 chars instead of just %zu+1 would be required."
122  , cStr(lexical_cast<string>(val)), space, len);
123  }
124  ENSURE (!empty());
125  return printbuffer_;
126  }
127  };
128 
129 
134  template<typename NUM>
135  struct Formatter;
136 
137  template<>
138  struct Formatter<int>
139  : PrintfFormatter<int, 9>
140  {
141  Formatter() : PrintfFormatter<int,9>("%3d") { }
142  };
143 
144  template<>
145  struct Formatter<double>
146  : PrintfFormatter<double, 7>
147  {
148  Formatter() : PrintfFormatter<double,7>("%06.3f") { }
149  };
150 
151  /* == other specialised Formatters == */
153  : PrintfFormatter<int, 4>
154  {
155  SexaFormatter() : PrintfFormatter<int,4>("%02d") { }
156  };
157 
159  : PrintfFormatter<uint, 2>
160  {
161  HexaFormatter() : PrintfFormatter<uint,2>("%02X") { }
162  };
163 
165  : PrintfFormatter<long, 20>
166  {
168  };
169 
171  : PrintfFormatter<int, 9>
172  {
174  };
175 
176 
178  {
179  void clear() { }
180  size_t maxlen() const { return 1; }
181  CBuf show (int val) { return val<0? "-":" "; }
182  };
183 
184  } //(End) digxel configuration namespace
185 
186 
187 
188 
189 
190  using std::bind;
191  using std::function;
192  using std::placeholders::_1;
193 
194 
214  template< typename NUM
215  , class FMT = digxel::Formatter<NUM>
216  >
217  class Digxel
218  : public boost::totally_ordered<Digxel<NUM,FMT>>
219  {
220  mutable
221  FMT buffer_;
222  NUM value_;
223 
224  typedef Digxel<NUM,FMT> _Digxel;
225  typedef function<void(NUM)> _Mutator;
226 
227 
228  _Mutator mutator;
229 
230  public:
241  template<typename FUN, class THIS>
242  void
243  installMutator (FUN mutate, THIS& self)
244  {
245  mutator = bind (mutate, &self, _1 );
246  }
247 
248 
249  Digxel ()
250  : buffer_()
251  , value_ ()
252  , mutator()
253  { }
254 
255  // using the standard copy operations
256 
257  operator NUM() const { return value_; }
258  operator string() const { return show(); }
259 
260  size_t maxlen() const { return buffer_.maxlen(); }
261 
262 
263  digxel::CBuf
264  show() const
265  {
266  return buffer_.show (value_);
267  }
268 
269 
270  void
271  operator= (NUM n)
272  {
273  if (n == value_) return;
274  if (mutator)
275  mutator (n);
276  else
277  setValueRaw (n);
278  }
279 
280  void
281  setValueRaw (NUM newVal)
282  {
283  if (newVal != value_)
284  {
285  value_ = newVal;
286  buffer_.clear();
287  }
288  }
289 
290 
291 
292  //---Supporting-increments--------------
293  Digxel& operator+= (NUM inc) { *this = value_ + inc; return *this; }
294  Digxel& operator-= (NUM dec) { *this = value_ - dec; return *this; }
295  Digxel& operator++ () { *this = value_ + 1; return *this; }
296  Digxel& operator-- () { *this = value_ - 1; return *this; }
297  NUM operator++ (int) { NUM p(value_); *this =p+1; return p;}
298  NUM operator-- (int) { NUM p(value_); *this =p-1; return p;}
299 
300  //---Supporting-totally_ordered---------
301  bool operator< (Digxel const& o) const { return value_ < NUM(o); }
302  bool operator== (Digxel const& o) const { return value_ == NUM(o); }
303  };
304 
305 
306 
307  /* == predefined Digxel configurations == */
311 
312  typedef int64_t FrameCnt;
314 
315 
318  class Signum
319  : public Digxel<int,digxel::SignFormatter>
320  {
322 
323  void
324  storeSign (int val)
325  {
326  setValueRaw (val<0? -1:+1);
327  }
328 
329  public:
330  Signum()
331  {
332  setValueRaw(1);
333  installMutator (&Signum::storeSign, *this);
334  }
335 
336  using _Par::operator=;
337 
338  friend int operator*= (Signum& s, int c) { s = c*s; return s; }
339  };
340 
341 
342 }} // lib::time
343 #endif
CStr cStr(std::string const &rendered)
convenience shortcut: forced conversion to c-String via string.
Definition: symbol.hpp:59
void installMutator(FUN mutate, THIS &self)
install an external functor to be applied on any new digxel value.
Definition: digxel.hpp:243
inline string literal This is a marker type to indicate that
Definition: symbol.hpp:76
bool operator==(PtrDerefIter< I1 > const &il, PtrDerefIter< I2 > const &ir)
Supporting equality comparisons...
Default / base implementation for Digxel formatting.
Definition: digxel.hpp:90
Implementation namespace for support and library code.
Marker types to indicate a literal string and a Symbol.
_Mutator mutator
Functor for setting a new digxel value.
Definition: digxel.hpp:228
Tiny helper functions and shortcuts to be used everywhere Consider this header to be effectively incl...
A number element for building structured numeric displays.
Definition: digxel.hpp:217
Lumiera error handling (C++ interface).
special Digxel to show a sign.
Definition: digxel.hpp:318
int64_t FrameCnt
relative framecount or frame number.
Definition: digxel.hpp:312
default configured Formatter implementations for some of the basic numeric types
Definition: digxel.hpp:135