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