rtcTime.h
Go to the documentation of this file.
00001 #ifndef RTC_TIME_H_
00002 #define RTC_TIME_H_
00003 
00004 #include "rtc/rtcBase.h"
00005 #include "rtc/rtcDuration.h"
00006 
00007 #include <iostream>
00008 #include <math.h>
00009 
00010 #ifdef WIN32
00011 #include <windows.h>
00012 #endif
00013 
00014 namespace rtc {
00015 
00016 inline void normalizeSecNSec(uint64_t& sec, uint64_t& nsec)
00017 {
00018   uint64_t nsec_part = nsec % 1000000000UL;
00019   uint64_t sec_part = nsec / 1000000000UL;
00020 
00021   if (sec_part > UINT_MAX)
00022     throw std::runtime_error("Time is out of dual 32-bit range");
00023 
00024   sec += sec_part;
00025   nsec = nsec_part;
00026 }
00027 
00028 inline void normalizeSecNSec(uint32_t& sec, uint32_t& nsec)
00029 {
00030   uint64_t sec64 = sec;
00031   uint64_t nsec64 = nsec;
00032 
00033   normalizeSecNSec(sec64, nsec64);
00034 
00035   sec = (uint32_t)sec64;
00036   nsec = (uint32_t)nsec64;
00037 }
00038 
00039 inline void normalizeSecNSecUnsigned(int64_t& sec, int64_t& nsec)
00040 {
00041   int64_t nsec_part = nsec;
00042   int64_t sec_part = sec;
00043 
00044   while (nsec_part >= 1000000000L)
00045   {
00046     nsec_part -= 1000000000L;
00047     ++sec_part;
00048   }
00049   while (nsec_part < 0)
00050   {
00051     nsec_part += 1000000000L;
00052     --sec_part;
00053   }
00054 
00055   if (sec_part < 0 || sec_part > INT_MAX)
00056     throw std::runtime_error("Time is out of dual 32-bit range");
00057 
00058   sec = sec_part;
00059   nsec = nsec_part;
00060 }
00061 
00062 template<class T, class D>
00063 class TimeBase
00064 {
00065 public:
00066   uint32_t sec, nsec;
00067 
00068   TimeBase() : sec(0), nsec(0) { }
00069   TimeBase(uint32_t _sec, uint32_t _nsec) : sec(_sec), nsec(_nsec)
00070   {
00071     normalizeSecNSec(sec, nsec);
00072   }
00073   explicit TimeBase(double t) { fromSec(t); }
00074   ~TimeBase() {}
00075   D operator-(const T &rhs) const;
00076   T operator+(const D &rhs) const;
00077   T operator-(const D &rhs) const;
00078   T& operator+=(const D &rhs);
00079   T& operator-=(const D &rhs);
00080   bool operator==(const T &rhs) const;
00081   inline bool operator!=(const T &rhs) const { return !(*static_cast<const T*>(this) == rhs); }
00082   bool operator>(const T &rhs) const;
00083   bool operator<(const T &rhs) const;
00084   bool operator>=(const T &rhs) const;
00085   bool operator<=(const T &rhs) const;
00086 
00087   double toSec()  const { return (double)sec + 1e-9*(double)nsec; };
00088   T& fromSec(double t) { sec = (uint32_t)floor(t); nsec = (uint32_t)round((t-sec) * 1e9);  return *static_cast<T*>(this);}
00089 
00090   uint64_t toNSec() const {return (uint64_t)sec*1000000000ull + (uint64_t)nsec;  }
00091   T& fromNSec(uint64_t t);
00092 
00093   inline bool isZero() const { return sec == 0 && nsec == 0; }
00094   inline bool is_zero() const { return isZero(); }
00095 };
00096 
00097 class Time : public TimeBase<Time, Duration>
00098 {
00099 public:
00100   Time()
00101     : TimeBase<Time, Duration>()
00102   {}
00103 
00104   Time(uint32_t _sec, uint32_t _nsec)
00105     : TimeBase<Time, Duration>(_sec, _nsec)
00106   {}
00107 
00108   explicit Time(double t) { fromSec(t); }
00109 
00110   static Time now();
00111   static bool sleepUntil(const Time& end);
00112 
00113   static void init();
00114   static void shutdown();
00115   static void setNow(const Time& new_now);
00116   static bool useSystemTime() { return use_system_time_; }
00117 private:
00118   static Time sim_time_;
00119   static bool use_system_time_;
00120 };
00121 
00122 static const Time TIME_MAX = rtc::Time(UINT_MAX, 999999999);
00123 static const Time TIME_MIN = rtc::Time(0, 0);
00124 
00125 class WallTime : public TimeBase<WallTime, WallDuration>
00126 {
00127 public:
00128   WallTime()
00129     : TimeBase<WallTime, WallDuration>()
00130   {}
00131 
00132   WallTime(uint32_t _sec, uint32_t _nsec)
00133     : TimeBase<WallTime, WallDuration>(_sec, _nsec)
00134   {}
00135 
00136   explicit WallTime(double t) { fromSec(t); }
00137 
00138   static WallTime now();
00139 
00140   static bool sleepUntil(const WallTime& end);
00141 };
00142 
00143 std::ostream &operator <<(std::ostream &os, const Time &rhs);
00144 std::ostream &operator <<(std::ostream &os, const WallTime &rhs);
00145 
00146 template<class T, class D>
00147 T& TimeBase<T, D>::fromNSec(uint64_t t)
00148 {
00149   sec  = (int32_t)(t / 1000000000);
00150   nsec = (int32_t)(t % 1000000000);
00151 
00152   normalizeSecNSec(sec, nsec);
00153 
00154   return *static_cast<T*>(this);
00155 }
00156 
00157 template<class T, class D>
00158 D TimeBase<T, D>::operator-(const T &rhs) const
00159 {
00160   return D((int32_t)sec -  (int32_t)rhs.sec,
00161     (int32_t)nsec - (int32_t)rhs.nsec); // carry handled in ctor
00162 }
00163 
00164 template<class T, class D>
00165 T TimeBase<T, D>::operator-(const D &rhs) const
00166 {
00167   return *static_cast<const T*>(this) + ( -rhs);
00168 }
00169 
00170 template<class T, class D>
00171 T TimeBase<T, D>::operator+(const D &rhs) const
00172 {
00173   int64_t sec_sum  = (int64_t)sec  + (int64_t)rhs.sec;
00174   int64_t nsec_sum = (int64_t)nsec + (int64_t)rhs.nsec;
00175 
00176   // Throws an exception if we go out of 32-bit range
00177   normalizeSecNSecUnsigned(sec_sum, nsec_sum);
00178 
00179   // now, it's safe to downcast back to uint32 bits
00180   return T((uint32_t)sec_sum, (uint32_t)nsec_sum);
00181 }
00182 
00183 template<class T, class D>
00184 T& TimeBase<T, D>::operator+=(const D &rhs)
00185 {
00186   *this = *this + rhs;
00187   return *static_cast<T*>(this);
00188 }
00189 
00190 template<class T, class D>
00191 T& TimeBase<T, D>::operator-=(const D &rhs)
00192 {
00193   *this += (-rhs);
00194   return *static_cast<T*>(this);
00195 }
00196 
00197 template<class T, class D>
00198 bool TimeBase<T, D>::operator==(const T &rhs) const
00199 {
00200   return sec == rhs.sec && nsec == rhs.nsec;
00201 }
00202 
00203 template<class T, class D>
00204 bool TimeBase<T, D>::operator<(const T &rhs) const
00205 {
00206   if (sec < rhs.sec)
00207     return true;
00208   else if (sec == rhs.sec && nsec < rhs.nsec)
00209     return true;
00210   return false;
00211 }
00212 
00213 template<class T, class D>
00214 bool TimeBase<T, D>::operator>(const T &rhs) const
00215 {
00216   if (sec > rhs.sec)
00217     return true;
00218   else if (sec == rhs.sec && nsec > rhs.nsec)
00219     return true;
00220   return false;
00221 }
00222 
00223 template<class T, class D>
00224 bool TimeBase<T, D>::operator<=(const T &rhs) const
00225 {
00226   if (sec < rhs.sec)
00227     return true;
00228   else if (sec == rhs.sec && nsec <= rhs.nsec)
00229     return true;
00230   return false;
00231 }
00232 
00233 template<class T, class D>
00234 bool TimeBase<T, D>::operator>=(const T &rhs) const
00235 {
00236   if (sec > rhs.sec)
00237     return true;
00238   else if (sec == rhs.sec && nsec >= rhs.nsec)
00239     return true;
00240   return false;
00241 }
00242 
00243 
00244 }       // namespace rtc
00245 
00246 #endif // RTC_TIME_H_


rtc
Author(s): Benjamin Pitzer
autogenerated on Thu Jan 2 2014 11:04:53