• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
2<html><head>
3<meta http-equiv="content-type" content="text/html; charset=ISO-8859-1">
4
5
6	<title>time2_demo</title>
7</head><body>
8
9<pre><font color="#c80000">/*
10Copyright (c) 2008 Howard Hinnant
11
12Distributed under the Boost Software License, Version 1.0. (See accompanying
13file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
14
15
16A prototype of a proposal for a time/duration/clock library for the C++ standard.
17It is intended that this be a solid foundation upon which higher level libraries
18can be based.  Examples of such libraries include a date/time library and a
19physical quantities library.
20
21Two general purpose facilities are proposed:
22
23    common_type
24    ratio
25
26And 5 time/duration/clock facilities are proposed
27
28    duration
29    time_point
30    system_clock
31    monotonic_clock        <font color="#c80000">// optional</font>
32    high_resolution_clock  <font color="#c80000">// optional</font>
33
34Much thanks to Andrei Alexandrescu,
35               Walter Brown,
36               Peter Dimov,
37               Jeff Garland,
38               Terry Golubiewski,
39               Daniel Krügler,
40               Anthony Williams.
41
42Synopsis
43
44namespace std
45{
46
47<font color="#c80000">// &lt;type_traits&gt;</font>
48
49<font color="#c80000">// common_type</font>
50
51<font color="#c80000">// common_type is ageneral purpose trait that can be specialized for user-defined types.</font>
52<font color="#c80000">// The semantics are intended to be identical to finding the resulting type of a</font>
53<font color="#c80000">// the conditional operator.</font>
54<font color="#c80000">// The client may need to specialize common_type if he wishes to convert to or from</font>
55<font color="#c80000">// another type only explicitly.  It is used to determine the result type</font>
56<font color="#c80000">// in "mixed-mode" duration and time_point arithmetic.  It will also find use in</font>
57<font color="#c80000">// similar "mixed-mode" arithmetic applications.</font>
58
59template &lt;class T, class U&gt;
60struct common_type
61{
62private:
63    static T t();
64    static U u();
65public:
66    typedef decltype(true ? t() : u()) type;
67};
68
69<font color="#c80000">// or...</font>
70
71template &lt;class ...T&gt; struct common_type;
72
73template &lt;class T&gt;
74struct common_type&lt;T&gt;
75{
76    typedef T type;
77};
78
79template &lt;class T, class U&gt;
80struct common_type&lt;T, U&gt;
81{
82private:
83    static T t();
84    static U u();
85public:
86    typedef decltype(true ? t() : u()) type;
87};
88
89template &lt;class T, class U, class ...V&gt;
90struct common_type&lt;T, U, V...&gt;
91{
92    typedef typename common_type&lt;typename common_type&lt;T, U&gt;::type, V...&gt;::type type;
93};
94
95<font color="#c80000">// This alternative variadic formulation of common_type has some advantages:</font>
96<font color="#c80000">//</font>
97<font color="#c80000">//   1.  The obvious advantage is that it can handle 3 or more arguments seamlessly.</font>
98<font color="#c80000">//       This can come in handy when writing template functions that take more than</font>
99<font color="#c80000">//       two arguments, such as fma(x, y, z).</font>
100<font color="#c80000">//</font>
101<font color="#c80000">//   2.  We could just get rid of identity (avoiding the legacy conflict) and use</font>
102<font color="#c80000">//       common_type&lt;T&gt;::type in the one place we use identity&lt;T&gt;::type today.</font>
103<font color="#c80000">//</font>
104<font color="#c80000">//   3.  For clients that need to specialize common_type (such as duration and time_point),</font>
105<font color="#c80000">//       the client still needs to specialize only the two-argument version.  The default</font>
106<font color="#c80000">//       definition of the higher-order common_type will automatically use the client's</font>
107<font color="#c80000">//       specialized two-argument version.</font>
108<font color="#c80000">//       For example:</font>
109<font color="#c80000">//           common_type&lt;duration&lt;double&gt;, hours, microseconds&gt;::type is duration&lt;double, micro&gt;</font>
110
111<font color="#c80000">// ... end or</font>
112
113<font color="#c80000">//  The cost of not including either version of common_type is that it is very likely that</font>
114<font color="#c80000">//  the implementation would include it anyway, but spell it __common_type instead.  This</font>
115<font color="#c80000">//  would prevent authors of arithmetic emulators from using their classes as representations</font>
116<font color="#c80000">//  with durations unless the emulator had exactly one implicit conversion to or from an</font>
117<font color="#c80000">//  arithmetic type.  This would be a large loss of functionality from the client's point</font>
118<font color="#c80000">//  of view, possibly mandating a less safe interface for the client's arithmetic emulator.</font>
119
120<font color="#c80000">// ratio</font>
121
122<font color="#c80000">// ratio is a general purpose type allowing one to easily and safely compute integral</font>
123<font color="#c80000">// ratio values at compile time.  The ratio class catches all errors (such as divide by</font>
124<font color="#c80000">// zero and overflow) at compile time.  It is used in the duration and time_point libraries</font>
125<font color="#c80000">// to efficiently create units of time.  It can also be used in other "quantity"</font>
126<font color="#c80000">// libraries (both std-defined and user-defined), or anywhere there is an integral</font>
127<font color="#c80000">// ratio which is known at compile time.  The use of this utility can greatly reduce</font>
128<font color="#c80000">// the chances of run time overflow because the ratio (and any ratios resulting from</font>
129<font color="#c80000">// ratio arithmetic) are always reduced to lowest terms.</font>
130
131<font color="#c80000">// The cost of not including ratio would mean that the implementor would likely have this</font>
132<font color="#c80000">// functionality anyway, but spell it __ratio instead.  This would prevent the client from</font>
133<font color="#c80000">// using ratio in his own code as demonstrated in the "User1" example.  Furthermore duration</font>
134<font color="#c80000">// would have to be templated on two long long's instead of on ratio like so:</font>
135<font color="#c80000">//</font>
136<font color="#c80000">//       template &lt;class Rep, long long N, long long D&gt; duration.</font>
137<font color="#c80000">//</font>
138<font color="#c80000">// This would mean that clients wanting to build a custom duration type (say a nanosecond</font>
139<font color="#c80000">// represented by a double) would have to write:</font>
140<font color="#c80000">//</font>
141<font color="#c80000">//       duration&lt;double, 1, 1000000000LL&gt;</font>
142<font color="#c80000">//</font>
143<font color="#c80000">// instead of:</font>
144<font color="#c80000">//</font>
145<font color="#c80000">//       duration&lt;double, nano&gt;</font>
146<font color="#c80000">//</font>
147<font color="#c80000">// This lack of syntatic niceness, along with the loss of functionality in the reuse of</font>
148<font color="#c80000">// ratio in user-written code seems to indicate that the loss of ratio would be a sizeable</font>
149<font color="#c80000">// loss to client code.</font>
150
151template &lt;intmax_t N, intmax_t D = 1&gt;
152class ratio
153{
154    <font color="#c80000">// For every possible value of N and D, abs(N) &gt;= 0 and abs(D) &gt; 0</font>
155    static_assert(__static_abs&lt;N&gt;::value &gt;= 0, "ratio numerator is out of range");
156    static_assert(__static_abs&lt;D&gt;::value &gt;  0, "ratio denominator is out of range");
157public:
158    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>
159    static const intmax_t den;   <font color="#c80000">// Reduced by greatest common divisor of N and D, always positive</font>
160                                 <font color="#c80000">// When num == 0, den == 1</font>
161};
162
163<font color="#c80000">// The static_asserts in ratio are there to catch any values which have a negative absolute value.</font>
164<font color="#c80000">// In a typical 2's complement representation this is only LLONG_MIN.  The reason for prohibiting</font>
165<font color="#c80000">// this value is because ratio must take the absolute values of its arguments and generally depends</font>
166<font color="#c80000">// on that number being non-negative in order to maintain invariants such as den &gt; 0.</font>
167
168<font color="#c80000">// convenience typedefs</font>
169
170typedef ratio&lt;1, 1000000000000000000000000&gt; yocto;  <font color="#c80000">// conditionally supported</font>
171typedef ratio&lt;1,    1000000000000000000000&gt; zepto;  <font color="#c80000">// conditionally supported</font>
172typedef ratio&lt;1,       1000000000000000000&gt; atto;
173typedef ratio&lt;1,          1000000000000000&gt; femto;
174typedef ratio&lt;1,             1000000000000&gt; pico;
175typedef ratio&lt;1,                1000000000&gt; nano;
176typedef ratio&lt;1,                   1000000&gt; micro;
177typedef ratio&lt;1,                      1000&gt; milli;
178typedef ratio&lt;1,                       100&gt; centi;
179typedef ratio&lt;1,                        10&gt; deci;
180typedef ratio&lt;                       10, 1&gt; deca;
181typedef ratio&lt;                      100, 1&gt; hecto;
182typedef ratio&lt;                     1000, 1&gt; kilo;
183typedef ratio&lt;                  1000000, 1&gt; mega;
184typedef ratio&lt;               1000000000, 1&gt; giga;
185typedef ratio&lt;            1000000000000, 1&gt; tera;
186typedef ratio&lt;         1000000000000000, 1&gt; peta;
187typedef ratio&lt;      1000000000000000000, 1&gt; exa;
188typedef ratio&lt;   1000000000000000000000, 1&gt; zetta;  <font color="#c80000">// conditionally supported</font>
189typedef ratio&lt;1000000000000000000000000, 1&gt; yotta;  <font color="#c80000">// conditionally supported</font>
190
191<font color="#c80000">// Compile time arithmetic and comparisons should either avoid overflow or not compile</font>
192
193template &lt;class R1, class R2&gt;
194requires R1 and R2 are instantiations of ratio
195struct ratio_add
196{
197    typedef ratio&lt;pseudo code: R1 + R2&gt; type;
198};
199
200template &lt;class R1, class R2&gt;
201requires R1 and R2 are instantiations of ratio
202struct ratio_subtract
203{
204    typedef ratio&lt;pseudo code: R1 - R2&gt; type;
205};
206
207template &lt;class R1, class R2&gt;
208requires R1 and R2 are instantiations of ratio
209struct ratio_multiply
210{
211    typedef ratio&lt;pseudo code: R1 * R2&gt; type;
212};
213
214template &lt;class R1, class R2&gt;
215requires R1 and R2 are instantiations of ratio
216struct ratio_divide
217{
218    typedef ratio&lt;pseudo code: R1 / R2&gt; type;
219};
220
221template &lt;class R1, class R2&gt;
222requires R1 and R2 are instantiations of ratio
223struct ratio_equal
224    : public integral_constant&lt;bool, pseudo code: R1 == R2&gt; {};
225
226template &lt;class R1, class R2&gt;
227requires R1 and R2 are instantiations of ratio
228struct ratio_not_equal
229    : public integral_constant&lt;bool, !ratio_equal&lt;R1, R2&gt;::value&gt; {};
230
231template &lt;class R1, class R2&gt;
232requires R1 and R2 are instantiations of ratio
233struct ratio_less
234    : public integral_constant&lt;bool, pseudo code: R1 &lt; R2&gt; {};
235
236template &lt;class R1, class R2&gt;
237requires R1 and R2 are instantiations of ratio
238struct ratio_less_equal
239    : public integral_constant&lt;bool, !ratio_less&lt;R2, R1&gt;::value&gt; {};
240
241template &lt;class R1, class R2&gt;
242requires R1 and R2 are instantiations of ratio
243struct ratio_greater
244    : public integral_constant&lt;bool, ratio_less&lt;R2, R1&gt;::value&gt; {};
245
246template &lt;class R1, class R2&gt;
247requires R1 and R2 are instantiations of ratio
248struct ratio_greater_equal
249    : public integral_constant&lt;bool, !ratio_less&lt;R1, R2&gt;::value&gt; {};
250
251namespace datetime
252{
253
254<font color="#c80000">// duration customization traits</font>
255
256<font color="#c80000">//   Authors of arithmetic emulation types should specialize treat_as_floating_point</font>
257<font color="#c80000">//   if their class emulates floating point and they want to use it as a duration's</font>
258<font color="#c80000">//   representation.</font>
259
260template &lt;class Rep&gt; struct treat_as_floating_point
261  : is_floating_point&lt;Rep&gt; {};
262
263<font color="#c80000">//   Authors of arithmetic emulation types should specialize duration_values</font>
264<font color="#c80000">//   if they want to use it as a duration's  representation, and the default</font>
265<font color="#c80000">//   definition of duration_values does not have the correct behavior.</font>
266
267template &lt;class Rep&gt;
268struct duration_values
269{
270public:
271    static constexpr Rep zero() {return Rep(0);}
272    static constexpr Rep max()  {return numeric_limits&lt;Rep&gt;::max();}
273    static constexpr Rep min()  {return -max();}
274};
275
276<font color="#c80000">// Note:  Rep(0) instead of Rep() is used for zero() because the author of Rep may</font>
277<font color="#c80000">//   chose to have Rep() refer to an inderminant or unitialized value.</font>
278
279<font color="#c80000">// duration</font>
280
281<font color="#c80000">// A duration has a representation and a period.</font>
282<font color="#c80000">// </font>
283<font color="#c80000">//    The representation is an arithmetic type, or a class emulating an arithmetic type.</font>
284<font color="#c80000">//</font>
285<font color="#c80000">//    The period is the rational number of seconds between "ticks" of the duration.  The</font>
286<font color="#c80000">//       duration simply holds a count of the elapsed number of ticks (using the</font>
287<font color="#c80000">//       representation), and that is related to seconds by multiplying by the period.</font>
288<font color="#c80000">//       Note, this multiplication is only required when one needs to convert between</font>
289<font color="#c80000">//       durations with different tick periods (e.g. milliseconds to microseconds).</font>
290<font color="#c80000">// </font>
291<font color="#c80000">//    A duration has defalt construction and default copy semantics.  One can also explicitly</font>
292<font color="#c80000">//       construct a duration from its representation or something implicitly convertible to</font>
293<font color="#c80000">//       its representation.  If the representation is integral (or emulated integral) the</font>
294<font color="#c80000">//       duration may not be constructed from a floating point (or emulated floating point)</font>
295<font color="#c80000">//       type, even if that type is impilcitly convertible to the representation (the client</font>
296<font color="#c80000">//       must explicitly convert such an argument as they pass it to the constructor if such</font>
297<font color="#c80000">//       a conversion is desired).</font>
298<font color="#c80000">// </font>
299<font color="#c80000">//    A duration may be implicitly constructible from another duration if the representations</font>
300<font color="#c80000">//       of the two durations meet certain requirements.  Let the representation of this duration</font>
301<font color="#c80000">//       be Rep1 and the representation of the other duration be Rep2.  Example representations</font>
302<font color="#c80000">//       include int, long long, double, or a user-defined class which emulates one of these</font>
303<font color="#c80000">//       arithmetic types.  To qualify for implicit constructability Rep1 must be explicitly</font>
304<font color="#c80000">//       constructible from Rep2.  Note that implicit constructibility of Rep1 from Rep2 is not</font>
305<font color="#c80000">//       required for this implicit construction between durations.  Additionally the trait</font>
306<font color="#c80000">//       common_type&lt;Rep1, Rep2&gt;::type must be well defined.  If a conditional expression involving</font>
307<font color="#c80000">//       these two types isn't valid, there must exist a common_type specialization which makes</font>
308<font color="#c80000">//       the trait valid.</font>
309<font color="#c80000">//       </font>
310<font color="#c80000">//       The requirements put on the relationship between Rep1 and Rep2 are intended to be minimal,</font>
311<font color="#c80000">//       and not require implicit conversions (which could be considered error prone by the author</font>
312<font color="#c80000">//       of either of these representations).</font>
313<font color="#c80000">//       </font>
314<font color="#c80000">//       In addition to the above relationship between the representations, implicit constructability</font>
315<font color="#c80000">//       also depends on whether the representation is considered floating point (or emulated floating</font>
316<font color="#c80000">//       point) or integral (or emulated integral).</font>
317<font color="#c80000">// </font>
318<font color="#c80000">//       If a duration has a floating point (or emulated floating point) representation it</font>
319<font color="#c80000">//       is implicitly constructible from all other durations of any period (as long as</font>
320<font color="#c80000">//       the representations are compatible as described above).</font>
321<font color="#c80000">//       </font>
322<font color="#c80000">//       If a duration has an integral (or emulated integral) representation it is implicitly</font>
323<font color="#c80000">//       constructible from other integral-based durations which have a period which will exactly convert</font>
324<font color="#c80000">//       to the period of this duration with no truncation error.  More specifically, if the</font>
325<font color="#c80000">//       period of this duration is P1, and the period of the other duration is P2, this</font>
326<font color="#c80000">//       duration is implicitly constructible from the other duration if P2/P1 is a whole number</font>
327<font color="#c80000">//       (as long as the representations are compatible as described above).  Example:</font>
328<font color="#c80000">//       microseconds has a period p1 = 1/1000000 seconds.  milliseconds has a period</font>
329<font color="#c80000">//       P2 = 1/1000 seconds.  P2/P1 is (1/1000)/(1/1000000) = 1000000/1000 = 1000.</font>
330<font color="#c80000">//       Therefore microseconds will implicitly construct from milliseconds (but not vice-versa).</font>
331<font color="#c80000">//</font>
332<font color="#c80000">//       These rules involving integral representations are meant to prevent accidental truncatation</font>
333<font color="#c80000">//       error.  If truncation error is desired, a duration_cast facility is available to force it.</font>
334<font color="#c80000">//       Example:</font>
335<font color="#c80000">//          milliseconds ms(3);                    // ok, ms.count() == 3,    which is 0.003    seconds</font>
336<font color="#c80000">//          microseconds us = ms;                  // ok, us.count() == 3000  which is 0.003000 seconds</font>
337<font color="#c80000">//          ++us;                                  // ok, us.count() == 3001  which is 0.003001 seconds</font>
338<font color="#c80000">//          ms = us;                               // won't compile, might truncate</font>
339<font color="#c80000">//          ms = duration_cast&lt;milliseconds&gt;(us);  // ok, ms.count() = 3, truncated a microsecond</font>
340<font color="#c80000">// </font>
341<font color="#c80000">//    A duration has a single observer:  rep count() const; which returns the stored</font>
342<font color="#c80000">//       representation which holds the number of elapsed "ticks".</font>
343<font color="#c80000">// </font>
344<font color="#c80000">//    A duration supports the following member arithmetic:</font>
345<font color="#c80000">// </font>
346<font color="#c80000">//       duration  operator+() const;</font>
347<font color="#c80000">//       duration  operator-() const;</font>
348<font color="#c80000">//       duration&amp; operator++();</font>
349<font color="#c80000">//       duration  operator++(int);</font>
350<font color="#c80000">//       duration&amp; operator--();</font>
351<font color="#c80000">//       duration  operator--(int);</font>
352<font color="#c80000">//       </font>
353<font color="#c80000">//       duration&amp; operator+=(duration d);</font>
354<font color="#c80000">//       duration&amp; operator-=(duration d);</font>
355<font color="#c80000">//       </font>
356<font color="#c80000">//       duration&amp; operator*=(rep rhs);</font>
357<font color="#c80000">//       duration&amp; operator/=(rep rhs);</font>
358<font color="#c80000">//</font>
359<font color="#c80000">//       The arithmetic simply manipulates the "tick" count in the obvious way (e.g. operator++</font>
360<font color="#c80000">//       increments the tick count by 1).</font>
361<font color="#c80000">// </font>
362<font color="#c80000">//    A duration supports the following non-member arithmetic.</font>
363<font color="#c80000">//       Let D1 represent duration&lt;Rep1, Period1&gt; and D2 represent duration&lt;Rep2, Period2&gt;.</font>
364<font color="#c80000">// </font>
365<font color="#c80000">//       common_type&lt;D1, D2&gt;::type                             operator+(  D1,   D2); // returns a duration</font>
366<font color="#c80000">//       common_type&lt;D1, D2&gt;::type                             operator-(  D1,   D2); // returns a duration</font>
367<font color="#c80000">//       duration&lt;common_type&lt;D1::rep,Rep2&gt;::type, D1::period&gt; operator*(  D1, Rep2); // returns a duration</font>
368<font color="#c80000">//       duration&lt;common_type&lt;D1::rep,Rep2&gt;::type, D1::period&gt; operator*(Rep2,   D1); // returns a duration</font>
369<font color="#c80000">//       duration&lt;common_type&lt;D1::rep,Rep2&gt;::type, D1::period&gt; operator/(  D1, Rep2); // returns a duration</font>
370<font color="#c80000">//       common_type&lt;D1::rep, D2::rep&gt;::type                   operator/(  D1,   D2); // returns a scalar</font>
371<font color="#c80000">// </font>
372<font color="#c80000">//    A duration D1 is fully equality and less-than comparable with any other duration D2, as</font>
373<font color="#c80000">//       long as common_type&lt;D1::rep, D2::rep&gt; is well defined.</font>
374<font color="#c80000">//       Example:</font>
375<font color="#c80000">//          milliseconds ms(3);    // ms.count() == 3,    which is 0.003    seconds</font>
376<font color="#c80000">//          microseconds us = ms;  // us.count() == 3000  which is 0.003000 seconds</font>
377<font color="#c80000">//          --us;                  // us.count() == 2999  which is 0.002999 seconds</font>
378<font color="#c80000">//          assert(ms != us);      // 3 milliseconds is not equal to 2999 microseconds</font>
379<font color="#c80000">//          assert(ms &gt;  us);      // 3 milliseconds is greater than 2999 microseconds</font>
380<font color="#c80000">//          ++us;                  // us.count() == 3000  which is 0.003000 seconds</font>
381<font color="#c80000">//          assert(ms == us);      // 3 milliseconds is equal to 3000 microseconds</font>
382<font color="#c80000">//</font>
383<font color="#c80000">//    Durations based on floating point representations are subject to round off error precisely the</font>
384<font color="#c80000">//       same way their representations are.</font>
385<font color="#c80000">// </font>
386<font color="#c80000">//    Arithmetic and comparisons among integral-based durations is not subject to truncation error or</font>
387<font color="#c80000">//       round off error.  If truncation error would result from the arithmetic (say</font>
388<font color="#c80000">//       by converting a smaller period duration to a larger one) the expression will</font>
389<font color="#c80000">//       not compile (unless duration_cast is used).  If one performs arithmetic</font>
390<font color="#c80000">//       involving the duration's representation (such as division), then truncation</font>
391<font color="#c80000">//       will happen implicitly.</font>
392<font color="#c80000">//    </font>
393<font color="#c80000">//    Overflow error may silently happen with a duration.  The std-defined durations</font>
394<font color="#c80000">//       have a minimum range of +/- 292 years.</font>
395<font color="#c80000">// </font>
396<font color="#c80000">//    A duration is a thin wrapper around its representation.  sizeof(duration&lt;Rep, Period&gt;) == sizeof(Rep).</font>
397<font color="#c80000">// </font>
398<font color="#c80000">//    A duration can represent units as small as 10^-18 seconds (attoseconds) and as large as 10^18 seconds</font>
399<font color="#c80000">//       (about 30 billion years).  The range of a duration is based on the range of its representation</font>
400<font color="#c80000">//       combined with its period.</font>
401
402<font color="#c80000">// The cost of not including the flexibility to represent different "tick periods" in the duration</font>
403<font color="#c80000">// type would be a great loss of both flexibility, convenience and safety for the client.  For example</font>
404<font color="#c80000">// if had just one duration type which counted nanoseconds (no matter how that count was represented),</font>
405<font color="#c80000">// then clients could never have the ability to traffic in picoseconds.  And the only hope of reaching</font>
406<font color="#c80000">// beyond a +/- 292 year range with nanoseconds is to increase the number of bits in the representation</font>
407<font color="#c80000">// (such as a long long).  Furthermore, if the client wanted to traffic in units larger than a nanosecond</font>
408<font color="#c80000">// (e.g. seconds) for convience, they would likely need to set up their own conversion constants and</font>
409<font color="#c80000">// convert manually.</font>
410<font color="#c80000">//</font>
411<font color="#c80000">// If the conversion constants are specified at run time, rather than as compile time integral constants,</font>
412<font color="#c80000">// then the client suffers a significant performance penalty as for every conversion one will have to</font>
413<font color="#c80000">// perform both a multiplication and a division.  In contrast, when converting among any two units of</font>
414<font color="#c80000">// the set (hours, minutes, seconds, milliseconds, microseconds, nanoseconds), there need be only a</font>
415<font color="#c80000">// single multiplication *or* division (never both).  This proposal makes every unit conversion as</font>
416<font color="#c80000">// efficient as if it had been coded by hand (see duration_cast).  Furthermore duration_cast encapsulates</font>
417<font color="#c80000">// all unit conversions within a single uniform-syntax function which is easily used in generic code.  There</font>
418<font color="#c80000">// is no need (or motivation) to set up a "hub-and-spoke" conversion regimen, so that the number of conversion</font>
419<font color="#c80000">// functions is O(N) rather than O(N^2).</font>
420
421template &lt;class Rep, class Period = ratio&lt;1&gt;&gt;
422requires Rep is an arithmetic type, or a class emulating an arithmetic type,
423         and not an instantiation of duration
424requires Period is an instantiation of ratio and represents a positive fraction
425class duration
426{
427public:
428    typedef Rep    rep;
429    typedef Period period;
430private:
431    rep rep_;  <font color="#c80000">// exposition only</font>
432public:
433    <font color="#c80000">// construction / destruction</font>
434    duration() = default;
435    template &lt;class Rep2&gt;
436        requires is_convertible&lt;Rep2, rep&gt;::value &amp;&amp;
437                 (treat_as_floating_point&lt;rep&gt;::value ||
438                 !treat_as_floating_point&lt;rep&gt;::value &amp;&amp; !treat_as_floating_point&lt;Rep2&gt;::value)
439        explicit duration(const Rep2&amp; r);
440    ~duration() = default;
441
442    <font color="#c80000">// copy semantics</font>
443    duration(const duration&amp;) = default;
444    duration&amp; operator=(const duration&amp;) = default;
445
446    <font color="#c80000">// conversions</font>
447    template &lt;class Rep2, class Period2&gt;
448       requires Rep2 is explicitly convertible to rep &amp;&amp;
449                (treat_as_floating_point&lt;rep&gt;::value ||
450                !treat_as_floating_point&lt;Rep2&gt;::value &amp;&amp; ratio_divide&lt;Period2, period&gt;::type::den == 1)
451       duration(const duration&lt;Rep2, Period2&gt;&amp; d);
452
453    <font color="#c80000">// observer</font>
454
455    rep count() const;
456
457    <font color="#c80000">// arithmetic</font>
458
459    duration  operator+() const;
460    duration  operator-() const;
461    duration&amp; operator++();
462    duration  operator++(int);
463    duration&amp; operator--();
464    duration  operator--(int);
465
466    duration&amp; operator+=(const duration&amp; d);
467    duration&amp; operator-=(const duration&amp; d);
468
469    duration&amp; operator*=(const rep&amp; rhs);
470    duration&amp; operator/=(const rep&amp; rhs);
471
472    <font color="#c80000">// special values</font>
473
474    static constexpr duration zero();
475    static constexpr duration min();
476    static constexpr duration max();
477};
478
479<font color="#c80000">// convenience typedefs</font>
480
481typedef duration&lt;int_least64_t,        nano&gt; nanoseconds;    <font color="#c80000">// 10^-9 seconds</font>
482typedef duration&lt;int_least55_t,       micro&gt; microseconds;   <font color="#c80000">// 10^-6 seconds</font>
483typedef duration&lt;int_least45_t,       milli&gt; milliseconds;   <font color="#c80000">// 10^-3 seconds</font>
484typedef duration&lt;int_least35_t             &gt; seconds;        <font color="#c80000">//     1 second</font>
485typedef duration&lt;int_least29_t, ratio&lt;  60&gt;&gt; minutes;        <font color="#c80000">//    60 seconds</font>
486typedef duration&lt;int_least23_t, ratio&lt;3600&gt;&gt; hours;          <font color="#c80000">//  3600 seconds</font>
487
488<font color="#c80000">//   duration_cast can be used to force a conversion between two durations (assuming</font>
489<font color="#c80000">//     the source representation can be explicitly converted to the target representation).</font>
490<font color="#c80000">//     Not all integral-based durations are implicitly convertible to another (to</font>
491<font color="#c80000">//     avoid accidental truncation error).  When truncation error is desired, the client</font>
492<font color="#c80000">//     uses duration_cast to explicitly request the non-exact conversion.  When</font>
493<font color="#c80000">//     duration_cast is used to convert between durations which have an implicit conversion,</font>
494<font color="#c80000">//     the behavior and performance of the conversion using duration_cast is identical to</font>
495<font color="#c80000">//     that of the implicit conversion.</font>
496
497template &lt;class ToDuration, class Rep, class Period&gt;
498  requires ToDuration is an instantiation of duration
499  ToDuration duration_cast(const duration&lt;Rep, Period&gt;&amp; fd);
500
501<font color="#c80000">//    Examples:</font>
502<font color="#c80000">//      microseconds us(3500);                              // 3500 microseconds</font>
503<font color="#c80000">//      milliseconds ms = us;                               // Does not compile (implicit truncation)</font>
504<font color="#c80000">//      milliseconds ms = duration_cast&lt;milliseconds&gt;(us);  // 3 milliseconds   (explicit truncation)</font>
505<font color="#c80000">//      us = ms;                                            // 3000 microseconds</font>
506<font color="#c80000">//      us = duration_cast&lt;microseconds&gt;(ms);               // 3000 microseconds</font>
507
508}  <font color="#c80000">// datetime</font>
509
510<font color="#c80000">//   Given two durations:  duration&lt;Rep1, Period1&gt; and duration&lt;Rep2, Period2&gt;, the common_type</font>
511<font color="#c80000">//     of those two durations is a duration with a representation of common_type&lt;Rep1, Rep2&gt;,</font>
512<font color="#c80000">//     and a period which is the "greatest common period" of Period1 and Period2.  The GCP</font>
513<font color="#c80000">//     (Greatest Common Period) of Period1 and Period2 is the largest period which will divide</font>
514<font color="#c80000">//     both Period1 and Period2 evenly (and is often equivalent to the minimum of Period1 and</font>
515<font color="#c80000">//     Period2).  This can be computed (by the implementation at compile time) by</font>
516<font color="#c80000">//     GCD(Period1::num, Period2::num) / LCM(Period1::den, Period2::den) where GCD is</font>
517<font color="#c80000">//     "Greatest Common Divisor" and LCM is "Least Common Multiple".</font>
518
519template &lt;class Rep1, class Period1, class Rep2, class Period2&gt;
520struct common_type&lt;datetime::duration&lt;Rep1, Period1&gt;, datetime::duration&lt;Rep2, Period2&gt; &gt;
521{
522    typedef datetime::duration&lt;typename common_type&lt;Rep1, Rep2&gt;::type,
523                       ratio&lt;GCD(Period1::num, Period2::num), LCM(Period1::den, Period2::den)&gt;&gt; type;
524};
525
526<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>
527<font color="#c80000">//   common_type&lt;D1, D2&gt;::type will have the largest possible period to make this possible, and</font>
528<font color="#c80000">//   may be the same type as D1 or D2.  Examples:</font>
529<font color="#c80000">//        common_type&lt;minutes,      microseconds&gt;::type is microseconds.</font>
530<font color="#c80000">//        common_type&lt;milliseconds, microseconds&gt;::type is microseconds.</font>
531<font color="#c80000">//        common_type&lt;nanoseconds,  microseconds&gt;::type is nanoseconds.</font>
532<font color="#c80000">//</font>
533<font color="#c80000">//    A more complex example:</font>
534<font color="#c80000">//        common_type&lt; duration&lt;long, milli&gt;, duration&lt;int, ratio&lt;1,30&gt;&gt; &gt;::type is</font>
535<font color="#c80000">//        duration&lt;long, ratio&lt;1,3000&gt;&gt;.  And both duration&lt;long, milli&gt; and </font>
536<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>
537<font color="#c80000">//        The former multitplies its representation by 3L and the latter converts its</font>
538<font color="#c80000">//        representation to long and multiplies that result by 1000L.  There exists no</font>
539<font color="#c80000">//        duration with a larger period such that both duration&lt;long, milli&gt; and</font>
540<font color="#c80000">//        duration&lt;int, ratio&lt;1,30&gt;&gt; will exactly convert to it.</font>
541
542namespace datetime {
543
544template &lt;class Rep1, class Period1, class Rep2, class Period2&gt;
545   bool operator==(const duration&lt;Rep1, Period1&gt;&amp; lhs, const duration&lt;Rep2, Period2&gt;&amp; rhs);
546template &lt;class Rep1, class Period1, class Rep2, class Period2&gt;
547   bool operator!=(const duration&lt;Rep1, Period1&gt;&amp; lhs, const duration&lt;Rep2, Period2&gt;&amp; rhs);
548template &lt;class Rep1, class Period1, class Rep2, class Period2&gt;
549   bool operator&lt; (const duration&lt;Rep1, Period1&gt;&amp; lhs, const duration&lt;Rep2, Period2&gt;&amp; rhs);
550template &lt;class Rep1, class Period1, class Rep2, class Period2&gt;
551   bool operator&lt;=(const duration&lt;Rep1, Period1&gt;&amp; lhs, const duration&lt;Rep2, Period2&gt;&amp; rhs);
552template &lt;class Rep1, class Period1, class Rep2, class Period2&gt;
553   bool operator&gt; (const duration&lt;Rep1, Period1&gt;&amp; lhs, const duration&lt;Rep2, Period2&gt;&amp; rhs);
554template &lt;class Rep1, class Period1, class Rep2, class Period2&gt;
555   bool operator&gt;=(const duration&lt;Rep1, Period1&gt;&amp; lhs, const duration&lt;Rep2, Period2&gt;&amp; rhs);
556
557template &lt;class Rep1, class Period1, class Rep2, class Period2&gt;
558  typename common_type&lt;duration&lt;Rep1, Period1&gt;, duration&lt;Rep2, Period2&gt; &gt;::type
559  operator+(const duration&lt;Rep1, Period1&gt;&amp; lhs, const duration&lt;Rep2, Period2&gt;&amp; rhs);
560
561template &lt;class Rep1, class Period1, class Rep2, class Period2&gt;
562  typename common_type&lt;duration&lt;Rep1, Period1&gt;, duration&lt;Rep2, Period2&gt; &gt;::type
563  operator-(const duration&lt;Rep1, Period1&gt;&amp; lhs, const duration&lt;Rep2, Period2&gt;&amp; rhs);
564
565template &lt;class Rep1, class Period, class Rep2&gt;
566  requires Constructible&lt;Rep1, typename common_type&lt;Rep1, Rep2&gt;::type&gt;::value&gt; &amp;&amp;
567           Constructible&lt;Rep2, typename common_type&lt;Rep1, Rep2&gt;::type&gt;::value&gt;
568  duration&lt;typename common_type&lt;Rep1, Rep2&gt;::type, Period&gt;
569  operator*(const duration&lt;Rep, Period&gt;&amp; d, const Rep2&amp; s);
570
571template &lt;class Rep1, class Period, class Rep2&gt;
572  requires Constructible&lt;Rep1, typename common_type&lt;Rep1, Rep2&gt;::type&gt;::value&gt; &amp;&amp;
573           Constructible&lt;Rep2, typename common_type&lt;Rep1, Rep2&gt;::type&gt;::value&gt;
574  duration&lt;typename common_type&lt;Rep1, Rep2&gt;::type, Period&gt;
575  operator*(const Rep2&amp; s, const duration&lt;Rep, Period&gt;&amp; d);
576
577template &lt;class Rep1, class Period, class Rep2&gt;
578  requires Rep2 is not a duration &amp;&amp;
579           Constructible&lt;Rep1, typename common_type&lt;Rep1, Rep2&gt;::type&gt;::value&gt; &amp;&amp;
580           Constructible&lt;Rep2, typename common_type&lt;Rep1, Rep2&gt;::type&gt;::value&gt;
581  duration&lt;typename common_type&lt;Rep1, Rep2&gt;::type, Period&gt;
582  operator/(const duration&lt;Rep, Period&gt;&amp; d, const Rep2&amp; s);
583
584<font color="#c80000">// Note: the above 3 signatures can be approximated with is_convertible if concepts do not</font>
585<font color="#c80000">//   make it into the language.  Requiring only *explicit* convertibility between the Rep</font>
586<font color="#c80000">//   types is strongly desired.  One way or another, Rep2 must be constrained.  Otherwise</font>
587<font color="#c80000">//   the operators are overly generic.</font>
588
589template &lt;class Rep1, class Period1, class Rep2, class Period2&gt;
590  typename common_type&lt;Rep1, Rep2&gt;::type
591  operator/(const duration&lt;Rep1, Period1&gt;&amp; lhs, const duration&lt;Rep2, Period2&gt;&amp; rhs);
592
593<font color="#c80000">// time_point</font>
594
595<font color="#c80000">// A time_point represents an epoch plus or minus a duration.  The relationship between a time_point</font>
596<font color="#c80000">//    which represents "now" and the time_point's epoch is obtained via a clock.  Each time_point is</font>
597<font color="#c80000">//    tied to a specific clock.  Thus, for any time_point, one can find the duration between that</font>
598<font color="#c80000">//    point in time and now, and between that point in time, and its epoch.</font>
599<font color="#c80000">// </font>
600<font color="#c80000">//    A time_point may be default constructed.  This time_point represents the epoch.  time_point has</font>
601<font color="#c80000">//       default copy semantics.</font>
602<font color="#c80000">//    </font>
603<font color="#c80000">//       time_point may be explicitly constructed by a duration having the same representation and period as</font>
604<font color="#c80000">//       the time_point.  Any other duration which is implicitly convertible to the time_point's "native" duration can</font>
605<font color="#c80000">//       also be used to explicitly construct the time_point.  The meaning of this construction is identical to</font>
606<font color="#c80000">//       time_point() + d.</font>
607<font color="#c80000">//</font>
608<font color="#c80000">//       A time_point is implicitly constructible from another time_point if they share the same clock,</font>
609<font color="#c80000">//       and the duration of this time_point is implicitly constructible from the duration of the other</font>
610<font color="#c80000">//       time_point.  A time_point constructed in this fashion will compare equal to the source time_point</font>
611<font color="#c80000">//       after the construction.</font>
612<font color="#c80000">//    </font>
613<font color="#c80000">//    A time_point supports the following member arithmetic:</font>
614<font color="#c80000">// </font>
615<font color="#c80000">//       time_point&amp; operator+=(duration d);</font>
616<font color="#c80000">//       time_point&amp; operator-=(duration d);</font>
617<font color="#c80000">// </font>
618<font color="#c80000">//    A time_point supports the following non-member arithmetic.</font>
619<font color="#c80000">//       Let T1 represent time_point&lt;Clock, Duration1&gt;,</font>
620<font color="#c80000">//       T2 represent time_point&lt;Clock, Duration2&gt;,</font>
621<font color="#c80000">//       and D represent duration&lt;Rep3, Period3&gt;.  Note that T1 and T2 must have the same Clock.</font>
622<font color="#c80000">//       Attempts to interoperate times having different clocks results in a compile time failure.</font>
623<font color="#c80000">// </font>
624<font color="#c80000">//       T2 operator+(T1,  D);  // return type is a time_point</font>
625<font color="#c80000">//       T2 operator+( D, T1);  // return type is a time_point</font>
626<font color="#c80000">//       T2 operator-(T1,  D);  // return type is a time_point</font>
627<font color="#c80000">//       D  operator-(T1, T2);  // return type is a duration</font>
628<font color="#c80000">// </font>
629<font color="#c80000">//    A time_point T1 is fully equality and less-than comparable with any other time_point T2 which</font>
630<font color="#c80000">//       has the same clock, and for which their durations are comparable.</font>
631<font color="#c80000">// </font>
632<font color="#c80000">//    Times based on floating point representations are subject to round off error precisely the</font>
633<font color="#c80000">//       same way their representations are.</font>
634<font color="#c80000">// </font>
635<font color="#c80000">//    Times based on integral representations are not subject to truncation error or round off</font>
636<font color="#c80000">//       error.  A compile time error will result if truncation error is possible.  Truncation error</font>
637<font color="#c80000">//       is only possible with construction or the member arithmetic (and won't compile).  Non-member</font>
638<font color="#c80000">//       arithmetic and comparison is always exact.  Overflow error with integral based times remains a</font>
639<font color="#c80000">//       possibility.</font>
640<font color="#c80000">// </font>
641<font color="#c80000">//    A time_point is a thin wrapper around its representation.</font>
642<font color="#c80000">//        sizeof(time_point&lt;Clock, Duration&gt;) == sizeof(Duration) == sizeof(Duration::rep).</font>
643<font color="#c80000">// </font>
644<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>
645<font color="#c80000">//       of a time_point is based on the range of its representation combined with its period.</font>
646<font color="#c80000">//</font>
647<font color="#c80000">//    Because no two clocks report the exact same time, even clocks which nominally have the same</font>
648<font color="#c80000">//       epoch, are considered by this framework to have different epochs, if only by a few nanoseconds.</font>
649<font color="#c80000">//       Converting time_points from one clock to another will involve synchronization of the clocks,</font>
650<font color="#c80000">//       which can be viewed as a synchronization of their epochs.  Such synchronization is clock specific</font>
651<font color="#c80000">//       and beyond the scope of this API.  A future API, or a platform specific API, can easily</font>
652<font color="#c80000">//       write such a synchronization API, basing it on this API.</font>
653
654<font color="#c80000">// The cost of not including a time_point class is the lack of the ability to safely interact with</font>
655<font color="#c80000">// the concept of "epoch + duration".  Without a separate type, the client is in danger of accidently</font>
656<font color="#c80000">// writing code that boils down to "epoch1 + duration1" + "epoch2 + duration2".  Algebraically this</font>
657<font color="#c80000">// results in epoch1+epoch2 as a subexpression which is likely to be completely without meaning.  What</font>
658<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>
659<font color="#c80000">// that matter, what is the meaning of "New Years 1970" + "New Years 1970"?</font>
660<font color="#c80000">//</font>
661<font color="#c80000">// Additionally this would force the duration type to play double duty as a time_point leading to</font>
662<font color="#c80000">// client confusion.  For example POSIX has timespec represent a duration in nanosleep, and yet the</font>
663<font color="#c80000">// same type is used as a time_point in pthread_cond_timedwait and pthread_mutex_timedlock.  The</font>
664<font color="#c80000">// confusion seems even more likely with a function such as clock_nanosleep where timespec can mean</font>
665<font color="#c80000">// either a duration or a time_point depending upon another argument to the function.</font>
666<font color="#c80000">//</font>
667<font color="#c80000">// In C++ we can easily mitigate such errors by detecting them at compile time.  This is done through</font>
668<font color="#c80000">// the use of distinct types for these distinct concepts (even though both types have identical layout!).</font>
669
670template &lt;class Clock, class Duration = typename Clock::duration&gt;
671requires Duration is an instantiation of duration
672class time_point
673{
674public:
675    typedef Clock                     clock;
676    typedef Duration                  duration;
677    typedef typename duration::rep    rep;
678    typedef typename duration::period period;
679private:
680    duration d_;  <font color="#c80000">// exposition only</font>
681
682public:
683    time_point();  <font color="#c80000">// has value "epoch"</font>
684    explicit time_point(const duration&amp; d);  <font color="#c80000">// same as time_point() + d</font>
685
686    <font color="#c80000">// conversions</font>
687    template &lt;class Duration2&gt;
688       requires Convertible&lt;Duration2, duration&gt;
689       time_point(const time_point&lt;clock, Duration2&gt;&amp; t);
690
691    <font color="#c80000">// observer</font>
692
693    duration time_since_epoch() const;
694
695    <font color="#c80000">// arithmetic</font>
696
697    time_point&amp; operator+=(const duration&amp; d);
698    time_point&amp; operator-=(const duration&amp; d);
699
700    <font color="#c80000">// special values</font>
701
702    static time_point min();
703    static time_point max();
704};
705
706}  <font color="#c80000">// datetime</font>
707
708template &lt;class Clock, class Duration1, class Duration2&gt;
709struct common_type&lt;datetime::time_point&lt;Clock, Duration1&gt;, datetime::time_point&lt;Clock, Duration2&gt; &gt;
710{
711    typedef datetime::time_point&lt;Clock, typename common_type&lt;Duration1, Duration2&gt;::type&gt; type;
712};
713
714namespace datetime {
715
716template &lt;class ToDuration, class Clock, class Duration&gt;
717  time_point&lt;Clock, ToDuration&gt; time_point_cast(const time_point&lt;Clock, Duration&gt;&amp; t);
718
719template &lt;class Clock, class Duration1, class Duration2&gt;
720   bool operator==(const time_point&lt;Clock, Duration1&gt;&amp; lhs, const time_point&lt;Clock, Duration2&gt;&amp; rhs);
721template &lt;class Clock, class Duration1, class Duration2&gt;
722   bool operator!=(const time_point&lt;Clock, Duration1&gt;&amp; lhs, const time_point&lt;Clock, Duration2&gt;&amp; rhs);
723template &lt;class Clock, class Duration1, class Duration2&gt;
724   bool operator&lt; (const time_point&lt;Clock, Duration1&gt;&amp; lhs, const time_point&lt;Clock, Duration2&gt;&amp; rhs);
725template &lt;class Clock, class Duration1, class Duration2&gt;
726   bool operator&lt;=(const time_point&lt;Clock, Duration1&gt;&amp; lhs, const time_point&lt;Clock, Duration2&gt;&amp; rhs);
727template &lt;class Clock, class Duration1, class Duration2&gt;
728   bool operator&gt; (const time_point&lt;Clock, Duration1&gt;&amp; lhs, const time_point&lt;Clock, Duration2&gt;&amp; rhs);
729template &lt;class Clock, class Duration1, class Duration2&gt;
730   bool operator&gt;=(const time_point&lt;Clock, Duration1&gt;&amp; lhs, const time_point&lt;Clock, Duration2&gt;&amp; rhs);
731
732template &lt;class Clock, class Duration1, class Rep2, class Period2&gt;
733  time_point&lt;Clock, typename common_type&lt;Duration1, duration&lt;Rep2, Period2&gt; &gt;::type&gt;
734  operator+(const time_point&lt;Clock, Duration1&gt;&amp; lhs, const duration&lt;Rep2, Period2&gt;&amp; rhs);
735
736template &lt;class Rep1, class Period1, class Clock, class Duration2&gt;
737  time_point&lt;Clock, typename common_type&lt;duration&lt;Rep1, Period1&gt;, Duration2&gt;::type&gt;
738  operator+(const duration&lt;Rep1, Period1&gt;&amp; lhs, const time_point&lt;Clock, Duration2&gt;&amp; rhs);
739
740template &lt;class Clock, class Duration1, class Rep2, class Period2&gt;
741  time_point&lt;Clock, typename common_type&lt;Duration1, duration&lt;Rep2, Period2&gt; &gt;::type&gt;
742  operator-(const time_point&lt;Clock, Duration1&gt;&amp; lhs, const duration&lt;Rep2, Period2&gt;&amp; rhs);
743
744template &lt;class Clock, class Duration1, class Duration2&gt;
745  typename common_type&lt;Duration1, Duration2&gt;::type
746  operator-(const time_point&lt;Clock, Duration1&gt;&amp; lhs, const time_point&lt;Clock, Duration2&gt;&amp; rhs);
747
748<font color="#c80000">// clocks</font>
749
750<font color="#c80000">// A clock specifies a representation, and a period.  These specifications are used to</font>
751<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>
752<font color="#c80000">//    time_point.  A clock need not have any state.</font>
753
754<font color="#c80000">// The cost of not including separate types for clocks is that there is no better place to</font>
755<font color="#c80000">// bundle the "native" duration and time_point types for a clock with the functionality to</font>
756<font color="#c80000">// get the current time_point (what time is it now?).  By bundling this information into a</font>
757<font color="#c80000">// type, the extension to support multiple clocks is both easy and obvious.  The ability to</font>
758<font color="#c80000">// easily support multiple clocks in such a flexible yet simple and efficient manner is</font>
759<font color="#c80000">// very important.  A client might (for example) write code with the clock as a generic</font>
760<font color="#c80000">// template parameter, and then easily experiment with different timers.</font>
761
762class system_clock
763{
764public:
765    typedef &lt;unspecified&gt;                      rep;
766    typedef ratio&lt;unspecified, unspecified&gt;    period;
767    typedef datetime::duration&lt;rep, period&gt;    duration;
768    typedef datetime::time_point&lt;system_clock&gt; time_point;
769    static const bool is_mononontic = &lt;unspecified&gt;;
770
771    static time_point now();
772
773    <font color="#c80000">// Map to C API</font>
774    static time_t      to_time_t  (const time_point&amp; t);
775    static time_point  from_time_t(time_t t);
776};
777
778class monotonic_clock  <font color="#c80000">// optional</font>
779{
780public:
781    typedef &lt;unspecified&gt;                         rep;
782    typedef ratio&lt;unspecified, unspecified&gt;       period;
783    typedef datetime::duration&lt;rep, period&gt;       duration;
784    typedef datetime::time_point&lt;monotonic_clock&gt; time_point;
785    static const bool is_mononontic = true;
786
787    static time_point now();
788};
789
790class high_resolution_clock  <font color="#c80000">// optional</font>
791{
792public:
793    typedef &lt;unspecified&gt;                               rep;
794    typedef ratio&lt;unspecified, unspecified&gt;             period;
795    typedef datetime::duration&lt;rep, period&gt;             duration;
796    typedef datetime::time_point&lt;high_resolution_clock&gt; time_point;
797    static const bool is_mononontic = &lt;unspecified&gt;;
798
799    static time_point now();
800};
801
802<font color="#c80000">// Note: These clocks may be three separate types, or typedefs to one or two common types.</font>
803
804}  <font color="#c80000">// datetime</font>
805
806<font color="#c80000">//////////////////////////</font>
807<font color="#c80000">//  Threading interface //</font>
808<font color="#c80000">//////////////////////////</font>
809
810<font color="#c80000">// timed_mutex</font>
811
812struct timed_mutex
813{
814public:
815    timed_mutex();
816    ~timed_mutex();
817
818    timed_mutex(const timed_mutex&amp;) = delete;
819    timed_mutex&amp; operator=(const timed_mutex&amp;) = delete;
820
821    void lock();
822    bool try_lock();
823    template &lt;class Rep, class Period&gt;
824        bool try_lock_for(const datetime::duration&lt;Rep, Period&gt;&amp; rel_time);
825    template &lt;class Clock, class Duration&gt;
826        bool try_lock_until(const datetime::time_point&lt;Clock, Duration&gt;&amp; abs_time);
827    void unlock();
828
829    typedef unspecified native_handle_type;  <font color="#c80000">// optional.  example: pthread_mutex_t*</font>
830    native_handle_type native_handle();      <font color="#c80000">// optional</font>
831};
832
833<font color="#c80000">// recursive_timed_mutex</font>
834
835struct recursive_timed_mutex
836{
837public:
838    recursive_timed_mutex();
839    ~recursive_timed_mutex();
840
841    recursive_timed_mutex(const recursive_timed_mutex&amp;) = delete;
842    recursive_timed_mutex&amp; operator=(const recursive_timed_mutex&amp;) = delete;
843
844    void lock();
845    bool try_lock();
846    template &lt;class Rep, class Period&gt;
847        bool try_lock_for(const datetime::duration&lt;Rep, Period&gt;&amp; rel_time);
848    template &lt;class Clock, class Duration&gt;
849        bool try_lock_until(const datetime::time_point&lt;Clock, Duration&gt;&amp; abs_time);
850    void unlock();
851
852    typedef unspecified native_handle_type;  <font color="#c80000">// optional.  example: pthread_mutex_t*</font>
853    native_handle_type native_handle();      <font color="#c80000">// optional</font>
854};
855
856<font color="#c80000">// unique_lock</font>
857
858template &lt;class Mutex&gt;
859class unique_lock
860{
861public:
862    typedef Mutex mutex_type;
863
864    unique_lock();
865    explicit unique_lock(mutex_type&amp; m);
866    unique_lock(mutex_type&amp; m, defer_lock_t);
867    unique_lock(mutex_type&amp; m, try_to_lock_t);
868    unique_lock(mutex_type&amp; m, adopt_lock_t);
869    template &lt;class Rep, class Period&gt;
870        unique_lock(mutex_type&amp; m, const datetime::duration&lt;Rep, Period&gt;&amp; rel_t);
871    template &lt;class Clock, class Duration&gt;
872        unique_lock(mutex_type&amp; m, const datetime::time_point&lt;Clock, Duration&gt;&amp; abs_time);
873    ~unique_lock();
874
875    unique_lock(unique_lock const&amp;) = delete;
876    unique_lock&amp; operator=(unique_lock const&amp;) = delete;
877
878    unique_lock(unique_lock&amp;&amp; u);
879    unique_lock&amp; operator=(unique_lock&amp;&amp; u);
880
881    void lock();
882    bool try_lock();
883    template &lt;class Rep, class Period&gt;
884        bool try_lock_for(const datetime::duration&lt;Rep, Period&gt;&amp; rel_t);
885    template &lt;class Clock, class Duration&gt;
886        bool try_lock_until(const datetime::time_point&lt;Clock, Duration&gt;&amp; abs_time);
887    void unlock();
888
889    bool owns_lock() const;
890    operator unspecified-bool-type () const;
891    mutex_type* mutex() const;
892
893    void swap(unique_lock&amp;&amp; u);
894    mutex_type* release();
895};
896
897<font color="#c80000">// condition_variable</font>
898
899class condition_variable
900{
901public:
902
903    condition_variable();
904    ~condition_variable();
905
906    condition_variable(const condition_variable&amp;) = delete;
907    condition_variable&amp; operator=(const condition_variable&amp;) = delete;
908
909    void notify_one();
910    void notify_all();
911
912    void wait(unique_lock&lt;mutex&gt;&amp; lock);
913    template &lt;class Predicate&gt;
914        void wait(unique_lock&lt;mutex&gt;&amp; lock, Predicate pred);
915
916    template &lt;class Clock, class Duration&gt;
917        bool wait_until(unique_lock&lt;mutex&gt;&amp; lock,
918                        const datetime::time_point&lt;Clock, Duration&gt;&amp; abs_time);
919    template &lt;class Clock, class Duration, class Predicate&gt;
920        bool wait_until(unique_lock&lt;mutex&gt;&amp; lock,
921                        const datetime::time_point&lt;Clock, Duration&gt;&amp; abs_time,
922                        Predicate pred);
923
924    template &lt;class Rep, class Period&gt;
925        bool wait_for(unique_lock&lt;mutex&gt;&amp; lock, const datetime::duration&lt;Rep, Period&gt;&amp; rel_time);
926    template &lt;class Rep, class Period, class Predicate&gt;
927        bool wait_for(unique_lock&lt;mutex&gt;&amp; lock,  const datetime::duration&lt;Rep, Period&gt;&amp; rel_time,
928                      Predicate pred);
929
930    typedef pthread_cond_t* native_handle_type;
931    native_handle_type native_handle();
932};
933
934<font color="#c80000">// condition_variable_any</font>
935
936class condition_variable_any
937{
938public:
939
940    condition_variable_any();
941    ~condition_variable_any();
942
943    condition_variable_any(const condition_variable_any&amp;) = delete;
944    condition_variable_any&amp; operator=(const condition_variable_any&amp;) = delete;
945
946    void notify_one();
947    void notify_all();
948
949    template &lt;class Lock&gt;
950        void wait(Lock&amp; lock);
951    template &lt;class Lock, class Predicate&gt;
952        void wait(Lock&amp; lock, Predicate pred);
953
954    template &lt;class Lock, class Clock, class Duration&gt;
955        bool wait_until(Lock&amp; lock, const datetime::time_point&lt;Clock, Duration&gt;&amp; abs_time);
956    template &lt;class Lock, class Clock, class Duration, class Predicate&gt;
957        bool wait_until(Lock&amp; lock, const datetime::time_point&lt;Clock, Duration&gt;&amp; abs_time,
958                        Predicate pred);
959
960    template &lt;class Lock, class Rep, class Period&gt;
961        bool wait_for(Lock&amp; lock, const datetime::duration&lt;Rep, Period&gt;&amp; rel_time);
962    template &lt;class Lock, class Rep, class Period, class Predicate&gt;
963        bool wait_for(Lock&amp; lock, const datetime::duration&lt;Rep, Period&gt;&amp; rel_time, Predicate pred);
964};
965
966<font color="#c80000">// sleep</font>
967
968namespace this_thread
969{
970
971    template &lt;class Rep, class Period&gt;
972        void sleep_for(const datetime::duration&lt;Rep, Period&gt;&amp; rel_time);
973
974    template &lt;class Clock, class Duration&gt;
975        void sleep_until(const datetime::time_point&lt;Clock, Duration&gt;&amp; abs_time);
976
977}  <font color="#c80000">// this_thread</font>
978
979}  <font color="#c80000">// std</font>
980
981*/</font>
982
983#include &lt;ctime&gt;
984#include &lt;climits&gt;
985#include &lt;inttypes.h&gt;
986#include &lt;limits&gt;
987#include "type_traits"
988
989#define decltype __typeof__
990
991namespace std
992{
993
994<font color="#c80000">//////////////////////////////////////////////////////////</font>
995<font color="#c80000">////////////////////// common_type ///////////////////////</font>
996<font color="#c80000">//////////////////////////////////////////////////////////</font>
997
998#define VARIADIC_COMMON_TYPE 0
999
1000#if VARIADIC_COMMON_TYPE == 0
1001
1002template &lt;class T, class U&gt;
1003struct common_type
1004{
1005private:
1006    static T t();
1007    static U u();
1008public:
1009    typedef decltype(true ? t() : u()) type;
1010};
1011
1012#else
1013
1014template &lt;class ...T&gt; struct common_type;
1015
1016template &lt;class T&gt;
1017struct common_type&lt;T&gt;
1018{
1019    typedef T type;
1020};
1021
1022template &lt;class T, class U&gt;
1023struct common_type&lt;T, U&gt;
1024{
1025private:
1026    static T t();
1027    static U u();
1028public:
1029    typedef decltype(true ? t() : u()) type;
1030};
1031
1032template &lt;class T, class U, class ...V&gt;
1033struct common_type&lt;T, U, V...&gt;
1034{
1035    typedef typename common_type&lt;typename common_type&lt;T, U&gt;::type, V...&gt;::type type;
1036};
1037
1038#endif
1039
1040<font color="#c80000">//////////////////////////////////////////////////////////</font>
1041<font color="#c80000">/////////////////////// ratio ////////////////////////////</font>
1042<font color="#c80000">//////////////////////////////////////////////////////////</font>
1043
1044<font color="#c80000">// __static_gcd</font>
1045
1046template &lt;intmax_t X, intmax_t Y&gt;
1047struct __static_gcd
1048{
1049    static const intmax_t value = __static_gcd&lt;Y, X % Y&gt;::value;
1050};
1051
1052template &lt;intmax_t X&gt;
1053struct __static_gcd&lt;X, 0&gt;
1054{
1055    static const intmax_t value = X;
1056};
1057
1058<font color="#c80000">// __static_lcm</font>
1059
1060template &lt;intmax_t X, intmax_t Y&gt;
1061struct __static_lcm
1062{
1063    static const intmax_t value = X / __static_gcd&lt;X, Y&gt;::value * Y;
1064};
1065
1066template &lt;intmax_t X&gt;
1067struct __static_abs
1068{
1069    static const intmax_t value = X &lt; 0 ? -X : X;
1070};
1071
1072template &lt;intmax_t X&gt;
1073struct __static_sign
1074{
1075    static const intmax_t value = X == 0 ? 0 : (X &lt; 0 ? -1 : 1);
1076};
1077
1078template &lt;intmax_t X, intmax_t Y, intmax_t = __static_sign&lt;Y&gt;::value&gt;
1079class __ll_add;
1080
1081template &lt;intmax_t X, intmax_t Y&gt;
1082class __ll_add&lt;X, Y, 1&gt;
1083{
1084    static const intmax_t min = (1LL &lt;&lt; (sizeof(intmax_t) * CHAR_BIT - 1)) + 1;
1085    static const intmax_t max = -min;
1086
1087    static char test[X &lt;= max - Y];
1088<font color="#c80000">//    static_assert(X &lt;= max - Y, "overflow in __ll_add");</font>
1089public:
1090    static const intmax_t value = X + Y;
1091};
1092
1093template &lt;intmax_t X, intmax_t Y&gt;
1094class __ll_add&lt;X, Y, 0&gt;
1095{
1096public:
1097    static const intmax_t value = X;
1098};
1099
1100template &lt;intmax_t X, intmax_t Y&gt;
1101class __ll_add&lt;X, Y, -1&gt;
1102{
1103    static const intmax_t min = (1LL &lt;&lt; (sizeof(intmax_t) * CHAR_BIT - 1)) + 1;
1104    static const intmax_t max = -min;
1105
1106    static char test[min - Y &lt;= X];
1107<font color="#c80000">//    static_assert(min - Y &lt;= X, "overflow in __ll_add");</font>
1108public:
1109    static const intmax_t value = X + Y;
1110};
1111
1112template &lt;intmax_t X, intmax_t Y, intmax_t = __static_sign&lt;Y&gt;::value&gt;
1113class __ll_sub;
1114
1115template &lt;intmax_t X, intmax_t Y&gt;
1116class __ll_sub&lt;X, Y, 1&gt;
1117{
1118    static const intmax_t min = (1LL &lt;&lt; (sizeof(intmax_t) * CHAR_BIT - 1)) + 1;
1119    static const intmax_t max = -min;
1120
1121    static char test[min + Y &lt;= X];
1122<font color="#c80000">//    static_assert(min + Y &lt;= X, "overflow in __ll_sub");</font>
1123public:
1124    static const intmax_t value = X - Y;
1125};
1126
1127template &lt;intmax_t X, intmax_t Y&gt;
1128class __ll_sub&lt;X, Y, 0&gt;
1129{
1130public:
1131    static const intmax_t value = X;
1132};
1133
1134template &lt;intmax_t X, intmax_t Y&gt;
1135class __ll_sub&lt;X, Y, -1&gt;
1136{
1137    static const intmax_t min = (1LL &lt;&lt; (sizeof(intmax_t) * CHAR_BIT - 1)) + 1;
1138    static const intmax_t max = -min;
1139
1140    static char test[X &lt;= max + Y];
1141<font color="#c80000">//    static_assert(X &lt;= max + Y, "overflow in __ll_sub");</font>
1142public:
1143    static const intmax_t value = X - Y;
1144};
1145
1146template &lt;intmax_t X, intmax_t Y&gt;
1147class __ll_mul
1148{
1149    static const intmax_t nan = (1LL &lt;&lt; (sizeof(intmax_t) * CHAR_BIT - 1));
1150    static const intmax_t min = nan + 1;
1151    static const intmax_t max = -min;
1152    static const intmax_t __a_x = __static_abs&lt;X&gt;::value;
1153    static const intmax_t __a_y = __static_abs&lt;Y&gt;::value;
1154
1155    static char test1[X != nan];
1156    static char test2[Y != nan];
1157    static char test[__a_x &lt;= max / __a_y];
1158<font color="#c80000">//    static_assert(X != nan &amp;&amp; Y != nan &amp;&amp; __a_x &lt;= max / __a_y, "overflow in __ll_mul");</font>
1159public:
1160    static const intmax_t value = X * Y;
1161};
1162
1163template &lt;intmax_t Y&gt;
1164class __ll_mul&lt;0, Y&gt;
1165{
1166public:
1167    static const intmax_t value = 0;
1168};
1169
1170template &lt;intmax_t X&gt;
1171class __ll_mul&lt;X, 0&gt;
1172{
1173public:
1174    static const intmax_t value = 0;
1175};
1176
1177template &lt;&gt;
1178class __ll_mul&lt;0, 0&gt;
1179{
1180public:
1181    static const intmax_t value = 0;
1182};
1183
1184<font color="#c80000">// Not actually used but left here in case needed in future maintenance</font>
1185template &lt;intmax_t X, intmax_t Y&gt;
1186class __ll_div
1187{
1188    static const intmax_t nan = (1LL &lt;&lt; (sizeof(intmax_t) * CHAR_BIT - 1));
1189    static const intmax_t min = nan + 1;
1190    static const intmax_t max = -min;
1191
1192    static char test1[X != nan];
1193    static char test2[Y != nan];
1194    static char test3[Y != 0];
1195<font color="#c80000">//    static_assert(X != nan &amp;&amp; Y != nan &amp;&amp; Y != 0, "overflow in __ll_div");</font>
1196public:
1197    static const intmax_t value = X / Y;
1198};
1199
1200template &lt;intmax_t N, intmax_t D = 1&gt;
1201class ratio
1202{
1203    static char test1[__static_abs&lt;N&gt;::value &gt;= 0];
1204    static char test2[__static_abs&lt;D&gt;::value &gt;  0];
1205<font color="#c80000">//    static_assert(__static_abs&lt;N&gt;::value &gt;= 0, "ratio numerator is out of range");</font>
1206<font color="#c80000">//    static_assert(D != 0, "ratio divide by 0");</font>
1207<font color="#c80000">//    static_assert(__static_abs&lt;D&gt;::value &gt;  0, "ratio denominator is out of range");</font>
1208    static const intmax_t __na = __static_abs&lt;N&gt;::value;
1209    static const intmax_t __da = __static_abs&lt;D&gt;::value;
1210    static const intmax_t __s = __static_sign&lt;N&gt;::value * __static_sign&lt;D&gt;::value;
1211    static const intmax_t __gcd = __static_gcd&lt;__na, __da&gt;::value;
1212public:
1213    static const intmax_t num = __s * __na / __gcd;
1214    static const intmax_t den = __da / __gcd;
1215};
1216
1217template &lt;class T&gt;                  struct ___is_ratio               : tmp::false_type {};
1218template &lt;intmax_t N, intmax_t D&gt; struct ___is_ratio&lt;ratio&lt;N, D&gt; &gt; : tmp::true_type  {};
1219template &lt;class T&gt; struct __is_ratio : ___is_ratio&lt;typename tmp::remove_cv&lt;T&gt;::type&gt; {};
1220
1221typedef ratio&lt;1LL, 1000000000000000000LL&gt; atto;
1222typedef ratio&lt;1LL,    1000000000000000LL&gt; femto;
1223typedef ratio&lt;1LL,       1000000000000LL&gt; pico;
1224typedef ratio&lt;1LL,          1000000000LL&gt; nano;
1225typedef ratio&lt;1LL,             1000000LL&gt; micro;
1226typedef ratio&lt;1LL,                1000LL&gt; milli;
1227typedef ratio&lt;1LL,                 100LL&gt; centi;
1228typedef ratio&lt;1LL,                  10LL&gt; deci;
1229typedef ratio&lt;                 10LL, 1LL&gt; deca;
1230typedef ratio&lt;                100LL, 1LL&gt; hecto;
1231typedef ratio&lt;               1000LL, 1LL&gt; kilo;
1232typedef ratio&lt;            1000000LL, 1LL&gt; mega;
1233typedef ratio&lt;         1000000000LL, 1LL&gt; giga;
1234typedef ratio&lt;      1000000000000LL, 1LL&gt; tera;
1235typedef ratio&lt;   1000000000000000LL, 1LL&gt; peta;
1236typedef ratio&lt;1000000000000000000LL, 1LL&gt; exa;
1237
1238template &lt;class R1, class R2&gt;
1239struct ratio_add
1240{
1241    typedef ratio&lt;__ll_add&lt;__ll_mul&lt;R1::num, R2::den&gt;::value,
1242                           __ll_mul&lt;R1::den, R2::num&gt;::value&gt;::value,
1243                  __ll_mul&lt;R1::den, R2::den&gt;::value&gt; type;
1244};
1245
1246template &lt;class R1, class R2&gt;
1247struct ratio_subtract
1248{
1249    typedef ratio&lt;__ll_sub&lt;__ll_mul&lt;R1::num, R2::den&gt;::value,
1250                           __ll_mul&lt;R1::den, R2::num&gt;::value&gt;::value,
1251                  __ll_mul&lt;R1::den, R2::den&gt;::value&gt; type;
1252};
1253
1254template &lt;class R1, class R2&gt;
1255struct ratio_multiply
1256{
1257    typedef ratio&lt;__ll_mul&lt;R1::num, R2::num&gt;::value, __ll_mul&lt;R1::den, R2::den&gt;::value&gt; type;
1258};
1259
1260template &lt;class R1, class R2&gt;
1261struct ratio_divide
1262{
1263    typedef ratio&lt;__ll_mul&lt;R1::num, R2::den&gt;::value, __ll_mul&lt;R1::den, R2::num&gt;::value&gt; type;
1264};
1265
1266<font color="#c80000">// ratio_equal</font>
1267
1268template &lt;class R1, class R2&gt;
1269struct ratio_equal
1270    : public tmp::integral_constant&lt;bool, R1::num == R2::num &amp;&amp; R1::den == R2::den&gt; {};
1271
1272template &lt;class R1, class R2&gt;
1273struct ratio_not_equal
1274    : public tmp::integral_constant&lt;bool, !ratio_equal&lt;R1, R2&gt;::value&gt; {};
1275
1276<font color="#c80000">// ratio_less</font>
1277
1278<font color="#c80000">// Protect against overflow, and still get the right answer as much as possible.</font>
1279<font color="#c80000">//   This just demonstrates for fun how far you can push things without hitting</font>
1280<font color="#c80000">//   overflow.  The obvious and simple implementation is conforming.</font>
1281
1282template &lt;class R1, class R2, bool ok1, bool ok2&gt;
1283struct __ratio_less3 <font color="#c80000">// true, true and false, false</font>
1284{
1285    static const bool value = __ll_mul&lt;R1::num, R2::den&gt;::value &lt; __ll_mul&lt;R2::num, R1::den&gt;::value;
1286};
1287
1288template &lt;class R1, class R2&gt;
1289struct __ratio_less3&lt;R1, R2, true, false&gt;
1290{
1291    static const bool value = true;
1292};
1293
1294template &lt;class R1, class R2&gt;
1295struct __ratio_less3&lt;R1, R2, false, true&gt;
1296{
1297    static const bool value = false;
1298};
1299
1300template &lt;class R1, class R2, bool = R1::num &lt; R1::den == R2::num &lt; R2::den&gt;
1301struct __ratio_less2  <font color="#c80000">// N1 &lt; D1 == N2 &lt; D2</font>
1302{
1303    static const intmax_t max = -((1LL &lt;&lt; (sizeof(intmax_t) * CHAR_BIT - 1)) + 1);
1304    static const bool ok1 = R1::num &lt;= max / R2::den;
1305    static const bool ok2 = R2::num &lt;= max / R1::den;
1306    static const bool value = __ratio_less3&lt;R1, R2, ok1, ok2&gt;::value;
1307};
1308
1309template &lt;class R1, class R2&gt;
1310struct __ratio_less2&lt;R1, R2, false&gt;  <font color="#c80000">// N1 &lt; D1 != N2 &lt; D2</font>
1311{
1312    static const bool value = R1::num &lt; R1::den;
1313};
1314
1315template &lt;class R1, class R2, bool = R1::num &lt; R1::den == R2::num &lt; R2::den&gt;
1316struct __ratio_less1  <font color="#c80000">// N1 &lt; D1 == N2 &lt; D2</font>
1317{
1318    static const bool value = __ratio_less2&lt;ratio&lt;R1::num, R2::num&gt;, ratio&lt;R1::den, R2::den&gt; &gt;::value;
1319};
1320
1321template &lt;class R1, class R2&gt;
1322struct __ratio_less1&lt;R1, R2, false&gt;  <font color="#c80000">// N1 &lt; D1 != N2 &lt; D2</font>
1323{
1324    static const bool value = R1::num &lt; R1::den;
1325};
1326
1327template &lt;class R1, class R2, intmax_t S1 = __static_sign&lt;R1::num&gt;::value,
1328                              intmax_t S2 = __static_sign&lt;R2::num&gt;::value&gt;
1329struct __ratio_less
1330{
1331    static const bool value = S1 &lt; S2;
1332};
1333
1334template &lt;class R1, class R2&gt;
1335struct __ratio_less&lt;R1, R2, 1LL, 1LL&gt;
1336{
1337    static const bool value = __ratio_less1&lt;R1, R2&gt;::value;
1338};
1339
1340template &lt;class R1, class R2&gt;
1341struct __ratio_less&lt;R1, R2, -1LL, -1LL&gt;
1342{
1343    static const bool value = __ratio_less1&lt;ratio&lt;-R2::num, R2::den&gt;, ratio&lt;-R1::num, R1::den&gt; &gt;::value;
1344};
1345
1346template &lt;class R1, class R2&gt;
1347struct ratio_less
1348    : public tmp::integral_constant&lt;bool, __ratio_less&lt;R1, R2&gt;::value&gt; {};
1349
1350template &lt;class R1, class R2&gt;
1351struct ratio_less_equal
1352    : public tmp::integral_constant&lt;bool, !ratio_less&lt;R2, R1&gt;::value&gt; {};
1353
1354template &lt;class R1, class R2&gt;
1355struct ratio_greater
1356    : public tmp::integral_constant&lt;bool, ratio_less&lt;R2, R1&gt;::value&gt; {};
1357
1358template &lt;class R1, class R2&gt;
1359struct ratio_greater_equal
1360    : public tmp::integral_constant&lt;bool, !ratio_less&lt;R1, R2&gt;::value&gt; {};
1361
1362template &lt;class R1, class R2&gt;
1363struct __ratio_gcd
1364{
1365    typedef ratio&lt;__static_gcd&lt;R1::num, R2::num&gt;::value,
1366                  __static_lcm&lt;R1::den, R2::den&gt;::value&gt; type;
1367};
1368
1369<font color="#c80000">//////////////////////////////////////////////////////////</font>
1370<font color="#c80000">////////////////////// duration //////////////////////////</font>
1371<font color="#c80000">//////////////////////////////////////////////////////////</font>
1372
1373namespace datetime
1374{
1375
1376template &lt;class RepType, class Period = ratio&lt;1&gt; &gt; class duration;
1377
1378template &lt;class T&gt;                 struct ___is_duration                         : tmp::false_type {};
1379template &lt;class Rep, class Period&gt; struct ___is_duration&lt;duration&lt;Rep, Period&gt; &gt; : tmp::true_type  {};
1380template &lt;class T&gt; struct __is_duration :  ___is_duration&lt;typename tmp::remove_cv&lt;T&gt;::type&gt; {};
1381
1382<font color="#c80000">// duration_cast</font>
1383
1384<font color="#c80000">// duration_cast is the heart of this whole prototype.  It can convert any</font>
1385<font color="#c80000">//   duration to any other.  It is also (implicitly) used in converting</font>
1386<font color="#c80000">//   time_points.  The conversion is always exact if possible.  And it is</font>
1387<font color="#c80000">//   always as efficient as hand written code.  If different representations</font>
1388<font color="#c80000">//   are involved, care is taken to never require implicit conversions.</font>
1389<font color="#c80000">//   Instead static_cast is used explicitly for every required conversion.</font>
1390<font color="#c80000">//   If there are a mixture of integral and floating point representations,</font>
1391<font color="#c80000">//   the use of common_type ensures that the most logical "intermediate"</font>
1392<font color="#c80000">//   representation is used.</font>
1393template &lt;class FromDuration, class ToDuration,
1394          class Period = typename ratio_divide&lt;typename FromDuration::period, typename ToDuration::period&gt;::type,
1395          bool = Period::num == 1,
1396          bool = Period::den == 1&gt;
1397struct __duration_cast;
1398
1399<font color="#c80000">// When the two periods are the same, all that is left to do is static_cast from</font>
1400<font color="#c80000">//   the source representation to the target representation (which may be a no-op).</font>
1401<font color="#c80000">//   This conversion is always exact as long as the static_cast from the source</font>
1402<font color="#c80000">//   representation to the destination representation is exact.</font>
1403template &lt;class FromDuration, class ToDuration, class Period&gt;
1404struct __duration_cast&lt;FromDuration, ToDuration, Period, true, true&gt;
1405{
1406    ToDuration operator()(const FromDuration&amp; fd) const
1407    {
1408        return ToDuration(static_cast&lt;typename ToDuration::rep&gt;(fd.count()));
1409    }
1410};
1411
1412<font color="#c80000">// When the numerator of FromPeriod / ToPeriod is 1, then all we need to do is</font>
1413<font color="#c80000">//   divide by the denominator of FromPeriod / ToPeriod.  The common_type of</font>
1414<font color="#c80000">//   the two representations is used for the intermediate computation before</font>
1415<font color="#c80000">//   static_cast'ing to the destination.</font>
1416<font color="#c80000">//   This conversion is generally not exact because of the division (but could be</font>
1417<font color="#c80000">//   if you get lucky on the run time value of fd.count()).</font>
1418template &lt;class FromDuration, class ToDuration, class Period&gt;
1419struct __duration_cast&lt;FromDuration, ToDuration, Period, true, false&gt;
1420{
1421    ToDuration operator()(const FromDuration&amp; fd) const
1422    {
1423#if VARIADIC_COMMON_TYPE == 0
1424        typedef typename common_type&lt;
1425            typename common_type&lt;typename ToDuration::rep, typename FromDuration::rep&gt;::type,
1426            intmax_t&gt;::type C;
1427#else
1428        typedef typename common_type&lt;typename ToDuration::rep, typename FromDuration::rep, intmax_t&gt;::type C;
1429#endif
1430        return ToDuration(static_cast&lt;typename ToDuration::rep&gt;(
1431                          static_cast&lt;C&gt;(fd.count()) / static_cast&lt;C&gt;(Period::den)));
1432    }
1433};
1434
1435<font color="#c80000">// When the denomenator of FromPeriod / ToPeriod is 1, then all we need to do is</font>
1436<font color="#c80000">//   multiply by the numerator of FromPeriod / ToPeriod.  The common_type of</font>
1437<font color="#c80000">//   the two representations is used for the intermediate computation before</font>
1438<font color="#c80000">//   static_cast'ing to the destination.</font>
1439<font color="#c80000">//   This conversion is always exact as long as the static_cast's involved are exact.</font>
1440template &lt;class FromDuration, class ToDuration, class Period&gt;
1441struct __duration_cast&lt;FromDuration, ToDuration, Period, false, true&gt;
1442{
1443    ToDuration operator()(const FromDuration&amp; fd) const
1444    {
1445#if VARIADIC_COMMON_TYPE == 0
1446        typedef typename common_type&lt;
1447            typename common_type&lt;typename ToDuration::rep, typename FromDuration::rep&gt;::type,
1448            intmax_t&gt;::type C;
1449#else
1450        typedef typename common_type&lt;typename ToDuration::rep, typename FromDuration::rep, intmax_t&gt;::type C;
1451#endif
1452        return ToDuration(static_cast&lt;typename ToDuration::rep&gt;(
1453                          static_cast&lt;C&gt;(fd.count()) * static_cast&lt;C&gt;(Period::num)));
1454    }
1455};
1456
1457<font color="#c80000">// When neither the numerator or denominator of FromPeriod / ToPeriod is 1, then we need to</font>
1458<font color="#c80000">//   multiply by the numerator and divide by the denominator of FromPeriod / ToPeriod.  The</font>
1459<font color="#c80000">//   common_type of the two representations is used for the intermediate computation before</font>
1460<font color="#c80000">//   static_cast'ing to the destination.</font>
1461<font color="#c80000">//   This conversion is generally not exact because of the division (but could be</font>
1462<font color="#c80000">//   if you get lucky on the run time value of fd.count()).</font>
1463template &lt;class FromDuration, class ToDuration, class Period&gt;
1464struct __duration_cast&lt;FromDuration, ToDuration, Period, false, false&gt;
1465{
1466    ToDuration operator()(const FromDuration&amp; fd) const
1467    {
1468#if VARIADIC_COMMON_TYPE == 0
1469        typedef typename common_type&lt;
1470            typename common_type&lt;typename ToDuration::rep, typename FromDuration::rep&gt;::type,
1471            intmax_t&gt;::type C;
1472#else
1473        typedef typename common_type&lt;typename ToDuration::rep, typename FromDuration::rep, intmax_t&gt;::type C;
1474#endif
1475        return ToDuration(static_cast&lt;typename ToDuration::rep&gt;(
1476                          static_cast&lt;C&gt;(fd.count()) * static_cast&lt;C&gt;(Period::num) / static_cast&lt;C&gt;(Period::den)));
1477    }
1478};
1479
1480<font color="#c80000">// Compile-time select the most efficient algorithm for the conversion...</font>
1481template &lt;class ToDuration, class Rep, class Period&gt;
1482inline
1483typename tmp::enable_if
1484&lt;
1485    __is_duration&lt;ToDuration&gt;::value,
1486    ToDuration
1487&gt;::type
1488duration_cast(const duration&lt;Rep, Period&gt;&amp; fd)
1489{
1490    return __duration_cast&lt;duration&lt;Rep, Period&gt;, ToDuration&gt;()(fd);
1491}
1492
1493<font color="#c80000">// Support bidirectional (non-exact) conversions for floating point rep types</font>
1494<font color="#c80000">//   (or user defined rep types which specialize treat_as_floating_point).</font>
1495template &lt;class Rep&gt; struct treat_as_floating_point : tmp::is_floating_point&lt;Rep&gt; {};
1496
1497template &lt;class Rep&gt;
1498struct duration_values
1499{
1500    static Rep __min_imp(tmp::false_type) {return -max();}
1501    static Rep __min_imp(tmp::true_type)  {return zero();}
1502public:
1503    static Rep zero() {return Rep(0);}
1504    static Rep max()  {return numeric_limits&lt;Rep&gt;::max();}
1505    static Rep min()  {return __min_imp(tmp::is_unsigned&lt;Rep&gt;());}
1506};
1507
1508<font color="#c80000">// duration</font>
1509
1510template &lt;class Rep, class Period&gt;
1511class duration
1512{
1513    static char test0[!__is_duration&lt;Rep&gt;::value];
1514<font color="#c80000">//  static_assert(!__is_duration&lt;Rep&gt;::value, "A duration representation can not be a duration");</font>
1515    static char test1[__is_ratio&lt;Period&gt;::value];
1516<font color="#c80000">//  static_assert(__is_ratio&lt;Period&gt;::value, "Second template parameter of duration must be a std::ratio");</font>
1517    static char test2[Period::num &gt; 0];
1518<font color="#c80000">//  static_assert(Period::num &gt; 0, "duration period must be positive");</font>
1519public:
1520    typedef Rep rep;
1521    typedef Period period;
1522private:
1523    rep rep_;
1524public:
1525
1526    duration() {} <font color="#c80000">// = default;</font>
1527    template &lt;class Rep2&gt;
1528        explicit duration(const Rep2&amp; r,
1529            typename tmp::enable_if
1530            &lt;
1531               tmp::is_convertible&lt;Rep2, rep&gt;::value &amp;&amp;
1532               (treat_as_floating_point&lt;rep&gt;::value ||
1533               !treat_as_floating_point&lt;rep&gt;::value &amp;&amp; !treat_as_floating_point&lt;Rep2&gt;::value)
1534            &gt;::type* = 0)
1535                : rep_(r) {}
1536
1537    <font color="#c80000">// conversions</font>
1538    template &lt;class Rep2, class Period2&gt;
1539        duration(const duration&lt;Rep2, Period2&gt;&amp; d,
1540            typename tmp::enable_if
1541            &lt;
1542                treat_as_floating_point&lt;rep&gt;::value ||
1543                (ratio_divide&lt;Period2, period&gt;::type::den == 1 &amp;&amp; !treat_as_floating_point&lt;Rep2&gt;::value)
1544            &gt;::type* = 0)
1545                : rep_(duration_cast&lt;duration&gt;(d).count()) {}
1546
1547    <font color="#c80000">// observer</font>
1548
1549    rep count() const {return rep_;}
1550
1551    <font color="#c80000">// arithmetic</font>
1552
1553    duration  operator+() const {return *this;}
1554    duration  operator-() const {return duration(-rep_);}
1555    duration&amp; operator++()      {++rep_; return *this;}
1556    duration  operator++(int)   {return duration(rep_++);}
1557    duration&amp; operator--()      {--rep_; return *this;}
1558    duration  operator--(int)   {return duration(rep_--);}
1559
1560    duration&amp; operator+=(const duration&amp; d) {rep_ += d.count(); return *this;}
1561    duration&amp; operator-=(const duration&amp; d) {rep_ -= d.count(); return *this;}
1562
1563    duration&amp; operator*=(const rep&amp; rhs) {rep_ *= rhs; return *this;}
1564    duration&amp; operator/=(const rep&amp; rhs) {rep_ /= rhs; return *this;}
1565
1566    <font color="#c80000">// special values</font>
1567
1568    static duration zero() {return duration(duration_values&lt;rep&gt;::zero());}
1569    static duration min()  {return duration(duration_values&lt;rep&gt;::min());}
1570    static duration max()  {return duration(duration_values&lt;rep&gt;::max());}
1571};
1572
1573typedef duration&lt;long long,         nano&gt; nanoseconds;
1574typedef duration&lt;long long,        micro&gt; microseconds;
1575typedef duration&lt;long long,        milli&gt; milliseconds;
1576typedef duration&lt;long long              &gt; seconds;
1577typedef duration&lt;     long, ratio&lt;  60&gt; &gt; minutes;
1578typedef duration&lt;     long, ratio&lt;3600&gt; &gt; hours;
1579
1580} <font color="#c80000">// datetime</font>
1581
1582template &lt;class Rep1, class Period1, class Rep2, class Period2&gt;
1583struct common_type&lt;datetime::duration&lt;Rep1, Period1&gt;, datetime::duration&lt;Rep2, Period2&gt; &gt;
1584{
1585    typedef datetime::duration&lt;typename common_type&lt;Rep1, Rep2&gt;::type,
1586                               typename __ratio_gcd&lt;Period1, Period2&gt;::type&gt; type;
1587};
1588
1589namespace datetime {
1590
1591<font color="#c80000">// Duration ==</font>
1592
1593template &lt;class LhsDuration, class RhsDuration&gt;
1594struct __duration_eq
1595{
1596    bool operator()(const LhsDuration&amp; lhs, const RhsDuration&amp; rhs)
1597        {
1598            typedef typename common_type&lt;LhsDuration, RhsDuration&gt;::type CD;
1599            return CD(lhs).count() == CD(rhs).count();
1600        }
1601};
1602
1603template &lt;class LhsDuration&gt;
1604struct __duration_eq&lt;LhsDuration, LhsDuration&gt;
1605{
1606    bool operator()(const LhsDuration&amp; lhs, const LhsDuration&amp; rhs)
1607        {return lhs.count() == rhs.count();}
1608};
1609
1610template &lt;class Rep1, class Period1, class Rep2, class Period2&gt;
1611inline
1612bool
1613operator==(const duration&lt;Rep1, Period1&gt;&amp; lhs, const duration&lt;Rep2, Period2&gt;&amp; rhs)
1614{
1615    return __duration_eq&lt;duration&lt;Rep1, Period1&gt;, duration&lt;Rep2, Period2&gt; &gt;()(lhs, rhs);
1616}
1617
1618<font color="#c80000">// Duration !=</font>
1619
1620template &lt;class Rep1, class Period1, class Rep2, class Period2&gt;
1621inline
1622bool
1623operator!=(const duration&lt;Rep1, Period1&gt;&amp; lhs, const duration&lt;Rep2, Period2&gt;&amp; rhs)
1624{
1625    return !(lhs == rhs);
1626}
1627
1628<font color="#c80000">// Duration &lt;</font>
1629
1630template &lt;class LhsDuration, class RhsDuration&gt;
1631struct __duration_lt
1632{
1633    bool operator()(const LhsDuration&amp; lhs, const RhsDuration&amp; rhs)
1634        {
1635            typedef typename common_type&lt;LhsDuration, RhsDuration&gt;::type CD;
1636            return CD(lhs).count() &lt; CD(rhs).count();
1637        }
1638};
1639
1640template &lt;class LhsDuration&gt;
1641struct __duration_lt&lt;LhsDuration, LhsDuration&gt;
1642{
1643    bool operator()(const LhsDuration&amp; lhs, const LhsDuration&amp; rhs)
1644        {return lhs.count() &lt; rhs.count();}
1645};
1646
1647template &lt;class Rep1, class Period1, class Rep2, class Period2&gt;
1648inline
1649bool
1650operator&lt; (const duration&lt;Rep1, Period1&gt;&amp; lhs, const duration&lt;Rep2, Period2&gt;&amp; rhs)
1651{
1652    return __duration_lt&lt;duration&lt;Rep1, Period1&gt;, duration&lt;Rep2, Period2&gt; &gt;()(lhs, rhs);
1653}
1654
1655<font color="#c80000">// Duration &gt;</font>
1656
1657template &lt;class Rep1, class Period1, class Rep2, class Period2&gt;
1658inline
1659bool
1660operator&gt; (const duration&lt;Rep1, Period1&gt;&amp; lhs, const duration&lt;Rep2, Period2&gt;&amp; rhs)
1661{
1662    return rhs &lt; lhs;
1663}
1664
1665<font color="#c80000">// Duration &lt;=</font>
1666
1667template &lt;class Rep1, class Period1, class Rep2, class Period2&gt;
1668inline
1669bool
1670operator&lt;=(const duration&lt;Rep1, Period1&gt;&amp; lhs, const duration&lt;Rep2, Period2&gt;&amp; rhs)
1671{
1672    return !(rhs &lt; lhs);
1673}
1674
1675<font color="#c80000">// Duration &gt;=</font>
1676
1677template &lt;class Rep1, class Period1, class Rep2, class Period2&gt;
1678inline
1679bool
1680operator&gt;=(const duration&lt;Rep1, Period1&gt;&amp; lhs, const duration&lt;Rep2, Period2&gt;&amp; rhs)
1681{
1682    return !(lhs &lt; rhs);
1683}
1684
1685<font color="#c80000">// Duration +</font>
1686
1687template &lt;class Rep1, class Period1, class Rep2, class Period2&gt;
1688inline
1689typename common_type&lt;duration&lt;Rep1, Period1&gt;, duration&lt;Rep2, Period2&gt; &gt;::type
1690operator+(const duration&lt;Rep1, Period1&gt;&amp; lhs, const duration&lt;Rep2, Period2&gt;&amp; rhs)
1691{
1692    typename common_type&lt;duration&lt;Rep1, Period1&gt;, duration&lt;Rep2, Period2&gt; &gt;::type result = lhs;
1693    result += rhs;
1694    return result;
1695}
1696
1697<font color="#c80000">// Duration -</font>
1698
1699template &lt;class Rep1, class Period1, class Rep2, class Period2&gt;
1700inline
1701typename common_type&lt;duration&lt;Rep1, Period1&gt;, duration&lt;Rep2, Period2&gt; &gt;::type
1702operator-(const duration&lt;Rep1, Period1&gt;&amp; lhs, const duration&lt;Rep2, Period2&gt;&amp; rhs)
1703{
1704    typename common_type&lt;duration&lt;Rep1, Period1&gt;, duration&lt;Rep2, Period2&gt; &gt;::type result = lhs;
1705    result -= rhs;
1706    return result;
1707}
1708
1709<font color="#c80000">// Duration *</font>
1710
1711template &lt;class Rep1, class Period, class Rep2&gt;
1712inline
1713typename tmp::enable_if
1714&lt;
1715    tmp::is_convertible&lt;Rep1, typename common_type&lt;Rep1, Rep2&gt;::type&gt;::value &amp;&amp;
1716    tmp::is_convertible&lt;Rep2, typename common_type&lt;Rep1, Rep2&gt;::type&gt;::value,
1717    duration&lt;typename common_type&lt;Rep1, Rep2&gt;::type, Period&gt;
1718&gt;::type
1719operator*(const duration&lt;Rep1, Period&gt;&amp; d, const Rep2&amp; s)
1720{
1721    typedef typename common_type&lt;Rep1, Rep2&gt;::type CR;
1722    duration&lt;CR, Period&gt; r = d;
1723    r *= static_cast&lt;CR&gt;(s);
1724    return r;
1725}
1726
1727template &lt;class Rep1, class Period, class Rep2&gt;
1728inline
1729typename tmp::enable_if
1730&lt;
1731    tmp::is_convertible&lt;Rep1, typename common_type&lt;Rep1, Rep2&gt;::type&gt;::value &amp;&amp;
1732    tmp::is_convertible&lt;Rep2, typename common_type&lt;Rep1, Rep2&gt;::type&gt;::value,
1733    duration&lt;typename common_type&lt;Rep1, Rep2&gt;::type, Period&gt;
1734&gt;::type
1735operator*(const Rep1&amp; s, const duration&lt;Rep2, Period&gt;&amp; d)
1736{
1737    return d * s;
1738}
1739
1740<font color="#c80000">// Duration /</font>
1741
1742template &lt;class Duration, class Rep, bool = __is_duration&lt;Rep&gt;::value&gt;
1743struct __duration_divide_result
1744{
1745};
1746
1747template &lt;class Duration, class Rep2,
1748    bool = tmp::is_convertible&lt;typename Duration::rep,
1749                               typename common_type&lt;typename Duration::rep, Rep2&gt;::type&gt;::value &amp;&amp;
1750           tmp::is_convertible&lt;Rep2,
1751                               typename common_type&lt;typename Duration::rep, Rep2&gt;::type&gt;::value&gt;
1752struct __duration_divide_imp
1753{
1754};
1755
1756template &lt;class Rep1, class Period, class Rep2&gt;
1757struct __duration_divide_imp&lt;duration&lt;Rep1, Period&gt;, Rep2, true&gt;
1758{
1759    typedef duration&lt;typename common_type&lt;Rep1, Rep2&gt;::type, Period&gt; type;
1760};
1761
1762template &lt;class Rep1, class Period, class Rep2&gt;
1763struct __duration_divide_result&lt;duration&lt;Rep1, Period&gt;, Rep2, false&gt;
1764    : __duration_divide_imp&lt;duration&lt;Rep1, Period&gt;, Rep2&gt;
1765{
1766};
1767
1768template &lt;class Rep1, class Period, class Rep2&gt;
1769inline
1770typename __duration_divide_result&lt;duration&lt;Rep1, Period&gt;, Rep2&gt;::type
1771operator/(const duration&lt;Rep1, Period&gt;&amp; d, const Rep2&amp; s)
1772{
1773    typedef typename common_type&lt;Rep1, Rep2&gt;::type CR;
1774    duration&lt;CR, Period&gt; r = d;
1775    r /= static_cast&lt;CR&gt;(s);
1776    return r;
1777}
1778
1779template &lt;class Rep1, class Period1, class Rep2, class Period2&gt;
1780inline
1781typename common_type&lt;Rep1, Rep2&gt;::type
1782operator/(const duration&lt;Rep1, Period1&gt;&amp; lhs, const duration&lt;Rep2, Period2&gt;&amp; rhs)
1783{
1784    typedef typename common_type&lt;duration&lt;Rep1, Period1&gt;, duration&lt;Rep2, Period2&gt; &gt;::type CD;
1785    return CD(lhs).count() / CD(rhs).count();
1786}
1787
1788<font color="#c80000">//////////////////////////////////////////////////////////</font>
1789<font color="#c80000">///////////////////// time_point /////////////////////////</font>
1790<font color="#c80000">//////////////////////////////////////////////////////////</font>
1791
1792template &lt;class Clock, class Duration = typename Clock::duration&gt;
1793class time_point
1794{
1795    static char test1[__is_duration&lt;Duration&gt;::value];
1796<font color="#c80000">//  static_assert(__is_duration&lt;Duration&gt;::value,</font>
1797<font color="#c80000">//                "Second template parameter of time_point must be a std::datetime::duration");</font>
1798public:
1799    typedef Clock                     clock;
1800    typedef Duration                  duration;
1801    typedef typename duration::rep    rep;
1802    typedef typename duration::period period;
1803private:
1804    duration d_;
1805
1806public:
1807    time_point() : d_(duration::zero()) {}
1808    explicit time_point(const duration&amp; d) : d_(d) {}
1809
1810    <font color="#c80000">// conversions</font>
1811    template &lt;class Duration2&gt;
1812    time_point(const time_point&lt;clock, Duration2&gt;&amp; t,
1813        typename tmp::enable_if
1814        &lt;
1815            tmp::is_convertible&lt;Duration2, duration&gt;::value
1816        &gt;::type* = 0)
1817            : d_(t.time_since_epoch()) {}
1818
1819    <font color="#c80000">// observer</font>
1820
1821    duration time_since_epoch() const {return d_;}
1822
1823    <font color="#c80000">// arithmetic</font>
1824
1825    time_point&amp; operator+=(const duration&amp; d) {d_ += d; return *this;}
1826    time_point&amp; operator-=(const duration&amp; d) {d_ -= d; return *this;}
1827
1828    <font color="#c80000">// special values</font>
1829
1830    static time_point min() {return time_point(duration::min());}
1831    static time_point max() {return time_point(duration::max());}
1832};
1833
1834} <font color="#c80000">// datetime</font>
1835
1836template &lt;class Clock, class Duration1, class Duration2&gt;
1837struct common_type&lt;datetime::time_point&lt;Clock, Duration1&gt;, datetime::time_point&lt;Clock, Duration2&gt; &gt;
1838{
1839    typedef datetime::time_point&lt;Clock, typename common_type&lt;Duration1, Duration2&gt;::type&gt; type;
1840};
1841
1842namespace datetime {
1843
1844template &lt;class ToDuration, class Clock, class Duration&gt;
1845inline
1846time_point&lt;Clock, ToDuration&gt;
1847time_point_cast(const time_point&lt;Clock, Duration&gt;&amp; t)
1848{
1849    return time_point&lt;Clock, ToDuration&gt;(duration_cast&lt;ToDuration&gt;(t.time_since_epoch()));
1850}
1851
1852<font color="#c80000">// time_point ==</font>
1853
1854template &lt;class Clock, class Duration1, class Duration2&gt;
1855inline
1856bool
1857operator==(const time_point&lt;Clock, Duration1&gt;&amp; lhs, const time_point&lt;Clock, Duration2&gt;&amp; rhs)
1858{
1859    return lhs.time_since_epoch() == rhs.time_since_epoch();
1860}
1861
1862<font color="#c80000">// time_point !=</font>
1863
1864template &lt;class Clock, class Duration1, class Duration2&gt;
1865inline
1866bool
1867operator!=(const time_point&lt;Clock, Duration1&gt;&amp; lhs, const time_point&lt;Clock, Duration2&gt;&amp; rhs)
1868{
1869    return !(lhs == rhs);
1870}
1871
1872<font color="#c80000">// time_point &lt;</font>
1873
1874template &lt;class Clock, class Duration1, class Duration2&gt;
1875inline
1876bool
1877operator&lt;(const time_point&lt;Clock, Duration1&gt;&amp; lhs, const time_point&lt;Clock, Duration2&gt;&amp; rhs)
1878{
1879    return lhs.time_since_epoch() &lt; rhs.time_since_epoch();
1880}
1881
1882<font color="#c80000">// time_point &gt;</font>
1883
1884template &lt;class Clock, class Duration1, class Duration2&gt;
1885inline
1886bool
1887operator&gt;(const time_point&lt;Clock, Duration1&gt;&amp; lhs, const time_point&lt;Clock, Duration2&gt;&amp; rhs)
1888{
1889    return rhs &lt; lhs;
1890}
1891
1892<font color="#c80000">// time_point &lt;=</font>
1893
1894template &lt;class Clock, class Duration1, class Duration2&gt;
1895inline
1896bool
1897operator&lt;=(const time_point&lt;Clock, Duration1&gt;&amp; lhs, const time_point&lt;Clock, Duration2&gt;&amp; rhs)
1898{
1899    return !(rhs &lt; lhs);
1900}
1901
1902<font color="#c80000">// time_point &gt;=</font>
1903
1904template &lt;class Clock, class Duration1, class Duration2&gt;
1905inline
1906bool
1907operator&gt;=(const time_point&lt;Clock, Duration1&gt;&amp; lhs, const time_point&lt;Clock, Duration2&gt;&amp; rhs)
1908{
1909    return !(lhs &lt; rhs);
1910}
1911
1912<font color="#c80000">// time_point operator+(time_point x, duration y);</font>
1913
1914template &lt;class Clock, class Duration1, class Rep2, class Period2&gt;
1915inline
1916time_point&lt;Clock, typename common_type&lt;Duration1, duration&lt;Rep2, Period2&gt; &gt;::type&gt;
1917operator+(const time_point&lt;Clock, Duration1&gt;&amp; lhs, const duration&lt;Rep2, Period2&gt;&amp; rhs)
1918{
1919    typedef time_point&lt;Clock, typename common_type&lt;Duration1, duration&lt;Rep2, Period2&gt; &gt;::type&gt; TimeResult;
1920    TimeResult r(lhs);
1921    r += rhs;
1922    return r;
1923}
1924
1925<font color="#c80000">// time_point operator+(duration x, time_point y);</font>
1926
1927template &lt;class Rep1, class Period1, class Clock, class Duration2&gt;
1928inline
1929time_point&lt;Clock, typename common_type&lt;duration&lt;Rep1, Period1&gt;, Duration2&gt;::type&gt;
1930operator+(const duration&lt;Rep1, Period1&gt;&amp; lhs, const time_point&lt;Clock, Duration2&gt;&amp; rhs)
1931{
1932    return rhs + lhs;
1933}
1934
1935<font color="#c80000">// time_point operator-(time_point x, duration y);</font>
1936
1937template &lt;class Clock, class Duration1, class Rep2, class Period2&gt;
1938inline
1939time_point&lt;Clock, typename common_type&lt;Duration1, duration&lt;Rep2, Period2&gt; &gt;::type&gt;
1940operator-(const time_point&lt;Clock, Duration1&gt;&amp; lhs, const duration&lt;Rep2, Period2&gt;&amp; rhs)
1941{
1942    return lhs + (-rhs);
1943}
1944
1945<font color="#c80000">// duration operator-(time_point x, time_point y);</font>
1946
1947template &lt;class Clock, class Duration1, class Duration2&gt;
1948inline
1949typename common_type&lt;Duration1, Duration2&gt;::type
1950operator-(const time_point&lt;Clock, Duration1&gt;&amp; lhs, const time_point&lt;Clock, Duration2&gt;&amp; rhs)
1951{
1952    return lhs.time_since_epoch() - rhs.time_since_epoch();
1953}
1954
1955<font color="#c80000">//////////////////////////////////////////////////////////</font>
1956<font color="#c80000">/////////////////////// clocks ///////////////////////////</font>
1957<font color="#c80000">//////////////////////////////////////////////////////////</font>
1958
1959<font color="#c80000">// If you're porting, clocks are the system-specific (non-portable) part.</font>
1960<font color="#c80000">// You'll need to know how to get the current time and implement that under now().</font>
1961<font color="#c80000">// You'll need to know what units (tick period) and representation makes the most</font>
1962<font color="#c80000">// sense for your clock and set those accordingly.</font>
1963<font color="#c80000">// If you know how to map this clock to time_t (perhaps your clock is std::time, which</font>
1964<font color="#c80000">// makes that trivial), then you can fill out system_clock's to_time_t() and from_time_t().</font>
1965
1966class system_clock
1967{
1968public:
1969    typedef microseconds                       duration;
1970    typedef duration::rep                      rep;
1971    typedef duration::period                   period;
1972    typedef datetime::time_point&lt;system_clock&gt; time_point;
1973    static const bool is_monotonic =           false;
1974
1975    static time_point now();
1976    static time_t     to_time_t  (const time_point&amp; t);
1977    static time_point from_time_t(time_t t);
1978};
1979
1980class monotonic_clock
1981{
1982public:
1983    typedef nanoseconds                           duration;
1984    typedef duration::rep                         rep;
1985    typedef duration::period                      period;
1986    typedef datetime::time_point&lt;monotonic_clock&gt; time_point;
1987    static const bool is_monotonic =              true;
1988
1989    static time_point now();
1990};
1991
1992typedef monotonic_clock high_resolution_clock;
1993
1994} <font color="#c80000">// datetime</font>
1995} <font color="#c80000">// std</font>
1996
1997<font color="#c80000">// clocks.cpp</font>
1998
1999#include &lt;sys/time.h&gt; <font color="#c80000">//for gettimeofday and timeval</font>
2000#include &lt;mach/mach_time.h&gt;  <font color="#c80000">// mach_absolute_time, mach_timebase_info_data_t</font>
2001
2002namespace std {
2003namespace datetime {
2004
2005<font color="#c80000">// system_clock</font>
2006
2007<font color="#c80000">// gettimeofday is the most precise "system time" available on this platform.</font>
2008<font color="#c80000">// It returns the number of microseconds since New Years 1970 in a struct called timeval</font>
2009<font color="#c80000">// which has a field for seconds and a field for microseconds.</font>
2010<font color="#c80000">//    Fill in the timeval and then convert that to the time_point</font>
2011system_clock::time_point
2012system_clock::now()
2013{
2014    timeval tv;
2015    gettimeofday(&amp;tv, 0);
2016    return time_point(seconds(tv.tv_sec) + microseconds(tv.tv_usec));
2017}
2018
2019<font color="#c80000">// Take advantage of the fact that on this platform time_t is nothing but</font>
2020<font color="#c80000">//    an integral count of seconds since New Years 1970 (same epoch as timeval).</font>
2021<font color="#c80000">//    Just get the duration out of the time_point and truncate it to seconds.</font>
2022time_t
2023system_clock::to_time_t(const time_point&amp; t)
2024{
2025    return time_t(duration_cast&lt;seconds&gt;(t.time_since_epoch()).count());
2026}
2027
2028<font color="#c80000">// Just turn the time_t into a count of seconds and construct a time_point with it.</font>
2029system_clock::time_point
2030system_clock::from_time_t(time_t t)
2031{
2032    return system_clock::time_point(seconds(t));
2033}
2034
2035<font color="#c80000">// monotonic_clock</font>
2036
2037<font color="#c80000">// Note, in this implementation monotonic_clock and high_resolution_clock</font>
2038<font color="#c80000">//   are the same clock.  They are both based on mach_absolute_time().</font>
2039<font color="#c80000">//   mach_absolute_time() * MachInfo.numer / MachInfo.denom is the number of</font>
2040<font color="#c80000">//   nanoseconds since the computer booted up.  MachInfo.numer and MachInfo.denom</font>
2041<font color="#c80000">//   are run time constants supplied by the OS.  This clock has no relationship</font>
2042<font color="#c80000">//   to the Gregorian calendar.  It's main use is as a high resolution timer.</font>
2043
2044<font color="#c80000">// MachInfo.numer / MachInfo.denom is often 1 on the latest equipment.  Specialize</font>
2045<font color="#c80000">//   for that case as an optimization.</font>
2046static
2047monotonic_clock::rep
2048monotonic_simplified()
2049{
2050    return mach_absolute_time();
2051}
2052
2053static
2054double
2055compute_monotonic_factor()
2056{
2057    mach_timebase_info_data_t MachInfo;
2058    mach_timebase_info(&amp;MachInfo);
2059    return static_cast&lt;double&gt;(MachInfo.numer) / MachInfo.denom;
2060}
2061
2062static
2063monotonic_clock::rep
2064monotonic_full()
2065{
2066    static const double factor = compute_monotonic_factor();
2067    return static_cast&lt;monotonic_clock::rep&gt;(mach_absolute_time() * factor);
2068}
2069
2070typedef monotonic_clock::rep (*FP)();
2071
2072static
2073FP
2074init_monotonic_clock()
2075{
2076    mach_timebase_info_data_t MachInfo;
2077    mach_timebase_info(&amp;MachInfo);
2078    if (MachInfo.numer == MachInfo.denom)
2079        return &amp;monotonic_simplified;
2080    return &amp;monotonic_full;
2081}
2082
2083monotonic_clock::time_point
2084monotonic_clock::now()
2085{
2086    static FP fp = init_monotonic_clock();
2087    return time_point(duration(fp()));
2088}
2089
2090<font color="#c80000">// clocks.cpp end</font>
2091
2092} } <font color="#c80000">// std::datetime</font>
2093
2094<font color="#c80000">//////////////////////////////////////////////////////////</font>
2095<font color="#c80000">///////////// simulated thread interface /////////////////</font>
2096<font color="#c80000">//////////////////////////////////////////////////////////</font>
2097
2098#include &lt;iostream&gt;
2099
2100namespace std {
2101
2102void __print_time(datetime::system_clock::time_point t)
2103{
2104    using namespace datetime;
2105    time_t c_time = system_clock::to_time_t(t);
2106    std::tm* tmptr = std::localtime(&amp;c_time);
2107    system_clock::duration d = t.time_since_epoch();
2108    std::cout &lt;&lt; tmptr-&gt;tm_hour &lt;&lt; ':' &lt;&lt; tmptr-&gt;tm_min &lt;&lt; ':' &lt;&lt; tmptr-&gt;tm_sec
2109              &lt;&lt; '.' &lt;&lt; (d - duration_cast&lt;seconds&gt;(d)).count();
2110}
2111
2112namespace this_thread {
2113
2114template &lt;class Rep, class Period&gt;
2115void sleep_for(const datetime::duration&lt;Rep, Period&gt;&amp; d)
2116{
2117    datetime::microseconds t = datetime::duration_cast&lt;datetime::microseconds&gt;(d);
2118    if (t &lt; d)
2119        ++t;
2120    if (t &gt; datetime::microseconds(0))
2121        std::cout &lt;&lt; "sleep_for " &lt;&lt; t.count() &lt;&lt; " microseconds\n";
2122}
2123
2124template &lt;class Clock, class Duration&gt;
2125void sleep_until(const datetime::time_point&lt;Clock, Duration&gt;&amp; t)
2126{
2127    using namespace datetime;
2128    typedef time_point&lt;Clock, Duration&gt; Time;
2129    typedef system_clock::time_point SysTime;
2130    if (t &gt; Clock::now())
2131    {
2132        typedef typename common_type&lt;typename Time::duration, typename SysTime::duration&gt;::type D;
2133        <font color="#c80000">/* auto */</font> D d = t - Clock::now();
2134        microseconds us = duration_cast&lt;microseconds&gt;(d);
2135        if (us &lt; d)
2136            ++us;
2137        SysTime st = system_clock::now() + us;
2138        std::cout &lt;&lt; "sleep_until    ";
2139        __print_time(st);
2140        std::cout &lt;&lt; " which is " &lt;&lt; (st - system_clock::now()).count() &lt;&lt; " microseconds away\n";
2141    }
2142}
2143
2144}  <font color="#c80000">// this_thread</font>
2145
2146struct mutex {};
2147
2148struct timed_mutex
2149{
2150    bool try_lock() {std::cout &lt;&lt; "timed_mutex::try_lock()\n";}
2151
2152    template &lt;class Rep, class Period&gt;
2153        bool try_lock_for(const datetime::duration&lt;Rep, Period&gt;&amp; d)
2154        {
2155            datetime::microseconds t = datetime::duration_cast&lt;datetime::microseconds&gt;(d);
2156            if (t &lt;= datetime::microseconds(0))
2157                return try_lock();
2158            std::cout &lt;&lt; "try_lock_for " &lt;&lt; t.count() &lt;&lt; " microseconds\n";
2159            return true;
2160        }
2161
2162    template &lt;class Clock, class Duration&gt;
2163    bool try_lock_until(const datetime::time_point&lt;Clock, Duration&gt;&amp; t)
2164    {
2165        using namespace datetime;
2166        typedef time_point&lt;Clock, Duration&gt; Time;
2167        typedef system_clock::time_point SysTime;
2168        if (t &lt;= Clock::now())
2169            return try_lock();
2170        typedef typename common_type&lt;typename Time::duration, typename Clock::duration&gt;::type D;
2171        <font color="#c80000">/* auto */</font> D d = t - Clock::now();
2172        microseconds us = duration_cast&lt;microseconds&gt;(d);
2173        SysTime st = system_clock::now() + us;
2174        std::cout &lt;&lt; "try_lock_until ";
2175        __print_time(st);
2176        std::cout &lt;&lt; " which is " &lt;&lt; (st - system_clock::now()).count() &lt;&lt; " microseconds away\n";
2177    }
2178};
2179
2180struct condition_variable
2181{
2182    template &lt;class Rep, class Period&gt;
2183        bool wait_for(mutex&amp;, const datetime::duration&lt;Rep, Period&gt;&amp; d)
2184        {
2185            datetime::microseconds t = datetime::duration_cast&lt;datetime::microseconds&gt;(d);
2186            std::cout &lt;&lt; "wait_for " &lt;&lt; t.count() &lt;&lt; " microseconds\n";
2187            return true;
2188        }
2189
2190    template &lt;class Clock, class Duration&gt;
2191    bool wait_until(mutex&amp;, const datetime::time_point&lt;Clock, Duration&gt;&amp; t)
2192    {
2193        using namespace datetime;
2194        typedef time_point&lt;Clock, Duration&gt; Time;
2195        typedef system_clock::time_point SysTime;
2196        if (t &lt;= Clock::now())
2197            return false;
2198        typedef typename common_type&lt;typename Time::duration, typename Clock::duration&gt;::type D;
2199        <font color="#c80000">/* auto */</font> D d = t - Clock::now();
2200        microseconds us = duration_cast&lt;microseconds&gt;(d);
2201        SysTime st = system_clock::now() + us;
2202         std::cout &lt;&lt; "wait_until     ";
2203        __print_time(st);
2204        std::cout &lt;&lt; " which is " &lt;&lt; (st - system_clock::now()).count() &lt;&lt; " microseconds away\n";
2205    }
2206};
2207
2208} <font color="#c80000">// std</font>
2209
2210<font color="#c80000">//////////////////////////////////////////////////////////</font>
2211<font color="#c80000">///////////////////  End of implemetation ////////////////</font>
2212<font color="#c80000">//////////////////////////////////////////////////////////</font>
2213
2214<font color="#c80000">//////////////////////////////////////////////////////////</font>
2215<font color="#c80000">//////////// Simple sleep and wait examples //////////////</font>
2216<font color="#c80000">//////////////////////////////////////////////////////////</font>
2217
2218std::mutex m;
2219std::timed_mutex mut;
2220std::condition_variable cv;
2221
2222void basic_examples()
2223{
2224    std::cout &lt;&lt; "Running basic examples\n";
2225    using namespace std;
2226    using namespace std::datetime;
2227    system_clock::time_point time_limit = system_clock::now() + seconds(4) + milliseconds(500);
2228    this_thread::sleep_for(seconds(3));
2229    this_thread::sleep_for(nanoseconds(300));
2230    this_thread::sleep_until(time_limit);
2231<font color="#c80000">//    this_thread::sleep_for(time_limit);  // desired compile-time error</font>
2232<font color="#c80000">//    this_thread::sleep_until(seconds(3)); // desired compile-time error</font>
2233    mut.try_lock_for(milliseconds(30));
2234    mut.try_lock_until(time_limit);
2235<font color="#c80000">//    mut.try_lock_for(time_limit);        // desired compile-time error</font>
2236<font color="#c80000">//    mut.try_lock_until(milliseconds(30)); // desired compile-time error</font>
2237    cv.wait_for(m, minutes(1));    <font color="#c80000">// real code would put this in a loop</font>
2238    cv.wait_until(m, time_limit);  <font color="#c80000">// real code would put this in a loop</font>
2239    <font color="#c80000">// For those who prefer floating point</font>
2240    this_thread::sleep_for(duration&lt;double&gt;(0.25));
2241    this_thread::sleep_until(system_clock::now() + duration&lt;double&gt;(1.5));
2242}
2243
2244<font color="#c80000">//////////////////////////////////////////////////////////</font>
2245<font color="#c80000">//////////////////// User1 Example ///////////////////////</font>
2246<font color="#c80000">//////////////////////////////////////////////////////////</font>
2247
2248namespace User1
2249{
2250<font color="#c80000">// Example type-safe "physics" code interoperating with std::datetime::duration types</font>
2251<font color="#c80000">//  and taking advantage of the std::ratio infrastructure and design philosophy.</font>
2252
2253<font color="#c80000">// length - mimics std::datetime::duration except restricts representation to double.</font>
2254<font color="#c80000">//    Uses std::ratio facilities for length units conversions.</font>
2255
2256template &lt;class Ratio&gt;
2257class length
2258{
2259public:
2260    typedef Ratio ratio;
2261private:
2262    double len_;
2263public:
2264
2265    length() : len_(1) {}
2266    length(const double&amp; len) : len_(len) {}
2267
2268    <font color="#c80000">// conversions</font>
2269    template &lt;class R&gt;
2270    length(const length&lt;R&gt;&amp; d)
2271            : len_(d.count() * std::ratio_divide&lt;Ratio, R&gt;::type::den /
2272                               std::ratio_divide&lt;Ratio, R&gt;::type::num) {}
2273
2274    <font color="#c80000">// observer</font>
2275
2276    double count() const {return len_;}
2277
2278    <font color="#c80000">// arithmetic</font>
2279
2280    length&amp; operator+=(const length&amp; d) {len_ += d.count(); return *this;}
2281    length&amp; operator-=(const length&amp; d) {len_ -= d.count(); return *this;}
2282
2283    length operator+() const {return *this;}
2284    length operator-() const {return length(-len_);}
2285
2286    length&amp; operator*=(double rhs) {len_ *= rhs; return *this;}
2287    length&amp; operator/=(double rhs) {len_ /= rhs; return *this;}
2288};
2289
2290<font color="#c80000">// Sparse sampling of length units</font>
2291typedef length&lt;std::ratio&lt;1&gt; &gt;          meter;        <font color="#c80000">// set meter as "unity"</font>
2292typedef length&lt;std::centi&gt;              centimeter;   <font color="#c80000">// 1/100 meter</font>
2293typedef length&lt;std::kilo&gt;               kilometer;    <font color="#c80000">// 1000  meters</font>
2294typedef length&lt;std::ratio&lt;254, 10000&gt; &gt; inch;         <font color="#c80000">// 254/10000 meters</font>
2295<font color="#c80000">// length takes ratio instead of two integral types so that definitions can be made like so:</font>
2296typedef length&lt;std::ratio_multiply&lt;std::ratio&lt;12&gt;, inch::ratio&gt;::type&gt;   foot;  <font color="#c80000">// 12 inchs</font>
2297typedef length&lt;std::ratio_multiply&lt;std::ratio&lt;5280&gt;, foot::ratio&gt;::type&gt; mile;  <font color="#c80000">// 5280 feet</font>
2298
2299<font color="#c80000">// Need a floating point definition of seconds</font>
2300typedef std::datetime::duration&lt;double&gt; seconds;                         <font color="#c80000">// unity</font>
2301<font color="#c80000">// Demo of (scientific) support for sub-nanosecond resolutions</font>
2302typedef std::datetime::duration&lt;double,  std::pico&gt; picosecond;  <font color="#c80000">// 10^-12 seconds</font>
2303typedef std::datetime::duration&lt;double, std::femto&gt; femtosecond; <font color="#c80000">// 10^-15 seconds</font>
2304typedef std::datetime::duration&lt;double,  std::atto&gt; attosecond;  <font color="#c80000">// 10^-18 seconds</font>
2305
2306<font color="#c80000">// A very brief proof-of-concept for SIUnits-like library</font>
2307<font color="#c80000">//  Hard-wired to floating point seconds and meters, but accepts other units (shown in testUser1())</font>
2308template &lt;class R1, class R2&gt;
2309class quantity
2310{
2311    double q_;
2312public:
2313    quantity() : q_(1) {}
2314
2315    double get() const {return q_;}
2316    void set(double q) {q_ = q;}
2317};
2318
2319template &lt;&gt;
2320class quantity&lt;std::ratio&lt;1&gt;, std::ratio&lt;0&gt; &gt;
2321{
2322    double q_;
2323public:
2324    quantity() : q_(1) {}
2325    quantity(seconds d) : q_(d.count()) {}  <font color="#c80000">// note:  only User1::seconds needed here</font>
2326
2327    double get() const {return q_;}
2328    void set(double q) {q_ = q;}
2329};
2330
2331template &lt;&gt;
2332class quantity&lt;std::ratio&lt;0&gt;, std::ratio&lt;1&gt; &gt;
2333{
2334    double q_;
2335public:
2336    quantity() : q_(1) {}
2337    quantity(meter d) : q_(d.count()) {}  <font color="#c80000">// note:  only User1::meter needed here</font>
2338
2339    double get() const {return q_;}
2340    void set(double q) {q_ = q;}
2341};
2342
2343template &lt;&gt;
2344class quantity&lt;std::ratio&lt;0&gt;, std::ratio&lt;0&gt; &gt;
2345{
2346    double q_;
2347public:
2348    quantity() : q_(1) {}
2349    quantity(double d) : q_(d) {}
2350
2351    double get() const {return q_;}
2352    void set(double q) {q_ = q;}
2353};
2354
2355<font color="#c80000">// Example SI-Units</font>
2356typedef quantity&lt;std::ratio&lt;0&gt;, std::ratio&lt;0&gt; &gt;  Scalar;
2357typedef quantity&lt;std::ratio&lt;1&gt;, std::ratio&lt;0&gt; &gt;  Time;         <font color="#c80000">// second</font>
2358typedef quantity&lt;std::ratio&lt;0&gt;, std::ratio&lt;1&gt; &gt;  Distance;     <font color="#c80000">// meter</font>
2359typedef quantity&lt;std::ratio&lt;-1&gt;, std::ratio&lt;1&gt; &gt; Speed;        <font color="#c80000">// meter/second</font>
2360typedef quantity&lt;std::ratio&lt;-2&gt;, std::ratio&lt;1&gt; &gt; Acceleration; <font color="#c80000">// meter/second^2</font>
2361
2362template &lt;class R1, class R2, class R3, class R4&gt;
2363quantity&lt;typename std::ratio_subtract&lt;R1, R3&gt;::type, typename std::ratio_subtract&lt;R2, R4&gt;::type&gt;
2364operator/(const quantity&lt;R1, R2&gt;&amp; x, const quantity&lt;R3, R4&gt;&amp; y)
2365{
2366    typedef quantity&lt;typename std::ratio_subtract&lt;R1, R3&gt;::type, typename std::ratio_subtract&lt;R2, R4&gt;::type&gt; R;
2367    R r;
2368    r.set(x.get() / y.get());
2369    return r;
2370}
2371
2372template &lt;class R1, class R2, class R3, class R4&gt;
2373quantity&lt;typename std::ratio_add&lt;R1, R3&gt;::type, typename std::ratio_add&lt;R2, R4&gt;::type&gt;
2374operator*(const quantity&lt;R1, R2&gt;&amp; x, const quantity&lt;R3, R4&gt;&amp; y)
2375{
2376    typedef quantity&lt;typename std::ratio_add&lt;R1, R3&gt;::type, typename std::ratio_add&lt;R2, R4&gt;::type&gt; R;
2377    R r;
2378    r.set(x.get() * y.get());
2379    return r;
2380}
2381
2382template &lt;class R1, class R2&gt;
2383quantity&lt;R1, R2&gt;
2384operator+(const quantity&lt;R1, R2&gt;&amp; x, const quantity&lt;R1, R2&gt;&amp; y)
2385{
2386    typedef quantity&lt;R1, R2&gt; R;
2387    R r;
2388    r.set(x.get() + y.get());
2389    return r;
2390}
2391
2392template &lt;class R1, class R2&gt;
2393quantity&lt;R1, R2&gt;
2394operator-(const quantity&lt;R1, R2&gt;&amp; x, const quantity&lt;R1, R2&gt;&amp; y)
2395{
2396    typedef quantity&lt;R1, R2&gt; R;
2397    R r;
2398    r.set(x.get() - y.get());
2399    return r;
2400}
2401
2402<font color="#c80000">// Example type-safe physics function</font>
2403Distance
2404compute_distance(Speed v0, Time t, Acceleration a)
2405{
2406    return v0 * t + Scalar(.5) * a * t * t;  <font color="#c80000">// if a units mistake is made here it won't compile</font>
2407}
2408
2409} <font color="#c80000">// User1</font>
2410
2411#include &lt;iostream&gt;
2412
2413<font color="#c80000">// Exercise example type-safe physics function and show interoperation</font>
2414<font color="#c80000">// of custom time durations (User1::seconds) and standard time durations (std::hours).</font>
2415<font color="#c80000">// Though input can be arbitrary (but type-safe) units, output is always in SI-units</font>
2416<font color="#c80000">//   (a limitation of the simplified Units lib demoed here).</font>
2417void testUser1()
2418{
2419    std::cout &lt;&lt; "*************\n";
2420    std::cout &lt;&lt; "* testUser1 *\n";
2421    std::cout &lt;&lt; "*************\n";
2422    User1::Distance d( User1::mile(110) );
2423    User1::Time t( std::datetime::hours(2) );
2424    User1::Speed s = d / t;
2425    std::cout &lt;&lt; "Speed = " &lt;&lt; s.get() &lt;&lt; " meters/sec\n";
2426    User1::Acceleration a = User1::Distance( User1::foot(32.2) ) / User1::Time() / User1::Time();
2427    std::cout &lt;&lt; "Acceleration = " &lt;&lt; a.get() &lt;&lt; " meters/sec^2\n";
2428    User1::Distance df = compute_distance(s, User1::Time( User1::seconds(0.5) ), a);
2429    std::cout &lt;&lt; "Distance = " &lt;&lt; df.get() &lt;&lt; " meters\n";
2430    std::cout &lt;&lt; "There are " &lt;&lt; User1::mile::ratio::den &lt;&lt; '/' &lt;&lt; User1::mile::ratio::num &lt;&lt; " miles/meter";
2431    User1::meter mt = 1;
2432    User1::mile mi = mt;
2433    std::cout &lt;&lt; " which is approximately " &lt;&lt; mi.count() &lt;&lt; '\n';
2434    std::cout &lt;&lt; "There are " &lt;&lt; User1::mile::ratio::num &lt;&lt; '/' &lt;&lt; User1::mile::ratio::den &lt;&lt; " meters/mile";
2435    mi = 1;
2436    mt = mi;
2437    std::cout &lt;&lt; " which is approximately " &lt;&lt; mt.count() &lt;&lt; '\n';
2438    User1::attosecond as(1);
2439    User1::seconds sec = as;
2440    std::cout &lt;&lt; "1 attosecond is " &lt;&lt; sec.count() &lt;&lt; " seconds\n";
2441    std::cout &lt;&lt; "sec = as;  <font color="#c80000">// compiles\n";</font>
2442    sec = User1::seconds(1);
2443    as = sec;
2444    std::cout &lt;&lt; "1 second is " &lt;&lt; as.count() &lt;&lt; " attoseconds\n";
2445    std::cout &lt;&lt; "as = sec;  <font color="#c80000">// compiles\n";</font>
2446    std::cout &lt;&lt; "\n";
2447}
2448
2449<font color="#c80000">//////////////////////////////////////////////////////////</font>
2450<font color="#c80000">//////////////////// User2 Example ///////////////////////</font>
2451<font color="#c80000">//////////////////////////////////////////////////////////</font>
2452
2453<font color="#c80000">// Demonstrate User2:</font>
2454<font color="#c80000">// A "saturating" signed integral type  is developed.  This type has +/- infinity and a nan</font>
2455<font color="#c80000">// (like IEEE floating point) but otherwise obeys signed integral arithmetic.</font>
2456<font color="#c80000">// This class is subsequently used as the rep in std::datetime::duration to demonstrate a</font>
2457<font color="#c80000">// duration class that does not silently ignore overflow.</font>
2458#include &lt;ostream&gt;
2459#include &lt;stdexcept&gt;
2460#include &lt;climits&gt;
2461
2462namespace User2
2463{
2464
2465template &lt;class I&gt;
2466class saturate
2467{
2468public:
2469    typedef I int_type;
2470
2471    static const int_type nan = int_type(int_type(1) &lt;&lt; (sizeof(int_type) * CHAR_BIT - 1));
2472    static const int_type neg_inf = nan + 1;
2473    static const int_type pos_inf = -neg_inf;
2474private:
2475    int_type i_;
2476
2477<font color="#c80000">//     static_assert(std::is_integral&lt;int_type&gt;::value &amp;&amp; std::is_signed&lt;int_type&gt;::value,</font>
2478<font color="#c80000">//                   "saturate only accepts signed integral types");</font>
2479<font color="#c80000">//     static_assert(nan == -nan &amp;&amp; neg_inf &lt; pos_inf,</font>
2480<font color="#c80000">//                   "saturate assumes two's complement hardware for signed integrals");</font>
2481
2482public:
2483    saturate() : i_(nan) {}
2484    explicit saturate(int_type i) : i_(i) {}
2485    <font color="#c80000">// explicit</font>
2486       operator int_type() const;
2487
2488    saturate&amp; operator+=(saturate x);
2489    saturate&amp; operator-=(saturate x) {return *this += -x;}
2490    saturate&amp; operator*=(saturate x);
2491    saturate&amp; operator/=(saturate x);
2492    saturate&amp; operator%=(saturate x);
2493
2494    saturate  operator- () const {return saturate(-i_);}
2495    saturate&amp; operator++()       {*this += saturate(int_type(1)); return *this;}
2496    saturate  operator++(int)    {saturate tmp(*this); ++(*this); return tmp;}
2497    saturate&amp; operator--()       {*this -= saturate(int_type(1)); return *this;}
2498    saturate  operator--(int)    {saturate tmp(*this); --(*this); return tmp;}
2499
2500    friend saturate operator+(saturate x, saturate y) {return x += y;}
2501    friend saturate operator-(saturate x, saturate y) {return x -= y;}
2502    friend saturate operator*(saturate x, saturate y) {return x *= y;}
2503    friend saturate operator/(saturate x, saturate y) {return x /= y;}
2504    friend saturate operator%(saturate x, saturate y) {return x %= y;}
2505
2506    friend bool operator==(saturate x, saturate y)
2507    {
2508        if (x.i_ == nan || y.i_ == nan)
2509            return false;
2510        return x.i_ == y.i_;
2511    }
2512
2513    friend bool operator!=(saturate x, saturate y) {return !(x == y);}
2514
2515    friend bool operator&lt;(saturate x, saturate y)
2516    {
2517        if (x.i_ == nan || y.i_ == nan)
2518            return false;
2519        return x.i_ &lt; y.i_;
2520    }
2521
2522    friend bool operator&lt;=(saturate x, saturate y)
2523    {
2524        if (x.i_ == nan || y.i_ == nan)
2525            return false;
2526        return x.i_ &lt;= y.i_;
2527    }
2528
2529    friend bool operator&gt;(saturate x, saturate y)
2530    {
2531        if (x.i_ == nan || y.i_ == nan)
2532            return false;
2533        return x.i_ &gt; y.i_;
2534    }
2535
2536    friend bool operator&gt;=(saturate x, saturate y)
2537    {
2538        if (x.i_ == nan || y.i_ == nan)
2539            return false;
2540        return x.i_ &gt;= y.i_;
2541    }
2542
2543    friend std::ostream&amp; operator&lt;&lt;(std::ostream&amp; os, saturate s)
2544    {
2545        switch (s.i_)
2546        {
2547        case pos_inf:
2548            return os &lt;&lt; "inf";
2549        case nan:
2550            return os &lt;&lt; "nan";
2551        case neg_inf:
2552            return os &lt;&lt; "-inf";
2553        };
2554        return os &lt;&lt; s.i_;
2555    }
2556};
2557
2558template &lt;class I&gt;
2559saturate&lt;I&gt;::operator int_type() const
2560{
2561    switch (i_)
2562    {
2563    case nan:
2564    case neg_inf:
2565    case pos_inf:
2566        throw std::out_of_range("saturate special value can not convert to int_type");
2567    }
2568    return i_;
2569}
2570
2571template &lt;class I&gt;
2572saturate&lt;I&gt;&amp;
2573saturate&lt;I&gt;::operator+=(saturate x)
2574{
2575    switch (i_)
2576    {
2577    case pos_inf:
2578        switch (x.i_)
2579        {
2580        case neg_inf:
2581        case nan:
2582            i_ = nan;
2583        }
2584        return *this;
2585    case nan:
2586        return *this;
2587    case neg_inf:
2588        switch (x.i_)
2589        {
2590        case pos_inf:
2591        case nan:
2592            i_ = nan;
2593        }
2594        return *this;
2595    }
2596    switch (x.i_)
2597    {
2598    case pos_inf:
2599    case neg_inf:
2600    case nan:
2601        i_ = x.i_;
2602        return *this;
2603    }
2604    if (x.i_ &gt;= 0)
2605    {
2606        if (i_ &lt; pos_inf - x.i_)
2607            i_ += x.i_;
2608        else
2609            i_ = pos_inf;
2610        return *this;
2611    }
2612    if (i_ &gt; neg_inf - x.i_)
2613        i_ += x.i_;
2614    else
2615        i_ = neg_inf;
2616    return *this;
2617}
2618
2619template &lt;class I&gt;
2620saturate&lt;I&gt;&amp;
2621saturate&lt;I&gt;::operator*=(saturate x)
2622{
2623    switch (i_)
2624    {
2625    case 0:
2626        switch (x.i_)
2627        {
2628        case pos_inf:
2629        case neg_inf:
2630        case nan:
2631            i_ = nan;
2632        }
2633        return *this;
2634    case pos_inf:
2635        switch (x.i_)
2636        {
2637        case nan:
2638        case 0:
2639            i_ = nan;
2640            return *this;
2641        }
2642        if (x.i_ &lt; 0)
2643            i_ = neg_inf;
2644        return *this;
2645    case nan:
2646        return *this;
2647    case neg_inf:
2648        switch (x.i_)
2649        {
2650        case nan:
2651        case 0:
2652            i_ = nan;
2653            return *this;
2654        }
2655        if (x.i_ &lt; 0)
2656            i_ = pos_inf;
2657        return *this;
2658    }
2659    switch (x.i_)
2660    {
2661    case 0:
2662        i_ = 0;
2663        return *this;
2664    case nan:
2665        i_ = nan;
2666        return *this;
2667    case pos_inf:
2668        if (i_ &lt; 0)
2669            i_ = neg_inf;
2670        else
2671            i_ = pos_inf;
2672        return *this;
2673    case neg_inf:
2674        if (i_ &lt; 0)
2675            i_ = pos_inf;
2676        else
2677            i_ = neg_inf;
2678        return *this;
2679    }
2680    int s = (i_ &lt; 0 ? -1 : 1) * (x.i_ &lt; 0 ? -1 : 1);
2681    i_ = i_ &lt; 0 ? -i_ : i_;
2682    int_type x_i_ = x.i_ &lt; 0 ? -x.i_ : x.i_;
2683    if (i_ &lt;= pos_inf / x_i_)
2684        i_ *= x_i_;
2685    else
2686        i_ = pos_inf;
2687    i_ *= s;
2688    return *this;
2689}
2690
2691template &lt;class I&gt;
2692saturate&lt;I&gt;&amp;
2693saturate&lt;I&gt;::operator/=(saturate x)
2694{
2695    switch (x.i_)
2696    {
2697    case pos_inf:
2698    case neg_inf:
2699        switch (i_)
2700        {
2701        case pos_inf:
2702        case neg_inf:
2703        case nan:
2704            i_ = nan;
2705            break;
2706        default:
2707            i_ = 0;
2708            break;
2709        }
2710        return *this;
2711    case nan:
2712        i_ = nan;
2713        return *this;
2714    case 0:
2715        switch (i_)
2716        {
2717        case pos_inf:
2718        case neg_inf:
2719        case nan:
2720            return *this;
2721        case 0:
2722            i_ = nan;
2723            return *this;
2724        }
2725        if (i_ &gt; 0)
2726            i_ = pos_inf;
2727        else
2728            i_ = neg_inf;
2729        return *this;
2730    }
2731    switch (i_)
2732    {
2733    case 0:
2734    case nan:
2735        return *this;
2736    case pos_inf:
2737    case neg_inf:
2738        if (x.i_ &lt; 0)
2739            i_ = -i_;
2740        return *this;
2741    }
2742    i_ /= x.i_;
2743    return *this;
2744}
2745
2746template &lt;class I&gt;
2747saturate&lt;I&gt;&amp;
2748saturate&lt;I&gt;::operator%=(saturate x)
2749{
2750<font color="#c80000">//    *this -= *this / x * x;  // definition</font>
2751    switch (x.i_)
2752    {
2753    case nan:
2754    case neg_inf:
2755    case 0:
2756    case pos_inf:
2757        i_ = nan;
2758        return *this;
2759    }
2760    switch (i_)
2761    {
2762    case neg_inf:
2763    case pos_inf:
2764        i_ = nan;
2765    case nan:
2766        return *this;
2767    }
2768    i_ %= x.i_;
2769    return *this;
2770}
2771
2772<font color="#c80000">// Demo overflow-safe integral durations ranging from picoseconds resolution to millennium resolution</font>
2773typedef std::datetime::duration&lt;saturate&lt;long long&gt;, std::pico                 &gt; picoseconds;
2774typedef std::datetime::duration&lt;saturate&lt;long long&gt;, std::nano                 &gt; nanoseconds;
2775typedef std::datetime::duration&lt;saturate&lt;long long&gt;, std::micro                &gt; microseconds;
2776typedef std::datetime::duration&lt;saturate&lt;long long&gt;, std::milli                &gt; milliseconds;
2777typedef std::datetime::duration&lt;saturate&lt;long long&gt;                            &gt; seconds;
2778typedef std::datetime::duration&lt;saturate&lt;long long&gt;, std::ratio&lt;         60LL&gt; &gt; minutes;
2779typedef std::datetime::duration&lt;saturate&lt;long long&gt;, std::ratio&lt;       3600LL&gt; &gt; hours;
2780typedef std::datetime::duration&lt;saturate&lt;long long&gt;, std::ratio&lt;      86400LL&gt; &gt; days;
2781typedef std::datetime::duration&lt;saturate&lt;long long&gt;, std::ratio&lt;   31556952LL&gt; &gt; years;
2782typedef std::datetime::duration&lt;saturate&lt;long long&gt;, std::ratio&lt;31556952000LL&gt; &gt; millennium;
2783
2784}  <font color="#c80000">// User2</font>
2785
2786<font color="#c80000">// Demonstrate custom promotion rules (needed only if there are no implicit conversions)</font>
2787namespace User2 { namespace detail {
2788
2789template &lt;class T1, class T2, bool = tmp::is_integral&lt;T1&gt;::value&gt;
2790struct promote_helper;
2791
2792template &lt;class T1, class T2&gt;
2793struct promote_helper&lt;T1, saturate&lt;T2&gt;, true&gt;  <font color="#c80000">// integral</font>
2794{
2795    typedef typename std::common_type&lt;T1, T2&gt;::type rep;
2796    typedef User2::saturate&lt;rep&gt; type;
2797};
2798
2799template &lt;class T1, class T2&gt;
2800struct promote_helper&lt;T1, saturate&lt;T2&gt;, false&gt;  <font color="#c80000">// floating</font>
2801{
2802    typedef T1 type;
2803};
2804
2805} }
2806
2807namespace std
2808{
2809
2810template &lt;class T1, class T2&gt;
2811struct common_type&lt;User2::saturate&lt;T1&gt;, User2::saturate&lt;T2&gt; &gt;
2812{
2813    typedef typename common_type&lt;T1, T2&gt;::type rep;
2814    typedef User2::saturate&lt;rep&gt; type;
2815};
2816
2817template &lt;class T1, class T2&gt;
2818struct common_type&lt;T1, User2::saturate&lt;T2&gt; &gt;
2819    : User2::detail::promote_helper&lt;T1, User2::saturate&lt;T2&gt; &gt; {};
2820
2821template &lt;class T1, class T2&gt;
2822struct common_type&lt;User2::saturate&lt;T1&gt;, T2&gt;
2823    : User2::detail::promote_helper&lt;T2, User2::saturate&lt;T1&gt; &gt; {};
2824
2825
2826<font color="#c80000">// Demonstrate specialization of duration_values:</font>
2827
2828namespace datetime {
2829
2830template &lt;class I&gt;
2831struct duration_values&lt;User2::saturate&lt;I&gt; &gt;
2832{
2833    typedef User2::saturate&lt;I&gt; Rep;
2834public:
2835    static Rep zero() {return Rep(0);}
2836    static Rep max()  {return Rep(Rep::pos_inf-1);}
2837    static Rep min()  {return -max();}
2838};
2839
2840}
2841
2842}
2843
2844#include &lt;iostream&gt;
2845
2846void testUser2()
2847{
2848    std::cout &lt;&lt; "*************\n";
2849    std::cout &lt;&lt; "* testUser2 *\n";
2850    std::cout &lt;&lt; "*************\n";
2851    using namespace User2;
2852    typedef seconds::rep sat;
2853    years yr(sat(100));
2854    std::cout &lt;&lt; "100 years expressed as years = " &lt;&lt; yr.count() &lt;&lt; '\n';
2855    nanoseconds ns = yr;
2856    std::cout &lt;&lt; "100 years expressed as nanoseconds = " &lt;&lt; ns.count() &lt;&lt; '\n';
2857    ns += yr;
2858    std::cout &lt;&lt; "200 years expressed as nanoseconds = " &lt;&lt; ns.count() &lt;&lt; '\n';
2859    ns += yr;
2860    std::cout &lt;&lt; "300 years expressed as nanoseconds = " &lt;&lt; ns.count() &lt;&lt; '\n';
2861<font color="#c80000">//    yr = ns;  // does not compile</font>
2862    std::cout &lt;&lt; "yr = ns;  <font color="#c80000">// does not compile\n";</font>
2863<font color="#c80000">//    picoseconds ps1 = yr;  // does not compile, compile-time overflow in ratio arithmetic</font>
2864    std::cout &lt;&lt; "ps = yr;  <font color="#c80000">// does not compile\n";</font>
2865    ns = yr;
2866    picoseconds ps = ns;
2867    std::cout &lt;&lt; "100 years expressed as picoseconds = " &lt;&lt; ps.count() &lt;&lt; '\n';
2868    ps = ns / sat(1000);
2869    std::cout &lt;&lt; "0.1 years expressed as picoseconds = " &lt;&lt; ps.count() &lt;&lt; '\n';
2870    yr = years(sat(-200000000));
2871    std::cout &lt;&lt; "200 million years ago encoded in years: " &lt;&lt; yr.count() &lt;&lt; '\n';
2872    days d = std::datetime::duration_cast&lt;days&gt;(yr);
2873    std::cout &lt;&lt; "200 million years ago encoded in days: " &lt;&lt; d.count() &lt;&lt; '\n';
2874    millennium c = std::datetime::duration_cast&lt;millennium&gt;(yr);
2875    std::cout &lt;&lt; "200 million years ago encoded in millennium: " &lt;&lt; c.count() &lt;&lt; '\n';
2876    std::cout &lt;&lt; "Demonstrate \"uninitialized protection\" behavior:\n";
2877    seconds sec;
2878    for (++sec; sec &lt; seconds(sat(10)); ++sec)
2879        ;
2880    std::cout &lt;&lt; sec.count() &lt;&lt; '\n';
2881    std::cout &lt;&lt; "\n";
2882}
2883
2884void testStdUser()
2885{
2886    std::cout &lt;&lt; "***************\n";
2887    std::cout &lt;&lt; "* testStdUser *\n";
2888    std::cout &lt;&lt; "***************\n";
2889    using namespace std::datetime;
2890    hours hr = hours(100);
2891    std::cout &lt;&lt; "100 hours expressed as hours = " &lt;&lt; hr.count() &lt;&lt; '\n';
2892    nanoseconds ns = hr;
2893    std::cout &lt;&lt; "100 hours expressed as nanoseconds = " &lt;&lt; ns.count() &lt;&lt; '\n';
2894    ns += hr;
2895    std::cout &lt;&lt; "200 hours expressed as nanoseconds = " &lt;&lt; ns.count() &lt;&lt; '\n';
2896    ns += hr;
2897    std::cout &lt;&lt; "300 hours expressed as nanoseconds = " &lt;&lt; ns.count() &lt;&lt; '\n';
2898<font color="#c80000">//    hr = ns;  // does not compile</font>
2899    std::cout &lt;&lt; "hr = ns;  <font color="#c80000">// does not compile\n";</font>
2900<font color="#c80000">//    hr * ns;  // does not compile</font>
2901    std::cout &lt;&lt; "hr * ns;  <font color="#c80000">// does not compile\n";</font>
2902    duration&lt;double&gt; fs(2.5);
2903    std::cout &lt;&lt; "duration&lt;double&gt; has count() = " &lt;&lt; fs.count() &lt;&lt; '\n';
2904<font color="#c80000">//    seconds sec = fs;  // does not compile</font>
2905    std::cout &lt;&lt; "seconds sec = duration&lt;double&gt; won't compile\n";
2906    seconds sec = duration_cast&lt;seconds&gt;(fs);
2907    std::cout &lt;&lt; "seconds has count() = " &lt;&lt; sec.count() &lt;&lt; '\n';
2908    std::cout &lt;&lt; "\n";
2909}
2910
2911<font color="#c80000">//  timeval clock demo</font>
2912<font color="#c80000">//     Demonstrate the use of a timeval-like struct to be used as the representation</font>
2913<font color="#c80000">//     type for both duraiton and time_point.</font>
2914
2915namespace timeval_demo
2916{
2917
2918class xtime {
2919private:
2920    long tv_sec;
2921    long tv_usec;
2922
2923    void fixup() {
2924        if (tv_usec &lt; 0) {
2925            tv_usec += 1000000;
2926            --tv_sec;
2927        }
2928    }
2929
2930public:
2931
2932    explicit xtime(long sec, long usec) {
2933        tv_sec = sec;
2934        tv_usec = usec;
2935        if (tv_usec &lt; 0 || tv_usec &gt;= 1000000) {
2936            tv_sec += tv_usec / 1000000;
2937            tv_usec %= 1000000;
2938            fixup();
2939        }
2940    }
2941
2942    explicit xtime(long long usec)
2943    {
2944        tv_usec = static_cast&lt;long&gt;(usec % 1000000);
2945        tv_sec  = static_cast&lt;long&gt;(usec / 1000000);
2946        fixup();
2947    }
2948
2949    <font color="#c80000">// explicit</font>
2950    operator long long() const {return static_cast&lt;long long&gt;(tv_sec) * 1000000 + tv_usec;}
2951
2952    xtime&amp; operator += (xtime rhs) {
2953        tv_sec += rhs.tv_sec;
2954        tv_usec += rhs.tv_usec;
2955        if (tv_usec &gt;= 1000000) {
2956            tv_usec -= 1000000;
2957            ++tv_sec;
2958        }
2959        return *this;
2960    }
2961
2962    xtime&amp; operator -= (xtime rhs) {
2963        tv_sec -= rhs.tv_sec;
2964        tv_usec -= rhs.tv_usec;
2965        fixup();
2966        return *this;
2967    }
2968
2969    xtime&amp; operator %= (xtime rhs) {
2970        long long t = tv_sec * 1000000 + tv_usec;
2971        long long r = rhs.tv_sec * 1000000 + rhs.tv_usec;
2972        t %= r;
2973        tv_sec = t / 1000000;
2974        tv_usec = t % 1000000;
2975        fixup();
2976        return *this;
2977    }
2978
2979    friend xtime operator+(xtime x, xtime y) {return x += y;}
2980    friend xtime operator-(xtime x, xtime y) {return x -= y;}
2981    friend xtime operator%(xtime x, xtime y) {return x %= y;}
2982
2983    friend bool operator==(xtime x, xtime y)
2984        { return (x.tv_sec == y.tv_sec &amp;&amp; x.tv_usec == y.tv_usec); }
2985
2986    friend bool operator&lt;(xtime x, xtime y) {
2987        if (x.tv_sec == y.tv_sec)
2988            return (x.tv_usec &lt; y.tv_usec);
2989        return (x.tv_sec &lt; y.tv_sec);
2990    }
2991
2992    friend bool operator!=(xtime x, xtime y) { return !(x == y); }
2993    friend bool operator&gt; (xtime x, xtime y) { return y &lt; x; }
2994    friend bool operator&lt;=(xtime x, xtime y) { return !(y &lt; x); }
2995    friend bool operator&gt;=(xtime x, xtime y) { return !(x &lt; y); }
2996
2997    friend std::ostream&amp; operator&lt;&lt;(std::ostream&amp; os, xtime x)
2998        {return os &lt;&lt; '{' &lt;&lt; x.tv_sec &lt;&lt; ',' &lt;&lt; x.tv_usec &lt;&lt; '}';}
2999};
3000
3001class xtime_clock
3002{
3003public:
3004    typedef xtime                                  rep;
3005    typedef std::micro                             period;
3006    typedef std::datetime::duration&lt;rep, period&gt;   duration;
3007    typedef std::datetime::time_point&lt;xtime_clock&gt; time_point;
3008
3009    static time_point now();
3010};
3011
3012xtime_clock::time_point
3013xtime_clock::now()
3014{
3015    time_point t(duration(xtime(0)));
3016    gettimeofday((timeval*)&amp;t, 0);
3017    return t;
3018}
3019
3020void test_xtime_clock()
3021{
3022    using namespace std::datetime;
3023    std::cout &lt;&lt; "timeval_demo system clock test\n";
3024    std::cout &lt;&lt; "sizeof xtime_clock::time_point = " &lt;&lt; sizeof(xtime_clock::time_point) &lt;&lt; '\n';
3025    std::cout &lt;&lt; "sizeof xtime_clock::duration = " &lt;&lt; sizeof(xtime_clock::duration) &lt;&lt; '\n';
3026    std::cout &lt;&lt; "sizeof xtime_clock::rep = " &lt;&lt; sizeof(xtime_clock::rep) &lt;&lt; '\n';
3027    xtime_clock::duration delay(milliseconds(5));
3028    xtime_clock::time_point start = xtime_clock::now();
3029    while (xtime_clock::now() - start &lt;= delay)
3030        ;
3031    xtime_clock::time_point stop = xtime_clock::now();
3032    xtime_clock::duration elapsed = stop - start;
3033    std::cout &lt;&lt; "paused " &lt;&lt; nanoseconds(elapsed).count() &lt;&lt; " nanoseconds\n";
3034}
3035
3036}  <font color="#c80000">// timeval_demo</font>
3037
3038<font color="#c80000">// Handle duration with resolution not known until run time</font>
3039
3040namespace runtime_resolution
3041{
3042
3043class duration
3044{
3045public:
3046    typedef long long rep;
3047private:
3048    rep rep_;
3049
3050    static const double ticks_per_nanosecond;
3051
3052public:
3053    typedef std::datetime::duration&lt;double, std::nano&gt; tonanosec;
3054
3055    duration() {} <font color="#c80000">// = default;</font>
3056    explicit duration(const rep&amp; r) : rep_(r) {}
3057
3058    <font color="#c80000">// conversions</font>
3059    explicit duration(const tonanosec&amp; d)
3060            : rep_(static_cast&lt;rep&gt;(d.count() * ticks_per_nanosecond)) {}
3061
3062    <font color="#c80000">// explicit</font>
3063       operator tonanosec() const {return tonanosec(rep_/ticks_per_nanosecond);}
3064
3065    <font color="#c80000">// observer</font>
3066
3067    rep count() const {return rep_;}
3068
3069    <font color="#c80000">// arithmetic</font>
3070
3071    duration&amp; operator+=(const duration&amp; d) {rep_ += d.rep_; return *this;}
3072    duration&amp; operator-=(const duration&amp; d) {rep_ += d.rep_; return *this;}
3073    duration&amp; operator*=(rep rhs)           {rep_ *= rhs; return *this;}
3074    duration&amp; operator/=(rep rhs)           {rep_ /= rhs; return *this;}
3075
3076    duration  operator+() const {return *this;}
3077    duration  operator-() const {return duration(-rep_);}
3078    duration&amp; operator++()      {++rep_; return *this;}
3079    duration  operator++(int)   {return duration(rep_++);}
3080    duration&amp; operator--()      {--rep_; return *this;}
3081    duration  operator--(int)   {return duration(rep_--);}
3082
3083    friend duration operator+(duration x, duration y) {return x += y;}
3084    friend duration operator-(duration x, duration y) {return x -= y;}
3085    friend duration operator*(duration x, rep y)      {return x *= y;}
3086    friend duration operator*(rep x, duration y)      {return y *= x;}
3087    friend duration operator/(duration x, rep y)      {return x /= y;}
3088
3089    friend bool operator==(duration x, duration y) {return x.rep_ == y.rep_;}
3090    friend bool operator!=(duration x, duration y) {return !(x == y);}
3091    friend bool operator&lt; (duration x, duration y) {return x.rep_ &lt; y.rep_;}
3092    friend bool operator&lt;=(duration x, duration y) {return !(y &lt; x);}
3093    friend bool operator&gt; (duration x, duration y) {return y &lt; x;}
3094    friend bool operator&gt;=(duration x, duration y) {return !(x &lt; y);}
3095};
3096
3097static
3098double
3099init_duration()
3100{
3101    mach_timebase_info_data_t MachInfo;
3102    mach_timebase_info(&amp;MachInfo);
3103    return static_cast&lt;double&gt;(MachInfo.denom) / MachInfo.numer;
3104}
3105
3106const double duration::ticks_per_nanosecond = init_duration();
3107
3108class clock;
3109
3110class time_point
3111{
3112public:
3113    typedef runtime_resolution::clock clock;
3114    typedef long long rep;
3115private:
3116    rep rep_;
3117
3118
3119    rep count() const {return rep_;}
3120public:
3121
3122    time_point() : rep_(0) {}
3123    explicit time_point(const duration&amp; d)
3124        : rep_(d.count()) {}
3125
3126    <font color="#c80000">// arithmetic</font>
3127
3128    time_point&amp; operator+=(const duration&amp; d) {rep_ += d.count(); return *this;}
3129    time_point&amp; operator-=(const duration&amp; d) {rep_ -= d.count(); return *this;}
3130
3131    friend time_point operator+(time_point x, duration y) {return x += y;}
3132    friend time_point operator+(duration x, time_point y) {return y += x;}
3133    friend time_point operator-(time_point x, duration y) {return x -= y;}
3134    friend duration operator-(time_point x, time_point y) {return duration(x.rep_ - y.rep_);}
3135};
3136
3137class clock
3138{
3139public:
3140    typedef duration::rep rep;
3141    typedef runtime_resolution::duration duration;
3142    typedef runtime_resolution::time_point time_point;
3143
3144    static time_point now() {return time_point(duration(mach_absolute_time()));}
3145};
3146
3147void test()
3148{
3149    using namespace std::datetime;
3150    std::cout &lt;&lt; "runtime_resolution test\n";
3151    clock::duration delay(std::datetime::milliseconds(5));
3152    clock::time_point start = clock::now();
3153    while (clock::now() - start &lt;= delay)
3154      ;
3155    clock::time_point stop = clock::now();
3156    clock::duration elapsed = stop - start;
3157    std::cout &lt;&lt; "paused " &lt;&lt; nanoseconds(duration_cast&lt;nanoseconds&gt;(duration::tonanosec(elapsed))).count()
3158                           &lt;&lt; " nanoseconds\n";
3159}
3160
3161}  <font color="#c80000">// runtime_resolution</font>
3162
3163<font color="#c80000">// miscellaneous tests and demos:</font>
3164
3165#include &lt;cassert&gt;
3166#include &lt;iostream&gt;
3167
3168using namespace std::datetime;
3169
3170void physics_function(duration&lt;double&gt; d)
3171{
3172    std::cout &lt;&lt; "d = " &lt;&lt; d.count() &lt;&lt; '\n';
3173}
3174
3175void drive_physics_function()
3176{
3177    physics_function(nanoseconds(3));
3178    physics_function(hours(3));
3179    physics_function(duration&lt;double&gt;(2./3));
3180    std::cout.precision(16);
3181    physics_function( hours(3) + nanoseconds(-3) );
3182}
3183
3184void test_range()
3185{
3186    using namespace std::datetime;
3187    hours h1 = hours(24 * ( 365 * 292 + 292/4));
3188    nanoseconds n1 = h1 + nanoseconds(1);
3189    nanoseconds delta = n1 - h1;
3190    std::cout &lt;&lt; "292 years of hours = " &lt;&lt; h1.count() &lt;&lt; "hr\n";
3191    std::cout &lt;&lt; "Add a nanosecond = " &lt;&lt; n1.count() &lt;&lt; "ns\n";
3192    std::cout &lt;&lt; "Find the difference = " &lt;&lt; delta.count() &lt;&lt; "ns\n";
3193}
3194
3195void test_extended_range()
3196{
3197    using namespace std::datetime;
3198    hours h1 = hours(24 * ( 365 * 244000 + 244000/4));
3199    <font color="#c80000">/*auto*/</font> microseconds u1 = h1 + microseconds(1);
3200    <font color="#c80000">/*auto*/</font> microseconds delta = u1 - h1;
3201    std::cout &lt;&lt; "244,000 years of hours = " &lt;&lt; h1.count() &lt;&lt; "hr\n";
3202    std::cout &lt;&lt; "Add a microsecond = " &lt;&lt; u1.count() &lt;&lt; "us\n";
3203    std::cout &lt;&lt; "Find the difference = " &lt;&lt; delta.count() &lt;&lt; "us\n";
3204}
3205
3206template &lt;class Rep, class Period&gt;
3207void inspect_duration(std::datetime::duration&lt;Rep, Period&gt; d, const std::string&amp; name)
3208{
3209    typedef std::datetime::duration&lt;Rep, Period&gt; Duration;
3210    std::cout &lt;&lt; "********* " &lt;&lt; name &lt;&lt; " *********\n";
3211    std::cout &lt;&lt; "The period of " &lt;&lt; name &lt;&lt; " is " &lt;&lt; (double)Period::num/Period::den &lt;&lt; " seconds.\n";
3212    std::cout &lt;&lt; "The frequency of " &lt;&lt; name &lt;&lt; " is " &lt;&lt; (double)Period::den/Period::num &lt;&lt; " Hz.\n";
3213    std::cout &lt;&lt; "The representation is ";
3214    if (tmp::is_floating_point&lt;Rep&gt;::value)
3215    {
3216        std::cout &lt;&lt; "floating point\n";
3217        std::cout &lt;&lt; "The precision is the most significant ";
3218        std::cout &lt;&lt; std::numeric_limits&lt;Rep&gt;::digits10 &lt;&lt; " decimal digits.\n";
3219    }
3220    else if (tmp::is_integral&lt;Rep&gt;::value)
3221    {
3222        std::cout &lt;&lt; "integral\n";
3223        d = Duration(Rep(1));
3224        std::datetime::duration&lt;double&gt; dsec = d;
3225        std::cout &lt;&lt; "The precision is " &lt;&lt; dsec.count() &lt;&lt; " seconds.\n";
3226    }
3227    else
3228    {
3229        std::cout &lt;&lt; "a class type\n";
3230        d = Duration(Rep(1));
3231        std::datetime::duration&lt;double&gt; dsec = d;
3232        std::cout &lt;&lt; "The precision is " &lt;&lt; dsec.count() &lt;&lt; " seconds.\n";
3233    }
3234    d = Duration(std::numeric_limits&lt;Rep&gt;::max());
3235    using namespace std::datetime;
3236    using namespace std;
3237    typedef duration&lt;double, ratio_multiply&lt;ratio&lt;24*3652425,10000&gt;, hours::period&gt;::type&gt; Years;
3238    Years years = d;
3239    std::cout &lt;&lt; "The range is +/- " &lt;&lt; years.count() &lt;&lt; " years.\n";
3240    std::cout &lt;&lt; "sizeof(" &lt;&lt; name &lt;&lt; ") = " &lt;&lt; sizeof(d) &lt;&lt; '\n';
3241}
3242
3243void inspect_all()
3244{
3245    using namespace std::datetime;
3246    std::cout.precision(6);
3247    inspect_duration(nanoseconds(), "nanoseconds");
3248    inspect_duration(microseconds(), "microseconds");
3249    inspect_duration(milliseconds(), "milliseconds");
3250    inspect_duration(seconds(), "seconds");
3251    inspect_duration(minutes(), "minutes");
3252    inspect_duration(hours(), "hours");
3253    inspect_duration(duration&lt;double&gt;(), "duration&lt;double&gt;");
3254}
3255
3256void test_milliseconds()
3257{
3258    using namespace std::datetime;
3259    milliseconds ms(250);
3260    ms += milliseconds(1);
3261    milliseconds ms2(150);
3262    milliseconds msdiff = ms - ms2;
3263    if (msdiff == milliseconds(101))
3264        std::cout &lt;&lt; "success\n";
3265    else
3266        std::cout &lt;&lt; "failure: " &lt;&lt; msdiff.count() &lt;&lt; '\n';
3267}
3268
3269    using namespace std;
3270    using namespace std::datetime;
3271
3272<font color="#c80000">// Example round_up utility:  converts d to To, rounding up for inexact conversions</font>
3273<font color="#c80000">//   Being able to *easily* write this function is a major feature!</font>
3274template &lt;class To, class Rep, class Period&gt;
3275To
3276round_up(duration&lt;Rep, Period&gt; d)
3277{
3278    To result = duration_cast&lt;To&gt;(d);
3279    if (result &lt; d)
3280        ++result;
3281    return result;
3282}
3283
3284<font color="#c80000">// demonstrate interaction with xtime-like facility:</font>
3285
3286using namespace std::datetime;
3287
3288struct xtime
3289{
3290    long sec;
3291    unsigned long usec;
3292};
3293
3294template &lt;class Rep, class Period&gt;
3295xtime
3296to_xtime_truncate(duration&lt;Rep, Period&gt; d)
3297{
3298    xtime xt;
3299    xt.sec = duration_cast&lt;seconds&gt;(d).count();
3300    xt.usec = duration_cast&lt;microseconds&gt;(d - seconds(xt.sec)).count();
3301    return xt;
3302}
3303
3304template &lt;class Rep, class Period&gt;
3305xtime
3306to_xtime_round_up(duration&lt;Rep, Period&gt; d)
3307{
3308    xtime xt;
3309    xt.sec = duration_cast&lt;seconds&gt;(d).count();
3310    xt.usec = round_up&lt;microseconds&gt;(d - seconds(xt.sec)).count();
3311    return xt;
3312}
3313
3314microseconds
3315from_xtime(xtime xt)
3316{
3317    return seconds(xt.sec) + microseconds(xt.usec);
3318}
3319
3320void print(xtime xt)
3321{
3322    cout &lt;&lt; '{' &lt;&lt; xt.sec &lt;&lt; ',' &lt;&lt; xt.usec &lt;&lt; "}\n";
3323}
3324
3325void test_with_xtime()
3326{
3327    cout &lt;&lt; "test_with_xtime\n";
3328    xtime xt = to_xtime_truncate(seconds(3) + milliseconds(251));
3329    print(xt);
3330    milliseconds ms = duration_cast&lt;milliseconds&gt;(from_xtime(xt));
3331    cout &lt;&lt; ms.count() &lt;&lt; " milliseconds\n";
3332    xt = to_xtime_round_up(ms);
3333    print(xt);
3334    xt = to_xtime_truncate(seconds(3) + nanoseconds(999));
3335    print(xt);
3336    xt = to_xtime_round_up(seconds(3) + nanoseconds(999));
3337    print(xt);
3338}
3339
3340void test_system_clock()
3341{
3342    cout &lt;&lt; "system_clock test" &lt;&lt; endl;
3343    system_clock::duration delay = milliseconds(5);
3344    system_clock::time_point start = system_clock::now();
3345    while (system_clock::now() - start &lt;= delay)
3346        ;
3347    system_clock::time_point stop = system_clock::now();
3348    system_clock::duration elapsed = stop - start;
3349    cout &lt;&lt; "paused " &lt;&lt; nanoseconds(elapsed).count() &lt;&lt; " nanoseconds\n";
3350    start = system_clock::now();
3351    stop = system_clock::now();
3352    cout &lt;&lt; "system_clock resolution estimate: " &lt;&lt; nanoseconds(stop-start).count() &lt;&lt; " nanoseconds\n";
3353}
3354
3355void test_monotonic_clock()
3356{
3357    cout &lt;&lt; "monotonic_clock test" &lt;&lt; endl;
3358    monotonic_clock::duration delay = milliseconds(5);
3359    monotonic_clock::time_point start = monotonic_clock::now();
3360    while (monotonic_clock::now() - start &lt;= delay)
3361        ;
3362    monotonic_clock::time_point stop = monotonic_clock::now();
3363    monotonic_clock::duration elapsed = stop - start;
3364    cout &lt;&lt; "paused " &lt;&lt; nanoseconds(elapsed).count() &lt;&lt; " nanoseconds\n";
3365    start = monotonic_clock::now();
3366    stop = monotonic_clock::now();
3367    cout &lt;&lt; "monotonic_clock resolution estimate: " &lt;&lt; nanoseconds(stop-start).count() &lt;&lt; " nanoseconds\n";
3368}
3369
3370void test_hi_resolution_clock()
3371{
3372    cout &lt;&lt; "high_resolution_clock test" &lt;&lt; endl;
3373    high_resolution_clock::duration delay = milliseconds(5);
3374    high_resolution_clock::time_point start = high_resolution_clock::now();
3375    while (high_resolution_clock::now() - start &lt;= delay)
3376      ;
3377    high_resolution_clock::time_point stop = high_resolution_clock::now();
3378    high_resolution_clock::duration elapsed = stop - start;
3379    cout &lt;&lt; "paused " &lt;&lt; nanoseconds(elapsed).count() &lt;&lt; " nanoseconds\n";
3380    start = high_resolution_clock::now();
3381    stop = high_resolution_clock::now();
3382    cout &lt;&lt; "high_resolution_clock resolution estimate: " &lt;&lt; nanoseconds(stop-start).count() &lt;&lt; " nanoseconds\n";
3383}
3384
3385void test_mixed_clock()
3386{
3387    cout &lt;&lt; "mixed clock test" &lt;&lt; endl;
3388    high_resolution_clock::time_point hstart = high_resolution_clock::now();
3389    cout &lt;&lt; "Add 5 milliseconds to a high_resolution_clock::time_point\n";
3390    monotonic_clock::time_point mend = hstart + milliseconds(5);
3391    bool b = hstart == mend;
3392    system_clock::time_point sstart = system_clock::now();
3393    std::cout &lt;&lt; "Subtracting system_clock::time_point from monotonic_clock::time_point doesn't compile\n";
3394<font color="#c80000">//  mend - sstart; // doesn't compile</font>
3395    cout &lt;&lt; "subtract high_resolution_clock::time_point from monotonic_clock::time_point"
3396            " and add that to a system_clock::time_point\n";
3397    system_clock::time_point send = sstart + duration_cast&lt;system_clock::duration&gt;(mend - hstart);
3398    cout &lt;&lt; "subtract two system_clock::time_point's and output that in microseconds:\n";
3399    microseconds ms = send - sstart;
3400    cout &lt;&lt; ms.count() &lt;&lt; " microseconds\n";
3401}
3402
3403void test_c_mapping()
3404{
3405    cout &lt;&lt; "C map test\n";
3406    using namespace std::datetime;
3407    system_clock::time_point t1 = system_clock::now();
3408    std::time_t c_time = system_clock::to_time_t(t1);
3409    std::tm* tmptr = std::localtime(&amp;c_time);
3410    std::cout &lt;&lt; "It is now " &lt;&lt; tmptr-&gt;tm_hour &lt;&lt; ':' &lt;&lt; tmptr-&gt;tm_min &lt;&lt; ':' &lt;&lt; tmptr-&gt;tm_sec &lt;&lt; ' '
3411              &lt;&lt; tmptr-&gt;tm_year + 1900 &lt;&lt; '-' &lt;&lt; tmptr-&gt;tm_mon + 1 &lt;&lt; '-' &lt;&lt; tmptr-&gt;tm_mday &lt;&lt; '\n';
3412    c_time = std::mktime(tmptr);
3413    system_clock::time_point t2 = system_clock::from_time_t(c_time);
3414    microseconds ms = t1 - t2;
3415    std::cout &lt;&lt; "Round-tripping through the C interface truncated the precision by " &lt;&lt; ms.count() &lt;&lt; " microseconds\n";
3416}
3417
3418void test_duration_division()
3419{
3420    cout &lt;&lt; hours(3) / milliseconds(5) &lt;&lt; '\n';
3421    cout &lt;&lt; milliseconds(5) / hours(3) &lt;&lt; '\n';
3422    cout &lt;&lt; hours(1) / milliseconds(1) &lt;&lt; '\n';
3423}
3424
3425namespace I_dont_like_the_default_duration_behavior
3426{
3427
3428<font color="#c80000">// Here's how you override the duration's default constructor to do anything you want (in this case zero)</font>
3429
3430template &lt;class R&gt;
3431class zero_default
3432{
3433public:
3434    typedef R rep;
3435
3436private:
3437    rep rep_;
3438public:
3439    zero_default(rep i = 0) : rep_(i) {}
3440    operator rep() const {return rep_;}
3441
3442    zero_default&amp; operator+=(zero_default x) {rep_ += x.rep_; return *this;}
3443    zero_default&amp; operator-=(zero_default x) {rep_ -= x.rep_; return *this;}
3444    zero_default&amp; operator*=(zero_default x) {rep_ *= x.rep_; return *this;}
3445    zero_default&amp; operator/=(zero_default x) {rep_ /= x.rep_; return *this;}
3446
3447    zero_default  operator+ () const {return *this;}
3448    zero_default  operator- () const {return zero_default(-rep_);}
3449    zero_default&amp; operator++()       {++rep_; return *this;}
3450    zero_default  operator++(int)    {return zero_default(rep_++);}
3451    zero_default&amp; operator--()       {--rep_; return *this;}
3452    zero_default  operator--(int)    {return zero_default(rep_--);}
3453
3454    friend zero_default operator+(zero_default x, zero_default y) {return x += y;}
3455    friend zero_default operator-(zero_default x, zero_default y) {return x -= y;}
3456    friend zero_default operator*(zero_default x, zero_default y) {return x *= y;}
3457    friend zero_default operator/(zero_default x, zero_default y) {return x /= y;}
3458
3459    friend bool operator==(zero_default x, zero_default y) {return x.rep_ == y.rep_;}
3460    friend bool operator!=(zero_default x, zero_default y) {return !(x == y);}
3461    friend bool operator&lt; (zero_default x, zero_default y) {return x.rep_ &lt; y.rep_;}
3462    friend bool operator&lt;=(zero_default x, zero_default y) {return !(y &lt; x);}
3463    friend bool operator&gt; (zero_default x, zero_default y) {return y &lt; x;}
3464    friend bool operator&gt;=(zero_default x, zero_default y) {return !(x &lt; y);}
3465};
3466
3467typedef std::datetime::duration&lt;zero_default&lt;long long&gt;, std::nano        &gt; nanoseconds;
3468typedef std::datetime::duration&lt;zero_default&lt;long long&gt;, std::micro       &gt; microseconds;
3469typedef std::datetime::duration&lt;zero_default&lt;long long&gt;, std::milli       &gt; milliseconds;
3470typedef std::datetime::duration&lt;zero_default&lt;long long&gt;                   &gt; seconds;
3471typedef std::datetime::duration&lt;zero_default&lt;long long&gt;, std::ratio&lt;60&gt;   &gt; minutes;
3472typedef std::datetime::duration&lt;zero_default&lt;long long&gt;, std::ratio&lt;3600&gt; &gt; hours;
3473
3474void test()
3475{
3476    milliseconds ms;
3477    cout &lt;&lt; ms.count() &lt;&lt; '\n';
3478}
3479
3480}  <font color="#c80000">// I_dont_like_the_default_duration_behavior</font>
3481
3482<font color="#c80000">// Build a min for two time_points</font>
3483
3484template &lt;class Rep, class Period&gt;
3485void
3486print_duration(ostream&amp; os, duration&lt;Rep, Period&gt; d)
3487{
3488    os &lt;&lt; d.count() &lt;&lt; " * " &lt;&lt; Period::num &lt;&lt; '/' &lt;&lt; Period::den &lt;&lt; " seconds\n";
3489}
3490
3491<font color="#c80000">// Example min utility:  returns the earliest time_point</font>
3492<font color="#c80000">//   Being able to *easily* write this function is a major feature!</font>
3493template &lt;class Clock, class Duration1, class Duration2&gt;
3494inline
3495typename common_type&lt;time_point&lt;Clock, Duration1&gt;, time_point&lt;Clock, Duration2&gt; &gt;::type
3496min(time_point&lt;Clock, Duration1&gt; t1, time_point&lt;Clock, Duration2&gt; t2)
3497{
3498    return t2 &lt; t1 ? t2 : t1;
3499}
3500
3501void test_min()
3502{
3503    typedef time_point&lt;system_clock, common_type&lt;system_clock::duration, seconds&gt;::type&gt; T1;
3504    typedef time_point&lt;system_clock, common_type&lt;system_clock::duration, nanoseconds&gt;::type&gt; T2;
3505    typedef common_type&lt;T1, T2&gt;::type T3;
3506    <font color="#c80000">/*auto*/</font> T1 t1 = system_clock::now() + seconds(3);
3507    <font color="#c80000">/*auto*/</font> T2 t2 = system_clock::now() + nanoseconds(3);
3508    <font color="#c80000">/*auto*/</font> T3 t3 = min(t1, t2);
3509    print_duration(cout, t1 - t3);
3510    print_duration(cout, t2 - t3);
3511}
3512
3513void explore_limits()
3514{
3515    typedef duration&lt;long long, ratio_multiply&lt;ratio&lt;24*3652425,10000&gt;, hours::period&gt;::type&gt; Years;
3516    monotonic_clock::time_point t1( Years(250));
3517    monotonic_clock::time_point t2(-Years(250));
3518    <font color="#c80000">// nanosecond resolution is likely to overflow.  "up cast" to microseconds.</font>
3519    <font color="#c80000">//   The "up cast" trades precision for range.</font>
3520    microseconds d = time_point_cast&lt;microseconds&gt;(t1) - time_point_cast&lt;microseconds&gt;(t2);
3521    cout &lt;&lt; d.count() &lt;&lt; " microseconds\n";
3522}
3523
3524void manipulate_clock_object(system_clock clock)
3525{
3526    system_clock::duration delay = milliseconds(5);
3527    system_clock::time_point start = clock.now();
3528    while (clock.now() - start &lt;= delay)
3529      ;
3530    system_clock::time_point stop = clock.now();
3531    system_clock::duration elapsed = stop - start;
3532    cout &lt;&lt; "paused " &lt;&lt; nanoseconds(elapsed).count() &lt;&lt; " nanoseconds\n";
3533};
3534
3535template &lt;long long speed&gt;
3536struct cycle_count
3537{
3538    typedef typename ratio_multiply&lt;ratio&lt;speed&gt;, mega&gt;::type frequency;  <font color="#c80000">// Mhz</font>
3539    typedef typename ratio_divide&lt;ratio&lt;1&gt;, frequency&gt;::type period;
3540    typedef long long rep;
3541    typedef std::datetime::duration&lt;rep, period&gt; duration;
3542    typedef std::datetime::time_point&lt;cycle_count&gt; time_point;
3543
3544    static time_point now()
3545    {
3546        static long long tick = 0;
3547        <font color="#c80000">// return exact cycle count</font>
3548        return time_point(duration(++tick));  <font color="#c80000">// fake access to clock cycle count</font>
3549    }
3550};
3551
3552template &lt;long long speed&gt;
3553struct approx_cycle_count
3554{
3555    static const long long frequency = speed * 1000000;  <font color="#c80000">// MHz</font>
3556    typedef nanoseconds duration;
3557    typedef duration::rep rep;
3558    typedef duration::period period;
3559    static const long long nanosec_per_sec = period::den;
3560    typedef std::datetime::time_point&lt;approx_cycle_count&gt; time_point;
3561
3562    static time_point now()
3563    {
3564        static long long tick = 0;
3565        <font color="#c80000">// return cycle count as an approximate number of nanoseconds</font>
3566        <font color="#c80000">// compute as if nanoseconds is only duration in the std::lib</font>
3567        return time_point(duration(++tick * nanosec_per_sec / frequency));
3568    }
3569};
3570
3571void cycle_count_delay()
3572{
3573    {
3574    typedef cycle_count&lt;400&gt; clock;
3575    cout &lt;&lt; "\nSimulated " &lt;&lt; clock::frequency::num / mega::num &lt;&lt; "MHz clock which has a tick period of "
3576         &lt;&lt; duration&lt;double, nano&gt;(clock::duration(1)).count() &lt;&lt; " nanoseconds\n";
3577    nanoseconds delayns(500);
3578    clock::duration delay = duration_cast&lt;clock::duration&gt;(delayns);
3579    cout &lt;&lt; "delay = " &lt;&lt; delayns.count() &lt;&lt; " nanoseconds which is " &lt;&lt; delay.count() &lt;&lt; " cycles\n";
3580    clock::time_point start = clock::now();
3581    clock::time_point stop = start + delay;
3582    while (clock::now() &lt; stop)  <font color="#c80000">// no multiplies or divides in this loop</font>
3583        ;
3584    clock::time_point end = clock::now();
3585    clock::duration elapsed = end - start;
3586    cout &lt;&lt; "paused " &lt;&lt; elapsed.count() &lt;&lt; " cycles ";
3587    cout &lt;&lt; "which is " &lt;&lt; duration_cast&lt;nanoseconds&gt;(elapsed).count() &lt;&lt; " nanoseconds\n";
3588    }
3589    {
3590    typedef approx_cycle_count&lt;400&gt; clock;
3591    cout &lt;&lt; "\nSimulated " &lt;&lt; clock::frequency / 1000000 &lt;&lt; "MHz clock modeled with nanoseconds\n";
3592    clock::duration delay = nanoseconds(500);
3593    cout &lt;&lt; "delay = " &lt;&lt; delay.count() &lt;&lt; " nanoseconds\n";
3594    clock::time_point start = clock::now();
3595    clock::time_point stop = start + delay;
3596    while (clock::now() &lt; stop) <font color="#c80000">// 1 multiplication and 1 division in this loop</font>
3597        ;
3598    clock::time_point end = clock::now();
3599    clock::duration elapsed = end - start;
3600    cout &lt;&lt; "paused " &lt;&lt; elapsed.count() &lt;&lt; " nanoseconds\n";
3601    }
3602    {
3603    typedef cycle_count&lt;1500&gt; clock;
3604    cout &lt;&lt; "\nSimulated " &lt;&lt; clock::frequency::num / mega::num &lt;&lt; "MHz clock which has a tick period of "
3605         &lt;&lt; duration&lt;double, nano&gt;(clock::duration(1)).count() &lt;&lt; " nanoseconds\n";
3606    nanoseconds delayns(500);
3607    clock::duration delay = duration_cast&lt;clock::duration&gt;(delayns);
3608    cout &lt;&lt; "delay = " &lt;&lt; delayns.count() &lt;&lt; " nanoseconds which is " &lt;&lt; delay.count() &lt;&lt; " cycles\n";
3609    clock::time_point start = clock::now();
3610    clock::time_point stop = start + delay;
3611    while (clock::now() &lt; stop)  <font color="#c80000">// no multiplies or divides in this loop</font>
3612        ;
3613    clock::time_point end = clock::now();
3614    clock::duration elapsed = end - start;
3615    cout &lt;&lt; "paused " &lt;&lt; elapsed.count() &lt;&lt; " cycles ";
3616    cout &lt;&lt; "which is " &lt;&lt; duration_cast&lt;nanoseconds&gt;(elapsed).count() &lt;&lt; " nanoseconds\n";
3617    }
3618    {
3619    typedef approx_cycle_count&lt;1500&gt; clock;
3620    cout &lt;&lt; "\nSimulated " &lt;&lt; clock::frequency / 1000000 &lt;&lt; "MHz clock modeled with nanoseconds\n";
3621    clock::duration delay = nanoseconds(500);
3622    cout &lt;&lt; "delay = " &lt;&lt; delay.count() &lt;&lt; " nanoseconds\n";
3623    clock::time_point start = clock::now();
3624    clock::time_point stop = start + delay;
3625    while (clock::now() &lt; stop) <font color="#c80000">// 1 multiplication and 1 division in this loop</font>
3626        ;
3627    clock::time_point end = clock::now();
3628    clock::duration elapsed = end - start;
3629    cout &lt;&lt; "paused " &lt;&lt; elapsed.count() &lt;&lt; " nanoseconds\n";
3630    }
3631}
3632
3633void test_special_values()
3634{
3635    std::cout &lt;&lt; "duration&lt;unsigned&gt;::min().count()  = " &lt;&lt; duration&lt;unsigned&gt;::min().count() &lt;&lt; '\n';
3636    std::cout &lt;&lt; "duration&lt;unsigned&gt;::zero().count() = " &lt;&lt; duration&lt;unsigned&gt;::zero().count() &lt;&lt; '\n';
3637    std::cout &lt;&lt; "duration&lt;unsigned&gt;::max().count()  = " &lt;&lt; duration&lt;unsigned&gt;::max().count() &lt;&lt; '\n';
3638    std::cout &lt;&lt; "duration&lt;int&gt;::min().count()       = " &lt;&lt; duration&lt;int&gt;::min().count() &lt;&lt; '\n';
3639    std::cout &lt;&lt; "duration&lt;int&gt;::zero().count()      = " &lt;&lt; duration&lt;int&gt;::zero().count() &lt;&lt; '\n';
3640    std::cout &lt;&lt; "duration&lt;int&gt;::max().count()       = " &lt;&lt; duration&lt;int&gt;::max().count() &lt;&lt; '\n';
3641}
3642
3643int main()
3644{
3645    basic_examples();
3646    testStdUser();
3647    testUser1();
3648    testUser2();
3649    drive_physics_function();
3650    test_range();
3651    test_extended_range();
3652    inspect_all();
3653    test_milliseconds();
3654    test_with_xtime();
3655    test_system_clock();
3656    test_monotonic_clock();
3657    test_hi_resolution_clock();
3658    test_mixed_clock();
3659    timeval_demo::test_xtime_clock();
3660    runtime_resolution::test();
3661    test_c_mapping();
3662    test_duration_division();
3663    I_dont_like_the_default_duration_behavior::test();
3664    test_min();
3665#if VARIADIC_COMMON_TYPE
3666    inspect_duration(common_type&lt;duration&lt;double&gt;, hours, microseconds&gt;::type(),
3667                    "common_type&lt;duration&lt;double&gt;, hours, microseconds&gt;::type");
3668#endif
3669    explore_limits();
3670    manipulate_clock_object(system_clock());
3671    duration&lt;double, milli&gt; d = milliseconds(3) * 2.5;
3672    inspect_duration(milliseconds(3) * 2.5, "milliseconds(3) * 2.5");
3673    cout &lt;&lt; d.count() &lt;&lt; '\n';
3674<font color="#c80000">//    milliseconds ms(3.5);  // doesn't compile</font>
3675    cout &lt;&lt; "milliseconds ms(3.5) doesn't compile\n";
3676    cycle_count_delay();
3677    test_special_values();
3678}
3679
3680<font color="#c80000">/*
3681Output
3682
3683Running basic examples
3684sleep_for 3000000 microseconds
3685sleep_for 1 microseconds
3686sleep_until    10:47:17.728293 which is 4499340 microseconds away
3687try_lock_for 30000 microseconds
3688try_lock_until 10:47:17.728285 which is 4499303 microseconds away
3689wait_for 60000000 microseconds
3690wait_until     10:47:17.728285 which is 4499264 microseconds away
3691sleep_for 250000 microseconds
3692sleep_until    10:47:14.729077 which is 1499979 microseconds away
3693***************
3694* testStdUser *
3695***************
3696100 hours expressed as hours = 100
3697100 hours expressed as nanoseconds = 360000000000000
3698200 hours expressed as nanoseconds = 720000000000000
3699300 hours expressed as nanoseconds = 1080000000000000
3700hr = ns;  <font color="#c80000">// does not compile</font>
3701hr * ns;  <font color="#c80000">// does not compile</font>
3702duration&lt;double&gt; has count() = 2.5
3703seconds sec = duration&lt;double&gt; won't compile
3704seconds has count() = 2
3705
3706*************
3707* testUser1 *
3708*************
3709Speed = 24.5872 meters/sec
3710Acceleration = 9.81456 meters/sec^2
3711Distance = 13.5204 meters
3712There are 125/201168 miles/meter which is approximately 0.000621371
3713There are 201168/125 meters/mile which is approximately 1609.34
37141 attosecond is 1e-18 seconds
3715sec = as;  <font color="#c80000">// compiles</font>
37161 second is 1e+18 attoseconds
3717as = sec;  <font color="#c80000">// compiles</font>
3718
3719*************
3720* testUser2 *
3721*************
3722100 years expressed as years = 100
3723100 years expressed as nanoseconds = 3155695200000000000
3724200 years expressed as nanoseconds = 6311390400000000000
3725300 years expressed as nanoseconds = inf
3726yr = ns;  <font color="#c80000">// does not compile</font>
3727ps = yr;  <font color="#c80000">// does not compile</font>
3728100 years expressed as picoseconds = inf
37290.1 years expressed as picoseconds = 3155695200000000000
3730200 million years ago encoded in years: -200000000
3731200 million years ago encoded in days: -73048500000
3732200 million years ago encoded in millennium: -200000
3733Demonstrate "uninitialized protection" behavior:
3734nan
3735
3736d = 3e-09
3737d = 10800
3738d = 0.666667
3739d = 10799.999999997
3740292 years of hours = 2559672hr
3741Add a nanosecond = 9214819200000000001ns
3742Find the difference = 1ns
3743244,000 years of hours = 2138904000hr
3744Add a microsecond = 7700054400000000001us
3745Find the difference = 1us
3746********* nanoseconds *********
3747The period of nanoseconds is 1e-09 seconds.
3748The frequency of nanoseconds is 1e+09 Hz.
3749The representation is integral
3750The precision is 1e-09 seconds.
3751The range is +/- 292.277 years.
3752sizeof(nanoseconds) = 8
3753********* microseconds *********
3754The period of microseconds is 1e-06 seconds.
3755The frequency of microseconds is 1e+06 Hz.
3756The representation is integral
3757The precision is 1e-06 seconds.
3758The range is +/- 292277 years.
3759sizeof(microseconds) = 8
3760********* milliseconds *********
3761The period of milliseconds is 0.001 seconds.
3762The frequency of milliseconds is 1000 Hz.
3763The representation is integral
3764The precision is 0.001 seconds.
3765The range is +/- 2.92277e+08 years.
3766sizeof(milliseconds) = 8
3767********* seconds *********
3768The period of seconds is 1 seconds.
3769The frequency of seconds is 1 Hz.
3770The representation is integral
3771The precision is 1 seconds.
3772The range is +/- 2.92277e+11 years.
3773sizeof(seconds) = 8
3774********* minutes *********
3775The period of minutes is 60 seconds.
3776The frequency of minutes is 0.0166667 Hz.
3777The representation is integral
3778The precision is 60 seconds.
3779The range is +/- 4083.06 years.
3780sizeof(minutes) = 4
3781********* hours *********
3782The period of hours is 3600 seconds.
3783The frequency of hours is 0.000277778 Hz.
3784The representation is integral
3785The precision is 3600 seconds.
3786The range is +/- 244984 years.
3787sizeof(hours) = 4
3788********* duration&lt;double&gt; *********
3789The period of duration&lt;double&gt; is 1 seconds.
3790The frequency of duration&lt;double&gt; is 1 Hz.
3791The representation is floating point
3792The precision is the most significant 15 decimal digits.
3793The range is +/- 5.69666e+300 years.
3794sizeof(duration&lt;double&gt;) = 8
3795success
3796test_with_xtime
3797{3,251000}
37983251 milliseconds
3799{3,251000}
3800{3,0}
3801{3,1}
3802system_clock test
3803paused 5001000 nanoseconds
3804system_clock resolution estimate: 0 nanoseconds
3805monotonic_clock test
3806paused 5000181 nanoseconds
3807monotonic_clock resolution estimate: 97 nanoseconds
3808high_resolution_clock test
3809paused 5000277 nanoseconds
3810high_resolution_clock resolution estimate: 96 nanoseconds
3811mixed clock test
3812Add 5 milliseconds to a high_resolution_clock::time_point
3813Subtracting system_clock::time_point from monotonic_clock::time_point doesn't compile
3814subtract high_resolution_clock::time_point from monotonic_clock::time_point and add that to a system_clock::time_point
3815subtract two system_clock::time_point's and output that in microseconds:
38165000 microseconds
3817timeval_demo system clock test
3818sizeof xtime_clock::time_point = 8
3819sizeof xtime_clock::duration = 8
3820sizeof xtime_clock::rep = 8
3821paused 5001000 nanoseconds
3822runtime_resolution test
3823paused 5000205 nanoseconds
3824C map test
3825It is now 10:47:13 2008-4-22
3826Round-tripping through the C interface truncated the precision by 255445 microseconds
38272160000
38280
38293600000
38300
38312999998997 * 1/1000000000 seconds
38320 * 1/1000000000 seconds
383315778476000000000 microseconds
3834paused 5001000 nanoseconds
3835********* milliseconds(3) * 2.5 *********
3836The period of milliseconds(3) * 2.5 is 0.001 seconds.
3837The frequency of milliseconds(3) * 2.5 is 1000 Hz.
3838The representation is floating point
3839The precision is the most significant 15 decimal digits.
3840The range is +/- 5.69666e+297 years.
3841sizeof(milliseconds(3) * 2.5) = 8
38427.5
3843milliseconds ms(3.5) doesn't compile
3844
3845Simulated 400MHz clock which has a tick period of 2.5 nanoseconds
3846delay = 500 nanoseconds which is 200 cycles
3847paused 201 cycles which is 502 nanoseconds
3848
3849Simulated 400MHz clock modeled with nanoseconds
3850delay = 500 nanoseconds
3851paused 503 nanoseconds
3852
3853Simulated 1500MHz clock which has a tick period of 0.666667 nanoseconds
3854delay = 500 nanoseconds which is 750 cycles
3855paused 751 cycles which is 500 nanoseconds
3856
3857Simulated 1500MHz clock modeled with nanoseconds
3858delay = 500 nanoseconds
3859paused 500 nanoseconds
3860duration&lt;unsigned&gt;::min().count()  = 0
3861duration&lt;unsigned&gt;::zero().count() = 0
3862duration&lt;unsigned&gt;::max().count()  = 4294967295
3863duration&lt;int&gt;::min().count()       = -2147483647
3864duration&lt;int&gt;::zero().count()      = 0
3865duration&lt;int&gt;::max().count()       = 2147483647
3866*/</font>
3867
3868<font color="#c80000">/*
3869Example disassemblies (to show efficiency).
3870Disclaimer:  I don't pretend to understand the optimizations made.
3871
3872Compiled with
3873g++ -O3 -arch x86_64 -S test2.cpp
3874
3875x86 64-bit architecture
3876
3877********************
3878
3879system_clock::duration
3880time_subtraction(system_clock::time_point x, system_clock::time_point y)
3881{
3882    return x - y;
3883}
3884
3885    pushq    %rbp
3886LCFI25:
3887    subq    %rsi, %rdi
3888    movq    %rdi, %rax
3889    movq    %rsp, %rbp
3890LCFI26:
3891    leave
3892    ret
3893
3894********************
3895
3896seconds
3897time_subtract_to_seconds(system_clock::time_point x, system_clock::time_point y)
3898{
3899    return duration_cast&lt;seconds&gt;(x - y);
3900}
3901
3902    subq    %rsi, %rdi
3903    movabsq    $4835703278458516699, %rdx
3904    pushq    %rbp
3905LCFI25:
3906    movq    %rdi, %rax
3907    sarq    $63, %rdi
3908    imulq    %rdx
3909    movq    %rsp, %rbp
3910LCFI26:
3911    leave
3912    sarq    $18, %rdx
3913    subq    %rdi, %rdx
3914    movq    %rdx, %rax
3915    ret
3916
3917********************
3918
3919nanoseconds
3920time_subtract_to_nanoseconds(system_clock::time_point x, system_clock::time_point y)
3921{
3922    return x - y;
3923}
3924
3925    pushq    %rbp
3926LCFI25:
3927    subq    %rsi, %rdi
3928    imulq    $1000, %rdi, %rax
3929    movq    %rsp, %rbp
3930LCFI26:
3931    leave
3932    ret
3933
3934********************
3935
3936system_clock::time_point
3937time_plus_duration(system_clock::time_point x, system_clock::duration y)
3938{
3939    return x + y;
3940}
3941
3942    pushq    %rbp
3943LCFI37:
3944    movq    %rsp, %rbp
3945LCFI38:
3946    leaq    (%rsi,%rdi), %rax
3947    leave
3948    ret
3949
3950********************
3951
3952milliseconds
3953duration_plus_duration(milliseconds x, milliseconds y)
3954{
3955    return x + y;
3956}
3957
3958    pushq    %rbp
3959LCFI11:
3960    leaq    (%rdi,%rsi), %rax
3961    movq    %rsp, %rbp
3962LCFI12:
3963    leave
3964    ret
3965
3966********************
3967
3968nanoseconds
3969milliseconds_plus_nanoseconds(milliseconds x, nanoseconds y)
3970{
3971    return x + y;
3972}
3973
3974    imulq    $1000000, %rdi, %rdi
3975    pushq    %rbp
3976LCFI20:
3977    movq    %rsp, %rbp
3978LCFI21:
3979    leave
3980    leaq    (%rdi,%rsi), %rax
3981    ret
3982
3983********************
3984
3985milliseconds
3986nanoseconds_to_milliseconds(nanoseconds x)
3987{
3988    return duration_cast&lt;milliseconds&gt;(x);
3989}
3990
3991    movq    %rdi, %rax
3992    movabsq    $4835703278458516699, %rdx
3993    pushq    %rbp
3994LCFI13:
3995    imulq    %rdx
3996    sarq    $63, %rdi
3997    movq    %rsp, %rbp
3998LCFI14:
3999    leave
4000    sarq    $18, %rdx
4001    subq    %rdi, %rdx
4002    movq    %rdx, %rax
4003    ret
4004
4005********************
4006
4007nanoseconds
4008milliseconds_to_nanoseconds(milliseconds x)
4009{
4010    return x;
4011}
4012
4013    pushq    %rbp
4014LCFI13:
4015    imulq    $1000000, %rdi, %rax
4016    movq    %rsp, %rbp
4017LCFI14:
4018    leave
4019    ret
4020
4021********************
4022
4023hours
4024increment_hours(hours x)
4025{
4026    return ++x;
4027}
4028
4029    pushq    %rbp
4030LCFI11:
4031    leaq    1(%rdi), %rax
4032    movq    %rsp, %rbp
4033LCFI12:
4034    leave
4035    ret
4036
4037*/</font>
4038</pre>
4039
4040</body></html>