chrono

Go to the documentation of this file.
00001 // <chrono> -*- C++ -*-
00002 
00003 // Copyright (C) 2008, 2009 Free Software Foundation, Inc.
00004 //
00005 // This file is part of the GNU ISO C++ Library.  This library is free
00006 // software; you can redistribute it and/or modify it under the
00007 // terms of the GNU General Public License as published by the
00008 // Free Software Foundation; either version 3, or (at your option)
00009 // any later version.
00010 
00011 // This library is distributed in the hope that it will be useful,
00012 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00013 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00014 // GNU General Public License for more details.
00015 
00016 // Under Section 7 of GPL version 3, you are granted additional
00017 // permissions described in the GCC Runtime Library Exception, version
00018 // 3.1, as published by the Free Software Foundation.
00019 
00020 // You should have received a copy of the GNU General Public License and
00021 // a copy of the GCC Runtime Library Exception along with this program;
00022 // see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
00023 // <http://www.gnu.org/licenses/>.
00024 
00025 /** @file include/chrono
00026  *  This is a Standard C++ Library header.
00027  */
00028 
00029 #ifndef _GLIBCXX_CHRONO
00030 #define _GLIBCXX_CHRONO 1
00031 
00032 #pragma GCC system_header
00033 
00034 #ifndef __GXX_EXPERIMENTAL_CXX0X__
00035 # include <c++0x_warning.h>
00036 #else
00037 
00038 #ifdef _GLIBCXX_INCLUDE_AS_TR1
00039 #  error C++0x header cannot be included from TR1 header
00040 #endif
00041 
00042 #include <ratio>
00043 #include <type_traits>
00044 #include <limits>
00045 #include <ctime>
00046 
00047 #ifdef _GLIBCXX_USE_C99_STDINT_TR1
00048 
00049 namespace std 
00050 {
00051   /**
00052    * @defgroup chrono Time
00053    * @ingroup utilities
00054    *
00055    * Classes and functions for time.
00056    * @{
00057    */
00058 
00059   /** @namespace std::chrono
00060    *  @brief ISO C++ 0x entities sub namespace for time and date.
00061    */
00062   namespace chrono
00063   {
00064     template<typename _Rep, typename _Period = ratio<1>>
00065       struct duration;
00066 
00067     template<typename _Clock, typename _Duration = typename _Clock::duration>
00068       struct time_point;
00069   }
00070 
00071   // 20.8.2.3 specialization of common_type (for duration)
00072   template<typename _Rep1, typename _Period1, typename _Rep2, typename _Period2>
00073     struct common_type<chrono::duration<_Rep1, _Period1>,
00074                        chrono::duration<_Rep2, _Period2>>
00075     {
00076       typedef chrono::duration<typename common_type<_Rep1, _Rep2>::type,
00077         ratio<__static_gcd<_Period1::num, _Period2::num>::value,
00078         (_Period1::den / __static_gcd<_Period1::den, _Period2::den>::value)
00079         * _Period2::den>> type;
00080     };
00081   
00082   // 20.8.2.3 specialization of common_type (for time_point)
00083   template<typename _Clock, typename _Duration1, typename _Duration2>
00084     struct common_type<chrono::time_point<_Clock, _Duration1>,
00085                        chrono::time_point<_Clock, _Duration2>>
00086     {
00087       typedef chrono::time_point<_Clock, 
00088         typename common_type<_Duration1, _Duration2>::type> type;
00089     };
00090 
00091   namespace chrono 
00092   {
00093     // Primary template for duration_cast impl.
00094     template<typename _ToDuration, typename _CF, typename _CR,
00095              bool _NumIsOne = false, bool _DenIsOne = false>
00096       struct __duration_cast_impl
00097       {
00098         template<typename _Rep, typename _Period>
00099           static _ToDuration __cast(const duration<_Rep, _Period>& __d)
00100           {
00101             return _ToDuration(static_cast<
00102               typename _ToDuration::rep>(static_cast<_CR>(__d.count())
00103               * static_cast<_CR>(_CF::num)
00104               / static_cast<_CR>(_CF::den)));
00105           }
00106       };
00107 
00108     template<typename _ToDuration, typename _CF, typename _CR>
00109       struct __duration_cast_impl<_ToDuration, _CF, _CR, true, true>
00110       {
00111         template<typename _Rep, typename _Period>
00112           static _ToDuration __cast(const duration<_Rep, _Period>& __d)
00113           {
00114             return _ToDuration(
00115               static_cast<typename _ToDuration::rep>(__d.count()));
00116           }
00117       };
00118 
00119     template<typename _ToDuration, typename _CF, typename _CR>
00120       struct __duration_cast_impl<_ToDuration, _CF, _CR, true, false>
00121       {
00122         template<typename _Rep, typename _Period>
00123           static _ToDuration __cast(const duration<_Rep, _Period>& __d)
00124           {
00125             return _ToDuration(static_cast<typename _ToDuration::rep>(
00126               static_cast<_CR>(__d.count()) / static_cast<_CR>(_CF::den))); 
00127           }
00128       };
00129 
00130     template<typename _ToDuration, typename _CF, typename _CR>
00131       struct __duration_cast_impl<_ToDuration, _CF, _CR, false, true>
00132       {
00133         template<typename _Rep, typename _Period>
00134           static _ToDuration __cast(const duration<_Rep, _Period>& __d)
00135           {
00136             return _ToDuration(static_cast<typename _ToDuration::rep>(
00137               static_cast<_CR>(__d.count()) * static_cast<_CR>(_CF::num)));
00138           }
00139       };
00140 
00141     /// duration_cast
00142     template<typename _ToDuration, typename _Rep, typename _Period>
00143       inline _ToDuration
00144       duration_cast(const duration<_Rep, _Period>& __d)
00145       {
00146         typedef typename
00147           ratio_divide<_Period, typename _ToDuration::period>::type __cf;
00148         typedef typename
00149           common_type<typename _ToDuration::rep, _Rep, intmax_t>::type __cr;
00150 
00151         return __duration_cast_impl<_ToDuration, __cf, __cr,
00152           __cf::num == 1, __cf::den == 1>::__cast(__d);
00153       }
00154 
00155     /// treat_as_floating_point
00156     template<typename _Rep>
00157       struct treat_as_floating_point 
00158       : is_floating_point<_Rep>
00159       { };
00160 
00161     /// duration_values
00162     template<typename _Rep>
00163       struct duration_values
00164       {
00165         static const _Rep
00166         zero()
00167         { return _Rep(0); }
00168         
00169         static const _Rep
00170         max()
00171         { return numeric_limits<_Rep>::max(); }
00172         
00173         static const _Rep
00174         min()
00175         { return numeric_limits<_Rep>::min(); }
00176       };
00177 
00178     template<typename _Tp>
00179       struct __is_duration
00180       : std::false_type
00181       { };
00182 
00183     template<typename _Rep, typename _Period>
00184       struct __is_duration<duration<_Rep, _Period>>
00185       : std::true_type
00186       { };
00187 
00188     template<typename T>
00189       struct __is_ratio
00190       : std::false_type
00191       { };
00192 
00193     template<intmax_t _Num, intmax_t _Den>
00194       struct __is_ratio<ratio<_Num, _Den>>
00195       : std::true_type
00196       { };
00197 
00198     /// duration
00199     template<typename _Rep, typename _Period>
00200       struct duration
00201       {
00202     static_assert(!__is_duration<_Rep>::value, "rep cannot be a duration");
00203     static_assert(__is_ratio<_Period>::value, 
00204               "period must be a specialization of ratio");
00205         static_assert(_Period::num > 0, "period must be positive");
00206         
00207         typedef _Rep    rep;
00208         typedef _Period period;
00209         
00210         // 20.8.3.1 construction / copy / destroy
00211     duration() = default;
00212 
00213         template<typename _Rep2>
00214           explicit duration(_Rep2 const& __rep)
00215           : __r(static_cast<rep>(__rep))
00216           {
00217             static_assert(is_convertible<_Rep2,rep>::value 
00218               && (treat_as_floating_point<rep>::value 
00219                   || !treat_as_floating_point<_Rep2>::value),
00220           "cannot construct integral duration with floating point type");
00221           }
00222 
00223         template<typename _Rep2, typename _Period2>
00224           duration(const duration<_Rep2, _Period2>& __d)
00225           : __r(duration_cast<duration>(__d).count())
00226           {
00227             static_assert(treat_as_floating_point<rep>::value == true 
00228               || ratio_divide<_Period2, period>::type::den == 1, 
00229               "the resulting duration is not exactly representable");
00230           }
00231 
00232     ~duration() = default;
00233     duration(const duration&) = default;
00234     duration& operator=(const duration&) = default;
00235 
00236         // 20.8.3.2 observer
00237         rep
00238         count() const
00239         { return __r; }
00240 
00241         // 20.8.3.3 arithmetic
00242         duration
00243         operator+() const 
00244         { return *this; }
00245 
00246         duration
00247         operator-() const 
00248         { return duration(-__r); }
00249 
00250         duration&
00251         operator++() 
00252         {
00253           ++__r;
00254           return *this;
00255         }
00256 
00257         duration
00258         operator++(int) 
00259         { return duration(__r++); }
00260 
00261         duration&
00262         operator--() 
00263         { 
00264           --__r;
00265           return *this;
00266         }
00267 
00268         duration
00269         operator--(int) 
00270         { return duration(__r--); }
00271         
00272         duration&
00273         operator+=(const duration& __d)
00274         {
00275           __r += __d.count();
00276           return *this;
00277         }
00278 
00279         duration&
00280         operator-=(const duration& __d)
00281         {
00282           __r -= __d.count();
00283           return *this;
00284         }
00285 
00286         duration&
00287         operator*=(const rep& __rhs)
00288         {
00289           __r *= __rhs;
00290           return *this;
00291         }
00292 
00293         duration&
00294         operator/=(const rep& __rhs)
00295         { 
00296           __r /= __rhs;
00297           return *this;
00298         }
00299 
00300         // 20.8.3.4 special values
00301         // TODO: These should be constexprs.
00302         static const duration
00303         zero()
00304         { return duration(duration_values<rep>::zero()); }
00305 
00306         static const duration
00307         min()
00308         { return duration(duration_values<rep>::min()); }
00309       
00310         static const duration
00311         max()
00312         { return duration(duration_values<rep>::max()); }
00313    
00314       private:    
00315         rep __r;
00316       };
00317 
00318     template<typename _Rep1, typename _Period1,
00319              typename _Rep2, typename _Period2>
00320       inline typename common_type<duration<_Rep1, _Period1>, 
00321                                   duration<_Rep2, _Period2>>::type
00322       operator+(const duration<_Rep1, _Period1>& __lhs, 
00323                 const duration<_Rep2, _Period2>& __rhs)
00324       {
00325         typedef typename common_type<duration<_Rep1, _Period1>, 
00326                                      duration<_Rep2, _Period2>>::type __ct;
00327         return __ct(__lhs) += __rhs;
00328       }
00329 
00330     template<typename _Rep1, typename _Period1, 
00331              typename _Rep2, typename _Period2>
00332       inline typename common_type<duration<_Rep1, _Period1>, 
00333                                   duration<_Rep2, _Period2>>::type
00334       operator-(const duration<_Rep1, _Period1>& __lhs, 
00335                 const duration<_Rep2, _Period2>& __rhs)
00336       {
00337         typedef typename common_type<duration<_Rep1, _Period1>,
00338                                      duration<_Rep2, _Period2>>::type __ct;
00339         return __ct(__lhs) -= __rhs;
00340       }
00341 
00342     template<typename _Rep1, typename _Period, typename _Rep2>
00343       inline duration<typename common_type<_Rep1, _Rep2>::type, _Period>
00344       operator*(const duration<_Rep1, _Period>& __d, const _Rep2& __s)
00345       {
00346         typedef typename common_type<_Rep1, _Rep2>::type __cr;
00347         return duration<__cr, _Period>(__d) *= __s;
00348       }
00349 
00350     template<typename _Rep1, typename _Period, typename _Rep2>
00351       inline duration<typename common_type<_Rep1, _Rep2>::type, _Period>
00352       operator*(const _Rep2& __s, const duration<_Rep1, _Period>& __d)
00353       { return __d * __s; }
00354 
00355     template<typename _Tp, typename _Up, typename _Ep = void>
00356       struct __division_impl;
00357   
00358     template<typename _Rep1, typename _Period, typename _Rep2>
00359       struct __division_impl<duration<_Rep1, _Period>, _Rep2, 
00360         typename enable_if<!__is_duration<_Rep2>::value>::type>
00361       {
00362         typedef typename common_type<_Rep1, _Rep2>::type __cr;
00363         typedef 
00364           duration<typename common_type<_Rep1, _Rep2>::type, _Period> __rt;
00365 
00366         static __rt
00367         __divide(const duration<_Rep1, _Period>& __d, const _Rep2& __s)
00368         { return duration<__cr, _Period>(__d) /= __s; }
00369       };
00370 
00371     template<typename _Rep1, typename _Period1, 
00372              typename _Rep2, typename _Period2>
00373       struct __division_impl<duration<_Rep1, _Period1>, 
00374                              duration<_Rep2, _Period2>>
00375       {
00376         typedef typename common_type<duration<_Rep1, _Period1>, 
00377                                      duration<_Rep2, _Period2>>::type __ct;
00378         typedef typename common_type<_Rep1, _Rep2>::type __rt;
00379 
00380         static __rt
00381         __divide(const duration<_Rep1, _Period1>& __lhs, 
00382                  const duration<_Rep2, _Period2>& __rhs)
00383         { return __ct(__lhs).count() / __ct(__rhs).count(); }
00384       };
00385   
00386     template<typename _Rep, typename _Period, typename _Up>
00387       inline typename __division_impl<duration<_Rep, _Period>, _Up>::__rt
00388       operator/(const duration<_Rep, _Period>& __d, const _Up& __u)
00389       {
00390         return 
00391           __division_impl<duration<_Rep, _Period>, _Up>::__divide(__d, __u);
00392       }
00393  
00394     // comparisons
00395     template<typename _Rep1, typename _Period1,
00396              typename _Rep2, typename _Period2>
00397       inline bool
00398       operator==(const duration<_Rep1, _Period1>& __lhs, 
00399                  const duration<_Rep2, _Period2>& __rhs)
00400       {
00401         typedef typename common_type<duration<_Rep1, _Period1>, 
00402                                      duration<_Rep2, _Period2>>::type __ct;
00403         return __ct(__lhs).count() == __ct(__rhs).count();
00404       }
00405 
00406     template<typename _Rep1, typename _Period1,
00407              typename _Rep2, typename _Period2>
00408       inline bool
00409       operator<(const duration<_Rep1, _Period1>& __lhs, 
00410                 const duration<_Rep2, _Period2>& __rhs)
00411       {
00412         typedef typename common_type<duration<_Rep1, _Period1>, 
00413                                      duration<_Rep2, _Period2>>::type __ct;
00414         return __ct(__lhs).count() < __ct(__rhs).count();
00415       }
00416 
00417     template<typename _Rep1, typename _Period1,
00418              typename _Rep2, typename _Period2>
00419       inline bool
00420       operator!=(const duration<_Rep1, _Period1>& __lhs, 
00421                  const duration<_Rep2, _Period2>& __rhs)
00422       { return !(__lhs == __rhs); }
00423 
00424     template<typename _Rep1, typename _Period1,
00425              typename _Rep2, typename _Period2>
00426       inline bool
00427       operator<=(const duration<_Rep1, _Period1>& __lhs, 
00428                  const duration<_Rep2, _Period2>& __rhs)
00429       { return !(__rhs < __lhs); }
00430 
00431     template<typename _Rep1, typename _Period1,
00432              typename _Rep2, typename _Period2>
00433       inline bool 
00434       operator>(const duration<_Rep1, _Period1>& __lhs, 
00435                 const duration<_Rep2, _Period2>& __rhs)
00436       { return __rhs < __lhs; }
00437 
00438     template<typename _Rep1, typename _Period1, 
00439              typename _Rep2, typename _Period2>
00440       inline bool
00441       operator>=(const duration<_Rep1, _Period1>& __lhs, 
00442                  const duration<_Rep2, _Period2>& __rhs)
00443       { return !(__lhs < __rhs); }
00444 
00445     /// nanoseconds
00446     typedef duration<int64_t,        nano> nanoseconds;
00447 
00448     /// microseconds
00449     typedef duration<int64_t,       micro> microseconds;
00450 
00451     /// milliseconds
00452     typedef duration<int64_t,       milli> milliseconds;
00453     
00454     /// seconds
00455     typedef duration<int64_t             > seconds;
00456 
00457     /// minutes
00458     typedef duration<int,     ratio<  60>> minutes;
00459 
00460     /// hours
00461     typedef duration<int,     ratio<3600>> hours;
00462 
00463     /// time_point
00464     template<typename _Clock, typename _Duration>
00465       struct time_point
00466       {
00467     typedef _Clock                    clock;
00468     typedef _Duration                 duration;
00469     typedef typename duration::rep    rep;
00470     typedef typename duration::period period;
00471 
00472     time_point() : __d(duration::zero())
00473     { }
00474 
00475     explicit time_point(const duration& __dur) 
00476     : __d(duration::zero() + __dur)
00477     { }
00478 
00479     // conversions
00480     template<typename _Duration2>
00481       time_point(const time_point<clock, _Duration2>& __t)
00482       : __d(__t.time_since_epoch())
00483       { }
00484 
00485     // observer
00486     duration
00487     time_since_epoch() const
00488     { return __d; }
00489     
00490     // arithmetic
00491     time_point&
00492     operator+=(const duration& __dur)
00493     {
00494       __d += __dur;
00495       return *this;
00496     }
00497     
00498     time_point&
00499     operator-=(const duration& __dur)
00500     {
00501       __d -= __dur;
00502       return *this;
00503     }
00504     
00505     // special values
00506     // TODO: These should be constexprs.
00507     static const time_point
00508     min()
00509     { return time_point(duration::min()); }
00510     
00511     static const time_point
00512     max()
00513     { return time_point(duration::max()); }
00514     
00515       private:
00516     duration __d;
00517       };
00518   
00519     /// time_point_cast
00520     template<typename _ToDuration, typename _Clock, typename _Duration>
00521       inline time_point<_Clock, _ToDuration> 
00522       time_point_cast(const time_point<_Clock, _Duration>& __t)
00523       {
00524         return time_point<_Clock, _ToDuration>(
00525           duration_cast<_ToDuration>(__t.time_since_epoch()));  
00526       }
00527 
00528     template<typename _Clock, typename _Duration1,
00529              typename _Rep2, typename _Period2>
00530       inline time_point<_Clock, 
00531         typename common_type<_Duration1, duration<_Rep2, _Period2>>::type>
00532       operator+(const time_point<_Clock, _Duration1>& __lhs, 
00533                 const duration<_Rep2, _Period2>& __rhs)
00534       {
00535         typedef time_point<_Clock, 
00536           typename common_type<_Duration1, 
00537                                duration<_Rep2, _Period2>>::type> __ct;
00538         return __ct(__lhs) += __rhs;
00539       }
00540 
00541     template<typename _Rep1, typename _Period1,
00542              typename _Clock, typename _Duration2>
00543       inline time_point<_Clock, 
00544         typename common_type<duration<_Rep1, _Period1>, _Duration2>::type>
00545       operator+(const duration<_Rep1, _Period1>& __lhs, 
00546                 const time_point<_Clock, _Duration2>& __rhs)
00547       { return __rhs + __lhs; }
00548 
00549     template<typename _Clock, typename _Duration1,
00550              typename _Rep2, typename _Period2>
00551       inline time_point<_Clock, 
00552         typename common_type<_Duration1, duration<_Rep2, _Period2>>::type>
00553       operator-(const time_point<_Clock, _Duration1>& __lhs, 
00554                 const duration<_Rep2, _Period2>& __rhs)
00555       { return __lhs + (-__rhs); }
00556 
00557     template<typename _Clock, typename _Duration1, typename _Duration2>
00558       inline typename common_type<_Duration1, _Duration2>::type
00559       operator-(const time_point<_Clock, _Duration1>& __lhs, 
00560                 const time_point<_Clock, _Duration2>& __rhs)
00561       { return __lhs.time_since_epoch() - __rhs.time_since_epoch(); }
00562 
00563     template<typename _Clock, typename _Duration1, typename _Duration2>
00564       inline bool
00565       operator==(const time_point<_Clock, _Duration1>& __lhs,
00566                  const time_point<_Clock, _Duration2>& __rhs)
00567       { return __lhs.time_since_epoch() == __rhs.time_since_epoch(); }
00568 
00569     template<typename _Clock, typename _Duration1, typename _Duration2>
00570       inline bool
00571       operator!=(const time_point<_Clock, _Duration1>& __lhs,
00572                  const time_point<_Clock, _Duration2>& __rhs)
00573       { return !(__lhs == __rhs); }
00574 
00575     template<typename _Clock, typename _Duration1, typename _Duration2>
00576       inline bool
00577       operator<(const time_point<_Clock, _Duration1>& __lhs,
00578                 const time_point<_Clock, _Duration2>& __rhs)
00579       { return  __lhs.time_since_epoch() < __rhs.time_since_epoch(); }
00580 
00581     template<typename _Clock, typename _Duration1, typename _Duration2>
00582       inline bool
00583       operator<=(const time_point<_Clock, _Duration1>& __lhs,
00584                  const time_point<_Clock, _Duration2>& __rhs)
00585       { return !(__rhs < __lhs); }
00586 
00587     template<typename _Clock, typename _Duration1, typename _Duration2>
00588       inline bool
00589       operator>(const time_point<_Clock, _Duration1>& __lhs,
00590                 const time_point<_Clock, _Duration2>& __rhs)
00591       { return __rhs < __lhs; }
00592 
00593     template<typename _Clock, typename _Duration1, typename _Duration2>
00594       inline bool
00595       operator>=(const time_point<_Clock, _Duration1>& __lhs,
00596                  const time_point<_Clock, _Duration2>& __rhs)
00597       { return !(__lhs < __rhs); }
00598 
00599     /// system_clock
00600     struct system_clock
00601     {
00602 #ifdef _GLIBCXX_USE_CLOCK_REALTIME
00603       typedef chrono::nanoseconds     duration;      
00604 #elif defined(_GLIBCXX_USE_GETTIMEOFDAY)
00605       typedef chrono::microseconds    duration;      
00606 #else
00607       typedef chrono::seconds         duration;      
00608 #endif
00609 
00610       typedef duration::rep    rep;
00611       typedef duration::period period;
00612       typedef chrono::time_point<system_clock, duration> time_point;
00613 
00614       static const bool is_monotonic = false;
00615 
00616       static time_point
00617       now();   
00618 
00619       // Map to C API
00620       static std::time_t
00621       to_time_t(const time_point& __t)
00622       {
00623         return std::time_t(
00624           duration_cast<chrono::seconds>(__t.time_since_epoch()).count());
00625       }
00626 
00627       static time_point
00628       from_time_t(std::time_t __t)
00629       { 
00630         return time_point_cast<system_clock::duration>(
00631           chrono::time_point<system_clock, chrono::seconds>(
00632             chrono::seconds(__t)));
00633       }
00634 
00635       // TODO: requires constexpr
00636       /*  
00637       static_assert(
00638         system_clock::duration::min() < 
00639         system_clock::duration::zero(), 
00640         "a clock's minimum duration cannot be less than its epoch");
00641       */
00642     };
00643 
00644 #ifdef _GLIBCXX_USE_CLOCK_MONOTONIC
00645     /// monotonic_clock
00646     struct monotonic_clock
00647     {
00648       typedef chrono::nanoseconds duration;
00649       typedef duration::rep       rep;
00650       typedef duration::period    period;
00651       typedef chrono::time_point<monotonic_clock, duration> time_point;
00652 
00653       static const bool is_monotonic = true;
00654 
00655       static time_point
00656       now();
00657     };
00658 #else
00659     typedef system_clock monotonic_clock;
00660 #endif
00661 
00662     typedef system_clock high_resolution_clock;
00663   } // namespace chrono
00664 
00665   // @} group chrono
00666 } // namespace std
00667 
00668 #endif //_GLIBCXX_USE_C99_STDINT_TR1
00669 
00670 #endif //__GXX_EXPERIMENTAL_CXX0X__
00671 
00672 #endif //_GLIBCXX_CHRONO

Generated on Thu Jul 23 21:16:02 2009 for libstdc++ by  doxygen 1.5.8