Home | History | Annotate | Download | only in include
      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();   
    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
    673