29# if __cplusplus >= 201103L
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);
38clock_nanosleep(
int clk_id,
int flags,
struct timespec
const* request,
struct timespec* remain);
39# ifndef CLOCK_MONOTONIC
40# define CLOCK_MONOTONIC 1
43# define TIMER_ABSTIME 1
79# if __cplusplus >= 201103L
81 constexpr TimeInterval(time_t
s,
long ns = 0,
bool negative =
false) noexcept
83 , m_negative{negative}
87 TimeInterval(time_t
s,
long ns = 0,
bool negative =
false) noexcept
89 , m_negative(negative)
106 m_negative = t.m_negative;
112 , m_negative(t.isNegative())
120 init_float<float>(dt);
128 init_float<double>(dt);
136 init_float<long double>(dt);
139 template <
typename T>
148 template <
typename T>
151 if(
s > std::numeric_limits<time_t>::max())
152 return TimeInterval(std::numeric_limits<time_t>::max(), 999999999L);
157 template <
typename T>
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);
164 return TimeInterval((time_t)s_, ((
long)ms % 1000L) * 1000000L);
167 template <
typename T>
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);
174 return TimeInterval((time_t)s_, ((
long)us % 1000000L) * 1000L);
177 template <
typename T>
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);
184 return TimeInterval((time_t)s_, (
long)ns % 1000000000L);
187# if __cplusplus >= 201103L
194 operator std::chrono::nanoseconds()
const
196 return std::chrono::nanoseconds(
197 (std::chrono::nanoseconds::rep)m_t.tv_sec *
BILLION
198 + (std::chrono::nanoseconds::rep)m_t.tv_nsec);
203 template <
typename T>
204 void init_float(T dt)
206# pragma GCC diagnostic push
207# pragma GCC diagnostic ignored "-Wfloat-equal"
209# pragma GCC diagnostic pop
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();
216 m_t.tv_sec = (time_t)std::fabs(dt);
218 m_t.tv_nsec = (long)(std::fmod(std::fabs(dt), (T)1.0) * (T)1e9);
226 template <
typename T>
231 m_t.tv_sec = (time_t)(dt >= 0 ? dt : -dt);
238 return m_t.tv_sec >= 0 && m_t.tv_nsec >= 0 && m_t.tv_nsec <
BILLION;
253 return m_t.tv_sec == 0 && m_t.tv_nsec == 0;
258 return m_t.tv_sec > std::numeric_limits<time_t>::max() / 2;
266 constexpr struct timespec const&
ts() const noexcept
276 template <
typename T>
279 T t = (T)m_t.tv_sec + (T)m_t.tv_nsec * (T)1e-9;
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);
293 return (!m_negative && t.m_negative)
295 || (m_negative && t.m_negative && t.isAbsBiggerThan(*
this));
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;
316 return !(*
this >= rhs);
321 return *
this == rhs || !(*
this > rhs);
326 if(t.m_negative == m_negative) {
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();
333 m_t.tv_sec += t.m_t.tv_sec;
334 m_t.tv_nsec += t.m_t.tv_nsec;
341 if(t.isAbsBiggerThan(*
this)) {
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;
348 m_t.tv_sec -= t.m_t.tv_sec;
349 m_t.tv_nsec -= t.m_t.tv_nsec;
351 if(m_t.tv_nsec < 0) {
363 template <
typename T>
400 template <
typename T>
407 template <
typename T>
413 template <
typename T>
420 template <
typename T>
440 res +=
format(
"%u s", (
unsigned int)m_t.tv_sec);
441 else if(m_t.tv_sec > 0)
443 format(
"%u.%03u s", (
unsigned int)m_t.tv_sec,
444 (
unsigned int)(m_t.tv_nsec / 1000000L));
446 res +=
format(
"%u us", (
unsigned int)m_t.tv_nsec / 1000U);
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;
452 res +=
format(
"%" PRIu64
"d:", d);
454 int h = int(rest / 3600);
457 res +=
format(
"%02d:", h);
463 int m = int(rest / 60);
466 res +=
format(
"%02d:", m);
472 double sec = (double)rest + (
double)m_t.tv_nsec * 1e-9;
474 res +=
format(
"%06.3f", sec);
476 res +=
format(
"%g s", sec);
494# if __cplusplus >= 201103L
504 return TimeInterval((time_t)std::min<unsigned long long int>(
505 x, (
unsigned long long int)std::numeric_limits<time_t>::max()));
517 return TimeInterval::from_ms(x);
529 return TimeInterval::from_us(x);
545# if __cplusplus >= 201103L
548 using rep = duration::rep;
556 int res __attribute__((unused)) = clock_gettime(CLOCK_MONOTONIC, &ts);
598 int res __attribute__((unused)) = clock_gettime(CLOCK_MONOTONIC, &t.m_t);
604 constexpr struct timespec const&
ts() const noexcept
608 constexpr operator struct timespec const&()
const noexcept
615 return ts().tv_sec < t.ts().tv_sec
616 || (
ts().tv_sec == t.ts().tv_sec &&
ts().tv_nsec < t.ts().tv_nsec);
621 return t.isBefore(*
this);
631 return ts().tv_nsec == rhs.ts().tv_nsec &&
ts().tv_sec == rhs.ts().tv_sec;
636 return !(*
this == rhs);
644 return *
this == rhs || this->
isBefore(rhs);
648 return rhs.isBefore(*
this);
652 return *
this == rhs || rhs.isBefore(*
this);
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) {
712 return rhs.timeTo(*
this);
722 return m_t.tv_sec == 0 && m_t.tv_nsec == 0;
725# if __cplusplus >= 201103L
726 template <
typename Duration>
728 Timestamp(std::chrono::time_point<monotonic_clock, Duration> tp)
730 auto d = tp.time_since_epoch();
731 auto ns = std::chrono::duration_cast<std::chrono::nanoseconds>(d).count();
736 operator std::chrono::time_point<monotonic_clock>()
const
750extern Timestamp startTime;
752extern Timestamp
const startTime;
Convenient wrapper around struct timespec that contains a time interval.
constexpr bool operator==(TimeInterval const &rhs) const noexcept
constexpr TimeInterval operator+(TimeInterval const &rhs) const noexcept
constexpr TimeInterval(T dt) noexcept
static constexpr TimeInterval from_s(T s)
constexpr bool operator>(TimeInterval const &rhs) const noexcept
static constexpr TimeInterval null() noexcept
constexpr TimeInterval operator-(TimeInterval const &rhs) const noexcept
TimeInterval(std::chrono::nanoseconds ns)
static constexpr TimeInterval from_ms(T ms)
constexpr bool isInfinite() const noexcept
static constexpr TimeInterval from_ns(T ns)
static constexpr TimeInterval infinity() noexcept
constexpr void sub(TimeInterval const &t) noexcept
constexpr bool hasPassed() const noexcept
constexpr TimeInterval() noexcept
constexpr TimeInterval operator/(T x) const noexcept
constexpr void add(TimeInterval const &t) noexcept
constexpr void mul(T x) noexcept
static constexpr TimeInterval from_us(T us)
constexpr bool operator<=(TimeInterval const &rhs) const noexcept
constexpr TimeInterval & operator*=(T x) noexcept
constexpr bool isPositive() const noexcept
constexpr TimeInterval & operator-=(TimeInterval const &rhs) noexcept
constexpr bool operator>=(TimeInterval const &rhs) const noexcept
TimeInterval & operator=(TimeInterval const &t) noexcept
constexpr TimeInterval(time_t s, long ns=0, bool negative=false) noexcept
constexpr double s() const noexcept
constexpr T s() const noexcept
constexpr bool isNegative() const noexcept
TimeInterval(long double dt)
static long const BILLION
constexpr bool isNull() const noexcept
constexpr TimeInterval & operator+=(TimeInterval const &rhs) noexcept
constexpr bool operator<(TimeInterval const &rhs) const noexcept
constexpr bool isAbsBiggerThan(TimeInterval const &t) const noexcept
constexpr TimeInterval operator-() const noexcept
constexpr TimeInterval(TimeInterval const &t) noexcept
constexpr TimeInterval & operator/=(T x) noexcept
constexpr TimeInterval operator*(T x) const noexcept
constexpr struct timespec const & ts() const noexcept
constexpr TimeInterval(struct timespec const &ts) noexcept
constexpr bool isNormal() const noexcept
constexpr bool isBiggerThan(TimeInterval const &t) const noexcept
Convenient wrapper around struct timespec that contains an absolute timestamp.
constexpr Timestamp(struct timespec const &ts) noexcept
constexpr TimeInterval operator-(Timestamp const &rhs) const noexcept
constexpr bool operator==(Timestamp const &rhs) const noexcept
constexpr Timestamp operator-(TimeInterval const &dt) const noexcept
constexpr struct timespec const & ts() const noexcept
constexpr bool isNull() const noexcept
constexpr Timestamp & operator-=(TimeInterval const &dt) noexcept
Timestamp(TimeInterval const &ti)
constexpr bool operator>=(Timestamp const &rhs) const noexcept
constexpr bool isAfter(Timestamp const &t) const noexcept
constexpr bool operator!=(Timestamp const &rhs) const noexcept
constexpr bool operator<(Timestamp const &rhs) const noexcept
bool hasPassed() const noexcept
constexpr void add(TimeInterval const &dt) noexcept
Timestamp(std::chrono::time_point< monotonic_clock, Duration > tp)
static constexpr Timestamp null() noexcept
constexpr bool operator>(Timestamp const &rhs) const noexcept
constexpr Timestamp(time_t sec, long nsec=0) noexcept
constexpr Timestamp() noexcept
constexpr bool isBefore(Timestamp const &t) const noexcept
constexpr TimeInterval timeTo(Timestamp const &t) const
TimeInterval passed() const
constexpr bool operator<=(Timestamp const &rhs) const noexcept
constexpr Timestamp & operator+=(TimeInterval const &dt) noexcept
constexpr Timestamp operator+(TimeInterval const &dt) const noexcept
#define ZTH_CLASS_NEW_DELETE(T)
Define new/delete operators for a class, which are allocator-aware.
string format(char const *fmt,...)
Format like sprintf(), but save the result in an zth::string.
static bool const UseLimitedFormatSpecifiers
Use limited formatting specifiers.
std::chrono::time_point< monotonic_clock > time_point
static time_point now() noexcept
static constexpr bool is_steady
std::chrono::nanoseconds duration
#define zth_assert(expr)
assert(), but better integrated in Zth.