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