OSDN Git Service

d18f2777f513e7a7b720842c5a9285be5d390a26
[pf3gnuchains/gcc-fork.git] / libstdc++-v3 / include / std / chrono
1 // <chrono> -*- C++ -*-
2
3 // Copyright (C) 2008, 2009 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 <c++0x_warning.h>
36 #else
37
38 #ifdef _GLIBCXX_INCLUDE_AS_TR1
39 #  error C++0x header cannot be included from TR1 header
40 #endif
41
42 #include <ratio>
43 #include <type_traits>
44 #include <limits>
45 #include <ctime>
46
47 #ifdef _GLIBCXX_USE_C99_STDINT_TR1
48
49 namespace std 
50 {
51   /**
52    * @defgroup chrono Time
53    * @ingroup utilities
54    *
55    * Classes and functions for time.
56    * @{
57    */
58
59   /** @namespace std::chrono
60    *  @brief ISO C++ 0x entities sub namespace for time and date.
61    */
62   namespace chrono
63   {
64     template<typename _Rep, typename _Period = ratio<1>>
65       struct duration;
66
67     template<typename _Clock, typename _Duration = typename _Clock::duration>
68       struct time_point;
69   }
70
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>>
75     {
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;
80     };
81   
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>>
86     {
87       typedef chrono::time_point<_Clock, 
88         typename common_type<_Duration1, _Duration2>::type> type;
89     };
90
91   namespace chrono 
92   {
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
97       {
98         template<typename _Rep, typename _Period>
99           static _ToDuration __cast(const duration<_Rep, _Period>& __d)
100           {
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)));
105           }
106       };
107
108     template<typename _ToDuration, typename _CF, typename _CR>
109       struct __duration_cast_impl<_ToDuration, _CF, _CR, true, true>
110       {
111         template<typename _Rep, typename _Period>
112           static _ToDuration __cast(const duration<_Rep, _Period>& __d)
113           {
114             return _ToDuration(
115               static_cast<typename _ToDuration::rep>(__d.count()));
116           }
117       };
118
119     template<typename _ToDuration, typename _CF, typename _CR>
120       struct __duration_cast_impl<_ToDuration, _CF, _CR, true, false>
121       {
122         template<typename _Rep, typename _Period>
123           static _ToDuration __cast(const duration<_Rep, _Period>& __d)
124           {
125             return _ToDuration(static_cast<typename _ToDuration::rep>(
126               static_cast<_CR>(__d.count()) / static_cast<_CR>(_CF::den))); 
127           }
128       };
129
130     template<typename _ToDuration, typename _CF, typename _CR>
131       struct __duration_cast_impl<_ToDuration, _CF, _CR, false, true>
132       {
133         template<typename _Rep, typename _Period>
134           static _ToDuration __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     /// duration_cast
142     template<typename _ToDuration, typename _Rep, typename _Period>
143       inline _ToDuration
144       duration_cast(const duration<_Rep, _Period>& __d)
145       {
146         typedef typename
147           ratio_divide<_Period, typename _ToDuration::period>::type __cf;
148         typedef typename
149           common_type<typename _ToDuration::rep, _Rep, intmax_t>::type __cr;
150
151         return __duration_cast_impl<_ToDuration, __cf, __cr,
152           __cf::num == 1, __cf::den == 1>::__cast(__d);
153       }
154
155     /// treat_as_floating_point
156     template<typename _Rep>
157       struct treat_as_floating_point 
158       : is_floating_point<_Rep>
159       { };
160
161     /// duration_values
162     template<typename _Rep>
163       struct duration_values
164       {
165         static const _Rep
166         zero()
167         { return _Rep(0); }
168         
169         static const _Rep
170         max()
171         { return numeric_limits<_Rep>::max(); }
172         
173         static const _Rep
174         min()
175         { return numeric_limits<_Rep>::min(); }
176       };
177
178     template<typename _Tp>
179       struct __is_duration
180       : std::false_type
181       { };
182
183     template<typename _Rep, typename _Period>
184       struct __is_duration<duration<_Rep, _Period>>
185       : std::true_type
186       { };
187
188     template<typename T>
189       struct __is_ratio
190       : std::false_type
191       { };
192
193     template<intmax_t _Num, intmax_t _Den>
194       struct __is_ratio<ratio<_Num, _Den>>
195       : std::true_type
196       { };
197
198     /// duration
199     template<typename _Rep, typename _Period>
200       struct duration
201       {
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");
206         
207         typedef _Rep    rep;
208         typedef _Period period;
209         
210         // 20.8.3.1 construction / copy / destroy
211         duration() = default;
212
213         template<typename _Rep2>
214           explicit duration(_Rep2 const& __rep)
215           : __r(static_cast<rep>(__rep))
216           {
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");
221           }
222
223         template<typename _Rep2, typename _Period2>
224           duration(const duration<_Rep2, _Period2>& __d)
225           : __r(duration_cast<duration>(__d).count())
226           {
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");
230           }
231
232         ~duration() = default;
233         duration(const duration&) = default;
234         duration& operator=(const duration&) = default;
235
236         // 20.8.3.2 observer
237         rep
238         count() const
239         { return __r; }
240
241         // 20.8.3.3 arithmetic
242         duration
243         operator+() const 
244         { return *this; }
245
246         duration
247         operator-() const 
248         { return duration(-__r); }
249
250         duration&
251         operator++() 
252         {
253           ++__r;
254           return *this;
255         }
256
257         duration
258         operator++(int) 
259         { return duration(__r++); }
260
261         duration&
262         operator--() 
263         { 
264           --__r;
265           return *this;
266         }
267
268         duration
269         operator--(int) 
270         { return duration(__r--); }
271         
272         duration&
273         operator+=(const duration& __d)
274         {
275           __r += __d.count();
276           return *this;
277         }
278
279         duration&
280         operator-=(const duration& __d)
281         {
282           __r -= __d.count();
283           return *this;
284         }
285
286         duration&
287         operator*=(const rep& __rhs)
288         {
289           __r *= __rhs;
290           return *this;
291         }
292
293         duration&
294         operator/=(const rep& __rhs)
295         { 
296           __r /= __rhs;
297           return *this;
298         }
299
300         // 20.8.3.4 special values
301         // TODO: These should be constexprs.
302         static const duration
303         zero()
304         { return duration(duration_values<rep>::zero()); }
305
306         static const duration
307         min()
308         { return duration(duration_values<rep>::min()); }
309       
310         static const duration
311         max()
312         { return duration(duration_values<rep>::max()); }
313    
314       private:    
315         rep __r;
316       };
317
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)
324       {
325         typedef typename common_type<duration<_Rep1, _Period1>, 
326                                      duration<_Rep2, _Period2>>::type __ct;
327         return __ct(__lhs) += __rhs;
328       }
329
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)
336       {
337         typedef typename common_type<duration<_Rep1, _Period1>,
338                                      duration<_Rep2, _Period2>>::type __ct;
339         return __ct(__lhs) -= __rhs;
340       }
341
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)
345       {
346         typedef typename common_type<_Rep1, _Rep2>::type __cr;
347         return duration<__cr, _Period>(__d) *= __s;
348       }
349
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; }
354
355     template<typename _Tp, typename _Up, typename _Ep = void>
356       struct __division_impl;
357   
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>
361       {
362         typedef typename common_type<_Rep1, _Rep2>::type __cr;
363         typedef 
364           duration<typename common_type<_Rep1, _Rep2>::type, _Period> __rt;
365
366         static __rt
367         __divide(const duration<_Rep1, _Period>& __d, const _Rep2& __s)
368         { return duration<__cr, _Period>(__d) /= __s; }
369       };
370
371     template<typename _Rep1, typename _Period1, 
372              typename _Rep2, typename _Period2>
373       struct __division_impl<duration<_Rep1, _Period1>, 
374                              duration<_Rep2, _Period2>>
375       {
376         typedef typename common_type<duration<_Rep1, _Period1>, 
377                                      duration<_Rep2, _Period2>>::type __ct;
378         typedef typename common_type<_Rep1, _Rep2>::type __rt;
379
380         static __rt
381         __divide(const duration<_Rep1, _Period1>& __lhs, 
382                  const duration<_Rep2, _Period2>& __rhs)
383         { return __ct(__lhs).count() / __ct(__rhs).count(); }
384       };
385   
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)
389       {
390         return 
391           __division_impl<duration<_Rep, _Period>, _Up>::__divide(__d, __u);
392       }
393  
394     // comparisons
395     template<typename _Rep1, typename _Period1,
396              typename _Rep2, typename _Period2>
397       inline bool
398       operator==(const duration<_Rep1, _Period1>& __lhs, 
399                  const duration<_Rep2, _Period2>& __rhs)
400       {
401         typedef typename common_type<duration<_Rep1, _Period1>, 
402                                      duration<_Rep2, _Period2>>::type __ct;
403         return __ct(__lhs).count() == __ct(__rhs).count();
404       }
405
406     template<typename _Rep1, typename _Period1,
407              typename _Rep2, typename _Period2>
408       inline bool
409       operator<(const duration<_Rep1, _Period1>& __lhs, 
410                 const duration<_Rep2, _Period2>& __rhs)
411       {
412         typedef typename common_type<duration<_Rep1, _Period1>, 
413                                      duration<_Rep2, _Period2>>::type __ct;
414         return __ct(__lhs).count() < __ct(__rhs).count();
415       }
416
417     template<typename _Rep1, typename _Period1,
418              typename _Rep2, typename _Period2>
419       inline bool
420       operator!=(const duration<_Rep1, _Period1>& __lhs, 
421                  const duration<_Rep2, _Period2>& __rhs)
422       { return !(__lhs == __rhs); }
423
424     template<typename _Rep1, typename _Period1,
425              typename _Rep2, typename _Period2>
426       inline bool
427       operator<=(const duration<_Rep1, _Period1>& __lhs, 
428                  const duration<_Rep2, _Period2>& __rhs)
429       { return !(__rhs < __lhs); }
430
431     template<typename _Rep1, typename _Period1,
432              typename _Rep2, typename _Period2>
433       inline bool 
434       operator>(const duration<_Rep1, _Period1>& __lhs, 
435                 const duration<_Rep2, _Period2>& __rhs)
436       { return __rhs < __lhs; }
437
438     template<typename _Rep1, typename _Period1, 
439              typename _Rep2, typename _Period2>
440       inline bool
441       operator>=(const duration<_Rep1, _Period1>& __lhs, 
442                  const duration<_Rep2, _Period2>& __rhs)
443       { return !(__lhs < __rhs); }
444
445     /// nanoseconds
446     typedef duration<int64_t,        nano> nanoseconds;
447
448     /// microseconds
449     typedef duration<int64_t,       micro> microseconds;
450
451     /// milliseconds
452     typedef duration<int64_t,       milli> milliseconds;
453     
454     /// seconds
455     typedef duration<int64_t             > seconds;
456
457     /// minutes
458     typedef duration<int,     ratio<  60>> minutes;
459
460     /// hours
461     typedef duration<int,     ratio<3600>> hours;
462
463     /// time_point
464     template<typename _Clock, typename _Duration>
465       struct time_point
466       {
467         typedef _Clock                    clock;
468         typedef _Duration                 duration;
469         typedef typename duration::rep    rep;
470         typedef typename duration::period period;
471
472         time_point() : __d(duration::zero())
473         { }
474
475         explicit time_point(const duration& __dur) 
476         : __d(duration::zero() + __dur)
477         { }
478
479         // conversions
480         template<typename _Duration2>
481           time_point(const time_point<clock, _Duration2>& __t)
482           : __d(__t.time_since_epoch())
483           { }
484
485         // observer
486         duration
487         time_since_epoch() const
488         { return __d; }
489         
490         // arithmetic
491         time_point&
492         operator+=(const duration& __dur)
493         {
494           __d += __dur;
495           return *this;
496         }
497         
498         time_point&
499         operator-=(const duration& __dur)
500         {
501           __d -= __dur;
502           return *this;
503         }
504         
505         // special values
506         // TODO: These should be constexprs.
507         static const time_point
508         min()
509         { return time_point(duration::min()); }
510         
511         static const time_point
512         max()
513         { return time_point(duration::max()); }
514         
515       private:
516         duration __d;
517       };
518   
519     /// time_point_cast
520     template<typename _ToDuration, typename _Clock, typename _Duration>
521       inline time_point<_Clock, _ToDuration> 
522       time_point_cast(const time_point<_Clock, _Duration>& __t)
523       {
524         return time_point<_Clock, _ToDuration>(
525           duration_cast<_ToDuration>(__t.time_since_epoch()));  
526       }
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       {
535         typedef time_point<_Clock, 
536           typename common_type<_Duration1, 
537                                duration<_Rep2, _Period2>>::type> __ct;
538         return __ct(__lhs) += __rhs;
539       }
540
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; }
548
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); }
556
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(); }
562
563     template<typename _Clock, typename _Duration1, typename _Duration2>
564       inline bool
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(); }
568
569     template<typename _Clock, typename _Duration1, typename _Duration2>
570       inline bool
571       operator!=(const time_point<_Clock, _Duration1>& __lhs,
572                  const time_point<_Clock, _Duration2>& __rhs)
573       { return !(__lhs == __rhs); }
574
575     template<typename _Clock, typename _Duration1, typename _Duration2>
576       inline bool
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(); }
580
581     template<typename _Clock, typename _Duration1, typename _Duration2>
582       inline bool
583       operator<=(const time_point<_Clock, _Duration1>& __lhs,
584                  const time_point<_Clock, _Duration2>& __rhs)
585       { return !(__rhs < __lhs); }
586
587     template<typename _Clock, typename _Duration1, typename _Duration2>
588       inline bool
589       operator>(const time_point<_Clock, _Duration1>& __lhs,
590                 const time_point<_Clock, _Duration2>& __rhs)
591       { return __rhs < __lhs; }
592
593     template<typename _Clock, typename _Duration1, typename _Duration2>
594       inline bool
595       operator>=(const time_point<_Clock, _Duration1>& __lhs,
596                  const time_point<_Clock, _Duration2>& __rhs)
597       { return !(__lhs < __rhs); }
598
599     /// system_clock
600     struct system_clock
601     {
602 #ifdef _GLIBCXX_USE_CLOCK_REALTIME
603       typedef chrono::nanoseconds     duration;      
604 #elif defined(_GLIBCXX_USE_GETTIMEOFDAY)
605       typedef chrono::microseconds    duration;      
606 #else
607       typedef chrono::seconds         duration;      
608 #endif
609
610       typedef duration::rep    rep;
611       typedef duration::period period;
612       typedef chrono::time_point<system_clock, duration> time_point;
613
614       static const bool is_monotonic = false;
615
616       static time_point
617       now() throw ();
618
619       // Map to C API
620       static std::time_t
621       to_time_t(const time_point& __t)
622       {
623         return std::time_t(
624           duration_cast<chrono::seconds>(__t.time_since_epoch()).count());
625       }
626
627       static time_point
628       from_time_t(std::time_t __t)
629       { 
630         return time_point_cast<system_clock::duration>(
631           chrono::time_point<system_clock, chrono::seconds>(
632             chrono::seconds(__t)));
633       }
634
635       // TODO: requires constexpr
636       /*  
637       static_assert(
638         system_clock::duration::min() < 
639         system_clock::duration::zero(), 
640         "a clock's minimum duration cannot be less than its epoch");
641       */
642     };
643
644 #ifdef _GLIBCXX_USE_CLOCK_MONOTONIC
645     /// monotonic_clock
646     struct monotonic_clock
647     {
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;
652
653       static const bool is_monotonic = true;
654
655       static time_point
656       now();
657     };
658 #else
659     typedef system_clock monotonic_clock;
660 #endif
661
662     typedef system_clock high_resolution_clock;
663   } // namespace chrono
664
665   // @} group chrono
666 } // namespace std
667
668 #endif //_GLIBCXX_USE_C99_STDINT_TR1
669
670 #endif //__GXX_EXPERIMENTAL_CXX0X__
671
672 #endif //_GLIBCXX_CHRONO