1// <chrono> -*- C++ -*- 2 3// Copyright (C) 2008, 2009, 2010 Free Software Foundation, Inc. 4// 5// This file is part of the GNU ISO C++ Library. This library is free 6// software; you can redistribute it and/or modify it under the 7// terms of the GNU General Public License as published by the 8// Free Software Foundation; either version 3, or (at your option) 9// any later version. 10 11// This library is distributed in the hope that it will be useful, 12// but WITHOUT ANY WARRANTY; without even the implied warranty of 13// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14// GNU General Public License for more details. 15 16// Under Section 7 of GPL version 3, you are granted additional 17// permissions described in the GCC Runtime Library Exception, version 18// 3.1, as published by the Free Software Foundation. 19 20// You should have received a copy of the GNU General Public License and 21// a copy of the GCC Runtime Library Exception along with this program; 22// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see 23// <http://www.gnu.org/licenses/>. 24 25/** @file include/chrono 26 * This is a Standard C++ Library header. 27 */ 28 29#ifndef _GLIBCXX_CHRONO 30#define _GLIBCXX_CHRONO 1 31 32#pragma GCC system_header 33 34#ifndef __GXX_EXPERIMENTAL_CXX0X__ 35# include <bits/c++0x_warning.h> 36#else 37 38#ifdef _GLIBCXX_INCLUDE_AS_TR1 39# error C++0x header cannot be included from TR1 header 40#endif 41 42#include <ratio> 43#include <type_traits> 44#include <limits> 45#include <ctime> 46 47#ifdef _GLIBCXX_USE_C99_STDINT_TR1 48 49namespace std 50{ 51 /** 52 * @defgroup chrono Time 53 * @ingroup utilities 54 * 55 * Classes and functions for time. 56 * @{ 57 */ 58 59 /** @namespace std::chrono 60 * @brief ISO C++ 0x entities sub namespace for time and date. 61 */ 62 namespace chrono 63 { 64 template<typename _Rep, typename _Period = ratio<1>> 65 struct duration; 66 67 template<typename _Clock, typename _Duration = typename _Clock::duration> 68 struct time_point; 69 } 70 71 // 20.8.2.3 specialization of common_type (for duration) 72 template<typename _Rep1, typename _Period1, typename _Rep2, typename _Period2> 73 struct common_type<chrono::duration<_Rep1, _Period1>, 74 chrono::duration<_Rep2, _Period2>> 75 { 76 typedef chrono::duration<typename common_type<_Rep1, _Rep2>::type, 77 ratio<__static_gcd<_Period1::num, _Period2::num>::value, 78 (_Period1::den / __static_gcd<_Period1::den, _Period2::den>::value) 79 * _Period2::den>> type; 80 }; 81 82 // 20.8.2.3 specialization of common_type (for time_point) 83 template<typename _Clock, typename _Duration1, typename _Duration2> 84 struct common_type<chrono::time_point<_Clock, _Duration1>, 85 chrono::time_point<_Clock, _Duration2>> 86 { 87 typedef chrono::time_point<_Clock, 88 typename common_type<_Duration1, _Duration2>::type> type; 89 }; 90 91 namespace chrono 92 { 93 // Primary template for duration_cast impl. 94 template<typename _ToDuration, typename _CF, typename _CR, 95 bool _NumIsOne = false, bool _DenIsOne = false> 96 struct __duration_cast_impl 97 { 98 template<typename _Rep, typename _Period> 99 static _ToDuration __cast(const duration<_Rep, _Period>& __d) 100 { 101 return _ToDuration(static_cast< 102 typename _ToDuration::rep>(static_cast<_CR>(__d.count()) 103 * static_cast<_CR>(_CF::num) 104 / static_cast<_CR>(_CF::den))); 105 } 106 }; 107 108 template<typename _ToDuration, typename _CF, typename _CR> 109 struct __duration_cast_impl<_ToDuration, _CF, _CR, true, true> 110 { 111 template<typename _Rep, typename _Period> 112 static _ToDuration __cast(const duration<_Rep, _Period>& __d) 113 { 114 return _ToDuration( 115 static_cast<typename _ToDuration::rep>(__d.count())); 116 } 117 }; 118 119 template<typename _ToDuration, typename _CF, typename _CR> 120 struct __duration_cast_impl<_ToDuration, _CF, _CR, true, false> 121 { 122 template<typename _Rep, typename _Period> 123 static _ToDuration __cast(const duration<_Rep, _Period>& __d) 124 { 125 return _ToDuration(static_cast<typename _ToDuration::rep>( 126 static_cast<_CR>(__d.count()) / static_cast<_CR>(_CF::den))); 127 } 128 }; 129 130 template<typename _ToDuration, typename _CF, typename _CR> 131 struct __duration_cast_impl<_ToDuration, _CF, _CR, false, true> 132 { 133 template<typename _Rep, typename _Period> 134 static _ToDuration __cast(const duration<_Rep, _Period>& __d) 135 { 136 return _ToDuration(static_cast<typename _ToDuration::rep>( 137 static_cast<_CR>(__d.count()) * static_cast<_CR>(_CF::num))); 138 } 139 }; 140 141 template<typename _Tp> 142 struct __is_duration 143 : std::false_type 144 { }; 145 146 template<typename _Rep, typename _Period> 147 struct __is_duration<duration<_Rep, _Period>> 148 : std::true_type 149 { }; 150 151 /// duration_cast 152 template<typename _ToDuration, typename _Rep, typename _Period> 153 inline typename enable_if<__is_duration<_ToDuration>::value, 154 _ToDuration>::type 155 duration_cast(const duration<_Rep, _Period>& __d) 156 { 157 typedef typename 158 ratio_divide<_Period, typename _ToDuration::period>::type __cf; 159 typedef typename 160 common_type<typename _ToDuration::rep, _Rep, intmax_t>::type __cr; 161 162 return __duration_cast_impl<_ToDuration, __cf, __cr, 163 __cf::num == 1, __cf::den == 1>::__cast(__d); 164 } 165 166 /// treat_as_floating_point 167 template<typename _Rep> 168 struct treat_as_floating_point 169 : is_floating_point<_Rep> 170 { }; 171 172 /// duration_values 173 template<typename _Rep> 174 struct duration_values 175 { 176 static const _Rep 177 zero() 178 { return _Rep(0); } 179 180 static const _Rep 181 max() 182 { return numeric_limits<_Rep>::max(); } 183 184 static const _Rep 185 min() 186 { return numeric_limits<_Rep>::min(); } 187 }; 188 189 template<typename T> 190 struct __is_ratio 191 : std::false_type 192 { }; 193 194 template<intmax_t _Num, intmax_t _Den> 195 struct __is_ratio<ratio<_Num, _Den>> 196 : std::true_type 197 { }; 198 199 /// duration 200 template<typename _Rep, typename _Period> 201 struct duration 202 { 203 static_assert(!__is_duration<_Rep>::value, "rep cannot be a duration"); 204 static_assert(__is_ratio<_Period>::value, 205 "period must be a specialization of ratio"); 206 static_assert(_Period::num > 0, "period must be positive"); 207 208 typedef _Rep rep; 209 typedef _Period period; 210 211 // 20.8.3.1 construction / copy / destroy 212 duration() = default; 213 214 template<typename _Rep2, typename = typename 215 enable_if<is_convertible<_Rep2, rep>::value 216 && (treat_as_floating_point<rep>::value 217 || !treat_as_floating_point<_Rep2>::value)>::type> 218 explicit duration(const _Rep2& __rep) 219 : __r(static_cast<rep>(__rep)) { } 220 221 template<typename _Rep2, typename _Period2, typename = typename 222 enable_if<treat_as_floating_point<rep>::value 223 || (ratio_divide<_Period2, period>::type::den == 1 224 && !treat_as_floating_point<_Rep2>::value)>::type> 225 duration(const duration<_Rep2, _Period2>& __d) 226 : __r(duration_cast<duration>(__d).count()) { } 227 228 ~duration() = default; 229 duration(const duration&) = default; 230 duration& operator=(const duration&) = default; 231 232 // 20.8.3.2 observer 233 rep 234 count() const 235 { return __r; } 236 237 // 20.8.3.3 arithmetic 238 duration 239 operator+() const 240 { return *this; } 241 242 duration 243 operator-() const 244 { return duration(-__r); } 245 246 duration& 247 operator++() 248 { 249 ++__r; 250 return *this; 251 } 252 253 duration 254 operator++(int) 255 { return duration(__r++); } 256 257 duration& 258 operator--() 259 { 260 --__r; 261 return *this; 262 } 263 264 duration 265 operator--(int) 266 { return duration(__r--); } 267 268 duration& 269 operator+=(const duration& __d) 270 { 271 __r += __d.count(); 272 return *this; 273 } 274 275 duration& 276 operator-=(const duration& __d) 277 { 278 __r -= __d.count(); 279 return *this; 280 } 281 282 duration& 283 operator*=(const rep& __rhs) 284 { 285 __r *= __rhs; 286 return *this; 287 } 288 289 duration& 290 operator/=(const rep& __rhs) 291 { 292 __r /= __rhs; 293 return *this; 294 } 295 296 // DR 934. 297 template<typename _Rep2 = rep> 298 typename enable_if<!treat_as_floating_point<_Rep2>::value, 299 duration&>::type 300 operator%=(const rep& __rhs) 301 { 302 __r %= __rhs; 303 return *this; 304 } 305 306 template<typename _Rep2 = rep> 307 typename enable_if<!treat_as_floating_point<_Rep2>::value, 308 duration&>::type 309 operator%=(const duration& __d) 310 { 311 __r %= __d.count(); 312 return *this; 313 } 314 315 // 20.8.3.4 special values 316 // TODO: These should be constexprs. 317 static const duration 318 zero() 319 { return duration(duration_values<rep>::zero()); } 320 321 static const duration 322 min() 323 { return duration(duration_values<rep>::min()); } 324 325 static const duration 326 max() 327 { return duration(duration_values<rep>::max()); } 328 329 private: 330 rep __r; 331 }; 332 333 template<typename _Rep1, typename _Period1, 334 typename _Rep2, typename _Period2> 335 inline typename common_type<duration<_Rep1, _Period1>, 336 duration<_Rep2, _Period2>>::type 337 operator+(const duration<_Rep1, _Period1>& __lhs, 338 const duration<_Rep2, _Period2>& __rhs) 339 { 340 typedef typename common_type<duration<_Rep1, _Period1>, 341 duration<_Rep2, _Period2>>::type __ct; 342 return __ct(__lhs) += __rhs; 343 } 344 345 template<typename _Rep1, typename _Period1, 346 typename _Rep2, typename _Period2> 347 inline typename common_type<duration<_Rep1, _Period1>, 348 duration<_Rep2, _Period2>>::type 349 operator-(const duration<_Rep1, _Period1>& __lhs, 350 const duration<_Rep2, _Period2>& __rhs) 351 { 352 typedef typename common_type<duration<_Rep1, _Period1>, 353 duration<_Rep2, _Period2>>::type __ct; 354 return __ct(__lhs) -= __rhs; 355 } 356 357 template<typename _Rep1, typename _Rep2, bool = 358 is_convertible<_Rep2, 359 typename common_type<_Rep1, _Rep2>::type>::value> 360 struct __common_rep_type { }; 361 362 template<typename _Rep1, typename _Rep2> 363 struct __common_rep_type<_Rep1, _Rep2, true> 364 { typedef typename common_type<_Rep1, _Rep2>::type type; }; 365 366 template<typename _Rep1, typename _Period, typename _Rep2> 367 inline duration<typename __common_rep_type<_Rep1, _Rep2>::type, _Period> 368 operator*(const duration<_Rep1, _Period>& __d, const _Rep2& __s) 369 { 370 typedef typename common_type<_Rep1, _Rep2>::type __cr; 371 return duration<__cr, _Period>(__d) *= __s; 372 } 373 374 template<typename _Rep1, typename _Period, typename _Rep2> 375 inline duration<typename __common_rep_type<_Rep2, _Rep1>::type, _Period> 376 operator*(const _Rep1& __s, const duration<_Rep2, _Period>& __d) 377 { return __d * __s; } 378 379 template<typename _Rep1, typename _Period, typename _Rep2> 380 inline duration<typename __common_rep_type<_Rep1, typename 381 enable_if<!__is_duration<_Rep2>::value, _Rep2>::type>::type, _Period> 382 operator/(const duration<_Rep1, _Period>& __d, const _Rep2& __s) 383 { 384 typedef typename common_type<_Rep1, _Rep2>::type __cr; 385 return duration<__cr, _Period>(__d) /= __s; 386 } 387 388 template<typename _Rep1, typename _Period1, 389 typename _Rep2, typename _Period2> 390 inline typename common_type<_Rep1, _Rep2>::type 391 operator/(const duration<_Rep1, _Period1>& __lhs, 392 const duration<_Rep2, _Period2>& __rhs) 393 { 394 typedef typename common_type<duration<_Rep1, _Period1>, 395 duration<_Rep2, _Period2>>::type __ct; 396 return __ct(__lhs).count() / __ct(__rhs).count(); 397 } 398 399 // DR 934. 400 template<typename _Rep1, typename _Period, typename _Rep2> 401 inline duration<typename __common_rep_type<_Rep1, typename 402 enable_if<!__is_duration<_Rep2>::value, _Rep2>::type>::type, _Period> 403 operator%(const duration<_Rep1, _Period>& __d, const _Rep2& __s) 404 { 405 typedef typename common_type<_Rep1, _Rep2>::type __cr; 406 return duration<__cr, _Period>(__d) %= __s; 407 } 408 409 template<typename _Rep1, typename _Period1, 410 typename _Rep2, typename _Period2> 411 inline typename common_type<duration<_Rep1, _Period1>, 412 duration<_Rep2, _Period2>>::type 413 operator%(const duration<_Rep1, _Period1>& __lhs, 414 const duration<_Rep2, _Period2>& __rhs) 415 { 416 typedef typename common_type<duration<_Rep1, _Period1>, 417 duration<_Rep2, _Period2>>::type __ct; 418 return __ct(__lhs) %= __rhs; 419 } 420 421 // comparisons 422 template<typename _Rep1, typename _Period1, 423 typename _Rep2, typename _Period2> 424 inline bool 425 operator==(const duration<_Rep1, _Period1>& __lhs, 426 const duration<_Rep2, _Period2>& __rhs) 427 { 428 typedef typename common_type<duration<_Rep1, _Period1>, 429 duration<_Rep2, _Period2>>::type __ct; 430 return __ct(__lhs).count() == __ct(__rhs).count(); 431 } 432 433 template<typename _Rep1, typename _Period1, 434 typename _Rep2, typename _Period2> 435 inline bool 436 operator<(const duration<_Rep1, _Period1>& __lhs, 437 const duration<_Rep2, _Period2>& __rhs) 438 { 439 typedef typename common_type<duration<_Rep1, _Period1>, 440 duration<_Rep2, _Period2>>::type __ct; 441 return __ct(__lhs).count() < __ct(__rhs).count(); 442 } 443 444 template<typename _Rep1, typename _Period1, 445 typename _Rep2, typename _Period2> 446 inline bool 447 operator!=(const duration<_Rep1, _Period1>& __lhs, 448 const duration<_Rep2, _Period2>& __rhs) 449 { return !(__lhs == __rhs); } 450 451 template<typename _Rep1, typename _Period1, 452 typename _Rep2, typename _Period2> 453 inline bool 454 operator<=(const duration<_Rep1, _Period1>& __lhs, 455 const duration<_Rep2, _Period2>& __rhs) 456 { return !(__rhs < __lhs); } 457 458 template<typename _Rep1, typename _Period1, 459 typename _Rep2, typename _Period2> 460 inline bool 461 operator>(const duration<_Rep1, _Period1>& __lhs, 462 const duration<_Rep2, _Period2>& __rhs) 463 { return __rhs < __lhs; } 464 465 template<typename _Rep1, typename _Period1, 466 typename _Rep2, typename _Period2> 467 inline bool 468 operator>=(const duration<_Rep1, _Period1>& __lhs, 469 const duration<_Rep2, _Period2>& __rhs) 470 { return !(__lhs < __rhs); } 471 472 /// nanoseconds 473 typedef duration<int64_t, nano> nanoseconds; 474 475 /// microseconds 476 typedef duration<int64_t, micro> microseconds; 477 478 /// milliseconds 479 typedef duration<int64_t, milli> milliseconds; 480 481 /// seconds 482 typedef duration<int64_t > seconds; 483 484 /// minutes 485 typedef duration<int, ratio< 60>> minutes; 486 487 /// hours 488 typedef duration<int, ratio<3600>> hours; 489 490 /// time_point 491 template<typename _Clock, typename _Duration> 492 struct time_point 493 { 494 typedef _Clock clock; 495 typedef _Duration duration; 496 typedef typename duration::rep rep; 497 typedef typename duration::period period; 498 499 time_point() : __d(duration::zero()) 500 { } 501 502 explicit time_point(const duration& __dur) 503 : __d(duration::zero() + __dur) 504 { } 505 506 // conversions 507 template<typename _Duration2> 508 time_point(const time_point<clock, _Duration2>& __t) 509 : __d(__t.time_since_epoch()) 510 { } 511 512 // observer 513 duration 514 time_since_epoch() const 515 { return __d; } 516 517 // arithmetic 518 time_point& 519 operator+=(const duration& __dur) 520 { 521 __d += __dur; 522 return *this; 523 } 524 525 time_point& 526 operator-=(const duration& __dur) 527 { 528 __d -= __dur; 529 return *this; 530 } 531 532 // special values 533 // TODO: These should be constexprs. 534 static const time_point 535 min() 536 { return time_point(duration::min()); } 537 538 static const time_point 539 max() 540 { return time_point(duration::max()); } 541 542 private: 543 duration __d; 544 }; 545 546 /// time_point_cast 547 template<typename _ToDuration, typename _Clock, typename _Duration> 548 inline typename enable_if<__is_duration<_ToDuration>::value, 549 time_point<_Clock, _ToDuration>>::type 550 time_point_cast(const time_point<_Clock, _Duration>& __t) 551 { 552 return time_point<_Clock, _ToDuration>( 553 duration_cast<_ToDuration>(__t.time_since_epoch())); 554 } 555 556 template<typename _Clock, typename _Duration1, 557 typename _Rep2, typename _Period2> 558 inline time_point<_Clock, 559 typename common_type<_Duration1, duration<_Rep2, _Period2>>::type> 560 operator+(const time_point<_Clock, _Duration1>& __lhs, 561 const duration<_Rep2, _Period2>& __rhs) 562 { 563 typedef time_point<_Clock, 564 typename common_type<_Duration1, 565 duration<_Rep2, _Period2>>::type> __ct; 566 return __ct(__lhs) += __rhs; 567 } 568 569 template<typename _Rep1, typename _Period1, 570 typename _Clock, typename _Duration2> 571 inline time_point<_Clock, 572 typename common_type<duration<_Rep1, _Period1>, _Duration2>::type> 573 operator+(const duration<_Rep1, _Period1>& __lhs, 574 const time_point<_Clock, _Duration2>& __rhs) 575 { return __rhs + __lhs; } 576 577 template<typename _Clock, typename _Duration1, 578 typename _Rep2, typename _Period2> 579 inline time_point<_Clock, 580 typename common_type<_Duration1, duration<_Rep2, _Period2>>::type> 581 operator-(const time_point<_Clock, _Duration1>& __lhs, 582 const duration<_Rep2, _Period2>& __rhs) 583 { return __lhs + (-__rhs); } 584 585 template<typename _Clock, typename _Duration1, typename _Duration2> 586 inline typename common_type<_Duration1, _Duration2>::type 587 operator-(const time_point<_Clock, _Duration1>& __lhs, 588 const time_point<_Clock, _Duration2>& __rhs) 589 { return __lhs.time_since_epoch() - __rhs.time_since_epoch(); } 590 591 template<typename _Clock, typename _Duration1, typename _Duration2> 592 inline bool 593 operator==(const time_point<_Clock, _Duration1>& __lhs, 594 const time_point<_Clock, _Duration2>& __rhs) 595 { return __lhs.time_since_epoch() == __rhs.time_since_epoch(); } 596 597 template<typename _Clock, typename _Duration1, typename _Duration2> 598 inline bool 599 operator!=(const time_point<_Clock, _Duration1>& __lhs, 600 const time_point<_Clock, _Duration2>& __rhs) 601 { return !(__lhs == __rhs); } 602 603 template<typename _Clock, typename _Duration1, typename _Duration2> 604 inline bool 605 operator<(const time_point<_Clock, _Duration1>& __lhs, 606 const time_point<_Clock, _Duration2>& __rhs) 607 { return __lhs.time_since_epoch() < __rhs.time_since_epoch(); } 608 609 template<typename _Clock, typename _Duration1, typename _Duration2> 610 inline bool 611 operator<=(const time_point<_Clock, _Duration1>& __lhs, 612 const time_point<_Clock, _Duration2>& __rhs) 613 { return !(__rhs < __lhs); } 614 615 template<typename _Clock, typename _Duration1, typename _Duration2> 616 inline bool 617 operator>(const time_point<_Clock, _Duration1>& __lhs, 618 const time_point<_Clock, _Duration2>& __rhs) 619 { return __rhs < __lhs; } 620 621 template<typename _Clock, typename _Duration1, typename _Duration2> 622 inline bool 623 operator>=(const time_point<_Clock, _Duration1>& __lhs, 624 const time_point<_Clock, _Duration2>& __rhs) 625 { return !(__lhs < __rhs); } 626 627 /// system_clock 628 struct system_clock 629 { 630#ifdef _GLIBCXX_USE_CLOCK_REALTIME 631 typedef chrono::nanoseconds duration; 632#elif defined(_GLIBCXX_USE_GETTIMEOFDAY) 633 typedef chrono::microseconds duration; 634#else 635 typedef chrono::seconds duration; 636#endif 637 638 typedef duration::rep rep; 639 typedef duration::period period; 640 typedef chrono::time_point<system_clock, duration> time_point; 641 642 static const bool is_monotonic = false; 643 644 static time_point 645 now() throw (); 646 647 // Map to C API 648 static std::time_t 649 to_time_t(const time_point& __t) 650 { 651 return std::time_t( 652 duration_cast<chrono::seconds>(__t.time_since_epoch()).count()); 653 } 654 655 static time_point 656 from_time_t(std::time_t __t) 657 { 658 return time_point_cast<system_clock::duration>( 659 chrono::time_point<system_clock, chrono::seconds>( 660 chrono::seconds(__t))); 661 } 662 663 // TODO: requires constexpr 664 /* 665 static_assert( 666 system_clock::duration::min() < 667 system_clock::duration::zero(), 668 "a clock's minimum duration cannot be less than its epoch"); 669 */ 670 }; 671 672#ifdef _GLIBCXX_USE_CLOCK_MONOTONIC 673 /// monotonic_clock 674 struct monotonic_clock 675 { 676 typedef chrono::nanoseconds duration; 677 typedef duration::rep rep; 678 typedef duration::period period; 679 typedef chrono::time_point<monotonic_clock, duration> time_point; 680 681 static const bool is_monotonic = true; 682 683 static time_point 684 now(); 685 }; 686#else 687 typedef system_clock monotonic_clock; 688#endif 689 690 typedef system_clock high_resolution_clock; 691 } // namespace chrono 692 693 // @} group chrono 694} // namespace std 695 696#endif //_GLIBCXX_USE_C99_STDINT_TR1 697 698#endif //__GXX_EXPERIMENTAL_CXX0X__ 699 700#endif //_GLIBCXX_CHRONO 701