#include #include namespace timer { struct timer { constexpr timer() = default; void start() { clock_gettime(kClock, &m_start); } void stop() { timespec end; clock_gettime(kClock, &end); m_nanos += ((end.tv_sec - m_start.tv_sec) * 1000000000ull) + (end.tv_nsec - m_start.tv_nsec); } constexpr double as_sec() const { return as_msec() / 1000.0; } constexpr double as_msec() const { return as_usec() / 1000.0; } constexpr double as_usec() const { return static_cast(m_nanos) / 1000.0; } private: static constexpr clockid_t kClock = CLOCK_MONOTONIC_RAW; timespec m_start{}; std::uint64_t m_nanos{0}; }; struct scoped_timer { explicit scoped_timer(timer& t) : m_timer(t) { m_timer.start(); } ~scoped_timer() { m_timer.stop(); } scoped_timer(const scoped_timer&) = delete; scoped_timer& operator=(const scoped_timer&) = delete; scoped_timer(scoped_timer&&) = delete; scoped_timer& operator=(scoped_timer&&) = delete; private: timer& m_timer; }; } // namespace timer