90 std::atomic<int> m_progress{0};
92 std::atomic<int> m_last_fill{-1};
94 static constexpr std::size_t bar_width = (Length >= 7) ? (Length - 7) : 1;
112 const int progress = m_progress.load();
113 if (progress > m_max)
115 const bool is_final = (progress == m_max);
118 const int current = int(bar_width *
double(progress) /
double(m_max));
119 if (!is_final && current <= m_last_fill.load(std::memory_order_relaxed))
122 print_prog_bar(progress);
129 void print_prog_bar(
int progress) {
130 const bool is_tty = isatty(fileno(stdout));
132 print_prog_bar_notty(progress);
136 const bool is_final = (progress == m_max);
139 const auto current = int(bar_width *
double(progress) /
double(m_max));
140 char buf[Length + 2];
143 for (
int j = 0; j < current; ++j)
145 for (
int j = current; j < (int)bar_width; ++j)
149 p += snprintf(p,
sizeof(buf) - std::size_t(p - buf) - 2,
"%d%%",
150 int(100.0 *
double(progress) /
double(m_max)));
151 *p++ = is_final ?
'\n' :
'\r';
160 m_last_fill.store(current, std::memory_order_relaxed);
166 void print_prog_bar_notty(
int progress) {
167 const bool is_initial = (progress == 0);
168 const bool is_final = (progress == m_max);
171 is_final ? 100 : int(100.0 *
double(progress) /
double(m_max));
174 static constexpr int n_entries =
static_cast<int>(Length) / 5;
175 static constexpr int interval =
176 (n_entries > 1) ? (100 / (n_entries - 1)) : 100;
177 const int slot = pct / interval;
179 if (!is_initial && !is_final &&
180 slot <= m_last_fill.load(std::memory_order_relaxed))
185 snprintf(buf,
sizeof(buf),
"100%%\n");
187 snprintf(buf,
sizeof(buf),
"%d%%, ", pct);
195 m_last_fill.store(slot, std::memory_order_relaxed);
ProgressBar(int max, bool print)
Construct progress bar for max iterations.
Definition Widgets.hpp:102
void progbar(int i, int max, int length=50)
Basic progress bar. Prints new line if (and only if) i==(max-1)
Definition Widgets.hpp:17
T max(T first, Args... rest)
Returns the maximum of any number of parameters (variadic).
Definition Maths.hpp:28