chrono revision 232950
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#include <__undef_min_max>
259
260#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
261#pragma GCC system_header
262#endif
263
264_LIBCPP_BEGIN_NAMESPACE_STD
265
266namespace chrono
267{
268
269template <class _Rep, class _Period = ratio<1> > class _LIBCPP_VISIBLE duration;
270
271template <class _Tp>
272struct __is_duration : false_type {};
273
274template <class _Rep, class _Period>
275struct __is_duration<duration<_Rep, _Period> > : true_type  {};
276
277template <class _Rep, class _Period>
278struct __is_duration<const duration<_Rep, _Period> > : true_type  {};
279
280template <class _Rep, class _Period>
281struct __is_duration<volatile duration<_Rep, _Period> > : true_type  {};
282
283template <class _Rep, class _Period>
284struct __is_duration<const volatile duration<_Rep, _Period> > : true_type  {};
285
286} // chrono
287
288template <class _Rep1, class _Period1, class _Rep2, class _Period2>
289struct _LIBCPP_VISIBLE common_type<chrono::duration<_Rep1, _Period1>,
290                                   chrono::duration<_Rep2, _Period2> >
291{
292    typedef chrono::duration<typename common_type<_Rep1, _Rep2>::type,
293                             typename __ratio_gcd<_Period1, _Period2>::type> type;
294};
295
296namespace chrono {
297
298// duration_cast
299
300template <class _FromDuration, class _ToDuration,
301          class _Period = typename ratio_divide<typename _FromDuration::period, typename _ToDuration::period>::type,
302          bool = _Period::num == 1,
303          bool = _Period::den == 1>
304struct __duration_cast;
305
306template <class _FromDuration, class _ToDuration, class _Period>
307struct __duration_cast<_FromDuration, _ToDuration, _Period, true, true>
308{
309    _LIBCPP_INLINE_VISIBILITY
310    _ToDuration operator()(const _FromDuration& __fd) const
311    {
312        return _ToDuration(static_cast<typename _ToDuration::rep>(__fd.count()));
313    }
314};
315
316template <class _FromDuration, class _ToDuration, class _Period>
317struct __duration_cast<_FromDuration, _ToDuration, _Period, true, false>
318{
319    _LIBCPP_INLINE_VISIBILITY
320    _ToDuration operator()(const _FromDuration& __fd) const
321    {
322        typedef typename common_type<typename _ToDuration::rep, typename _FromDuration::rep, intmax_t>::type _Ct;
323        return _ToDuration(static_cast<typename _ToDuration::rep>(
324                           static_cast<_Ct>(__fd.count()) / static_cast<_Ct>(_Period::den)));
325    }
326};
327
328template <class _FromDuration, class _ToDuration, class _Period>
329struct __duration_cast<_FromDuration, _ToDuration, _Period, false, true>
330{
331    _LIBCPP_INLINE_VISIBILITY
332    _ToDuration operator()(const _FromDuration& __fd) const
333    {
334        typedef typename common_type<typename _ToDuration::rep, typename _FromDuration::rep, intmax_t>::type _Ct;
335        return _ToDuration(static_cast<typename _ToDuration::rep>(
336                           static_cast<_Ct>(__fd.count()) * static_cast<_Ct>(_Period::num)));
337    }
338};
339
340template <class _FromDuration, class _ToDuration, class _Period>
341struct __duration_cast<_FromDuration, _ToDuration, _Period, false, false>
342{
343    _LIBCPP_INLINE_VISIBILITY
344    _ToDuration operator()(const _FromDuration& __fd) const
345    {
346        typedef typename common_type<typename _ToDuration::rep, typename _FromDuration::rep, intmax_t>::type _Ct;
347        return _ToDuration(static_cast<typename _ToDuration::rep>(
348                           static_cast<_Ct>(__fd.count()) * static_cast<_Ct>(_Period::num)
349                                                          / static_cast<_Ct>(_Period::den)));
350    }
351};
352
353template <class _ToDuration, class _Rep, class _Period>
354inline _LIBCPP_INLINE_VISIBILITY
355typename enable_if
356<
357    __is_duration<_ToDuration>::value,
358    _ToDuration
359>::type
360duration_cast(const duration<_Rep, _Period>& __fd)
361{
362    return __duration_cast<duration<_Rep, _Period>, _ToDuration>()(__fd);
363}
364
365template <class _Rep>
366struct _LIBCPP_VISIBLE treat_as_floating_point : is_floating_point<_Rep> {};
367
368template <class _Rep>
369struct _LIBCPP_VISIBLE duration_values
370{
371public:
372    _LIBCPP_INLINE_VISIBILITY static _Rep zero() {return _Rep(0);}
373    _LIBCPP_INLINE_VISIBILITY static _Rep max()  {return numeric_limits<_Rep>::max();}
374    _LIBCPP_INLINE_VISIBILITY static _Rep min()  {return numeric_limits<_Rep>::lowest();}
375};
376
377// duration
378
379template <class _Rep, class _Period>
380class _LIBCPP_VISIBLE duration
381{
382    static_assert(!__is_duration<_Rep>::value, "A duration representation can not be a duration");
383    static_assert(__is_ratio<_Period>::value, "Second template parameter of duration must be a std::ratio");
384    static_assert(_Period::num > 0, "duration period must be positive");
385public:
386    typedef _Rep rep;
387    typedef _Period period;
388private:
389    rep __rep_;
390public:
391
392    _LIBCPP_INLINE_VISIBILITY duration() {} // = default;
393    template <class _Rep2>
394        _LIBCPP_INLINE_VISIBILITY
395        explicit duration(const _Rep2& __r,
396            typename enable_if
397            <
398               is_convertible<_Rep2, rep>::value &&
399               (treat_as_floating_point<rep>::value ||
400               !treat_as_floating_point<_Rep2>::value)
401            >::type* = 0)
402                : __rep_(__r) {}
403
404    // conversions
405    template <class _Rep2, class _Period2>
406        _LIBCPP_INLINE_VISIBILITY
407        duration(const duration<_Rep2, _Period2>& __d,
408            typename enable_if
409            <
410                treat_as_floating_point<rep>::value ||
411                (ratio_divide<_Period2, period>::type::den == 1 &&
412                 !treat_as_floating_point<_Rep2>::value)
413            >::type* = 0)
414                : __rep_(_VSTD::chrono::duration_cast<duration>(__d).count()) {}
415
416    // observer
417
418    _LIBCPP_INLINE_VISIBILITY rep count() const {return __rep_;}
419
420    // arithmetic
421
422    _LIBCPP_INLINE_VISIBILITY duration  operator+() const {return *this;}
423    _LIBCPP_INLINE_VISIBILITY duration  operator-() const {return duration(-__rep_);}
424    _LIBCPP_INLINE_VISIBILITY duration& operator++()      {++__rep_; return *this;}
425    _LIBCPP_INLINE_VISIBILITY duration  operator++(int)   {return duration(__rep_++);}
426    _LIBCPP_INLINE_VISIBILITY duration& operator--()      {--__rep_; return *this;}
427    _LIBCPP_INLINE_VISIBILITY duration  operator--(int)   {return duration(__rep_--);}
428
429    _LIBCPP_INLINE_VISIBILITY duration& operator+=(const duration& __d) {__rep_ += __d.count(); return *this;}
430    _LIBCPP_INLINE_VISIBILITY duration& operator-=(const duration& __d) {__rep_ -= __d.count(); return *this;}
431
432    _LIBCPP_INLINE_VISIBILITY duration& operator*=(const rep& rhs) {__rep_ *= rhs; return *this;}
433    _LIBCPP_INLINE_VISIBILITY duration& operator/=(const rep& rhs) {__rep_ /= rhs; return *this;}
434    _LIBCPP_INLINE_VISIBILITY duration& operator%=(const rep& rhs) {__rep_ %= rhs; return *this;}
435    _LIBCPP_INLINE_VISIBILITY duration& operator%=(const duration& rhs) {__rep_ %= rhs.count(); return *this;}
436
437    // special values
438
439    _LIBCPP_INLINE_VISIBILITY static duration zero() {return duration(duration_values<rep>::zero());}
440    _LIBCPP_INLINE_VISIBILITY static duration min()  {return duration(duration_values<rep>::min());}
441    _LIBCPP_INLINE_VISIBILITY static duration max()  {return duration(duration_values<rep>::max());}
442};
443
444typedef duration<long long,         nano> nanoseconds;
445typedef duration<long long,        micro> microseconds;
446typedef duration<long long,        milli> milliseconds;
447typedef duration<long long              > seconds;
448typedef duration<     long, ratio<  60> > minutes;
449typedef duration<     long, ratio<3600> > hours;
450
451// Duration ==
452
453template <class _LhsDuration, class _RhsDuration>
454struct __duration_eq
455{
456    _LIBCPP_INLINE_VISIBILITY
457    bool operator()(const _LhsDuration& __lhs, const _RhsDuration& __rhs)
458        {
459            typedef typename common_type<_LhsDuration, _RhsDuration>::type _Ct;
460            return _Ct(__lhs).count() == _Ct(__rhs).count();
461        }
462};
463
464template <class _LhsDuration>
465struct __duration_eq<_LhsDuration, _LhsDuration>
466{
467    _LIBCPP_INLINE_VISIBILITY
468    bool operator()(const _LhsDuration& __lhs, const _LhsDuration& __rhs)
469        {return __lhs.count() == __rhs.count();}
470};
471
472template <class _Rep1, class _Period1, class _Rep2, class _Period2>
473inline _LIBCPP_INLINE_VISIBILITY
474bool
475operator==(const duration<_Rep1, _Period1>& __lhs, const duration<_Rep2, _Period2>& __rhs)
476{
477    return __duration_eq<duration<_Rep1, _Period1>, duration<_Rep2, _Period2> >()(__lhs, __rhs);
478}
479
480// Duration !=
481
482template <class _Rep1, class _Period1, class _Rep2, class _Period2>
483inline _LIBCPP_INLINE_VISIBILITY
484bool
485operator!=(const duration<_Rep1, _Period1>& __lhs, const duration<_Rep2, _Period2>& __rhs)
486{
487    return !(__lhs == __rhs);
488}
489
490// Duration <
491
492template <class _LhsDuration, class _RhsDuration>
493struct __duration_lt
494{
495    _LIBCPP_INLINE_VISIBILITY
496    bool operator()(const _LhsDuration& __lhs, const _RhsDuration& __rhs)
497        {
498            typedef typename common_type<_LhsDuration, _RhsDuration>::type _Ct;
499            return _Ct(__lhs).count() < _Ct(__rhs).count();
500        }
501};
502
503template <class _LhsDuration>
504struct __duration_lt<_LhsDuration, _LhsDuration>
505{
506    _LIBCPP_INLINE_VISIBILITY
507    bool operator()(const _LhsDuration& __lhs, const _LhsDuration& __rhs)
508        {return __lhs.count() < __rhs.count();}
509};
510
511template <class _Rep1, class _Period1, class _Rep2, class _Period2>
512inline _LIBCPP_INLINE_VISIBILITY
513bool
514operator< (const duration<_Rep1, _Period1>& __lhs, const duration<_Rep2, _Period2>& __rhs)
515{
516    return __duration_lt<duration<_Rep1, _Period1>, duration<_Rep2, _Period2> >()(__lhs, __rhs);
517}
518
519// Duration >
520
521template <class _Rep1, class _Period1, class _Rep2, class _Period2>
522inline _LIBCPP_INLINE_VISIBILITY
523bool
524operator> (const duration<_Rep1, _Period1>& __lhs, const duration<_Rep2, _Period2>& __rhs)
525{
526    return __rhs < __lhs;
527}
528
529// Duration <=
530
531template <class _Rep1, class _Period1, class _Rep2, class _Period2>
532inline _LIBCPP_INLINE_VISIBILITY
533bool
534operator<=(const duration<_Rep1, _Period1>& __lhs, const duration<_Rep2, _Period2>& __rhs)
535{
536    return !(__rhs < __lhs);
537}
538
539// Duration >=
540
541template <class _Rep1, class _Period1, class _Rep2, class _Period2>
542inline _LIBCPP_INLINE_VISIBILITY
543bool
544operator>=(const duration<_Rep1, _Period1>& __lhs, const duration<_Rep2, _Period2>& __rhs)
545{
546    return !(__lhs < __rhs);
547}
548
549// Duration +
550
551template <class _Rep1, class _Period1, class _Rep2, class _Period2>
552inline _LIBCPP_INLINE_VISIBILITY
553typename common_type<duration<_Rep1, _Period1>, duration<_Rep2, _Period2> >::type
554operator+(const duration<_Rep1, _Period1>& __lhs, const duration<_Rep2, _Period2>& __rhs)
555{
556    typename common_type<duration<_Rep1, _Period1>, duration<_Rep2, _Period2> >::type __r = __lhs;
557    __r += __rhs;
558    return __r;
559}
560
561// Duration -
562
563template <class _Rep1, class _Period1, class _Rep2, class _Period2>
564inline _LIBCPP_INLINE_VISIBILITY
565typename common_type<duration<_Rep1, _Period1>, duration<_Rep2, _Period2> >::type
566operator-(const duration<_Rep1, _Period1>& __lhs, const duration<_Rep2, _Period2>& __rhs)
567{
568    typename common_type<duration<_Rep1, _Period1>, duration<_Rep2, _Period2> >::type __r = __lhs;
569    __r -= __rhs;
570    return __r;
571}
572
573// Duration *
574
575template <class _Rep1, class _Period, class _Rep2>
576inline _LIBCPP_INLINE_VISIBILITY
577typename enable_if
578<
579    is_convertible<_Rep2, typename common_type<_Rep1, _Rep2>::type>::value,
580    duration<typename common_type<_Rep1, _Rep2>::type, _Period>
581>::type
582operator*(const duration<_Rep1, _Period>& __d, const _Rep2& __s)
583{
584    typedef typename common_type<_Rep1, _Rep2>::type _Cr;
585    duration<_Cr, _Period> __r = __d;
586    __r *= static_cast<_Cr>(__s);
587    return __r;
588}
589
590template <class _Rep1, class _Period, class _Rep2>
591inline _LIBCPP_INLINE_VISIBILITY
592typename enable_if
593<
594    is_convertible<_Rep1, typename common_type<_Rep1, _Rep2>::type>::value,
595    duration<typename common_type<_Rep1, _Rep2>::type, _Period>
596>::type
597operator*(const _Rep1& __s, const duration<_Rep2, _Period>& __d)
598{
599    return __d * __s;
600}
601
602// Duration /
603
604template <class _Duration, class _Rep, bool = __is_duration<_Rep>::value>
605struct __duration_divide_result
606{
607};
608
609template <class _Duration, class _Rep2,
610    bool = is_convertible<_Rep2,
611                          typename common_type<typename _Duration::rep, _Rep2>::type>::value>
612struct __duration_divide_imp
613{
614};
615
616template <class _Rep1, class _Period, class _Rep2>
617struct __duration_divide_imp<duration<_Rep1, _Period>, _Rep2, true>
618{
619    typedef duration<typename common_type<_Rep1, _Rep2>::type, _Period> type;
620};
621
622template <class _Rep1, class _Period, class _Rep2>
623struct __duration_divide_result<duration<_Rep1, _Period>, _Rep2, false>
624    : __duration_divide_imp<duration<_Rep1, _Period>, _Rep2>
625{
626};
627
628template <class _Rep1, class _Period, class _Rep2>
629inline _LIBCPP_INLINE_VISIBILITY
630typename __duration_divide_result<duration<_Rep1, _Period>, _Rep2>::type
631operator/(const duration<_Rep1, _Period>& __d, const _Rep2& __s)
632{
633    typedef typename common_type<_Rep1, _Rep2>::type _Cr;
634    duration<_Cr, _Period> __r = __d;
635    __r /= static_cast<_Cr>(__s);
636    return __r;
637}
638
639template <class _Rep1, class _Period1, class _Rep2, class _Period2>
640inline _LIBCPP_INLINE_VISIBILITY
641typename common_type<_Rep1, _Rep2>::type
642operator/(const duration<_Rep1, _Period1>& __lhs, const duration<_Rep2, _Period2>& __rhs)
643{
644    typedef typename common_type<duration<_Rep1, _Period1>, duration<_Rep2, _Period2> >::type _Ct;
645    return _Ct(__lhs).count() / _Ct(__rhs).count();
646}
647
648// Duration %
649
650template <class _Rep1, class _Period, class _Rep2>
651inline _LIBCPP_INLINE_VISIBILITY
652typename __duration_divide_result<duration<_Rep1, _Period>, _Rep2>::type
653operator%(const duration<_Rep1, _Period>& __d, const _Rep2& __s)
654{
655    typedef typename common_type<_Rep1, _Rep2>::type _Cr;
656    duration<_Cr, _Period> __r = __d;
657    __r %= static_cast<_Cr>(__s);
658    return __r;
659}
660
661template <class _Rep1, class _Period1, class _Rep2, class _Period2>
662inline _LIBCPP_INLINE_VISIBILITY
663typename common_type<duration<_Rep1, _Period1>, duration<_Rep2, _Period2> >::type
664operator%(const duration<_Rep1, _Period1>& __lhs, const duration<_Rep2, _Period2>& __rhs)
665{
666    typename common_type<duration<_Rep1, _Period1>, duration<_Rep2, _Period2> >::type __r = __lhs;
667    __r %= __rhs;
668    return __r;
669}
670
671//////////////////////////////////////////////////////////
672///////////////////// time_point /////////////////////////
673//////////////////////////////////////////////////////////
674
675template <class _Clock, class _Duration = typename _Clock::duration>
676class _LIBCPP_VISIBLE time_point
677{
678    static_assert(__is_duration<_Duration>::value,
679                  "Second template parameter of time_point must be a std::chrono::duration");
680public:
681    typedef _Clock                    clock;
682    typedef _Duration                 duration;
683    typedef typename duration::rep    rep;
684    typedef typename duration::period period;
685private:
686    duration __d_;
687
688public:
689    _LIBCPP_INLINE_VISIBILITY time_point() : __d_(duration::zero()) {}
690    _LIBCPP_INLINE_VISIBILITY explicit time_point(const duration& __d) : __d_(__d) {}
691
692    // conversions
693    template <class _Duration2>
694    _LIBCPP_INLINE_VISIBILITY
695    time_point(const time_point<clock, _Duration2>& t,
696        typename enable_if
697        <
698            is_convertible<_Duration2, duration>::value
699        >::type* = 0)
700            : __d_(t.time_since_epoch()) {}
701
702    // observer
703
704    _LIBCPP_INLINE_VISIBILITY duration time_since_epoch() const {return __d_;}
705
706    // arithmetic
707
708    _LIBCPP_INLINE_VISIBILITY time_point& operator+=(const duration& __d) {__d_ += __d;}
709    _LIBCPP_INLINE_VISIBILITY time_point& operator-=(const duration& __d) {__d_ -= __d;}
710
711    // special values
712
713    _LIBCPP_INLINE_VISIBILITY static time_point min() {return time_point(duration::min());}
714    _LIBCPP_INLINE_VISIBILITY static time_point max() {return time_point(duration::max());}
715};
716
717} // chrono
718
719template <class _Clock, class _Duration1, class _Duration2>
720struct _LIBCPP_VISIBLE common_type<chrono::time_point<_Clock, _Duration1>,
721                                   chrono::time_point<_Clock, _Duration2> >
722{
723    typedef chrono::time_point<_Clock, typename common_type<_Duration1, _Duration2>::type> type;
724};
725
726namespace chrono {
727
728template <class _ToDuration, class _Clock, class _Duration>
729inline _LIBCPP_INLINE_VISIBILITY
730time_point<_Clock, _ToDuration>
731time_point_cast(const time_point<_Clock, _Duration>& __t)
732{
733    return time_point<_Clock, _ToDuration>(_VSTD::chrono::duration_cast<_ToDuration>(__t.time_since_epoch()));
734}
735
736// time_point ==
737
738template <class _Clock, class _Duration1, class _Duration2>
739inline _LIBCPP_INLINE_VISIBILITY
740bool
741operator==(const time_point<_Clock, _Duration1>& __lhs, const time_point<_Clock, _Duration2>& __rhs)
742{
743    return __lhs.time_since_epoch() == __rhs.time_since_epoch();
744}
745
746// time_point !=
747
748template <class _Clock, class _Duration1, class _Duration2>
749inline _LIBCPP_INLINE_VISIBILITY
750bool
751operator!=(const time_point<_Clock, _Duration1>& __lhs, const time_point<_Clock, _Duration2>& __rhs)
752{
753    return !(__lhs == __rhs);
754}
755
756// time_point <
757
758template <class _Clock, class _Duration1, class _Duration2>
759inline _LIBCPP_INLINE_VISIBILITY
760bool
761operator<(const time_point<_Clock, _Duration1>& __lhs, const time_point<_Clock, _Duration2>& __rhs)
762{
763    return __lhs.time_since_epoch() < __rhs.time_since_epoch();
764}
765
766// time_point >
767
768template <class _Clock, class _Duration1, class _Duration2>
769inline _LIBCPP_INLINE_VISIBILITY
770bool
771operator>(const time_point<_Clock, _Duration1>& __lhs, const time_point<_Clock, _Duration2>& __rhs)
772{
773    return __rhs < __lhs;
774}
775
776// time_point <=
777
778template <class _Clock, class _Duration1, class _Duration2>
779inline _LIBCPP_INLINE_VISIBILITY
780bool
781operator<=(const time_point<_Clock, _Duration1>& __lhs, const time_point<_Clock, _Duration2>& __rhs)
782{
783    return !(__rhs < __lhs);
784}
785
786// time_point >=
787
788template <class _Clock, class _Duration1, class _Duration2>
789inline _LIBCPP_INLINE_VISIBILITY
790bool
791operator>=(const time_point<_Clock, _Duration1>& __lhs, const time_point<_Clock, _Duration2>& __rhs)
792{
793    return !(__lhs < __rhs);
794}
795
796// time_point operator+(time_point x, duration y);
797
798template <class _Clock, class _Duration1, class _Rep2, class _Period2>
799inline _LIBCPP_INLINE_VISIBILITY
800time_point<_Clock, typename common_type<_Duration1, duration<_Rep2, _Period2> >::type>
801operator+(const time_point<_Clock, _Duration1>& __lhs, const duration<_Rep2, _Period2>& __rhs)
802{
803    typedef time_point<_Clock, typename common_type<_Duration1, duration<_Rep2, _Period2> >::type> _Tr;
804    _Tr __r(__lhs.time_since_epoch());
805    __r += __rhs;
806    return __r;
807}
808
809// time_point operator+(duration x, time_point y);
810
811template <class _Rep1, class _Period1, class _Clock, class _Duration2>
812inline _LIBCPP_INLINE_VISIBILITY
813time_point<_Clock, typename common_type<duration<_Rep1, _Period1>, _Duration2>::type>
814operator+(const duration<_Rep1, _Period1>& __lhs, const time_point<_Clock, _Duration2>& __rhs)
815{
816    return __rhs + __lhs;
817}
818
819// time_point operator-(time_point x, duration y);
820
821template <class _Clock, class _Duration1, class _Rep2, class _Period2>
822inline _LIBCPP_INLINE_VISIBILITY
823time_point<_Clock, typename common_type<_Duration1, duration<_Rep2, _Period2> >::type>
824operator-(const time_point<_Clock, _Duration1>& __lhs, const duration<_Rep2, _Period2>& __rhs)
825{
826    return __lhs + (-__rhs);
827}
828
829// duration operator-(time_point x, time_point y);
830
831template <class _Clock, class _Duration1, class _Duration2>
832inline _LIBCPP_INLINE_VISIBILITY
833typename common_type<_Duration1, _Duration2>::type
834operator-(const time_point<_Clock, _Duration1>& __lhs, const time_point<_Clock, _Duration2>& __rhs)
835{
836    return __lhs.time_since_epoch() - __rhs.time_since_epoch();
837}
838
839//////////////////////////////////////////////////////////
840/////////////////////// clocks ///////////////////////////
841//////////////////////////////////////////////////////////
842
843class _LIBCPP_VISIBLE system_clock
844{
845public:
846    typedef microseconds                     duration;
847    typedef duration::rep                    rep;
848    typedef duration::period                 period;
849    typedef chrono::time_point<system_clock> time_point;
850    static const bool is_steady =            false;
851
852    static time_point now() _NOEXCEPT;
853    static time_t     to_time_t  (const time_point& __t) _NOEXCEPT;
854    static time_point from_time_t(time_t __t) _NOEXCEPT;
855};
856
857class _LIBCPP_VISIBLE steady_clock
858{
859public:
860    typedef nanoseconds                                   duration;
861    typedef duration::rep                                 rep;
862    typedef duration::period                              period;
863    typedef chrono::time_point<steady_clock, duration>    time_point;
864    static const bool is_steady =                         true;
865
866    static time_point now() _NOEXCEPT;
867};
868
869typedef steady_clock high_resolution_clock;
870
871} // chrono
872
873_LIBCPP_END_NAMESPACE_STD
874
875#endif  // _LIBCPP_CHRONO
876