#ifndef LLVM_TOOLS_LLVM_EXEGESIS_PROGRESSMETER_H
#define LLVM_TOOLS_LLVM_EXEGESIS_PROGRESSMETER_H
#include "llvm/Support/Format.h"
#include "llvm/Support/raw_ostream.h"
#include <cassert>
#include <chrono>
#include <cmath>
#include <optional>
#include <type_traits>
namespace llvm {
namespace exegesis {
template <typename NumTy, typename DenTy = int> class SimpleMovingAverage { … };
template <typename ClockTypeTy = std::chrono::steady_clock,
typename = std::enable_if_t<ClockTypeTy::is_steady>>
class ProgressMeter {
public:
using ClockType = ClockTypeTy;
using TimePointType = std::chrono::time_point<ClockType>;
using DurationType = std::chrono::duration<typename ClockType::rep,
typename ClockType::period>;
using CompetionPercentage = int;
using Sec = std::chrono::duration<double, std::chrono::seconds::period>;
private:
raw_ostream &Out;
const int NumStepsTotal;
SimpleMovingAverage<DurationType> ElapsedTotal;
public:
friend class ProgressMeterStep;
class ProgressMeterStep {
ProgressMeter *P;
const TimePointType Begin;
public:
inline ProgressMeterStep(ProgressMeter *P_)
: P(P_), Begin(P ? ProgressMeter<ClockType>::ClockType::now()
: TimePointType()) {}
inline ~ProgressMeterStep() {
if (!P)
return;
const TimePointType End = ProgressMeter<ClockType>::ClockType::now();
P->step(End - Begin);
}
ProgressMeterStep(const ProgressMeterStep &) = delete;
ProgressMeterStep(ProgressMeterStep &&) = delete;
ProgressMeterStep &operator=(const ProgressMeterStep &) = delete;
ProgressMeterStep &operator=(ProgressMeterStep &&) = delete;
};
ProgressMeter(int NumStepsTotal_, raw_ostream &out_ = errs())
: … { … }
ProgressMeter(const ProgressMeter &) = delete;
ProgressMeter(ProgressMeter &&) = delete;
ProgressMeter &operator=(const ProgressMeter &) = delete;
ProgressMeter &operator=(ProgressMeter &&) = delete;
private:
void step(DurationType Elapsed) { … }
inline std::pair<CompetionPercentage, std::optional<Sec>> eta() const { … }
};
}
}
#endif