source: mainline/uspace/lib/cpp/include/__bits/chrono.hpp@ 34b2f54d

Last change on this file since 34b2f54d was b57ba05, checked in by Jiří Zárevúcky <zarevucky.jiri@…>, 3 years ago

Update headers in C++ files

  • Property mode set to 100644
File size: 22.0 KB
Line 
1/*
2 * SPDX-FileCopyrightText: 2018 Jaroslav Jindrak
3 *
4 * SPDX-License-Identifier: BSD-3-Clause
5 */
6
7#ifndef LIBCPP_BITS_CHRONO
8#define LIBCPP_BITS_CHRONO
9
10#include <ctime>
11#include <limits>
12#include <ratio>
13#include <type_traits>
14
15namespace std::chrono
16{
17 /**
18 * 20.12.5, class template duration:
19 */
20
21 // Forward declarations.
22 template<class Rep, class Period = ratio<1>>
23 class duration;
24
25 template<class ToDuration, class Rep, class Period>
26 constexpr ToDuration duration_cast(const duration<Rep, Period>& dur);
27
28 template<class Rep>
29 struct duration_values;
30
31 template<class Rep, class Period>
32 class duration
33 {
34 public:
35 using rep = Rep;
36 using period = Period;
37
38 /**
39 * 20.12.5.1, construct/copy/destroy:
40 */
41
42 constexpr duration() = default;
43
44 // TODO: check remarks to these two constructors, need is_convertible
45 template<class Rep2>
46 constexpr explicit duration(const Rep2& r)
47 : rep_{r}
48 { /* DUMMY BODY */ }
49
50 template<class Rep2, class Period2>
51 constexpr duration(const duration<Rep2, Period2>& other)
52 : rep_{duration_cast<duration>(other).count()}
53 { /* DUMMY BODY */ }
54
55 ~duration() = default;
56
57 duration(const duration&) = default;
58
59 duration& operator=(const duration&) = default;
60
61 /**
62 * 20.12.5.2, observer:
63 */
64
65 constexpr rep count() const
66 {
67 return rep_;
68 }
69
70 /**
71 * 20.12.5.3, arithmetic:
72 */
73
74 constexpr duration operator+() const
75 {
76 return *this;
77 }
78
79 constexpr duration operator-() const
80 {
81 return duration{-rep_};
82 }
83
84 duration& operator++()
85 {
86 ++rep_;
87
88 return *this;
89 }
90
91 duration operator++(int)
92 {
93 return duration{rep_++};
94 }
95
96 duration& operator--()
97 {
98 --rep_;
99
100 *this;
101 }
102
103 duration operator--(int)
104 {
105 return duration{rep_--};
106 }
107
108 duration& operator+=(const duration& rhs)
109 {
110 rep_ += rhs.count();
111
112 return *this;
113 }
114
115 duration& operator-=(const duration& rhs)
116 {
117 rep_ -= rhs.count();
118
119 return *this;
120 }
121
122 duration& operator*=(const rep& rhs)
123 {
124 rep_ *= rhs;
125
126 return *this;
127 }
128
129 duration& operator/=(const rep& rhs)
130 {
131 rep_ /= rhs;
132
133 return *this;
134 }
135
136 duration& operator%=(const rep& rhs)
137 {
138 rep_ %= rhs;
139
140 return *this;
141 }
142
143 duration& operator%=(const duration& rhs)
144 {
145 rep_ %= rhs.count();
146
147 return *this;
148 }
149
150 /**
151 * 20.12.5.4, special values:
152 */
153
154 static constexpr duration zero()
155 {
156 return duration{duration_values<rep>::zero()};
157 }
158
159 static constexpr duration min()
160 {
161 return duration{duration_values<rep>::min()};
162 }
163
164 static constexpr duration max()
165 {
166 return duration{duration_values<rep>::max()};
167 }
168
169 private:
170 rep rep_;
171 };
172
173 /**
174 * 20.12.6, class template time_point:
175 */
176
177 template<class Clock, class Duration = typename Clock::duration>
178 class time_point
179 {
180 public:
181 using clock = Clock;
182 using duration = Duration;
183 using rep = typename duration::rep;
184 using period = typename duration::period;
185
186 /**
187 * 20.12.6.1, construct:
188 */
189
190 constexpr time_point()
191 : duration_{duration::zero()}
192 { /* DUMMY BODY */ }
193
194 constexpr explicit time_point(const duration& d)
195 : duration_{d}
196 { /* DUMMY BODY */ }
197
198 // TODO: see remark to this constuctor
199 template<class Duration2>
200 constexpr time_point(const time_point<clock, Duration2>& other)
201 : duration_{static_cast<duration>(other.time_since_epoch())}
202 { /* DUMMY BODY */ }
203
204 /**
205 * 20.12.6.2, observer:
206 */
207
208 constexpr duration time_since_epoch() const
209 {
210 return duration_;
211 }
212
213 /**
214 * 20.12.6.3, arithmetic:
215 */
216
217 time_point& operator+=(const duration& rhs)
218 {
219 duration_ += rhs;
220
221 return *this;
222 }
223
224 time_point& operator-=(const duration& rhs)
225 {
226 duration_ -= rhs;
227
228 return *this;
229 }
230
231 /**
232 * 20.12.6.4, special values:
233 */
234
235 static constexpr time_point min()
236 {
237 return time_point{duration::min()};
238 }
239
240 static constexpr time_point max()
241 {
242 return time_point{duration::max()};
243 }
244
245 private:
246 duration duration_;
247 };
248}
249
250namespace std
251{
252 /**
253 * 20.12.4.3, common_type specializations:
254 */
255
256 template<class Rep1, class Period1, class Rep2, class Period2>
257 struct common_type<chrono::duration<Rep1, Period1>, chrono::duration<Rep2, Period2>>
258 {
259 using type = chrono::duration<
260 common_type_t<Rep1, Rep2>,
261 ratio<aux::gcd_v<Period1::num, Period2::num>, aux::lcm_v<Period1::den, Period2::den>>
262 >;
263 };
264
265 template<class Clock, class Duration1, class Duration2>
266 struct common_type<chrono::time_point<Clock, Duration1>, chrono::time_point<Clock, Duration2>>
267 {
268 using type = chrono::time_point<Clock, common_type_t<Duration1, Duration2>>;
269 };
270}
271
272namespace std::chrono
273{
274 /**
275 * 20.12.4, customization traits:
276 */
277
278 template<class Rep>
279 struct treat_as_floating_point: is_floating_point<Rep>
280 { /* DUMMY BODY */ };
281
282 template<class Rep>
283 struct duration_values
284 {
285 static constexpr Rep zero()
286 {
287 // Note: Using Rep(0) instead of Rep{} is intentional, do not change.
288 return Rep(0);
289 }
290
291 static constexpr Rep min()
292 {
293 return numeric_limits<Rep>::lowest();
294 }
295
296 static constexpr Rep max()
297 {
298 return numeric_limits<Rep>::max();
299 }
300 };
301
302 /**
303 * 20.12.5.5, duration arithmetic:
304 */
305
306 template<class Rep1, class Period1, class Rep2, class Period2>
307 constexpr common_type_t<duration<Rep1, Period1>, duration<Rep2, Period2>>
308 operator+(const duration<Rep1, Period1>& lhs, const duration<Rep2, Period2>& rhs)
309 {
310 using CD = common_type_t<duration<Rep1, Period1>, duration<Rep2, Period2>>;
311 return CD(CD(lhs).count() + CD(rhs).count());
312 }
313
314 template<class Rep1, class Period1, class Rep2, class Period2>
315 constexpr common_type_t<duration<Rep1, Period1>, duration<Rep2, Period2>>
316 operator-(const duration<Rep1, Period1>& lhs, const duration<Rep2, Period2>& rhs)
317 {
318 using CD = common_type_t<duration<Rep1, Period1>, duration<Rep2, Period2>>;
319 return CD(CD(lhs).count() - CD(rhs).count());
320 }
321
322 // TODO: This shall not participate in overloading if Rep2 is not implicitly
323 // convertible to CR(Rep1, Rep2) -> CR(A, B) defined in standard as
324 // common_type_t<A, B>.
325 template<class Rep1, class Period, class Rep2>
326 constexpr duration<common_type_t<Rep1, Rep2>, Period>
327 operator*(const duration<Rep1, Period>& dur, const Rep2& rep)
328 {
329 using CD = duration<common_type_t<Rep1, Rep2>, Period>;
330 return CD(CD(dur).count() * rep);
331 }
332
333 // TODO: This shall not participate in overloading if Rep2 is not implicitly
334 // convertible to CR(Rep1, Rep2) -> CR(A, B) defined in standard as
335 // common_type_t<A, B>.
336 template<class Rep1, class Period, class Rep2>
337 constexpr duration<common_type_t<Rep1, Rep2>, Period>
338 operator*(const Rep2& rep, const duration<Rep1, Period>& dur)
339 {
340 return dur * rep;
341 }
342
343 // TODO: This shall not participate in overloading if Rep2 is not implicitly
344 // convertible to CR(Rep1, Rep2) -> CR(A, B) defined in standard as
345 // common_type_t<A, B>.
346 template<class Rep1, class Period, class Rep2>
347 constexpr duration<common_type_t<Rep1, Rep2>, Period>
348 operator/(const duration<Rep1, Period>& dur, const Rep2& rep)
349 {
350 using CD = duration<common_type_t<Rep1, Rep2>, Period>;
351 return CD(CD(dur).count() / rep);
352 }
353
354 template<class Rep1, class Period1, class Rep2, class Period2>
355 constexpr common_type_t<Rep1, Rep2>
356 operator/(const duration<Rep1, Period1>& lhs, const duration<Rep2, Period2>& rhs)
357 {
358 using CD = common_type_t<Rep1, Rep2>;
359 return CD(lhs).count() / CD(rhs).count();
360 }
361
362 // TODO: This shall not participate in overloading if Rep2 is not implicitly
363 // convertible to CR(Rep1, Rep2) -> CR(A, B) defined in standard as
364 // common_type_t<A, B>.
365 template<class Rep1, class Period, class Rep2>
366 constexpr duration<common_type_t<Rep1, Rep2>, Period>
367 operator%(const duration<Rep1, Period>& dur, const Rep2& rep)
368 {
369 using CD = duration<common_type_t<Rep1, Rep2>, Period>;
370 return CD(CD(dur).count() / rep);
371 }
372
373 template<class Rep1, class Period1, class Rep2, class Period2>
374 constexpr common_type_t<duration<Rep1, Period1>, duration<Rep2, Period2>>
375 operator%(const duration<Rep1, Period1>& lhs, const duration<Rep2, Period2>& rhs)
376 {
377 using CD = common_type_t<duration<Rep1, Period1>, duration<Rep2, Period2>>;
378 return CD(CD(lhs).count() % CD(rhs).count());
379 }
380
381 /**
382 * 20.12.5.6, duration comparisons:
383 */
384
385 template<class Rep1, class Period1, class Rep2, class Period2>
386 constexpr bool operator==(const duration<Rep1, Period1>& lhs,
387 const duration<Rep2, Period2>& rhs)
388 {
389 using CT = common_type_t<duration<Rep1, Period1>, duration<Rep2, Period2>>;
390 return CT(lhs).count() == CT(rhs).count();
391 }
392
393 template<class Rep1, class Period1, class Rep2, class Period2>
394 constexpr bool operator!=(const duration<Rep1, Period1>& lhs,
395 const duration<Rep2, Period2>& rhs)
396 {
397 return !(lhs == rhs);
398 }
399
400 template<class Rep1, class Period1, class Rep2, class Period2>
401 constexpr bool operator<(const duration<Rep1, Period1>& lhs,
402 const duration<Rep2, Period2>& rhs)
403 {
404 using CT = common_type_t<duration<Rep1, Period1>, duration<Rep2, Period2>>;
405 return CT(lhs).count() < CT(rhs).count();
406 }
407
408 template<class Rep1, class Period1, class Rep2, class Period2>
409 constexpr bool operator<=(const duration<Rep1, Period1>& lhs,
410 const duration<Rep2, Period2>& rhs)
411 {
412 return !(rhs < lhs);
413 }
414
415 template<class Rep1, class Period1, class Rep2, class Period2>
416 constexpr bool operator>(const duration<Rep1, Period1>& lhs,
417 const duration<Rep2, Period2>& rhs)
418 {
419 return rhs < lhs;
420 }
421
422 template<class Rep1, class Period1, class Rep2, class Period2>
423 constexpr bool operator>=(const duration<Rep1, Period1>& lhs,
424 const duration<Rep2, Period2>& rhs)
425 {
426 return !(lhs < rhs);
427 }
428
429 /**
430 * 20.12.5.7, duration cast:
431 */
432
433 // TODO: This function should not participate in overloading
434 // unless ToDuration is an instantiation of duration.
435 template<class ToDuration, class Rep, class Period>
436 constexpr ToDuration duration_cast(const duration<Rep, Period>& dur)
437 {
438 using CF = ratio_divide<Period, typename ToDuration::period>;
439 using CR = typename common_type<typename ToDuration::rep, Rep, intmax_t>::type;
440
441 using to_rep = typename ToDuration::rep;
442
443 if constexpr (CF::num == 1 && CF::den == 1)
444 return ToDuration(static_cast<to_rep>(dur.count()));
445 else if constexpr (CF::num != 1 && CF::den == 1)
446 {
447 return ToDuration(
448 static_cast<to_rep>(
449 static_cast<CR>(dur.count()) * static_cast<CR>(CF::num)
450 )
451 );
452 }
453 else if constexpr (CF::num == 1 && CF::den != 1)
454 {
455 return ToDuration(
456 static_cast<to_rep>(
457 static_cast<CR>(dur.count()) / static_cast<CR>(CF::den)
458 )
459 );
460 }
461 else
462 {
463 return ToDuration(
464 static_cast<to_rep>(
465 static_cast<CR>(dur.count()) * static_cast<CR>(CF::num)
466 / static_cast<CR>(CF::den)
467 )
468 );
469 }
470 }
471
472 // convenience typedefs
473 using nanoseconds = duration<int64_t, nano>;
474 using microseconds = duration<int64_t, micro>;
475 using milliseconds = duration<int64_t, milli>;
476 using seconds = duration<int64_t>;
477 using minutes = duration<int32_t, ratio<60>>;
478 using hours = duration<int32_t, ratio<3600>>;
479
480 /**
481 * 20.12.6.5, time_point arithmetic:
482 */
483
484 template<class Clock, class Duration1, class Rep2, class Period2>
485 constexpr time_point<Clock, common_type_t<Duration1, duration<Rep2, Period2>>>
486 operator+(const time_point<Clock, Duration1>& lhs, const duration<Rep2, Period2>& rhs)
487 {
488 using CT = time_point<Clock, common_type_t<Duration1, duration<Rep2, Period2>>>;
489 return CT(lhs.time_since_epoch() + rhs);
490 }
491
492 template<class Rep1, class Period1, class Clock, class Duration2>
493 constexpr time_point<Clock, common_type_t<duration<Rep1, Period1>, Duration2>>
494 operator+(const duration<Rep1, Period1>& lhs, const time_point<Clock, Duration2>& rhs)
495 {
496 return rhs + lhs;
497 }
498
499 template<class Clock, class Duration1, class Rep2, class Period2>
500 constexpr time_point<Clock, common_type_t<Duration1, duration<Rep2, Period2>>>
501 operator-(const time_point<Clock, Duration1>& lhs, const duration<Rep2, Period2>& rhs)
502 {
503 return lhs + (-rhs);
504 }
505
506 template<class Clock, class Duration1, class Duration2>
507 constexpr common_type_t<Duration1, Duration2>
508 operator-(const time_point<Clock, Duration1>& lhs, const time_point<Clock, Duration2>& rhs)
509 {
510 return lhs.time_since_epoch() - rhs.time_since_epoch();
511 }
512
513 /**
514 * 20.12.6.6, time_point comparisons:
515 */
516
517 template<class Clock, class Duration1, class Duration2>
518 constexpr bool operator==(const time_point<Clock, Duration1>& lhs,
519 const time_point<Clock, Duration2>& rhs)
520 {
521 return lhs.time_since_epoch() == rhs.time_since_epoch();
522 }
523
524 template<class Clock, class Duration1, class Duration2>
525 constexpr bool operator!=(const time_point<Clock, Duration1>& lhs,
526 const time_point<Clock, Duration2>& rhs)
527 {
528 return !(lhs == rhs);
529 }
530
531 template<class Clock, class Duration1, class Duration2>
532 constexpr bool operator<(const time_point<Clock, Duration1>& lhs,
533 const time_point<Clock, Duration2>& rhs)
534 {
535 return lhs.time_since_epoch() < rhs.time_since_epoch();
536 }
537
538 template<class Clock, class Duration1, class Duration2>
539 constexpr bool operator<=(const time_point<Clock, Duration1>& lhs,
540 const time_point<Clock, Duration2>& rhs)
541 {
542 return !(rhs < lhs);
543 }
544
545 template<class Clock, class Duration1, class Duration2>
546 constexpr bool operator>(const time_point<Clock, Duration1>& lhs,
547 const time_point<Clock, Duration2>& rhs)
548 {
549 return rhs < lhs;
550 }
551
552 template<class Clock, class Duration1, class Duration2>
553 constexpr bool operator>=(const time_point<Clock, Duration1>& lhs,
554 const time_point<Clock, Duration2>& rhs)
555 {
556 return !(lhs < rhs);
557 }
558
559 /**
560 * 20.12.6.7, time_point cast:
561 */
562
563 // TODO: This function should not participate in overloading
564 // unless ToDuration is an instantiation of duration.
565 template<class ToDuration, class Clock, class Duration>
566 constexpr time_point<Clock, ToDuration>
567 time_point_cast(const time_point<Clock, Duration>& tp)
568 {
569 return time_point<Clock, ToDuration>(
570 duration_cast<ToDuration>(tp.time_since_epoch())
571 );
572 }
573
574 /**
575 * 20.12.7, clocks:
576 */
577
578 class system_clock
579 {
580 public:
581 using rep = int64_t;
582 using period = micro;
583 using duration = chrono::duration<rep, period>;
584 using time_point = chrono::time_point<system_clock>;
585
586 // TODO: is it steady?
587 static constexpr bool is_steady = true;
588
589 static time_point now()
590 {
591 ::std::timespec ts{};
592 ::helenos::getrealtime(&ts);
593
594 rep time = NSEC2USEC(ts.tv_nsec);
595 time += (ts.tv_sec * 1'000'000ul);
596
597 return time_point{duration{time - epoch_usecs}};
598 }
599
600 static time_t to_time_t(const time_point& tp)
601 {
602 /* auto dur = tp.time_since_epoch(); */
603 /* auto time_t_dur = duration_cast<chrono::duration<time_t, seconds>>(dur); */
604
605 /* return time_t{time_t_dur.count()}; */
606 return time_t{};
607 }
608
609 static time_point from_time_t(time_t tt)
610 {
611 /* auto time_t_dur = chrono::duration<time_t, seconds>{tt}; */
612 /* auto dur = duration_cast<duration>(time_t_dur); */
613
614 /* return time_point{duration_cast<duration>(chrono::duration<time_t, seconds>{tt})}; */
615 return time_point{};
616 }
617
618 private:
619 static constexpr rep epoch_usecs{11644473600ul * 1'000'000ul};
620 };
621
622 class steady_clock
623 {
624 public:
625 using rep = int64_t;
626 using period = micro;
627 using duration = chrono::duration<rep, period>;
628 using time_point = chrono::time_point<steady_clock>;
629
630 static constexpr bool is_steady = true;
631
632 static time_point now()
633 {
634 ::std::timespec ts{};
635 ::helenos::getuptime(&ts);
636
637 rep time = NSEC2USEC(ts.tv_nsec);
638 time += (ts.tv_sec * 1'000'000ul);
639
640 return time_point{duration{time}};
641 }
642 };
643
644 using high_resolution_clock = system_clock;
645}
646
647namespace std
648{
649 inline namespace literals
650 {
651 inline namespace chrono_literals
652 {
653 /**
654 * 20.125.8, suffixes for duration literals:
655 */
656
657 /**
658 * Note: According to the standard, literal suffixes that do not
659 * start with an underscore are reserved for future standardization,
660 * but since we are implementing the standard, we're going to ignore it.
661 * This should work (according to their documentation) work for clang,
662 * but that should be tested.
663 */
664#pragma GCC diagnostic push
665#pragma GCC diagnostic ignored "-Wliteral-suffix"
666
667 constexpr chrono::hours operator ""h(unsigned long long hrs)
668 {
669 return chrono::hours{static_cast<chrono::hours::rep>(hrs)};
670 }
671
672 constexpr chrono::duration<long double, ratio<3600>> operator ""h(long double hrs)
673 {
674 return chrono::duration<long double, ratio<3600>>{hrs};
675 }
676
677 constexpr chrono::minutes operator ""m(unsigned long long mins)
678 {
679 return chrono::minutes{static_cast<chrono::minutes::rep>(mins)};
680 }
681
682 constexpr chrono::duration<long double, ratio<60>> operator ""m(long double mins)
683 {
684 return chrono::duration<long double, ratio<60>>{mins};
685 }
686
687 constexpr chrono::seconds operator ""s(unsigned long long secs)
688 {
689 return chrono::seconds{static_cast<chrono::seconds::rep>(secs)};
690 }
691
692 constexpr chrono::duration<long double, ratio<1>> operator ""s(long double secs)
693 {
694 return chrono::duration<long double, ratio<1>>{secs};
695 }
696
697 constexpr chrono::milliseconds operator ""ms(unsigned long long msecs)
698 {
699 return chrono::milliseconds{static_cast<chrono::milliseconds::rep>(msecs)};
700 }
701
702 constexpr chrono::duration<long double, milli> operator ""ms(long double msecs)
703 {
704 return chrono::duration<long double, milli>{msecs};
705 }
706
707 constexpr chrono::microseconds operator ""us(unsigned long long usecs)
708 {
709 return chrono::microseconds{static_cast<chrono::microseconds::rep>(usecs)};
710 }
711
712 constexpr chrono::duration<long double, micro> operator ""us(long double usecs)
713 {
714 return chrono::duration<long double, micro>{usecs};
715 }
716
717 constexpr chrono::nanoseconds operator ""ns(unsigned long long nsecs)
718 {
719 return chrono::nanoseconds{static_cast<chrono::nanoseconds::rep>(nsecs)};
720 }
721
722 constexpr chrono::duration<long double, nano> operator ""ns(long double nsecs)
723 {
724 return chrono::duration<long double, nano>{nsecs};
725 }
726
727#pragma GCC diagnostic pop
728 }
729 }
730
731 namespace chrono
732 {
733 using namespace literals::chrono_literals;
734 }
735}
736
737#endif
Note: See TracBrowser for help on using the repository browser.