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">// <type_traits></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 <class T, class U> 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 <class ...T> struct common_type; 72 73template <class T> 74struct common_type<T> 75{ 76 typedef T type; 77}; 78 79template <class T, class U> 80struct common_type<T, U> 81{ 82private: 83 static T t(); 84 static U u(); 85public: 86 typedef decltype(true ? t() : u()) type; 87}; 88 89template <class T, class U, class ...V> 90struct common_type<T, U, V...> 91{ 92 typedef typename common_type<typename common_type<T, U>::type, V...>::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<T>::type in the one place we use identity<T>::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<duration<double>, hours, microseconds>::type is duration<double, micro></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 <class Rep, long long N, long long D> 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<double, 1, 1000000000LL></font> 142<font color="#c80000">//</font> 143<font color="#c80000">// instead of:</font> 144<font color="#c80000">//</font> 145<font color="#c80000">// duration<double, nano></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 <intmax_t N, intmax_t D = 1> 152class ratio 153{ 154 <font color="#c80000">// For every possible value of N and D, abs(N) >= 0 and abs(D) > 0</font> 155 static_assert(__static_abs<N>::value >= 0, "ratio numerator is out of range"); 156 static_assert(__static_abs<D>::value > 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 > 0.</font> 167 168<font color="#c80000">// convenience typedefs</font> 169 170typedef ratio<1, 1000000000000000000000000> yocto; <font color="#c80000">// conditionally supported</font> 171typedef ratio<1, 1000000000000000000000> zepto; <font color="#c80000">// conditionally supported</font> 172typedef ratio<1, 1000000000000000000> atto; 173typedef ratio<1, 1000000000000000> femto; 174typedef ratio<1, 1000000000000> pico; 175typedef ratio<1, 1000000000> nano; 176typedef ratio<1, 1000000> micro; 177typedef ratio<1, 1000> milli; 178typedef ratio<1, 100> centi; 179typedef ratio<1, 10> deci; 180typedef ratio< 10, 1> deca; 181typedef ratio< 100, 1> hecto; 182typedef ratio< 1000, 1> kilo; 183typedef ratio< 1000000, 1> mega; 184typedef ratio< 1000000000, 1> giga; 185typedef ratio< 1000000000000, 1> tera; 186typedef ratio< 1000000000000000, 1> peta; 187typedef ratio< 1000000000000000000, 1> exa; 188typedef ratio< 1000000000000000000000, 1> zetta; <font color="#c80000">// conditionally supported</font> 189typedef ratio<1000000000000000000000000, 1> 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 <class R1, class R2> 194requires R1 and R2 are instantiations of ratio 195struct ratio_add 196{ 197 typedef ratio<pseudo code: R1 + R2> type; 198}; 199 200template <class R1, class R2> 201requires R1 and R2 are instantiations of ratio 202struct ratio_subtract 203{ 204 typedef ratio<pseudo code: R1 - R2> type; 205}; 206 207template <class R1, class R2> 208requires R1 and R2 are instantiations of ratio 209struct ratio_multiply 210{ 211 typedef ratio<pseudo code: R1 * R2> type; 212}; 213 214template <class R1, class R2> 215requires R1 and R2 are instantiations of ratio 216struct ratio_divide 217{ 218 typedef ratio<pseudo code: R1 / R2> type; 219}; 220 221template <class R1, class R2> 222requires R1 and R2 are instantiations of ratio 223struct ratio_equal 224 : public integral_constant<bool, pseudo code: R1 == R2> {}; 225 226template <class R1, class R2> 227requires R1 and R2 are instantiations of ratio 228struct ratio_not_equal 229 : public integral_constant<bool, !ratio_equal<R1, R2>::value> {}; 230 231template <class R1, class R2> 232requires R1 and R2 are instantiations of ratio 233struct ratio_less 234 : public integral_constant<bool, pseudo code: R1 < R2> {}; 235 236template <class R1, class R2> 237requires R1 and R2 are instantiations of ratio 238struct ratio_less_equal 239 : public integral_constant<bool, !ratio_less<R2, R1>::value> {}; 240 241template <class R1, class R2> 242requires R1 and R2 are instantiations of ratio 243struct ratio_greater 244 : public integral_constant<bool, ratio_less<R2, R1>::value> {}; 245 246template <class R1, class R2> 247requires R1 and R2 are instantiations of ratio 248struct ratio_greater_equal 249 : public integral_constant<bool, !ratio_less<R1, R2>::value> {}; 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 <class Rep> struct treat_as_floating_point 261 : is_floating_point<Rep> {}; 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 <class Rep> 268struct duration_values 269{ 270public: 271 static constexpr Rep zero() {return Rep(0);} 272 static constexpr Rep max() {return numeric_limits<Rep>::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<Rep1, Rep2>::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<milliseconds>(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& operator++();</font> 349<font color="#c80000">// duration operator++(int);</font> 350<font color="#c80000">// duration& operator--();</font> 351<font color="#c80000">// duration operator--(int);</font> 352<font color="#c80000">// </font> 353<font color="#c80000">// duration& operator+=(duration d);</font> 354<font color="#c80000">// duration& operator-=(duration d);</font> 355<font color="#c80000">// </font> 356<font color="#c80000">// duration& operator*=(rep rhs);</font> 357<font color="#c80000">// duration& 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<Rep1, Period1> and D2 represent duration<Rep2, Period2>.</font> 364<font color="#c80000">// </font> 365<font color="#c80000">// common_type<D1, D2>::type operator+( D1, D2); // returns a duration</font> 366<font color="#c80000">// common_type<D1, D2>::type operator-( D1, D2); // returns a duration</font> 367<font color="#c80000">// duration<common_type<D1::rep,Rep2>::type, D1::period> operator*( D1, Rep2); // returns a duration</font> 368<font color="#c80000">// duration<common_type<D1::rep,Rep2>::type, D1::period> operator*(Rep2, D1); // returns a duration</font> 369<font color="#c80000">// duration<common_type<D1::rep,Rep2>::type, D1::period> operator/( D1, Rep2); // returns a duration</font> 370<font color="#c80000">// common_type<D1::rep, D2::rep>::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<D1::rep, D2::rep> 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 > 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<Rep, Period>) == 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 <class Rep, class Period = ratio<1>> 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 <class Rep2> 436 requires is_convertible<Rep2, rep>::value && 437 (treat_as_floating_point<rep>::value || 438 !treat_as_floating_point<rep>::value && !treat_as_floating_point<Rep2>::value) 439 explicit duration(const Rep2& r); 440 ~duration() = default; 441 442 <font color="#c80000">// copy semantics</font> 443 duration(const duration&) = default; 444 duration& operator=(const duration&) = default; 445 446 <font color="#c80000">// conversions</font> 447 template <class Rep2, class Period2> 448 requires Rep2 is explicitly convertible to rep && 449 (treat_as_floating_point<rep>::value || 450 !treat_as_floating_point<Rep2>::value && ratio_divide<Period2, period>::type::den == 1) 451 duration(const duration<Rep2, Period2>& 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& operator++(); 462 duration operator++(int); 463 duration& operator--(); 464 duration operator--(int); 465 466 duration& operator+=(const duration& d); 467 duration& operator-=(const duration& d); 468 469 duration& operator*=(const rep& rhs); 470 duration& operator/=(const rep& 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<int_least64_t, nano> nanoseconds; <font color="#c80000">// 10^-9 seconds</font> 482typedef duration<int_least55_t, micro> microseconds; <font color="#c80000">// 10^-6 seconds</font> 483typedef duration<int_least45_t, milli> milliseconds; <font color="#c80000">// 10^-3 seconds</font> 484typedef duration<int_least35_t > seconds; <font color="#c80000">// 1 second</font> 485typedef duration<int_least29_t, ratio< 60>> minutes; <font color="#c80000">// 60 seconds</font> 486typedef duration<int_least23_t, ratio<3600>> 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 <class ToDuration, class Rep, class Period> 498 requires ToDuration is an instantiation of duration 499 ToDuration duration_cast(const duration<Rep, Period>& 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<milliseconds>(us); // 3 milliseconds (explicit truncation)</font> 505<font color="#c80000">// us = ms; // 3000 microseconds</font> 506<font color="#c80000">// us = duration_cast<microseconds>(ms); // 3000 microseconds</font> 507 508} <font color="#c80000">// datetime</font> 509 510<font color="#c80000">// Given two durations: duration<Rep1, Period1> and duration<Rep2, Period2>, the common_type</font> 511<font color="#c80000">// of those two durations is a duration with a representation of common_type<Rep1, Rep2>,</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 <class Rep1, class Period1, class Rep2, class Period2> 520struct common_type<datetime::duration<Rep1, Period1>, datetime::duration<Rep2, Period2> > 521{ 522 typedef datetime::duration<typename common_type<Rep1, Rep2>::type, 523 ratio<GCD(Period1::num, Period2::num), LCM(Period1::den, Period2::den)>> type; 524}; 525 526<font color="#c80000">// Note: For any two durations D1 and D2, they will both exactly convert to common_type<D1, D2>::type.</font> 527<font color="#c80000">// common_type<D1, D2>::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<minutes, microseconds>::type is microseconds.</font> 530<font color="#c80000">// common_type<milliseconds, microseconds>::type is microseconds.</font> 531<font color="#c80000">// common_type<nanoseconds, microseconds>::type is nanoseconds.</font> 532<font color="#c80000">//</font> 533<font color="#c80000">// A more complex example:</font> 534<font color="#c80000">// common_type< duration<long, milli>, duration<int, ratio<1,30>> >::type is</font> 535<font color="#c80000">// duration<long, ratio<1,3000>>. And both duration<long, milli> and </font> 536<font color="#c80000">// duration<int, ratio<1,30>> will exactly convert to duration<long, ratio<1,3000>>.</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<long, milli> and</font> 540<font color="#c80000">// duration<int, ratio<1,30>> will exactly convert to it.</font> 541 542namespace datetime { 543 544template <class Rep1, class Period1, class Rep2, class Period2> 545 bool operator==(const duration<Rep1, Period1>& lhs, const duration<Rep2, Period2>& rhs); 546template <class Rep1, class Period1, class Rep2, class Period2> 547 bool operator!=(const duration<Rep1, Period1>& lhs, const duration<Rep2, Period2>& rhs); 548template <class Rep1, class Period1, class Rep2, class Period2> 549 bool operator< (const duration<Rep1, Period1>& lhs, const duration<Rep2, Period2>& rhs); 550template <class Rep1, class Period1, class Rep2, class Period2> 551 bool operator<=(const duration<Rep1, Period1>& lhs, const duration<Rep2, Period2>& rhs); 552template <class Rep1, class Period1, class Rep2, class Period2> 553 bool operator> (const duration<Rep1, Period1>& lhs, const duration<Rep2, Period2>& rhs); 554template <class Rep1, class Period1, class Rep2, class Period2> 555 bool operator>=(const duration<Rep1, Period1>& lhs, const duration<Rep2, Period2>& rhs); 556 557template <class Rep1, class Period1, class Rep2, class Period2> 558 typename common_type<duration<Rep1, Period1>, duration<Rep2, Period2> >::type 559 operator+(const duration<Rep1, Period1>& lhs, const duration<Rep2, Period2>& rhs); 560 561template <class Rep1, class Period1, class Rep2, class Period2> 562 typename common_type<duration<Rep1, Period1>, duration<Rep2, Period2> >::type 563 operator-(const duration<Rep1, Period1>& lhs, const duration<Rep2, Period2>& rhs); 564 565template <class Rep1, class Period, class Rep2> 566 requires Constructible<Rep1, typename common_type<Rep1, Rep2>::type>::value> && 567 Constructible<Rep2, typename common_type<Rep1, Rep2>::type>::value> 568 duration<typename common_type<Rep1, Rep2>::type, Period> 569 operator*(const duration<Rep, Period>& d, const Rep2& s); 570 571template <class Rep1, class Period, class Rep2> 572 requires Constructible<Rep1, typename common_type<Rep1, Rep2>::type>::value> && 573 Constructible<Rep2, typename common_type<Rep1, Rep2>::type>::value> 574 duration<typename common_type<Rep1, Rep2>::type, Period> 575 operator*(const Rep2& s, const duration<Rep, Period>& d); 576 577template <class Rep1, class Period, class Rep2> 578 requires Rep2 is not a duration && 579 Constructible<Rep1, typename common_type<Rep1, Rep2>::type>::value> && 580 Constructible<Rep2, typename common_type<Rep1, Rep2>::type>::value> 581 duration<typename common_type<Rep1, Rep2>::type, Period> 582 operator/(const duration<Rep, Period>& d, const Rep2& 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 <class Rep1, class Period1, class Rep2, class Period2> 590 typename common_type<Rep1, Rep2>::type 591 operator/(const duration<Rep1, Period1>& lhs, const duration<Rep2, Period2>& 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& operator+=(duration d);</font> 616<font color="#c80000">// time_point& 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<Clock, Duration1>,</font> 620<font color="#c80000">// T2 represent time_point<Clock, Duration2>,</font> 621<font color="#c80000">// and D represent duration<Rep3, Period3>. 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<Clock, Duration>) == 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 <class Clock, class Duration = typename Clock::duration> 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& d); <font color="#c80000">// same as time_point() + d</font> 685 686 <font color="#c80000">// conversions</font> 687 template <class Duration2> 688 requires Convertible<Duration2, duration> 689 time_point(const time_point<clock, Duration2>& 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& operator+=(const duration& d); 698 time_point& operator-=(const duration& 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 <class Clock, class Duration1, class Duration2> 709struct common_type<datetime::time_point<Clock, Duration1>, datetime::time_point<Clock, Duration2> > 710{ 711 typedef datetime::time_point<Clock, typename common_type<Duration1, Duration2>::type> type; 712}; 713 714namespace datetime { 715 716template <class ToDuration, class Clock, class Duration> 717 time_point<Clock, ToDuration> time_point_cast(const time_point<Clock, Duration>& t); 718 719template <class Clock, class Duration1, class Duration2> 720 bool operator==(const time_point<Clock, Duration1>& lhs, const time_point<Clock, Duration2>& rhs); 721template <class Clock, class Duration1, class Duration2> 722 bool operator!=(const time_point<Clock, Duration1>& lhs, const time_point<Clock, Duration2>& rhs); 723template <class Clock, class Duration1, class Duration2> 724 bool operator< (const time_point<Clock, Duration1>& lhs, const time_point<Clock, Duration2>& rhs); 725template <class Clock, class Duration1, class Duration2> 726 bool operator<=(const time_point<Clock, Duration1>& lhs, const time_point<Clock, Duration2>& rhs); 727template <class Clock, class Duration1, class Duration2> 728 bool operator> (const time_point<Clock, Duration1>& lhs, const time_point<Clock, Duration2>& rhs); 729template <class Clock, class Duration1, class Duration2> 730 bool operator>=(const time_point<Clock, Duration1>& lhs, const time_point<Clock, Duration2>& rhs); 731 732template <class Clock, class Duration1, class Rep2, class Period2> 733 time_point<Clock, typename common_type<Duration1, duration<Rep2, Period2> >::type> 734 operator+(const time_point<Clock, Duration1>& lhs, const duration<Rep2, Period2>& rhs); 735 736template <class Rep1, class Period1, class Clock, class Duration2> 737 time_point<Clock, typename common_type<duration<Rep1, Period1>, Duration2>::type> 738 operator+(const duration<Rep1, Period1>& lhs, const time_point<Clock, Duration2>& rhs); 739 740template <class Clock, class Duration1, class Rep2, class Period2> 741 time_point<Clock, typename common_type<Duration1, duration<Rep2, Period2> >::type> 742 operator-(const time_point<Clock, Duration1>& lhs, const duration<Rep2, Period2>& rhs); 743 744template <class Clock, class Duration1, class Duration2> 745 typename common_type<Duration1, Duration2>::type 746 operator-(const time_point<Clock, Duration1>& lhs, const time_point<Clock, Duration2>& 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 <unspecified> rep; 766 typedef ratio<unspecified, unspecified> period; 767 typedef datetime::duration<rep, period> duration; 768 typedef datetime::time_point<system_clock> time_point; 769 static const bool is_mononontic = <unspecified>; 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& 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 <unspecified> rep; 782 typedef ratio<unspecified, unspecified> period; 783 typedef datetime::duration<rep, period> duration; 784 typedef datetime::time_point<monotonic_clock> 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 <unspecified> rep; 794 typedef ratio<unspecified, unspecified> period; 795 typedef datetime::duration<rep, period> duration; 796 typedef datetime::time_point<high_resolution_clock> time_point; 797 static const bool is_mononontic = <unspecified>; 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&) = delete; 819 timed_mutex& operator=(const timed_mutex&) = delete; 820 821 void lock(); 822 bool try_lock(); 823 template <class Rep, class Period> 824 bool try_lock_for(const datetime::duration<Rep, Period>& rel_time); 825 template <class Clock, class Duration> 826 bool try_lock_until(const datetime::time_point<Clock, Duration>& 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&) = delete; 842 recursive_timed_mutex& operator=(const recursive_timed_mutex&) = delete; 843 844 void lock(); 845 bool try_lock(); 846 template <class Rep, class Period> 847 bool try_lock_for(const datetime::duration<Rep, Period>& rel_time); 848 template <class Clock, class Duration> 849 bool try_lock_until(const datetime::time_point<Clock, Duration>& 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 <class Mutex> 859class unique_lock 860{ 861public: 862 typedef Mutex mutex_type; 863 864 unique_lock(); 865 explicit unique_lock(mutex_type& m); 866 unique_lock(mutex_type& m, defer_lock_t); 867 unique_lock(mutex_type& m, try_to_lock_t); 868 unique_lock(mutex_type& m, adopt_lock_t); 869 template <class Rep, class Period> 870 unique_lock(mutex_type& m, const datetime::duration<Rep, Period>& rel_t); 871 template <class Clock, class Duration> 872 unique_lock(mutex_type& m, const datetime::time_point<Clock, Duration>& abs_time); 873 ~unique_lock(); 874 875 unique_lock(unique_lock const&) = delete; 876 unique_lock& operator=(unique_lock const&) = delete; 877 878 unique_lock(unique_lock&& u); 879 unique_lock& operator=(unique_lock&& u); 880 881 void lock(); 882 bool try_lock(); 883 template <class Rep, class Period> 884 bool try_lock_for(const datetime::duration<Rep, Period>& rel_t); 885 template <class Clock, class Duration> 886 bool try_lock_until(const datetime::time_point<Clock, Duration>& 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&& 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&) = delete; 907 condition_variable& operator=(const condition_variable&) = delete; 908 909 void notify_one(); 910 void notify_all(); 911 912 void wait(unique_lock<mutex>& lock); 913 template <class Predicate> 914 void wait(unique_lock<mutex>& lock, Predicate pred); 915 916 template <class Clock, class Duration> 917 bool wait_until(unique_lock<mutex>& lock, 918 const datetime::time_point<Clock, Duration>& abs_time); 919 template <class Clock, class Duration, class Predicate> 920 bool wait_until(unique_lock<mutex>& lock, 921 const datetime::time_point<Clock, Duration>& abs_time, 922 Predicate pred); 923 924 template <class Rep, class Period> 925 bool wait_for(unique_lock<mutex>& lock, const datetime::duration<Rep, Period>& rel_time); 926 template <class Rep, class Period, class Predicate> 927 bool wait_for(unique_lock<mutex>& lock, const datetime::duration<Rep, Period>& 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&) = delete; 944 condition_variable_any& operator=(const condition_variable_any&) = delete; 945 946 void notify_one(); 947 void notify_all(); 948 949 template <class Lock> 950 void wait(Lock& lock); 951 template <class Lock, class Predicate> 952 void wait(Lock& lock, Predicate pred); 953 954 template <class Lock, class Clock, class Duration> 955 bool wait_until(Lock& lock, const datetime::time_point<Clock, Duration>& abs_time); 956 template <class Lock, class Clock, class Duration, class Predicate> 957 bool wait_until(Lock& lock, const datetime::time_point<Clock, Duration>& abs_time, 958 Predicate pred); 959 960 template <class Lock, class Rep, class Period> 961 bool wait_for(Lock& lock, const datetime::duration<Rep, Period>& rel_time); 962 template <class Lock, class Rep, class Period, class Predicate> 963 bool wait_for(Lock& lock, const datetime::duration<Rep, Period>& rel_time, Predicate pred); 964}; 965 966<font color="#c80000">// sleep</font> 967 968namespace this_thread 969{ 970 971 template <class Rep, class Period> 972 void sleep_for(const datetime::duration<Rep, Period>& rel_time); 973 974 template <class Clock, class Duration> 975 void sleep_until(const datetime::time_point<Clock, Duration>& abs_time); 976 977} <font color="#c80000">// this_thread</font> 978 979} <font color="#c80000">// std</font> 980 981*/</font> 982 983#include <ctime> 984#include <climits> 985#include <inttypes.h> 986#include <limits> 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 <class T, class U> 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 <class ...T> struct common_type; 1015 1016template <class T> 1017struct common_type<T> 1018{ 1019 typedef T type; 1020}; 1021 1022template <class T, class U> 1023struct common_type<T, U> 1024{ 1025private: 1026 static T t(); 1027 static U u(); 1028public: 1029 typedef decltype(true ? t() : u()) type; 1030}; 1031 1032template <class T, class U, class ...V> 1033struct common_type<T, U, V...> 1034{ 1035 typedef typename common_type<typename common_type<T, U>::type, V...>::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 <intmax_t X, intmax_t Y> 1047struct __static_gcd 1048{ 1049 static const intmax_t value = __static_gcd<Y, X % Y>::value; 1050}; 1051 1052template <intmax_t X> 1053struct __static_gcd<X, 0> 1054{ 1055 static const intmax_t value = X; 1056}; 1057 1058<font color="#c80000">// __static_lcm</font> 1059 1060template <intmax_t X, intmax_t Y> 1061struct __static_lcm 1062{ 1063 static const intmax_t value = X / __static_gcd<X, Y>::value * Y; 1064}; 1065 1066template <intmax_t X> 1067struct __static_abs 1068{ 1069 static const intmax_t value = X < 0 ? -X : X; 1070}; 1071 1072template <intmax_t X> 1073struct __static_sign 1074{ 1075 static const intmax_t value = X == 0 ? 0 : (X < 0 ? -1 : 1); 1076}; 1077 1078template <intmax_t X, intmax_t Y, intmax_t = __static_sign<Y>::value> 1079class __ll_add; 1080 1081template <intmax_t X, intmax_t Y> 1082class __ll_add<X, Y, 1> 1083{ 1084 static const intmax_t min = (1LL << (sizeof(intmax_t) * CHAR_BIT - 1)) + 1; 1085 static const intmax_t max = -min; 1086 1087 static char test[X <= max - Y]; 1088<font color="#c80000">// static_assert(X <= max - Y, "overflow in __ll_add");</font> 1089public: 1090 static const intmax_t value = X + Y; 1091}; 1092 1093template <intmax_t X, intmax_t Y> 1094class __ll_add<X, Y, 0> 1095{ 1096public: 1097 static const intmax_t value = X; 1098}; 1099 1100template <intmax_t X, intmax_t Y> 1101class __ll_add<X, Y, -1> 1102{ 1103 static const intmax_t min = (1LL << (sizeof(intmax_t) * CHAR_BIT - 1)) + 1; 1104 static const intmax_t max = -min; 1105 1106 static char test[min - Y <= X]; 1107<font color="#c80000">// static_assert(min - Y <= X, "overflow in __ll_add");</font> 1108public: 1109 static const intmax_t value = X + Y; 1110}; 1111 1112template <intmax_t X, intmax_t Y, intmax_t = __static_sign<Y>::value> 1113class __ll_sub; 1114 1115template <intmax_t X, intmax_t Y> 1116class __ll_sub<X, Y, 1> 1117{ 1118 static const intmax_t min = (1LL << (sizeof(intmax_t) * CHAR_BIT - 1)) + 1; 1119 static const intmax_t max = -min; 1120 1121 static char test[min + Y <= X]; 1122<font color="#c80000">// static_assert(min + Y <= X, "overflow in __ll_sub");</font> 1123public: 1124 static const intmax_t value = X - Y; 1125}; 1126 1127template <intmax_t X, intmax_t Y> 1128class __ll_sub<X, Y, 0> 1129{ 1130public: 1131 static const intmax_t value = X; 1132}; 1133 1134template <intmax_t X, intmax_t Y> 1135class __ll_sub<X, Y, -1> 1136{ 1137 static const intmax_t min = (1LL << (sizeof(intmax_t) * CHAR_BIT - 1)) + 1; 1138 static const intmax_t max = -min; 1139 1140 static char test[X <= max + Y]; 1141<font color="#c80000">// static_assert(X <= max + Y, "overflow in __ll_sub");</font> 1142public: 1143 static const intmax_t value = X - Y; 1144}; 1145 1146template <intmax_t X, intmax_t Y> 1147class __ll_mul 1148{ 1149 static const intmax_t nan = (1LL << (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<X>::value; 1153 static const intmax_t __a_y = __static_abs<Y>::value; 1154 1155 static char test1[X != nan]; 1156 static char test2[Y != nan]; 1157 static char test[__a_x <= max / __a_y]; 1158<font color="#c80000">// static_assert(X != nan && Y != nan && __a_x <= max / __a_y, "overflow in __ll_mul");</font> 1159public: 1160 static const intmax_t value = X * Y; 1161}; 1162 1163template <intmax_t Y> 1164class __ll_mul<0, Y> 1165{ 1166public: 1167 static const intmax_t value = 0; 1168}; 1169 1170template <intmax_t X> 1171class __ll_mul<X, 0> 1172{ 1173public: 1174 static const intmax_t value = 0; 1175}; 1176 1177template <> 1178class __ll_mul<0, 0> 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 <intmax_t X, intmax_t Y> 1186class __ll_div 1187{ 1188 static const intmax_t nan = (1LL << (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 && Y != nan && Y != 0, "overflow in __ll_div");</font> 1196public: 1197 static const intmax_t value = X / Y; 1198}; 1199 1200template <intmax_t N, intmax_t D = 1> 1201class ratio 1202{ 1203 static char test1[__static_abs<N>::value >= 0]; 1204 static char test2[__static_abs<D>::value > 0]; 1205<font color="#c80000">// static_assert(__static_abs<N>::value >= 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<D>::value > 0, "ratio denominator is out of range");</font> 1208 static const intmax_t __na = __static_abs<N>::value; 1209 static const intmax_t __da = __static_abs<D>::value; 1210 static const intmax_t __s = __static_sign<N>::value * __static_sign<D>::value; 1211 static const intmax_t __gcd = __static_gcd<__na, __da>::value; 1212public: 1213 static const intmax_t num = __s * __na / __gcd; 1214 static const intmax_t den = __da / __gcd; 1215}; 1216 1217template <class T> struct ___is_ratio : tmp::false_type {}; 1218template <intmax_t N, intmax_t D> struct ___is_ratio<ratio<N, D> > : tmp::true_type {}; 1219template <class T> struct __is_ratio : ___is_ratio<typename tmp::remove_cv<T>::type> {}; 1220 1221typedef ratio<1LL, 1000000000000000000LL> atto; 1222typedef ratio<1LL, 1000000000000000LL> femto; 1223typedef ratio<1LL, 1000000000000LL> pico; 1224typedef ratio<1LL, 1000000000LL> nano; 1225typedef ratio<1LL, 1000000LL> micro; 1226typedef ratio<1LL, 1000LL> milli; 1227typedef ratio<1LL, 100LL> centi; 1228typedef ratio<1LL, 10LL> deci; 1229typedef ratio< 10LL, 1LL> deca; 1230typedef ratio< 100LL, 1LL> hecto; 1231typedef ratio< 1000LL, 1LL> kilo; 1232typedef ratio< 1000000LL, 1LL> mega; 1233typedef ratio< 1000000000LL, 1LL> giga; 1234typedef ratio< 1000000000000LL, 1LL> tera; 1235typedef ratio< 1000000000000000LL, 1LL> peta; 1236typedef ratio<1000000000000000000LL, 1LL> exa; 1237 1238template <class R1, class R2> 1239struct ratio_add 1240{ 1241 typedef ratio<__ll_add<__ll_mul<R1::num, R2::den>::value, 1242 __ll_mul<R1::den, R2::num>::value>::value, 1243 __ll_mul<R1::den, R2::den>::value> type; 1244}; 1245 1246template <class R1, class R2> 1247struct ratio_subtract 1248{ 1249 typedef ratio<__ll_sub<__ll_mul<R1::num, R2::den>::value, 1250 __ll_mul<R1::den, R2::num>::value>::value, 1251 __ll_mul<R1::den, R2::den>::value> type; 1252}; 1253 1254template <class R1, class R2> 1255struct ratio_multiply 1256{ 1257 typedef ratio<__ll_mul<R1::num, R2::num>::value, __ll_mul<R1::den, R2::den>::value> type; 1258}; 1259 1260template <class R1, class R2> 1261struct ratio_divide 1262{ 1263 typedef ratio<__ll_mul<R1::num, R2::den>::value, __ll_mul<R1::den, R2::num>::value> type; 1264}; 1265 1266<font color="#c80000">// ratio_equal</font> 1267 1268template <class R1, class R2> 1269struct ratio_equal 1270 : public tmp::integral_constant<bool, R1::num == R2::num && R1::den == R2::den> {}; 1271 1272template <class R1, class R2> 1273struct ratio_not_equal 1274 : public tmp::integral_constant<bool, !ratio_equal<R1, R2>::value> {}; 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 <class R1, class R2, bool ok1, bool ok2> 1283struct __ratio_less3 <font color="#c80000">// true, true and false, false</font> 1284{ 1285 static const bool value = __ll_mul<R1::num, R2::den>::value < __ll_mul<R2::num, R1::den>::value; 1286}; 1287 1288template <class R1, class R2> 1289struct __ratio_less3<R1, R2, true, false> 1290{ 1291 static const bool value = true; 1292}; 1293 1294template <class R1, class R2> 1295struct __ratio_less3<R1, R2, false, true> 1296{ 1297 static const bool value = false; 1298}; 1299 1300template <class R1, class R2, bool = R1::num < R1::den == R2::num < R2::den> 1301struct __ratio_less2 <font color="#c80000">// N1 < D1 == N2 < D2</font> 1302{ 1303 static const intmax_t max = -((1LL << (sizeof(intmax_t) * CHAR_BIT - 1)) + 1); 1304 static const bool ok1 = R1::num <= max / R2::den; 1305 static const bool ok2 = R2::num <= max / R1::den; 1306 static const bool value = __ratio_less3<R1, R2, ok1, ok2>::value; 1307}; 1308 1309template <class R1, class R2> 1310struct __ratio_less2<R1, R2, false> <font color="#c80000">// N1 < D1 != N2 < D2</font> 1311{ 1312 static const bool value = R1::num < R1::den; 1313}; 1314 1315template <class R1, class R2, bool = R1::num < R1::den == R2::num < R2::den> 1316struct __ratio_less1 <font color="#c80000">// N1 < D1 == N2 < D2</font> 1317{ 1318 static const bool value = __ratio_less2<ratio<R1::num, R2::num>, ratio<R1::den, R2::den> >::value; 1319}; 1320 1321template <class R1, class R2> 1322struct __ratio_less1<R1, R2, false> <font color="#c80000">// N1 < D1 != N2 < D2</font> 1323{ 1324 static const bool value = R1::num < R1::den; 1325}; 1326 1327template <class R1, class R2, intmax_t S1 = __static_sign<R1::num>::value, 1328 intmax_t S2 = __static_sign<R2::num>::value> 1329struct __ratio_less 1330{ 1331 static const bool value = S1 < S2; 1332}; 1333 1334template <class R1, class R2> 1335struct __ratio_less<R1, R2, 1LL, 1LL> 1336{ 1337 static const bool value = __ratio_less1<R1, R2>::value; 1338}; 1339 1340template <class R1, class R2> 1341struct __ratio_less<R1, R2, -1LL, -1LL> 1342{ 1343 static const bool value = __ratio_less1<ratio<-R2::num, R2::den>, ratio<-R1::num, R1::den> >::value; 1344}; 1345 1346template <class R1, class R2> 1347struct ratio_less 1348 : public tmp::integral_constant<bool, __ratio_less<R1, R2>::value> {}; 1349 1350template <class R1, class R2> 1351struct ratio_less_equal 1352 : public tmp::integral_constant<bool, !ratio_less<R2, R1>::value> {}; 1353 1354template <class R1, class R2> 1355struct ratio_greater 1356 : public tmp::integral_constant<bool, ratio_less<R2, R1>::value> {}; 1357 1358template <class R1, class R2> 1359struct ratio_greater_equal 1360 : public tmp::integral_constant<bool, !ratio_less<R1, R2>::value> {}; 1361 1362template <class R1, class R2> 1363struct __ratio_gcd 1364{ 1365 typedef ratio<__static_gcd<R1::num, R2::num>::value, 1366 __static_lcm<R1::den, R2::den>::value> 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 <class RepType, class Period = ratio<1> > class duration; 1377 1378template <class T> struct ___is_duration : tmp::false_type {}; 1379template <class Rep, class Period> struct ___is_duration<duration<Rep, Period> > : tmp::true_type {}; 1380template <class T> struct __is_duration : ___is_duration<typename tmp::remove_cv<T>::type> {}; 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 <class FromDuration, class ToDuration, 1394 class Period = typename ratio_divide<typename FromDuration::period, typename ToDuration::period>::type, 1395 bool = Period::num == 1, 1396 bool = Period::den == 1> 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 <class FromDuration, class ToDuration, class Period> 1404struct __duration_cast<FromDuration, ToDuration, Period, true, true> 1405{ 1406 ToDuration operator()(const FromDuration& fd) const 1407 { 1408 return ToDuration(static_cast<typename ToDuration::rep>(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 <class FromDuration, class ToDuration, class Period> 1419struct __duration_cast<FromDuration, ToDuration, Period, true, false> 1420{ 1421 ToDuration operator()(const FromDuration& fd) const 1422 { 1423#if VARIADIC_COMMON_TYPE == 0 1424 typedef typename common_type< 1425 typename common_type<typename ToDuration::rep, typename FromDuration::rep>::type, 1426 intmax_t>::type C; 1427#else 1428 typedef typename common_type<typename ToDuration::rep, typename FromDuration::rep, intmax_t>::type C; 1429#endif 1430 return ToDuration(static_cast<typename ToDuration::rep>( 1431 static_cast<C>(fd.count()) / static_cast<C>(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 <class FromDuration, class ToDuration, class Period> 1441struct __duration_cast<FromDuration, ToDuration, Period, false, true> 1442{ 1443 ToDuration operator()(const FromDuration& fd) const 1444 { 1445#if VARIADIC_COMMON_TYPE == 0 1446 typedef typename common_type< 1447 typename common_type<typename ToDuration::rep, typename FromDuration::rep>::type, 1448 intmax_t>::type C; 1449#else 1450 typedef typename common_type<typename ToDuration::rep, typename FromDuration::rep, intmax_t>::type C; 1451#endif 1452 return ToDuration(static_cast<typename ToDuration::rep>( 1453 static_cast<C>(fd.count()) * static_cast<C>(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 <class FromDuration, class ToDuration, class Period> 1464struct __duration_cast<FromDuration, ToDuration, Period, false, false> 1465{ 1466 ToDuration operator()(const FromDuration& fd) const 1467 { 1468#if VARIADIC_COMMON_TYPE == 0 1469 typedef typename common_type< 1470 typename common_type<typename ToDuration::rep, typename FromDuration::rep>::type, 1471 intmax_t>::type C; 1472#else 1473 typedef typename common_type<typename ToDuration::rep, typename FromDuration::rep, intmax_t>::type C; 1474#endif 1475 return ToDuration(static_cast<typename ToDuration::rep>( 1476 static_cast<C>(fd.count()) * static_cast<C>(Period::num) / static_cast<C>(Period::den))); 1477 } 1478}; 1479 1480<font color="#c80000">// Compile-time select the most efficient algorithm for the conversion...</font> 1481template <class ToDuration, class Rep, class Period> 1482inline 1483typename tmp::enable_if 1484< 1485 __is_duration<ToDuration>::value, 1486 ToDuration 1487>::type 1488duration_cast(const duration<Rep, Period>& fd) 1489{ 1490 return __duration_cast<duration<Rep, Period>, ToDuration>()(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 <class Rep> struct treat_as_floating_point : tmp::is_floating_point<Rep> {}; 1496 1497template <class Rep> 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<Rep>::max();} 1505 static Rep min() {return __min_imp(tmp::is_unsigned<Rep>());} 1506}; 1507 1508<font color="#c80000">// duration</font> 1509 1510template <class Rep, class Period> 1511class duration 1512{ 1513 static char test0[!__is_duration<Rep>::value]; 1514<font color="#c80000">// static_assert(!__is_duration<Rep>::value, "A duration representation can not be a duration");</font> 1515 static char test1[__is_ratio<Period>::value]; 1516<font color="#c80000">// static_assert(__is_ratio<Period>::value, "Second template parameter of duration must be a std::ratio");</font> 1517 static char test2[Period::num > 0]; 1518<font color="#c80000">// static_assert(Period::num > 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 <class Rep2> 1528 explicit duration(const Rep2& r, 1529 typename tmp::enable_if 1530 < 1531 tmp::is_convertible<Rep2, rep>::value && 1532 (treat_as_floating_point<rep>::value || 1533 !treat_as_floating_point<rep>::value && !treat_as_floating_point<Rep2>::value) 1534 >::type* = 0) 1535 : rep_(r) {} 1536 1537 <font color="#c80000">// conversions</font> 1538 template <class Rep2, class Period2> 1539 duration(const duration<Rep2, Period2>& d, 1540 typename tmp::enable_if 1541 < 1542 treat_as_floating_point<rep>::value || 1543 (ratio_divide<Period2, period>::type::den == 1 && !treat_as_floating_point<Rep2>::value) 1544 >::type* = 0) 1545 : rep_(duration_cast<duration>(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& operator++() {++rep_; return *this;} 1556 duration operator++(int) {return duration(rep_++);} 1557 duration& operator--() {--rep_; return *this;} 1558 duration operator--(int) {return duration(rep_--);} 1559 1560 duration& operator+=(const duration& d) {rep_ += d.count(); return *this;} 1561 duration& operator-=(const duration& d) {rep_ -= d.count(); return *this;} 1562 1563 duration& operator*=(const rep& rhs) {rep_ *= rhs; return *this;} 1564 duration& operator/=(const rep& rhs) {rep_ /= rhs; return *this;} 1565 1566 <font color="#c80000">// special values</font> 1567 1568 static duration zero() {return duration(duration_values<rep>::zero());} 1569 static duration min() {return duration(duration_values<rep>::min());} 1570 static duration max() {return duration(duration_values<rep>::max());} 1571}; 1572 1573typedef duration<long long, nano> nanoseconds; 1574typedef duration<long long, micro> microseconds; 1575typedef duration<long long, milli> milliseconds; 1576typedef duration<long long > seconds; 1577typedef duration< long, ratio< 60> > minutes; 1578typedef duration< long, ratio<3600> > hours; 1579 1580} <font color="#c80000">// datetime</font> 1581 1582template <class Rep1, class Period1, class Rep2, class Period2> 1583struct common_type<datetime::duration<Rep1, Period1>, datetime::duration<Rep2, Period2> > 1584{ 1585 typedef datetime::duration<typename common_type<Rep1, Rep2>::type, 1586 typename __ratio_gcd<Period1, Period2>::type> type; 1587}; 1588 1589namespace datetime { 1590 1591<font color="#c80000">// Duration ==</font> 1592 1593template <class LhsDuration, class RhsDuration> 1594struct __duration_eq 1595{ 1596 bool operator()(const LhsDuration& lhs, const RhsDuration& rhs) 1597 { 1598 typedef typename common_type<LhsDuration, RhsDuration>::type CD; 1599 return CD(lhs).count() == CD(rhs).count(); 1600 } 1601}; 1602 1603template <class LhsDuration> 1604struct __duration_eq<LhsDuration, LhsDuration> 1605{ 1606 bool operator()(const LhsDuration& lhs, const LhsDuration& rhs) 1607 {return lhs.count() == rhs.count();} 1608}; 1609 1610template <class Rep1, class Period1, class Rep2, class Period2> 1611inline 1612bool 1613operator==(const duration<Rep1, Period1>& lhs, const duration<Rep2, Period2>& rhs) 1614{ 1615 return __duration_eq<duration<Rep1, Period1>, duration<Rep2, Period2> >()(lhs, rhs); 1616} 1617 1618<font color="#c80000">// Duration !=</font> 1619 1620template <class Rep1, class Period1, class Rep2, class Period2> 1621inline 1622bool 1623operator!=(const duration<Rep1, Period1>& lhs, const duration<Rep2, Period2>& rhs) 1624{ 1625 return !(lhs == rhs); 1626} 1627 1628<font color="#c80000">// Duration <</font> 1629 1630template <class LhsDuration, class RhsDuration> 1631struct __duration_lt 1632{ 1633 bool operator()(const LhsDuration& lhs, const RhsDuration& rhs) 1634 { 1635 typedef typename common_type<LhsDuration, RhsDuration>::type CD; 1636 return CD(lhs).count() < CD(rhs).count(); 1637 } 1638}; 1639 1640template <class LhsDuration> 1641struct __duration_lt<LhsDuration, LhsDuration> 1642{ 1643 bool operator()(const LhsDuration& lhs, const LhsDuration& rhs) 1644 {return lhs.count() < rhs.count();} 1645}; 1646 1647template <class Rep1, class Period1, class Rep2, class Period2> 1648inline 1649bool 1650operator< (const duration<Rep1, Period1>& lhs, const duration<Rep2, Period2>& rhs) 1651{ 1652 return __duration_lt<duration<Rep1, Period1>, duration<Rep2, Period2> >()(lhs, rhs); 1653} 1654 1655<font color="#c80000">// Duration ></font> 1656 1657template <class Rep1, class Period1, class Rep2, class Period2> 1658inline 1659bool 1660operator> (const duration<Rep1, Period1>& lhs, const duration<Rep2, Period2>& rhs) 1661{ 1662 return rhs < lhs; 1663} 1664 1665<font color="#c80000">// Duration <=</font> 1666 1667template <class Rep1, class Period1, class Rep2, class Period2> 1668inline 1669bool 1670operator<=(const duration<Rep1, Period1>& lhs, const duration<Rep2, Period2>& rhs) 1671{ 1672 return !(rhs < lhs); 1673} 1674 1675<font color="#c80000">// Duration >=</font> 1676 1677template <class Rep1, class Period1, class Rep2, class Period2> 1678inline 1679bool 1680operator>=(const duration<Rep1, Period1>& lhs, const duration<Rep2, Period2>& rhs) 1681{ 1682 return !(lhs < rhs); 1683} 1684 1685<font color="#c80000">// Duration +</font> 1686 1687template <class Rep1, class Period1, class Rep2, class Period2> 1688inline 1689typename common_type<duration<Rep1, Period1>, duration<Rep2, Period2> >::type 1690operator+(const duration<Rep1, Period1>& lhs, const duration<Rep2, Period2>& rhs) 1691{ 1692 typename common_type<duration<Rep1, Period1>, duration<Rep2, Period2> >::type result = lhs; 1693 result += rhs; 1694 return result; 1695} 1696 1697<font color="#c80000">// Duration -</font> 1698 1699template <class Rep1, class Period1, class Rep2, class Period2> 1700inline 1701typename common_type<duration<Rep1, Period1>, duration<Rep2, Period2> >::type 1702operator-(const duration<Rep1, Period1>& lhs, const duration<Rep2, Period2>& rhs) 1703{ 1704 typename common_type<duration<Rep1, Period1>, duration<Rep2, Period2> >::type result = lhs; 1705 result -= rhs; 1706 return result; 1707} 1708 1709<font color="#c80000">// Duration *</font> 1710 1711template <class Rep1, class Period, class Rep2> 1712inline 1713typename tmp::enable_if 1714< 1715 tmp::is_convertible<Rep1, typename common_type<Rep1, Rep2>::type>::value && 1716 tmp::is_convertible<Rep2, typename common_type<Rep1, Rep2>::type>::value, 1717 duration<typename common_type<Rep1, Rep2>::type, Period> 1718>::type 1719operator*(const duration<Rep1, Period>& d, const Rep2& s) 1720{ 1721 typedef typename common_type<Rep1, Rep2>::type CR; 1722 duration<CR, Period> r = d; 1723 r *= static_cast<CR>(s); 1724 return r; 1725} 1726 1727template <class Rep1, class Period, class Rep2> 1728inline 1729typename tmp::enable_if 1730< 1731 tmp::is_convertible<Rep1, typename common_type<Rep1, Rep2>::type>::value && 1732 tmp::is_convertible<Rep2, typename common_type<Rep1, Rep2>::type>::value, 1733 duration<typename common_type<Rep1, Rep2>::type, Period> 1734>::type 1735operator*(const Rep1& s, const duration<Rep2, Period>& d) 1736{ 1737 return d * s; 1738} 1739 1740<font color="#c80000">// Duration /</font> 1741 1742template <class Duration, class Rep, bool = __is_duration<Rep>::value> 1743struct __duration_divide_result 1744{ 1745}; 1746 1747template <class Duration, class Rep2, 1748 bool = tmp::is_convertible<typename Duration::rep, 1749 typename common_type<typename Duration::rep, Rep2>::type>::value && 1750 tmp::is_convertible<Rep2, 1751 typename common_type<typename Duration::rep, Rep2>::type>::value> 1752struct __duration_divide_imp 1753{ 1754}; 1755 1756template <class Rep1, class Period, class Rep2> 1757struct __duration_divide_imp<duration<Rep1, Period>, Rep2, true> 1758{ 1759 typedef duration<typename common_type<Rep1, Rep2>::type, Period> type; 1760}; 1761 1762template <class Rep1, class Period, class Rep2> 1763struct __duration_divide_result<duration<Rep1, Period>, Rep2, false> 1764 : __duration_divide_imp<duration<Rep1, Period>, Rep2> 1765{ 1766}; 1767 1768template <class Rep1, class Period, class Rep2> 1769inline 1770typename __duration_divide_result<duration<Rep1, Period>, Rep2>::type 1771operator/(const duration<Rep1, Period>& d, const Rep2& s) 1772{ 1773 typedef typename common_type<Rep1, Rep2>::type CR; 1774 duration<CR, Period> r = d; 1775 r /= static_cast<CR>(s); 1776 return r; 1777} 1778 1779template <class Rep1, class Period1, class Rep2, class Period2> 1780inline 1781typename common_type<Rep1, Rep2>::type 1782operator/(const duration<Rep1, Period1>& lhs, const duration<Rep2, Period2>& rhs) 1783{ 1784 typedef typename common_type<duration<Rep1, Period1>, duration<Rep2, Period2> >::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 <class Clock, class Duration = typename Clock::duration> 1793class time_point 1794{ 1795 static char test1[__is_duration<Duration>::value]; 1796<font color="#c80000">// static_assert(__is_duration<Duration>::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& d) : d_(d) {} 1809 1810 <font color="#c80000">// conversions</font> 1811 template <class Duration2> 1812 time_point(const time_point<clock, Duration2>& t, 1813 typename tmp::enable_if 1814 < 1815 tmp::is_convertible<Duration2, duration>::value 1816 >::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& operator+=(const duration& d) {d_ += d; return *this;} 1826 time_point& operator-=(const duration& 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 <class Clock, class Duration1, class Duration2> 1837struct common_type<datetime::time_point<Clock, Duration1>, datetime::time_point<Clock, Duration2> > 1838{ 1839 typedef datetime::time_point<Clock, typename common_type<Duration1, Duration2>::type> type; 1840}; 1841 1842namespace datetime { 1843 1844template <class ToDuration, class Clock, class Duration> 1845inline 1846time_point<Clock, ToDuration> 1847time_point_cast(const time_point<Clock, Duration>& t) 1848{ 1849 return time_point<Clock, ToDuration>(duration_cast<ToDuration>(t.time_since_epoch())); 1850} 1851 1852<font color="#c80000">// time_point ==</font> 1853 1854template <class Clock, class Duration1, class Duration2> 1855inline 1856bool 1857operator==(const time_point<Clock, Duration1>& lhs, const time_point<Clock, Duration2>& rhs) 1858{ 1859 return lhs.time_since_epoch() == rhs.time_since_epoch(); 1860} 1861 1862<font color="#c80000">// time_point !=</font> 1863 1864template <class Clock, class Duration1, class Duration2> 1865inline 1866bool 1867operator!=(const time_point<Clock, Duration1>& lhs, const time_point<Clock, Duration2>& rhs) 1868{ 1869 return !(lhs == rhs); 1870} 1871 1872<font color="#c80000">// time_point <</font> 1873 1874template <class Clock, class Duration1, class Duration2> 1875inline 1876bool 1877operator<(const time_point<Clock, Duration1>& lhs, const time_point<Clock, Duration2>& rhs) 1878{ 1879 return lhs.time_since_epoch() < rhs.time_since_epoch(); 1880} 1881 1882<font color="#c80000">// time_point ></font> 1883 1884template <class Clock, class Duration1, class Duration2> 1885inline 1886bool 1887operator>(const time_point<Clock, Duration1>& lhs, const time_point<Clock, Duration2>& rhs) 1888{ 1889 return rhs < lhs; 1890} 1891 1892<font color="#c80000">// time_point <=</font> 1893 1894template <class Clock, class Duration1, class Duration2> 1895inline 1896bool 1897operator<=(const time_point<Clock, Duration1>& lhs, const time_point<Clock, Duration2>& rhs) 1898{ 1899 return !(rhs < lhs); 1900} 1901 1902<font color="#c80000">// time_point >=</font> 1903 1904template <class Clock, class Duration1, class Duration2> 1905inline 1906bool 1907operator>=(const time_point<Clock, Duration1>& lhs, const time_point<Clock, Duration2>& rhs) 1908{ 1909 return !(lhs < rhs); 1910} 1911 1912<font color="#c80000">// time_point operator+(time_point x, duration y);</font> 1913 1914template <class Clock, class Duration1, class Rep2, class Period2> 1915inline 1916time_point<Clock, typename common_type<Duration1, duration<Rep2, Period2> >::type> 1917operator+(const time_point<Clock, Duration1>& lhs, const duration<Rep2, Period2>& rhs) 1918{ 1919 typedef time_point<Clock, typename common_type<Duration1, duration<Rep2, Period2> >::type> 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 <class Rep1, class Period1, class Clock, class Duration2> 1928inline 1929time_point<Clock, typename common_type<duration<Rep1, Period1>, Duration2>::type> 1930operator+(const duration<Rep1, Period1>& lhs, const time_point<Clock, Duration2>& rhs) 1931{ 1932 return rhs + lhs; 1933} 1934 1935<font color="#c80000">// time_point operator-(time_point x, duration y);</font> 1936 1937template <class Clock, class Duration1, class Rep2, class Period2> 1938inline 1939time_point<Clock, typename common_type<Duration1, duration<Rep2, Period2> >::type> 1940operator-(const time_point<Clock, Duration1>& lhs, const duration<Rep2, Period2>& rhs) 1941{ 1942 return lhs + (-rhs); 1943} 1944 1945<font color="#c80000">// duration operator-(time_point x, time_point y);</font> 1946 1947template <class Clock, class Duration1, class Duration2> 1948inline 1949typename common_type<Duration1, Duration2>::type 1950operator-(const time_point<Clock, Duration1>& lhs, const time_point<Clock, Duration2>& 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<system_clock> 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& 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<monotonic_clock> 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 <sys/time.h> <font color="#c80000">//for gettimeofday and timeval</font> 2000#include <mach/mach_time.h> <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(&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& t) 2024{ 2025 return time_t(duration_cast<seconds>(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(&MachInfo); 2059 return static_cast<double>(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<monotonic_clock::rep>(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(&MachInfo); 2078 if (MachInfo.numer == MachInfo.denom) 2079 return &monotonic_simplified; 2080 return &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 <iostream> 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(&c_time); 2107 system_clock::duration d = t.time_since_epoch(); 2108 std::cout << tmptr->tm_hour << ':' << tmptr->tm_min << ':' << tmptr->tm_sec 2109 << '.' << (d - duration_cast<seconds>(d)).count(); 2110} 2111 2112namespace this_thread { 2113 2114template <class Rep, class Period> 2115void sleep_for(const datetime::duration<Rep, Period>& d) 2116{ 2117 datetime::microseconds t = datetime::duration_cast<datetime::microseconds>(d); 2118 if (t < d) 2119 ++t; 2120 if (t > datetime::microseconds(0)) 2121 std::cout << "sleep_for " << t.count() << " microseconds\n"; 2122} 2123 2124template <class Clock, class Duration> 2125void sleep_until(const datetime::time_point<Clock, Duration>& t) 2126{ 2127 using namespace datetime; 2128 typedef time_point<Clock, Duration> Time; 2129 typedef system_clock::time_point SysTime; 2130 if (t > Clock::now()) 2131 { 2132 typedef typename common_type<typename Time::duration, typename SysTime::duration>::type D; 2133 <font color="#c80000">/* auto */</font> D d = t - Clock::now(); 2134 microseconds us = duration_cast<microseconds>(d); 2135 if (us < d) 2136 ++us; 2137 SysTime st = system_clock::now() + us; 2138 std::cout << "sleep_until "; 2139 __print_time(st); 2140 std::cout << " which is " << (st - system_clock::now()).count() << " 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 << "timed_mutex::try_lock()\n";} 2151 2152 template <class Rep, class Period> 2153 bool try_lock_for(const datetime::duration<Rep, Period>& d) 2154 { 2155 datetime::microseconds t = datetime::duration_cast<datetime::microseconds>(d); 2156 if (t <= datetime::microseconds(0)) 2157 return try_lock(); 2158 std::cout << "try_lock_for " << t.count() << " microseconds\n"; 2159 return true; 2160 } 2161 2162 template <class Clock, class Duration> 2163 bool try_lock_until(const datetime::time_point<Clock, Duration>& t) 2164 { 2165 using namespace datetime; 2166 typedef time_point<Clock, Duration> Time; 2167 typedef system_clock::time_point SysTime; 2168 if (t <= Clock::now()) 2169 return try_lock(); 2170 typedef typename common_type<typename Time::duration, typename Clock::duration>::type D; 2171 <font color="#c80000">/* auto */</font> D d = t - Clock::now(); 2172 microseconds us = duration_cast<microseconds>(d); 2173 SysTime st = system_clock::now() + us; 2174 std::cout << "try_lock_until "; 2175 __print_time(st); 2176 std::cout << " which is " << (st - system_clock::now()).count() << " microseconds away\n"; 2177 } 2178}; 2179 2180struct condition_variable 2181{ 2182 template <class Rep, class Period> 2183 bool wait_for(mutex&, const datetime::duration<Rep, Period>& d) 2184 { 2185 datetime::microseconds t = datetime::duration_cast<datetime::microseconds>(d); 2186 std::cout << "wait_for " << t.count() << " microseconds\n"; 2187 return true; 2188 } 2189 2190 template <class Clock, class Duration> 2191 bool wait_until(mutex&, const datetime::time_point<Clock, Duration>& t) 2192 { 2193 using namespace datetime; 2194 typedef time_point<Clock, Duration> Time; 2195 typedef system_clock::time_point SysTime; 2196 if (t <= Clock::now()) 2197 return false; 2198 typedef typename common_type<typename Time::duration, typename Clock::duration>::type D; 2199 <font color="#c80000">/* auto */</font> D d = t - Clock::now(); 2200 microseconds us = duration_cast<microseconds>(d); 2201 SysTime st = system_clock::now() + us; 2202 std::cout << "wait_until "; 2203 __print_time(st); 2204 std::cout << " which is " << (st - system_clock::now()).count() << " 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 << "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<double>(0.25)); 2241 this_thread::sleep_until(system_clock::now() + duration<double>(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 <class Ratio> 2257class length 2258{ 2259public: 2260 typedef Ratio ratio; 2261private: 2262 double len_; 2263public: 2264 2265 length() : len_(1) {} 2266 length(const double& len) : len_(len) {} 2267 2268 <font color="#c80000">// conversions</font> 2269 template <class R> 2270 length(const length<R>& d) 2271 : len_(d.count() * std::ratio_divide<Ratio, R>::type::den / 2272 std::ratio_divide<Ratio, R>::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& operator+=(const length& d) {len_ += d.count(); return *this;} 2281 length& operator-=(const length& d) {len_ -= d.count(); return *this;} 2282 2283 length operator+() const {return *this;} 2284 length operator-() const {return length(-len_);} 2285 2286 length& operator*=(double rhs) {len_ *= rhs; return *this;} 2287 length& operator/=(double rhs) {len_ /= rhs; return *this;} 2288}; 2289 2290<font color="#c80000">// Sparse sampling of length units</font> 2291typedef length<std::ratio<1> > meter; <font color="#c80000">// set meter as "unity"</font> 2292typedef length<std::centi> centimeter; <font color="#c80000">// 1/100 meter</font> 2293typedef length<std::kilo> kilometer; <font color="#c80000">// 1000 meters</font> 2294typedef length<std::ratio<254, 10000> > 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<std::ratio_multiply<std::ratio<12>, inch::ratio>::type> foot; <font color="#c80000">// 12 inchs</font> 2297typedef length<std::ratio_multiply<std::ratio<5280>, foot::ratio>::type> mile; <font color="#c80000">// 5280 feet</font> 2298 2299<font color="#c80000">// Need a floating point definition of seconds</font> 2300typedef std::datetime::duration<double> seconds; <font color="#c80000">// unity</font> 2301<font color="#c80000">// Demo of (scientific) support for sub-nanosecond resolutions</font> 2302typedef std::datetime::duration<double, std::pico> picosecond; <font color="#c80000">// 10^-12 seconds</font> 2303typedef std::datetime::duration<double, std::femto> femtosecond; <font color="#c80000">// 10^-15 seconds</font> 2304typedef std::datetime::duration<double, std::atto> 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 <class R1, class R2> 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 <> 2320class quantity<std::ratio<1>, std::ratio<0> > 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 <> 2332class quantity<std::ratio<0>, std::ratio<1> > 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 <> 2344class quantity<std::ratio<0>, std::ratio<0> > 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<std::ratio<0>, std::ratio<0> > Scalar; 2357typedef quantity<std::ratio<1>, std::ratio<0> > Time; <font color="#c80000">// second</font> 2358typedef quantity<std::ratio<0>, std::ratio<1> > Distance; <font color="#c80000">// meter</font> 2359typedef quantity<std::ratio<-1>, std::ratio<1> > Speed; <font color="#c80000">// meter/second</font> 2360typedef quantity<std::ratio<-2>, std::ratio<1> > Acceleration; <font color="#c80000">// meter/second^2</font> 2361 2362template <class R1, class R2, class R3, class R4> 2363quantity<typename std::ratio_subtract<R1, R3>::type, typename std::ratio_subtract<R2, R4>::type> 2364operator/(const quantity<R1, R2>& x, const quantity<R3, R4>& y) 2365{ 2366 typedef quantity<typename std::ratio_subtract<R1, R3>::type, typename std::ratio_subtract<R2, R4>::type> R; 2367 R r; 2368 r.set(x.get() / y.get()); 2369 return r; 2370} 2371 2372template <class R1, class R2, class R3, class R4> 2373quantity<typename std::ratio_add<R1, R3>::type, typename std::ratio_add<R2, R4>::type> 2374operator*(const quantity<R1, R2>& x, const quantity<R3, R4>& y) 2375{ 2376 typedef quantity<typename std::ratio_add<R1, R3>::type, typename std::ratio_add<R2, R4>::type> R; 2377 R r; 2378 r.set(x.get() * y.get()); 2379 return r; 2380} 2381 2382template <class R1, class R2> 2383quantity<R1, R2> 2384operator+(const quantity<R1, R2>& x, const quantity<R1, R2>& y) 2385{ 2386 typedef quantity<R1, R2> R; 2387 R r; 2388 r.set(x.get() + y.get()); 2389 return r; 2390} 2391 2392template <class R1, class R2> 2393quantity<R1, R2> 2394operator-(const quantity<R1, R2>& x, const quantity<R1, R2>& y) 2395{ 2396 typedef quantity<R1, R2> 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 <iostream> 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 << "*************\n"; 2420 std::cout << "* testUser1 *\n"; 2421 std::cout << "*************\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 << "Speed = " << s.get() << " meters/sec\n"; 2426 User1::Acceleration a = User1::Distance( User1::foot(32.2) ) / User1::Time() / User1::Time(); 2427 std::cout << "Acceleration = " << a.get() << " meters/sec^2\n"; 2428 User1::Distance df = compute_distance(s, User1::Time( User1::seconds(0.5) ), a); 2429 std::cout << "Distance = " << df.get() << " meters\n"; 2430 std::cout << "There are " << User1::mile::ratio::den << '/' << User1::mile::ratio::num << " miles/meter"; 2431 User1::meter mt = 1; 2432 User1::mile mi = mt; 2433 std::cout << " which is approximately " << mi.count() << '\n'; 2434 std::cout << "There are " << User1::mile::ratio::num << '/' << User1::mile::ratio::den << " meters/mile"; 2435 mi = 1; 2436 mt = mi; 2437 std::cout << " which is approximately " << mt.count() << '\n'; 2438 User1::attosecond as(1); 2439 User1::seconds sec = as; 2440 std::cout << "1 attosecond is " << sec.count() << " seconds\n"; 2441 std::cout << "sec = as; <font color="#c80000">// compiles\n";</font> 2442 sec = User1::seconds(1); 2443 as = sec; 2444 std::cout << "1 second is " << as.count() << " attoseconds\n"; 2445 std::cout << "as = sec; <font color="#c80000">// compiles\n";</font> 2446 std::cout << "\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 <ostream> 2459#include <stdexcept> 2460#include <climits> 2461 2462namespace User2 2463{ 2464 2465template <class I> 2466class saturate 2467{ 2468public: 2469 typedef I int_type; 2470 2471 static const int_type nan = int_type(int_type(1) << (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<int_type>::value && std::is_signed<int_type>::value,</font> 2478<font color="#c80000">// "saturate only accepts signed integral types");</font> 2479<font color="#c80000">// static_assert(nan == -nan && neg_inf < 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& operator+=(saturate x); 2489 saturate& operator-=(saturate x) {return *this += -x;} 2490 saturate& operator*=(saturate x); 2491 saturate& operator/=(saturate x); 2492 saturate& operator%=(saturate x); 2493 2494 saturate operator- () const {return saturate(-i_);} 2495 saturate& operator++() {*this += saturate(int_type(1)); return *this;} 2496 saturate operator++(int) {saturate tmp(*this); ++(*this); return tmp;} 2497 saturate& 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<(saturate x, saturate y) 2516 { 2517 if (x.i_ == nan || y.i_ == nan) 2518 return false; 2519 return x.i_ < y.i_; 2520 } 2521 2522 friend bool operator<=(saturate x, saturate y) 2523 { 2524 if (x.i_ == nan || y.i_ == nan) 2525 return false; 2526 return x.i_ <= y.i_; 2527 } 2528 2529 friend bool operator>(saturate x, saturate y) 2530 { 2531 if (x.i_ == nan || y.i_ == nan) 2532 return false; 2533 return x.i_ > y.i_; 2534 } 2535 2536 friend bool operator>=(saturate x, saturate y) 2537 { 2538 if (x.i_ == nan || y.i_ == nan) 2539 return false; 2540 return x.i_ >= y.i_; 2541 } 2542 2543 friend std::ostream& operator<<(std::ostream& os, saturate s) 2544 { 2545 switch (s.i_) 2546 { 2547 case pos_inf: 2548 return os << "inf"; 2549 case nan: 2550 return os << "nan"; 2551 case neg_inf: 2552 return os << "-inf"; 2553 }; 2554 return os << s.i_; 2555 } 2556}; 2557 2558template <class I> 2559saturate<I>::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 <class I> 2572saturate<I>& 2573saturate<I>::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_ >= 0) 2605 { 2606 if (i_ < pos_inf - x.i_) 2607 i_ += x.i_; 2608 else 2609 i_ = pos_inf; 2610 return *this; 2611 } 2612 if (i_ > neg_inf - x.i_) 2613 i_ += x.i_; 2614 else 2615 i_ = neg_inf; 2616 return *this; 2617} 2618 2619template <class I> 2620saturate<I>& 2621saturate<I>::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_ < 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_ < 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_ < 0) 2669 i_ = neg_inf; 2670 else 2671 i_ = pos_inf; 2672 return *this; 2673 case neg_inf: 2674 if (i_ < 0) 2675 i_ = pos_inf; 2676 else 2677 i_ = neg_inf; 2678 return *this; 2679 } 2680 int s = (i_ < 0 ? -1 : 1) * (x.i_ < 0 ? -1 : 1); 2681 i_ = i_ < 0 ? -i_ : i_; 2682 int_type x_i_ = x.i_ < 0 ? -x.i_ : x.i_; 2683 if (i_ <= pos_inf / x_i_) 2684 i_ *= x_i_; 2685 else 2686 i_ = pos_inf; 2687 i_ *= s; 2688 return *this; 2689} 2690 2691template <class I> 2692saturate<I>& 2693saturate<I>::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_ > 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_ < 0) 2739 i_ = -i_; 2740 return *this; 2741 } 2742 i_ /= x.i_; 2743 return *this; 2744} 2745 2746template <class I> 2747saturate<I>& 2748saturate<I>::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<saturate<long long>, std::pico > picoseconds; 2774typedef std::datetime::duration<saturate<long long>, std::nano > nanoseconds; 2775typedef std::datetime::duration<saturate<long long>, std::micro > microseconds; 2776typedef std::datetime::duration<saturate<long long>, std::milli > milliseconds; 2777typedef std::datetime::duration<saturate<long long> > seconds; 2778typedef std::datetime::duration<saturate<long long>, std::ratio< 60LL> > minutes; 2779typedef std::datetime::duration<saturate<long long>, std::ratio< 3600LL> > hours; 2780typedef std::datetime::duration<saturate<long long>, std::ratio< 86400LL> > days; 2781typedef std::datetime::duration<saturate<long long>, std::ratio< 31556952LL> > years; 2782typedef std::datetime::duration<saturate<long long>, std::ratio<31556952000LL> > 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 <class T1, class T2, bool = tmp::is_integral<T1>::value> 2790struct promote_helper; 2791 2792template <class T1, class T2> 2793struct promote_helper<T1, saturate<T2>, true> <font color="#c80000">// integral</font> 2794{ 2795 typedef typename std::common_type<T1, T2>::type rep; 2796 typedef User2::saturate<rep> type; 2797}; 2798 2799template <class T1, class T2> 2800struct promote_helper<T1, saturate<T2>, false> <font color="#c80000">// floating</font> 2801{ 2802 typedef T1 type; 2803}; 2804 2805} } 2806 2807namespace std 2808{ 2809 2810template <class T1, class T2> 2811struct common_type<User2::saturate<T1>, User2::saturate<T2> > 2812{ 2813 typedef typename common_type<T1, T2>::type rep; 2814 typedef User2::saturate<rep> type; 2815}; 2816 2817template <class T1, class T2> 2818struct common_type<T1, User2::saturate<T2> > 2819 : User2::detail::promote_helper<T1, User2::saturate<T2> > {}; 2820 2821template <class T1, class T2> 2822struct common_type<User2::saturate<T1>, T2> 2823 : User2::detail::promote_helper<T2, User2::saturate<T1> > {}; 2824 2825 2826<font color="#c80000">// Demonstrate specialization of duration_values:</font> 2827 2828namespace datetime { 2829 2830template <class I> 2831struct duration_values<User2::saturate<I> > 2832{ 2833 typedef User2::saturate<I> 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 <iostream> 2845 2846void testUser2() 2847{ 2848 std::cout << "*************\n"; 2849 std::cout << "* testUser2 *\n"; 2850 std::cout << "*************\n"; 2851 using namespace User2; 2852 typedef seconds::rep sat; 2853 years yr(sat(100)); 2854 std::cout << "100 years expressed as years = " << yr.count() << '\n'; 2855 nanoseconds ns = yr; 2856 std::cout << "100 years expressed as nanoseconds = " << ns.count() << '\n'; 2857 ns += yr; 2858 std::cout << "200 years expressed as nanoseconds = " << ns.count() << '\n'; 2859 ns += yr; 2860 std::cout << "300 years expressed as nanoseconds = " << ns.count() << '\n'; 2861<font color="#c80000">// yr = ns; // does not compile</font> 2862 std::cout << "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 << "ps = yr; <font color="#c80000">// does not compile\n";</font> 2865 ns = yr; 2866 picoseconds ps = ns; 2867 std::cout << "100 years expressed as picoseconds = " << ps.count() << '\n'; 2868 ps = ns / sat(1000); 2869 std::cout << "0.1 years expressed as picoseconds = " << ps.count() << '\n'; 2870 yr = years(sat(-200000000)); 2871 std::cout << "200 million years ago encoded in years: " << yr.count() << '\n'; 2872 days d = std::datetime::duration_cast<days>(yr); 2873 std::cout << "200 million years ago encoded in days: " << d.count() << '\n'; 2874 millennium c = std::datetime::duration_cast<millennium>(yr); 2875 std::cout << "200 million years ago encoded in millennium: " << c.count() << '\n'; 2876 std::cout << "Demonstrate \"uninitialized protection\" behavior:\n"; 2877 seconds sec; 2878 for (++sec; sec < seconds(sat(10)); ++sec) 2879 ; 2880 std::cout << sec.count() << '\n'; 2881 std::cout << "\n"; 2882} 2883 2884void testStdUser() 2885{ 2886 std::cout << "***************\n"; 2887 std::cout << "* testStdUser *\n"; 2888 std::cout << "***************\n"; 2889 using namespace std::datetime; 2890 hours hr = hours(100); 2891 std::cout << "100 hours expressed as hours = " << hr.count() << '\n'; 2892 nanoseconds ns = hr; 2893 std::cout << "100 hours expressed as nanoseconds = " << ns.count() << '\n'; 2894 ns += hr; 2895 std::cout << "200 hours expressed as nanoseconds = " << ns.count() << '\n'; 2896 ns += hr; 2897 std::cout << "300 hours expressed as nanoseconds = " << ns.count() << '\n'; 2898<font color="#c80000">// hr = ns; // does not compile</font> 2899 std::cout << "hr = ns; <font color="#c80000">// does not compile\n";</font> 2900<font color="#c80000">// hr * ns; // does not compile</font> 2901 std::cout << "hr * ns; <font color="#c80000">// does not compile\n";</font> 2902 duration<double> fs(2.5); 2903 std::cout << "duration<double> has count() = " << fs.count() << '\n'; 2904<font color="#c80000">// seconds sec = fs; // does not compile</font> 2905 std::cout << "seconds sec = duration<double> won't compile\n"; 2906 seconds sec = duration_cast<seconds>(fs); 2907 std::cout << "seconds has count() = " << sec.count() << '\n'; 2908 std::cout << "\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 < 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 < 0 || tv_usec >= 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<long>(usec % 1000000); 2945 tv_sec = static_cast<long>(usec / 1000000); 2946 fixup(); 2947 } 2948 2949 <font color="#c80000">// explicit</font> 2950 operator long long() const {return static_cast<long long>(tv_sec) * 1000000 + tv_usec;} 2951 2952 xtime& operator += (xtime rhs) { 2953 tv_sec += rhs.tv_sec; 2954 tv_usec += rhs.tv_usec; 2955 if (tv_usec >= 1000000) { 2956 tv_usec -= 1000000; 2957 ++tv_sec; 2958 } 2959 return *this; 2960 } 2961 2962 xtime& operator -= (xtime rhs) { 2963 tv_sec -= rhs.tv_sec; 2964 tv_usec -= rhs.tv_usec; 2965 fixup(); 2966 return *this; 2967 } 2968 2969 xtime& 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 && x.tv_usec == y.tv_usec); } 2985 2986 friend bool operator<(xtime x, xtime y) { 2987 if (x.tv_sec == y.tv_sec) 2988 return (x.tv_usec < y.tv_usec); 2989 return (x.tv_sec < y.tv_sec); 2990 } 2991 2992 friend bool operator!=(xtime x, xtime y) { return !(x == y); } 2993 friend bool operator> (xtime x, xtime y) { return y < x; } 2994 friend bool operator<=(xtime x, xtime y) { return !(y < x); } 2995 friend bool operator>=(xtime x, xtime y) { return !(x < y); } 2996 2997 friend std::ostream& operator<<(std::ostream& os, xtime x) 2998 {return os << '{' << x.tv_sec << ',' << x.tv_usec << '}';} 2999}; 3000 3001class xtime_clock 3002{ 3003public: 3004 typedef xtime rep; 3005 typedef std::micro period; 3006 typedef std::datetime::duration<rep, period> duration; 3007 typedef std::datetime::time_point<xtime_clock> 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*)&t, 0); 3017 return t; 3018} 3019 3020void test_xtime_clock() 3021{ 3022 using namespace std::datetime; 3023 std::cout << "timeval_demo system clock test\n"; 3024 std::cout << "sizeof xtime_clock::time_point = " << sizeof(xtime_clock::time_point) << '\n'; 3025 std::cout << "sizeof xtime_clock::duration = " << sizeof(xtime_clock::duration) << '\n'; 3026 std::cout << "sizeof xtime_clock::rep = " << sizeof(xtime_clock::rep) << '\n'; 3027 xtime_clock::duration delay(milliseconds(5)); 3028 xtime_clock::time_point start = xtime_clock::now(); 3029 while (xtime_clock::now() - start <= delay) 3030 ; 3031 xtime_clock::time_point stop = xtime_clock::now(); 3032 xtime_clock::duration elapsed = stop - start; 3033 std::cout << "paused " << nanoseconds(elapsed).count() << " 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<double, std::nano> tonanosec; 3054 3055 duration() {} <font color="#c80000">// = default;</font> 3056 explicit duration(const rep& r) : rep_(r) {} 3057 3058 <font color="#c80000">// conversions</font> 3059 explicit duration(const tonanosec& d) 3060 : rep_(static_cast<rep>(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& operator+=(const duration& d) {rep_ += d.rep_; return *this;} 3072 duration& operator-=(const duration& d) {rep_ += d.rep_; return *this;} 3073 duration& operator*=(rep rhs) {rep_ *= rhs; return *this;} 3074 duration& operator/=(rep rhs) {rep_ /= rhs; return *this;} 3075 3076 duration operator+() const {return *this;} 3077 duration operator-() const {return duration(-rep_);} 3078 duration& operator++() {++rep_; return *this;} 3079 duration operator++(int) {return duration(rep_++);} 3080 duration& 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< (duration x, duration y) {return x.rep_ < y.rep_;} 3092 friend bool operator<=(duration x, duration y) {return !(y < x);} 3093 friend bool operator> (duration x, duration y) {return y < x;} 3094 friend bool operator>=(duration x, duration y) {return !(x < y);} 3095}; 3096 3097static 3098double 3099init_duration() 3100{ 3101 mach_timebase_info_data_t MachInfo; 3102 mach_timebase_info(&MachInfo); 3103 return static_cast<double>(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& d) 3124 : rep_(d.count()) {} 3125 3126 <font color="#c80000">// arithmetic</font> 3127 3128 time_point& operator+=(const duration& d) {rep_ += d.count(); return *this;} 3129 time_point& operator-=(const duration& 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 << "runtime_resolution test\n"; 3151 clock::duration delay(std::datetime::milliseconds(5)); 3152 clock::time_point start = clock::now(); 3153 while (clock::now() - start <= delay) 3154 ; 3155 clock::time_point stop = clock::now(); 3156 clock::duration elapsed = stop - start; 3157 std::cout << "paused " << nanoseconds(duration_cast<nanoseconds>(duration::tonanosec(elapsed))).count() 3158 << " nanoseconds\n"; 3159} 3160 3161} <font color="#c80000">// runtime_resolution</font> 3162 3163<font color="#c80000">// miscellaneous tests and demos:</font> 3164 3165#include <cassert> 3166#include <iostream> 3167 3168using namespace std::datetime; 3169 3170void physics_function(duration<double> d) 3171{ 3172 std::cout << "d = " << d.count() << '\n'; 3173} 3174 3175void drive_physics_function() 3176{ 3177 physics_function(nanoseconds(3)); 3178 physics_function(hours(3)); 3179 physics_function(duration<double>(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 << "292 years of hours = " << h1.count() << "hr\n"; 3191 std::cout << "Add a nanosecond = " << n1.count() << "ns\n"; 3192 std::cout << "Find the difference = " << delta.count() << "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 << "244,000 years of hours = " << h1.count() << "hr\n"; 3202 std::cout << "Add a microsecond = " << u1.count() << "us\n"; 3203 std::cout << "Find the difference = " << delta.count() << "us\n"; 3204} 3205 3206template <class Rep, class Period> 3207void inspect_duration(std::datetime::duration<Rep, Period> d, const std::string& name) 3208{ 3209 typedef std::datetime::duration<Rep, Period> Duration; 3210 std::cout << "********* " << name << " *********\n"; 3211 std::cout << "The period of " << name << " is " << (double)Period::num/Period::den << " seconds.\n"; 3212 std::cout << "The frequency of " << name << " is " << (double)Period::den/Period::num << " Hz.\n"; 3213 std::cout << "The representation is "; 3214 if (tmp::is_floating_point<Rep>::value) 3215 { 3216 std::cout << "floating point\n"; 3217 std::cout << "The precision is the most significant "; 3218 std::cout << std::numeric_limits<Rep>::digits10 << " decimal digits.\n"; 3219 } 3220 else if (tmp::is_integral<Rep>::value) 3221 { 3222 std::cout << "integral\n"; 3223 d = Duration(Rep(1)); 3224 std::datetime::duration<double> dsec = d; 3225 std::cout << "The precision is " << dsec.count() << " seconds.\n"; 3226 } 3227 else 3228 { 3229 std::cout << "a class type\n"; 3230 d = Duration(Rep(1)); 3231 std::datetime::duration<double> dsec = d; 3232 std::cout << "The precision is " << dsec.count() << " seconds.\n"; 3233 } 3234 d = Duration(std::numeric_limits<Rep>::max()); 3235 using namespace std::datetime; 3236 using namespace std; 3237 typedef duration<double, ratio_multiply<ratio<24*3652425,10000>, hours::period>::type> Years; 3238 Years years = d; 3239 std::cout << "The range is +/- " << years.count() << " years.\n"; 3240 std::cout << "sizeof(" << name << ") = " << sizeof(d) << '\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<double>(), "duration<double>"); 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 << "success\n"; 3265 else 3266 std::cout << "failure: " << msdiff.count() << '\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 <class To, class Rep, class Period> 3275To 3276round_up(duration<Rep, Period> d) 3277{ 3278 To result = duration_cast<To>(d); 3279 if (result < 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 <class Rep, class Period> 3295xtime 3296to_xtime_truncate(duration<Rep, Period> d) 3297{ 3298 xtime xt; 3299 xt.sec = duration_cast<seconds>(d).count(); 3300 xt.usec = duration_cast<microseconds>(d - seconds(xt.sec)).count(); 3301 return xt; 3302} 3303 3304template <class Rep, class Period> 3305xtime 3306to_xtime_round_up(duration<Rep, Period> d) 3307{ 3308 xtime xt; 3309 xt.sec = duration_cast<seconds>(d).count(); 3310 xt.usec = round_up<microseconds>(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 << '{' << xt.sec << ',' << xt.usec << "}\n"; 3323} 3324 3325void test_with_xtime() 3326{ 3327 cout << "test_with_xtime\n"; 3328 xtime xt = to_xtime_truncate(seconds(3) + milliseconds(251)); 3329 print(xt); 3330 milliseconds ms = duration_cast<milliseconds>(from_xtime(xt)); 3331 cout << ms.count() << " 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 << "system_clock test" << endl; 3343 system_clock::duration delay = milliseconds(5); 3344 system_clock::time_point start = system_clock::now(); 3345 while (system_clock::now() - start <= delay) 3346 ; 3347 system_clock::time_point stop = system_clock::now(); 3348 system_clock::duration elapsed = stop - start; 3349 cout << "paused " << nanoseconds(elapsed).count() << " nanoseconds\n"; 3350 start = system_clock::now(); 3351 stop = system_clock::now(); 3352 cout << "system_clock resolution estimate: " << nanoseconds(stop-start).count() << " nanoseconds\n"; 3353} 3354 3355void test_monotonic_clock() 3356{ 3357 cout << "monotonic_clock test" << endl; 3358 monotonic_clock::duration delay = milliseconds(5); 3359 monotonic_clock::time_point start = monotonic_clock::now(); 3360 while (monotonic_clock::now() - start <= delay) 3361 ; 3362 monotonic_clock::time_point stop = monotonic_clock::now(); 3363 monotonic_clock::duration elapsed = stop - start; 3364 cout << "paused " << nanoseconds(elapsed).count() << " nanoseconds\n"; 3365 start = monotonic_clock::now(); 3366 stop = monotonic_clock::now(); 3367 cout << "monotonic_clock resolution estimate: " << nanoseconds(stop-start).count() << " nanoseconds\n"; 3368} 3369 3370void test_hi_resolution_clock() 3371{ 3372 cout << "high_resolution_clock test" << 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 <= delay) 3376 ; 3377 high_resolution_clock::time_point stop = high_resolution_clock::now(); 3378 high_resolution_clock::duration elapsed = stop - start; 3379 cout << "paused " << nanoseconds(elapsed).count() << " nanoseconds\n"; 3380 start = high_resolution_clock::now(); 3381 stop = high_resolution_clock::now(); 3382 cout << "high_resolution_clock resolution estimate: " << nanoseconds(stop-start).count() << " nanoseconds\n"; 3383} 3384 3385void test_mixed_clock() 3386{ 3387 cout << "mixed clock test" << endl; 3388 high_resolution_clock::time_point hstart = high_resolution_clock::now(); 3389 cout << "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 << "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 << "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<system_clock::duration>(mend - hstart); 3398 cout << "subtract two system_clock::time_point's and output that in microseconds:\n"; 3399 microseconds ms = send - sstart; 3400 cout << ms.count() << " microseconds\n"; 3401} 3402 3403void test_c_mapping() 3404{ 3405 cout << "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(&c_time); 3410 std::cout << "It is now " << tmptr->tm_hour << ':' << tmptr->tm_min << ':' << tmptr->tm_sec << ' ' 3411 << tmptr->tm_year + 1900 << '-' << tmptr->tm_mon + 1 << '-' << tmptr->tm_mday << '\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 << "Round-tripping through the C interface truncated the precision by " << ms.count() << " microseconds\n"; 3416} 3417 3418void test_duration_division() 3419{ 3420 cout << hours(3) / milliseconds(5) << '\n'; 3421 cout << milliseconds(5) / hours(3) << '\n'; 3422 cout << hours(1) / milliseconds(1) << '\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 <class R> 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& operator+=(zero_default x) {rep_ += x.rep_; return *this;} 3443 zero_default& operator-=(zero_default x) {rep_ -= x.rep_; return *this;} 3444 zero_default& operator*=(zero_default x) {rep_ *= x.rep_; return *this;} 3445 zero_default& 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& operator++() {++rep_; return *this;} 3450 zero_default operator++(int) {return zero_default(rep_++);} 3451 zero_default& 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< (zero_default x, zero_default y) {return x.rep_ < y.rep_;} 3462 friend bool operator<=(zero_default x, zero_default y) {return !(y < x);} 3463 friend bool operator> (zero_default x, zero_default y) {return y < x;} 3464 friend bool operator>=(zero_default x, zero_default y) {return !(x < y);} 3465}; 3466 3467typedef std::datetime::duration<zero_default<long long>, std::nano > nanoseconds; 3468typedef std::datetime::duration<zero_default<long long>, std::micro > microseconds; 3469typedef std::datetime::duration<zero_default<long long>, std::milli > milliseconds; 3470typedef std::datetime::duration<zero_default<long long> > seconds; 3471typedef std::datetime::duration<zero_default<long long>, std::ratio<60> > minutes; 3472typedef std::datetime::duration<zero_default<long long>, std::ratio<3600> > hours; 3473 3474void test() 3475{ 3476 milliseconds ms; 3477 cout << ms.count() << '\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 <class Rep, class Period> 3485void 3486print_duration(ostream& os, duration<Rep, Period> d) 3487{ 3488 os << d.count() << " * " << Period::num << '/' << Period::den << " 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 <class Clock, class Duration1, class Duration2> 3494inline 3495typename common_type<time_point<Clock, Duration1>, time_point<Clock, Duration2> >::type 3496min(time_point<Clock, Duration1> t1, time_point<Clock, Duration2> t2) 3497{ 3498 return t2 < t1 ? t2 : t1; 3499} 3500 3501void test_min() 3502{ 3503 typedef time_point<system_clock, common_type<system_clock::duration, seconds>::type> T1; 3504 typedef time_point<system_clock, common_type<system_clock::duration, nanoseconds>::type> T2; 3505 typedef common_type<T1, T2>::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<long long, ratio_multiply<ratio<24*3652425,10000>, hours::period>::type> 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<microseconds>(t1) - time_point_cast<microseconds>(t2); 3521 cout << d.count() << " 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 <= delay) 3529 ; 3530 system_clock::time_point stop = clock.now(); 3531 system_clock::duration elapsed = stop - start; 3532 cout << "paused " << nanoseconds(elapsed).count() << " nanoseconds\n"; 3533}; 3534 3535template <long long speed> 3536struct cycle_count 3537{ 3538 typedef typename ratio_multiply<ratio<speed>, mega>::type frequency; <font color="#c80000">// Mhz</font> 3539 typedef typename ratio_divide<ratio<1>, frequency>::type period; 3540 typedef long long rep; 3541 typedef std::datetime::duration<rep, period> duration; 3542 typedef std::datetime::time_point<cycle_count> 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 <long long speed> 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<approx_cycle_count> 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<400> clock; 3575 cout << "\nSimulated " << clock::frequency::num / mega::num << "MHz clock which has a tick period of " 3576 << duration<double, nano>(clock::duration(1)).count() << " nanoseconds\n"; 3577 nanoseconds delayns(500); 3578 clock::duration delay = duration_cast<clock::duration>(delayns); 3579 cout << "delay = " << delayns.count() << " nanoseconds which is " << delay.count() << " cycles\n"; 3580 clock::time_point start = clock::now(); 3581 clock::time_point stop = start + delay; 3582 while (clock::now() < 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 << "paused " << elapsed.count() << " cycles "; 3587 cout << "which is " << duration_cast<nanoseconds>(elapsed).count() << " nanoseconds\n"; 3588 } 3589 { 3590 typedef approx_cycle_count<400> clock; 3591 cout << "\nSimulated " << clock::frequency / 1000000 << "MHz clock modeled with nanoseconds\n"; 3592 clock::duration delay = nanoseconds(500); 3593 cout << "delay = " << delay.count() << " nanoseconds\n"; 3594 clock::time_point start = clock::now(); 3595 clock::time_point stop = start + delay; 3596 while (clock::now() < 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 << "paused " << elapsed.count() << " nanoseconds\n"; 3601 } 3602 { 3603 typedef cycle_count<1500> clock; 3604 cout << "\nSimulated " << clock::frequency::num / mega::num << "MHz clock which has a tick period of " 3605 << duration<double, nano>(clock::duration(1)).count() << " nanoseconds\n"; 3606 nanoseconds delayns(500); 3607 clock::duration delay = duration_cast<clock::duration>(delayns); 3608 cout << "delay = " << delayns.count() << " nanoseconds which is " << delay.count() << " cycles\n"; 3609 clock::time_point start = clock::now(); 3610 clock::time_point stop = start + delay; 3611 while (clock::now() < 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 << "paused " << elapsed.count() << " cycles "; 3616 cout << "which is " << duration_cast<nanoseconds>(elapsed).count() << " nanoseconds\n"; 3617 } 3618 { 3619 typedef approx_cycle_count<1500> clock; 3620 cout << "\nSimulated " << clock::frequency / 1000000 << "MHz clock modeled with nanoseconds\n"; 3621 clock::duration delay = nanoseconds(500); 3622 cout << "delay = " << delay.count() << " nanoseconds\n"; 3623 clock::time_point start = clock::now(); 3624 clock::time_point stop = start + delay; 3625 while (clock::now() < 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 << "paused " << elapsed.count() << " nanoseconds\n"; 3630 } 3631} 3632 3633void test_special_values() 3634{ 3635 std::cout << "duration<unsigned>::min().count() = " << duration<unsigned>::min().count() << '\n'; 3636 std::cout << "duration<unsigned>::zero().count() = " << duration<unsigned>::zero().count() << '\n'; 3637 std::cout << "duration<unsigned>::max().count() = " << duration<unsigned>::max().count() << '\n'; 3638 std::cout << "duration<int>::min().count() = " << duration<int>::min().count() << '\n'; 3639 std::cout << "duration<int>::zero().count() = " << duration<int>::zero().count() << '\n'; 3640 std::cout << "duration<int>::max().count() = " << duration<int>::max().count() << '\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<duration<double>, hours, microseconds>::type(), 3667 "common_type<duration<double>, hours, microseconds>::type"); 3668#endif 3669 explore_limits(); 3670 manipulate_clock_object(system_clock()); 3671 duration<double, milli> d = milliseconds(3) * 2.5; 3672 inspect_duration(milliseconds(3) * 2.5, "milliseconds(3) * 2.5"); 3673 cout << d.count() << '\n'; 3674<font color="#c80000">// milliseconds ms(3.5); // doesn't compile</font> 3675 cout << "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<double> has count() = 2.5 3703seconds sec = duration<double> 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<double> ********* 3789The period of duration<double> is 1 seconds. 3790The frequency of duration<double> 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<double>) = 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<unsigned>::min().count() = 0 3861duration<unsigned>::zero().count() = 0 3862duration<unsigned>::max().count() = 4294967295 3863duration<int>::min().count() = -2147483647 3864duration<int>::zero().count() = 0 3865duration<int>::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<seconds>(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<milliseconds>(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>