Created
April 14, 2017 05:25
-
-
Save bshillingford/aec0ccb65db6228a6ddd40aa06193cf3 to your computer and use it in GitHub Desktop.
really simple C++ single-header progress bar class
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <iostream> | |
#include <chrono> | |
#include <ratio> | |
class progbar { | |
private: | |
int call_count = 0; | |
// formatting: | |
std::ostream& out; | |
int width; | |
char fill; | |
char space; | |
// timing: | |
using clock = std::chrono::steady_clock; // low-precision but monotone | |
bool show_time; | |
clock::time_point start_time; | |
inline void write_time(std::ostream& out, std::chrono::duration<float> dur) { | |
using namespace std::chrono_literals; | |
using namespace std::chrono; | |
using std::ratio; | |
using std::milli; | |
// save/restore stream's precision setting | |
auto old_prec = out.precision(); | |
out.precision(3); | |
if (dur > 1h) { | |
out << duration<float, ratio<3600>>(dur).count() << "h"; | |
} else if (dur > 1min) { | |
out << duration<float, ratio<60>>(dur).count() << "m"; | |
} else if (dur > 1s) { | |
out << duration<float>(dur).count() << "s"; | |
} else { | |
out << duration<float, milli>(dur).count() << "ms"; | |
} | |
out.precision(old_prec); | |
} | |
public: | |
progbar(std::ostream& out_, int width_=40, char fill_='#', char space_='.', bool show_time_=true) | |
: out(out_), width(width_), fill(fill_), space(space_), show_time(show_time_) {} | |
void update(uint64_t cur, uint64_t tot) { | |
// up one line, clear current line, and beginning of line (CR) | |
out << "\033[A\033[2K\r"; | |
// output bar: | |
int fills = (int)((float)cur / tot * width); | |
out << '['; | |
for (int i = 0; i < width; i++) { | |
out << (i < fills ? fill : space); | |
} | |
out << "] " << cur << '/' << tot; | |
// time estimate | |
if (show_time) { | |
if (call_count == 0) { | |
start_time = clock::now(); | |
} else if (cur > 0 && cur < tot) { | |
// if not first call, output time estimate for remaining time | |
out << ' '; | |
auto elapsed = (clock::now() - start_time); | |
auto estimate = elapsed / cur * (tot - cur); | |
write_time(out, estimate); | |
out << " remaining; "; | |
write_time(out, elapsed); | |
out << " elapsed."; | |
} else { | |
out << " done"; | |
} | |
} | |
out << std::endl; | |
call_count++; | |
} | |
}; // class progbar |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include "progbar.h" | |
#include <unistd.h> | |
int main() { | |
const int tot = 8; | |
progbar bar(std::cerr, 36, '=', ' '); | |
for(int i = 0; i < tot; i++) { | |
bar.update(i, tot); | |
usleep(712345); | |
} | |
} | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment