1 // <chrono> -*- C++ -*-
3 // Copyright (C) 2008, 2009 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 <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)));
142 template<typename _ToDuration, typename _Rep, typename _Period>
144 duration_cast(const duration<_Rep, _Period>& __d)
147 ratio_divide<_Period, typename _ToDuration::period>::type __cf;
149 common_type<typename _ToDuration::rep, _Rep, intmax_t>::type __cr;
151 return __duration_cast_impl<_ToDuration, __cf, __cr,
152 __cf::num == 1, __cf::den == 1>::__cast(__d);
155 /// treat_as_floating_point
156 template<typename _Rep>
157 struct treat_as_floating_point
158 : is_floating_point<_Rep>
162 template<typename _Rep>
163 struct duration_values
171 { return numeric_limits<_Rep>::max(); }
175 { return numeric_limits<_Rep>::min(); }
178 template<typename _Tp>
183 template<typename _Rep, typename _Period>
184 struct __is_duration<duration<_Rep, _Period>>
193 template<intmax_t _Num, intmax_t _Den>
194 struct __is_ratio<ratio<_Num, _Den>>
199 template<typename _Rep, typename _Period>
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");
208 typedef _Period period;
210 // 20.8.3.1 construction / copy / destroy
211 duration() = default;
213 template<typename _Rep2>
214 explicit duration(_Rep2 const& __rep)
215 : __r(static_cast<rep>(__rep))
217 static_assert(is_convertible<_Rep2,rep>::value
218 && (treat_as_floating_point<rep>::value
219 || !treat_as_floating_point<_Rep2>::value),
220 "cannot construct integral duration with floating point type");
223 template<typename _Rep2, typename _Period2>
224 duration(const duration<_Rep2, _Period2>& __d)
225 : __r(duration_cast<duration>(__d).count())
227 static_assert(treat_as_floating_point<rep>::value == true
228 || ratio_divide<_Period2, period>::type::den == 1,
229 "the resulting duration is not exactly representable");
232 ~duration() = default;
233 duration(const duration&) = default;
234 duration& operator=(const duration&) = default;
241 // 20.8.3.3 arithmetic
248 { return duration(-__r); }
259 { return duration(__r++); }
270 { return duration(__r--); }
273 operator+=(const duration& __d)
280 operator-=(const duration& __d)
287 operator*=(const rep& __rhs)
294 operator/=(const rep& __rhs)
300 // 20.8.3.4 special values
301 // TODO: These should be constexprs.
302 static const duration
304 { return duration(duration_values<rep>::zero()); }
306 static const duration
308 { return duration(duration_values<rep>::min()); }
310 static const duration
312 { return duration(duration_values<rep>::max()); }
318 template<typename _Rep1, typename _Period1,
319 typename _Rep2, typename _Period2>
320 inline typename common_type<duration<_Rep1, _Period1>,
321 duration<_Rep2, _Period2>>::type
322 operator+(const duration<_Rep1, _Period1>& __lhs,
323 const duration<_Rep2, _Period2>& __rhs)
325 typedef typename common_type<duration<_Rep1, _Period1>,
326 duration<_Rep2, _Period2>>::type __ct;
327 return __ct(__lhs) += __rhs;
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)
337 typedef typename common_type<duration<_Rep1, _Period1>,
338 duration<_Rep2, _Period2>>::type __ct;
339 return __ct(__lhs) -= __rhs;
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)
346 typedef typename common_type<_Rep1, _Rep2>::type __cr;
347 return duration<__cr, _Period>(__d) *= __s;
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; }
355 template<typename _Tp, typename _Up, typename _Ep = void>
356 struct __division_impl;
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>
362 typedef typename common_type<_Rep1, _Rep2>::type __cr;
364 duration<typename common_type<_Rep1, _Rep2>::type, _Period> __rt;
367 __divide(const duration<_Rep1, _Period>& __d, const _Rep2& __s)
368 { return duration<__cr, _Period>(__d) /= __s; }
371 template<typename _Rep1, typename _Period1,
372 typename _Rep2, typename _Period2>
373 struct __division_impl<duration<_Rep1, _Period1>,
374 duration<_Rep2, _Period2>>
376 typedef typename common_type<duration<_Rep1, _Period1>,
377 duration<_Rep2, _Period2>>::type __ct;
378 typedef typename common_type<_Rep1, _Rep2>::type __rt;
381 __divide(const duration<_Rep1, _Period1>& __lhs,
382 const duration<_Rep2, _Period2>& __rhs)
383 { return __ct(__lhs).count() / __ct(__rhs).count(); }
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)
391 __division_impl<duration<_Rep, _Period>, _Up>::__divide(__d, __u);
395 template<typename _Rep1, typename _Period1,
396 typename _Rep2, typename _Period2>
398 operator==(const duration<_Rep1, _Period1>& __lhs,
399 const duration<_Rep2, _Period2>& __rhs)
401 typedef typename common_type<duration<_Rep1, _Period1>,
402 duration<_Rep2, _Period2>>::type __ct;
403 return __ct(__lhs).count() == __ct(__rhs).count();
406 template<typename _Rep1, typename _Period1,
407 typename _Rep2, typename _Period2>
409 operator<(const duration<_Rep1, _Period1>& __lhs,
410 const duration<_Rep2, _Period2>& __rhs)
412 typedef typename common_type<duration<_Rep1, _Period1>,
413 duration<_Rep2, _Period2>>::type __ct;
414 return __ct(__lhs).count() < __ct(__rhs).count();
417 template<typename _Rep1, typename _Period1,
418 typename _Rep2, typename _Period2>
420 operator!=(const duration<_Rep1, _Period1>& __lhs,
421 const duration<_Rep2, _Period2>& __rhs)
422 { return !(__lhs == __rhs); }
424 template<typename _Rep1, typename _Period1,
425 typename _Rep2, typename _Period2>
427 operator<=(const duration<_Rep1, _Period1>& __lhs,
428 const duration<_Rep2, _Period2>& __rhs)
429 { return !(__rhs < __lhs); }
431 template<typename _Rep1, typename _Period1,
432 typename _Rep2, typename _Period2>
434 operator>(const duration<_Rep1, _Period1>& __lhs,
435 const duration<_Rep2, _Period2>& __rhs)
436 { return __rhs < __lhs; }
438 template<typename _Rep1, typename _Period1,
439 typename _Rep2, typename _Period2>
441 operator>=(const duration<_Rep1, _Period1>& __lhs,
442 const duration<_Rep2, _Period2>& __rhs)
443 { return !(__lhs < __rhs); }
446 typedef duration<int64_t, nano> nanoseconds;
449 typedef duration<int64_t, micro> microseconds;
452 typedef duration<int64_t, milli> milliseconds;
455 typedef duration<int64_t > seconds;
458 typedef duration<int, ratio< 60>> minutes;
461 typedef duration<int, ratio<3600>> hours;
464 template<typename _Clock, typename _Duration>
467 typedef _Clock clock;
468 typedef _Duration duration;
469 typedef typename duration::rep rep;
470 typedef typename duration::period period;
472 time_point() : __d(duration::zero())
475 explicit time_point(const duration& __dur)
476 : __d(duration::zero() + __dur)
480 template<typename _Duration2>
481 time_point(const time_point<clock, _Duration2>& __t)
482 : __d(__t.time_since_epoch())
487 time_since_epoch() const
492 operator+=(const duration& __dur)
499 operator-=(const duration& __dur)
506 // TODO: These should be constexprs.
507 static const time_point
509 { return time_point(duration::min()); }
511 static const time_point
513 { return time_point(duration::max()); }
520 template<typename _ToDuration, typename _Clock, typename _Duration>
521 inline time_point<_Clock, _ToDuration>
522 time_point_cast(const time_point<_Clock, _Duration>& __t)
524 return time_point<_Clock, _ToDuration>(
525 duration_cast<_ToDuration>(__t.time_since_epoch()));
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)
535 typedef time_point<_Clock,
536 typename common_type<_Duration1,
537 duration<_Rep2, _Period2>>::type> __ct;
538 return __ct(__lhs) += __rhs;
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; }
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); }
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(); }
563 template<typename _Clock, typename _Duration1, typename _Duration2>
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(); }
569 template<typename _Clock, typename _Duration1, typename _Duration2>
571 operator!=(const time_point<_Clock, _Duration1>& __lhs,
572 const time_point<_Clock, _Duration2>& __rhs)
573 { return !(__lhs == __rhs); }
575 template<typename _Clock, typename _Duration1, typename _Duration2>
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(); }
581 template<typename _Clock, typename _Duration1, typename _Duration2>
583 operator<=(const time_point<_Clock, _Duration1>& __lhs,
584 const time_point<_Clock, _Duration2>& __rhs)
585 { return !(__rhs < __lhs); }
587 template<typename _Clock, typename _Duration1, typename _Duration2>
589 operator>(const time_point<_Clock, _Duration1>& __lhs,
590 const time_point<_Clock, _Duration2>& __rhs)
591 { return __rhs < __lhs; }
593 template<typename _Clock, typename _Duration1, typename _Duration2>
595 operator>=(const time_point<_Clock, _Duration1>& __lhs,
596 const time_point<_Clock, _Duration2>& __rhs)
597 { return !(__lhs < __rhs); }
602 #ifdef _GLIBCXX_USE_CLOCK_REALTIME
603 typedef chrono::nanoseconds duration;
604 #elif defined(_GLIBCXX_USE_GETTIMEOFDAY)
605 typedef chrono::microseconds duration;
607 typedef chrono::seconds duration;
610 typedef duration::rep rep;
611 typedef duration::period period;
612 typedef chrono::time_point<system_clock, duration> time_point;
614 static const bool is_monotonic = false;
621 to_time_t(const time_point& __t)
624 duration_cast<chrono::seconds>(__t.time_since_epoch()).count());
628 from_time_t(std::time_t __t)
630 return time_point_cast<system_clock::duration>(
631 chrono::time_point<system_clock, chrono::seconds>(
632 chrono::seconds(__t)));
635 // TODO: requires constexpr
638 system_clock::duration::min() <
639 system_clock::duration::zero(),
640 "a clock's minimum duration cannot be less than its epoch");
644 #ifdef _GLIBCXX_USE_CLOCK_MONOTONIC
646 struct monotonic_clock
648 typedef chrono::nanoseconds duration;
649 typedef duration::rep rep;
650 typedef duration::period period;
651 typedef chrono::time_point<monotonic_clock, duration> time_point;
653 static const bool is_monotonic = true;
659 typedef system_clock monotonic_clock;
662 typedef system_clock high_resolution_clock;
663 } // namespace chrono
668 #endif //_GLIBCXX_USE_C99_STDINT_TR1
670 #endif //__GXX_EXPERIMENTAL_CXX0X__
672 #endif //_GLIBCXX_CHRONO