1 // <chrono> -*- C++ -*-
3 // Copyright (C) 2008, 2009, 2010 Free Software Foundation, Inc.
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)
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.
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.
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/>.
25 /** @file include/chrono
26 * This is a Standard C++ Library header.
29 #ifndef _GLIBCXX_CHRONO
30 #define _GLIBCXX_CHRONO 1
32 #pragma GCC system_header
34 #ifndef __GXX_EXPERIMENTAL_CXX0X__
35 # include <bits/c++0x_warning.h>
39 #include <type_traits>
43 #ifdef _GLIBCXX_USE_C99_STDINT_TR1
45 _GLIBCXX_BEGIN_NAMESPACE(std)
48 * @defgroup chrono Time
51 * Classes and functions for time.
55 /** @namespace std::chrono
56 * @brief ISO C++ 0x entities sub namespace for time and date.
60 template<typename _Rep, typename _Period = ratio<1>>
63 template<typename _Clock, typename _Dur = typename _Clock::duration>
67 // 20.8.2.3 specialization of common_type (for duration)
68 template<typename _Rep1, typename _Period1, typename _Rep2, typename _Period2>
69 struct common_type<chrono::duration<_Rep1, _Period1>,
70 chrono::duration<_Rep2, _Period2>>
73 typedef __static_gcd<_Period1::num, _Period2::num> __gcd_num;
74 typedef __static_gcd<_Period1::den, _Period2::den> __gcd_den;
75 typedef typename common_type<_Rep1, _Rep2>::type __cr;
76 typedef ratio<__gcd_num::value,
77 (_Period1::den / __gcd_den::value) * _Period2::den> __r;
80 typedef chrono::duration<__cr, __r> type;
83 // 20.8.2.3 specialization of common_type (for time_point)
84 template<typename _Clock, typename _Dur1, typename _Dur2>
85 struct common_type<chrono::time_point<_Clock, _Dur1>,
86 chrono::time_point<_Clock, _Dur2>>
89 typedef typename common_type<_Dur1, _Dur2>::type __ct;
92 typedef chrono::time_point<_Clock, __ct> type;
97 // Primary template for duration_cast impl.
98 template<typename _ToDur, typename _CF, typename _CR,
99 bool _NumIsOne = false, bool _DenIsOne = false>
100 struct __duration_cast_impl
102 template<typename _Rep, typename _Period>
103 static constexpr _ToDur
104 __cast(const duration<_Rep, _Period>& __d)
106 typedef typename _ToDur::rep __to_rep;
107 return _ToDur(static_cast<__to_rep>(static_cast<_CR>(__d.count())
108 * static_cast<_CR>(_CF::num)
109 / static_cast<_CR>(_CF::den)));
113 template<typename _ToDur, typename _CF, typename _CR>
114 struct __duration_cast_impl<_ToDur, _CF, _CR, true, true>
116 template<typename _Rep, typename _Period>
117 static constexpr _ToDur
118 __cast(const duration<_Rep, _Period>& __d)
120 typedef typename _ToDur::rep __to_rep;
121 return _ToDur(static_cast<__to_rep>(__d.count()));
125 template<typename _ToDur, typename _CF, typename _CR>
126 struct __duration_cast_impl<_ToDur, _CF, _CR, true, false>
128 template<typename _Rep, typename _Period>
129 static constexpr _ToDur
130 __cast(const duration<_Rep, _Period>& __d)
132 typedef typename _ToDur::rep __to_rep;
133 return _ToDur(static_cast<__to_rep>(
134 static_cast<_CR>(__d.count()) / static_cast<_CR>(_CF::den)));
138 template<typename _ToDur, typename _CF, typename _CR>
139 struct __duration_cast_impl<_ToDur, _CF, _CR, false, true>
141 template<typename _Rep, typename _Period>
142 static constexpr _ToDur
143 __cast(const duration<_Rep, _Period>& __d)
145 typedef typename _ToDur::rep __to_rep;
146 return _ToDur(static_cast<__to_rep>(
147 static_cast<_CR>(__d.count()) * static_cast<_CR>(_CF::num)));
151 template<typename _Tp>
156 template<typename _Rep, typename _Period>
157 struct __is_duration<duration<_Rep, _Period>>
162 template<typename _ToDur, typename _Rep, typename _Period>
163 inline constexpr typename enable_if<__is_duration<_ToDur>::value,
165 duration_cast(const duration<_Rep, _Period>& __d)
167 typedef typename _ToDur::period __to_period;
168 typedef typename _ToDur::rep __to_rep;
169 typedef ratio_divide<_Period, __to_period> __r_div;
170 typedef typename __r_div::type __cf;
171 typedef typename common_type<__to_rep, _Rep, intmax_t>::type
173 typedef __duration_cast_impl<_ToDur, __cf, __cr,
174 __cf::num == 1, __cf::den == 1> __dc;
175 return __dc::__cast(__d);
178 /// treat_as_floating_point
179 template<typename _Rep>
180 struct treat_as_floating_point
181 : is_floating_point<_Rep>
185 template<typename _Rep>
186 struct duration_values
188 static constexpr _Rep
192 static constexpr _Rep
194 { return numeric_limits<_Rep>::max(); }
196 static constexpr _Rep
198 { return numeric_limits<_Rep>::min(); }
206 template<intmax_t _Num, intmax_t _Den>
207 struct __is_ratio<ratio<_Num, _Den>>
212 template<typename _Rep, typename _Period>
216 typedef _Period period;
218 static_assert(!__is_duration<_Rep>::value, "rep cannot be a duration");
219 static_assert(__is_ratio<_Period>::value,
220 "period must be a specialization of ratio");
221 static_assert(_Period::num > 0, "period must be positive");
223 // 20.8.3.1 construction / copy / destroy
224 constexpr duration() : __r() { }
226 template<typename _Rep2, typename = typename
227 enable_if<is_convertible<_Rep2, rep>::value
228 && (treat_as_floating_point<rep>::value
229 || !treat_as_floating_point<_Rep2>::value)>::type>
230 constexpr explicit duration(const _Rep2& __rep)
231 : __r(static_cast<rep>(__rep)) { }
233 template<typename _Rep2, typename _Period2, typename = typename
234 enable_if<treat_as_floating_point<rep>::value
235 || (ratio_divide<_Period2, period>::type::den == 1
236 && !treat_as_floating_point<_Rep2>::value)>::type>
237 constexpr duration(const duration<_Rep2, _Period2>& __d)
238 : __r(duration_cast<duration>(__d).count()) { }
240 ~duration() = default;
241 duration(const duration&) = default;
242 duration& operator=(const duration&) = default;
249 // 20.8.3.3 arithmetic
256 { return duration(-__r); }
267 { return duration(__r++); }
278 { return duration(__r--); }
281 operator+=(const duration& __d)
288 operator-=(const duration& __d)
295 operator*=(const rep& __rhs)
302 operator/=(const rep& __rhs)
309 template<typename _Rep2 = rep>
310 typename enable_if<!treat_as_floating_point<_Rep2>::value,
312 operator%=(const rep& __rhs)
318 template<typename _Rep2 = rep>
319 typename enable_if<!treat_as_floating_point<_Rep2>::value,
321 operator%=(const duration& __d)
327 // 20.8.3.4 special values
328 static constexpr duration
330 { return duration(duration_values<rep>::zero()); }
332 static constexpr duration
334 { return duration(duration_values<rep>::min()); }
336 static constexpr duration
338 { return duration(duration_values<rep>::max()); }
344 template<typename _Rep1, typename _Period1,
345 typename _Rep2, typename _Period2>
346 inline typename common_type<duration<_Rep1, _Period1>,
347 duration<_Rep2, _Period2>>::type
348 operator+(const duration<_Rep1, _Period1>& __lhs,
349 const duration<_Rep2, _Period2>& __rhs)
351 typedef duration<_Rep1, _Period1> __dur1;
352 typedef duration<_Rep2, _Period2> __dur2;
353 typedef typename common_type<__dur1,__dur2>::type __ct;
354 return __ct(__lhs) += __rhs;
357 template<typename _Rep1, typename _Period1,
358 typename _Rep2, typename _Period2>
359 inline typename common_type<duration<_Rep1, _Period1>,
360 duration<_Rep2, _Period2>>::type
361 operator-(const duration<_Rep1, _Period1>& __lhs,
362 const duration<_Rep2, _Period2>& __rhs)
364 typedef duration<_Rep1, _Period1> __dur1;
365 typedef duration<_Rep2, _Period2> __dur2;
366 typedef typename common_type<__dur1,__dur2>::type __ct;
367 return __ct(__lhs) -= __rhs;
370 template<typename _Rep1, typename _Rep2, bool =
371 is_convertible<_Rep2,
372 typename common_type<_Rep1, _Rep2>::type>::value>
373 struct __common_rep_type { };
375 template<typename _Rep1, typename _Rep2>
376 struct __common_rep_type<_Rep1, _Rep2, true>
377 { typedef typename common_type<_Rep1, _Rep2>::type type; };
379 template<typename _Rep1, typename _Period, typename _Rep2>
380 inline duration<typename __common_rep_type<_Rep1, _Rep2>::type, _Period>
381 operator*(const duration<_Rep1, _Period>& __d, const _Rep2& __s)
383 typedef typename common_type<_Rep1, _Rep2>::type __cr;
384 return duration<__cr, _Period>(__d) *= __s;
387 template<typename _Rep1, typename _Period, typename _Rep2>
388 inline duration<typename __common_rep_type<_Rep2, _Rep1>::type, _Period>
389 operator*(const _Rep1& __s, const duration<_Rep2, _Period>& __d)
390 { return __d * __s; }
392 template<typename _Rep1, typename _Period, typename _Rep2>
393 inline duration<typename __common_rep_type<_Rep1, typename
394 enable_if<!__is_duration<_Rep2>::value, _Rep2>::type>::type, _Period>
395 operator/(const duration<_Rep1, _Period>& __d, const _Rep2& __s)
397 typedef typename common_type<_Rep1, _Rep2>::type __cr;
398 return duration<__cr, _Period>(__d) /= __s;
401 template<typename _Rep1, typename _Period1,
402 typename _Rep2, typename _Period2>
403 inline typename common_type<_Rep1, _Rep2>::type
404 operator/(const duration<_Rep1, _Period1>& __lhs,
405 const duration<_Rep2, _Period2>& __rhs)
407 typedef duration<_Rep1, _Period1> __dur1;
408 typedef duration<_Rep2, _Period2> __dur2;
409 typedef typename common_type<__dur1,__dur2>::type __ct;
410 return __ct(__lhs).count() / __ct(__rhs).count();
414 template<typename _Rep1, typename _Period, typename _Rep2>
415 inline duration<typename __common_rep_type<_Rep1, typename
416 enable_if<!__is_duration<_Rep2>::value, _Rep2>::type>::type, _Period>
417 operator%(const duration<_Rep1, _Period>& __d, const _Rep2& __s)
419 typedef typename common_type<_Rep1, _Rep2>::type __cr;
420 return duration<__cr, _Period>(__d) %= __s;
423 template<typename _Rep1, typename _Period1,
424 typename _Rep2, typename _Period2>
425 inline typename common_type<duration<_Rep1, _Period1>,
426 duration<_Rep2, _Period2>>::type
427 operator%(const duration<_Rep1, _Period1>& __lhs,
428 const duration<_Rep2, _Period2>& __rhs)
430 typedef duration<_Rep1, _Period1> __dur1;
431 typedef duration<_Rep2, _Period2> __dur2;
432 typedef typename common_type<__dur1,__dur2>::type __ct;
433 return __ct(__lhs) %= __rhs;
437 template<typename _Rep1, typename _Period1,
438 typename _Rep2, typename _Period2>
439 inline constexpr bool
440 operator==(const duration<_Rep1, _Period1>& __lhs,
441 const duration<_Rep2, _Period2>& __rhs)
443 typedef duration<_Rep1, _Period1> __dur1;
444 typedef duration<_Rep2, _Period2> __dur2;
445 typedef typename common_type<__dur1,__dur2>::type __ct;
446 return __ct(__lhs).count() == __ct(__rhs).count();
449 template<typename _Rep1, typename _Period1,
450 typename _Rep2, typename _Period2>
451 inline constexpr bool
452 operator<(const duration<_Rep1, _Period1>& __lhs,
453 const duration<_Rep2, _Period2>& __rhs)
455 typedef duration<_Rep1, _Period1> __dur1;
456 typedef duration<_Rep2, _Period2> __dur2;
457 typedef typename common_type<__dur1,__dur2>::type __ct;
458 return __ct(__lhs).count() < __ct(__rhs).count();
461 template<typename _Rep1, typename _Period1,
462 typename _Rep2, typename _Period2>
463 inline constexpr bool
464 operator!=(const duration<_Rep1, _Period1>& __lhs,
465 const duration<_Rep2, _Period2>& __rhs)
466 { return !(__lhs == __rhs); }
468 template<typename _Rep1, typename _Period1,
469 typename _Rep2, typename _Period2>
470 inline constexpr bool
471 operator<=(const duration<_Rep1, _Period1>& __lhs,
472 const duration<_Rep2, _Period2>& __rhs)
473 { return !(__rhs < __lhs); }
475 template<typename _Rep1, typename _Period1,
476 typename _Rep2, typename _Period2>
477 inline constexpr bool
478 operator>(const duration<_Rep1, _Period1>& __lhs,
479 const duration<_Rep2, _Period2>& __rhs)
480 { return __rhs < __lhs; }
482 template<typename _Rep1, typename _Period1,
483 typename _Rep2, typename _Period2>
484 inline constexpr bool
485 operator>=(const duration<_Rep1, _Period1>& __lhs,
486 const duration<_Rep2, _Period2>& __rhs)
487 { return !(__lhs < __rhs); }
490 typedef duration<int64_t, nano> nanoseconds;
493 typedef duration<int64_t, micro> microseconds;
496 typedef duration<int64_t, milli> milliseconds;
499 typedef duration<int64_t> seconds;
502 typedef duration<int, ratio< 60>> minutes;
505 typedef duration<int, ratio<3600>> hours;
508 template<typename _Clock, typename _Dur>
511 typedef _Clock clock;
512 typedef _Dur duration;
513 typedef typename duration::rep rep;
514 typedef typename duration::period period;
516 constexpr time_point() : __d(duration::zero())
519 constexpr explicit time_point(const duration& __dur)
524 template<typename _Dur2>
525 constexpr time_point(const time_point<clock, _Dur2>& __t)
526 : __d(__t.time_since_epoch())
531 time_since_epoch() const
536 operator+=(const duration& __dur)
543 operator-=(const duration& __dur)
550 static constexpr time_point
552 { return time_point(duration::min()); }
554 static constexpr time_point
556 { return time_point(duration::max()); }
563 template<typename _ToDur, typename _Clock, typename _Dur>
564 inline constexpr typename enable_if<__is_duration<_ToDur>::value,
565 time_point<_Clock, _ToDur>>::type
566 time_point_cast(const time_point<_Clock, _Dur>& __t)
568 typedef time_point<_Clock, _ToDur> __time_point;
569 return __time_point(duration_cast<_ToDur>(__t.time_since_epoch()));
572 template<typename _Clock, typename _Dur1,
573 typename _Rep2, typename _Period2>
574 inline time_point<_Clock,
575 typename common_type<_Dur1, duration<_Rep2, _Period2>>::type>
576 operator+(const time_point<_Clock, _Dur1>& __lhs,
577 const duration<_Rep2, _Period2>& __rhs)
579 typedef duration<_Rep2, _Period2> __dur2;
580 typedef typename common_type<_Dur1,__dur2>::type __ct;
581 typedef time_point<_Clock, __ct> __time_point;
582 return __time_point(__lhs) += __rhs;
585 template<typename _Rep1, typename _Period1,
586 typename _Clock, typename _Dur2>
587 inline time_point<_Clock,
588 typename common_type<duration<_Rep1, _Period1>, _Dur2>::type>
589 operator+(const duration<_Rep1, _Period1>& __lhs,
590 const time_point<_Clock, _Dur2>& __rhs)
591 { return __rhs + __lhs; }
593 template<typename _Clock, typename _Dur1,
594 typename _Rep2, typename _Period2>
595 inline time_point<_Clock,
596 typename common_type<_Dur1, duration<_Rep2, _Period2>>::type>
597 operator-(const time_point<_Clock, _Dur1>& __lhs,
598 const duration<_Rep2, _Period2>& __rhs)
599 { return __lhs + (-__rhs); }
601 template<typename _Clock, typename _Dur1, typename _Dur2>
602 inline typename common_type<_Dur1, _Dur2>::type
603 operator-(const time_point<_Clock, _Dur1>& __lhs,
604 const time_point<_Clock, _Dur2>& __rhs)
605 { return __lhs.time_since_epoch() - __rhs.time_since_epoch(); }
607 template<typename _Clock, typename _Dur1, typename _Dur2>
608 inline constexpr bool
609 operator==(const time_point<_Clock, _Dur1>& __lhs,
610 const time_point<_Clock, _Dur2>& __rhs)
611 { return __lhs.time_since_epoch() == __rhs.time_since_epoch(); }
613 template<typename _Clock, typename _Dur1, typename _Dur2>
614 inline constexpr bool
615 operator!=(const time_point<_Clock, _Dur1>& __lhs,
616 const time_point<_Clock, _Dur2>& __rhs)
617 { return !(__lhs == __rhs); }
619 template<typename _Clock, typename _Dur1, typename _Dur2>
620 inline constexpr bool
621 operator<(const time_point<_Clock, _Dur1>& __lhs,
622 const time_point<_Clock, _Dur2>& __rhs)
623 { return __lhs.time_since_epoch() < __rhs.time_since_epoch(); }
625 template<typename _Clock, typename _Dur1, typename _Dur2>
626 inline constexpr bool
627 operator<=(const time_point<_Clock, _Dur1>& __lhs,
628 const time_point<_Clock, _Dur2>& __rhs)
629 { return !(__rhs < __lhs); }
631 template<typename _Clock, typename _Dur1, typename _Dur2>
632 inline constexpr bool
633 operator>(const time_point<_Clock, _Dur1>& __lhs,
634 const time_point<_Clock, _Dur2>& __rhs)
635 { return __rhs < __lhs; }
637 template<typename _Clock, typename _Dur1, typename _Dur2>
638 inline constexpr bool
639 operator>=(const time_point<_Clock, _Dur1>& __lhs,
640 const time_point<_Clock, _Dur2>& __rhs)
641 { return !(__lhs < __rhs); }
646 #ifdef _GLIBCXX_USE_CLOCK_REALTIME
647 typedef chrono::nanoseconds duration;
648 #elif defined(_GLIBCXX_USE_GETTIMEOFDAY)
649 typedef chrono::microseconds duration;
651 typedef chrono::seconds duration;
654 typedef duration::rep rep;
655 typedef duration::period period;
656 typedef chrono::time_point<system_clock, duration> time_point;
658 static_assert(system_clock::duration::min()
659 < system_clock::duration::zero(),
660 "a clock's minimum duration cannot be less than its epoch");
662 static const bool is_monotonic = false;
669 to_time_t(const time_point& __t)
671 return std::time_t(duration_cast<chrono::seconds>
672 (__t.time_since_epoch()).count());
676 from_time_t(std::time_t __t)
678 typedef chrono::time_point<system_clock, seconds> __from;
679 return time_point_cast<system_clock::duration>
680 (__from(chrono::seconds(__t)));
684 #ifdef _GLIBCXX_USE_CLOCK_MONOTONIC
686 struct monotonic_clock
688 typedef chrono::nanoseconds duration;
689 typedef duration::rep rep;
690 typedef duration::period period;
691 typedef chrono::time_point<monotonic_clock, duration> time_point;
693 static const bool is_monotonic = true;
699 typedef system_clock monotonic_clock;
702 typedef system_clock high_resolution_clock;
703 } // namespace chrono
706 _GLIBCXX_END_NAMESPACE
708 #endif //_GLIBCXX_USE_C99_STDINT_TR1
710 #endif //__GXX_EXPERIMENTAL_CXX0X__
712 #endif //_GLIBCXX_CHRONO