1 // <chrono> -*- C++ -*-
3 // Copyright (C) 2008 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 2, 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 // You should have received a copy of the GNU General Public License
17 // along with this library; see the file COPYING. If not, write to
18 // the Free Software Foundation, 51 Franklin Street, Fifth Floor,
19 // Boston, MA 02110-1301, USA.
21 // As a special exception, you may use this file as part of a free software
22 // library without restriction. Specifically, if other files instantiate
23 // templates or use macros or inline functions from this file, or you compile
24 // this file and link it with other files to produce an executable, this
25 // file does not by itself cause the resulting executable to be covered by
26 // the GNU General Public License. This exception does not however
27 // invalidate any other reasons why the executable file might be covered by
28 // the GNU General Public License.
30 /** @file include/chrono
31 * This is a Standard C++ Library header.
34 #ifndef _GLIBCXX_CHRONO
35 #define _GLIBCXX_CHRONO 1
37 #pragma GCC system_header
39 #ifndef __GXX_EXPERIMENTAL_CXX0X__
40 # include <c++0x_warning.h>
43 #ifdef _GLIBCXX_INCLUDE_AS_TR1
44 # error C++0x header cannot be included from TR1 header
48 #include <type_traits>
52 #ifdef _GLIBCXX_USE_C99_STDINT_TR1
58 template<typename _Rep, typename _Period = ratio<1>>
61 template<typename _Clock, typename _Duration = typename _Clock::duration>
65 // 20.8.2.3 specialization of common_type (for duration)
66 template<typename _Rep1, typename _Period1, typename _Rep2, typename _Period2>
67 struct common_type<chrono::duration<_Rep1, _Period1>,
68 chrono::duration<_Rep2, _Period2>>
70 typedef chrono::duration<typename common_type<_Rep1, _Rep2>::type,
71 ratio<__static_gcd<_Period1::num, _Period2::num>::value,
72 (_Period1::den / __static_gcd<_Period1::den, _Period2::den>::value)
73 * _Period2::den>> type;
76 // 20.8.2.3 specialization of common_type (for time_point)
77 template<typename _Clock, typename _Duration1, typename _Duration2>
78 struct common_type<chrono::time_point<_Clock, _Duration1>,
79 chrono::time_point<_Clock, _Duration2>>
81 typedef chrono::time_point<_Clock,
82 typename common_type<_Duration1, _Duration2>::type> type;
87 // primary template for duration_cast impl.
88 template<typename _ToDuration, typename _CF, typename _CR,
89 bool _NumIsOne = false, bool _DenIsOne = false>
90 struct __duration_cast_impl
92 template<typename _Rep, typename _Period>
93 static _ToDuration __cast(const duration<_Rep, _Period>& __d)
95 return _ToDuration(static_cast<
96 typename _ToDuration::rep>(static_cast<_CR>(__d.count())
97 * static_cast<_CR>(_CF::num)
98 / static_cast<_CR>(_CF::den)));
102 template<typename _ToDuration, typename _CF, typename _CR>
103 struct __duration_cast_impl<_ToDuration, _CF, _CR, true, true>
105 template<typename _Rep, typename _Period>
106 static _ToDuration __cast(const duration<_Rep, _Period>& __d)
109 static_cast<typename _ToDuration::rep>(__d.count()));
113 template<typename _ToDuration, typename _CF, typename _CR>
114 struct __duration_cast_impl<_ToDuration, _CF, _CR, true, false>
116 template<typename _Rep, typename _Period>
117 static _ToDuration __cast(const duration<_Rep, _Period>& __d)
119 return _ToDuration(static_cast<typename _ToDuration::rep>(
120 static_cast<_CR>(__d.count()) / static_cast<_CR>(_CF::den)));
124 template<typename _ToDuration, typename _CF, typename _CR>
125 struct __duration_cast_impl<_ToDuration, _CF, _CR, false, true>
127 template<typename _Rep, typename _Period>
128 static _ToDuration __cast(const duration<_Rep, _Period>& __d)
130 return _ToDuration(static_cast<typename _ToDuration::rep>(
131 static_cast<_CR>(__d.count()) * static_cast<_CR>(_CF::num)));
135 template<typename _ToDuration, typename _Rep, typename _Period>
137 duration_cast(const duration<_Rep, _Period>& __d)
140 ratio_divide<_Period, typename _ToDuration::period>::type __cf;
142 common_type<typename _ToDuration::rep, _Rep, intmax_t>::type __cr;
144 return __duration_cast_impl<_ToDuration, __cf, __cr,
145 __cf::num == 1, __cf::den == 1>::__cast(__d);
148 template<typename _Rep>
149 struct treat_as_floating_point
150 : is_floating_point<_Rep>
153 template<typename _Rep>
154 struct duration_values
162 { return numeric_limits<_Rep>::max(); }
166 { return numeric_limits<_Rep>::min(); }
169 template<typename _Rep, typename _Period>
172 static_assert(_Period::num > 0, "period must be positive");
175 typedef _Period period;
177 // construction / destruction
182 template<typename _Rep2>
183 explicit duration(_Rep2 const& __rep)
184 : __r(static_cast<rep>(__rep))
186 static_assert(is_convertible<_Rep2,rep>::value == true
187 && (treat_as_floating_point<rep>::value == true
188 || (!treat_as_floating_point<rep>::value
189 && !treat_as_floating_point<_Rep2>::value)),
190 "cannot construct integral duration with floating point type");
193 duration(const duration& __d)
198 template<typename _Rep2, typename _Period2>
199 duration(const duration<_Rep2, _Period2>& __d)
200 : __r(duration_cast<duration>(__d).count())
202 static_assert(treat_as_floating_point<rep>::value == true
203 || ratio_divide<_Period2, period>::type::den == 1,
204 "the resulting duration is not exactly representable");
219 { return duration(-__r); }
230 { return duration(__r++); }
241 { return duration(__r--); }
244 operator+=(const duration& __d)
251 operator-=(const duration& __d)
258 operator*=(const rep& __rhs)
265 operator/=(const rep& __rhs)
272 // TODO: These should be constexprs.
273 static const duration
275 { return duration(duration_values<rep>::zero()); }
277 static const duration
279 { return duration(duration_values<rep>::min()); }
281 static const duration
283 { return duration(duration_values<rep>::max()); }
289 template<typename _Rep1, typename _Period1,
290 typename _Rep2, typename _Period2>
291 inline typename common_type<duration<_Rep1, _Period1>,
292 duration<_Rep2, _Period2>>::type
293 operator+(const duration<_Rep1, _Period1>& __lhs,
294 const duration<_Rep2, _Period2>& __rhs)
296 typedef typename common_type<duration<_Rep1, _Period1>,
297 duration<_Rep2, _Period2>>::type __ct;
298 return __ct(__lhs) += __rhs;
301 template<typename _Rep1, typename _Period1,
302 typename _Rep2, typename _Period2>
303 inline typename common_type<duration<_Rep1, _Period1>,
304 duration<_Rep2, _Period2>>::type
305 operator-(const duration<_Rep1, _Period1>& __lhs,
306 const duration<_Rep2, _Period2>& __rhs)
308 typedef typename common_type<duration<_Rep1, _Period1>,
309 duration<_Rep2, _Period2>>::type __ct;
310 return __ct(__lhs) -= __rhs;
313 template<typename _Rep1, typename _Period, typename _Rep2>
314 inline duration<typename common_type<_Rep1, _Rep2>::type, _Period>
315 operator*(const duration<_Rep1, _Period>& __d, const _Rep2& __s)
317 typedef typename common_type<_Rep1, _Rep2>::type __cr;
318 return duration<__cr, _Period>(__d) *= __s;
321 template<typename _Rep1, typename _Period, typename _Rep2>
322 inline duration<typename common_type<_Rep1, _Rep2>::type, _Period>
323 operator*(const _Rep2& __s, const duration<_Rep1, _Period>& __d)
324 { return __d * __s; }
326 template<typename _Tp>
327 struct __is_not_duration
331 template<typename _Rep, typename _Period>
332 struct __is_not_duration<duration<_Rep, _Period>>
336 template<typename _Tp, typename _Up, typename _Ep = void>
337 struct __division_impl;
339 template<typename _Rep1, typename _Period, typename _Rep2>
340 struct __division_impl<duration<_Rep1, _Period>, _Rep2,
341 typename enable_if<__is_not_duration<_Rep2>::value>::type>
343 typedef typename common_type<_Rep1, _Rep2>::type __cr;
345 duration<typename common_type<_Rep1, _Rep2>::type, _Period> __rt;
348 __divide(const duration<_Rep1, _Period>& __d, const _Rep2& __s)
349 { return duration<__cr, _Period>(__d) /= __s; }
352 template<typename _Rep1, typename _Period1,
353 typename _Rep2, typename _Period2>
354 struct __division_impl<duration<_Rep1, _Period1>,
355 duration<_Rep2, _Period2>>
357 typedef typename common_type<duration<_Rep1, _Period1>,
358 duration<_Rep2, _Period2>>::type __ct;
359 typedef typename common_type<_Rep1, _Rep2>::type __rt;
362 __divide(const duration<_Rep1, _Period1>& __lhs,
363 const duration<_Rep2, _Period2>& __rhs)
364 { return __ct(__lhs).count() / __ct(__rhs).count(); }
367 template<typename _Rep, typename _Period, typename _Up>
368 inline typename __division_impl<duration<_Rep, _Period>, _Up>::__rt
369 operator/(const duration<_Rep, _Period>& __d, const _Up& __u)
372 __division_impl<duration<_Rep, _Period>, _Up>::__divide(__d, __u);
376 template<typename _Rep1, typename _Period1,
377 typename _Rep2, typename _Period2>
379 operator==(const duration<_Rep1, _Period1>& __lhs,
380 const duration<_Rep2, _Period2>& __rhs)
382 typedef typename common_type<duration<_Rep1, _Period1>,
383 duration<_Rep2, _Period2>>::type __ct;
384 return __ct(__lhs).count() == __ct(__rhs).count();
387 template<typename _Rep1, typename _Period1,
388 typename _Rep2, typename _Period2>
390 operator<(const duration<_Rep1, _Period1>& __lhs,
391 const duration<_Rep2, _Period2>& __rhs)
393 typedef typename common_type<duration<_Rep1, _Period1>,
394 duration<_Rep2, _Period2>>::type __ct;
395 return __ct(__lhs).count() < __ct(__rhs).count();
398 template<typename _Rep1, typename _Period1,
399 typename _Rep2, typename _Period2>
401 operator!=(const duration<_Rep1, _Period1>& __lhs,
402 const duration<_Rep2, _Period2>& __rhs)
403 { return !(__lhs == __rhs); }
405 template<typename _Rep1, typename _Period1,
406 typename _Rep2, typename _Period2>
408 operator<=(const duration<_Rep1, _Period1>& __lhs,
409 const duration<_Rep2, _Period2>& __rhs)
410 { return !(__rhs < __lhs); }
412 template<typename _Rep1, typename _Period1,
413 typename _Rep2, typename _Period2>
415 operator>(const duration<_Rep1, _Period1>& __lhs,
416 const duration<_Rep2, _Period2>& __rhs)
417 { return __rhs < __lhs; }
419 template<typename _Rep1, typename _Period1,
420 typename _Rep2, typename _Period2>
422 operator>=(const duration<_Rep1, _Period1>& __lhs,
423 const duration<_Rep2, _Period2>& __rhs)
424 { return !(__lhs < __rhs); }
426 typedef duration<int64_t, nano> nanoseconds;
427 typedef duration<int64_t, micro> microseconds;
428 typedef duration<int64_t, milli> milliseconds;
429 typedef duration<int64_t > seconds;
430 typedef duration<int, ratio< 60>> minutes;
431 typedef duration<int, ratio<3600>> hours;
433 template<typename _Clock, typename _Duration>
436 typedef _Clock clock;
437 typedef _Duration duration;
438 typedef typename duration::rep rep;
439 typedef typename duration::period period;
442 : __d(duration::zero())
445 explicit time_point(const duration& __dur)
446 : __d(duration::zero() + __dur)
450 template<typename _Duration2>
451 time_point(const time_point<clock, _Duration2>& __t)
452 : __d(__t.time_since_epoch())
457 time_since_epoch() const
462 operator+=(const duration& __dur)
469 operator-=(const duration& __dur)
476 // TODO: These should be constexprs.
477 static const time_point
479 { return time_point(duration::min()); }
481 static const time_point
483 { return time_point(duration::max()); }
489 template<typename _ToDuration, typename _Clock, typename _Duration>
490 inline time_point<_Clock, _ToDuration>
491 time_point_cast(const time_point<_Clock, _Duration>& __t)
493 return time_point<_Clock, _ToDuration>(
494 duration_cast<_ToDuration>(__t.time_since_epoch()));
497 template<typename _Clock, typename _Duration1,
498 typename _Rep2, typename _Period2>
499 inline time_point<_Clock,
500 typename common_type<_Duration1, duration<_Rep2, _Period2>>::type>
501 operator+(const time_point<_Clock, _Duration1>& __lhs,
502 const duration<_Rep2, _Period2>& __rhs)
504 typedef time_point<_Clock,
505 typename common_type<_Duration1,
506 duration<_Rep2, _Period2>>::type> __ct;
507 return __ct(__lhs) += __rhs;
510 template<typename _Rep1, typename _Period1,
511 typename _Clock, typename _Duration2>
512 inline time_point<_Clock,
513 typename common_type<duration<_Rep1, _Period1>, _Duration2>::type>
514 operator+(const duration<_Rep1, _Period1>& __lhs,
515 const time_point<_Clock, _Duration2>& __rhs)
516 { return __rhs + __lhs; }
518 template<typename _Clock, typename _Duration1,
519 typename _Rep2, typename _Period2>
520 inline time_point<_Clock,
521 typename common_type<_Duration1, duration<_Rep2, _Period2>>::type>
522 operator-(const time_point<_Clock, _Duration1>& __lhs,
523 const duration<_Rep2, _Period2>& __rhs)
524 { return __lhs + (-__rhs); }
526 template<typename _Clock, typename _Duration1, typename _Duration2>
527 inline typename common_type<_Duration1, _Duration2>::type
528 operator-(const time_point<_Clock, _Duration1>& __lhs,
529 const time_point<_Clock, _Duration2>& __rhs)
530 { return __lhs.time_since_epoch() - __rhs.time_since_epoch(); }
532 template<typename _Clock, typename _Duration1, typename _Duration2>
534 operator==(const time_point<_Clock, _Duration1>& __lhs,
535 const time_point<_Clock, _Duration2>& __rhs)
536 { return __lhs.time_since_epoch() == __rhs.time_since_epoch(); }
538 template<typename _Clock, typename _Duration1, typename _Duration2>
540 operator!=(const time_point<_Clock, _Duration1>& __lhs,
541 const time_point<_Clock, _Duration2>& __rhs)
542 { return !(__lhs == __rhs); }
544 template<typename _Clock, typename _Duration1, typename _Duration2>
546 operator<(const time_point<_Clock, _Duration1>& __lhs,
547 const time_point<_Clock, _Duration2>& __rhs)
548 { return __lhs.time_since_epoch() < __rhs.time_since_epoch(); }
550 template<typename _Clock, typename _Duration1, typename _Duration2>
552 operator<=(const time_point<_Clock, _Duration1>& __lhs,
553 const time_point<_Clock, _Duration2>& __rhs)
554 { return !(__rhs < __lhs); }
556 template<typename _Clock, typename _Duration1, typename _Duration2>
558 operator>(const time_point<_Clock, _Duration1>& __lhs,
559 const time_point<_Clock, _Duration2>& __rhs)
560 { return __rhs < __lhs; }
562 template<typename _Clock, typename _Duration1, typename _Duration2>
564 operator>=(const time_point<_Clock, _Duration1>& __lhs,
565 const time_point<_Clock, _Duration2>& __rhs)
566 { return !(__lhs < __rhs); }
570 #if defined(_GLIBCXX_USE_CLOCK_MONOTONIC) || \
571 defined(_GLIBCXX_USE_CLOCK_REALTIME)
572 typedef chrono::nanoseconds duration;
573 #elif defined(_GLIBCXX_USE_GETTIMEOFDAY)
574 typedef chrono::microseconds duration;
576 typedef chrono::seconds duration;
579 typedef duration::rep rep;
580 typedef duration::period period;
581 typedef chrono::time_point<system_clock, duration> time_point;
583 #ifdef _GLIBCXX_USE_CLOCK_MONOTONIC
584 static const bool is_monotonic = true;
586 static const bool is_monotonic = false;
594 to_time_t(const time_point& __t)
597 duration_cast<chrono::seconds>(__t.time_since_epoch()).count());
601 from_time_t(std::time_t __t)
603 return time_point_cast<system_clock::duration>(
604 chrono::time_point<system_clock, chrono::seconds>(
605 chrono::seconds(__t)));
608 // TODO: requires constexpr
611 system_clock::duration::min() <
612 system_clock::duration::zero(),
613 "a clock's minimum duration cannot be less than its epoch");
617 typedef system_clock high_resolution_clock;
618 typedef system_clock monotonic_clock;
622 #endif //_GLIBCXX_USE_C99_STDINT_TR1
624 #endif //__GXX_EXPERIMENTAL_CXX0X__
626 #endif //_GLIBCXX_CHRONO