Skip to content

Instantly share code, notes, and snippets.

@ibab
Last active August 29, 2015 14:01
Show Gist options
  • Save ibab/696fb0dbe428196c5c2f to your computer and use it in GitHub Desktop.
Save ibab/696fb0dbe428196c5c2f to your computer and use it in GitHub Desktop.
A convenient iterator that prints a progress bar to the terminal.
#ifndef PROGRESS_H
#define PROGRESS_H
#include <iostream>
template <class T>
class Progress {
public:
class ProgressIterator {
public:
Progress<T> _owner;
T _current;
ProgressIterator(T current, Progress& owner)
: _current(current),
_owner(owner)
{
}
void operator++()
{
_current += _owner._step;
if (_current + _owner._step >= _owner._end) {
_current = _owner._end;
}
int percent = static_cast<int>(100 * (_current - _owner._start) / (_owner._end - _owner._start));
std::string bar;
for(int i = 0; i < 50; i++){
if (i < (percent / 2)) {
bar.replace(i, 1, "=");
} else if( i == (percent / 2)){
bar.replace(i, 1, ">");
} else{
bar.replace(i, 1, " ");
}
}
// Hide cursor
std::cout << "\e[?25l";
std::cout << "\r" "[" << bar << "] ";
std::cout.width(3);
std::cout << percent << "% " << std::flush;
if (_current == _owner._end) {
std::cout << std::endl;
// Show cursor
std::cout << "\e[?25h";
}
}
bool operator!=(const ProgressIterator& other) const {
return !(_current == other._current);
}
T operator*() {
return _current;
}
};
Progress(T start, T end, T step)
: _start(start),
_end(end),
_step(step)
{
}
Progress(T start, T end)
: _start(start),
_end(end),
_step(1)
{
}
ProgressIterator begin() {
return Progress<T>::ProgressIterator(_start, *this);
}
ProgressIterator end() {
return Progress<T>::ProgressIterator(_end, *this);
}
private:
T _start;
T _end;
T _step;
};
#endif /* end of include guard: PROGRESS_H */
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment