// -*- 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 #include #include #include #include #ifdef _GLIBCXX_USE_C99_STDINT_TR1 _GLIBCXX_BEGIN_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>> { private: typedef __static_gcd<_Period1::num, _Period2::num> __gcd_num; typedef __static_gcd<_Period1::den, _Period2::den> __gcd_den; typedef typename common_type<_Rep1, _Rep2>::type __cr; typedef ratio<__gcd_num::value, (_Period1::den / __gcd_den::value) * _Period2::den> __r; public: typedef chrono::duration<__cr, __r> type; }; // 20.8.2.3 specialization of common_type (for time_point) template struct common_type, chrono::time_point<_Clock, _Dur2>> { private: typedef typename common_type<_Dur1, _Dur2>::type __ct; public: typedef chrono::time_point<_Clock, __ct> type; }; namespace chrono { // Primary template for duration_cast impl. template struct __duration_cast_impl { template static constexpr _ToDur __cast(const duration<_Rep, _Period>& __d) { typedef typename _ToDur::rep __to_rep; return _ToDur(static_cast<__to_rep>(static_cast<_CR>(__d.count()) * static_cast<_CR>(_CF::num) / static_cast<_CR>(_CF::den))); } }; template struct __duration_cast_impl<_ToDur, _CF, _CR, true, true> { template static constexpr _ToDur __cast(const duration<_Rep, _Period>& __d) { typedef typename _ToDur::rep __to_rep; return _ToDur(static_cast<__to_rep>(__d.count())); } }; template struct __duration_cast_impl<_ToDur, _CF, _CR, true, false> { template static constexpr _ToDur __cast(const duration<_Rep, _Period>& __d) { typedef typename _ToDur::rep __to_rep; return _ToDur(static_cast<__to_rep>( static_cast<_CR>(__d.count()) / static_cast<_CR>(_CF::den))); } }; template struct __duration_cast_impl<_ToDur, _CF, _CR, false, true> { template static constexpr _ToDur __cast(const duration<_Rep, _Period>& __d) { typedef typename _ToDur::rep __to_rep; return _ToDur(static_cast<__to_rep>( 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 constexpr typename enable_if<__is_duration<_ToDur>::value, _ToDur>::type duration_cast(const duration<_Rep, _Period>& __d) { typedef typename _ToDur::period __to_period; typedef typename _ToDur::rep __to_rep; typedef ratio_divide<_Period, __to_period> __r_div; typedef typename __r_div::type __cf; typedef typename common_type<__to_rep, _Rep, intmax_t>::type __cr; typedef __duration_cast_impl<_ToDur, __cf, __cr, __cf::num == 1, __cf::den == 1> __dc; return __dc::__cast(__d); } /// treat_as_floating_point template struct treat_as_floating_point : is_floating_point<_Rep> { }; /// duration_values template struct duration_values { static constexpr _Rep zero() { return _Rep(0); } static constexpr _Rep max() { return numeric_limits<_Rep>::max(); } static constexpr _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 { typedef _Rep rep; typedef _Period period; 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"); // 20.8.3.1 construction / copy / destroy constexpr duration() : __r() { } template::value && (treat_as_floating_point::value || !treat_as_floating_point<_Rep2>::value)>::type> constexpr 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> constexpr 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 constexpr rep count() const { return __r; } // 20.8.3.3 arithmetic constexpr duration operator+() const { return *this; } constexpr 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 static constexpr duration zero() { return duration(duration_values::zero()); } static constexpr duration min() { return duration(duration_values::min()); } static constexpr 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 duration<_Rep1, _Period1> __dur1; typedef duration<_Rep2, _Period2> __dur2; typedef typename common_type<__dur1,__dur2>::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 duration<_Rep1, _Period1> __dur1; typedef duration<_Rep2, _Period2> __dur2; typedef typename common_type<__dur1,__dur2>::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 duration<_Rep1, _Period1> __dur1; typedef duration<_Rep2, _Period2> __dur2; typedef typename common_type<__dur1,__dur2>::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 duration<_Rep1, _Period1> __dur1; typedef duration<_Rep2, _Period2> __dur2; typedef typename common_type<__dur1,__dur2>::type __ct; return __ct(__lhs) %= __rhs; } // comparisons template inline constexpr bool operator==(const duration<_Rep1, _Period1>& __lhs, const duration<_Rep2, _Period2>& __rhs) { typedef duration<_Rep1, _Period1> __dur1; typedef duration<_Rep2, _Period2> __dur2; typedef typename common_type<__dur1,__dur2>::type __ct; return __ct(__lhs).count() == __ct(__rhs).count(); } template inline constexpr bool operator<(const duration<_Rep1, _Period1>& __lhs, const duration<_Rep2, _Period2>& __rhs) { typedef duration<_Rep1, _Period1> __dur1; typedef duration<_Rep2, _Period2> __dur2; typedef typename common_type<__dur1,__dur2>::type __ct; return __ct(__lhs).count() < __ct(__rhs).count(); } template inline constexpr bool operator!=(const duration<_Rep1, _Period1>& __lhs, const duration<_Rep2, _Period2>& __rhs) { return !(__lhs == __rhs); } template inline constexpr bool operator<=(const duration<_Rep1, _Period1>& __lhs, const duration<_Rep2, _Period2>& __rhs) { return !(__rhs < __lhs); } template inline constexpr bool operator>(const duration<_Rep1, _Period1>& __lhs, const duration<_Rep2, _Period2>& __rhs) { return __rhs < __lhs; } template inline constexpr 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 _Dur duration; typedef typename duration::rep rep; typedef typename duration::period period; constexpr time_point() : __d(duration::zero()) { } constexpr explicit time_point(const duration& __dur) : __d(__dur) { } // conversions template constexpr time_point(const time_point& __t) : __d(__t.time_since_epoch()) { } // observer constexpr 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 static constexpr time_point min() { return time_point(duration::min()); } static constexpr time_point max() { return time_point(duration::max()); } private: duration __d; }; /// time_point_cast template inline constexpr typename enable_if<__is_duration<_ToDur>::value, time_point<_Clock, _ToDur>>::type time_point_cast(const time_point<_Clock, _Dur>& __t) { typedef time_point<_Clock, _ToDur> __time_point; return __time_point(duration_cast<_ToDur>(__t.time_since_epoch())); } template inline time_point<_Clock, typename common_type<_Dur1, duration<_Rep2, _Period2>>::type> operator+(const time_point<_Clock, _Dur1>& __lhs, const duration<_Rep2, _Period2>& __rhs) { typedef duration<_Rep2, _Period2> __dur2; typedef typename common_type<_Dur1,__dur2>::type __ct; typedef time_point<_Clock, __ct> __time_point; return __time_point(__lhs) += __rhs; } template inline time_point<_Clock, typename common_type, _Dur2>::type> operator+(const duration<_Rep1, _Period1>& __lhs, const time_point<_Clock, _Dur2>& __rhs) { return __rhs + __lhs; } template inline time_point<_Clock, typename common_type<_Dur1, duration<_Rep2, _Period2>>::type> operator-(const time_point<_Clock, _Dur1>& __lhs, const duration<_Rep2, _Period2>& __rhs) { return __lhs + (-__rhs); } template inline typename common_type<_Dur1, _Dur2>::type operator-(const time_point<_Clock, _Dur1>& __lhs, const time_point<_Clock, _Dur2>& __rhs) { return __lhs.time_since_epoch() - __rhs.time_since_epoch(); } template inline constexpr bool operator==(const time_point<_Clock, _Dur1>& __lhs, const time_point<_Clock, _Dur2>& __rhs) { return __lhs.time_since_epoch() == __rhs.time_since_epoch(); } template inline constexpr bool operator!=(const time_point<_Clock, _Dur1>& __lhs, const time_point<_Clock, _Dur2>& __rhs) { return !(__lhs == __rhs); } template inline constexpr bool operator<(const time_point<_Clock, _Dur1>& __lhs, const time_point<_Clock, _Dur2>& __rhs) { return __lhs.time_since_epoch() < __rhs.time_since_epoch(); } template inline constexpr bool operator<=(const time_point<_Clock, _Dur1>& __lhs, const time_point<_Clock, _Dur2>& __rhs) { return !(__rhs < __lhs); } template inline constexpr bool operator>(const time_point<_Clock, _Dur1>& __lhs, const time_point<_Clock, _Dur2>& __rhs) { return __rhs < __lhs; } template inline constexpr bool operator>=(const time_point<_Clock, _Dur1>& __lhs, const time_point<_Clock, _Dur2>& __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_assert(system_clock::duration::min() < system_clock::duration::zero(), "a clock's minimum duration cannot be less than its epoch"); static constexpr 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) { typedef chrono::time_point __from; return time_point_cast (__from(chrono::seconds(__t))); } }; #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 constexpr 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 _GLIBCXX_END_NAMESPACE #endif //_GLIBCXX_USE_C99_STDINT_TR1 #endif //__GXX_EXPERIMENTAL_CXX0X__ #endif //_GLIBCXX_CHRONO