You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and dots ('.'), can be up to 35 characters long. Letters must be lowercase.
786 lines
28 KiB
786 lines
28 KiB
// duration.hpp --------------------------------------------------------------// |
|
|
|
// Copyright 2008 Howard Hinnant |
|
// Copyright 2008 Beman Dawes |
|
// Copyright 2009-2011 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_CHRONO_DURATION_HPP |
|
#define BOOST_CHRONO_DURATION_HPP |
|
|
|
#include <boost/chrono/config.hpp> |
|
#include <boost/chrono/detail/static_assert.hpp> |
|
|
|
#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_arithmetic.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/chrono/detail/is_evenly_divisible_by.hpp> |
|
|
|
#include <boost/cstdint.hpp> |
|
#include <boost/utility/enable_if.hpp> |
|
#include <boost/detail/workaround.hpp> |
|
#include <boost/integer_traits.hpp> |
|
|
|
#if !defined(BOOST_NO_STATIC_ASSERT) || !defined(BOOST_CHRONO_USES_MPL_ASSERT) |
|
#define BOOST_CHRONO_A_DURATION_REPRESENTATION_CAN_NOT_BE_A_DURATION "A duration representation can not be a duration" |
|
#define BOOST_CHRONO_SECOND_TEMPLATE_PARAMETER_OF_DURATION_MUST_BE_A_STD_RATIO "Second template parameter of duration must be a boost::ratio" |
|
#define BOOST_CHRONO_DURATION_PERIOD_MUST_BE_POSITIVE "duration period must be positive" |
|
#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" |
|
#endif |
|
|
|
|
|
//----------------------------------------------------------------------------// |
|
// // |
|
// 20.9 Time utilities [time] // |
|
// synopsis // |
|
// // |
|
//----------------------------------------------------------------------------// |
|
|
|
namespace boost { |
|
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 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 common_type<typename Duration::rep, Rep2>::type>::value)) |
|
&& ((boost::is_convertible<Rep2, |
|
typename 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 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 common_type<typename Duration::rep, Rep>::type>::value)) |
|
&& ((boost::is_convertible<Rep, |
|
typename 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 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 common_type<typename Duration::rep, Rep2>::type>::value |
|
//&& |
|
boost::is_convertible<Rep2, |
|
typename 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 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 |
|
|
|
|
|
// common_type trait specializations |
|
|
|
template <class Rep1, class Period1, class Rep2, class Period2> |
|
struct common_type<chrono::duration<Rep1, Period1>, |
|
chrono::duration<Rep2, Period2> >; |
|
|
|
|
|
namespace chrono { |
|
|
|
// customization traits |
|
template <class Rep> struct treat_as_floating_point; |
|
template <class Rep> struct duration_values; |
|
|
|
// convenience typedefs |
|
typedef duration<boost::int_least64_t, nano> nanoseconds; // at least 64 bits needed |
|
typedef duration<boost::int_least64_t, micro> microseconds; // at least 55 bits needed |
|
typedef duration<boost::int_least64_t, 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, |
|
bool PeriodNumEq1, |
|
bool PeriodDenEq1> |
|
struct duration_cast_aux; |
|
|
|
// 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_aux<FromDuration, ToDuration, Period, true, true> |
|
{ |
|
BOOST_CHRONO_CONSTEXPR 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_aux<FromDuration, ToDuration, Period, true, false> |
|
{ |
|
BOOST_CHRONO_CONSTEXPR ToDuration operator()(const FromDuration& fd) const |
|
{ |
|
typedef typename 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 denominator 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_aux<FromDuration, ToDuration, Period, false, true> |
|
{ |
|
BOOST_CHRONO_CONSTEXPR ToDuration operator()(const FromDuration& fd) const |
|
{ |
|
typedef typename 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_aux<FromDuration, ToDuration, Period, false, false> |
|
{ |
|
BOOST_CHRONO_CONSTEXPR ToDuration operator()(const FromDuration& fd) const |
|
{ |
|
typedef typename 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))); |
|
} |
|
}; |
|
|
|
template <class FromDuration, class ToDuration> |
|
struct duration_cast { |
|
typedef typename ratio_divide<typename FromDuration::period, |
|
typename ToDuration::period>::type Period; |
|
typedef duration_cast_aux< |
|
FromDuration, |
|
ToDuration, |
|
Period, |
|
Period::num == 1, |
|
Period::den == 1 |
|
> Aux; |
|
BOOST_CHRONO_CONSTEXPR ToDuration operator()(const FromDuration& fd) const |
|
{ |
|
return Aux()(fd); |
|
} |
|
}; |
|
|
|
} // 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 = 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 remove_cv<T>::type> |
|
{}; |
|
|
|
} |
|
template <class Rep> |
|
struct duration_values |
|
{ |
|
static BOOST_CHRONO_CONSTEXPR Rep zero() {return Rep(0);} |
|
static BOOST_CHRONO_CONSTEXPR Rep max BOOST_PREVENT_MACRO_SUBSTITUTION () |
|
{ |
|
return (std::numeric_limits<Rep>::max)(); |
|
} |
|
|
|
static BOOST_CHRONO_CONSTEXPR 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] // |
|
//----------------------------------------------------------------------------// |
|
|
|
template <class Rep1, class Period1, class Rep2, class Period2> |
|
struct common_type<chrono::duration<Rep1, Period1>, |
|
chrono::duration<Rep2, Period2> > |
|
{ |
|
typedef 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 chrono { |
|
|
|
template <class Rep, class Period> |
|
class duration |
|
{ |
|
//BOOST_CHRONO_STATIC_ASSERT(boost::is_integral<Rep>::value, BOOST_CHRONO_A_DURATION_REPRESENTATION_MUST_BE_INTEGRAL, ()); |
|
BOOST_CHRONO_STATIC_ASSERT(!boost::chrono::detail::is_duration<Rep>::value, |
|
BOOST_CHRONO_A_DURATION_REPRESENTATION_CAN_NOT_BE_A_DURATION, ()); |
|
BOOST_CHRONO_STATIC_ASSERT(boost::ratio_detail::is_ratio<typename Period::type>::value, |
|
BOOST_CHRONO_SECOND_TEMPLATE_PARAMETER_OF_DURATION_MUST_BE_A_STD_RATIO, ()); |
|
BOOST_CHRONO_STATIC_ASSERT(Period::num>0, |
|
BOOST_CHRONO_DURATION_PERIOD_MUST_BE_POSITIVE, ()); |
|
public: |
|
typedef Rep rep; |
|
typedef Period period; |
|
private: |
|
rep rep_; |
|
public: |
|
|
|
BOOST_CHRONO_CONSTEXPR |
|
duration() : rep_(duration_values<rep>::zero()) { } |
|
template <class Rep2> |
|
BOOST_CHRONO_CONSTEXPR |
|
explicit duration(const Rep2& r |
|
, typename boost::enable_if < |
|
mpl::and_ < |
|
boost::is_convertible<Rep2, rep>, |
|
mpl::or_ < |
|
treat_as_floating_point<rep>, |
|
mpl::and_ < |
|
mpl::not_ < treat_as_floating_point<rep> >, |
|
mpl::not_ < treat_as_floating_point<Rep2> > |
|
> |
|
> |
|
> |
|
>::type* = 0 |
|
) : rep_(r) { } |
|
~duration() {} //= default; |
|
BOOST_CHRONO_CONSTEXPR |
|
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> |
|
BOOST_CHRONO_CONSTEXPR |
|
duration(const duration<Rep2, Period2>& d |
|
, typename boost::enable_if < |
|
mpl::or_ < |
|
treat_as_floating_point<rep>, |
|
mpl::and_ < |
|
chrono_detail::is_evenly_divisible_by<Period2, period>, |
|
mpl::not_ < treat_as_floating_point<Rep2> > |
|
> |
|
> |
|
>::type* = 0 |
|
) |
|
: rep_(chrono::detail::duration_cast<duration<Rep2, Period2>, duration>()(d).count()) {} |
|
|
|
// observer |
|
|
|
BOOST_CHRONO_CONSTEXPR |
|
rep count() const {return rep_;} |
|
|
|
// arithmetic |
|
|
|
BOOST_CHRONO_CONSTEXPR |
|
duration operator+() const {return *this;} |
|
BOOST_CHRONO_CONSTEXPR |
|
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 BOOST_CHRONO_CONSTEXPR duration zero() |
|
{ |
|
return duration(duration_values<rep>::zero()); |
|
} |
|
static BOOST_CHRONO_CONSTEXPR duration min BOOST_PREVENT_MACRO_SUBSTITUTION () |
|
{ |
|
return duration((duration_values<rep>::min)()); |
|
} |
|
static BOOST_CHRONO_CONSTEXPR 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 BOOST_CHRONO_CONSTEXPR |
|
typename common_type<duration<Rep1, Period1>, duration<Rep2, Period2> >::type |
|
operator+(const duration<Rep1, Period1>& lhs, |
|
const duration<Rep2, Period2>& rhs) |
|
{ |
|
typedef typename common_type<duration<Rep1, Period1>, |
|
duration<Rep2, Period2> >::type CD; |
|
return CD(CD(lhs).count()+CD(rhs).count()); |
|
} |
|
|
|
// Duration - |
|
|
|
template <class Rep1, class Period1, class Rep2, class Period2> |
|
inline BOOST_CHRONO_CONSTEXPR |
|
typename common_type<duration<Rep1, Period1>, duration<Rep2, Period2> >::type |
|
operator-(const duration<Rep1, Period1>& lhs, |
|
const duration<Rep2, Period2>& rhs) |
|
{ |
|
typedef typename common_type<duration<Rep1, Period1>, |
|
duration<Rep2, Period2> >::type CD; |
|
return CD(CD(lhs).count()-CD(rhs).count()); |
|
} |
|
|
|
// Duration * |
|
|
|
template <class Rep1, class Period, class Rep2> |
|
inline BOOST_CHRONO_CONSTEXPR |
|
typename boost::enable_if < |
|
mpl::and_ < |
|
boost::is_convertible<Rep1, typename common_type<Rep1, Rep2>::type>, |
|
boost::is_convertible<Rep2, typename common_type<Rep1, Rep2>::type> |
|
>, |
|
duration<typename common_type<Rep1, Rep2>::type, Period> |
|
>::type |
|
operator*(const duration<Rep1, Period>& d, const Rep2& s) |
|
{ |
|
typedef typename common_type<Rep1, Rep2>::type CR; |
|
typedef duration<CR, Period> CD; |
|
return CD(CD(d).count()*static_cast<CR>(s)); |
|
} |
|
|
|
template <class Rep1, class Period, class Rep2> |
|
inline BOOST_CHRONO_CONSTEXPR |
|
typename boost::enable_if < |
|
mpl::and_ < |
|
boost::is_convertible<Rep1, typename common_type<Rep1, Rep2>::type>, |
|
boost::is_convertible<Rep2, typename common_type<Rep1, Rep2>::type> |
|
>, |
|
duration<typename common_type<Rep1, Rep2>::type, Period> |
|
>::type |
|
operator*(const Rep1& s, const duration<Rep2, Period>& d) |
|
{ |
|
return d * s; |
|
} |
|
|
|
// Duration / |
|
|
|
template <class Rep1, class Period, class Rep2> |
|
inline BOOST_CHRONO_CONSTEXPR |
|
typename boost::disable_if <boost::chrono::detail::is_duration<Rep2>, |
|
typename boost::chrono::detail::duration_divide_result< |
|
duration<Rep1, Period>, Rep2>::type |
|
>::type |
|
operator/(const duration<Rep1, Period>& d, const Rep2& s) |
|
{ |
|
typedef typename common_type<Rep1, Rep2>::type CR; |
|
typedef duration<CR, Period> CD; |
|
|
|
return CD(CD(d).count()/static_cast<CR>(s)); |
|
} |
|
|
|
template <class Rep1, class Period1, class Rep2, class Period2> |
|
inline BOOST_CHRONO_CONSTEXPR |
|
typename common_type<Rep1, Rep2>::type |
|
operator/(const duration<Rep1, Period1>& lhs, const duration<Rep2, Period2>& rhs) |
|
{ |
|
typedef typename common_type<duration<Rep1, Period1>, |
|
duration<Rep2, Period2> >::type CD; |
|
return CD(lhs).count() / CD(rhs).count(); |
|
} |
|
|
|
#ifdef BOOST_CHRONO_EXTENSIONS |
|
template <class Rep1, class Rep2, class Period> |
|
inline BOOST_CHRONO_CONSTEXPR |
|
typename boost::disable_if <boost::chrono::detail::is_duration<Rep1>, |
|
typename boost::chrono::detail::duration_divide_result2< |
|
Rep1, duration<Rep2, Period> >::type |
|
>::type |
|
operator/(const Rep1& s, const duration<Rep2, Period>& d) |
|
{ |
|
typedef typename common_type<Rep1, Rep2>::type CR; |
|
typedef duration<CR, Period> CD; |
|
|
|
return static_cast<CR>(s)/CD(d).count(); |
|
} |
|
#endif |
|
// Duration % |
|
|
|
template <class Rep1, class Period, class Rep2> |
|
inline BOOST_CHRONO_CONSTEXPR |
|
typename boost::disable_if <boost::chrono::detail::is_duration<Rep2>, |
|
typename boost::chrono::detail::duration_modulo_result< |
|
duration<Rep1, Period>, Rep2>::type |
|
>::type |
|
operator%(const duration<Rep1, Period>& d, const Rep2& s) |
|
{ |
|
typedef typename common_type<Rep1, Rep2>::type CR; |
|
typedef duration<CR, Period> CD; |
|
|
|
return CD(CD(d).count()%static_cast<CR>(s)); |
|
} |
|
|
|
template <class Rep1, class Period1, class Rep2, class Period2> |
|
inline BOOST_CHRONO_CONSTEXPR |
|
typename common_type<duration<Rep1, Period1>, duration<Rep2, Period2> >::type |
|
operator%(const duration<Rep1, Period1>& lhs, |
|
const duration<Rep2, Period2>& rhs) { |
|
typedef typename common_type<duration<Rep1, Period1>, |
|
duration<Rep2, Period2> >::type CD; |
|
|
|
return CD(CD(lhs).count()%CD(rhs).count()); |
|
} |
|
|
|
|
|
//----------------------------------------------------------------------------// |
|
// 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 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 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 BOOST_CHRONO_CONSTEXPR |
|
bool |
|
operator==(const duration<Rep1, Period1>& lhs, |
|
const duration<Rep2, Period2>& rhs) |
|
{ |
|
return boost::chrono::detail::duration_eq< |
|
duration<Rep1, Period1>, duration<Rep2, Period2> >()(lhs, rhs); |
|
} |
|
|
|
// Duration != |
|
|
|
template <class Rep1, class Period1, class Rep2, class Period2> |
|
inline BOOST_CHRONO_CONSTEXPR |
|
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 BOOST_CHRONO_CONSTEXPR |
|
bool |
|
operator< (const duration<Rep1, Period1>& lhs, |
|
const duration<Rep2, Period2>& rhs) |
|
{ |
|
return boost::chrono::detail::duration_lt< |
|
duration<Rep1, Period1>, duration<Rep2, Period2> >()(lhs, rhs); |
|
} |
|
|
|
// Duration > |
|
|
|
template <class Rep1, class Period1, class Rep2, class Period2> |
|
inline BOOST_CHRONO_CONSTEXPR |
|
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 BOOST_CHRONO_CONSTEXPR |
|
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 BOOST_CHRONO_CONSTEXPR |
|
typename boost::enable_if < |
|
boost::chrono::detail::is_duration<ToDuration>, ToDuration>::type |
|
duration_cast(const duration<Rep, Period>& fd) |
|
{ |
|
return boost::chrono::detail::duration_cast< |
|
duration<Rep, Period>, ToDuration>()(fd); |
|
} |
|
|
|
} // namespace chrono |
|
} // namespace boost |
|
|
|
#endif // BOOST_CHRONO_DURATION_HPP
|
|
|