2 // detail/chrono_time_traits.hpp
3 // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
5 // Copyright (c) 2003-2016 Christopher M. Kohlhoff (chris at kohlhoff dot com)
7 // Distributed under the Boost Software License, Version 1.0. (See accompanying
8 // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
11 #ifndef BOOST_ASIO_DETAIL_CHRONO_TIME_TRAITS_HPP
12 #define BOOST_ASIO_DETAIL_CHRONO_TIME_TRAITS_HPP
14 #if defined(_MSC_VER) && (_MSC_VER >= 1200)
16 #endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
18 #include <boost/asio/detail/cstdint.hpp>
20 #include <boost/asio/detail/push_options.hpp>
26 // Helper template to compute the greatest common divisor.
27 template <int64_t v1, int64_t v2>
28 struct gcd { enum { value = gcd<v2, v1 % v2>::value }; };
31 struct gcd<v1, 0> { enum { value = v1 }; };
33 // Adapts std::chrono clocks for use with a deadline timer.
34 template <typename Clock, typename WaitTraits>
35 struct chrono_time_traits
38 typedef Clock clock_type;
40 // The duration type of the clock.
41 typedef typename clock_type::duration duration_type;
43 // The time point type of the clock.
44 typedef typename clock_type::time_point time_type;
46 // The period of the clock.
47 typedef typename duration_type::period period_type;
49 // Get the current time.
50 static time_type now()
52 return clock_type::now();
55 // Add a duration to a time.
56 static time_type add(const time_type& t, const duration_type& d)
58 const time_type epoch;
61 if ((time_type::max)() - t < d)
62 return (time_type::max)();
66 if (-(t - (time_type::min)()) > d)
67 return (time_type::min)();
73 // Subtract one time from another.
74 static duration_type subtract(const time_type& t1, const time_type& t2)
76 const time_type epoch;
83 else if (t2 == (time_type::min)())
85 return (duration_type::max)();
87 else if ((time_type::max)() - t1 < epoch - t2)
89 return (duration_type::max)();
102 else if (t1 == (time_type::min)())
104 return (duration_type::min)();
106 else if ((time_type::max)() - t2 < epoch - t1)
108 return (duration_type::min)();
117 // Test whether one time is less than another.
118 static bool less_than(const time_type& t1, const time_type& t2)
123 // Implement just enough of the posix_time::time_duration interface to supply
124 // what the timer_queue requires.
125 class posix_time_duration
128 explicit posix_time_duration(const duration_type& d)
133 int64_t ticks() const
138 int64_t total_seconds() const
140 return duration_cast<1, 1>();
143 int64_t total_milliseconds() const
145 return duration_cast<1, 1000>();
148 int64_t total_microseconds() const
150 return duration_cast<1, 1000000>();
154 template <int64_t Num, int64_t Den>
155 int64_t duration_cast() const
157 const int64_t num1 = period_type::num / gcd<period_type::num, Num>::value;
158 const int64_t num2 = Num / gcd<period_type::num, Num>::value;
160 const int64_t den1 = period_type::den / gcd<period_type::den, Den>::value;
161 const int64_t den2 = Den / gcd<period_type::den, Den>::value;
163 const int64_t num = num1 * den2;
164 const int64_t den = num2 * den1;
166 if (num == 1 && den == 1)
168 else if (num != 1 && den == 1)
169 return ticks() * num;
170 else if (num == 1 && period_type::den != 1)
171 return ticks() / den;
173 return ticks() * num / den;
179 // Convert to POSIX duration type.
180 static posix_time_duration to_posix_duration(const duration_type& d)
182 return posix_time_duration(WaitTraits::to_wait_duration(d));
186 } // namespace detail
190 #include <boost/asio/detail/pop_options.hpp>
192 #endif // BOOST_ASIO_DETAIL_CHRONO_TIME_TRAITS_HPP