Photon microGUI widgets library 0.6.0
chrono.hpp
1#ifndef _STDEX_CHRONO_H
2#define _STDEX_CHRONO_H
3
4#if _MSC_VER > 1000
5#pragma once
6#endif // _MSC_VER > 1000
7
8// stdex includes
9#include "./cstdint.hpp" // stdex::intmax_t, STDEX_INTMAX_MAX, STDEX_INTMAX_MIN
10#include "./ratio.hpp" // all ratio
11#include "./type_traits.hpp" // stdex::common_type, stdex::is_floating_point
12#include "./ctime.hpp"
13
14// POSIX includes
15/*none*/
16
17// std includes
18//#include <climits> //???
19#include <limits> // std::numeric_limit
20#include <stdexcept>
21
22
23#ifdef _STDEX_NATIVE_CPP11_SUPPORT
24
25#define _STDEX_DELETED_FUNCTION =delete
26#define _STDEX_NOEXCEPT_FUNCTION noexcept
27
28#else
29
30#define _STDEX_DELETED_FUNCTION
31#define _STDEX_NOEXCEPT_FUNCTION throw()
32
33#endif
34
35namespace stdex
36{
37 namespace detail
38 {
39 template<class>
40 struct _chrono_force_tmpl_param{};
41 }
42
43 namespace chrono
44 {
45 namespace detail
46 {
47 template<unsigned _Rank> struct _priority_tag : _priority_tag < _Rank - 1 > {};
48 template<> struct _priority_tag<0> {};
49
50 template<class _Tp>
51 struct _is_ratio
52 {
53 static const bool value = false;
54 };
55
56 template<stdex::intmax_t _Num, stdex::intmax_t _Den>
57 struct _is_ratio<stdex::ratio<_Num, _Den>>
58 {
59 static const bool value = true;
60 };
61
62 template<class _Tp, bool>
63 struct _sizeof_ratio_members_helper
64 {
65 enum
66 {
67 num = sizeof(_Tp::num),
68 den = sizeof(_Tp::den)
69 };
70 };
71
72 template<class _Tp>
73 struct _sizeof_ratio_members_helper<_Tp, false>
74 {
75 enum
76 {
77 num = 0,
78 den = 0
79 };
80 };
81
82 template<class _Tp>
83 struct _sizeof_ratio_members
84 : _sizeof_ratio_members_helper<_Tp, _is_ratio<_Tp>::value>
85 { };
86
87
88 template<class _Rep, class _Period, bool>
89 struct _use_big_int_impl
90 {
91 static const bool value = false;
92 };
93
94 template<class _Rep, class _Period>
95 struct _use_big_int_impl<_Rep, _Period, true>
96 {
97 static const bool value =
98 is_integral<_Rep>::value &&
99 (sizeof(_Rep) * CHAR_BIT) < 64;
100 };
101
102 template<class _Rep, class _Period>
103 struct _use_big_int :
104 _use_big_int_impl<_Rep, _Period, _is_ratio<_Period>::value>
105 { };
106 }
107
108 template <class _Rep, class _Period = ratio<1>>
109 class duration;
110
111 template<class _Clock, class _Dur = typename _Clock::duration>
112 class time_point;
113
114 template <class _Rep>
115 struct treat_as_floating_point :
116 stdex::is_floating_point<_Rep> {};
117 }
118
119 template<class _Rep1, class _Period1, class _Rep2, class _Period2>
120 struct common_type<chrono::duration<_Rep1, _Period1>,
121 chrono::duration<_Rep2, _Period2> >
122 {
123 private:
124 typedef detail::_gcd<_Period1::num, _Period2::num> _gcd_num;
125 typedef detail::_gcd<_Period1::den, _Period2::den> _gcd_den;
126 typedef typename common_type<_Rep1, _Rep2>::type _cr;
127 typedef ratio<_gcd_num::value,
128 stdex::intmax_t( (_Period1::den / _gcd_den::value) * _Period2::den )> _r;
129
130 public:
131 typedef chrono::duration<_cr, _r> type;
132 };
133
134 // specialization of common_type (for time_point)
135 template<class _Clock, class _Dur1, class _Dur2>
136 struct common_type<chrono::time_point<_Clock, _Dur1>,
137 chrono::time_point<_Clock, _Dur2> >
138 {
139 private:
140 typedef typename common_type<_Dur1, _Dur2>::type _ct;
141
142 public:
143 typedef chrono::time_point<_Clock, _ct> type;
144 };
145
146 namespace chrono
147 {
148 namespace detail
149 {
150 // this structure is used internally to represent platform specific big integers
151 // and safe number precision checks (throws out_of_range)
152 struct _big_int
153 {
154 char least64_value[8];
155
156 _big_int(stdex::intmax_t _value = 0);
157
158 _big_int(const _big_int&);
159 _big_int& operator=(const _big_int&);
160
161 _big_int operator+() const;
162 _big_int operator-() const;
163
164 _big_int& operator++();
165 _big_int operator++(int);
166 _big_int& operator--();
167 _big_int operator--(int);
168
169 _big_int& operator+=(const _big_int&);
170 _big_int& operator-=(const _big_int&);
171 _big_int& operator*=(const _big_int&);
172 _big_int& operator/=(const _big_int&);
173 _big_int& operator%=(const _big_int&);
174
175 stdex::intmax_t to_integer() const;
176 long double to_floating_point() const;
177 };
178
179 _big_int operator+(const _big_int&, const _big_int&);
180 _big_int operator-(const _big_int&, const _big_int&);
181 _big_int operator*(const _big_int&, const _big_int&);
182 _big_int operator/(const _big_int&, const _big_int&);
183 _big_int operator%(const _big_int&, const _big_int&);
184
185 bool operator< (const _big_int&, const _big_int&);
186 bool operator> (const _big_int&, const _big_int&);
187 bool operator==(const _big_int&, const _big_int&);
188 bool operator!=(const _big_int&, const _big_int&);
189 bool operator>=(const _big_int&, const _big_int&);
190 bool operator<=(const _big_int&, const _big_int&);
191
192 class _disabled_big_int_operator;
193
194 template<class _Tp>
195 inline
196 _big_int operator+(const _Tp& _lhs,
197 typename
198 conditional<is_integral<_Tp>::value, const _big_int&, _disabled_big_int_operator>::type _rhs)
199 {
200 return _big_int(_lhs) + _rhs;
201 }
202
203 template<class _Tp>
204 inline
205 _big_int operator-(const _Tp& _lhs,
206 typename
207 conditional<is_integral<_Tp>::value, const _big_int&, _disabled_big_int_operator>::type _rhs)
208 {
209 return _big_int(_lhs) - _rhs;
210 }
211
212 template<class _Tp>
213 inline
214 _big_int operator*(const _Tp& _lhs,
215 typename
216 conditional<is_integral<_Tp>::value, const _big_int&, _disabled_big_int_operator>::type _rhs)
217 {
218 return _big_int(_lhs) * _rhs;
219 }
220
221 template<class _Tp>
222 inline
223 _big_int operator/(const _Tp& _lhs,
224 typename
225 conditional<is_integral<_Tp>::value, const _big_int&, _disabled_big_int_operator>::type _rhs)
226 {
227 return _big_int(_lhs) / _rhs;
228 }
229
230 template<class _Tp>
231 inline
232 _big_int operator%(const _Tp& _lhs,
233 typename
234 conditional<is_integral<_Tp>::value, const _big_int&, _disabled_big_int_operator>::type _rhs)
235 {
236 return _big_int(_lhs) % _rhs;
237 }
238
239 template<int>
240 class _disabled_chrono_convert;
241
242 template<class _To, class _From>
243 inline
244 _To _chrono_convert(_From _from,
245 typename
246 conditional<bool(
247 is_same<typename remove_reference<typename remove_cv<_From>::type>::type, _big_int>::value == bool(false) &&
248 is_same<typename remove_reference<typename remove_cv<_To>::type>::type, _big_int>::value == bool(false) ),
249 const _priority_tag<0>&,
250 _disabled_chrono_convert<__LINE__>&
251 >::type)
252 {
253 return static_cast<_To>(_from);
254 }
255
256 template<class _To, class _From>
257 inline
258 _To _chrono_convert(_From _from,
259 typename
260 conditional<bool(
261 is_same<typename remove_reference<typename remove_cv<_From>::type>::type, _big_int>::value == bool(false) &&
262 is_same<typename remove_reference<typename remove_cv<_To>::type>::type, _big_int>::value == bool(true) ),
263 const _priority_tag<1>&,
264 _disabled_chrono_convert<__LINE__>&
265 >::type)
266 {
267 return intmax_t(_from);
268 }
269
270 template<class _To, class _From>
271 inline
272 _To _chrono_convert(const _From& _from,
273 typename
274 conditional<bool(
275 is_same<typename remove_reference<typename remove_cv<_From>::type>::type, _big_int>::value == bool(true) &&
276 is_same<typename remove_reference<typename remove_cv<_To>::type>::type, _big_int>::value == bool(false) &&
277 is_floating_point<_To>::value == bool(true) ),
278 const _priority_tag<2>&,
279 _disabled_chrono_convert<__LINE__>&
280 >::type)
281 {
282 return _To(_from.to_floating_point());
283 }
284
285 template<class _To, class _From>
286 inline
287 _To _chrono_convert(const _From& _from,
288 typename
289 conditional<bool(
290 is_same<typename remove_reference<typename remove_cv<_From>::type>::type, _big_int>::value == bool(true) &&
291 is_same<typename remove_reference<typename remove_cv<_To>::type>::type, _big_int>::value == bool(false) &&
292 is_floating_point<_To>::value == bool(false) ),
293 const _priority_tag<3>&,
294 _disabled_chrono_convert<__LINE__>&
295 >::type)
296 {
297 return _To(_from.to_integer());
298 }
299
300 template<class _To, class _From>
301 inline
302 _To _chrono_convert(const _From& _from,
303 typename
304 conditional<bool(
305 is_same<typename remove_reference<typename remove_cv<_From>::type>::type, _big_int>::value == bool(true) &&
306 is_same<typename remove_reference<typename remove_cv<_To>::type>::type, _big_int>::value == bool(true) ),
307 const _priority_tag<4>&,
308 _disabled_chrono_convert<__LINE__>&
309 >::type)
310 {
311 return _from;
312 }
313
314
315 struct _chrono_convert_func
316 {
317 template<class _To, class _From>
318 static _To call(const _From& _from, const stdex::detail::_chrono_force_tmpl_param<_To>&)
319 {
320 return _chrono_convert<_To>(_from, _priority_tag<4>());
321 }
322 };
323
324 template <class _Rep, class _Period,
325 bool _Fallback>
326 class duration_base;
327
328 struct duration_secret
329 {
330 template<class _Rep, class _Period,
331 bool _Fallback>
332 static
333 typename
334 duration_base<_Rep, _Period, _Fallback>::
335 internal_value_type duration_count(
336 const duration_base<_Rep, _Period, _Fallback> &_dur)
337 {
338 return _dur._r;
339 }
340 };
341
342 template <class _Rep, class _Period>
343 class duration_base<_Rep, _Period, false>
344 {
345 protected:
346
347 typedef _Rep internal_value_type;
348 internal_value_type _r;
349
350 template <class _Rep2>
351 duration_base(const _Rep2& _r_in) :
352 _r(_chrono_convert<_Rep>(_r_in, _priority_tag<4>())) {}
353
354 friend
355 struct stdex::chrono::detail::duration_secret;
356 };
357
358 template <class _Rep, class _Period>
359 class duration_base<_Rep, _Period, true>
360 {
361 protected:
362
363 typedef _big_int internal_value_type;
364 internal_value_type _r;
365
366 duration_base(const internal_value_type& _r_in) :
367 _r(_r_in) {}
368
369 template <class _Rep2>
370 duration_base(const _Rep2& _r_in) :
371 _r(_chrono_convert<_Rep>(_r_in, _priority_tag<4>())) {}
372
373
374 friend
375 struct stdex::chrono::detail::duration_secret;
376 };
377
378 struct _duration_count_func
379 {
380 template <class _Rep, class _Period>
381 static _Rep call(
382 const duration_base<_Rep, _Period, false>& _dur)
383 {
384 return duration_secret::duration_count(_dur);
385 }
386 template <class _Rep, class _Period>
387 static _big_int call(
388 const duration_base<_Rep, _Period, true>& _dur)
389 {
390 return duration_secret::duration_count(_dur);
391 }
392 };
393
394 template<class _ToRep, class _FromRep, bool>
395 struct _duration_common_type_impl
396 {
397 typedef _big_int type;
398 };
399
400 template<class _ToRep, class _FromRep>
401 struct _duration_common_type_impl<_ToRep, _FromRep, false>
402 {
403 typedef
404 typename
405 common_type<_ToRep, _FromRep, stdex::intmax_t>::type type;
406 };
407
408 template<class _ToRep, class _FromRep, class _Period>
409 struct _duration_common_type:
410 _duration_common_type_impl <
411 _ToRep,
412 _FromRep,
413 _use_big_int<
414 typename
415 common_type<_ToRep, _FromRep, stdex::intmax_t>::type,
416 _Period
417 >::value
418 >
419 { };
420
421 /*template<class _Tp>
422 struct _can_be_big_int
423 {
424 typedef
425 typename remove_reference<
426 typename remove_cv<_Tp>::type
427 >::type type;
428
429 static const bool value =
430 is_same<type, _big_int>::value == bool(true) ||
431 is_integral<type>::value == bool(true) ||
432 is_floating_point<type>::value == bool(true);
433 };*/
434
435
436
437 // Primary template for duration_cast impl.
438 template<class _ToDur, class _CR,
439 bool _NumIsOne = false, bool _DenIsOne = false>
440 struct _duration_cast_ct_impl
441 {
442 template<class _Rep, class _Period, class _CF>
443 static _ToDur _cast(const duration<_Rep, _Period>& _d, const _CF &_cf)
444 {
445 typedef typename _ToDur::rep _to_dur_rep;
446 typedef
447 typename
448 detail::_duration_common_type<_to_dur_rep, _to_dur_rep, _Period>::type
449 _to_rep;
450 return _ToDur(
451 _chrono_convert<_to_rep>(
452 _chrono_convert<_CR>(_duration_count_func::call(_d), _priority_tag<4>())
453 * _chrono_convert<_CR>(_cf.num, _priority_tag<4>())
454 / _chrono_convert<_CR>(_cf.den, _priority_tag<4>())
455 , _priority_tag<4>())
456 );
457 }
458 };
459
460 template<class _ToDur, class _CR>
461 struct _duration_cast_ct_impl<_ToDur, _CR, true, true>
462 {
463 template<class _Rep, class _Period, class _CF>
464 static _ToDur _cast(const duration<_Rep, _Period>& _d, const _CF&)
465 {
466 typedef typename _ToDur::rep _to_dur_rep;
467 typedef
468 typename
469 detail::_duration_common_type<_to_dur_rep, _to_dur_rep, _Period>::type
470 _to_rep;
471 return _ToDur(
472 _chrono_convert<_to_rep>(
473 _duration_count_func::call(_d),
474 _priority_tag<4>())
475 );
476 }
477 };
478
479 template<class _ToDur, class _CR>
480 struct _duration_cast_ct_impl<_ToDur, _CR, true, false>
481 {
482 template<class _Rep, class _Period, class _CF>
483 static _ToDur _cast(const duration<_Rep, _Period>& _d, const _CF &_cf)
484 {
485 typedef typename _ToDur::rep _to_dur_rep;
486 typedef
487 typename
488 detail::_duration_common_type<_to_dur_rep, _to_dur_rep, _Period>::type
489 _to_rep;
490 (void)(_cf); // removes stupid MS warning of unreferenced formal parameter
491 return _ToDur(
492 _chrono_convert<_to_rep>(
493 _chrono_convert<_CR>(_duration_count_func::call(_d), _priority_tag<4>()) /
494 _chrono_convert<_CR>(_cf.den, _priority_tag<4>())
495 , _priority_tag<4>())
496 );
497 }
498 };
499
500 template<class _ToDur, class _CR>
501 struct _duration_cast_ct_impl<_ToDur, _CR, false, true>
502 {
503 template<class _Rep, class _Period, class _CF>
504 static _ToDur _cast(const duration<_Rep, _Period>& _d, const _CF &_cf)
505 {
506 typedef typename _ToDur::rep _to_dur_rep;
507 typedef
508 typename
509 detail::_duration_common_type<_to_dur_rep, _to_dur_rep, _Period>::type
510 _to_rep;
511 (void)(_cf); // removes stupid MS warning of unreferenced formal parameter
512 return _ToDur(
513 _chrono_convert<_to_rep>(
514 _chrono_convert<_CR>(_duration_count_func::call(_d), _priority_tag<4>()) *
515 _chrono_convert<_CR>(_cf.num, _priority_tag<4>()),
516 _priority_tag<4>())
517 );
518 }
519 };
520
521 template<class _ToDur, class _CR>
522 struct _duration_cast_rt_impl
523 {
524 template<class _Rep, class _Period, class _CF>
525 static _ToDur _cast(const duration<_Rep, _Period>& _d, const _CF &_cf)
526 {
527 if(_cf.den != 1 && _cf.num != 1)
528 return _duration_cast_ct_impl<
529 _ToDur, _CR, false, false>::_cast(_d, _cf);
530 if(_cf.den == 1 && _cf.num == 1)
531 return _duration_cast_ct_impl<
532 _ToDur, _CR, true, true>::_cast(_d, _cf);
533 if(_cf.num == 1)
534 return _duration_cast_ct_impl<
535 _ToDur, _CR, true, false>::_cast(_d, _cf);
536
537 return _duration_cast_ct_impl<
538 _ToDur, _CR, false, true>::_cast(_d, _cf);
539 }
540 };
541
542 template<class _Tp>
543 struct _is_duration
544 {
545 static const bool value = false;
546 };
547
548 template<class _Rep, class _Period>
549 struct _is_duration<duration<_Rep, _Period>>
550 {
551 static const bool value = true;
552 };
553
554 template<class _Tp>
555 struct _sizeof_duration_rep
556 {
557 static const std::size_t value = 0;
558 };
559
560 template<class _Rep, class _Period>
561 struct _sizeof_duration_rep<duration<_Rep, _Period>>
562 {
563 static const std::size_t value =
564 sizeof(_Rep);
565 };
566
567 template <bool, class _Tp>
568 struct _enable_if_is_duration_impl
569 {};
570
571 template <class _Tp>
572 struct _enable_if_is_duration_impl<true, _Tp>
573 {
574 typedef _Tp type;
575 };
576
577 template <class _Tp>
578 struct _enable_if_is_duration:
579 _enable_if_is_duration_impl<bool( _is_duration<_Tp>::value == bool(true) ), _Tp>
580 {};
581
582 template <class _Tp>
583 struct _disable_if_is_duration :
584 _enable_if_is_duration_impl<bool( _is_duration<_Tp>::value == bool(false) ), _Tp>
585 {};
586
587 template<class _FromDur, class _ToDur,
588 bool _RunTimeCast>
589 struct _duration_cast_impl;
590
591 template<class _FromDur, class _ToDur>
592 struct _duration_cast_impl<_FromDur, _ToDur, false> // ct-cast
593 {
594 typedef typename _ToDur::period _to_period;
595 typedef typename _ToDur::rep _to_rep;
596 typedef typename _FromDur::period _from_period;
597 typedef typename _FromDur::rep _from_rep;
598 typedef ratio_divide<_from_period, _to_period> _cf;
599 typedef typename _duration_common_type<_to_rep, _from_rep, _from_period>::type
600 _cr;
601 typedef _duration_cast_ct_impl<_ToDur, _cr,
602 bool(_cf::num == 1), bool(_cf::den == 1)> type;
603
604 static _ToDur _cast(const _FromDur& _d)
605 {
606 _cf _cf_value;
607 return type::_cast(_d, _cf_value);
608 }
609 };
610
611 namespace runtime_ratio
612 {
613 struct ratio
614 {
615 _big_int num;
616 _big_int den;
617 };
618
619 static inline
620 _big_int naive_gcd(_big_int n1, _big_int n2)
621 {
622 _big_int _tmp;
623 while (n2 != 0) {
624 _tmp = n1;
625 n1 = n2;
626 n2 = _tmp % n2;
627 }
628 return n1;
629 }
630
631 template<class _R1, class _R2>
632 static ratio ratio_multiply()
633 {
634
635 const _big_int gcd1 =
636 naive_gcd(_R1::num, _R2::den);
637 const _big_int gcd2 =
638 naive_gcd(_R2::num, _R1::den);
639
640 ratio result;
641
642 result.num = (_big_int(_R1::num) / gcd1) * (_big_int(_R2::num) / gcd2);
643 result.den = (_big_int(_R1::den) / gcd2) * (_big_int(_R2::den) / gcd1);
644
645 return result;
646 }
647
648 template<class _R1, class _R2>
649 struct _ratio_divide
650 {
651 static ratio call()
652 {
653 typedef stdex::ratio<_R2::den, _R2::num> _R2_inv;
654
655 STATIC_ASSERT(_R2::num != 0, should_not_be_zero);
656
657 return ratio_multiply<_R1, _R2_inv>();
658 }
659 };
660 } // namespace runtime_ratio
661
662 template<class _R1, class _R2>
663 struct _runtime_ratio_ratio_divide
664 : runtime_ratio::_ratio_divide<_R1, _R2>
665 { };
666
667 template<class _FromDur, class _ToDur>
668 struct _duration_cast_impl<_FromDur, _ToDur, true> // rt-cast
669 {
670 typedef typename _ToDur::period _to_period;
671 typedef typename _ToDur::rep _to_rep;
672 typedef typename _FromDur::period _from_period;
673 typedef typename _FromDur::rep _from_rep;
674 typedef typename _duration_common_type<_to_rep, _from_rep, _from_period>::type
675 _cr;
676 typedef _duration_cast_rt_impl<_ToDur, _cr> type;
677
678 static _ToDur _cast(const _FromDur& _d)
679 {
680 runtime_ratio::ratio _cf_value =
681 _runtime_ratio_ratio_divide<_from_period, _to_period>::call();
682
683 return type::_cast(_d, _cf_value);
684 }
685 };
686
687 template<class _FromDur, class _ToDur>
688 struct _duration_cast_impl_chooser
689 {
690 typedef
691 _duration_cast_impl<_FromDur, _ToDur, bool(
692 _use_big_int<typename _ToDur::rep, typename _ToDur::period>::value == bool(true) ||
693 _use_big_int<typename _FromDur::rep, typename _FromDur::period>::value == bool(true) )>
694 type;
695 };
696
697 template<class _FromDur, class _ToDur>
698 struct _duration_cast
699 {
700 typedef typename _duration_cast_impl_chooser<_FromDur, _ToDur>::type impl;
701 static _ToDur call(const _FromDur &_from)
702 {
703 return impl::_cast(_from);
704 }
705 };
706
707 } // namespace detail
708
709 // duration_cast
710 template<class _ToDur, class _Rep, class _Period>
711 inline
712 typename detail::_enable_if_is_duration<_ToDur>::type
713 duration_cast(const duration<_Rep, _Period> &_d)
714 {
715 using stdex::chrono::detail::_duration_cast;
716 typedef duration<_Rep, _Period> _from_dur;
717 typedef _ToDur _to_dur;
718 typedef _duration_cast<_from_dur, _to_dur> _dc;
719
720 return _dc::call(_d);
721 }
722
723
724 // duration_values
725 template<class _Rep>
726 struct duration_values
727 {
728 static _Rep zero()
729 {
730 return _Rep(0);
731 }
732
733 #ifdef max
734 static _Rep(max)() { return (std::numeric_limits<_Rep>::max)(); }
735 #else
736 static _Rep max() { return std::numeric_limits<_Rep>::max(); }
737 #endif
738
739 #ifdef min
740 static _Rep(min)() { return (std::numeric_limits<_Rep>::min)(); }
741 #else
742 static _Rep min() { return std::numeric_limits<_Rep>::min(); }
743 #endif
744
745 // since we have no constexpr use this in template params
746 struct template_constants
747 {
748 static const _Rep zero = 0;
749 static const _Rep max = std::numeric_limits<_Rep>::max;
750 static const _Rep min = std::numeric_limits<_Rep>::min;
751 };
752 };
753
754 template<>
755 struct duration_values<stdex::intmax_t>
756 {
757 static stdex::intmax_t zero()
758 {
759 return stdex::intmax_t(0);
760 }
761
762 #ifdef max
763 static stdex::intmax_t(max)()
764 #else
765 static stdex::intmax_t max()
766 #endif
767 {
768 return STDEX_INTMAX_MAX;
769 }
770
771 #ifdef min
772 static stdex::intmax_t(min)()
773 #else
774 static stdex::intmax_t min()
775 #endif
776 {
777 return STDEX_INTMAX_MIN;
778 }
779
780 // since we have no constexpr use this in template params
781 struct template_constants
782 {
783 static const stdex::intmax_t zero = 0;
784 static const stdex::intmax_t max = STDEX_INTMAX_MAX;
785 static const stdex::intmax_t min = STDEX_INTMAX_MIN;
786 };
787 };
788
789 template<>
790 struct duration_values<stdex::uintmax_t>
791 {
792 static stdex::uintmax_t zero()
793 {
794 return stdex::uintmax_t(0);
795 }
796
797 #ifdef max
798 static stdex::uintmax_t(max)()
799 #else
800 static stdex::uintmax_t max()
801 #endif
802 {
803 return STDEX_UINTMAX_MAX;
804 }
805
806 #ifdef min
807 static stdex::uintmax_t(min)()
808 #else
809 static stdex::uintmax_t min()
810 #endif
811 {
812 return 0;
813 }
814
815 // since we have no constexpr use this in template params
816 struct template_constants
817 {
818 static const stdex::uintmax_t zero = 0;
819 static const stdex::uintmax_t max = STDEX_UINTMAX_MAX;
820 static const stdex::uintmax_t min = 0;
821 };
822 };
823
824 namespace intern
825 {
826 // since we have no static_assert in pre-C++11 we just compile-time assert this way:
827 namespace chrono_asserts
828 {
829 template<bool>
830 struct rep_cannot_be_a_duration_assert; // if you are there means 1st template param _Rep in duration class is duration type
831
832 template<bool>
833 struct period_must_be_a_specialization_of_ratio_assert; // if you are there means 2nd template param _Period in duration class is not a specialization of ratio class
834
835 template<bool>
836 struct period_must_be_positive_assert; // if you are there means 2nd template param _Period in duration class is ratio of negative
837
838 template<bool>
839 struct a_clocks_minimum_duration_cannot_be_less_than_its_epoch_assert; // if you are there means that what it says
840
841 template<bool>
842 struct a_duration_with_an_integer_tick_count_cannot_be_constructed_from_a_floating_point_value_assert; // if you are there means that what it says
843
844 template<bool>
845 struct duration_does_not_use_floating_point_ticks_or_other_duration_period_is_not_exactly_divisible_by_current_period; // if you are there means that what it says
846
847 template<bool>
848 struct a_duration_with_an_integer_tick_count_cannot_be_constructed_from_a_duration_with_floating_point_tick_assert; // if you are there means that what it says
849
850 template<>
851 struct rep_cannot_be_a_duration_assert<true>
852 {
853 typedef bool rep_cannot_be_a_duration_assert_failed;
854 };
855
856 template<>
857 struct period_must_be_a_specialization_of_ratio_assert<true>
858 {
859 typedef bool period_must_be_a_specialization_of_ratio_assert_failed;
860 };
861
862 template<>
863 struct period_must_be_positive_assert<true>
864 {
865 typedef bool period_must_be_positive_assert_failed;
866 };
867
868 template<>
869 struct a_clocks_minimum_duration_cannot_be_less_than_its_epoch_assert<true>
870 {
871 typedef bool a_clocks_minimum_duration_cannot_be_less_than_its_epoch_assert_failed;
872 };
873
874 template<>
875 struct a_duration_with_an_integer_tick_count_cannot_be_constructed_from_a_floating_point_value_assert<true>
876 {
877 typedef bool a_duration_with_an_integer_tick_count_cannot_be_constructed_from_a_floating_point_value_assert_failed;
878 };
879
880 template<>
881 struct duration_does_not_use_floating_point_ticks_or_other_duration_period_is_not_exactly_divisible_by_current_period<true>
882 {
883 typedef bool duration_does_not_use_floating_point_ticks_or_other_duration_period_is_not_exactly_divisible_by_current_period_assert_failed;
884 };
885
886 template<>
887 struct a_duration_with_an_integer_tick_count_cannot_be_constructed_from_a_duration_with_floating_point_tick_assert<true>
888 {
889 typedef bool a_duration_with_an_integer_tick_count_cannot_be_constructed_from_a_duration_with_floating_point_tick_assert_failed;
890 };
891 } // namespace chrono_asserts
892 } // namespace intern
893
894 namespace detail
895 {
896 template<stdex::intmax_t _Lhs, stdex::intmax_t _Rhs>
897 struct _greater
898 {
899 static const bool value = (_Lhs > _Rhs);
900 };
901 }
902
905 template <class _Rep, class _Period>
906 class duration:
907 public detail::duration_base<_Rep, _Period,
908 detail::_use_big_int<_Rep, _Period>::value>
909 {
910 private:
911
912 typedef detail::duration_base<_Rep, _Period,
913 detail::_use_big_int<_Rep, _Period>::value> base_type;
914
915 typedef typename base_type::internal_value_type internal_value_type;
916
917 internal_value_type &_get_r()
918 {
919 return base_type::_r;
920 }
921
922 const internal_value_type &_get_r() const
923 {
924 return base_type::_r;
925 }
926
927 struct _disabled1;
928 struct _disabled2;
929
930 void _modulus(const _Rep &_r_in) { _get_r() %= _r_in; }
931 void _modulus(const duration &other) { _get_r() %= detail::_duration_count_func::call(other); }
932 void _modulus(const _disabled1 &) { }
933 void _modulus(const _disabled2 &) { }
934
935 typedef typename intern::chrono_asserts::rep_cannot_be_a_duration_assert< bool(detail::_is_duration<_Rep>::value == bool(false)) >::
936 rep_cannot_be_a_duration_assert_failed
937 check1; // if you are there means 1st template param _Rep is duration type
938 typedef typename intern::chrono_asserts::period_must_be_a_specialization_of_ratio_assert< bool(detail::_is_ratio<typename _Period::type>::value == bool(true)) >::
939 period_must_be_a_specialization_of_ratio_assert_failed
940 check2; // if you are there means 2nd template param _Period is not a specialization of ratio class
941 typedef typename intern::chrono_asserts::period_must_be_positive_assert< detail::_greater<_Period::num, 0>::value >::
942 period_must_be_positive_assert_failed
943 check3; // if you are there means 2nd template param _Period in duration class is ratio of negative
944
945 template<class _Clock, class _Duration>
946 duration(const time_point<_Clock, _Duration>&) _STDEX_DELETED_FUNCTION;
947
948 public:
949 typedef _Rep rep;
950 typedef _Period period;
951
953 explicit duration():
954 base_type(0)
955 {};
956
957 duration(const rep &_r_in) :
958 base_type(_r_in) { }
959
961 template <class _Rep2>
962 duration(const _Rep2 &_r_in) :
963 base_type(_r_in)
964 {
965 typedef typename intern::chrono_asserts::a_duration_with_an_integer_tick_count_cannot_be_constructed_from_a_floating_point_value_assert<bool( (treat_as_floating_point<_Rep>::value == bool(true)) || (treat_as_floating_point<_Rep2>::value == bool(false)) )>::
966 a_duration_with_an_integer_tick_count_cannot_be_constructed_from_a_floating_point_value_assert_failed
967 check4; // if you are there means rep type is integer but floating-point type is passed as argument
968 }
969
970
971 duration(const duration& other):
972 base_type(static_cast<const base_type&>(other))
973 { }
974
975 template<class _Rep2, class _Period2>
976 duration(const duration<_Rep2, _Period2> &other):
977 base_type(detail::_duration_count_func::call( duration_cast<duration>(other) ))
978 { // construct from a duration
979 typedef stdex::detail::_ratio_divide_den<_Period2, _Period> _Checked_type;
980
981 typedef typename intern::chrono_asserts::duration_does_not_use_floating_point_ticks_or_other_duration_period_is_not_exactly_divisible_by_current_period<bool(
982 (treat_as_floating_point<_Rep>::value == bool(true)) ||
983 ( (_Checked_type::value == 1 && treat_as_floating_point<_Rep2>::value == bool(false)) )
984 )>::duration_does_not_use_floating_point_ticks_or_other_duration_period_is_not_exactly_divisible_by_current_period_assert_failed
985 check5;
986
987
988 typedef typename intern::chrono_asserts::a_duration_with_an_integer_tick_count_cannot_be_constructed_from_a_duration_with_floating_point_tick_assert<bool( (treat_as_floating_point<_Rep>::value == bool(true)) || (treat_as_floating_point<_Rep2>::value == bool(false)) )>::
989 a_duration_with_an_integer_tick_count_cannot_be_constructed_from_a_duration_with_floating_point_tick_assert_failed
990 check6; // if you are there means rep type is integer but floating-point duration type is passed as argument
991 }
992
993 duration& operator=(const duration& other)
994 {
995 static_cast<base_type&>(*this) =
996 static_cast<const base_type&>(other);
997
998 return *this;
999 }
1000
1002 rep count() const
1003 {
1004 return detail::_chrono_convert_func::call( _get_r(),
1005 stdex::detail::_chrono_force_tmpl_param<rep>() );
1006 }
1007
1008 duration operator+() const
1009 { // get value
1010 return (*this);
1011 }
1012
1013 duration operator-() const
1014 { // get negated value
1015 return (-_get_r());
1016 }
1017
1018 duration& operator++()
1019 { // increment rep
1020 ++_get_r();
1021 return (*this);
1022 }
1023
1024 duration operator++(int)
1025 { // postincrement rep
1026 return (duration<_Rep, _Period>(_get_r()++));
1027 }
1028
1029 duration& operator--()
1030 { // decrement rep
1031 --_get_r();
1032 return (*this);
1033 }
1034
1035 duration operator--(int)
1036 { // postdecrement rep
1037 return (duration<_Rep, _Period>(_get_r()--));
1038 }
1039
1040 duration& operator+=(const duration &other)
1041 { // add other to rep
1042 _get_r() += other._get_r();
1043 return (*this);
1044 }
1045
1046 duration& operator-=(const duration &other)
1047 { // subtract other from rep
1048 _get_r() -= other._get_r();
1049 return (*this);
1050 }
1051
1052 duration& operator*=(const _Rep &_r_in)
1053 { // multiply rep by r
1054 _get_r() *= _r_in;
1055 return (*this);
1056 }
1057
1058 duration& operator/=(const _Rep &_r_in)
1059 { // divide rep by r
1060 _get_r() /= _r_in;
1061 return (*this);
1062 }
1063
1064 duration& operator%=(
1065 typename
1066 conditional<
1067 bool( treat_as_floating_point<_Rep>::value == bool(false) ),
1068 const _Rep &,
1069 _disabled1&
1070 >::type _r_in
1071 )
1072 { // modulus rep by r
1073 _modulus(_r_in);
1074 return (*this);
1075 }
1076
1077 duration& operator%=(
1078 typename
1079 conditional<
1080 bool( treat_as_floating_point<_Rep>::value == bool(false) ),
1081 const duration &,
1082 _disabled2&
1083 >::type other
1084 )
1085 { // modulus rep by other
1086 _modulus(other);
1087 return (*this);
1088 }
1089
1090 static const duration zero()
1091 { // get zero value
1092 return duration_values<_Rep>::zero();
1093 }
1094
1095 #ifdef max
1096 static const duration(max)() { return (duration_values<_Rep>::max)(); }
1097 #else
1098 static const duration max() { return duration_values<_Rep>::max(); }
1099 #endif
1100
1101 #ifdef min
1102 static const duration(min)() { return (duration_values<_Rep>::min)(); }
1103 #else
1104 static const duration min() { return duration_values<_Rep>::min(); }
1105 #endif
1106 };
1107
1108 template<class _Rep1, class _Period1,
1109 class _Rep2, class _Period2>
1110 inline
1111 typename
1112 common_type<
1113 duration<_Rep1, _Period1>,
1114 duration<_Rep2, _Period2>
1115 >::type
1116 operator+(const duration<_Rep1, _Period1> &lhs,
1117 const duration<_Rep2, _Period2> &rhs)
1118 {
1119 typedef duration<_Rep1, _Period1> _dur1;
1120 typedef duration<_Rep2, _Period2> _dur2;
1121 typedef typename common_type<_dur1, _dur2>::type _cd;
1122
1123 return _cd(
1124 detail::_duration_count_func::call(_cd(lhs)) +
1125 detail::_duration_count_func::call(_cd(rhs))
1126 );
1127 }
1128
1129 template<class _Rep1, class _Period1,
1130 class _Rep2, class _Period2>
1131 inline
1132 typename
1133 common_type<
1134 duration<_Rep1, _Period1>,
1135 duration<_Rep2, _Period2>
1136 >::type
1137 operator-(const duration<_Rep1, _Period1> &lhs,
1138 const duration<_Rep2, _Period2> & rhs)
1139 {
1140 typedef duration<_Rep1, _Period1> _dur1;
1141 typedef duration<_Rep2, _Period2> _dur2;
1142 typedef typename common_type<_dur1, _dur2>::type _cd;
1143
1144 return _cd(
1145 detail::_duration_count_func::call(_cd(lhs)) -
1146 detail::_duration_count_func::call(_cd(rhs))
1147 );
1148 }
1149
1150 namespace detail
1151 {
1152 template<bool, class _CRep>
1153 struct _rep_t_enable_if
1154 { };
1155
1156 template<class _CRep>
1157 struct _rep_t_enable_if<true, _CRep>
1158 {
1159 typedef _CRep type;
1160 };
1161
1162 template<class _Rep1, class _Rep2,
1163 class _CRep = typename common_type<_Rep1, _Rep2>::type>
1164 struct _common_rep_t:
1165 _rep_t_enable_if<sizeof(_Rep2) <= sizeof(_CRep), _CRep>
1166 {};
1167 } // namespace detail
1168
1169 template<class _Rep1, class _Period, class _Rep2>
1170 duration<typename detail::_common_rep_t<_Rep1, _Rep2>::type, _Period>
1171 operator*(const duration<_Rep1, _Period> &_d, const _Rep2 &_s)
1172 {
1173 typedef duration<typename common_type<_Rep1, _Rep2>::type, _Period> _cd;
1174
1175 return _cd(
1176 detail::_duration_count_func::call(_cd(_d)) * _s
1177 );
1178 }
1179
1180 template<class _Rep1, class _Rep2, class _Period>
1181 duration<typename detail::_common_rep_t<_Rep2, _Rep1>::type, _Period>
1182 operator*(const _Rep1 &_s, const duration<_Rep2, _Period> &_d)
1183 {
1184 return _d * _s;
1185 }
1186
1187 template<class _Rep1, class _Period, class _Rep2>
1188 duration<typename detail::_common_rep_t<_Rep1, typename detail::_disable_if_is_duration<_Rep2>::type >::type, _Period>
1189 operator/(const duration<_Rep1, _Period> &_d, const _Rep2 &_s)
1190 {
1191 typedef duration<typename common_type<_Rep1, _Rep2>::type, _Period> _cd;
1192
1193 return _cd(
1194 detail::_duration_count_func::call(_cd(_d)) / _s
1195 );
1196 }
1197
1198 template<class _Rep1, class _Period1,
1199 class _Rep2, class _Period2>
1200 typename common_type<_Rep1, _Rep2>::type
1201 operator/(const duration<_Rep1, _Period1> &lhs, const duration<_Rep2, _Period2> &rhs)
1202 {
1203 typedef duration<_Rep1, _Period1> _dur1;
1204 typedef duration<_Rep2, _Period2> _dur2;
1205 typedef typename common_type<_dur1, _dur2>::type _cd;
1206
1207 return
1208 _cd(
1209 detail::_duration_count_func::call(_cd(lhs)) /
1210 detail::_duration_count_func::call(_cd(rhs))
1211 ).count();
1212 }
1213
1214 // DR 934.
1215 template<class _Rep1, class _Period, class _Rep2>
1216 duration<typename detail::_common_rep_t<_Rep1, typename detail::_disable_if_is_duration<_Rep2>::type >::type, _Period>
1217 operator%(const duration<_Rep1, _Period> &_d, const _Rep2 &_s)
1218 {
1219 typedef duration<typename common_type<_Rep1, _Rep2>::type, _Period> _cd;
1220 return _cd(
1221 detail::_duration_count_func::call(_cd(_d)) % _s
1222 );
1223 }
1224
1225 template<class _Rep1, class _Period1, class _Rep2, class _Period2>
1226 typename common_type< duration<_Rep1, _Period1>, duration<_Rep2, _Period2> >::type
1227 operator%(const duration<_Rep1, _Period1> &lhs, const duration<_Rep2, _Period2> &rhs)
1228 {
1229 typedef duration<_Rep1, _Period1> _dur1;
1230 typedef duration<_Rep2, _Period2> _dur2;
1231 typedef typename common_type<_dur1, _dur2>::type _cd;
1232 return _cd(
1233 detail::_duration_count_func::call(_cd(lhs)) %
1234 detail::_duration_count_func::call(_cd(rhs))
1235 );
1236 }
1237
1238 // comparisons
1239 template<class _Rep1, class _Period1, class _Rep2, class _Period2>
1240 bool operator==(const duration<_Rep1, _Period1> &lhs, const duration<_Rep2, _Period2> &rhs)
1241 {
1242 typedef duration<_Rep1, _Period1> _dur1;
1243 typedef duration<_Rep2, _Period2> _dur2;
1244 typedef typename common_type<_dur1, _dur2>::type _ct;
1245
1246 return
1247 detail::_duration_count_func::call(_ct(lhs)) ==
1248 detail::_duration_count_func::call(_ct(rhs));
1249 }
1250
1251 template<class _Rep1, class _Period1, class _Rep2, class _Period2>
1252 bool operator<(const duration<_Rep1, _Period1> &lhs, const duration<_Rep2, _Period2> &rhs)
1253 {
1254 typedef duration<_Rep1, _Period1> _dur1;
1255 typedef duration<_Rep2, _Period2> _dur2;
1256 typedef typename common_type<_dur1, _dur2>::type _ct;
1257
1258 return
1259 detail::_duration_count_func::call(_ct(lhs)) <
1260 detail::_duration_count_func::call(_ct(rhs));
1261 }
1262
1263 template<class _Rep1, class _Period1, class _Rep2, class _Period2>
1264 bool operator!=(const duration<_Rep1, _Period1> &lhs, const duration<_Rep2, _Period2> &rhs)
1265 {
1266 return !(lhs == rhs);
1267 }
1268
1269 template<class _Rep1, class _Period1, class _Rep2, class _Period2>
1270 bool operator<=(const duration<_Rep1, _Period1> &lhs, const duration<_Rep2, _Period2> &rhs)
1271 {
1272 return !(rhs < lhs);
1273 }
1274
1275 template<class _Rep1, class _Period1, class _Rep2, class _Period2>
1276 bool operator>(const duration<_Rep1, _Period1> &lhs, const duration<_Rep2, _Period2> &rhs)
1277 {
1278 return rhs < lhs;
1279 }
1280
1281 template<class _Rep1, class _Period1, class _Rep2, class _Period2>
1282 bool operator>=(const duration<_Rep1, _Period1> &lhs, const duration<_Rep2, _Period2> &rhs)
1283 {
1284 return !(lhs < rhs);
1285 }
1286
1287 namespace detail
1288 {
1289 struct _duration_predefined
1290 {
1291 struct duration_cannot_be_implemented;
1292
1293 typedef
1294 conditional<
1295 _is_ratio<nano>::value,
1296 duration<stdex::intmax_t, nano>,
1297 duration_cannot_be_implemented
1298 >::type nanoseconds;
1299
1300 typedef
1301 conditional<
1302 _is_ratio<micro>::value,
1303 duration<stdex::intmax_t, micro>,
1304 duration_cannot_be_implemented
1305 >::type microseconds;
1306
1307 typedef
1308 conditional<
1309 _is_ratio<milli>::value,
1310 duration<stdex::intmax_t, milli>,
1311 duration_cannot_be_implemented
1312 >::type milliseconds;
1313
1314 typedef duration<stdex::intmax_t> seconds;
1315 typedef duration<stdex::intmax_t, ratio<60>> minutes;
1316 typedef duration<stdex::intmax_t, ratio<3600>> hours;
1317 };
1318 }
1319
1320 // Standard duration types.
1321 typedef detail::_duration_predefined::nanoseconds nanoseconds;
1322 typedef detail::_duration_predefined::microseconds microseconds;
1323 typedef detail::_duration_predefined::milliseconds milliseconds;
1324 typedef detail::_duration_predefined::seconds seconds;
1325 typedef detail::_duration_predefined::minutes minutes;
1326 typedef detail::_duration_predefined::hours hours;
1327
1328 template<class _Clock, class _Duration>
1329 class time_point
1330 { // represents a point in time
1331 public:
1332 typedef _Clock clock;
1333 typedef _Duration duration;
1334 typedef typename _Duration::rep rep;
1335 typedef typename _Duration::period period;
1336
1337 time_point()
1338 : _d(_Duration::zero())
1339 {}
1340
1341 // construct from a duration
1342 explicit time_point(const duration &_d_in)
1343 : _d(_d_in)
1344 {}
1345
1346 time_point(const time_point &other)
1347 : _d(other._d)
1348 {}
1349
1350 // construct from another duration
1351 template<class _Duration2>
1352 time_point(const time_point<_Clock, _Duration2> &_tp)
1353 : _d(_tp.time_since_epoch())
1354 {}
1355
1356 time_point& operator=(const time_point &other)
1357 {
1358 _d = other._d;
1359
1360 return *this;
1361 }
1362
1363 duration time_since_epoch() const
1364 { // get duration from epoch
1365 return (_d);
1366 }
1367
1368 time_point& operator+=(const duration &_d_in)
1369 { // increment by duration
1370 _d += _d_in;
1371 return (*this);
1372 }
1373
1374 time_point& operator-=(const duration &_d_in)
1375 { // decrement by duration
1376 _d -= _d_in;
1377 return (*this);
1378 }
1379
1380 #ifdef min
1381 static const time_point(min)()
1382 { // get minimum time point
1383 typedef time_point<_Clock, _Duration> that_type;
1384 return (that_type((that_type::duration::min)()));
1385 }
1386 #else
1387 static const time_point min()
1388 { // get minimum time point
1389 typedef time_point<_Clock, _Duration> that_type;
1390 return (that_type(that_type::duration::min()));
1391 }
1392 #endif
1393
1394 #ifdef max
1395 static const time_point(max)()
1396 { // get maximum time point
1397 typedef time_point<_Clock, _Duration> that_type;
1398 return (that_type((that_type::duration::max)()));
1399 }
1400 #else
1401 static const time_point max()
1402 { // get maximum time point
1403 typedef time_point<_Clock, _Duration> that_type;
1404 return (that_type(that_type::duration::max()));
1405 }
1406 #endif
1407
1408 private:
1409 duration _d; // duration since the epoch
1410 };
1411
1412 namespace detail
1413 {
1414 template <bool, class _ToDur, class _Clock>
1415 struct _time_point_enable_if_is_duration_impl
1416 {
1417 typedef time_point<_Clock, _ToDur> type;
1418 };
1419
1420 template <class _ToDur, class _Clock>
1421 struct _time_point_enable_if_is_duration_impl<false, _ToDur, _Clock>
1422 { };
1423
1424 template <class _ToDur, class _Clock>
1425 struct _time_point_enable_if_is_duration:
1426 _time_point_enable_if_is_duration_impl< _is_duration<_ToDur>::value, _ToDur, _Clock>
1427 { };
1428
1429 } // namespace detail
1430
1431 // time_point_cast
1432 template<class _ToDur, class _Clock, class _Dur>
1433 inline
1434 typename
1435 detail::_time_point_enable_if_is_duration<
1436 _ToDur,
1437 _Clock
1438 >::type
1439 time_point_cast(const time_point<_Clock, _Dur> &_t)
1440 {
1441 typedef time_point<_Clock, _ToDur> _time_point;
1442
1443 return _time_point(duration_cast<_ToDur>(_t.time_since_epoch()));
1444 }
1445
1446 template<class _Clock, class _Dur1,
1447 class _Rep2, class _Period2>
1448 time_point<_Clock,
1449 typename common_type<_Dur1, duration<_Rep2, _Period2> >::type>
1450 operator+(const time_point<_Clock, _Dur1> &lhs, const duration<_Rep2, _Period2> &rhs)
1451 {
1452 typedef duration<_Rep2, _Period2> _dur2;
1453 typedef typename common_type<_Dur1, _dur2>::type _ct;
1454 typedef time_point<_Clock, _ct> _time_point;
1455
1456 return _time_point(lhs.time_since_epoch() + rhs);
1457 }
1458
1459 template<class _Rep1, class _Period1,
1460 class _Clock, class _Dur2>
1461 time_point<_Clock,
1462 typename common_type<duration<_Rep1, _Period1>, _Dur2>::type>
1463 operator+(const duration<_Rep1, _Period1> &lhs, const time_point<_Clock, _Dur2> &rhs)
1464 {
1465 typedef duration<_Rep1, _Period1> _dur1;
1466 typedef typename common_type<_dur1, _Dur2>::type _ct;
1467 typedef time_point<_Clock, _ct> _time_point;
1468
1469 return _time_point(rhs.time_since_epoch() + lhs);
1470 }
1471
1472 template<class _Clock, class _Dur1,
1473 class _Rep2, class _Period2>
1474 time_point<_Clock,
1475 typename common_type<_Dur1, duration<_Rep2, _Period2> >::type>
1476 operator-(const time_point<_Clock, _Dur1> &lhs, const duration<_Rep2, _Period2> &rhs)
1477 {
1478 typedef duration<_Rep2, _Period2> _dur2;
1479 typedef typename common_type<_Dur1, _dur2>::type _ct;
1480 typedef time_point<_Clock, _ct> _time_point;
1481
1482 return _time_point(lhs.time_since_epoch() - rhs);
1483 }
1484
1485 template<class _Clock, class _Dur1, class _Dur2>
1486 typename common_type<_Dur1, _Dur2>::type
1487 operator-(const time_point<_Clock, _Dur1> &lhs, const time_point<_Clock, _Dur2> &rhs)
1488 {
1489 return lhs.time_since_epoch() - rhs.time_since_epoch();
1490 }
1491
1492 template<class _Clock, class _Dur1, class _Dur2>
1493 bool operator==(const time_point<_Clock, _Dur1> &lhs, const time_point<_Clock, _Dur2> &rhs)
1494 {
1495 return lhs.time_since_epoch() == rhs.time_since_epoch();
1496 }
1497
1498 template<class _Clock, class _Dur1, class _Dur2>
1499 bool operator!=(const time_point<_Clock, _Dur1> &lhs, const time_point<_Clock, _Dur2> &rhs)
1500 {
1501 return !(lhs == rhs);
1502 }
1503
1504 template<class _Clock, class _Dur1, class _Dur2>
1505 bool operator<(const time_point<_Clock, _Dur1> &lhs, const time_point<_Clock, _Dur2> &rhs)
1506 {
1507 return lhs.time_since_epoch() < rhs.time_since_epoch();
1508 }
1509
1510 template<class _Clock, class _Dur1, class _Dur2>
1511 bool operator<=(const time_point<_Clock, _Dur1> &lhs, const time_point<_Clock, _Dur2> &rhs)
1512 {
1513 return !(rhs < lhs);
1514 }
1515
1516 template<class _Clock, class _Dur1, class _Dur2>
1517 bool operator>(const time_point<_Clock, _Dur1> &lhs, const time_point<_Clock, _Dur2> &rhs)
1518 {
1519 return rhs < lhs;
1520 }
1521
1522 template<class _Clock, class _Dur1, class _Dur2>
1523 bool operator>=(const time_point<_Clock, _Dur1> &lhs, const time_point<_Clock, _Dur2> &rhs)
1524 {
1525 return !(lhs < rhs);
1526 }
1527
1528 namespace detail
1529 {
1530 template<class _Dur, bool>
1531 struct _duration_is_using_big_int_impl
1532 {
1533 typedef false_type type;
1534 };
1535
1536 template<class _Dur>
1537 struct _duration_is_using_big_int_impl<_Dur, true>
1538 {
1539 typedef _use_big_int<typename _Dur::rep, typename _Dur::period> type;
1540 };
1541
1542 template<class _Dur>
1543 struct _duration_is_using_big_int:
1544 _duration_is_using_big_int_impl<_Dur, _is_duration<_Dur>::value>::type
1545 { };
1546 }
1547
1548
1554 struct system_clock
1555 {
1556 private:
1557
1558 typedef bool_constant<bool(detail::_sizeof_duration_rep<chrono::nanoseconds>::value * CHAR_BIT >= 64)> _nanoseconds_can_be_used;
1559 typedef bool_constant<detail::_duration_is_using_big_int<chrono::nanoseconds>::value> _big_int_is_used_for_nanoseconds;
1560
1561 public:
1562
1563 typedef
1564 stdex::conditional<bool(
1565 bool(_nanoseconds_can_be_used::value == bool(true)) ||
1566 bool(_big_int_is_used_for_nanoseconds::value == bool(true)) ),
1567 chrono::nanoseconds,
1568 chrono::microseconds
1569 >::type duration;
1570 typedef system_clock::duration::rep rep;
1571 typedef system_clock::duration::period period;
1572 typedef chrono::time_point<system_clock, duration> time_point;
1573
1574 static const bool is_steady;
1575
1576 static time_point
1577 now() _STDEX_NOEXCEPT_FUNCTION;
1578
1579 // Map to POSIX API
1580 static stdex::timespec
1581 to_timespec(const time_point&) _STDEX_NOEXCEPT_FUNCTION;
1582
1583 // Map to C API
1584 static stdex::time_t
1585 to_time_t(const time_point &_t) _STDEX_NOEXCEPT_FUNCTION;
1586
1587 static time_point
1588 from_time_t(stdex::time_t _t) _STDEX_NOEXCEPT_FUNCTION;
1589
1590 private:
1591
1592
1593 typedef duration_values<rep>::template_constants duration_constants;
1594
1595 typedef intern::chrono_asserts::a_clocks_minimum_duration_cannot_be_less_than_its_epoch_assert< (duration_constants::min < duration_constants::zero) >::
1596 a_clocks_minimum_duration_cannot_be_less_than_its_epoch_assert_failed
1597 check1; // if you are there means that what it says
1598 };
1599
1605 struct steady_clock
1606 {
1607 private:
1608
1609 typedef bool_constant<bool(detail::_sizeof_duration_rep<chrono::nanoseconds>::value * CHAR_BIT >= 64)> _nanoseconds_can_be_used;
1610 typedef bool_constant<detail::_duration_is_using_big_int<chrono::nanoseconds>::value> _big_int_is_used_for_nanoseconds;
1611
1612 public:
1613
1614 typedef
1615 stdex::conditional<bool(
1616 bool(_nanoseconds_can_be_used::value == bool(true)) ||
1617 bool(_big_int_is_used_for_nanoseconds::value == bool(true)) ),
1618 chrono::nanoseconds,
1619 chrono::microseconds
1620 >::type duration;
1621 typedef steady_clock::duration::rep rep;
1622 typedef steady_clock::duration::period period;
1623 typedef chrono::time_point<steady_clock, duration> time_point;
1624
1625 static const bool is_steady;
1626
1627 static time_point
1628 now() _STDEX_NOEXCEPT_FUNCTION;
1629 };
1630
1631
1639 typedef
1640 stdex::conditional<
1641 detail::_greater<steady_clock::period::den, system_clock::period::den>::value,
1642 steady_clock,
1643 system_clock
1644 >::type high_resolution_clock;
1645 } // namespace chrono
1646
1647 // literals
1648 namespace literals
1649 {
1650 namespace chrono_literals
1651 {
1652 // non-standard operator >> for literals macros to work:
1653 template <class _Rep, class _Period, class _Rep2>
1654 chrono::duration<_Rep, _Period> operator,(const _Rep2 &input, const chrono::duration<_Rep, _Period> &dur)
1655 {
1656 return chrono::duration<_Rep, _Period>(input);
1657 }
1658
1659 template <class _Rep, class _Period>
1660 chrono::duration<_Rep, _Period> operator,(const float &input, const chrono::duration<_Rep, _Period> &dur);
1661
1662 template <class _Rep, class _Period>
1663 chrono::duration<_Rep, _Period> operator,(const double &input, const chrono::duration<_Rep, _Period> &dur);
1664 } // namespace chrono_literals
1665 } // namespace literals
1666
1667 namespace chrono
1668 {
1669 using namespace literals::chrono_literals;
1670 } // namespace chrono
1671
1672 // use this literals as (10,sec) + (5,min) + (6,h)
1673
1674 /*static const stdex::chrono::hours h;
1675 static const stdex::chrono::minutes min;
1676 static const stdex::chrono::seconds s;
1677 static const stdex::chrono::milliseconds ms;
1678 static const stdex::chrono::microseconds us;
1679 static const stdex::chrono::nanoseconds ns;*/
1680
1681} // namespace stdex
1682
1683#undef _STDEX_DELETED_FUNCTION
1684#undef _STDEX_NOEXCEPT_FUNCTION
1685
1686#endif // _STDEX_CHRONO_H
Definition: chrono.hpp:909
duration()
Construct a duration by default.
Definition: chrono.hpp:953
duration(const _Rep2 &_r_in)
Construct a duration object with the given duration.
Definition: chrono.hpp:962
rep count() const
Return the value of the duration object.
Definition: chrono.hpp:1002