]> git.proxmox.com Git - ceph.git/blame - ceph/src/boost/libs/chrono/doc/time2_demo.html
bump version to 12.2.2-pve1
[ceph.git] / ceph / src / boost / libs / chrono / doc / time2_demo.html
CommitLineData
7c673cae
FG
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>