Zth (libzth)
Loading...
Searching...
No Matches
time.h
Go to the documentation of this file.
1#ifndef ZTH_TIME_H
2#define ZTH_TIME_H
3/*
4 * SPDX-FileCopyrightText: 2019-2026 Jochem Rutgers
5 *
6 * SPDX-License-Identifier: MPL-2.0
7 */
8
14#include <libzth/macros.h>
15
16#ifdef __cplusplus
17
18# include <libzth/allocator.h>
19# include <libzth/config.h>
20# include <libzth/util.h>
21
22# include <algorithm>
23# include <cmath>
24# include <cstdio>
25# include <ctime>
26# include <inttypes.h>
27# include <limits>
28
29# if __cplusplus >= 201103L
30# include <chrono>
31# endif // C++11
32
33# if defined(ZTH_OS_MAC) || defined(ZTH_OS_BAREMETAL)
34# ifdef ZTH_CUSTOM_CLOCK_GETTIME
35extern "C" int clock_gettime(int clk_id, struct timespec* res);
36# endif
37extern "C" int
38clock_nanosleep(int clk_id, int flags, struct timespec const* request, struct timespec* remain);
39# ifndef CLOCK_MONOTONIC
40# define CLOCK_MONOTONIC 1
41# endif
42# ifndef TIMER_ABSTIME
43# define TIMER_ABSTIME 1
44# endif
45# endif
46
47namespace zth {
48
49class Timestamp;
50
57private:
58 // Do not convert automatically.
59 TimeInterval(Timestamp const&);
60
61public:
62 static long const BILLION = 1000000000L;
63
64 constexpr static TimeInterval infinity() noexcept
65 {
66 return TimeInterval(std::numeric_limits<time_t>::max());
67 }
68
69 constexpr static TimeInterval null() noexcept
70 {
71 return TimeInterval();
72 }
73
74 constexpr TimeInterval() noexcept
75 : m_t()
76 , m_negative()
77 {}
78
79# if __cplusplus >= 201103L
80 // cppcheck-suppress noExplicitConstructor
81 constexpr TimeInterval(time_t s, long ns = 0, bool negative = false) noexcept
82 : m_t{s, ns}
83 , m_negative{negative}
84 {}
85# else
86 // cppcheck-suppress noExplicitConstructor
87 TimeInterval(time_t s, long ns = 0, bool negative = false) noexcept
88 : m_t()
89 , m_negative(negative)
90 {
91 m_t.tv_sec = s;
92 m_t.tv_nsec = ns;
94 }
95# endif
96
97 // cppcheck-suppress noExplicitConstructor
98 constexpr TimeInterval(struct timespec const& ts) noexcept
99 : m_t(ts)
100 , m_negative()
101 {}
102
104 {
105 m_t = t.m_t;
106 m_negative = t.m_negative;
107 return *this;
108 }
109
110 constexpr TimeInterval(TimeInterval const& t) noexcept
111 : m_t(t.ts())
112 , m_negative(t.isNegative())
113 {}
114
115 // cppcheck-suppress noExplicitConstructor
116 TimeInterval(float dt)
117 : m_t()
118 , m_negative()
119 {
120 init_float<float>(dt);
121 }
122
123 // cppcheck-suppress noExplicitConstructor
124 TimeInterval(double dt)
125 : m_t()
126 , m_negative()
127 {
128 init_float<double>(dt);
129 }
130
131 // cppcheck-suppress noExplicitConstructor
132 TimeInterval(long double dt)
133 : m_t()
134 , m_negative()
135 {
136 init_float<long double>(dt);
137 }
138
139 template <typename T>
140 // cppcheck-suppress noExplicitConstructor
142 : m_t()
143 , m_negative()
144 {
145 init_int<T>(dt);
146 }
147
148 template <typename T>
150 {
151 if(s > std::numeric_limits<time_t>::max())
152 return TimeInterval(std::numeric_limits<time_t>::max(), 999999999L);
153
154 return TimeInterval(s);
155 }
156
157 template <typename T>
159 {
160 T s_ = ms / (T)1000;
161 if((unsigned long long)s_ > (unsigned long long)std::numeric_limits<time_t>::max())
162 return TimeInterval(std::numeric_limits<time_t>::max(), 999999999L);
163
164 return TimeInterval((time_t)s_, ((long)ms % 1000L) * 1000000L);
165 }
166
167 template <typename T>
169 {
170 T s_ = us / (T)1000000;
171 if((unsigned long long)s_ > (unsigned long long)std::numeric_limits<time_t>::max())
172 return TimeInterval(std::numeric_limits<time_t>::max(), 999999999L);
173
174 return TimeInterval((time_t)s_, ((long)us % 1000000L) * 1000L);
175 }
176
177 template <typename T>
179 {
180 T s_ = ns / (T)1000000000L;
181 if(s_ > std::numeric_limits<time_t>::max())
182 return TimeInterval(std::numeric_limits<time_t>::max(), 999999999L);
183
184 return TimeInterval((time_t)s_, (long)ns % 1000000000L);
185 }
186
187# if __cplusplus >= 201103L
188 // cppcheck-suppress noExplicitConstructor
189 TimeInterval(std::chrono::nanoseconds ns)
190 {
191 *this = from_ns(ns.count());
192 }
193
194 operator std::chrono::nanoseconds() const
195 {
196 return std::chrono::nanoseconds(
197 (std::chrono::nanoseconds::rep)m_t.tv_sec * BILLION
198 + (std::chrono::nanoseconds::rep)m_t.tv_nsec);
199 }
200# endif // C++11
201
202private:
203 template <typename T>
204 void init_float(T dt)
205 {
206# pragma GCC diagnostic push
207# pragma GCC diagnostic ignored "-Wfloat-equal"
208 zth_assert(dt == dt); // Should not be NaN
209# pragma GCC diagnostic pop
210
211 m_negative = dt < 0;
212
213 if(std::fabs(dt) > (T)(std::numeric_limits<time_t>::max() / 2 - 1))
214 m_t.tv_sec = std::numeric_limits<time_t>::max();
215 else
216 m_t.tv_sec = (time_t)std::fabs(dt);
217 // cppcheck-suppress suspiciousFloatingPointCast
218 m_t.tv_nsec = (long)(std::fmod(std::fabs(dt), (T)1.0) * (T)1e9);
219
220 if(m_t.tv_nsec >= BILLION) {
221 m_t.tv_nsec -= BILLION;
222 m_t.tv_sec++;
223 }
224 }
225
226 template <typename T>
227 constexpr14 void init_int(T dt) noexcept
228 {
229 // seconds only.
230 m_negative = dt < 0;
231 m_t.tv_sec = (time_t)(dt >= 0 ? dt : -dt);
232 m_t.tv_nsec = 0;
233 }
234
235public:
236 constexpr bool isNormal() const noexcept
237 {
238 return m_t.tv_sec >= 0 && m_t.tv_nsec >= 0 && m_t.tv_nsec < BILLION;
239 }
240
241 constexpr bool isNegative() const noexcept
242 {
243 return m_negative;
244 }
245
246 constexpr bool isPositive() const noexcept
247 {
248 return !isNegative();
249 }
250
251 constexpr bool isNull() const noexcept
252 {
253 return m_t.tv_sec == 0 && m_t.tv_nsec == 0;
254 }
255
256 constexpr bool isInfinite() const noexcept
257 {
258 return m_t.tv_sec > std::numeric_limits<time_t>::max() / 2;
259 }
260
261 constexpr bool hasPassed() const noexcept
262 {
263 return isNegative() || isNull();
264 }
265
266 constexpr struct timespec const& ts() const noexcept
267 {
268 return m_t;
269 }
270
271 constexpr14 double s() const noexcept
272 {
273 return s<double>();
274 }
275
276 template <typename T>
277 constexpr14 T s() const noexcept
278 {
279 T t = (T)m_t.tv_sec + (T)m_t.tv_nsec * (T)1e-9;
280 if(m_negative)
281 t = -t;
282 return t;
283 }
284
285 constexpr bool isAbsBiggerThan(TimeInterval const& t) const noexcept
286 {
287 return m_t.tv_sec > t.m_t.tv_sec
288 || (m_t.tv_sec == t.m_t.tv_sec && m_t.tv_nsec > t.m_t.tv_nsec);
289 }
290
291 constexpr bool isBiggerThan(TimeInterval const& t) const noexcept
292 {
293 return (!m_negative && t.m_negative)
294 || (!m_negative && !t.m_negative && this->isAbsBiggerThan(t))
295 || (m_negative && t.m_negative && t.isAbsBiggerThan(*this));
296 }
297
298 constexpr bool operator==(TimeInterval const& rhs) const noexcept
299 {
300 return m_t.tv_nsec == rhs.m_t.tv_nsec && m_t.tv_sec == rhs.m_t.tv_sec
301 && m_negative == rhs.m_negative;
302 }
303
304 constexpr bool operator>(TimeInterval const& rhs) const noexcept
305 {
306 return this->isBiggerThan(rhs);
307 }
308
309 constexpr bool operator>=(TimeInterval const& rhs) const noexcept
310 {
311 return *this == rhs || this->isBiggerThan(rhs);
312 }
313
314 constexpr bool operator<(TimeInterval const& rhs) const noexcept
315 {
316 return !(*this >= rhs);
317 }
318
319 constexpr bool operator<=(TimeInterval const& rhs) const noexcept
320 {
321 return *this == rhs || !(*this > rhs);
322 }
323
324 constexpr14 void add(TimeInterval const& t) noexcept
325 {
326 if(t.m_negative == m_negative) {
327 // Check for overflow.
328 if(isInfinite() || t.isInfinite()
329 || std::numeric_limits<time_t>::max() - m_t.tv_sec - 1 <= t.m_t.tv_sec) {
330 m_t.tv_sec = std::numeric_limits<time_t>::max(); // infinite
331 } else {
332 // Add in same sign direction.
333 m_t.tv_sec += t.m_t.tv_sec;
334 m_t.tv_nsec += t.m_t.tv_nsec;
335 if(m_t.tv_nsec > BILLION) {
336 m_t.tv_nsec -= BILLION;
337 m_t.tv_sec++;
338 }
339 }
340 } else {
341 if(t.isAbsBiggerThan(*this)) {
342 // Add in other sign direction with sign flip.
343 m_t.tv_sec = t.m_t.tv_sec - m_t.tv_sec;
344 m_t.tv_nsec = t.m_t.tv_nsec - m_t.tv_nsec;
345 m_negative = !m_negative;
346 } else {
347 // Add in other sign direction (but without sign flip).
348 m_t.tv_sec -= t.m_t.tv_sec;
349 m_t.tv_nsec -= t.m_t.tv_nsec;
350 }
351 if(m_t.tv_nsec < 0) {
352 m_t.tv_nsec += BILLION;
353 m_t.tv_sec--;
354 }
355 }
356 }
357
358 constexpr14 void sub(TimeInterval const& t) noexcept
359 {
360 add(TimeInterval(t.ts().tv_sec, t.ts().tv_nsec, !t.isNegative()));
361 }
362
363 template <typename T>
364 constexpr14 void mul(T x) noexcept
365 {
366 *this = TimeInterval(s<T>() * x);
367 }
368
370 {
371 add(rhs);
372 return *this;
373 }
374
376 {
377 TimeInterval ti(*this);
378 ti += rhs;
379 return ti;
380 }
381
383 {
384 sub(rhs);
385 return *this;
386 }
387
389 {
390 TimeInterval ti(*this);
391 ti -= rhs;
392 return ti;
393 }
394
396 {
397 return TimeInterval(ts().tv_sec, ts().tv_nsec, !isNegative());
398 }
399
400 template <typename T>
402 {
403 mul<T>(x);
404 return *this;
405 }
406
407 template <typename T>
409 {
410 return TimeInterval(s<T>() * x);
411 }
412
413 template <typename T>
415 {
416 mul<T>((T)1 / x);
417 return *this;
418 }
419
420 template <typename T>
422 {
423 return TimeInterval(s<T>() / x);
424 }
425
426 string str() const
427 {
428 string res;
429 if(isInfinite()) {
430 res = "infinity";
431 return res;
432 }
433
434 if(m_negative)
435 res = "-";
436
438 // Do a simplified print without float formatting support.
439 if(m_t.tv_sec >= 60)
440 res += format("%u s", (unsigned int)m_t.tv_sec);
441 else if(m_t.tv_sec > 0)
442 res +=
443 format("%u.%03u s", (unsigned int)m_t.tv_sec,
444 (unsigned int)(m_t.tv_nsec / 1000000L));
445 else
446 res += format("%u us", (unsigned int)m_t.tv_nsec / 1000U);
447 } else {
448 uint64_t d = (uint64_t)(m_t.tv_sec / 3600 / 24);
449 time_t rest = m_t.tv_sec - d * 3600 * 24;
450 bool doPrint = d > 0;
451 if(doPrint)
452 res += format("%" PRIu64 "d:", d);
453
454 int h = int(rest / 3600);
455 rest -= h * 3600;
456 if(doPrint) {
457 res += format("%02d:", h);
458 } else if(h > 0) {
459 res += format("%d:", h);
460 doPrint = true;
461 }
462
463 int m = int(rest / 60);
464 rest -= m * 60;
465 if(doPrint) {
466 res += format("%02d:", m);
467 } else if(m > 0) {
468 res += format("%d:", m);
469 doPrint = true;
470 }
471
472 double sec = (double)rest + (double)m_t.tv_nsec * 1e-9;
473 if(doPrint) {
474 res += format("%06.3f", sec);
475 } else {
476 res += format("%g s", sec);
477 }
478 }
479
480 return res;
481 }
482
483private:
484 struct timespec m_t;
485 bool m_negative;
486};
487
488template <>
489inline cow_string str<TimeInterval const&>(TimeInterval const& value)
490{
491 return value.str();
492}
493
494# if __cplusplus >= 201103L
502ZTH_EXPORT constexpr14 inline TimeInterval operator"" _s(unsigned long long int x) noexcept
503{
504 return TimeInterval((time_t)std::min<unsigned long long int>(
505 x, (unsigned long long int)std::numeric_limits<time_t>::max()));
506}
507
515ZTH_EXPORT constexpr14 inline TimeInterval operator"" _ms(unsigned long long int x) noexcept
516{
517 return TimeInterval::from_ms(x);
518}
519
527ZTH_EXPORT constexpr14 inline TimeInterval operator"" _us(unsigned long long int x) noexcept
528{
529 return TimeInterval::from_us(x);
530}
531
539ZTH_EXPORT inline TimeInterval operator"" _s(long double x)
540{
541 return TimeInterval(x);
542}
543# endif // C++11
544
545# if __cplusplus >= 201103L
547 using duration = std::chrono::nanoseconds;
548 using rep = duration::rep;
549 using period = duration::period;
550 using time_point = std::chrono::time_point<monotonic_clock>;
551 static constexpr bool is_steady = true;
552
553 static time_point now() noexcept
554 {
555 struct timespec ts;
556 int res __attribute__((unused)) = clock_gettime(CLOCK_MONOTONIC, &ts);
557 zth_assert(res == 0);
558 return time_point{
559 duration((rep)ts.tv_sec * TimeInterval::BILLION + (rep)ts.tv_nsec)};
560 }
561};
562# endif // C++11
563
570public:
571 // null
572 constexpr Timestamp() noexcept
573 : m_t()
574 {}
575
576 // cppcheck-suppress noExplicitConstructor
577 constexpr Timestamp(struct timespec const& ts) noexcept
578 : m_t(ts)
579 {}
580
581 constexpr14 explicit Timestamp(time_t sec, long nsec = 0) noexcept
582 : m_t()
583 {
584 m_t.tv_sec = sec;
585 m_t.tv_nsec = nsec;
586 }
587
588 // cppcheck-suppress noExplicitConstructor
590 : m_t()
591 {
592 *this = now() + ti;
593 }
594
595 static Timestamp now()
596 {
597 Timestamp t;
598 int res __attribute__((unused)) = clock_gettime(CLOCK_MONOTONIC, &t.m_t);
599 zth_assert(res == 0);
600 zth_assert(!t.isNull());
601 return t;
602 }
603
604 constexpr struct timespec const& ts() const noexcept
605 {
606 return m_t;
607 }
608 constexpr operator struct timespec const&() const noexcept
609 {
610 return ts();
611 }
612
613 constexpr bool isBefore(Timestamp const& t) const noexcept
614 {
615 return ts().tv_sec < t.ts().tv_sec
616 || (ts().tv_sec == t.ts().tv_sec && ts().tv_nsec < t.ts().tv_nsec);
617 }
618
619 constexpr bool isAfter(Timestamp const& t) const noexcept
620 {
621 return t.isBefore(*this);
622 }
623
624 bool hasPassed() const noexcept
625 {
626 return now().isBefore(*this);
627 }
628
629 constexpr bool operator==(Timestamp const& rhs) const noexcept
630 {
631 return ts().tv_nsec == rhs.ts().tv_nsec && ts().tv_sec == rhs.ts().tv_sec;
632 }
633
634 constexpr bool operator!=(Timestamp const& rhs) const noexcept
635 {
636 return !(*this == rhs);
637 }
638 constexpr bool operator<(Timestamp const& rhs) const noexcept
639 {
640 return this->isBefore(rhs);
641 }
642 constexpr bool operator<=(Timestamp const& rhs) const noexcept
643 {
644 return *this == rhs || this->isBefore(rhs);
645 }
646 constexpr bool operator>(Timestamp const& rhs) const noexcept
647 {
648 return rhs.isBefore(*this);
649 }
650 constexpr bool operator>=(Timestamp const& rhs) const noexcept
651 {
652 return *this == rhs || rhs.isBefore(*this);
653 }
654
656 {
657 return TimeInterval(t.ts().tv_sec, t.ts().tv_nsec)
658 - TimeInterval(ts().tv_sec, ts().tv_nsec);
659 }
660
662 {
663 // Assume we are in the past. If so, interval calculations are
664 // simpler than in the general timeTo() case.
665 Timestamp t = now();
666 zth_assert(!isAfter(t));
667
668 t.m_t.tv_sec -= m_t.tv_sec;
669 t.m_t.tv_nsec -= m_t.tv_nsec;
670 if(t.m_t.tv_nsec < 0) {
671 t.m_t.tv_sec--;
672 t.m_t.tv_nsec += TimeInterval::BILLION;
673 }
674
675 return TimeInterval(t.m_t.tv_sec, t.m_t.tv_nsec);
676 }
677
678 constexpr14 void add(TimeInterval const& dt) noexcept
679 {
680 TimeInterval t(m_t.tv_sec, m_t.tv_nsec);
681 t += dt;
683 m_t = t.ts();
684 }
685
687 {
688 add(dt);
689 return *this;
690 }
691
692 constexpr14 Timestamp operator+(TimeInterval const& dt) const noexcept
693 {
694 Timestamp t(*this);
695 return t += dt;
696 }
697
699 {
700 add(-dt);
701 return *this;
702 }
703
704 constexpr14 Timestamp operator-(TimeInterval const& dt) const noexcept
705 {
706 Timestamp t(*this);
707 return t -= dt;
708 }
709
710 constexpr14 TimeInterval operator-(Timestamp const& rhs) const noexcept
711 {
712 return rhs.timeTo(*this);
713 }
714
715 static constexpr Timestamp null() noexcept
716 {
717 return Timestamp();
718 }
719
720 constexpr bool isNull() const noexcept
721 {
722 return m_t.tv_sec == 0 && m_t.tv_nsec == 0;
723 }
724
725# if __cplusplus >= 201103L
726 template <typename Duration>
727 // cppcheck-suppress noExplicitConstructor
728 Timestamp(std::chrono::time_point<monotonic_clock, Duration> tp)
729 {
730 auto d = tp.time_since_epoch();
731 auto ns = std::chrono::duration_cast<std::chrono::nanoseconds>(d).count();
732 m_t.tv_sec = (time_t)(ns / TimeInterval::BILLION);
733 m_t.tv_nsec = (long)(ns % TimeInterval::BILLION);
734 }
735
736 operator std::chrono::time_point<monotonic_clock>() const
737 {
738 return std::chrono::time_point<monotonic_clock>{monotonic_clock::duration{
740 + (monotonic_clock::rep)m_t.tv_nsec}};
741 }
742# endif // C++11
743
744private:
745 struct timespec m_t;
746};
747
748# ifdef ZTH_OS_MAC
749// Should be const, but the alias-trick does not work on OSX.
750extern Timestamp /* const */ startTime;
751# else
752extern Timestamp const startTime;
753# endif
754
755} // namespace zth
756
757#endif // __cplusplus
758#endif // ZTH_TIME_H
Convenient wrapper around struct timespec that contains a time interval.
Definition time.h:55
constexpr bool operator==(TimeInterval const &rhs) const noexcept
Definition time.h:298
constexpr TimeInterval operator+(TimeInterval const &rhs) const noexcept
Definition time.h:375
constexpr TimeInterval(T dt) noexcept
Definition time.h:141
static constexpr TimeInterval from_s(T s)
Definition time.h:149
TimeInterval(double dt)
Definition time.h:124
constexpr bool operator>(TimeInterval const &rhs) const noexcept
Definition time.h:304
static constexpr TimeInterval null() noexcept
Definition time.h:69
constexpr TimeInterval operator-(TimeInterval const &rhs) const noexcept
Definition time.h:388
TimeInterval(std::chrono::nanoseconds ns)
Definition time.h:189
static constexpr TimeInterval from_ms(T ms)
Definition time.h:158
constexpr bool isInfinite() const noexcept
Definition time.h:256
static constexpr TimeInterval from_ns(T ns)
Definition time.h:178
static constexpr TimeInterval infinity() noexcept
Definition time.h:64
constexpr void sub(TimeInterval const &t) noexcept
Definition time.h:358
constexpr bool hasPassed() const noexcept
Definition time.h:261
constexpr TimeInterval() noexcept
Definition time.h:74
constexpr TimeInterval operator/(T x) const noexcept
Definition time.h:421
constexpr void add(TimeInterval const &t) noexcept
Definition time.h:324
constexpr void mul(T x) noexcept
Definition time.h:364
static constexpr TimeInterval from_us(T us)
Definition time.h:168
string str() const
Definition time.h:426
constexpr bool operator<=(TimeInterval const &rhs) const noexcept
Definition time.h:319
constexpr TimeInterval & operator*=(T x) noexcept
Definition time.h:401
constexpr bool isPositive() const noexcept
Definition time.h:246
constexpr TimeInterval & operator-=(TimeInterval const &rhs) noexcept
Definition time.h:382
constexpr bool operator>=(TimeInterval const &rhs) const noexcept
Definition time.h:309
TimeInterval & operator=(TimeInterval const &t) noexcept
Definition time.h:103
constexpr TimeInterval(time_t s, long ns=0, bool negative=false) noexcept
Definition time.h:81
constexpr double s() const noexcept
Definition time.h:271
constexpr T s() const noexcept
Definition time.h:277
constexpr bool isNegative() const noexcept
Definition time.h:241
TimeInterval(long double dt)
Definition time.h:132
static long const BILLION
Definition time.h:62
constexpr bool isNull() const noexcept
Definition time.h:251
constexpr TimeInterval & operator+=(TimeInterval const &rhs) noexcept
Definition time.h:369
constexpr bool operator<(TimeInterval const &rhs) const noexcept
Definition time.h:314
constexpr bool isAbsBiggerThan(TimeInterval const &t) const noexcept
Definition time.h:285
constexpr TimeInterval operator-() const noexcept
Definition time.h:395
TimeInterval(float dt)
Definition time.h:116
constexpr TimeInterval(TimeInterval const &t) noexcept
Definition time.h:110
constexpr TimeInterval & operator/=(T x) noexcept
Definition time.h:414
constexpr TimeInterval operator*(T x) const noexcept
Definition time.h:408
constexpr struct timespec const & ts() const noexcept
Definition time.h:266
constexpr TimeInterval(struct timespec const &ts) noexcept
Definition time.h:98
constexpr bool isNormal() const noexcept
Definition time.h:236
constexpr bool isBiggerThan(TimeInterval const &t) const noexcept
Definition time.h:291
Convenient wrapper around struct timespec that contains an absolute timestamp.
Definition time.h:568
constexpr Timestamp(struct timespec const &ts) noexcept
Definition time.h:577
static Timestamp now()
Definition time.h:595
constexpr TimeInterval operator-(Timestamp const &rhs) const noexcept
Definition time.h:710
constexpr bool operator==(Timestamp const &rhs) const noexcept
Definition time.h:629
constexpr Timestamp operator-(TimeInterval const &dt) const noexcept
Definition time.h:704
constexpr struct timespec const & ts() const noexcept
Definition time.h:604
constexpr bool isNull() const noexcept
Definition time.h:720
constexpr Timestamp & operator-=(TimeInterval const &dt) noexcept
Definition time.h:698
Timestamp(TimeInterval const &ti)
Definition time.h:589
constexpr bool operator>=(Timestamp const &rhs) const noexcept
Definition time.h:650
constexpr bool isAfter(Timestamp const &t) const noexcept
Definition time.h:619
constexpr bool operator!=(Timestamp const &rhs) const noexcept
Definition time.h:634
constexpr bool operator<(Timestamp const &rhs) const noexcept
Definition time.h:638
bool hasPassed() const noexcept
Definition time.h:624
constexpr void add(TimeInterval const &dt) noexcept
Definition time.h:678
Timestamp(std::chrono::time_point< monotonic_clock, Duration > tp)
Definition time.h:728
static constexpr Timestamp null() noexcept
Definition time.h:715
constexpr bool operator>(Timestamp const &rhs) const noexcept
Definition time.h:646
constexpr Timestamp(time_t sec, long nsec=0) noexcept
Definition time.h:581
constexpr Timestamp() noexcept
Definition time.h:572
constexpr bool isBefore(Timestamp const &t) const noexcept
Definition time.h:613
constexpr TimeInterval timeTo(Timestamp const &t) const
Definition time.h:655
TimeInterval passed() const
Definition time.h:661
constexpr bool operator<=(Timestamp const &rhs) const noexcept
Definition time.h:642
constexpr Timestamp & operator+=(TimeInterval const &dt) noexcept
Definition time.h:686
constexpr Timestamp operator+(TimeInterval const &dt) const noexcept
Definition time.h:692
Copy-on-write string.
Definition util.h:319
#define ZTH_CLASS_NEW_DELETE(T)
Define new/delete operators for a class, which are allocator-aware.
Definition allocator.h:143
#define constexpr14
Definition macros.h:208
string format(char const *fmt,...)
Format like sprintf(), but save the result in an zth::string.
Definition util.h:478
static bool const UseLimitedFormatSpecifiers
Use limited formatting specifiers.
Definition config.h:195
std::chrono::time_point< monotonic_clock > time_point
Definition time.h:550
static time_point now() noexcept
Definition time.h:553
static constexpr bool is_steady
Definition time.h:551
std::chrono::nanoseconds duration
Definition time.h:547
duration::rep rep
Definition time.h:548
duration::period period
Definition time.h:549
#define zth_assert(expr)
assert(), but better integrated in Zth.
Definition util.h:212