1// duration.hpp --------------------------------------------------------------//
2
3// Copyright 2008 Howard Hinnant
4// Copyright 2008 Beman Dawes
5// Copyright 2009-2012 Vicente J. Botet Escriba
6
7// Distributed under the Boost Software License, Version 1.0.
8// See http://www.boost.org/LICENSE_1_0.txt
9
10/*
11
12This code was derived by Beman Dawes from Howard Hinnant's time2_demo prototype.
13Many thanks to Howard for making his code available under the Boost license.
14The original code was modified to conform to Boost conventions and to section
1520.9 Time utilities [time] of the C++ committee's working paper N2798.
16See http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2798.pdf.
17
18time2_demo contained this comment:
19
20 Much thanks to Andrei Alexandrescu,
21 Walter Brown,
22 Peter Dimov,
23 Jeff Garland,
24 Terry Golubiewski,
25 Daniel Krugler,
26 Anthony Williams.
27*/
28
29
30#ifndef BOOST_CHRONO_TIME_POINT_HPP
31#define BOOST_CHRONO_TIME_POINT_HPP
32
33#include <boost/chrono/duration.hpp>
34
35#ifndef BOOST_CHRONO_HEADER_ONLY
36// this must occur after all of the includes and before any code appears:
37#include <boost/config/abi_prefix.hpp> // must be the last #include
38#endif
39
40//----------------------------------------------------------------------------//
41// //
42// 20.9 Time utilities [time] //
43// synopsis //
44// //
45//----------------------------------------------------------------------------//
46
47namespace boost {
48namespace chrono {
49
50 template <class Clock, class Duration = typename Clock::duration>
51 class time_point;
52
53
54} // namespace chrono
55
56
57// common_type trait specializations
58
59template <class Clock, class Duration1, class Duration2>
60 struct common_type<chrono::time_point<Clock, Duration1>,
61 chrono::time_point<Clock, Duration2> >;
62
63
64//----------------------------------------------------------------------------//
65// 20.9.2.3 Specializations of common_type [time.traits.specializations] //
66//----------------------------------------------------------------------------//
67
68
69template <class Clock, class Duration1, class Duration2>
70struct common_type<chrono::time_point<Clock, Duration1>,
71 chrono::time_point<Clock, Duration2> >
72{
73 typedef chrono::time_point<Clock,
74 typename common_type<Duration1, Duration2>::type> type;
75};
76
77
78
79namespace chrono {
80
81 // time_point arithmetic
82 template <class Clock, class Duration1, class Rep2, class Period2>
83 inline BOOST_CONSTEXPR
84 time_point<Clock,
85 typename common_type<Duration1, duration<Rep2, Period2> >::type>
86 operator+(
87 const time_point<Clock, Duration1>& lhs,
88 const duration<Rep2, Period2>& rhs);
89 template <class Rep1, class Period1, class Clock, class Duration2>
90 inline BOOST_CONSTEXPR
91 time_point<Clock,
92 typename common_type<duration<Rep1, Period1>, Duration2>::type>
93 operator+(
94 const duration<Rep1, Period1>& lhs,
95 const time_point<Clock, Duration2>& rhs);
96 template <class Clock, class Duration1, class Rep2, class Period2>
97 inline BOOST_CONSTEXPR
98 time_point<Clock,
99 typename common_type<Duration1, duration<Rep2, Period2> >::type>
100 operator-(
101 const time_point<Clock, Duration1>& lhs,
102 const duration<Rep2, Period2>& rhs);
103 template <class Clock, class Duration1, class Duration2>
104 inline BOOST_CONSTEXPR
105 typename common_type<Duration1, Duration2>::type
106 operator-(
107 const time_point<Clock, Duration1>& lhs,
108 const time_point<Clock,
109 Duration2>& rhs);
110
111 // time_point comparisons
112 template <class Clock, class Duration1, class Duration2>
113 inline BOOST_CONSTEXPR
114 bool operator==(
115 const time_point<Clock, Duration1>& lhs,
116 const time_point<Clock, Duration2>& rhs);
117 template <class Clock, class Duration1, class Duration2>
118 inline BOOST_CONSTEXPR
119 bool operator!=(
120 const time_point<Clock, Duration1>& lhs,
121 const time_point<Clock, Duration2>& rhs);
122 template <class Clock, class Duration1, class Duration2>
123 inline BOOST_CONSTEXPR
124 bool operator< (
125 const time_point<Clock, Duration1>& lhs,
126 const time_point<Clock, Duration2>& rhs);
127 template <class Clock, class Duration1, class Duration2>
128 inline BOOST_CONSTEXPR
129 bool operator<=(
130 const time_point<Clock, Duration1>& lhs,
131 const time_point<Clock, Duration2>& rhs);
132 template <class Clock, class Duration1, class Duration2>
133 inline BOOST_CONSTEXPR
134 bool operator> (
135 const time_point<Clock, Duration1>& lhs,
136 const time_point<Clock, Duration2>& rhs);
137 template <class Clock, class Duration1, class Duration2>
138 inline BOOST_CONSTEXPR
139 bool operator>=(
140 const time_point<Clock, Duration1>& lhs,
141 const time_point<Clock, Duration2>& rhs);
142
143 // time_point_cast
144 template <class ToDuration, class Clock, class Duration>
145 inline BOOST_CONSTEXPR
146 time_point<Clock, ToDuration> time_point_cast(const time_point<Clock, Duration>& t);
147
148//----------------------------------------------------------------------------//
149// //
150// 20.9.4 Class template time_point [time.point] //
151// //
152//----------------------------------------------------------------------------//
153
154 template <class Clock, class Duration>
155 class time_point
156 {
157 BOOST_CHRONO_STATIC_ASSERT(boost::chrono::detail::is_duration<Duration>::value,
158 BOOST_CHRONO_SECOND_TEMPLATE_PARAMETER_OF_TIME_POINT_MUST_BE_A_BOOST_CHRONO_DURATION, (Duration));
159 public:
160 typedef Clock clock;
161 typedef Duration duration;
162 typedef typename duration::rep rep;
163 typedef typename duration::period period;
164 typedef Duration difference_type;
165
166 private:
167 duration d_;
168
169 public:
170 BOOST_FORCEINLINE BOOST_CONSTEXPR
171 time_point() : d_(duration::zero())
172 {}
173 BOOST_FORCEINLINE BOOST_CONSTEXPR
174 explicit time_point(const duration& d)
175 : d_(d)
176 {}
177
178 // conversions
179 template <class Duration2>
180 BOOST_FORCEINLINE BOOST_CONSTEXPR
181 time_point(const time_point<clock, Duration2>& t
182 , typename boost::enable_if
183 <
184 boost::is_convertible<Duration2, duration>
185 >::type* = 0
186 )
187 : d_(t.time_since_epoch())
188 {
189 }
190 // observer
191
192 BOOST_CONSTEXPR
193 duration time_since_epoch() const
194 {
195 return d_;
196 }
197
198 // arithmetic
199
200#ifdef BOOST_CHRONO_EXTENSIONS
201 BOOST_CONSTEXPR
202 time_point operator+() const {return *this;}
203 BOOST_CONSTEXPR
204 time_point operator-() const {return time_point(-d_);}
205 time_point& operator++() {++d_; return *this;}
206 time_point operator++(int) {return time_point(d_++);}
207 time_point& operator--() {--d_; return *this;}
208 time_point operator--(int) {return time_point(d_--);}
209
210 time_point& operator+=(const rep& r) {d_ += duration(r); return *this;}
211 time_point& operator-=(const rep& r) {d_ -= duration(r); return *this;}
212
213#endif
214
215 time_point& operator+=(const duration& d) {d_ += d; return *this;}
216 time_point& operator-=(const duration& d) {d_ -= d; return *this;}
217
218 // special values
219
220 static BOOST_CHRONO_LIB_CONSTEXPR time_point
221 min BOOST_PREVENT_MACRO_SUBSTITUTION ()
222 {
223 return time_point((duration::min)());
224 }
225 static BOOST_CHRONO_LIB_CONSTEXPR time_point
226 max BOOST_PREVENT_MACRO_SUBSTITUTION ()
227 {
228 return time_point((duration::max)());
229 }
230 };
231
232//----------------------------------------------------------------------------//
233// 20.9.4.5 time_point non-member arithmetic [time.point.nonmember] //
234//----------------------------------------------------------------------------//
235
236 // time_point operator+(time_point x, duration y);
237
238 template <class Clock, class Duration1, class Rep2, class Period2>
239 inline BOOST_CONSTEXPR
240 time_point<Clock,
241 typename common_type<Duration1, duration<Rep2, Period2> >::type>
242 operator+(const time_point<Clock, Duration1>& lhs,
243 const duration<Rep2, Period2>& rhs)
244 {
245 typedef typename common_type<Duration1, duration<Rep2, Period2> >::type CDuration;
246 typedef time_point<
247 Clock,
248 CDuration
249 > TimeResult;
250 return TimeResult(lhs.time_since_epoch() + CDuration(rhs));
251 }
252
253 // time_point operator+(duration x, time_point y);
254
255 template <class Rep1, class Period1, class Clock, class Duration2>
256 inline BOOST_CONSTEXPR
257 time_point<Clock,
258 typename common_type<duration<Rep1, Period1>, Duration2>::type>
259 operator+(const duration<Rep1, Period1>& lhs,
260 const time_point<Clock, Duration2>& rhs)
261 {
262 return rhs + lhs;
263 }
264
265 // time_point operator-(time_point x, duration y);
266
267 template <class Clock, class Duration1, class Rep2, class Period2>
268 inline BOOST_CONSTEXPR
269 time_point<Clock,
270 typename common_type<Duration1, duration<Rep2, Period2> >::type>
271 operator-(const time_point<Clock, Duration1>& lhs,
272 const duration<Rep2, Period2>& rhs)
273 {
274 return lhs + (-rhs);
275 }
276
277 // duration operator-(time_point x, time_point y);
278
279 template <class Clock, class Duration1, class Duration2>
280 inline BOOST_CONSTEXPR
281 typename common_type<Duration1, Duration2>::type
282 operator-(const time_point<Clock, Duration1>& lhs,
283 const time_point<Clock, Duration2>& rhs)
284 {
285 return lhs.time_since_epoch() - rhs.time_since_epoch();
286 }
287
288//----------------------------------------------------------------------------//
289// 20.9.4.6 time_point comparisons [time.point.comparisons] //
290//----------------------------------------------------------------------------//
291
292 // time_point ==
293
294 template <class Clock, class Duration1, class Duration2>
295 inline BOOST_CONSTEXPR
296 bool
297 operator==(const time_point<Clock, Duration1>& lhs,
298 const time_point<Clock, Duration2>& rhs)
299 {
300 return lhs.time_since_epoch() == rhs.time_since_epoch();
301 }
302
303 // time_point !=
304
305 template <class Clock, class Duration1, class Duration2>
306 inline BOOST_CONSTEXPR
307 bool
308 operator!=(const time_point<Clock, Duration1>& lhs,
309 const time_point<Clock, Duration2>& rhs)
310 {
311 return !(lhs == rhs);
312 }
313
314 // time_point <
315
316 template <class Clock, class Duration1, class Duration2>
317 inline BOOST_CONSTEXPR
318 bool
319 operator<(const time_point<Clock, Duration1>& lhs,
320 const time_point<Clock, Duration2>& rhs)
321 {
322 return lhs.time_since_epoch() < rhs.time_since_epoch();
323 }
324
325 // time_point >
326
327 template <class Clock, class Duration1, class Duration2>
328 inline BOOST_CONSTEXPR
329 bool
330 operator>(const time_point<Clock, Duration1>& lhs,
331 const time_point<Clock, Duration2>& rhs)
332 {
333 return rhs < lhs;
334 }
335
336 // time_point <=
337
338 template <class Clock, class Duration1, class Duration2>
339 inline BOOST_CONSTEXPR
340 bool
341 operator<=(const time_point<Clock, Duration1>& lhs,
342 const time_point<Clock, Duration2>& rhs)
343 {
344 return !(rhs < lhs);
345 }
346
347 // time_point >=
348
349 template <class Clock, class Duration1, class Duration2>
350 inline BOOST_CONSTEXPR
351 bool
352 operator>=(const time_point<Clock, Duration1>& lhs,
353 const time_point<Clock, Duration2>& rhs)
354 {
355 return !(lhs < rhs);
356 }
357
358//----------------------------------------------------------------------------//
359// 20.9.4.7 time_point_cast [time.point.cast] //
360//----------------------------------------------------------------------------//
361
362 template <class ToDuration, class Clock, class Duration>
363 inline BOOST_CONSTEXPR
364 time_point<Clock, ToDuration>
365 time_point_cast(const time_point<Clock, Duration>& t)
366 {
367 return time_point<Clock, ToDuration>(
368 duration_cast<ToDuration>(t.time_since_epoch()));
369 }
370
371} // namespace chrono
372} // namespace boost
373
374#ifndef BOOST_CHRONO_HEADER_ONLY
375// the suffix header occurs after all of our code:
376#include <boost/config/abi_suffix.hpp> // pops abi_prefix.hpp pragmas
377#endif
378
379#endif // BOOST_CHRONO_TIME_POINT_HPP
380