SolidUtils
Timer.hpp
Go to the documentation of this file.
1 
31 #ifndef SOLIDUTILS_INCLUDE_TIMER_HPP
32 #define SOLIDUTILS_INCLUDE_TIMER_HPP
33 
34 
35 #include <chrono>
36 #include <memory>
37 #include <stdexcept>
38 
39 
40 namespace sl
41 {
42 
78 class Timer
79 {
80  public:
88  static double now()
89  {
90  std::chrono::high_resolution_clock::time_point time =
91  std::chrono::high_resolution_clock::now();
92  size_t const ticks = \
93  static_cast<size_t>(time.time_since_epoch().count());
94  double constexpr SECONDS_PER_TICK = \
95  static_cast<double>(std::chrono::system_clock::period::num) / \
96  static_cast<double>(std::chrono::system_clock::period::den);
97  double const seconds = ticks * SECONDS_PER_TICK;
98  return seconds;
99  }
100 
106  class Scope
107  {
108  public:
115  Timer * const parent) :
116  m_parent(parent),
117  m_start(now())
118  {
119  // do nothing
120  }
121 
128  Scope&& scope) :
129  m_parent(scope.m_parent),
130  m_start(scope.m_start)
131  {
132  scope.m_parent = nullptr;
133  scope.m_start = 0;
134  }
135 
141  Scope(
142  Scope const & other) = delete;
143 
151  Scope& operator=(
152  Scope const & other) = delete;
153 
158  {
159  double const stop = now();
160 
161  if (m_parent != nullptr) {
162  m_parent->add(stop - m_start);
163  }
164  }
165 
166  private:
167  Timer * m_parent;
168  double m_start;
169  };
170 
174  Timer() :
175  m_duration(0),
176  m_scope(nullptr)
177  {
178  // do nothing
179  }
180 
188  {
189  if (m_scope.get() != nullptr) {
190  throw std::runtime_error(
191  "Cannot start scope for already running timer.");
192  }
193 
194  return Scope(this);
195  }
196 
200  void start()
201  {
202  if (m_scope.get() != nullptr) {
203  throw std::runtime_error("Cannot start already running timer.");
204  }
205 
206  m_scope.reset(new Scope(this));
207  }
208 
212  void stop()
213  {
214  if (m_scope.get() == nullptr) {
215  throw std::runtime_error("Cannot stop non-running timer.");
216  }
217 
218  // destroy scope (adding durationg).
219  m_scope.reset(nullptr);
220  }
221 
227  double poll() const
228  {
229  if (m_scope.get() != nullptr) {
230  throw std::runtime_error("Cannot poll running timer.");
231  }
232 
233  return m_duration;
234  }
235 
241  void add(
242  double duration)
243  {
244  m_duration += duration;
245  }
246 
247  private:
248  double m_duration;
249  std::unique_ptr<Scope> m_scope;
250 };
251 
252 }
253 
254 #endif
This class is used to perform wall timings of varius tasks. It provides means to meanually start and ...
Definition: Timer.hpp:78
Scope(Scope &&scope)
Move once Scope to this Scope.
Definition: Timer.hpp:127
This class provides a means of timing a scoped region. It begins timing when it is created...
Definition: Timer.hpp:106
Definition: Alloc.hpp:40
Scope & operator=(Scope const &other)=delete
Deleted assignment operator.
Scope(Timer *const parent)
Create a new Scope from the given timer.
Definition: Timer.hpp:114
Scope scope()
Start a new timed scope. The duration from when the Scope object is created.
Definition: Timer.hpp:187
static double now()
Get a double representing the current time in seconds. This is an arbitrary value by itself...
Definition: Timer.hpp:88
double poll() const
Get the elapsed number of seconds on the timer.
Definition: Timer.hpp:227
~Scope()
Destroy this timer Scope.
Definition: Timer.hpp:157
Timer()
Creat a new timer.
Definition: Timer.hpp:174
void stop()
Stop the timer.
Definition: Timer.hpp:212
void add(double duration)
Add some amount of time to the timer.
Definition: Timer.hpp:241
void start()
Start or continue the timer.
Definition: Timer.hpp:200