// -*- C++ -*- // Copyright (C) 2008 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 2, 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. // You should have received a copy of the GNU General Public License // along with this library; see the file COPYING. If not, write to // the Free Software Foundation, 51 Franklin Street, Fifth Floor, // Boston, MA 02110-1301, USA. // As a special exception, you may use this file as part of a free software // library without restriction. Specifically, if other files instantiate // templates or use macros or inline functions from this file, or you compile // this file and link it with other files to produce an executable, this // file does not by itself cause the resulting executable to be covered by // the GNU General Public License. This exception does not however // invalidate any other reasons why the executable file might be covered by // the GNU General Public License. /** @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 { 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 inline _ToDuration 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); } template struct treat_as_floating_point : is_floating_point<_Rep> { }; 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_duration : std::false_type { }; template struct __is_duration> : std::true_type { }; 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 explicit duration(_Rep2 const& __rep) : __r(static_cast(__rep)) { static_assert(is_convertible<_Rep2,rep>::value && (treat_as_floating_point::value || !treat_as_floating_point<_Rep2>::value), "cannot construct integral duration with floating point type"); } template duration(const duration<_Rep2, _Period2>& __d) : __r(duration_cast(__d).count()) { static_assert(treat_as_floating_point::value == true || ratio_divide<_Period2, period>::type::den == 1, "the resulting duration is not exactly representable"); } ~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; } // 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 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 _Rep2& __s, const duration<_Rep1, _Period>& __d) { return __d * __s; } template struct __division_impl; template struct __division_impl, _Rep2, typename enable_if::value>::type> { typedef typename common_type<_Rep1, _Rep2>::type __cr; typedef duration::type, _Period> __rt; static __rt __divide(const duration<_Rep1, _Period>& __d, const _Rep2& __s) { return duration<__cr, _Period>(__d) /= __s; } }; template struct __division_impl, duration<_Rep2, _Period2>> { typedef typename common_type, duration<_Rep2, _Period2>>::type __ct; typedef typename common_type<_Rep1, _Rep2>::type __rt; static __rt __divide(const duration<_Rep1, _Period1>& __lhs, const duration<_Rep2, _Period2>& __rhs) { return __ct(__lhs).count() / __ct(__rhs).count(); } }; template inline typename __division_impl, _Up>::__rt operator/(const duration<_Rep, _Period>& __d, const _Up& __u) { return __division_impl, _Up>::__divide(__d, __u); } // 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); } typedef duration nanoseconds; typedef duration microseconds; typedef duration milliseconds; typedef duration seconds; typedef duration> minutes; 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; }; template inline time_point<_Clock, _ToDuration> 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 { #if defined(_GLIBCXX_USE_CLOCK_MONOTONIC) || \ defined(_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; #ifdef _GLIBCXX_USE_CLOCK_MONOTONIC static const bool is_monotonic = true; #else static const bool is_monotonic = false; #endif static time_point now(); // 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"); */ }; typedef system_clock high_resolution_clock; typedef system_clock monotonic_clock; } } #endif //_GLIBCXX_USE_C99_STDINT_TR1 #endif //__GXX_EXPERIMENTAL_CXX0X__ #endif //_GLIBCXX_CHRONO