libstdc++
chrono
Go to the documentation of this file.
1 // <chrono> -*- C++ -*-
2 
3 // Copyright (C) 2008, 2009, 2010, 2011 Free Software Foundation, Inc.
4 //
5 // This file is part of the GNU ISO C++ Library. This library is free
6 // software; you can redistribute it and/or modify it under the
7 // terms of the GNU General Public License as published by the
8 // Free Software Foundation; either version 3, or (at your option)
9 // any later version.
10 
11 // This library is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 // GNU General Public License for more details.
15 
16 // Under Section 7 of GPL version 3, you are granted additional
17 // permissions described in the GCC Runtime Library Exception, version
18 // 3.1, as published by the Free Software Foundation.
19 
20 // You should have received a copy of the GNU General Public License and
21 // a copy of the GCC Runtime Library Exception along with this program;
22 // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
23 // <http://www.gnu.org/licenses/>.
24 
25 /** @file include/chrono
26  * This is a Standard C++ Library header.
27  */
28 
29 #ifndef _GLIBCXX_CHRONO
30 #define _GLIBCXX_CHRONO 1
31 
32 #pragma GCC system_header
33 
34 #ifndef __GXX_EXPERIMENTAL_CXX0X__
35 # include <bits/c++0x_warning.h>
36 #else
37 
38 #include <ratio>
39 #include <type_traits>
40 #include <limits>
41 #include <ctime>
42 
43 #ifdef _GLIBCXX_USE_C99_STDINT_TR1
44 
45 namespace std _GLIBCXX_VISIBILITY(default)
46 {
47  /**
48  * @defgroup chrono Time
49  * @ingroup utilities
50  *
51  * Classes and functions for time.
52  * @{
53  */
54 
55  /** @namespace std::chrono
56  * @brief ISO C++ 0x entities sub namespace for time and date.
57  */
58  namespace chrono
59  {
60  _GLIBCXX_BEGIN_NAMESPACE_VERSION
61 
62  template<typename _Rep, typename _Period = ratio<1>>
63  struct duration;
64 
65  template<typename _Clock, typename _Dur = typename _Clock::duration>
66  struct time_point;
67 
68  _GLIBCXX_END_NAMESPACE_VERSION
69  }
70 
71 _GLIBCXX_BEGIN_NAMESPACE_VERSION
72  // 20.8.2.3 specialization of common_type (for duration)
73  template<typename _Rep1, typename _Period1, typename _Rep2, typename _Period2>
74  struct common_type<chrono::duration<_Rep1, _Period1>,
75  chrono::duration<_Rep2, _Period2>>
76  {
77  private:
78  typedef __static_gcd<_Period1::num, _Period2::num> __gcd_num;
79  typedef __static_gcd<_Period1::den, _Period2::den> __gcd_den;
80  typedef typename common_type<_Rep1, _Rep2>::type __cr;
81  typedef ratio<__gcd_num::value,
82  (_Period1::den / __gcd_den::value) * _Period2::den> __r;
83 
84  public:
85  typedef chrono::duration<__cr, __r> type;
86  };
87 
88  // 20.8.2.3 specialization of common_type (for time_point)
89  template<typename _Clock, typename _Dur1, typename _Dur2>
90  struct common_type<chrono::time_point<_Clock, _Dur1>,
91  chrono::time_point<_Clock, _Dur2>>
92  {
93  private:
94  typedef typename common_type<_Dur1, _Dur2>::type __ct;
95 
96  public:
98  };
99 _GLIBCXX_END_NAMESPACE_VERSION
100 
101  namespace chrono
102  {
103  _GLIBCXX_BEGIN_NAMESPACE_VERSION
104 
105  // Primary template for duration_cast impl.
106  template<typename _ToDur, typename _CF, typename _CR,
107  bool _NumIsOne = false, bool _DenIsOne = false>
108  struct __duration_cast_impl
109  {
110  template<typename _Rep, typename _Period>
111  static constexpr _ToDur
112  __cast(const duration<_Rep, _Period>& __d)
113  {
114  typedef typename _ToDur::rep __to_rep;
115  return _ToDur(static_cast<__to_rep>(static_cast<_CR>(__d.count())
116  * static_cast<_CR>(_CF::num)
117  / static_cast<_CR>(_CF::den)));
118  }
119  };
120 
121  template<typename _ToDur, typename _CF, typename _CR>
122  struct __duration_cast_impl<_ToDur, _CF, _CR, true, true>
123  {
124  template<typename _Rep, typename _Period>
125  static constexpr _ToDur
126  __cast(const duration<_Rep, _Period>& __d)
127  {
128  typedef typename _ToDur::rep __to_rep;
129  return _ToDur(static_cast<__to_rep>(__d.count()));
130  }
131  };
132 
133  template<typename _ToDur, typename _CF, typename _CR>
134  struct __duration_cast_impl<_ToDur, _CF, _CR, true, false>
135  {
136  template<typename _Rep, typename _Period>
137  static constexpr _ToDur
138  __cast(const duration<_Rep, _Period>& __d)
139  {
140  typedef typename _ToDur::rep __to_rep;
141  return _ToDur(static_cast<__to_rep>(
142  static_cast<_CR>(__d.count()) / static_cast<_CR>(_CF::den)));
143  }
144  };
145 
146  template<typename _ToDur, typename _CF, typename _CR>
147  struct __duration_cast_impl<_ToDur, _CF, _CR, false, true>
148  {
149  template<typename _Rep, typename _Period>
150  static constexpr _ToDur
151  __cast(const duration<_Rep, _Period>& __d)
152  {
153  typedef typename _ToDur::rep __to_rep;
154  return _ToDur(static_cast<__to_rep>(
155  static_cast<_CR>(__d.count()) * static_cast<_CR>(_CF::num)));
156  }
157  };
158 
159  template<typename _Tp>
160  struct __is_duration
162  { };
163 
164  template<typename _Rep, typename _Period>
165  struct __is_duration<duration<_Rep, _Period>>
167  { };
168 
169  /// duration_cast
170  template<typename _ToDur, typename _Rep, typename _Period>
171  inline constexpr typename enable_if<__is_duration<_ToDur>::value,
172  _ToDur>::type
174  {
175  typedef typename _ToDur::period __to_period;
176  typedef typename _ToDur::rep __to_rep;
177  typedef ratio_divide<_Period, __to_period> __r_div;
178  typedef typename __r_div::type __cf;
180  __cr;
181  typedef __duration_cast_impl<_ToDur, __cf, __cr,
182  __cf::num == 1, __cf::den == 1> __dc;
183  return __dc::__cast(__d);
184  }
185 
186  /// treat_as_floating_point
187  template<typename _Rep>
189  : is_floating_point<_Rep>
190  { };
191 
192  /// duration_values
193  template<typename _Rep>
195  {
196  static constexpr _Rep
197  zero()
198  { return _Rep(0); }
199 
200  static constexpr _Rep
201  max()
202  { return numeric_limits<_Rep>::max(); }
203 
204  static constexpr _Rep
205  min()
206  { return numeric_limits<_Rep>::min(); }
207  };
208 
209  template<typename T>
210  struct __is_ratio
212  { };
213 
214  template<intmax_t _Num, intmax_t _Den>
215  struct __is_ratio<ratio<_Num, _Den>>
217  { };
218 
219  /// duration
220  template<typename _Rep, typename _Period>
221  struct duration
222  {
223  typedef _Rep rep;
224  typedef _Period period;
225 
226  static_assert(!__is_duration<_Rep>::value, "rep cannot be a duration");
227  static_assert(__is_ratio<_Period>::value,
228  "period must be a specialization of ratio");
229  static_assert(_Period::num > 0, "period must be positive");
230 
231  // 20.8.3.1 construction / copy / destroy
232  constexpr duration() : __r() { }
233 
234  constexpr duration(const duration&) = default;
235 
236  template<typename _Rep2, typename = typename
237  enable_if<is_convertible<_Rep2, rep>::value
238  && (treat_as_floating_point<rep>::value
239  || !treat_as_floating_point<_Rep2>::value)>::type>
240  constexpr explicit duration(const _Rep2& __rep)
241  : __r(static_cast<rep>(__rep)) { }
242 
243  template<typename _Rep2, typename _Period2, typename = typename
244  enable_if<treat_as_floating_point<rep>::value
245  || (ratio_divide<_Period2, period>::type::den == 1
246  && !treat_as_floating_point<_Rep2>::value)>::type>
247  constexpr duration(const duration<_Rep2, _Period2>& __d)
248  : __r(duration_cast<duration>(__d).count()) { }
249 
250  ~duration() = default;
251  duration& operator=(const duration&) = default;
252 
253  // 20.8.3.2 observer
254  constexpr rep
255  count() const
256  { return __r; }
257 
258  // 20.8.3.3 arithmetic
259  constexpr duration
260  operator+() const
261  { return *this; }
262 
263  constexpr duration
264  operator-() const
265  { return duration(-__r); }
266 
267  duration&
268  operator++()
269  {
270  ++__r;
271  return *this;
272  }
273 
274  duration
275  operator++(int)
276  { return duration(__r++); }
277 
278  duration&
279  operator--()
280  {
281  --__r;
282  return *this;
283  }
284 
285  duration
286  operator--(int)
287  { return duration(__r--); }
288 
289  duration&
290  operator+=(const duration& __d)
291  {
292  __r += __d.count();
293  return *this;
294  }
295 
296  duration&
297  operator-=(const duration& __d)
298  {
299  __r -= __d.count();
300  return *this;
301  }
302 
303  duration&
304  operator*=(const rep& __rhs)
305  {
306  __r *= __rhs;
307  return *this;
308  }
309 
310  duration&
311  operator/=(const rep& __rhs)
312  {
313  __r /= __rhs;
314  return *this;
315  }
316 
317  // DR 934.
318  template<typename _Rep2 = rep>
319  typename enable_if<!treat_as_floating_point<_Rep2>::value,
320  duration&>::type
321  operator%=(const rep& __rhs)
322  {
323  __r %= __rhs;
324  return *this;
325  }
326 
327  template<typename _Rep2 = rep>
328  typename enable_if<!treat_as_floating_point<_Rep2>::value,
329  duration&>::type
330  operator%=(const duration& __d)
331  {
332  __r %= __d.count();
333  return *this;
334  }
335 
336  // 20.8.3.4 special values
337  static constexpr duration
338  zero()
339  { return duration(duration_values<rep>::zero()); }
340 
341  static constexpr duration
342  min()
343  { return duration(duration_values<rep>::min()); }
344 
345  static constexpr duration
346  max()
347  { return duration(duration_values<rep>::max()); }
348 
349  private:
350  rep __r;
351  };
352 
353  template<typename _Rep1, typename _Period1,
354  typename _Rep2, typename _Period2>
355  inline typename common_type<duration<_Rep1, _Period1>,
356  duration<_Rep2, _Period2>>::type
357  operator+(const duration<_Rep1, _Period1>& __lhs,
358  const duration<_Rep2, _Period2>& __rhs)
359  {
360  typedef duration<_Rep1, _Period1> __dur1;
361  typedef duration<_Rep2, _Period2> __dur2;
362  typedef typename common_type<__dur1,__dur2>::type __ct;
363  return __ct(__lhs) += __rhs;
364  }
365 
366  template<typename _Rep1, typename _Period1,
367  typename _Rep2, typename _Period2>
368  inline typename common_type<duration<_Rep1, _Period1>,
369  duration<_Rep2, _Period2>>::type
370  operator-(const duration<_Rep1, _Period1>& __lhs,
371  const duration<_Rep2, _Period2>& __rhs)
372  {
373  typedef duration<_Rep1, _Period1> __dur1;
374  typedef duration<_Rep2, _Period2> __dur2;
375  typedef typename common_type<__dur1,__dur2>::type __ct;
376  return __ct(__lhs) -= __rhs;
377  }
378 
379  template<typename _Rep1, typename _Rep2, bool =
380  is_convertible<_Rep2,
381  typename common_type<_Rep1, _Rep2>::type>::value>
382  struct __common_rep_type { };
383 
384  template<typename _Rep1, typename _Rep2>
385  struct __common_rep_type<_Rep1, _Rep2, true>
386  { typedef typename common_type<_Rep1, _Rep2>::type type; };
387 
388  template<typename _Rep1, typename _Period, typename _Rep2>
389  inline duration<typename __common_rep_type<_Rep1, _Rep2>::type, _Period>
390  operator*(const duration<_Rep1, _Period>& __d, const _Rep2& __s)
391  {
392  typedef typename common_type<_Rep1, _Rep2>::type __cr;
393  return duration<__cr, _Period>(__d) *= __s;
394  }
395 
396  template<typename _Rep1, typename _Period, typename _Rep2>
397  inline duration<typename __common_rep_type<_Rep2, _Rep1>::type, _Period>
398  operator*(const _Rep1& __s, const duration<_Rep2, _Period>& __d)
399  { return __d * __s; }
400 
401  template<typename _Rep1, typename _Period, typename _Rep2>
402  inline duration<typename __common_rep_type<_Rep1, typename
403  enable_if<!__is_duration<_Rep2>::value, _Rep2>::type>::type, _Period>
404  operator/(const duration<_Rep1, _Period>& __d, const _Rep2& __s)
405  {
406  typedef typename common_type<_Rep1, _Rep2>::type __cr;
407  return duration<__cr, _Period>(__d) /= __s;
408  }
409 
410  template<typename _Rep1, typename _Period1,
411  typename _Rep2, typename _Period2>
412  inline typename common_type<_Rep1, _Rep2>::type
413  operator/(const duration<_Rep1, _Period1>& __lhs,
414  const duration<_Rep2, _Period2>& __rhs)
415  {
416  typedef duration<_Rep1, _Period1> __dur1;
417  typedef duration<_Rep2, _Period2> __dur2;
418  typedef typename common_type<__dur1,__dur2>::type __ct;
419  return __ct(__lhs).count() / __ct(__rhs).count();
420  }
421 
422  // DR 934.
423  template<typename _Rep1, typename _Period, typename _Rep2>
424  inline duration<typename __common_rep_type<_Rep1, typename
425  enable_if<!__is_duration<_Rep2>::value, _Rep2>::type>::type, _Period>
426  operator%(const duration<_Rep1, _Period>& __d, const _Rep2& __s)
427  {
428  typedef typename common_type<_Rep1, _Rep2>::type __cr;
429  return duration<__cr, _Period>(__d) %= __s;
430  }
431 
432  template<typename _Rep1, typename _Period1,
433  typename _Rep2, typename _Period2>
434  inline typename common_type<duration<_Rep1, _Period1>,
435  duration<_Rep2, _Period2>>::type
436  operator%(const duration<_Rep1, _Period1>& __lhs,
437  const duration<_Rep2, _Period2>& __rhs)
438  {
439  typedef duration<_Rep1, _Period1> __dur1;
440  typedef duration<_Rep2, _Period2> __dur2;
441  typedef typename common_type<__dur1,__dur2>::type __ct;
442  return __ct(__lhs) %= __rhs;
443  }
444 
445  // comparisons
446  template<typename _Rep1, typename _Period1,
447  typename _Rep2, typename _Period2>
448  inline constexpr bool
449  operator==(const duration<_Rep1, _Period1>& __lhs,
450  const duration<_Rep2, _Period2>& __rhs)
451  {
452  typedef duration<_Rep1, _Period1> __dur1;
453  typedef duration<_Rep2, _Period2> __dur2;
454  typedef typename common_type<__dur1,__dur2>::type __ct;
455  return __ct(__lhs).count() == __ct(__rhs).count();
456  }
457 
458  template<typename _Rep1, typename _Period1,
459  typename _Rep2, typename _Period2>
460  inline constexpr bool
461  operator<(const duration<_Rep1, _Period1>& __lhs,
462  const duration<_Rep2, _Period2>& __rhs)
463  {
464  typedef duration<_Rep1, _Period1> __dur1;
465  typedef duration<_Rep2, _Period2> __dur2;
466  typedef typename common_type<__dur1,__dur2>::type __ct;
467  return __ct(__lhs).count() < __ct(__rhs).count();
468  }
469 
470  template<typename _Rep1, typename _Period1,
471  typename _Rep2, typename _Period2>
472  inline constexpr bool
473  operator!=(const duration<_Rep1, _Period1>& __lhs,
474  const duration<_Rep2, _Period2>& __rhs)
475  { return !(__lhs == __rhs); }
476 
477  template<typename _Rep1, typename _Period1,
478  typename _Rep2, typename _Period2>
479  inline constexpr bool
480  operator<=(const duration<_Rep1, _Period1>& __lhs,
481  const duration<_Rep2, _Period2>& __rhs)
482  { return !(__rhs < __lhs); }
483 
484  template<typename _Rep1, typename _Period1,
485  typename _Rep2, typename _Period2>
486  inline constexpr bool
487  operator>(const duration<_Rep1, _Period1>& __lhs,
488  const duration<_Rep2, _Period2>& __rhs)
489  { return __rhs < __lhs; }
490 
491  template<typename _Rep1, typename _Period1,
492  typename _Rep2, typename _Period2>
493  inline constexpr bool
494  operator>=(const duration<_Rep1, _Period1>& __lhs,
495  const duration<_Rep2, _Period2>& __rhs)
496  { return !(__lhs < __rhs); }
497 
498  /// nanoseconds
500 
501  /// microseconds
503 
504  /// milliseconds
506 
507  /// seconds
509 
510  /// minutes
512 
513  /// hours
515 
516  /// time_point
517  template<typename _Clock, typename _Dur>
518  struct time_point
519  {
520  typedef _Clock clock;
521  typedef _Dur duration;
522  typedef typename duration::rep rep;
523  typedef typename duration::period period;
524 
525  constexpr time_point() : __d(duration::zero())
526  { }
527 
528  constexpr explicit time_point(const duration& __dur)
529  : __d(__dur)
530  { }
531 
532  // conversions
533  template<typename _Dur2>
534  constexpr time_point(const time_point<clock, _Dur2>& __t)
535  : __d(__t.time_since_epoch())
536  { }
537 
538  // observer
539  constexpr duration
540  time_since_epoch() const
541  { return __d; }
542 
543  // arithmetic
544  time_point&
545  operator+=(const duration& __dur)
546  {
547  __d += __dur;
548  return *this;
549  }
550 
551  time_point&
552  operator-=(const duration& __dur)
553  {
554  __d -= __dur;
555  return *this;
556  }
557 
558  // special values
559  static constexpr time_point
560  min()
561  { return time_point(duration::min()); }
562 
563  static constexpr time_point
564  max()
565  { return time_point(duration::max()); }
566 
567  private:
568  duration __d;
569  };
570 
571  /// time_point_cast
572  template<typename _ToDur, typename _Clock, typename _Dur>
573  inline constexpr typename enable_if<__is_duration<_ToDur>::value,
574  time_point<_Clock, _ToDur>>::type
576  {
577  typedef time_point<_Clock, _ToDur> __time_point;
578  return __time_point(duration_cast<_ToDur>(__t.time_since_epoch()));
579  }
580 
581  template<typename _Clock, typename _Dur1,
582  typename _Rep2, typename _Period2>
583  inline time_point<_Clock,
585  operator+(const time_point<_Clock, _Dur1>& __lhs,
586  const duration<_Rep2, _Period2>& __rhs)
587  {
588  typedef duration<_Rep2, _Period2> __dur2;
589  typedef typename common_type<_Dur1,__dur2>::type __ct;
590  typedef time_point<_Clock, __ct> __time_point;
591  return __time_point(__lhs) += __rhs;
592  }
593 
594  template<typename _Rep1, typename _Period1,
595  typename _Clock, typename _Dur2>
596  inline time_point<_Clock,
597  typename common_type<duration<_Rep1, _Period1>, _Dur2>::type>
598  operator+(const duration<_Rep1, _Period1>& __lhs,
599  const time_point<_Clock, _Dur2>& __rhs)
600  { return __rhs + __lhs; }
601 
602  template<typename _Clock, typename _Dur1,
603  typename _Rep2, typename _Period2>
604  inline time_point<_Clock,
605  typename common_type<_Dur1, duration<_Rep2, _Period2>>::type>
606  operator-(const time_point<_Clock, _Dur1>& __lhs,
607  const duration<_Rep2, _Period2>& __rhs)
608  { return __lhs + (-__rhs); }
609 
610  template<typename _Clock, typename _Dur1, typename _Dur2>
611  inline typename common_type<_Dur1, _Dur2>::type
612  operator-(const time_point<_Clock, _Dur1>& __lhs,
613  const time_point<_Clock, _Dur2>& __rhs)
614  { return __lhs.time_since_epoch() - __rhs.time_since_epoch(); }
615 
616  template<typename _Clock, typename _Dur1, typename _Dur2>
617  inline constexpr bool
618  operator==(const time_point<_Clock, _Dur1>& __lhs,
619  const time_point<_Clock, _Dur2>& __rhs)
620  { return __lhs.time_since_epoch() == __rhs.time_since_epoch(); }
621 
622  template<typename _Clock, typename _Dur1, typename _Dur2>
623  inline constexpr bool
624  operator!=(const time_point<_Clock, _Dur1>& __lhs,
625  const time_point<_Clock, _Dur2>& __rhs)
626  { return !(__lhs == __rhs); }
627 
628  template<typename _Clock, typename _Dur1, typename _Dur2>
629  inline constexpr bool
630  operator<(const time_point<_Clock, _Dur1>& __lhs,
631  const time_point<_Clock, _Dur2>& __rhs)
632  { return __lhs.time_since_epoch() < __rhs.time_since_epoch(); }
633 
634  template<typename _Clock, typename _Dur1, typename _Dur2>
635  inline constexpr bool
636  operator<=(const time_point<_Clock, _Dur1>& __lhs,
637  const time_point<_Clock, _Dur2>& __rhs)
638  { return !(__rhs < __lhs); }
639 
640  template<typename _Clock, typename _Dur1, typename _Dur2>
641  inline constexpr bool
642  operator>(const time_point<_Clock, _Dur1>& __lhs,
643  const time_point<_Clock, _Dur2>& __rhs)
644  { return __rhs < __lhs; }
645 
646  template<typename _Clock, typename _Dur1, typename _Dur2>
647  inline constexpr bool
648  operator>=(const time_point<_Clock, _Dur1>& __lhs,
649  const time_point<_Clock, _Dur2>& __rhs)
650  { return !(__lhs < __rhs); }
651 
652  /// system_clock
654  {
655 #ifdef _GLIBCXX_USE_CLOCK_REALTIME
657 #elif defined(_GLIBCXX_USE_GETTIMEOFDAY)
659 #else
660  typedef chrono::seconds duration;
661 #endif
662 
663  typedef duration::rep rep;
664  typedef duration::period period;
666 
667  static_assert(system_clock::duration::min()
668  < system_clock::duration::zero(),
669  "a clock's minimum duration cannot be less than its epoch");
670 
671  static constexpr bool is_monotonic = false;
672 
673  static time_point
674  now() throw ();
675 
676  // Map to C API
677  static std::time_t
678  to_time_t(const time_point& __t)
679  {
680  return std::time_t(duration_cast<chrono::seconds>
681  (__t.time_since_epoch()).count());
682  }
683 
684  static time_point
685  from_time_t(std::time_t __t)
686  {
689  (__from(chrono::seconds(__t)));
690  }
691  };
692 
693 #ifdef _GLIBCXX_USE_CLOCK_MONOTONIC
694  /// monotonic_clock
695  struct monotonic_clock
696  {
698  typedef duration::rep rep;
699  typedef duration::period period;
701 
702  static constexpr bool is_monotonic = true;
703 
704  static time_point
705  now();
706  };
707 #else
708  typedef system_clock monotonic_clock;
709 #endif
710 
711  typedef system_clock high_resolution_clock;
712 
713  _GLIBCXX_END_NAMESPACE_VERSION
714  } // namespace chrono
715 
716  // @} group chrono
717 } // namespace
718 
719 #endif //_GLIBCXX_USE_C99_STDINT_TR1
720 
721 #endif //__GXX_EXPERIMENTAL_CXX0X__
722 
723 #endif //_GLIBCXX_CHRONO