33# if __cplusplus >= 201103L
37# if defined(ZTH_OS_MAC) || defined(ZTH_OS_BAREMETAL)
38# ifdef ZTH_CUSTOM_CLOCK_GETTIME
39extern "C" int clock_gettime(
int clk_id,
struct timespec* res);
42clock_nanosleep(
int clk_id,
int flags,
struct timespec
const* request,
struct timespec* remain);
43# ifndef CLOCK_MONOTONIC
44# define CLOCK_MONOTONIC 1
47# define TIMER_ABSTIME 1
59ZTH_EXPORT
inline void now(
struct timespec& ts)
61 int res = clock_gettime(CLOCK_MONOTONIC, &ts);
74ZTH_EXPORT
int realsleep(
struct timespec
const& ts);
106# if __cplusplus >= 201103L
108 constexpr TimeInterval(time_t
s,
long ns = 0,
bool negative =
false) noexcept
110 , m_negative{negative}
114 TimeInterval(time_t
s,
long ns = 0,
bool negative =
false) noexcept
116 , m_negative(negative)
133 m_negative = t.m_negative;
139 , m_negative(t.isNegative())
147 init_float<float>(dt);
155 init_float<double>(dt);
163 init_float<long double>(dt);
166 template <
typename T>
175 template <
typename T>
178 if(
s > std::numeric_limits<time_t>::max())
179 return TimeInterval(std::numeric_limits<time_t>::max(), 999999999L);
184 template <
typename T>
188 if((
unsigned long long)s_ > (
unsigned long long)std::numeric_limits<time_t>::max())
189 return TimeInterval(std::numeric_limits<time_t>::max(), 999999999L);
191 return TimeInterval((time_t)s_, ((
long)ms % 1000L) * 1000000L);
194 template <
typename T>
197 T s_ = us / (T)1000000;
198 if((
unsigned long long)s_ > (
unsigned long long)std::numeric_limits<time_t>::max())
199 return TimeInterval(std::numeric_limits<time_t>::max(), 999999999L);
201 return TimeInterval((time_t)s_, ((
long)us % 1000000L) * 1000L);
204 template <
typename T>
207 T s_ = ns / (T)1000000000L;
208 if(s_ > std::numeric_limits<time_t>::max())
209 return TimeInterval(std::numeric_limits<time_t>::max(), 999999999L);
211 return TimeInterval((time_t)s_, (
long)ns % 1000000000L);
214# if __cplusplus >= 201103L
215 template <
typename Rep>
222 template <
typename Rep>
229 template <
typename Rep>
236 template <
typename Rep>
243 template <
typename Rep,
typename Period>
249 operator std::chrono::nanoseconds()
const
251 return std::chrono::nanoseconds(
252 (std::chrono::nanoseconds::rep)m_t.tv_sec *
BILLION
253 + (std::chrono::nanoseconds::rep)m_t.tv_nsec);
256 template <
typename Rep,
typename Period>
257 operator std::chrono::duration<Rep, Period>()
const
259 return std::chrono::duration_cast<std::chrono::duration<Rep, Period>>(
260 (std::chrono::nanoseconds) *
this);
265 template <
typename T>
266 void init_float(T dt)
268# pragma GCC diagnostic push
269# pragma GCC diagnostic ignored "-Wfloat-equal"
271# pragma GCC diagnostic pop
275 if(std::fabs(dt) > (T)(std::numeric_limits<time_t>::max() / 2 - 1))
276 m_t.tv_sec = std::numeric_limits<time_t>::max();
278 m_t.tv_sec = (time_t)std::fabs(dt);
280 m_t.tv_nsec = (long)(std::fmod(std::fabs(dt), (T)1.0) * (T)1e9);
288 template <
typename T>
293 m_t.tv_sec = (time_t)(dt >= 0 ? dt : -dt);
300 return m_t.tv_sec >= 0 && m_t.tv_nsec >= 0 && m_t.tv_nsec <
BILLION;
315 return m_t.tv_sec == 0 && m_t.tv_nsec == 0;
320 return m_t.tv_sec > std::numeric_limits<time_t>::max() / 2;
328 constexpr struct timespec const&
ts() const noexcept
338 template <
typename T>
341 T t = (T)m_t.tv_sec + (T)m_t.tv_nsec * (T)1e-9;
349 return m_t.tv_sec > t.m_t.tv_sec
350 || (m_t.tv_sec == t.m_t.tv_sec && m_t.tv_nsec > t.m_t.tv_nsec);
355 return (!m_negative && t.m_negative)
357 || (m_negative && t.m_negative && t.isAbsBiggerThan(*
this));
362 return m_t.tv_nsec == rhs.m_t.tv_nsec && m_t.tv_sec == rhs.m_t.tv_sec
363 && m_negative == rhs.m_negative;
378 return !(*
this >= rhs);
383 return *
this == rhs || !(*
this > rhs);
388 if(t.m_negative == m_negative) {
391 || std::numeric_limits<time_t>::max() - m_t.tv_sec - 1 <= t.m_t.tv_sec) {
392 m_t.tv_sec = std::numeric_limits<time_t>::max();
395 m_t.tv_sec += t.m_t.tv_sec;
396 m_t.tv_nsec += t.m_t.tv_nsec;
403 if(t.isAbsBiggerThan(*
this)) {
405 m_t.tv_sec = t.m_t.tv_sec - m_t.tv_sec;
406 m_t.tv_nsec = t.m_t.tv_nsec - m_t.tv_nsec;
407 m_negative = !m_negative;
410 m_t.tv_sec -= t.m_t.tv_sec;
411 m_t.tv_nsec -= t.m_t.tv_nsec;
413 if(m_t.tv_nsec < 0) {
425 template <
typename T>
462 template <
typename T>
469 template <
typename T>
475 template <
typename T>
482 template <
typename T>
502 res +=
format(
"%u s", (
unsigned int)m_t.tv_sec);
503 else if(m_t.tv_sec > 0)
505 format(
"%u.%03u s", (
unsigned int)m_t.tv_sec,
506 (
unsigned int)(m_t.tv_nsec / 1000000L));
508 res +=
format(
"%u us", (
unsigned int)m_t.tv_nsec / 1000U);
510 uint64_t d = (uint64_t)(m_t.tv_sec / 3600 / 24);
511 time_t rest = m_t.tv_sec - d * 3600 * 24;
512 bool doPrint = d > 0;
514 res +=
format(
"%" PRIu64
"d:", d);
516 int h = int(rest / 3600);
519 res +=
format(
"%02d:", h);
525 int m = int(rest / 60);
528 res +=
format(
"%02d:", m);
534 double sec = (double)rest + (
double)m_t.tv_nsec * 1e-9;
536 res +=
format(
"%06.3f", sec);
538 res +=
format(
"%g s", sec);
556# if __cplusplus >= 201103L
566 return TimeInterval((time_t)std::min<unsigned long long int>(
567 x, (
unsigned long long int)std::numeric_limits<time_t>::max()));
579 return TimeInterval::from_ms(x);
591 return TimeInterval::from_us(x);
607# if __cplusplus >= 201103L
610 using rep = duration::rep;
664 constexpr struct timespec const&
ts() const noexcept
668 constexpr operator struct timespec const&()
const noexcept
675 return ts().tv_sec < t.ts().tv_sec
676 || (
ts().tv_sec == t.ts().tv_sec &&
ts().tv_nsec < t.ts().tv_nsec);
681 return t.isBefore(*
this);
691 return ts().tv_nsec == rhs.ts().tv_nsec &&
ts().tv_sec == rhs.ts().tv_sec;
696 return !(*
this == rhs);
704 return *
this == rhs || this->
isBefore(rhs);
708 return rhs.isBefore(*
this);
712 return *
this == rhs || rhs.isBefore(*
this);
728 t.m_t.tv_sec -= m_t.tv_sec;
729 t.m_t.tv_nsec -= m_t.tv_nsec;
730 if(t.m_t.tv_nsec < 0) {
772 return rhs.timeTo(*
this);
782 return m_t.tv_sec == 0 && m_t.tv_nsec == 0;
785# if __cplusplus >= 201103L
786 template <
typename Duration>
788 Timestamp(std::chrono::time_point<monotonic_clock, Duration> tp)
790 auto d = tp.time_since_epoch();
791 auto ns = std::chrono::duration_cast<std::chrono::nanoseconds>(d).count();
796 operator std::chrono::time_point<monotonic_clock>()
const
810extern Timestamp startTime;
812extern Timestamp
const startTime;
835 struct timespec ts = {};
838 *s = (uint64_t)ts.tv_sec;
840 *ns = (uint32_t)ts.tv_nsec;
845# include <sys/time.h>
847ZTH_EXPORT
void zth_now(
struct timespec
const* ts);
848ZTH_EXPORT
void zth_now2(uint64_t* s, uint32_t* ns);
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
TimeInterval(std::chrono::duration< Rep, Period > d)
constexpr TimeInterval operator-(TimeInterval const &rhs) const noexcept
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
TimeInterval(std::chrono::duration< Rep, std::ratio< 1 > > s)
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
TimeInterval(std::chrono::duration< Rep, std::micro > us)
constexpr T s() const noexcept
TimeInterval(std::chrono::duration< Rep, std::milli > ms)
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
operator std::chrono::nanoseconds() const
TimeInterval(std::chrono::duration< Rep, std::nano > ns)
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
void zth_now(struct timespec *ts)
Returns the current timestamp.
void zth_now2(uint64_t *s, uint32_t *ns)
Returns the current timestamp.
#define ZTH_CLASS_NEW_DELETE(T)
Define new/delete operators for a class, which are allocator-aware.
void now(struct timespec &ts)
Returns the current timestamp.
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.