MIRA
TimeHumanReadable.h
Go to the documentation of this file.
1 /*
2  * Copyright (C) by
3  * MetraLabs GmbH (MLAB), GERMANY
4  * and
5  * Neuroinformatics and Cognitive Robotics Labs (NICR) at TU Ilmenau, GERMANY
6  * All rights reserved.
7  *
8  * Contact: info@mira-project.org
9  *
10  * Commercial Usage:
11  * Licensees holding valid commercial licenses may use this file in
12  * accordance with the commercial license agreement provided with the
13  * software or, alternatively, in accordance with the terms contained in
14  * a written agreement between you and MLAB or NICR.
15  *
16  * GNU General Public License Usage:
17  * Alternatively, this file may be used under the terms of the GNU
18  * General Public License version 3.0 as published by the Free Software
19  * Foundation and appearing in the file LICENSE.GPL3 included in the
20  * packaging of this file. Please review the following information to
21  * ensure the GNU General Public License version 3.0 requirements will be
22  * met: http://www.gnu.org/copyleft/gpl.html.
23  * Alternatively you may (at your option) use any later version of the GNU
24  * General Public License if such license has been publicly approved by
25  * MLAB and NICR (or its successors, if any).
26  *
27  * IN NO EVENT SHALL "MLAB" OR "NICR" BE LIABLE TO ANY PARTY FOR DIRECT,
28  * INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT OF
29  * THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF "MLAB" OR
30  * "NICR" HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31  *
32  * "MLAB" AND "NICR" SPECIFICALLY DISCLAIM ANY WARRANTIES, INCLUDING,
33  * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
34  * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
35  * ON AN "AS IS" BASIS, AND "MLAB" AND "NICR" HAVE NO OBLIGATION TO
36  * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS OR MODIFICATIONS.
37  */
38 
47 #ifndef _MIRA_TIMEHUMANREADABLE_H_
48 #define _MIRA_TIMEHUMANREADABLE_H_
49 
50 #include <utils/Time.h>
51 #include <error/Exceptions.h>
52 
54 #include <serialization/Accessor.h>
56 
57 #include <utils/IsCheapToCopy.h>
58 
59 namespace mira {
60 
62 
84 namespace HumanReadableSerialization {
85 
91 template<bool AsString = true>
92 class Date : public mira::Date {
93 public:
94  typedef mira::Date Base;
95 public:
96 #if !defined(DATE_TIME_NO_DEFAULT_CONSTRUCTOR)
97  Date() {}
98 #endif
99  Date(const Base& date) : Base(date) {}
100  using mira::Date::Date; // inherit all constructors
101 };
102 
103 } // namespace HumanReadableSerialization
104 
106 
109 
112 
114 
115 template <>
116 class IsCheapToCopy<DateSerializedAsIsoString> : public std::true_type {};
117 
118 template <>
119 class IsCheapToCopy<DateSerializedAsYMD> : public std::true_type {};
120 
122 
125 
126 template<typename Reflector>
127 void reflectRead(Reflector& r, DateSerializedAsIsoString& date)
128 {
129  std::string s = to_iso_extended_string(date);
130  r.delegate(s);
131 }
132 
133 template<typename Reflector>
134 void reflectRead(Reflector& r, DateSerializedAsYMD& date)
135 {
136  DateSerializedAsYMD::ymd_type ymd = date.year_month_day();
137  int y = ymd.year;
138  int m = ymd.month;
139  int d = ymd.day;
140  r.member("Year", y, "year");
141  r.member("Month", m, "month");
142  r.member("Day", d, "day");
143 
144  r.roproperty("Weekday", boost::lexical_cast<std::string>(date.day_of_week()),
145  "Day of week");
146 }
147 
148 template<typename Reflector>
149 void reflectWrite(Reflector& r, DateSerializedAsIsoString& date)
150 {
151  std::string s;
152  r.delegate(s);
153  date = boost::gregorian::from_string(s);
154 }
155 
156 template<typename Reflector>
157 void reflectWrite(Reflector& r, DateSerializedAsYMD& date)
158 {
159  int y, m, d;
160  r.member("Year", y, "");
161  r.member("Month", m, "");
162  r.member("Day", d, "");
163 
164  date = DateSerializedAsYMD::Base(y, m, d);
165 }
166 
167 void reflect(PropertySerializer& r, DateSerializedAsYMD& date);
168 
170 
171 namespace HumanReadableSerialization {
172 
178 template<bool AsString = true>
179 class Duration : public mira::Duration {
180 public:
182 #if !defined(DATE_TIME_NO_DEFAULT_CONSTRUCTOR)
183  Duration() {}
184 #endif
185  Duration(const Base& date) : Base(date) {}
186  using mira::Duration::Duration; // inherit all constructors
187 
189 
190  template<typename Reflector>
191  void reflectRead(Reflector& r)
192  {
193  if constexpr (AsString) {
194  std::string s = to_simple_string(*this);
195  r.delegate(s);
196  }
197  else {
198  int h = hours();
199  int m = minutes();
200  int s = seconds();
201  int us = milliseconds() * 1000ll + microseconds();
202  r.member("Hours", h, "Hours 0..23");
203  r.member("Minutes", m, "Minutes 0..59");
204  r.member("Seconds", s, "Seconds 0..59");
205  r.member("MicroSeconds", us, "Microseconds 0..999999 (optional, default=0)");
206  }
207  }
208 
209  template<typename Reflector>
210  void reflectWrite(Reflector& r)
211  {
212  if constexpr (AsString) {
213  std::string s;
214  r.delegate(s);
215  if (s.find(':') == std::string::npos) {
216  MIRA_THROW(XIO, "DurationSerializedAsIsoString: Duration string for deserialization "
217  "expects format 'hh:mm[:ss[.frac]]'");
218  }
219  *this = Base(boost::posix_time::duration_from_string(s));
220  } else {
221  int64 h, m, s, us;
222  r.member("Hours", h, "Hours 0..23");
223  r.member("Minutes", m, "Minutes 0..59");
224  r.member("Seconds", s, "Seconds 0..59");
225  r.member("MicroSeconds", us, "Microseconds 0..999999 (optional, default=0)", 0);
226 
227  *this = Base(h, m, s, us);
228  }
229  }
230 
232  {
233  if constexpr (AsString) {
234  reflectRead(r);
235  }
236  else {
237  r.property("Positive",
238  getter<bool>([this]{ return !is_negative(); }),
239  setter<bool>([this](bool p){ if (p == is_negative()) *this = invert_sign(); }),
240  "Is positive?");
241  r.property("Hours",
242  getter<int>([this]{ return std::abs(hours()); }),
243  setter<int>([this](int h){
244  int hs = (is_negative() ? -h : h);
245  *this = Base(hs, minutes(), seconds(),
246  milliseconds()*1000ll + microseconds());
247  }),
248  "Hours", PropertyHints::minimum(0));
249  r.property("Minutes",
250  getter<int>([this]{ return std::abs(minutes()); }),
251  setter<int>([this](int m){
252  int ms = (is_negative() ? -m : m);
253  *this = Base(hours(), ms, seconds(),
254  milliseconds()*1000ll + microseconds());
255  }),
256  "Minutes", PropertyHints::limits(0, 59));
257  r.property("Seconds",
258  getter<int>([this]{ return std::abs(seconds()); }),
259  setter<int>([this](int s){
260  int ss = (is_negative() ? -s : s);
261  *this = Base(hours(), minutes(), ss,
262  milliseconds()*1000ll + microseconds());
263  }),
264  "Seconds", PropertyHints::limits(0, 59));
265  r.property("Microseconds",
266  getter<int>([this]{ return std::abs(milliseconds()) * 1000ll
267  + std::abs(microseconds()); }),
268  setter<int>([this](int us){
269  int uss = (is_negative() ? -us : us);
270  *this = Base(hours(), minutes(), seconds(), uss);
271  }),
272  "Microseconds", PropertyHints::limits(0ll, 999999ll));
273  }
274  }
275 };
276 
277 } // namespace HumanReadableSerialization
278 
280 
283 
286 
288 
289 template <>
290 class IsCheapToCopy<DurationSerializedAsIsoString> : public std::true_type {};
291 
292 template <>
293 class IsCheapToCopy<DurationSerializedAsHMS> : public std::true_type {};
294 
296 
297 namespace HumanReadableSerialization {
298 
304 template<bool AsString = true>
305 class Time : public mira::Time {
306 public:
307  typedef mira::Time Base;
308 #if !defined(DATE_TIME_NO_DEFAULT_CONSTRUCTOR)
309  Time() {}
310 #endif
311  Time(const Base& date) : Base(date) {}
312  using mira::Time::Time; // inherit all constructors
313 
315 
316  template<typename Reflector>
317  void reflectRead(Reflector& r)
318  {
319  if constexpr (AsString) {
320  std::string s = to_iso_extended_string(*this);
321  r.delegate(s);
322  } else {
323  DateSerializedAsYMD dateHR(date());
324  mira::reflectRead(r, dateHR);
325  DurationSerializedAsHMS(time_of_day()).reflectRead(r);
326  }
327  }
328 
329  template<typename Reflector>
330  void reflectWrite(Reflector& r)
331  {
332  if constexpr (AsString) {
333  std::string s;
334  r.delegate(s);
335  if (s.find('T') == std::string::npos) {
336  MIRA_THROW(XIO, "TimeSerializedAsIsoString: Time string for deserialization "
337  "expects format 'yyyy-mm-ddThh:mm:ss[.frac]'");
338  }
339 #if BOOST_VERSION >= 107300
340  *this = Base(boost::posix_time::from_iso_extended_string(s));
341 #else
342  *this = Base(boost::date_time::parse_delimited_time<Base>(s, 'T'));
343 #endif
344  } else {
345  DateSerializedAsYMD date;
346  mira::reflectWrite(r, date);
347 
348  DurationSerializedAsHMS timeOfDay;
349  timeOfDay.reflectWrite(r);
350 
351  *this = Base(date, timeOfDay);
352  }
353  }
354 
356  {
357  if constexpr (AsString) {
358  reflectRead(r);
359  }
360  else {
361  using mira::Date;
362  using mira::Duration;
363 
364  r.property("Year",
365  getter<int>([this]{ return date().year();}),
366  setter<int>([this](int y){
367  auto d = date();
368  *this = Base(Date(y, d.month(), d.day()),
369  time_of_day());
370  }),
371  "Year");
372  r.property("Month",
373  getter<int>([this]{ return date().month();}),
374  setter<int>([this](int m){
375  auto d = date();
376  *this = Base(Date(d.year(), m, d.day()),
377  time_of_day());
378  }),
379  "Month", PropertyHints::limits(1, 12));
380  r.property("Day",
381  getter<int>([this]{ return date().day();}),
382  setter<int>([this](int dy){
383  auto d = date();
384  *this = Base(Date(d.year(), d.month(), dy),
385  time_of_day());
386  }),
387  "Day", PropertyHints::limits(1, 31));
388  r.roproperty("Weekday",
389  getter<std::string>([this]{
390  return boost::lexical_cast<std::string>(date().day_of_week());
391  }),
392  "Day of week");
393  r.property("Hours",
394  getter<int>([this]{ return time_of_day().hours(); }),
395  setter<int>([this](int h){
396  auto t = time_of_day();
397  *this = Base(date(), Duration(h, t.minutes(), t.seconds(),
398  t.total_microseconds() % 1000000ll));
399  }),
400  "Hours", PropertyHints::limits(0, 23));
401  r.property("Minutes",
402  getter<int>([this]{ return time_of_day().minutes(); }),
403  setter<int>([this](int m){
404  auto t = time_of_day();
405  *this = Base(date(), Duration(t.hours(), m, t.seconds(),
406  t.total_microseconds() % 1000000ll));
407  }),
408  "Minutes", PropertyHints::limits(0, 59));
409  r.property("Seconds",
410  getter<int>([this]{ return time_of_day().seconds(); }),
411  setter<int>([this](int s){
412  auto t = time_of_day();
413  *this = Base(date(), Duration(t.hours(), t.minutes(), s,
414  t.total_microseconds() % 1000000ll));
415  }),
416  "Seconds", PropertyHints::limits(0, 59));
417  r.property("Microseconds",
418  getter<int>([this]{ return time_of_day().total_microseconds() % 1000000ll; }),
419  setter<int>([this](int us){
420  auto t = time_of_day();
421  *this = Base(date(), Duration(t.hours(), t.minutes(), t.seconds(), us));
422  }),
423  "Microseconds", PropertyHints::limits(0ll, 999999ll));
424  }
425  }
426 };
427 
428 } // namespace HumanReadableSerialization
429 
431 
441 
444 
446 
447 template<typename SerializerTag>
448 class IsTransparentSerializable<DateSerializedAsIsoString, SerializerTag> : public std::true_type {};
449 
450 template<typename SerializerTag>
451 class IsTransparentSerializable<DurationSerializedAsIsoString, SerializerTag> : public std::true_type {};
452 
453 template<typename SerializerTag>
454 class IsTransparentSerializable<TimeSerializedAsIsoString ,SerializerTag> : public std::true_type {};
455 
457 
458 template <>
459 class IsCheapToCopy<TimeSerializedAsIsoString> : public std::true_type {};
460 
461 template <>
462 class IsCheapToCopy<TimeSerializedAsYMDHMS> : public std::true_type {};
463 
465 
471 
494 
497 
501 
504 
507 
511 
514 
517 
521 
524 
527 
531 
534 
537 
541 
544 
547 
551 
553 
554 }
555 
556 #endif
MIRA_SPLIT_REFLECT_MEMBER void reflectRead(Reflector &r)
Definition: TimeHumanReadable.h:191
void reflectWrite(Reflector &r)
Definition: TimeHumanReadable.h:210
void reflectWrite(Reflector &r, Buffer< T, Allocator > &c)
Specialization of the non-intrusive reflect for Buffer.
Definition: Buffer.h:581
Type trait that indicates whether a type should be serialized "transparently", i.e.
Definition: IsTransparentSerializable.h:81
tick_type milliseconds() const
Returns normalized number of milliseconds (0..999)
Definition: Time.h:285
#define MIRA_SPLIT_REFLECT(Type)
Macro that inserts a reflect() method consisting of just a call to splitReflect() (splitting to refle...
Definition: SplitReflect.h:150
specialize cv::DataType for our ImgPixel and inherit from cv::DataType<Vec>
Definition: IOService.h:67
Duration()
Default constructor constructs to Duration of 0 length.
Definition: Time.h:206
#define MIRA_SPLIT_REFLECT_MEMBER
Macro that insert a class member reflect() method just splitting reflection into a reflectRead() and ...
Definition: SplitReflect.h:209
Time and Duration wrapper class.
Holds a boost::function object to a special setter function that must meet the signature "void method...
Definition: GetterSetter.h:395
mira::Date Base
Definition: TimeHumanReadable.h:94
Contains internal accessor class that abstracts from the underlying getter and setter classes or dire...
void reflect(PropertySerializer &r)
Definition: TimeHumanReadable.h:355
#define MIRA_THROW(ex, msg)
Macro for throwing an exception.
Definition: Exception.h:82
Derivation of mira::Date with human-readable serialization.
Definition: TimeHumanReadable.h:92
boost::posix_time::ptime Base
Definition: Time.h:422
Wrapper class for boost::posix_time::ptime for adding more functionality to it.
Definition: Time.h:418
MIRA_SPLIT_REFLECT_MEMBER void reflectRead(Reflector &r)
Definition: TimeHumanReadable.h:317
Flags controlling reflector behaviour.
Derivation of mira::Duration with human-readable serialization.
Definition: TimeHumanReadable.h:179
Time()
Default constructor constructs to not_a_date_time.
Definition: Time.h:451
Commonly used exception classes.
boost::posix_time::time_duration Base
Definition: Time.h:110
Serializer that handles properties and creates PropertyNodes.
PropertyHint limits(const T &min, const T &max)
Sets both attributes "minimum" and "maximum" to the specified values.
Definition: PropertyHint.h:275
By default, IsCheapToCopy<T>::value evaluates to true for fundamental types T, false for all other ty...
Definition: IsCheapToCopy.h:63
min_type minutes() const
Returns normalized number of minutes (0..59)
Definition: Time.h:275
sec_type seconds() const
Returns normalized number of seconds (0..59)
Definition: Time.h:280
void roproperty(const char *name, const T &member, const char *comment, PropertyHint &&hint=PropertyHint(), ReflectCtrlFlags flags=REFLECT_CTRLFLAG_NONE)
Definition: PropertyReflector.h:213
Use this class to represent time durations.
Definition: Time.h:106
boost::gregorian::date Date
Typedef for the boost Gregorian calendar date.
Definition: Time.h:70
Type trait to define if a class is cheap to copy.
hour_type hours() const
Returns number of hours in the duration.
Definition: Time.h:270
void reflect(Reflector &r, LogRecord &record)
Non-intrusive reflector for LogRecord.
Definition: LoggingCore.h:137
A special PropertyReflector that creates a PropertyNode for each reflected property.
Definition: PropertySerializer.h:67
Setter< DateSerializedAsIsoString > humanReadableSetter(Date &date)
Setter for Date using DateSerializedAsIsoString proxy.
tick_type microseconds() const
Returns normalized number of microseconds (0..999)
Definition: Time.h:290
PropertyHint minimum(const T &min)
Sets the attribute "minimum" to the specified value.
Definition: PropertyHint.h:243
Date()
Definition: TimeHumanReadable.h:97
mira::Time Base
Definition: TimeHumanReadable.h:307
The Accessor class is used as an adapter to reduce the code bloat within the reflection and serializa...
Definition: Accessor.h:244
void reflectWrite(Reflector &r)
Definition: TimeHumanReadable.h:330
Holds a boost::function object to a special getter function that must meet the signature "T method()"...
Definition: GetterSetter.h:87
void reflectRead(Reflector &r, Buffer< T, Allocator > &c)
Specialization of the non-intrusive reflect for Buffer.
Definition: Buffer.h:565
Time()
Definition: TimeHumanReadable.h:309
Date(const Base &date)
Definition: TimeHumanReadable.h:99
void reflect(PropertySerializer &r)
Definition: TimeHumanReadable.h:231
Getter< DateSerializedAsIsoString > humanReadableGetter(const Date &date)
In addition to classes which can replace Date/Duration/Time, there are getters/setters/accessors for ...
Accessor< Getter< DateSerializedAsIsoString >, Setter< DateSerializedAsIsoString > > humanReadableAccessor(Date &date)
Accessor for Date using DateSerializedAsIsoString proxy.
void property(const char *name, T &member, const char *comment, PropertyHint &&hint=PropertyHint(), ReflectCtrlFlags flags=REFLECT_CTRLFLAG_NONE)
Definition: PropertyReflector.h:126
Duration(const Base &date)
Definition: TimeHumanReadable.h:185
mira::Duration Base
Definition: TimeHumanReadable.h:181
HumanReadableSerialization::Duration< false > DurationSerializedAsHMS
Derivation of mira::Duration with serialization as hours/minutes/seconds/milli-/microseconds members...
Definition: TimeHumanReadable.h:285
Time(const Base &date)
Definition: TimeHumanReadable.h:311
HumanReadableSerialization::Date< false > DateSerializedAsYMD
Derivation of mira::Date with serialization as year/month/day members.
Definition: TimeHumanReadable.h:111
Derivation of mira::Time with human-readable serialization.
Definition: TimeHumanReadable.h:305
Duration()
Definition: TimeHumanReadable.h:183
A tag type used as parameter type in humanReadableGetter, humanReadableSetter, humanReadableAccessor ...
Definition: TimeHumanReadable.h:470