1 // duration.hpp --------------------------------------------------------------//
3 // Copyright 2008 Howard Hinnant
4 // Copyright 2008 Beman Dawes
5 // Copyright 2009-2011 Vicente J. Botet Escriba
7 // Distributed under the Boost Software License, Version 1.0.
8 // See http://www.boost.org/LICENSE_1_0.txt
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.
18 time2_demo contained this comment:
20 Much thanks to Andrei Alexandrescu,
30 #ifndef BOOST_CHRONO_DURATION_HPP
31 #define BOOST_CHRONO_DURATION_HPP
33 #include <boost/chrono/config.hpp>
34 #include <boost/chrono/detail/static_assert.hpp>
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>
49 #include <boost/cstdint.hpp>
50 #include <boost/utility/enable_if.hpp>
51 #include <boost/detail/workaround.hpp>
52 #include <boost/integer_traits.hpp>
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"
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
66 //----------------------------------------------------------------------------//
68 // 20.9 Time utilities [time] //
71 //----------------------------------------------------------------------------//
76 template <class Rep, class Period = ratio<1> >
83 : boost::false_type {};
85 template <class Rep, class Period>
86 struct is_duration<duration<Rep, Period> >
87 : boost::true_type {};
89 template <class Duration, class Rep, bool = is_duration<Rep>::value>
90 struct duration_divide_result
94 template <class Duration, class Rep2,
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))
102 struct duration_divide_imp
106 template <class Rep1, class Period, class Rep2>
107 struct duration_divide_imp<duration<Rep1, Period>, Rep2, true>
109 typedef duration<typename common_type<Rep1, Rep2>::type, Period> type;
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>
119 template <class Rep, class Duration, bool = is_duration<Rep>::value>
120 struct duration_divide_result2
124 template <class Rep, class Duration,
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))
132 struct duration_divide_imp2
136 template <class Rep1, class Rep2, class Period >
137 struct duration_divide_imp2<Rep1, duration<Rep2, Period>, true>
139 //typedef typename common_type<Rep1, Rep2>::type type;
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> >
150 template <class Duration, class Rep, bool = is_duration<Rep>::value>
151 struct duration_modulo_result
155 template <class Duration, class Rep2,
157 //boost::is_convertible<typename Duration::rep,
158 //typename common_type<typename Duration::rep, Rep2>::type>::value
160 boost::is_convertible<Rep2,
161 typename common_type<typename Duration::rep, Rep2>::type>::value
164 struct duration_modulo_imp
168 template <class Rep1, class Period, class Rep2>
169 struct duration_modulo_imp<duration<Rep1, Period>, Rep2, true>
171 typedef duration<typename common_type<Rep1, Rep2>::type, Period> type;
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>
180 } // namespace detail
181 } // namespace chrono
184 // common_type trait specializations
186 template <class Rep1, class Period1, class Rep2, class Period2>
187 struct common_type<chrono::duration<Rep1, Period1>,
188 chrono::duration<Rep2, Period2> >;
193 // customization traits
194 template <class Rep> struct treat_as_floating_point;
195 template <class Rep> struct duration_values;
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
205 //----------------------------------------------------------------------------//
206 // duration helpers //
207 //----------------------------------------------------------------------------//
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,
227 struct duration_cast_aux;
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>
236 BOOST_CONSTEXPR ToDuration operator()(const FromDuration& fd) const
238 return ToDuration(static_cast<typename ToDuration::rep>(fd.count()));
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>
251 BOOST_CONSTEXPR ToDuration operator()(const FromDuration& fd) const
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)));
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>
270 BOOST_CONSTEXPR ToDuration operator()(const FromDuration& fd) const
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)));
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>
290 BOOST_CONSTEXPR ToDuration operator()(const FromDuration& fd) const
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)));
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<
313 BOOST_CONSTEXPR ToDuration operator()(const FromDuration& fd) const
319 } // namespace detail
321 //----------------------------------------------------------------------------//
323 // 20.9.2 Time-related traits [time.traits] //
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 //----------------------------------------------------------------------------//
331 // Support bidirectional (non-exact) conversions for floating point rep types
332 // (or user defined rep types which specialize treat_as_floating_point).
334 struct treat_as_floating_point : boost::is_floating_point<Rep> {};
336 //----------------------------------------------------------------------------//
337 // 20.9.2.2 duration_values [time.traits.duration_values] //
338 //----------------------------------------------------------------------------//
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) ();}
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) ();}
352 struct chrono_numeric_limits<float,true> {
353 static BOOST_CHRONO_LIB_CONSTEXPR float lowest() BOOST_CHRONO_LIB_NOEXCEPT_OR_THROW
355 return -(std::numeric_limits<float>::max) ();
360 struct chrono_numeric_limits<double,true> {
361 static BOOST_CHRONO_LIB_CONSTEXPR double lowest() BOOST_CHRONO_LIB_NOEXCEPT_OR_THROW
363 return -(std::numeric_limits<double>::max) ();
368 struct chrono_numeric_limits<long double,true> {
369 static BOOST_CHRONO_LIB_CONSTEXPR long double lowest() BOOST_CHRONO_LIB_NOEXCEPT_OR_THROW
371 return -(std::numeric_limits<long double>::max)();
376 struct numeric_limits : chrono_numeric_limits<typename remove_cv<T>::type>
381 struct duration_values
383 static BOOST_CONSTEXPR Rep zero() {return Rep(0);}
384 static BOOST_CHRONO_LIB_CONSTEXPR Rep max BOOST_PREVENT_MACRO_SUBSTITUTION ()
386 return (std::numeric_limits<Rep>::max)();
389 static BOOST_CHRONO_LIB_CONSTEXPR Rep min BOOST_PREVENT_MACRO_SUBSTITUTION ()
391 return detail::numeric_limits<Rep>::lowest();
395 } // namespace chrono
397 //----------------------------------------------------------------------------//
398 // 20.9.2.3 Specializations of common_type [time.traits.specializations] //
399 //----------------------------------------------------------------------------//
401 template <class Rep1, class Period1, class Rep2, class Period2>
402 struct common_type<chrono::duration<Rep1, Period1>,
403 chrono::duration<Rep2, Period2> >
405 typedef chrono::duration<typename common_type<Rep1, Rep2>::type,
406 typename boost::ratio_gcd<Period1, Period2>::type> type;
410 //----------------------------------------------------------------------------//
412 // 20.9.3 Class template duration [time.duration] //
414 //----------------------------------------------------------------------------//
419 template <class Rep, class Period>
420 class BOOST_SYMBOL_VISIBLE duration
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, ());
431 typedef Period period;
436 #if defined BOOST_NO_CXX11_DEFAULTED_FUNCTIONS
437 BOOST_FORCEINLINE BOOST_CONSTEXPR
438 duration() : rep_(duration_values<rep>::zero()) { }
440 BOOST_CONSTEXPR duration() BOOST_NOEXCEPT {};
442 template <class Rep2>
443 BOOST_SYMBOL_VISIBLE BOOST_FORCEINLINE BOOST_CONSTEXPR
444 explicit duration(const Rep2& r
445 , typename boost::enable_if <
447 boost::is_convertible<Rep2, rep>,
449 treat_as_floating_point<rep>,
451 mpl::not_ < treat_as_floating_point<rep> >,
452 mpl::not_ < treat_as_floating_point<Rep2> >
458 #if defined BOOST_NO_CXX11_DEFAULTED_FUNCTIONS
459 duration& operator=(const duration& rhs)
461 if (&rhs != this) rep_= rhs.rep_;
465 duration& operator=(const duration& rhs) = default;
468 template <class Rep2, class Period2>
469 BOOST_FORCEINLINE BOOST_CONSTEXPR
470 duration(const duration<Rep2, Period2>& d
471 , typename boost::enable_if <
473 treat_as_floating_point<rep>,
475 chrono_detail::is_evenly_divisible_by<Period2, period>,
476 mpl::not_ < treat_as_floating_point<Rep2> >
481 : rep_(chrono::detail::duration_cast<duration<Rep2, Period2>, duration>()(d).count()) {}
486 rep count() const {return rep_;}
491 duration operator+() const {return duration(rep_);;}
493 duration operator-() const {return duration(-rep_);}
494 duration& operator++() {++rep_; return *this;}
495 duration operator++(int) {return duration(rep_++);}
496 duration& operator--() {--rep_; return *this;}
497 duration operator--(int) {return duration(rep_--);}
499 duration& operator+=(const duration& d)
501 rep_ += d.count(); return *this;
503 duration& operator-=(const duration& d)
505 rep_ -= d.count(); return *this;
508 duration& operator*=(const rep& rhs) {rep_ *= rhs; return *this;}
509 duration& operator/=(const rep& rhs) {rep_ /= rhs; return *this;}
510 duration& operator%=(const rep& rhs) {rep_ %= rhs; return *this;}
511 duration& operator%=(const duration& rhs)
513 rep_ %= rhs.count(); return *this;
515 // 20.9.3.4 duration special values [time.duration.special]
517 static BOOST_CONSTEXPR duration zero()
519 return duration(duration_values<rep>::zero());
521 static BOOST_CHRONO_LIB_CONSTEXPR duration min BOOST_PREVENT_MACRO_SUBSTITUTION ()
523 return duration((duration_values<rep>::min)());
525 static BOOST_CHRONO_LIB_CONSTEXPR duration max BOOST_PREVENT_MACRO_SUBSTITUTION ()
527 return duration((duration_values<rep>::max)());
531 //----------------------------------------------------------------------------//
532 // 20.9.3.5 duration non-member arithmetic [time.duration.nonmember] //
533 //----------------------------------------------------------------------------//
537 template <class Rep1, class Period1, class Rep2, class Period2>
538 inline BOOST_CONSTEXPR
539 typename common_type<duration<Rep1, Period1>, duration<Rep2, Period2> >::type
540 operator+(const duration<Rep1, Period1>& lhs,
541 const duration<Rep2, Period2>& rhs)
543 typedef typename common_type<duration<Rep1, Period1>,
544 duration<Rep2, Period2> >::type CD;
545 return CD(CD(lhs).count()+CD(rhs).count());
550 template <class Rep1, class Period1, class Rep2, class Period2>
551 inline BOOST_CONSTEXPR
552 typename common_type<duration<Rep1, Period1>, duration<Rep2, Period2> >::type
553 operator-(const duration<Rep1, Period1>& lhs,
554 const duration<Rep2, Period2>& rhs)
556 typedef typename common_type<duration<Rep1, Period1>,
557 duration<Rep2, Period2> >::type CD;
558 return CD(CD(lhs).count()-CD(rhs).count());
563 template <class Rep1, class Period, class Rep2>
564 inline BOOST_CONSTEXPR
565 typename boost::enable_if <
567 boost::is_convertible<Rep1, typename common_type<Rep1, Rep2>::type>,
568 boost::is_convertible<Rep2, typename common_type<Rep1, Rep2>::type>
570 duration<typename common_type<Rep1, Rep2>::type, Period>
572 operator*(const duration<Rep1, Period>& d, const Rep2& s)
574 typedef typename common_type<Rep1, Rep2>::type CR;
575 typedef duration<CR, Period> CD;
576 return CD(CD(d).count()*static_cast<CR>(s));
579 template <class Rep1, class Period, class Rep2>
580 inline BOOST_CONSTEXPR
581 typename boost::enable_if <
583 boost::is_convertible<Rep1, typename common_type<Rep1, Rep2>::type>,
584 boost::is_convertible<Rep2, typename common_type<Rep1, Rep2>::type>
586 duration<typename common_type<Rep1, Rep2>::type, Period>
588 operator*(const Rep1& s, const duration<Rep2, Period>& d)
595 template <class Rep1, class Period, class Rep2>
596 inline BOOST_CONSTEXPR
597 typename boost::disable_if <boost::chrono::detail::is_duration<Rep2>,
598 typename boost::chrono::detail::duration_divide_result<
599 duration<Rep1, Period>, Rep2>::type
601 operator/(const duration<Rep1, Period>& d, const Rep2& s)
603 typedef typename common_type<Rep1, Rep2>::type CR;
604 typedef duration<CR, Period> CD;
606 return CD(CD(d).count()/static_cast<CR>(s));
609 template <class Rep1, class Period1, class Rep2, class Period2>
610 inline BOOST_CONSTEXPR
611 typename common_type<Rep1, Rep2>::type
612 operator/(const duration<Rep1, Period1>& lhs, const duration<Rep2, Period2>& rhs)
614 typedef typename common_type<duration<Rep1, Period1>,
615 duration<Rep2, Period2> >::type CD;
616 return CD(lhs).count() / CD(rhs).count();
619 #ifdef BOOST_CHRONO_EXTENSIONS
620 template <class Rep1, class Rep2, class Period>
621 inline BOOST_CONSTEXPR
622 typename boost::disable_if <boost::chrono::detail::is_duration<Rep1>,
623 typename boost::chrono::detail::duration_divide_result2<
624 Rep1, duration<Rep2, Period> >::type
626 operator/(const Rep1& s, const duration<Rep2, Period>& d)
628 typedef typename common_type<Rep1, Rep2>::type CR;
629 typedef duration<CR, Period> CD;
631 return static_cast<CR>(s)/CD(d).count();
636 template <class Rep1, class Period, class Rep2>
637 inline BOOST_CONSTEXPR
638 typename boost::disable_if <boost::chrono::detail::is_duration<Rep2>,
639 typename boost::chrono::detail::duration_modulo_result<
640 duration<Rep1, Period>, Rep2>::type
642 operator%(const duration<Rep1, Period>& d, const Rep2& s)
644 typedef typename common_type<Rep1, Rep2>::type CR;
645 typedef duration<CR, Period> CD;
647 return CD(CD(d).count()%static_cast<CR>(s));
650 template <class Rep1, class Period1, class Rep2, class Period2>
651 inline BOOST_CONSTEXPR
652 typename common_type<duration<Rep1, Period1>, duration<Rep2, Period2> >::type
653 operator%(const duration<Rep1, Period1>& lhs,
654 const duration<Rep2, Period2>& rhs) {
655 typedef typename common_type<duration<Rep1, Period1>,
656 duration<Rep2, Period2> >::type CD;
658 return CD(CD(lhs).count()%CD(rhs).count());
662 //----------------------------------------------------------------------------//
663 // 20.9.3.6 duration comparisons [time.duration.comparisons] //
664 //----------------------------------------------------------------------------//
668 template <class LhsDuration, class RhsDuration>
671 BOOST_CONSTEXPR bool operator()(const LhsDuration& lhs, const RhsDuration& rhs) const
673 typedef typename common_type<LhsDuration, RhsDuration>::type CD;
674 return CD(lhs).count() == CD(rhs).count();
678 template <class LhsDuration>
679 struct duration_eq<LhsDuration, LhsDuration>
681 BOOST_CONSTEXPR bool operator()(const LhsDuration& lhs, const LhsDuration& rhs) const
683 return lhs.count() == rhs.count();
687 template <class LhsDuration, class RhsDuration>
690 BOOST_CONSTEXPR bool operator()(const LhsDuration& lhs, const RhsDuration& rhs) const
692 typedef typename common_type<LhsDuration, RhsDuration>::type CD;
693 return CD(lhs).count() < CD(rhs).count();
697 template <class LhsDuration>
698 struct duration_lt<LhsDuration, LhsDuration>
700 BOOST_CONSTEXPR bool operator()(const LhsDuration& lhs, const LhsDuration& rhs) const
702 return lhs.count() < rhs.count();
706 } // namespace detail
710 template <class Rep1, class Period1, class Rep2, class Period2>
711 inline BOOST_CONSTEXPR
713 operator==(const duration<Rep1, Period1>& lhs,
714 const duration<Rep2, Period2>& rhs)
716 return boost::chrono::detail::duration_eq<
717 duration<Rep1, Period1>, duration<Rep2, Period2> >()(lhs, rhs);
722 template <class Rep1, class Period1, class Rep2, class Period2>
723 inline BOOST_CONSTEXPR
725 operator!=(const duration<Rep1, Period1>& lhs,
726 const duration<Rep2, Period2>& rhs)
728 return !(lhs == rhs);
733 template <class Rep1, class Period1, class Rep2, class Period2>
734 inline BOOST_CONSTEXPR
736 operator< (const duration<Rep1, Period1>& lhs,
737 const duration<Rep2, Period2>& rhs)
739 return boost::chrono::detail::duration_lt<
740 duration<Rep1, Period1>, duration<Rep2, Period2> >()(lhs, rhs);
745 template <class Rep1, class Period1, class Rep2, class Period2>
746 inline BOOST_CONSTEXPR
748 operator> (const duration<Rep1, Period1>& lhs,
749 const duration<Rep2, Period2>& rhs)
756 template <class Rep1, class Period1, class Rep2, class Period2>
757 inline BOOST_CONSTEXPR
759 operator<=(const duration<Rep1, Period1>& lhs,
760 const duration<Rep2, Period2>& rhs)
767 template <class Rep1, class Period1, class Rep2, class Period2>
768 inline BOOST_CONSTEXPR
770 operator>=(const duration<Rep1, Period1>& lhs,
771 const duration<Rep2, Period2>& rhs)
776 //----------------------------------------------------------------------------//
777 // 20.9.3.7 duration_cast [time.duration.cast] //
778 //----------------------------------------------------------------------------//
780 // Compile-time select the most efficient algorithm for the conversion...
781 template <class ToDuration, class Rep, class Period>
782 inline BOOST_CONSTEXPR
783 typename boost::enable_if <
784 boost::chrono::detail::is_duration<ToDuration>, ToDuration>::type
785 duration_cast(const duration<Rep, Period>& fd)
787 return boost::chrono::detail::duration_cast<
788 duration<Rep, Period>, ToDuration>()(fd);
791 } // namespace chrono
794 #ifndef BOOST_CHRONO_HEADER_ONLY
795 // the suffix header occurs after all of our code:
796 #include <boost/config/abi_suffix.hpp> // pops abi_prefix.hpp pragmas
799 #endif // BOOST_CHRONO_DURATION_HPP