Helios Engine
A modular ECS based data-oriented C++23 game engine framework
Loading...
Searching...
No Matches
timer.hpp
Go to the documentation of this file.
1#pragma once
2
4
5#include <chrono>
6#include <concepts>
7#include <cstdint>
8#include <ratio>
9#include <type_traits>
10
11namespace helios::utils {
12
13namespace details {
14
15/**
16 * @brief Concept for clock types compatible with std::chrono clocks.
17 * @details Requires nested types rep, period, duration and time_point, and a
18 * static now() function.
19 */
20template <typename T>
21concept ClockTrait = requires {
22 typename T::rep;
23 typename T::period;
24 typename T::duration;
25 typename T::time_point;
26 { T::now() } -> std::same_as<typename T::time_point>;
27};
28
29/**
30 * @brief Concept for duration types based on std::chrono::duration.
31 */
32template <typename T>
34 std::same_as<T, std::chrono::duration<typename T::rep, typename T::period>>;
35
36/**
37 * @brief Helper alias to normalize a duration to its canonical
38 * std::chrono::duration form.
39 */
40template <typename Rep, typename Period>
41using NormalizedDuration = std::chrono::duration<Rep, Period>;
42
43/**
44 * @brief Helper alias to normalize a clock's duration to a specific rep/period.
45 */
46template <typename Clock, typename Rep, typename Period>
47using NormalizedClockDuration = std::chrono::duration<Rep, Period>;
48
49} // namespace details
50
51/**
52 * @brief High–resolution timer with configurable clock and rich elapsed API.
53 * @details The timer measures elapsed time from the last reset point.
54 *
55 * - The clock type is configurable via the template parameter @p Clock.
56 * - Users can query elapsed time as:
57 * - A raw `Clock::duration`.
58 * - Any `std::chrono::duration` (via `ElapsedDuration`).
59 * - Arbitrary arithmetic type with specified time unit (via `Elapsed`).
60 * - Convenience helpers (seconds, milliseconds, microseconds, nanoseconds).
61 *
62 * @note The default clock is `std::chrono::steady_clock`.
63 * @tparam Clock Clock type used to measure time. Must satisfy
64 * `details::ClockTrait`.
65 */
66template <details::ClockTrait Clock = std::chrono::steady_clock>
67class Timer {
68public:
69 using ClockType = Clock;
70 using TimePoint = typename Clock::time_point;
71 using Duration = typename Clock::duration;
72
73 /**
74 * @brief Constructs timer and immediately resets start timestamp.
75 */
76 constexpr Timer() noexcept(noexcept(Clock::now())) = default;
77 constexpr Timer(const Timer&) noexcept(
78 std::is_nothrow_copy_constructible_v<Clock>) = default;
79 constexpr Timer(Timer&&) noexcept(
80 std::is_nothrow_move_constructible_v<Clock>) = default;
81 constexpr ~Timer() noexcept(std::is_nothrow_destructible_v<Clock>) = default;
82
83 constexpr Timer& operator=(const Timer&) noexcept(
84 std::is_nothrow_copy_assignable_v<Clock>) = default;
85 constexpr Timer& operator=(Timer&&) noexcept(
86 std::is_nothrow_move_assignable_v<Clock>) = default;
87
88 /**
89 * @brief Reset the timer start point to current time.
90 */
91 constexpr void Reset() noexcept(noexcept(Clock::now())) {
92 start_time_ = Clock::now();
93 }
94
95 /**
96 * @brief Get elapsed time as a `std::chrono::duration`.
97 * @details This is the primary API for time measurement and should be
98 * preferred when working with `std::chrono`.
99 * @tparam Units Duration type to convert to. Must satisfy
100 * `details::DurationTrait`. Defaults to `Clock::duration`.
101 * @return Elapsed time since last reset as `Units`.
102 */
103 template <details::DurationTrait Units = Duration>
104 [[nodiscard]] constexpr Units ElapsedDuration() const;
105
106 /**
107 * @brief Get elapsed time converted to an arithmetic value with specified
108 * units.
109 * @details This method allows querying elapsed time in arbitrary precision
110 * and units, for example:
111 * - `Elapsed<double, std::chrono::seconds>()`
112 * - `Elapsed<std::uint64_t, std::chrono::microseconds>()`
113 * @tparam Type Arithmetic type used for the returned value.
114 * @tparam Units Duration type representing the desired time unit.
115 * @return Elapsed time as `Type`, where the underlying duration is `Units`.
116 */
117 template <utils::ArithmeticTrait Type = typename Duration::rep,
119 [[nodiscard]] constexpr Type Elapsed() const;
120
121 /**
122 * @brief Elapsed time in seconds as double.
123 * @return Elapsed time since last reset in seconds.
124 */
125 [[nodiscard]] constexpr double ElapsedSec() const {
127 }
128
129 /**
130 * @brief Elapsed time in milliseconds as double.
131 * @return Elapsed time since last reset in milliseconds.
132 */
133 [[nodiscard]] constexpr double ElapsedMilliSec() const {
135 }
136
137 /**
138 * @brief Elapsed time in microseconds as 64-bit integer.
139 * @return Elapsed time since last reset in microseconds.
140 */
141 [[nodiscard]] constexpr int64_t ElapsedMicroSec() const {
143 }
144
145 /**
146 * @brief Elapsed time in nanoseconds as 64-bit integer.
147 * @return Elapsed time since last reset in nanoseconds.
148 */
149 [[nodiscard]] constexpr int64_t ElapsedNanoSec() const {
151 }
152
153 /**
154 * @brief Get the raw start timestamp of the timer.
155 * @return Starting time point.
156 */
157 [[nodiscard]] constexpr TimePoint Start() const noexcept {
158 return start_time_;
159 }
160
161private:
162 TimePoint start_time_{Clock::now()};
163};
164
165template <details::ClockTrait Clock>
166template <details::DurationTrait Units>
167constexpr Units Timer<Clock>::ElapsedDuration() const {
168 const auto now = Clock::now();
169 const auto diff = now - start_time_;
170 return std::chrono::duration_cast<Units>(diff);
171}
172
173template <details::ClockTrait Clock>
174template <utils::ArithmeticTrait Type, details::DurationTrait Units>
175constexpr Type Timer<Clock>::Elapsed() const {
176 const auto duration = ElapsedDuration<Units>();
177 return static_cast<Type>(duration.count());
178}
179
180} // namespace helios::utils
constexpr int64_t ElapsedNanoSec() const
Elapsed time in nanoseconds as 64-bit integer.
Definition timer.hpp:149
constexpr double ElapsedSec() const
Elapsed time in seconds as double.
Definition timer.hpp:125
constexpr void Reset() noexcept(noexcept(Clock::now()))
Reset the timer start point to current time.
Definition timer.hpp:91
constexpr int64_t ElapsedMicroSec() const
Elapsed time in microseconds as 64-bit integer.
Definition timer.hpp:141
constexpr Timer() noexcept(noexcept(Clock::now()))=default
Constructs timer and immediately resets start timestamp.
constexpr double ElapsedMilliSec() const
Elapsed time in milliseconds as double.
Definition timer.hpp:133
constexpr Units ElapsedDuration() const
Get elapsed time as a std::chrono::duration.
Definition timer.hpp:167
constexpr Type Elapsed() const
Get elapsed time converted to an arithmetic value with specified units.
Definition timer.hpp:175
typename Clock::time_point TimePoint
Definition timer.hpp:70
typename Clock::duration Duration
Definition timer.hpp:71
constexpr TimePoint Start() const noexcept
Get the raw start timestamp of the timer.
Definition timer.hpp:157
Concept for arithmetic types (integral or floating-point).
Concept for clock types compatible with std::chrono clocks.
Definition timer.hpp:21
Concept for duration types based on std::chrono::duration.
Definition timer.hpp:33
std::chrono::duration< Rep, Period > NormalizedDuration
Helper alias to normalize a duration to its canonical std::chrono::duration form.
Definition timer.hpp:41
std::chrono::duration< Rep, Period > NormalizedClockDuration
Helper alias to normalize a clock's duration to a specific rep/period.
Definition timer.hpp:47
STL namespace.