rtcDuration.h
Go to the documentation of this file.
00001 #ifndef RTC_DURATION_H_
00002 #define RTC_DURATION_H_
00003 
00004 #include "rtc/rtcBase.h"
00005 #include <iostream>
00006 #include <math.h>
00007 #include <stdexcept>
00008 #include <climits>
00009 
00010 #ifdef WIN32
00011 #include <windows.h>
00012 #endif
00013 
00014 namespace rtc {
00015 
00016 inline void normalizeSecNSecSigned(int64_t& sec, int64_t& nsec)
00017 {
00018   int64_t nsec_part = nsec;
00019   int64_t sec_part = sec;
00020 
00021   while (nsec_part > 1000000000L)
00022   {
00023     nsec_part -= 1000000000L;
00024     ++sec_part;
00025   }
00026   while (nsec_part < 0)
00027   {
00028     nsec_part += 1000000000L;
00029     --sec_part;
00030   }
00031 
00032   if (sec_part < INT_MIN || sec_part > INT_MAX)
00033     throw std::runtime_error("Duration is out of dual 32-bit range");
00034 
00035   sec = sec_part;
00036   nsec = nsec_part;
00037 }
00038 
00039 inline void normalizeSecNSecSigned(int32_t& sec, int32_t& nsec)
00040 {
00041   int64_t sec64 = sec;
00042   int64_t nsec64 = nsec;
00043 
00044   normalizeSecNSecSigned(sec64, nsec64);
00045 
00046   sec = (int32_t)sec64;
00047   nsec = (int32_t)nsec64;
00048 }
00049 
00050 template<class T>
00051 class DurationBase
00052 {
00053 public:
00054   int32_t sec, nsec;
00055   DurationBase() : sec(0), nsec(0) { }
00056   DurationBase(int32_t _sec, int32_t _nsec);
00057   explicit DurationBase(double t){fromSec(t);};
00058   ~DurationBase() {}
00059   T operator+(const T &rhs) const;
00060   T operator-(const T &rhs) const;
00061   T operator-() const;
00062   T operator*(double scale) const;
00063   T& operator+=(const T &rhs);
00064   T& operator-=(const T &rhs);
00065   T& operator*=(double scale);
00066   bool operator==(const T &rhs) const;
00067   inline bool operator!=(const T &rhs) const { return !(*static_cast<const T*>(this) == rhs); }
00068   bool operator>(const T &rhs) const;
00069   bool operator<(const T &rhs) const;
00070   bool operator>=(const T &rhs) const;
00071   bool operator<=(const T &rhs) const;
00072   double toSec() const { return (double)sec + 1e-9*(double)nsec; };
00073   int64_t toNSec() const {return (int64_t)sec*1000000000ll + (int64_t)nsec;  };
00074   T& fromSec(double t);
00075   T& fromNSec(int64_t t);
00076   bool isZero();
00077 };
00078 
00079 class Duration : public DurationBase<Duration>
00080 {
00081 public:
00082   Duration()
00083   : DurationBase<Duration>()
00084   { }
00085 
00086   Duration(int32_t _sec, int32_t _nsec)
00087   : DurationBase<Duration>(_sec, _nsec)
00088   {}
00089 
00090   explicit Duration(double t) { fromSec(t); }
00091 
00095   bool sleep() const;
00096 };
00097 
00098 extern const Duration DURATION_MAX;
00099 extern const Duration DURATION_MIN;
00100 
00101 class WallDuration : public DurationBase<WallDuration>
00102 {
00103 public:
00104   WallDuration()
00105   : DurationBase<WallDuration>()
00106   { }
00107 
00108   WallDuration(int32_t _sec, int32_t _nsec)
00109   : DurationBase<WallDuration>(_sec, _nsec)
00110   {}
00111 
00112   explicit WallDuration(double t) { fromSec(t); }
00113 
00117   bool sleep() const;
00118 };
00119 
00120 std::ostream &operator <<(std::ostream &os, const Duration &rhs);
00121 std::ostream &operator <<(std::ostream &os, const WallDuration &rhs);
00122 
00123 //
00124 // DurationBase template member function implementation
00125 //
00126 template<class T>
00127 DurationBase<T>::DurationBase(int32_t _sec, int32_t _nsec)
00128 : sec(_sec), nsec(_nsec)
00129 {
00130   normalizeSecNSecSigned(sec, nsec);
00131 }
00132 
00133 template<class T>
00134 T& DurationBase<T>::fromSec(double d)
00135 {
00136 #ifdef HAVE_TRUNC
00137   sec  = (int32_t)trunc(d);
00138 #else
00139   // (morgan: why doesn't win32 provide trunc? argh. hacked this together
00140   // without much thought. need to test this conversion.
00141   if (d >= 0.0)
00142     sec = (int32_t)floor(d);
00143   else
00144     sec = (int32_t)floor(d) + 1;
00145 #endif
00146   nsec = (int32_t)((d - (double)sec)*1000000000);
00147   return *static_cast<T*>(this);
00148 }
00149 
00150 template<class T>
00151 T& DurationBase<T>::fromNSec(int64_t t)
00152 {
00153   sec  = (int32_t)(t / 1000000000);
00154   nsec = (int32_t)(t % 1000000000);
00155 
00156   normalizeSecNSecSigned(sec, nsec);
00157 
00158   return *static_cast<T*>(this);
00159 }
00160 
00161 template<class T>
00162 T DurationBase<T>::operator+(const T &rhs) const
00163 {
00164   return T(sec + rhs.sec, nsec + rhs.nsec);
00165 }
00166 
00167 template<class T>
00168 T DurationBase<T>::operator*(double scale) const
00169 {
00170   return T(toSec() * scale);
00171 }
00172 
00173 template<class T>
00174 T DurationBase<T>::operator-(const T &rhs) const
00175 {
00176   return T(sec - rhs.sec, nsec - rhs.nsec);
00177 }
00178 
00179 template<class T>
00180 T DurationBase<T>::operator-() const
00181 {
00182   return T(-sec , -nsec);
00183 }
00184 
00185 template<class T>
00186 T& DurationBase<T>::operator+=(const T &rhs)
00187 {
00188   *this = *this + rhs;
00189   return *static_cast<T*>(this);
00190 }
00191 
00192 template<class T>
00193 T& DurationBase<T>::operator-=(const T &rhs)
00194 {
00195   *this += (-rhs);
00196   return *static_cast<T*>(this);
00197 }
00198 
00199 template<class T>
00200 T& DurationBase<T>::operator*=(double scale)
00201 {
00202   fromSec(toSec() * scale);
00203   return *static_cast<T*>(this);
00204 }
00205 
00206 template<class T>
00207 bool DurationBase<T>::operator<(const T &rhs) const
00208 {
00209   if (sec < rhs.sec)
00210     return true;
00211   else if (sec == rhs.sec && nsec < rhs.nsec)
00212     return true;
00213   return false;
00214 }
00215 
00216 template<class T>
00217 bool DurationBase<T>::operator>(const T &rhs) const
00218 {
00219   if (sec > rhs.sec)
00220     return true;
00221   else if (sec == rhs.sec && nsec > rhs.nsec)
00222     return true;
00223   return false;
00224 }
00225 
00226 template<class T>
00227 bool DurationBase<T>::operator<=(const T &rhs) const
00228 {
00229   if (sec < rhs.sec)
00230     return true;
00231   else if (sec == rhs.sec && nsec <= rhs.nsec)
00232     return true;
00233   return false;
00234 }
00235 
00236 template<class T>
00237 bool DurationBase<T>::operator>=(const T &rhs) const
00238 {
00239   if (sec > rhs.sec)
00240     return true;
00241   else if (sec == rhs.sec && nsec >= rhs.nsec)
00242     return true;
00243   return false;
00244 }
00245 
00246 template<class T>
00247 bool DurationBase<T>::operator==(const T &rhs) const
00248 {
00249   return sec == rhs.sec && nsec == rhs.nsec;
00250 }
00251 
00252 template<class T>
00253 bool DurationBase<T>::isZero()
00254 {
00255   return sec == 0 && nsec == 0;
00256 }
00257 
00258 }       // namespace rtc
00259 
00260 #endif // RTC_DURATION_H_


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