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) Lumiera.org
5  2010, 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 
65 #ifndef LIB_TIME_DIGXEL_H
66 #define LIB_TIME_DIGXEL_H
67 
68 #include "lib/error.hpp"
69 #include "lib/symbol.hpp"
70 #include "lib/util.hpp"
71 
72 #include <boost/operators.hpp>
73 #include <boost/lexical_cast.hpp>
74 #include <functional>
75 #include <string>
76 #include <cstdio>
77 #include <cmath>
78 
79 using std::string;
80 
81 
82 namespace lib {
83 namespace time {
84 
85  namespace digxel {
86 
87  using lib::Literal;
88  using boost::lexical_cast;
89 
90  using CBuf = CStr;
91 
92 
98  template<typename NUM, size_t len>
100  {
101  enum{ bufsiz = len+1 };
102 
103  char printbuffer_[bufsiz];
104  Literal formatSpec_;
105 
106  public:
108  : printbuffer_()
109  , formatSpec_(fmt)
110  {
111  clear();
112  }
113 
114  void clear() { printbuffer_[0] = '\0'; }
115  bool empty() { return '\0' == *printbuffer_; }
116 
117  size_t
118  maxlen() const
119  {
120  return len;
121  }
122 
123  CBuf
124  show (NUM val)
125  {
126  if (empty())
127  {
128  size_t space = std::snprintf (printbuffer_, bufsiz, formatSpec_, val);
129  REQUIRE (space < bufsiz, "Digxel value exceeded available buffer size. "
130  "For showing %s, %zu+1 chars instead of just %zu+1 would be required."
131  , cStr(lexical_cast<string>(val)), space, len);
132  }
133  ENSURE (!empty());
134  return printbuffer_;
135  }
136  };
137 
138 
143  template<typename NUM>
144  struct Formatter;
145 
146  template<>
147  struct Formatter<int>
148  : PrintfFormatter<int, 9>
149  {
150  Formatter() : PrintfFormatter<int,9>("%3d") { }
151  };
152 
153  template<>
154  struct Formatter<double>
155  : PrintfFormatter<double, 7>
156  {
157  Formatter() : PrintfFormatter<double,7>("%06.3f") { }
158  };
159 
160  /* == other specialised Formatters == */
162  : PrintfFormatter<int, 4>
163  {
164  SexaFormatter() : PrintfFormatter<int,4>("%02d") { }
165  };
166 
168  : PrintfFormatter<uint, 2>
169  {
170  HexaFormatter() : PrintfFormatter<uint,2>("%02X") { }
171  };
172 
174  : PrintfFormatter<long, 20>
175  {
177  };
178 
180  : PrintfFormatter<int, 9>
181  {
183  };
184 
185 
187  {
188  void clear() { }
189  size_t maxlen() const { return 1; }
190  CBuf show (int val) { return val<0? "-":" "; }
191  };
192 
193  } //(End) digxel configuration namespace
194 
195 
196 
197 
198 
199  using std::bind;
200  using std::function;
201  using std::placeholders::_1;
202 
203 
223  template< typename NUM
224  , class FMT = digxel::Formatter<NUM>
225  >
226  class Digxel
227  : public boost::totally_ordered<Digxel<NUM,FMT>>
228  {
229  mutable
230  FMT buffer_;
231  NUM value_;
232 
233  typedef Digxel<NUM,FMT> _Digxel;
234  typedef function<void(NUM)> _Mutator;
235 
236 
237  _Mutator mutator;
238 
239  public:
250  template<typename FUN, class THIS>
251  void
252  installMutator (FUN mutate, THIS& self)
253  {
254  mutator = bind (mutate, &self, _1 );
255  }
256 
257 
258  Digxel ()
259  : buffer_()
260  , value_ ()
261  , mutator()
262  { }
263 
264  // using the standard copy operations
265 
266  operator NUM() const { return value_; }
267  operator string() const { return show(); }
268 
269  size_t maxlen() const { return buffer_.maxlen(); }
270 
271 
272  digxel::CBuf
273  show() const
274  {
275  return buffer_.show (value_);
276  }
277 
278 
279  void
280  operator= (NUM n)
281  {
282  if (n == value_) return;
283  if (mutator)
284  mutator (n);
285  else
286  setValueRaw (n);
287  }
288 
289  void
290  setValueRaw (NUM newVal)
291  {
292  if (newVal != value_)
293  {
294  value_ = newVal;
295  buffer_.clear();
296  }
297  }
298 
299 
300 
301  //---Supporting-increments--------------
302  Digxel& operator+= (NUM inc) { *this = value_ + inc; return *this; }
303  Digxel& operator-= (NUM dec) { *this = value_ - dec; return *this; }
304  Digxel& operator++ () { *this = value_ + 1; return *this; }
305  Digxel& operator-- () { *this = value_ - 1; return *this; }
306  NUM operator++ (int) { NUM p(value_); *this =p+1; return p;}
307  NUM operator-- (int) { NUM p(value_); *this =p-1; return p;}
308 
309  //---Supporting-totally_ordered---------
310  bool operator< (Digxel const& o) const { return value_ < NUM(o); }
311  bool operator== (Digxel const& o) const { return value_ == NUM(o); }
312  };
313 
314 
315 
316  /* == predefined Digxel configurations == */
320 
321  typedef int64_t FrameCnt;
323 
324 
327  class Signum
328  : public Digxel<int,digxel::SignFormatter>
329  {
331 
332  void
333  storeSign (int val)
334  {
335  setValueRaw (val<0? -1:+1);
336  }
337 
338  public:
339  Signum()
340  {
341  setValueRaw(1);
342  installMutator (&Signum::storeSign, *this);
343  }
344 
345  using _Par::operator=;
346 
347  friend int operator*= (Signum& s, int c) { s = c*s; return s; }
348  };
349 
350 
351 }} // lib::time
352 #endif
CStr cStr(std::string const &rendered)
convenience shortcut: forced conversion to c-String via string.
Definition: symbol.hpp:68
void installMutator(FUN mutate, THIS &self)
install an external functor to be applied on any new digxel value.
Definition: digxel.hpp:252
inline string literal This is a marker type to indicate that
Definition: symbol.hpp:85
bool operator==(PtrDerefIter< I1 > const &il, PtrDerefIter< I2 > const &ir)
Supporting equality comparisons...
Default / base implementation for Digxel formatting.
Definition: digxel.hpp:99
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:237
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:226
Lumiera error handling (C++ interface).
special Digxel to show a sign.
Definition: digxel.hpp:327
int64_t FrameCnt
relative framecount or frame number.
Definition: digxel.hpp:321
default configured Formatter implementations for some of the basic numeric types
Definition: digxel.hpp:144