OSDN Git Service

2008-07-15 Chris Fairles <chris.fairles@gmail.com>
[pf3gnuchains/gcc-fork.git] / libstdc++-v3 / include / std / chrono
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
54 namespace 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
169     template<typename _Rep, typename _Period>
170       struct duration
171       {
172         static_assert(_Period::num > 0, "period must be positive");
173         
174         typedef _Rep    rep;
175         typedef _Period period;
176         
177         // construction / destruction  
178         duration ()
179         : __r(rep(0))
180         { }
181
182         template<typename _Rep2>
183           explicit duration(_Rep2 const& __rep)
184           : __r(static_cast<rep>(__rep))
185           {
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");
191           }
192
193         duration(const duration& __d)
194         : __r(__d.count())
195         { }
196
197         // conversions
198         template<typename _Rep2, typename _Period2>
199           duration(const duration<_Rep2, _Period2>& __d)
200           : __r(duration_cast<duration>(__d).count())
201           {
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");
205           }
206
207         // observer
208         rep
209         count() const
210         { return __r; }
211
212         // arithmetic
213         duration
214         operator+() const 
215         { return *this; }
216
217         duration
218         operator-() const 
219         { return duration(-__r); }
220
221         duration&
222         operator++() 
223         {
224           ++__r;
225           return *this;
226         }
227
228         duration
229         operator++(int) 
230         { return duration(__r++); }
231
232         duration&
233         operator--() 
234         { 
235           --__r;
236           return *this;
237         }
238
239         duration
240         operator--(int) 
241         { return duration(__r--); }
242         
243         duration&
244         operator+=(const duration& __d)
245         {
246           __r += __d.count();
247           return *this;
248         }
249
250         duration&
251         operator-=(const duration& __d)
252         {
253           __r -= __d.count();
254           return *this;
255         }
256
257         duration&
258         operator*=(const rep& __rhs)
259         {
260           __r *= __rhs;
261           return *this;
262         }
263
264         duration&
265         operator/=(const rep& __rhs)
266         { 
267           __r /= __rhs;
268           return *this;
269         }
270
271         // special values
272         // TODO: These should be constexprs.
273         static const duration
274         zero()
275         { return duration(duration_values<rep>::zero()); }
276
277         static const duration
278         min()
279         { return duration(duration_values<rep>::min()); }
280       
281         static const duration
282         max()
283         { return duration(duration_values<rep>::max()); }
284    
285       private:    
286         rep __r;
287       };
288
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)
295       {
296         typedef typename common_type<duration<_Rep1, _Period1>, 
297                                      duration<_Rep2, _Period2>>::type __ct;
298         return __ct(__lhs) += __rhs;
299       }
300
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)
307       {
308         typedef typename common_type<duration<_Rep1, _Period1>,
309                                      duration<_Rep2, _Period2>>::type __ct;
310         return __ct(__lhs) -= __rhs;
311       }
312
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)
316       {
317         typedef typename common_type<_Rep1, _Rep2>::type __cr;
318         return duration<__cr, _Period>(__d) *= __s;
319       }
320
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; }
325
326     template<typename _Tp>
327       struct __is_not_duration
328       : std::true_type
329       { };
330     
331     template<typename _Rep, typename _Period>
332       struct __is_not_duration<duration<_Rep, _Period>>
333       : std::false_type
334       { };
335   
336     template<typename _Tp, typename _Up, typename _Ep = void>
337       struct __division_impl;
338   
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>
342       {
343         typedef typename common_type<_Rep1, _Rep2>::type __cr;
344         typedef 
345           duration<typename common_type<_Rep1, _Rep2>::type, _Period> __rt;
346
347         static __rt
348         __divide(const duration<_Rep1, _Period>& __d, const _Rep2& __s)
349         { return duration<__cr, _Period>(__d) /= __s; }
350       };
351
352     template<typename _Rep1, typename _Period1, 
353              typename _Rep2, typename _Period2>
354       struct __division_impl<duration<_Rep1, _Period1>, 
355                              duration<_Rep2, _Period2>>
356       {
357         typedef typename common_type<duration<_Rep1, _Period1>, 
358                                      duration<_Rep2, _Period2>>::type __ct;
359         typedef typename common_type<_Rep1, _Rep2>::type __rt;
360
361         static __rt
362         __divide(const duration<_Rep1, _Period1>& __lhs, 
363                  const duration<_Rep2, _Period2>& __rhs)
364         { return __ct(__lhs).count() / __ct(__rhs).count(); }
365       };
366   
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)
370       {
371         return 
372           __division_impl<duration<_Rep, _Period>, _Up>::__divide(__d, __u);
373       }
374  
375     // comparisons
376     template<typename _Rep1, typename _Period1,
377              typename _Rep2, typename _Period2>
378       inline bool
379       operator==(const duration<_Rep1, _Period1>& __lhs, 
380                  const duration<_Rep2, _Period2>& __rhs)
381       {
382         typedef typename common_type<duration<_Rep1, _Period1>, 
383                                      duration<_Rep2, _Period2>>::type __ct;
384         return __ct(__lhs).count() == __ct(__rhs).count();
385       }
386
387     template<typename _Rep1, typename _Period1,
388              typename _Rep2, typename _Period2>
389       inline bool
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     template<typename _Rep1, typename _Period1,
399              typename _Rep2, typename _Period2>
400       inline bool
401       operator!=(const duration<_Rep1, _Period1>& __lhs, 
402                  const duration<_Rep2, _Period2>& __rhs)
403       { return !(__lhs == __rhs); }
404
405     template<typename _Rep1, typename _Period1,
406              typename _Rep2, typename _Period2>
407       inline bool
408       operator<=(const duration<_Rep1, _Period1>& __lhs, 
409                  const duration<_Rep2, _Period2>& __rhs)
410       { return !(__rhs < __lhs); }
411
412     template<typename _Rep1, typename _Period1,
413              typename _Rep2, typename _Period2>
414       inline bool 
415       operator>(const duration<_Rep1, _Period1>& __lhs, 
416                 const duration<_Rep2, _Period2>& __rhs)
417       { return __rhs < __lhs; }
418
419     template<typename _Rep1, typename _Period1, 
420              typename _Rep2, typename _Period2>
421       inline bool
422       operator>=(const duration<_Rep1, _Period1>& __lhs, 
423                  const duration<_Rep2, _Period2>& __rhs)
424       { return !(__lhs < __rhs); }
425
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;
432
433     template<typename _Clock, typename _Duration>
434     struct time_point
435     {
436       typedef _Clock                    clock;
437       typedef _Duration                 duration;
438       typedef typename duration::rep    rep;
439       typedef typename duration::period period;
440
441       time_point()
442       : __d(duration::zero())
443       { }
444
445       explicit time_point(const duration& __dur)
446       : __d(duration::zero() + __dur)
447       { }
448
449       // conversions
450       template<typename _Duration2>
451         time_point(const time_point<clock, _Duration2>& __t)
452         : __d(__t.time_since_epoch())
453         { }
454
455       // observer
456       duration
457       time_since_epoch() const
458       { return __d; }
459
460       // arithmetic
461       time_point&
462       operator+=(const duration& __dur)
463       {
464         __d += __dur;
465         return *this;
466       }
467
468       time_point&
469       operator-=(const duration& __dur)
470       {
471         __d -= __dur;
472         return *this;
473       }
474
475       // special values
476       // TODO: These should be constexprs.
477       static const time_point
478       min()
479       { return time_point(duration::min()); }
480
481       static const time_point
482       max()
483       { return time_point(duration::max()); }
484
485     private:
486       duration __d;
487     };
488   
489     template<typename _ToDuration, typename _Clock, typename _Duration>
490       inline time_point<_Clock, _ToDuration> 
491       time_point_cast(const time_point<_Clock, _Duration>& __t)
492       {
493         return time_point<_Clock, _ToDuration>(
494           duration_cast<_ToDuration>(__t.time_since_epoch()));  
495       }
496
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)
503       {
504         typedef time_point<_Clock, 
505           typename common_type<_Duration1, 
506                                duration<_Rep2, _Period2>>::type> __ct;
507         return __ct(__lhs) += __rhs;
508       }
509
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; }
517
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); }
525
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(); }
531
532     template<typename _Clock, typename _Duration1, typename _Duration2>
533       inline bool
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(); }
537
538     template<typename _Clock, typename _Duration1, typename _Duration2>
539       inline bool
540       operator!=(const time_point<_Clock, _Duration1>& __lhs,
541                  const time_point<_Clock, _Duration2>& __rhs)
542       { return !(__lhs == __rhs); }
543
544     template<typename _Clock, typename _Duration1, typename _Duration2>
545       inline bool
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(); }
549
550     template<typename _Clock, typename _Duration1, typename _Duration2>
551       inline bool
552       operator<=(const time_point<_Clock, _Duration1>& __lhs,
553                  const time_point<_Clock, _Duration2>& __rhs)
554       { return !(__rhs < __lhs); }
555
556     template<typename _Clock, typename _Duration1, typename _Duration2>
557       inline bool
558       operator>(const time_point<_Clock, _Duration1>& __lhs,
559                 const time_point<_Clock, _Duration2>& __rhs)
560       { return __rhs < __lhs; }
561
562     template<typename _Clock, typename _Duration1, typename _Duration2>
563       inline bool
564       operator>=(const time_point<_Clock, _Duration1>& __lhs,
565                  const time_point<_Clock, _Duration2>& __rhs)
566       { return !(__lhs < __rhs); }
567
568     struct system_clock
569     {
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;      
575 #else
576       typedef chrono::seconds         duration;      
577 #endif
578
579       typedef duration::rep    rep;
580       typedef duration::period period;
581       typedef chrono::time_point<system_clock, duration> time_point;
582
583 #ifdef _GLIBCXX_USE_CLOCK_MONOTONIC
584       static const bool is_monotonic = true;
585 #else
586       static const bool is_monotonic = false;
587 #endif      
588
589       static time_point
590       now();      
591
592       // Map to C API
593       static std::time_t
594       to_time_t(const time_point& __t)
595       {
596         return std::time_t(
597           duration_cast<chrono::seconds>(__t.time_since_epoch()).count());
598       }
599
600       static time_point
601       from_time_t(std::time_t __t)
602       { 
603         return time_point_cast<system_clock::duration>(
604           chrono::time_point<system_clock, chrono::seconds>(
605             chrono::seconds(__t)));
606       }
607
608       // TODO: requires constexpr
609       /*  
610       static_assert(
611         system_clock::duration::min() < 
612         system_clock::duration::zero(), 
613         "a clock's minimum duration cannot be less than its epoch");
614       */
615     };
616
617     typedef system_clock high_resolution_clock;
618     typedef system_clock monotonic_clock;    
619   }
620 }
621
622 #endif //_GLIBCXX_USE_C99_STDINT_TR1
623
624 #endif //__GXX_EXPERIMENTAL_CXX0X__
625
626 #endif //_GLIBCXX_CHRONO