xref: /freebsd/contrib/llvm-project/libcxx/include/__chrono/duration.h (revision 9aaf4e3be61fc20a84347b7c2c524256a4b93a43)
1 // -*- C++ -*-
2 //===----------------------------------------------------------------------===//
3 //
4 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
5 // See https://llvm.org/LICENSE.txt for license information.
6 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7 //
8 //===----------------------------------------------------------------------===//
9 
10 #ifndef _LIBCPP___CHRONO_DURATION_H
11 #define _LIBCPP___CHRONO_DURATION_H
12 
13 #include <__compare/ordering.h>
14 #include <__compare/three_way_comparable.h>
15 #include <__config>
16 #include <__type_traits/common_type.h>
17 #include <__type_traits/enable_if.h>
18 #include <__type_traits/is_convertible.h>
19 #include <__type_traits/is_floating_point.h>
20 #include <limits>
21 #include <ratio>
22 
23 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
24 #  pragma GCC system_header
25 #endif
26 
27 _LIBCPP_PUSH_MACROS
28 #include <__undef_macros>
29 
30 _LIBCPP_BEGIN_NAMESPACE_STD
31 
32 namespace chrono
33 {
34 
35 template <class _Rep, class _Period = ratio<1> > class _LIBCPP_TEMPLATE_VIS duration;
36 
37 template <class _Tp>
38 struct __is_duration : false_type {};
39 
40 template <class _Rep, class _Period>
41 struct __is_duration<duration<_Rep, _Period> > : true_type  {};
42 
43 template <class _Rep, class _Period>
44 struct __is_duration<const duration<_Rep, _Period> > : true_type  {};
45 
46 template <class _Rep, class _Period>
47 struct __is_duration<volatile duration<_Rep, _Period> > : true_type  {};
48 
49 template <class _Rep, class _Period>
50 struct __is_duration<const volatile duration<_Rep, _Period> > : true_type  {};
51 
52 } // namespace chrono
53 
54 template <class _Rep1, class _Period1, class _Rep2, class _Period2>
55 struct _LIBCPP_TEMPLATE_VIS common_type<chrono::duration<_Rep1, _Period1>,
56                                          chrono::duration<_Rep2, _Period2> >
57 {
58     typedef chrono::duration<typename common_type<_Rep1, _Rep2>::type,
59                              typename __ratio_gcd<_Period1, _Period2>::type> type;
60 };
61 
62 namespace chrono {
63 
64 // duration_cast
65 
66 template <class _FromDuration, class _ToDuration,
67           class _Period = typename ratio_divide<typename _FromDuration::period, typename _ToDuration::period>::type,
68           bool = _Period::num == 1,
69           bool = _Period::den == 1>
70 struct __duration_cast;
71 
72 template <class _FromDuration, class _ToDuration, class _Period>
73 struct __duration_cast<_FromDuration, _ToDuration, _Period, true, true>
74 {
75     _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR
76     _ToDuration operator()(const _FromDuration& __fd) const
77     {
78         return _ToDuration(static_cast<typename _ToDuration::rep>(__fd.count()));
79     }
80 };
81 
82 template <class _FromDuration, class _ToDuration, class _Period>
83 struct __duration_cast<_FromDuration, _ToDuration, _Period, true, false>
84 {
85     _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR
86     _ToDuration operator()(const _FromDuration& __fd) const
87     {
88         typedef typename common_type<typename _ToDuration::rep, typename _FromDuration::rep, intmax_t>::type _Ct;
89         return _ToDuration(static_cast<typename _ToDuration::rep>(
90                            static_cast<_Ct>(__fd.count()) / static_cast<_Ct>(_Period::den)));
91     }
92 };
93 
94 template <class _FromDuration, class _ToDuration, class _Period>
95 struct __duration_cast<_FromDuration, _ToDuration, _Period, false, true>
96 {
97     _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR
98     _ToDuration operator()(const _FromDuration& __fd) const
99     {
100         typedef typename common_type<typename _ToDuration::rep, typename _FromDuration::rep, intmax_t>::type _Ct;
101         return _ToDuration(static_cast<typename _ToDuration::rep>(
102                            static_cast<_Ct>(__fd.count()) * static_cast<_Ct>(_Period::num)));
103     }
104 };
105 
106 template <class _FromDuration, class _ToDuration, class _Period>
107 struct __duration_cast<_FromDuration, _ToDuration, _Period, false, false>
108 {
109     _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR
110     _ToDuration operator()(const _FromDuration& __fd) const
111     {
112         typedef typename common_type<typename _ToDuration::rep, typename _FromDuration::rep, intmax_t>::type _Ct;
113         return _ToDuration(static_cast<typename _ToDuration::rep>(
114                            static_cast<_Ct>(__fd.count()) * static_cast<_Ct>(_Period::num)
115                                                           / static_cast<_Ct>(_Period::den)));
116     }
117 };
118 
119 template <class _ToDuration, class _Rep, class _Period>
120 inline _LIBCPP_INLINE_VISIBILITY
121 _LIBCPP_CONSTEXPR
122 typename enable_if
123 <
124     __is_duration<_ToDuration>::value,
125     _ToDuration
126 >::type
127 duration_cast(const duration<_Rep, _Period>& __fd)
128 {
129     return __duration_cast<duration<_Rep, _Period>, _ToDuration>()(__fd);
130 }
131 
132 template <class _Rep>
133 struct _LIBCPP_TEMPLATE_VIS treat_as_floating_point : is_floating_point<_Rep> {};
134 
135 #if _LIBCPP_STD_VER >= 17
136 template <class _Rep>
137 inline constexpr bool treat_as_floating_point_v = treat_as_floating_point<_Rep>::value;
138 #endif
139 
140 template <class _Rep>
141 struct _LIBCPP_TEMPLATE_VIS duration_values
142 {
143 public:
144     _LIBCPP_INLINE_VISIBILITY static _LIBCPP_CONSTEXPR _Rep zero() _NOEXCEPT {return _Rep(0);}
145     _LIBCPP_INLINE_VISIBILITY static _LIBCPP_CONSTEXPR _Rep max()  _NOEXCEPT {return numeric_limits<_Rep>::max();}
146     _LIBCPP_INLINE_VISIBILITY static _LIBCPP_CONSTEXPR _Rep min()  _NOEXCEPT {return numeric_limits<_Rep>::lowest();}
147 };
148 
149 #if _LIBCPP_STD_VER >= 17
150 template <class _ToDuration, class _Rep, class _Period>
151 inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR
152 typename enable_if
153 <
154     __is_duration<_ToDuration>::value,
155     _ToDuration
156 >::type
157 floor(const duration<_Rep, _Period>& __d)
158 {
159     _ToDuration __t = chrono::duration_cast<_ToDuration>(__d);
160     if (__t > __d)
161         __t = __t - _ToDuration{1};
162     return __t;
163 }
164 
165 template <class _ToDuration, class _Rep, class _Period>
166 inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR
167 typename enable_if
168 <
169     __is_duration<_ToDuration>::value,
170     _ToDuration
171 >::type
172 ceil(const duration<_Rep, _Period>& __d)
173 {
174     _ToDuration __t = chrono::duration_cast<_ToDuration>(__d);
175     if (__t < __d)
176         __t = __t + _ToDuration{1};
177     return __t;
178 }
179 
180 template <class _ToDuration, class _Rep, class _Period>
181 inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR
182 typename enable_if
183 <
184     __is_duration<_ToDuration>::value,
185     _ToDuration
186 >::type
187 round(const duration<_Rep, _Period>& __d)
188 {
189     _ToDuration __lower = chrono::floor<_ToDuration>(__d);
190     _ToDuration __upper = __lower + _ToDuration{1};
191     auto __lower_diff   = __d - __lower;
192     auto __upper_diff   = __upper - __d;
193     if (__lower_diff < __upper_diff)
194         return __lower;
195     if (__lower_diff > __upper_diff)
196         return __upper;
197     return __lower.count() & 1 ? __upper : __lower;
198 }
199 #endif
200 
201 // duration
202 
203 template <class _Rep, class _Period>
204 class _LIBCPP_TEMPLATE_VIS duration
205 {
206     static_assert(!__is_duration<_Rep>::value, "A duration representation can not be a duration");
207     static_assert(__is_ratio<_Period>::value, "Second template parameter of duration must be a std::ratio");
208     static_assert(_Period::num > 0, "duration period must be positive");
209 
210     template <class _R1, class _R2>
211     struct __no_overflow
212     {
213     private:
214         static const intmax_t __gcd_n1_n2 = __static_gcd<_R1::num, _R2::num>::value;
215         static const intmax_t __gcd_d1_d2 = __static_gcd<_R1::den, _R2::den>::value;
216         static const intmax_t __n1 = _R1::num / __gcd_n1_n2;
217         static const intmax_t __d1 = _R1::den / __gcd_d1_d2;
218         static const intmax_t __n2 = _R2::num / __gcd_n1_n2;
219         static const intmax_t __d2 = _R2::den / __gcd_d1_d2;
220         static const intmax_t max = -((intmax_t(1) << (sizeof(intmax_t) * CHAR_BIT - 1)) + 1);
221 
222         template <intmax_t _Xp, intmax_t _Yp, bool __overflow>
223         struct __mul    // __overflow == false
224         {
225             static const intmax_t value = _Xp * _Yp;
226         };
227 
228         template <intmax_t _Xp, intmax_t _Yp>
229         struct __mul<_Xp, _Yp, true>
230         {
231             static const intmax_t value = 1;
232         };
233 
234     public:
235         static const bool value = (__n1 <= max / __d2) && (__n2 <= max / __d1);
236         typedef ratio<__mul<__n1, __d2, !value>::value,
237                       __mul<__n2, __d1, !value>::value> type;
238     };
239 
240 public:
241     typedef _Rep rep;
242     typedef typename _Period::type period;
243 private:
244     rep __rep_;
245 public:
246 
247 #ifndef _LIBCPP_CXX03_LANG
248         constexpr duration() = default;
249 #else
250         _LIBCPP_HIDE_FROM_ABI duration() {}
251 #endif
252 
253     template <class _Rep2>
254         _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR
255         explicit duration(const _Rep2& __r,
256             typename enable_if
257             <
258                is_convertible<const _Rep2&, rep>::value &&
259                (treat_as_floating_point<rep>::value ||
260                !treat_as_floating_point<_Rep2>::value)
261             >::type* = nullptr)
262                 : __rep_(__r) {}
263 
264     // conversions
265     template <class _Rep2, class _Period2>
266         _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR
267         duration(const duration<_Rep2, _Period2>& __d,
268             typename enable_if
269             <
270                 __no_overflow<_Period2, period>::value && (
271                 treat_as_floating_point<rep>::value ||
272                 (__no_overflow<_Period2, period>::type::den == 1 &&
273                  !treat_as_floating_point<_Rep2>::value))
274             >::type* = nullptr)
275                 : __rep_(chrono::duration_cast<duration>(__d).count()) {}
276 
277     // observer
278 
279     _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR rep count() const {return __rep_;}
280 
281     // arithmetic
282 
283     _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR typename common_type<duration>::type operator+() const {return typename common_type<duration>::type(*this);}
284     _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR typename common_type<duration>::type operator-() const {return typename common_type<duration>::type(-__rep_);}
285     _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX17 duration& operator++()      {++__rep_; return *this;}
286     _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX17 duration  operator++(int)   {return duration(__rep_++);}
287     _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX17 duration& operator--()      {--__rep_; return *this;}
288     _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX17 duration  operator--(int)   {return duration(__rep_--);}
289 
290     _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX17 duration& operator+=(const duration& __d) {__rep_ += __d.count(); return *this;}
291     _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX17 duration& operator-=(const duration& __d) {__rep_ -= __d.count(); return *this;}
292 
293     _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX17 duration& operator*=(const rep& __rhs) {__rep_ *= __rhs; return *this;}
294     _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX17 duration& operator/=(const rep& __rhs) {__rep_ /= __rhs; return *this;}
295     _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX17 duration& operator%=(const rep& __rhs) {__rep_ %= __rhs; return *this;}
296     _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX17 duration& operator%=(const duration& __rhs) {__rep_ %= __rhs.count(); return *this;}
297 
298     // special values
299 
300     _LIBCPP_INLINE_VISIBILITY static _LIBCPP_CONSTEXPR duration zero() _NOEXCEPT {return duration(duration_values<rep>::zero());}
301     _LIBCPP_INLINE_VISIBILITY static _LIBCPP_CONSTEXPR duration min()  _NOEXCEPT {return duration(duration_values<rep>::min());}
302     _LIBCPP_INLINE_VISIBILITY static _LIBCPP_CONSTEXPR duration max()  _NOEXCEPT {return duration(duration_values<rep>::max());}
303 };
304 
305 typedef duration<long long,         nano> nanoseconds;
306 typedef duration<long long,        micro> microseconds;
307 typedef duration<long long,        milli> milliseconds;
308 typedef duration<long long              > seconds;
309 typedef duration<     long, ratio<  60> > minutes;
310 typedef duration<     long, ratio<3600> > hours;
311 #if _LIBCPP_STD_VER >= 20
312 typedef duration<     int, ratio_multiply<ratio<24>, hours::period>>         days;
313 typedef duration<     int, ratio_multiply<ratio<7>,   days::period>>         weeks;
314 typedef duration<     int, ratio_multiply<ratio<146097, 400>, days::period>> years;
315 typedef duration<     int, ratio_divide<years::period, ratio<12>>>           months;
316 #endif
317 // Duration ==
318 
319 template <class _LhsDuration, class _RhsDuration>
320 struct __duration_eq
321 {
322     _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR
323     bool operator()(const _LhsDuration& __lhs, const _RhsDuration& __rhs) const
324         {
325             typedef typename common_type<_LhsDuration, _RhsDuration>::type _Ct;
326             return _Ct(__lhs).count() == _Ct(__rhs).count();
327         }
328 };
329 
330 template <class _LhsDuration>
331 struct __duration_eq<_LhsDuration, _LhsDuration>
332 {
333     _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR
334     bool operator()(const _LhsDuration& __lhs, const _LhsDuration& __rhs) const
335         {return __lhs.count() == __rhs.count();}
336 };
337 
338 template <class _Rep1, class _Period1, class _Rep2, class _Period2>
339 inline _LIBCPP_INLINE_VISIBILITY
340 _LIBCPP_CONSTEXPR
341 bool
342 operator==(const duration<_Rep1, _Period1>& __lhs, const duration<_Rep2, _Period2>& __rhs)
343 {
344     return __duration_eq<duration<_Rep1, _Period1>, duration<_Rep2, _Period2> >()(__lhs, __rhs);
345 }
346 
347 #if _LIBCPP_STD_VER <= 17
348 
349 // Duration !=
350 
351 template <class _Rep1, class _Period1, class _Rep2, class _Period2>
352 inline _LIBCPP_INLINE_VISIBILITY
353 _LIBCPP_CONSTEXPR
354 bool
355 operator!=(const duration<_Rep1, _Period1>& __lhs, const duration<_Rep2, _Period2>& __rhs)
356 {
357     return !(__lhs == __rhs);
358 }
359 
360 #endif // _LIBCPP_STD_VER <= 17
361 
362 // Duration <
363 
364 template <class _LhsDuration, class _RhsDuration>
365 struct __duration_lt
366 {
367     _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR
368     bool operator()(const _LhsDuration& __lhs, const _RhsDuration& __rhs) const
369         {
370             typedef typename common_type<_LhsDuration, _RhsDuration>::type _Ct;
371             return _Ct(__lhs).count() < _Ct(__rhs).count();
372         }
373 };
374 
375 template <class _LhsDuration>
376 struct __duration_lt<_LhsDuration, _LhsDuration>
377 {
378     _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR
379     bool operator()(const _LhsDuration& __lhs, const _LhsDuration& __rhs) const
380         {return __lhs.count() < __rhs.count();}
381 };
382 
383 template <class _Rep1, class _Period1, class _Rep2, class _Period2>
384 inline _LIBCPP_INLINE_VISIBILITY
385 _LIBCPP_CONSTEXPR
386 bool
387 operator< (const duration<_Rep1, _Period1>& __lhs, const duration<_Rep2, _Period2>& __rhs)
388 {
389     return __duration_lt<duration<_Rep1, _Period1>, duration<_Rep2, _Period2> >()(__lhs, __rhs);
390 }
391 
392 // Duration >
393 
394 template <class _Rep1, class _Period1, class _Rep2, class _Period2>
395 inline _LIBCPP_INLINE_VISIBILITY
396 _LIBCPP_CONSTEXPR
397 bool
398 operator> (const duration<_Rep1, _Period1>& __lhs, const duration<_Rep2, _Period2>& __rhs)
399 {
400     return __rhs < __lhs;
401 }
402 
403 // Duration <=
404 
405 template <class _Rep1, class _Period1, class _Rep2, class _Period2>
406 inline _LIBCPP_INLINE_VISIBILITY
407 _LIBCPP_CONSTEXPR
408 bool
409 operator<=(const duration<_Rep1, _Period1>& __lhs, const duration<_Rep2, _Period2>& __rhs)
410 {
411     return !(__rhs < __lhs);
412 }
413 
414 // Duration >=
415 
416 template <class _Rep1, class _Period1, class _Rep2, class _Period2>
417 inline _LIBCPP_INLINE_VISIBILITY
418 _LIBCPP_CONSTEXPR
419 bool
420 operator>=(const duration<_Rep1, _Period1>& __lhs, const duration<_Rep2, _Period2>& __rhs)
421 {
422     return !(__lhs < __rhs);
423 }
424 
425 #if _LIBCPP_STD_VER >= 20
426 
427 template<class _Rep1, class _Period1, class _Rep2, class _Period2>
428   requires three_way_comparable<common_type_t<_Rep1, _Rep2>>
429 _LIBCPP_HIDE_FROM_ABI
430 constexpr auto operator<=>(const duration<_Rep1, _Period1>& __lhs,
431                            const duration<_Rep2, _Period2>& __rhs)
432 {
433     using _Ct = common_type_t<duration<_Rep1, _Period1>, duration<_Rep2, _Period2>>;
434     return _Ct(__lhs).count() <=> _Ct(__rhs).count();
435 }
436 
437 #endif // _LIBCPP_STD_VER >= 20
438 
439 // Duration +
440 
441 template <class _Rep1, class _Period1, class _Rep2, class _Period2>
442 inline _LIBCPP_INLINE_VISIBILITY
443 _LIBCPP_CONSTEXPR
444 typename common_type<duration<_Rep1, _Period1>, duration<_Rep2, _Period2> >::type
445 operator+(const duration<_Rep1, _Period1>& __lhs, const duration<_Rep2, _Period2>& __rhs)
446 {
447     typedef typename common_type<duration<_Rep1, _Period1>, duration<_Rep2, _Period2> >::type _Cd;
448     return _Cd(_Cd(__lhs).count() + _Cd(__rhs).count());
449 }
450 
451 // Duration -
452 
453 template <class _Rep1, class _Period1, class _Rep2, class _Period2>
454 inline _LIBCPP_INLINE_VISIBILITY
455 _LIBCPP_CONSTEXPR
456 typename common_type<duration<_Rep1, _Period1>, duration<_Rep2, _Period2> >::type
457 operator-(const duration<_Rep1, _Period1>& __lhs, const duration<_Rep2, _Period2>& __rhs)
458 {
459     typedef typename common_type<duration<_Rep1, _Period1>, duration<_Rep2, _Period2> >::type _Cd;
460     return _Cd(_Cd(__lhs).count() - _Cd(__rhs).count());
461 }
462 
463 // Duration *
464 
465 template <class _Rep1, class _Period, class _Rep2>
466 inline _LIBCPP_INLINE_VISIBILITY
467 _LIBCPP_CONSTEXPR
468 typename enable_if
469 <
470     is_convertible<_Rep2, typename common_type<_Rep1, _Rep2>::type>::value,
471     duration<typename common_type<_Rep1, _Rep2>::type, _Period>
472 >::type
473 operator*(const duration<_Rep1, _Period>& __d, const _Rep2& __s)
474 {
475     typedef typename common_type<_Rep1, _Rep2>::type _Cr;
476     typedef duration<_Cr, _Period> _Cd;
477     return _Cd(_Cd(__d).count() * static_cast<_Cr>(__s));
478 }
479 
480 template <class _Rep1, class _Period, class _Rep2>
481 inline _LIBCPP_INLINE_VISIBILITY
482 _LIBCPP_CONSTEXPR
483 typename enable_if
484 <
485     is_convertible<_Rep1, typename common_type<_Rep1, _Rep2>::type>::value,
486     duration<typename common_type<_Rep1, _Rep2>::type, _Period>
487 >::type
488 operator*(const _Rep1& __s, const duration<_Rep2, _Period>& __d)
489 {
490     return __d * __s;
491 }
492 
493 // Duration /
494 
495 template <class _Rep1, class _Period, class _Rep2>
496 inline _LIBCPP_INLINE_VISIBILITY
497 _LIBCPP_CONSTEXPR
498 typename enable_if
499 <
500     !__is_duration<_Rep2>::value &&
501       is_convertible<_Rep2, typename common_type<_Rep1, _Rep2>::type>::value,
502     duration<typename common_type<_Rep1, _Rep2>::type, _Period>
503 >::type
504 operator/(const duration<_Rep1, _Period>& __d, const _Rep2& __s)
505 {
506     typedef typename common_type<_Rep1, _Rep2>::type _Cr;
507     typedef duration<_Cr, _Period> _Cd;
508     return _Cd(_Cd(__d).count() / static_cast<_Cr>(__s));
509 }
510 
511 template <class _Rep1, class _Period1, class _Rep2, class _Period2>
512 inline _LIBCPP_INLINE_VISIBILITY
513 _LIBCPP_CONSTEXPR
514 typename common_type<_Rep1, _Rep2>::type
515 operator/(const duration<_Rep1, _Period1>& __lhs, const duration<_Rep2, _Period2>& __rhs)
516 {
517     typedef typename common_type<duration<_Rep1, _Period1>, duration<_Rep2, _Period2> >::type _Ct;
518     return _Ct(__lhs).count() / _Ct(__rhs).count();
519 }
520 
521 // Duration %
522 
523 template <class _Rep1, class _Period, class _Rep2>
524 inline _LIBCPP_INLINE_VISIBILITY
525 _LIBCPP_CONSTEXPR
526 typename enable_if
527 <
528     !__is_duration<_Rep2>::value &&
529       is_convertible<_Rep2, typename common_type<_Rep1, _Rep2>::type>::value,
530     duration<typename common_type<_Rep1, _Rep2>::type, _Period>
531 >::type
532 operator%(const duration<_Rep1, _Period>& __d, const _Rep2& __s)
533 {
534     typedef typename common_type<_Rep1, _Rep2>::type _Cr;
535     typedef duration<_Cr, _Period> _Cd;
536     return _Cd(_Cd(__d).count() % static_cast<_Cr>(__s));
537 }
538 
539 template <class _Rep1, class _Period1, class _Rep2, class _Period2>
540 inline _LIBCPP_INLINE_VISIBILITY
541 _LIBCPP_CONSTEXPR
542 typename common_type<duration<_Rep1, _Period1>, duration<_Rep2, _Period2> >::type
543 operator%(const duration<_Rep1, _Period1>& __lhs, const duration<_Rep2, _Period2>& __rhs)
544 {
545     typedef typename common_type<_Rep1, _Rep2>::type _Cr;
546     typedef typename common_type<duration<_Rep1, _Period1>, duration<_Rep2, _Period2> >::type _Cd;
547     return _Cd(static_cast<_Cr>(_Cd(__lhs).count()) % static_cast<_Cr>(_Cd(__rhs).count()));
548 }
549 
550 } // namespace chrono
551 
552 #if _LIBCPP_STD_VER >= 14
553 // Suffixes for duration literals [time.duration.literals]
554 inline namespace literals
555 {
556   inline namespace chrono_literals
557   {
558 
559     _LIBCPP_HIDE_FROM_ABI constexpr chrono::hours operator""h(unsigned long long __h)
560     {
561         return chrono::hours(static_cast<chrono::hours::rep>(__h));
562     }
563 
564     _LIBCPP_HIDE_FROM_ABI constexpr chrono::duration<long double, ratio<3600,1>> operator""h(long double __h)
565     {
566         return chrono::duration<long double, ratio<3600,1>>(__h);
567     }
568 
569 
570     _LIBCPP_HIDE_FROM_ABI constexpr chrono::minutes operator""min(unsigned long long __m)
571     {
572         return chrono::minutes(static_cast<chrono::minutes::rep>(__m));
573     }
574 
575     _LIBCPP_HIDE_FROM_ABI constexpr chrono::duration<long double, ratio<60,1>> operator""min(long double __m)
576     {
577         return chrono::duration<long double, ratio<60,1>> (__m);
578     }
579 
580 
581     _LIBCPP_HIDE_FROM_ABI constexpr chrono::seconds operator""s(unsigned long long __s)
582     {
583         return chrono::seconds(static_cast<chrono::seconds::rep>(__s));
584     }
585 
586     _LIBCPP_HIDE_FROM_ABI constexpr chrono::duration<long double> operator""s(long double __s)
587     {
588         return chrono::duration<long double> (__s);
589     }
590 
591 
592     _LIBCPP_HIDE_FROM_ABI constexpr chrono::milliseconds operator""ms(unsigned long long __ms)
593     {
594         return chrono::milliseconds(static_cast<chrono::milliseconds::rep>(__ms));
595     }
596 
597     _LIBCPP_HIDE_FROM_ABI constexpr chrono::duration<long double, milli> operator""ms(long double __ms)
598     {
599         return chrono::duration<long double, milli>(__ms);
600     }
601 
602 
603     _LIBCPP_HIDE_FROM_ABI constexpr chrono::microseconds operator""us(unsigned long long __us)
604     {
605         return chrono::microseconds(static_cast<chrono::microseconds::rep>(__us));
606     }
607 
608     _LIBCPP_HIDE_FROM_ABI constexpr chrono::duration<long double, micro> operator""us(long double __us)
609     {
610         return chrono::duration<long double, micro> (__us);
611     }
612 
613 
614     _LIBCPP_HIDE_FROM_ABI constexpr chrono::nanoseconds operator""ns(unsigned long long __ns)
615     {
616         return chrono::nanoseconds(static_cast<chrono::nanoseconds::rep>(__ns));
617     }
618 
619     _LIBCPP_HIDE_FROM_ABI constexpr chrono::duration<long double, nano> operator""ns(long double __ns)
620     {
621         return chrono::duration<long double, nano> (__ns);
622     }
623 
624 } // namespace chrono_literals
625 } // namespace literals
626 
627 namespace chrono { // hoist the literals into namespace std::chrono
628    using namespace literals::chrono_literals;
629 } // namespace chrono
630 
631 #endif // _LIBCPP_STD_VER >= 14
632 
633 _LIBCPP_END_NAMESPACE_STD
634 
635 _LIBCPP_POP_MACROS
636 
637 #if !defined(_LIBCPP_REMOVE_TRANSITIVE_INCLUDES) && _LIBCPP_STD_VER <= 20
638 #  include <type_traits>
639 #endif
640 
641 #endif // _LIBCPP___CHRONO_DURATION_H
642