#pragma once
#include <config.h>
#include <vector>
#include <chrono>
#include <numeric>
template < typename TimeT = std::chrono::milliseconds, typename ClockT =
#if defined(_MSC_VER) && _MSC_VER == 1800
std::chrono::system_clock
#else
std::chrono::steady_clock
#endif
>
class StopWatch {
public:
StopWatch(const bool calibrate = false) : myTimingCost(0) {
if (calibrate) {
myStart = ClockT::now();
for (int i = 0; i < 1000; i++) {
myEnd = ClockT::now();
}
myTimingCost = std::chrono::duration_cast<TimeT>(myEnd - myStart) / 1000;
}
start();
}
void start() {
myStart = myEnd = ClockT::now();
}
long long int stop() {
myEnd = ClockT::now();
return elapsed();
}
long long int elapsed() const {
const TimeT& delta = std::chrono::duration_cast<TimeT>(myEnd - myStart) - (2 * myTimingCost);
myHistory.push_back(delta);
return (long long int)delta.count();
}
void add(const StopWatch<TimeT, ClockT>& other) {
myHistory.insert(myHistory.end(), other.myHistory.begin(), other.myHistory.end());
}
const std::vector<TimeT>& getHistory() const {
return myHistory;
}
long long int getAverage() const {
return (long long int)(std::accumulate(myHistory.begin(), myHistory.end(), TimeT{}) / myHistory.size()).count();
}
long long int getTotal() const {
return (long long int)(std::accumulate(myHistory.begin(), myHistory.end(), TimeT{})).count();
}
private:
std::chrono::time_point<ClockT> myStart;
std::chrono::time_point<ClockT> myEnd;
TimeT myTimingCost;
mutable std::vector<TimeT> myHistory;
};