I'm making a timer class in C++. This is the overview:
#include <chrono>
namespace ktp {
class Timer {
using Clock = std::chrono::high_resolution_clock;
using TimePoint = std::chrono::high_resolution_clock::time_point;
public:
Timer(bool start = false) {
if (start) Timer::start();
}
void pause() {
if (m_started && !m_paused) {
m_paused_time = now();
m_paused = true;
}
}
auto restart() {
const auto time {milliseconds()};
stop();
start();
return time;
}
void resume() {
if (m_started && m_paused) {
// we substract the total duration of the pause
m_started_time = now() - (m_paused_time - m_started_time);
m_paused = false;
}
}
void start() {
m_started_time = now();
m_paused_time = {};
m_started = true;
m_stoped = false;
m_paused = false;
}
void stop() {
m_started = false;
m_paused = false;
m_stoped = true;
m_started_time = {};
m_paused_time = {};
}
// THIS BELOW IS WHAT I DON'T LIKE
const std::chrono::milliseconds milliseconds() const {
if (m_started) {
if (m_paused) {
return std::chrono::duration_cast<std::chrono::milliseconds>(m_paused_time - m_started_time);
} else { // started and running
return std::chrono::duration_cast<std::chrono::milliseconds>(now() - m_started_time);
}
}
return std::chrono::milliseconds {};
}
const std::chrono::seconds seconds() const {
// same as milliseconds but with seconds
}
// more of the same for nanoseconds, minutes, etc...
private:
static const TimePoint now() { return Clock::now(); }
static inline const TimePoint s_initialization_time {now()};
TimePoint m_paused_time {};
TimePoint m_started_time {};
bool m_paused {false};
bool m_started {false};
bool m_stoped {false};
};
} // end namespace ktp
As you can see, I've to write a bunch of functions that are the same, it justs changes the type. So I decided to make a private template like this:
template<typename T>
const T duration(T) const {
if (m_started) {
if (m_paused) {
return std::chrono::duration_cast<T>(m_paused_time - m_started_time);
} else { // started and running
return std::chrono::duration_cast<T>(now() - m_started_time);
}
}
return T {};
}
Which changes the milliseconds()
and the other time returning functions to this:
const std::chrono::milliseconds milliseconds() const {
return duration(std::chrono::milliseconds {}); // this object
}
But I feel that creating an object and passing it as an argument just to know it's type maybe is not the best option. The code works, but I'm wondering if anyone knows a better solution.