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