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#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
49namespace 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    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 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 const _Rep
177        zero()
178        { return _Rep(0); }
179        
180        static const _Rep
181        max()
182        { return numeric_limits<_Rep>::max(); }
183        
184        static const _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	static_assert(!__is_duration<_Rep>::value, "rep cannot be a duration");
204	static_assert(__is_ratio<_Period>::value, 
205		      "period must be a specialization of ratio");
206        static_assert(_Period::num > 0, "period must be positive");
207        
208        typedef _Rep    rep;
209        typedef _Period period;
210        
211        // 20.8.3.1 construction / copy / destroy
212	duration() = default;
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          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          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        rep
234        count() const
235        { return __r; }
236
237        // 20.8.3.3 arithmetic
238        duration
239        operator+() const 
240        { return *this; }
241
242        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        // TODO: These should be constexprs.
317        static const duration
318        zero()
319        { return duration(duration_values<rep>::zero()); }
320
321        static const duration
322        min()
323        { return duration(duration_values<rep>::min()); }
324      
325        static const duration
326        max()
327        { return duration(duration_values<rep>::max()); }
328
329      private:
330        rep __r;
331      };
332
333    template<typename _Rep1, typename _Period1,
334             typename _Rep2, typename _Period2>
335      inline typename common_type<duration<_Rep1, _Period1>, 
336                                  duration<_Rep2, _Period2>>::type
337      operator+(const duration<_Rep1, _Period1>& __lhs, 
338                const duration<_Rep2, _Period2>& __rhs)
339      {
340        typedef typename common_type<duration<_Rep1, _Period1>, 
341                                     duration<_Rep2, _Period2>>::type __ct;
342        return __ct(__lhs) += __rhs;
343      }
344
345    template<typename _Rep1, typename _Period1, 
346             typename _Rep2, typename _Period2>
347      inline typename common_type<duration<_Rep1, _Period1>, 
348                                  duration<_Rep2, _Period2>>::type
349      operator-(const duration<_Rep1, _Period1>& __lhs, 
350                const duration<_Rep2, _Period2>& __rhs)
351      {
352        typedef typename common_type<duration<_Rep1, _Period1>,
353                                     duration<_Rep2, _Period2>>::type __ct;
354        return __ct(__lhs) -= __rhs;
355      }
356
357    template<typename _Rep1, typename _Rep2, bool =
358	     is_convertible<_Rep2,
359			    typename common_type<_Rep1, _Rep2>::type>::value>
360      struct __common_rep_type { };
361
362    template<typename _Rep1, typename _Rep2>
363      struct __common_rep_type<_Rep1, _Rep2, true>
364      { typedef typename common_type<_Rep1, _Rep2>::type type; };     
365
366    template<typename _Rep1, typename _Period, typename _Rep2>
367      inline duration<typename __common_rep_type<_Rep1, _Rep2>::type, _Period>
368      operator*(const duration<_Rep1, _Period>& __d, const _Rep2& __s)
369      {
370        typedef typename common_type<_Rep1, _Rep2>::type __cr;
371        return duration<__cr, _Period>(__d) *= __s;
372      }
373
374    template<typename _Rep1, typename _Period, typename _Rep2>
375      inline duration<typename __common_rep_type<_Rep2, _Rep1>::type, _Period>
376      operator*(const _Rep1& __s, const duration<_Rep2, _Period>& __d)
377      { return __d * __s; }
378 
379    template<typename _Rep1, typename _Period, typename _Rep2>
380      inline duration<typename __common_rep_type<_Rep1, typename
381	enable_if<!__is_duration<_Rep2>::value, _Rep2>::type>::type, _Period>
382      operator/(const duration<_Rep1, _Period>& __d, const _Rep2& __s)
383      {
384	typedef typename common_type<_Rep1, _Rep2>::type __cr;
385	return duration<__cr, _Period>(__d) /= __s;
386      }
387
388     template<typename _Rep1, typename _Period1,
389	      typename _Rep2, typename _Period2>
390      inline typename common_type<_Rep1, _Rep2>::type
391      operator/(const duration<_Rep1, _Period1>& __lhs, 
392                const duration<_Rep2, _Period2>& __rhs)
393      {
394        typedef typename common_type<duration<_Rep1, _Period1>, 
395                                     duration<_Rep2, _Period2>>::type __ct;
396        return __ct(__lhs).count() / __ct(__rhs).count();
397      }
398
399    // DR 934.
400    template<typename _Rep1, typename _Period, typename _Rep2>
401      inline duration<typename __common_rep_type<_Rep1, typename
402	enable_if<!__is_duration<_Rep2>::value, _Rep2>::type>::type, _Period>
403      operator%(const duration<_Rep1, _Period>& __d, const _Rep2& __s)
404      {
405	typedef typename common_type<_Rep1, _Rep2>::type __cr;
406	return duration<__cr, _Period>(__d) %= __s;
407      }
408
409     template<typename _Rep1, typename _Period1,
410	      typename _Rep2, typename _Period2>
411      inline typename common_type<duration<_Rep1, _Period1>, 
412                                  duration<_Rep2, _Period2>>::type
413      operator%(const duration<_Rep1, _Period1>& __lhs, 
414                const duration<_Rep2, _Period2>& __rhs)
415      {
416        typedef typename common_type<duration<_Rep1, _Period1>, 
417                                     duration<_Rep2, _Period2>>::type __ct;
418        return __ct(__lhs) %= __rhs;
419      }
420
421    // comparisons
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      {
428        typedef typename common_type<duration<_Rep1, _Period1>, 
429                                     duration<_Rep2, _Period2>>::type __ct;
430        return __ct(__lhs).count() == __ct(__rhs).count();
431      }
432
433    template<typename _Rep1, typename _Period1,
434             typename _Rep2, typename _Period2>
435      inline bool
436      operator<(const duration<_Rep1, _Period1>& __lhs, 
437                const duration<_Rep2, _Period2>& __rhs)
438      {
439        typedef typename common_type<duration<_Rep1, _Period1>, 
440                                     duration<_Rep2, _Period2>>::type __ct;
441        return __ct(__lhs).count() < __ct(__rhs).count();
442      }
443
444    template<typename _Rep1, typename _Period1,
445             typename _Rep2, typename _Period2>
446      inline bool
447      operator!=(const duration<_Rep1, _Period1>& __lhs, 
448                 const duration<_Rep2, _Period2>& __rhs)
449      { return !(__lhs == __rhs); }
450
451    template<typename _Rep1, typename _Period1,
452             typename _Rep2, typename _Period2>
453      inline bool
454      operator<=(const duration<_Rep1, _Period1>& __lhs, 
455                 const duration<_Rep2, _Period2>& __rhs)
456      { return !(__rhs < __lhs); }
457
458    template<typename _Rep1, typename _Period1,
459             typename _Rep2, typename _Period2>
460      inline bool 
461      operator>(const duration<_Rep1, _Period1>& __lhs, 
462                const duration<_Rep2, _Period2>& __rhs)
463      { return __rhs < __lhs; }
464
465    template<typename _Rep1, typename _Period1, 
466             typename _Rep2, typename _Period2>
467      inline bool
468      operator>=(const duration<_Rep1, _Period1>& __lhs, 
469                 const duration<_Rep2, _Period2>& __rhs)
470      { return !(__lhs < __rhs); }
471
472    /// nanoseconds
473    typedef duration<int64_t,        nano> nanoseconds;
474
475    /// microseconds
476    typedef duration<int64_t,       micro> microseconds;
477
478    /// milliseconds
479    typedef duration<int64_t,       milli> milliseconds;
480    
481    /// seconds
482    typedef duration<int64_t             > seconds;
483
484    /// minutes
485    typedef duration<int,     ratio<  60>> minutes;
486
487    /// hours
488    typedef duration<int,     ratio<3600>> hours;
489
490    /// time_point
491    template<typename _Clock, typename _Duration>
492      struct time_point
493      {
494	typedef _Clock                    clock;
495	typedef _Duration                 duration;
496	typedef typename duration::rep    rep;
497	typedef typename duration::period period;
498
499	time_point() : __d(duration::zero())
500	{ }
501
502	explicit time_point(const duration& __dur) 
503	: __d(duration::zero() + __dur)
504	{ }
505
506	// conversions
507	template<typename _Duration2>
508	  time_point(const time_point<clock, _Duration2>& __t)
509	  : __d(__t.time_since_epoch())
510	  { }
511
512	// observer
513	duration
514	time_since_epoch() const
515	{ return __d; }
516	
517	// arithmetic
518	time_point&
519	operator+=(const duration& __dur)
520	{
521	  __d += __dur;
522	  return *this;
523	}
524	
525	time_point&
526	operator-=(const duration& __dur)
527	{
528	  __d -= __dur;
529	  return *this;
530	}
531	
532	// special values
533	// TODO: These should be constexprs.
534	static const time_point
535	min()
536	{ return time_point(duration::min()); }
537	
538	static const time_point
539	max()
540	{ return time_point(duration::max()); }
541	
542      private:
543	duration __d;
544      };
545  
546    /// time_point_cast
547    template<typename _ToDuration, typename _Clock, typename _Duration>
548      inline typename enable_if<__is_duration<_ToDuration>::value,
549				time_point<_Clock, _ToDuration>>::type
550      time_point_cast(const time_point<_Clock, _Duration>& __t)
551      {
552        return time_point<_Clock, _ToDuration>(
553          duration_cast<_ToDuration>(__t.time_since_epoch()));  
554      }
555
556    template<typename _Clock, typename _Duration1,
557             typename _Rep2, typename _Period2>
558      inline time_point<_Clock, 
559        typename common_type<_Duration1, duration<_Rep2, _Period2>>::type>
560      operator+(const time_point<_Clock, _Duration1>& __lhs, 
561                const duration<_Rep2, _Period2>& __rhs)
562      {
563        typedef time_point<_Clock, 
564          typename common_type<_Duration1, 
565                               duration<_Rep2, _Period2>>::type> __ct;
566        return __ct(__lhs) += __rhs;
567      }
568
569    template<typename _Rep1, typename _Period1,
570             typename _Clock, typename _Duration2>
571      inline time_point<_Clock, 
572        typename common_type<duration<_Rep1, _Period1>, _Duration2>::type>
573      operator+(const duration<_Rep1, _Period1>& __lhs, 
574                const time_point<_Clock, _Duration2>& __rhs)
575      { return __rhs + __lhs; }
576
577    template<typename _Clock, typename _Duration1,
578             typename _Rep2, typename _Period2>
579      inline time_point<_Clock, 
580        typename common_type<_Duration1, duration<_Rep2, _Period2>>::type>
581      operator-(const time_point<_Clock, _Duration1>& __lhs, 
582                const duration<_Rep2, _Period2>& __rhs)
583      { return __lhs + (-__rhs); }
584
585    template<typename _Clock, typename _Duration1, typename _Duration2>
586      inline typename common_type<_Duration1, _Duration2>::type
587      operator-(const time_point<_Clock, _Duration1>& __lhs, 
588                const time_point<_Clock, _Duration2>& __rhs)
589      { return __lhs.time_since_epoch() - __rhs.time_since_epoch(); }
590
591    template<typename _Clock, typename _Duration1, typename _Duration2>
592      inline bool
593      operator==(const time_point<_Clock, _Duration1>& __lhs,
594                 const time_point<_Clock, _Duration2>& __rhs)
595      { return __lhs.time_since_epoch() == __rhs.time_since_epoch(); }
596
597    template<typename _Clock, typename _Duration1, typename _Duration2>
598      inline bool
599      operator!=(const time_point<_Clock, _Duration1>& __lhs,
600                 const time_point<_Clock, _Duration2>& __rhs)
601      { return !(__lhs == __rhs); }
602
603    template<typename _Clock, typename _Duration1, typename _Duration2>
604      inline bool
605      operator<(const time_point<_Clock, _Duration1>& __lhs,
606                const time_point<_Clock, _Duration2>& __rhs)
607      { return  __lhs.time_since_epoch() < __rhs.time_since_epoch(); }
608
609    template<typename _Clock, typename _Duration1, typename _Duration2>
610      inline bool
611      operator<=(const time_point<_Clock, _Duration1>& __lhs,
612                 const time_point<_Clock, _Duration2>& __rhs)
613      { return !(__rhs < __lhs); }
614
615    template<typename _Clock, typename _Duration1, typename _Duration2>
616      inline bool
617      operator>(const time_point<_Clock, _Duration1>& __lhs,
618                const time_point<_Clock, _Duration2>& __rhs)
619      { return __rhs < __lhs; }
620
621    template<typename _Clock, typename _Duration1, typename _Duration2>
622      inline bool
623      operator>=(const time_point<_Clock, _Duration1>& __lhs,
624                 const time_point<_Clock, _Duration2>& __rhs)
625      { return !(__lhs < __rhs); }
626
627    /// system_clock
628    struct system_clock
629    {
630#ifdef _GLIBCXX_USE_CLOCK_REALTIME
631      typedef chrono::nanoseconds     duration;      
632#elif defined(_GLIBCXX_USE_GETTIMEOFDAY)
633      typedef chrono::microseconds    duration;      
634#else
635      typedef chrono::seconds         duration;      
636#endif
637
638      typedef duration::rep    rep;
639      typedef duration::period period;
640      typedef chrono::time_point<system_clock, duration> time_point;
641
642      static const bool is_monotonic = false;
643
644      static time_point
645      now() throw ();
646
647      // Map to C API
648      static std::time_t
649      to_time_t(const time_point& __t)
650      {
651        return std::time_t(
652          duration_cast<chrono::seconds>(__t.time_since_epoch()).count());
653      }
654
655      static time_point
656      from_time_t(std::time_t __t)
657      { 
658        return time_point_cast<system_clock::duration>(
659          chrono::time_point<system_clock, chrono::seconds>(
660            chrono::seconds(__t)));
661      }
662
663      // TODO: requires constexpr
664      /*  
665      static_assert(
666        system_clock::duration::min() < 
667        system_clock::duration::zero(), 
668        "a clock's minimum duration cannot be less than its epoch");
669      */
670    };
671
672#ifdef _GLIBCXX_USE_CLOCK_MONOTONIC
673    /// monotonic_clock
674    struct monotonic_clock
675    {
676      typedef chrono::nanoseconds duration;
677      typedef duration::rep       rep;
678      typedef duration::period    period;
679      typedef chrono::time_point<monotonic_clock, duration> time_point;
680
681      static const bool is_monotonic = true;
682
683      static time_point
684      now();
685    };
686#else
687    typedef system_clock monotonic_clock;
688#endif
689
690    typedef system_clock high_resolution_clock;
691  } // namespace chrono
692
693  // @} group chrono
694} // namespace std
695
696#endif //_GLIBCXX_USE_C99_STDINT_TR1
697
698#endif //__GXX_EXPERIMENTAL_CXX0X__
699
700#endif //_GLIBCXX_CHRONO
701