The Battle for Wesnoth  1.19.5+dev
optimer.hpp
Go to the documentation of this file.
1 /*
2  Copyright (C) 2020 - 2024
3  by Iris Morelle <shadowm2006@gmail.com>
4  Part of the Battle for Wesnoth Project https://www.wesnoth.org/
5 
6  This program is free software; you can redistribute it and/or modify
7  it under the terms of the GNU General Public License as published by
8  the Free Software Foundation; either version 2 of the License, or
9  (at your option) any later version.
10  This program is distributed in the hope that it will be useful,
11  but WITHOUT ANY WARRANTY.
12 
13  See the COPYING file for more details.
14 */
15 
16 #pragma once
17 
18 #include <chrono>
19 #include <functional>
20 #include <iosfwd>
21 #include <utility>
22 
23 namespace utils {
24 
25 /**
26  * Reports time elapsed at the end of an object scope.
27  *
28  * The constructor accepts a callable that takes the optimer as its only
29  * argument, which can then be used to write the elapsed time to a stream,
30  * variable, or anything else that's desirable for a particular use case.
31  *
32  * @tparam ResolutionType Clock resolution -- milliseconds, microseconds, etc.
33  * @tparam ClockType Clock type -- a monotonic clock by default.
34  */
35 template<typename ResolutionType, typename ClockType = std::chrono::steady_clock>
36 struct optimer
37 {
38  using clock = ClockType;
39  using resolution = ResolutionType;
40  using point = typename clock::time_point;
41  using interval = typename clock::duration;
42  using report_callback = std::function<void(const optimer&)>;
43 
44  /**
45  * Constructor, which starts the timer.
46  *
47  * The report callback may be an empty object, in which case the destructor
48  * will not do anything. This may be useful in order to obtain and keep
49  * track of elapsed time manually for other purposes than console printing.
50  */
52  : start_()
53  , repf_(f)
54  {
55  reset();
56  }
57 
58  /**
59  * Destructor, which invokes the report callback.
60  */
62  {
63  if(repf_) {
64  repf_(*this);
65  }
66  }
67 
68  /** Resets the timer back to zero and returns the previous tick value. */
70  {
71  return std::exchange(start_, clock::now());
72  }
73 
74  /** Returns the start time point. */
75  point start() const
76  {
77  return start_;
78  }
79 
80  /** Returns the elapsed time value. */
81  interval elapsed() const
82  {
83  return clock::now() - start_;
84  }
85 
86  /**
87  * Resets the starting tick and returns the elapsed time.
88  *
89  * @note This method is preferred to calling elapsed() followed by reset()
90  * since it guarantees resetting to the same tick as is used for duration
91  * (or, in other words, clock::now() is called only once.)
92  */
94  {
95  auto prev_start = reset();
96  return start_ - prev_start;
97  }
98 
99 private:
102 };
103 
104 /**
105  * Formats time elapsed for writing to a stream.
106  *
107  * @note The resulting output does <b>not</b> include a time unit suffix.
108  */
109 template<typename... OpTimerArgs>
110 inline std::ostream& operator<<(std::ostream& o, const optimer<OpTimerArgs...>& tm)
111 {
112  o << std::chrono::duration_cast<typename optimer<OpTimerArgs...>::resolution>(tm.elapsed()).count();
113  return o;
114 }
115 
116 /**
117  * Time elapsed with millisecond resolution.
118  */
120 
121 } // end namespace utils
std::ostream & operator<<(std::ostream &s, const irdya_date &d)
Holds a 2D point.
Definition: point.hpp:25
Reports time elapsed at the end of an object scope.
Definition: optimer.hpp:37
~optimer()
Destructor, which invokes the report callback.
Definition: optimer.hpp:61
interval lap()
Resets the starting tick and returns the elapsed time.
Definition: optimer.hpp:93
optimer(report_callback f=report_callback{})
Constructor, which starts the timer.
Definition: optimer.hpp:51
std::function< void(const optimer &)> report_callback
Definition: optimer.hpp:42
report_callback repf_
Definition: optimer.hpp:101
point start() const
Returns the start time point.
Definition: optimer.hpp:75
typename clock::duration interval
Definition: optimer.hpp:41
ClockType clock
Definition: optimer.hpp:38
point reset()
Resets the timer back to zero and returns the previous tick value.
Definition: optimer.hpp:69
ResolutionType resolution
Definition: optimer.hpp:39
interval elapsed() const
Returns the elapsed time value.
Definition: optimer.hpp:81
#define f