// -*- C++ -*- // Copyright (C) 2008, 2009, 2010 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the // terms of the GNU General Public License as published by the // Free Software Foundation; either version 3, or (at your option) // any later version. // This library is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // Under Section 7 of GPL version 3, you are granted additional // permissions described in the GCC Runtime Library Exception, version // 3.1, as published by the Free Software Foundation. // You should have received a copy of the GNU General Public License and // a copy of the GCC Runtime Library Exception along with this program; // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see // . /** @file include/chrono * This is a Standard C++ Library header. */ #ifndef _GLIBCXX_CHRONO #define _GLIBCXX_CHRONO 1 #pragma GCC system_header #ifndef __GXX_EXPERIMENTAL_CXX0X__ # include #else #ifdef _GLIBCXX_INCLUDE_AS_TR1 # error C++0x header cannot be included from TR1 header #endif #include #include #include #include #ifdef _GLIBCXX_USE_C99_STDINT_TR1 namespace std { /** * @defgroup chrono Time * @ingroup utilities * * Classes and functions for time. * @{ */ /** @namespace std::chrono * @brief ISO C++ 0x entities sub namespace for time and date. */ namespace chrono { template> struct duration; template struct time_point; } // 20.8.2.3 specialization of common_type (for duration) template struct common_type, chrono::duration<_Rep2, _Period2>> { typedef chrono::duration::type, ratio<__static_gcd<_Period1::num, _Period2::num>::value, (_Period1::den / __static_gcd<_Period1::den, _Period2::den>::value) * _Period2::den>> type; }; // 20.8.2.3 specialization of common_type (for time_point) template struct common_type, chrono::time_point<_Clock, _Duration2>> { typedef chrono::time_point<_Clock, typename common_type<_Duration1, _Duration2>::type> type; }; namespace chrono { // Primary template for duration_cast impl. template struct __duration_cast_impl { template static _ToDuration __cast(const duration<_Rep, _Period>& __d) { return _ToDuration(static_cast< typename _ToDuration::rep>(static_cast<_CR>(__d.count()) * static_cast<_CR>(_CF::num) / static_cast<_CR>(_CF::den))); } }; template struct __duration_cast_impl<_ToDuration, _CF, _CR, true, true> { template static _ToDuration __cast(const duration<_Rep, _Period>& __d) { return _ToDuration( static_cast(__d.count())); } }; template struct __duration_cast_impl<_ToDuration, _CF, _CR, true, false> { template static _ToDuration __cast(const duration<_Rep, _Period>& __d) { return _ToDuration(static_cast( static_cast<_CR>(__d.count()) / static_cast<_CR>(_CF::den))); } }; template struct __duration_cast_impl<_ToDuration, _CF, _CR, false, true> { template static _ToDuration __cast(const duration<_Rep, _Period>& __d) { return _ToDuration(static_cast( static_cast<_CR>(__d.count()) * static_cast<_CR>(_CF::num))); } }; template struct __is_duration : std::false_type { }; template struct __is_duration> : std::true_type { }; /// duration_cast template inline typename enable_if<__is_duration<_ToDuration>::value, _ToDuration>::type duration_cast(const duration<_Rep, _Period>& __d) { typedef typename ratio_divide<_Period, typename _ToDuration::period>::type __cf; typedef typename common_type::type __cr; return __duration_cast_impl<_ToDuration, __cf, __cr, __cf::num == 1, __cf::den == 1>::__cast(__d); } /// treat_as_floating_point template struct treat_as_floating_point : is_floating_point<_Rep> { }; /// duration_values template struct duration_values { static const _Rep zero() { return _Rep(0); } static const _Rep max() { return numeric_limits<_Rep>::max(); } static const _Rep min() { return numeric_limits<_Rep>::min(); } }; template struct __is_ratio : std::false_type { }; template struct __is_ratio> : std::true_type { }; /// duration template struct duration { static_assert(!__is_duration<_Rep>::value, "rep cannot be a duration"); static_assert(__is_ratio<_Period>::value, "period must be a specialization of ratio"); static_assert(_Period::num > 0, "period must be positive"); typedef _Rep rep; typedef _Period period; // 20.8.3.1 construction / copy / destroy duration() = default; template::value && (treat_as_floating_point::value || !treat_as_floating_point<_Rep2>::value)>::type> explicit duration(const _Rep2& __rep) : __r(static_cast(__rep)) { } template::value || (ratio_divide<_Period2, period>::type::den == 1 && !treat_as_floating_point<_Rep2>::value)>::type> duration(const duration<_Rep2, _Period2>& __d) : __r(duration_cast(__d).count()) { } ~duration() = default; duration(const duration&) = default; duration& operator=(const duration&) = default; // 20.8.3.2 observer rep count() const { return __r; } // 20.8.3.3 arithmetic duration operator+() const { return *this; } duration operator-() const { return duration(-__r); } duration& operator++() { ++__r; return *this; } duration operator++(int) { return duration(__r++); } duration& operator--() { --__r; return *this; } duration operator--(int) { return duration(__r--); } duration& operator+=(const duration& __d) { __r += __d.count(); return *this; } duration& operator-=(const duration& __d) { __r -= __d.count(); return *this; } duration& operator*=(const rep& __rhs) { __r *= __rhs; return *this; } duration& operator/=(const rep& __rhs) { __r /= __rhs; return *this; } // DR 934. template typename enable_if::value, duration&>::type operator%=(const rep& __rhs) { __r %= __rhs; return *this; } template typename enable_if::value, duration&>::type operator%=(const duration& __d) { __r %= __d.count(); return *this; } // 20.8.3.4 special values // TODO: These should be constexprs. static const duration zero() { return duration(duration_values::zero()); } static const duration min() { return duration(duration_values::min()); } static const duration max() { return duration(duration_values::max()); } private: rep __r; }; template inline typename common_type, duration<_Rep2, _Period2>>::type operator+(const duration<_Rep1, _Period1>& __lhs, const duration<_Rep2, _Period2>& __rhs) { typedef typename common_type, duration<_Rep2, _Period2>>::type __ct; return __ct(__lhs) += __rhs; } template inline typename common_type, duration<_Rep2, _Period2>>::type operator-(const duration<_Rep1, _Period1>& __lhs, const duration<_Rep2, _Period2>& __rhs) { typedef typename common_type, duration<_Rep2, _Period2>>::type __ct; return __ct(__lhs) -= __rhs; } template::type>::value> struct __common_rep_type { }; template struct __common_rep_type<_Rep1, _Rep2, true> { typedef typename common_type<_Rep1, _Rep2>::type type; }; template inline duration::type, _Period> operator*(const duration<_Rep1, _Period>& __d, const _Rep2& __s) { typedef typename common_type<_Rep1, _Rep2>::type __cr; return duration<__cr, _Period>(__d) *= __s; } template inline duration::type, _Period> operator*(const _Rep1& __s, const duration<_Rep2, _Period>& __d) { return __d * __s; } template inline duration::value, _Rep2>::type>::type, _Period> operator/(const duration<_Rep1, _Period>& __d, const _Rep2& __s) { typedef typename common_type<_Rep1, _Rep2>::type __cr; return duration<__cr, _Period>(__d) /= __s; } template inline typename common_type<_Rep1, _Rep2>::type operator/(const duration<_Rep1, _Period1>& __lhs, const duration<_Rep2, _Period2>& __rhs) { typedef typename common_type, duration<_Rep2, _Period2>>::type __ct; return __ct(__lhs).count() / __ct(__rhs).count(); } // DR 934. template inline duration::value, _Rep2>::type>::type, _Period> operator%(const duration<_Rep1, _Period>& __d, const _Rep2& __s) { typedef typename common_type<_Rep1, _Rep2>::type __cr; return duration<__cr, _Period>(__d) %= __s; } template inline typename common_type, duration<_Rep2, _Period2>>::type operator%(const duration<_Rep1, _Period1>& __lhs, const duration<_Rep2, _Period2>& __rhs) { typedef typename common_type, duration<_Rep2, _Period2>>::type __ct; return __ct(__lhs) %= __rhs; } // comparisons template inline bool operator==(const duration<_Rep1, _Period1>& __lhs, const duration<_Rep2, _Period2>& __rhs) { typedef typename common_type, duration<_Rep2, _Period2>>::type __ct; return __ct(__lhs).count() == __ct(__rhs).count(); } template inline bool operator<(const duration<_Rep1, _Period1>& __lhs, const duration<_Rep2, _Period2>& __rhs) { typedef typename common_type, duration<_Rep2, _Period2>>::type __ct; return __ct(__lhs).count() < __ct(__rhs).count(); } template inline bool operator!=(const duration<_Rep1, _Period1>& __lhs, const duration<_Rep2, _Period2>& __rhs) { return !(__lhs == __rhs); } template inline bool operator<=(const duration<_Rep1, _Period1>& __lhs, const duration<_Rep2, _Period2>& __rhs) { return !(__rhs < __lhs); } template inline bool operator>(const duration<_Rep1, _Period1>& __lhs, const duration<_Rep2, _Period2>& __rhs) { return __rhs < __lhs; } template inline bool operator>=(const duration<_Rep1, _Period1>& __lhs, const duration<_Rep2, _Period2>& __rhs) { return !(__lhs < __rhs); } /// nanoseconds typedef duration nanoseconds; /// microseconds typedef duration microseconds; /// milliseconds typedef duration milliseconds; /// seconds typedef duration seconds; /// minutes typedef duration> minutes; /// hours typedef duration> hours; /// time_point template struct time_point { typedef _Clock clock; typedef _Duration duration; typedef typename duration::rep rep; typedef typename duration::period period; time_point() : __d(duration::zero()) { } explicit time_point(const duration& __dur) : __d(duration::zero() + __dur) { } // conversions template time_point(const time_point& __t) : __d(__t.time_since_epoch()) { } // observer duration time_since_epoch() const { return __d; } // arithmetic time_point& operator+=(const duration& __dur) { __d += __dur; return *this; } time_point& operator-=(const duration& __dur) { __d -= __dur; return *this; } // special values // TODO: These should be constexprs. static const time_point min() { return time_point(duration::min()); } static const time_point max() { return time_point(duration::max()); } private: duration __d; }; /// time_point_cast template inline typename enable_if<__is_duration<_ToDuration>::value, time_point<_Clock, _ToDuration>>::type time_point_cast(const time_point<_Clock, _Duration>& __t) { return time_point<_Clock, _ToDuration>( duration_cast<_ToDuration>(__t.time_since_epoch())); } template inline time_point<_Clock, typename common_type<_Duration1, duration<_Rep2, _Period2>>::type> operator+(const time_point<_Clock, _Duration1>& __lhs, const duration<_Rep2, _Period2>& __rhs) { typedef time_point<_Clock, typename common_type<_Duration1, duration<_Rep2, _Period2>>::type> __ct; return __ct(__lhs) += __rhs; } template inline time_point<_Clock, typename common_type, _Duration2>::type> operator+(const duration<_Rep1, _Period1>& __lhs, const time_point<_Clock, _Duration2>& __rhs) { return __rhs + __lhs; } template inline time_point<_Clock, typename common_type<_Duration1, duration<_Rep2, _Period2>>::type> operator-(const time_point<_Clock, _Duration1>& __lhs, const duration<_Rep2, _Period2>& __rhs) { return __lhs + (-__rhs); } template inline typename common_type<_Duration1, _Duration2>::type operator-(const time_point<_Clock, _Duration1>& __lhs, const time_point<_Clock, _Duration2>& __rhs) { return __lhs.time_since_epoch() - __rhs.time_since_epoch(); } template inline bool operator==(const time_point<_Clock, _Duration1>& __lhs, const time_point<_Clock, _Duration2>& __rhs) { return __lhs.time_since_epoch() == __rhs.time_since_epoch(); } template inline bool operator!=(const time_point<_Clock, _Duration1>& __lhs, const time_point<_Clock, _Duration2>& __rhs) { return !(__lhs == __rhs); } template inline bool operator<(const time_point<_Clock, _Duration1>& __lhs, const time_point<_Clock, _Duration2>& __rhs) { return __lhs.time_since_epoch() < __rhs.time_since_epoch(); } template inline bool operator<=(const time_point<_Clock, _Duration1>& __lhs, const time_point<_Clock, _Duration2>& __rhs) { return !(__rhs < __lhs); } template inline bool operator>(const time_point<_Clock, _Duration1>& __lhs, const time_point<_Clock, _Duration2>& __rhs) { return __rhs < __lhs; } template inline bool operator>=(const time_point<_Clock, _Duration1>& __lhs, const time_point<_Clock, _Duration2>& __rhs) { return !(__lhs < __rhs); } /// system_clock struct system_clock { #ifdef _GLIBCXX_USE_CLOCK_REALTIME typedef chrono::nanoseconds duration; #elif defined(_GLIBCXX_USE_GETTIMEOFDAY) typedef chrono::microseconds duration; #else typedef chrono::seconds duration; #endif typedef duration::rep rep; typedef duration::period period; typedef chrono::time_point time_point; static const bool is_monotonic = false; static time_point now() throw (); // Map to C API static std::time_t to_time_t(const time_point& __t) { return std::time_t( duration_cast(__t.time_since_epoch()).count()); } static time_point from_time_t(std::time_t __t) { return time_point_cast( chrono::time_point( chrono::seconds(__t))); } // TODO: requires constexpr /* static_assert( system_clock::duration::min() < system_clock::duration::zero(), "a clock's minimum duration cannot be less than its epoch"); */ }; #ifdef _GLIBCXX_USE_CLOCK_MONOTONIC /// monotonic_clock struct monotonic_clock { typedef chrono::nanoseconds duration; typedef duration::rep rep; typedef duration::period period; typedef chrono::time_point time_point; static const bool is_monotonic = true; static time_point now(); }; #else typedef system_clock monotonic_clock; #endif typedef system_clock high_resolution_clock; } // namespace chrono // @} group chrono } // namespace std #endif //_GLIBCXX_USE_C99_STDINT_TR1 #endif //__GXX_EXPERIMENTAL_CXX0X__ #endif //_GLIBCXX_CHRONO