/Modules/Core/Common/src/itkRealTimeStamp.cxx

https://github.com/crtc/ITK-PBNRR-GITHUB · C++ · 375 lines · 220 code · 67 blank · 88 comment · 22 complexity · 42d1f63a1bc7b6af77f4ec72a4bf668d MD5 · raw file

  1. /*=========================================================================
  2. *
  3. * Copyright Insight Software Consortium
  4. *
  5. * Licensed under the Apache License, Version 2.0 (the "License");
  6. * you may not use this file except in compliance with the License.
  7. * You may obtain a copy of the License at
  8. *
  9. * http://www.apache.org/licenses/LICENSE-2.0.txt
  10. *
  11. * Unless required by applicable law or agreed to in writing, software
  12. * distributed under the License is distributed on an "AS IS" BASIS,
  13. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  14. * See the License for the specific language governing permissions and
  15. * limitations under the License.
  16. *
  17. *=========================================================================*/
  18. #include "itkRealTimeStamp.h"
  19. #include "itkNumericTraits.h"
  20. // This macro makes sure that if the number of microseconds is ever enough to
  21. // complete a second, then the number of seconds will be incremented, and the
  22. // remainder of microseconds will be kept. It also ensures that if the number
  23. // of microseconds is negative, then we decrement the number of seconds and
  24. // assign to the microseconds variable the complement that is a positive number.
  25. #define CARRY_UNITS_OVER( seconds, micro_seconds ) \
  26. if ( micro_seconds > 1000000L ) \
  27. { \
  28. seconds += 1; \
  29. micro_seconds -= 1000000L; \
  30. } \
  31. if ( micro_seconds < 0 ) \
  32. { \
  33. seconds -= 1; \
  34. micro_seconds += 1000000L; \
  35. }
  36. // This macro ensures that the sign of the seconds is the same as the sign of
  37. // the microseconds. In other words, both of them are measured toward the same
  38. // direction of time.
  39. #define ALIGN_THE_ARROW_OF_TIME( seconds, micro_seconds ) \
  40. if( seconds > 0 && micro_seconds < 0 ) \
  41. { \
  42. seconds -= 1; \
  43. micro_seconds = 1000000L - micro_seconds; \
  44. } \
  45. if( seconds < 0 && micro_seconds > 0 ) \
  46. { \
  47. seconds += 1; \
  48. micro_seconds = 1000000L + micro_seconds; \
  49. }
  50. namespace itk
  51. {
  52. /**
  53. * Constructor to initialize a time stamp
  54. */
  55. RealTimeStamp::RealTimeStamp()
  56. {
  57. this->m_Seconds = itk::NumericTraits< SecondsCounterType >::Zero;
  58. this->m_MicroSeconds = itk::NumericTraits< MicroSecondsCounterType >::Zero;
  59. }
  60. /**
  61. * Constructor with values to initialize a time stamp.
  62. * This constructor should only be called from the RealTimeClock,
  63. * or from a file reading class.
  64. */
  65. RealTimeStamp::RealTimeStamp( SecondsCounterType seconds, MicroSecondsCounterType micro_seconds )
  66. {
  67. this->m_Seconds = seconds;
  68. this->m_MicroSeconds = micro_seconds;
  69. }
  70. /**
  71. * Destructor.
  72. */
  73. RealTimeStamp::~RealTimeStamp()
  74. {
  75. }
  76. /**
  77. * Return time in microseconds.
  78. */
  79. RealTimeStamp::TimeRepresentationType
  80. RealTimeStamp::GetTimeInMicroSeconds() const
  81. {
  82. TimeRepresentationType result = static_cast< TimeRepresentationType >( this->m_Seconds );
  83. result *= 1e6;
  84. result += static_cast< TimeRepresentationType >( this->m_MicroSeconds );
  85. return result;
  86. }
  87. /**
  88. * Return time in milliseconds.
  89. */
  90. RealTimeStamp::TimeRepresentationType
  91. RealTimeStamp::GetTimeInMilliSeconds() const
  92. {
  93. TimeRepresentationType result = static_cast< TimeRepresentationType >( this->m_Seconds );
  94. result *= 1e3;
  95. result += static_cast< TimeRepresentationType >( this->m_MicroSeconds ) / 1e3;
  96. return result;
  97. }
  98. /**
  99. * Return time in second.
  100. */
  101. RealTimeStamp::TimeRepresentationType
  102. RealTimeStamp::GetTimeInSeconds() const
  103. {
  104. TimeRepresentationType result = static_cast< TimeRepresentationType >( this->m_MicroSeconds );
  105. result /= 1e6;
  106. result += static_cast< TimeRepresentationType >( this->m_Seconds );
  107. return result;
  108. }
  109. /**
  110. * Return time in minutes.
  111. */
  112. RealTimeStamp::TimeRepresentationType
  113. RealTimeStamp::GetTimeInMinutes() const
  114. {
  115. const TimeRepresentationType result = this->GetTimeInSeconds() / 60.00;
  116. return result;
  117. }
  118. /**
  119. * Return time in hours.
  120. */
  121. RealTimeStamp::TimeRepresentationType
  122. RealTimeStamp::GetTimeInHours() const
  123. {
  124. const TimeRepresentationType result = this->GetTimeInSeconds() / 3600.00;
  125. return result;
  126. }
  127. /**
  128. * Return time in days.
  129. */
  130. RealTimeStamp::TimeRepresentationType
  131. RealTimeStamp::GetTimeInDays() const
  132. {
  133. const TimeRepresentationType result = this->GetTimeInSeconds() / 86400.00;
  134. return result;
  135. }
  136. /**
  137. * Compute the time interval between two time stamps.
  138. */
  139. RealTimeInterval
  140. RealTimeStamp::operator-( const Self & other ) const
  141. {
  142. SecondsDifferenceType seconds = this->m_Seconds - other.m_Seconds;
  143. MicroSecondsDifferenceType micro_seconds = this->m_MicroSeconds - other.m_MicroSeconds;
  144. ALIGN_THE_ARROW_OF_TIME( seconds, micro_seconds );
  145. RealTimeInterval difference;
  146. difference.m_Seconds = seconds;
  147. difference.m_MicroSeconds = micro_seconds;
  148. return difference;
  149. }
  150. /**
  151. * Add a time interval to this time stamp to compute a new time stamp.
  152. */
  153. RealTimeStamp
  154. RealTimeStamp::operator+( const RealTimeInterval & difference ) const
  155. {
  156. SecondsDifferenceType seconds = this->m_Seconds + difference.m_Seconds;
  157. if( seconds < 0 )
  158. {
  159. itkGenericExceptionMacro("RealTimeStamp can't go before the origin of time");
  160. }
  161. MicroSecondsDifferenceType micro_seconds = this->m_MicroSeconds + difference.m_MicroSeconds;
  162. CARRY_UNITS_OVER( seconds, micro_seconds );
  163. Self result;
  164. result.m_Seconds = static_cast< SecondsCounterType >( seconds );
  165. result.m_MicroSeconds = static_cast< MicroSecondsCounterType >( micro_seconds );
  166. return result;
  167. }
  168. /**
  169. * Add a time interval to this time stamp to compute a new time stamp.
  170. */
  171. RealTimeStamp
  172. RealTimeStamp::operator-( const RealTimeInterval & difference ) const
  173. {
  174. SecondsDifferenceType seconds = this->m_Seconds - difference.m_Seconds;
  175. if( seconds < 0 )
  176. {
  177. itkGenericExceptionMacro("RealTimeStamp can't go before the origin of time");
  178. }
  179. MicroSecondsDifferenceType micro_seconds = this->m_MicroSeconds - difference.m_MicroSeconds;
  180. CARRY_UNITS_OVER( seconds, micro_seconds );
  181. Self result;
  182. result.m_Seconds = static_cast< SecondsCounterType >( seconds );
  183. result.m_MicroSeconds = static_cast< MicroSecondsCounterType >( micro_seconds );
  184. return result;
  185. }
  186. /**
  187. * Add a time interval to this time stamp and update it.
  188. */
  189. const RealTimeStamp &
  190. RealTimeStamp::operator+=( const RealTimeInterval & difference )
  191. {
  192. SecondsDifferenceType seconds = this->m_Seconds + difference.m_Seconds;
  193. if( seconds < 0 )
  194. {
  195. itkGenericExceptionMacro("RealTimeStamp can't go before the origin of time");
  196. }
  197. MicroSecondsDifferenceType micro_seconds = this->m_MicroSeconds + difference.m_MicroSeconds;
  198. CARRY_UNITS_OVER( seconds, micro_seconds );
  199. this->m_Seconds = static_cast< SecondsCounterType >( seconds );
  200. this->m_MicroSeconds = static_cast< MicroSecondsCounterType >( micro_seconds );
  201. return *this;
  202. }
  203. /**
  204. * Subtract a time interval from this time stamp and update it.
  205. */
  206. const RealTimeStamp &
  207. RealTimeStamp::operator-=( const RealTimeInterval & difference )
  208. {
  209. SecondsDifferenceType seconds = this->m_Seconds - difference.m_Seconds;
  210. if( seconds < 0 )
  211. {
  212. itkGenericExceptionMacro("RealTimeStamp can't go before the origin of time");
  213. }
  214. MicroSecondsDifferenceType micro_seconds = this->m_MicroSeconds - difference.m_MicroSeconds;
  215. CARRY_UNITS_OVER( seconds, micro_seconds );
  216. this->m_Seconds = static_cast< SecondsCounterType >( seconds );
  217. this->m_MicroSeconds = static_cast< MicroSecondsCounterType >( micro_seconds );
  218. return *this;
  219. }
  220. /**
  221. * Compare two time Stamps.
  222. */
  223. bool
  224. RealTimeStamp::operator>( const Self & other ) const
  225. {
  226. if( this->m_Seconds > other.m_Seconds )
  227. {
  228. return true;
  229. }
  230. if( this->m_Seconds < other.m_Seconds )
  231. {
  232. return false;
  233. }
  234. return ( this->m_MicroSeconds > other.m_MicroSeconds );
  235. }
  236. /**
  237. * Compare two time Stamps.
  238. */
  239. bool
  240. RealTimeStamp::operator<( const Self & other ) const
  241. {
  242. if( this->m_Seconds < other.m_Seconds )
  243. {
  244. return true;
  245. }
  246. if( this->m_Seconds > other.m_Seconds )
  247. {
  248. return false;
  249. }
  250. return ( this->m_MicroSeconds < other.m_MicroSeconds );
  251. }
  252. /**
  253. * Compare two time Stamps.
  254. */
  255. bool
  256. RealTimeStamp::operator>=( const Self & other ) const
  257. {
  258. if( this->m_Seconds > other.m_Seconds )
  259. {
  260. return true;
  261. }
  262. if( this->m_Seconds < other.m_Seconds )
  263. {
  264. return false;
  265. }
  266. return ( this->m_MicroSeconds >= other.m_MicroSeconds );
  267. }
  268. /**
  269. * Compare two time Stamps.
  270. */
  271. bool
  272. RealTimeStamp::operator<=( const Self & other ) const
  273. {
  274. if( this->m_Seconds < other.m_Seconds )
  275. {
  276. return true;
  277. }
  278. if( this->m_Seconds > other.m_Seconds )
  279. {
  280. return false;
  281. }
  282. return ( this->m_MicroSeconds <= other.m_MicroSeconds );
  283. }
  284. /**
  285. * Compare two time Stamps.
  286. */
  287. bool
  288. RealTimeStamp::operator==( const Self & other ) const
  289. {
  290. return ( ( this->m_MicroSeconds == other.m_MicroSeconds ) &&
  291. ( this->m_Seconds == other.m_Seconds ) );
  292. }
  293. /**
  294. * Compare two time Stamps.
  295. */
  296. bool
  297. RealTimeStamp::operator!=( const Self & other ) const
  298. {
  299. return ( ( this->m_MicroSeconds != other.m_MicroSeconds ) ||
  300. ( this->m_Seconds != other.m_Seconds ) );
  301. }
  302. /** Default print out of a RealTimeStamp */
  303. std::ostream & operator<<(std::ostream & os, const RealTimeStamp & v)
  304. {
  305. os << v.GetTimeInSeconds() << " seconds ";
  306. return os;
  307. }
  308. } // end of namespace itk