UNPKG

boost-react-native-bundle

Version:

Boost library as in https://sourceforge.net/projects/boost/files/boost/1.57.0/

754 lines (648 loc) 172 kB
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html><head> <meta http-equiv="content-type" content="text/html; charset=ISO-8859-1"> <title>time2_demo</title> </head><body> <pre><font color="#c80000">/* Copyright (c) 2008 Howard Hinnant Distributed under the Boost Software License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) A prototype of a proposal for a time/duration/clock library for the C++ standard. It is intended that this be a solid foundation upon which higher level libraries can be based. Examples of such libraries include a date/time library and a physical quantities library. Two general purpose facilities are proposed: common_type ratio And 5 time/duration/clock facilities are proposed duration time_point system_clock monotonic_clock <font color="#c80000">// optional</font> high_resolution_clock <font color="#c80000">// optional</font> Much thanks to Andrei Alexandrescu, Walter Brown, Peter Dimov, Jeff Garland, Terry Golubiewski, Daniel Krügler, Anthony Williams. Synopsis namespace std { <font color="#c80000">// &lt;type_traits&gt;</font> <font color="#c80000">// common_type</font> <font color="#c80000">// common_type is ageneral purpose trait that can be specialized for user-defined types.</font> <font color="#c80000">// The semantics are intended to be identical to finding the resulting type of a</font> <font color="#c80000">// the conditional operator.</font> <font color="#c80000">// The client may need to specialize common_type if he wishes to convert to or from</font> <font color="#c80000">// another type only explicitly. It is used to determine the result type</font> <font color="#c80000">// in "mixed-mode" duration and time_point arithmetic. It will also find use in</font> <font color="#c80000">// similar "mixed-mode" arithmetic applications.</font> template &lt;class T, class U&gt; struct common_type { private: static T t(); static U u(); public: typedef decltype(true ? t() : u()) type; }; <font color="#c80000">// or...</font> template &lt;class ...T&gt; struct common_type; template &lt;class T&gt; struct common_type&lt;T&gt; { typedef T type; }; template &lt;class T, class U&gt; struct common_type&lt;T, U&gt; { private: static T t(); static U u(); public: typedef decltype(true ? t() : u()) type; }; template &lt;class T, class U, class ...V&gt; struct common_type&lt;T, U, V...&gt; { typedef typename common_type&lt;typename common_type&lt;T, U&gt;::type, V...&gt;::type type; }; <font color="#c80000">// This alternative variadic formulation of common_type has some advantages:</font> <font color="#c80000">//</font> <font color="#c80000">// 1. The obvious advantage is that it can handle 3 or more arguments seamlessly.</font> <font color="#c80000">// This can come in handy when writing template functions that take more than</font> <font color="#c80000">// two arguments, such as fma(x, y, z).</font> <font color="#c80000">//</font> <font color="#c80000">// 2. We could just get rid of identity (avoiding the legacy conflict) and use</font> <font color="#c80000">// common_type&lt;T&gt;::type in the one place we use identity&lt;T&gt;::type today.</font> <font color="#c80000">//</font> <font color="#c80000">// 3. For clients that need to specialize common_type (such as duration and time_point),</font> <font color="#c80000">// the client still needs to specialize only the two-argument version. The default</font> <font color="#c80000">// definition of the higher-order common_type will automatically use the client's</font> <font color="#c80000">// specialized two-argument version.</font> <font color="#c80000">// For example:</font> <font color="#c80000">// common_type&lt;duration&lt;double&gt;, hours, microseconds&gt;::type is duration&lt;double, micro&gt;</font> <font color="#c80000">// ... end or</font> <font color="#c80000">// The cost of not including either version of common_type is that it is very likely that</font> <font color="#c80000">// the implementation would include it anyway, but spell it __common_type instead. This</font> <font color="#c80000">// would prevent authors of arithmetic emulators from using their classes as representations</font> <font color="#c80000">// with durations unless the emulator had exactly one implicit conversion to or from an</font> <font color="#c80000">// arithmetic type. This would be a large loss of functionality from the client's point</font> <font color="#c80000">// of view, possibly mandating a less safe interface for the client's arithmetic emulator.</font> <font color="#c80000">// ratio</font> <font color="#c80000">// ratio is a general purpose type allowing one to easily and safely compute integral</font> <font color="#c80000">// ratio values at compile time. The ratio class catches all errors (such as divide by</font> <font color="#c80000">// zero and overflow) at compile time. It is used in the duration and time_point libraries</font> <font color="#c80000">// to efficiently create units of time. It can also be used in other "quantity"</font> <font color="#c80000">// libraries (both std-defined and user-defined), or anywhere there is an integral</font> <font color="#c80000">// ratio which is known at compile time. The use of this utility can greatly reduce</font> <font color="#c80000">// the chances of run time overflow because the ratio (and any ratios resulting from</font> <font color="#c80000">// ratio arithmetic) are always reduced to lowest terms.</font> <font color="#c80000">// The cost of not including ratio would mean that the implementor would likely have this</font> <font color="#c80000">// functionality anyway, but spell it __ratio instead. This would prevent the client from</font> <font color="#c80000">// using ratio in his own code as demonstrated in the "User1" example. Furthermore duration</font> <font color="#c80000">// would have to be templated on two long long's instead of on ratio like so:</font> <font color="#c80000">//</font> <font color="#c80000">// template &lt;class Rep, long long N, long long D&gt; duration.</font> <font color="#c80000">//</font> <font color="#c80000">// This would mean that clients wanting to build a custom duration type (say a nanosecond</font> <font color="#c80000">// represented by a double) would have to write:</font> <font color="#c80000">//</font> <font color="#c80000">// duration&lt;double, 1, 1000000000LL&gt;</font> <font color="#c80000">//</font> <font color="#c80000">// instead of:</font> <font color="#c80000">//</font> <font color="#c80000">// duration&lt;double, nano&gt;</font> <font color="#c80000">//</font> <font color="#c80000">// This lack of syntatic niceness, along with the loss of functionality in the reuse of</font> <font color="#c80000">// ratio in user-written code seems to indicate that the loss of ratio would be a sizeable</font> <font color="#c80000">// loss to client code.</font> template &lt;intmax_t N, intmax_t D = 1&gt; class ratio { <font color="#c80000">// For every possible value of N and D, abs(N) &gt;= 0 and abs(D) &gt; 0</font> static_assert(__static_abs&lt;N&gt;::value &gt;= 0, "ratio numerator is out of range"); static_assert(__static_abs&lt;D&gt;::value &gt; 0, "ratio denominator is out of range"); public: static const intmax_t num; <font color="#c80000">// Reduced by greatest common divisor of N and D, has sign of sign(N) * sign(D)</font> static const intmax_t den; <font color="#c80000">// Reduced by greatest common divisor of N and D, always positive</font> <font color="#c80000">// When num == 0, den == 1</font> }; <font color="#c80000">// The static_asserts in ratio are there to catch any values which have a negative absolute value.</font> <font color="#c80000">// In a typical 2's complement representation this is only LLONG_MIN. The reason for prohibiting</font> <font color="#c80000">// this value is because ratio must take the absolute values of its arguments and generally depends</font> <font color="#c80000">// on that number being non-negative in order to maintain invariants such as den &gt; 0.</font> <font color="#c80000">// convenience typedefs</font> typedef ratio&lt;1, 1000000000000000000000000&gt; yocto; <font color="#c80000">// conditionally supported</font> typedef ratio&lt;1, 1000000000000000000000&gt; zepto; <font color="#c80000">// conditionally supported</font> typedef ratio&lt;1, 1000000000000000000&gt; atto; typedef ratio&lt;1, 1000000000000000&gt; femto; typedef ratio&lt;1, 1000000000000&gt; pico; typedef ratio&lt;1, 1000000000&gt; nano; typedef ratio&lt;1, 1000000&gt; micro; typedef ratio&lt;1, 1000&gt; milli; typedef ratio&lt;1, 100&gt; centi; typedef ratio&lt;1, 10&gt; deci; typedef ratio&lt; 10, 1&gt; deca; typedef ratio&lt; 100, 1&gt; hecto; typedef ratio&lt; 1000, 1&gt; kilo; typedef ratio&lt; 1000000, 1&gt; mega; typedef ratio&lt; 1000000000, 1&gt; giga; typedef ratio&lt; 1000000000000, 1&gt; tera; typedef ratio&lt; 1000000000000000, 1&gt; peta; typedef ratio&lt; 1000000000000000000, 1&gt; exa; typedef ratio&lt; 1000000000000000000000, 1&gt; zetta; <font color="#c80000">// conditionally supported</font> typedef ratio&lt;1000000000000000000000000, 1&gt; yotta; <font color="#c80000">// conditionally supported</font> <font color="#c80000">// Compile time arithmetic and comparisons should either avoid overflow or not compile</font> template &lt;class R1, class R2&gt; requires R1 and R2 are instantiations of ratio struct ratio_add { typedef ratio&lt;pseudo code: R1 + R2&gt; type; }; template &lt;class R1, class R2&gt; requires R1 and R2 are instantiations of ratio struct ratio_subtract { typedef ratio&lt;pseudo code: R1 - R2&gt; type; }; template &lt;class R1, class R2&gt; requires R1 and R2 are instantiations of ratio struct ratio_multiply { typedef ratio&lt;pseudo code: R1 * R2&gt; type; }; template &lt;class R1, class R2&gt; requires R1 and R2 are instantiations of ratio struct ratio_divide { typedef ratio&lt;pseudo code: R1 / R2&gt; type; }; template &lt;class R1, class R2&gt; requires R1 and R2 are instantiations of ratio struct ratio_equal : public integral_constant&lt;bool, pseudo code: R1 == R2&gt; {}; template &lt;class R1, class R2&gt; requires R1 and R2 are instantiations of ratio struct ratio_not_equal : public integral_constant&lt;bool, !ratio_equal&lt;R1, R2&gt;::value&gt; {}; template &lt;class R1, class R2&gt; requires R1 and R2 are instantiations of ratio struct ratio_less : public integral_constant&lt;bool, pseudo code: R1 &lt; R2&gt; {}; template &lt;class R1, class R2&gt; requires R1 and R2 are instantiations of ratio struct ratio_less_equal : public integral_constant&lt;bool, !ratio_less&lt;R2, R1&gt;::value&gt; {}; template &lt;class R1, class R2&gt; requires R1 and R2 are instantiations of ratio struct ratio_greater : public integral_constant&lt;bool, ratio_less&lt;R2, R1&gt;::value&gt; {}; template &lt;class R1, class R2&gt; requires R1 and R2 are instantiations of ratio struct ratio_greater_equal : public integral_constant&lt;bool, !ratio_less&lt;R1, R2&gt;::value&gt; {}; namespace datetime { <font color="#c80000">// duration customization traits</font> <font color="#c80000">// Authors of arithmetic emulation types should specialize treat_as_floating_point</font> <font color="#c80000">// if their class emulates floating point and they want to use it as a duration's</font> <font color="#c80000">// representation.</font> template &lt;class Rep&gt; struct treat_as_floating_point : is_floating_point&lt;Rep&gt; {}; <font color="#c80000">// Authors of arithmetic emulation types should specialize duration_values</font> <font color="#c80000">// if they want to use it as a duration's representation, and the default</font> <font color="#c80000">// definition of duration_values does not have the correct behavior.</font> template &lt;class Rep&gt; struct duration_values { public: static constexpr Rep zero() {return Rep(0);} static constexpr Rep max() {return numeric_limits&lt;Rep&gt;::max();} static constexpr Rep min() {return -max();} }; <font color="#c80000">// Note: Rep(0) instead of Rep() is used for zero() because the author of Rep may</font> <font color="#c80000">// chose to have Rep() refer to an inderminant or unitialized value.</font> <font color="#c80000">// duration</font> <font color="#c80000">// A duration has a representation and a period.</font> <font color="#c80000">// </font> <font color="#c80000">// The representation is an arithmetic type, or a class emulating an arithmetic type.</font> <font color="#c80000">//</font> <font color="#c80000">// The period is the rational number of seconds between "ticks" of the duration. The</font> <font color="#c80000">// duration simply holds a count of the elapsed number of ticks (using the</font> <font color="#c80000">// representation), and that is related to seconds by multiplying by the period.</font> <font color="#c80000">// Note, this multiplication is only required when one needs to convert between</font> <font color="#c80000">// durations with different tick periods (e.g. milliseconds to microseconds).</font> <font color="#c80000">// </font> <font color="#c80000">// A duration has defalt construction and default copy semantics. One can also explicitly</font> <font color="#c80000">// construct a duration from its representation or something implicitly convertible to</font> <font color="#c80000">// its representation. If the representation is integral (or emulated integral) the</font> <font color="#c80000">// duration may not be constructed from a floating point (or emulated floating point)</font> <font color="#c80000">// type, even if that type is impilcitly convertible to the representation (the client</font> <font color="#c80000">// must explicitly convert such an argument as they pass it to the constructor if such</font> <font color="#c80000">// a conversion is desired).</font> <font color="#c80000">// </font> <font color="#c80000">// A duration may be implicitly constructible from another duration if the representations</font> <font color="#c80000">// of the two durations meet certain requirements. Let the representation of this duration</font> <font color="#c80000">// be Rep1 and the representation of the other duration be Rep2. Example representations</font> <font color="#c80000">// include int, long long, double, or a user-defined class which emulates one of these</font> <font color="#c80000">// arithmetic types. To qualify for implicit constructability Rep1 must be explicitly</font> <font color="#c80000">// constructible from Rep2. Note that implicit constructibility of Rep1 from Rep2 is not</font> <font color="#c80000">// required for this implicit construction between durations. Additionally the trait</font> <font color="#c80000">// common_type&lt;Rep1, Rep2&gt;::type must be well defined. If a conditional expression involving</font> <font color="#c80000">// these two types isn't valid, there must exist a common_type specialization which makes</font> <font color="#c80000">// the trait valid.</font> <font color="#c80000">// </font> <font color="#c80000">// The requirements put on the relationship between Rep1 and Rep2 are intended to be minimal,</font> <font color="#c80000">// and not require implicit conversions (which could be considered error prone by the author</font> <font color="#c80000">// of either of these representations).</font> <font color="#c80000">// </font> <font color="#c80000">// In addition to the above relationship between the representations, implicit constructability</font> <font color="#c80000">// also depends on whether the representation is considered floating point (or emulated floating</font> <font color="#c80000">// point) or integral (or emulated integral).</font> <font color="#c80000">// </font> <font color="#c80000">// If a duration has a floating point (or emulated floating point) representation it</font> <font color="#c80000">// is implicitly constructible from all other durations of any period (as long as</font> <font color="#c80000">// the representations are compatible as described above).</font> <font color="#c80000">// </font> <font color="#c80000">// If a duration has an integral (or emulated integral) representation it is implicitly</font> <font color="#c80000">// constructible from other integral-based durations which have a period which will exactly convert</font> <font color="#c80000">// to the period of this duration with no truncation error. More specifically, if the</font> <font color="#c80000">// period of this duration is P1, and the period of the other duration is P2, this</font> <font color="#c80000">// duration is implicitly constructible from the other duration if P2/P1 is a whole number</font> <font color="#c80000">// (as long as the representations are compatible as described above). Example:</font> <font color="#c80000">// microseconds has a period p1 = 1/1000000 seconds. milliseconds has a period</font> <font color="#c80000">// P2 = 1/1000 seconds. P2/P1 is (1/1000)/(1/1000000) = 1000000/1000 = 1000.</font> <font color="#c80000">// Therefore microseconds will implicitly construct from milliseconds (but not vice-versa).</font> <font color="#c80000">//</font> <font color="#c80000">// These rules involving integral representations are meant to prevent accidental truncatation</font> <font color="#c80000">// error. If truncation error is desired, a duration_cast facility is available to force it.</font> <font color="#c80000">// Example:</font> <font color="#c80000">// milliseconds ms(3); // ok, ms.count() == 3, which is 0.003 seconds</font> <font color="#c80000">// microseconds us = ms; // ok, us.count() == 3000 which is 0.003000 seconds</font> <font color="#c80000">// ++us; // ok, us.count() == 3001 which is 0.003001 seconds</font> <font color="#c80000">// ms = us; // won't compile, might truncate</font> <font color="#c80000">// ms = duration_cast&lt;milliseconds&gt;(us); // ok, ms.count() = 3, truncated a microsecond</font> <font color="#c80000">// </font> <font color="#c80000">// A duration has a single observer: rep count() const; which returns the stored</font> <font color="#c80000">// representation which holds the number of elapsed "ticks".</font> <font color="#c80000">// </font> <font color="#c80000">// A duration supports the following member arithmetic:</font> <font color="#c80000">// </font> <font color="#c80000">// duration operator+() const;</font> <font color="#c80000">// duration operator-() const;</font> <font color="#c80000">// duration&amp; operator++();</font> <font color="#c80000">// duration operator++(int);</font> <font color="#c80000">// duration&amp; operator--();</font> <font color="#c80000">// duration operator--(int);</font> <font color="#c80000">// </font> <font color="#c80000">// duration&amp; operator+=(duration d);</font> <font color="#c80000">// duration&amp; operator-=(duration d);</font> <font color="#c80000">// </font> <font color="#c80000">// duration&amp; operator*=(rep rhs);</font> <font color="#c80000">// duration&amp; operator/=(rep rhs);</font> <font color="#c80000">//</font> <font color="#c80000">// The arithmetic simply manipulates the "tick" count in the obvious way (e.g. operator++</font> <font color="#c80000">// increments the tick count by 1).</font> <font color="#c80000">// </font> <font color="#c80000">// A duration supports the following non-member arithmetic.</font> <font color="#c80000">// Let D1 represent duration&lt;Rep1, Period1&gt; and D2 represent duration&lt;Rep2, Period2&gt;.</font> <font color="#c80000">// </font> <font color="#c80000">// common_type&lt;D1, D2&gt;::type operator+( D1, D2); // returns a duration</font> <font color="#c80000">// common_type&lt;D1, D2&gt;::type operator-( D1, D2); // returns a duration</font> <font color="#c80000">// duration&lt;common_type&lt;D1::rep,Rep2&gt;::type, D1::period&gt; operator*( D1, Rep2); // returns a duration</font> <font color="#c80000">// duration&lt;common_type&lt;D1::rep,Rep2&gt;::type, D1::period&gt; operator*(Rep2, D1); // returns a duration</font> <font color="#c80000">// duration&lt;common_type&lt;D1::rep,Rep2&gt;::type, D1::period&gt; operator/( D1, Rep2); // returns a duration</font> <font color="#c80000">// common_type&lt;D1::rep, D2::rep&gt;::type operator/( D1, D2); // returns a scalar</font> <font color="#c80000">// </font> <font color="#c80000">// A duration D1 is fully equality and less-than comparable with any other duration D2, as</font> <font color="#c80000">// long as common_type&lt;D1::rep, D2::rep&gt; is well defined.</font> <font color="#c80000">// Example:</font> <font color="#c80000">// milliseconds ms(3); // ms.count() == 3, which is 0.003 seconds</font> <font color="#c80000">// microseconds us = ms; // us.count() == 3000 which is 0.003000 seconds</font> <font color="#c80000">// --us; // us.count() == 2999 which is 0.002999 seconds</font> <font color="#c80000">// assert(ms != us); // 3 milliseconds is not equal to 2999 microseconds</font> <font color="#c80000">// assert(ms &gt; us); // 3 milliseconds is greater than 2999 microseconds</font> <font color="#c80000">// ++us; // us.count() == 3000 which is 0.003000 seconds</font> <font color="#c80000">// assert(ms == us); // 3 milliseconds is equal to 3000 microseconds</font> <font color="#c80000">//</font> <font color="#c80000">// Durations based on floating point representations are subject to round off error precisely the</font> <font color="#c80000">// same way their representations are.</font> <font color="#c80000">// </font> <font color="#c80000">// Arithmetic and comparisons among integral-based durations is not subject to truncation error or</font> <font color="#c80000">// round off error. If truncation error would result from the arithmetic (say</font> <font color="#c80000">// by converting a smaller period duration to a larger one) the expression will</font> <font color="#c80000">// not compile (unless duration_cast is used). If one performs arithmetic</font> <font color="#c80000">// involving the duration's representation (such as division), then truncation</font> <font color="#c80000">// will happen implicitly.</font> <font color="#c80000">// </font> <font color="#c80000">// Overflow error may silently happen with a duration. The std-defined durations</font> <font color="#c80000">// have a minimum range of +/- 292 years.</font> <font color="#c80000">// </font> <font color="#c80000">// A duration is a thin wrapper around its representation. sizeof(duration&lt;Rep, Period&gt;) == sizeof(Rep).</font> <font color="#c80000">// </font> <font color="#c80000">// A duration can represent units as small as 10^-18 seconds (attoseconds) and as large as 10^18 seconds</font> <font color="#c80000">// (about 30 billion years). The range of a duration is based on the range of its representation</font> <font color="#c80000">// combined with its period.</font> <font color="#c80000">// The cost of not including the flexibility to represent different "tick periods" in the duration</font> <font color="#c80000">// type would be a great loss of both flexibility, convenience and safety for the client. For example</font> <font color="#c80000">// if had just one duration type which counted nanoseconds (no matter how that count was represented),</font> <font color="#c80000">// then clients could never have the ability to traffic in picoseconds. And the only hope of reaching</font> <font color="#c80000">// beyond a +/- 292 year range with nanoseconds is to increase the number of bits in the representation</font> <font color="#c80000">// (such as a long long). Furthermore, if the client wanted to traffic in units larger than a nanosecond</font> <font color="#c80000">// (e.g. seconds) for convience, they would likely need to set up their own conversion constants and</font> <font color="#c80000">// convert manually.</font> <font color="#c80000">//</font> <font color="#c80000">// If the conversion constants are specified at run time, rather than as compile time integral constants,</font> <font color="#c80000">// then the client suffers a significant performance penalty as for every conversion one will have to</font> <font color="#c80000">// perform both a multiplication and a division. In contrast, when converting among any two units of</font> <font color="#c80000">// the set (hours, minutes, seconds, milliseconds, microseconds, nanoseconds), there need be only a</font> <font color="#c80000">// single multiplication *or* division (never both). This proposal makes every unit conversion as</font> <font color="#c80000">// efficient as if it had been coded by hand (see duration_cast). Furthermore duration_cast encapsulates</font> <font color="#c80000">// all unit conversions within a single uniform-syntax function which is easily used in generic code. There</font> <font color="#c80000">// is no need (or motivation) to set up a "hub-and-spoke" conversion regimen, so that the number of conversion</font> <font color="#c80000">// functions is O(N) rather than O(N^2).</font> template &lt;class Rep, class Period = ratio&lt;1&gt;&gt; requires Rep is an arithmetic type, or a class emulating an arithmetic type, and not an instantiation of duration requires Period is an instantiation of ratio and represents a positive fraction class duration { public: typedef Rep rep; typedef Period period; private: rep rep_; <font color="#c80000">// exposition only</font> public: <font color="#c80000">// construction / destruction</font> duration() = default; template &lt;class Rep2&gt; requires is_convertible&lt;Rep2, rep&gt;::value &amp;&amp; (treat_as_floating_point&lt;rep&gt;::value || !treat_as_floating_point&lt;rep&gt;::value &amp;&amp; !treat_as_floating_point&lt;Rep2&gt;::value) explicit duration(const Rep2&amp; r); ~duration() = default; <font color="#c80000">// copy semantics</font> duration(const duration&amp;) = default; duration&amp; operator=(const duration&amp;) = default; <font color="#c80000">// conversions</font> template &lt;class Rep2, class Period2&gt; requires Rep2 is explicitly convertible to rep &amp;&amp; (treat_as_floating_point&lt;rep&gt;::value || !treat_as_floating_point&lt;Rep2&gt;::value &amp;&amp; ratio_divide&lt;Period2, period&gt;::type::den == 1) duration(const duration&lt;Rep2, Period2&gt;&amp; d); <font color="#c80000">// observer</font> rep count() const; <font color="#c80000">// arithmetic</font> duration operator+() const; duration operator-() const; duration&amp; operator++(); duration operator++(int); duration&amp; operator--(); duration operator--(int); duration&amp; operator+=(const duration&amp; d); duration&amp; operator-=(const duration&amp; d); duration&amp; operator*=(const rep&amp; rhs); duration&amp; operator/=(const rep&amp; rhs); <font color="#c80000">// special values</font> static constexpr duration zero(); static constexpr duration min(); static constexpr duration max(); }; <font color="#c80000">// convenience typedefs</font> typedef duration&lt;int_least64_t, nano&gt; nanoseconds; <font color="#c80000">// 10^-9 seconds</font> typedef duration&lt;int_least55_t, micro&gt; microseconds; <font color="#c80000">// 10^-6 seconds</font> typedef duration&lt;int_least45_t, milli&gt; milliseconds; <font color="#c80000">// 10^-3 seconds</font> typedef duration&lt;int_least35_t &gt; seconds; <font color="#c80000">// 1 second</font> typedef duration&lt;int_least29_t, ratio&lt; 60&gt;&gt; minutes; <font color="#c80000">// 60 seconds</font> typedef duration&lt;int_least23_t, ratio&lt;3600&gt;&gt; hours; <font color="#c80000">// 3600 seconds</font> <font color="#c80000">// duration_cast can be used to force a conversion between two durations (assuming</font> <font color="#c80000">// the source representation can be explicitly converted to the target representation).</font> <font color="#c80000">// Not all integral-based durations are implicitly convertible to another (to</font> <font color="#c80000">// avoid accidental truncation error). When truncation error is desired, the client</font> <font color="#c80000">// uses duration_cast to explicitly request the non-exact conversion. When</font> <font color="#c80000">// duration_cast is used to convert between durations which have an implicit conversion,</font> <font color="#c80000">// the behavior and performance of the conversion using duration_cast is identical to</font> <font color="#c80000">// that of the implicit conversion.</font> template &lt;class ToDuration, class Rep, class Period&gt; requires ToDuration is an instantiation of duration ToDuration duration_cast(const duration&lt;Rep, Period&gt;&amp; fd); <font color="#c80000">// Examples:</font> <font color="#c80000">// microseconds us(3500); // 3500 microseconds</font> <font color="#c80000">// milliseconds ms = us; // Does not compile (implicit truncation)</font> <font color="#c80000">// milliseconds ms = duration_cast&lt;milliseconds&gt;(us); // 3 milliseconds (explicit truncation)</font> <font color="#c80000">// us = ms; // 3000 microseconds</font> <font color="#c80000">// us = duration_cast&lt;microseconds&gt;(ms); // 3000 microseconds</font> } <font color="#c80000">// datetime</font> <font color="#c80000">// Given two durations: duration&lt;Rep1, Period1&gt; and duration&lt;Rep2, Period2&gt;, the common_type</font> <font color="#c80000">// of those two durations is a duration with a representation of common_type&lt;Rep1, Rep2&gt;,</font> <font color="#c80000">// and a period which is the "greatest common period" of Period1 and Period2. The GCP</font> <font color="#c80000">// (Greatest Common Period) of Period1 and Period2 is the largest period which will divide</font> <font color="#c80000">// both Period1 and Period2 evenly (and is often equivalent to the minimum of Period1 and</font> <font color="#c80000">// Period2). This can be computed (by the implementation at compile time) by</font> <font color="#c80000">// GCD(Period1::num, Period2::num) / LCM(Period1::den, Period2::den) where GCD is</font> <font color="#c80000">// "Greatest Common Divisor" and LCM is "Least Common Multiple".</font> template &lt;class Rep1, class Period1, class Rep2, class Period2&gt; struct common_type&lt;datetime::duration&lt;Rep1, Period1&gt;, datetime::duration&lt;Rep2, Period2&gt; &gt; { typedef datetime::duration&lt;typename common_type&lt;Rep1, Rep2&gt;::type, ratio&lt;GCD(Period1::num, Period2::num), LCM(Period1::den, Period2::den)&gt;&gt; type; }; <font color="#c80000">// Note: For any two durations D1 and D2, they will both exactly convert to common_type&lt;D1, D2&gt;::type.</font> <font color="#c80000">// common_type&lt;D1, D2&gt;::type will have the largest possible period to make this possible, and</font> <font color="#c80000">// may be the same type as D1 or D2. Examples:</font> <font color="#c80000">// common_type&lt;minutes, microseconds&gt;::type is microseconds.</font> <font color="#c80000">// common_type&lt;milliseconds, microseconds&gt;::type is microseconds.</font> <font color="#c80000">// common_type&lt;nanoseconds, microseconds&gt;::type is nanoseconds.</font> <font color="#c80000">//</font> <font color="#c80000">// A more complex example:</font> <font color="#c80000">// common_type&lt; duration&lt;long, milli&gt;, duration&lt;int, ratio&lt;1,30&gt;&gt; &gt;::type is</font> <font color="#c80000">// duration&lt;long, ratio&lt;1,3000&gt;&gt;. And both duration&lt;long, milli&gt; and </font> <font color="#c80000">// duration&lt;int, ratio&lt;1,30&gt;&gt; will exactly convert to duration&lt;long, ratio&lt;1,3000&gt;&gt;.</font> <font color="#c80000">// The former multitplies its representation by 3L and the latter converts its</font> <font color="#c80000">// representation to long and multiplies that result by 1000L. There exists no</font> <font color="#c80000">// duration with a larger period such that both duration&lt;long, milli&gt; and</font> <font color="#c80000">// duration&lt;int, ratio&lt;1,30&gt;&gt; will exactly convert to it.</font> namespace datetime { template &lt;class Rep1, class Period1, class Rep2, class Period2&gt; bool operator==(const duration&lt;Rep1, Period1&gt;&amp; lhs, const duration&lt;Rep2, Period2&gt;&amp; rhs); template &lt;class Rep1, class Period1, class Rep2, class Period2&gt; bool operator!=(const duration&lt;Rep1, Period1&gt;&amp; lhs, const duration&lt;Rep2, Period2&gt;&amp; rhs); template &lt;class Rep1, class Period1, class Rep2, class Period2&gt; bool operator&lt; (const duration&lt;Rep1, Period1&gt;&amp; lhs, const duration&lt;Rep2, Period2&gt;&amp; rhs); template &lt;class Rep1, class Period1, class Rep2, class Period2&gt; bool operator&lt;=(const duration&lt;Rep1, Period1&gt;&amp; lhs, const duration&lt;Rep2, Period2&gt;&amp; rhs); template &lt;class Rep1, class Period1, class Rep2, class Period2&gt; bool operator&gt; (const duration&lt;Rep1, Period1&gt;&amp; lhs, const duration&lt;Rep2, Period2&gt;&amp; rhs); template &lt;class Rep1, class Period1, class Rep2, class Period2&gt; bool operator&gt;=(const duration&lt;Rep1, Period1&gt;&amp; lhs, const duration&lt;Rep2, Period2&gt;&amp; rhs); template &lt;class Rep1, class Period1, class Rep2, class Period2&gt; typename common_type&lt;duration&lt;Rep1, Period1&gt;, duration&lt;Rep2, Period2&gt; &gt;::type operator+(const duration&lt;Rep1, Period1&gt;&amp; lhs, const duration&lt;Rep2, Period2&gt;&amp; rhs); template &lt;class Rep1, class Period1, class Rep2, class Period2&gt; typename common_type&lt;duration&lt;Rep1, Period1&gt;, duration&lt;Rep2, Period2&gt; &gt;::type operator-(const duration&lt;Rep1, Period1&gt;&amp; lhs, const duration&lt;Rep2, Period2&gt;&amp; rhs); template &lt;class Rep1, class Period, class Rep2&gt; requires Constructible&lt;Rep1, typename common_type&lt;Rep1, Rep2&gt;::type&gt;::value&gt; &amp;&amp; Constructible&lt;Rep2, typename common_type&lt;Rep1, Rep2&gt;::type&gt;::value&gt; duration&lt;typename common_type&lt;Rep1, Rep2&gt;::type, Period&gt; operator*(const duration&lt;Rep, Period&gt;&amp; d, const Rep2&amp; s); template &lt;class Rep1, class Period, class Rep2&gt; requires Constructible&lt;Rep1, typename common_type&lt;Rep1, Rep2&gt;::type&gt;::value&gt; &amp;&amp; Constructible&lt;Rep2, typename common_type&lt;Rep1, Rep2&gt;::type&gt;::value&gt; duration&lt;typename common_type&lt;Rep1, Rep2&gt;::type, Period&gt; operator*(const Rep2&amp; s, const duration&lt;Rep, Period&gt;&amp; d); template &lt;class Rep1, class Period, class Rep2&gt; requires Rep2 is not a duration &amp;&amp; Constructible&lt;Rep1, typename common_type&lt;Rep1, Rep2&gt;::type&gt;::value&gt; &amp;&amp; Constructible&lt;Rep2, typename common_type&lt;Rep1, Rep2&gt;::type&gt;::value&gt; duration&lt;typename common_type&lt;Rep1, Rep2&gt;::type, Period&gt; operator/(const duration&lt;Rep, Period&gt;&amp; d, const Rep2&amp; s); <font color="#c80000">// Note: the above 3 signatures can be approximated with is_convertible if concepts do not</font> <font color="#c80000">// make it into the language. Requiring only *explicit* convertibility between the Rep</font> <font color="#c80000">// types is strongly desired. One way or another, Rep2 must be constrained. Otherwise</font> <font color="#c80000">// the operators are overly generic.</font> template &lt;class Rep1, class Period1, class Rep2, class Period2&gt; typename common_type&lt;Rep1, Rep2&gt;::type operator/(const duration&lt;Rep1, Period1&gt;&amp; lhs, const duration&lt;Rep2, Period2&gt;&amp; rhs); <font color="#c80000">// time_point</font> <font color="#c80000">// A time_point represents an epoch plus or minus a duration. The relationship between a time_point</font> <font color="#c80000">// which represents "now" and the time_point's epoch is obtained via a clock. Each time_point is</font> <font color="#c80000">// tied to a specific clock. Thus, for any time_point, one can find the duration between that</font> <font color="#c80000">// point in time and now, and between that point in time, and its epoch.</font> <font color="#c80000">// </font> <font color="#c80000">// A time_point may be default constructed. This time_point represents the epoch. time_point has</font> <font color="#c80000">// default copy semantics.</font> <font color="#c80000">// </font> <font color="#c80000">// time_point may be explicitly constructed by a duration having the same representation and period as</font> <font color="#c80000">// the time_point. Any other duration which is implicitly convertible to the time_point's "native" duration can</font> <font color="#c80000">// also be used to explicitly construct the time_point. The meaning of this construction is identical to</font> <font color="#c80000">// time_point() + d.</font> <font color="#c80000">//</font> <font color="#c80000">// A time_point is implicitly constructible from another time_point if they share the same clock,</font> <font color="#c80000">// and the duration of this time_point is implicitly constructible from the duration of the other</font> <font color="#c80000">// time_point. A time_point constructed in this fashion will compare equal to the source time_point</font> <font color="#c80000">// after the construction.</font> <font color="#c80000">// </font> <font color="#c80000">// A time_point supports the following member arithmetic:</font> <font color="#c80000">// </font> <font color="#c80000">// time_point&amp; operator+=(duration d);</font> <font color="#c80000">// time_point&amp; operator-=(duration d);</font> <font color="#c80000">// </font> <font color="#c80000">// A time_point supports the following non-member arithmetic.</font> <font color="#c80000">// Let T1 represent time_point&lt;Clock, Duration1&gt;,</font> <font color="#c80000">// T2 represent time_point&lt;Clock, Duration2&gt;,</font> <font color="#c80000">// and D represent duration&lt;Rep3, Period3&gt;. Note that T1 and T2 must have the same Clock.</font> <font color="#c80000">// Attempts to interoperate times having different clocks results in a compile time failure.</font> <font color="#c80000">// </font> <font color="#c80000">// T2 operator+(T1, D); // return type is a time_point</font> <font color="#c80000">// T2 operator+( D, T1); // return type is a time_point</font> <font color="#c80000">// T2 operator-(T1, D); // return type is a time_point</font> <font color="#c80000">// D operator-(T1, T2); // return type is a duration</font> <font color="#c80000">// </font> <font color="#c80000">// A time_point T1 is fully equality and less-than comparable with any other time_point T2 which</font> <font color="#c80000">// has the same clock, and for which their durations are comparable.</font> <font color="#c80000">// </font> <font color="#c80000">// Times based on floating point representations are subject to round off error precisely the</font> <font color="#c80000">// same way their representations are.</font> <font color="#c80000">// </font> <font color="#c80000">// Times based on integral representations are not subject to truncation error or round off</font> <font color="#c80000">// error. A compile time error will result if truncation error is possible. Truncation error</font> <font color="#c80000">// is only possible with construction or the member arithmetic (and won't compile). Non-member</font> <font color="#c80000">// arithmetic and comparison is always exact. Overflow error with integral based times remains a</font> <font color="#c80000">// possibility.</font> <font color="#c80000">// </font> <font color="#c80000">// A time_point is a thin wrapper around its representation.</font> <font color="#c80000">// sizeof(time_point&lt;Clock, Duration&gt;) == sizeof(Duration) == sizeof(Duration::rep).</font> <font color="#c80000">// </font> <font color="#c80000">// A time_point can represent units as small as 10^-18 seconds and as large as 10^18 seconds. The range</font> <font color="#c80000">// of a time_point is based on the range of its representation combined with its period.</font> <font color="#c80000">//</font> <font color="#c80000">// Because no two clocks report the exact same time, even clocks which nominally have the same</font> <font color="#c80000">// epoch, are considered by this framework to have different epochs, if only by a few nanoseconds.</font> <font color="#c80000">// Converting time_points from one clock to another will involve synchronization of the clocks,</font> <font color="#c80000">// which can be viewed as a synchronization of their epochs. Such synchronization is clock specific</font> <font color="#c80000">// and beyond the scope of this API. A future API, or a platform specific API, can easily</font> <font color="#c80000">// write such a synchronization API, basing it on this API.</font> <font color="#c80000">// The cost of not including a time_point class is the lack of the ability to safely interact with</font> <font color="#c80000">// the concept of "epoch + duration". Without a separate type, the client is in danger of accidently</font> <font color="#c80000">// writing code that boils down to "epoch1 + duration1" + "epoch2 + duration2". Algebraically this</font> <font color="#c80000">// results in epoch1+epoch2 as a subexpression which is likely to be completely without meaning. What</font> <font color="#c80000">// would it mean to add New Years 1970 to the point in time at which your computer booted up? Or for</font> <font color="#c80000">// that matter, what is the meaning of "New Years 1970" + "New Years 1970"?</font> <font color="#c80000">//</font> <font color="#c80000">// Additionally this would force the duration type to play double duty as a time_point leading to</font> <font color="#c80000">// client confusion. For example POSIX has timespec represent a duration in nanosleep, and yet the</font> <font color="#c80000">// same type is used as a time_point in pthread_cond_timedwait and pthread_mutex_timedlock. The</font> <font color="#c80000">// confusion seems even more likely with a function such as clock_nanosleep where timespec can mean</font> <font color="#c80000">// either a duration or a time_point depending upon another argument to the function.</font> <font color="#c80000">//</font> <font color="#c80000">// In C++ we can easily mitigate such errors by detecting them at compile time. This is done through</font> <font color="#c80000">// the use of distinct types for these distinct concepts (even though both types have identical layout!).</font> template &lt;class Clock, class Duration = typename Clock::duration&gt; requires Duration is an instantiation of duration class time_point { public: typedef Clock clock; typedef Duration duration; typedef typename duration::rep rep; typedef typename duration::period period; private: duration d_; <font color="#c80000">// exposition only</font> public: time_point(); <font color="#c80000">// has value "epoch"</font> explicit time_point(const duration&amp; d); <font color="#c80000">// same as time_point() + d</font> <font color="#c80000">// conversions</font> template &lt;class Duration2&gt; requires Convertible&lt;Duration2, duration&gt; time_point(const time_point&lt;clock, Duration2&gt;&amp; t); <font color="#c80000">// observer</font> duration time_since_epoch() const; <font color="#c80000">// arithmetic</font> time_point&amp; operator+=(const duration&amp; d); time_point&amp; operator-=(const duration&amp; d); <font color="#c80000">// special values</font> static time_point min(); static time_point max(); }; } <font color="#c80000">// datetime</font> template &lt;class Clock, class Duration1, class Duration2&gt; struct common_type&lt;datetime::time_point&lt;Clock, Duration1&gt;, datetime::time_point&lt;Clock, Duration2&gt; &gt; { typedef datetime::time_point&lt;Clock, typename common_type&lt;Duration1, Duration2&gt;::type&gt; type; }; namespace datetime { template &lt;class ToDuration, class Clock, class Duration&gt; time_point&lt;Clock, ToDuration&gt; time_point_cast(const time_point&lt;Clock, Duration&gt;&amp; t); template &lt;class Clock, class Duration1, class Duration2&gt; bool operator==(const time_point&lt;Clock, Duration1&gt;&amp; lhs, const time_point&lt;Clock, Duration2&gt;&amp; rhs); template &lt;class Clock, class Duration1, class Duration2&gt; bool operator!=(const time_point&lt;Clock, Duration1&gt;&amp; lhs, const time_point&lt;Clock, Duration2&gt;&amp; rhs); template &lt;class Clock, class Duration1, class Duration2&gt; bool operator&lt; (const time_point&lt;Clock, Duration1&gt;&amp; lhs, const time_point&lt;Clock, Duration2&gt;&amp; rhs); template &lt;class Clock, class Duration1, class Duration2&gt; bool operator&lt;=(const time_point&lt;Clock, Duration1&gt;&amp; lhs, const time_point&lt;Clock, Duration2&gt;&amp; rhs); template &lt;class Clock, class Duration1, class Duration2&gt; bool operator&gt; (const time_point&lt;Clock, Duration1&gt;&amp; lhs, const time_point&lt;Clock, Duration2&gt;&amp; rhs); template &lt;class Clock, class Duration1, class Duration2&gt; bool operator&gt;=(const time_point&lt;Clock, Duration1&gt;&amp; lhs, const time_point&lt;Clock, Duration2&gt;&amp; rhs); template &lt;class Clock, class Duration1, class Rep2, class Period2&gt; time_point&lt;Clock, typename common_type&lt;Duration1, duration&lt;Rep2, Period2&gt; &gt;::type&gt; operator+(const time_point&lt;Clock, Duration1&gt;&amp; lhs, const duration&lt;Rep2, Period2&gt;&amp; rhs); template &lt;class Rep1, class Period1, class Clock, class Duration2&gt; time_point&lt;Clock, typename common_type&lt;duration&lt;Rep1, Period1&gt;, Duration2&gt;::type&gt; operator+(const duration&lt;Rep1, Period1&gt;&amp; lhs, const time_point&lt;Clock, Duration2&gt;&amp; rhs); template &lt;class Clock, class Duration1, class Rep2, class Period2&gt; time_point&lt;Clock, typename common_type&lt;Duration1, duration&lt;Rep2, Period2&gt; &gt;::type&gt; operator-(const time_point&lt;Clock, Duration1&gt;&amp; lhs, const duration&lt;Rep2, Period2&gt;&amp; rhs); template &lt;class Clock, class Duration1, class Duration2&gt; typename common_type&lt;Duration1, Duration2&gt;::type operator-(const time_point&lt;Clock, Duration1&gt;&amp; lhs, const time_point&lt;Clock, Duration2&gt;&amp; rhs); <font color="#c80000">// clocks</font> <font color="#c80000">// A clock specifies a representation, and a period. These specifications are used to</font> <font color="#c80000">// to define a clock's native duration and time_point types. A clock also has a function to get the current</font> <font color="#c80000">// time_point. A clock need not have any state.</font> <font color="#c80000">// Th