123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799 |
- // duration.hpp --------------------------------------------------------------//
- // Copyright 2008 Howard Hinnant
- // Copyright 2008 Beman Dawes
- // Copyright 2009-2010 Vicente J. Botet Escriba
- // Distributed under the Boost Software License, Version 1.0.
- // See http://www.boost.org/LICENSE_1_0.txt
- /*
- This code was derived by Beman Dawes from Howard Hinnant's time2_demo prototype.
- Many thanks to Howard for making his code available under the Boost license.
- The original code was modified to conform to Boost conventions and to section
- 20.9 Time utilities [time] of the C++ committee's working paper N2798.
- See http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2798.pdf.
- time2_demo contained this comment:
- Much thanks to Andrei Alexandrescu,
- Walter Brown,
- Peter Dimov,
- Jeff Garland,
- Terry Golubiewski,
- Daniel Krugler,
- Anthony Williams.
- */
- #ifndef BOOST_EX_CHRONO_DURATION_HPP
- #define BOOST_EX_CHRONO_DURATION_HPP
- #include "config.hpp"
- #include "static_assert.hpp"
- //~ #include <iostream>
- #include <climits>
- #include <limits>
- #include <boost/mpl/logical.hpp>
- #include <boost/ratio/ratio.hpp>
- #include <boost/type_traits/common_type.hpp>
- #include <boost/type_traits/is_convertible.hpp>
- #include <boost/type_traits/is_floating_point.hpp>
- #include <boost/type_traits/is_unsigned.hpp>
- #include <boost/type_traits/is_arithmetic.hpp>
- #include <boost/cstdint.hpp>
- #if (defined(BOOST_MSVC) && (BOOST_MSVC == 1500)) || defined(__IBMCPP__)
- #else
- #include <boost/utility/enable_if.hpp>
- #endif
- #include <boost/detail/workaround.hpp>
- #include <boost/integer_traits.hpp>
- #if !defined(BOOST_NO_CXX11_STATIC_ASSERT) || !defined(BOOST_EX_CHRONO_USES_MPL_ASSERT)
- #define BOOST_EX_CHRONO_A_DURATION_REPRESENTATION_CAN_NOT_BE_A_DURATION "A duration representation can not be a duration"
- #define BOOST_EX_CHRONO_SECOND_TEMPLATE_PARAMETER_OF_DURATION_MUST_BE_A_STD_RATIO "Second template parameter of duration must be a boost::ratio"
- #define BOOST_EX_CHRONO_DURATION_PERIOD_MUST_BE_POSITIVE "duration period must be positive"
- #define BOOST_EX_CHRONO_SECOND_TEMPLATE_PARAMETER_OF_TIME_POINT_MUST_BE_A_BOOST_EX_CHRONO_DURATION "Second template parameter of time_point must be a boost_ex::chrono::duration"
- #endif
- //----------------------------------------------------------------------------//
- // //
- // 20.9 Time utilities [time] //
- // synopsis //
- // //
- //----------------------------------------------------------------------------//
- namespace boost_ex {
- using boost::ratio;
- namespace chrono {
- template <class Rep, class Period = ratio<1> >
- class duration;
- namespace detail
- {
- template <class T>
- struct is_duration
- : boost::false_type {};
- template <class Rep, class Period>
- struct is_duration<duration<Rep, Period> >
- : boost::true_type {};
- //template <class T>
- // struct is_duration
- // : is_duration<typename boost::remove_cv<T>::type> {};
- template <class Duration, class Rep, bool = is_duration<Rep>::value>
- struct duration_divide_result
- {
- };
- template <class Duration, class Rep2,
- bool = (
- (boost::is_convertible<typename Duration::rep,
- typename boost::common_type<typename Duration::rep, Rep2>::type>::value)
- && (boost::is_convertible<Rep2,
- typename boost::common_type<typename Duration::rep, Rep2>::type>::value)
- )
- >
- struct duration_divide_imp
- {
- };
- template <class Rep1, class Period, class Rep2>
- struct duration_divide_imp<duration<Rep1, Period>, Rep2, true>
- {
- typedef duration<typename boost::common_type<Rep1, Rep2>::type, Period> type;
- };
- template <class Rep1, class Period, class Rep2>
- struct duration_divide_result<duration<Rep1, Period>, Rep2, false>
- : duration_divide_imp<duration<Rep1, Period>, Rep2>
- {
- };
- ///
- template <class Rep, class Duration, bool = is_duration<Rep>::value>
- struct duration_divide_result2
- {
- };
- template <class Rep, class Duration,
- bool = (
- (boost::is_convertible<typename Duration::rep,
- typename boost::common_type<typename Duration::rep, Rep>::type>::value)
- && (boost::is_convertible<Rep,
- typename boost::common_type<typename Duration::rep, Rep>::type>::value)
- )
- >
- struct duration_divide_imp2
- {
- };
- template <class Rep1, class Rep2, class Period >
- struct duration_divide_imp2<Rep1, duration<Rep2, Period>, true>
- {
- //typedef typename boost::common_type<Rep1, Rep2>::type type;
- typedef double type;
- };
- template <class Rep1, class Rep2, class Period >
- struct duration_divide_result2<Rep1, duration<Rep2, Period>, false>
- : duration_divide_imp2<Rep1, duration<Rep2, Period> >
- {
- };
- ///
- template <class Duration, class Rep, bool = is_duration<Rep>::value>
- struct duration_modulo_result
- {
- };
- template <class Duration, class Rep2,
- bool = (
- //boost::is_convertible<typename Duration::rep,
- //typename boost::common_type<typename Duration::rep, Rep2>::type>::value
- //&&
- boost::is_convertible<Rep2,
- typename boost::common_type<typename Duration::rep, Rep2>::type>::value
- )
- >
- struct duration_modulo_imp
- {
- };
- template <class Rep1, class Period, class Rep2>
- struct duration_modulo_imp<duration<Rep1, Period>, Rep2, true>
- {
- typedef duration<typename boost::common_type<Rep1, Rep2>::type, Period> type;
- };
- template <class Rep1, class Period, class Rep2>
- struct duration_modulo_result<duration<Rep1, Period>, Rep2, false>
- : duration_modulo_imp<duration<Rep1, Period>, Rep2>
- {
- };
- } // namespace detail
- } // namespace chrono
- }
- namespace boost {
- // common_type trait specializations
- template <class Rep1, class Period1, class Rep2, class Period2>
- struct common_type<boost_ex::chrono::duration<Rep1, Period1>,
- boost_ex::chrono::duration<Rep2, Period2> >;
- }
- namespace boost_ex {
- namespace chrono {
- // customization traits
- template <class Rep> struct treat_as_floating_point;
- template <class Rep> struct duration_values;
- // duration arithmetic
- // template <class Rep1, class Period1, class Rep2, class Period2>
- // typename common_type<duration<Rep1, Period1>, duration<Rep2, Period2> >::type
- // operator+(const duration<Rep1, Period1>& lhs, const duration<Rep2, Period2>& rhs);
- // template <class Rep1, class Period1, class Rep2, class Period2>
- // typename common_type<duration<Rep1, Period1>, duration<Rep2, Period2> >::type
- // operator-(const duration<Rep1, Period1>& lhs, const duration<Rep2, Period2>& rhs);
- // template <class Rep1, class Period, class Rep2>
- // typename boost::enable_if_c
- // <
- // boost::is_convertible<Rep1, typename common_type<Rep1, Rep2>::type>::value
- // && boost::is_convertible<Rep2, typename common_type<Rep1, Rep2>::type>::value,
- // duration<typename common_type<Rep1, Rep2>::type, Period>
- // >::type
- // operator*(const duration<Rep1, Period>& d, const Rep2& s);
- // template <class Rep1, class Period, class Rep2>
- // typename boost::enable_if_c
- // <
- // boost::is_convertible<Rep1, typename common_type<Rep1, Rep2>::type>::value
- // && boost::is_convertible<Rep2, typename common_type<Rep1, Rep2>::type>::value,
- // duration<typename common_type<Rep1, Rep2>::type, Period>
- // >::type
- // operator*(const Rep1& s, const duration<Rep2, Period>& d);
- // template <class Rep1, class Period, class Rep2>
- // typename boost::disable_if <detail::is_duration<Rep2>,
- // typename detail::duration_divide_result<duration<Rep1, Period>, Rep2>::type
- // >::type
- // operator/(const duration<Rep1, Period>& d, const Rep2& s);
- // template <class Rep1, class Period1, class Rep2, class Period2>
- // typename common_type<Rep1, Rep2>::type
- // operator/(const duration<Rep1, Period1>& lhs, const duration<Rep2, Period2>& rhs);
- // duration comparisons
- // template <class Rep1, class Period1, class Rep2, class Period2>
- // bool operator==(const duration<Rep1, Period1>& lhs, const duration<Rep2, Period2>& rhs);
- // template <class Rep1, class Period1, class Rep2, class Period2>
- // bool operator!=(const duration<Rep1, Period1>& lhs, const duration<Rep2, Period2>& rhs);
- // template <class Rep1, class Period1, class Rep2, class Period2>
- // bool operator< (const duration<Rep1, Period1>& lhs, const duration<Rep2, Period2>& rhs);
- // template <class Rep1, class Period1, class Rep2, class Period2>
- // bool operator<=(const duration<Rep1, Period1>& lhs, const duration<Rep2, Period2>& rhs);
- // template <class Rep1, class Period1, class Rep2, class Period2>
- // bool operator> (const duration<Rep1, Period1>& lhs, const duration<Rep2, Period2>& rhs);
- // template <class Rep1, class Period1, class Rep2, class Period2>
- // bool operator>=(const duration<Rep1, Period1>& lhs, const duration<Rep2, Period2>& rhs);
- // duration_cast
- //template <class ToDuration, class Rep, class Period>
- // ToDuration duration_cast(const duration<Rep, Period>& d);
- // convenience typedefs
- typedef duration<boost::int_least64_t, boost::nano> nanoseconds; // at least 64 bits needed
- typedef duration<boost::int_least64_t, boost::micro> microseconds; // at least 55 bits needed
- typedef duration<boost::int_least64_t, boost::milli> milliseconds; // at least 45 bits needed
- typedef duration<boost::int_least64_t> seconds; // at least 35 bits needed
- typedef duration<boost::int_least32_t, ratio< 60> > minutes; // at least 29 bits needed
- typedef duration<boost::int_least32_t, ratio<3600> > hours; // at least 23 bits needed
- //----------------------------------------------------------------------------//
- // duration helpers //
- //----------------------------------------------------------------------------//
- namespace detail
- {
- // duration_cast
- // duration_cast is the heart of this whole prototype. It can convert any
- // duration to any other. It is also (implicitly) used in converting
- // time_points. The conversion is always exact if possible. And it is
- // always as efficient as hand written code. If different representations
- // are involved, care is taken to never require implicit conversions.
- // Instead static_cast is used explicitly for every required conversion.
- // If there are a mixture of integral and floating point representations,
- // the use of common_type ensures that the most logical "intermediate"
- // representation is used.
- template <class FromDuration, class ToDuration,
- class Period = typename boost::ratio_divide<typename FromDuration::period,
- typename ToDuration::period>::type,
- bool = Period::num == 1,
- bool = Period::den == 1>
- struct duration_cast;
- // When the two periods are the same, all that is left to do is static_cast from
- // the source representation to the target representation (which may be a no-op).
- // This conversion is always exact as long as the static_cast from the source
- // representation to the destination representation is exact.
- template <class FromDuration, class ToDuration, class Period>
- struct duration_cast<FromDuration, ToDuration, Period, true, true>
- {
- ToDuration operator()(const FromDuration& fd) const
- {
- return ToDuration(static_cast<typename ToDuration::rep>(fd.count()));
- }
- };
- // When the numerator of FromPeriod / ToPeriod is 1, then all we need to do is
- // divide by the denominator of FromPeriod / ToPeriod. The common_type of
- // the two representations is used for the intermediate computation before
- // static_cast'ing to the destination.
- // This conversion is generally not exact because of the division (but could be
- // if you get lucky on the run time value of fd.count()).
- template <class FromDuration, class ToDuration, class Period>
- struct duration_cast<FromDuration, ToDuration, Period, true, false>
- {
- ToDuration operator()(const FromDuration& fd) const
- {
- typedef typename boost::common_type<
- typename ToDuration::rep,
- typename FromDuration::rep,
- boost::intmax_t>::type C;
- return ToDuration(static_cast<typename ToDuration::rep>(
- static_cast<C>(fd.count()) / static_cast<C>(Period::den)));
- }
- };
- // When the denomenator of FromPeriod / ToPeriod is 1, then all we need to do is
- // multiply by the numerator of FromPeriod / ToPeriod. The common_type of
- // the two representations is used for the intermediate computation before
- // static_cast'ing to the destination.
- // This conversion is always exact as long as the static_cast's involved are exact.
- template <class FromDuration, class ToDuration, class Period>
- struct duration_cast<FromDuration, ToDuration, Period, false, true>
- {
- ToDuration operator()(const FromDuration& fd) const
- {
- typedef typename boost::common_type<
- typename ToDuration::rep,
- typename FromDuration::rep,
- boost::intmax_t>::type C;
- return ToDuration(static_cast<typename ToDuration::rep>(
- static_cast<C>(fd.count()) * static_cast<C>(Period::num)));
- }
- };
- // When neither the numerator or denominator of FromPeriod / ToPeriod is 1, then we need to
- // multiply by the numerator and divide by the denominator of FromPeriod / ToPeriod. The
- // common_type of the two representations is used for the intermediate computation before
- // static_cast'ing to the destination.
- // This conversion is generally not exact because of the division (but could be
- // if you get lucky on the run time value of fd.count()).
- template <class FromDuration, class ToDuration, class Period>
- struct duration_cast<FromDuration, ToDuration, Period, false, false>
- {
- ToDuration operator()(const FromDuration& fd) const
- {
- typedef typename boost::common_type<
- typename ToDuration::rep,
- typename FromDuration::rep,
- boost::intmax_t>::type C;
- return ToDuration(static_cast<typename ToDuration::rep>(
- static_cast<C>(fd.count()) * static_cast<C>(Period::num)
- / static_cast<C>(Period::den)));
- }
- };
- } // namespace detail
- //----------------------------------------------------------------------------//
- // //
- // 20.9.2 Time-related traits [time.traits] //
- // //
- //----------------------------------------------------------------------------//
- //----------------------------------------------------------------------------//
- // 20.9.2.1 treat_as_floating_point [time.traits.is_fp] //
- // Probably should have been treat_as_floating_point. Editor notifed. //
- //----------------------------------------------------------------------------//
- // Support bidirectional (non-exact) conversions for floating point rep types
- // (or user defined rep types which specialize treat_as_floating_point).
- template <class Rep>
- struct treat_as_floating_point : boost::is_floating_point<Rep> {};
- //----------------------------------------------------------------------------//
- // 20.9.2.2 duration_values [time.traits.duration_values] //
- //----------------------------------------------------------------------------//
- namespace detail {
- template <class T, bool = boost::is_arithmetic<T>::value>
- struct chrono_numeric_limits {
- static T lowest() throw() {return (std::numeric_limits<T>::min) ();}
- };
- template <class T>
- struct chrono_numeric_limits<T,true> {
- static T lowest() throw() {return (std::numeric_limits<T>::min) ();}
- };
- template <>
- struct chrono_numeric_limits<float,true> {
- static float lowest() throw() {return -(std::numeric_limits<float>::max) ();}
- };
- template <>
- struct chrono_numeric_limits<double,true> {
- static double lowest() throw() {return -(std::numeric_limits<double>::max) ();}
- };
- template <>
- struct chrono_numeric_limits<long double,true> {
- static long double lowest() throw() {return -(std::numeric_limits<long double>::max)();}
- };
- template <class T>
- struct numeric_limits : chrono_numeric_limits<typename boost::remove_cv<T>::type> {};
- }
- template <class Rep>
- struct duration_values
- {
- static Rep zero() {return Rep(0);}
- static Rep max BOOST_PREVENT_MACRO_SUBSTITUTION () {return (std::numeric_limits<Rep>::max)();}
- static Rep min BOOST_PREVENT_MACRO_SUBSTITUTION () {return detail::numeric_limits<Rep>::lowest();}
- };
- } // namespace chrono
- }
- //----------------------------------------------------------------------------//
- // 20.9.2.3 Specializations of common_type [time.traits.specializations] //
- //----------------------------------------------------------------------------//
- namespace boost {
- template <class Rep1, class Period1, class Rep2, class Period2>
- struct common_type<boost_ex::chrono::duration<Rep1, Period1>,
- boost_ex::chrono::duration<Rep2, Period2> >
- {
- typedef boost_ex::chrono::duration<typename common_type<Rep1, Rep2>::type,
- typename boost::ratio_gcd<Period1, Period2>::type> type;
- };
- }
- //----------------------------------------------------------------------------//
- // //
- // 20.9.3 Class template duration [time.duration] //
- // //
- //----------------------------------------------------------------------------//
- namespace boost_ex {
- namespace chrono {
- template <class Rep, class Period>
- class duration
- {
- BOOST_EX_CHRONO_STATIC_ASSERT(!boost_ex::chrono::detail::is_duration<Rep>::value, BOOST_EX_CHRONO_A_DURATION_REPRESENTATION_CAN_NOT_BE_A_DURATION, ());
- BOOST_EX_CHRONO_STATIC_ASSERT(boost::ratio_detail::is_ratio<Period>::value, BOOST_EX_CHRONO_SECOND_TEMPLATE_PARAMETER_OF_DURATION_MUST_BE_A_STD_RATIO, ());
- BOOST_EX_CHRONO_STATIC_ASSERT(Period::num>0, BOOST_EX_CHRONO_DURATION_PERIOD_MUST_BE_POSITIVE, ());
- public:
- typedef Rep rep;
- typedef Period period;
- private:
- rep rep_;
- public:
- duration() { } // = default;
- template <class Rep2>
- explicit duration(const Rep2& r
- #if (defined(BOOST_MSVC) && (BOOST_MSVC == 1500)) || defined(__IBMCPP__)
- #else
- , typename boost::enable_if <
- boost::mpl::and_ <
- boost::is_convertible<Rep2, rep>,
- boost::mpl::or_ <
- treat_as_floating_point<rep>,
- boost::mpl::and_ <
- boost::mpl::not_ < treat_as_floating_point<rep> >,
- boost::mpl::not_ < treat_as_floating_point<Rep2> >
- >
- >
- >
- >::type* = 0
- #endif
- )
- : rep_(r) { }
- ~duration() {} //= default;
- duration(const duration& rhs) : rep_(rhs.rep_) {} // = default;
- duration& operator=(const duration& rhs) // = default;
- {
- if (&rhs != this) rep_= rhs.rep_;
- return *this;
- }
- // conversions
- template <class Rep2, class Period2>
- duration(const duration<Rep2, Period2>& d
- #if (defined(BOOST_MSVC) && (BOOST_MSVC == 1500)) || defined(__IBMCPP__)
- #else
- , typename boost::enable_if <
- boost::mpl::or_ <
- treat_as_floating_point<rep>,
- boost::mpl::and_ <
- boost::mpl::bool_ < boost::ratio_divide<Period2, period>::type::den == 1>,
- boost::mpl::not_ < treat_as_floating_point<Rep2> >
- >
- >
- >::type* = 0
- #endif
- )
- //~ #ifdef __GNUC__
- // GCC 4.2.4 refused to accept a definition at this point,
- // yet both VC++ 9.0 SP1 and Intel ia32 11.0 accepted the definition
- // without complaint. VC++ 9.0 SP1 refused to accept a later definition,
- // although that was fine with GCC 4.2.4 and Intel ia32 11.0. Thus we
- // have to support both approaches.
- //~ ;
- //~ #else
- //~ : rep_(chrono::duration_cast<duration>(d).count()) {}
- : rep_(chrono::detail::duration_cast<duration<Rep2, Period2>, duration>()(d).count()) {}
- //~ #endif
- // observer
- rep count() const {return rep_;}
- // arithmetic
- duration operator+() const {return *this;}
- duration operator-() const {return duration(-rep_);}
- duration& operator++() {++rep_; return *this;}
- duration operator++(int) {return duration(rep_++);}
- duration& operator--() {--rep_; return *this;}
- duration operator--(int) {return duration(rep_--);}
- duration& operator+=(const duration& d) {rep_ += d.count(); return *this;}
- duration& operator-=(const duration& d) {rep_ -= d.count(); return *this;}
- duration& operator*=(const rep& rhs) {rep_ *= rhs; return *this;}
- duration& operator/=(const rep& rhs) {rep_ /= rhs; return *this;}
- duration& operator%=(const rep& rhs) {rep_ %= rhs; return *this;}
- duration& operator%=(const duration& rhs) {rep_ %= rhs.count(); return *this;};
- // 20.9.3.4 duration special values [time.duration.special]
- static duration zero() {return duration(duration_values<rep>::zero());}
- static duration min BOOST_PREVENT_MACRO_SUBSTITUTION () {return duration((duration_values<rep>::min)());}
- static duration max BOOST_PREVENT_MACRO_SUBSTITUTION () {return duration((duration_values<rep>::max)());}
- };
- //----------------------------------------------------------------------------//
- // 20.9.3.5 duration non-member arithmetic [time.duration.nonmember] //
- //----------------------------------------------------------------------------//
- // Duration +
- template <class Rep1, class Period1, class Rep2, class Period2>
- inline
- typename boost::common_type<duration<Rep1, Period1>, duration<Rep2, Period2> >::type
- operator+(const duration<Rep1, Period1>& lhs, const duration<Rep2, Period2>& rhs)
- {
- typename boost::common_type<duration<Rep1, Period1>,
- duration<Rep2, Period2> >::type result = lhs;
- result += rhs;
- return result;
- }
- // Duration -
- template <class Rep1, class Period1, class Rep2, class Period2>
- inline
- typename boost::common_type<duration<Rep1, Period1>, duration<Rep2, Period2> >::type
- operator-(const duration<Rep1, Period1>& lhs, const duration<Rep2, Period2>& rhs)
- {
- typename boost::common_type<duration<Rep1, Period1>,
- duration<Rep2, Period2> >::type result = lhs;
- result -= rhs;
- return result;
- }
- // Duration *
- template <class Rep1, class Period, class Rep2>
- inline
- #if (defined(BOOST_MSVC) && (BOOST_MSVC == 1500)) || defined(__IBMCPP__)
- duration<typename boost::common_type<Rep1, Rep2>::type, Period>
- #else
- typename boost::enable_if <
- boost::mpl::and_ <
- boost::is_convertible<Rep1, typename boost::common_type<Rep1, Rep2>::type>,
- boost::is_convertible<Rep2, typename boost::common_type<Rep1, Rep2>::type>
- >,
- duration<typename boost::common_type<Rep1, Rep2>::type, Period>
- >::type
- #endif
- operator*(const duration<Rep1, Period>& d, const Rep2& s)
- {
- typedef typename boost::common_type<Rep1, Rep2>::type CR;
- duration<CR, Period> r = d;
- r *= static_cast<CR>(s);
- return r;
- }
- template <class Rep1, class Period, class Rep2>
- inline
- #if (defined(BOOST_MSVC) && (BOOST_MSVC == 1500)) || defined(__IBMCPP__)
- duration<typename boost::common_type<Rep1, Rep2>::type, Period>
- #else
- typename boost::enable_if <
- boost::mpl::and_ <
- boost::is_convertible<Rep1, typename boost::common_type<Rep1, Rep2>::type>,
- boost::is_convertible<Rep2, typename boost::common_type<Rep1, Rep2>::type>
- >,
- duration<typename boost::common_type<Rep1, Rep2>::type, Period>
- >::type
- #endif
- operator*(const Rep1& s, const duration<Rep2, Period>& d)
- {
- return d * s;
- }
- // Duration /
- template <class Rep1, class Period, class Rep2>
- inline
- typename boost::disable_if <boost_ex::chrono::detail::is_duration<Rep2>,
- typename boost_ex::chrono::detail::duration_divide_result<duration<Rep1, Period>, Rep2>::type
- >::type
- operator/(const duration<Rep1, Period>& d, const Rep2& s)
- {
- typedef typename boost::common_type<Rep1, Rep2>::type CR;
- duration<CR, Period> r = d;
- r /= static_cast<CR>(s);
- return r;
- }
- template <class Rep1, class Period1, class Rep2, class Period2>
- inline
- typename boost::common_type<Rep1, Rep2>::type
- operator/(const duration<Rep1, Period1>& lhs, const duration<Rep2, Period2>& rhs)
- {
- typedef typename boost::common_type<duration<Rep1, Period1>,
- duration<Rep2, Period2> >::type CD;
- return CD(lhs).count() / CD(rhs).count();
- }
- template <class Rep1, class Rep2, class Period>
- inline
- typename boost::disable_if <boost_ex::chrono::detail::is_duration<Rep1>,
- typename boost_ex::chrono::detail::duration_divide_result2<Rep1, duration<Rep2, Period> >::type
- >::type
- operator/(const Rep1& s, const duration<Rep2, Period>& d)
- {
- typedef typename boost::common_type<Rep1, Rep2>::type CR;
- duration<CR, Period> r = d;
- //return static_cast<CR>(r.count()) / static_cast<CR>(s);
- return static_cast<CR>(s)/r.count();
- }
- // Duration %
- template <class Rep1, class Period, class Rep2>
- typename boost::disable_if <boost_ex::chrono::detail::is_duration<Rep2>,
- typename boost_ex::chrono::detail::duration_modulo_result<duration<Rep1, Period>, Rep2>::type
- >::type
- operator%(const duration<Rep1, Period>& d, const Rep2& s) {
- typedef typename boost::common_type<Rep1, Rep2>::type CR;
- duration<CR, Period> r = d;
- r %= static_cast<CR>(s);
- return r;
- }
- template <class Rep1, class Period1, class Rep2, class Period2>
- typename boost::common_type<duration<Rep1, Period1>, duration<Rep2, Period2> >::type
- operator%(const duration<Rep1, Period1>& lhs, const duration<Rep2, Period2>& rhs) {
- typedef typename boost::common_type<duration<Rep1, Period1>,
- duration<Rep2, Period2> >::type CD;
- CD r(lhs);
- r%=CD(rhs);
- return r;
- }
- //----------------------------------------------------------------------------//
- // 20.9.3.6 duration comparisons [time.duration.comparisons] //
- //----------------------------------------------------------------------------//
- namespace detail
- {
- template <class LhsDuration, class RhsDuration>
- struct duration_eq
- {
- bool operator()(const LhsDuration& lhs, const RhsDuration& rhs)
- {
- typedef typename boost::common_type<LhsDuration, RhsDuration>::type CD;
- return CD(lhs).count() == CD(rhs).count();
- }
- };
- template <class LhsDuration>
- struct duration_eq<LhsDuration, LhsDuration>
- {
- bool operator()(const LhsDuration& lhs, const LhsDuration& rhs)
- {return lhs.count() == rhs.count();}
- };
- template <class LhsDuration, class RhsDuration>
- struct duration_lt
- {
- bool operator()(const LhsDuration& lhs, const RhsDuration& rhs)
- {
- typedef typename boost::common_type<LhsDuration, RhsDuration>::type CD;
- return CD(lhs).count() < CD(rhs).count();
- }
- };
- template <class LhsDuration>
- struct duration_lt<LhsDuration, LhsDuration>
- {
- bool operator()(const LhsDuration& lhs, const LhsDuration& rhs)
- {return lhs.count() < rhs.count();}
- };
- } // namespace detail
- // Duration ==
- template <class Rep1, class Period1, class Rep2, class Period2>
- inline
- bool
- operator==(const duration<Rep1, Period1>& lhs, const duration<Rep2, Period2>& rhs)
- {
- return boost_ex::chrono::detail::duration_eq<duration<Rep1, Period1>, duration<Rep2, Period2> >()(lhs, rhs);
- }
- // Duration !=
- template <class Rep1, class Period1, class Rep2, class Period2>
- inline
- bool
- operator!=(const duration<Rep1, Period1>& lhs, const duration<Rep2, Period2>& rhs)
- {
- return !(lhs == rhs);
- }
- // Duration <
- template <class Rep1, class Period1, class Rep2, class Period2>
- inline
- bool
- operator< (const duration<Rep1, Period1>& lhs, const duration<Rep2, Period2>& rhs)
- {
- return boost_ex::chrono::detail::duration_lt<duration<Rep1, Period1>, duration<Rep2, Period2> >()(lhs, rhs);
- }
- // Duration >
- template <class Rep1, class Period1, class Rep2, class Period2>
- inline
- bool
- operator> (const duration<Rep1, Period1>& lhs, const duration<Rep2, Period2>& rhs)
- {
- return rhs < lhs;
- }
- // Duration <=
- template <class Rep1, class Period1, class Rep2, class Period2>
- inline
- bool
- operator<=(const duration<Rep1, Period1>& lhs, const duration<Rep2, Period2>& rhs)
- {
- return !(rhs < lhs);
- }
- // Duration >=
- template <class Rep1, class Period1, class Rep2, class Period2>
- inline
- bool
- operator>=(const duration<Rep1, Period1>& lhs, const duration<Rep2, Period2>& rhs)
- {
- return !(lhs < rhs);
- }
- //----------------------------------------------------------------------------//
- // 20.9.3.7 duration_cast [time.duration.cast] //
- //----------------------------------------------------------------------------//
- // Compile-time select the most efficient algorithm for the conversion...
- template <class ToDuration, class Rep, class Period>
- inline
- #if (defined(BOOST_MSVC) && (BOOST_MSVC == 1500)) || defined(__IBMCPP__)
- ToDuration
- #else
- typename boost::enable_if <boost_ex::chrono::detail::is_duration<ToDuration>, ToDuration>::type
- #endif
- duration_cast(const duration<Rep, Period>& fd)
- {
- return boost_ex::chrono::detail::duration_cast<duration<Rep, Period>, ToDuration>()(fd);
- }
- }
- }
- #endif // BOOST_EX_CHRONO_DURATION_HPP
|