LArSoft  v09_90_00
Liquid Argon Software toolkit - https://larsoft.org/
StopWatch.h
Go to the documentation of this file.
1 
12 #ifndef LARCORE_TESTUTILS_STOPWATCH_H
13 #define LARCORE_TESTUTILS_STOPWATCH_H
14 
15 // C/C++ standard libraries
16 #include <chrono>
17 #include <cstdint> // std::intmax_t
18 #include <ratio>
19 #include <type_traits> // std::true_type, std::false_type
20 
21 namespace testing {
22  namespace details {
24  template <typename Duration>
25  struct isDuration;
26  } // namespace details
27 
73  template <typename DefaultUnit = std::chrono::duration<double>, // seconds (ratio<1>)
74  typename Clock = std::chrono::high_resolution_clock>
75  class StopWatch {
77  "DefaultUnit type is not a std::chrono::duration specialization");
78 
79  public:
80  using Clock_t = Clock;
81  using DefaultUnit_t = DefaultUnit;
82 
84  using ElapsedTime_t = typename DefaultUnit_t::rep;
85 
90  StopWatch(bool start = true);
91 
97  template <typename Unit>
98  StopWatch(Unit prev, bool start = true);
99 
102 
104  void restart();
105 
107  void resume();
108 
110  void stop();
111 
113  template <typename Unit = DefaultUnit_t>
114  void setPrevious(Unit dur);
115 
117 
120 
122  template <typename Unit = DefaultUnit_t>
123  ElapsedTime_t elapsed() const;
124 
126  template <typename Unit = DefaultUnit_t>
127  ElapsedTime_t partial() const;
128 
130  template <typename Unit = DefaultUnit_t>
131  ElapsedTime_t previous() const;
132 
134  bool running() const;
135 
137 
138  protected:
139  using TimePoint_t = decltype(Clock_t::now());
140 
143  bool isRunning;
144 
146  static TimePoint_t now();
147 
149  DefaultUnit_t partialDur() const;
150 
152  template <typename>
154 
156  template <typename Unit>
158 
160  template <typename Unit, typename From>
161  static auto durationTo(From const& dur);
162 
163  }; // class StopWatch
164 
167 
168 } // namespace testing
169 
170 //------------------------------------------------------------------------------
171 namespace testing {
172  namespace details {
173  template <typename Duration>
174  struct isDuration : public std::false_type {};
175 
176  template <typename Rep, typename Period>
177  struct isDuration<std::chrono::duration<Rep, Period>> : public std::true_type {};
178 
179  } // namespace details
180 } // namespace testing
181 
182 //------------------------------------------------------------------------------
183 //--- StopWatch implementartion
184 //---
185 //------------------------------------------------------------------------------
186 template <typename DefaultUnit, typename Clock>
188  : lastStart{start ? now() : TimePoint_t{}}, previousTime{}, isRunning{start}
189 {}
190 
191 template <typename DefaultUnit, typename Clock>
192 template <typename Unit>
193 testing::StopWatch<DefaultUnit, Clock>::StopWatch(Unit prev, bool start /* = true */)
194  : StopWatch(start)
195 {
196  previousTime = prev;
197 }
198 
199 //------------------------------------------------------------------------------
200 template <typename DefaultUnit, typename Clock>
202 {
203  lastStart = now();
204  isRunning = true;
206 } // testing::StopWatch<>::restart()
207 
208 //------------------------------------------------------------------------------
209 template <typename DefaultUnit, typename Clock>
211 {
212  if (running()) return;
213  lastStart = now();
214  isRunning = true;
215 } // testing::StopWatch<>::resume()
216 
217 //------------------------------------------------------------------------------
218 template <typename DefaultUnit, typename Clock>
220 {
222  isRunning = false;
223 } // testing::StopWatch<>::stop()
224 
225 //------------------------------------------------------------------------------
226 template <typename DefaultUnit, typename Clock>
227 template <typename Unit>
229 {
230  previousTime = std::chrono::duration_cast<DefaultUnit_t>(dur);
231 } // testing::StopWatch<>::setPrevious()
232 
233 //------------------------------------------------------------------------------
234 template <typename DefaultUnit, typename Clock>
235 template <typename Unit>
238 {
239  auto const prev = previous<Unit>();
240  return running() ? (prev + partial<Unit>()) : prev;
241 } // testing::StopWatch<>::elapsed()
242 
243 //------------------------------------------------------------------------------
244 template <typename DefaultUnit, typename Clock>
245 template <typename Unit>
248 {
249  return running() ? durationTo<Unit>(partialDur()).count() : ElapsedTime_t(0);
250 } // testing::StopWatch<>::partial()
251 
252 //------------------------------------------------------------------------------
253 template <typename DefaultUnit, typename Clock>
254 template <typename Unit>
257 {
258  return durationTo<Unit>(previousTime).count();
259 } // testing::StopWatch<>::previous()
260 
261 //------------------------------------------------------------------------------
262 template <typename DefaultUnit, typename Clock>
264 {
265  return isRunning;
266 }
267 
268 //------------------------------------------------------------------------------
269 template <typename DefaultUnit, typename Clock>
272 {
273  return Clock_t::now();
274 }
275 
276 //------------------------------------------------------------------------------
277 template <typename DefaultUnit, typename Clock>
280 {
281  return std::chrono::duration_cast<DefaultUnit_t>(now() - lastStart);
282 } // testing::StopWatch<>::setPrevious()
283 
284 //------------------------------------------------------------------------------
285 // Specialisation: on std::chrono::duration (type is that very same)
286 namespace testing {
287  template <typename DefaultUnit, typename Clock>
288  template <typename Rep, typename Duration>
289  struct StopWatch<DefaultUnit, Clock>::makeDurationTrait<std::chrono::duration<Rep, Duration>> {
290  using type = std::chrono::duration<Rep, Duration>;
291  }; // StopWatch<>::makeDurationTrait<duration>
292 
293  // Specialisation: on std::ratio (type is a duration based on that ratio)
294  template <typename DefaultUnit, typename Clock>
295  template <std::intmax_t Num, std::intmax_t Den>
296  struct StopWatch<DefaultUnit, Clock>::makeDurationTrait<std::ratio<Num, Den>> {
297  using type = std::chrono::duration<typename StopWatch<DefaultUnit, Clock>::ElapsedTime_t,
298  std::ratio<Num, Den>>;
299  }; // struct makeDurationTrait<duration>
300 
301 } // namespace testing
302 
303 //------------------------------------------------------------------------------
304 template <typename DefaultUnit, typename Clock>
305 template <typename Unit, typename From>
307 {
308  return std::chrono::duration_cast<makeDuration_t<Unit>>(dur);
309 }
310 
311 //------------------------------------------------------------------------------
312 
313 #endif // LARCORE_TESTUTILS_STOPWATCH_H
bool running() const
Returns whether the watch is tracking time right now.
Definition: StopWatch.h:263
DefaultUnit DefaultUnit_t
default unit for time report
Definition: StopWatch.h:81
decltype(Clock_t::now()) TimePoint_t
type to store start time
Definition: StopWatch.h:139
LArSoft test utilities.
Type trait containing whether Duration is std::chrono::duration.
Definition: StopWatch.h:25
StopWatch(bool start=true)
Initializes and starts the timer.
Definition: StopWatch.h:187
static auto durationTo(From const &dur)
Convert a duration into a unit (may be a ratio or a duration)
Definition: StopWatch.h:306
TimePoint_t lastStart
time of the last start
Definition: StopWatch.h:141
DefaultUnit_t partialDur() const
Returns partial time as a duration.
Definition: StopWatch.h:279
typename DefaultUnit_t::rep ElapsedTime_t
Type representing the reported time.
Definition: StopWatch.h:84
void stop()
Pauses the watch.
Definition: StopWatch.h:219
STL namespace.
void restart()
Restarts the watch; previous time is forgotten.
Definition: StopWatch.h:201
void setPrevious(Unit dur)
Changes the amount of time accumulated before this run.
Definition: StopWatch.h:228
Clock Clock_t
type of clock used to extract current time
Definition: StopWatch.h:80
Provides time interval measurements.
Definition: StopWatch.h:75
bool isRunning
whether we are measuring time now
Definition: StopWatch.h:143
ElapsedTime_t previous() const
Returns the time accumulated before the current run.
ElapsedTime_t partial() const
Returns the time spent running since the last resume.
void resume()
Resumes the run of the watch; previous time is preserved.
Definition: StopWatch.h:210
DefaultUnit_t previousTime
time accumulated from previous runs
Definition: StopWatch.h:142
Trait whose type member is a std::chrono::duration type.
Definition: StopWatch.h:153
typename makeDurationTrait< Unit >::type makeDuration_t
Type of std::chrono::duration type constructed from makeDurationTrait.
Definition: StopWatch.h:157
static TimePoint_t now()
Returns the current time point from our clock.
Definition: StopWatch.h:271
ElapsedTime_t elapsed() const
Returns the total time spent running since the last restart.