1//
2// detail/chrono_time_traits.hpp
3// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
4//
5// Copyright (c) 2003-2015 Christopher M. Kohlhoff (chris at kohlhoff dot com)
6//
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)
9//
10
11#ifndef BOOST_ASIO_DETAIL_CHRONO_TIME_TRAITS_HPP
12#define BOOST_ASIO_DETAIL_CHRONO_TIME_TRAITS_HPP
13
14#if defined(_MSC_VER) && (_MSC_VER >= 1200)
15# pragma once
16#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
17
18#include <boost/asio/detail/cstdint.hpp>
19
20#include <boost/asio/detail/push_options.hpp>
21
22namespace boost {
23namespace asio {
24namespace detail {
25
26// Helper template to compute the greatest common divisor.
27template <int64_t v1, int64_t v2>
28struct gcd { enum { value = gcd<v2, v1 % v2>::value }; };
29
30template <int64_t v1>
31struct gcd<v1, 0> { enum { value = v1 }; };
32
33// Adapts std::chrono clocks for use with a deadline timer.
34template <typename Clock, typename WaitTraits>
35struct chrono_time_traits
36{
37 // The clock type.
38 typedef Clock clock_type;
39
40 // The duration type of the clock.
41 typedef typename clock_type::duration duration_type;
42
43 // The time point type of the clock.
44 typedef typename clock_type::time_point time_type;
45
46 // The period of the clock.
47 typedef typename duration_type::period period_type;
48
49 // Get the current time.
50 static time_type now()
51 {
52 return clock_type::now();
53 }
54
55 // Add a duration to a time.
56 static time_type add(const time_type& t, const duration_type& d)
57 {
58 const time_type epoch;
59 if (t >= epoch)
60 {
61 if ((time_type::max)() - t < d)
62 return (time_type::max)();
63 }
64 else // t < epoch
65 {
66 if (-(t - (time_type::min)()) > d)
67 return (time_type::min)();
68 }
69
70 return t + d;
71 }
72
73 // Subtract one time from another.
74 static duration_type subtract(const time_type& t1, const time_type& t2)
75 {
76 const time_type epoch;
77 if (t1 >= epoch)
78 {
79 if (t2 >= epoch)
80 {
81 return t1 - t2;
82 }
83 else if (t2 == (time_type::min)())
84 {
85 return (duration_type::max)();
86 }
87 else if ((time_type::max)() - t1 < epoch - t2)
88 {
89 return (duration_type::max)();
90 }
91 else
92 {
93 return t1 - t2;
94 }
95 }
96 else // t1 < epoch
97 {
98 if (t2 < epoch)
99 {
100 return t1 - t2;
101 }
102 else if (t1 == (time_type::min)())
103 {
104 return (duration_type::min)();
105 }
106 else if ((time_type::max)() - t2 < epoch - t1)
107 {
108 return (duration_type::min)();
109 }
110 else
111 {
112 return -(t2 - t1);
113 }
114 }
115 }
116
117 // Test whether one time is less than another.
118 static bool less_than(const time_type& t1, const time_type& t2)
119 {
120 return t1 < t2;
121 }
122
123 // Implement just enough of the posix_time::time_duration interface to supply
124 // what the timer_queue requires.
125 class posix_time_duration
126 {
127 public:
128 explicit posix_time_duration(const duration_type& d)
129 : d_(d)
130 {
131 }
132
133 int64_t ticks() const
134 {
135 return d_.count();
136 }
137
138 int64_t total_seconds() const
139 {
140 return duration_cast<1, 1>();
141 }
142
143 int64_t total_milliseconds() const
144 {
145 return duration_cast<1, 1000>();
146 }
147
148 int64_t total_microseconds() const
149 {
150 return duration_cast<1, 1000000>();
151 }
152
153 private:
154 template <int64_t Num, int64_t Den>
155 int64_t duration_cast() const
156 {
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;
159
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;
162
163 const int64_t num = num1 * den2;
164 const int64_t den = num2 * den1;
165
166 if (num == 1 && den == 1)
167 return ticks();
168 else if (num != 1 && den == 1)
169 return ticks() * num;
170 else if (num == 1 && period_type::den != 1)
171 return ticks() / den;
172 else
173 return ticks() * num / den;
174 }
175
176 duration_type d_;
177 };
178
179 // Convert to POSIX duration type.
180 static posix_time_duration to_posix_duration(const duration_type& d)
181 {
182 return posix_time_duration(WaitTraits::to_wait_duration(d));
183 }
184};
185
186} // namespace detail
187} // namespace asio
188} // namespace boost
189
190#include <boost/asio/detail/pop_options.hpp>
191
192#endif // BOOST_ASIO_DETAIL_CHRONO_TIME_TRAITS_HPP
193

source code of boost/boost/asio/detail/chrono_time_traits.hpp