Mercurial > hg > vamp-build-and-test
comparison DEPENDENCIES/generic/include/boost/chrono/duration.hpp @ 16:2665513ce2d3
Add boost headers
author | Chris Cannam |
---|---|
date | Tue, 05 Aug 2014 11:11:38 +0100 |
parents | |
children | c530137014c0 |
comparison
equal
deleted
inserted
replaced
15:663ca0da4350 | 16:2665513ce2d3 |
---|---|
1 // duration.hpp --------------------------------------------------------------// | |
2 | |
3 // Copyright 2008 Howard Hinnant | |
4 // Copyright 2008 Beman Dawes | |
5 // Copyright 2009-2011 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 | |
12 This code was derived by Beman Dawes from Howard Hinnant's time2_demo prototype. | |
13 Many thanks to Howard for making his code available under the Boost license. | |
14 The original code was modified to conform to Boost conventions and to section | |
15 20.9 Time utilities [time] of the C++ committee's working paper N2798. | |
16 See http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2798.pdf. | |
17 | |
18 time2_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_DURATION_HPP | |
31 #define BOOST_CHRONO_DURATION_HPP | |
32 | |
33 #include <boost/chrono/config.hpp> | |
34 #include <boost/chrono/detail/static_assert.hpp> | |
35 | |
36 #include <climits> | |
37 #include <limits> | |
38 | |
39 | |
40 #include <boost/mpl/logical.hpp> | |
41 #include <boost/ratio/ratio.hpp> | |
42 #include <boost/type_traits/common_type.hpp> | |
43 #include <boost/type_traits/is_arithmetic.hpp> | |
44 #include <boost/type_traits/is_convertible.hpp> | |
45 #include <boost/type_traits/is_floating_point.hpp> | |
46 #include <boost/type_traits/is_unsigned.hpp> | |
47 #include <boost/chrono/detail/is_evenly_divisible_by.hpp> | |
48 | |
49 #include <boost/cstdint.hpp> | |
50 #include <boost/utility/enable_if.hpp> | |
51 #include <boost/detail/workaround.hpp> | |
52 #include <boost/integer_traits.hpp> | |
53 | |
54 #if !defined(BOOST_NO_CXX11_STATIC_ASSERT) || !defined(BOOST_CHRONO_USES_MPL_ASSERT) | |
55 #define BOOST_CHRONO_A_DURATION_REPRESENTATION_CAN_NOT_BE_A_DURATION "A duration representation can not be a duration" | |
56 #define BOOST_CHRONO_SECOND_TEMPLATE_PARAMETER_OF_DURATION_MUST_BE_A_STD_RATIO "Second template parameter of duration must be a boost::ratio" | |
57 #define BOOST_CHRONO_DURATION_PERIOD_MUST_BE_POSITIVE "duration period must be positive" | |
58 #define BOOST_CHRONO_SECOND_TEMPLATE_PARAMETER_OF_TIME_POINT_MUST_BE_A_BOOST_CHRONO_DURATION "Second template parameter of time_point must be a boost::chrono::duration" | |
59 #endif | |
60 | |
61 #ifndef BOOST_CHRONO_HEADER_ONLY | |
62 // this must occur after all of the includes and before any code appears: | |
63 #include <boost/config/abi_prefix.hpp> // must be the last #include | |
64 #endif | |
65 | |
66 //----------------------------------------------------------------------------// | |
67 // // | |
68 // 20.9 Time utilities [time] // | |
69 // synopsis // | |
70 // // | |
71 //----------------------------------------------------------------------------// | |
72 | |
73 namespace boost { | |
74 namespace chrono { | |
75 | |
76 template <class Rep, class Period = ratio<1> > | |
77 class duration; | |
78 | |
79 namespace detail | |
80 { | |
81 template <class T> | |
82 struct is_duration | |
83 : boost::false_type {}; | |
84 | |
85 template <class Rep, class Period> | |
86 struct is_duration<duration<Rep, Period> > | |
87 : boost::true_type {}; | |
88 | |
89 template <class Duration, class Rep, bool = is_duration<Rep>::value> | |
90 struct duration_divide_result | |
91 { | |
92 }; | |
93 | |
94 template <class Duration, class Rep2, | |
95 bool = ( | |
96 ((boost::is_convertible<typename Duration::rep, | |
97 typename common_type<typename Duration::rep, Rep2>::type>::value)) | |
98 && ((boost::is_convertible<Rep2, | |
99 typename common_type<typename Duration::rep, Rep2>::type>::value)) | |
100 ) | |
101 > | |
102 struct duration_divide_imp | |
103 { | |
104 }; | |
105 | |
106 template <class Rep1, class Period, class Rep2> | |
107 struct duration_divide_imp<duration<Rep1, Period>, Rep2, true> | |
108 { | |
109 typedef duration<typename common_type<Rep1, Rep2>::type, Period> type; | |
110 }; | |
111 | |
112 template <class Rep1, class Period, class Rep2> | |
113 struct duration_divide_result<duration<Rep1, Period>, Rep2, false> | |
114 : duration_divide_imp<duration<Rep1, Period>, Rep2> | |
115 { | |
116 }; | |
117 | |
118 /// | |
119 template <class Rep, class Duration, bool = is_duration<Rep>::value> | |
120 struct duration_divide_result2 | |
121 { | |
122 }; | |
123 | |
124 template <class Rep, class Duration, | |
125 bool = ( | |
126 ((boost::is_convertible<typename Duration::rep, | |
127 typename common_type<typename Duration::rep, Rep>::type>::value)) | |
128 && ((boost::is_convertible<Rep, | |
129 typename common_type<typename Duration::rep, Rep>::type>::value)) | |
130 ) | |
131 > | |
132 struct duration_divide_imp2 | |
133 { | |
134 }; | |
135 | |
136 template <class Rep1, class Rep2, class Period > | |
137 struct duration_divide_imp2<Rep1, duration<Rep2, Period>, true> | |
138 { | |
139 //typedef typename common_type<Rep1, Rep2>::type type; | |
140 typedef double type; | |
141 }; | |
142 | |
143 template <class Rep1, class Rep2, class Period > | |
144 struct duration_divide_result2<Rep1, duration<Rep2, Period>, false> | |
145 : duration_divide_imp2<Rep1, duration<Rep2, Period> > | |
146 { | |
147 }; | |
148 | |
149 /// | |
150 template <class Duration, class Rep, bool = is_duration<Rep>::value> | |
151 struct duration_modulo_result | |
152 { | |
153 }; | |
154 | |
155 template <class Duration, class Rep2, | |
156 bool = ( | |
157 //boost::is_convertible<typename Duration::rep, | |
158 //typename common_type<typename Duration::rep, Rep2>::type>::value | |
159 //&& | |
160 boost::is_convertible<Rep2, | |
161 typename common_type<typename Duration::rep, Rep2>::type>::value | |
162 ) | |
163 > | |
164 struct duration_modulo_imp | |
165 { | |
166 }; | |
167 | |
168 template <class Rep1, class Period, class Rep2> | |
169 struct duration_modulo_imp<duration<Rep1, Period>, Rep2, true> | |
170 { | |
171 typedef duration<typename common_type<Rep1, Rep2>::type, Period> type; | |
172 }; | |
173 | |
174 template <class Rep1, class Period, class Rep2> | |
175 struct duration_modulo_result<duration<Rep1, Period>, Rep2, false> | |
176 : duration_modulo_imp<duration<Rep1, Period>, Rep2> | |
177 { | |
178 }; | |
179 | |
180 } // namespace detail | |
181 } // namespace chrono | |
182 | |
183 | |
184 // common_type trait specializations | |
185 | |
186 template <class Rep1, class Period1, class Rep2, class Period2> | |
187 struct common_type<chrono::duration<Rep1, Period1>, | |
188 chrono::duration<Rep2, Period2> >; | |
189 | |
190 | |
191 namespace chrono { | |
192 | |
193 // customization traits | |
194 template <class Rep> struct treat_as_floating_point; | |
195 template <class Rep> struct duration_values; | |
196 | |
197 // convenience typedefs | |
198 typedef duration<boost::int_least64_t, nano> nanoseconds; // at least 64 bits needed | |
199 typedef duration<boost::int_least64_t, micro> microseconds; // at least 55 bits needed | |
200 typedef duration<boost::int_least64_t, milli> milliseconds; // at least 45 bits needed | |
201 typedef duration<boost::int_least64_t> seconds; // at least 35 bits needed | |
202 typedef duration<boost::int_least32_t, ratio< 60> > minutes; // at least 29 bits needed | |
203 typedef duration<boost::int_least32_t, ratio<3600> > hours; // at least 23 bits needed | |
204 | |
205 //----------------------------------------------------------------------------// | |
206 // duration helpers // | |
207 //----------------------------------------------------------------------------// | |
208 | |
209 namespace detail | |
210 { | |
211 | |
212 // duration_cast | |
213 | |
214 // duration_cast is the heart of this whole prototype. It can convert any | |
215 // duration to any other. It is also (implicitly) used in converting | |
216 // time_points. The conversion is always exact if possible. And it is | |
217 // always as efficient as hand written code. If different representations | |
218 // are involved, care is taken to never require implicit conversions. | |
219 // Instead static_cast is used explicitly for every required conversion. | |
220 // If there are a mixture of integral and floating point representations, | |
221 // the use of common_type ensures that the most logical "intermediate" | |
222 // representation is used. | |
223 template <class FromDuration, class ToDuration, | |
224 class Period, | |
225 bool PeriodNumEq1, | |
226 bool PeriodDenEq1> | |
227 struct duration_cast_aux; | |
228 | |
229 // When the two periods are the same, all that is left to do is static_cast from | |
230 // the source representation to the target representation (which may be a no-op). | |
231 // This conversion is always exact as long as the static_cast from the source | |
232 // representation to the destination representation is exact. | |
233 template <class FromDuration, class ToDuration, class Period> | |
234 struct duration_cast_aux<FromDuration, ToDuration, Period, true, true> | |
235 { | |
236 BOOST_CONSTEXPR ToDuration operator()(const FromDuration& fd) const | |
237 { | |
238 return ToDuration(static_cast<typename ToDuration::rep>(fd.count())); | |
239 } | |
240 }; | |
241 | |
242 // When the numerator of FromPeriod / ToPeriod is 1, then all we need to do is | |
243 // divide by the denominator of FromPeriod / ToPeriod. The common_type of | |
244 // the two representations is used for the intermediate computation before | |
245 // static_cast'ing to the destination. | |
246 // This conversion is generally not exact because of the division (but could be | |
247 // if you get lucky on the run time value of fd.count()). | |
248 template <class FromDuration, class ToDuration, class Period> | |
249 struct duration_cast_aux<FromDuration, ToDuration, Period, true, false> | |
250 { | |
251 BOOST_CONSTEXPR ToDuration operator()(const FromDuration& fd) const | |
252 { | |
253 typedef typename common_type< | |
254 typename ToDuration::rep, | |
255 typename FromDuration::rep, | |
256 boost::intmax_t>::type C; | |
257 return ToDuration(static_cast<typename ToDuration::rep>( | |
258 static_cast<C>(fd.count()) / static_cast<C>(Period::den))); | |
259 } | |
260 }; | |
261 | |
262 // When the denominator of FromPeriod / ToPeriod is 1, then all we need to do is | |
263 // multiply by the numerator of FromPeriod / ToPeriod. The common_type of | |
264 // the two representations is used for the intermediate computation before | |
265 // static_cast'ing to the destination. | |
266 // This conversion is always exact as long as the static_cast's involved are exact. | |
267 template <class FromDuration, class ToDuration, class Period> | |
268 struct duration_cast_aux<FromDuration, ToDuration, Period, false, true> | |
269 { | |
270 BOOST_CONSTEXPR ToDuration operator()(const FromDuration& fd) const | |
271 { | |
272 typedef typename common_type< | |
273 typename ToDuration::rep, | |
274 typename FromDuration::rep, | |
275 boost::intmax_t>::type C; | |
276 return ToDuration(static_cast<typename ToDuration::rep>( | |
277 static_cast<C>(fd.count()) * static_cast<C>(Period::num))); | |
278 } | |
279 }; | |
280 | |
281 // When neither the numerator or denominator of FromPeriod / ToPeriod is 1, then we need to | |
282 // multiply by the numerator and divide by the denominator of FromPeriod / ToPeriod. The | |
283 // common_type of the two representations is used for the intermediate computation before | |
284 // static_cast'ing to the destination. | |
285 // This conversion is generally not exact because of the division (but could be | |
286 // if you get lucky on the run time value of fd.count()). | |
287 template <class FromDuration, class ToDuration, class Period> | |
288 struct duration_cast_aux<FromDuration, ToDuration, Period, false, false> | |
289 { | |
290 BOOST_CONSTEXPR ToDuration operator()(const FromDuration& fd) const | |
291 { | |
292 typedef typename common_type< | |
293 typename ToDuration::rep, | |
294 typename FromDuration::rep, | |
295 boost::intmax_t>::type C; | |
296 return ToDuration(static_cast<typename ToDuration::rep>( | |
297 static_cast<C>(fd.count()) * static_cast<C>(Period::num) | |
298 / static_cast<C>(Period::den))); | |
299 } | |
300 }; | |
301 | |
302 template <class FromDuration, class ToDuration> | |
303 struct duration_cast { | |
304 typedef typename ratio_divide<typename FromDuration::period, | |
305 typename ToDuration::period>::type Period; | |
306 typedef duration_cast_aux< | |
307 FromDuration, | |
308 ToDuration, | |
309 Period, | |
310 Period::num == 1, | |
311 Period::den == 1 | |
312 > Aux; | |
313 BOOST_CONSTEXPR ToDuration operator()(const FromDuration& fd) const | |
314 { | |
315 return Aux()(fd); | |
316 } | |
317 }; | |
318 | |
319 } // namespace detail | |
320 | |
321 //----------------------------------------------------------------------------// | |
322 // // | |
323 // 20.9.2 Time-related traits [time.traits] // | |
324 // // | |
325 //----------------------------------------------------------------------------// | |
326 //----------------------------------------------------------------------------// | |
327 // 20.9.2.1 treat_as_floating_point [time.traits.is_fp] // | |
328 // Probably should have been treat_as_floating_point. Editor notifed. // | |
329 //----------------------------------------------------------------------------// | |
330 | |
331 // Support bidirectional (non-exact) conversions for floating point rep types | |
332 // (or user defined rep types which specialize treat_as_floating_point). | |
333 template <class Rep> | |
334 struct treat_as_floating_point : boost::is_floating_point<Rep> {}; | |
335 | |
336 //----------------------------------------------------------------------------// | |
337 // 20.9.2.2 duration_values [time.traits.duration_values] // | |
338 //----------------------------------------------------------------------------// | |
339 | |
340 namespace detail { | |
341 template <class T, bool = is_arithmetic<T>::value> | |
342 struct chrono_numeric_limits { | |
343 static BOOST_CHRONO_LIB_CONSTEXPR T lowest() BOOST_CHRONO_LIB_NOEXCEPT_OR_THROW {return (std::numeric_limits<T>::min) ();} | |
344 }; | |
345 | |
346 template <class T> | |
347 struct chrono_numeric_limits<T,true> { | |
348 static BOOST_CHRONO_LIB_CONSTEXPR T lowest() BOOST_CHRONO_LIB_NOEXCEPT_OR_THROW {return (std::numeric_limits<T>::min) ();} | |
349 }; | |
350 | |
351 template <> | |
352 struct chrono_numeric_limits<float,true> { | |
353 static BOOST_CHRONO_LIB_CONSTEXPR float lowest() BOOST_CHRONO_LIB_NOEXCEPT_OR_THROW | |
354 { | |
355 return -(std::numeric_limits<float>::max) (); | |
356 } | |
357 }; | |
358 | |
359 template <> | |
360 struct chrono_numeric_limits<double,true> { | |
361 static BOOST_CHRONO_LIB_CONSTEXPR double lowest() BOOST_CHRONO_LIB_NOEXCEPT_OR_THROW | |
362 { | |
363 return -(std::numeric_limits<double>::max) (); | |
364 } | |
365 }; | |
366 | |
367 template <> | |
368 struct chrono_numeric_limits<long double,true> { | |
369 static BOOST_CHRONO_LIB_CONSTEXPR long double lowest() BOOST_CHRONO_LIB_NOEXCEPT_OR_THROW | |
370 { | |
371 return -(std::numeric_limits<long double>::max)(); | |
372 } | |
373 }; | |
374 | |
375 template <class T> | |
376 struct numeric_limits : chrono_numeric_limits<typename remove_cv<T>::type> | |
377 {}; | |
378 | |
379 } | |
380 template <class Rep> | |
381 struct duration_values | |
382 { | |
383 static BOOST_CONSTEXPR Rep zero() {return Rep(0);} | |
384 static BOOST_CHRONO_LIB_CONSTEXPR Rep max BOOST_PREVENT_MACRO_SUBSTITUTION () | |
385 { | |
386 return (std::numeric_limits<Rep>::max)(); | |
387 } | |
388 | |
389 static BOOST_CHRONO_LIB_CONSTEXPR Rep min BOOST_PREVENT_MACRO_SUBSTITUTION () | |
390 { | |
391 return detail::numeric_limits<Rep>::lowest(); | |
392 } | |
393 }; | |
394 | |
395 } // namespace chrono | |
396 | |
397 //----------------------------------------------------------------------------// | |
398 // 20.9.2.3 Specializations of common_type [time.traits.specializations] // | |
399 //----------------------------------------------------------------------------// | |
400 | |
401 template <class Rep1, class Period1, class Rep2, class Period2> | |
402 struct common_type<chrono::duration<Rep1, Period1>, | |
403 chrono::duration<Rep2, Period2> > | |
404 { | |
405 typedef chrono::duration<typename common_type<Rep1, Rep2>::type, | |
406 typename boost::ratio_gcd<Period1, Period2>::type> type; | |
407 }; | |
408 | |
409 | |
410 //----------------------------------------------------------------------------// | |
411 // // | |
412 // 20.9.3 Class template duration [time.duration] // | |
413 // // | |
414 //----------------------------------------------------------------------------// | |
415 | |
416 | |
417 namespace chrono { | |
418 | |
419 template <class Rep, class Period> | |
420 class BOOST_SYMBOL_VISIBLE duration | |
421 { | |
422 //BOOST_CHRONO_STATIC_ASSERT(boost::is_integral<Rep>::value, BOOST_CHRONO_A_DURATION_REPRESENTATION_MUST_BE_INTEGRAL, ()); | |
423 BOOST_CHRONO_STATIC_ASSERT(!boost::chrono::detail::is_duration<Rep>::value, | |
424 BOOST_CHRONO_A_DURATION_REPRESENTATION_CAN_NOT_BE_A_DURATION, ()); | |
425 BOOST_CHRONO_STATIC_ASSERT(boost::ratio_detail::is_ratio<typename Period::type>::value, | |
426 BOOST_CHRONO_SECOND_TEMPLATE_PARAMETER_OF_DURATION_MUST_BE_A_STD_RATIO, ()); | |
427 BOOST_CHRONO_STATIC_ASSERT(Period::num>0, | |
428 BOOST_CHRONO_DURATION_PERIOD_MUST_BE_POSITIVE, ()); | |
429 public: | |
430 typedef Rep rep; | |
431 typedef Period period; | |
432 private: | |
433 rep rep_; | |
434 public: | |
435 | |
436 BOOST_FORCEINLINE BOOST_CONSTEXPR | |
437 duration() : rep_(duration_values<rep>::zero()) { } | |
438 template <class Rep2> | |
439 BOOST_SYMBOL_VISIBLE BOOST_FORCEINLINE BOOST_CONSTEXPR | |
440 explicit duration(const Rep2& r | |
441 , typename boost::enable_if < | |
442 mpl::and_ < | |
443 boost::is_convertible<Rep2, rep>, | |
444 mpl::or_ < | |
445 treat_as_floating_point<rep>, | |
446 mpl::and_ < | |
447 mpl::not_ < treat_as_floating_point<rep> >, | |
448 mpl::not_ < treat_as_floating_point<Rep2> > | |
449 > | |
450 > | |
451 > | |
452 >::type* = 0 | |
453 ) : rep_(r) { } | |
454 //~duration() {} //= default; | |
455 // BOOST_CONSTEXPR duration(const duration& rhs) : rep_(rhs.rep_) {} // = default; | |
456 duration& operator=(const duration& rhs) // = default; | |
457 { | |
458 if (&rhs != this) rep_= rhs.rep_; | |
459 return *this; | |
460 } | |
461 | |
462 // conversions | |
463 template <class Rep2, class Period2> | |
464 BOOST_FORCEINLINE BOOST_CONSTEXPR | |
465 duration(const duration<Rep2, Period2>& d | |
466 , typename boost::enable_if < | |
467 mpl::or_ < | |
468 treat_as_floating_point<rep>, | |
469 mpl::and_ < | |
470 chrono_detail::is_evenly_divisible_by<Period2, period>, | |
471 mpl::not_ < treat_as_floating_point<Rep2> > | |
472 > | |
473 > | |
474 >::type* = 0 | |
475 ) | |
476 : rep_(chrono::detail::duration_cast<duration<Rep2, Period2>, duration>()(d).count()) {} | |
477 | |
478 // observer | |
479 | |
480 BOOST_CONSTEXPR | |
481 rep count() const {return rep_;} | |
482 | |
483 // arithmetic | |
484 | |
485 BOOST_CONSTEXPR | |
486 duration operator+() const {return duration(rep_);;} | |
487 BOOST_CONSTEXPR | |
488 duration operator-() const {return duration(-rep_);} | |
489 duration& operator++() {++rep_; return *this;} | |
490 duration operator++(int) {return duration(rep_++);} | |
491 duration& operator--() {--rep_; return *this;} | |
492 duration operator--(int) {return duration(rep_--);} | |
493 | |
494 duration& operator+=(const duration& d) | |
495 { | |
496 rep_ += d.count(); return *this; | |
497 } | |
498 duration& operator-=(const duration& d) | |
499 { | |
500 rep_ -= d.count(); return *this; | |
501 } | |
502 | |
503 duration& operator*=(const rep& rhs) {rep_ *= rhs; return *this;} | |
504 duration& operator/=(const rep& rhs) {rep_ /= rhs; return *this;} | |
505 duration& operator%=(const rep& rhs) {rep_ %= rhs; return *this;} | |
506 duration& operator%=(const duration& rhs) | |
507 { | |
508 rep_ %= rhs.count(); return *this; | |
509 } | |
510 // 20.9.3.4 duration special values [time.duration.special] | |
511 | |
512 static BOOST_CONSTEXPR duration zero() | |
513 { | |
514 return duration(duration_values<rep>::zero()); | |
515 } | |
516 static BOOST_CHRONO_LIB_CONSTEXPR duration min BOOST_PREVENT_MACRO_SUBSTITUTION () | |
517 { | |
518 return duration((duration_values<rep>::min)()); | |
519 } | |
520 static BOOST_CHRONO_LIB_CONSTEXPR duration max BOOST_PREVENT_MACRO_SUBSTITUTION () | |
521 { | |
522 return duration((duration_values<rep>::max)()); | |
523 } | |
524 }; | |
525 | |
526 //----------------------------------------------------------------------------// | |
527 // 20.9.3.5 duration non-member arithmetic [time.duration.nonmember] // | |
528 //----------------------------------------------------------------------------// | |
529 | |
530 // Duration + | |
531 | |
532 template <class Rep1, class Period1, class Rep2, class Period2> | |
533 inline BOOST_CONSTEXPR | |
534 typename common_type<duration<Rep1, Period1>, duration<Rep2, Period2> >::type | |
535 operator+(const duration<Rep1, Period1>& lhs, | |
536 const duration<Rep2, Period2>& rhs) | |
537 { | |
538 typedef typename common_type<duration<Rep1, Period1>, | |
539 duration<Rep2, Period2> >::type CD; | |
540 return CD(CD(lhs).count()+CD(rhs).count()); | |
541 } | |
542 | |
543 // Duration - | |
544 | |
545 template <class Rep1, class Period1, class Rep2, class Period2> | |
546 inline BOOST_CONSTEXPR | |
547 typename common_type<duration<Rep1, Period1>, duration<Rep2, Period2> >::type | |
548 operator-(const duration<Rep1, Period1>& lhs, | |
549 const duration<Rep2, Period2>& rhs) | |
550 { | |
551 typedef typename common_type<duration<Rep1, Period1>, | |
552 duration<Rep2, Period2> >::type CD; | |
553 return CD(CD(lhs).count()-CD(rhs).count()); | |
554 } | |
555 | |
556 // Duration * | |
557 | |
558 template <class Rep1, class Period, class Rep2> | |
559 inline BOOST_CONSTEXPR | |
560 typename boost::enable_if < | |
561 mpl::and_ < | |
562 boost::is_convertible<Rep1, typename common_type<Rep1, Rep2>::type>, | |
563 boost::is_convertible<Rep2, typename common_type<Rep1, Rep2>::type> | |
564 >, | |
565 duration<typename common_type<Rep1, Rep2>::type, Period> | |
566 >::type | |
567 operator*(const duration<Rep1, Period>& d, const Rep2& s) | |
568 { | |
569 typedef typename common_type<Rep1, Rep2>::type CR; | |
570 typedef duration<CR, Period> CD; | |
571 return CD(CD(d).count()*static_cast<CR>(s)); | |
572 } | |
573 | |
574 template <class Rep1, class Period, class Rep2> | |
575 inline BOOST_CONSTEXPR | |
576 typename boost::enable_if < | |
577 mpl::and_ < | |
578 boost::is_convertible<Rep1, typename common_type<Rep1, Rep2>::type>, | |
579 boost::is_convertible<Rep2, typename common_type<Rep1, Rep2>::type> | |
580 >, | |
581 duration<typename common_type<Rep1, Rep2>::type, Period> | |
582 >::type | |
583 operator*(const Rep1& s, const duration<Rep2, Period>& d) | |
584 { | |
585 return d * s; | |
586 } | |
587 | |
588 // Duration / | |
589 | |
590 template <class Rep1, class Period, class Rep2> | |
591 inline BOOST_CONSTEXPR | |
592 typename boost::disable_if <boost::chrono::detail::is_duration<Rep2>, | |
593 typename boost::chrono::detail::duration_divide_result< | |
594 duration<Rep1, Period>, Rep2>::type | |
595 >::type | |
596 operator/(const duration<Rep1, Period>& d, const Rep2& s) | |
597 { | |
598 typedef typename common_type<Rep1, Rep2>::type CR; | |
599 typedef duration<CR, Period> CD; | |
600 | |
601 return CD(CD(d).count()/static_cast<CR>(s)); | |
602 } | |
603 | |
604 template <class Rep1, class Period1, class Rep2, class Period2> | |
605 inline BOOST_CONSTEXPR | |
606 typename common_type<Rep1, Rep2>::type | |
607 operator/(const duration<Rep1, Period1>& lhs, const duration<Rep2, Period2>& rhs) | |
608 { | |
609 typedef typename common_type<duration<Rep1, Period1>, | |
610 duration<Rep2, Period2> >::type CD; | |
611 return CD(lhs).count() / CD(rhs).count(); | |
612 } | |
613 | |
614 #ifdef BOOST_CHRONO_EXTENSIONS | |
615 template <class Rep1, class Rep2, class Period> | |
616 inline BOOST_CONSTEXPR | |
617 typename boost::disable_if <boost::chrono::detail::is_duration<Rep1>, | |
618 typename boost::chrono::detail::duration_divide_result2< | |
619 Rep1, duration<Rep2, Period> >::type | |
620 >::type | |
621 operator/(const Rep1& s, const duration<Rep2, Period>& d) | |
622 { | |
623 typedef typename common_type<Rep1, Rep2>::type CR; | |
624 typedef duration<CR, Period> CD; | |
625 | |
626 return static_cast<CR>(s)/CD(d).count(); | |
627 } | |
628 #endif | |
629 // Duration % | |
630 | |
631 template <class Rep1, class Period, class Rep2> | |
632 inline BOOST_CONSTEXPR | |
633 typename boost::disable_if <boost::chrono::detail::is_duration<Rep2>, | |
634 typename boost::chrono::detail::duration_modulo_result< | |
635 duration<Rep1, Period>, Rep2>::type | |
636 >::type | |
637 operator%(const duration<Rep1, Period>& d, const Rep2& s) | |
638 { | |
639 typedef typename common_type<Rep1, Rep2>::type CR; | |
640 typedef duration<CR, Period> CD; | |
641 | |
642 return CD(CD(d).count()%static_cast<CR>(s)); | |
643 } | |
644 | |
645 template <class Rep1, class Period1, class Rep2, class Period2> | |
646 inline BOOST_CONSTEXPR | |
647 typename common_type<duration<Rep1, Period1>, duration<Rep2, Period2> >::type | |
648 operator%(const duration<Rep1, Period1>& lhs, | |
649 const duration<Rep2, Period2>& rhs) { | |
650 typedef typename common_type<duration<Rep1, Period1>, | |
651 duration<Rep2, Period2> >::type CD; | |
652 | |
653 return CD(CD(lhs).count()%CD(rhs).count()); | |
654 } | |
655 | |
656 | |
657 //----------------------------------------------------------------------------// | |
658 // 20.9.3.6 duration comparisons [time.duration.comparisons] // | |
659 //----------------------------------------------------------------------------// | |
660 | |
661 namespace detail | |
662 { | |
663 template <class LhsDuration, class RhsDuration> | |
664 struct duration_eq | |
665 { | |
666 BOOST_CONSTEXPR bool operator()(const LhsDuration& lhs, const RhsDuration& rhs) const | |
667 { | |
668 typedef typename common_type<LhsDuration, RhsDuration>::type CD; | |
669 return CD(lhs).count() == CD(rhs).count(); | |
670 } | |
671 }; | |
672 | |
673 template <class LhsDuration> | |
674 struct duration_eq<LhsDuration, LhsDuration> | |
675 { | |
676 BOOST_CONSTEXPR bool operator()(const LhsDuration& lhs, const LhsDuration& rhs) const | |
677 { | |
678 return lhs.count() == rhs.count(); | |
679 } | |
680 }; | |
681 | |
682 template <class LhsDuration, class RhsDuration> | |
683 struct duration_lt | |
684 { | |
685 BOOST_CONSTEXPR bool operator()(const LhsDuration& lhs, const RhsDuration& rhs) const | |
686 { | |
687 typedef typename common_type<LhsDuration, RhsDuration>::type CD; | |
688 return CD(lhs).count() < CD(rhs).count(); | |
689 } | |
690 }; | |
691 | |
692 template <class LhsDuration> | |
693 struct duration_lt<LhsDuration, LhsDuration> | |
694 { | |
695 BOOST_CONSTEXPR bool operator()(const LhsDuration& lhs, const LhsDuration& rhs) const | |
696 { | |
697 return lhs.count() < rhs.count(); | |
698 } | |
699 }; | |
700 | |
701 } // namespace detail | |
702 | |
703 // Duration == | |
704 | |
705 template <class Rep1, class Period1, class Rep2, class Period2> | |
706 inline BOOST_CONSTEXPR | |
707 bool | |
708 operator==(const duration<Rep1, Period1>& lhs, | |
709 const duration<Rep2, Period2>& rhs) | |
710 { | |
711 return boost::chrono::detail::duration_eq< | |
712 duration<Rep1, Period1>, duration<Rep2, Period2> >()(lhs, rhs); | |
713 } | |
714 | |
715 // Duration != | |
716 | |
717 template <class Rep1, class Period1, class Rep2, class Period2> | |
718 inline BOOST_CONSTEXPR | |
719 bool | |
720 operator!=(const duration<Rep1, Period1>& lhs, | |
721 const duration<Rep2, Period2>& rhs) | |
722 { | |
723 return !(lhs == rhs); | |
724 } | |
725 | |
726 // Duration < | |
727 | |
728 template <class Rep1, class Period1, class Rep2, class Period2> | |
729 inline BOOST_CONSTEXPR | |
730 bool | |
731 operator< (const duration<Rep1, Period1>& lhs, | |
732 const duration<Rep2, Period2>& rhs) | |
733 { | |
734 return boost::chrono::detail::duration_lt< | |
735 duration<Rep1, Period1>, duration<Rep2, Period2> >()(lhs, rhs); | |
736 } | |
737 | |
738 // Duration > | |
739 | |
740 template <class Rep1, class Period1, class Rep2, class Period2> | |
741 inline BOOST_CONSTEXPR | |
742 bool | |
743 operator> (const duration<Rep1, Period1>& lhs, | |
744 const duration<Rep2, Period2>& rhs) | |
745 { | |
746 return rhs < lhs; | |
747 } | |
748 | |
749 // Duration <= | |
750 | |
751 template <class Rep1, class Period1, class Rep2, class Period2> | |
752 inline BOOST_CONSTEXPR | |
753 bool | |
754 operator<=(const duration<Rep1, Period1>& lhs, | |
755 const duration<Rep2, Period2>& rhs) | |
756 { | |
757 return !(rhs < lhs); | |
758 } | |
759 | |
760 // Duration >= | |
761 | |
762 template <class Rep1, class Period1, class Rep2, class Period2> | |
763 inline BOOST_CONSTEXPR | |
764 bool | |
765 operator>=(const duration<Rep1, Period1>& lhs, | |
766 const duration<Rep2, Period2>& rhs) | |
767 { | |
768 return !(lhs < rhs); | |
769 } | |
770 | |
771 //----------------------------------------------------------------------------// | |
772 // 20.9.3.7 duration_cast [time.duration.cast] // | |
773 //----------------------------------------------------------------------------// | |
774 | |
775 // Compile-time select the most efficient algorithm for the conversion... | |
776 template <class ToDuration, class Rep, class Period> | |
777 inline BOOST_CONSTEXPR | |
778 typename boost::enable_if < | |
779 boost::chrono::detail::is_duration<ToDuration>, ToDuration>::type | |
780 duration_cast(const duration<Rep, Period>& fd) | |
781 { | |
782 return boost::chrono::detail::duration_cast< | |
783 duration<Rep, Period>, ToDuration>()(fd); | |
784 } | |
785 | |
786 } // namespace chrono | |
787 } // namespace boost | |
788 | |
789 #ifndef BOOST_CHRONO_HEADER_ONLY | |
790 // the suffix header occurs after all of our code: | |
791 #include <boost/config/abi_suffix.hpp> // pops abi_prefix.hpp pragmas | |
792 #endif | |
793 | |
794 #endif // BOOST_CHRONO_DURATION_HPP |