|
Boost-Commit : |
Subject: [Boost-commit] svn:boost r49698 - in sandbox/chrono: . boost boost/chrono boost/type_traits libs libs/chrono libs/chrono/build libs/chrono/doc libs/chrono/example libs/chrono/src libs/chrono/test libs/chrono/test/chrono_msvc libs/chrono/test/chrono_msvc/await_keystroke libs/chrono/test/chrono_msvc/ratio_test libs/chrono/test/chrono_msvc/time2_demo
From: bdawes_at_[hidden]
Date: 2008-11-12 08:44:25
Author: bemandawes
Date: 2008-11-12 08:44:21 EST (Wed, 12 Nov 2008)
New Revision: 49698
URL: http://svn.boost.org/trac/boost/changeset/49698
Log:
Boost.Chrono: Initial commit of work-in-progress.
Added:
sandbox/chrono/
sandbox/chrono/boost/
sandbox/chrono/boost/chrono/
sandbox/chrono/boost/chrono.hpp (contents, props changed)
sandbox/chrono/boost/chrono/config.hpp (contents, props changed)
sandbox/chrono/boost/ratio.hpp (contents, props changed)
sandbox/chrono/boost/type_traits/
sandbox/chrono/boost/type_traits/common_type.hpp (contents, props changed)
sandbox/chrono/libs/
sandbox/chrono/libs/chrono/
sandbox/chrono/libs/chrono/build/
sandbox/chrono/libs/chrono/build/Jamfile.v2 (contents, props changed)
sandbox/chrono/libs/chrono/doc/
sandbox/chrono/libs/chrono/doc/time2_demo.html (contents, props changed)
sandbox/chrono/libs/chrono/example/
sandbox/chrono/libs/chrono/example/await_keystroke.cpp (contents, props changed)
sandbox/chrono/libs/chrono/example/time2_demo.cpp (contents, props changed)
sandbox/chrono/libs/chrono/example/time2_demo_output.txt (contents, props changed)
sandbox/chrono/libs/chrono/src/
sandbox/chrono/libs/chrono/src/chrono.cpp (contents, props changed)
sandbox/chrono/libs/chrono/test/
sandbox/chrono/libs/chrono/test/Jamfile.v2 (contents, props changed)
sandbox/chrono/libs/chrono/test/chrono_msvc/
sandbox/chrono/libs/chrono/test/chrono_msvc/await_keystroke/
sandbox/chrono/libs/chrono/test/chrono_msvc/await_keystroke/await_keystroke.vcproj (contents, props changed)
sandbox/chrono/libs/chrono/test/chrono_msvc/chrono_msvc.sln (contents, props changed)
sandbox/chrono/libs/chrono/test/chrono_msvc/common.vsprops (contents, props changed)
sandbox/chrono/libs/chrono/test/chrono_msvc/ratio_test/
sandbox/chrono/libs/chrono/test/chrono_msvc/ratio_test/ratio_test.vcproj (contents, props changed)
sandbox/chrono/libs/chrono/test/chrono_msvc/time2_demo/
sandbox/chrono/libs/chrono/test/chrono_msvc/time2_demo/time2_demo.vcproj (contents, props changed)
sandbox/chrono/libs/chrono/test/chrono_unit_test.cpp (contents, props changed)
sandbox/chrono/libs/chrono/test/ratio_test.cpp (contents, props changed)
Added: sandbox/chrono/boost/chrono.hpp
==============================================================================
--- (empty file)
+++ sandbox/chrono/boost/chrono.hpp 2008-11-12 08:44:21 EST (Wed, 12 Nov 2008)
@@ -0,0 +1,907 @@
+// chrono.hpp --------------------------------------------------------------//
+
+// Copyright 2008 Howard Hinnant
+// Copyright 2008 Beman Dawes
+
+// 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 Krügler,
+ Anthony Williams.
+*/
+
+#ifndef BOOST_CHRONO_HPP
+#define BOOST_CHRONO_HPP
+
+#include <ctime>
+#include <climits>
+#include <limits>
+
+#include <boost/chrono/config.hpp>
+#include <boost/ratio.hpp>
+#include <boost/type_traits/common_type.hpp>
+#include <boost/cstdint.hpp>
+#include <boost/type_traits.hpp>
+#include <boost/utility/enable_if.hpp>
+#include <boost/detail/workaround.hpp>
+
+#include <boost/config/abi_prefix.hpp> // must be the last #include
+
+#ifdef BOOST_CHRONO_WINDOWS_API
+// The system_clock tick is 100 nanoseconds
+# define BOOST_SYSTEM_CLOCK_DURATION duration<boost::int_least64_t, ratio<1LL, 10000000LL> >
+#else
+# define BOOST_SYSTEM_CLOCK_DURATION boost::chrono::nanoseconds
+#endif
+
+//----------------------------------------------------------------------------//
+// //
+// 20.9 Time utilities [time] //
+// synopsis //
+// //
+//----------------------------------------------------------------------------//
+
+namespace boost {
+namespace chrono {
+
+ template <class Rep, class Period = ratio<1> >
+ class duration;
+ template <class Clock, class Duration = typename Clock::duration>
+ class time_point;
+
+} // 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> >;
+
+template <class Clock, class Duration1, class Duration2>
+ struct common_type<chrono::time_point<Clock, Duration1>,
+ chrono::time_point<Clock, Duration2> >;
+
+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>
+ // duration<typename common_type<Rep1, Rep2>::type, Period>
+ // operator*(const duration<Rep1, Period>& d, const Rep2& s);
+ template <class Rep1, class Period, class Rep2>
+ duration<typename common_type<Rep1, Rep2>::type, Period>
+ operator*(const Rep1& s, const duration<Rep2, Period>& d);
+ //template <class Rep1, class Period, class Rep2>
+ // duration<typename common_type<Rep1, Rep2>::type, Period>
+ // 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
+
+ # if !BOOST_WORKAROUND( BOOST_MSVC, <= 1500 ) // VC++ 9.0 can't handle this
+
+ template <class ToDuration, class Rep, class Period>
+ ToDuration duration_cast(const duration<Rep, Period>& d);
+
+ # endif
+
+ // 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
+
+ // time_point arithmetic
+ template <class Clock, class Duration1, class Rep2, class Period2>
+ time_point<Clock, typename common_type<Duration1, duration<Rep2, Period2> >::type>
+ operator+(const time_point<Clock, Duration1>& lhs, const duration<Rep2, Period2>& rhs);
+ template <class Rep1, class Period1, class Clock, class Duration2>
+ time_point<Clock, typename common_type<duration<Rep1, Period1>, Duration2>::type>
+ operator+(const duration<Rep1, Period1>& lhs, const time_point<Clock, Duration2>& rhs);
+ template <class Clock, class Duration1, class Rep2, class Period2>
+ time_point<Clock, typename common_type<Duration1, duration<Rep2, Period2> >::type>
+ operator-(const time_point<Clock, Duration1>& lhs, const duration<Rep2, Period2>& rhs);
+ template <class Clock, class Duration1, class Duration2>
+ typename common_type<Duration1, Duration2>::type
+ operator-(const time_point<Clock, Duration1>& lhs, const time_point<Clock,
+ Duration2>& rhs);
+
+ // time_point comparisons
+ template <class Clock, class Duration1, class Duration2>
+ bool operator==(const time_point<Clock, Duration1>& lhs, const time_point<Clock,
+ Duration2>& rhs);
+ template <class Clock, class Duration1, class Duration2>
+ bool operator!=(const time_point<Clock, Duration1>& lhs, const time_point<Clock,
+ Duration2>& rhs);
+ template <class Clock, class Duration1, class Duration2>
+ bool operator< (const time_point<Clock, Duration1>& lhs, const time_point<Clock,
+ Duration2>& rhs);
+ template <class Clock, class Duration1, class Duration2>
+ bool operator<=(const time_point<Clock, Duration1>& lhs, const time_point<Clock,
+ Duration2>& rhs);
+ template <class Clock, class Duration1, class Duration2>
+ bool operator> (const time_point<Clock, Duration1>& lhs, const time_point<Clock,
+ Duration2>& rhs);
+ template <class Clock, class Duration1, class Duration2>
+ bool operator>=(const time_point<Clock, Duration1>& lhs, const time_point<Clock,
+ Duration2>& rhs);
+
+ // time_point_cast
+ template <class ToDuration, class Clock, class Duration>
+ time_point<Clock, ToDuration> time_point_cast(const time_point<Clock, Duration>& t);
+
+ // Clocks
+ class system_clock;
+ class monotonic_clock;
+ typedef monotonic_clock high_resolution_clock; // as permitted by [time.clock.hires]
+
+//----------------------------------------------------------------------------//
+// duration helpers //
+//----------------------------------------------------------------------------//
+
+ 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> {};
+
+ // 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 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
+ {
+ #if BOOST_VARIADIC_COMMON_TYPE == 0
+ typedef typename common_type<
+ typename common_type<typename ToDuration::rep,
+ typename FromDuration::rep>::type,
+ intmax_t>::type C;
+ #else
+ typedef typename common_type<
+ typename ToDuration::rep,
+ typename FromDuration::rep,
+ intmax_t>::type C;
+ #endif
+ 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
+ {
+ #if BOOST_VARIADIC_COMMON_TYPE == 0
+ typedef typename common_type<
+ typename common_type<typename ToDuration::rep,
+ typename FromDuration::rep>::type,
+ intmax_t>::type C;
+ #else
+ typedef typename common_type<
+ typename ToDuration::rep,
+ typename FromDuration::rep,
+ intmax_t>::type C;
+ #endif
+ 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
+ {
+ #if BOOST_VARIADIC_COMMON_TYPE == 0
+ typedef typename common_type<
+ typename common_type<
+ typename ToDuration::rep,
+ typename FromDuration::rep>::type,
+ intmax_t>::type C;
+ #else
+ typedef typename common_type<
+ typename ToDuration::rep,
+ typename FromDuration::rep,
+ intmax_t>::type C;
+ #endif
+ 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 is_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] //
+//----------------------------------------------------------------------------//
+
+ template <class Rep>
+ struct duration_values
+ {
+ static Rep m_min_imp(boost::false_type) {return -max();}
+ static Rep m_min_imp(boost::true_type) {return zero();}
+ public:
+ static Rep zero() {return Rep(0);}
+ static Rep max() {return std::numeric_limits<Rep>::max();}
+ static Rep min() {return m_min_imp(boost::is_unsigned<Rep>());}
+ };
+
+} // 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 detail::ratio_gcd<Period1, Period2>::type> type;
+};
+
+template <class Clock, class Duration1, class Duration2>
+struct common_type<chrono::time_point<Clock, Duration1>,
+ chrono::time_point<Clock, Duration2> >
+{
+ typedef chrono::time_point<Clock,
+ typename common_type<Duration1, Duration2>::type> type;
+};
+
+//----------------------------------------------------------------------------//
+// //
+// 20.9.3 Class template duration [time.duration] //
+// //
+//----------------------------------------------------------------------------//
+
+namespace chrono {
+
+ template <class Rep, class Period>
+ class duration
+ {
+ // static char test0[!detail::is_duration<Rep>];
+ //// static_assert(!detail::is_duration<Rep>, "A duration representation can not be a duration");
+ // static char test1[detail::is_ratio<Period>];
+ //// static_assert(detail::is_ratio<Period>::value, "Second template parameter of duration must be a std::ratio");
+ // static char test2[Period::num > 0];
+ //// static_assert(Period::num > 0, "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,
+ typename boost::enable_if_c
+ <
+ boost::is_convertible<Rep2, rep>::value
+ && (treat_as_floating_point<rep>::value
+ || (!treat_as_floating_point<rep>::value
+ && !treat_as_floating_point<Rep2>::value))
+ >::type* = 0)
+ : rep_(r) {}
+
+ // conversions
+ template <class Rep2, class Period2>
+ duration(const duration<Rep2, Period2>& d,
+ typename boost::enable_if_c
+ <
+ treat_as_floating_point<rep>::value
+ || (ratio_divide<Period2, period>::type::den == 1
+ && !treat_as_floating_point<Rep2>::value)
+ >::type* = 0)
+ : rep_(duration_cast<duration>(d).count()) {}
+
+ // 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;}
+
+ // 20.9.3.4 duration special values [time.duration.special]
+
+ static duration zero() {return duration(duration_values<rep>::zero());}
+ static duration min() {return duration(duration_values<rep>::min());}
+ static duration max() {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 common_type<duration<Rep1, Period1>, duration<Rep2, Period2> >::type
+ operator+(const duration<Rep1, Period1>& lhs, const duration<Rep2, Period2>& rhs)
+ {
+ typename 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 common_type<duration<Rep1, Period1>, duration<Rep2, Period2> >::type
+ operator-(const duration<Rep1, Period1>& lhs, const duration<Rep2, Period2>& rhs)
+ {
+ typename common_type<duration<Rep1, Period1>,
+ duration<Rep2, Period2> >::type result = lhs;
+ result -= rhs;
+ return result;
+ }
+
+ // Duration *
+
+ template <class Rep1, class Period, class Rep2>
+ inline
+ 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)
+ {
+ typedef typename 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
+ 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)
+ {
+ return d * s;
+ }
+
+ // Duration /
+
+ namespace detail
+ {
+ 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>
+ {
+ };
+ } // namespace detail
+
+ template <class Rep1, class Period, class Rep2>
+ inline
+ typename detail::duration_divide_result<duration<Rep1, Period>, Rep2>::type
+ operator/(const duration<Rep1, Period>& d, const Rep2& s)
+ {
+ typedef typename 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 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();
+ }
+
+//----------------------------------------------------------------------------//
+// 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
+ bool
+ operator==(const duration<Rep1, Period1>& lhs, const duration<Rep2, Period2>& rhs)
+ {
+ return 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 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
+ typename boost::enable_if <detail::is_duration<ToDuration>, ToDuration>::type
+ duration_cast(const duration<Rep, Period>& fd)
+ {
+ return detail::duration_cast<duration<Rep, Period>, ToDuration>()(fd);
+ }
+
+//----------------------------------------------------------------------------//
+// //
+// 20.9.4 Class template time_point [time.point] //
+// //
+//----------------------------------------------------------------------------//
+
+template <class Clock, class Duration>
+ class time_point
+ {
+ // static char test1[detail::is_duration<Duration>];
+ //// static_assert(detail::is_duration<Duration>,
+ //// "Second template parameter of time_point must be a std::datetime::duration");
+ public:
+ typedef Clock clock;
+ typedef Duration duration;
+ typedef typename duration::rep rep;
+ typedef typename duration::period period;
+ private:
+ duration d_;
+
+ public:
+ time_point() : d_(duration::zero()) {}
+ explicit time_point(const duration& d) : d_(d) {}
+
+ // conversions
+ template <class Duration2>
+ time_point(const time_point<clock, Duration2>& t,
+ typename boost::enable_if
+ <
+ boost::is_convertible<Duration2, duration>
+ >::type* = 0)
+ : d_(t.time_since_epoch()) {}
+
+ // observer
+
+ duration time_since_epoch() const {return d_;}
+
+ // arithmetic
+
+ time_point& operator+=(const duration& d) {d_ += d; return *this;}
+ time_point& operator-=(const duration& d) {d_ -= d; return *this;}
+
+ // special values
+
+ static time_point min() {return time_point(duration::min());}
+ static time_point max() {return time_point(duration::max());}
+ };
+
+//----------------------------------------------------------------------------//
+// 20.9.4.5 time_point non-member arithmetic [time.point.nonmember] //
+//----------------------------------------------------------------------------//
+
+ // time_point operator+(time_point x, duration y);
+
+ template <class Clock, class Duration1, class Rep2, class Period2>
+ inline
+ time_point<Clock, typename common_type<Duration1, duration<Rep2, Period2> >::type>
+ operator+(const time_point<Clock, Duration1>& lhs,
+ const duration<Rep2, Period2>& rhs)
+ {
+ typedef time_point<Clock,
+ typename common_type<Duration1, duration<Rep2, Period2> >::type> TimeResult;
+ TimeResult r(lhs);
+ r += rhs;
+ return r;
+ }
+
+ // time_point operator+(duration x, time_point y);
+
+ template <class Rep1, class Period1, class Clock, class Duration2>
+ inline
+ time_point<Clock, typename common_type<duration<Rep1, Period1>, Duration2>::type>
+ operator+(const duration<Rep1, Period1>& lhs,
+ const time_point<Clock, Duration2>& rhs)
+ {
+ return rhs + lhs;
+ }
+
+ // time_point operator-(time_point x, duration y);
+
+ template <class Clock, class Duration1, class Rep2, class Period2>
+ inline
+ time_point<Clock, typename common_type<Duration1, duration<Rep2, Period2> >::type>
+ operator-(const time_point<Clock, Duration1>& lhs,
+ const duration<Rep2, Period2>& rhs)
+ {
+ return lhs + (-rhs);
+ }
+
+ // duration operator-(time_point x, time_point y);
+
+ template <class Clock, class Duration1, class Duration2>
+ inline
+ typename common_type<Duration1, Duration2>::type
+ operator-(const time_point<Clock, Duration1>& lhs,
+ const time_point<Clock, Duration2>& rhs)
+ {
+ return lhs.time_since_epoch() - rhs.time_since_epoch();
+ }
+
+//----------------------------------------------------------------------------//
+// 20.9.4.6 time_point comparisons [time.point.comparisons] //
+//----------------------------------------------------------------------------//
+
+ // time_point ==
+
+ template <class Clock, class Duration1, class Duration2>
+ inline
+ bool
+ operator==(const time_point<Clock, Duration1>& lhs,
+ const time_point<Clock, Duration2>& rhs)
+ {
+ return lhs.time_since_epoch() == rhs.time_since_epoch();
+ }
+
+ // time_point !=
+
+ template <class Clock, class Duration1, class Duration2>
+ inline
+ bool
+ operator!=(const time_point<Clock, Duration1>& lhs,
+ const time_point<Clock, Duration2>& rhs)
+ {
+ return !(lhs == rhs);
+ }
+
+ // time_point <
+
+ template <class Clock, class Duration1, class Duration2>
+ inline
+ bool
+ operator<(const time_point<Clock, Duration1>& lhs,
+ const time_point<Clock, Duration2>& rhs)
+ {
+ return lhs.time_since_epoch() < rhs.time_since_epoch();
+ }
+
+ // time_point >
+
+ template <class Clock, class Duration1, class Duration2>
+ inline
+ bool
+ operator>(const time_point<Clock, Duration1>& lhs,
+ const time_point<Clock, Duration2>& rhs)
+ {
+ return rhs < lhs;
+ }
+
+ // time_point <=
+
+ template <class Clock, class Duration1, class Duration2>
+ inline
+ bool
+ operator<=(const time_point<Clock, Duration1>& lhs,
+ const time_point<Clock, Duration2>& rhs)
+ {
+ return !(rhs < lhs);
+ }
+
+ // time_point >=
+
+ template <class Clock, class Duration1, class Duration2>
+ inline
+ bool
+ operator>=(const time_point<Clock, Duration1>& lhs,
+ const time_point<Clock, Duration2>& rhs)
+ {
+ return !(lhs < rhs);
+ }
+
+//----------------------------------------------------------------------------//
+// 20.9.4.7 time_point_cast [time.point.cast] //
+//----------------------------------------------------------------------------//
+
+ template <class ToDuration, class Clock, class Duration>
+ inline
+ time_point<Clock, ToDuration>
+ time_point_cast(const time_point<Clock, Duration>& t)
+ {
+ return time_point<Clock, ToDuration>(
+ duration_cast<ToDuration>(t.time_since_epoch()));
+ }
+
+//----------------------------------------------------------------------------//
+// //
+// 20.9.5 Clocks [time.clock] //
+// //
+//----------------------------------------------------------------------------//
+
+// If you're porting, clocks are the system-specific (non-portable) part.
+// You'll need to know how to get the current time and implement that under now().
+// You'll need to know what units (tick period) and representation makes the most
+// sense for your clock and set those accordingly.
+// If you know how to map this clock to time_t (perhaps your clock is std::time, which
+// makes that trivial), then you can fill out system_clock's to_time_t() and from_time_t().
+
+//----------------------------------------------------------------------------//
+// 20.9.5.1 Class system_clock [time.clock.system] //
+//----------------------------------------------------------------------------//
+
+ class system_clock
+ {
+ public:
+ typedef BOOST_SYSTEM_CLOCK_DURATION duration;
+ typedef duration::rep rep;
+ typedef duration::period period;
+ typedef chrono::time_point<system_clock> time_point;
+ static const bool is_monotonic = false;
+
+ static time_point now();
+
+ static std::time_t to_time_t(const time_point& t);
+ static time_point from_time_t(std::time_t t);
+ };
+
+//----------------------------------------------------------------------------//
+// 20.9.5.2 Class monotonic_clock [time.clock.monotonic] //
+//----------------------------------------------------------------------------//
+
+ class monotonic_clock
+ {
+ public:
+ typedef nanoseconds duration;
+ typedef duration::rep rep;
+ typedef duration::period period;
+ typedef chrono::time_point<monotonic_clock> time_point;
+ static const bool is_monotonic = true;
+
+ static time_point now();
+ };
+
+//----------------------------------------------------------------------------//
+// 20.9.5.3 Class high_resolution_clock [time.clock.hires] //
+//----------------------------------------------------------------------------//
+
+// As permitted, monotonic_clock is a typedef for high_resolution_clock.
+// See synopsis.
+
+} // namespace chrono
+} // namespace boost
+
+#endif // BOOST_CHRONO_HPP
Added: sandbox/chrono/boost/chrono/config.hpp
==============================================================================
--- (empty file)
+++ sandbox/chrono/boost/chrono/config.hpp 2008-11-12 08:44:21 EST (Wed, 12 Nov 2008)
@@ -0,0 +1,89 @@
+// boost/chrono/config.hpp -------------------------------------------------//
+
+// Copyright Beman Dawes 2003, 2006, 2008
+
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// See http://www.boost.org/libs/chrono for documentation.
+
+#ifndef BOOST_CHRONO_CONFIG_HPP
+#define BOOST_CHRONO_CONFIG_HPP
+
+#include <boost/config.hpp>
+
+// BOOST_CHRONO_POSIX_API, BOOST_CHRONO_MAC_API, or BOOST_CHRONO_WINDOWS_API
+// can be defined by the user to specify which API should be used
+
+#ifdef BOOST_CHRONO_WINDOWS_API
+# warning Boost.Chrono will use the Windows API
+#elif BOOST_CHRONO_MAC_API
+# warning Boost.Chrono will use the Mac API
+#elif BOOST_CHRONO_POSIX_API
+# warning Boost.Chrono will use the POSIX API
+#endif
+
+# if defined( BOOST_CHRONO_WINDOWS_API ) && defined( BOOST_CHRONO_POSIX_API )
+# error both BOOST_CHRONO_WINDOWS_API and BOOST_CHRONO_POSIX_API are defined
+# elif defined( BOOST_CHRONO_WINDOWS_API ) && defined( BOOST_CHRONO_MAC_API )
+# error both BOOST_CHRONO_WINDOWS_API and BOOST_CHRONO_MAC_API are defined
+# elif defined( BOOST_CHRONO_MAC_API ) && defined( BOOST_CHRONO_POSIX_API )
+# error both BOOST_CHRONO_MAC_API and BOOST_CHRONO_POSIX_API are defined
+# elif !defined( BOOST_CHRONO_WINDOWS_API ) && !defined( BOOST_CHRONO_MAC_API ) && !defined( BOOST_CHRONO_POSIX_API )
+# if (defined(_WIN32) || defined(__WIN32__) || defined(WIN32))
+# define BOOST_CHRONO_WINDOWS_API
+# elif defined(macintosh) || defined(__APPLE__) || defined(__APPLE_CC__)
+# define BOOST_CHRONO_MAC_API
+# else
+# define BOOST_CHRONO_POSIX_API
+# endif
+# endif
+
+// enable dynamic linking on Windows ---------------------------------------//
+
+//# if (defined(BOOST_ALL_DYN_LINK) || defined(BOOST_CHRONO_DYN_LINK)) && defined(__BORLANDC__) && defined(__WIN32__)
+//# error Dynamic linking Boost.System does not work for Borland; use static linking instead
+//# endif
+
+#ifdef BOOST_HAS_DECLSPEC // defined by boost.config
+// we need to import/export our code only if the user has specifically
+// asked for it by defining either BOOST_ALL_DYN_LINK if they want all boost
+// libraries to be dynamically linked, or BOOST_CHRONO_DYN_LINK
+// if they want just this one to be dynamically liked:
+#if defined(BOOST_ALL_DYN_LINK) || defined(BOOST_CHRONO_DYN_LINK)
+// export if this is our own source, otherwise import:
+#ifdef BOOST_CHRONO_SOURCE
+# define BOOST_CHRONO_DECL __declspec(dllexport)
+#else
+# define BOOST_CHRONO_DECL __declspec(dllimport)
+#endif // BOOST_CHRONO_SOURCE
+#endif // DYN_LINK
+#endif // BOOST_HAS_DECLSPEC
+//
+// if BOOST_CHRONO_DECL isn't defined yet define it now:
+#ifndef BOOST_CHRONO_DECL
+#define BOOST_CHRONO_DECL
+#endif
+
+// enable automatic library variant selection ------------------------------//
+
+#if !defined(BOOST_CHRONO_SOURCE) && !defined(BOOST_ALL_NO_LIB) && !defined(BOOST_CHRONO_NO_LIB)
+//
+// Set the name of our library; this will get undef'ed by auto_link.hpp
+// once it's done with it:
+//
+#define BOOST_LIB_NAME boost_chrono
+//
+// If we're importing code from a dll, then tell auto_link.hpp about it:
+//
+#if defined(BOOST_ALL_DYN_LINK) || defined(BOOST_CHRONO_DYN_LINK)
+# define BOOST_DYN_LINK
+#endif
+//
+// And include the header that does the work:
+//
+#include <boost/config/auto_link.hpp>
+#endif // auto-linking disabled
+
+#endif // BOOST_CHRONO_CONFIG_HPP
+
Added: sandbox/chrono/boost/ratio.hpp
==============================================================================
--- (empty file)
+++ sandbox/chrono/boost/ratio.hpp 2008-11-12 08:44:21 EST (Wed, 12 Nov 2008)
@@ -0,0 +1,441 @@
+// ratio.hpp ---------------------------------------------------------------//
+
+// Copyright 2008 Howard Hinnant
+// Copyright 2008 Beman Dawes
+
+// 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.4 Compile-time rational arithmetic [ratio], of the C++ committee 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 Krügler,
+ Anthony Williams.
+*/
+
+#ifndef BOOST_RATIO_HPP
+#define BOOST_RATIO_HPP
+
+#include <cstdlib>
+#include <climits>
+#include <limits>
+#include <boost/cstdint.hpp>
+#include <boost/type_traits.hpp>
+
+namespace boost
+{
+
+//----------------------------------------------------------------------------//
+// //
+// 20.4 Compile-time rational arithmetic [ratio] //
+// //
+//----------------------------------------------------------------------------//
+
+template <boost::intmax_t N, boost::intmax_t D = 1> class ratio;
+
+// ratio arithmetic
+template <class R1, class R2> struct ratio_add;
+template <class R1, class R2> struct ratio_subtract;
+template <class R1, class R2> struct ratio_multiply;
+template <class R1, class R2> struct ratio_divide;
+
+// ratio comparison
+template <class R1, class R2> struct ratio_equal;
+template <class R1, class R2> struct ratio_not_equal;
+template <class R1, class R2> struct ratio_less;
+template <class R1, class R2> struct ratio_less_equal;
+template <class R1, class R2> struct ratio_greater;
+template <class R1, class R2> struct ratio_greater_equal;
+
+// convenience SI typedefs
+typedef ratio<1LL, 1000000000000000000LL> atto;
+typedef ratio<1LL, 1000000000000000LL> femto;
+typedef ratio<1LL, 1000000000000LL> pico;
+typedef ratio<1LL, 1000000000LL> nano;
+typedef ratio<1LL, 1000000LL> micro;
+typedef ratio<1LL, 1000LL> milli;
+typedef ratio<1LL, 100LL> centi;
+typedef ratio<1LL, 10LL> deci;
+typedef ratio< 10LL, 1LL> deca;
+typedef ratio< 100LL, 1LL> hecto;
+typedef ratio< 1000LL, 1LL> kilo;
+typedef ratio< 1000000LL, 1LL> mega;
+typedef ratio< 1000000000LL, 1LL> giga;
+typedef ratio< 1000000000000LL, 1LL> tera;
+typedef ratio< 1000000000000000LL, 1LL> peta;
+typedef ratio<1000000000000000000LL, 1LL> exa;
+
+//----------------------------------------------------------------------------//
+// helpers //
+//----------------------------------------------------------------------------//
+
+namespace detail
+{
+
+ // static_gcd
+
+ template <boost::intmax_t X, boost::intmax_t Y>
+ struct static_gcd
+ {
+ static const boost::intmax_t value = static_gcd<Y, X % Y>::value;
+ };
+
+ template <boost::intmax_t X>
+ struct static_gcd<X, 0>
+ {
+ static const boost::intmax_t value = X;
+ };
+
+ // static_lcm
+
+ template <boost::intmax_t X, boost::intmax_t Y>
+ struct static_lcm
+ {
+ static const boost::intmax_t value = X / static_gcd<X, Y>::value * Y;
+ };
+
+ template <boost::intmax_t X>
+ struct static_abs
+ {
+ static const boost::intmax_t value = X < 0 ? -X : X;
+ };
+
+ template <boost::intmax_t X>
+ struct static_sign
+ {
+ static const boost::intmax_t value = X == 0 ? 0 : (X < 0 ? -1 : 1);
+ };
+
+ template <boost::intmax_t X, boost::intmax_t Y, boost::intmax_t = static_sign<Y>::value>
+ class ll_add;
+
+ template <boost::intmax_t X, boost::intmax_t Y>
+ class ll_add<X, Y, 1>
+ {
+ static const boost::intmax_t min =
+ (1LL << (sizeof(boost::intmax_t) * CHAR_BIT - 1)) + 1;
+ static const boost::intmax_t max = -min;
+
+ static char test[X <= max - Y];
+ // static_assert(X <= max - Y, "overflow in ll_add");
+ public:
+ static const boost::intmax_t value = X + Y;
+ };
+
+ template <boost::intmax_t X, boost::intmax_t Y>
+ class ll_add<X, Y, 0>
+ {
+ public:
+ static const boost::intmax_t value = X;
+ };
+
+ template <boost::intmax_t X, boost::intmax_t Y>
+ class ll_add<X, Y, -1>
+ {
+ static const boost::intmax_t min =
+ (1LL << (sizeof(boost::intmax_t) * CHAR_BIT - 1)) + 1;
+ static const boost::intmax_t max = -min;
+
+ static char test[min - Y <= X];
+ // static_assert(min - Y <= X, "overflow in ll_add");
+ public:
+ static const boost::intmax_t value = X + Y;
+ };
+
+ template <boost::intmax_t X, boost::intmax_t Y, boost::intmax_t = static_sign<Y>::value>
+ class ll_sub;
+
+ template <boost::intmax_t X, boost::intmax_t Y>
+ class ll_sub<X, Y, 1>
+ {
+ static const boost::intmax_t min =
+ (1LL << (sizeof(boost::intmax_t) * CHAR_BIT - 1)) + 1;
+ static const boost::intmax_t max = -min;
+
+ static char test[min + Y <= X];
+ // static_assert(min + Y <= X, "overflow in ll_sub");
+ public:
+ static const boost::intmax_t value = X - Y;
+ };
+
+ template <boost::intmax_t X, boost::intmax_t Y>
+ class ll_sub<X, Y, 0>
+ {
+ public:
+ static const boost::intmax_t value = X;
+ };
+
+ template <boost::intmax_t X, boost::intmax_t Y>
+ class ll_sub<X, Y, -1>
+ {
+ static const boost::intmax_t min =
+ (1LL << (sizeof(boost::intmax_t) * CHAR_BIT - 1)) + 1;
+ static const boost::intmax_t max = -min;
+
+ static char test[X <= max + Y];
+ // static_assert(X <= max + Y, "overflow in ll_sub");
+ public:
+ static const boost::intmax_t value = X - Y;
+ };
+
+ template <boost::intmax_t X, boost::intmax_t Y>
+ class ll_mul
+ {
+ static const boost::intmax_t nan =
+ (1LL << (sizeof(boost::intmax_t) * CHAR_BIT - 1));
+ static const boost::intmax_t min = nan + 1;
+ static const boost::intmax_t max = -min;
+ static const boost::intmax_t a_x = static_abs<X>::value;
+ static const boost::intmax_t a_y = static_abs<Y>::value;
+
+ static char test1[X != nan];
+ static char test2[Y != nan];
+ static char test[a_x <= max / a_y];
+ // static_assert(X != nan && Y != nan && a_x <= max / a_y, "overflow in ll_mul");
+ public:
+ static const boost::intmax_t value = X * Y;
+ };
+
+ template <boost::intmax_t Y>
+ class ll_mul<0, Y>
+ {
+ public:
+ static const boost::intmax_t value = 0;
+ };
+
+ template <boost::intmax_t X>
+ class ll_mul<X, 0>
+ {
+ public:
+ static const boost::intmax_t value = 0;
+ };
+
+ template <>
+ class ll_mul<0, 0>
+ {
+ public:
+ static const boost::intmax_t value = 0;
+ };
+
+ // Not actually used but left here in case needed in future maintenance
+ template <boost::intmax_t X, boost::intmax_t Y>
+ class ll_div
+ {
+ static const boost::intmax_t nan = (1LL << (sizeof(boost::intmax_t) * CHAR_BIT - 1));
+ static const boost::intmax_t min = nan + 1;
+ static const boost::intmax_t max = -min;
+
+ static char test1[X != nan];
+ static char test2[Y != nan];
+ static char test3[Y != 0];
+ // static_assert(X != nan && Y != nan && Y != 0, "overflow in ll_div");
+ public:
+ static const boost::intmax_t value = X / Y;
+ };
+
+ //template <class T>
+ // struct is_ratio : public false_type {};
+ //template <intmax_t N, intmax_t D>
+ // struct is_ratio<ratio<N, D> > : public true_type {};
+ //template <class T>
+ // struct is_ratio : is_ratio<typename remove_cv<T>::type> {};
+
+} // namespace detail
+
+//----------------------------------------------------------------------------//
+// //
+// 20.4.1 Class template ratio [ratio.ratio] //
+// //
+//----------------------------------------------------------------------------//
+
+template <boost::intmax_t N, boost::intmax_t D>
+class ratio
+{
+ static char test1[detail::static_abs<N>::value >= 0];
+ static char test2[detail::static_abs<D>::value > 0];
+// static_assert(detail::static_abs<N>::value >= 0, "ratio numerator is out of range");
+// static_assert(D != 0, "ratio divide by 0");
+// static_assert(detail::static_abs<D>::value > 0, "ratio denominator is out of range");
+ static const boost::intmax_t m_na = detail::static_abs<N>::value;
+ static const boost::intmax_t m_da = detail::static_abs<D>::value;
+ static const boost::intmax_t m_s = detail::static_sign<N>::value
+ * detail::static_sign<D>::value;
+ static const boost::intmax_t m_gcd = detail::static_gcd<m_na, m_da>::value;
+public:
+ static const boost::intmax_t num = m_s * m_na / m_gcd;
+ static const boost::intmax_t den = m_da / m_gcd;
+};
+
+//----------------------------------------------------------------------------//
+// //
+// Implementation //
+// //
+//----------------------------------------------------------------------------//
+
+template <class R1, class R2>
+struct ratio_add
+{
+ typedef ratio<detail::ll_add<detail::ll_mul<R1::num, R2::den>::value,
+ detail::ll_mul<R1::den, R2::num>::value>::value,
+ detail::ll_mul<R1::den, R2::den>::value> type;
+};
+
+template <class R1, class R2>
+struct ratio_subtract
+{
+ typedef ratio<detail::ll_sub<detail::ll_mul<R1::num, R2::den>::value,
+ detail::ll_mul<R1::den, R2::num>::value>::value,
+ detail::ll_mul<R1::den, R2::den>::value> type;
+};
+
+template <class R1, class R2>
+struct ratio_multiply
+{
+ typedef ratio<detail::ll_mul<R1::num, R2::num>::value,
+ detail::ll_mul<R1::den, R2::den>::value> type;
+};
+
+template <class R1, class R2>
+struct ratio_divide
+{
+ typedef ratio<detail::ll_mul<R1::num, R2::den>::value,
+ detail::ll_mul<R1::den, R2::num>::value> type;
+};
+
+// ratio_equal
+
+template <class R1, class R2>
+struct ratio_equal
+ : public boost::integral_constant<bool,
+ R1::num == R2::num && R1::den == R2::den> {};
+
+template <class R1, class R2>
+struct ratio_not_equal
+ : public boost::integral_constant<bool, !ratio_equal<R1, R2>::value> {};
+
+// ratio_less
+
+
+//----------------------------------------------------------------------------//
+// more helpers //
+//----------------------------------------------------------------------------//
+
+namespace detail
+{
+ // Protect against overflow, and still get the right answer as much as possible.
+ // This just demonstrates for fun how far you can push things without hitting
+ // overflow. The obvious and simple implementation is conforming.
+
+ template <class R1, class R2, bool ok1, bool ok2>
+ struct ratio_less3 // true, true and false, false
+ {
+ static const bool value = ll_mul<R1::num,
+ R2::den>::value < ll_mul<R2::num, R1::den>::value;
+ };
+
+ template <class R1, class R2>
+ struct ratio_less3<R1, R2, true, false>
+ {
+ static const bool value = true;
+ };
+
+ template <class R1, class R2>
+ struct ratio_less3<R1, R2, false, true>
+ {
+ static const bool value = false;
+ };
+
+ template <class R1, class R2, bool = (R1::num < R1::den == R2::num < R2::den) >
+ struct ratio_less2 // N1 < D1 == N2 < D2
+ {
+ static const intmax_t max = -((1LL << (sizeof(intmax_t) * CHAR_BIT - 1)) + 1);
+ static const bool ok1 = R1::num <= max / R2::den;
+ static const bool ok2 = R2::num <= max / R1::den;
+ static const bool value = ratio_less3<R1, R2, ok1, ok2>::value;
+ };
+
+ template <class R1, class R2>
+ struct ratio_less2<R1, R2, false> // N1 < D1 != N2 < D2
+ {
+ static const bool value = R1::num < R1::den;
+ };
+
+ template <class R1, class R2, bool = (R1::num < R1::den == R2::num < R2::den) >
+ struct ratio_less1 // N1 < D1 == N2 < D2
+ {
+ static const bool value = ratio_less2<ratio<R1::num, R2::num>,
+ ratio<R1::den, R2::den> >::value;
+ };
+
+ template <class R1, class R2>
+ struct ratio_less1<R1, R2, false> // N1 < D1 != N2 < D2
+ {
+ static const bool value = R1::num < R1::den;
+ };
+
+ template <class R1, class R2, intmax_t S1 = static_sign<R1::num>::value,
+ intmax_t S2 = static_sign<R2::num>::value>
+ struct ratio_less
+ {
+ static const bool value = S1 < S2;
+ };
+
+ template <class R1, class R2>
+ struct ratio_less<R1, R2, 1LL, 1LL>
+ {
+ static const bool value = ratio_less1<R1, R2>::value;
+ };
+
+ template <class R1, class R2>
+ struct ratio_less<R1, R2, -1LL, -1LL>
+ {
+ static const bool value = ratio_less1<ratio<-R2::num, R2::den>,
+ ratio<-R1::num, R1::den> >::value;
+ };
+
+ template <class R1, class R2>
+ struct ratio_gcd
+ {
+ typedef ratio<detail::static_gcd<R1::num, R2::num>::value,
+ detail::static_lcm<R1::den, R2::den>::value> type;
+ };
+} // namespace detail
+
+//----------------------------------------------------------------------------//
+// //
+// more implementation //
+// //
+//----------------------------------------------------------------------------//
+
+template <class R1, class R2>
+struct ratio_less
+ : public boost::integral_constant<bool, detail::ratio_less<R1, R2>::value> {};
+
+template <class R1, class R2>
+struct ratio_less_equal
+ : public boost::integral_constant<bool, !ratio_less<R2, R1>::value> {};
+
+template <class R1, class R2>
+struct ratio_greater
+ : public boost::integral_constant<bool, ratio_less<R2, R1>::value> {};
+
+template <class R1, class R2>
+struct ratio_greater_equal
+ : public boost::integral_constant<bool, !ratio_less<R1, R2>::value> {};
+
+} // namespace boost
+
+#endif // BOOST_RATIO_HPP
Added: sandbox/chrono/boost/type_traits/common_type.hpp
==============================================================================
--- (empty file)
+++ sandbox/chrono/boost/type_traits/common_type.hpp 2008-11-12 08:44:21 EST (Wed, 12 Nov 2008)
@@ -0,0 +1,56 @@
+// common_type.hpp ---------------------------------------------------------//
+
+// Copyright 2008 Howard Hinnant
+// Copyright 2008 Beman Dawes
+
+// Distributed under the Boost Software License, Version 1.0.
+// See http://www.boost.org/LICENSE_1_0.txt
+
+#ifndef BOOST_COMMON_TYPE_HPP
+#define BOOST_COMMON_TYPE_HPP
+
+#define BOOST_VARIADIC_COMMON_TYPE 0
+
+#include <boost/typeof/typeof.hpp> // boost wonders never cease!
+
+//----------------------------------------------------------------------------//
+// //
+// C++03 implementation of //
+// 20.6.7 Other transformations [meta.trans.other] //
+// Written by Howard Hinnant //
+// Adapted for Boost by Beman Dawes //
+// //
+//----------------------------------------------------------------------------//
+
+namespace boost
+{
+
+ template <class T, class U = void, class V = void>
+ struct common_type
+ {
+ public:
+ typedef typename common_type<typename common_type<T, U>::type, V>::type type;
+ };
+
+
+ template <class T>
+ struct common_type<T, void, void>
+ {
+ public:
+ typedef T type;
+ };
+
+ template <class T, class U>
+ struct common_type<T, U, void>
+ {
+ private:
+ static T m_t();
+ static U m_u();
+ static bool m_f(); // workaround gcc bug; not required by std
+ public:
+ typedef BOOST_TYPEOF_TPL(m_f() ? m_t() : m_u()) type;
+ };
+
+} // namespace boost
+
+#endif // BOOST_COMMON_TYPE_HPP
Added: sandbox/chrono/libs/chrono/build/Jamfile.v2
==============================================================================
--- (empty file)
+++ sandbox/chrono/libs/chrono/build/Jamfile.v2 2008-11-12 08:44:21 EST (Wed, 12 Nov 2008)
@@ -0,0 +1,25 @@
+# Boost Chrono Library Build Jamfile
+
+# Copyright Beman Dawes 2002, 2006, 2008
+
+# Distributed under the Boost Software License, Version 1.0.
+# (See accompanying file LICENSE_1_0.txt or www.boost.org/LICENSE_1_0.txt)
+
+# See library home page at http://www.boost.org/libs/chrono
+
+project boost/chrono
+ : source-location ../src
+ : usage-requirements # pass these requirement to dependents (i.e. users)
+ <link>shared:<define>BOOST_CHRONO_DYN_LINK=1
+ <link>static:<define>BOOST_CHRONO_STATIC_LINK=1
+ ;
+
+SOURCES = chrono ;
+
+lib boost_chrono
+ : $(SOURCES).cpp
+ : <link>shared:<define>BOOST_CHRONO_DYN_LINK=1
+ <link>static:<define>BOOST_CHRONO_STATIC_LINK=1
+ ;
+
+boost-install boost_chrono ;
\ No newline at end of file
Added: sandbox/chrono/libs/chrono/doc/time2_demo.html
==============================================================================
--- (empty file)
+++ sandbox/chrono/libs/chrono/doc/time2_demo.html 2008-11-12 08:44:21 EST (Wed, 12 Nov 2008)
@@ -0,0 +1,4040 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<html><head>
+<meta http-equiv="content-type" content="text/html; charset=ISO-8859-1">
+
+
+ <title>time2_demo</title>
+</head><body>
+
+<pre><font color="#c80000">/*
+Copyright (c) 2008 Howard Hinnant
+
+Distributed under the Boost Software License, Version 1.0. (See accompanying
+file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+
+A prototype of a proposal for a time/duration/clock library for the C++ standard.
+It is intended that this be a solid foundation upon which higher level libraries
+can be based. Examples of such libraries include a date/time library and a
+physical quantities library.
+
+Two general purpose facilities are proposed:
+
+ common_type
+ ratio
+
+And 5 time/duration/clock facilities are proposed
+
+ duration
+ time_point
+ system_clock
+ monotonic_clock <font color="#c80000">// optional</font>
+ high_resolution_clock <font color="#c80000">// optional</font>
+
+Much thanks to Andrei Alexandrescu,
+ Walter Brown,
+ Peter Dimov,
+ Jeff Garland,
+ Terry Golubiewski,
+ Daniel Krügler,
+ Anthony Williams.
+
+Synopsis
+
+namespace std
+{
+
+<font color="#c80000">// <type_traits></font>
+
+<font color="#c80000">// common_type</font>
+
+<font color="#c80000">// common_type is ageneral purpose trait that can be specialized for user-defined types.</font>
+<font color="#c80000">// The semantics are intended to be identical to finding the resulting type of a</font>
+<font color="#c80000">// the conditional operator.</font>
+<font color="#c80000">// The client may need to specialize common_type if he wishes to convert to or from</font>
+<font color="#c80000">// another type only explicitly. It is used to determine the result type</font>
+<font color="#c80000">// in "mixed-mode" duration and time_point arithmetic. It will also find use in</font>
+<font color="#c80000">// similar "mixed-mode" arithmetic applications.</font>
+
+template <class T, class U>
+struct common_type
+{
+private:
+ static T t();
+ static U u();
+public:
+ typedef decltype(true ? t() : u()) type;
+};
+
+<font color="#c80000">// or...</font>
+
+template <class ...T> struct common_type;
+
+template <class T>
+struct common_type<T>
+{
+ typedef T type;
+};
+
+template <class T, class U>
+struct common_type<T, U>
+{
+private:
+ static T t();
+ static U u();
+public:
+ typedef decltype(true ? t() : u()) type;
+};
+
+template <class T, class U, class ...V>
+struct common_type<T, U, V...>
+{
+ typedef typename common_type<typename common_type<T, U>::type, V...>::type type;
+};
+
+<font color="#c80000">// This alternative variadic formulation of common_type has some advantages:</font>
+<font color="#c80000">//</font>
+<font color="#c80000">// 1. The obvious advantage is that it can handle 3 or more arguments seamlessly.</font>
+<font color="#c80000">// This can come in handy when writing template functions that take more than</font>
+<font color="#c80000">// two arguments, such as fma(x, y, z).</font>
+<font color="#c80000">//</font>
+<font color="#c80000">// 2. We could just get rid of identity (avoiding the legacy conflict) and use</font>
+<font color="#c80000">// common_type<T>::type in the one place we use identity<T>::type today.</font>
+<font color="#c80000">//</font>
+<font color="#c80000">// 3. For clients that need to specialize common_type (such as duration and time_point),</font>
+<font color="#c80000">// the client still needs to specialize only the two-argument version. The default</font>
+<font color="#c80000">// definition of the higher-order common_type will automatically use the client's</font>
+<font color="#c80000">// specialized two-argument version.</font>
+<font color="#c80000">// For example:</font>
+<font color="#c80000">// common_type<duration<double>, hours, microseconds>::type is duration<double, micro></font>
+
+<font color="#c80000">// ... end or</font>
+
+<font color="#c80000">// The cost of not including either version of common_type is that it is very likely that</font>
+<font color="#c80000">// the implementation would include it anyway, but spell it __common_type instead. This</font>
+<font color="#c80000">// would prevent authors of arithmetic emulators from using their classes as representations</font>
+<font color="#c80000">// with durations unless the emulator had exactly one implicit conversion to or from an</font>
+<font color="#c80000">// arithmetic type. This would be a large loss of functionality from the client's point</font>
+<font color="#c80000">// of view, possibly mandating a less safe interface for the client's arithmetic emulator.</font>
+
+<font color="#c80000">// ratio</font>
+
+<font color="#c80000">// ratio is a general purpose type allowing one to easily and safely compute integral</font>
+<font color="#c80000">// ratio values at compile time. The ratio class catches all errors (such as divide by</font>
+<font color="#c80000">// zero and overflow) at compile time. It is used in the duration and time_point libraries</font>
+<font color="#c80000">// to efficiently create units of time. It can also be used in other "quantity"</font>
+<font color="#c80000">// libraries (both std-defined and user-defined), or anywhere there is an integral</font>
+<font color="#c80000">// ratio which is known at compile time. The use of this utility can greatly reduce</font>
+<font color="#c80000">// the chances of run time overflow because the ratio (and any ratios resulting from</font>
+<font color="#c80000">// ratio arithmetic) are always reduced to lowest terms.</font>
+
+<font color="#c80000">// The cost of not including ratio would mean that the implementor would likely have this</font>
+<font color="#c80000">// functionality anyway, but spell it __ratio instead. This would prevent the client from</font>
+<font color="#c80000">// using ratio in his own code as demonstrated in the "User1" example. Furthermore duration</font>
+<font color="#c80000">// would have to be templated on two long long's instead of on ratio like so:</font>
+<font color="#c80000">//</font>
+<font color="#c80000">// template <class Rep, long long N, long long D> duration.</font>
+<font color="#c80000">//</font>
+<font color="#c80000">// This would mean that clients wanting to build a custom duration type (say a nanosecond</font>
+<font color="#c80000">// represented by a double) would have to write:</font>
+<font color="#c80000">//</font>
+<font color="#c80000">// duration<double, 1, 1000000000LL></font>
+<font color="#c80000">//</font>
+<font color="#c80000">// instead of:</font>
+<font color="#c80000">//</font>
+<font color="#c80000">// duration<double, nano></font>
+<font color="#c80000">//</font>
+<font color="#c80000">// This lack of syntatic niceness, along with the loss of functionality in the reuse of</font>
+<font color="#c80000">// ratio in user-written code seems to indicate that the loss of ratio would be a sizeable</font>
+<font color="#c80000">// loss to client code.</font>
+
+template <intmax_t N, intmax_t D = 1>
+class ratio
+{
+ <font color="#c80000">// For every possible value of N and D, abs(N) >= 0 and abs(D) > 0</font>
+ static_assert(__static_abs<N>::value >= 0, "ratio numerator is out of range");
+ static_assert(__static_abs<D>::value > 0, "ratio denominator is out of range");
+public:
+ static const intmax_t num; <font color="#c80000">// Reduced by greatest common divisor of N and D, has sign of sign(N) * sign(D)</font>
+ static const intmax_t den; <font color="#c80000">// Reduced by greatest common divisor of N and D, always positive</font>
+ <font color="#c80000">// When num == 0, den == 1</font>
+};
+
+<font color="#c80000">// The static_asserts in ratio are there to catch any values which have a negative absolute value.</font>
+<font color="#c80000">// In a typical 2's complement representation this is only LLONG_MIN. The reason for prohibiting</font>
+<font color="#c80000">// this value is because ratio must take the absolute values of its arguments and generally depends</font>
+<font color="#c80000">// on that number being non-negative in order to maintain invariants such as den > 0.</font>
+
+<font color="#c80000">// convenience typedefs</font>
+
+typedef ratio<1, 1000000000000000000000000> yocto; <font color="#c80000">// conditionally supported</font>
+typedef ratio<1, 1000000000000000000000> zepto; <font color="#c80000">// conditionally supported</font>
+typedef ratio<1, 1000000000000000000> atto;
+typedef ratio<1, 1000000000000000> femto;
+typedef ratio<1, 1000000000000> pico;
+typedef ratio<1, 1000000000> nano;
+typedef ratio<1, 1000000> micro;
+typedef ratio<1, 1000> milli;
+typedef ratio<1, 100> centi;
+typedef ratio<1, 10> deci;
+typedef ratio< 10, 1> deca;
+typedef ratio< 100, 1> hecto;
+typedef ratio< 1000, 1> kilo;
+typedef ratio< 1000000, 1> mega;
+typedef ratio< 1000000000, 1> giga;
+typedef ratio< 1000000000000, 1> tera;
+typedef ratio< 1000000000000000, 1> peta;
+typedef ratio< 1000000000000000000, 1> exa;
+typedef ratio< 1000000000000000000000, 1> zetta; <font color="#c80000">// conditionally supported</font>
+typedef ratio<1000000000000000000000000, 1> yotta; <font color="#c80000">// conditionally supported</font>
+
+<font color="#c80000">// Compile time arithmetic and comparisons should either avoid overflow or not compile</font>
+
+template <class R1, class R2>
+requires R1 and R2 are instantiations of ratio
+struct ratio_add
+{
+ typedef ratio<pseudo code: R1 + R2> type;
+};
+
+template <class R1, class R2>
+requires R1 and R2 are instantiations of ratio
+struct ratio_subtract
+{
+ typedef ratio<pseudo code: R1 - R2> type;
+};
+
+template <class R1, class R2>
+requires R1 and R2 are instantiations of ratio
+struct ratio_multiply
+{
+ typedef ratio<pseudo code: R1 * R2> type;
+};
+
+template <class R1, class R2>
+requires R1 and R2 are instantiations of ratio
+struct ratio_divide
+{
+ typedef ratio<pseudo code: R1 / R2> type;
+};
+
+template <class R1, class R2>
+requires R1 and R2 are instantiations of ratio
+struct ratio_equal
+ : public integral_constant<bool, pseudo code: R1 == R2> {};
+
+template <class R1, class R2>
+requires R1 and R2 are instantiations of ratio
+struct ratio_not_equal
+ : public integral_constant<bool, !ratio_equal<R1, R2>::value> {};
+
+template <class R1, class R2>
+requires R1 and R2 are instantiations of ratio
+struct ratio_less
+ : public integral_constant<bool, pseudo code: R1 < R2> {};
+
+template <class R1, class R2>
+requires R1 and R2 are instantiations of ratio
+struct ratio_less_equal
+ : public integral_constant<bool, !ratio_less<R2, R1>::value> {};
+
+template <class R1, class R2>
+requires R1 and R2 are instantiations of ratio
+struct ratio_greater
+ : public integral_constant<bool, ratio_less<R2, R1>::value> {};
+
+template <class R1, class R2>
+requires R1 and R2 are instantiations of ratio
+struct ratio_greater_equal
+ : public integral_constant<bool, !ratio_less<R1, R2>::value> {};
+
+namespace datetime
+{
+
+<font color="#c80000">// duration customization traits</font>
+
+<font color="#c80000">// Authors of arithmetic emulation types should specialize treat_as_floating_point</font>
+<font color="#c80000">// if their class emulates floating point and they want to use it as a duration's</font>
+<font color="#c80000">// representation.</font>
+
+template <class Rep> struct treat_as_floating_point
+ : is_floating_point<Rep> {};
+
+<font color="#c80000">// Authors of arithmetic emulation types should specialize duration_values</font>
+<font color="#c80000">// if they want to use it as a duration's representation, and the default</font>
+<font color="#c80000">// definition of duration_values does not have the correct behavior.</font>
+
+template <class Rep>
+struct duration_values
+{
+public:
+ static constexpr Rep zero() {return Rep(0);}
+ static constexpr Rep max() {return numeric_limits<Rep>::max();}
+ static constexpr Rep min() {return -max();}
+};
+
+<font color="#c80000">// Note: Rep(0) instead of Rep() is used for zero() because the author of Rep may</font>
+<font color="#c80000">// chose to have Rep() refer to an inderminant or unitialized value.</font>
+
+<font color="#c80000">// duration</font>
+
+<font color="#c80000">// A duration has a representation and a period.</font>
+<font color="#c80000">// </font>
+<font color="#c80000">// The representation is an arithmetic type, or a class emulating an arithmetic type.</font>
+<font color="#c80000">//</font>
+<font color="#c80000">// The period is the rational number of seconds between "ticks" of the duration. The</font>
+<font color="#c80000">// duration simply holds a count of the elapsed number of ticks (using the</font>
+<font color="#c80000">// representation), and that is related to seconds by multiplying by the period.</font>
+<font color="#c80000">// Note, this multiplication is only required when one needs to convert between</font>
+<font color="#c80000">// durations with different tick periods (e.g. milliseconds to microseconds).</font>
+<font color="#c80000">// </font>
+<font color="#c80000">// A duration has defalt construction and default copy semantics. One can also explicitly</font>
+<font color="#c80000">// construct a duration from its representation or something implicitly convertible to</font>
+<font color="#c80000">// its representation. If the representation is integral (or emulated integral) the</font>
+<font color="#c80000">// duration may not be constructed from a floating point (or emulated floating point)</font>
+<font color="#c80000">// type, even if that type is impilcitly convertible to the representation (the client</font>
+<font color="#c80000">// must explicitly convert such an argument as they pass it to the constructor if such</font>
+<font color="#c80000">// a conversion is desired).</font>
+<font color="#c80000">// </font>
+<font color="#c80000">// A duration may be implicitly constructible from another duration if the representations</font>
+<font color="#c80000">// of the two durations meet certain requirements. Let the representation of this duration</font>
+<font color="#c80000">// be Rep1 and the representation of the other duration be Rep2. Example representations</font>
+<font color="#c80000">// include int, long long, double, or a user-defined class which emulates one of these</font>
+<font color="#c80000">// arithmetic types. To qualify for implicit constructability Rep1 must be explicitly</font>
+<font color="#c80000">// constructible from Rep2. Note that implicit constructibility of Rep1 from Rep2 is not</font>
+<font color="#c80000">// required for this implicit construction between durations. Additionally the trait</font>
+<font color="#c80000">// common_type<Rep1, Rep2>::type must be well defined. If a conditional expression involving</font>
+<font color="#c80000">// these two types isn't valid, there must exist a common_type specialization which makes</font>
+<font color="#c80000">// the trait valid.</font>
+<font color="#c80000">// </font>
+<font color="#c80000">// The requirements put on the relationship between Rep1 and Rep2 are intended to be minimal,</font>
+<font color="#c80000">// and not require implicit conversions (which could be considered error prone by the author</font>
+<font color="#c80000">// of either of these representations).</font>
+<font color="#c80000">// </font>
+<font color="#c80000">// In addition to the above relationship between the representations, implicit constructability</font>
+<font color="#c80000">// also depends on whether the representation is considered floating point (or emulated floating</font>
+<font color="#c80000">// point) or integral (or emulated integral).</font>
+<font color="#c80000">// </font>
+<font color="#c80000">// If a duration has a floating point (or emulated floating point) representation it</font>
+<font color="#c80000">// is implicitly constructible from all other durations of any period (as long as</font>
+<font color="#c80000">// the representations are compatible as described above).</font>
+<font color="#c80000">// </font>
+<font color="#c80000">// If a duration has an integral (or emulated integral) representation it is implicitly</font>
+<font color="#c80000">// constructible from other integral-based durations which have a period which will exactly convert</font>
+<font color="#c80000">// to the period of this duration with no truncation error. More specifically, if the</font>
+<font color="#c80000">// period of this duration is P1, and the period of the other duration is P2, this</font>
+<font color="#c80000">// duration is implicitly constructible from the other duration if P2/P1 is a whole number</font>
+<font color="#c80000">// (as long as the representations are compatible as described above). Example:</font>
+<font color="#c80000">// microseconds has a period p1 = 1/1000000 seconds. milliseconds has a period</font>
+<font color="#c80000">// P2 = 1/1000 seconds. P2/P1 is (1/1000)/(1/1000000) = 1000000/1000 = 1000.</font>
+<font color="#c80000">// Therefore microseconds will implicitly construct from milliseconds (but not vice-versa).</font>
+<font color="#c80000">//</font>
+<font color="#c80000">// These rules involving integral representations are meant to prevent accidental truncatation</font>
+<font color="#c80000">// error. If truncation error is desired, a duration_cast facility is available to force it.</font>
+<font color="#c80000">// Example:</font>
+<font color="#c80000">// milliseconds ms(3); // ok, ms.count() == 3, which is 0.003 seconds</font>
+<font color="#c80000">// microseconds us = ms; // ok, us.count() == 3000 which is 0.003000 seconds</font>
+<font color="#c80000">// ++us; // ok, us.count() == 3001 which is 0.003001 seconds</font>
+<font color="#c80000">// ms = us; // won't compile, might truncate</font>
+<font color="#c80000">// ms = duration_cast<milliseconds>(us); // ok, ms.count() = 3, truncated a microsecond</font>
+<font color="#c80000">// </font>
+<font color="#c80000">// A duration has a single observer: rep count() const; which returns the stored</font>
+<font color="#c80000">// representation which holds the number of elapsed "ticks".</font>
+<font color="#c80000">// </font>
+<font color="#c80000">// A duration supports the following member arithmetic:</font>
+<font color="#c80000">// </font>
+<font color="#c80000">// duration operator+() const;</font>
+<font color="#c80000">// duration operator-() const;</font>
+<font color="#c80000">// duration& operator++();</font>
+<font color="#c80000">// duration operator++(int);</font>
+<font color="#c80000">// duration& operator--();</font>
+<font color="#c80000">// duration operator--(int);</font>
+<font color="#c80000">// </font>
+<font color="#c80000">// duration& operator+=(duration d);</font>
+<font color="#c80000">// duration& operator-=(duration d);</font>
+<font color="#c80000">// </font>
+<font color="#c80000">// duration& operator*=(rep rhs);</font>
+<font color="#c80000">// duration& operator/=(rep rhs);</font>
+<font color="#c80000">//</font>
+<font color="#c80000">// The arithmetic simply manipulates the "tick" count in the obvious way (e.g. operator++</font>
+<font color="#c80000">// increments the tick count by 1).</font>
+<font color="#c80000">// </font>
+<font color="#c80000">// A duration supports the following non-member arithmetic.</font>
+<font color="#c80000">// Let D1 represent duration<Rep1, Period1> and D2 represent duration<Rep2, Period2>.</font>
+<font color="#c80000">// </font>
+<font color="#c80000">// common_type<D1, D2>::type operator+( D1, D2); // returns a duration</font>
+<font color="#c80000">// common_type<D1, D2>::type operator-( D1, D2); // returns a duration</font>
+<font color="#c80000">// duration<common_type<D1::rep,Rep2>::type, D1::period> operator*( D1, Rep2); // returns a duration</font>
+<font color="#c80000">// duration<common_type<D1::rep,Rep2>::type, D1::period> operator*(Rep2, D1); // returns a duration</font>
+<font color="#c80000">// duration<common_type<D1::rep,Rep2>::type, D1::period> operator/( D1, Rep2); // returns a duration</font>
+<font color="#c80000">// common_type<D1::rep, D2::rep>::type operator/( D1, D2); // returns a scalar</font>
+<font color="#c80000">// </font>
+<font color="#c80000">// A duration D1 is fully equality and less-than comparable with any other duration D2, as</font>
+<font color="#c80000">// long as common_type<D1::rep, D2::rep> is well defined.</font>
+<font color="#c80000">// Example:</font>
+<font color="#c80000">// milliseconds ms(3); // ms.count() == 3, which is 0.003 seconds</font>
+<font color="#c80000">// microseconds us = ms; // us.count() == 3000 which is 0.003000 seconds</font>
+<font color="#c80000">// --us; // us.count() == 2999 which is 0.002999 seconds</font>
+<font color="#c80000">// assert(ms != us); // 3 milliseconds is not equal to 2999 microseconds</font>
+<font color="#c80000">// assert(ms > us); // 3 milliseconds is greater than 2999 microseconds</font>
+<font color="#c80000">// ++us; // us.count() == 3000 which is 0.003000 seconds</font>
+<font color="#c80000">// assert(ms == us); // 3 milliseconds is equal to 3000 microseconds</font>
+<font color="#c80000">//</font>
+<font color="#c80000">// Durations based on floating point representations are subject to round off error precisely the</font>
+<font color="#c80000">// same way their representations are.</font>
+<font color="#c80000">// </font>
+<font color="#c80000">// Arithmetic and comparisons among integral-based durations is not subject to truncation error or</font>
+<font color="#c80000">// round off error. If truncation error would result from the arithmetic (say</font>
+<font color="#c80000">// by converting a smaller period duration to a larger one) the expression will</font>
+<font color="#c80000">// not compile (unless duration_cast is used). If one performs arithmetic</font>
+<font color="#c80000">// involving the duration's representation (such as division), then truncation</font>
+<font color="#c80000">// will happen implicitly.</font>
+<font color="#c80000">// </font>
+<font color="#c80000">// Overflow error may silently happen with a duration. The std-defined durations</font>
+<font color="#c80000">// have a minimum range of +/- 292 years.</font>
+<font color="#c80000">// </font>
+<font color="#c80000">// A duration is a thin wrapper around its representation. sizeof(duration<Rep, Period>) == sizeof(Rep).</font>
+<font color="#c80000">// </font>
+<font color="#c80000">// A duration can represent units as small as 10^-18 seconds (attoseconds) and as large as 10^18 seconds</font>
+<font color="#c80000">// (about 30 billion years). The range of a duration is based on the range of its representation</font>
+<font color="#c80000">// combined with its period.</font>
+
+<font color="#c80000">// The cost of not including the flexibility to represent different "tick periods" in the duration</font>
+<font color="#c80000">// type would be a great loss of both flexibility, convenience and safety for the client. For example</font>
+<font color="#c80000">// if had just one duration type which counted nanoseconds (no matter how that count was represented),</font>
+<font color="#c80000">// then clients could never have the ability to traffic in picoseconds. And the only hope of reaching</font>
+<font color="#c80000">// beyond a +/- 292 year range with nanoseconds is to increase the number of bits in the representation</font>
+<font color="#c80000">// (such as a long long). Furthermore, if the client wanted to traffic in units larger than a nanosecond</font>
+<font color="#c80000">// (e.g. seconds) for convience, they would likely need to set up their own conversion constants and</font>
+<font color="#c80000">// convert manually.</font>
+<font color="#c80000">//</font>
+<font color="#c80000">// If the conversion constants are specified at run time, rather than as compile time integral constants,</font>
+<font color="#c80000">// then the client suffers a significant performance penalty as for every conversion one will have to</font>
+<font color="#c80000">// perform both a multiplication and a division. In contrast, when converting among any two units of</font>
+<font color="#c80000">// the set (hours, minutes, seconds, milliseconds, microseconds, nanoseconds), there need be only a</font>
+<font color="#c80000">// single multiplication *or* division (never both). This proposal makes every unit conversion as</font>
+<font color="#c80000">// efficient as if it had been coded by hand (see duration_cast). Furthermore duration_cast encapsulates</font>
+<font color="#c80000">// all unit conversions within a single uniform-syntax function which is easily used in generic code. There</font>
+<font color="#c80000">// is no need (or motivation) to set up a "hub-and-spoke" conversion regimen, so that the number of conversion</font>
+<font color="#c80000">// functions is O(N) rather than O(N^2).</font>
+
+template <class Rep, class Period = ratio<1>>
+requires Rep is an arithmetic type, or a class emulating an arithmetic type,
+ and not an instantiation of duration
+requires Period is an instantiation of ratio and represents a positive fraction
+class duration
+{
+public:
+ typedef Rep rep;
+ typedef Period period;
+private:
+ rep rep_; <font color="#c80000">// exposition only</font>
+public:
+ <font color="#c80000">// construction / destruction</font>
+ duration() = default;
+ template <class Rep2>
+ requires is_convertible<Rep2, rep>::value &&
+ (treat_as_floating_point<rep>::value ||
+ !treat_as_floating_point<rep>::value && !treat_as_floating_point<Rep2>::value)
+ explicit duration(const Rep2& r);
+ ~duration() = default;
+
+ <font color="#c80000">// copy semantics</font>
+ duration(const duration&) = default;
+ duration& operator=(const duration&) = default;
+
+ <font color="#c80000">// conversions</font>
+ template <class Rep2, class Period2>
+ requires Rep2 is explicitly convertible to rep &&
+ (treat_as_floating_point<rep>::value ||
+ !treat_as_floating_point<Rep2>::value && ratio_divide<Period2, period>::type::den == 1)
+ duration(const duration<Rep2, Period2>& d);
+
+ <font color="#c80000">// observer</font>
+
+ rep count() const;
+
+ <font color="#c80000">// arithmetic</font>
+
+ duration operator+() const;
+ duration operator-() const;
+ duration& operator++();
+ duration operator++(int);
+ duration& operator--();
+ duration operator--(int);
+
+ duration& operator+=(const duration& d);
+ duration& operator-=(const duration& d);
+
+ duration& operator*=(const rep& rhs);
+ duration& operator/=(const rep& rhs);
+
+ <font color="#c80000">// special values</font>
+
+ static constexpr duration zero();
+ static constexpr duration min();
+ static constexpr duration max();
+};
+
+<font color="#c80000">// convenience typedefs</font>
+
+typedef duration<int_least64_t, nano> nanoseconds; <font color="#c80000">// 10^-9 seconds</font>
+typedef duration<int_least55_t, micro> microseconds; <font color="#c80000">// 10^-6 seconds</font>
+typedef duration<int_least45_t, milli> milliseconds; <font color="#c80000">// 10^-3 seconds</font>
+typedef duration<int_least35_t > seconds; <font color="#c80000">// 1 second</font>
+typedef duration<int_least29_t, ratio< 60>> minutes; <font color="#c80000">// 60 seconds</font>
+typedef duration<int_least23_t, ratio<3600>> hours; <font color="#c80000">// 3600 seconds</font>
+
+<font color="#c80000">// duration_cast can be used to force a conversion between two durations (assuming</font>
+<font color="#c80000">// the source representation can be explicitly converted to the target representation).</font>
+<font color="#c80000">// Not all integral-based durations are implicitly convertible to another (to</font>
+<font color="#c80000">// avoid accidental truncation error). When truncation error is desired, the client</font>
+<font color="#c80000">// uses duration_cast to explicitly request the non-exact conversion. When</font>
+<font color="#c80000">// duration_cast is used to convert between durations which have an implicit conversion,</font>
+<font color="#c80000">// the behavior and performance of the conversion using duration_cast is identical to</font>
+<font color="#c80000">// that of the implicit conversion.</font>
+
+template <class ToDuration, class Rep, class Period>
+ requires ToDuration is an instantiation of duration
+ ToDuration duration_cast(const duration<Rep, Period>& fd);
+
+<font color="#c80000">// Examples:</font>
+<font color="#c80000">// microseconds us(3500); // 3500 microseconds</font>
+<font color="#c80000">// milliseconds ms = us; // Does not compile (implicit truncation)</font>
+<font color="#c80000">// milliseconds ms = duration_cast<milliseconds>(us); // 3 milliseconds (explicit truncation)</font>
+<font color="#c80000">// us = ms; // 3000 microseconds</font>
+<font color="#c80000">// us = duration_cast<microseconds>(ms); // 3000 microseconds</font>
+
+} <font color="#c80000">// datetime</font>
+
+<font color="#c80000">// Given two durations: duration<Rep1, Period1> and duration<Rep2, Period2>, the common_type</font>
+<font color="#c80000">// of those two durations is a duration with a representation of common_type<Rep1, Rep2>,</font>
+<font color="#c80000">// and a period which is the "greatest common period" of Period1 and Period2. The GCP</font>
+<font color="#c80000">// (Greatest Common Period) of Period1 and Period2 is the largest period which will divide</font>
+<font color="#c80000">// both Period1 and Period2 evenly (and is often equivalent to the minimum of Period1 and</font>
+<font color="#c80000">// Period2). This can be computed (by the implementation at compile time) by</font>
+<font color="#c80000">// GCD(Period1::num, Period2::num) / LCM(Period1::den, Period2::den) where GCD is</font>
+<font color="#c80000">// "Greatest Common Divisor" and LCM is "Least Common Multiple".</font>
+
+template <class Rep1, class Period1, class Rep2, class Period2>
+struct common_type<datetime::duration<Rep1, Period1>, datetime::duration<Rep2, Period2> >
+{
+ typedef datetime::duration<typename common_type<Rep1, Rep2>::type,
+ ratio<GCD(Period1::num, Period2::num), LCM(Period1::den, Period2::den)>> type;
+};
+
+<font color="#c80000">// Note: For any two durations D1 and D2, they will both exactly convert to common_type<D1, D2>::type.</font>
+<font color="#c80000">// common_type<D1, D2>::type will have the largest possible period to make this possible, and</font>
+<font color="#c80000">// may be the same type as D1 or D2. Examples:</font>
+<font color="#c80000">// common_type<minutes, microseconds>::type is microseconds.</font>
+<font color="#c80000">// common_type<milliseconds, microseconds>::type is microseconds.</font>
+<font color="#c80000">// common_type<nanoseconds, microseconds>::type is nanoseconds.</font>
+<font color="#c80000">//</font>
+<font color="#c80000">// A more complex example:</font>
+<font color="#c80000">// common_type< duration<long, milli>, duration<int, ratio<1,30>> >::type is</font>
+<font color="#c80000">// duration<long, ratio<1,3000>>. And both duration<long, milli> and </font>
+<font color="#c80000">// duration<int, ratio<1,30>> will exactly convert to duration<long, ratio<1,3000>>.</font>
+<font color="#c80000">// The former multitplies its representation by 3L and the latter converts its</font>
+<font color="#c80000">// representation to long and multiplies that result by 1000L. There exists no</font>
+<font color="#c80000">// duration with a larger period such that both duration<long, milli> and</font>
+<font color="#c80000">// duration<int, ratio<1,30>> will exactly convert to it.</font>
+
+namespace datetime {
+
+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);
+
+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>
+ requires Constructible<Rep1, typename common_type<Rep1, Rep2>::type>::value> &&
+ Constructible<Rep2, typename common_type<Rep1, Rep2>::type>::value>
+ duration<typename common_type<Rep1, Rep2>::type, Period>
+ operator*(const duration<Rep, Period>& d, const Rep2& s);
+
+template <class Rep1, class Period, class Rep2>
+ requires Constructible<Rep1, typename common_type<Rep1, Rep2>::type>::value> &&
+ Constructible<Rep2, typename common_type<Rep1, Rep2>::type>::value>
+ duration<typename common_type<Rep1, Rep2>::type, Period>
+ operator*(const Rep2& s, const duration<Rep, Period>& d);
+
+template <class Rep1, class Period, class Rep2>
+ requires Rep2 is not a duration &&
+ Constructible<Rep1, typename common_type<Rep1, Rep2>::type>::value> &&
+ Constructible<Rep2, typename common_type<Rep1, Rep2>::type>::value>
+ duration<typename common_type<Rep1, Rep2>::type, Period>
+ operator/(const duration<Rep, Period>& d, const Rep2& s);
+
+<font color="#c80000">// Note: the above 3 signatures can be approximated with is_convertible if concepts do not</font>
+<font color="#c80000">// make it into the language. Requiring only *explicit* convertibility between the Rep</font>
+<font color="#c80000">// types is strongly desired. One way or another, Rep2 must be constrained. Otherwise</font>
+<font color="#c80000">// the operators are overly generic.</font>
+
+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);
+
+<font color="#c80000">// time_point</font>
+
+<font color="#c80000">// A time_point represents an epoch plus or minus a duration. The relationship between a time_point</font>
+<font color="#c80000">// which represents "now" and the time_point's epoch is obtained via a clock. Each time_point is</font>
+<font color="#c80000">// tied to a specific clock. Thus, for any time_point, one can find the duration between that</font>
+<font color="#c80000">// point in time and now, and between that point in time, and its epoch.</font>
+<font color="#c80000">// </font>
+<font color="#c80000">// A time_point may be default constructed. This time_point represents the epoch. time_point has</font>
+<font color="#c80000">// default copy semantics.</font>
+<font color="#c80000">// </font>
+<font color="#c80000">// time_point may be explicitly constructed by a duration having the same representation and period as</font>
+<font color="#c80000">// the time_point. Any other duration which is implicitly convertible to the time_point's "native" duration can</font>
+<font color="#c80000">// also be used to explicitly construct the time_point. The meaning of this construction is identical to</font>
+<font color="#c80000">// time_point() + d.</font>
+<font color="#c80000">//</font>
+<font color="#c80000">// A time_point is implicitly constructible from another time_point if they share the same clock,</font>
+<font color="#c80000">// and the duration of this time_point is implicitly constructible from the duration of the other</font>
+<font color="#c80000">// time_point. A time_point constructed in this fashion will compare equal to the source time_point</font>
+<font color="#c80000">// after the construction.</font>
+<font color="#c80000">// </font>
+<font color="#c80000">// A time_point supports the following member arithmetic:</font>
+<font color="#c80000">// </font>
+<font color="#c80000">// time_point& operator+=(duration d);</font>
+<font color="#c80000">// time_point& operator-=(duration d);</font>
+<font color="#c80000">// </font>
+<font color="#c80000">// A time_point supports the following non-member arithmetic.</font>
+<font color="#c80000">// Let T1 represent time_point<Clock, Duration1>,</font>
+<font color="#c80000">// T2 represent time_point<Clock, Duration2>,</font>
+<font color="#c80000">// and D represent duration<Rep3, Period3>. Note that T1 and T2 must have the same Clock.</font>
+<font color="#c80000">// Attempts to interoperate times having different clocks results in a compile time failure.</font>
+<font color="#c80000">// </font>
+<font color="#c80000">// T2 operator+(T1, D); // return type is a time_point</font>
+<font color="#c80000">// T2 operator+( D, T1); // return type is a time_point</font>
+<font color="#c80000">// T2 operator-(T1, D); // return type is a time_point</font>
+<font color="#c80000">// D operator-(T1, T2); // return type is a duration</font>
+<font color="#c80000">// </font>
+<font color="#c80000">// A time_point T1 is fully equality and less-than comparable with any other time_point T2 which</font>
+<font color="#c80000">// has the same clock, and for which their durations are comparable.</font>
+<font color="#c80000">// </font>
+<font color="#c80000">// Times based on floating point representations are subject to round off error precisely the</font>
+<font color="#c80000">// same way their representations are.</font>
+<font color="#c80000">// </font>
+<font color="#c80000">// Times based on integral representations are not subject to truncation error or round off</font>
+<font color="#c80000">// error. A compile time error will result if truncation error is possible. Truncation error</font>
+<font color="#c80000">// is only possible with construction or the member arithmetic (and won't compile). Non-member</font>
+<font color="#c80000">// arithmetic and comparison is always exact. Overflow error with integral based times remains a</font>
+<font color="#c80000">// possibility.</font>
+<font color="#c80000">// </font>
+<font color="#c80000">// A time_point is a thin wrapper around its representation.</font>
+<font color="#c80000">// sizeof(time_point<Clock, Duration>) == sizeof(Duration) == sizeof(Duration::rep).</font>
+<font color="#c80000">// </font>
+<font color="#c80000">// A time_point can represent units as small as 10^-18 seconds and as large as 10^18 seconds. The range</font>
+<font color="#c80000">// of a time_point is based on the range of its representation combined with its period.</font>
+<font color="#c80000">//</font>
+<font color="#c80000">// Because no two clocks report the exact same time, even clocks which nominally have the same</font>
+<font color="#c80000">// epoch, are considered by this framework to have different epochs, if only by a few nanoseconds.</font>
+<font color="#c80000">// Converting time_points from one clock to another will involve synchronization of the clocks,</font>
+<font color="#c80000">// which can be viewed as a synchronization of their epochs. Such synchronization is clock specific</font>
+<font color="#c80000">// and beyond the scope of this API. A future API, or a platform specific API, can easily</font>
+<font color="#c80000">// write such a synchronization API, basing it on this API.</font>
+
+<font color="#c80000">// The cost of not including a time_point class is the lack of the ability to safely interact with</font>
+<font color="#c80000">// the concept of "epoch + duration". Without a separate type, the client is in danger of accidently</font>
+<font color="#c80000">// writing code that boils down to "epoch1 + duration1" + "epoch2 + duration2". Algebraically this</font>
+<font color="#c80000">// results in epoch1+epoch2 as a subexpression which is likely to be completely without meaning. What</font>
+<font color="#c80000">// would it mean to add New Years 1970 to the point in time at which your computer booted up? Or for</font>
+<font color="#c80000">// that matter, what is the meaning of "New Years 1970" + "New Years 1970"?</font>
+<font color="#c80000">//</font>
+<font color="#c80000">// Additionally this would force the duration type to play double duty as a time_point leading to</font>
+<font color="#c80000">// client confusion. For example POSIX has timespec represent a duration in nanosleep, and yet the</font>
+<font color="#c80000">// same type is used as a time_point in pthread_cond_timedwait and pthread_mutex_timedlock. The</font>
+<font color="#c80000">// confusion seems even more likely with a function such as clock_nanosleep where timespec can mean</font>
+<font color="#c80000">// either a duration or a time_point depending upon another argument to the function.</font>
+<font color="#c80000">//</font>
+<font color="#c80000">// In C++ we can easily mitigate such errors by detecting them at compile time. This is done through</font>
+<font color="#c80000">// the use of distinct types for these distinct concepts (even though both types have identical layout!).</font>
+
+template <class Clock, class Duration = typename Clock::duration>
+requires Duration is an instantiation of duration
+class time_point
+{
+public:
+ typedef Clock clock;
+ typedef Duration duration;
+ typedef typename duration::rep rep;
+ typedef typename duration::period period;
+private:
+ duration d_; <font color="#c80000">// exposition only</font>
+
+public:
+ time_point(); <font color="#c80000">// has value "epoch"</font>
+ explicit time_point(const duration& d); <font color="#c80000">// same as time_point() + d</font>
+
+ <font color="#c80000">// conversions</font>
+ template <class Duration2>
+ requires Convertible<Duration2, duration>
+ time_point(const time_point<clock, Duration2>& t);
+
+ <font color="#c80000">// observer</font>
+
+ duration time_since_epoch() const;
+
+ <font color="#c80000">// arithmetic</font>
+
+ time_point& operator+=(const duration& d);
+ time_point& operator-=(const duration& d);
+
+ <font color="#c80000">// special values</font>
+
+ static time_point min();
+ static time_point max();
+};
+
+} <font color="#c80000">// datetime</font>
+
+template <class Clock, class Duration1, class Duration2>
+struct common_type<datetime::time_point<Clock, Duration1>, datetime::time_point<Clock, Duration2> >
+{
+ typedef datetime::time_point<Clock, typename common_type<Duration1, Duration2>::type> type;
+};
+
+namespace datetime {
+
+template <class ToDuration, class Clock, class Duration>
+ time_point<Clock, ToDuration> time_point_cast(const time_point<Clock, Duration>& t);
+
+template <class Clock, class Duration1, class Duration2>
+ bool operator==(const time_point<Clock, Duration1>& lhs, const time_point<Clock, Duration2>& rhs);
+template <class Clock, class Duration1, class Duration2>
+ bool operator!=(const time_point<Clock, Duration1>& lhs, const time_point<Clock, Duration2>& rhs);
+template <class Clock, class Duration1, class Duration2>
+ bool operator< (const time_point<Clock, Duration1>& lhs, const time_point<Clock, Duration2>& rhs);
+template <class Clock, class Duration1, class Duration2>
+ bool operator<=(const time_point<Clock, Duration1>& lhs, const time_point<Clock, Duration2>& rhs);
+template <class Clock, class Duration1, class Duration2>
+ bool operator> (const time_point<Clock, Duration1>& lhs, const time_point<Clock, Duration2>& rhs);
+template <class Clock, class Duration1, class Duration2>
+ bool operator>=(const time_point<Clock, Duration1>& lhs, const time_point<Clock, Duration2>& rhs);
+
+template <class Clock, class Duration1, class Rep2, class Period2>
+ time_point<Clock, typename common_type<Duration1, duration<Rep2, Period2> >::type>
+ operator+(const time_point<Clock, Duration1>& lhs, const duration<Rep2, Period2>& rhs);
+
+template <class Rep1, class Period1, class Clock, class Duration2>
+ time_point<Clock, typename common_type<duration<Rep1, Period1>, Duration2>::type>
+ operator+(const duration<Rep1, Period1>& lhs, const time_point<Clock, Duration2>& rhs);
+
+template <class Clock, class Duration1, class Rep2, class Period2>
+ time_point<Clock, typename common_type<Duration1, duration<Rep2, Period2> >::type>
+ operator-(const time_point<Clock, Duration1>& lhs, const duration<Rep2, Period2>& rhs);
+
+template <class Clock, class Duration1, class Duration2>
+ typename common_type<Duration1, Duration2>::type
+ operator-(const time_point<Clock, Duration1>& lhs, const time_point<Clock, Duration2>& rhs);
+
+<font color="#c80000">// clocks</font>
+
+<font color="#c80000">// A clock specifies a representation, and a period. These specifications are used to</font>
+<font color="#c80000">// to define a clock's native duration and time_point types. A clock also has a function to get the current</font>
+<font color="#c80000">// time_point. A clock need not have any state.</font>
+
+<font color="#c80000">// The cost of not including separate types for clocks is that there is no better place to</font>
+<font color="#c80000">// bundle the "native" duration and time_point types for a clock with the functionality to</font>
+<font color="#c80000">// get the current time_point (what time is it now?). By bundling this information into a</font>
+<font color="#c80000">// type, the extension to support multiple clocks is both easy and obvious. The ability to</font>
+<font color="#c80000">// easily support multiple clocks in such a flexible yet simple and efficient manner is</font>
+<font color="#c80000">// very important. A client might (for example) write code with the clock as a generic</font>
+<font color="#c80000">// template parameter, and then easily experiment with different timers.</font>
+
+class system_clock
+{
+public:
+ typedef <unspecified> rep;
+ typedef ratio<unspecified, unspecified> period;
+ typedef datetime::duration<rep, period> duration;
+ typedef datetime::time_point<system_clock> time_point;
+ static const bool is_mononontic = <unspecified>;
+
+ static time_point now();
+
+ <font color="#c80000">// Map to C API</font>
+ static time_t to_time_t (const time_point& t);
+ static time_point from_time_t(time_t t);
+};
+
+class monotonic_clock <font color="#c80000">// optional</font>
+{
+public:
+ typedef <unspecified> rep;
+ typedef ratio<unspecified, unspecified> period;
+ typedef datetime::duration<rep, period> duration;
+ typedef datetime::time_point<monotonic_clock> time_point;
+ static const bool is_mononontic = true;
+
+ static time_point now();
+};
+
+class high_resolution_clock <font color="#c80000">// optional</font>
+{
+public:
+ typedef <unspecified> rep;
+ typedef ratio<unspecified, unspecified> period;
+ typedef datetime::duration<rep, period> duration;
+ typedef datetime::time_point<high_resolution_clock> time_point;
+ static const bool is_mononontic = <unspecified>;
+
+ static time_point now();
+};
+
+<font color="#c80000">// Note: These clocks may be three separate types, or typedefs to one or two common types.</font>
+
+} <font color="#c80000">// datetime</font>
+
+<font color="#c80000">//////////////////////////</font>
+<font color="#c80000">// Threading interface //</font>
+<font color="#c80000">//////////////////////////</font>
+
+<font color="#c80000">// timed_mutex</font>
+
+struct timed_mutex
+{
+public:
+ timed_mutex();
+ ~timed_mutex();
+
+ timed_mutex(const timed_mutex&) = delete;
+ timed_mutex& operator=(const timed_mutex&) = delete;
+
+ void lock();
+ bool try_lock();
+ template <class Rep, class Period>
+ bool try_lock_for(const datetime::duration<Rep, Period>& rel_time);
+ template <class Clock, class Duration>
+ bool try_lock_until(const datetime::time_point<Clock, Duration>& abs_time);
+ void unlock();
+
+ typedef unspecified native_handle_type; <font color="#c80000">// optional. example: pthread_mutex_t*</font>
+ native_handle_type native_handle(); <font color="#c80000">// optional</font>
+};
+
+<font color="#c80000">// recursive_timed_mutex</font>
+
+struct recursive_timed_mutex
+{
+public:
+ recursive_timed_mutex();
+ ~recursive_timed_mutex();
+
+ recursive_timed_mutex(const recursive_timed_mutex&) = delete;
+ recursive_timed_mutex& operator=(const recursive_timed_mutex&) = delete;
+
+ void lock();
+ bool try_lock();
+ template <class Rep, class Period>
+ bool try_lock_for(const datetime::duration<Rep, Period>& rel_time);
+ template <class Clock, class Duration>
+ bool try_lock_until(const datetime::time_point<Clock, Duration>& abs_time);
+ void unlock();
+
+ typedef unspecified native_handle_type; <font color="#c80000">// optional. example: pthread_mutex_t*</font>
+ native_handle_type native_handle(); <font color="#c80000">// optional</font>
+};
+
+<font color="#c80000">// unique_lock</font>
+
+template <class Mutex>
+class unique_lock
+{
+public:
+ typedef Mutex mutex_type;
+
+ unique_lock();
+ explicit unique_lock(mutex_type& m);
+ unique_lock(mutex_type& m, defer_lock_t);
+ unique_lock(mutex_type& m, try_to_lock_t);
+ unique_lock(mutex_type& m, adopt_lock_t);
+ template <class Rep, class Period>
+ unique_lock(mutex_type& m, const datetime::duration<Rep, Period>& rel_t);
+ template <class Clock, class Duration>
+ unique_lock(mutex_type& m, const datetime::time_point<Clock, Duration>& abs_time);
+ ~unique_lock();
+
+ unique_lock(unique_lock const&) = delete;
+ unique_lock& operator=(unique_lock const&) = delete;
+
+ unique_lock(unique_lock&& u);
+ unique_lock& operator=(unique_lock&& u);
+
+ void lock();
+ bool try_lock();
+ template <class Rep, class Period>
+ bool try_lock_for(const datetime::duration<Rep, Period>& rel_t);
+ template <class Clock, class Duration>
+ bool try_lock_until(const datetime::time_point<Clock, Duration>& abs_time);
+ void unlock();
+
+ bool owns_lock() const;
+ operator unspecified-bool-type () const;
+ mutex_type* mutex() const;
+
+ void swap(unique_lock&& u);
+ mutex_type* release();
+};
+
+<font color="#c80000">// condition_variable</font>
+
+class condition_variable
+{
+public:
+
+ condition_variable();
+ ~condition_variable();
+
+ condition_variable(const condition_variable&) = delete;
+ condition_variable& operator=(const condition_variable&) = delete;
+
+ void notify_one();
+ void notify_all();
+
+ void wait(unique_lock<mutex>& lock);
+ template <class Predicate>
+ void wait(unique_lock<mutex>& lock, Predicate pred);
+
+ template <class Clock, class Duration>
+ bool wait_until(unique_lock<mutex>& lock,
+ const datetime::time_point<Clock, Duration>& abs_time);
+ template <class Clock, class Duration, class Predicate>
+ bool wait_until(unique_lock<mutex>& lock,
+ const datetime::time_point<Clock, Duration>& abs_time,
+ Predicate pred);
+
+ template <class Rep, class Period>
+ bool wait_for(unique_lock<mutex>& lock, const datetime::duration<Rep, Period>& rel_time);
+ template <class Rep, class Period, class Predicate>
+ bool wait_for(unique_lock<mutex>& lock, const datetime::duration<Rep, Period>& rel_time,
+ Predicate pred);
+
+ typedef pthread_cond_t* native_handle_type;
+ native_handle_type native_handle();
+};
+
+<font color="#c80000">// condition_variable_any</font>
+
+class condition_variable_any
+{
+public:
+
+ condition_variable_any();
+ ~condition_variable_any();
+
+ condition_variable_any(const condition_variable_any&) = delete;
+ condition_variable_any& operator=(const condition_variable_any&) = delete;
+
+ void notify_one();
+ void notify_all();
+
+ template <class Lock>
+ void wait(Lock& lock);
+ template <class Lock, class Predicate>
+ void wait(Lock& lock, Predicate pred);
+
+ template <class Lock, class Clock, class Duration>
+ bool wait_until(Lock& lock, const datetime::time_point<Clock, Duration>& abs_time);
+ template <class Lock, class Clock, class Duration, class Predicate>
+ bool wait_until(Lock& lock, const datetime::time_point<Clock, Duration>& abs_time,
+ Predicate pred);
+
+ template <class Lock, class Rep, class Period>
+ bool wait_for(Lock& lock, const datetime::duration<Rep, Period>& rel_time);
+ template <class Lock, class Rep, class Period, class Predicate>
+ bool wait_for(Lock& lock, const datetime::duration<Rep, Period>& rel_time, Predicate pred);
+};
+
+<font color="#c80000">// sleep</font>
+
+namespace this_thread
+{
+
+ template <class Rep, class Period>
+ void sleep_for(const datetime::duration<Rep, Period>& rel_time);
+
+ template <class Clock, class Duration>
+ void sleep_until(const datetime::time_point<Clock, Duration>& abs_time);
+
+} <font color="#c80000">// this_thread</font>
+
+} <font color="#c80000">// std</font>
+
+*/</font>
+
+#include <ctime>
+#include <climits>
+#include <inttypes.h>
+#include <limits>
+#include "type_traits"
+
+#define decltype __typeof__
+
+namespace std
+{
+
+<font color="#c80000">//////////////////////////////////////////////////////////</font>
+<font color="#c80000">////////////////////// common_type ///////////////////////</font>
+<font color="#c80000">//////////////////////////////////////////////////////////</font>
+
+#define VARIADIC_COMMON_TYPE 0
+
+#if VARIADIC_COMMON_TYPE == 0
+
+template <class T, class U>
+struct common_type
+{
+private:
+ static T t();
+ static U u();
+public:
+ typedef decltype(true ? t() : u()) type;
+};
+
+#else
+
+template <class ...T> struct common_type;
+
+template <class T>
+struct common_type<T>
+{
+ typedef T type;
+};
+
+template <class T, class U>
+struct common_type<T, U>
+{
+private:
+ static T t();
+ static U u();
+public:
+ typedef decltype(true ? t() : u()) type;
+};
+
+template <class T, class U, class ...V>
+struct common_type<T, U, V...>
+{
+ typedef typename common_type<typename common_type<T, U>::type, V...>::type type;
+};
+
+#endif
+
+<font color="#c80000">//////////////////////////////////////////////////////////</font>
+<font color="#c80000">/////////////////////// ratio ////////////////////////////</font>
+<font color="#c80000">//////////////////////////////////////////////////////////</font>
+
+<font color="#c80000">// __static_gcd</font>
+
+template <intmax_t X, intmax_t Y>
+struct __static_gcd
+{
+ static const intmax_t value = __static_gcd<Y, X % Y>::value;
+};
+
+template <intmax_t X>
+struct __static_gcd<X, 0>
+{
+ static const intmax_t value = X;
+};
+
+<font color="#c80000">// __static_lcm</font>
+
+template <intmax_t X, intmax_t Y>
+struct __static_lcm
+{
+ static const intmax_t value = X / __static_gcd<X, Y>::value * Y;
+};
+
+template <intmax_t X>
+struct __static_abs
+{
+ static const intmax_t value = X < 0 ? -X : X;
+};
+
+template <intmax_t X>
+struct __static_sign
+{
+ static const intmax_t value = X == 0 ? 0 : (X < 0 ? -1 : 1);
+};
+
+template <intmax_t X, intmax_t Y, intmax_t = __static_sign<Y>::value>
+class __ll_add;
+
+template <intmax_t X, intmax_t Y>
+class __ll_add<X, Y, 1>
+{
+ static const intmax_t min = (1LL << (sizeof(intmax_t) * CHAR_BIT - 1)) + 1;
+ static const intmax_t max = -min;
+
+ static char test[X <= max - Y];
+<font color="#c80000">// static_assert(X <= max - Y, "overflow in __ll_add");</font>
+public:
+ static const intmax_t value = X + Y;
+};
+
+template <intmax_t X, intmax_t Y>
+class __ll_add<X, Y, 0>
+{
+public:
+ static const intmax_t value = X;
+};
+
+template <intmax_t X, intmax_t Y>
+class __ll_add<X, Y, -1>
+{
+ static const intmax_t min = (1LL << (sizeof(intmax_t) * CHAR_BIT - 1)) + 1;
+ static const intmax_t max = -min;
+
+ static char test[min - Y <= X];
+<font color="#c80000">// static_assert(min - Y <= X, "overflow in __ll_add");</font>
+public:
+ static const intmax_t value = X + Y;
+};
+
+template <intmax_t X, intmax_t Y, intmax_t = __static_sign<Y>::value>
+class __ll_sub;
+
+template <intmax_t X, intmax_t Y>
+class __ll_sub<X, Y, 1>
+{
+ static const intmax_t min = (1LL << (sizeof(intmax_t) * CHAR_BIT - 1)) + 1;
+ static const intmax_t max = -min;
+
+ static char test[min + Y <= X];
+<font color="#c80000">// static_assert(min + Y <= X, "overflow in __ll_sub");</font>
+public:
+ static const intmax_t value = X - Y;
+};
+
+template <intmax_t X, intmax_t Y>
+class __ll_sub<X, Y, 0>
+{
+public:
+ static const intmax_t value = X;
+};
+
+template <intmax_t X, intmax_t Y>
+class __ll_sub<X, Y, -1>
+{
+ static const intmax_t min = (1LL << (sizeof(intmax_t) * CHAR_BIT - 1)) + 1;
+ static const intmax_t max = -min;
+
+ static char test[X <= max + Y];
+<font color="#c80000">// static_assert(X <= max + Y, "overflow in __ll_sub");</font>
+public:
+ static const intmax_t value = X - Y;
+};
+
+template <intmax_t X, intmax_t Y>
+class __ll_mul
+{
+ static const intmax_t nan = (1LL << (sizeof(intmax_t) * CHAR_BIT - 1));
+ static const intmax_t min = nan + 1;
+ static const intmax_t max = -min;
+ static const intmax_t __a_x = __static_abs<X>::value;
+ static const intmax_t __a_y = __static_abs<Y>::value;
+
+ static char test1[X != nan];
+ static char test2[Y != nan];
+ static char test[__a_x <= max / __a_y];
+<font color="#c80000">// static_assert(X != nan && Y != nan && __a_x <= max / __a_y, "overflow in __ll_mul");</font>
+public:
+ static const intmax_t value = X * Y;
+};
+
+template <intmax_t Y>
+class __ll_mul<0, Y>
+{
+public:
+ static const intmax_t value = 0;
+};
+
+template <intmax_t X>
+class __ll_mul<X, 0>
+{
+public:
+ static const intmax_t value = 0;
+};
+
+template <>
+class __ll_mul<0, 0>
+{
+public:
+ static const intmax_t value = 0;
+};
+
+<font color="#c80000">// Not actually used but left here in case needed in future maintenance</font>
+template <intmax_t X, intmax_t Y>
+class __ll_div
+{
+ static const intmax_t nan = (1LL << (sizeof(intmax_t) * CHAR_BIT - 1));
+ static const intmax_t min = nan + 1;
+ static const intmax_t max = -min;
+
+ static char test1[X != nan];
+ static char test2[Y != nan];
+ static char test3[Y != 0];
+<font color="#c80000">// static_assert(X != nan && Y != nan && Y != 0, "overflow in __ll_div");</font>
+public:
+ static const intmax_t value = X / Y;
+};
+
+template <intmax_t N, intmax_t D = 1>
+class ratio
+{
+ static char test1[__static_abs<N>::value >= 0];
+ static char test2[__static_abs<D>::value > 0];
+<font color="#c80000">// static_assert(__static_abs<N>::value >= 0, "ratio numerator is out of range");</font>
+<font color="#c80000">// static_assert(D != 0, "ratio divide by 0");</font>
+<font color="#c80000">// static_assert(__static_abs<D>::value > 0, "ratio denominator is out of range");</font>
+ static const intmax_t __na = __static_abs<N>::value;
+ static const intmax_t __da = __static_abs<D>::value;
+ static const intmax_t __s = __static_sign<N>::value * __static_sign<D>::value;
+ static const intmax_t __gcd = __static_gcd<__na, __da>::value;
+public:
+ static const intmax_t num = __s * __na / __gcd;
+ static const intmax_t den = __da / __gcd;
+};
+
+template <class T> struct ___is_ratio : tmp::false_type {};
+template <intmax_t N, intmax_t D> struct ___is_ratio<ratio<N, D> > : tmp::true_type {};
+template <class T> struct __is_ratio : ___is_ratio<typename tmp::remove_cv<T>::type> {};
+
+typedef ratio<1LL, 1000000000000000000LL> atto;
+typedef ratio<1LL, 1000000000000000LL> femto;
+typedef ratio<1LL, 1000000000000LL> pico;
+typedef ratio<1LL, 1000000000LL> nano;
+typedef ratio<1LL, 1000000LL> micro;
+typedef ratio<1LL, 1000LL> milli;
+typedef ratio<1LL, 100LL> centi;
+typedef ratio<1LL, 10LL> deci;
+typedef ratio< 10LL, 1LL> deca;
+typedef ratio< 100LL, 1LL> hecto;
+typedef ratio< 1000LL, 1LL> kilo;
+typedef ratio< 1000000LL, 1LL> mega;
+typedef ratio< 1000000000LL, 1LL> giga;
+typedef ratio< 1000000000000LL, 1LL> tera;
+typedef ratio< 1000000000000000LL, 1LL> peta;
+typedef ratio<1000000000000000000LL, 1LL> exa;
+
+template <class R1, class R2>
+struct ratio_add
+{
+ typedef ratio<__ll_add<__ll_mul<R1::num, R2::den>::value,
+ __ll_mul<R1::den, R2::num>::value>::value,
+ __ll_mul<R1::den, R2::den>::value> type;
+};
+
+template <class R1, class R2>
+struct ratio_subtract
+{
+ typedef ratio<__ll_sub<__ll_mul<R1::num, R2::den>::value,
+ __ll_mul<R1::den, R2::num>::value>::value,
+ __ll_mul<R1::den, R2::den>::value> type;
+};
+
+template <class R1, class R2>
+struct ratio_multiply
+{
+ typedef ratio<__ll_mul<R1::num, R2::num>::value, __ll_mul<R1::den, R2::den>::value> type;
+};
+
+template <class R1, class R2>
+struct ratio_divide
+{
+ typedef ratio<__ll_mul<R1::num, R2::den>::value, __ll_mul<R1::den, R2::num>::value> type;
+};
+
+<font color="#c80000">// ratio_equal</font>
+
+template <class R1, class R2>
+struct ratio_equal
+ : public tmp::integral_constant<bool, R1::num == R2::num && R1::den == R2::den> {};
+
+template <class R1, class R2>
+struct ratio_not_equal
+ : public tmp::integral_constant<bool, !ratio_equal<R1, R2>::value> {};
+
+<font color="#c80000">// ratio_less</font>
+
+<font color="#c80000">// Protect against overflow, and still get the right answer as much as possible.</font>
+<font color="#c80000">// This just demonstrates for fun how far you can push things without hitting</font>
+<font color="#c80000">// overflow. The obvious and simple implementation is conforming.</font>
+
+template <class R1, class R2, bool ok1, bool ok2>
+struct __ratio_less3 <font color="#c80000">// true, true and false, false</font>
+{
+ static const bool value = __ll_mul<R1::num, R2::den>::value < __ll_mul<R2::num, R1::den>::value;
+};
+
+template <class R1, class R2>
+struct __ratio_less3<R1, R2, true, false>
+{
+ static const bool value = true;
+};
+
+template <class R1, class R2>
+struct __ratio_less3<R1, R2, false, true>
+{
+ static const bool value = false;
+};
+
+template <class R1, class R2, bool = R1::num < R1::den == R2::num < R2::den>
+struct __ratio_less2 <font color="#c80000">// N1 < D1 == N2 < D2</font>
+{
+ static const intmax_t max = -((1LL << (sizeof(intmax_t) * CHAR_BIT - 1)) + 1);
+ static const bool ok1 = R1::num <= max / R2::den;
+ static const bool ok2 = R2::num <= max / R1::den;
+ static const bool value = __ratio_less3<R1, R2, ok1, ok2>::value;
+};
+
+template <class R1, class R2>
+struct __ratio_less2<R1, R2, false> <font color="#c80000">// N1 < D1 != N2 < D2</font>
+{
+ static const bool value = R1::num < R1::den;
+};
+
+template <class R1, class R2, bool = R1::num < R1::den == R2::num < R2::den>
+struct __ratio_less1 <font color="#c80000">// N1 < D1 == N2 < D2</font>
+{
+ static const bool value = __ratio_less2<ratio<R1::num, R2::num>, ratio<R1::den, R2::den> >::value;
+};
+
+template <class R1, class R2>
+struct __ratio_less1<R1, R2, false> <font color="#c80000">// N1 < D1 != N2 < D2</font>
+{
+ static const bool value = R1::num < R1::den;
+};
+
+template <class R1, class R2, intmax_t S1 = __static_sign<R1::num>::value,
+ intmax_t S2 = __static_sign<R2::num>::value>
+struct __ratio_less
+{
+ static const bool value = S1 < S2;
+};
+
+template <class R1, class R2>
+struct __ratio_less<R1, R2, 1LL, 1LL>
+{
+ static const bool value = __ratio_less1<R1, R2>::value;
+};
+
+template <class R1, class R2>
+struct __ratio_less<R1, R2, -1LL, -1LL>
+{
+ static const bool value = __ratio_less1<ratio<-R2::num, R2::den>, ratio<-R1::num, R1::den> >::value;
+};
+
+template <class R1, class R2>
+struct ratio_less
+ : public tmp::integral_constant<bool, __ratio_less<R1, R2>::value> {};
+
+template <class R1, class R2>
+struct ratio_less_equal
+ : public tmp::integral_constant<bool, !ratio_less<R2, R1>::value> {};
+
+template <class R1, class R2>
+struct ratio_greater
+ : public tmp::integral_constant<bool, ratio_less<R2, R1>::value> {};
+
+template <class R1, class R2>
+struct ratio_greater_equal
+ : public tmp::integral_constant<bool, !ratio_less<R1, R2>::value> {};
+
+template <class R1, class R2>
+struct __ratio_gcd
+{
+ typedef ratio<__static_gcd<R1::num, R2::num>::value,
+ __static_lcm<R1::den, R2::den>::value> type;
+};
+
+<font color="#c80000">//////////////////////////////////////////////////////////</font>
+<font color="#c80000">////////////////////// duration //////////////////////////</font>
+<font color="#c80000">//////////////////////////////////////////////////////////</font>
+
+namespace datetime
+{
+
+template <class RepType, class Period = ratio<1> > class duration;
+
+template <class T> struct ___is_duration : tmp::false_type {};
+template <class Rep, class Period> struct ___is_duration<duration<Rep, Period> > : tmp::true_type {};
+template <class T> struct __is_duration : ___is_duration<typename tmp::remove_cv<T>::type> {};
+
+<font color="#c80000">// duration_cast</font>
+
+<font color="#c80000">// duration_cast is the heart of this whole prototype. It can convert any</font>
+<font color="#c80000">// duration to any other. It is also (implicitly) used in converting</font>
+<font color="#c80000">// time_points. The conversion is always exact if possible. And it is</font>
+<font color="#c80000">// always as efficient as hand written code. If different representations</font>
+<font color="#c80000">// are involved, care is taken to never require implicit conversions.</font>
+<font color="#c80000">// Instead static_cast is used explicitly for every required conversion.</font>
+<font color="#c80000">// If there are a mixture of integral and floating point representations,</font>
+<font color="#c80000">// the use of common_type ensures that the most logical "intermediate"</font>
+<font color="#c80000">// representation is used.</font>
+template <class FromDuration, class ToDuration,
+ class Period = typename ratio_divide<typename FromDuration::period, typename ToDuration::period>::type,
+ bool = Period::num == 1,
+ bool = Period::den == 1>
+struct __duration_cast;
+
+<font color="#c80000">// When the two periods are the same, all that is left to do is static_cast from</font>
+<font color="#c80000">// the source representation to the target representation (which may be a no-op).</font>
+<font color="#c80000">// This conversion is always exact as long as the static_cast from the source</font>
+<font color="#c80000">// representation to the destination representation is exact.</font>
+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()));
+ }
+};
+
+<font color="#c80000">// When the numerator of FromPeriod / ToPeriod is 1, then all we need to do is</font>
+<font color="#c80000">// divide by the denominator of FromPeriod / ToPeriod. The common_type of</font>
+<font color="#c80000">// the two representations is used for the intermediate computation before</font>
+<font color="#c80000">// static_cast'ing to the destination.</font>
+<font color="#c80000">// This conversion is generally not exact because of the division (but could be</font>
+<font color="#c80000">// if you get lucky on the run time value of fd.count()).</font>
+template <class FromDuration, class ToDuration, class Period>
+struct __duration_cast<FromDuration, ToDuration, Period, true, false>
+{
+ ToDuration operator()(const FromDuration& fd) const
+ {
+#if VARIADIC_COMMON_TYPE == 0
+ typedef typename common_type<
+ typename common_type<typename ToDuration::rep, typename FromDuration::rep>::type,
+ intmax_t>::type C;
+#else
+ typedef typename common_type<typename ToDuration::rep, typename FromDuration::rep, intmax_t>::type C;
+#endif
+ return ToDuration(static_cast<typename ToDuration::rep>(
+ static_cast<C>(fd.count()) / static_cast<C>(Period::den)));
+ }
+};
+
+<font color="#c80000">// When the denomenator of FromPeriod / ToPeriod is 1, then all we need to do is</font>
+<font color="#c80000">// multiply by the numerator of FromPeriod / ToPeriod. The common_type of</font>
+<font color="#c80000">// the two representations is used for the intermediate computation before</font>
+<font color="#c80000">// static_cast'ing to the destination.</font>
+<font color="#c80000">// This conversion is always exact as long as the static_cast's involved are exact.</font>
+template <class FromDuration, class ToDuration, class Period>
+struct __duration_cast<FromDuration, ToDuration, Period, false, true>
+{
+ ToDuration operator()(const FromDuration& fd) const
+ {
+#if VARIADIC_COMMON_TYPE == 0
+ typedef typename common_type<
+ typename common_type<typename ToDuration::rep, typename FromDuration::rep>::type,
+ intmax_t>::type C;
+#else
+ typedef typename common_type<typename ToDuration::rep, typename FromDuration::rep, intmax_t>::type C;
+#endif
+ return ToDuration(static_cast<typename ToDuration::rep>(
+ static_cast<C>(fd.count()) * static_cast<C>(Period::num)));
+ }
+};
+
+<font color="#c80000">// When neither the numerator or denominator of FromPeriod / ToPeriod is 1, then we need to</font>
+<font color="#c80000">// multiply by the numerator and divide by the denominator of FromPeriod / ToPeriod. The</font>
+<font color="#c80000">// common_type of the two representations is used for the intermediate computation before</font>
+<font color="#c80000">// static_cast'ing to the destination.</font>
+<font color="#c80000">// This conversion is generally not exact because of the division (but could be</font>
+<font color="#c80000">// if you get lucky on the run time value of fd.count()).</font>
+template <class FromDuration, class ToDuration, class Period>
+struct __duration_cast<FromDuration, ToDuration, Period, false, false>
+{
+ ToDuration operator()(const FromDuration& fd) const
+ {
+#if VARIADIC_COMMON_TYPE == 0
+ typedef typename common_type<
+ typename common_type<typename ToDuration::rep, typename FromDuration::rep>::type,
+ intmax_t>::type C;
+#else
+ typedef typename common_type<typename ToDuration::rep, typename FromDuration::rep, intmax_t>::type C;
+#endif
+ return ToDuration(static_cast<typename ToDuration::rep>(
+ static_cast<C>(fd.count()) * static_cast<C>(Period::num) / static_cast<C>(Period::den)));
+ }
+};
+
+<font color="#c80000">// Compile-time select the most efficient algorithm for the conversion...</font>
+template <class ToDuration, class Rep, class Period>
+inline
+typename tmp::enable_if
+<
+ __is_duration<ToDuration>::value,
+ ToDuration
+>::type
+duration_cast(const duration<Rep, Period>& fd)
+{
+ return __duration_cast<duration<Rep, Period>, ToDuration>()(fd);
+}
+
+<font color="#c80000">// Support bidirectional (non-exact) conversions for floating point rep types</font>
+<font color="#c80000">// (or user defined rep types which specialize treat_as_floating_point).</font>
+template <class Rep> struct treat_as_floating_point : tmp::is_floating_point<Rep> {};
+
+template <class Rep>
+struct duration_values
+{
+ static Rep __min_imp(tmp::false_type) {return -max();}
+ static Rep __min_imp(tmp::true_type) {return zero();}
+public:
+ static Rep zero() {return Rep(0);}
+ static Rep max() {return numeric_limits<Rep>::max();}
+ static Rep min() {return __min_imp(tmp::is_unsigned<Rep>());}
+};
+
+<font color="#c80000">// duration</font>
+
+template <class Rep, class Period>
+class duration
+{
+ static char test0[!__is_duration<Rep>::value];
+<font color="#c80000">// static_assert(!__is_duration<Rep>::value, "A duration representation can not be a duration");</font>
+ static char test1[__is_ratio<Period>::value];
+<font color="#c80000">// static_assert(__is_ratio<Period>::value, "Second template parameter of duration must be a std::ratio");</font>
+ static char test2[Period::num > 0];
+<font color="#c80000">// static_assert(Period::num > 0, "duration period must be positive");</font>
+public:
+ typedef Rep rep;
+ typedef Period period;
+private:
+ rep rep_;
+public:
+
+ duration() {} <font color="#c80000">// = default;</font>
+ template <class Rep2>
+ explicit duration(const Rep2& r,
+ typename tmp::enable_if
+ <
+ tmp::is_convertible<Rep2, rep>::value &&
+ (treat_as_floating_point<rep>::value ||
+ !treat_as_floating_point<rep>::value && !treat_as_floating_point<Rep2>::value)
+ >::type* = 0)
+ : rep_(r) {}
+
+ <font color="#c80000">// conversions</font>
+ template <class Rep2, class Period2>
+ duration(const duration<Rep2, Period2>& d,
+ typename tmp::enable_if
+ <
+ treat_as_floating_point<rep>::value ||
+ (ratio_divide<Period2, period>::type::den == 1 && !treat_as_floating_point<Rep2>::value)
+ >::type* = 0)
+ : rep_(duration_cast<duration>(d).count()) {}
+
+ <font color="#c80000">// observer</font>
+
+ rep count() const {return rep_;}
+
+ <font color="#c80000">// arithmetic</font>
+
+ 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;}
+
+ <font color="#c80000">// special values</font>
+
+ static duration zero() {return duration(duration_values<rep>::zero());}
+ static duration min() {return duration(duration_values<rep>::min());}
+ static duration max() {return duration(duration_values<rep>::max());}
+};
+
+typedef duration<long long, nano> nanoseconds;
+typedef duration<long long, micro> microseconds;
+typedef duration<long long, milli> milliseconds;
+typedef duration<long long > seconds;
+typedef duration< long, ratio< 60> > minutes;
+typedef duration< long, ratio<3600> > hours;
+
+} <font color="#c80000">// datetime</font>
+
+template <class Rep1, class Period1, class Rep2, class Period2>
+struct common_type<datetime::duration<Rep1, Period1>, datetime::duration<Rep2, Period2> >
+{
+ typedef datetime::duration<typename common_type<Rep1, Rep2>::type,
+ typename __ratio_gcd<Period1, Period2>::type> type;
+};
+
+namespace datetime {
+
+<font color="#c80000">// Duration ==</font>
+
+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 Rep1, class Period1, class Rep2, class Period2>
+inline
+bool
+operator==(const duration<Rep1, Period1>& lhs, const duration<Rep2, Period2>& rhs)
+{
+ return __duration_eq<duration<Rep1, Period1>, duration<Rep2, Period2> >()(lhs, rhs);
+}
+
+<font color="#c80000">// Duration !=</font>
+
+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);
+}
+
+<font color="#c80000">// Duration <</font>
+
+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();}
+};
+
+template <class Rep1, class Period1, class Rep2, class Period2>
+inline
+bool
+operator< (const duration<Rep1, Period1>& lhs, const duration<Rep2, Period2>& rhs)
+{
+ return __duration_lt<duration<Rep1, Period1>, duration<Rep2, Period2> >()(lhs, rhs);
+}
+
+<font color="#c80000">// Duration ></font>
+
+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;
+}
+
+<font color="#c80000">// Duration <=</font>
+
+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);
+}
+
+<font color="#c80000">// Duration >=</font>
+
+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);
+}
+
+<font color="#c80000">// Duration +</font>
+
+template <class Rep1, class Period1, class Rep2, class Period2>
+inline
+typename common_type<duration<Rep1, Period1>, duration<Rep2, Period2> >::type
+operator+(const duration<Rep1, Period1>& lhs, const duration<Rep2, Period2>& rhs)
+{
+ typename common_type<duration<Rep1, Period1>, duration<Rep2, Period2> >::type result = lhs;
+ result += rhs;
+ return result;
+}
+
+<font color="#c80000">// Duration -</font>
+
+template <class Rep1, class Period1, class Rep2, class Period2>
+inline
+typename common_type<duration<Rep1, Period1>, duration<Rep2, Period2> >::type
+operator-(const duration<Rep1, Period1>& lhs, const duration<Rep2, Period2>& rhs)
+{
+ typename common_type<duration<Rep1, Period1>, duration<Rep2, Period2> >::type result = lhs;
+ result -= rhs;
+ return result;
+}
+
+<font color="#c80000">// Duration *</font>
+
+template <class Rep1, class Period, class Rep2>
+inline
+typename tmp::enable_if
+<
+ tmp::is_convertible<Rep1, typename common_type<Rep1, Rep2>::type>::value &&
+ tmp::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)
+{
+ typedef typename 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
+typename tmp::enable_if
+<
+ tmp::is_convertible<Rep1, typename common_type<Rep1, Rep2>::type>::value &&
+ tmp::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)
+{
+ return d * s;
+}
+
+<font color="#c80000">// Duration /</font>
+
+template <class Duration, class Rep, bool = __is_duration<Rep>::value>
+struct __duration_divide_result
+{
+};
+
+template <class Duration, class Rep2,
+ bool = tmp::is_convertible<typename Duration::rep,
+ typename common_type<typename Duration::rep, Rep2>::type>::value &&
+ tmp::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 Rep1, class Period, class Rep2>
+inline
+typename __duration_divide_result<duration<Rep1, Period>, Rep2>::type
+operator/(const duration<Rep1, Period>& d, const Rep2& s)
+{
+ typedef typename 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 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();
+}
+
+<font color="#c80000">//////////////////////////////////////////////////////////</font>
+<font color="#c80000">///////////////////// time_point /////////////////////////</font>
+<font color="#c80000">//////////////////////////////////////////////////////////</font>
+
+template <class Clock, class Duration = typename Clock::duration>
+class time_point
+{
+ static char test1[__is_duration<Duration>::value];
+<font color="#c80000">// static_assert(__is_duration<Duration>::value,</font>
+<font color="#c80000">// "Second template parameter of time_point must be a std::datetime::duration");</font>
+public:
+ typedef Clock clock;
+ typedef Duration duration;
+ typedef typename duration::rep rep;
+ typedef typename duration::period period;
+private:
+ duration d_;
+
+public:
+ time_point() : d_(duration::zero()) {}
+ explicit time_point(const duration& d) : d_(d) {}
+
+ <font color="#c80000">// conversions</font>
+ template <class Duration2>
+ time_point(const time_point<clock, Duration2>& t,
+ typename tmp::enable_if
+ <
+ tmp::is_convertible<Duration2, duration>::value
+ >::type* = 0)
+ : d_(t.time_since_epoch()) {}
+
+ <font color="#c80000">// observer</font>
+
+ duration time_since_epoch() const {return d_;}
+
+ <font color="#c80000">// arithmetic</font>
+
+ time_point& operator+=(const duration& d) {d_ += d; return *this;}
+ time_point& operator-=(const duration& d) {d_ -= d; return *this;}
+
+ <font color="#c80000">// special values</font>
+
+ static time_point min() {return time_point(duration::min());}
+ static time_point max() {return time_point(duration::max());}
+};
+
+} <font color="#c80000">// datetime</font>
+
+template <class Clock, class Duration1, class Duration2>
+struct common_type<datetime::time_point<Clock, Duration1>, datetime::time_point<Clock, Duration2> >
+{
+ typedef datetime::time_point<Clock, typename common_type<Duration1, Duration2>::type> type;
+};
+
+namespace datetime {
+
+template <class ToDuration, class Clock, class Duration>
+inline
+time_point<Clock, ToDuration>
+time_point_cast(const time_point<Clock, Duration>& t)
+{
+ return time_point<Clock, ToDuration>(duration_cast<ToDuration>(t.time_since_epoch()));
+}
+
+<font color="#c80000">// time_point ==</font>
+
+template <class Clock, class Duration1, class Duration2>
+inline
+bool
+operator==(const time_point<Clock, Duration1>& lhs, const time_point<Clock, Duration2>& rhs)
+{
+ return lhs.time_since_epoch() == rhs.time_since_epoch();
+}
+
+<font color="#c80000">// time_point !=</font>
+
+template <class Clock, class Duration1, class Duration2>
+inline
+bool
+operator!=(const time_point<Clock, Duration1>& lhs, const time_point<Clock, Duration2>& rhs)
+{
+ return !(lhs == rhs);
+}
+
+<font color="#c80000">// time_point <</font>
+
+template <class Clock, class Duration1, class Duration2>
+inline
+bool
+operator<(const time_point<Clock, Duration1>& lhs, const time_point<Clock, Duration2>& rhs)
+{
+ return lhs.time_since_epoch() < rhs.time_since_epoch();
+}
+
+<font color="#c80000">// time_point ></font>
+
+template <class Clock, class Duration1, class Duration2>
+inline
+bool
+operator>(const time_point<Clock, Duration1>& lhs, const time_point<Clock, Duration2>& rhs)
+{
+ return rhs < lhs;
+}
+
+<font color="#c80000">// time_point <=</font>
+
+template <class Clock, class Duration1, class Duration2>
+inline
+bool
+operator<=(const time_point<Clock, Duration1>& lhs, const time_point<Clock, Duration2>& rhs)
+{
+ return !(rhs < lhs);
+}
+
+<font color="#c80000">// time_point >=</font>
+
+template <class Clock, class Duration1, class Duration2>
+inline
+bool
+operator>=(const time_point<Clock, Duration1>& lhs, const time_point<Clock, Duration2>& rhs)
+{
+ return !(lhs < rhs);
+}
+
+<font color="#c80000">// time_point operator+(time_point x, duration y);</font>
+
+template <class Clock, class Duration1, class Rep2, class Period2>
+inline
+time_point<Clock, typename common_type<Duration1, duration<Rep2, Period2> >::type>
+operator+(const time_point<Clock, Duration1>& lhs, const duration<Rep2, Period2>& rhs)
+{
+ typedef time_point<Clock, typename common_type<Duration1, duration<Rep2, Period2> >::type> TimeResult;
+ TimeResult r(lhs);
+ r += rhs;
+ return r;
+}
+
+<font color="#c80000">// time_point operator+(duration x, time_point y);</font>
+
+template <class Rep1, class Period1, class Clock, class Duration2>
+inline
+time_point<Clock, typename common_type<duration<Rep1, Period1>, Duration2>::type>
+operator+(const duration<Rep1, Period1>& lhs, const time_point<Clock, Duration2>& rhs)
+{
+ return rhs + lhs;
+}
+
+<font color="#c80000">// time_point operator-(time_point x, duration y);</font>
+
+template <class Clock, class Duration1, class Rep2, class Period2>
+inline
+time_point<Clock, typename common_type<Duration1, duration<Rep2, Period2> >::type>
+operator-(const time_point<Clock, Duration1>& lhs, const duration<Rep2, Period2>& rhs)
+{
+ return lhs + (-rhs);
+}
+
+<font color="#c80000">// duration operator-(time_point x, time_point y);</font>
+
+template <class Clock, class Duration1, class Duration2>
+inline
+typename common_type<Duration1, Duration2>::type
+operator-(const time_point<Clock, Duration1>& lhs, const time_point<Clock, Duration2>& rhs)
+{
+ return lhs.time_since_epoch() - rhs.time_since_epoch();
+}
+
+<font color="#c80000">//////////////////////////////////////////////////////////</font>
+<font color="#c80000">/////////////////////// clocks ///////////////////////////</font>
+<font color="#c80000">//////////////////////////////////////////////////////////</font>
+
+<font color="#c80000">// If you're porting, clocks are the system-specific (non-portable) part.</font>
+<font color="#c80000">// You'll need to know how to get the current time and implement that under now().</font>
+<font color="#c80000">// You'll need to know what units (tick period) and representation makes the most</font>
+<font color="#c80000">// sense for your clock and set those accordingly.</font>
+<font color="#c80000">// If you know how to map this clock to time_t (perhaps your clock is std::time, which</font>
+<font color="#c80000">// makes that trivial), then you can fill out system_clock's to_time_t() and from_time_t().</font>
+
+class system_clock
+{
+public:
+ typedef microseconds duration;
+ typedef duration::rep rep;
+ typedef duration::period period;
+ typedef datetime::time_point<system_clock> time_point;
+ static const bool is_monotonic = false;
+
+ static time_point now();
+ static time_t to_time_t (const time_point& t);
+ static time_point from_time_t(time_t t);
+};
+
+class monotonic_clock
+{
+public:
+ typedef nanoseconds duration;
+ typedef duration::rep rep;
+ typedef duration::period period;
+ typedef datetime::time_point<monotonic_clock> time_point;
+ static const bool is_monotonic = true;
+
+ static time_point now();
+};
+
+typedef monotonic_clock high_resolution_clock;
+
+} <font color="#c80000">// datetime</font>
+} <font color="#c80000">// std</font>
+
+<font color="#c80000">// clocks.cpp</font>
+
+#include <sys/time.h> <font color="#c80000">//for gettimeofday and timeval</font>
+#include <mach/mach_time.h> <font color="#c80000">// mach_absolute_time, mach_timebase_info_data_t</font>
+
+namespace std {
+namespace datetime {
+
+<font color="#c80000">// system_clock</font>
+
+<font color="#c80000">// gettimeofday is the most precise "system time" available on this platform.</font>
+<font color="#c80000">// It returns the number of microseconds since New Years 1970 in a struct called timeval</font>
+<font color="#c80000">// which has a field for seconds and a field for microseconds.</font>
+<font color="#c80000">// Fill in the timeval and then convert that to the time_point</font>
+system_clock::time_point
+system_clock::now()
+{
+ timeval tv;
+ gettimeofday(&tv, 0);
+ return time_point(seconds(tv.tv_sec) + microseconds(tv.tv_usec));
+}
+
+<font color="#c80000">// Take advantage of the fact that on this platform time_t is nothing but</font>
+<font color="#c80000">// an integral count of seconds since New Years 1970 (same epoch as timeval).</font>
+<font color="#c80000">// Just get the duration out of the time_point and truncate it to seconds.</font>
+time_t
+system_clock::to_time_t(const time_point& t)
+{
+ return time_t(duration_cast<seconds>(t.time_since_epoch()).count());
+}
+
+<font color="#c80000">// Just turn the time_t into a count of seconds and construct a time_point with it.</font>
+system_clock::time_point
+system_clock::from_time_t(time_t t)
+{
+ return system_clock::time_point(seconds(t));
+}
+
+<font color="#c80000">// monotonic_clock</font>
+
+<font color="#c80000">// Note, in this implementation monotonic_clock and high_resolution_clock</font>
+<font color="#c80000">// are the same clock. They are both based on mach_absolute_time().</font>
+<font color="#c80000">// mach_absolute_time() * MachInfo.numer / MachInfo.denom is the number of</font>
+<font color="#c80000">// nanoseconds since the computer booted up. MachInfo.numer and MachInfo.denom</font>
+<font color="#c80000">// are run time constants supplied by the OS. This clock has no relationship</font>
+<font color="#c80000">// to the Gregorian calendar. It's main use is as a high resolution timer.</font>
+
+<font color="#c80000">// MachInfo.numer / MachInfo.denom is often 1 on the latest equipment. Specialize</font>
+<font color="#c80000">// for that case as an optimization.</font>
+static
+monotonic_clock::rep
+monotonic_simplified()
+{
+ return mach_absolute_time();
+}
+
+static
+double
+compute_monotonic_factor()
+{
+ mach_timebase_info_data_t MachInfo;
+ mach_timebase_info(&MachInfo);
+ return static_cast<double>(MachInfo.numer) / MachInfo.denom;
+}
+
+static
+monotonic_clock::rep
+monotonic_full()
+{
+ static const double factor = compute_monotonic_factor();
+ return static_cast<monotonic_clock::rep>(mach_absolute_time() * factor);
+}
+
+typedef monotonic_clock::rep (*FP)();
+
+static
+FP
+init_monotonic_clock()
+{
+ mach_timebase_info_data_t MachInfo;
+ mach_timebase_info(&MachInfo);
+ if (MachInfo.numer == MachInfo.denom)
+ return &monotonic_simplified;
+ return &monotonic_full;
+}
+
+monotonic_clock::time_point
+monotonic_clock::now()
+{
+ static FP fp = init_monotonic_clock();
+ return time_point(duration(fp()));
+}
+
+<font color="#c80000">// clocks.cpp end</font>
+
+} } <font color="#c80000">// std::datetime</font>
+
+<font color="#c80000">//////////////////////////////////////////////////////////</font>
+<font color="#c80000">///////////// simulated thread interface /////////////////</font>
+<font color="#c80000">//////////////////////////////////////////////////////////</font>
+
+#include <iostream>
+
+namespace std {
+
+void __print_time(datetime::system_clock::time_point t)
+{
+ using namespace datetime;
+ time_t c_time = system_clock::to_time_t(t);
+ std::tm* tmptr = std::localtime(&c_time);
+ system_clock::duration d = t.time_since_epoch();
+ std::cout << tmptr->tm_hour << ':' << tmptr->tm_min << ':' << tmptr->tm_sec
+ << '.' << (d - duration_cast<seconds>(d)).count();
+}
+
+namespace this_thread {
+
+template <class Rep, class Period>
+void sleep_for(const datetime::duration<Rep, Period>& d)
+{
+ datetime::microseconds t = datetime::duration_cast<datetime::microseconds>(d);
+ if (t < d)
+ ++t;
+ if (t > datetime::microseconds(0))
+ std::cout << "sleep_for " << t.count() << " microseconds\n";
+}
+
+template <class Clock, class Duration>
+void sleep_until(const datetime::time_point<Clock, Duration>& t)
+{
+ using namespace datetime;
+ typedef time_point<Clock, Duration> Time;
+ typedef system_clock::time_point SysTime;
+ if (t > Clock::now())
+ {
+ typedef typename common_type<typename Time::duration, typename SysTime::duration>::type D;
+ <font color="#c80000">/* auto */</font> D d = t - Clock::now();
+ microseconds us = duration_cast<microseconds>(d);
+ if (us < d)
+ ++us;
+ SysTime st = system_clock::now() + us;
+ std::cout << "sleep_until ";
+ __print_time(st);
+ std::cout << " which is " << (st - system_clock::now()).count() << " microseconds away\n";
+ }
+}
+
+} <font color="#c80000">// this_thread</font>
+
+struct mutex {};
+
+struct timed_mutex
+{
+ bool try_lock() {std::cout << "timed_mutex::try_lock()\n";}
+
+ template <class Rep, class Period>
+ bool try_lock_for(const datetime::duration<Rep, Period>& d)
+ {
+ datetime::microseconds t = datetime::duration_cast<datetime::microseconds>(d);
+ if (t <= datetime::microseconds(0))
+ return try_lock();
+ std::cout << "try_lock_for " << t.count() << " microseconds\n";
+ return true;
+ }
+
+ template <class Clock, class Duration>
+ bool try_lock_until(const datetime::time_point<Clock, Duration>& t)
+ {
+ using namespace datetime;
+ typedef time_point<Clock, Duration> Time;
+ typedef system_clock::time_point SysTime;
+ if (t <= Clock::now())
+ return try_lock();
+ typedef typename common_type<typename Time::duration, typename Clock::duration>::type D;
+ <font color="#c80000">/* auto */</font> D d = t - Clock::now();
+ microseconds us = duration_cast<microseconds>(d);
+ SysTime st = system_clock::now() + us;
+ std::cout << "try_lock_until ";
+ __print_time(st);
+ std::cout << " which is " << (st - system_clock::now()).count() << " microseconds away\n";
+ }
+};
+
+struct condition_variable
+{
+ template <class Rep, class Period>
+ bool wait_for(mutex&, const datetime::duration<Rep, Period>& d)
+ {
+ datetime::microseconds t = datetime::duration_cast<datetime::microseconds>(d);
+ std::cout << "wait_for " << t.count() << " microseconds\n";
+ return true;
+ }
+
+ template <class Clock, class Duration>
+ bool wait_until(mutex&, const datetime::time_point<Clock, Duration>& t)
+ {
+ using namespace datetime;
+ typedef time_point<Clock, Duration> Time;
+ typedef system_clock::time_point SysTime;
+ if (t <= Clock::now())
+ return false;
+ typedef typename common_type<typename Time::duration, typename Clock::duration>::type D;
+ <font color="#c80000">/* auto */</font> D d = t - Clock::now();
+ microseconds us = duration_cast<microseconds>(d);
+ SysTime st = system_clock::now() + us;
+ std::cout << "wait_until ";
+ __print_time(st);
+ std::cout << " which is " << (st - system_clock::now()).count() << " microseconds away\n";
+ }
+};
+
+} <font color="#c80000">// std</font>
+
+<font color="#c80000">//////////////////////////////////////////////////////////</font>
+<font color="#c80000">/////////////////// End of implemetation ////////////////</font>
+<font color="#c80000">//////////////////////////////////////////////////////////</font>
+
+<font color="#c80000">//////////////////////////////////////////////////////////</font>
+<font color="#c80000">//////////// Simple sleep and wait examples //////////////</font>
+<font color="#c80000">//////////////////////////////////////////////////////////</font>
+
+std::mutex m;
+std::timed_mutex mut;
+std::condition_variable cv;
+
+void basic_examples()
+{
+ std::cout << "Running basic examples\n";
+ using namespace std;
+ using namespace std::datetime;
+ system_clock::time_point time_limit = system_clock::now() + seconds(4) + milliseconds(500);
+ this_thread::sleep_for(seconds(3));
+ this_thread::sleep_for(nanoseconds(300));
+ this_thread::sleep_until(time_limit);
+<font color="#c80000">// this_thread::sleep_for(time_limit); // desired compile-time error</font>
+<font color="#c80000">// this_thread::sleep_until(seconds(3)); // desired compile-time error</font>
+ mut.try_lock_for(milliseconds(30));
+ mut.try_lock_until(time_limit);
+<font color="#c80000">// mut.try_lock_for(time_limit); // desired compile-time error</font>
+<font color="#c80000">// mut.try_lock_until(milliseconds(30)); // desired compile-time error</font>
+ cv.wait_for(m, minutes(1)); <font color="#c80000">// real code would put this in a loop</font>
+ cv.wait_until(m, time_limit); <font color="#c80000">// real code would put this in a loop</font>
+ <font color="#c80000">// For those who prefer floating point</font>
+ this_thread::sleep_for(duration<double>(0.25));
+ this_thread::sleep_until(system_clock::now() + duration<double>(1.5));
+}
+
+<font color="#c80000">//////////////////////////////////////////////////////////</font>
+<font color="#c80000">//////////////////// User1 Example ///////////////////////</font>
+<font color="#c80000">//////////////////////////////////////////////////////////</font>
+
+namespace User1
+{
+<font color="#c80000">// Example type-safe "physics" code interoperating with std::datetime::duration types</font>
+<font color="#c80000">// and taking advantage of the std::ratio infrastructure and design philosophy.</font>
+
+<font color="#c80000">// length - mimics std::datetime::duration except restricts representation to double.</font>
+<font color="#c80000">// Uses std::ratio facilities for length units conversions.</font>
+
+template <class Ratio>
+class length
+{
+public:
+ typedef Ratio ratio;
+private:
+ double len_;
+public:
+
+ length() : len_(1) {}
+ length(const double& len) : len_(len) {}
+
+ <font color="#c80000">// conversions</font>
+ template <class R>
+ length(const length<R>& d)
+ : len_(d.count() * std::ratio_divide<Ratio, R>::type::den /
+ std::ratio_divide<Ratio, R>::type::num) {}
+
+ <font color="#c80000">// observer</font>
+
+ double count() const {return len_;}
+
+ <font color="#c80000">// arithmetic</font>
+
+ length& operator+=(const length& d) {len_ += d.count(); return *this;}
+ length& operator-=(const length& d) {len_ -= d.count(); return *this;}
+
+ length operator+() const {return *this;}
+ length operator-() const {return length(-len_);}
+
+ length& operator*=(double rhs) {len_ *= rhs; return *this;}
+ length& operator/=(double rhs) {len_ /= rhs; return *this;}
+};
+
+<font color="#c80000">// Sparse sampling of length units</font>
+typedef length<std::ratio<1> > meter; <font color="#c80000">// set meter as "unity"</font>
+typedef length<std::centi> centimeter; <font color="#c80000">// 1/100 meter</font>
+typedef length<std::kilo> kilometer; <font color="#c80000">// 1000 meters</font>
+typedef length<std::ratio<254, 10000> > inch; <font color="#c80000">// 254/10000 meters</font>
+<font color="#c80000">// length takes ratio instead of two integral types so that definitions can be made like so:</font>
+typedef length<std::ratio_multiply<std::ratio<12>, inch::ratio>::type> foot; <font color="#c80000">// 12 inchs</font>
+typedef length<std::ratio_multiply<std::ratio<5280>, foot::ratio>::type> mile; <font color="#c80000">// 5280 feet</font>
+
+<font color="#c80000">// Need a floating point definition of seconds</font>
+typedef std::datetime::duration<double> seconds; <font color="#c80000">// unity</font>
+<font color="#c80000">// Demo of (scientific) support for sub-nanosecond resolutions</font>
+typedef std::datetime::duration<double, std::pico> picosecond; <font color="#c80000">// 10^-12 seconds</font>
+typedef std::datetime::duration<double, std::femto> femtosecond; <font color="#c80000">// 10^-15 seconds</font>
+typedef std::datetime::duration<double, std::atto> attosecond; <font color="#c80000">// 10^-18 seconds</font>
+
+<font color="#c80000">// A very brief proof-of-concept for SIUnits-like library</font>
+<font color="#c80000">// Hard-wired to floating point seconds and meters, but accepts other units (shown in testUser1())</font>
+template <class R1, class R2>
+class quantity
+{
+ double q_;
+public:
+ quantity() : q_(1) {}
+
+ double get() const {return q_;}
+ void set(double q) {q_ = q;}
+};
+
+template <>
+class quantity<std::ratio<1>, std::ratio<0> >
+{
+ double q_;
+public:
+ quantity() : q_(1) {}
+ quantity(seconds d) : q_(d.count()) {} <font color="#c80000">// note: only User1::seconds needed here</font>
+
+ double get() const {return q_;}
+ void set(double q) {q_ = q;}
+};
+
+template <>
+class quantity<std::ratio<0>, std::ratio<1> >
+{
+ double q_;
+public:
+ quantity() : q_(1) {}
+ quantity(meter d) : q_(d.count()) {} <font color="#c80000">// note: only User1::meter needed here</font>
+
+ double get() const {return q_;}
+ void set(double q) {q_ = q;}
+};
+
+template <>
+class quantity<std::ratio<0>, std::ratio<0> >
+{
+ double q_;
+public:
+ quantity() : q_(1) {}
+ quantity(double d) : q_(d) {}
+
+ double get() const {return q_;}
+ void set(double q) {q_ = q;}
+};
+
+<font color="#c80000">// Example SI-Units</font>
+typedef quantity<std::ratio<0>, std::ratio<0> > Scalar;
+typedef quantity<std::ratio<1>, std::ratio<0> > Time; <font color="#c80000">// second</font>
+typedef quantity<std::ratio<0>, std::ratio<1> > Distance; <font color="#c80000">// meter</font>
+typedef quantity<std::ratio<-1>, std::ratio<1> > Speed; <font color="#c80000">// meter/second</font>
+typedef quantity<std::ratio<-2>, std::ratio<1> > Acceleration; <font color="#c80000">// meter/second^2</font>
+
+template <class R1, class R2, class R3, class R4>
+quantity<typename std::ratio_subtract<R1, R3>::type, typename std::ratio_subtract<R2, R4>::type>
+operator/(const quantity<R1, R2>& x, const quantity<R3, R4>& y)
+{
+ typedef quantity<typename std::ratio_subtract<R1, R3>::type, typename std::ratio_subtract<R2, R4>::type> R;
+ R r;
+ r.set(x.get() / y.get());
+ return r;
+}
+
+template <class R1, class R2, class R3, class R4>
+quantity<typename std::ratio_add<R1, R3>::type, typename std::ratio_add<R2, R4>::type>
+operator*(const quantity<R1, R2>& x, const quantity<R3, R4>& y)
+{
+ typedef quantity<typename std::ratio_add<R1, R3>::type, typename std::ratio_add<R2, R4>::type> R;
+ R r;
+ r.set(x.get() * y.get());
+ return r;
+}
+
+template <class R1, class R2>
+quantity<R1, R2>
+operator+(const quantity<R1, R2>& x, const quantity<R1, R2>& y)
+{
+ typedef quantity<R1, R2> R;
+ R r;
+ r.set(x.get() + y.get());
+ return r;
+}
+
+template <class R1, class R2>
+quantity<R1, R2>
+operator-(const quantity<R1, R2>& x, const quantity<R1, R2>& y)
+{
+ typedef quantity<R1, R2> R;
+ R r;
+ r.set(x.get() - y.get());
+ return r;
+}
+
+<font color="#c80000">// Example type-safe physics function</font>
+Distance
+compute_distance(Speed v0, Time t, Acceleration a)
+{
+ return v0 * t + Scalar(.5) * a * t * t; <font color="#c80000">// if a units mistake is made here it won't compile</font>
+}
+
+} <font color="#c80000">// User1</font>
+
+#include <iostream>
+
+<font color="#c80000">// Exercise example type-safe physics function and show interoperation</font>
+<font color="#c80000">// of custom time durations (User1::seconds) and standard time durations (std::hours).</font>
+<font color="#c80000">// Though input can be arbitrary (but type-safe) units, output is always in SI-units</font>
+<font color="#c80000">// (a limitation of the simplified Units lib demoed here).</font>
+void testUser1()
+{
+ std::cout << "*************\n";
+ std::cout << "* testUser1 *\n";
+ std::cout << "*************\n";
+ User1::Distance d( User1::mile(110) );
+ User1::Time t( std::datetime::hours(2) );
+ User1::Speed s = d / t;
+ std::cout << "Speed = " << s.get() << " meters/sec\n";
+ User1::Acceleration a = User1::Distance( User1::foot(32.2) ) / User1::Time() / User1::Time();
+ std::cout << "Acceleration = " << a.get() << " meters/sec^2\n";
+ User1::Distance df = compute_distance(s, User1::Time( User1::seconds(0.5) ), a);
+ std::cout << "Distance = " << df.get() << " meters\n";
+ std::cout << "There are " << User1::mile::ratio::den << '/' << User1::mile::ratio::num << " miles/meter";
+ User1::meter mt = 1;
+ User1::mile mi = mt;
+ std::cout << " which is approximately " << mi.count() << '\n';
+ std::cout << "There are " << User1::mile::ratio::num << '/' << User1::mile::ratio::den << " meters/mile";
+ mi = 1;
+ mt = mi;
+ std::cout << " which is approximately " << mt.count() << '\n';
+ User1::attosecond as(1);
+ User1::seconds sec = as;
+ std::cout << "1 attosecond is " << sec.count() << " seconds\n";
+ std::cout << "sec = as; <font color="#c80000">// compiles\n";</font>
+ sec = User1::seconds(1);
+ as = sec;
+ std::cout << "1 second is " << as.count() << " attoseconds\n";
+ std::cout << "as = sec; <font color="#c80000">// compiles\n";</font>
+ std::cout << "\n";
+}
+
+<font color="#c80000">//////////////////////////////////////////////////////////</font>
+<font color="#c80000">//////////////////// User2 Example ///////////////////////</font>
+<font color="#c80000">//////////////////////////////////////////////////////////</font>
+
+<font color="#c80000">// Demonstrate User2:</font>
+<font color="#c80000">// A "saturating" signed integral type is developed. This type has +/- infinity and a nan</font>
+<font color="#c80000">// (like IEEE floating point) but otherwise obeys signed integral arithmetic.</font>
+<font color="#c80000">// This class is subsequently used as the rep in std::datetime::duration to demonstrate a</font>
+<font color="#c80000">// duration class that does not silently ignore overflow.</font>
+#include <ostream>
+#include <stdexcept>
+#include <climits>
+
+namespace User2
+{
+
+template <class I>
+class saturate
+{
+public:
+ typedef I int_type;
+
+ static const int_type nan = int_type(int_type(1) << (sizeof(int_type) * CHAR_BIT - 1));
+ static const int_type neg_inf = nan + 1;
+ static const int_type pos_inf = -neg_inf;
+private:
+ int_type i_;
+
+<font color="#c80000">// static_assert(std::is_integral<int_type>::value && std::is_signed<int_type>::value,</font>
+<font color="#c80000">// "saturate only accepts signed integral types");</font>
+<font color="#c80000">// static_assert(nan == -nan && neg_inf < pos_inf,</font>
+<font color="#c80000">// "saturate assumes two's complement hardware for signed integrals");</font>
+
+public:
+ saturate() : i_(nan) {}
+ explicit saturate(int_type i) : i_(i) {}
+ <font color="#c80000">// explicit</font>
+ operator int_type() const;
+
+ saturate& operator+=(saturate x);
+ saturate& operator-=(saturate x) {return *this += -x;}
+ saturate& operator*=(saturate x);
+ saturate& operator/=(saturate x);
+ saturate& operator%=(saturate x);
+
+ saturate operator- () const {return saturate(-i_);}
+ saturate& operator++() {*this += saturate(int_type(1)); return *this;}
+ saturate operator++(int) {saturate tmp(*this); ++(*this); return tmp;}
+ saturate& operator--() {*this -= saturate(int_type(1)); return *this;}
+ saturate operator--(int) {saturate tmp(*this); --(*this); return tmp;}
+
+ friend saturate operator+(saturate x, saturate y) {return x += y;}
+ friend saturate operator-(saturate x, saturate y) {return x -= y;}
+ friend saturate operator*(saturate x, saturate y) {return x *= y;}
+ friend saturate operator/(saturate x, saturate y) {return x /= y;}
+ friend saturate operator%(saturate x, saturate y) {return x %= y;}
+
+ friend bool operator==(saturate x, saturate y)
+ {
+ if (x.i_ == nan || y.i_ == nan)
+ return false;
+ return x.i_ == y.i_;
+ }
+
+ friend bool operator!=(saturate x, saturate y) {return !(x == y);}
+
+ friend bool operator<(saturate x, saturate y)
+ {
+ if (x.i_ == nan || y.i_ == nan)
+ return false;
+ return x.i_ < y.i_;
+ }
+
+ friend bool operator<=(saturate x, saturate y)
+ {
+ if (x.i_ == nan || y.i_ == nan)
+ return false;
+ return x.i_ <= y.i_;
+ }
+
+ friend bool operator>(saturate x, saturate y)
+ {
+ if (x.i_ == nan || y.i_ == nan)
+ return false;
+ return x.i_ > y.i_;
+ }
+
+ friend bool operator>=(saturate x, saturate y)
+ {
+ if (x.i_ == nan || y.i_ == nan)
+ return false;
+ return x.i_ >= y.i_;
+ }
+
+ friend std::ostream& operator<<(std::ostream& os, saturate s)
+ {
+ switch (s.i_)
+ {
+ case pos_inf:
+ return os << "inf";
+ case nan:
+ return os << "nan";
+ case neg_inf:
+ return os << "-inf";
+ };
+ return os << s.i_;
+ }
+};
+
+template <class I>
+saturate<I>::operator int_type() const
+{
+ switch (i_)
+ {
+ case nan:
+ case neg_inf:
+ case pos_inf:
+ throw std::out_of_range("saturate special value can not convert to int_type");
+ }
+ return i_;
+}
+
+template <class I>
+saturate<I>&
+saturate<I>::operator+=(saturate x)
+{
+ switch (i_)
+ {
+ case pos_inf:
+ switch (x.i_)
+ {
+ case neg_inf:
+ case nan:
+ i_ = nan;
+ }
+ return *this;
+ case nan:
+ return *this;
+ case neg_inf:
+ switch (x.i_)
+ {
+ case pos_inf:
+ case nan:
+ i_ = nan;
+ }
+ return *this;
+ }
+ switch (x.i_)
+ {
+ case pos_inf:
+ case neg_inf:
+ case nan:
+ i_ = x.i_;
+ return *this;
+ }
+ if (x.i_ >= 0)
+ {
+ if (i_ < pos_inf - x.i_)
+ i_ += x.i_;
+ else
+ i_ = pos_inf;
+ return *this;
+ }
+ if (i_ > neg_inf - x.i_)
+ i_ += x.i_;
+ else
+ i_ = neg_inf;
+ return *this;
+}
+
+template <class I>
+saturate<I>&
+saturate<I>::operator*=(saturate x)
+{
+ switch (i_)
+ {
+ case 0:
+ switch (x.i_)
+ {
+ case pos_inf:
+ case neg_inf:
+ case nan:
+ i_ = nan;
+ }
+ return *this;
+ case pos_inf:
+ switch (x.i_)
+ {
+ case nan:
+ case 0:
+ i_ = nan;
+ return *this;
+ }
+ if (x.i_ < 0)
+ i_ = neg_inf;
+ return *this;
+ case nan:
+ return *this;
+ case neg_inf:
+ switch (x.i_)
+ {
+ case nan:
+ case 0:
+ i_ = nan;
+ return *this;
+ }
+ if (x.i_ < 0)
+ i_ = pos_inf;
+ return *this;
+ }
+ switch (x.i_)
+ {
+ case 0:
+ i_ = 0;
+ return *this;
+ case nan:
+ i_ = nan;
+ return *this;
+ case pos_inf:
+ if (i_ < 0)
+ i_ = neg_inf;
+ else
+ i_ = pos_inf;
+ return *this;
+ case neg_inf:
+ if (i_ < 0)
+ i_ = pos_inf;
+ else
+ i_ = neg_inf;
+ return *this;
+ }
+ int s = (i_ < 0 ? -1 : 1) * (x.i_ < 0 ? -1 : 1);
+ i_ = i_ < 0 ? -i_ : i_;
+ int_type x_i_ = x.i_ < 0 ? -x.i_ : x.i_;
+ if (i_ <= pos_inf / x_i_)
+ i_ *= x_i_;
+ else
+ i_ = pos_inf;
+ i_ *= s;
+ return *this;
+}
+
+template <class I>
+saturate<I>&
+saturate<I>::operator/=(saturate x)
+{
+ switch (x.i_)
+ {
+ case pos_inf:
+ case neg_inf:
+ switch (i_)
+ {
+ case pos_inf:
+ case neg_inf:
+ case nan:
+ i_ = nan;
+ break;
+ default:
+ i_ = 0;
+ break;
+ }
+ return *this;
+ case nan:
+ i_ = nan;
+ return *this;
+ case 0:
+ switch (i_)
+ {
+ case pos_inf:
+ case neg_inf:
+ case nan:
+ return *this;
+ case 0:
+ i_ = nan;
+ return *this;
+ }
+ if (i_ > 0)
+ i_ = pos_inf;
+ else
+ i_ = neg_inf;
+ return *this;
+ }
+ switch (i_)
+ {
+ case 0:
+ case nan:
+ return *this;
+ case pos_inf:
+ case neg_inf:
+ if (x.i_ < 0)
+ i_ = -i_;
+ return *this;
+ }
+ i_ /= x.i_;
+ return *this;
+}
+
+template <class I>
+saturate<I>&
+saturate<I>::operator%=(saturate x)
+{
+<font color="#c80000">// *this -= *this / x * x; // definition</font>
+ switch (x.i_)
+ {
+ case nan:
+ case neg_inf:
+ case 0:
+ case pos_inf:
+ i_ = nan;
+ return *this;
+ }
+ switch (i_)
+ {
+ case neg_inf:
+ case pos_inf:
+ i_ = nan;
+ case nan:
+ return *this;
+ }
+ i_ %= x.i_;
+ return *this;
+}
+
+<font color="#c80000">// Demo overflow-safe integral durations ranging from picoseconds resolution to millennium resolution</font>
+typedef std::datetime::duration<saturate<long long>, std::pico > picoseconds;
+typedef std::datetime::duration<saturate<long long>, std::nano > nanoseconds;
+typedef std::datetime::duration<saturate<long long>, std::micro > microseconds;
+typedef std::datetime::duration<saturate<long long>, std::milli > milliseconds;
+typedef std::datetime::duration<saturate<long long> > seconds;
+typedef std::datetime::duration<saturate<long long>, std::ratio< 60LL> > minutes;
+typedef std::datetime::duration<saturate<long long>, std::ratio< 3600LL> > hours;
+typedef std::datetime::duration<saturate<long long>, std::ratio< 86400LL> > days;
+typedef std::datetime::duration<saturate<long long>, std::ratio< 31556952LL> > years;
+typedef std::datetime::duration<saturate<long long>, std::ratio<31556952000LL> > millennium;
+
+} <font color="#c80000">// User2</font>
+
+<font color="#c80000">// Demonstrate custom promotion rules (needed only if there are no implicit conversions)</font>
+namespace User2 { namespace detail {
+
+template <class T1, class T2, bool = tmp::is_integral<T1>::value>
+struct promote_helper;
+
+template <class T1, class T2>
+struct promote_helper<T1, saturate<T2>, true> <font color="#c80000">// integral</font>
+{
+ typedef typename std::common_type<T1, T2>::type rep;
+ typedef User2::saturate<rep> type;
+};
+
+template <class T1, class T2>
+struct promote_helper<T1, saturate<T2>, false> <font color="#c80000">// floating</font>
+{
+ typedef T1 type;
+};
+
+} }
+
+namespace std
+{
+
+template <class T1, class T2>
+struct common_type<User2::saturate<T1>, User2::saturate<T2> >
+{
+ typedef typename common_type<T1, T2>::type rep;
+ typedef User2::saturate<rep> type;
+};
+
+template <class T1, class T2>
+struct common_type<T1, User2::saturate<T2> >
+ : User2::detail::promote_helper<T1, User2::saturate<T2> > {};
+
+template <class T1, class T2>
+struct common_type<User2::saturate<T1>, T2>
+ : User2::detail::promote_helper<T2, User2::saturate<T1> > {};
+
+
+<font color="#c80000">// Demonstrate specialization of duration_values:</font>
+
+namespace datetime {
+
+template <class I>
+struct duration_values<User2::saturate<I> >
+{
+ typedef User2::saturate<I> Rep;
+public:
+ static Rep zero() {return Rep(0);}
+ static Rep max() {return Rep(Rep::pos_inf-1);}
+ static Rep min() {return -max();}
+};
+
+}
+
+}
+
+#include <iostream>
+
+void testUser2()
+{
+ std::cout << "*************\n";
+ std::cout << "* testUser2 *\n";
+ std::cout << "*************\n";
+ using namespace User2;
+ typedef seconds::rep sat;
+ years yr(sat(100));
+ std::cout << "100 years expressed as years = " << yr.count() << '\n';
+ nanoseconds ns = yr;
+ std::cout << "100 years expressed as nanoseconds = " << ns.count() << '\n';
+ ns += yr;
+ std::cout << "200 years expressed as nanoseconds = " << ns.count() << '\n';
+ ns += yr;
+ std::cout << "300 years expressed as nanoseconds = " << ns.count() << '\n';
+<font color="#c80000">// yr = ns; // does not compile</font>
+ std::cout << "yr = ns; <font color="#c80000">// does not compile\n";</font>
+<font color="#c80000">// picoseconds ps1 = yr; // does not compile, compile-time overflow in ratio arithmetic</font>
+ std::cout << "ps = yr; <font color="#c80000">// does not compile\n";</font>
+ ns = yr;
+ picoseconds ps = ns;
+ std::cout << "100 years expressed as picoseconds = " << ps.count() << '\n';
+ ps = ns / sat(1000);
+ std::cout << "0.1 years expressed as picoseconds = " << ps.count() << '\n';
+ yr = years(sat(-200000000));
+ std::cout << "200 million years ago encoded in years: " << yr.count() << '\n';
+ days d = std::datetime::duration_cast<days>(yr);
+ std::cout << "200 million years ago encoded in days: " << d.count() << '\n';
+ millennium c = std::datetime::duration_cast<millennium>(yr);
+ std::cout << "200 million years ago encoded in millennium: " << c.count() << '\n';
+ std::cout << "Demonstrate \"uninitialized protection\" behavior:\n";
+ seconds sec;
+ for (++sec; sec < seconds(sat(10)); ++sec)
+ ;
+ std::cout << sec.count() << '\n';
+ std::cout << "\n";
+}
+
+void testStdUser()
+{
+ std::cout << "***************\n";
+ std::cout << "* testStdUser *\n";
+ std::cout << "***************\n";
+ using namespace std::datetime;
+ hours hr = hours(100);
+ std::cout << "100 hours expressed as hours = " << hr.count() << '\n';
+ nanoseconds ns = hr;
+ std::cout << "100 hours expressed as nanoseconds = " << ns.count() << '\n';
+ ns += hr;
+ std::cout << "200 hours expressed as nanoseconds = " << ns.count() << '\n';
+ ns += hr;
+ std::cout << "300 hours expressed as nanoseconds = " << ns.count() << '\n';
+<font color="#c80000">// hr = ns; // does not compile</font>
+ std::cout << "hr = ns; <font color="#c80000">// does not compile\n";</font>
+<font color="#c80000">// hr * ns; // does not compile</font>
+ std::cout << "hr * ns; <font color="#c80000">// does not compile\n";</font>
+ duration<double> fs(2.5);
+ std::cout << "duration<double> has count() = " << fs.count() << '\n';
+<font color="#c80000">// seconds sec = fs; // does not compile</font>
+ std::cout << "seconds sec = duration<double> won't compile\n";
+ seconds sec = duration_cast<seconds>(fs);
+ std::cout << "seconds has count() = " << sec.count() << '\n';
+ std::cout << "\n";
+}
+
+<font color="#c80000">// timeval clock demo</font>
+<font color="#c80000">// Demonstrate the use of a timeval-like struct to be used as the representation</font>
+<font color="#c80000">// type for both duraiton and time_point.</font>
+
+namespace timeval_demo
+{
+
+class xtime {
+private:
+ long tv_sec;
+ long tv_usec;
+
+ void fixup() {
+ if (tv_usec < 0) {
+ tv_usec += 1000000;
+ --tv_sec;
+ }
+ }
+
+public:
+
+ explicit xtime(long sec, long usec) {
+ tv_sec = sec;
+ tv_usec = usec;
+ if (tv_usec < 0 || tv_usec >= 1000000) {
+ tv_sec += tv_usec / 1000000;
+ tv_usec %= 1000000;
+ fixup();
+ }
+ }
+
+ explicit xtime(long long usec)
+ {
+ tv_usec = static_cast<long>(usec % 1000000);
+ tv_sec = static_cast<long>(usec / 1000000);
+ fixup();
+ }
+
+ <font color="#c80000">// explicit</font>
+ operator long long() const {return static_cast<long long>(tv_sec) * 1000000 + tv_usec;}
+
+ xtime& operator += (xtime rhs) {
+ tv_sec += rhs.tv_sec;
+ tv_usec += rhs.tv_usec;
+ if (tv_usec >= 1000000) {
+ tv_usec -= 1000000;
+ ++tv_sec;
+ }
+ return *this;
+ }
+
+ xtime& operator -= (xtime rhs) {
+ tv_sec -= rhs.tv_sec;
+ tv_usec -= rhs.tv_usec;
+ fixup();
+ return *this;
+ }
+
+ xtime& operator %= (xtime rhs) {
+ long long t = tv_sec * 1000000 + tv_usec;
+ long long r = rhs.tv_sec * 1000000 + rhs.tv_usec;
+ t %= r;
+ tv_sec = t / 1000000;
+ tv_usec = t % 1000000;
+ fixup();
+ return *this;
+ }
+
+ friend xtime operator+(xtime x, xtime y) {return x += y;}
+ friend xtime operator-(xtime x, xtime y) {return x -= y;}
+ friend xtime operator%(xtime x, xtime y) {return x %= y;}
+
+ friend bool operator==(xtime x, xtime y)
+ { return (x.tv_sec == y.tv_sec && x.tv_usec == y.tv_usec); }
+
+ friend bool operator<(xtime x, xtime y) {
+ if (x.tv_sec == y.tv_sec)
+ return (x.tv_usec < y.tv_usec);
+ return (x.tv_sec < y.tv_sec);
+ }
+
+ friend bool operator!=(xtime x, xtime y) { return !(x == y); }
+ friend bool operator> (xtime x, xtime y) { return y < x; }
+ friend bool operator<=(xtime x, xtime y) { return !(y < x); }
+ friend bool operator>=(xtime x, xtime y) { return !(x < y); }
+
+ friend std::ostream& operator<<(std::ostream& os, xtime x)
+ {return os << '{' << x.tv_sec << ',' << x.tv_usec << '}';}
+};
+
+class xtime_clock
+{
+public:
+ typedef xtime rep;
+ typedef std::micro period;
+ typedef std::datetime::duration<rep, period> duration;
+ typedef std::datetime::time_point<xtime_clock> time_point;
+
+ static time_point now();
+};
+
+xtime_clock::time_point
+xtime_clock::now()
+{
+ time_point t(duration(xtime(0)));
+ gettimeofday((timeval*)&t, 0);
+ return t;
+}
+
+void test_xtime_clock()
+{
+ using namespace std::datetime;
+ std::cout << "timeval_demo system clock test\n";
+ std::cout << "sizeof xtime_clock::time_point = " << sizeof(xtime_clock::time_point) << '\n';
+ std::cout << "sizeof xtime_clock::duration = " << sizeof(xtime_clock::duration) << '\n';
+ std::cout << "sizeof xtime_clock::rep = " << sizeof(xtime_clock::rep) << '\n';
+ xtime_clock::duration delay(milliseconds(5));
+ xtime_clock::time_point start = xtime_clock::now();
+ while (xtime_clock::now() - start <= delay)
+ ;
+ xtime_clock::time_point stop = xtime_clock::now();
+ xtime_clock::duration elapsed = stop - start;
+ std::cout << "paused " << nanoseconds(elapsed).count() << " nanoseconds\n";
+}
+
+} <font color="#c80000">// timeval_demo</font>
+
+<font color="#c80000">// Handle duration with resolution not known until run time</font>
+
+namespace runtime_resolution
+{
+
+class duration
+{
+public:
+ typedef long long rep;
+private:
+ rep rep_;
+
+ static const double ticks_per_nanosecond;
+
+public:
+ typedef std::datetime::duration<double, std::nano> tonanosec;
+
+ duration() {} <font color="#c80000">// = default;</font>
+ explicit duration(const rep& r) : rep_(r) {}
+
+ <font color="#c80000">// conversions</font>
+ explicit duration(const tonanosec& d)
+ : rep_(static_cast<rep>(d.count() * ticks_per_nanosecond)) {}
+
+ <font color="#c80000">// explicit</font>
+ operator tonanosec() const {return tonanosec(rep_/ticks_per_nanosecond);}
+
+ <font color="#c80000">// observer</font>
+
+ rep count() const {return rep_;}
+
+ <font color="#c80000">// arithmetic</font>
+
+ duration& operator+=(const duration& d) {rep_ += d.rep_; return *this;}
+ duration& operator-=(const duration& d) {rep_ += d.rep_; return *this;}
+ duration& operator*=(rep rhs) {rep_ *= rhs; return *this;}
+ duration& operator/=(rep rhs) {rep_ /= rhs; return *this;}
+
+ 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_--);}
+
+ friend duration operator+(duration x, duration y) {return x += y;}
+ friend duration operator-(duration x, duration y) {return x -= y;}
+ friend duration operator*(duration x, rep y) {return x *= y;}
+ friend duration operator*(rep x, duration y) {return y *= x;}
+ friend duration operator/(duration x, rep y) {return x /= y;}
+
+ friend bool operator==(duration x, duration y) {return x.rep_ == y.rep_;}
+ friend bool operator!=(duration x, duration y) {return !(x == y);}
+ friend bool operator< (duration x, duration y) {return x.rep_ < y.rep_;}
+ friend bool operator<=(duration x, duration y) {return !(y < x);}
+ friend bool operator> (duration x, duration y) {return y < x;}
+ friend bool operator>=(duration x, duration y) {return !(x < y);}
+};
+
+static
+double
+init_duration()
+{
+ mach_timebase_info_data_t MachInfo;
+ mach_timebase_info(&MachInfo);
+ return static_cast<double>(MachInfo.denom) / MachInfo.numer;
+}
+
+const double duration::ticks_per_nanosecond = init_duration();
+
+class clock;
+
+class time_point
+{
+public:
+ typedef runtime_resolution::clock clock;
+ typedef long long rep;
+private:
+ rep rep_;
+
+
+ rep count() const {return rep_;}
+public:
+
+ time_point() : rep_(0) {}
+ explicit time_point(const duration& d)
+ : rep_(d.count()) {}
+
+ <font color="#c80000">// arithmetic</font>
+
+ time_point& operator+=(const duration& d) {rep_ += d.count(); return *this;}
+ time_point& operator-=(const duration& d) {rep_ -= d.count(); return *this;}
+
+ friend time_point operator+(time_point x, duration y) {return x += y;}
+ friend time_point operator+(duration x, time_point y) {return y += x;}
+ friend time_point operator-(time_point x, duration y) {return x -= y;}
+ friend duration operator-(time_point x, time_point y) {return duration(x.rep_ - y.rep_);}
+};
+
+class clock
+{
+public:
+ typedef duration::rep rep;
+ typedef runtime_resolution::duration duration;
+ typedef runtime_resolution::time_point time_point;
+
+ static time_point now() {return time_point(duration(mach_absolute_time()));}
+};
+
+void test()
+{
+ using namespace std::datetime;
+ std::cout << "runtime_resolution test\n";
+ clock::duration delay(std::datetime::milliseconds(5));
+ clock::time_point start = clock::now();
+ while (clock::now() - start <= delay)
+ ;
+ clock::time_point stop = clock::now();
+ clock::duration elapsed = stop - start;
+ std::cout << "paused " << nanoseconds(duration_cast<nanoseconds>(duration::tonanosec(elapsed))).count()
+ << " nanoseconds\n";
+}
+
+} <font color="#c80000">// runtime_resolution</font>
+
+<font color="#c80000">// miscellaneous tests and demos:</font>
+
+#include <cassert>
+#include <iostream>
+
+using namespace std::datetime;
+
+void physics_function(duration<double> d)
+{
+ std::cout << "d = " << d.count() << '\n';
+}
+
+void drive_physics_function()
+{
+ physics_function(nanoseconds(3));
+ physics_function(hours(3));
+ physics_function(duration<double>(2./3));
+ std::cout.precision(16);
+ physics_function( hours(3) + nanoseconds(-3) );
+}
+
+void test_range()
+{
+ using namespace std::datetime;
+ hours h1 = hours(24 * ( 365 * 292 + 292/4));
+ nanoseconds n1 = h1 + nanoseconds(1);
+ nanoseconds delta = n1 - h1;
+ std::cout << "292 years of hours = " << h1.count() << "hr\n";
+ std::cout << "Add a nanosecond = " << n1.count() << "ns\n";
+ std::cout << "Find the difference = " << delta.count() << "ns\n";
+}
+
+void test_extended_range()
+{
+ using namespace std::datetime;
+ hours h1 = hours(24 * ( 365 * 244000 + 244000/4));
+ <font color="#c80000">/*auto*/</font> microseconds u1 = h1 + microseconds(1);
+ <font color="#c80000">/*auto*/</font> microseconds delta = u1 - h1;
+ std::cout << "244,000 years of hours = " << h1.count() << "hr\n";
+ std::cout << "Add a microsecond = " << u1.count() << "us\n";
+ std::cout << "Find the difference = " << delta.count() << "us\n";
+}
+
+template <class Rep, class Period>
+void inspect_duration(std::datetime::duration<Rep, Period> d, const std::string& name)
+{
+ typedef std::datetime::duration<Rep, Period> Duration;
+ std::cout << "********* " << name << " *********\n";
+ std::cout << "The period of " << name << " is " << (double)Period::num/Period::den << " seconds.\n";
+ std::cout << "The frequency of " << name << " is " << (double)Period::den/Period::num << " Hz.\n";
+ std::cout << "The representation is ";
+ if (tmp::is_floating_point<Rep>::value)
+ {
+ std::cout << "floating point\n";
+ std::cout << "The precision is the most significant ";
+ std::cout << std::numeric_limits<Rep>::digits10 << " decimal digits.\n";
+ }
+ else if (tmp::is_integral<Rep>::value)
+ {
+ std::cout << "integral\n";
+ d = Duration(Rep(1));
+ std::datetime::duration<double> dsec = d;
+ std::cout << "The precision is " << dsec.count() << " seconds.\n";
+ }
+ else
+ {
+ std::cout << "a class type\n";
+ d = Duration(Rep(1));
+ std::datetime::duration<double> dsec = d;
+ std::cout << "The precision is " << dsec.count() << " seconds.\n";
+ }
+ d = Duration(std::numeric_limits<Rep>::max());
+ using namespace std::datetime;
+ using namespace std;
+ typedef duration<double, ratio_multiply<ratio<24*3652425,10000>, hours::period>::type> Years;
+ Years years = d;
+ std::cout << "The range is +/- " << years.count() << " years.\n";
+ std::cout << "sizeof(" << name << ") = " << sizeof(d) << '\n';
+}
+
+void inspect_all()
+{
+ using namespace std::datetime;
+ std::cout.precision(6);
+ inspect_duration(nanoseconds(), "nanoseconds");
+ inspect_duration(microseconds(), "microseconds");
+ inspect_duration(milliseconds(), "milliseconds");
+ inspect_duration(seconds(), "seconds");
+ inspect_duration(minutes(), "minutes");
+ inspect_duration(hours(), "hours");
+ inspect_duration(duration<double>(), "duration<double>");
+}
+
+void test_milliseconds()
+{
+ using namespace std::datetime;
+ milliseconds ms(250);
+ ms += milliseconds(1);
+ milliseconds ms2(150);
+ milliseconds msdiff = ms - ms2;
+ if (msdiff == milliseconds(101))
+ std::cout << "success\n";
+ else
+ std::cout << "failure: " << msdiff.count() << '\n';
+}
+
+ using namespace std;
+ using namespace std::datetime;
+
+<font color="#c80000">// Example round_up utility: converts d to To, rounding up for inexact conversions</font>
+<font color="#c80000">// Being able to *easily* write this function is a major feature!</font>
+template <class To, class Rep, class Period>
+To
+round_up(duration<Rep, Period> d)
+{
+ To result = duration_cast<To>(d);
+ if (result < d)
+ ++result;
+ return result;
+}
+
+<font color="#c80000">// demonstrate interaction with xtime-like facility:</font>
+
+using namespace std::datetime;
+
+struct xtime
+{
+ long sec;
+ unsigned long usec;
+};
+
+template <class Rep, class Period>
+xtime
+to_xtime_truncate(duration<Rep, Period> d)
+{
+ xtime xt;
+ xt.sec = duration_cast<seconds>(d).count();
+ xt.usec = duration_cast<microseconds>(d - seconds(xt.sec)).count();
+ return xt;
+}
+
+template <class Rep, class Period>
+xtime
+to_xtime_round_up(duration<Rep, Period> d)
+{
+ xtime xt;
+ xt.sec = duration_cast<seconds>(d).count();
+ xt.usec = round_up<microseconds>(d - seconds(xt.sec)).count();
+ return xt;
+}
+
+microseconds
+from_xtime(xtime xt)
+{
+ return seconds(xt.sec) + microseconds(xt.usec);
+}
+
+void print(xtime xt)
+{
+ cout << '{' << xt.sec << ',' << xt.usec << "}\n";
+}
+
+void test_with_xtime()
+{
+ cout << "test_with_xtime\n";
+ xtime xt = to_xtime_truncate(seconds(3) + milliseconds(251));
+ print(xt);
+ milliseconds ms = duration_cast<milliseconds>(from_xtime(xt));
+ cout << ms.count() << " milliseconds\n";
+ xt = to_xtime_round_up(ms);
+ print(xt);
+ xt = to_xtime_truncate(seconds(3) + nanoseconds(999));
+ print(xt);
+ xt = to_xtime_round_up(seconds(3) + nanoseconds(999));
+ print(xt);
+}
+
+void test_system_clock()
+{
+ cout << "system_clock test" << endl;
+ system_clock::duration delay = milliseconds(5);
+ system_clock::time_point start = system_clock::now();
+ while (system_clock::now() - start <= delay)
+ ;
+ system_clock::time_point stop = system_clock::now();
+ system_clock::duration elapsed = stop - start;
+ cout << "paused " << nanoseconds(elapsed).count() << " nanoseconds\n";
+ start = system_clock::now();
+ stop = system_clock::now();
+ cout << "system_clock resolution estimate: " << nanoseconds(stop-start).count() << " nanoseconds\n";
+}
+
+void test_monotonic_clock()
+{
+ cout << "monotonic_clock test" << endl;
+ monotonic_clock::duration delay = milliseconds(5);
+ monotonic_clock::time_point start = monotonic_clock::now();
+ while (monotonic_clock::now() - start <= delay)
+ ;
+ monotonic_clock::time_point stop = monotonic_clock::now();
+ monotonic_clock::duration elapsed = stop - start;
+ cout << "paused " << nanoseconds(elapsed).count() << " nanoseconds\n";
+ start = monotonic_clock::now();
+ stop = monotonic_clock::now();
+ cout << "monotonic_clock resolution estimate: " << nanoseconds(stop-start).count() << " nanoseconds\n";
+}
+
+void test_hi_resolution_clock()
+{
+ cout << "high_resolution_clock test" << endl;
+ high_resolution_clock::duration delay = milliseconds(5);
+ high_resolution_clock::time_point start = high_resolution_clock::now();
+ while (high_resolution_clock::now() - start <= delay)
+ ;
+ high_resolution_clock::time_point stop = high_resolution_clock::now();
+ high_resolution_clock::duration elapsed = stop - start;
+ cout << "paused " << nanoseconds(elapsed).count() << " nanoseconds\n";
+ start = high_resolution_clock::now();
+ stop = high_resolution_clock::now();
+ cout << "high_resolution_clock resolution estimate: " << nanoseconds(stop-start).count() << " nanoseconds\n";
+}
+
+void test_mixed_clock()
+{
+ cout << "mixed clock test" << endl;
+ high_resolution_clock::time_point hstart = high_resolution_clock::now();
+ cout << "Add 5 milliseconds to a high_resolution_clock::time_point\n";
+ monotonic_clock::time_point mend = hstart + milliseconds(5);
+ bool b = hstart == mend;
+ system_clock::time_point sstart = system_clock::now();
+ std::cout << "Subtracting system_clock::time_point from monotonic_clock::time_point doesn't compile\n";
+<font color="#c80000">// mend - sstart; // doesn't compile</font>
+ cout << "subtract high_resolution_clock::time_point from monotonic_clock::time_point"
+ " and add that to a system_clock::time_point\n";
+ system_clock::time_point send = sstart + duration_cast<system_clock::duration>(mend - hstart);
+ cout << "subtract two system_clock::time_point's and output that in microseconds:\n";
+ microseconds ms = send - sstart;
+ cout << ms.count() << " microseconds\n";
+}
+
+void test_c_mapping()
+{
+ cout << "C map test\n";
+ using namespace std::datetime;
+ system_clock::time_point t1 = system_clock::now();
+ std::time_t c_time = system_clock::to_time_t(t1);
+ std::tm* tmptr = std::localtime(&c_time);
+ std::cout << "It is now " << tmptr->tm_hour << ':' << tmptr->tm_min << ':' << tmptr->tm_sec << ' '
+ << tmptr->tm_year + 1900 << '-' << tmptr->tm_mon + 1 << '-' << tmptr->tm_mday << '\n';
+ c_time = std::mktime(tmptr);
+ system_clock::time_point t2 = system_clock::from_time_t(c_time);
+ microseconds ms = t1 - t2;
+ std::cout << "Round-tripping through the C interface truncated the precision by " << ms.count() << " microseconds\n";
+}
+
+void test_duration_division()
+{
+ cout << hours(3) / milliseconds(5) << '\n';
+ cout << milliseconds(5) / hours(3) << '\n';
+ cout << hours(1) / milliseconds(1) << '\n';
+}
+
+namespace I_dont_like_the_default_duration_behavior
+{
+
+<font color="#c80000">// Here's how you override the duration's default constructor to do anything you want (in this case zero)</font>
+
+template <class R>
+class zero_default
+{
+public:
+ typedef R rep;
+
+private:
+ rep rep_;
+public:
+ zero_default(rep i = 0) : rep_(i) {}
+ operator rep() const {return rep_;}
+
+ zero_default& operator+=(zero_default x) {rep_ += x.rep_; return *this;}
+ zero_default& operator-=(zero_default x) {rep_ -= x.rep_; return *this;}
+ zero_default& operator*=(zero_default x) {rep_ *= x.rep_; return *this;}
+ zero_default& operator/=(zero_default x) {rep_ /= x.rep_; return *this;}
+
+ zero_default operator+ () const {return *this;}
+ zero_default operator- () const {return zero_default(-rep_);}
+ zero_default& operator++() {++rep_; return *this;}
+ zero_default operator++(int) {return zero_default(rep_++);}
+ zero_default& operator--() {--rep_; return *this;}
+ zero_default operator--(int) {return zero_default(rep_--);}
+
+ friend zero_default operator+(zero_default x, zero_default y) {return x += y;}
+ friend zero_default operator-(zero_default x, zero_default y) {return x -= y;}
+ friend zero_default operator*(zero_default x, zero_default y) {return x *= y;}
+ friend zero_default operator/(zero_default x, zero_default y) {return x /= y;}
+
+ friend bool operator==(zero_default x, zero_default y) {return x.rep_ == y.rep_;}
+ friend bool operator!=(zero_default x, zero_default y) {return !(x == y);}
+ friend bool operator< (zero_default x, zero_default y) {return x.rep_ < y.rep_;}
+ friend bool operator<=(zero_default x, zero_default y) {return !(y < x);}
+ friend bool operator> (zero_default x, zero_default y) {return y < x;}
+ friend bool operator>=(zero_default x, zero_default y) {return !(x < y);}
+};
+
+typedef std::datetime::duration<zero_default<long long>, std::nano > nanoseconds;
+typedef std::datetime::duration<zero_default<long long>, std::micro > microseconds;
+typedef std::datetime::duration<zero_default<long long>, std::milli > milliseconds;
+typedef std::datetime::duration<zero_default<long long> > seconds;
+typedef std::datetime::duration<zero_default<long long>, std::ratio<60> > minutes;
+typedef std::datetime::duration<zero_default<long long>, std::ratio<3600> > hours;
+
+void test()
+{
+ milliseconds ms;
+ cout << ms.count() << '\n';
+}
+
+} <font color="#c80000">// I_dont_like_the_default_duration_behavior</font>
+
+<font color="#c80000">// Build a min for two time_points</font>
+
+template <class Rep, class Period>
+void
+print_duration(ostream& os, duration<Rep, Period> d)
+{
+ os << d.count() << " * " << Period::num << '/' << Period::den << " seconds\n";
+}
+
+<font color="#c80000">// Example min utility: returns the earliest time_point</font>
+<font color="#c80000">// Being able to *easily* write this function is a major feature!</font>
+template <class Clock, class Duration1, class Duration2>
+inline
+typename common_type<time_point<Clock, Duration1>, time_point<Clock, Duration2> >::type
+min(time_point<Clock, Duration1> t1, time_point<Clock, Duration2> t2)
+{
+ return t2 < t1 ? t2 : t1;
+}
+
+void test_min()
+{
+ typedef time_point<system_clock, common_type<system_clock::duration, seconds>::type> T1;
+ typedef time_point<system_clock, common_type<system_clock::duration, nanoseconds>::type> T2;
+ typedef common_type<T1, T2>::type T3;
+ <font color="#c80000">/*auto*/</font> T1 t1 = system_clock::now() + seconds(3);
+ <font color="#c80000">/*auto*/</font> T2 t2 = system_clock::now() + nanoseconds(3);
+ <font color="#c80000">/*auto*/</font> T3 t3 = min(t1, t2);
+ print_duration(cout, t1 - t3);
+ print_duration(cout, t2 - t3);
+}
+
+void explore_limits()
+{
+ typedef duration<long long, ratio_multiply<ratio<24*3652425,10000>, hours::period>::type> Years;
+ monotonic_clock::time_point t1( Years(250));
+ monotonic_clock::time_point t2(-Years(250));
+ <font color="#c80000">// nanosecond resolution is likely to overflow. "up cast" to microseconds.</font>
+ <font color="#c80000">// The "up cast" trades precision for range.</font>
+ microseconds d = time_point_cast<microseconds>(t1) - time_point_cast<microseconds>(t2);
+ cout << d.count() << " microseconds\n";
+}
+
+void manipulate_clock_object(system_clock clock)
+{
+ system_clock::duration delay = milliseconds(5);
+ system_clock::time_point start = clock.now();
+ while (clock.now() - start <= delay)
+ ;
+ system_clock::time_point stop = clock.now();
+ system_clock::duration elapsed = stop - start;
+ cout << "paused " << nanoseconds(elapsed).count() << " nanoseconds\n";
+};
+
+template <long long speed>
+struct cycle_count
+{
+ typedef typename ratio_multiply<ratio<speed>, mega>::type frequency; <font color="#c80000">// Mhz</font>
+ typedef typename ratio_divide<ratio<1>, frequency>::type period;
+ typedef long long rep;
+ typedef std::datetime::duration<rep, period> duration;
+ typedef std::datetime::time_point<cycle_count> time_point;
+
+ static time_point now()
+ {
+ static long long tick = 0;
+ <font color="#c80000">// return exact cycle count</font>
+ return time_point(duration(++tick)); <font color="#c80000">// fake access to clock cycle count</font>
+ }
+};
+
+template <long long speed>
+struct approx_cycle_count
+{
+ static const long long frequency = speed * 1000000; <font color="#c80000">// MHz</font>
+ typedef nanoseconds duration;
+ typedef duration::rep rep;
+ typedef duration::period period;
+ static const long long nanosec_per_sec = period::den;
+ typedef std::datetime::time_point<approx_cycle_count> time_point;
+
+ static time_point now()
+ {
+ static long long tick = 0;
+ <font color="#c80000">// return cycle count as an approximate number of nanoseconds</font>
+ <font color="#c80000">// compute as if nanoseconds is only duration in the std::lib</font>
+ return time_point(duration(++tick * nanosec_per_sec / frequency));
+ }
+};
+
+void cycle_count_delay()
+{
+ {
+ typedef cycle_count<400> clock;
+ cout << "\nSimulated " << clock::frequency::num / mega::num << "MHz clock which has a tick period of "
+ << duration<double, nano>(clock::duration(1)).count() << " nanoseconds\n";
+ nanoseconds delayns(500);
+ clock::duration delay = duration_cast<clock::duration>(delayns);
+ cout << "delay = " << delayns.count() << " nanoseconds which is " << delay.count() << " cycles\n";
+ clock::time_point start = clock::now();
+ clock::time_point stop = start + delay;
+ while (clock::now() < stop) <font color="#c80000">// no multiplies or divides in this loop</font>
+ ;
+ clock::time_point end = clock::now();
+ clock::duration elapsed = end - start;
+ cout << "paused " << elapsed.count() << " cycles ";
+ cout << "which is " << duration_cast<nanoseconds>(elapsed).count() << " nanoseconds\n";
+ }
+ {
+ typedef approx_cycle_count<400> clock;
+ cout << "\nSimulated " << clock::frequency / 1000000 << "MHz clock modeled with nanoseconds\n";
+ clock::duration delay = nanoseconds(500);
+ cout << "delay = " << delay.count() << " nanoseconds\n";
+ clock::time_point start = clock::now();
+ clock::time_point stop = start + delay;
+ while (clock::now() < stop) <font color="#c80000">// 1 multiplication and 1 division in this loop</font>
+ ;
+ clock::time_point end = clock::now();
+ clock::duration elapsed = end - start;
+ cout << "paused " << elapsed.count() << " nanoseconds\n";
+ }
+ {
+ typedef cycle_count<1500> clock;
+ cout << "\nSimulated " << clock::frequency::num / mega::num << "MHz clock which has a tick period of "
+ << duration<double, nano>(clock::duration(1)).count() << " nanoseconds\n";
+ nanoseconds delayns(500);
+ clock::duration delay = duration_cast<clock::duration>(delayns);
+ cout << "delay = " << delayns.count() << " nanoseconds which is " << delay.count() << " cycles\n";
+ clock::time_point start = clock::now();
+ clock::time_point stop = start + delay;
+ while (clock::now() < stop) <font color="#c80000">// no multiplies or divides in this loop</font>
+ ;
+ clock::time_point end = clock::now();
+ clock::duration elapsed = end - start;
+ cout << "paused " << elapsed.count() << " cycles ";
+ cout << "which is " << duration_cast<nanoseconds>(elapsed).count() << " nanoseconds\n";
+ }
+ {
+ typedef approx_cycle_count<1500> clock;
+ cout << "\nSimulated " << clock::frequency / 1000000 << "MHz clock modeled with nanoseconds\n";
+ clock::duration delay = nanoseconds(500);
+ cout << "delay = " << delay.count() << " nanoseconds\n";
+ clock::time_point start = clock::now();
+ clock::time_point stop = start + delay;
+ while (clock::now() < stop) <font color="#c80000">// 1 multiplication and 1 division in this loop</font>
+ ;
+ clock::time_point end = clock::now();
+ clock::duration elapsed = end - start;
+ cout << "paused " << elapsed.count() << " nanoseconds\n";
+ }
+}
+
+void test_special_values()
+{
+ std::cout << "duration<unsigned>::min().count() = " << duration<unsigned>::min().count() << '\n';
+ std::cout << "duration<unsigned>::zero().count() = " << duration<unsigned>::zero().count() << '\n';
+ std::cout << "duration<unsigned>::max().count() = " << duration<unsigned>::max().count() << '\n';
+ std::cout << "duration<int>::min().count() = " << duration<int>::min().count() << '\n';
+ std::cout << "duration<int>::zero().count() = " << duration<int>::zero().count() << '\n';
+ std::cout << "duration<int>::max().count() = " << duration<int>::max().count() << '\n';
+}
+
+int main()
+{
+ basic_examples();
+ testStdUser();
+ testUser1();
+ testUser2();
+ drive_physics_function();
+ test_range();
+ test_extended_range();
+ inspect_all();
+ test_milliseconds();
+ test_with_xtime();
+ test_system_clock();
+ test_monotonic_clock();
+ test_hi_resolution_clock();
+ test_mixed_clock();
+ timeval_demo::test_xtime_clock();
+ runtime_resolution::test();
+ test_c_mapping();
+ test_duration_division();
+ I_dont_like_the_default_duration_behavior::test();
+ test_min();
+#if VARIADIC_COMMON_TYPE
+ inspect_duration(common_type<duration<double>, hours, microseconds>::type(),
+ "common_type<duration<double>, hours, microseconds>::type");
+#endif
+ explore_limits();
+ manipulate_clock_object(system_clock());
+ duration<double, milli> d = milliseconds(3) * 2.5;
+ inspect_duration(milliseconds(3) * 2.5, "milliseconds(3) * 2.5");
+ cout << d.count() << '\n';
+<font color="#c80000">// milliseconds ms(3.5); // doesn't compile</font>
+ cout << "milliseconds ms(3.5) doesn't compile\n";
+ cycle_count_delay();
+ test_special_values();
+}
+
+<font color="#c80000">/*
+Output
+
+Running basic examples
+sleep_for 3000000 microseconds
+sleep_for 1 microseconds
+sleep_until 10:47:17.728293 which is 4499340 microseconds away
+try_lock_for 30000 microseconds
+try_lock_until 10:47:17.728285 which is 4499303 microseconds away
+wait_for 60000000 microseconds
+wait_until 10:47:17.728285 which is 4499264 microseconds away
+sleep_for 250000 microseconds
+sleep_until 10:47:14.729077 which is 1499979 microseconds away
+***************
+* testStdUser *
+***************
+100 hours expressed as hours = 100
+100 hours expressed as nanoseconds = 360000000000000
+200 hours expressed as nanoseconds = 720000000000000
+300 hours expressed as nanoseconds = 1080000000000000
+hr = ns; <font color="#c80000">// does not compile</font>
+hr * ns; <font color="#c80000">// does not compile</font>
+duration<double> has count() = 2.5
+seconds sec = duration<double> won't compile
+seconds has count() = 2
+
+*************
+* testUser1 *
+*************
+Speed = 24.5872 meters/sec
+Acceleration = 9.81456 meters/sec^2
+Distance = 13.5204 meters
+There are 125/201168 miles/meter which is approximately 0.000621371
+There are 201168/125 meters/mile which is approximately 1609.34
+1 attosecond is 1e-18 seconds
+sec = as; <font color="#c80000">// compiles</font>
+1 second is 1e+18 attoseconds
+as = sec; <font color="#c80000">// compiles</font>
+
+*************
+* testUser2 *
+*************
+100 years expressed as years = 100
+100 years expressed as nanoseconds = 3155695200000000000
+200 years expressed as nanoseconds = 6311390400000000000
+300 years expressed as nanoseconds = inf
+yr = ns; <font color="#c80000">// does not compile</font>
+ps = yr; <font color="#c80000">// does not compile</font>
+100 years expressed as picoseconds = inf
+0.1 years expressed as picoseconds = 3155695200000000000
+200 million years ago encoded in years: -200000000
+200 million years ago encoded in days: -73048500000
+200 million years ago encoded in millennium: -200000
+Demonstrate "uninitialized protection" behavior:
+nan
+
+d = 3e-09
+d = 10800
+d = 0.666667
+d = 10799.999999997
+292 years of hours = 2559672hr
+Add a nanosecond = 9214819200000000001ns
+Find the difference = 1ns
+244,000 years of hours = 2138904000hr
+Add a microsecond = 7700054400000000001us
+Find the difference = 1us
+********* nanoseconds *********
+The period of nanoseconds is 1e-09 seconds.
+The frequency of nanoseconds is 1e+09 Hz.
+The representation is integral
+The precision is 1e-09 seconds.
+The range is +/- 292.277 years.
+sizeof(nanoseconds) = 8
+********* microseconds *********
+The period of microseconds is 1e-06 seconds.
+The frequency of microseconds is 1e+06 Hz.
+The representation is integral
+The precision is 1e-06 seconds.
+The range is +/- 292277 years.
+sizeof(microseconds) = 8
+********* milliseconds *********
+The period of milliseconds is 0.001 seconds.
+The frequency of milliseconds is 1000 Hz.
+The representation is integral
+The precision is 0.001 seconds.
+The range is +/- 2.92277e+08 years.
+sizeof(milliseconds) = 8
+********* seconds *********
+The period of seconds is 1 seconds.
+The frequency of seconds is 1 Hz.
+The representation is integral
+The precision is 1 seconds.
+The range is +/- 2.92277e+11 years.
+sizeof(seconds) = 8
+********* minutes *********
+The period of minutes is 60 seconds.
+The frequency of minutes is 0.0166667 Hz.
+The representation is integral
+The precision is 60 seconds.
+The range is +/- 4083.06 years.
+sizeof(minutes) = 4
+********* hours *********
+The period of hours is 3600 seconds.
+The frequency of hours is 0.000277778 Hz.
+The representation is integral
+The precision is 3600 seconds.
+The range is +/- 244984 years.
+sizeof(hours) = 4
+********* duration<double> *********
+The period of duration<double> is 1 seconds.
+The frequency of duration<double> is 1 Hz.
+The representation is floating point
+The precision is the most significant 15 decimal digits.
+The range is +/- 5.69666e+300 years.
+sizeof(duration<double>) = 8
+success
+test_with_xtime
+{3,251000}
+3251 milliseconds
+{3,251000}
+{3,0}
+{3,1}
+system_clock test
+paused 5001000 nanoseconds
+system_clock resolution estimate: 0 nanoseconds
+monotonic_clock test
+paused 5000181 nanoseconds
+monotonic_clock resolution estimate: 97 nanoseconds
+high_resolution_clock test
+paused 5000277 nanoseconds
+high_resolution_clock resolution estimate: 96 nanoseconds
+mixed clock test
+Add 5 milliseconds to a high_resolution_clock::time_point
+Subtracting system_clock::time_point from monotonic_clock::time_point doesn't compile
+subtract high_resolution_clock::time_point from monotonic_clock::time_point and add that to a system_clock::time_point
+subtract two system_clock::time_point's and output that in microseconds:
+5000 microseconds
+timeval_demo system clock test
+sizeof xtime_clock::time_point = 8
+sizeof xtime_clock::duration = 8
+sizeof xtime_clock::rep = 8
+paused 5001000 nanoseconds
+runtime_resolution test
+paused 5000205 nanoseconds
+C map test
+It is now 10:47:13 2008-4-22
+Round-tripping through the C interface truncated the precision by 255445 microseconds
+2160000
+0
+3600000
+0
+2999998997 * 1/1000000000 seconds
+0 * 1/1000000000 seconds
+15778476000000000 microseconds
+paused 5001000 nanoseconds
+********* milliseconds(3) * 2.5 *********
+The period of milliseconds(3) * 2.5 is 0.001 seconds.
+The frequency of milliseconds(3) * 2.5 is 1000 Hz.
+The representation is floating point
+The precision is the most significant 15 decimal digits.
+The range is +/- 5.69666e+297 years.
+sizeof(milliseconds(3) * 2.5) = 8
+7.5
+milliseconds ms(3.5) doesn't compile
+
+Simulated 400MHz clock which has a tick period of 2.5 nanoseconds
+delay = 500 nanoseconds which is 200 cycles
+paused 201 cycles which is 502 nanoseconds
+
+Simulated 400MHz clock modeled with nanoseconds
+delay = 500 nanoseconds
+paused 503 nanoseconds
+
+Simulated 1500MHz clock which has a tick period of 0.666667 nanoseconds
+delay = 500 nanoseconds which is 750 cycles
+paused 751 cycles which is 500 nanoseconds
+
+Simulated 1500MHz clock modeled with nanoseconds
+delay = 500 nanoseconds
+paused 500 nanoseconds
+duration<unsigned>::min().count() = 0
+duration<unsigned>::zero().count() = 0
+duration<unsigned>::max().count() = 4294967295
+duration<int>::min().count() = -2147483647
+duration<int>::zero().count() = 0
+duration<int>::max().count() = 2147483647
+*/</font>
+
+<font color="#c80000">/*
+Example disassemblies (to show efficiency).
+Disclaimer: I don't pretend to understand the optimizations made.
+
+Compiled with
+g++ -O3 -arch x86_64 -S test2.cpp
+
+x86 64-bit architecture
+
+********************
+
+system_clock::duration
+time_subtraction(system_clock::time_point x, system_clock::time_point y)
+{
+ return x - y;
+}
+
+ pushq %rbp
+LCFI25:
+ subq %rsi, %rdi
+ movq %rdi, %rax
+ movq %rsp, %rbp
+LCFI26:
+ leave
+ ret
+
+********************
+
+seconds
+time_subtract_to_seconds(system_clock::time_point x, system_clock::time_point y)
+{
+ return duration_cast<seconds>(x - y);
+}
+
+ subq %rsi, %rdi
+ movabsq $4835703278458516699, %rdx
+ pushq %rbp
+LCFI25:
+ movq %rdi, %rax
+ sarq $63, %rdi
+ imulq %rdx
+ movq %rsp, %rbp
+LCFI26:
+ leave
+ sarq $18, %rdx
+ subq %rdi, %rdx
+ movq %rdx, %rax
+ ret
+
+********************
+
+nanoseconds
+time_subtract_to_nanoseconds(system_clock::time_point x, system_clock::time_point y)
+{
+ return x - y;
+}
+
+ pushq %rbp
+LCFI25:
+ subq %rsi, %rdi
+ imulq $1000, %rdi, %rax
+ movq %rsp, %rbp
+LCFI26:
+ leave
+ ret
+
+********************
+
+system_clock::time_point
+time_plus_duration(system_clock::time_point x, system_clock::duration y)
+{
+ return x + y;
+}
+
+ pushq %rbp
+LCFI37:
+ movq %rsp, %rbp
+LCFI38:
+ leaq (%rsi,%rdi), %rax
+ leave
+ ret
+
+********************
+
+milliseconds
+duration_plus_duration(milliseconds x, milliseconds y)
+{
+ return x + y;
+}
+
+ pushq %rbp
+LCFI11:
+ leaq (%rdi,%rsi), %rax
+ movq %rsp, %rbp
+LCFI12:
+ leave
+ ret
+
+********************
+
+nanoseconds
+milliseconds_plus_nanoseconds(milliseconds x, nanoseconds y)
+{
+ return x + y;
+}
+
+ imulq $1000000, %rdi, %rdi
+ pushq %rbp
+LCFI20:
+ movq %rsp, %rbp
+LCFI21:
+ leave
+ leaq (%rdi,%rsi), %rax
+ ret
+
+********************
+
+milliseconds
+nanoseconds_to_milliseconds(nanoseconds x)
+{
+ return duration_cast<milliseconds>(x);
+}
+
+ movq %rdi, %rax
+ movabsq $4835703278458516699, %rdx
+ pushq %rbp
+LCFI13:
+ imulq %rdx
+ sarq $63, %rdi
+ movq %rsp, %rbp
+LCFI14:
+ leave
+ sarq $18, %rdx
+ subq %rdi, %rdx
+ movq %rdx, %rax
+ ret
+
+********************
+
+nanoseconds
+milliseconds_to_nanoseconds(milliseconds x)
+{
+ return x;
+}
+
+ pushq %rbp
+LCFI13:
+ imulq $1000000, %rdi, %rax
+ movq %rsp, %rbp
+LCFI14:
+ leave
+ ret
+
+********************
+
+hours
+increment_hours(hours x)
+{
+ return ++x;
+}
+
+ pushq %rbp
+LCFI11:
+ leaq 1(%rdi), %rax
+ movq %rsp, %rbp
+LCFI12:
+ leave
+ ret
+
+*/</font>
+</pre>
+
+</body></html>
\ No newline at end of file
Added: sandbox/chrono/libs/chrono/example/await_keystroke.cpp
==============================================================================
--- (empty file)
+++ sandbox/chrono/libs/chrono/example/await_keystroke.cpp 2008-11-12 08:44:21 EST (Wed, 12 Nov 2008)
@@ -0,0 +1,73 @@
+// await_keystroke.cpp -----------------------------------------------------//
+
+// Copyright Beman Dawes 2008
+
+// Distributed under the Boost Software License, Version 1.0.
+// See http://www.boost.org/LICENSE_1_0.txt
+
+#define _CRT_SECURE_NO_WARNINGS
+
+#include <boost/chrono.hpp>
+#include <iostream>
+#include <iomanip>
+
+using namespace boost::chrono;
+
+template< class Clock >
+class timer
+{
+ typename Clock::time_point start;
+public:
+
+ timer() : start( Clock::now() ) {}
+
+ typename Clock::duration elapsed() const
+ {
+ return Clock::now() - start;
+ }
+
+ double seconds() const
+ {
+ return elapsed().count() * ((double)Clock::period::num/Clock::period::den);
+ }
+};
+
+int main()
+{
+ timer<system_clock> t1;
+ timer<monotonic_clock> t2;
+ timer<high_resolution_clock> t3;
+
+ std::cout << "Strike any key: ";
+ std::cin.get();
+
+ std::cout << std::fixed << std::setprecision(9);
+ std::cout << "system_clock-----------: "
+ << t1.seconds() << " seconds\n";
+ std::cout << "monotonic_clock--------: "
+ << t2.seconds() << " seconds\n";
+ std::cout << "high_resolution_clock--: "
+ << t3.seconds() << " seconds\n";
+
+ system_clock::time_point d4 = system_clock::now();
+ system_clock::time_point d5 = system_clock::now();
+
+ std::cout << "\nsystem_clock latency-----------: " << (d5 - d4).count() << std::endl;
+
+ monotonic_clock::time_point d6 = monotonic_clock::now();
+ monotonic_clock::time_point d7 = monotonic_clock::now();
+
+ std::cout << "monotonic_clock latency--------: " << (d7 - d6).count() << std::endl;
+
+ high_resolution_clock::time_point d8 = high_resolution_clock::now();
+ high_resolution_clock::time_point d9 = high_resolution_clock::now();
+
+ std::cout << "high_resolution_clock latency--: " << (d9 - d8).count() << std::endl;
+
+ std::time_t now = system_clock::to_time_t(system_clock::now());
+
+ std::cout << "\nsystem_clock::now() reports UTC is "
+ << std::asctime(std::gmtime(&now)) << "\n";
+
+ return 0;
+}
Added: sandbox/chrono/libs/chrono/example/time2_demo.cpp
==============================================================================
--- (empty file)
+++ sandbox/chrono/libs/chrono/example/time2_demo.cpp 2008-11-12 08:44:21 EST (Wed, 12 Nov 2008)
@@ -0,0 +1,1663 @@
+// time2_demo.cpp ----------------------------------------------------------//
+
+// Copyright 2008 Howard Hinnant
+// Copyright 2008 Beman Dawes
+
+// 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 Krügler,
+ Anthony Williams.
+*/
+
+#define _CRT_SECURE_NO_WARNINGS // disable VC++ foolishness
+
+#include <boost/chrono.hpp>
+#include <boost/type_traits.hpp>
+
+#include <iostream>
+
+#include <windows.h>
+#undef min
+#undef max
+
+namespace
+{
+ //struct timeval {
+ // long tv_sec; /* seconds */
+ // long tv_usec; /* and microseconds */
+ //};
+
+ int gettimeofday(struct timeval * tp, void *)
+ {
+ FILETIME ft;
+ ::GetSystemTimeAsFileTime( &ft ); // never fails
+ long long t = (static_cast<long long>(ft.dwHighDateTime) << 32) | ft.dwLowDateTime;
+ # if !defined( BOOST_MSVC ) || BOOST_MSVC > 1300 // > VC++ 7.0
+ t -= 116444736000000000LL;
+ # else
+ t -= 116444736000000000;
+ # endif
+ t /= 10; // microseconds
+ tp->tv_sec = static_cast<long>( t / 1000000UL);
+ tp->tv_usec = static_cast<long>( t % 1000000UL);
+ return 0;
+ }
+} // unnamed namespace
+
+//////////////////////////////////////////////////////////
+///////////// simulated thread interface /////////////////
+//////////////////////////////////////////////////////////
+
+#include <iostream>
+
+namespace std {
+
+void __print_time(boost::chrono::system_clock::time_point t)
+{
+ using namespace boost::chrono;
+ time_t c_time = system_clock::to_time_t(t);
+ std::tm* tmptr = std::localtime(&c_time);
+ system_clock::duration d = t.time_since_epoch();
+ std::cout << tmptr->tm_hour << ':' << tmptr->tm_min << ':' << tmptr->tm_sec
+ << '.' << (d - duration_cast<seconds>(d)).count();
+}
+
+namespace this_thread {
+
+template <class Rep, class Period>
+void sleep_for(const boost::chrono::duration<Rep, Period>& d)
+{
+ boost::chrono::microseconds t = boost::chrono::duration_cast<boost::chrono::microseconds>(d);
+ if (t < d)
+ ++t;
+ if (t > boost::chrono::microseconds(0))
+ std::cout << "sleep_for " << t.count() << " microseconds\n";
+}
+
+template <class Clock, class Duration>
+void sleep_until(const boost::chrono::time_point<Clock, Duration>& t)
+{
+ using namespace boost::chrono;
+ typedef time_point<Clock, Duration> Time;
+ typedef system_clock::time_point SysTime;
+ if (t > Clock::now())
+ {
+ typedef typename boost::common_type<typename Time::duration,
+ typename SysTime::duration>::type D;
+ /* auto */ D d = t - Clock::now();
+ microseconds us = duration_cast<microseconds>(d);
+ if (us < d)
+ ++us;
+ SysTime st = system_clock::now() + us;
+ std::cout << "sleep_until ";
+ __print_time(st);
+ std::cout << " which is " << (st - system_clock::now()).count() << " microseconds away\n";
+ }
+}
+
+} // this_thread
+
+struct mutex {};
+
+struct timed_mutex
+{
+ bool try_lock() {std::cout << "timed_mutex::try_lock()\n"; return true;}
+
+ template <class Rep, class Period>
+ bool try_lock_for(const boost::chrono::duration<Rep, Period>& d)
+ {
+ boost::chrono::microseconds t = boost::chrono::duration_cast<boost::chrono::microseconds>(d);
+ if (t <= boost::chrono::microseconds(0))
+ return try_lock();
+ std::cout << "try_lock_for " << t.count() << " microseconds\n";
+ return true;
+ }
+
+ template <class Clock, class Duration>
+ bool try_lock_until(const boost::chrono::time_point<Clock, Duration>& t)
+ {
+ using namespace boost::chrono;
+ typedef time_point<Clock, Duration> Time;
+ typedef system_clock::time_point SysTime;
+ if (t <= Clock::now())
+ return try_lock();
+ typedef typename boost::common_type<typename Time::duration,
+ typename Clock::duration>::type D;
+ /* auto */ D d = t - Clock::now();
+ microseconds us = duration_cast<microseconds>(d);
+ SysTime st = system_clock::now() + us;
+ std::cout << "try_lock_until ";
+ __print_time(st);
+ std::cout << " which is " << (st - system_clock::now()).count()
+ << " microseconds away\n";
+ return true;
+ }
+};
+
+struct condition_variable
+{
+ template <class Rep, class Period>
+ bool wait_for(mutex&, const boost::chrono::duration<Rep, Period>& d)
+ {
+ boost::chrono::microseconds t = boost::chrono::duration_cast<boost::chrono::microseconds>(d);
+ std::cout << "wait_for " << t.count() << " microseconds\n";
+ return true;
+ }
+
+ template <class Clock, class Duration>
+ bool wait_until(mutex&, const boost::chrono::time_point<Clock, Duration>& t)
+ {
+ using namespace boost::chrono;
+ typedef time_point<Clock, Duration> Time;
+ typedef system_clock::time_point SysTime;
+ if (t <= Clock::now())
+ return false;
+ typedef typename boost::common_type<typename Time::duration,
+ typename Clock::duration>::type D;
+ /* auto */ D d = t - Clock::now();
+ microseconds us = duration_cast<microseconds>(d);
+ SysTime st = system_clock::now() + us;
+ std::cout << "wait_until ";
+ __print_time(st);
+ std::cout << " which is " << (st - system_clock::now()).count()
+ << " microseconds away\n";
+ return true;
+ }
+};
+
+} // namespace std
+
+//////////////////////////////////////////////////////////
+//////////// Simple sleep and wait examples //////////////
+//////////////////////////////////////////////////////////
+
+std::mutex m;
+std::timed_mutex mut;
+std::condition_variable cv;
+
+void basic_examples()
+{
+ std::cout << "Running basic examples\n";
+ using namespace std;
+ using namespace boost::chrono;
+ system_clock::time_point time_limit = system_clock::now() + seconds(4) + milliseconds(500);
+ this_thread::sleep_for(seconds(3));
+ this_thread::sleep_for(nanoseconds(300));
+ this_thread::sleep_until(time_limit);
+// this_thread::sleep_for(time_limit); // desired compile-time error
+// this_thread::sleep_until(seconds(3)); // desired compile-time error
+ mut.try_lock_for(milliseconds(30));
+ mut.try_lock_until(time_limit);
+// mut.try_lock_for(time_limit); // desired compile-time error
+// mut.try_lock_until(milliseconds(30)); // desired compile-time error
+ cv.wait_for(m, minutes(1)); // real code would put this in a loop
+ cv.wait_until(m, time_limit); // real code would put this in a loop
+ // For those who prefer floating point
+ this_thread::sleep_for(duration<double>(0.25));
+ this_thread::sleep_until(system_clock::now() + duration<double>(1.5));
+}
+
+//////////////////////////////////////////////////////////
+//////////////////// User1 Example ///////////////////////
+//////////////////////////////////////////////////////////
+
+namespace User1
+{
+// Example type-safe "physics" code interoperating with boost::chrono::duration types
+// and taking advantage of the boost::ratio infrastructure and design philosophy.
+
+// length - mimics boost::chrono::duration except restricts representation to double.
+// Uses boost::ratio facilities for length units conversions.
+
+template <class Ratio>
+class length
+{
+public:
+ typedef Ratio ratio;
+private:
+ double len_;
+public:
+
+ length() : len_(1) {}
+ length(const double& len) : len_(len) {}
+
+ // conversions
+ template <class R>
+ length(const length<R>& d)
+ : len_(d.count() * boost::ratio_divide<Ratio, R>::type::den /
+ boost::ratio_divide<Ratio, R>::type::num) {}
+
+ // observer
+
+ double count() const {return len_;}
+
+ // arithmetic
+
+ length& operator+=(const length& d) {len_ += d.count(); return *this;}
+ length& operator-=(const length& d) {len_ -= d.count(); return *this;}
+
+ length operator+() const {return *this;}
+ length operator-() const {return length(-len_);}
+
+ length& operator*=(double rhs) {len_ *= rhs; return *this;}
+ length& operator/=(double rhs) {len_ /= rhs; return *this;}
+};
+
+// Sparse sampling of length units
+typedef length<boost::ratio<1> > meter; // set meter as "unity"
+typedef length<boost::centi> centimeter; // 1/100 meter
+typedef length<boost::kilo> kilometer; // 1000 meters
+typedef length<boost::ratio<254, 10000> > inch; // 254/10000 meters
+// length takes ratio instead of two integral types so that definitions can be made like so:
+typedef length<boost::ratio_multiply<boost::ratio<12>, inch::ratio>::type> foot; // 12 inchs
+typedef length<boost::ratio_multiply<boost::ratio<5280>, foot::ratio>::type> mile; // 5280 feet
+
+// Need a floating point definition of seconds
+typedef boost::chrono::duration<double> seconds; // unity
+// Demo of (scientific) support for sub-nanosecond resolutions
+typedef boost::chrono::duration<double, boost::pico> picosecond; // 10^-12 seconds
+typedef boost::chrono::duration<double, boost::femto> femtosecond; // 10^-15 seconds
+typedef boost::chrono::duration<double, boost::atto> attosecond; // 10^-18 seconds
+
+// A very brief proof-of-concept for SIUnits-like library
+// Hard-wired to floating point seconds and meters, but accepts other units (shown in testUser1())
+template <class R1, class R2>
+class quantity
+{
+ double q_;
+public:
+ quantity() : q_(1) {}
+
+ double get() const {return q_;}
+ void set(double q) {q_ = q;}
+};
+
+template <>
+class quantity<boost::ratio<1>, boost::ratio<0> >
+{
+ double q_;
+public:
+ quantity() : q_(1) {}
+ quantity(seconds d) : q_(d.count()) {} // note: only User1::seconds needed here
+
+ double get() const {return q_;}
+ void set(double q) {q_ = q;}
+};
+
+template <>
+class quantity<boost::ratio<0>, boost::ratio<1> >
+{
+ double q_;
+public:
+ quantity() : q_(1) {}
+ quantity(meter d) : q_(d.count()) {} // note: only User1::meter needed here
+
+ double get() const {return q_;}
+ void set(double q) {q_ = q;}
+};
+
+template <>
+class quantity<boost::ratio<0>, boost::ratio<0> >
+{
+ double q_;
+public:
+ quantity() : q_(1) {}
+ quantity(double d) : q_(d) {}
+
+ double get() const {return q_;}
+ void set(double q) {q_ = q;}
+};
+
+// Example SI-Units
+typedef quantity<boost::ratio<0>, boost::ratio<0> > Scalar;
+typedef quantity<boost::ratio<1>, boost::ratio<0> > Time; // second
+typedef quantity<boost::ratio<0>, boost::ratio<1> > Distance; // meter
+typedef quantity<boost::ratio<-1>, boost::ratio<1> > Speed; // meter/second
+typedef quantity<boost::ratio<-2>, boost::ratio<1> > Acceleration; // meter/second^2
+
+template <class R1, class R2, class R3, class R4>
+quantity<typename boost::ratio_subtract<R1, R3>::type, typename boost::ratio_subtract<R2, R4>::type>
+operator/(const quantity<R1, R2>& x, const quantity<R3, R4>& y)
+{
+ typedef quantity<typename boost::ratio_subtract<R1, R3>::type, typename boost::ratio_subtract<R2, R4>::type> R;
+ R r;
+ r.set(x.get() / y.get());
+ return r;
+}
+
+template <class R1, class R2, class R3, class R4>
+quantity<typename boost::ratio_add<R1, R3>::type, typename boost::ratio_add<R2, R4>::type>
+operator*(const quantity<R1, R2>& x, const quantity<R3, R4>& y)
+{
+ typedef quantity<typename boost::ratio_add<R1, R3>::type, typename boost::ratio_add<R2, R4>::type> R;
+ R r;
+ r.set(x.get() * y.get());
+ return r;
+}
+
+template <class R1, class R2>
+quantity<R1, R2>
+operator+(const quantity<R1, R2>& x, const quantity<R1, R2>& y)
+{
+ typedef quantity<R1, R2> R;
+ R r;
+ r.set(x.get() + y.get());
+ return r;
+}
+
+template <class R1, class R2>
+quantity<R1, R2>
+operator-(const quantity<R1, R2>& x, const quantity<R1, R2>& y)
+{
+ typedef quantity<R1, R2> R;
+ R r;
+ r.set(x.get() - y.get());
+ return r;
+}
+
+// Example type-safe physics function
+Distance
+compute_distance(Speed v0, Time t, Acceleration a)
+{
+ return v0 * t + Scalar(.5) * a * t * t; // if a units mistake is made here it won't compile
+}
+
+} // User1
+
+#include <iostream>
+
+// Exercise example type-safe physics function and show interoperation
+// of custom time durations (User1::seconds) and standard time durations (std::hours).
+// Though input can be arbitrary (but type-safe) units, output is always in SI-units
+// (a limitation of the simplified Units lib demoed here).
+void testUser1()
+{
+ std::cout << "*************\n";
+ std::cout << "* testUser1 *\n";
+ std::cout << "*************\n";
+ User1::Distance d( User1::mile(110) );
+ User1::Time t( boost::chrono::hours(2) );
+ User1::Speed s = d / t;
+ std::cout << "Speed = " << s.get() << " meters/sec\n";
+ User1::Acceleration a = User1::Distance( User1::foot(32.2) ) / User1::Time() / User1::Time();
+ std::cout << "Acceleration = " << a.get() << " meters/sec^2\n";
+ User1::Distance df = compute_distance(s, User1::Time( User1::seconds(0.5) ), a);
+ std::cout << "Distance = " << df.get() << " meters\n";
+ std::cout << "There are " << User1::mile::ratio::den << '/' << User1::mile::ratio::num << " miles/meter";
+ User1::meter mt = 1;
+ User1::mile mi = mt;
+ std::cout << " which is approximately " << mi.count() << '\n';
+ std::cout << "There are " << User1::mile::ratio::num << '/' << User1::mile::ratio::den << " meters/mile";
+ mi = 1;
+ mt = mi;
+ std::cout << " which is approximately " << mt.count() << '\n';
+ User1::attosecond as(1);
+ User1::seconds sec = as;
+ std::cout << "1 attosecond is " << sec.count() << " seconds\n";
+ std::cout << "sec = as; // compiles\n";
+ sec = User1::seconds(1);
+ as = sec;
+ std::cout << "1 second is " << as.count() << " attoseconds\n";
+ std::cout << "as = sec; // compiles\n";
+ std::cout << "\n";
+}
+
+//////////////////////////////////////////////////////////
+//////////////////// User2 Example ///////////////////////
+//////////////////////////////////////////////////////////
+
+// Demonstrate User2:
+// A "saturating" signed integral type is developed. This type has +/- infinity and a nan
+// (like IEEE floating point) but otherwise obeys signed integral arithmetic.
+// This class is subsequently used as the rep in boost::chrono::duration to demonstrate a
+// duration class that does not silently ignore overflow.
+#include <ostream>
+#include <stdexcept>
+#include <climits>
+
+namespace User2
+{
+
+template <class I>
+class saturate
+{
+public:
+ typedef I int_type;
+
+ static const int_type nan = int_type(int_type(1) << (sizeof(int_type) * CHAR_BIT - 1));
+ static const int_type neg_inf = nan + 1;
+ static const int_type pos_inf = -neg_inf;
+private:
+ int_type i_;
+
+// static_assert(std::is_integral<int_type>::value && std::is_signed<int_type>::value,
+// "saturate only accepts signed integral types");
+// static_assert(nan == -nan && neg_inf < pos_inf,
+// "saturate assumes two's complement hardware for signed integrals");
+
+public:
+ saturate() : i_(nan) {}
+ explicit saturate(int_type i) : i_(i) {}
+ // explicit
+ operator int_type() const;
+
+ saturate& operator+=(saturate x);
+ saturate& operator-=(saturate x) {return *this += -x;}
+ saturate& operator*=(saturate x);
+ saturate& operator/=(saturate x);
+ saturate& operator%=(saturate x);
+
+ saturate operator- () const {return saturate(-i_);}
+ saturate& operator++() {*this += saturate(int_type(1)); return *this;}
+ saturate operator++(int) {saturate tmp(*this); ++(*this); return tmp;}
+ saturate& operator--() {*this -= saturate(int_type(1)); return *this;}
+ saturate operator--(int) {saturate tmp(*this); --(*this); return tmp;}
+
+ friend saturate operator+(saturate x, saturate y) {return x += y;}
+ friend saturate operator-(saturate x, saturate y) {return x -= y;}
+ friend saturate operator*(saturate x, saturate y) {return x *= y;}
+ friend saturate operator/(saturate x, saturate y) {return x /= y;}
+ friend saturate operator%(saturate x, saturate y) {return x %= y;}
+
+ friend bool operator==(saturate x, saturate y)
+ {
+ if (x.i_ == nan || y.i_ == nan)
+ return false;
+ return x.i_ == y.i_;
+ }
+
+ friend bool operator!=(saturate x, saturate y) {return !(x == y);}
+
+ friend bool operator<(saturate x, saturate y)
+ {
+ if (x.i_ == nan || y.i_ == nan)
+ return false;
+ return x.i_ < y.i_;
+ }
+
+ friend bool operator<=(saturate x, saturate y)
+ {
+ if (x.i_ == nan || y.i_ == nan)
+ return false;
+ return x.i_ <= y.i_;
+ }
+
+ friend bool operator>(saturate x, saturate y)
+ {
+ if (x.i_ == nan || y.i_ == nan)
+ return false;
+ return x.i_ > y.i_;
+ }
+
+ friend bool operator>=(saturate x, saturate y)
+ {
+ if (x.i_ == nan || y.i_ == nan)
+ return false;
+ return x.i_ >= y.i_;
+ }
+
+ friend std::ostream& operator<<(std::ostream& os, saturate s)
+ {
+ switch (s.i_)
+ {
+ case pos_inf:
+ return os << "inf";
+ case nan:
+ return os << "nan";
+ case neg_inf:
+ return os << "-inf";
+ };
+ return os << s.i_;
+ }
+};
+
+template <class I>
+saturate<I>::operator int_type() const
+{
+ switch (i_)
+ {
+ case nan:
+ case neg_inf:
+ case pos_inf:
+ throw std::out_of_range("saturate special value can not convert to int_type");
+ }
+ return i_;
+}
+
+template <class I>
+saturate<I>&
+saturate<I>::operator+=(saturate x)
+{
+ switch (i_)
+ {
+ case pos_inf:
+ switch (x.i_)
+ {
+ case neg_inf:
+ case nan:
+ i_ = nan;
+ }
+ return *this;
+ case nan:
+ return *this;
+ case neg_inf:
+ switch (x.i_)
+ {
+ case pos_inf:
+ case nan:
+ i_ = nan;
+ }
+ return *this;
+ }
+ switch (x.i_)
+ {
+ case pos_inf:
+ case neg_inf:
+ case nan:
+ i_ = x.i_;
+ return *this;
+ }
+ if (x.i_ >= 0)
+ {
+ if (i_ < pos_inf - x.i_)
+ i_ += x.i_;
+ else
+ i_ = pos_inf;
+ return *this;
+ }
+ if (i_ > neg_inf - x.i_)
+ i_ += x.i_;
+ else
+ i_ = neg_inf;
+ return *this;
+}
+
+template <class I>
+saturate<I>&
+saturate<I>::operator*=(saturate x)
+{
+ switch (i_)
+ {
+ case 0:
+ switch (x.i_)
+ {
+ case pos_inf:
+ case neg_inf:
+ case nan:
+ i_ = nan;
+ }
+ return *this;
+ case pos_inf:
+ switch (x.i_)
+ {
+ case nan:
+ case 0:
+ i_ = nan;
+ return *this;
+ }
+ if (x.i_ < 0)
+ i_ = neg_inf;
+ return *this;
+ case nan:
+ return *this;
+ case neg_inf:
+ switch (x.i_)
+ {
+ case nan:
+ case 0:
+ i_ = nan;
+ return *this;
+ }
+ if (x.i_ < 0)
+ i_ = pos_inf;
+ return *this;
+ }
+ switch (x.i_)
+ {
+ case 0:
+ i_ = 0;
+ return *this;
+ case nan:
+ i_ = nan;
+ return *this;
+ case pos_inf:
+ if (i_ < 0)
+ i_ = neg_inf;
+ else
+ i_ = pos_inf;
+ return *this;
+ case neg_inf:
+ if (i_ < 0)
+ i_ = pos_inf;
+ else
+ i_ = neg_inf;
+ return *this;
+ }
+ int s = (i_ < 0 ? -1 : 1) * (x.i_ < 0 ? -1 : 1);
+ i_ = i_ < 0 ? -i_ : i_;
+ int_type x_i_ = x.i_ < 0 ? -x.i_ : x.i_;
+ if (i_ <= pos_inf / x_i_)
+ i_ *= x_i_;
+ else
+ i_ = pos_inf;
+ i_ *= s;
+ return *this;
+}
+
+template <class I>
+saturate<I>&
+saturate<I>::operator/=(saturate x)
+{
+ switch (x.i_)
+ {
+ case pos_inf:
+ case neg_inf:
+ switch (i_)
+ {
+ case pos_inf:
+ case neg_inf:
+ case nan:
+ i_ = nan;
+ break;
+ default:
+ i_ = 0;
+ break;
+ }
+ return *this;
+ case nan:
+ i_ = nan;
+ return *this;
+ case 0:
+ switch (i_)
+ {
+ case pos_inf:
+ case neg_inf:
+ case nan:
+ return *this;
+ case 0:
+ i_ = nan;
+ return *this;
+ }
+ if (i_ > 0)
+ i_ = pos_inf;
+ else
+ i_ = neg_inf;
+ return *this;
+ }
+ switch (i_)
+ {
+ case 0:
+ case nan:
+ return *this;
+ case pos_inf:
+ case neg_inf:
+ if (x.i_ < 0)
+ i_ = -i_;
+ return *this;
+ }
+ i_ /= x.i_;
+ return *this;
+}
+
+template <class I>
+saturate<I>&
+saturate<I>::operator%=(saturate x)
+{
+// *this -= *this / x * x; // definition
+ switch (x.i_)
+ {
+ case nan:
+ case neg_inf:
+ case 0:
+ case pos_inf:
+ i_ = nan;
+ return *this;
+ }
+ switch (i_)
+ {
+ case neg_inf:
+ case pos_inf:
+ i_ = nan;
+ case nan:
+ return *this;
+ }
+ i_ %= x.i_;
+ return *this;
+}
+
+// Demo overflow-safe integral durations ranging from picoseconds resolution to millennium resolution
+typedef boost::chrono::duration<saturate<long long>, boost::pico > picoseconds;
+typedef boost::chrono::duration<saturate<long long>, boost::nano > nanoseconds;
+typedef boost::chrono::duration<saturate<long long>, boost::micro > microseconds;
+typedef boost::chrono::duration<saturate<long long>, boost::milli > milliseconds;
+typedef boost::chrono::duration<saturate<long long> > seconds;
+typedef boost::chrono::duration<saturate<long long>, boost::ratio< 60LL> > minutes;
+typedef boost::chrono::duration<saturate<long long>, boost::ratio< 3600LL> > hours;
+typedef boost::chrono::duration<saturate<long long>, boost::ratio< 86400LL> > days;
+typedef boost::chrono::duration<saturate<long long>, boost::ratio< 31556952LL> > years;
+typedef boost::chrono::duration<saturate<long long>, boost::ratio<31556952000LL> > millennium;
+
+} // User2
+
+// Demonstrate custom promotion rules (needed only if there are no implicit conversions)
+namespace User2 { namespace detail {
+
+template <class T1, class T2, bool = boost::is_integral<T1>::value>
+struct promote_helper;
+
+template <class T1, class T2>
+struct promote_helper<T1, saturate<T2>, true> // integral
+{
+ typedef typename boost::common_type<T1, T2>::type rep;
+ typedef User2::saturate<rep> type;
+};
+
+template <class T1, class T2>
+struct promote_helper<T1, saturate<T2>, false> // floating
+{
+ typedef T1 type;
+};
+
+} }
+
+namespace boost
+{
+
+template <class T1, class T2>
+struct common_type<User2::saturate<T1>, User2::saturate<T2> >
+{
+ typedef typename common_type<T1, T2>::type rep;
+ typedef User2::saturate<rep> type;
+};
+
+template <class T1, class T2>
+struct common_type<T1, User2::saturate<T2> >
+ : User2::detail::promote_helper<T1, User2::saturate<T2> > {};
+
+template <class T1, class T2>
+struct common_type<User2::saturate<T1>, T2>
+ : User2::detail::promote_helper<T2, User2::saturate<T1> > {};
+
+
+// Demonstrate specialization of duration_values:
+
+namespace chrono {
+
+template <class I>
+struct duration_values<User2::saturate<I> >
+{
+ typedef User2::saturate<I> Rep;
+public:
+ static Rep zero() {return Rep(0);}
+ static Rep max() {return Rep(Rep::pos_inf-1);}
+ static Rep min() {return -max();}
+};
+
+} // namespace chrono
+
+} // namespace boost
+
+#include <iostream>
+
+void testUser2()
+{
+ std::cout << "*************\n";
+ std::cout << "* testUser2 *\n";
+ std::cout << "*************\n";
+ using namespace User2;
+ typedef seconds::rep sat;
+ years yr(sat(100));
+ std::cout << "100 years expressed as years = " << yr.count() << '\n';
+ nanoseconds ns = yr;
+ std::cout << "100 years expressed as nanoseconds = " << ns.count() << '\n';
+ ns += yr;
+ std::cout << "200 years expressed as nanoseconds = " << ns.count() << '\n';
+ ns += yr;
+ std::cout << "300 years expressed as nanoseconds = " << ns.count() << '\n';
+// yr = ns; // does not compile
+ std::cout << "yr = ns; // does not compile\n";
+// picoseconds ps1 = yr; // does not compile, compile-time overflow in ratio arithmetic
+ std::cout << "ps = yr; // does not compile\n";
+ ns = yr;
+ picoseconds ps = ns;
+ std::cout << "100 years expressed as picoseconds = " << ps.count() << '\n';
+ ps = ns / sat(1000);
+ std::cout << "0.1 years expressed as picoseconds = " << ps.count() << '\n';
+ yr = years(sat(-200000000));
+ std::cout << "200 million years ago encoded in years: " << yr.count() << '\n';
+ days d = boost::chrono::duration_cast<days>(yr);
+ std::cout << "200 million years ago encoded in days: " << d.count() << '\n';
+ millennium c = boost::chrono::duration_cast<millennium>(yr);
+ std::cout << "200 million years ago encoded in millennium: " << c.count() << '\n';
+ std::cout << "Demonstrate \"uninitialized protection\" behavior:\n";
+ seconds sec;
+ for (++sec; sec < seconds(sat(10)); ++sec)
+ ;
+ std::cout << sec.count() << '\n';
+ std::cout << "\n";
+}
+
+void testStdUser()
+{
+ std::cout << "***************\n";
+ std::cout << "* testStdUser *\n";
+ std::cout << "***************\n";
+ using namespace boost::chrono;
+ hours hr = hours(100);
+ std::cout << "100 hours expressed as hours = " << hr.count() << '\n';
+ nanoseconds ns = hr;
+ std::cout << "100 hours expressed as nanoseconds = " << ns.count() << '\n';
+ ns += hr;
+ std::cout << "200 hours expressed as nanoseconds = " << ns.count() << '\n';
+ ns += hr;
+ std::cout << "300 hours expressed as nanoseconds = " << ns.count() << '\n';
+// hr = ns; // does not compile
+ std::cout << "hr = ns; // does not compile\n";
+// hr * ns; // does not compile
+ std::cout << "hr * ns; // does not compile\n";
+ duration<double> fs(2.5);
+ std::cout << "duration<double> has count() = " << fs.count() << '\n';
+// seconds sec = fs; // does not compile
+ std::cout << "seconds sec = duration<double> won't compile\n";
+ seconds sec = duration_cast<seconds>(fs);
+ std::cout << "seconds has count() = " << sec.count() << '\n';
+ std::cout << "\n";
+}
+
+// timeval clock demo
+// Demonstrate the use of a timeval-like struct to be used as the representation
+// type for both duraiton and time_point.
+
+namespace timeval_demo
+{
+
+class xtime {
+private:
+ long tv_sec;
+ long tv_usec;
+
+ void fixup() {
+ if (tv_usec < 0) {
+ tv_usec += 1000000;
+ --tv_sec;
+ }
+ }
+
+public:
+
+ explicit xtime(long sec, long usec) {
+ tv_sec = sec;
+ tv_usec = usec;
+ if (tv_usec < 0 || tv_usec >= 1000000) {
+ tv_sec += tv_usec / 1000000;
+ tv_usec %= 1000000;
+ fixup();
+ }
+ }
+
+ explicit xtime(long long usec)
+ {
+ tv_usec = static_cast<long>(usec % 1000000);
+ tv_sec = static_cast<long>(usec / 1000000);
+ fixup();
+ }
+
+ // explicit
+ operator long long() const {return static_cast<long long>(tv_sec) * 1000000 + tv_usec;}
+
+ xtime& operator += (xtime rhs) {
+ tv_sec += rhs.tv_sec;
+ tv_usec += rhs.tv_usec;
+ if (tv_usec >= 1000000) {
+ tv_usec -= 1000000;
+ ++tv_sec;
+ }
+ return *this;
+ }
+
+ xtime& operator -= (xtime rhs) {
+ tv_sec -= rhs.tv_sec;
+ tv_usec -= rhs.tv_usec;
+ fixup();
+ return *this;
+ }
+
+ xtime& operator %= (xtime rhs) {
+ long long t = tv_sec * 1000000 + tv_usec;
+ long long r = rhs.tv_sec * 1000000 + rhs.tv_usec;
+ t %= r;
+ tv_sec = static_cast<long>(t / 1000000);
+ tv_usec = t % 1000000;
+ fixup();
+ return *this;
+ }
+
+ friend xtime operator+(xtime x, xtime y) {return x += y;}
+ friend xtime operator-(xtime x, xtime y) {return x -= y;}
+ friend xtime operator%(xtime x, xtime y) {return x %= y;}
+
+ friend bool operator==(xtime x, xtime y)
+ { return (x.tv_sec == y.tv_sec && x.tv_usec == y.tv_usec); }
+
+ friend bool operator<(xtime x, xtime y) {
+ if (x.tv_sec == y.tv_sec)
+ return (x.tv_usec < y.tv_usec);
+ return (x.tv_sec < y.tv_sec);
+ }
+
+ friend bool operator!=(xtime x, xtime y) { return !(x == y); }
+ friend bool operator> (xtime x, xtime y) { return y < x; }
+ friend bool operator<=(xtime x, xtime y) { return !(y < x); }
+ friend bool operator>=(xtime x, xtime y) { return !(x < y); }
+
+ friend std::ostream& operator<<(std::ostream& os, xtime x)
+ {return os << '{' << x.tv_sec << ',' << x.tv_usec << '}';}
+};
+
+class xtime_clock
+{
+public:
+ typedef xtime rep;
+ typedef boost::micro period;
+ typedef boost::chrono::duration<rep, period> duration;
+ typedef boost::chrono::time_point<xtime_clock> time_point;
+
+ static time_point now();
+};
+
+xtime_clock::time_point
+xtime_clock::now()
+{
+ time_point t(duration(xtime(0)));
+ gettimeofday((timeval*)&t, 0);
+ return t;
+}
+
+void test_xtime_clock()
+{
+ using namespace boost::chrono;
+ std::cout << "timeval_demo system clock test\n";
+ std::cout << "sizeof xtime_clock::time_point = " << sizeof(xtime_clock::time_point) << '\n';
+ std::cout << "sizeof xtime_clock::duration = " << sizeof(xtime_clock::duration) << '\n';
+ std::cout << "sizeof xtime_clock::rep = " << sizeof(xtime_clock::rep) << '\n';
+ xtime_clock::duration delay(milliseconds(5));
+ xtime_clock::time_point start = xtime_clock::now();
+ while (xtime_clock::now() - start <= delay)
+ {
+ }
+ xtime_clock::time_point stop = xtime_clock::now();
+ xtime_clock::duration elapsed = stop - start;
+ std::cout << "paused " << nanoseconds(elapsed).count() << " nanoseconds\n";
+}
+
+} // timeval_demo
+
+// Handle duration with resolution not known until run time
+
+namespace runtime_resolution
+{
+
+class duration
+{
+public:
+ typedef long long rep;
+private:
+ rep rep_;
+
+ static const double ticks_per_nanosecond;
+
+public:
+ typedef boost::chrono::duration<double, boost::nano> tonanosec;
+
+ duration() {} // = default;
+ explicit duration(const rep& r) : rep_(r) {}
+
+ // conversions
+ explicit duration(const tonanosec& d)
+ : rep_(static_cast<rep>(d.count() * ticks_per_nanosecond)) {}
+
+ // explicit
+ operator tonanosec() const {return tonanosec(rep_/ticks_per_nanosecond);}
+
+ // observer
+
+ rep count() const {return rep_;}
+
+ // arithmetic
+
+ duration& operator+=(const duration& d) {rep_ += d.rep_; return *this;}
+ duration& operator-=(const duration& d) {rep_ += d.rep_; return *this;}
+ duration& operator*=(rep rhs) {rep_ *= rhs; return *this;}
+ duration& operator/=(rep rhs) {rep_ /= rhs; return *this;}
+
+ 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_--);}
+
+ friend duration operator+(duration x, duration y) {return x += y;}
+ friend duration operator-(duration x, duration y) {return x -= y;}
+ friend duration operator*(duration x, rep y) {return x *= y;}
+ friend duration operator*(rep x, duration y) {return y *= x;}
+ friend duration operator/(duration x, rep y) {return x /= y;}
+
+ friend bool operator==(duration x, duration y) {return x.rep_ == y.rep_;}
+ friend bool operator!=(duration x, duration y) {return !(x == y);}
+ friend bool operator< (duration x, duration y) {return x.rep_ < y.rep_;}
+ friend bool operator<=(duration x, duration y) {return !(y < x);}
+ friend bool operator> (duration x, duration y) {return y < x;}
+ friend bool operator>=(duration x, duration y) {return !(x < y);}
+};
+
+static
+double
+init_duration()
+{
+ //mach_timebase_info_data_t MachInfo;
+ //mach_timebase_info(&MachInfo);
+ //return static_cast<double>(MachInfo.denom) / MachInfo.numer;
+ return static_cast<double>(1) / 1000; // Windows FILETIME is 1 per microsec
+}
+
+const double duration::ticks_per_nanosecond = init_duration();
+
+class clock;
+
+class time_point
+{
+public:
+ typedef runtime_resolution::clock clock;
+ typedef long long rep;
+private:
+ rep rep_;
+
+
+ rep count() const {return rep_;}
+public:
+
+ time_point() : rep_(0) {}
+ explicit time_point(const duration& d)
+ : rep_(d.count()) {}
+
+ // arithmetic
+
+ time_point& operator+=(const duration& d) {rep_ += d.count(); return *this;}
+ time_point& operator-=(const duration& d) {rep_ -= d.count(); return *this;}
+
+ friend time_point operator+(time_point x, duration y) {return x += y;}
+ friend time_point operator+(duration x, time_point y) {return y += x;}
+ friend time_point operator-(time_point x, duration y) {return x -= y;}
+ friend duration operator-(time_point x, time_point y) {return duration(x.rep_ - y.rep_);}
+};
+
+class clock
+{
+public:
+ typedef duration::rep rep;
+ typedef runtime_resolution::duration duration;
+ typedef runtime_resolution::time_point time_point;
+
+ static time_point now()
+ {
+ timeval tv;
+ gettimeofday( &tv, 0 );
+ return time_point(duration((static_cast<rep>(tv.tv_sec)<<32) | tv.tv_usec));
+ }
+};
+
+void test()
+{
+ using namespace boost::chrono;
+ std::cout << "runtime_resolution test\n";
+ clock::duration delay(boost::chrono::milliseconds(5));
+ clock::time_point start = clock::now();
+ while (clock::now() - start <= delay)
+ ;
+ clock::time_point stop = clock::now();
+ clock::duration elapsed = stop - start;
+ std::cout << "paused " << nanoseconds(duration_cast<nanoseconds>(duration::tonanosec(elapsed))).count()
+ << " nanoseconds\n";
+}
+
+} // runtime_resolution
+
+// miscellaneous tests and demos:
+
+#include <cassert>
+#include <iostream>
+
+using namespace boost::chrono;
+
+void physics_function(duration<double> d)
+{
+ std::cout << "d = " << d.count() << '\n';
+}
+
+void drive_physics_function()
+{
+ physics_function(nanoseconds(3));
+ physics_function(hours(3));
+ physics_function(duration<double>(2./3));
+ std::cout.precision(16);
+ physics_function( hours(3) + nanoseconds(-3) );
+}
+
+void test_range()
+{
+ using namespace boost::chrono;
+ hours h1 = hours(24 * ( 365 * 292 + 292/4));
+ nanoseconds n1 = h1 + nanoseconds(1);
+ nanoseconds delta = n1 - h1;
+ std::cout << "292 years of hours = " << h1.count() << "hr\n";
+ std::cout << "Add a nanosecond = " << n1.count() << "ns\n";
+ std::cout << "Find the difference = " << delta.count() << "ns\n";
+}
+
+void test_extended_range()
+{
+ using namespace boost::chrono;
+ hours h1 = hours(24 * ( 365 * 244000 + 244000/4));
+ /*auto*/ microseconds u1 = h1 + microseconds(1);
+ /*auto*/ microseconds delta = u1 - h1;
+ std::cout << "244,000 years of hours = " << h1.count() << "hr\n";
+ std::cout << "Add a microsecond = " << u1.count() << "us\n";
+ std::cout << "Find the difference = " << delta.count() << "us\n";
+}
+
+template <class Rep, class Period>
+void inspect_duration(boost::chrono::duration<Rep, Period> d, const std::string& name)
+{
+ typedef boost::chrono::duration<Rep, Period> Duration;
+ std::cout << "********* " << name << " *********\n";
+ std::cout << "The period of " << name << " is " << (double)Period::num/Period::den << " seconds.\n";
+ std::cout << "The frequency of " << name << " is " << (double)Period::den/Period::num << " Hz.\n";
+ std::cout << "The representation is ";
+ if (boost::is_floating_point<Rep>::value)
+ {
+ std::cout << "floating point\n";
+ std::cout << "The precision is the most significant ";
+ std::cout << std::numeric_limits<Rep>::digits10 << " decimal digits.\n";
+ }
+ else if (boost::is_integral<Rep>::value)
+ {
+ std::cout << "integral\n";
+ d = Duration(Rep(1));
+ boost::chrono::duration<double> dsec = d;
+ std::cout << "The precision is " << dsec.count() << " seconds.\n";
+ }
+ else
+ {
+ std::cout << "a class type\n";
+ d = Duration(Rep(1));
+ boost::chrono::duration<double> dsec = d;
+ std::cout << "The precision is " << dsec.count() << " seconds.\n";
+ }
+ d = Duration(std::numeric_limits<Rep>::max());
+ using namespace boost::chrono;
+ using namespace std;
+ typedef duration<double, boost::ratio_multiply<boost::ratio<24*3652425,10000>, hours::period>::type> Years;
+ Years years = d;
+ std::cout << "The range is +/- " << years.count() << " years.\n";
+ std::cout << "sizeof(" << name << ") = " << sizeof(d) << '\n';
+}
+
+void inspect_all()
+{
+ using namespace boost::chrono;
+ std::cout.precision(6);
+ inspect_duration(nanoseconds(), "nanoseconds");
+ inspect_duration(microseconds(), "microseconds");
+ inspect_duration(milliseconds(), "milliseconds");
+ inspect_duration(seconds(), "seconds");
+ inspect_duration(minutes(), "minutes");
+ inspect_duration(hours(), "hours");
+ inspect_duration(duration<double>(), "duration<double>");
+}
+
+void test_milliseconds()
+{
+ using namespace boost::chrono;
+ milliseconds ms(250);
+ ms += milliseconds(1);
+ milliseconds ms2(150);
+ milliseconds msdiff = ms - ms2;
+ if (msdiff == milliseconds(101))
+ std::cout << "success\n";
+ else
+ std::cout << "failure: " << msdiff.count() << '\n';
+}
+
+ using namespace std;
+ using namespace boost::chrono;
+
+// Example round_up utility: converts d to To, rounding up for inexact conversions
+// Being able to *easily* write this function is a major feature!
+template <class To, class Rep, class Period>
+To
+round_up(duration<Rep, Period> d)
+{
+ To result = duration_cast<To>(d);
+ if (result < d)
+ ++result;
+ return result;
+}
+
+// demonstrate interaction with xtime-like facility:
+
+using namespace boost::chrono;
+
+struct xtime
+{
+ long sec;
+ unsigned long usec;
+};
+
+template <class Rep, class Period>
+xtime
+to_xtime_truncate(duration<Rep, Period> d)
+{
+ xtime xt;
+ xt.sec = static_cast<long>(duration_cast<seconds>(d).count());
+ xt.usec = static_cast<long>(duration_cast<microseconds>(d - seconds(xt.sec)).count());
+ return xt;
+}
+
+template <class Rep, class Period>
+xtime
+to_xtime_round_up(duration<Rep, Period> d)
+{
+ xtime xt;
+ xt.sec = static_cast<long>(duration_cast<seconds>(d).count());
+ xt.usec = static_cast<unsigned long>(round_up<microseconds>(d - seconds(xt.sec)).count());
+ return xt;
+}
+
+microseconds
+from_xtime(xtime xt)
+{
+ return seconds(xt.sec) + microseconds(xt.usec);
+}
+
+void print(xtime xt)
+{
+ cout << '{' << xt.sec << ',' << xt.usec << "}\n";
+}
+
+void test_with_xtime()
+{
+ cout << "test_with_xtime\n";
+ xtime xt = to_xtime_truncate(seconds(3) + milliseconds(251));
+ print(xt);
+ milliseconds ms = duration_cast<milliseconds>(from_xtime(xt));
+ cout << ms.count() << " milliseconds\n";
+ xt = to_xtime_round_up(ms);
+ print(xt);
+ xt = to_xtime_truncate(seconds(3) + nanoseconds(999));
+ print(xt);
+ xt = to_xtime_round_up(seconds(3) + nanoseconds(999));
+ print(xt);
+}
+
+void test_system_clock()
+{
+ cout << "system_clock test" << endl;
+ system_clock::duration delay = milliseconds(5);
+ system_clock::time_point start = system_clock::now();
+ while (system_clock::now() - start <= delay)
+ ;
+ system_clock::time_point stop = system_clock::now();
+ system_clock::duration elapsed = stop - start;
+ cout << "paused " << nanoseconds(elapsed).count() << " nanoseconds\n";
+ start = system_clock::now();
+ stop = system_clock::now();
+ cout << "system_clock resolution estimate: " << nanoseconds(stop-start).count() << " nanoseconds\n";
+}
+
+void test_monotonic_clock()
+{
+ cout << "monotonic_clock test" << endl;
+ monotonic_clock::duration delay = milliseconds(5);
+ monotonic_clock::time_point start = monotonic_clock::now();
+ while (monotonic_clock::now() - start <= delay)
+ ;
+ monotonic_clock::time_point stop = monotonic_clock::now();
+ monotonic_clock::duration elapsed = stop - start;
+ cout << "paused " << nanoseconds(elapsed).count() << " nanoseconds\n";
+ start = monotonic_clock::now();
+ stop = monotonic_clock::now();
+ cout << "monotonic_clock resolution estimate: " << nanoseconds(stop-start).count() << " nanoseconds\n";
+}
+
+void test_hi_resolution_clock()
+{
+ cout << "high_resolution_clock test" << endl;
+ high_resolution_clock::duration delay = milliseconds(5);
+ high_resolution_clock::time_point start = high_resolution_clock::now();
+ while (high_resolution_clock::now() - start <= delay)
+ ;
+ high_resolution_clock::time_point stop = high_resolution_clock::now();
+ high_resolution_clock::duration elapsed = stop - start;
+ cout << "paused " << nanoseconds(elapsed).count() << " nanoseconds\n";
+ start = high_resolution_clock::now();
+ stop = high_resolution_clock::now();
+ cout << "high_resolution_clock resolution estimate: " << nanoseconds(stop-start).count() << " nanoseconds\n";
+}
+
+//void test_mixed_clock()
+//{
+// cout << "mixed clock test" << endl;
+// high_resolution_clock::time_point hstart = high_resolution_clock::now();
+// cout << "Add 5 milliseconds to a high_resolution_clock::time_point\n";
+// monotonic_clock::time_point mend = hstart + milliseconds(5);
+// bool b = hstart == mend;
+// system_clock::time_point sstart = system_clock::now();
+// std::cout << "Subtracting system_clock::time_point from monotonic_clock::time_point doesn't compile\n";
+//// mend - sstart; // doesn't compile
+// cout << "subtract high_resolution_clock::time_point from monotonic_clock::time_point"
+// " and add that to a system_clock::time_point\n";
+// system_clock::time_point send = sstart + duration_cast<system_clock::duration>(mend - hstart);
+// cout << "subtract two system_clock::time_point's and output that in microseconds:\n";
+// microseconds ms = send - sstart;
+// cout << ms.count() << " microseconds\n";
+//}
+//
+//void test_c_mapping()
+//{
+// cout << "C map test\n";
+// using namespace boost::chrono;
+// system_clock::time_point t1 = system_clock::now();
+// std::time_t c_time = system_clock::to_time_t(t1);
+// std::tm* tmptr = std::localtime(&c_time);
+// std::cout << "It is now " << tmptr->tm_hour << ':' << tmptr->tm_min << ':' << tmptr->tm_sec << ' '
+// << tmptr->tm_year + 1900 << '-' << tmptr->tm_mon + 1 << '-' << tmptr->tm_mday << '\n';
+// c_time = std::mktime(tmptr);
+// system_clock::time_point t2 = system_clock::from_time_t(c_time);
+// microseconds ms = t1 - t2;
+// std::cout << "Round-tripping through the C interface truncated the precision by " << ms.count() << " microseconds\n";
+//}
+
+void test_duration_division()
+{
+ cout << hours(3) / milliseconds(5) << '\n';
+ cout << milliseconds(5) / hours(3) << '\n';
+ cout << hours(1) / milliseconds(1) << '\n';
+}
+
+namespace I_dont_like_the_default_duration_behavior
+{
+
+// Here's how you override the duration's default constructor to do anything you want (in this case zero)
+
+template <class R>
+class zero_default
+{
+public:
+ typedef R rep;
+
+private:
+ rep rep_;
+public:
+ zero_default(rep i = 0) : rep_(i) {}
+ operator rep() const {return rep_;}
+
+ zero_default& operator+=(zero_default x) {rep_ += x.rep_; return *this;}
+ zero_default& operator-=(zero_default x) {rep_ -= x.rep_; return *this;}
+ zero_default& operator*=(zero_default x) {rep_ *= x.rep_; return *this;}
+ zero_default& operator/=(zero_default x) {rep_ /= x.rep_; return *this;}
+
+ zero_default operator+ () const {return *this;}
+ zero_default operator- () const {return zero_default(-rep_);}
+ zero_default& operator++() {++rep_; return *this;}
+ zero_default operator++(int) {return zero_default(rep_++);}
+ zero_default& operator--() {--rep_; return *this;}
+ zero_default operator--(int) {return zero_default(rep_--);}
+
+ friend zero_default operator+(zero_default x, zero_default y) {return x += y;}
+ friend zero_default operator-(zero_default x, zero_default y) {return x -= y;}
+ friend zero_default operator*(zero_default x, zero_default y) {return x *= y;}
+ friend zero_default operator/(zero_default x, zero_default y) {return x /= y;}
+
+ friend bool operator==(zero_default x, zero_default y) {return x.rep_ == y.rep_;}
+ friend bool operator!=(zero_default x, zero_default y) {return !(x == y);}
+ friend bool operator< (zero_default x, zero_default y) {return x.rep_ < y.rep_;}
+ friend bool operator<=(zero_default x, zero_default y) {return !(y < x);}
+ friend bool operator> (zero_default x, zero_default y) {return y < x;}
+ friend bool operator>=(zero_default x, zero_default y) {return !(x < y);}
+};
+
+typedef boost::chrono::duration<zero_default<long long>, boost::nano > nanoseconds;
+typedef boost::chrono::duration<zero_default<long long>, boost::micro > microseconds;
+typedef boost::chrono::duration<zero_default<long long>, boost::milli > milliseconds;
+typedef boost::chrono::duration<zero_default<long long> > seconds;
+typedef boost::chrono::duration<zero_default<long long>, boost::ratio<60> > minutes;
+typedef boost::chrono::duration<zero_default<long long>, boost::ratio<3600> > hours;
+
+void test()
+{
+ milliseconds ms;
+ cout << ms.count() << '\n';
+}
+
+} // I_dont_like_the_default_duration_behavior
+
+// Build a min for two time_points
+
+template <class Rep, class Period>
+void
+print_duration(ostream& os, duration<Rep, Period> d)
+{
+ os << d.count() << " * " << Period::num << '/' << Period::den << " seconds\n";
+}
+
+// Example min utility: returns the earliest time_point
+// Being able to *easily* write this function is a major feature!
+template <class Clock, class Duration1, class Duration2>
+inline
+typename boost::common_type<time_point<Clock, Duration1>,
+ time_point<Clock, Duration2> >::type
+min(time_point<Clock, Duration1> t1, time_point<Clock, Duration2> t2)
+{
+ return t2 < t1 ? t2 : t1;
+}
+
+void test_min()
+{
+ typedef time_point<system_clock,
+ boost::common_type<system_clock::duration, seconds>::type> T1;
+ typedef time_point<system_clock,
+ boost::common_type<system_clock::duration, nanoseconds>::type> T2;
+ typedef boost::common_type<T1, T2>::type T3;
+ /*auto*/ T1 t1 = system_clock::now() + seconds(3);
+ /*auto*/ T2 t2 = system_clock::now() + nanoseconds(3);
+ /*auto*/ T3 t3 = min(t1, t2);
+ print_duration(cout, t1 - t3);
+ print_duration(cout, t2 - t3);
+}
+
+void explore_limits()
+{
+ typedef duration<long long, boost::ratio_multiply<boost::ratio<24*3652425,10000>,
+ hours::period>::type> Years;
+ monotonic_clock::time_point t1( Years(250));
+ monotonic_clock::time_point t2(-Years(250));
+ // nanosecond resolution is likely to overflow. "up cast" to microseconds.
+ // The "up cast" trades precision for range.
+ microseconds d = time_point_cast<microseconds>(t1) - time_point_cast<microseconds>(t2);
+ cout << d.count() << " microseconds\n";
+}
+
+void manipulate_clock_object(system_clock clock)
+{
+ system_clock::duration delay = milliseconds(5);
+ system_clock::time_point start = clock.now();
+ while (clock.now() - start <= delay)
+ ;
+ system_clock::time_point stop = clock.now();
+ system_clock::duration elapsed = stop - start;
+ cout << "paused " << nanoseconds(elapsed).count() << " nanoseconds\n";
+};
+
+template <long long speed>
+struct cycle_count
+{
+ typedef typename boost::ratio_multiply<boost::ratio<speed>, boost::mega>::type frequency; // Mhz
+ typedef typename boost::ratio_divide<boost::ratio<1>, frequency>::type period;
+ typedef long long rep;
+ typedef boost::chrono::duration<rep, period> duration;
+ typedef boost::chrono::time_point<cycle_count> time_point;
+
+ static time_point now()
+ {
+ static long long tick = 0;
+ // return exact cycle count
+ return time_point(duration(++tick)); // fake access to clock cycle count
+ }
+};
+
+template <long long speed>
+struct approx_cycle_count
+{
+ static const long long frequency = speed * 1000000; // MHz
+ typedef nanoseconds duration;
+ typedef duration::rep rep;
+ typedef duration::period period;
+ static const long long nanosec_per_sec = period::den;
+ typedef boost::chrono::time_point<approx_cycle_count> time_point;
+
+ static time_point now()
+ {
+ static long long tick = 0;
+ // return cycle count as an approximate number of nanoseconds
+ // compute as if nanoseconds is only duration in the std::lib
+ return time_point(duration(++tick * nanosec_per_sec / frequency));
+ }
+};
+
+void cycle_count_delay()
+{
+ {
+ typedef cycle_count<400> clock;
+ cout << "\nSimulated " << clock::frequency::num / boost::mega::num << "MHz clock which has a tick period of "
+ << duration<double, boost::nano>(clock::duration(1)).count() << " nanoseconds\n";
+ nanoseconds delayns(500);
+ clock::duration delay = duration_cast<clock::duration>(delayns);
+ cout << "delay = " << delayns.count() << " nanoseconds which is " << delay.count() << " cycles\n";
+ clock::time_point start = clock::now();
+ clock::time_point stop = start + delay;
+ while (clock::now() < stop) // no multiplies or divides in this loop
+ ;
+ clock::time_point end = clock::now();
+ clock::duration elapsed = end - start;
+ cout << "paused " << elapsed.count() << " cycles ";
+ cout << "which is " << duration_cast<nanoseconds>(elapsed).count() << " nanoseconds\n";
+ }
+ {
+ typedef approx_cycle_count<400> clock;
+ cout << "\nSimulated " << clock::frequency / 1000000 << "MHz clock modeled with nanoseconds\n";
+ clock::duration delay = nanoseconds(500);
+ cout << "delay = " << delay.count() << " nanoseconds\n";
+ clock::time_point start = clock::now();
+ clock::time_point stop = start + delay;
+ while (clock::now() < stop) // 1 multiplication and 1 division in this loop
+ ;
+ clock::time_point end = clock::now();
+ clock::duration elapsed = end - start;
+ cout << "paused " << elapsed.count() << " nanoseconds\n";
+ }
+ {
+ typedef cycle_count<1500> clock;
+ cout << "\nSimulated " << clock::frequency::num / boost::mega::num << "MHz clock which has a tick period of "
+ << duration<double, boost::nano>(clock::duration(1)).count() << " nanoseconds\n";
+ nanoseconds delayns(500);
+ clock::duration delay = duration_cast<clock::duration>(delayns);
+ cout << "delay = " << delayns.count() << " nanoseconds which is " << delay.count() << " cycles\n";
+ clock::time_point start = clock::now();
+ clock::time_point stop = start + delay;
+ while (clock::now() < stop) // no multiplies or divides in this loop
+ ;
+ clock::time_point end = clock::now();
+ clock::duration elapsed = end - start;
+ cout << "paused " << elapsed.count() << " cycles ";
+ cout << "which is " << duration_cast<nanoseconds>(elapsed).count() << " nanoseconds\n";
+ }
+ {
+ typedef approx_cycle_count<1500> clock;
+ cout << "\nSimulated " << clock::frequency / 1000000 << "MHz clock modeled with nanoseconds\n";
+ clock::duration delay = nanoseconds(500);
+ cout << "delay = " << delay.count() << " nanoseconds\n";
+ clock::time_point start = clock::now();
+ clock::time_point stop = start + delay;
+ while (clock::now() < stop) // 1 multiplication and 1 division in this loop
+ ;
+ clock::time_point end = clock::now();
+ clock::duration elapsed = end - start;
+ cout << "paused " << elapsed.count() << " nanoseconds\n";
+ }
+}
+
+void test_special_values()
+{
+ std::cout << "duration<unsigned>::min().count() = " << duration<unsigned>::min().count() << '\n';
+ std::cout << "duration<unsigned>::zero().count() = " << duration<unsigned>::zero().count() << '\n';
+ std::cout << "duration<unsigned>::max().count() = " << duration<unsigned>::max().count() << '\n';
+ std::cout << "duration<int>::min().count() = " << duration<int>::min().count() << '\n';
+ std::cout << "duration<int>::zero().count() = " << duration<int>::zero().count() << '\n';
+ std::cout << "duration<int>::max().count() = " << duration<int>::max().count() << '\n';
+}
+
+int main()
+{
+ basic_examples();
+ testStdUser();
+ testUser1();
+ testUser2();
+ drive_physics_function();
+ test_range();
+ test_extended_range();
+ inspect_all();
+ test_milliseconds();
+ test_with_xtime();
+ test_system_clock();
+ test_monotonic_clock();
+ test_hi_resolution_clock();
+ //test_mixed_clock();
+ timeval_demo::test_xtime_clock();
+ runtime_resolution::test();
+ //test_c_mapping();
+ test_duration_division();
+ I_dont_like_the_default_duration_behavior::test();
+ test_min();
+#if BOOST_VARIADIC_COMMON_TYPE
+ inspect_duration(common_type<duration<double>, hours, microseconds>::type(),
+ "common_type<duration<double>, hours, microseconds>::type");
+#endif
+ explore_limits();
+ manipulate_clock_object(system_clock());
+ duration<double, boost::milli> d = milliseconds(3) * 2.5;
+ inspect_duration(milliseconds(3) * 2.5, "milliseconds(3) * 2.5");
+ cout << d.count() << '\n';
+// milliseconds ms(3.5); // doesn't compile
+ cout << "milliseconds ms(3.5) doesn't compile\n";
+ cycle_count_delay();
+ test_special_values();
+ return 0;
+}
+
Added: sandbox/chrono/libs/chrono/example/time2_demo_output.txt
==============================================================================
--- (empty file)
+++ sandbox/chrono/libs/chrono/example/time2_demo_output.txt 2008-11-12 08:44:21 EST (Wed, 12 Nov 2008)
@@ -0,0 +1,183 @@
+Running basic examples
+sleep_for 3000000 microseconds
+sleep_for 1 microseconds
+sleep_until 10:47:17.728293 which is 4499340 microseconds away
+try_lock_for 30000 microseconds
+try_lock_until 10:47:17.728285 which is 4499303 microseconds away
+wait_for 60000000 microseconds
+wait_until 10:47:17.728285 which is 4499264 microseconds away
+sleep_for 250000 microseconds
+sleep_until 10:47:14.729077 which is 1499979 microseconds away
+***************
+* testStdUser *
+***************
+100 hours expressed as hours = 100
+100 hours expressed as nanoseconds = 360000000000000
+200 hours expressed as nanoseconds = 720000000000000
+300 hours expressed as nanoseconds = 1080000000000000
+hr = ns; // does not compile
+hr * ns; // does not compile
+duration<double> has count() = 2.5
+seconds sec = duration<double> won't compile
+seconds has count() = 2
+
+*************
+* testUser1 *
+*************
+Speed = 24.5872 meters/sec
+Acceleration = 9.81456 meters/sec^2
+Distance = 13.5204 meters
+There are 125/201168 miles/meter which is approximately 0.000621371
+There are 201168/125 meters/mile which is approximately 1609.34
+1 attosecond is 1e-18 seconds
+sec = as; // compiles
+1 second is 1e+18 attoseconds
+as = sec; // compiles
+
+*************
+* testUser2 *
+*************
+100 years expressed as years = 100
+100 years expressed as nanoseconds = 3155695200000000000
+200 years expressed as nanoseconds = 6311390400000000000
+300 years expressed as nanoseconds = inf
+yr = ns; // does not compile
+ps = yr; // does not compile
+100 years expressed as picoseconds = inf
+0.1 years expressed as picoseconds = 3155695200000000000
+200 million years ago encoded in years: -200000000
+200 million years ago encoded in days: -73048500000
+200 million years ago encoded in millennium: -200000
+Demonstrate "uninitialized protection" behavior:
+nan
+
+d = 3e-09
+d = 10800
+d = 0.666667
+d = 10799.999999997
+292 years of hours = 2559672hr
+Add a nanosecond = 9214819200000000001ns
+Find the difference = 1ns
+244,000 years of hours = 2138904000hr
+Add a microsecond = 7700054400000000001us
+Find the difference = 1us
+********* nanoseconds *********
+The period of nanoseconds is 1e-09 seconds.
+The frequency of nanoseconds is 1e+09 Hz.
+The representation is integral
+The precision is 1e-09 seconds.
+The range is +/- 292.277 years.
+sizeof(nanoseconds) = 8
+********* microseconds *********
+The period of microseconds is 1e-06 seconds.
+The frequency of microseconds is 1e+06 Hz.
+The representation is integral
+The precision is 1e-06 seconds.
+The range is +/- 292277 years.
+sizeof(microseconds) = 8
+********* milliseconds *********
+The period of milliseconds is 0.001 seconds.
+The frequency of milliseconds is 1000 Hz.
+The representation is integral
+The precision is 0.001 seconds.
+The range is +/- 2.92277e+08 years.
+sizeof(milliseconds) = 8
+********* seconds *********
+The period of seconds is 1 seconds.
+The frequency of seconds is 1 Hz.
+The representation is integral
+The precision is 1 seconds.
+The range is +/- 2.92277e+11 years.
+sizeof(seconds) = 8
+********* minutes *********
+The period of minutes is 60 seconds.
+The frequency of minutes is 0.0166667 Hz.
+The representation is integral
+The precision is 60 seconds.
+The range is +/- 4083.06 years.
+sizeof(minutes) = 4
+********* hours *********
+The period of hours is 3600 seconds.
+The frequency of hours is 0.000277778 Hz.
+The representation is integral
+The precision is 3600 seconds.
+The range is +/- 244984 years.
+sizeof(hours) = 4
+********* duration<double> *********
+The period of duration<double> is 1 seconds.
+The frequency of duration<double> is 1 Hz.
+The representation is floating point
+The precision is the most significant 15 decimal digits.
+The range is +/- 5.69666e+300 years.
+sizeof(duration<double>) = 8
+success
+test_with_xtime
+{3,251000}
+3251 milliseconds
+{3,251000}
+{3,0}
+{3,1}
+system_clock test
+paused 5001000 nanoseconds
+system_clock resolution estimate: 0 nanoseconds
+monotonic_clock test
+paused 5000181 nanoseconds
+monotonic_clock resolution estimate: 97 nanoseconds
+high_resolution_clock test
+paused 5000277 nanoseconds
+high_resolution_clock resolution estimate: 96 nanoseconds
+mixed clock test
+Add 5 milliseconds to a high_resolution_clock::time_point
+Subtracting system_clock::time_point from monotonic_clock::time_point doesn't compile
+subtract high_resolution_clock::time_point from monotonic_clock::time_point and add that to a system_clock::time_point
+subtract two system_clock::time_point's and output that in microseconds:
+5000 microseconds
+timeval_demo system clock test
+sizeof xtime_clock::time_point = 8
+sizeof xtime_clock::duration = 8
+sizeof xtime_clock::rep = 8
+paused 5001000 nanoseconds
+runtime_resolution test
+paused 5000205 nanoseconds
+C map test
+It is now 10:47:13 2008-4-22
+Round-tripping through the C interface truncated the precision by 255445 microseconds
+2160000
+0
+3600000
+0
+2999998997 * 1/1000000000 seconds
+0 * 1/1000000000 seconds
+15778476000000000 microseconds
+paused 5001000 nanoseconds
+********* milliseconds(3) * 2.5 *********
+The period of milliseconds(3) * 2.5 is 0.001 seconds.
+The frequency of milliseconds(3) * 2.5 is 1000 Hz.
+The representation is floating point
+The precision is the most significant 15 decimal digits.
+The range is +/- 5.69666e+297 years.
+sizeof(milliseconds(3) * 2.5) = 8
+7.5
+milliseconds ms(3.5) doesn't compile
+
+Simulated 400MHz clock which has a tick period of 2.5 nanoseconds
+delay = 500 nanoseconds which is 200 cycles
+paused 201 cycles which is 502 nanoseconds
+
+Simulated 400MHz clock modeled with nanoseconds
+delay = 500 nanoseconds
+paused 503 nanoseconds
+
+Simulated 1500MHz clock which has a tick period of 0.666667 nanoseconds
+delay = 500 nanoseconds which is 750 cycles
+paused 751 cycles which is 500 nanoseconds
+
+Simulated 1500MHz clock modeled with nanoseconds
+delay = 500 nanoseconds
+paused 500 nanoseconds
+duration<unsigned>::min().count() = 0
+duration<unsigned>::zero().count() = 0
+duration<unsigned>::max().count() = 4294967295
+duration<int>::min().count() = -2147483647
+duration<int>::zero().count() = 0
+duration<int>::max().count() = 2147483647
Added: sandbox/chrono/libs/chrono/src/chrono.cpp
==============================================================================
--- (empty file)
+++ sandbox/chrono/libs/chrono/src/chrono.cpp 2008-11-12 08:44:21 EST (Wed, 12 Nov 2008)
@@ -0,0 +1,174 @@
+// chrono.cpp --------------------------------------------------------------//
+
+// Copyright Beman Dawes 2008
+
+// Distributed under the Boost Software License, Version 1.0.
+// See http://www.boost.org/LICENSE_1_0.txt
+
+#include <boost/chrono.hpp>
+#include <stdexcept>
+
+//----------------------------------------------------------------------------//
+// //
+// Platform-specific Implementations //
+// //
+//----------------------------------------------------------------------------//
+
+//----------------------------------------------------------------------------//
+// Windows //
+//----------------------------------------------------------------------------//
+#if defined(BOOST_CHRONO_WINDOWS_API)
+
+#include <windows.h>
+#undef min
+#undef max
+
+namespace
+{
+ double get_nanosecs_per_tic()
+ {
+ LARGE_INTEGER freq;
+ if ( !QueryPerformanceFrequency( &freq ) )
+ {
+ throw
+ std::runtime_error( "monotonic_clock: QueryPerformanceFrequency failed" );
+ }
+ return 1000000000.0L / freq.QuadPart;
+ }
+
+ double nanosecs_per_tic = get_nanosecs_per_tic();
+}
+
+namespace boost
+{
+namespace chrono
+{
+
+ monotonic_clock::time_point monotonic_clock::now()
+ {
+ LARGE_INTEGER pcount;
+ if ( !QueryPerformanceCounter( &pcount ) )
+ {
+ throw
+ std::runtime_error( "monotonic_clock: QueryPerformanceCounter failed" );
+ }
+
+ return time_point(duration(
+ static_cast<monotonic_clock::rep>(nanosecs_per_tic * pcount.QuadPart) ));
+ }
+
+
+ system_clock::time_point system_clock::now()
+ {
+ FILETIME ft;
+ ::GetSystemTimeAsFileTime( &ft ); // never fails
+ return time_point(duration(
+ (static_cast<__int64>( ft.dwHighDateTime ) << 32) | ft.dwLowDateTime));
+ }
+
+ std::time_t system_clock::to_time_t(const system_clock::time_point& t)
+ {
+ __int64 temp = t.time_since_epoch().count();
+
+ # if !defined( BOOST_MSVC ) || BOOST_MSVC > 1300 // > VC++ 7.0
+ temp -= 116444736000000000LL; // delta from epoch in microseconds
+ # else
+ temp -= 116444736000000000;
+ # endif
+
+ temp /= 10000000;
+ return static_cast<std::time_t>( temp );
+ }
+
+ system_clock::time_point system_clock::from_time_t(std::time_t t)
+ {
+ __int64 temp = t;
+ temp *= 10000000;
+
+ # if !defined( BOOST_MSVC ) || BOOST_MSVC > 1300 // > VC++ 7.0
+ temp += 116444736000000000LL;
+ # else
+ temp += 116444736000000000;
+ # endif
+
+ return time_point(duration(temp));
+ }
+
+} // namespace chrono
+} // namespace boost
+
+//----------------------------------------------------------------------------//
+// Mac //
+//----------------------------------------------------------------------------//
+#elif defined(BOOST_CHRONO_MAC_API)
+
+//----------------------------------------------------------------------------//
+// POSIX //
+//----------------------------------------------------------------------------//
+#elif defined(BOOST_CHRONO_POSIX_API)
+
+//#include <sys/time.h>
+#include <time.h>
+
+namespace boost
+{
+namespace chrono
+{
+
+ //system_clock::time_point system_clock::now()
+ //{
+ // timeval tod;
+ // ::gettimeofday( &tod, 0 );
+ //
+ // return time_point(duration(
+ // (static_cast<system_clock::rep>( tod.tv_sec ) * 1000000) + tod.tv_usec));
+ //}
+
+ #ifndef CLOCK_REALTIME
+ # error <time.h> does not supply CLOCK_REALTIME
+ #endif
+
+ system_clock::time_point system_clock::now()
+ {
+ timespec ts;
+ if ( ::clock_gettime( CLOCK_REALTIME, &ts ) )
+ {
+ boost::throw_exception(
+ std::runtime_error( "system_clock: clock_gettime failed" ));
+ }
+
+ return time_point(duration(
+ static_cast<system_clock::rep>( ts.tv_sec ) * 1000000000 + ts.tv_nsec));
+ }
+
+ std::time_t system_clock::to_time_t(const system_clock::time_point& t)
+ {
+ return static_cast<std::time_t>( t.time_since_epoch().count() / 1000000000 );
+ }
+
+ system_clock::time_point system_clock::from_time_t(std::time_t t)
+ {
+ return time_point(duration(static_cast<system_clock::rep>(t) * 1000000000));
+ }
+
+ #ifndef CLOCK_MONOTONIC
+ # error <time.h> does not supply CLOCK_MONOTONIC
+ #endif
+
+ monotonic_clock::time_point monotonic_clock::now()
+ {
+ timespec ts;
+ if ( ::clock_gettime( CLOCK_MONOTONIC, &ts ) )
+ {
+ boost::throw_exception(
+ std::runtime_error( "monotonic_clock: clock_gettime failed" ));
+ }
+
+ return time_point(duration(
+ static_cast<monotonic_clock::rep>( ts.tv_sec ) * 1000000000 + ts.tv_nsec));
+ }
+
+} // namespace chrono
+} // namespace boost
+
+#endif // POSIX
Added: sandbox/chrono/libs/chrono/test/Jamfile.v2
==============================================================================
--- (empty file)
+++ sandbox/chrono/libs/chrono/test/Jamfile.v2 2008-11-12 08:44:21 EST (Wed, 12 Nov 2008)
@@ -0,0 +1,26 @@
+# Boost Chrono Library test Jamfile
+
+# Copyright Beman Dawes 2003, 2006, 2008
+
+# Distributed under the Boost Software License, Version 1.0.
+# See accompanying file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt
+
+# See library home page at http://www.boost.org/libs/chrono
+
+project
+ : requirements
+ <library>/boost/chrono//boost_chrono
+ <toolset>msvc:<asynch-exceptions>on
+ ;
+
+ test-suite "chrono"
+ : [ run ../example/time2_demo.cpp
+ : # command line
+ : # input files
+ : # requirements
+ <link>static
+ ]
+ [ run ../example/time2_demo.cpp
+ : : : : time2_demo_dll
+ ]
+ ;
Added: sandbox/chrono/libs/chrono/test/chrono_msvc/await_keystroke/await_keystroke.vcproj
==============================================================================
--- (empty file)
+++ sandbox/chrono/libs/chrono/test/chrono_msvc/await_keystroke/await_keystroke.vcproj 2008-11-12 08:44:21 EST (Wed, 12 Nov 2008)
@@ -0,0 +1,195 @@
+<?xml version="1.0" encoding="Windows-1252"?>
+<VisualStudioProject
+ ProjectType="Visual C++"
+ Version="9.00"
+ Name="await_keystroke"
+ ProjectGUID="{E0E5B024-EF94-46AE-A848-3973848F2773}"
+ RootNamespace="await_keystroke"
+ Keyword="Win32Proj"
+ TargetFrameworkVersion="196613"
+ >
+ <Platforms>
+ <Platform
+ Name="Win32"
+ />
+ </Platforms>
+ <ToolFiles>
+ </ToolFiles>
+ <Configurations>
+ <Configuration
+ Name="Debug|Win32"
+ ConfigurationType="1"
+ InheritedPropertySheets="..\common.vsprops"
+ CharacterSet="1"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE"
+ MinimalRebuild="true"
+ BasicRuntimeChecks="3"
+ RuntimeLibrary="3"
+ UsePrecompiledHeader="0"
+ WarningLevel="3"
+ DebugInformationFormat="4"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ LinkIncremental="2"
+ GenerateDebugInformation="true"
+ SubSystem="1"
+ TargetMachine="1"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCManifestTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCAppVerifierTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ <Configuration
+ Name="Release|Win32"
+ ConfigurationType="1"
+ InheritedPropertySheets="..\common.vsprops"
+ CharacterSet="1"
+ WholeProgramOptimization="1"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="2"
+ EnableIntrinsicFunctions="true"
+ PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE"
+ RuntimeLibrary="2"
+ EnableFunctionLevelLinking="true"
+ UsePrecompiledHeader="0"
+ WarningLevel="3"
+ DebugInformationFormat="3"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ LinkIncremental="1"
+ GenerateDebugInformation="true"
+ SubSystem="1"
+ OptimizeReferences="2"
+ EnableCOMDATFolding="2"
+ TargetMachine="1"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCManifestTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCAppVerifierTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ </Configurations>
+ <References>
+ </References>
+ <Files>
+ <Filter
+ Name="Source Files"
+ Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx"
+ UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"
+ >
+ <File
+ RelativePath="..\..\..\example\await_keystroke.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\..\src\chrono.cpp"
+ >
+ </File>
+ </Filter>
+ <Filter
+ Name="Header Files"
+ Filter="h;hpp;hxx;hm;inl;inc;xsd"
+ UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"
+ >
+ </Filter>
+ <Filter
+ Name="Resource Files"
+ Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav"
+ UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}"
+ >
+ </Filter>
+ </Files>
+ <Globals>
+ </Globals>
+</VisualStudioProject>
Added: sandbox/chrono/libs/chrono/test/chrono_msvc/chrono_msvc.sln
==============================================================================
--- (empty file)
+++ sandbox/chrono/libs/chrono/test/chrono_msvc/chrono_msvc.sln 2008-11-12 08:44:21 EST (Wed, 12 Nov 2008)
@@ -0,0 +1,32 @@
+
+Microsoft Visual Studio Solution File, Format Version 10.00
+# Visual C++ Express 2008
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ratio_test", "ratio_test\ratio_test.vcproj", "{C2B1EC73-9C8A-46C8-A602-F4DC36EF4874}"
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "time2_demo", "time2_demo\time2_demo.vcproj", "{1635693B-62F9-4D21-B341-090987602716}"
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "await_keystroke", "await_keystroke\await_keystroke.vcproj", "{E0E5B024-EF94-46AE-A848-3973848F2773}"
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|Win32 = Debug|Win32
+ Release|Win32 = Release|Win32
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {C2B1EC73-9C8A-46C8-A602-F4DC36EF4874}.Debug|Win32.ActiveCfg = Debug|Win32
+ {C2B1EC73-9C8A-46C8-A602-F4DC36EF4874}.Debug|Win32.Build.0 = Debug|Win32
+ {C2B1EC73-9C8A-46C8-A602-F4DC36EF4874}.Release|Win32.ActiveCfg = Release|Win32
+ {C2B1EC73-9C8A-46C8-A602-F4DC36EF4874}.Release|Win32.Build.0 = Release|Win32
+ {1635693B-62F9-4D21-B341-090987602716}.Debug|Win32.ActiveCfg = Debug|Win32
+ {1635693B-62F9-4D21-B341-090987602716}.Debug|Win32.Build.0 = Debug|Win32
+ {1635693B-62F9-4D21-B341-090987602716}.Release|Win32.ActiveCfg = Release|Win32
+ {1635693B-62F9-4D21-B341-090987602716}.Release|Win32.Build.0 = Release|Win32
+ {E0E5B024-EF94-46AE-A848-3973848F2773}.Debug|Win32.ActiveCfg = Debug|Win32
+ {E0E5B024-EF94-46AE-A848-3973848F2773}.Debug|Win32.Build.0 = Debug|Win32
+ {E0E5B024-EF94-46AE-A848-3973848F2773}.Release|Win32.ActiveCfg = Release|Win32
+ {E0E5B024-EF94-46AE-A848-3973848F2773}.Release|Win32.Build.0 = Release|Win32
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+EndGlobal
Added: sandbox/chrono/libs/chrono/test/chrono_msvc/common.vsprops
==============================================================================
--- (empty file)
+++ sandbox/chrono/libs/chrono/test/chrono_msvc/common.vsprops 2008-11-12 08:44:21 EST (Wed, 12 Nov 2008)
@@ -0,0 +1,15 @@
+<?xml version="1.0" encoding="Windows-1252"?>
+<VisualStudioPropertySheet
+ ProjectType="Visual C++"
+ Version="8.00"
+ Name="common"
+ OutputDirectory="$(TEMP)\$(SolutionName)\$(ConfigurationName)"
+ IntermediateDirectory="$(TEMP)\$(SolutionName)\$(ProjectName)\$(ConfigurationName)"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ AdditionalIncludeDirectories="..\..\..\.."
+ PreprocessorDefinitions="BOOST_ALL_NO_LIB"
+ ExceptionHandling="2"
+ />
+</VisualStudioPropertySheet>
Added: sandbox/chrono/libs/chrono/test/chrono_msvc/ratio_test/ratio_test.vcproj
==============================================================================
--- (empty file)
+++ sandbox/chrono/libs/chrono/test/chrono_msvc/ratio_test/ratio_test.vcproj 2008-11-12 08:44:21 EST (Wed, 12 Nov 2008)
@@ -0,0 +1,195 @@
+<?xml version="1.0" encoding="Windows-1252"?>
+<VisualStudioProject
+ ProjectType="Visual C++"
+ Version="9.00"
+ Name="ratio_test"
+ ProjectGUID="{C2B1EC73-9C8A-46C8-A602-F4DC36EF4874}"
+ RootNamespace="ratio_test"
+ Keyword="Win32Proj"
+ TargetFrameworkVersion="196613"
+ >
+ <Platforms>
+ <Platform
+ Name="Win32"
+ />
+ </Platforms>
+ <ToolFiles>
+ </ToolFiles>
+ <Configurations>
+ <Configuration
+ Name="Debug|Win32"
+ OutputDirectory="$(SolutionDir)$(ConfigurationName)"
+ IntermediateDirectory="$(ConfigurationName)"
+ ConfigurationType="1"
+ InheritedPropertySheets="..\common.vsprops"
+ CharacterSet="1"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE"
+ MinimalRebuild="true"
+ BasicRuntimeChecks="3"
+ RuntimeLibrary="3"
+ UsePrecompiledHeader="0"
+ WarningLevel="3"
+ DebugInformationFormat="4"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ LinkIncremental="2"
+ GenerateDebugInformation="true"
+ SubSystem="1"
+ TargetMachine="1"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCManifestTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCAppVerifierTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ <Configuration
+ Name="Release|Win32"
+ OutputDirectory="$(SolutionDir)$(ConfigurationName)"
+ IntermediateDirectory="$(ConfigurationName)"
+ ConfigurationType="1"
+ InheritedPropertySheets="..\common.vsprops"
+ CharacterSet="1"
+ WholeProgramOptimization="1"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="2"
+ EnableIntrinsicFunctions="true"
+ PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE"
+ RuntimeLibrary="2"
+ EnableFunctionLevelLinking="true"
+ UsePrecompiledHeader="0"
+ WarningLevel="3"
+ DebugInformationFormat="3"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ LinkIncremental="1"
+ GenerateDebugInformation="true"
+ SubSystem="1"
+ OptimizeReferences="2"
+ EnableCOMDATFolding="2"
+ TargetMachine="1"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCManifestTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCAppVerifierTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ </Configurations>
+ <References>
+ </References>
+ <Files>
+ <Filter
+ Name="Source Files"
+ Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx"
+ UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"
+ >
+ <File
+ RelativePath="..\..\ratio_test.cpp"
+ >
+ </File>
+ </Filter>
+ <Filter
+ Name="Header Files"
+ Filter="h;hpp;hxx;hm;inl;inc;xsd"
+ UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"
+ >
+ </Filter>
+ <Filter
+ Name="Resource Files"
+ Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav"
+ UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}"
+ >
+ </Filter>
+ </Files>
+ <Globals>
+ </Globals>
+</VisualStudioProject>
Added: sandbox/chrono/libs/chrono/test/chrono_msvc/time2_demo/time2_demo.vcproj
==============================================================================
--- (empty file)
+++ sandbox/chrono/libs/chrono/test/chrono_msvc/time2_demo/time2_demo.vcproj 2008-11-12 08:44:21 EST (Wed, 12 Nov 2008)
@@ -0,0 +1,195 @@
+<?xml version="1.0" encoding="Windows-1252"?>
+<VisualStudioProject
+ ProjectType="Visual C++"
+ Version="9.00"
+ Name="time2_demo"
+ ProjectGUID="{1635693B-62F9-4D21-B341-090987602716}"
+ RootNamespace="time2_demo"
+ Keyword="Win32Proj"
+ TargetFrameworkVersion="196613"
+ >
+ <Platforms>
+ <Platform
+ Name="Win32"
+ />
+ </Platforms>
+ <ToolFiles>
+ </ToolFiles>
+ <Configurations>
+ <Configuration
+ Name="Debug|Win32"
+ ConfigurationType="1"
+ InheritedPropertySheets="..\common.vsprops"
+ CharacterSet="1"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE"
+ MinimalRebuild="true"
+ BasicRuntimeChecks="3"
+ RuntimeLibrary="3"
+ UsePrecompiledHeader="0"
+ WarningLevel="3"
+ DebugInformationFormat="4"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ LinkIncremental="2"
+ GenerateDebugInformation="true"
+ SubSystem="1"
+ TargetMachine="1"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCManifestTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCAppVerifierTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ <Configuration
+ Name="Release|Win32"
+ ConfigurationType="1"
+ InheritedPropertySheets="..\common.vsprops"
+ CharacterSet="1"
+ WholeProgramOptimization="1"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="2"
+ EnableIntrinsicFunctions="true"
+ PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE"
+ RuntimeLibrary="2"
+ EnableFunctionLevelLinking="true"
+ UsePrecompiledHeader="0"
+ WarningLevel="3"
+ DebugInformationFormat="3"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ LinkIncremental="1"
+ GenerateDebugInformation="true"
+ SubSystem="1"
+ OptimizeReferences="2"
+ EnableCOMDATFolding="2"
+ TargetMachine="1"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCManifestTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCAppVerifierTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ </Configurations>
+ <References>
+ </References>
+ <Files>
+ <Filter
+ Name="Source Files"
+ Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx"
+ UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"
+ >
+ <File
+ RelativePath="..\..\..\src\chrono.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\..\example\time2_demo.cpp"
+ >
+ </File>
+ </Filter>
+ <Filter
+ Name="Header Files"
+ Filter="h;hpp;hxx;hm;inl;inc;xsd"
+ UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"
+ >
+ </Filter>
+ <Filter
+ Name="Resource Files"
+ Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav"
+ UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}"
+ >
+ </Filter>
+ </Files>
+ <Globals>
+ </Globals>
+</VisualStudioProject>
Added: sandbox/chrono/libs/chrono/test/chrono_unit_test.cpp
==============================================================================
--- (empty file)
+++ sandbox/chrono/libs/chrono/test/chrono_unit_test.cpp 2008-11-12 08:44:21 EST (Wed, 12 Nov 2008)
@@ -0,0 +1,29 @@
+// chrono_unit_test.cpp ----------------------------------------------------//
+
+// Copyright 2008 Beman Dawes
+
+// Distributed under the Boost Software License, Version 1.0.
+// See http://www.boost.org/LICENSE_1_0.txt
+
+#include <boost/chrono.hpp>
+#include <iostream>
+
+
+int main()
+{
+ boost::chrono::nanoseconds nanosecs;
+ boost::chrono::microseconds microsecs;
+ boost::chrono::milliseconds millisecs;
+ boost::chrono::seconds secs;
+ boost::chrono::minutes mins;
+ boost::chrono::hours hrs;
+
+ std::time_t sys_time
+ = boost::chrono::system_clock::to_time_t(boost::chrono::system_clock::now());
+
+ std::cout
+ << "system_clock::to_time_t(system_clock::now()) is "
+ << std::asctime(std::gmtime(&sys_time)) << std::endl;
+
+ return 0;
+}
Added: sandbox/chrono/libs/chrono/test/ratio_test.cpp
==============================================================================
--- (empty file)
+++ sandbox/chrono/libs/chrono/test/ratio_test.cpp 2008-11-12 08:44:21 EST (Wed, 12 Nov 2008)
@@ -0,0 +1,215 @@
+// ratio_test.cpp ----------------------------------------------------------//
+
+// Copyright 2008 Howard Hinnant
+// Copyright 2008 Beman Dawes
+
+// Distributed under the Boost Software License, Version 1.0.
+// See http://www.boost.org/LICENSE_1_0.txt
+
+#include <boost/ratio.hpp>
+#include <iostream>
+
+//////////////////////////////////////////////////////////
+//////////////////// User1 Example ///////////////////////
+//////////////////////////////////////////////////////////
+
+namespace User1
+{
+// Example type-safe "physics" code interoperating with std::chrono::duration types
+// and taking advantage of the std::ratio infrastructure and design philosophy.
+
+// length - mimics std::chrono::duration except restricts representation to double.
+// Uses std::ratio facilities for length units conversions.
+
+template <class Ratio>
+class length
+{
+public:
+ typedef Ratio ratio;
+private:
+ double len_;
+public:
+
+ length() : len_(1) {}
+ length(const double& len) : len_(len) {}
+
+ // conversions
+ template <class R>
+ length(const length<R>& d)
+ : len_(d.count() * boost::ratio_divide<Ratio, R>::type::den /
+ boost::ratio_divide<Ratio, R>::type::num) {}
+
+ // observer
+
+ double count() const {return len_;}
+
+ // arithmetic
+
+ length& operator+=(const length& d) {len_ += d.count(); return *this;}
+ length& operator-=(const length& d) {len_ -= d.count(); return *this;}
+
+ length operator+() const {return *this;}
+ length operator-() const {return length(-len_);}
+
+ length& operator*=(double rhs) {len_ *= rhs; return *this;}
+ length& operator/=(double rhs) {len_ /= rhs; return *this;}
+};
+
+// Sparse sampling of length units
+typedef length<boost::ratio<1> > meter; // set meter as "unity"
+typedef length<boost::centi> centimeter; // 1/100 meter
+typedef length<boost::kilo> kilometer; // 1000 meters
+typedef length<boost::ratio<254, 10000> > inch; // 254/10000 meters
+// length takes ratio instead of two integral types so that definitions can be made like so:
+typedef length<boost::ratio_multiply<boost::ratio<12>, inch::ratio>::type> foot; // 12 inchs
+typedef length<boost::ratio_multiply<boost::ratio<5280>, foot::ratio>::type> mile; // 5280 feet
+
+// Need a floating point definition of seconds
+typedef boost::chrono::duration<double> seconds; // unity
+// Demo of (scientific) support for sub-nanosecond resolutions
+typedef boost::chrono::duration<double, boost::pico> picosecond; // 10^-12 seconds
+typedef boost::chrono::duration<double, boost::femto> femtosecond; // 10^-15 seconds
+typedef boost::chrono::duration<double, boost::atto> attosecond; // 10^-18 seconds
+
+// A very brief proof-of-concept for SIUnits-like library
+// Hard-wired to floating point seconds and meters, but accepts other units (shown in testUser1())
+template <class R1, class R2>
+class quantity
+{
+ double q_;
+public:
+ quantity() : q_(1) {}
+
+ double get() const {return q_;}
+ void set(double q) {q_ = q;}
+};
+
+template <>
+class quantity<boost::ratio<1>, boost::ratio<0> >
+{
+ double q_;
+public:
+ quantity() : q_(1) {}
+ quantity(seconds d) : q_(d.count()) {} // note: only User1::seconds needed here
+
+ double get() const {return q_;}
+ void set(double q) {q_ = q;}
+};
+
+template <>
+class quantity<boost::ratio<0>, boost::ratio<1> >
+{
+ double q_;
+public:
+ quantity() : q_(1) {}
+ quantity(meter d) : q_(d.count()) {} // note: only User1::meter needed here
+
+ double get() const {return q_;}
+ void set(double q) {q_ = q;}
+};
+
+template <>
+class quantity<boost::ratio<0>, boost::ratio<0> >
+{
+ double q_;
+public:
+ quantity() : q_(1) {}
+ quantity(double d) : q_(d) {}
+
+ double get() const {return q_;}
+ void set(double q) {q_ = q;}
+};
+
+// Example SI-Units
+typedef quantity<boost::ratio<0>, boost::ratio<0> > Scalar;
+typedef quantity<boost::ratio<1>, boost::ratio<0> > Time; // second
+typedef quantity<boost::ratio<0>, boost::ratio<1> > Distance; // meter
+typedef quantity<boost::ratio<-1>, boost::ratio<1> > Speed; // meter/second
+typedef quantity<boost::ratio<-2>, boost::ratio<1> > Acceleration; // meter/second^2
+
+template <class R1, class R2, class R3, class R4>
+quantity<typename boost::ratio_subtract<R1, R3>::type, typename boost::ratio_subtract<R2, R4>::type>
+operator/(const quantity<R1, R2>& x, const quantity<R3, R4>& y)
+{
+ typedef quantity<typename boost::ratio_subtract<R1, R3>::type, typename boost::ratio_subtract<R2, R4>::type> R;
+ R r;
+ r.set(x.get() / y.get());
+ return r;
+}
+
+template <class R1, class R2, class R3, class R4>
+quantity<typename boost::ratio_add<R1, R3>::type, typename boost::ratio_add<R2, R4>::type>
+operator*(const quantity<R1, R2>& x, const quantity<R3, R4>& y)
+{
+ typedef quantity<typename boost::ratio_add<R1, R3>::type, typename boost::ratio_add<R2, R4>::type> R;
+ R r;
+ r.set(x.get() * y.get());
+ return r;
+}
+
+template <class R1, class R2>
+quantity<R1, R2>
+operator+(const quantity<R1, R2>& x, const quantity<R1, R2>& y)
+{
+ typedef quantity<R1, R2> R;
+ R r;
+ r.set(x.get() + y.get());
+ return r;
+}
+
+template <class R1, class R2>
+quantity<R1, R2>
+operator-(const quantity<R1, R2>& x, const quantity<R1, R2>& y)
+{
+ typedef quantity<R1, R2> R;
+ R r;
+ r.set(x.get() - y.get());
+ return r;
+}
+
+// Example type-safe physics function
+Distance
+compute_distance(Speed v0, Time t, Acceleration a)
+{
+ return v0 * t + Scalar(.5) * a * t * t; // if a units mistake is made here it won't compile
+}
+
+} // User1
+
+// Exercise example type-safe physics function and show interoperation
+// of custom time durations (User1::seconds) and standard time durations (std::hours).
+// Though input can be arbitrary (but type-safe) units, output is always in SI-units
+// (a limitation of the simplified Units lib demoed here).
+
+int main()
+{
+ std::cout << "*************\n";
+ std::cout << "* testUser1 *\n";
+ std::cout << "*************\n";
+ User1::Distance d( User1::mile(110) );
+ User1::Time t( std::chrono::hours(2) );
+ User1::Speed s = d / t;
+ std::cout << "Speed = " << s.get() << " meters/sec\n";
+ User1::Acceleration a = User1::Distance( User1::foot(32.2) ) / User1::Time() / User1::Time();
+ std::cout << "Acceleration = " << a.get() << " meters/sec^2\n";
+ User1::Distance df = compute_distance(s, User1::Time( User1::seconds(0.5) ), a);
+ std::cout << "Distance = " << df.get() << " meters\n";
+ std::cout << "There are " << User1::mile::ratio::den << '/' << User1::mile::ratio::num << " miles/meter";
+ User1::meter mt = 1;
+ User1::mile mi = mt;
+ std::cout << " which is approximately " << mi.count() << '\n';
+ std::cout << "There are " << User1::mile::ratio::num << '/' << User1::mile::ratio::den << " meters/mile";
+ mi = 1;
+ mt = mi;
+ std::cout << " which is approximately " << mt.count() << '\n';
+ User1::attosecond as(1);
+ User1::seconds sec = as;
+ std::cout << "1 attosecond is " << sec.count() << " seconds\n";
+ std::cout << "sec = as; // compiles\n";
+ sec = User1::seconds(1);
+ as = sec;
+ std::cout << "1 second is " << as.count() << " attoseconds\n";
+ std::cout << "as = sec; // compiles\n";
+ std::cout << "\n";
+ return 0;
+}
Boost-Commit list run by bdawes at acm.org, david.abrahams at rcn.com, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk