ChipMaster's trial hacks on C++CMS starting with v1.2.1. Not sure I'll follow on with the v2 since it looks to be breaking and mostly frivolous.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

339 lines
7.2 KiB

  1. //
  2. // Copyright (C) 2009-2012 Artyom Beilis (Tonkikh)
  3. //
  4. // Distributed under the Boost Software License, Version 1.0. (See
  5. // accompanying file LICENSE_1_0.txt or copy at
  6. // http://www.boost.org/LICENSE_1_0.txt)
  7. //
  8. #ifndef BOOSTER_POSIX_TIME_H
  9. #define BOOSTER_POSIX_TIME_H
  10. #include <booster/config.h>
  11. #include <ctime>
  12. #include <iosfwd>
  13. #include <math.h>
  14. namespace booster {
  15. ///
  16. /// \brief This class represents POSIX time.
  17. ///
  18. /// The time from Jan 1, 1970 in seconds in UTC (without leap seconds) similar to time_t.
  19. ///
  20. /// ptime internally holds 64 bit integer for seconds part and int for nanoseconds
  21. /// part which gives fine-grained time representation.
  22. ///
  23. class BOOSTER_API ptime {
  24. public:
  25. ///
  26. /// Create the POSIX time from seconds and nanoseconds.
  27. ///
  28. explicit
  29. ptime(long long seconds=0,int nano=0) :
  30. sec(seconds),
  31. nsec(nano)
  32. {
  33. normalize();
  34. }
  35. ///
  36. /// Get the seconds part of POSIX time
  37. ///
  38. long long get_seconds() const
  39. {
  40. return sec;
  41. }
  42. ///
  43. /// Get the nanoseconds fraction part of POSIX time
  44. ///
  45. int get_nanoseconds() const
  46. {
  47. return nsec;
  48. }
  49. ///
  50. /// Get the milliseconds fraction part of POSIX time (which is equal to get_nanoseconds() / 1,000,000)
  51. ///
  52. int get_milliseconds() const
  53. {
  54. return nsec / one_e6;
  55. }
  56. ///
  57. /// Get the microseconds fraction part of POSIX time (which is equal to get_nanoseconds() / 1,000)
  58. ///
  59. int get_microseconds() const
  60. {
  61. return nsec / one_e3;
  62. }
  63. ///
  64. /// Get amount of full seconds in \a p
  65. ///
  66. static long long seconds(ptime const &p)
  67. {
  68. return p.sec;
  69. }
  70. ///
  71. /// Convert a seconds \a v to ptime.
  72. ///
  73. static ptime seconds(long long v)
  74. {
  75. return ptime(v);
  76. }
  77. ///
  78. /// Get amount of full milliseconds in \a p.
  79. /// Not the same as p.get_milliseconds() as takes seconds as well
  80. ///
  81. static long long milliseconds(ptime const &p)
  82. {
  83. return p.get_seconds() * one_e3 + p.get_milliseconds();
  84. }
  85. ///
  86. /// Convert a milliseconds \a v to ptime.
  87. ///
  88. static ptime milliseconds(long long v)
  89. {
  90. return ptime(v/one_e3,v%one_e3 * one_e6);
  91. }
  92. ///
  93. /// Get amount of full microseconds in \a p.
  94. /// Not the same as p.get_microseconds() as takes seconds as well
  95. ///
  96. static long long microseconds(ptime const &p)
  97. {
  98. return p.get_seconds() * one_e6 + p.get_nanoseconds() / one_e3;
  99. }
  100. ///
  101. /// Convert a microseconds \a v to ptime.
  102. ///
  103. static ptime microseconds(long long v)
  104. {
  105. return ptime(v/one_e6,v%one_e6 * one_e3);
  106. }
  107. ///
  108. /// Get amount of nanoseconds in \a p
  109. /// Not the same as p.get_nanoseconds() as takes seconds as well
  110. ///
  111. static long long nanoseconds(ptime const &p)
  112. {
  113. return p.get_seconds() * one_e9 + p.get_nanoseconds();
  114. }
  115. ///
  116. /// Convert a nanoseconds \a v to ptime.
  117. ///
  118. static ptime nanoseconds(long long v)
  119. {
  120. return ptime(v/one_e9,v%one_e9);
  121. }
  122. ///
  123. /// Get amount of full minutes in \a p
  124. ///
  125. static ptime minutes(long long v)
  126. {
  127. return ptime(v*60);
  128. }
  129. ///
  130. /// Convert minutes \a v to ptime.
  131. ///
  132. static long long minutes(ptime const &p)
  133. {
  134. return p.get_seconds() / 60;
  135. }
  136. ///
  137. /// Get amount of full hours in \a p
  138. ///
  139. static long long hours(ptime const &p)
  140. {
  141. return p.get_seconds() / 3600;
  142. }
  143. ///
  144. /// Convert hours \a v to ptime.
  145. ///
  146. static ptime hours(long long v)
  147. {
  148. return ptime(v*3600);
  149. }
  150. ///
  151. /// Get amount of full days in \a p
  152. ///
  153. static long long days(ptime const &p)
  154. {
  155. return p.get_seconds() / (3600*24);
  156. }
  157. ///
  158. /// Convert days \a v to ptime.
  159. ///
  160. static ptime days(long long v)
  161. {
  162. return ptime(v*(3600*24));
  163. }
  164. ///
  165. /// Convert \a t to floating point number that represents POSIX time in seconds
  166. ///
  167. static double to_number(ptime const &t)
  168. {
  169. return double(t.sec) + double(t.nsec) * 1e-9;
  170. }
  171. ///
  172. /// Convert floating point number \a d that represents POSIX time in seconds to ptime
  173. ///
  174. static ptime from_number(double d)
  175. {
  176. double sec = floor(d);
  177. double subsec = d-sec;
  178. long long seconds = static_cast<long long>(sec);
  179. int nano = static_cast<int>(floor(subsec * 1e9));
  180. if(nano < 0) nano = 0;
  181. if(nano >= one_e9) nano = one_e9-1;
  182. return ptime(seconds,nano);
  183. }
  184. ///
  185. /// Add two POSIX time ranges (as numbers)
  186. ///
  187. ptime operator+(ptime const &other) const
  188. {
  189. return ptime(sec+other.sec,nsec+other.nsec);
  190. }
  191. ///
  192. /// Add two POSIX time ranges (as numbers)
  193. ///
  194. /// \ver{v1_2}
  195. ptime& operator+=(ptime const &other)
  196. {
  197. *this = ptime(sec+other.sec,nsec+other.nsec);
  198. return *this;
  199. }
  200. ///
  201. /// Subtract one time from other (as number)
  202. ///
  203. ptime operator-(ptime const &other) const
  204. {
  205. return ptime(sec-other.sec,nsec-other.nsec);
  206. }
  207. ///
  208. /// Subtract one time from other (as number)
  209. ///
  210. /// \ver{v1_2}
  211. ptime& operator-=(ptime const &other)
  212. {
  213. *this = ptime(sec-other.sec,nsec-other.nsec);
  214. return *this;
  215. }
  216. bool operator==(ptime const &other) const
  217. {
  218. return sec==other.sec && nsec == other.nsec;
  219. }
  220. bool operator!=(ptime const &other) const
  221. {
  222. return !((*this)==other);
  223. }
  224. bool operator<(ptime const &other) const
  225. {
  226. if(sec < other.sec)
  227. return true;
  228. if(sec > other.sec)
  229. return false;
  230. return nsec < other.nsec;
  231. }
  232. bool operator>(ptime const &other) const
  233. {
  234. return other < *this;
  235. }
  236. bool operator <= (ptime const &other) const
  237. {
  238. return !(*this > other);
  239. }
  240. bool operator >=(ptime const &other) const
  241. {
  242. return !(*this < other);
  243. }
  244. ///
  245. /// Convert local time to POSIX time similar to mktime
  246. ///
  247. static ptime local_time(std::tm const &v);
  248. ///
  249. /// Convert universal time to POSIX time similar to timegm or mktime in GMT timezone
  250. ///
  251. static ptime universal_time(std::tm const &v);
  252. ///
  253. /// Convert POSIX time \a v to a local time similar to localtime_r
  254. ///
  255. static std::tm local_time(ptime const &v);
  256. ///
  257. /// Convert POSIX time \a v to a GMT time similar to gmtime_r
  258. ///
  259. static std::tm universal_time(ptime const &v);
  260. ///
  261. /// Get current time
  262. ///
  263. static ptime now();
  264. ///
  265. /// Same as ptime() -- 0 in terms of POSIX time
  266. ///
  267. static ptime const zero;
  268. ///
  269. /// Sleep at least \a v milliseconds
  270. ///
  271. static void millisleep(long long v)
  272. {
  273. sleep(milliseconds(v));
  274. }
  275. ///
  276. /// Sleep at least \a v nanoseconds
  277. ///
  278. static void nanosleep(long long v)
  279. {
  280. sleep(nanoseconds(v));
  281. }
  282. ///
  283. /// Sleep at least \a v amount of time.
  284. ///
  285. static void sleep(ptime const &v );
  286. private:
  287. void normalize()
  288. {
  289. if(nsec > one_e9) {
  290. sec += nsec / one_e9;
  291. nsec = nsec % one_e9;
  292. }
  293. else if(nsec < 0) {
  294. while(nsec < 0) {
  295. nsec += one_e9;
  296. sec -= 1;
  297. }
  298. }
  299. }
  300. static const int one_e3 = 1000;
  301. static const int one_e6 = 1000000;
  302. static const int one_e9 = 1000000000;
  303. long long sec;
  304. int nsec;
  305. };
  306. ///
  307. /// Write ptime to stream. It is written as double, so it would give expected result when
  308. /// working with booster::locale::as::date_time formatter
  309. ///
  310. BOOSTER_API std::ostream &operator<<(std::ostream &,ptime const &);
  311. ///
  312. /// Read ptime from stream. It is read as double, so it would give expected result when
  313. /// working with booster::locale::as::date_time formatter
  314. ///
  315. BOOSTER_API std::istream &operator>>(std::istream &,ptime &);
  316. }
  317. #endif