2012-07-21 14:37:40 -04:00
// 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>
2013-01-13 17:38:19 -05:00
# if !defined(BOOST_NO_CXX11_STATIC_ASSERT) || !defined(BOOST_CHRONO_USES_MPL_ASSERT)
2012-07-21 14:37:40 -04:00
# 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
2013-01-13 17:38:19 -05:00
# ifndef BOOST_CHRONO_HEADER_ONLY
// this must occur after all of the includes and before any code appears:
# include <boost/config/abi_prefix.hpp> // must be the last #include
# endif
2012-07-21 14:37:40 -04:00
//----------------------------------------------------------------------------//
// //
// 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_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_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_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_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_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 {
2013-01-13 17:38:19 -05:00
static BOOST_CHRONO_LIB_CONSTEXPR T lowest ( ) BOOST_CHRONO_LIB_NOEXCEPT_OR_THROW { return ( std : : numeric_limits < T > : : min ) ( ) ; }
2012-07-21 14:37:40 -04:00
} ;
template < class T >
struct chrono_numeric_limits < T , true > {
2013-01-13 17:38:19 -05:00
static BOOST_CHRONO_LIB_CONSTEXPR T lowest ( ) BOOST_CHRONO_LIB_NOEXCEPT_OR_THROW { return ( std : : numeric_limits < T > : : min ) ( ) ; }
2012-07-21 14:37:40 -04:00
} ;
template < >
struct chrono_numeric_limits < float , true > {
2013-01-13 17:38:19 -05:00
static BOOST_CHRONO_LIB_CONSTEXPR float lowest ( ) BOOST_CHRONO_LIB_NOEXCEPT_OR_THROW
2012-07-21 14:37:40 -04:00
{
return - ( std : : numeric_limits < float > : : max ) ( ) ;
}
} ;
template < >
struct chrono_numeric_limits < double , true > {
2013-01-13 17:38:19 -05:00
static BOOST_CHRONO_LIB_CONSTEXPR double lowest ( ) BOOST_CHRONO_LIB_NOEXCEPT_OR_THROW
2012-07-21 14:37:40 -04:00
{
return - ( std : : numeric_limits < double > : : max ) ( ) ;
}
} ;
template < >
struct chrono_numeric_limits < long double , true > {
2013-01-13 17:38:19 -05:00
static BOOST_CHRONO_LIB_CONSTEXPR long double lowest ( ) BOOST_CHRONO_LIB_NOEXCEPT_OR_THROW
2012-07-21 14:37:40 -04:00
{
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_CONSTEXPR Rep zero ( ) { return Rep ( 0 ) ; }
2013-01-13 17:38:19 -05:00
static BOOST_CHRONO_LIB_CONSTEXPR Rep max BOOST_PREVENT_MACRO_SUBSTITUTION ( )
2012-07-21 14:37:40 -04:00
{
return ( std : : numeric_limits < Rep > : : max ) ( ) ;
}
2013-01-13 17:38:19 -05:00
static BOOST_CHRONO_LIB_CONSTEXPR Rep min BOOST_PREVENT_MACRO_SUBSTITUTION ( )
2012-07-21 14:37:40 -04:00
{
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_CONSTEXPR
duration ( ) : rep_ ( duration_values < rep > : : zero ( ) ) { }
template < class Rep2 >
BOOST_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 ) { }
2013-01-13 17:38:19 -05:00
//~duration() {} //= default;
//BOOST_CONSTEXPR
//duration(const duration& rhs) : rep_(rhs.rep_) {} // = default;
2012-07-21 14:37:40 -04:00
duration & operator = ( const duration & rhs ) // = default;
{
if ( & rhs ! = this ) rep_ = rhs . rep_ ;
return * this ;
}
// conversions
template < class Rep2 , class Period2 >
BOOST_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_CONSTEXPR
rep count ( ) const { return rep_ ; }
// arithmetic
BOOST_CONSTEXPR
2013-01-13 17:38:19 -05:00
duration operator + ( ) const { return duration ( rep_ ) ; ; }
2012-07-21 14:37:40 -04:00
BOOST_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_CONSTEXPR duration zero ( )
{
return duration ( duration_values < rep > : : zero ( ) ) ;
}
2013-01-13 17:38:19 -05:00
static BOOST_CHRONO_LIB_CONSTEXPR duration min BOOST_PREVENT_MACRO_SUBSTITUTION ( )
2012-07-21 14:37:40 -04:00
{
return duration ( ( duration_values < rep > : : min ) ( ) ) ;
}
2013-01-13 17:38:19 -05:00
static BOOST_CHRONO_LIB_CONSTEXPR duration max BOOST_PREVENT_MACRO_SUBSTITUTION ( )
2012-07-21 14:37:40 -04:00
{
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_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_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_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_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_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_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_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_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_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
{
2013-01-13 17:38:19 -05:00
BOOST_CONSTEXPR bool operator ( ) ( const LhsDuration & lhs , const RhsDuration & rhs )
2012-07-21 14:37:40 -04:00
{
typedef typename common_type < LhsDuration , RhsDuration > : : type CD ;
return CD ( lhs ) . count ( ) = = CD ( rhs ) . count ( ) ;
}
} ;
template < class LhsDuration >
struct duration_eq < LhsDuration , LhsDuration >
{
2013-01-13 17:38:19 -05:00
BOOST_CONSTEXPR bool operator ( ) ( const LhsDuration & lhs , const LhsDuration & rhs )
2012-07-21 14:37:40 -04:00
{
return lhs . count ( ) = = rhs . count ( ) ;
}
} ;
template < class LhsDuration , class RhsDuration >
struct duration_lt
{
2013-01-13 17:38:19 -05:00
BOOST_CONSTEXPR bool operator ( ) ( const LhsDuration & lhs , const RhsDuration & rhs )
2012-07-21 14:37:40 -04:00
{
typedef typename common_type < LhsDuration , RhsDuration > : : type CD ;
return CD ( lhs ) . count ( ) < CD ( rhs ) . count ( ) ;
}
} ;
template < class LhsDuration >
struct duration_lt < LhsDuration , LhsDuration >
{
2013-01-13 17:38:19 -05:00
BOOST_CONSTEXPR bool operator ( ) ( const LhsDuration & lhs , const LhsDuration & rhs )
2012-07-21 14:37:40 -04:00
{
return lhs . count ( ) < rhs . count ( ) ;
}
} ;
} // namespace detail
// Duration ==
template < class Rep1 , class Period1 , class Rep2 , class Period2 >
inline BOOST_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_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_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_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_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 >
2013-01-13 17:38:19 -05:00
inline BOOST_CONSTEXPR
2012-07-21 14:37:40 -04:00
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_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
2013-01-13 17:38:19 -05:00
# ifndef BOOST_CHRONO_HEADER_ONLY
// the suffix header occurs after all of our code:
# include <boost/config/abi_suffix.hpp> // pops abi_prefix.hpp pragmas
# endif
2012-07-21 14:37:40 -04:00
# endif // BOOST_CHRONO_DURATION_HPP