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