drop progress.hpp into your project.
#include "progress.hpp"
// basic bar
progress::Bar bar(total, "training");
for (auto& batch : batches) {
train(batch);
bar.update();
}
bar.finish();output:
training [===================> ] 72% 1243.5/s eta 00:03
live suffix stats:
update the suffix mid-loop to show per-step metrics (thread-safe):
progress::Bar bar(epochs, "training");
for (int e = 0; e < epochs; e++) {
float loss = train_epoch(e);
bar.set_suffix("loss=" + std::to_string(loss));
bar.update();
}
bar.finish();output:
training [===================> ] 72% 1243.5/s eta 00:03 loss=0.234
spinner for when you don't know the total:
progress::Spinner s("loading dataset...");
s.start();
load_data();
s.stop("done");multiple bars at once:
progress::MultiBar mb;
auto& download = mb.add(1000, "download");
auto& extract = mb.add(500, "extract");
mb.start();
std::thread t1([&]{ for (int i=0; i<1000; i++) { do_work(); download.update(); } });
std::thread t2([&]{ for (int i=0; i<500; i++) { do_work(); extract.update(); } });
t1.join(); t2.join();
mb.stop();output:
download [===================> ] 72% 1243.5/s eta 00:03
extract [===========> ] 44% 980.1/s eta 00:02
range-based iteration:
wrap any container with progress::Range to track progress in a range-for loop:
std::vector<Image> images = load_images();
for (auto& img : progress::Range(images, "processing")) {
process(img);
}for numeric loops use progress::irange:
for (size_t i : progress::irange(1000, "training")) {
train_step(i);
}colored bars:
#include "progress.hpp"
progress::Bar bar(total, "training");
bar.bar_color = progress::color::green; // green fill
bar.update(50);
bar.finish();
// available: color::green, yellow, red, blue, cyan, magentaBar options:
bar.width = 40; // bar width in chars
bar.show_eta = true;
bar.show_rate = true;
bar.bar_color = progress::color::cyan;
bar.min_interval_ms = 50; // re-render at most every N ms
bar.set_suffix("key=val"); // live suffix text, thread-safeLicense: MIT