tqdm++ is a C++ range/view interface for displaying a progress bar in the
terminal. It is a rudimentary equivalent to the Python
tqdm library. Wrap a range or view in Tqdm()
and it will display a progress bar in the terminal:
#include <tqdm/tqdm.h>
using tqdm::Tqdm;
for (auto&& i : Tqdm(std::views::iota(0, 10000))) {
std::this_thread::sleep_for(std::chrono::milliseconds(10));
} 17%│███▍ │ 1730/10000 [00:17<01:24 98.38it/s]
tqdm::Range(N) can be used as a shortcut for the iota above to achieve a timed
integer iteration.
Note
This port does not have quite a lot of the functionality of the Python library. This is intentional. It is meant to be lighter weight and to support the majority of use cases (and all of my personal uses).
tqdm++ is a header-only library requiring C++23 or newer. To add it to a CMake project:
FetchContent_Declare(
tqdmpp
GIT_REPOSITORY https://github.com/sophec/tqdmpp.git
GIT_TAG main
)
FetchContent_MakeAvailable(tqdmpp)
target_link_libraries(mytarget PRIVATE tqdmpp)The primary interface for the project is the tqdm::Tqdm class. This will wrap
any (ish) range/view and display a progress bar:
#include <tqdm/tqdm.h>
using tqdm::Tqdm;
for (auto&& item : Tqdm(my_range)) {
// ...
}Additionally, the helper function tqdm::Range() allows you to easily replace
a classic for (int i{}; i < N; ++i) loop like so:
// iterates 0..99
for (std::size_t i : tqdm::Range(100)) {}
// iterates 10..109
for (std::size_t i : tqdm::Range(10, 100)) {}If the range's bound is not known (i.e., not std::ranges::sized_range<R>),
the progress bar is not shown. Instead, a running count, elapsed time, and items
per second will be shown.
As a shorthand for an iteration counter with unknown upper bound, the
tqdm::Iota() function is provided:
// iterates forever, starting from 0
for (std::size_t i : tqdm::Iota()) {
if (some_condition) {
break;
}
}
// iterates forever, starting from 10
for (std::size_t i : tqdm::Iota(10)) {
if (some_condition) {
break;
}
}The constructor for the Tqdm class and the Range/Iota helper overloads
accept an optional last argument of type tqdm::Config. This lets you configure
some of the behavior of the progress bar. For example:
for (auto&& item : Tqdm(my_range, {
.prefix = "doing stuff: ",
.unit = "files",
.segments = 30,
.term_progress = true,
})) {
// ...
}
for (auto&& i : tqdm::Range(100, { .unit = "items" })) {}
for (auto&& i : tqdm::Iota({ .unit = "items" })) {}| Option | Type | Default | Description |
|---|---|---|---|
prefix |
string_view |
"" |
A prefix for the progress bar (should include a trailing space) |
unit |
string_view |
"it" |
Units (displayed as 123.45{unit}/s) |
segments |
size_t |
20 |
Number of segments in the progress bar (should be at least 1) |
min_update_ms |
unsigned |
100 |
Minimum number of milliseconds between consecutive iterations before updating the status bar (improves performance by skipping unecessary writes) |
ascii |
bool |
false |
Use ASCII instead of unicode for the bar (uses 0-9 for partial progress and # for full segments) |
use_stderr |
bool |
false |
Print the progress bar to stderr instead of stdout |
term_progress |
bool |
false |
Use ConEmu Progress Bar sequences (OSC 9;4) to set the terminal progress bar (requires terminal support) |