libstdc++
chrono
Go to the documentation of this file.
1 // <chrono> -*- C++ -*-
2 
3 // Copyright (C) 2008, 2009 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 <c++0x_warning.h>
36 #else
37 
38 #ifdef _GLIBCXX_INCLUDE_AS_TR1
39 # error C++0x header cannot be included from TR1 header
40 #endif
41 
42 #include <ratio>
43 #include <type_traits>
44 #include <limits>
45 #include <ctime>
46 
47 #ifdef _GLIBCXX_USE_C99_STDINT_TR1
48 
49 namespace std
50 {
51  /**
52  * @defgroup chrono Time
53  * @ingroup utilities
54  *
55  * Classes and functions for time.
56  * @{
57  */
58 
59  /** @namespace std::chrono
60  * @brief ISO C++ 0x entities sub namespace for time and date.
61  */
62  namespace chrono
63  {
64  template<typename _Rep, typename _Period = ratio<1>>
65  struct duration;
66 
67  template<typename _Clock, typename _Duration = typename _Clock::duration>
68  struct time_point;
69  }
70 
71  // 20.8.2.3 specialization of common_type (for duration)
72  template<typename _Rep1, typename _Period1, typename _Rep2, typename _Period2>
73  struct common_type<chrono::duration<_Rep1, _Period1>,
74  chrono::duration<_Rep2, _Period2>>
75  {
76  typedef chrono::duration<typename common_type<_Rep1, _Rep2>::type,
77  ratio<__static_gcd<_Period1::num, _Period2::num>::value,
78  (_Period1::den / __static_gcd<_Period1::den, _Period2::den>::value)
79  * _Period2::den>> type;
80  };
81 
82  // 20.8.2.3 specialization of common_type (for time_point)
83  template<typename _Clock, typename _Duration1, typename _Duration2>
84  struct common_type<chrono::time_point<_Clock, _Duration1>,
85  chrono::time_point<_Clock, _Duration2>>
86  {
87  typedef chrono::time_point<_Clock,
88  typename common_type<_Duration1, _Duration2>::type> type;
89  };
90 
91  namespace chrono
92  {
93  // Primary template for duration_cast impl.
94  template<typename _ToDuration, typename _CF, typename _CR,
95  bool _NumIsOne = false, bool _DenIsOne = false>
96  struct __duration_cast_impl
97  {
98  template<typename _Rep, typename _Period>
99  static _ToDuration __cast(const duration<_Rep, _Period>& __d)
100  {
101  return _ToDuration(static_cast<
102  typename _ToDuration::rep>(static_cast<_CR>(__d.count())
103  * static_cast<_CR>(_CF::num)
104  / static_cast<_CR>(_CF::den)));
105  }
106  };
107 
108  template<typename _ToDuration, typename _CF, typename _CR>
109  struct __duration_cast_impl<_ToDuration, _CF, _CR, true, true>
110  {
111  template<typename _Rep, typename _Period>
112  static _ToDuration __cast(const duration<_Rep, _Period>& __d)
113  {
114  return _ToDuration(
115  static_cast<typename _ToDuration::rep>(__d.count()));
116  }
117  };
118 
119  template<typename _ToDuration, typename _CF, typename _CR>
120  struct __duration_cast_impl<_ToDuration, _CF, _CR, true, false>
121  {
122  template<typename _Rep, typename _Period>
123  static _ToDuration __cast(const duration<_Rep, _Period>& __d)
124  {
125  return _ToDuration(static_cast<typename _ToDuration::rep>(
126  static_cast<_CR>(__d.count()) / static_cast<_CR>(_CF::den)));
127  }
128  };
129 
130  template<typename _ToDuration, typename _CF, typename _CR>
131  struct __duration_cast_impl<_ToDuration, _CF, _CR, false, true>
132  {
133  template<typename _Rep, typename _Period>
134  static _ToDuration __cast(const duration<_Rep, _Period>& __d)
135  {
136  return _ToDuration(static_cast<typename _ToDuration::rep>(
137  static_cast<_CR>(__d.count()) * static_cast<_CR>(_CF::num)));
138  }
139  };
140 
141  /// duration_cast
142  template<typename _ToDuration, typename _Rep, typename _Period>
143  inline _ToDuration
145  {
146  typedef typename
148  typedef typename
149  common_type<typename _ToDuration::rep, _Rep, intmax_t>::type __cr;
150 
151  return __duration_cast_impl<_ToDuration, __cf, __cr,
152  __cf::num == 1, __cf::den == 1>::__cast(__d);
153  }
154 
155  /// treat_as_floating_point
156  template<typename _Rep>
158  : is_floating_point<_Rep>
159  { };
160 
161  /// duration_values
162  template<typename _Rep>
164  {
165  static const _Rep
166  zero()
167  { return _Rep(0); }
168 
169  static const _Rep
170  max()
171  { return numeric_limits<_Rep>::max(); }
172 
173  static const _Rep
174  min()
175  { return numeric_limits<_Rep>::min(); }
176  };
177 
178  template<typename _Tp>
179  struct __is_duration
181  { };
182 
183  template<typename _Rep, typename _Period>
184  struct __is_duration<duration<_Rep, _Period>>
186  { };
187 
188  template<typename T>
189  struct __is_ratio
191  { };
192 
193  template<intmax_t _Num, intmax_t _Den>
194  struct __is_ratio<ratio<_Num, _Den>>
196  { };
197 
198  /// duration
199  template<typename _Rep, typename _Period>
200  struct duration
201  {
202  static_assert(!__is_duration<_Rep>::value, "rep cannot be a duration");
203  static_assert(__is_ratio<_Period>::value,
204  "period must be a specialization of ratio");
205  static_assert(_Period::num > 0, "period must be positive");
206 
207  typedef _Rep rep;
208  typedef _Period period;
209 
210  // 20.8.3.1 construction / copy / destroy
211  duration() = default;
212 
213  template<typename _Rep2>
214  explicit duration(_Rep2 const& __rep)
215  : __r(static_cast<rep>(__rep))
216  {
217  static_assert(is_convertible<_Rep2,rep>::value
220  "cannot construct integral duration with floating point type");
221  }
222 
223  template<typename _Rep2, typename _Period2>
225  : __r(duration_cast<duration>(__d).count())
226  {
227  static_assert(treat_as_floating_point<rep>::value == true
229  "the resulting duration is not exactly representable");
230  }
231 
232  ~duration() = default;
233  duration(const duration&) = default;
234  duration& operator=(const duration&) = default;
235 
236  // 20.8.3.2 observer
237  rep
238  count() const
239  { return __r; }
240 
241  // 20.8.3.3 arithmetic
242  duration
243  operator+() const
244  { return *this; }
245 
246  duration
247  operator-() const
248  { return duration(-__r); }
249 
250  duration&
251  operator++()
252  {
253  ++__r;
254  return *this;
255  }
256 
257  duration
258  operator++(int)
259  { return duration(__r++); }
260 
261  duration&
262  operator--()
263  {
264  --__r;
265  return *this;
266  }
267 
268  duration
269  operator--(int)
270  { return duration(__r--); }
271 
272  duration&
273  operator+=(const duration& __d)
274  {
275  __r += __d.count();
276  return *this;
277  }
278 
279  duration&
280  operator-=(const duration& __d)
281  {
282  __r -= __d.count();
283  return *this;
284  }
285 
286  duration&
287  operator*=(const rep& __rhs)
288  {
289  __r *= __rhs;
290  return *this;
291  }
292 
293  duration&
294  operator/=(const rep& __rhs)
295  {
296  __r /= __rhs;
297  return *this;
298  }
299 
300  // 20.8.3.4 special values
301  // TODO: These should be constexprs.
302  static const duration
303  zero()
304  { return duration(duration_values<rep>::zero()); }
305 
306  static const duration
307  min()
308  { return duration(duration_values<rep>::min()); }
309 
310  static const duration
311  max()
312  { return duration(duration_values<rep>::max()); }
313 
314  private:
315  rep __r;
316  };
317 
318  template<typename _Rep1, typename _Period1,
319  typename _Rep2, typename _Period2>
320  inline typename common_type<duration<_Rep1, _Period1>,
322  operator+(const duration<_Rep1, _Period1>& __lhs,
323  const duration<_Rep2, _Period2>& __rhs)
324  {
325  typedef typename common_type<duration<_Rep1, _Period1>,
326  duration<_Rep2, _Period2>>::type __ct;
327  return __ct(__lhs) += __rhs;
328  }
329 
330  template<typename _Rep1, typename _Period1,
331  typename _Rep2, typename _Period2>
332  inline typename common_type<duration<_Rep1, _Period1>,
333  duration<_Rep2, _Period2>>::type
334  operator-(const duration<_Rep1, _Period1>& __lhs,
335  const duration<_Rep2, _Period2>& __rhs)
336  {
337  typedef typename common_type<duration<_Rep1, _Period1>,
338  duration<_Rep2, _Period2>>::type __ct;
339  return __ct(__lhs) -= __rhs;
340  }
341 
342  template<typename _Rep1, typename _Period, typename _Rep2>
343  inline duration<typename common_type<_Rep1, _Rep2>::type, _Period>
344  operator*(const duration<_Rep1, _Period>& __d, const _Rep2& __s)
345  {
346  typedef typename common_type<_Rep1, _Rep2>::type __cr;
347  return duration<__cr, _Period>(__d) *= __s;
348  }
349 
350  template<typename _Rep1, typename _Period, typename _Rep2>
351  inline duration<typename common_type<_Rep1, _Rep2>::type, _Period>
352  operator*(const _Rep2& __s, const duration<_Rep1, _Period>& __d)
353  { return __d * __s; }
354 
355  template<typename _Tp, typename _Up, typename _Ep = void>
356  struct __division_impl;
357 
358  template<typename _Rep1, typename _Period, typename _Rep2>
359  struct __division_impl<duration<_Rep1, _Period>, _Rep2,
360  typename enable_if<!__is_duration<_Rep2>::value>::type>
361  {
362  typedef typename common_type<_Rep1, _Rep2>::type __cr;
363  typedef
364  duration<typename common_type<_Rep1, _Rep2>::type, _Period> __rt;
365 
366  static __rt
367  __divide(const duration<_Rep1, _Period>& __d, const _Rep2& __s)
368  { return duration<__cr, _Period>(__d) /= __s; }
369  };
370 
371  template<typename _Rep1, typename _Period1,
372  typename _Rep2, typename _Period2>
373  struct __division_impl<duration<_Rep1, _Period1>,
374  duration<_Rep2, _Period2>>
375  {
376  typedef typename common_type<duration<_Rep1, _Period1>,
377  duration<_Rep2, _Period2>>::type __ct;
378  typedef typename common_type<_Rep1, _Rep2>::type __rt;
379 
380  static __rt
381  __divide(const duration<_Rep1, _Period1>& __lhs,
382  const duration<_Rep2, _Period2>& __rhs)
383  { return __ct(__lhs).count() / __ct(__rhs).count(); }
384  };
385 
386  template<typename _Rep, typename _Period, typename _Up>
387  inline typename __division_impl<duration<_Rep, _Period>, _Up>::__rt
388  operator/(const duration<_Rep, _Period>& __d, const _Up& __u)
389  {
390  return
391  __division_impl<duration<_Rep, _Period>, _Up>::__divide(__d, __u);
392  }
393 
394  // comparisons
395  template<typename _Rep1, typename _Period1,
396  typename _Rep2, typename _Period2>
397  inline bool
398  operator==(const duration<_Rep1, _Period1>& __lhs,
399  const duration<_Rep2, _Period2>& __rhs)
400  {
401  typedef typename common_type<duration<_Rep1, _Period1>,
402  duration<_Rep2, _Period2>>::type __ct;
403  return __ct(__lhs).count() == __ct(__rhs).count();
404  }
405 
406  template<typename _Rep1, typename _Period1,
407  typename _Rep2, typename _Period2>
408  inline bool
409  operator<(const duration<_Rep1, _Period1>& __lhs,
410  const duration<_Rep2, _Period2>& __rhs)
411  {
412  typedef typename common_type<duration<_Rep1, _Period1>,
413  duration<_Rep2, _Period2>>::type __ct;
414  return __ct(__lhs).count() < __ct(__rhs).count();
415  }
416 
417  template<typename _Rep1, typename _Period1,
418  typename _Rep2, typename _Period2>
419  inline bool
420  operator!=(const duration<_Rep1, _Period1>& __lhs,
421  const duration<_Rep2, _Period2>& __rhs)
422  { return !(__lhs == __rhs); }
423 
424  template<typename _Rep1, typename _Period1,
425  typename _Rep2, typename _Period2>
426  inline bool
427  operator<=(const duration<_Rep1, _Period1>& __lhs,
428  const duration<_Rep2, _Period2>& __rhs)
429  { return !(__rhs < __lhs); }
430 
431  template<typename _Rep1, typename _Period1,
432  typename _Rep2, typename _Period2>
433  inline bool
434  operator>(const duration<_Rep1, _Period1>& __lhs,
435  const duration<_Rep2, _Period2>& __rhs)
436  { return __rhs < __lhs; }
437 
438  template<typename _Rep1, typename _Period1,
439  typename _Rep2, typename _Period2>
440  inline bool
441  operator>=(const duration<_Rep1, _Period1>& __lhs,
442  const duration<_Rep2, _Period2>& __rhs)
443  { return !(__lhs < __rhs); }
444 
445  /// nanoseconds
447 
448  /// microseconds
450 
451  /// milliseconds
453 
454  /// seconds
456 
457  /// minutes
459 
460  /// hours
462 
463  /// time_point
464  template<typename _Clock, typename _Duration>
465  struct time_point
466  {
467  typedef _Clock clock;
468  typedef _Duration duration;
469  typedef typename duration::rep rep;
470  typedef typename duration::period period;
471 
472  time_point() : __d(duration::zero())
473  { }
474 
475  explicit time_point(const duration& __dur)
476  : __d(duration::zero() + __dur)
477  { }
478 
479  // conversions
480  template<typename _Duration2>
482  : __d(__t.time_since_epoch())
483  { }
484 
485  // observer
486  duration
487  time_since_epoch() const
488  { return __d; }
489 
490  // arithmetic
491  time_point&
492  operator+=(const duration& __dur)
493  {
494  __d += __dur;
495  return *this;
496  }
497 
498  time_point&
499  operator-=(const duration& __dur)
500  {
501  __d -= __dur;
502  return *this;
503  }
504 
505  // special values
506  // TODO: These should be constexprs.
507  static const time_point
508  min()
509  { return time_point(duration::min()); }
510 
511  static const time_point
512  max()
513  { return time_point(duration::max()); }
514 
515  private:
516  duration __d;
517  };
518 
519  /// time_point_cast
520  template<typename _ToDuration, typename _Clock, typename _Duration>
523  {
525  duration_cast<_ToDuration>(__t.time_since_epoch()));
526  }
527 
528  template<typename _Clock, typename _Duration1,
529  typename _Rep2, typename _Period2>
530  inline time_point<_Clock,
531  typename common_type<_Duration1, duration<_Rep2, _Period2>>::type>
532  operator+(const time_point<_Clock, _Duration1>& __lhs,
533  const duration<_Rep2, _Period2>& __rhs)
534  {
535  typedef time_point<_Clock,
536  typename common_type<_Duration1,
537  duration<_Rep2, _Period2>>::type> __ct;
538  return __ct(__lhs) += __rhs;
539  }
540 
541  template<typename _Rep1, typename _Period1,
542  typename _Clock, typename _Duration2>
543  inline time_point<_Clock,
544  typename common_type<duration<_Rep1, _Period1>, _Duration2>::type>
545  operator+(const duration<_Rep1, _Period1>& __lhs,
546  const time_point<_Clock, _Duration2>& __rhs)
547  { return __rhs + __lhs; }
548 
549  template<typename _Clock, typename _Duration1,
550  typename _Rep2, typename _Period2>
551  inline time_point<_Clock,
552  typename common_type<_Duration1, duration<_Rep2, _Period2>>::type>
553  operator-(const time_point<_Clock, _Duration1>& __lhs,
554  const duration<_Rep2, _Period2>& __rhs)
555  { return __lhs + (-__rhs); }
556 
557  template<typename _Clock, typename _Duration1, typename _Duration2>
558  inline typename common_type<_Duration1, _Duration2>::type
559  operator-(const time_point<_Clock, _Duration1>& __lhs,
560  const time_point<_Clock, _Duration2>& __rhs)
561  { return __lhs.time_since_epoch() - __rhs.time_since_epoch(); }
562 
563  template<typename _Clock, typename _Duration1, typename _Duration2>
564  inline bool
565  operator==(const time_point<_Clock, _Duration1>& __lhs,
566  const time_point<_Clock, _Duration2>& __rhs)
567  { return __lhs.time_since_epoch() == __rhs.time_since_epoch(); }
568 
569  template<typename _Clock, typename _Duration1, typename _Duration2>
570  inline bool
571  operator!=(const time_point<_Clock, _Duration1>& __lhs,
572  const time_point<_Clock, _Duration2>& __rhs)
573  { return !(__lhs == __rhs); }
574 
575  template<typename _Clock, typename _Duration1, typename _Duration2>
576  inline bool
577  operator<(const time_point<_Clock, _Duration1>& __lhs,
578  const time_point<_Clock, _Duration2>& __rhs)
579  { return __lhs.time_since_epoch() < __rhs.time_since_epoch(); }
580 
581  template<typename _Clock, typename _Duration1, typename _Duration2>
582  inline bool
583  operator<=(const time_point<_Clock, _Duration1>& __lhs,
584  const time_point<_Clock, _Duration2>& __rhs)
585  { return !(__rhs < __lhs); }
586 
587  template<typename _Clock, typename _Duration1, typename _Duration2>
588  inline bool
589  operator>(const time_point<_Clock, _Duration1>& __lhs,
590  const time_point<_Clock, _Duration2>& __rhs)
591  { return __rhs < __lhs; }
592 
593  template<typename _Clock, typename _Duration1, typename _Duration2>
594  inline bool
595  operator>=(const time_point<_Clock, _Duration1>& __lhs,
596  const time_point<_Clock, _Duration2>& __rhs)
597  { return !(__lhs < __rhs); }
598 
599  /// system_clock
601  {
602 #ifdef _GLIBCXX_USE_CLOCK_REALTIME
603  typedef chrono::nanoseconds duration;
604 #elif defined(_GLIBCXX_USE_GETTIMEOFDAY)
606 #else
607  typedef chrono::seconds duration;
608 #endif
609 
610  typedef duration::rep rep;
611  typedef duration::period period;
613 
614  static const bool is_monotonic = false;
615 
616  static time_point
617  now();
618 
619  // Map to C API
620  static std::time_t
621  to_time_t(const time_point& __t)
622  {
623  return std::time_t(
624  duration_cast<chrono::seconds>(__t.time_since_epoch()).count());
625  }
626 
627  static time_point
628  from_time_t(std::time_t __t)
629  {
632  chrono::seconds(__t)));
633  }
634 
635  // TODO: requires constexpr
636  /*
637  static_assert(
638  system_clock::duration::min() <
639  system_clock::duration::zero(),
640  "a clock's minimum duration cannot be less than its epoch");
641  */
642  };
643 
644 #ifdef _GLIBCXX_USE_CLOCK_MONOTONIC
645  /// monotonic_clock
646  struct monotonic_clock
647  {
649  typedef duration::rep rep;
650  typedef duration::period period;
652 
653  static const bool is_monotonic = true;
654 
655  static time_point
656  now();
657  };
658 #else
659  typedef system_clock monotonic_clock;
660 #endif
661 
662  typedef system_clock high_resolution_clock;
663  } // namespace chrono
664 
665  // @} group chrono
666 } // namespace std
667 
668 #endif //_GLIBCXX_USE_C99_STDINT_TR1
669 
670 #endif //__GXX_EXPERIMENTAL_CXX0X__
671 
672 #endif //_GLIBCXX_CHRONO