Chris@16: // duration.hpp --------------------------------------------------------------// Chris@16: Chris@16: // Copyright 2008 Howard Hinnant Chris@16: // Copyright 2008 Beman Dawes Chris@16: // Copyright 2009-2011 Vicente J. Botet Escriba Chris@16: Chris@16: // Distributed under the Boost Software License, Version 1.0. Chris@16: // See http://www.boost.org/LICENSE_1_0.txt Chris@16: Chris@16: /* Chris@16: Chris@16: This code was derived by Beman Dawes from Howard Hinnant's time2_demo prototype. Chris@16: Many thanks to Howard for making his code available under the Boost license. Chris@16: The original code was modified to conform to Boost conventions and to section Chris@16: 20.9 Time utilities [time] of the C++ committee's working paper N2798. Chris@16: See http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2798.pdf. Chris@16: Chris@16: time2_demo contained this comment: Chris@16: Chris@16: Much thanks to Andrei Alexandrescu, Chris@16: Walter Brown, Chris@16: Peter Dimov, Chris@16: Jeff Garland, Chris@16: Terry Golubiewski, Chris@16: Daniel Krugler, Chris@16: Anthony Williams. Chris@16: */ Chris@16: Chris@16: Chris@16: #ifndef BOOST_CHRONO_DURATION_HPP Chris@16: #define BOOST_CHRONO_DURATION_HPP Chris@16: Chris@16: #include Chris@16: #include Chris@16: Chris@16: #include Chris@16: #include Chris@16: Chris@16: Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: Chris@16: #if !defined(BOOST_NO_CXX11_STATIC_ASSERT) || !defined(BOOST_CHRONO_USES_MPL_ASSERT) Chris@16: #define BOOST_CHRONO_A_DURATION_REPRESENTATION_CAN_NOT_BE_A_DURATION "A duration representation can not be a duration" Chris@16: #define BOOST_CHRONO_SECOND_TEMPLATE_PARAMETER_OF_DURATION_MUST_BE_A_STD_RATIO "Second template parameter of duration must be a boost::ratio" Chris@16: #define BOOST_CHRONO_DURATION_PERIOD_MUST_BE_POSITIVE "duration period must be positive" Chris@16: #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" Chris@16: #endif Chris@16: Chris@16: #ifndef BOOST_CHRONO_HEADER_ONLY Chris@16: // this must occur after all of the includes and before any code appears: Chris@16: #include // must be the last #include Chris@16: #endif Chris@16: Chris@16: //----------------------------------------------------------------------------// Chris@16: // // Chris@16: // 20.9 Time utilities [time] // Chris@16: // synopsis // Chris@16: // // Chris@16: //----------------------------------------------------------------------------// Chris@16: Chris@16: namespace boost { Chris@16: namespace chrono { Chris@16: Chris@16: template > Chris@16: class duration; Chris@16: Chris@16: namespace detail Chris@16: { Chris@16: template Chris@16: struct is_duration Chris@16: : boost::false_type {}; Chris@16: Chris@16: template Chris@16: struct is_duration > Chris@16: : boost::true_type {}; Chris@16: Chris@16: template ::value> Chris@16: struct duration_divide_result Chris@16: { Chris@16: }; Chris@16: Chris@16: template ::type>::value)) Chris@16: && ((boost::is_convertible::type>::value)) Chris@16: ) Chris@16: > Chris@16: struct duration_divide_imp Chris@16: { Chris@16: }; Chris@16: Chris@16: template Chris@16: struct duration_divide_imp, Rep2, true> Chris@16: { Chris@16: typedef duration::type, Period> type; Chris@16: }; Chris@16: Chris@16: template Chris@16: struct duration_divide_result, Rep2, false> Chris@16: : duration_divide_imp, Rep2> Chris@16: { Chris@16: }; Chris@16: Chris@16: /// Chris@16: template ::value> Chris@16: struct duration_divide_result2 Chris@16: { Chris@16: }; Chris@16: Chris@16: template ::type>::value)) Chris@16: && ((boost::is_convertible::type>::value)) Chris@16: ) Chris@16: > Chris@16: struct duration_divide_imp2 Chris@16: { Chris@16: }; Chris@16: Chris@16: template Chris@16: struct duration_divide_imp2, true> Chris@16: { Chris@16: //typedef typename common_type::type type; Chris@16: typedef double type; Chris@16: }; Chris@16: Chris@16: template Chris@16: struct duration_divide_result2, false> Chris@16: : duration_divide_imp2 > Chris@16: { Chris@16: }; Chris@16: Chris@16: /// Chris@16: template ::value> Chris@16: struct duration_modulo_result Chris@16: { Chris@16: }; Chris@16: Chris@16: template ::type>::value Chris@16: //&& Chris@16: boost::is_convertible::type>::value Chris@16: ) Chris@16: > Chris@16: struct duration_modulo_imp Chris@16: { Chris@16: }; Chris@16: Chris@16: template Chris@16: struct duration_modulo_imp, Rep2, true> Chris@16: { Chris@16: typedef duration::type, Period> type; Chris@16: }; Chris@16: Chris@16: template Chris@16: struct duration_modulo_result, Rep2, false> Chris@16: : duration_modulo_imp, Rep2> Chris@16: { Chris@16: }; Chris@16: Chris@16: } // namespace detail Chris@16: } // namespace chrono Chris@16: Chris@16: Chris@16: // common_type trait specializations Chris@16: Chris@16: template Chris@16: struct common_type, Chris@16: chrono::duration >; Chris@16: Chris@16: Chris@16: namespace chrono { Chris@16: Chris@16: // customization traits Chris@16: template struct treat_as_floating_point; Chris@16: template struct duration_values; Chris@16: Chris@16: // convenience typedefs Chris@16: typedef duration nanoseconds; // at least 64 bits needed Chris@16: typedef duration microseconds; // at least 55 bits needed Chris@16: typedef duration milliseconds; // at least 45 bits needed Chris@16: typedef duration seconds; // at least 35 bits needed Chris@16: typedef duration > minutes; // at least 29 bits needed Chris@16: typedef duration > hours; // at least 23 bits needed Chris@16: Chris@16: //----------------------------------------------------------------------------// Chris@16: // duration helpers // Chris@16: //----------------------------------------------------------------------------// Chris@16: Chris@16: namespace detail Chris@16: { Chris@16: Chris@16: // duration_cast Chris@16: Chris@16: // duration_cast is the heart of this whole prototype. It can convert any Chris@16: // duration to any other. It is also (implicitly) used in converting Chris@16: // time_points. The conversion is always exact if possible. And it is Chris@16: // always as efficient as hand written code. If different representations Chris@16: // are involved, care is taken to never require implicit conversions. Chris@16: // Instead static_cast is used explicitly for every required conversion. Chris@16: // If there are a mixture of integral and floating point representations, Chris@16: // the use of common_type ensures that the most logical "intermediate" Chris@16: // representation is used. Chris@16: template Chris@16: struct duration_cast_aux; Chris@16: Chris@16: // When the two periods are the same, all that is left to do is static_cast from Chris@16: // the source representation to the target representation (which may be a no-op). Chris@16: // This conversion is always exact as long as the static_cast from the source Chris@16: // representation to the destination representation is exact. Chris@16: template Chris@16: struct duration_cast_aux Chris@16: { Chris@16: BOOST_CONSTEXPR ToDuration operator()(const FromDuration& fd) const Chris@16: { Chris@16: return ToDuration(static_cast(fd.count())); Chris@16: } Chris@16: }; Chris@16: Chris@16: // When the numerator of FromPeriod / ToPeriod is 1, then all we need to do is Chris@16: // divide by the denominator of FromPeriod / ToPeriod. The common_type of Chris@16: // the two representations is used for the intermediate computation before Chris@16: // static_cast'ing to the destination. Chris@16: // This conversion is generally not exact because of the division (but could be Chris@16: // if you get lucky on the run time value of fd.count()). Chris@16: template Chris@16: struct duration_cast_aux Chris@16: { Chris@16: BOOST_CONSTEXPR ToDuration operator()(const FromDuration& fd) const Chris@16: { Chris@16: typedef typename common_type< Chris@16: typename ToDuration::rep, Chris@16: typename FromDuration::rep, Chris@16: boost::intmax_t>::type C; Chris@16: return ToDuration(static_cast( Chris@16: static_cast(fd.count()) / static_cast(Period::den))); Chris@16: } Chris@16: }; Chris@16: Chris@16: // When the denominator of FromPeriod / ToPeriod is 1, then all we need to do is Chris@16: // multiply by the numerator of FromPeriod / ToPeriod. The common_type of Chris@16: // the two representations is used for the intermediate computation before Chris@16: // static_cast'ing to the destination. Chris@16: // This conversion is always exact as long as the static_cast's involved are exact. Chris@16: template Chris@16: struct duration_cast_aux Chris@16: { Chris@16: BOOST_CONSTEXPR ToDuration operator()(const FromDuration& fd) const Chris@16: { Chris@16: typedef typename common_type< Chris@16: typename ToDuration::rep, Chris@16: typename FromDuration::rep, Chris@16: boost::intmax_t>::type C; Chris@16: return ToDuration(static_cast( Chris@16: static_cast(fd.count()) * static_cast(Period::num))); Chris@16: } Chris@16: }; Chris@16: Chris@16: // When neither the numerator or denominator of FromPeriod / ToPeriod is 1, then we need to Chris@16: // multiply by the numerator and divide by the denominator of FromPeriod / ToPeriod. The Chris@16: // common_type of the two representations is used for the intermediate computation before Chris@16: // static_cast'ing to the destination. Chris@16: // This conversion is generally not exact because of the division (but could be Chris@16: // if you get lucky on the run time value of fd.count()). Chris@16: template Chris@16: struct duration_cast_aux Chris@16: { Chris@16: BOOST_CONSTEXPR ToDuration operator()(const FromDuration& fd) const Chris@16: { Chris@16: typedef typename common_type< Chris@16: typename ToDuration::rep, Chris@16: typename FromDuration::rep, Chris@16: boost::intmax_t>::type C; Chris@16: return ToDuration(static_cast( Chris@16: static_cast(fd.count()) * static_cast(Period::num) Chris@16: / static_cast(Period::den))); Chris@16: } Chris@16: }; Chris@16: Chris@16: template Chris@16: struct duration_cast { Chris@16: typedef typename ratio_divide::type Period; Chris@16: typedef duration_cast_aux< Chris@16: FromDuration, Chris@16: ToDuration, Chris@16: Period, Chris@16: Period::num == 1, Chris@16: Period::den == 1 Chris@16: > Aux; Chris@16: BOOST_CONSTEXPR ToDuration operator()(const FromDuration& fd) const Chris@16: { Chris@16: return Aux()(fd); Chris@16: } Chris@16: }; Chris@16: Chris@16: } // namespace detail Chris@16: Chris@16: //----------------------------------------------------------------------------// Chris@16: // // Chris@16: // 20.9.2 Time-related traits [time.traits] // Chris@16: // // Chris@16: //----------------------------------------------------------------------------// Chris@16: //----------------------------------------------------------------------------// Chris@16: // 20.9.2.1 treat_as_floating_point [time.traits.is_fp] // Chris@16: // Probably should have been treat_as_floating_point. Editor notifed. // Chris@16: //----------------------------------------------------------------------------// Chris@16: Chris@16: // Support bidirectional (non-exact) conversions for floating point rep types Chris@16: // (or user defined rep types which specialize treat_as_floating_point). Chris@16: template Chris@16: struct treat_as_floating_point : boost::is_floating_point {}; Chris@16: Chris@16: //----------------------------------------------------------------------------// Chris@16: // 20.9.2.2 duration_values [time.traits.duration_values] // Chris@16: //----------------------------------------------------------------------------// Chris@16: Chris@16: namespace detail { Chris@16: template ::value> Chris@16: struct chrono_numeric_limits { Chris@16: static BOOST_CHRONO_LIB_CONSTEXPR T lowest() BOOST_CHRONO_LIB_NOEXCEPT_OR_THROW {return (std::numeric_limits::min) ();} Chris@16: }; Chris@16: Chris@16: template Chris@16: struct chrono_numeric_limits { Chris@16: static BOOST_CHRONO_LIB_CONSTEXPR T lowest() BOOST_CHRONO_LIB_NOEXCEPT_OR_THROW {return (std::numeric_limits::min) ();} Chris@16: }; Chris@16: Chris@16: template <> Chris@16: struct chrono_numeric_limits { Chris@16: static BOOST_CHRONO_LIB_CONSTEXPR float lowest() BOOST_CHRONO_LIB_NOEXCEPT_OR_THROW Chris@16: { Chris@16: return -(std::numeric_limits::max) (); Chris@16: } Chris@16: }; Chris@16: Chris@16: template <> Chris@16: struct chrono_numeric_limits { Chris@16: static BOOST_CHRONO_LIB_CONSTEXPR double lowest() BOOST_CHRONO_LIB_NOEXCEPT_OR_THROW Chris@16: { Chris@16: return -(std::numeric_limits::max) (); Chris@16: } Chris@16: }; Chris@16: Chris@16: template <> Chris@16: struct chrono_numeric_limits { Chris@16: static BOOST_CHRONO_LIB_CONSTEXPR long double lowest() BOOST_CHRONO_LIB_NOEXCEPT_OR_THROW Chris@16: { Chris@16: return -(std::numeric_limits::max)(); Chris@16: } Chris@16: }; Chris@16: Chris@16: template Chris@16: struct numeric_limits : chrono_numeric_limits::type> Chris@16: {}; Chris@16: Chris@16: } Chris@16: template Chris@16: struct duration_values Chris@16: { Chris@16: static BOOST_CONSTEXPR Rep zero() {return Rep(0);} Chris@16: static BOOST_CHRONO_LIB_CONSTEXPR Rep max BOOST_PREVENT_MACRO_SUBSTITUTION () Chris@16: { Chris@16: return (std::numeric_limits::max)(); Chris@16: } Chris@16: Chris@16: static BOOST_CHRONO_LIB_CONSTEXPR Rep min BOOST_PREVENT_MACRO_SUBSTITUTION () Chris@16: { Chris@16: return detail::numeric_limits::lowest(); Chris@16: } Chris@16: }; Chris@16: Chris@16: } // namespace chrono Chris@16: Chris@16: //----------------------------------------------------------------------------// Chris@16: // 20.9.2.3 Specializations of common_type [time.traits.specializations] // Chris@16: //----------------------------------------------------------------------------// Chris@16: Chris@16: template Chris@16: struct common_type, Chris@16: chrono::duration > Chris@16: { Chris@16: typedef chrono::duration::type, Chris@16: typename boost::ratio_gcd::type> type; Chris@16: }; Chris@16: Chris@16: Chris@16: //----------------------------------------------------------------------------// Chris@16: // // Chris@16: // 20.9.3 Class template duration [time.duration] // Chris@16: // // Chris@16: //----------------------------------------------------------------------------// Chris@16: Chris@16: Chris@16: namespace chrono { Chris@16: Chris@16: template Chris@16: class BOOST_SYMBOL_VISIBLE duration Chris@16: { Chris@16: //BOOST_CHRONO_STATIC_ASSERT(boost::is_integral::value, BOOST_CHRONO_A_DURATION_REPRESENTATION_MUST_BE_INTEGRAL, ()); Chris@16: BOOST_CHRONO_STATIC_ASSERT(!boost::chrono::detail::is_duration::value, Chris@16: BOOST_CHRONO_A_DURATION_REPRESENTATION_CAN_NOT_BE_A_DURATION, ()); Chris@16: BOOST_CHRONO_STATIC_ASSERT(boost::ratio_detail::is_ratio::value, Chris@16: BOOST_CHRONO_SECOND_TEMPLATE_PARAMETER_OF_DURATION_MUST_BE_A_STD_RATIO, ()); Chris@16: BOOST_CHRONO_STATIC_ASSERT(Period::num>0, Chris@16: BOOST_CHRONO_DURATION_PERIOD_MUST_BE_POSITIVE, ()); Chris@16: public: Chris@16: typedef Rep rep; Chris@16: typedef Period period; Chris@16: private: Chris@16: rep rep_; Chris@16: public: Chris@16: Chris@101: #if defined BOOST_NO_CXX11_DEFAULTED_FUNCTIONS Chris@16: BOOST_FORCEINLINE BOOST_CONSTEXPR Chris@16: duration() : rep_(duration_values::zero()) { } Chris@101: #else Chris@101: BOOST_CONSTEXPR duration() BOOST_NOEXCEPT {}; Chris@101: #endif Chris@16: template Chris@16: BOOST_SYMBOL_VISIBLE BOOST_FORCEINLINE BOOST_CONSTEXPR Chris@16: explicit duration(const Rep2& r Chris@16: , typename boost::enable_if < Chris@16: mpl::and_ < Chris@16: boost::is_convertible, Chris@16: mpl::or_ < Chris@16: treat_as_floating_point, Chris@16: mpl::and_ < Chris@16: mpl::not_ < treat_as_floating_point >, Chris@16: mpl::not_ < treat_as_floating_point > Chris@16: > Chris@16: > Chris@16: > Chris@16: >::type* = 0 Chris@16: ) : rep_(r) { } Chris@101: #if defined BOOST_NO_CXX11_DEFAULTED_FUNCTIONS Chris@101: duration& operator=(const duration& rhs) Chris@16: { Chris@16: if (&rhs != this) rep_= rhs.rep_; Chris@16: return *this; Chris@16: } Chris@101: #else Chris@101: duration& operator=(const duration& rhs) = default; Chris@101: #endif Chris@16: // conversions Chris@16: template Chris@16: BOOST_FORCEINLINE BOOST_CONSTEXPR Chris@16: duration(const duration& d Chris@16: , typename boost::enable_if < Chris@16: mpl::or_ < Chris@16: treat_as_floating_point, Chris@16: mpl::and_ < Chris@16: chrono_detail::is_evenly_divisible_by, Chris@16: mpl::not_ < treat_as_floating_point > Chris@16: > Chris@16: > Chris@16: >::type* = 0 Chris@16: ) Chris@16: : rep_(chrono::detail::duration_cast, duration>()(d).count()) {} Chris@16: Chris@16: // observer Chris@16: Chris@16: BOOST_CONSTEXPR Chris@16: rep count() const {return rep_;} Chris@16: Chris@16: // arithmetic Chris@16: Chris@16: BOOST_CONSTEXPR Chris@16: duration operator+() const {return duration(rep_);;} Chris@16: BOOST_CONSTEXPR Chris@16: duration operator-() const {return duration(-rep_);} Chris@16: duration& operator++() {++rep_; return *this;} Chris@16: duration operator++(int) {return duration(rep_++);} Chris@16: duration& operator--() {--rep_; return *this;} Chris@16: duration operator--(int) {return duration(rep_--);} Chris@16: Chris@16: duration& operator+=(const duration& d) Chris@16: { Chris@16: rep_ += d.count(); return *this; Chris@16: } Chris@16: duration& operator-=(const duration& d) Chris@16: { Chris@16: rep_ -= d.count(); return *this; Chris@16: } Chris@16: Chris@16: duration& operator*=(const rep& rhs) {rep_ *= rhs; return *this;} Chris@16: duration& operator/=(const rep& rhs) {rep_ /= rhs; return *this;} Chris@16: duration& operator%=(const rep& rhs) {rep_ %= rhs; return *this;} Chris@16: duration& operator%=(const duration& rhs) Chris@16: { Chris@16: rep_ %= rhs.count(); return *this; Chris@16: } Chris@16: // 20.9.3.4 duration special values [time.duration.special] Chris@16: Chris@16: static BOOST_CONSTEXPR duration zero() Chris@16: { Chris@16: return duration(duration_values::zero()); Chris@16: } Chris@16: static BOOST_CHRONO_LIB_CONSTEXPR duration min BOOST_PREVENT_MACRO_SUBSTITUTION () Chris@16: { Chris@16: return duration((duration_values::min)()); Chris@16: } Chris@16: static BOOST_CHRONO_LIB_CONSTEXPR duration max BOOST_PREVENT_MACRO_SUBSTITUTION () Chris@16: { Chris@16: return duration((duration_values::max)()); Chris@16: } Chris@16: }; Chris@16: Chris@16: //----------------------------------------------------------------------------// Chris@16: // 20.9.3.5 duration non-member arithmetic [time.duration.nonmember] // Chris@16: //----------------------------------------------------------------------------// Chris@16: Chris@16: // Duration + Chris@16: Chris@16: template Chris@16: inline BOOST_CONSTEXPR Chris@16: typename common_type, duration >::type Chris@16: operator+(const duration& lhs, Chris@16: const duration& rhs) Chris@16: { Chris@16: typedef typename common_type, Chris@16: duration >::type CD; Chris@16: return CD(CD(lhs).count()+CD(rhs).count()); Chris@16: } Chris@16: Chris@16: // Duration - Chris@16: Chris@16: template Chris@16: inline BOOST_CONSTEXPR Chris@16: typename common_type, duration >::type Chris@16: operator-(const duration& lhs, Chris@16: const duration& rhs) Chris@16: { Chris@16: typedef typename common_type, Chris@16: duration >::type CD; Chris@16: return CD(CD(lhs).count()-CD(rhs).count()); Chris@16: } Chris@16: Chris@16: // Duration * Chris@16: Chris@16: template Chris@16: inline BOOST_CONSTEXPR Chris@16: typename boost::enable_if < Chris@16: mpl::and_ < Chris@16: boost::is_convertible::type>, Chris@16: boost::is_convertible::type> Chris@16: >, Chris@16: duration::type, Period> Chris@16: >::type Chris@16: operator*(const duration& d, const Rep2& s) Chris@16: { Chris@16: typedef typename common_type::type CR; Chris@16: typedef duration CD; Chris@16: return CD(CD(d).count()*static_cast(s)); Chris@16: } Chris@16: Chris@16: template Chris@16: inline BOOST_CONSTEXPR Chris@16: typename boost::enable_if < Chris@16: mpl::and_ < Chris@16: boost::is_convertible::type>, Chris@16: boost::is_convertible::type> Chris@16: >, Chris@16: duration::type, Period> Chris@16: >::type Chris@16: operator*(const Rep1& s, const duration& d) Chris@16: { Chris@16: return d * s; Chris@16: } Chris@16: Chris@16: // Duration / Chris@16: Chris@16: template Chris@16: inline BOOST_CONSTEXPR Chris@16: typename boost::disable_if , Chris@16: typename boost::chrono::detail::duration_divide_result< Chris@16: duration, Rep2>::type Chris@16: >::type Chris@16: operator/(const duration& d, const Rep2& s) Chris@16: { Chris@16: typedef typename common_type::type CR; Chris@16: typedef duration CD; Chris@16: Chris@16: return CD(CD(d).count()/static_cast(s)); Chris@16: } Chris@16: Chris@16: template Chris@16: inline BOOST_CONSTEXPR Chris@16: typename common_type::type Chris@16: operator/(const duration& lhs, const duration& rhs) Chris@16: { Chris@16: typedef typename common_type, Chris@16: duration >::type CD; Chris@16: return CD(lhs).count() / CD(rhs).count(); Chris@16: } Chris@16: Chris@16: #ifdef BOOST_CHRONO_EXTENSIONS Chris@16: template Chris@16: inline BOOST_CONSTEXPR Chris@16: typename boost::disable_if , Chris@16: typename boost::chrono::detail::duration_divide_result2< Chris@16: Rep1, duration >::type Chris@16: >::type Chris@16: operator/(const Rep1& s, const duration& d) Chris@16: { Chris@16: typedef typename common_type::type CR; Chris@16: typedef duration CD; Chris@16: Chris@16: return static_cast(s)/CD(d).count(); Chris@16: } Chris@16: #endif Chris@16: // Duration % Chris@16: Chris@16: template Chris@16: inline BOOST_CONSTEXPR Chris@16: typename boost::disable_if , Chris@16: typename boost::chrono::detail::duration_modulo_result< Chris@16: duration, Rep2>::type Chris@16: >::type Chris@16: operator%(const duration& d, const Rep2& s) Chris@16: { Chris@16: typedef typename common_type::type CR; Chris@16: typedef duration CD; Chris@16: Chris@16: return CD(CD(d).count()%static_cast(s)); Chris@16: } Chris@16: Chris@16: template Chris@16: inline BOOST_CONSTEXPR Chris@16: typename common_type, duration >::type Chris@16: operator%(const duration& lhs, Chris@16: const duration& rhs) { Chris@16: typedef typename common_type, Chris@16: duration >::type CD; Chris@16: Chris@16: return CD(CD(lhs).count()%CD(rhs).count()); Chris@16: } Chris@16: Chris@16: Chris@16: //----------------------------------------------------------------------------// Chris@16: // 20.9.3.6 duration comparisons [time.duration.comparisons] // Chris@16: //----------------------------------------------------------------------------// Chris@16: Chris@16: namespace detail Chris@16: { Chris@16: template Chris@16: struct duration_eq Chris@16: { Chris@16: BOOST_CONSTEXPR bool operator()(const LhsDuration& lhs, const RhsDuration& rhs) const Chris@16: { Chris@16: typedef typename common_type::type CD; Chris@16: return CD(lhs).count() == CD(rhs).count(); Chris@16: } Chris@16: }; Chris@16: Chris@16: template Chris@16: struct duration_eq Chris@16: { Chris@16: BOOST_CONSTEXPR bool operator()(const LhsDuration& lhs, const LhsDuration& rhs) const Chris@16: { Chris@16: return lhs.count() == rhs.count(); Chris@16: } Chris@16: }; Chris@16: Chris@16: template Chris@16: struct duration_lt Chris@16: { Chris@16: BOOST_CONSTEXPR bool operator()(const LhsDuration& lhs, const RhsDuration& rhs) const Chris@16: { Chris@16: typedef typename common_type::type CD; Chris@16: return CD(lhs).count() < CD(rhs).count(); Chris@16: } Chris@16: }; Chris@16: Chris@16: template Chris@16: struct duration_lt Chris@16: { Chris@16: BOOST_CONSTEXPR bool operator()(const LhsDuration& lhs, const LhsDuration& rhs) const Chris@16: { Chris@16: return lhs.count() < rhs.count(); Chris@16: } Chris@16: }; Chris@16: Chris@16: } // namespace detail Chris@16: Chris@16: // Duration == Chris@16: Chris@16: template Chris@16: inline BOOST_CONSTEXPR Chris@16: bool Chris@16: operator==(const duration& lhs, Chris@16: const duration& rhs) Chris@16: { Chris@16: return boost::chrono::detail::duration_eq< Chris@16: duration, duration >()(lhs, rhs); Chris@16: } Chris@16: Chris@16: // Duration != Chris@16: Chris@16: template Chris@16: inline BOOST_CONSTEXPR Chris@16: bool Chris@16: operator!=(const duration& lhs, Chris@16: const duration& rhs) Chris@16: { Chris@16: return !(lhs == rhs); Chris@16: } Chris@16: Chris@16: // Duration < Chris@16: Chris@16: template Chris@16: inline BOOST_CONSTEXPR Chris@16: bool Chris@16: operator< (const duration& lhs, Chris@16: const duration& rhs) Chris@16: { Chris@16: return boost::chrono::detail::duration_lt< Chris@16: duration, duration >()(lhs, rhs); Chris@16: } Chris@16: Chris@16: // Duration > Chris@16: Chris@16: template Chris@16: inline BOOST_CONSTEXPR Chris@16: bool Chris@16: operator> (const duration& lhs, Chris@16: const duration& rhs) Chris@16: { Chris@16: return rhs < lhs; Chris@16: } Chris@16: Chris@16: // Duration <= Chris@16: Chris@16: template Chris@16: inline BOOST_CONSTEXPR Chris@16: bool Chris@16: operator<=(const duration& lhs, Chris@16: const duration& rhs) Chris@16: { Chris@16: return !(rhs < lhs); Chris@16: } Chris@16: Chris@16: // Duration >= Chris@16: Chris@16: template Chris@16: inline BOOST_CONSTEXPR Chris@16: bool Chris@16: operator>=(const duration& lhs, Chris@16: const duration& rhs) Chris@16: { Chris@16: return !(lhs < rhs); Chris@16: } Chris@16: Chris@16: //----------------------------------------------------------------------------// Chris@16: // 20.9.3.7 duration_cast [time.duration.cast] // Chris@16: //----------------------------------------------------------------------------// Chris@16: Chris@16: // Compile-time select the most efficient algorithm for the conversion... Chris@16: template Chris@16: inline BOOST_CONSTEXPR Chris@16: typename boost::enable_if < Chris@16: boost::chrono::detail::is_duration, ToDuration>::type Chris@16: duration_cast(const duration& fd) Chris@16: { Chris@16: return boost::chrono::detail::duration_cast< Chris@16: duration, ToDuration>()(fd); Chris@16: } Chris@16: Chris@16: } // namespace chrono Chris@16: } // namespace boost Chris@16: Chris@16: #ifndef BOOST_CHRONO_HEADER_ONLY Chris@16: // the suffix header occurs after all of our code: Chris@16: #include // pops abi_prefix.hpp pragmas Chris@16: #endif Chris@16: Chris@16: #endif // BOOST_CHRONO_DURATION_HPP