OSDN Git Service

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