chrono revision 227825
1// -*- C++ -*-
2//===---------------------------- chrono ----------------------------------===//
3//
4//                     The LLVM Compiler Infrastructure
5//
6// This file is dual licensed under the MIT and the University of Illinois Open
7// Source Licenses. See LICENSE.TXT for details.
8//
9//===----------------------------------------------------------------------===//
10
11#ifndef _LIBCPP_CHRONO
12#define _LIBCPP_CHRONO
13
14/*
15    chrono synopsis
16
17namespace std
18{
19namespace chrono
20{
21
22template <class ToDuration, class Rep, class Period>
23ToDuration
24duration_cast(const duration<Rep, Period>& fd);
25
26template <class Rep> struct treat_as_floating_point : is_floating_point<Rep> {};
27
28template <class Rep>
29struct duration_values
30{
31public:
32    static Rep zero();
33    static Rep max();
34    static Rep min();
35};
36
37// duration
38
39template <class Rep, class Period = ratio<1>>
40class duration
41{
42    static_assert(!__is_duration<Rep>::value, "A duration representation can not be a duration");
43    static_assert(__is_ratio<Period>::value, "Second template parameter of duration must be a std::ratio");
44    static_assert(Period::num > 0, "duration period must be positive");
45public:
46    typedef Rep rep;
47    typedef Period period;
48
49    duration() = default;
50    template <class Rep2>
51        explicit duration(const Rep2& r,
52            typename enable_if
53            <
54               is_convertible<Rep2, rep>::value &&
55               (treat_as_floating_point<rep>::value ||
56               !treat_as_floating_point<rep>::value && !treat_as_floating_point<Rep2>::value)
57            >::type* = 0);
58
59    // conversions
60    template <class Rep2, class Period2>
61        duration(const duration<Rep2, Period2>& d,
62            typename enable_if
63            <
64                treat_as_floating_point<rep>::value ||
65                ratio_divide<Period2, period>::type::den == 1
66            >::type* = 0);
67
68    // observer
69
70    rep count() const;
71
72    // arithmetic
73
74    duration  operator+() const;
75    duration  operator-() const;
76    duration& operator++();
77    duration  operator++(int);
78    duration& operator--();
79    duration  operator--(int);
80
81    duration& operator+=(const duration& d);
82    duration& operator-=(const duration& d);
83
84    duration& operator*=(const rep& rhs);
85    duration& operator/=(const rep& rhs);
86
87    // special values
88
89    static duration zero();
90    static duration min();
91    static duration max();
92};
93
94typedef duration<long long,         nano> nanoseconds;
95typedef duration<long long,        micro> microseconds;
96typedef duration<long long,        milli> milliseconds;
97typedef duration<long long              > seconds;
98typedef duration<     long, ratio<  60> > minutes;
99typedef duration<     long, ratio<3600> > hours;
100
101template <class Clock, class Duration = typename Clock::duration>
102class time_point
103{
104public:
105    typedef Clock                     clock;
106    typedef Duration                  duration;
107    typedef typename duration::rep    rep;
108    typedef typename duration::period period;
109private:
110    duration d_;  // exposition only
111
112public:
113    time_point();  // has value "epoch"
114    explicit time_point(const duration& d);  // same as time_point() + d
115
116    // conversions
117    template <class Duration2>
118       time_point(const time_point<clock, Duration2>& t);
119
120    // observer
121
122    duration time_since_epoch() const;
123
124    // arithmetic
125
126    time_point& operator+=(const duration& d);
127    time_point& operator-=(const duration& d);
128
129    // special values
130
131    static constexpr time_point min();
132    static constexpr time_point max();
133};
134
135} // chrono
136
137// common_type traits
138template <class Rep1, class Period1, class Rep2, class Period2>
139  struct common_type<chrono::duration<Rep1, Period1>, chrono::duration<Rep2, Period2>>;
140
141template <class Clock, class Duration1, class Duration2>
142  struct common_type<chrono::time_point<Clock, Duration1>, chrono::time_point<Clock, Duration2>>;
143
144namespace chrono {
145
146// duration arithmetic
147template <class Rep1, class Period1, class Rep2, class Period2>
148  typename common_type<duration<Rep1, Period1>, duration<Rep2, Period2>>::type
149  operator+(const duration<Rep1, Period1>& lhs, const duration<Rep2, Period2>& rhs);
150template <class Rep1, class Period1, class Rep2, class Period2>
151  typename common_type<duration<Rep1, Period1>, duration<Rep2, Period2>>::type
152  operator-(const duration<Rep1, Period1>& lhs, const duration<Rep2, Period2>& rhs);
153template <class Rep1, class Period, class Rep2>
154  duration<typename common_type<Rep1, Rep2>::type, Period>
155  operator*(const duration<Rep1, Period>& d, const Rep2& s);
156template <class Rep1, class Period, class Rep2>
157  duration<typename common_type<Rep1, Rep2>::type, Period>
158  operator*(const Rep1& s, const duration<Rep2, Period>& d);
159template <class Rep1, class Period, class Rep2>
160  duration<typename common_type<Rep1, Rep2>::type, Period>
161  operator/(const duration<Rep1, Period>& d, const Rep2& s);
162template <class Rep1, class Period1, class Rep2, class Period2>
163  typename common_type<Rep1, Rep2>::type
164  operator/(const duration<Rep1, Period1>& lhs, const duration<Rep2, Period2>& rhs);
165
166// duration comparisons
167template <class Rep1, class Period1, class Rep2, class Period2>
168   bool operator==(const duration<Rep1, Period1>& lhs, const duration<Rep2, Period2>& rhs);
169template <class Rep1, class Period1, class Rep2, class Period2>
170   bool operator!=(const duration<Rep1, Period1>& lhs, const duration<Rep2, Period2>& rhs);
171template <class Rep1, class Period1, class Rep2, class Period2>
172   bool operator< (const duration<Rep1, Period1>& lhs, const duration<Rep2, Period2>& rhs);
173template <class Rep1, class Period1, class Rep2, class Period2>
174   bool operator<=(const duration<Rep1, Period1>& lhs, const duration<Rep2, Period2>& rhs);
175template <class Rep1, class Period1, class Rep2, class Period2>
176   bool operator> (const duration<Rep1, Period1>& lhs, const duration<Rep2, Period2>& rhs);
177template <class Rep1, class Period1, class Rep2, class Period2>
178   bool operator>=(const duration<Rep1, Period1>& lhs, const duration<Rep2, Period2>& rhs);
179
180// duration_cast
181template <class ToDuration, class Rep, class Period>
182  ToDuration duration_cast(const duration<Rep, Period>& d);
183
184// time_point arithmetic
185template <class Clock, class Duration1, class Rep2, class Period2>
186  time_point<Clock, typename common_type<Duration1, duration<Rep2, Period2>>::type>
187  operator+(const time_point<Clock, Duration1>& lhs, const duration<Rep2, Period2>& rhs);
188template <class Rep1, class Period1, class Clock, class Duration2>
189  time_point<Clock, typename common_type<duration<Rep1, Period1>, Duration2>::type>
190  operator+(const duration<Rep1, Period1>& lhs, const time_point<Clock, Duration2>& rhs);
191template <class Clock, class Duration1, class Rep2, class Period2>
192  time_point<Clock, typename common_type<Duration1, duration<Rep2, Period2>>::type>
193  operator-(const time_point<Clock, Duration1>& lhs, const duration<Rep2, Period2>& rhs);
194template <class Clock, class Duration1, class Duration2>
195  typename common_type<Duration1, Duration2>::type
196  operator-(const time_point<Clock, Duration1>& lhs, const time_point<Clock, Duration2>& rhs);
197
198// time_point comparisons
199template <class Clock, class Duration1, class Duration2>
200   bool operator==(const time_point<Clock, Duration1>& lhs, const time_point<Clock, Duration2>& rhs);
201template <class Clock, class Duration1, class Duration2>
202   bool operator!=(const time_point<Clock, Duration1>& lhs, const time_point<Clock, Duration2>& rhs);
203template <class Clock, class Duration1, class Duration2>
204   bool operator< (const time_point<Clock, Duration1>& lhs, const time_point<Clock, Duration2>& rhs);
205template <class Clock, class Duration1, class Duration2>
206   bool operator<=(const time_point<Clock, Duration1>& lhs, const time_point<Clock, Duration2>& rhs);
207template <class Clock, class Duration1, class Duration2>
208   bool operator> (const time_point<Clock, Duration1>& lhs, const time_point<Clock, Duration2>& rhs);
209template <class Clock, class Duration1, class Duration2>
210   bool operator>=(const time_point<Clock, Duration1>& lhs, const time_point<Clock, Duration2>& rhs);
211
212// time_point_cast
213
214template <class ToDuration, class Clock, class Duration>
215  time_point<Clock, ToDuration> time_point_cast(const time_point<Clock, Duration>& t);
216
217// Clocks
218
219class system_clock
220{
221public:
222    typedef microseconds                     duration;
223    typedef duration::rep                    rep;
224    typedef duration::period                 period;
225    typedef chrono::time_point<system_clock> time_point;
226    static const bool is_steady =            false;
227
228    static time_point now() noexcept;
229    static time_t     to_time_t  (const time_point& __t) noexcept;
230    static time_point from_time_t(time_t __t) noexcept;
231};
232
233class steady_clock
234{
235public:
236    typedef nanoseconds                                   duration;
237    typedef duration::rep                                 rep;
238    typedef duration::period                              period;
239    typedef chrono::time_point<steady_clock, duration>    time_point;
240    static const bool is_steady =                         true;
241
242    static time_point now() noexcept;
243};
244
245typedef steady_clock high_resolution_clock;
246
247}  // chrono
248
249}  // std
250*/
251
252#include <__config>
253#include <ctime>
254#include <type_traits>
255#include <ratio>
256#include <limits>
257
258#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
259#pragma GCC system_header
260#endif
261
262_LIBCPP_BEGIN_NAMESPACE_STD
263
264namespace chrono
265{
266
267template <class _Rep, class _Period = ratio<1> > class _LIBCPP_VISIBLE duration;
268
269template <class _Tp>
270struct __is_duration : false_type {};
271
272template <class _Rep, class _Period>
273struct __is_duration<duration<_Rep, _Period> > : true_type  {};
274
275template <class _Rep, class _Period>
276struct __is_duration<const duration<_Rep, _Period> > : true_type  {};
277
278template <class _Rep, class _Period>
279struct __is_duration<volatile duration<_Rep, _Period> > : true_type  {};
280
281template <class _Rep, class _Period>
282struct __is_duration<const volatile duration<_Rep, _Period> > : true_type  {};
283
284} // chrono
285
286template <class _Rep1, class _Period1, class _Rep2, class _Period2>
287struct _LIBCPP_VISIBLE common_type<chrono::duration<_Rep1, _Period1>,
288                                   chrono::duration<_Rep2, _Period2> >
289{
290    typedef chrono::duration<typename common_type<_Rep1, _Rep2>::type,
291                             typename __ratio_gcd<_Period1, _Period2>::type> type;
292};
293
294namespace chrono {
295
296// duration_cast
297
298template <class _FromDuration, class _ToDuration,
299          class _Period = typename ratio_divide<typename _FromDuration::period, typename _ToDuration::period>::type,
300          bool = _Period::num == 1,
301          bool = _Period::den == 1>
302struct __duration_cast;
303
304template <class _FromDuration, class _ToDuration, class _Period>
305struct __duration_cast<_FromDuration, _ToDuration, _Period, true, true>
306{
307    _LIBCPP_INLINE_VISIBILITY
308    _ToDuration operator()(const _FromDuration& __fd) const
309    {
310        return _ToDuration(static_cast<typename _ToDuration::rep>(__fd.count()));
311    }
312};
313
314template <class _FromDuration, class _ToDuration, class _Period>
315struct __duration_cast<_FromDuration, _ToDuration, _Period, true, false>
316{
317    _LIBCPP_INLINE_VISIBILITY
318    _ToDuration operator()(const _FromDuration& __fd) const
319    {
320        typedef typename common_type<typename _ToDuration::rep, typename _FromDuration::rep, intmax_t>::type _Ct;
321        return _ToDuration(static_cast<typename _ToDuration::rep>(
322                           static_cast<_Ct>(__fd.count()) / static_cast<_Ct>(_Period::den)));
323    }
324};
325
326template <class _FromDuration, class _ToDuration, class _Period>
327struct __duration_cast<_FromDuration, _ToDuration, _Period, false, true>
328{
329    _LIBCPP_INLINE_VISIBILITY
330    _ToDuration operator()(const _FromDuration& __fd) const
331    {
332        typedef typename common_type<typename _ToDuration::rep, typename _FromDuration::rep, intmax_t>::type _Ct;
333        return _ToDuration(static_cast<typename _ToDuration::rep>(
334                           static_cast<_Ct>(__fd.count()) * static_cast<_Ct>(_Period::num)));
335    }
336};
337
338template <class _FromDuration, class _ToDuration, class _Period>
339struct __duration_cast<_FromDuration, _ToDuration, _Period, false, false>
340{
341    _LIBCPP_INLINE_VISIBILITY
342    _ToDuration operator()(const _FromDuration& __fd) const
343    {
344        typedef typename common_type<typename _ToDuration::rep, typename _FromDuration::rep, intmax_t>::type _Ct;
345        return _ToDuration(static_cast<typename _ToDuration::rep>(
346                           static_cast<_Ct>(__fd.count()) * static_cast<_Ct>(_Period::num)
347                                                          / static_cast<_Ct>(_Period::den)));
348    }
349};
350
351template <class _ToDuration, class _Rep, class _Period>
352inline _LIBCPP_INLINE_VISIBILITY
353typename enable_if
354<
355    __is_duration<_ToDuration>::value,
356    _ToDuration
357>::type
358duration_cast(const duration<_Rep, _Period>& __fd)
359{
360    return __duration_cast<duration<_Rep, _Period>, _ToDuration>()(__fd);
361}
362
363template <class _Rep>
364struct _LIBCPP_VISIBLE treat_as_floating_point : is_floating_point<_Rep> {};
365
366template <class _Rep>
367struct _LIBCPP_VISIBLE duration_values
368{
369public:
370    _LIBCPP_INLINE_VISIBILITY static _Rep zero() {return _Rep(0);}
371    _LIBCPP_INLINE_VISIBILITY static _Rep max()  {return numeric_limits<_Rep>::max();}
372    _LIBCPP_INLINE_VISIBILITY static _Rep min()  {return numeric_limits<_Rep>::lowest();}
373};
374
375// duration
376
377template <class _Rep, class _Period>
378class _LIBCPP_VISIBLE duration
379{
380    static_assert(!__is_duration<_Rep>::value, "A duration representation can not be a duration");
381    static_assert(__is_ratio<_Period>::value, "Second template parameter of duration must be a std::ratio");
382    static_assert(_Period::num > 0, "duration period must be positive");
383public:
384    typedef _Rep rep;
385    typedef _Period period;
386private:
387    rep __rep_;
388public:
389
390    _LIBCPP_INLINE_VISIBILITY duration() {} // = default;
391    template <class _Rep2>
392        _LIBCPP_INLINE_VISIBILITY
393        explicit duration(const _Rep2& __r,
394            typename enable_if
395            <
396               is_convertible<_Rep2, rep>::value &&
397               (treat_as_floating_point<rep>::value ||
398               !treat_as_floating_point<_Rep2>::value)
399            >::type* = 0)
400                : __rep_(__r) {}
401
402    // conversions
403    template <class _Rep2, class _Period2>
404        _LIBCPP_INLINE_VISIBILITY
405        duration(const duration<_Rep2, _Period2>& __d,
406            typename enable_if
407            <
408                treat_as_floating_point<rep>::value ||
409                (ratio_divide<_Period2, period>::type::den == 1 &&
410                 !treat_as_floating_point<_Rep2>::value)
411            >::type* = 0)
412                : __rep_(_VSTD::chrono::duration_cast<duration>(__d).count()) {}
413
414    // observer
415
416    _LIBCPP_INLINE_VISIBILITY rep count() const {return __rep_;}
417
418    // arithmetic
419
420    _LIBCPP_INLINE_VISIBILITY duration  operator+() const {return *this;}
421    _LIBCPP_INLINE_VISIBILITY duration  operator-() const {return duration(-__rep_);}
422    _LIBCPP_INLINE_VISIBILITY duration& operator++()      {++__rep_; return *this;}
423    _LIBCPP_INLINE_VISIBILITY duration  operator++(int)   {return duration(__rep_++);}
424    _LIBCPP_INLINE_VISIBILITY duration& operator--()      {--__rep_; return *this;}
425    _LIBCPP_INLINE_VISIBILITY duration  operator--(int)   {return duration(__rep_--);}
426
427    _LIBCPP_INLINE_VISIBILITY duration& operator+=(const duration& __d) {__rep_ += __d.count(); return *this;}
428    _LIBCPP_INLINE_VISIBILITY duration& operator-=(const duration& __d) {__rep_ -= __d.count(); return *this;}
429
430    _LIBCPP_INLINE_VISIBILITY duration& operator*=(const rep& rhs) {__rep_ *= rhs; return *this;}
431    _LIBCPP_INLINE_VISIBILITY duration& operator/=(const rep& rhs) {__rep_ /= rhs; return *this;}
432    _LIBCPP_INLINE_VISIBILITY duration& operator%=(const rep& rhs) {__rep_ %= rhs; return *this;}
433    _LIBCPP_INLINE_VISIBILITY duration& operator%=(const duration& rhs) {__rep_ %= rhs.count(); return *this;}
434
435    // special values
436
437    _LIBCPP_INLINE_VISIBILITY static duration zero() {return duration(duration_values<rep>::zero());}
438    _LIBCPP_INLINE_VISIBILITY static duration min()  {return duration(duration_values<rep>::min());}
439    _LIBCPP_INLINE_VISIBILITY static duration max()  {return duration(duration_values<rep>::max());}
440};
441
442typedef duration<long long,         nano> nanoseconds;
443typedef duration<long long,        micro> microseconds;
444typedef duration<long long,        milli> milliseconds;
445typedef duration<long long              > seconds;
446typedef duration<     long, ratio<  60> > minutes;
447typedef duration<     long, ratio<3600> > hours;
448
449// Duration ==
450
451template <class _LhsDuration, class _RhsDuration>
452struct __duration_eq
453{
454    _LIBCPP_INLINE_VISIBILITY
455    bool operator()(const _LhsDuration& __lhs, const _RhsDuration& __rhs)
456        {
457            typedef typename common_type<_LhsDuration, _RhsDuration>::type _Ct;
458            return _Ct(__lhs).count() == _Ct(__rhs).count();
459        }
460};
461
462template <class _LhsDuration>
463struct __duration_eq<_LhsDuration, _LhsDuration>
464{
465    _LIBCPP_INLINE_VISIBILITY
466    bool operator()(const _LhsDuration& __lhs, const _LhsDuration& __rhs)
467        {return __lhs.count() == __rhs.count();}
468};
469
470template <class _Rep1, class _Period1, class _Rep2, class _Period2>
471inline _LIBCPP_INLINE_VISIBILITY
472bool
473operator==(const duration<_Rep1, _Period1>& __lhs, const duration<_Rep2, _Period2>& __rhs)
474{
475    return __duration_eq<duration<_Rep1, _Period1>, duration<_Rep2, _Period2> >()(__lhs, __rhs);
476}
477
478// Duration !=
479
480template <class _Rep1, class _Period1, class _Rep2, class _Period2>
481inline _LIBCPP_INLINE_VISIBILITY
482bool
483operator!=(const duration<_Rep1, _Period1>& __lhs, const duration<_Rep2, _Period2>& __rhs)
484{
485    return !(__lhs == __rhs);
486}
487
488// Duration <
489
490template <class _LhsDuration, class _RhsDuration>
491struct __duration_lt
492{
493    _LIBCPP_INLINE_VISIBILITY
494    bool operator()(const _LhsDuration& __lhs, const _RhsDuration& __rhs)
495        {
496            typedef typename common_type<_LhsDuration, _RhsDuration>::type _Ct;
497            return _Ct(__lhs).count() < _Ct(__rhs).count();
498        }
499};
500
501template <class _LhsDuration>
502struct __duration_lt<_LhsDuration, _LhsDuration>
503{
504    _LIBCPP_INLINE_VISIBILITY
505    bool operator()(const _LhsDuration& __lhs, const _LhsDuration& __rhs)
506        {return __lhs.count() < __rhs.count();}
507};
508
509template <class _Rep1, class _Period1, class _Rep2, class _Period2>
510inline _LIBCPP_INLINE_VISIBILITY
511bool
512operator< (const duration<_Rep1, _Period1>& __lhs, const duration<_Rep2, _Period2>& __rhs)
513{
514    return __duration_lt<duration<_Rep1, _Period1>, duration<_Rep2, _Period2> >()(__lhs, __rhs);
515}
516
517// Duration >
518
519template <class _Rep1, class _Period1, class _Rep2, class _Period2>
520inline _LIBCPP_INLINE_VISIBILITY
521bool
522operator> (const duration<_Rep1, _Period1>& __lhs, const duration<_Rep2, _Period2>& __rhs)
523{
524    return __rhs < __lhs;
525}
526
527// Duration <=
528
529template <class _Rep1, class _Period1, class _Rep2, class _Period2>
530inline _LIBCPP_INLINE_VISIBILITY
531bool
532operator<=(const duration<_Rep1, _Period1>& __lhs, const duration<_Rep2, _Period2>& __rhs)
533{
534    return !(__rhs < __lhs);
535}
536
537// Duration >=
538
539template <class _Rep1, class _Period1, class _Rep2, class _Period2>
540inline _LIBCPP_INLINE_VISIBILITY
541bool
542operator>=(const duration<_Rep1, _Period1>& __lhs, const duration<_Rep2, _Period2>& __rhs)
543{
544    return !(__lhs < __rhs);
545}
546
547// Duration +
548
549template <class _Rep1, class _Period1, class _Rep2, class _Period2>
550inline _LIBCPP_INLINE_VISIBILITY
551typename common_type<duration<_Rep1, _Period1>, duration<_Rep2, _Period2> >::type
552operator+(const duration<_Rep1, _Period1>& __lhs, const duration<_Rep2, _Period2>& __rhs)
553{
554    typename common_type<duration<_Rep1, _Period1>, duration<_Rep2, _Period2> >::type __r = __lhs;
555    __r += __rhs;
556    return __r;
557}
558
559// Duration -
560
561template <class _Rep1, class _Period1, class _Rep2, class _Period2>
562inline _LIBCPP_INLINE_VISIBILITY
563typename common_type<duration<_Rep1, _Period1>, duration<_Rep2, _Period2> >::type
564operator-(const duration<_Rep1, _Period1>& __lhs, const duration<_Rep2, _Period2>& __rhs)
565{
566    typename common_type<duration<_Rep1, _Period1>, duration<_Rep2, _Period2> >::type __r = __lhs;
567    __r -= __rhs;
568    return __r;
569}
570
571// Duration *
572
573template <class _Rep1, class _Period, class _Rep2>
574inline _LIBCPP_INLINE_VISIBILITY
575typename enable_if
576<
577    is_convertible<_Rep2, typename common_type<_Rep1, _Rep2>::type>::value,
578    duration<typename common_type<_Rep1, _Rep2>::type, _Period>
579>::type
580operator*(const duration<_Rep1, _Period>& __d, const _Rep2& __s)
581{
582    typedef typename common_type<_Rep1, _Rep2>::type _Cr;
583    duration<_Cr, _Period> __r = __d;
584    __r *= static_cast<_Cr>(__s);
585    return __r;
586}
587
588template <class _Rep1, class _Period, class _Rep2>
589inline _LIBCPP_INLINE_VISIBILITY
590typename enable_if
591<
592    is_convertible<_Rep1, typename common_type<_Rep1, _Rep2>::type>::value,
593    duration<typename common_type<_Rep1, _Rep2>::type, _Period>
594>::type
595operator*(const _Rep1& __s, const duration<_Rep2, _Period>& __d)
596{
597    return __d * __s;
598}
599
600// Duration /
601
602template <class _Duration, class _Rep, bool = __is_duration<_Rep>::value>
603struct __duration_divide_result
604{
605};
606
607template <class _Duration, class _Rep2,
608    bool = is_convertible<_Rep2,
609                          typename common_type<typename _Duration::rep, _Rep2>::type>::value>
610struct __duration_divide_imp
611{
612};
613
614template <class _Rep1, class _Period, class _Rep2>
615struct __duration_divide_imp<duration<_Rep1, _Period>, _Rep2, true>
616{
617    typedef duration<typename common_type<_Rep1, _Rep2>::type, _Period> type;
618};
619
620template <class _Rep1, class _Period, class _Rep2>
621struct __duration_divide_result<duration<_Rep1, _Period>, _Rep2, false>
622    : __duration_divide_imp<duration<_Rep1, _Period>, _Rep2>
623{
624};
625
626template <class _Rep1, class _Period, class _Rep2>
627inline _LIBCPP_INLINE_VISIBILITY
628typename __duration_divide_result<duration<_Rep1, _Period>, _Rep2>::type
629operator/(const duration<_Rep1, _Period>& __d, const _Rep2& __s)
630{
631    typedef typename common_type<_Rep1, _Rep2>::type _Cr;
632    duration<_Cr, _Period> __r = __d;
633    __r /= static_cast<_Cr>(__s);
634    return __r;
635}
636
637template <class _Rep1, class _Period1, class _Rep2, class _Period2>
638inline _LIBCPP_INLINE_VISIBILITY
639typename common_type<_Rep1, _Rep2>::type
640operator/(const duration<_Rep1, _Period1>& __lhs, const duration<_Rep2, _Period2>& __rhs)
641{
642    typedef typename common_type<duration<_Rep1, _Period1>, duration<_Rep2, _Period2> >::type _Ct;
643    return _Ct(__lhs).count() / _Ct(__rhs).count();
644}
645
646// Duration %
647
648template <class _Rep1, class _Period, class _Rep2>
649inline _LIBCPP_INLINE_VISIBILITY
650typename __duration_divide_result<duration<_Rep1, _Period>, _Rep2>::type
651operator%(const duration<_Rep1, _Period>& __d, const _Rep2& __s)
652{
653    typedef typename common_type<_Rep1, _Rep2>::type _Cr;
654    duration<_Cr, _Period> __r = __d;
655    __r %= static_cast<_Cr>(__s);
656    return __r;
657}
658
659template <class _Rep1, class _Period1, class _Rep2, class _Period2>
660inline _LIBCPP_INLINE_VISIBILITY
661typename common_type<duration<_Rep1, _Period1>, duration<_Rep2, _Period2> >::type
662operator%(const duration<_Rep1, _Period1>& __lhs, const duration<_Rep2, _Period2>& __rhs)
663{
664    typename common_type<duration<_Rep1, _Period1>, duration<_Rep2, _Period2> >::type __r = __lhs;
665    __r %= __rhs;
666    return __r;
667}
668
669//////////////////////////////////////////////////////////
670///////////////////// time_point /////////////////////////
671//////////////////////////////////////////////////////////
672
673template <class _Clock, class _Duration = typename _Clock::duration>
674class _LIBCPP_VISIBLE time_point
675{
676    static_assert(__is_duration<_Duration>::value,
677                  "Second template parameter of time_point must be a std::chrono::duration");
678public:
679    typedef _Clock                    clock;
680    typedef _Duration                 duration;
681    typedef typename duration::rep    rep;
682    typedef typename duration::period period;
683private:
684    duration __d_;
685
686public:
687    _LIBCPP_INLINE_VISIBILITY time_point() : __d_(duration::zero()) {}
688    _LIBCPP_INLINE_VISIBILITY explicit time_point(const duration& __d) : __d_(__d) {}
689
690    // conversions
691    template <class _Duration2>
692    _LIBCPP_INLINE_VISIBILITY
693    time_point(const time_point<clock, _Duration2>& t,
694        typename enable_if
695        <
696            is_convertible<_Duration2, duration>::value
697        >::type* = 0)
698            : __d_(t.time_since_epoch()) {}
699
700    // observer
701
702    _LIBCPP_INLINE_VISIBILITY duration time_since_epoch() const {return __d_;}
703
704    // arithmetic
705
706    _LIBCPP_INLINE_VISIBILITY time_point& operator+=(const duration& __d) {__d_ += __d;}
707    _LIBCPP_INLINE_VISIBILITY time_point& operator-=(const duration& __d) {__d_ -= __d;}
708
709    // special values
710
711    _LIBCPP_INLINE_VISIBILITY static time_point min() {return time_point(duration::min());}
712    _LIBCPP_INLINE_VISIBILITY static time_point max() {return time_point(duration::max());}
713};
714
715} // chrono
716
717template <class _Clock, class _Duration1, class _Duration2>
718struct _LIBCPP_VISIBLE common_type<chrono::time_point<_Clock, _Duration1>,
719                                   chrono::time_point<_Clock, _Duration2> >
720{
721    typedef chrono::time_point<_Clock, typename common_type<_Duration1, _Duration2>::type> type;
722};
723
724namespace chrono {
725
726template <class _ToDuration, class _Clock, class _Duration>
727inline _LIBCPP_INLINE_VISIBILITY
728time_point<_Clock, _ToDuration>
729time_point_cast(const time_point<_Clock, _Duration>& __t)
730{
731    return time_point<_Clock, _ToDuration>(_VSTD::chrono::duration_cast<_ToDuration>(__t.time_since_epoch()));
732}
733
734// time_point ==
735
736template <class _Clock, class _Duration1, class _Duration2>
737inline _LIBCPP_INLINE_VISIBILITY
738bool
739operator==(const time_point<_Clock, _Duration1>& __lhs, const time_point<_Clock, _Duration2>& __rhs)
740{
741    return __lhs.time_since_epoch() == __rhs.time_since_epoch();
742}
743
744// time_point !=
745
746template <class _Clock, class _Duration1, class _Duration2>
747inline _LIBCPP_INLINE_VISIBILITY
748bool
749operator!=(const time_point<_Clock, _Duration1>& __lhs, const time_point<_Clock, _Duration2>& __rhs)
750{
751    return !(__lhs == __rhs);
752}
753
754// time_point <
755
756template <class _Clock, class _Duration1, class _Duration2>
757inline _LIBCPP_INLINE_VISIBILITY
758bool
759operator<(const time_point<_Clock, _Duration1>& __lhs, const time_point<_Clock, _Duration2>& __rhs)
760{
761    return __lhs.time_since_epoch() < __rhs.time_since_epoch();
762}
763
764// time_point >
765
766template <class _Clock, class _Duration1, class _Duration2>
767inline _LIBCPP_INLINE_VISIBILITY
768bool
769operator>(const time_point<_Clock, _Duration1>& __lhs, const time_point<_Clock, _Duration2>& __rhs)
770{
771    return __rhs < __lhs;
772}
773
774// time_point <=
775
776template <class _Clock, class _Duration1, class _Duration2>
777inline _LIBCPP_INLINE_VISIBILITY
778bool
779operator<=(const time_point<_Clock, _Duration1>& __lhs, const time_point<_Clock, _Duration2>& __rhs)
780{
781    return !(__rhs < __lhs);
782}
783
784// time_point >=
785
786template <class _Clock, class _Duration1, class _Duration2>
787inline _LIBCPP_INLINE_VISIBILITY
788bool
789operator>=(const time_point<_Clock, _Duration1>& __lhs, const time_point<_Clock, _Duration2>& __rhs)
790{
791    return !(__lhs < __rhs);
792}
793
794// time_point operator+(time_point x, duration y);
795
796template <class _Clock, class _Duration1, class _Rep2, class _Period2>
797inline _LIBCPP_INLINE_VISIBILITY
798time_point<_Clock, typename common_type<_Duration1, duration<_Rep2, _Period2> >::type>
799operator+(const time_point<_Clock, _Duration1>& __lhs, const duration<_Rep2, _Period2>& __rhs)
800{
801    typedef time_point<_Clock, typename common_type<_Duration1, duration<_Rep2, _Period2> >::type> _Tr;
802    _Tr __r(__lhs.time_since_epoch());
803    __r += __rhs;
804    return __r;
805}
806
807// time_point operator+(duration x, time_point y);
808
809template <class _Rep1, class _Period1, class _Clock, class _Duration2>
810inline _LIBCPP_INLINE_VISIBILITY
811time_point<_Clock, typename common_type<duration<_Rep1, _Period1>, _Duration2>::type>
812operator+(const duration<_Rep1, _Period1>& __lhs, const time_point<_Clock, _Duration2>& __rhs)
813{
814    return __rhs + __lhs;
815}
816
817// time_point operator-(time_point x, duration y);
818
819template <class _Clock, class _Duration1, class _Rep2, class _Period2>
820inline _LIBCPP_INLINE_VISIBILITY
821time_point<_Clock, typename common_type<_Duration1, duration<_Rep2, _Period2> >::type>
822operator-(const time_point<_Clock, _Duration1>& __lhs, const duration<_Rep2, _Period2>& __rhs)
823{
824    return __lhs + (-__rhs);
825}
826
827// duration operator-(time_point x, time_point y);
828
829template <class _Clock, class _Duration1, class _Duration2>
830inline _LIBCPP_INLINE_VISIBILITY
831typename common_type<_Duration1, _Duration2>::type
832operator-(const time_point<_Clock, _Duration1>& __lhs, const time_point<_Clock, _Duration2>& __rhs)
833{
834    return __lhs.time_since_epoch() - __rhs.time_since_epoch();
835}
836
837//////////////////////////////////////////////////////////
838/////////////////////// clocks ///////////////////////////
839//////////////////////////////////////////////////////////
840
841class _LIBCPP_VISIBLE system_clock
842{
843public:
844    typedef microseconds                     duration;
845    typedef duration::rep                    rep;
846    typedef duration::period                 period;
847    typedef chrono::time_point<system_clock> time_point;
848    static const bool is_steady =            false;
849
850    static time_point now() _NOEXCEPT;
851    static time_t     to_time_t  (const time_point& __t) _NOEXCEPT;
852    static time_point from_time_t(time_t __t) _NOEXCEPT;
853};
854
855class _LIBCPP_VISIBLE steady_clock
856{
857public:
858    typedef nanoseconds                                   duration;
859    typedef duration::rep                                 rep;
860    typedef duration::period                              period;
861    typedef chrono::time_point<steady_clock, duration>    time_point;
862    static const bool is_steady =                         true;
863
864    static time_point now() _NOEXCEPT;
865};
866
867typedef steady_clock high_resolution_clock;
868
869} // chrono
870
871_LIBCPP_END_NAMESPACE_STD
872
873#endif  // _LIBCPP_CHRONO
874