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

source code of boost/libs/chrono/include/boost/chrono/duration.hpp