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>
38 #ifdef _GLIBCXX_INCLUDE_AS_TR1
39 # error C++0x header cannot be included from TR1 header
43 #include <type_traits>
47 #ifdef _GLIBCXX_USE_C99_STDINT_TR1
52 * @defgroup chrono Time
55 * Classes and functions for time.
59 /** @namespace std::chrono
60 * @brief ISO C++ 0x entities sub namespace for time and date.
64 template<typename _Rep, typename _Period = ratio<1>>
67 template<typename _Clock, typename _Duration = typename _Clock::duration>
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>>
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;
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>>
87 typedef chrono::time_point<_Clock,
88 typename common_type<_Duration1, _Duration2>::type> type;
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
98 template<typename _Rep, typename _Period>
99 static _ToDuration __cast(const duration<_Rep, _Period>& __d)
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)));
108 template<typename _ToDuration, typename _CF, typename _CR>
109 struct __duration_cast_impl<_ToDuration, _CF, _CR, true, true>
111 template<typename _Rep, typename _Period>
112 static _ToDuration __cast(const duration<_Rep, _Period>& __d)
115 static_cast<typename _ToDuration::rep>(__d.count()));
119 template<typename _ToDuration, typename _CF, typename _CR>
120 struct __duration_cast_impl<_ToDuration, _CF, _CR, true, false>
122 template<typename _Rep, typename _Period>
123 static _ToDuration __cast(const duration<_Rep, _Period>& __d)
125 return _ToDuration(static_cast<typename _ToDuration::rep>(
126 static_cast<_CR>(__d.count()) / static_cast<_CR>(_CF::den)));
130 template<typename _ToDuration, typename _CF, typename _CR>
131 struct __duration_cast_impl<_ToDuration, _CF, _CR, false, true>
133 template<typename _Rep, typename _Period>
134 static _ToDuration __cast(const duration<_Rep, _Period>& __d)
136 return _ToDuration(static_cast<typename _ToDuration::rep>(
137 static_cast<_CR>(__d.count()) * static_cast<_CR>(_CF::num)));
141 template<typename _Tp>
146 template<typename _Rep, typename _Period>
147 struct __is_duration<duration<_Rep, _Period>>
152 template<typename _ToDuration, typename _Rep, typename _Period>
153 inline typename enable_if<__is_duration<_ToDuration>::value,
155 duration_cast(const duration<_Rep, _Period>& __d)
158 ratio_divide<_Period, typename _ToDuration::period>::type __cf;
160 common_type<typename _ToDuration::rep, _Rep, intmax_t>::type __cr;
162 return __duration_cast_impl<_ToDuration, __cf, __cr,
163 __cf::num == 1, __cf::den == 1>::__cast(__d);
166 /// treat_as_floating_point
167 template<typename _Rep>
168 struct treat_as_floating_point
169 : is_floating_point<_Rep>
173 template<typename _Rep>
174 struct duration_values
182 { return numeric_limits<_Rep>::max(); }
186 { return numeric_limits<_Rep>::min(); }
194 template<intmax_t _Num, intmax_t _Den>
195 struct __is_ratio<ratio<_Num, _Den>>
200 template<typename _Rep, typename _Period>
203 static_assert(!__is_duration<_Rep>::value, "rep cannot be a duration");
204 static_assert(__is_ratio<_Period>::value,
205 "period must be a specialization of ratio");
206 static_assert(_Period::num > 0, "period must be positive");
209 typedef _Period period;
211 // 20.8.3.1 construction / copy / destroy
212 duration() = default;
214 template<typename _Rep2, typename = typename
215 enable_if<is_convertible<_Rep2, rep>::value
216 && (treat_as_floating_point<rep>::value
217 || !treat_as_floating_point<_Rep2>::value)>::type>
218 explicit duration(const _Rep2& __rep)
219 : __r(static_cast<rep>(__rep)) { }
221 template<typename _Rep2, typename _Period2, typename = typename
222 enable_if<treat_as_floating_point<rep>::value
223 || (ratio_divide<_Period2, period>::type::den == 1
224 && !treat_as_floating_point<_Rep2>::value)>::type>
225 duration(const duration<_Rep2, _Period2>& __d)
226 : __r(duration_cast<duration>(__d).count()) { }
228 ~duration() = default;
229 duration(const duration&) = default;
230 duration& operator=(const duration&) = default;
237 // 20.8.3.3 arithmetic
244 { return duration(-__r); }
255 { return duration(__r++); }
266 { return duration(__r--); }
269 operator+=(const duration& __d)
276 operator-=(const duration& __d)
283 operator*=(const rep& __rhs)
290 operator/=(const rep& __rhs)
297 template<typename _Rep2 = rep>
298 typename enable_if<!treat_as_floating_point<_Rep2>::value,
300 operator%=(const rep& __rhs)
306 template<typename _Rep2 = rep>
307 typename enable_if<!treat_as_floating_point<_Rep2>::value,
309 operator%=(const duration& __d)
315 // 20.8.3.4 special values
316 // TODO: These should be constexprs.
317 static const duration
319 { return duration(duration_values<rep>::zero()); }
321 static const duration
323 { return duration(duration_values<rep>::min()); }
325 static const duration
327 { return duration(duration_values<rep>::max()); }
333 template<typename _Rep1, typename _Period1,
334 typename _Rep2, typename _Period2>
335 inline typename common_type<duration<_Rep1, _Period1>,
336 duration<_Rep2, _Period2>>::type
337 operator+(const duration<_Rep1, _Period1>& __lhs,
338 const duration<_Rep2, _Period2>& __rhs)
340 typedef typename common_type<duration<_Rep1, _Period1>,
341 duration<_Rep2, _Period2>>::type __ct;
342 return __ct(__lhs) += __rhs;
345 template<typename _Rep1, typename _Period1,
346 typename _Rep2, typename _Period2>
347 inline typename common_type<duration<_Rep1, _Period1>,
348 duration<_Rep2, _Period2>>::type
349 operator-(const duration<_Rep1, _Period1>& __lhs,
350 const duration<_Rep2, _Period2>& __rhs)
352 typedef typename common_type<duration<_Rep1, _Period1>,
353 duration<_Rep2, _Period2>>::type __ct;
354 return __ct(__lhs) -= __rhs;
357 template<typename _Rep1, typename _Rep2, bool =
358 is_convertible<_Rep2,
359 typename common_type<_Rep1, _Rep2>::type>::value>
360 struct __common_rep_type { };
362 template<typename _Rep1, typename _Rep2>
363 struct __common_rep_type<_Rep1, _Rep2, true>
364 { typedef typename common_type<_Rep1, _Rep2>::type type; };
366 template<typename _Rep1, typename _Period, typename _Rep2>
367 inline duration<typename __common_rep_type<_Rep1, _Rep2>::type, _Period>
368 operator*(const duration<_Rep1, _Period>& __d, const _Rep2& __s)
370 typedef typename common_type<_Rep1, _Rep2>::type __cr;
371 return duration<__cr, _Period>(__d) *= __s;
374 template<typename _Rep1, typename _Period, typename _Rep2>
375 inline duration<typename __common_rep_type<_Rep2, _Rep1>::type, _Period>
376 operator*(const _Rep1& __s, const duration<_Rep2, _Period>& __d)
377 { return __d * __s; }
379 template<typename _Rep1, typename _Period, typename _Rep2>
380 inline duration<typename __common_rep_type<_Rep1, typename
381 enable_if<!__is_duration<_Rep2>::value, _Rep2>::type>::type, _Period>
382 operator/(const duration<_Rep1, _Period>& __d, const _Rep2& __s)
384 typedef typename common_type<_Rep1, _Rep2>::type __cr;
385 return duration<__cr, _Period>(__d) /= __s;
388 template<typename _Rep1, typename _Period1,
389 typename _Rep2, typename _Period2>
390 inline typename common_type<_Rep1, _Rep2>::type
391 operator/(const duration<_Rep1, _Period1>& __lhs,
392 const duration<_Rep2, _Period2>& __rhs)
394 typedef typename common_type<duration<_Rep1, _Period1>,
395 duration<_Rep2, _Period2>>::type __ct;
396 return __ct(__lhs).count() / __ct(__rhs).count();
400 template<typename _Rep1, typename _Period, typename _Rep2>
401 inline duration<typename __common_rep_type<_Rep1, typename
402 enable_if<!__is_duration<_Rep2>::value, _Rep2>::type>::type, _Period>
403 operator%(const duration<_Rep1, _Period>& __d, const _Rep2& __s)
405 typedef typename common_type<_Rep1, _Rep2>::type __cr;
406 return duration<__cr, _Period>(__d) %= __s;
409 template<typename _Rep1, typename _Period1,
410 typename _Rep2, typename _Period2>
411 inline typename common_type<duration<_Rep1, _Period1>,
412 duration<_Rep2, _Period2>>::type
413 operator%(const duration<_Rep1, _Period1>& __lhs,
414 const duration<_Rep2, _Period2>& __rhs)
416 typedef typename common_type<duration<_Rep1, _Period1>,
417 duration<_Rep2, _Period2>>::type __ct;
418 return __ct(__lhs) %= __rhs;
422 template<typename _Rep1, typename _Period1,
423 typename _Rep2, typename _Period2>
425 operator==(const duration<_Rep1, _Period1>& __lhs,
426 const duration<_Rep2, _Period2>& __rhs)
428 typedef typename common_type<duration<_Rep1, _Period1>,
429 duration<_Rep2, _Period2>>::type __ct;
430 return __ct(__lhs).count() == __ct(__rhs).count();
433 template<typename _Rep1, typename _Period1,
434 typename _Rep2, typename _Period2>
436 operator<(const duration<_Rep1, _Period1>& __lhs,
437 const duration<_Rep2, _Period2>& __rhs)
439 typedef typename common_type<duration<_Rep1, _Period1>,
440 duration<_Rep2, _Period2>>::type __ct;
441 return __ct(__lhs).count() < __ct(__rhs).count();
444 template<typename _Rep1, typename _Period1,
445 typename _Rep2, typename _Period2>
447 operator!=(const duration<_Rep1, _Period1>& __lhs,
448 const duration<_Rep2, _Period2>& __rhs)
449 { return !(__lhs == __rhs); }
451 template<typename _Rep1, typename _Period1,
452 typename _Rep2, typename _Period2>
454 operator<=(const duration<_Rep1, _Period1>& __lhs,
455 const duration<_Rep2, _Period2>& __rhs)
456 { return !(__rhs < __lhs); }
458 template<typename _Rep1, typename _Period1,
459 typename _Rep2, typename _Period2>
461 operator>(const duration<_Rep1, _Period1>& __lhs,
462 const duration<_Rep2, _Period2>& __rhs)
463 { return __rhs < __lhs; }
465 template<typename _Rep1, typename _Period1,
466 typename _Rep2, typename _Period2>
468 operator>=(const duration<_Rep1, _Period1>& __lhs,
469 const duration<_Rep2, _Period2>& __rhs)
470 { return !(__lhs < __rhs); }
473 typedef duration<int64_t, nano> nanoseconds;
476 typedef duration<int64_t, micro> microseconds;
479 typedef duration<int64_t, milli> milliseconds;
482 typedef duration<int64_t > seconds;
485 typedef duration<int, ratio< 60>> minutes;
488 typedef duration<int, ratio<3600>> hours;
491 template<typename _Clock, typename _Duration>
494 typedef _Clock clock;
495 typedef _Duration duration;
496 typedef typename duration::rep rep;
497 typedef typename duration::period period;
499 time_point() : __d(duration::zero())
502 explicit time_point(const duration& __dur)
503 : __d(duration::zero() + __dur)
507 template<typename _Duration2>
508 time_point(const time_point<clock, _Duration2>& __t)
509 : __d(__t.time_since_epoch())
514 time_since_epoch() const
519 operator+=(const duration& __dur)
526 operator-=(const duration& __dur)
533 // TODO: These should be constexprs.
534 static const time_point
536 { return time_point(duration::min()); }
538 static const time_point
540 { return time_point(duration::max()); }
547 template<typename _ToDuration, typename _Clock, typename _Duration>
548 inline typename enable_if<__is_duration<_ToDuration>::value,
549 time_point<_Clock, _ToDuration>>::type
550 time_point_cast(const time_point<_Clock, _Duration>& __t)
552 return time_point<_Clock, _ToDuration>(
553 duration_cast<_ToDuration>(__t.time_since_epoch()));
556 template<typename _Clock, typename _Duration1,
557 typename _Rep2, typename _Period2>
558 inline time_point<_Clock,
559 typename common_type<_Duration1, duration<_Rep2, _Period2>>::type>
560 operator+(const time_point<_Clock, _Duration1>& __lhs,
561 const duration<_Rep2, _Period2>& __rhs)
563 typedef time_point<_Clock,
564 typename common_type<_Duration1,
565 duration<_Rep2, _Period2>>::type> __ct;
566 return __ct(__lhs) += __rhs;
569 template<typename _Rep1, typename _Period1,
570 typename _Clock, typename _Duration2>
571 inline time_point<_Clock,
572 typename common_type<duration<_Rep1, _Period1>, _Duration2>::type>
573 operator+(const duration<_Rep1, _Period1>& __lhs,
574 const time_point<_Clock, _Duration2>& __rhs)
575 { return __rhs + __lhs; }
577 template<typename _Clock, typename _Duration1,
578 typename _Rep2, typename _Period2>
579 inline time_point<_Clock,
580 typename common_type<_Duration1, duration<_Rep2, _Period2>>::type>
581 operator-(const time_point<_Clock, _Duration1>& __lhs,
582 const duration<_Rep2, _Period2>& __rhs)
583 { return __lhs + (-__rhs); }
585 template<typename _Clock, typename _Duration1, typename _Duration2>
586 inline typename common_type<_Duration1, _Duration2>::type
587 operator-(const time_point<_Clock, _Duration1>& __lhs,
588 const time_point<_Clock, _Duration2>& __rhs)
589 { return __lhs.time_since_epoch() - __rhs.time_since_epoch(); }
591 template<typename _Clock, typename _Duration1, typename _Duration2>
593 operator==(const time_point<_Clock, _Duration1>& __lhs,
594 const time_point<_Clock, _Duration2>& __rhs)
595 { return __lhs.time_since_epoch() == __rhs.time_since_epoch(); }
597 template<typename _Clock, typename _Duration1, typename _Duration2>
599 operator!=(const time_point<_Clock, _Duration1>& __lhs,
600 const time_point<_Clock, _Duration2>& __rhs)
601 { return !(__lhs == __rhs); }
603 template<typename _Clock, typename _Duration1, typename _Duration2>
605 operator<(const time_point<_Clock, _Duration1>& __lhs,
606 const time_point<_Clock, _Duration2>& __rhs)
607 { return __lhs.time_since_epoch() < __rhs.time_since_epoch(); }
609 template<typename _Clock, typename _Duration1, typename _Duration2>
611 operator<=(const time_point<_Clock, _Duration1>& __lhs,
612 const time_point<_Clock, _Duration2>& __rhs)
613 { return !(__rhs < __lhs); }
615 template<typename _Clock, typename _Duration1, typename _Duration2>
617 operator>(const time_point<_Clock, _Duration1>& __lhs,
618 const time_point<_Clock, _Duration2>& __rhs)
619 { return __rhs < __lhs; }
621 template<typename _Clock, typename _Duration1, typename _Duration2>
623 operator>=(const time_point<_Clock, _Duration1>& __lhs,
624 const time_point<_Clock, _Duration2>& __rhs)
625 { return !(__lhs < __rhs); }
630 #ifdef _GLIBCXX_USE_CLOCK_REALTIME
631 typedef chrono::nanoseconds duration;
632 #elif defined(_GLIBCXX_USE_GETTIMEOFDAY)
633 typedef chrono::microseconds duration;
635 typedef chrono::seconds duration;
638 typedef duration::rep rep;
639 typedef duration::period period;
640 typedef chrono::time_point<system_clock, duration> time_point;
642 static const bool is_monotonic = false;
649 to_time_t(const time_point& __t)
652 duration_cast<chrono::seconds>(__t.time_since_epoch()).count());
656 from_time_t(std::time_t __t)
658 return time_point_cast<system_clock::duration>(
659 chrono::time_point<system_clock, chrono::seconds>(
660 chrono::seconds(__t)));
663 // TODO: requires constexpr
666 system_clock::duration::min() <
667 system_clock::duration::zero(),
668 "a clock's minimum duration cannot be less than its epoch");
672 #ifdef _GLIBCXX_USE_CLOCK_MONOTONIC
674 struct monotonic_clock
676 typedef chrono::nanoseconds duration;
677 typedef duration::rep rep;
678 typedef duration::period period;
679 typedef chrono::time_point<monotonic_clock, duration> time_point;
681 static const bool is_monotonic = true;
687 typedef system_clock monotonic_clock;
690 typedef system_clock high_resolution_clock;
691 } // namespace chrono
696 #endif //_GLIBCXX_USE_C99_STDINT_TR1
698 #endif //__GXX_EXPERIMENTAL_CXX0X__
700 #endif //_GLIBCXX_CHRONO