libstdc++
|
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