summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
Diffstat (limited to '3rdParty/Boost/src/boost/chrono/duration.hpp')
-rw-r--r--3rdParty/Boost/src/boost/chrono/duration.hpp795
1 files changed, 795 insertions, 0 deletions
diff --git a/3rdParty/Boost/src/boost/chrono/duration.hpp b/3rdParty/Boost/src/boost/chrono/duration.hpp
new file mode 100644
index 0000000..97fe3d7
--- /dev/null
+++ b/3rdParty/Boost/src/boost/chrono/duration.hpp
@@ -0,0 +1,795 @@
+// 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_CXX11_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
+
+#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
+
+//----------------------------------------------------------------------------//
+// //
+// 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 {
+ static BOOST_CHRONO_LIB_CONSTEXPR T lowest() BOOST_CHRONO_LIB_NOEXCEPT_OR_THROW {return (std::numeric_limits<T>::min) ();}
+ };
+
+ template <class T>
+ struct chrono_numeric_limits<T,true> {
+ static BOOST_CHRONO_LIB_CONSTEXPR T lowest() BOOST_CHRONO_LIB_NOEXCEPT_OR_THROW {return (std::numeric_limits<T>::min) ();}
+ };
+
+ template <>
+ struct chrono_numeric_limits<float,true> {
+ static BOOST_CHRONO_LIB_CONSTEXPR float lowest() BOOST_CHRONO_LIB_NOEXCEPT_OR_THROW
+ {
+ return -(std::numeric_limits<float>::max) ();
+ }
+ };
+
+ template <>
+ struct chrono_numeric_limits<double,true> {
+ static BOOST_CHRONO_LIB_CONSTEXPR double lowest() BOOST_CHRONO_LIB_NOEXCEPT_OR_THROW
+ {
+ return -(std::numeric_limits<double>::max) ();
+ }
+ };
+
+ template <>
+ struct chrono_numeric_limits<long double,true> {
+ static BOOST_CHRONO_LIB_CONSTEXPR long double lowest() BOOST_CHRONO_LIB_NOEXCEPT_OR_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_CONSTEXPR Rep zero() {return Rep(0);}
+ static BOOST_CHRONO_LIB_CONSTEXPR Rep max BOOST_PREVENT_MACRO_SUBSTITUTION ()
+ {
+ return (std::numeric_limits<Rep>::max)();
+ }
+
+ static BOOST_CHRONO_LIB_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_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) { }
+ //~duration() {} //= default;
+ //BOOST_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_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
+ duration operator+() const {return duration(rep_);;}
+ 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());
+ }
+ static BOOST_CHRONO_LIB_CONSTEXPR duration min BOOST_PREVENT_MACRO_SUBSTITUTION ()
+ {
+ return duration((duration_values<rep>::min)());
+ }
+ static BOOST_CHRONO_LIB_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_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
+ {
+ BOOST_CONSTEXPR 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>
+ {
+ BOOST_CONSTEXPR bool operator()(const LhsDuration& lhs, const LhsDuration& rhs)
+ {
+ return lhs.count() == rhs.count();
+ }
+ };
+
+ template <class LhsDuration, class RhsDuration>
+ struct duration_lt
+ {
+ BOOST_CONSTEXPR 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>
+ {
+ BOOST_CONSTEXPR 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_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>
+ inline BOOST_CONSTEXPR
+ 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
+
+#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
+
+#endif // BOOST_CHRONO_DURATION_HPP