    /*
    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        // optional
        high_resolution_clock  // optional

    Much thanks to Andrei Alexandrescu,
                   Walter Brown,
                   Peter Dimov,
                   Jeff Garland,
                   Terry Golubiewski,
                   Daniel Krügler,
                   Anthony Williams.

    Synopsis

    namespace std
    {

    // <type_traits>

    // common_type

    // common_type is ageneral purpose trait that can be specialized for user-defined types.
    // The semantics are intended to be identical to finding the resulting type of a
    // the conditional operator.
    // The client may need to specialize common_type if he wishes to convert to or from
    // another type only explicitly.  It is used to determine the result type
    // in "mixed-mode" duration and time_point arithmetic.  It will also find use in
    // similar "mixed-mode" arithmetic applications.

    template <class T, class U>
    struct common_type
    {
    private:
        static T t();
        static U u();
    public:
        typedef decltype(true ? t() : u()) type;
    };

    // or...

    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;
    };

    // This alternative variadic formulation of common_type has some advantages:
    //
    //   1.  The obvious advantage is that it can handle 3 or more arguments seamlessly.
    //       This can come in handy when writing template functions that take more than
    //       two arguments, such as fma(x, y, z).
    //
    //   2.  We could just get rid of identity (avoiding the legacy conflict) and use
    //       common_type<T>::type in the one place we use identity<T>::type today.
    //
    //   3.  For clients that need to specialize common_type (such as duration and time_point),
    //       the client still needs to specialize only the two-argument version.  The default
    //       definition of the higher-order common_type will automatically use the client's
    //       specialized two-argument version.
    //       For example:
    //           common_type<duration<double>, hours, microseconds>::type is duration<double, micro>

    // ... end or

    //  The cost of not including either version of common_type is that it is very likely that
    //  the implementation would include it anyway, but spell it __common_type instead.  This
    //  would prevent authors of arithmetic emulators from using their classes as representations
    //  with durations unless the emulator had exactly one implicit conversion to or from an
    //  arithmetic type.  This would be a large loss of functionality from the client's point
    //  of view, possibly mandating a less safe interface for the client's arithmetic emulator.

    // ratio

    // ratio is a general purpose type allowing one to easily and safely compute integral
    // ratio values at compile time.  The ratio class catches all errors (such as divide by
    // zero and overflow) at compile time.  It is used in the duration and time_point libraries
    // to efficiently create units of time.  It can also be used in other "quantity"
    // libraries (both std-defined and user-defined), or anywhere there is an integral
    // ratio which is known at compile time.  The use of this utility can greatly reduce
    // the chances of run time overflow because the ratio (and any ratios resulting from
    // ratio arithmetic) are always reduced to lowest terms.

    // The cost of not including ratio would mean that the implementor would likely have this
    // functionality anyway, but spell it __ratio instead.  This would prevent the client from
    // using ratio in his own code as demonstrated in the "User1" example.  Furthermore duration
    // would have to be templated on two long long's instead of on ratio like so:
    //
    //       template <class Rep, long long N, long long D> duration.
    //
    // This would mean that clients wanting to build a custom duration type (say a nanosecond
    // represented by a double) would have to write:
    //
    //       duration<double, 1, 1000000000LL>
    //
    // instead of:
    //
    //       duration<double, nano>
    //
    // This lack of syntatic niceness, along with the loss of functionality in the reuse of
    // ratio in user-written code seems to indicate that the loss of ratio would be a sizeable
    // loss to client code.

    template <intmax_t N, intmax_t D = 1>
    class ratio
    {
        // For every possible value of N and D, abs(N) >= 0 and abs(D) > 0
        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;   // Reduced by greatest common divisor of N and D, has sign of sign(N) * sign(D)
        static const intmax_t den;   // Reduced by greatest common divisor of N and D, always positive
                                     // When num == 0, den == 1
    };

    // The static_asserts in ratio are there to catch any values which have a negative absolute value.
    // In a typical 2's complement representation this is only LLONG_MIN.  The reason for prohibiting
    // this value is because ratio must take the absolute values of its arguments and generally depends
    // on that number being non-negative in order to maintain invariants such as den > 0.

    // convenience typedefs

    typedef ratio<1, 1000000000000000000000000> yocto;  // conditionally supported
    typedef ratio<1,    1000000000000000000000> zepto;  // conditionally supported
    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;  // conditionally supported
    typedef ratio<1000000000000000000000000, 1> yotta;  // conditionally supported

    // Compile time arithmetic and comparisons should either avoid overflow or not compile

    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
    {

    // duration customization traits

    //   Authors of arithmetic emulation types should specialize treat_as_floating_point
    //   if their class emulates floating point and they want to use it as a duration's
    //   representation.

    template <class Rep> struct treat_as_floating_point
      : is_floating_point<Rep> {};

    //   Authors of arithmetic emulation types should specialize duration_values
    //   if they want to use it as a duration's  representation, and the default
    //   definition of duration_values does not have the correct behavior.

    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();}
    };

    // Note:  Rep(0) instead of Rep() is used for zero() because the author of Rep may
    //   chose to have Rep() refer to an inderminant or unitialized value.

    // duration

    // A duration has a representation and a period.
    //
    //    The representation is an arithmetic type, or a class emulating an arithmetic type.
    //
    //    The period is the rational number of seconds between "ticks" of the duration.  The
    //       duration simply holds a count of the elapsed number of ticks (using the
    //       representation), and that is related to seconds by multiplying by the period.
    //       Note, this multiplication is only required when one needs to convert between
    //       durations with different tick periods (e.g. milliseconds to microseconds).
    //
    //    A duration has defalt construction and default copy semantics.  One can also explicitly
    //       construct a duration from its representation or something implicitly convertible to
    //       its representation.  If the representation is integral (or emulated integral) the
    //       duration may not be constructed from a floating point (or emulated floating point)
    //       type, even if that type is impilcitly convertible to the representation (the client
    //       must explicitly convert such an argument as they pass it to the constructor if such
    //       a conversion is desired).
    //
    //    A duration may be implicitly constructible from another duration if the representations
    //       of the two durations meet certain requirements.  Let the representation of this duration
    //       be Rep1 and the representation of the other duration be Rep2.  Example representations
    //       include int, long long, double, or a user-defined class which emulates one of these
    //       arithmetic types.  To qualify for implicit constructability Rep1 must be explicitly
    //       constructible from Rep2.  Note that implicit constructibility of Rep1 from Rep2 is not
    //       required for this implicit construction between durations.  Additionally the trait
    //       common_type<Rep1, Rep2>::type must be well defined.  If a conditional expression involving
    //       these two types isn't valid, there must exist a common_type specialization which makes
    //       the trait valid.
    //
    //       The requirements put on the relationship between Rep1 and Rep2 are intended to be minimal,
    //       and not require implicit conversions (which could be considered error prone by the author
    //       of either of these representations).
    //
    //       In addition to the above relationship between the representations, implicit constructability
    //       also depends on whether the representation is considered floating point (or emulated floating
    //       point) or integral (or emulated integral).
    //
    //       If a duration has a floating point (or emulated floating point) representation it
    //       is implicitly constructible from all other durations of any period (as long as
    //       the representations are compatible as described above).
    //
    //       If a duration has an integral (or emulated integral) representation it is implicitly
    //       constructible from other integral-based durations which have a period which will exactly convert
    //       to the period of this duration with no truncation error.  More specifically, if the
    //       period of this duration is P1, and the period of the other duration is P2, this
    //       duration is implicitly constructible from the other duration if P2/P1 is a whole number
    //       (as long as the representations are compatible as described above).  Example:
    //       microseconds has a period p1 = 1/1000000 seconds.  milliseconds has a period
    //       P2 = 1/1000 seconds.  P2/P1 is (1/1000)/(1/1000000) = 1000000/1000 = 1000.
    //       Therefore microseconds will implicitly construct from milliseconds (but not vice-versa).
    //
    //       These rules involving integral representations are meant to prevent accidental truncatation
    //       error.  If truncation error is desired, a duration_cast facility is available to force it.
    //       Example:
    //          milliseconds ms(3);                    // ok, ms.count() == 3,    which is 0.003    seconds
    //          microseconds us = ms;                  // ok, us.count() == 3000  which is 0.003000 seconds
    //          ++us;                                  // ok, us.count() == 3001  which is 0.003001 seconds
    //          ms = us;                               // won't compile, might truncate
    //          ms = duration_cast<milliseconds>(us);  // ok, ms.count() = 3, truncated a microsecond
    //
    //    A duration has a single observer:  rep count() const; which returns the stored
    //       representation which holds the number of elapsed "ticks".
    //
    //    A duration supports the following member arithmetic:
    //
    //       duration  operator+() const;
    //       duration  operator-() const;
    //       duration& operator++();
    //       duration  operator++(int);
    //       duration& operator--();
    //       duration  operator--(int);
    //
    //       duration& operator+=(duration d);
    //       duration& operator-=(duration d);
    //
    //       duration& operator*=(rep rhs);
    //       duration& operator/=(rep rhs);
    //
    //       The arithmetic simply manipulates the "tick" count in the obvious way (e.g. operator++
    //       increments the tick count by 1).
    //
    //    A duration supports the following non-member arithmetic.
    //       Let D1 represent duration<Rep1, Period1> and D2 represent duration<Rep2, Period2>.
    //
    //       common_type<D1, D2>::type                             operator+(  D1,   D2); // returns a duration
    //       common_type<D1, D2>::type                             operator-(  D1,   D2); // returns a duration
    //       duration<common_type<D1::rep,Rep2>::type, D1::period> operator*(  D1, Rep2); // returns a duration
    //       duration<common_type<D1::rep,Rep2>::type, D1::period> operator*(Rep2,   D1); // returns a duration
    //       duration<common_type<D1::rep,Rep2>::type, D1::period> operator/(  D1, Rep2); // returns a duration
    //       common_type<D1::rep, D2::rep>::type                   operator/(  D1,   D2); // returns a scalar
    //
    //    A duration D1 is fully equality and less-than comparable with any other duration D2, as
    //       long as common_type<D1::rep, D2::rep> is well defined.
    //       Example:
    //          milliseconds ms(3);    // ms.count() == 3,    which is 0.003    seconds
    //          microseconds us = ms;  // us.count() == 3000  which is 0.003000 seconds
    //          --us;                  // us.count() == 2999  which is 0.002999 seconds
    //          assert(ms != us);      // 3 milliseconds is not equal to 2999 microseconds
    //          assert(ms >  us);      // 3 milliseconds is greater than 2999 microseconds
    //          ++us;                  // us.count() == 3000  which is 0.003000 seconds
    //          assert(ms == us);      // 3 milliseconds is equal to 3000 microseconds
    //
    //    Durations based on floating point representations are subject to round off error precisely the
    //       same way their representations are.
    //
    //    Arithmetic and comparisons among integral-based durations is not subject to truncation error or
    //       round off error.  If truncation error would result from the arithmetic (say
    //       by converting a smaller period duration to a larger one) the expression will
    //       not compile (unless duration_cast is used).  If one performs arithmetic
    //       involving the duration's representation (such as division), then truncation
    //       will happen implicitly.
    //
    //    Overflow error may silently happen with a duration.  The std-defined durations
    //       have a minimum range of +/- 292 years.
    //
    //    A duration is a thin wrapper around its representation.  sizeof(duration<Rep, Period>) == sizeof(Rep).
    //
    //    A duration can represent units as small as 10^-18 seconds (attoseconds) and as large as 10^18 seconds
    //       (about 30 billion years).  The range of a duration is based on the range of its representation
    //       combined with its period.

    // The cost of not including the flexibility to represent different "tick periods" in the duration
    // type would be a great loss of both flexibility, convenience and safety for the client.  For example
    // if had just one duration type which counted nanoseconds (no matter how that count was represented),
    // then clients could never have the ability to traffic in picoseconds.  And the only hope of reaching
    // beyond a +/- 292 year range with nanoseconds is to increase the number of bits in the representation
    // (such as a long long).  Furthermore, if the client wanted to traffic in units larger than a nanosecond
    // (e.g. seconds) for convience, they would likely need to set up their own conversion constants and
    // convert manually.
    //
    // If the conversion constants are specified at run time, rather than as compile time integral constants,
    // then the client suffers a significant performance penalty as for every conversion one will have to
    // perform both a multiplication and a division.  In contrast, when converting among any two units of
    // the set (hours, minutes, seconds, milliseconds, microseconds, nanoseconds), there need be only a
    // single multiplication *or* division (never both).  This proposal makes every unit conversion as
    // efficient as if it had been coded by hand (see duration_cast).  Furthermore duration_cast encapsulates
    // all unit conversions within a single uniform-syntax function which is easily used in generic code.  There
    // is no need (or motivation) to set up a "hub-and-spoke" conversion regimen, so that the number of conversion
    // functions is O(N) rather than O(N^2).

    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_;  // exposition only
    public:
        // construction / destruction
        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;

        // copy semantics
        duration(const duration&) = default;
        duration& operator=(const duration&) = default;

        // conversions
        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);

        // observer

        rep count() const;

        // arithmetic

        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);

        // special values

        static constexpr duration zero();
        static constexpr duration min();
        static constexpr duration max();
    };

    // convenience typedefs

    typedef duration<int_least64_t,        nano> nanoseconds;    // 10^-9 seconds
    typedef duration<int_least55_t,       micro> microseconds;   // 10^-6 seconds
    typedef duration<int_least45_t,       milli> milliseconds;   // 10^-3 seconds
    typedef duration<int_least35_t             > seconds;        //     1 second
    typedef duration<int_least29_t, ratio<  60>> minutes;        //    60 seconds
    typedef duration<int_least23_t, ratio<3600>> hours;          //  3600 seconds

    //   duration_cast can be used to force a conversion between two durations (assuming
    //     the source representation can be explicitly converted to the target representation).
    //     Not all integral-based durations are implicitly convertible to another (to
    //     avoid accidental truncation error).  When truncation error is desired, the client
    //     uses duration_cast to explicitly request the non-exact conversion.  When
    //     duration_cast is used to convert between durations which have an implicit conversion,
    //     the behavior and performance of the conversion using duration_cast is identical to
    //     that of the implicit conversion.

    template <class ToDuration, class Rep, class Period>
      requires ToDuration is an instantiation of duration
      ToDuration duration_cast(const duration<Rep, Period>& fd);

    //    Examples:
    //      microseconds us(3500);                              // 3500 microseconds
    //      milliseconds ms = us;                               // Does not compile (implicit truncation)
    //      milliseconds ms = duration_cast<milliseconds>(us);  // 3 milliseconds   (explicit truncation)
    //      us = ms;                                            // 3000 microseconds
    //      us = duration_cast<microseconds>(ms);               // 3000 microseconds

    }  // datetime

    //   Given two durations:  duration<Rep1, Period1> and duration<Rep2, Period2>, the common_type
    //     of those two durations is a duration with a representation of common_type<Rep1, Rep2>,
    //     and a period which is the "greatest common period" of Period1 and Period2.  The GCP
    //     (Greatest Common Period) of Period1 and Period2 is the largest period which will divide
    //     both Period1 and Period2 evenly (and is often equivalent to the minimum of Period1 and
    //     Period2).  This can be computed (by the implementation at compile time) by
    //     GCD(Period1::num, Period2::num) / LCM(Period1::den, Period2::den) where GCD is
    //     "Greatest Common Divisor" and LCM is "Least Common Multiple".

    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;
    };

    // Note:  For any two durations D1 and D2, they will both exactly convert to common_type<D1, D2>::type.
    //   common_type<D1, D2>::type will have the largest possible period to make this possible, and
    //   may be the same type as D1 or D2.  Examples:
    //        common_type<minutes,      microseconds>::type is microseconds.
    //        common_type<milliseconds, microseconds>::type is microseconds.
    //        common_type<nanoseconds,  microseconds>::type is nanoseconds.
    //
    //    A more complex example:
    //        common_type< duration<long, milli>, duration<int, ratio<1,30>> >::type is
    //        duration<long, ratio<1,3000>>.  And both duration<long, milli> and
    //        duration<int, ratio<1,30>> will exactly convert to duration<long, ratio<1,3000>>.
    //        The former multitplies its representation by 3L and the latter converts its
    //        representation to long and multiplies that result by 1000L.  There exists no
    //        duration with a larger period such that both duration<long, milli> and
    //        duration<int, ratio<1,30>> will exactly convert to it.

    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);

    // Note: the above 3 signatures can be approximated with is_convertible if concepts do not
    //   make it into the language.  Requiring only *explicit* convertibility between the Rep
    //   types is strongly desired.  One way or another, Rep2 must be constrained.  Otherwise
    //   the operators are overly generic.

    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);

    // time_point

    // A time_point represents an epoch plus or minus a duration.  The relationship between a time_point
    //    which represents "now" and the time_point's epoch is obtained via a clock.  Each time_point is
    //    tied to a specific clock.  Thus, for any time_point, one can find the duration between that
    //    point in time and now, and between that point in time, and its epoch.
    //
    //    A time_point may be default constructed.  This time_point represents the epoch.  time_point has
    //       default copy semantics.
    //
    //       time_point may be explicitly constructed by a duration having the same representation and period as
    //       the time_point.  Any other duration which is implicitly convertible to the time_point's "native" duration can
    //       also be used to explicitly construct the time_point.  The meaning of this construction is identical to
    //       time_point() + d.
    //
    //       A time_point is implicitly constructible from another time_point if they share the same clock,
    //       and the duration of this time_point is implicitly constructible from the duration of the other
    //       time_point.  A time_point constructed in this fashion will compare equal to the source time_point
    //       after the construction.
    //
    //    A time_point supports the following member arithmetic:
    //
    //       time_point& operator+=(duration d);
    //       time_point& operator-=(duration d);
    //
    //    A time_point supports the following non-member arithmetic.
    //       Let T1 represent time_point<Clock, Duration1>,
    //       T2 represent time_point<Clock, Duration2>,
    //       and D represent duration<Rep3, Period3>.  Note that T1 and T2 must have the same Clock.
    //       Attempts to interoperate times having different clocks results in a compile time failure.
    //
    //       T2 operator+(T1,  D);  // return type is a time_point
    //       T2 operator+( D, T1);  // return type is a time_point
    //       T2 operator-(T1,  D);  // return type is a time_point
    //       D  operator-(T1, T2);  // return type is a duration
    //
    //    A time_point T1 is fully equality and less-than comparable with any other time_point T2 which
    //       has the same clock, and for which their durations are comparable.
    //
    //    Times based on floating point representations are subject to round off error precisely the
    //       same way their representations are.
    //
    //    Times based on integral representations are not subject to truncation error or round off
    //       error.  A compile time error will result if truncation error is possible.  Truncation error
    //       is only possible with construction or the member arithmetic (and won't compile).  Non-member
    //       arithmetic and comparison is always exact.  Overflow error with integral based times remains a
    //       possibility.
    //
    //    A time_point is a thin wrapper around its representation.
    //        sizeof(time_point<Clock, Duration>) == sizeof(Duration) == sizeof(Duration::rep).
    //
    //    A time_point can represent units as small as 10^-18 seconds and as large as 10^18 seconds.  The range
    //       of a time_point is based on the range of its representation combined with its period.
    //
    //    Because no two clocks report the exact same time, even clocks which nominally have the same
    //       epoch, are considered by this framework to have different epochs, if only by a few nanoseconds.
    //       Converting time_points from one clock to another will involve synchronization of the clocks,
    //       which can be viewed as a synchronization of their epochs.  Such synchronization is clock specific
    //       and beyond the scope of this API.  A future API, or a platform specific API, can easily
    //       write such a synchronization API, basing it on this API.

    // The cost of not including a time_point class is the lack of the ability to safely interact with
    // the concept of "epoch + duration".  Without a separate type, the client is in danger of accidently
    // writing code that boils down to "epoch1 + duration1" + "epoch2 + duration2".  Algebraically this
    // results in epoch1+epoch2 as a subexpression which is likely to be completely without meaning.  What
    // would it mean to add New Years 1970 to the point in time at which your computer booted up?  Or for
    // that matter, what is the meaning of "New Years 1970" + "New Years 1970"?
    //
    // Additionally this would force the duration type to play double duty as a time_point leading to
    // client confusion.  For example POSIX has timespec represent a duration in nanosleep, and yet the
    // same type is used as a time_point in pthread_cond_timedwait and pthread_mutex_timedlock.  The
    // confusion seems even more likely with a function such as clock_nanosleep where timespec can mean
    // either a duration or a time_point depending upon another argument to the function.
    //
    // In C++ we can easily mitigate such errors by detecting them at compile time.  This is done through
    // the use of distinct types for these distinct concepts (even though both types have identical layout!).

    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_;  // exposition only

    public:
        time_point();  // has value "epoch"
        explicit time_point(const duration& d);  // same as time_point() + d

        // conversions
        template <class Duration2>
           requires Convertible<Duration2, duration>
           time_point(const time_point<clock, Duration2>& t);

        // observer

        duration time_since_epoch() const;

        // arithmetic

        time_point& operator+=(const duration& d);
        time_point& operator-=(const duration& d);

        // special values

        static time_point min();
        static time_point max();
    };

    }  // datetime

    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);

    // clocks

    // A clock specifies a representation, and a period.  These specifications are used to
    //    to define a clock's native duration and time_point types.  A clock also has a function to get the current
    //    time_point.  A clock need not have any state.

    // The cost of not including separate types for clocks is that there is no better place to
    // bundle the "native" duration and time_point types for a clock with the functionality to
    // get the current time_point (what time is it now?).  By bundling this information into a
    // type, the extension to support multiple clocks is both easy and obvious.  The ability to
    // easily support multiple clocks in such a flexible yet simple and efficient manner is
    // very important.  A client might (for example) write code with the clock as a generic
    // template parameter, and then easily experiment with different timers.

    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();

        // Map to C API
        static time_t      to_time_t  (const time_point& t);
        static time_point  from_time_t(time_t t);
    };

    class monotonic_clock  // optional
    {
    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  // optional
    {
    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();
    };

    // Note: These clocks may be three separate types, or typedefs to one or two common types.

    }  // datetime

    //////////////////////////
    //  Threading interface //
    //////////////////////////

    // timed_mutex

    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;  // optional.  example: pthread_mutex_t*
        native_handle_type native_handle();      // optional
    };

    // recursive_timed_mutex

    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;  // optional.  example: pthread_mutex_t*
        native_handle_type native_handle();      // optional
    };

    // unique_lock

    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();
    };

    // condition_variable

    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();
    };

    // condition_variable_any

    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);
    };

    // sleep

    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);

    }  // this_thread

    }  // std

    */

    #include <ctime>
    #include <climits>
    #include <inttypes.h>
    #include <limits>
    #include "type_traits"

    #define decltype __typeof__

    namespace std
    {

    //////////////////////////////////////////////////////////
    ////////////////////// common_type ///////////////////////
    //////////////////////////////////////////////////////////

    #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

    //////////////////////////////////////////////////////////
    /////////////////////// ratio ////////////////////////////
    //////////////////////////////////////////////////////////

    // __static_gcd

    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;
    };

    // __static_lcm

    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];
    //    static_assert(X <= max - Y, "overflow in __ll_add");
    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];
    //    static_assert(min - Y <= X, "overflow in __ll_add");
    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];
    //    static_assert(min + Y <= X, "overflow in __ll_sub");
    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];
    //    static_assert(X <= max + Y, "overflow in __ll_sub");
    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];
    //    static_assert(X != nan && Y != nan && __a_x <= max / __a_y, "overflow in __ll_mul");
    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;
    };

    // Not actually used but left here in case needed in future maintenance
    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];
    //    static_assert(X != nan && Y != nan && Y != 0, "overflow in __ll_div");
    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];
    //    static_assert(__static_abs<N>::value >= 0, "ratio numerator is out of range");
    //    static_assert(D != 0, "ratio divide by 0");
    //    static_assert(__static_abs<D>::value >  0, "ratio denominator is out of range");
        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;
    };

    // ratio_equal

    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> {};

    // ratio_less

    // 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_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;
    };

    //////////////////////////////////////////////////////////
    ////////////////////// duration //////////////////////////
    //////////////////////////////////////////////////////////

    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> {};

    // 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 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 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 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)));
        }
    };

    // Compile-time select the most efficient algorithm for the conversion...
    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);
    }

    // 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 : 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>());}
    };

    // duration

    template <class Rep, class Period>
    class duration
    {
        static char test0[!__is_duration<Rep>::value];
    //  static_assert(!__is_duration<Rep>::value, "A duration representation can not be a duration");
        static char test1[__is_ratio<Period>::value];
    //  static_assert(__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 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) {}

        // conversions
        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()) {}

        // 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;}

        // special values

        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;

    } // datetime

    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 {

    // Duration ==

    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);
    }

    // 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 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);
    }

    // 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);
    }

    // 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 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;
    }

    // Duration /

    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();
    }

    //////////////////////////////////////////////////////////
    ///////////////////// time_point /////////////////////////
    //////////////////////////////////////////////////////////

    template <class Clock, class Duration = typename Clock::duration>
    class time_point
    {
        static char test1[__is_duration<Duration>::value];
    //  static_assert(__is_duration<Duration>::value,
    //                "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 tmp::enable_if
            <
                tmp::is_convertible<Duration2, duration>::value
            >::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());}
    };

    } // datetime

    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()));
    }

    // 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);
    }

    // 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();
    }

    //////////////////////////////////////////////////////////
    /////////////////////// clocks ///////////////////////////
    //////////////////////////////////////////////////////////

    // 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().

    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;

    } // datetime
    } // std

    // clocks.cpp

    #include <sys/time.h> //for gettimeofday and timeval
    #include <mach/mach_time.h>  // mach_absolute_time, mach_timebase_info_data_t

    namespace std {
    namespace datetime {

    // system_clock

    // gettimeofday is the most precise "system time" available on this platform.
    // It returns the number of microseconds since New Years 1970 in a struct called timeval
    // which has a field for seconds and a field for microseconds.
    //    Fill in the timeval and then convert that to the time_point
    system_clock::time_point
    system_clock::now()
    {
        timeval tv;
        gettimeofday(&tv, 0);
        return time_point(seconds(tv.tv_sec) + microseconds(tv.tv_usec));
    }

    // Take advantage of the fact that on this platform time_t is nothing but
    //    an integral count of seconds since New Years 1970 (same epoch as timeval).
    //    Just get the duration out of the time_point and truncate it to seconds.
    time_t
    system_clock::to_time_t(const time_point& t)
    {
        return time_t(duration_cast<seconds>(t.time_since_epoch()).count());
    }

    // Just turn the time_t into a count of seconds and construct a time_point with it.
    system_clock::time_point
    system_clock::from_time_t(time_t t)
    {
        return system_clock::time_point(seconds(t));
    }

    // monotonic_clock

    // Note, in this implementation monotonic_clock and high_resolution_clock
    //   are the same clock.  They are both based on mach_absolute_time().
    //   mach_absolute_time() * MachInfo.numer / MachInfo.denom is the number of
    //   nanoseconds since the computer booted up.  MachInfo.numer and MachInfo.denom
    //   are run time constants supplied by the OS.  This clock has no relationship
    //   to the Gregorian calendar.  It's main use is as a high resolution timer.

    // MachInfo.numer / MachInfo.denom is often 1 on the latest equipment.  Specialize
    //   for that case as an optimization.
    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()));
    }

    // clocks.cpp end

    } } // std::datetime

    //////////////////////////////////////////////////////////
    ///////////// simulated thread interface /////////////////
    //////////////////////////////////////////////////////////

    #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;
            /* 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";}

        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;
            /* 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";
        }
    };

    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;
            /* 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";
        }
    };

    } // std

    //////////////////////////////////////////////////////////
    ///////////////////  End of implemetation ////////////////
    //////////////////////////////////////////////////////////

    //////////////////////////////////////////////////////////
    //////////// 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 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);
    //    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 std::datetime::duration types
    //  and taking advantage of the std::ratio infrastructure and design philosophy.

    // length - mimics std::datetime::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() * std::ratio_divide<Ratio, R>::type::den /
                                   std::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<std::ratio<1> >          meter;        // set meter as "unity"
    typedef length<std::centi>              centimeter;   // 1/100 meter
    typedef length<std::kilo>               kilometer;    // 1000  meters
    typedef length<std::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<std::ratio_multiply<std::ratio<12>, inch::ratio>::type>   foot;  // 12 inchs
    typedef length<std::ratio_multiply<std::ratio<5280>, foot::ratio>::type> mile;  // 5280 feet

    // Need a floating point definition of seconds
    typedef std::datetime::duration<double> seconds;                         // unity
    // Demo of (scientific) support for sub-nanosecond resolutions
    typedef std::datetime::duration<double,  std::pico> picosecond;  // 10^-12 seconds
    typedef std::datetime::duration<double, std::femto> femtosecond; // 10^-15 seconds
    typedef std::datetime::duration<double,  std::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<std::ratio<1>, std::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<std::ratio<0>, std::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<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;}
    };

    // Example SI-Units
    typedef quantity<std::ratio<0>, std::ratio<0> >  Scalar;
    typedef quantity<std::ratio<1>, std::ratio<0> >  Time;         // second
    typedef quantity<std::ratio<0>, std::ratio<1> >  Distance;     // meter
    typedef quantity<std::ratio<-1>, std::ratio<1> > Speed;        // meter/second
    typedef quantity<std::ratio<-2>, std::ratio<1> > Acceleration; // meter/second^2

    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;
    }

    // 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( 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;  // 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 std::datetime::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 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;

    }  // User2

    // Demonstrate custom promotion rules (needed only if there are no implicit conversions)
    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>  // integral
    {
        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>  // floating
    {
        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> > {};

    // Demonstrate specialization of duration_values:

    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';
    //    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 = 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';
    //    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 = 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";
    }

    }  // 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 std::datetime::duration<double, std::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;
    }

    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() {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";
    }

    }  // runtime_resolution

    // miscellaneous tests and demos:

    #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));
        /*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(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;

    // 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 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";
    //  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 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
    {

    // 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 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';
    }

    }  // 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 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;
        /*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, ratio_multiply<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 ratio_multiply<ratio<speed>, mega>::type frequency;  // Mhz
        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;
            // 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 std::datetime::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 / 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)  // 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 / 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)  // 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 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';
    //    milliseconds ms(3.5);  // doesn't compile
        cout << "milliseconds ms(3.5) doesn't compile\n";
        cycle_count_delay();
        test_special_values();
    }

    /*
    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;  // 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
    */

    /*
    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

    */