-
Notifications
You must be signed in to change notification settings - Fork 18
/
Copy pathstopwatch.hpp
109 lines (89 loc) · 2.43 KB
/
stopwatch.hpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
/*
The Capo Library
Code covered by the MIT License
Author: mutouyun (http://orzz.org)
*/
#pragma once
#include <chrono> // std::chrono
#include <array> // std::array
#include <utility> // std::pair, std::declval
#include <cstddef> // size_t
namespace capo {
////////////////////////////////////////////////////////////////
/// Stopwatch - can store multiple sets of time
////////////////////////////////////////////////////////////////
template <size_t CountN = 1, class ClockT = std::chrono::steady_clock>
class stopwatch : public ClockT
{
using base_t = ClockT;
static_assert(CountN > 0, "The count must be greater than 0");
public:
using rep = typename ClockT::rep;
using period = typename ClockT::period;
using duration = typename ClockT::duration;
using time_point = typename ClockT::time_point;
private:
using pair_t = std::pair<time_point/*start*/, time_point/*paused*/>;
std::array<pair_t, CountN> points_;
bool is_stopped_ = true;
public:
stopwatch(bool start_watch = false)
{
if (start_watch) start();
}
public:
bool is_stopped(void) const
{
return is_stopped_;
}
template <size_t N = 0>
bool is_paused(void) const
{
return (points_[N].second != points_[N].first);
}
template <size_t N = 0>
duration elapsed(void)
{
if (is_stopped())
return duration::zero();
else
if (is_paused<N>())
return (points_[N].second - points_[N].first);
else
return ClockT::now() - points_[N].first;
}
template <typename ToDur, size_t N = 0>
auto elapsed(void) -> decltype(std::declval<ToDur>().count())
{
return std::chrono::duration_cast<ToDur>(elapsed<N>()).count();
}
template <size_t N = 0>
void pause(void)
{
points_[N].second = ClockT::now();
}
template <size_t N = 0>
void restart(void)
{
points_[N].second = points_[N].first =
ClockT::now() - (points_[N].second - points_[N].first);
}
void start(void)
{
time_point now = ClockT::now();
for (auto& pt : points_)
{
pt.second = pt.first = now - (pt.second - pt.first);
}
is_stopped_ = false;
}
void stop(void)
{
for (auto& pt : points_)
{
pt.second = pt.first;
}
is_stopped_ = true;
}
};
} // namespace capo