Chris@16: // Chris@16: // detail/chrono_time_traits.hpp Chris@16: // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Chris@16: // Chris@101: // Copyright (c) 2003-2015 Christopher M. Kohlhoff (chris at kohlhoff dot com) Chris@16: // Chris@16: // Distributed under the Boost Software License, Version 1.0. (See accompanying Chris@16: // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) Chris@16: // Chris@16: Chris@16: #ifndef BOOST_ASIO_DETAIL_CHRONO_TIME_TRAITS_HPP Chris@16: #define BOOST_ASIO_DETAIL_CHRONO_TIME_TRAITS_HPP Chris@16: Chris@16: #if defined(_MSC_VER) && (_MSC_VER >= 1200) Chris@16: # pragma once Chris@16: #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) Chris@16: Chris@16: #include Chris@16: Chris@16: #include Chris@16: Chris@16: namespace boost { Chris@16: namespace asio { Chris@16: namespace detail { Chris@16: Chris@101: // Helper template to compute the greatest common divisor. Chris@101: template Chris@101: struct gcd { enum { value = gcd::value }; }; Chris@101: Chris@101: template Chris@101: struct gcd { enum { value = v1 }; }; Chris@101: Chris@16: // Adapts std::chrono clocks for use with a deadline timer. Chris@16: template Chris@16: struct chrono_time_traits Chris@16: { Chris@16: // The clock type. Chris@16: typedef Clock clock_type; Chris@16: Chris@16: // The duration type of the clock. Chris@16: typedef typename clock_type::duration duration_type; Chris@16: Chris@16: // The time point type of the clock. Chris@16: typedef typename clock_type::time_point time_type; Chris@16: Chris@16: // The period of the clock. Chris@16: typedef typename duration_type::period period_type; Chris@16: Chris@16: // Get the current time. Chris@16: static time_type now() Chris@16: { Chris@16: return clock_type::now(); Chris@16: } Chris@16: Chris@16: // Add a duration to a time. Chris@16: static time_type add(const time_type& t, const duration_type& d) Chris@16: { Chris@16: const time_type epoch; Chris@16: if (t >= epoch) Chris@16: { Chris@16: if ((time_type::max)() - t < d) Chris@16: return (time_type::max)(); Chris@16: } Chris@16: else // t < epoch Chris@16: { Chris@16: if (-(t - (time_type::min)()) > d) Chris@16: return (time_type::min)(); Chris@16: } Chris@16: Chris@16: return t + d; Chris@16: } Chris@16: Chris@16: // Subtract one time from another. Chris@16: static duration_type subtract(const time_type& t1, const time_type& t2) Chris@16: { Chris@16: const time_type epoch; Chris@16: if (t1 >= epoch) Chris@16: { Chris@16: if (t2 >= epoch) Chris@16: { Chris@16: return t1 - t2; Chris@16: } Chris@16: else if (t2 == (time_type::min)()) Chris@16: { Chris@16: return (duration_type::max)(); Chris@16: } Chris@16: else if ((time_type::max)() - t1 < epoch - t2) Chris@16: { Chris@16: return (duration_type::max)(); Chris@16: } Chris@16: else Chris@16: { Chris@16: return t1 - t2; Chris@16: } Chris@16: } Chris@16: else // t1 < epoch Chris@16: { Chris@16: if (t2 < epoch) Chris@16: { Chris@16: return t1 - t2; Chris@16: } Chris@16: else if (t1 == (time_type::min)()) Chris@16: { Chris@16: return (duration_type::min)(); Chris@16: } Chris@16: else if ((time_type::max)() - t2 < epoch - t1) Chris@16: { Chris@16: return (duration_type::min)(); Chris@16: } Chris@16: else Chris@16: { Chris@16: return -(t2 - t1); Chris@16: } Chris@16: } Chris@16: } Chris@16: Chris@16: // Test whether one time is less than another. Chris@16: static bool less_than(const time_type& t1, const time_type& t2) Chris@16: { Chris@16: return t1 < t2; Chris@16: } Chris@16: Chris@16: // Implement just enough of the posix_time::time_duration interface to supply Chris@16: // what the timer_queue requires. Chris@16: class posix_time_duration Chris@16: { Chris@16: public: Chris@16: explicit posix_time_duration(const duration_type& d) Chris@16: : d_(d) Chris@16: { Chris@16: } Chris@16: Chris@16: int64_t ticks() const Chris@16: { Chris@16: return d_.count(); Chris@16: } Chris@16: Chris@16: int64_t total_seconds() const Chris@16: { Chris@16: return duration_cast<1, 1>(); Chris@16: } Chris@16: Chris@16: int64_t total_milliseconds() const Chris@16: { Chris@16: return duration_cast<1, 1000>(); Chris@16: } Chris@16: Chris@16: int64_t total_microseconds() const Chris@16: { Chris@16: return duration_cast<1, 1000000>(); Chris@16: } Chris@16: Chris@16: private: Chris@16: template Chris@16: int64_t duration_cast() const Chris@16: { Chris@101: const int64_t num1 = period_type::num / gcd::value; Chris@101: const int64_t num2 = Num / gcd::value; Chris@101: Chris@101: const int64_t den1 = period_type::den / gcd::value; Chris@101: const int64_t den2 = Den / gcd::value; Chris@101: Chris@101: const int64_t num = num1 * den2; Chris@101: const int64_t den = num2 * den1; Chris@16: Chris@16: if (num == 1 && den == 1) Chris@16: return ticks(); Chris@16: else if (num != 1 && den == 1) Chris@16: return ticks() * num; Chris@16: else if (num == 1 && period_type::den != 1) Chris@16: return ticks() / den; Chris@16: else Chris@16: return ticks() * num / den; Chris@16: } Chris@16: Chris@16: duration_type d_; Chris@16: }; Chris@16: Chris@16: // Convert to POSIX duration type. Chris@16: static posix_time_duration to_posix_duration(const duration_type& d) Chris@16: { Chris@16: return posix_time_duration(WaitTraits::to_wait_duration(d)); Chris@16: } Chris@16: }; Chris@16: Chris@16: } // namespace detail Chris@16: } // namespace asio Chris@16: } // namespace boost Chris@16: Chris@16: #include Chris@16: Chris@16: #endif // BOOST_ASIO_DETAIL_CHRONO_TIME_TRAITS_HPP