Clang format

This commit is contained in:
Pranav Srinivas Kumar
2020-02-13 14:21:01 +05:30
parent f5b6b4d779
commit 89ae8cec39
15 changed files with 862 additions and 860 deletions

View File

@@ -60,7 +60,8 @@ int main() {
p.set_option(option::ShowPercentage{false}); p.set_option(option::ShowPercentage{false});
auto job = [&p]() { auto job = [&p]() {
while (true) { while (true) {
p.set_option(option::PrefixText{"Reading package list... " + std::to_string(p.current()) + "% "}); p.set_option(
option::PrefixText{"Reading package list... " + std::to_string(p.current()) + "% "});
if (p.current() + 2 >= 100) if (p.current() + 2 >= 100)
p.set_option(option::PrefixText{"Reading package list... Done"}); p.set_option(option::PrefixText{"Reading package list... Done"});
p.tick(); p.tick();
@@ -155,16 +156,14 @@ int main() {
// //
// GOING BACKWARDS // GOING BACKWARDS
// //
indicators::ProgressBar p{ indicators::ProgressBar p{option::BarWidth{50},
option::BarWidth {50},
option::Start{"["}, option::Start{"["},
option::Fill{""}, option::Fill{""},
option::Lead{""}, option::Lead{""},
option::Remainder{"-"}, option::Remainder{"-"},
option::End{"]"}, option::End{"]"},
option::ForegroundColor{indicators::Color::white}, option::ForegroundColor{indicators::Color::white},
option::PostfixText{"Reverting system restore"} option::PostfixText{"Reverting system restore"}};
};
p.set_progress(100); // TODO backwards as an option? p.set_progress(100); // TODO backwards as an option?
std::atomic<size_t> progress{100}; std::atomic<size_t> progress{100};
auto job = [&p, &progress]() { auto job = [&p, &progress]() {
@@ -189,11 +188,9 @@ int main() {
// PROGRESS BAR 5 // PROGRESS BAR 5
// //
indicators::ProgressSpinner p{ indicators::ProgressSpinner p{
option::PrefixText{""}, option::PrefixText{""}, option::PostfixText{"Checking credentials"},
option::PostfixText{"Checking credentials"},
option::ForegroundColor{indicators::Color::yellow}, option::ForegroundColor{indicators::Color::yellow},
option::SpinnerStates{std::vector<std::string>{"", "", "", "", "", "", "", ""}} option::SpinnerStates{std::vector<std::string>{"", "", "", "", "", "", "", ""}}};
};
auto job = [&p]() { auto job = [&p]() {
while (true) { while (true) {
@@ -220,12 +217,9 @@ int main() {
// PROGRESS BAR 6 // PROGRESS BAR 6
// //
indicators::ProgressSpinner p{ indicators::ProgressSpinner p{
option::PrefixText{" - "}, option::PrefixText{" - "}, option::PostfixText{"Searching for the Moon"},
option::PostfixText{"Searching for the Moon"}, option::ForegroundColor{indicators::Color::white}, option::ShowPercentage{false},
option::ForegroundColor{indicators::Color::white}, option::SpinnerStates{std::vector<std::string>{"", "", "", ""}}};
option::ShowPercentage{false},
option::SpinnerStates{std::vector<std::string>{"", "", "", ""}}
};
auto job = [&p]() { auto job = [&p]() {
while (true) { while (true) {
auto current = p.current(); auto current = p.current();
@@ -261,8 +255,7 @@ int main() {
// //
// NESTED PROGRESS BAR // NESTED PROGRESS BAR
// //
indicators::ProgressBar p2{ indicators::ProgressBar p2{option::BarWidth{30},
option::BarWidth{30},
option::PrefixText{" - "}, option::PrefixText{" - "},
option::Start{"🌎"}, option::Start{"🌎"},
option::Fill{"·"}, option::Fill{"·"},
@@ -270,8 +263,7 @@ int main() {
option::Remainder{" "}, option::Remainder{" "},
option::End{"🌑"}, option::End{"🌑"},
option::PostfixText{"Achieved low-Earth orbit"}, option::PostfixText{"Achieved low-Earth orbit"},
option::ForegroundColor{indicators::Color::white} option::ForegroundColor{indicators::Color::white}};
};
std::vector<std::string> ship_trail{"", "", "", "", "", "", "", ""}; std::vector<std::string> ship_trail{"", "", "", "", "", "", "", ""};
std::atomic<int> ship_trail_index{0}; std::atomic<int> ship_trail_index{0};
auto job2 = [&p2, &ship_trail_index, &ship_trail]() { auto job2 = [&p2, &ship_trail_index, &ship_trail]() {

View File

@@ -33,62 +33,73 @@ SOFTWARE.
#include <algorithm> #include <algorithm>
#include <atomic> #include <atomic>
#include <chrono> #include <chrono>
#include <indicators/setting.hpp>
#include <iomanip> #include <iomanip>
#include <iostream> #include <iostream>
#include <mutex> #include <mutex>
#include <string> #include <string>
#include <tuple>
#include <thread> #include <thread>
#include <indicators/setting.hpp> #include <tuple>
namespace indicators { namespace indicators {
class BlockProgressBar { class BlockProgressBar {
using Settings = std::tuple< using Settings = std::tuple<option::ForegroundColor, option::BarWidth, option::Start, option::End,
option::ForegroundColor, option::PrefixText, option::PostfixText, option::ShowPercentage,
option::BarWidth, option::ShowElapsedTime, option::ShowRemainingTime, option::Completed,
option::Start, option::SavedStartTime, option::MaxPostfixTextLen>;
option::End,
option::PrefixText,
option::PostfixText,
option::ShowPercentage,
option::ShowElapsedTime,
option::ShowRemainingTime,
option::Completed,
option::SavedStartTime,
option::MaxPostfixTextLen>;
public: public:
template <typename... Args, typename std::enable_if<details::are_settings_from_tuple<Settings, typename std::decay<Args>::type...>::value, void*>::type = nullptr> template <typename... Args,
explicit BlockProgressBar(Args&&... args) : settings_( typename std::enable_if<details::are_settings_from_tuple<
details::get<details::ProgressBarOption::foreground_color>(option::ForegroundColor{Color::white}, std::forward<Args>(args)...), Settings, typename std::decay<Args>::type...>::value,
details::get<details::ProgressBarOption::bar_width>(option::BarWidth{100}, std::forward<Args>(args)...), void *>::type = nullptr>
details::get<details::ProgressBarOption::start>(option::Start{"["}, std::forward<Args>(args)...), explicit BlockProgressBar(Args &&... args)
details::get<details::ProgressBarOption::end>(option::End{"]"}, std::forward<Args>(args)...), : settings_(details::get<details::ProgressBarOption::foreground_color>(
details::get<details::ProgressBarOption::prefix_text>(option::PrefixText{""}, std::forward<Args>(args)...), option::ForegroundColor{Color::white}, std::forward<Args>(args)...),
details::get<details::ProgressBarOption::postfix_text>(option::PostfixText{""}, std::forward<Args>(args)...), details::get<details::ProgressBarOption::bar_width>(option::BarWidth{100},
details::get<details::ProgressBarOption::show_percentage>(option::ShowPercentage{true}, std::forward<Args>(args)...), std::forward<Args>(args)...),
details::get<details::ProgressBarOption::show_elapsed_time>(option::ShowElapsedTime{false}, std::forward<Args>(args)...), details::get<details::ProgressBarOption::start>(option::Start{"["},
details::get<details::ProgressBarOption::show_remaining_time>(option::ShowRemainingTime{false}, std::forward<Args>(args)...), std::forward<Args>(args)...),
details::get<details::ProgressBarOption::completed>(option::Completed{false}, std::forward<Args>(args)...), details::get<details::ProgressBarOption::end>(option::End{"]"},
details::get<details::ProgressBarOption::saved_start_time>(option::SavedStartTime{false}, std::forward<Args>(args)...), std::forward<Args>(args)...),
details::get<details::ProgressBarOption::max_postfix_text_len>(option::MaxPostfixTextLen{0}, std::forward<Args>(args)...) details::get<details::ProgressBarOption::prefix_text>(
) {} option::PrefixText{""}, std::forward<Args>(args)...),
details::get<details::ProgressBarOption::postfix_text>(
option::PostfixText{""}, std::forward<Args>(args)...),
details::get<details::ProgressBarOption::show_percentage>(
option::ShowPercentage{true}, std::forward<Args>(args)...),
details::get<details::ProgressBarOption::show_elapsed_time>(
option::ShowElapsedTime{false}, std::forward<Args>(args)...),
details::get<details::ProgressBarOption::show_remaining_time>(
option::ShowRemainingTime{false}, std::forward<Args>(args)...),
details::get<details::ProgressBarOption::completed>(option::Completed{false},
std::forward<Args>(args)...),
details::get<details::ProgressBarOption::saved_start_time>(
option::SavedStartTime{false}, std::forward<Args>(args)...),
details::get<details::ProgressBarOption::max_postfix_text_len>(
option::MaxPostfixTextLen{0}, std::forward<Args>(args)...)) {}
template <typename T, details::ProgressBarOption id> template <typename T, details::ProgressBarOption id>
void set_option(details::Setting<T, id> &&setting) { void set_option(details::Setting<T, id> &&setting) {
static_assert(!std::is_same<T, typename std::decay<decltype(details::get_value<id>(std::declval<Settings>()))>::type>::value, "Setting has wrong type!"); static_assert(!std::is_same<T, typename std::decay<decltype(details::get_value<id>(
std::declval<Settings>()))>::type>::value,
"Setting has wrong type!");
std::lock_guard<std::mutex> lock(mutex_); std::lock_guard<std::mutex> lock(mutex_);
get_value<id>() = std::move(setting).value; get_value<id>() = std::move(setting).value;
} }
template <typename T, details::ProgressBarOption id> template <typename T, details::ProgressBarOption id>
void set_option(const details::Setting<T, id> &setting) { void set_option(const details::Setting<T, id> &setting) {
static_assert(!std::is_same<T, typename std::decay<decltype(details::get_value<id>(std::declval<Settings>()))>::type>::value, "Setting has wrong type!"); static_assert(!std::is_same<T, typename std::decay<decltype(details::get_value<id>(
std::declval<Settings>()))>::type>::value,
"Setting has wrong type!");
std::lock_guard<std::mutex> lock(mutex_); std::lock_guard<std::mutex> lock(mutex_);
get_value<id>() = setting.value; get_value<id>() = setting.value;
} }
void set_option(const details::Setting<std::string, details::ProgressBarOption::postfix_text>& setting){ void set_option(
const details::Setting<std::string, details::ProgressBarOption::postfix_text> &setting) {
std::lock_guard<std::mutex> lock(mutex_); std::lock_guard<std::mutex> lock(mutex_);
get_value<details::ProgressBarOption::postfix_text>() = setting.value; get_value<details::ProgressBarOption::postfix_text>() = setting.value;
if (setting.value.length() > get_value<details::ProgressBarOption::max_postfix_text_len>()) { if (setting.value.length() > get_value<details::ProgressBarOption::max_postfix_text_len>()) {
@@ -96,7 +107,8 @@ public:
} }
} }
void set_option(details::Setting<std::string, details::ProgressBarOption::postfix_text>&& setting){ void
set_option(details::Setting<std::string, details::ProgressBarOption::postfix_text> &&setting) {
std::lock_guard<std::mutex> lock(mutex_); std::lock_guard<std::mutex> lock(mutex_);
get_value<details::ProgressBarOption::postfix_text>() = std::move(setting).value; get_value<details::ProgressBarOption::postfix_text>() = std::move(setting).value;
auto &new_value = get_value<details::ProgressBarOption::postfix_text>(); auto &new_value = get_value<details::ProgressBarOption::postfix_text>();
@@ -136,14 +148,14 @@ public:
} }
private: private:
template <details::ProgressBarOption id> template <details::ProgressBarOption id>
auto get_value() -> decltype((details::get_value<id>(std::declval<Settings &>()).value)) { auto get_value() -> decltype((details::get_value<id>(std::declval<Settings &>()).value)) {
return details::get_value<id>(settings_).value; return details::get_value<id>(settings_).value;
} }
template <details::ProgressBarOption id> template <details::ProgressBarOption id>
auto get_value() const -> decltype((details::get_value<id>(std::declval<const Settings&>()).value)) { auto get_value() const
-> decltype((details::get_value<id>(std::declval<const Settings &>()).value)) {
return details::get_value<id>(settings_).value; return details::get_value<id>(settings_).value;
} }
@@ -181,7 +193,8 @@ private:
std::cout << get_value<details::ProgressBarOption::prefix_text>(); std::cout << get_value<details::ProgressBarOption::prefix_text>();
std::cout << get_value<details::ProgressBarOption::start>(); std::cout << get_value<details::ProgressBarOption::start>();
details::BlockProgressScaleWriter writer{std::cout, get_value<details::ProgressBarOption::bar_width>()}; details::BlockProgressScaleWriter writer{std::cout,
get_value<details::ProgressBarOption::bar_width>()};
writer.write(progress_); writer.write(progress_);
std::cout << get_value<details::ProgressBarOption::end>(); std::cout << get_value<details::ProgressBarOption::end>();
@@ -211,12 +224,15 @@ private:
if (get_value<details::ProgressBarOption::max_postfix_text_len>() == 0) if (get_value<details::ProgressBarOption::max_postfix_text_len>() == 0)
get_value<details::ProgressBarOption::max_postfix_text_len>() = 10; get_value<details::ProgressBarOption::max_postfix_text_len>() = 10;
std::cout << " " << get_value<details::ProgressBarOption::postfix_text>() << std::string(get_value<details::ProgressBarOption::max_postfix_text_len>(), ' ') << "\r"; std::cout << " " << get_value<details::ProgressBarOption::postfix_text>()
<< std::string(get_value<details::ProgressBarOption::max_postfix_text_len>(), ' ')
<< "\r";
std::cout.flush(); std::cout.flush();
if (progress_ > 100.0) { if (progress_ > 100.0) {
get_value<details::ProgressBarOption::completed>() = true; get_value<details::ProgressBarOption::completed>() = true;
} }
if (get_value<details::ProgressBarOption::completed>() && !from_multi_progress) // Don't std::endl if calling from MultiProgress if (get_value<details::ProgressBarOption::completed>() &&
!from_multi_progress) // Don't std::endl if calling from MultiProgress
std::cout << termcolor::reset << std::endl; std::cout << termcolor::reset << std::endl;
} }
}; };

View File

@@ -69,13 +69,9 @@ inline std::ostream &write_duration(std::ostream &os, std::chrono::nanoseconds n
return os; return os;
} }
class BlockProgressScaleWriter class BlockProgressScaleWriter {
{
public: public:
BlockProgressScaleWriter(std::ostream& os, size_t bar_width) BlockProgressScaleWriter(std::ostream &os, size_t bar_width) : os(os), bar_width(bar_width) {}
: os(os)
, bar_width(bar_width)
{}
std::ostream &write(float progress) { std::ostream &write(float progress) {
std::string fill_text{""}; std::string fill_text{""};
@@ -94,25 +90,17 @@ public:
os << " "; os << " ";
return os; return os;
} }
private: private:
std::ostream &os; std::ostream &os;
size_t bar_width = 0; size_t bar_width = 0;
}; };
class ProgressScaleWriter class ProgressScaleWriter {
{
public: public:
ProgressScaleWriter(std::ostream& os, ProgressScaleWriter(std::ostream &os, size_t bar_width, const std::string &fill,
size_t bar_width, const std::string &lead, const std::string &remainder)
const std::string& fill, : os(os), bar_width(bar_width), fill(fill), lead(lead), remainder(remainder) {}
const std::string& lead,
const std::string& remainder)
: os(os)
, bar_width(bar_width)
, fill(fill)
, lead(lead)
, remainder(remainder)
{}
std::ostream &write(float progress) { std::ostream &write(float progress) {
auto pos = static_cast<size_t>(progress * static_cast<float>(bar_width) / 100.0); auto pos = static_cast<size_t>(progress * static_cast<float>(bar_width) / 100.0);
@@ -135,5 +123,5 @@ private:
std::string remainder; std::string remainder;
}; };
} } // namespace details
} } // namespace indicators

View File

@@ -35,7 +35,6 @@ SOFTWARE.
#include <cmath> #include <cmath>
#include <indicators/color.hpp> #include <indicators/color.hpp>
#include <indicators/setting.hpp> #include <indicators/setting.hpp>
#include <tuple>
#include <iomanip> #include <iomanip>
#include <iostream> #include <iostream>
#include <mutex> #include <mutex>
@@ -47,60 +46,70 @@ SOFTWARE.
namespace indicators { namespace indicators {
class ProgressBar { class ProgressBar {
using Settings = std::tuple< using Settings =
option::BarWidth, std::tuple<option::BarWidth, option::PrefixText, option::PostfixText, option::Start,
option::PrefixText, option::End, option::Fill, option::Lead, option::Remainder,
option::PostfixText, option::MaxPostfixTextLen, option::Completed, option::ShowPercentage,
option::Start, option::ShowElapsedTime, option::ShowRemainingTime, option::SavedStartTime,
option::End, option::ForegroundColor>;
option::Fill,
option::Lead,
option::Remainder,
option::MaxPostfixTextLen,
option::Completed,
option::ShowPercentage,
option::ShowElapsedTime,
option::ShowRemainingTime,
option::SavedStartTime,
option::ForegroundColor
>;
public: public:
template <typename... Args, typename std::enable_if<details::are_settings_from_tuple<Settings, typename std::decay<Args>::type...>::value, void*>::type = nullptr> template <typename... Args,
explicit ProgressBar(Args&&... args) : typename std::enable_if<details::are_settings_from_tuple<
settings_( Settings, typename std::decay<Args>::type...>::value,
details::get<details::ProgressBarOption::bar_width>(option::BarWidth{100}, std::forward<Args>(args)...), void *>::type = nullptr>
details::get<details::ProgressBarOption::prefix_text>(option::PrefixText{}, std::forward<Args>(args)...), explicit ProgressBar(Args &&... args)
details::get<details::ProgressBarOption::postfix_text>(option::PostfixText{}, std::forward<Args>(args)...), : settings_(details::get<details::ProgressBarOption::bar_width>(option::BarWidth{100},
details::get<details::ProgressBarOption::start>(option::Start{"["}, std::forward<Args>(args)...), std::forward<Args>(args)...),
details::get<details::ProgressBarOption::end>(option::End{"]"}, std::forward<Args>(args)...), details::get<details::ProgressBarOption::prefix_text>(
details::get<details::ProgressBarOption::fill>(option::Fill{"="}, std::forward<Args>(args)...), option::PrefixText{}, std::forward<Args>(args)...),
details::get<details::ProgressBarOption::lead>(option::Lead{">"}, std::forward<Args>(args)...), details::get<details::ProgressBarOption::postfix_text>(
details::get<details::ProgressBarOption::remainder>(option::Remainder{" "}, std::forward<Args>(args)...), option::PostfixText{}, std::forward<Args>(args)...),
details::get<details::ProgressBarOption::max_postfix_text_len>(option::MaxPostfixTextLen{0}, std::forward<Args>(args)...), details::get<details::ProgressBarOption::start>(option::Start{"["},
details::get<details::ProgressBarOption::completed>(option::Completed{false}, std::forward<Args>(args)...), std::forward<Args>(args)...),
details::get<details::ProgressBarOption::show_percentage>(option::ShowPercentage{false} ,std::forward<Args>(args)...), details::get<details::ProgressBarOption::end>(option::End{"]"},
details::get<details::ProgressBarOption::show_elapsed_time>(option::ShowElapsedTime{false}, std::forward<Args>(args)...), std::forward<Args>(args)...),
details::get<details::ProgressBarOption::show_remaining_time>(option::ShowRemainingTime{false}, std::forward<Args>(args)...), details::get<details::ProgressBarOption::fill>(option::Fill{"="},
details::get<details::ProgressBarOption::saved_start_time>(option::SavedStartTime{false}, std::forward<Args>(args)...), std::forward<Args>(args)...),
details::get<details::ProgressBarOption::foreground_color>(option::ForegroundColor{Color::white}, std::forward<Args>(args)...) details::get<details::ProgressBarOption::lead>(option::Lead{">"},
) std::forward<Args>(args)...),
{} details::get<details::ProgressBarOption::remainder>(option::Remainder{" "},
std::forward<Args>(args)...),
details::get<details::ProgressBarOption::max_postfix_text_len>(
option::MaxPostfixTextLen{0}, std::forward<Args>(args)...),
details::get<details::ProgressBarOption::completed>(option::Completed{false},
std::forward<Args>(args)...),
details::get<details::ProgressBarOption::show_percentage>(
option::ShowPercentage{false}, std::forward<Args>(args)...),
details::get<details::ProgressBarOption::show_elapsed_time>(
option::ShowElapsedTime{false}, std::forward<Args>(args)...),
details::get<details::ProgressBarOption::show_remaining_time>(
option::ShowRemainingTime{false}, std::forward<Args>(args)...),
details::get<details::ProgressBarOption::saved_start_time>(
option::SavedStartTime{false}, std::forward<Args>(args)...),
details::get<details::ProgressBarOption::foreground_color>(
option::ForegroundColor{Color::white}, std::forward<Args>(args)...)) {}
template <typename T, details::ProgressBarOption id> template <typename T, details::ProgressBarOption id>
void set_option(details::Setting<T, id> &&setting) { void set_option(details::Setting<T, id> &&setting) {
static_assert(!std::is_same<T, typename std::decay<decltype(details::get_value<id>(std::declval<Settings>()))>::type>::value, "Setting has wrong type!"); static_assert(!std::is_same<T, typename std::decay<decltype(details::get_value<id>(
std::declval<Settings>()))>::type>::value,
"Setting has wrong type!");
std::lock_guard<std::mutex> lock(mutex_); std::lock_guard<std::mutex> lock(mutex_);
get_value<id>() = std::move(setting).value; get_value<id>() = std::move(setting).value;
} }
template <typename T, details::ProgressBarOption id> template <typename T, details::ProgressBarOption id>
void set_option(const details::Setting<T, id> &setting) { void set_option(const details::Setting<T, id> &setting) {
static_assert(!std::is_same<T, typename std::decay<decltype(details::get_value<id>(std::declval<Settings>()))>::type>::value, "Setting has wrong type!"); static_assert(!std::is_same<T, typename std::decay<decltype(details::get_value<id>(
std::declval<Settings>()))>::type>::value,
"Setting has wrong type!");
std::lock_guard<std::mutex> lock(mutex_); std::lock_guard<std::mutex> lock(mutex_);
get_value<id>() = setting.value; get_value<id>() = setting.value;
} }
void set_option(const details::Setting<std::string, details::ProgressBarOption::postfix_text>& setting){ void set_option(
const details::Setting<std::string, details::ProgressBarOption::postfix_text> &setting) {
std::lock_guard<std::mutex> lock(mutex_); std::lock_guard<std::mutex> lock(mutex_);
get_value<details::ProgressBarOption::postfix_text>() = setting.value; get_value<details::ProgressBarOption::postfix_text>() = setting.value;
if (setting.value.length() > get_value<details::ProgressBarOption::max_postfix_text_len>()) { if (setting.value.length() > get_value<details::ProgressBarOption::max_postfix_text_len>()) {
@@ -108,7 +117,8 @@ public:
} }
} }
void set_option(details::Setting<std::string, details::ProgressBarOption::postfix_text>&& setting){ void
set_option(details::Setting<std::string, details::ProgressBarOption::postfix_text> &&setting) {
std::lock_guard<std::mutex> lock(mutex_); std::lock_guard<std::mutex> lock(mutex_);
get_value<details::ProgressBarOption::postfix_text>() = std::move(setting).value; get_value<details::ProgressBarOption::postfix_text>() = std::move(setting).value;
auto &new_value = get_value<details::ProgressBarOption::postfix_text>(); auto &new_value = get_value<details::ProgressBarOption::postfix_text>();
@@ -149,14 +159,14 @@ public:
} }
private: private:
template <details::ProgressBarOption id> template <details::ProgressBarOption id>
auto get_value() -> decltype((details::get_value<id>(std::declval<Settings &>()).value)) { auto get_value() -> decltype((details::get_value<id>(std::declval<Settings &>()).value)) {
return details::get_value<id>(settings_).value; return details::get_value<id>(settings_).value;
} }
template <details::ProgressBarOption id> template <details::ProgressBarOption id>
auto get_value() const -> decltype((details::get_value<id>(std::declval<const Settings&>()).value)) { auto get_value() const
-> decltype((details::get_value<id>(std::declval<const Settings &>()).value)) {
return details::get_value<id>(settings_).value; return details::get_value<id>(settings_).value;
} }
@@ -197,7 +207,8 @@ private:
std::cout << get_value<details::ProgressBarOption::start>(); std::cout << get_value<details::ProgressBarOption::start>();
details::ProgressScaleWriter writer{std::cout, get_value<details::ProgressBarOption::bar_width>(), details::ProgressScaleWriter writer{std::cout,
get_value<details::ProgressBarOption::bar_width>(),
get_value<details::ProgressBarOption::fill>(), get_value<details::ProgressBarOption::fill>(),
get_value<details::ProgressBarOption::lead>(), get_value<details::ProgressBarOption::lead>(),
get_value<details::ProgressBarOption::remainder>()}; get_value<details::ProgressBarOption::remainder>()};
@@ -231,12 +242,15 @@ private:
if (get_value<details::ProgressBarOption::max_postfix_text_len>() == 0) if (get_value<details::ProgressBarOption::max_postfix_text_len>() == 0)
get_value<details::ProgressBarOption::max_postfix_text_len>() = 10; get_value<details::ProgressBarOption::max_postfix_text_len>() = 10;
std::cout << " " << get_value<details::ProgressBarOption::postfix_text>() << std::string(get_value<details::ProgressBarOption::max_postfix_text_len>(), ' ') << "\r"; std::cout << " " << get_value<details::ProgressBarOption::postfix_text>()
<< std::string(get_value<details::ProgressBarOption::max_postfix_text_len>(), ' ')
<< "\r";
std::cout.flush(); std::cout.flush();
if (progress_ > 100.0) { if (progress_ > 100.0) {
get_value<details::ProgressBarOption::completed>() = true; get_value<details::ProgressBarOption::completed>() = true;
} }
if (get_value<details::ProgressBarOption::completed>() && !from_multi_progress) // Don't std::endl if calling from MultiProgress if (get_value<details::ProgressBarOption::completed>() &&
!from_multi_progress) // Don't std::endl if calling from MultiProgress
std::cout << termcolor::reset << std::endl; std::cout << termcolor::reset << std::endl;
} }
}; };

View File

@@ -39,57 +39,70 @@ SOFTWARE.
#include <iostream> #include <iostream>
#include <mutex> #include <mutex>
#include <string> #include <string>
#include <tuple>
#include <thread> #include <thread>
#include <tuple>
#include <vector> #include <vector>
namespace indicators { namespace indicators {
class ProgressSpinner { class ProgressSpinner {
using Settings = std::tuple< using Settings =
option::ForegroundColor, std::tuple<option::ForegroundColor, option::PrefixText, option::PostfixText,
option::PrefixText, option::ShowPercentage, option::ShowElapsedTime, option::ShowRemainingTime,
option::PostfixText, option::ShowSpinner, option::SavedStartTime, option::Completed,
option::ShowPercentage, option::MaxPostfixTextLen, option::SpinnerStates>;
option::ShowElapsedTime,
option::ShowRemainingTime,
option::ShowSpinner,
option::SavedStartTime,
option::Completed,
option::MaxPostfixTextLen,
option::SpinnerStates
>;
public: public:
template <typename... Args, typename std::enable_if<details::are_settings_from_tuple<Settings, typename std::decay<Args>::type...>::value, void*>::type = nullptr> template <typename... Args,
explicit ProgressSpinner(Args&&... args) : settings_( typename std::enable_if<details::are_settings_from_tuple<
details::get<details::ProgressBarOption::foreground_color>(option::ForegroundColor{Color::white}, std::forward<Args>(args)...), Settings, typename std::decay<Args>::type...>::value,
details::get<details::ProgressBarOption::prefix_text>(option::PrefixText{}, std::forward<Args>(args)...), void *>::type = nullptr>
details::get<details::ProgressBarOption::postfix_text>(option::PostfixText{}, std::forward<Args>(args)...), explicit ProgressSpinner(Args &&... args)
details::get<details::ProgressBarOption::show_percentage>(option::ShowPercentage{true}, std::forward<Args>(args)...), : settings_(details::get<details::ProgressBarOption::foreground_color>(
details::get<details::ProgressBarOption::show_elapsed_time>(option::ShowElapsedTime{false}, std::forward<Args>(args)...), option::ForegroundColor{Color::white}, std::forward<Args>(args)...),
details::get<details::ProgressBarOption::show_remaining_time>(option::ShowRemainingTime{false}, std::forward<Args>(args)...), details::get<details::ProgressBarOption::prefix_text>(
details::get<details::ProgressBarOption::spinner_show>(option::ShowSpinner{true}, std::forward<Args>(args)...), option::PrefixText{}, std::forward<Args>(args)...),
details::get<details::ProgressBarOption::saved_start_time>(option::SavedStartTime{false}, std::forward<Args>(args)...), details::get<details::ProgressBarOption::postfix_text>(
details::get<details::ProgressBarOption::completed>(option::Completed{false}, std::forward<Args>(args)...), option::PostfixText{}, std::forward<Args>(args)...),
details::get<details::ProgressBarOption::max_postfix_text_len>(option::MaxPostfixTextLen{0}, std::forward<Args>(args)...), details::get<details::ProgressBarOption::show_percentage>(
details::get<details::ProgressBarOption::spinner_states>(option::SpinnerStates{std::vector<std::string>{"", "", "", "", "", "", "", "", "", ""}}, std::forward<Args>(args)...) option::ShowPercentage{true}, std::forward<Args>(args)...),
){} details::get<details::ProgressBarOption::show_elapsed_time>(
option::ShowElapsedTime{false}, std::forward<Args>(args)...),
details::get<details::ProgressBarOption::show_remaining_time>(
option::ShowRemainingTime{false}, std::forward<Args>(args)...),
details::get<details::ProgressBarOption::spinner_show>(
option::ShowSpinner{true}, std::forward<Args>(args)...),
details::get<details::ProgressBarOption::saved_start_time>(
option::SavedStartTime{false}, std::forward<Args>(args)...),
details::get<details::ProgressBarOption::completed>(option::Completed{false},
std::forward<Args>(args)...),
details::get<details::ProgressBarOption::max_postfix_text_len>(
option::MaxPostfixTextLen{0}, std::forward<Args>(args)...),
details::get<details::ProgressBarOption::spinner_states>(
option::SpinnerStates{std::vector<std::string>{"", "", "", "", "", "",
"", "", "", ""}},
std::forward<Args>(args)...)) {}
template <typename T, details::ProgressBarOption id> template <typename T, details::ProgressBarOption id>
void set_option(details::Setting<T, id> &&setting) { void set_option(details::Setting<T, id> &&setting) {
static_assert(!std::is_same<T, typename std::decay<decltype(details::get_value<id>(std::declval<Settings>()))>::type>::value, "Setting has wrong type!"); static_assert(!std::is_same<T, typename std::decay<decltype(details::get_value<id>(
std::declval<Settings>()))>::type>::value,
"Setting has wrong type!");
std::lock_guard<std::mutex> lock(mutex_); std::lock_guard<std::mutex> lock(mutex_);
get_value<id>() = std::move(setting).value; get_value<id>() = std::move(setting).value;
} }
template <typename T, details::ProgressBarOption id> template <typename T, details::ProgressBarOption id>
void set_option(const details::Setting<T, id> &setting) { void set_option(const details::Setting<T, id> &setting) {
static_assert(!std::is_same<T, typename std::decay<decltype(details::get_value<id>(std::declval<Settings>()))>::type>::value, "Setting has wrong type!"); static_assert(!std::is_same<T, typename std::decay<decltype(details::get_value<id>(
std::declval<Settings>()))>::type>::value,
"Setting has wrong type!");
std::lock_guard<std::mutex> lock(mutex_); std::lock_guard<std::mutex> lock(mutex_);
get_value<id>() = setting.value; get_value<id>() = setting.value;
} }
void set_option(const details::Setting<std::string, details::ProgressBarOption::postfix_text>& setting){ void set_option(
const details::Setting<std::string, details::ProgressBarOption::postfix_text> &setting) {
std::lock_guard<std::mutex> lock(mutex_); std::lock_guard<std::mutex> lock(mutex_);
get_value<details::ProgressBarOption::postfix_text>() = setting.value; get_value<details::ProgressBarOption::postfix_text>() = setting.value;
if (setting.value.length() > get_value<details::ProgressBarOption::max_postfix_text_len>()) { if (setting.value.length() > get_value<details::ProgressBarOption::max_postfix_text_len>()) {
@@ -97,7 +110,8 @@ public:
} }
} }
void set_option(details::Setting<std::string, details::ProgressBarOption::postfix_text>&& setting){ void
set_option(details::Setting<std::string, details::ProgressBarOption::postfix_text> &&setting) {
std::lock_guard<std::mutex> lock(mutex_); std::lock_guard<std::mutex> lock(mutex_);
get_value<details::ProgressBarOption::postfix_text>() = std::move(setting).value; get_value<details::ProgressBarOption::postfix_text>() = std::move(setting).value;
auto &new_value = get_value<details::ProgressBarOption::postfix_text>(); auto &new_value = get_value<details::ProgressBarOption::postfix_text>();
@@ -149,7 +163,8 @@ private:
} }
template <details::ProgressBarOption id> template <details::ProgressBarOption id>
auto get_value() const -> decltype((details::get_value<id>(std::declval<const Settings&>()).value)) { auto get_value() const
-> decltype((details::get_value<id>(std::declval<const Settings &>()).value)) {
return details::get_value<id>(settings_).value; return details::get_value<id>(settings_).value;
} }
@@ -172,7 +187,8 @@ private:
details::set_stream_color(std::cout, get_value<details::ProgressBarOption::foreground_color>()); details::set_stream_color(std::cout, get_value<details::ProgressBarOption::foreground_color>());
std::cout << get_value<details::ProgressBarOption::prefix_text>(); std::cout << get_value<details::ProgressBarOption::prefix_text>();
if (get_value<details::ProgressBarOption::spinner_show>()) if (get_value<details::ProgressBarOption::spinner_show>())
std::cout << get_value<details::ProgressBarOption::spinner_states>()[index_ % get_value<details::ProgressBarOption::spinner_states>().size()]; std::cout << get_value<details::ProgressBarOption::spinner_states>()
[index_ % get_value<details::ProgressBarOption::spinner_states>().size()];
if (get_value<details::ProgressBarOption::show_percentage>()) { if (get_value<details::ProgressBarOption::show_percentage>()) {
std::cout << " " << std::min(static_cast<size_t>(progress_), size_t(100)) << "%"; std::cout << " " << std::min(static_cast<size_t>(progress_), size_t(100)) << "%";
} }
@@ -199,7 +215,9 @@ private:
if (get_value<details::ProgressBarOption::max_postfix_text_len>() == 0) if (get_value<details::ProgressBarOption::max_postfix_text_len>() == 0)
get_value<details::ProgressBarOption::max_postfix_text_len>() = 10; get_value<details::ProgressBarOption::max_postfix_text_len>() = 10;
std::cout << " " << get_value<details::ProgressBarOption::postfix_text>() << std::string(get_value<details::ProgressBarOption::max_postfix_text_len>(), ' ') << "\r"; std::cout << " " << get_value<details::ProgressBarOption::postfix_text>()
<< std::string(get_value<details::ProgressBarOption::max_postfix_text_len>(), ' ')
<< "\r";
std::cout.flush(); std::cout.flush();
index_ += 1; index_ += 1;
if (progress_ > 100.0) { if (progress_ > 100.0) {

View File

@@ -32,54 +32,41 @@ SOFTWARE.
#include <type_traits> #include <type_traits>
#include <utility> #include <utility>
namespace indicators { namespace indicators {
namespace details { namespace details {
template <bool condition> template <bool condition> struct if_else;
struct if_else;
template<> template <> struct if_else<true> { using type = std::true_type; };
struct if_else<true>{
using type = std::true_type;
};
template<> template <> struct if_else<false> { using type = std::false_type; };
struct if_else<false>{
using type = std::false_type ;
};
template <bool condition, typename True, typename False> template <bool condition, typename True, typename False> struct if_else_type;
struct if_else_type;
template <typename True, typename False> template <typename True, typename False> struct if_else_type<true, True, False> {
struct if_else_type<true, True, False>{
using type = True; using type = True;
}; };
template <typename True, typename False> template <typename True, typename False> struct if_else_type<false, True, False> {
struct if_else_type<false, True, False>{
using type = False; using type = False;
}; };
template <typename... Ops> template <typename... Ops> struct conjuction;
struct conjuction;
template <> template <> struct conjuction<> : std::true_type {};
struct conjuction<> : std::true_type {};
template <typename Op, typename... TailOps> template <typename Op, typename... TailOps>
struct conjuction<Op, TailOps...> : if_else_type<!Op::value, std::false_type, conjuction<TailOps...>>::type {}; struct conjuction<Op, TailOps...>
: if_else_type<!Op::value, std::false_type, conjuction<TailOps...>>::type {};
template <typename... Ops> template <typename... Ops> struct disjunction;
struct disjunction;
template <> template <> struct disjunction<> : std::false_type {};
struct disjunction<> : std::false_type {};
template <typename Op, typename... TailOps> template <typename Op, typename... TailOps>
struct disjunction<Op, TailOps...> : if_else_type<Op::value, std::true_type, disjunction<TailOps...>>::type {}; struct disjunction<Op, TailOps...>
: if_else_type<Op::value, std::true_type, disjunction<TailOps...>>::type {};
enum class ProgressBarOption { enum class ProgressBarOption {
bar_width = 0, bar_width = 0,
@@ -101,9 +88,9 @@ enum class ProgressBarOption{
spinner_states spinner_states
}; };
template <typename T, ProgressBarOption Id> template <typename T, ProgressBarOption Id> struct Setting {
struct Setting{ template <typename... Args,
template <typename... Args, typename = typename std::enable_if<std::is_constructible<T, Args...>::value>::type> typename = typename std::enable_if<std::is_constructible<T, Args...>::value>::type>
explicit Setting(Args &&... args) : value(std::forward<Args>(args)...) {} explicit Setting(Args &&... args) : value(std::forward<Args>(args)...) {}
Setting(const Setting &) = default; Setting(const Setting &) = default;
Setting(Setting &&) = default; Setting(Setting &&) = default;
@@ -114,91 +101,81 @@ struct Setting{
T value{}; T value{};
}; };
template <typename T> template <typename T> struct is_setting : std::false_type {};
struct is_setting : std::false_type{};
template <ProgressBarOption Id, typename T> template <ProgressBarOption Id, typename T> struct is_setting<Setting<T, Id>> : std::true_type {};
struct is_setting<Setting<T, Id>> : std::true_type{};
template <typename... Args> template <typename... Args>
struct are_settings : if_else<conjuction<is_setting<Args>...>::value>::type {}; struct are_settings : if_else<conjuction<is_setting<Args>...>::value>::type {};
template <> template <> struct are_settings<> : std::true_type {};
struct are_settings<> : std::true_type{};
template<typename Setting, typename Tuple> template <typename Setting, typename Tuple> struct is_setting_from_tuple;
struct is_setting_from_tuple;
template<typename Setting> template <typename Setting> struct is_setting_from_tuple<Setting, std::tuple<>> : std::true_type {};
struct is_setting_from_tuple<Setting, std::tuple<>> : std::true_type {};
template <typename Setting, typename... TupleTypes> template <typename Setting, typename... TupleTypes>
struct is_setting_from_tuple<Setting, std::tuple<TupleTypes...>> : struct is_setting_from_tuple<Setting, std::tuple<TupleTypes...>>
if_else<disjunction<std::is_same<Setting, TupleTypes>...>::value>::type {}; : if_else<disjunction<std::is_same<Setting, TupleTypes>...>::value>::type {};
template <typename Tuple, typename... Settings> template <typename Tuple, typename... Settings>
struct are_settings_from_tuple : if_else<conjuction<is_setting_from_tuple<Settings, Tuple>...>::value>::type {}; struct are_settings_from_tuple
: if_else<conjuction<is_setting_from_tuple<Settings, Tuple>...>::value>::type {};
template <ProgressBarOption Id> struct always_true { static constexpr auto value = true; };
template <ProgressBarOption Id> template <ProgressBarOption Id, typename Default> Default &&get_impl(Default &&def) {
struct always_true{
static constexpr auto value = true;
};
template<ProgressBarOption Id, typename Default>
Default&& get_impl(Default&& def){
return std::forward<Default>(def); return std::forward<Default>(def);
} }
template <ProgressBarOption Id, typename Default, typename T, typename... Args> template <ProgressBarOption Id, typename Default, typename T, typename... Args>
auto get_impl(Default&& def, T&& first, Args&&... tail) -> typename std::enable_if< auto get_impl(Default &&def, T &&first, Args &&... tail) ->
(std::decay<T>::type::id == Id), typename std::enable_if<(std::decay<T>::type::id == Id),
decltype(std::forward<T>(first))> decltype(std::forward<T>(first))>::type {
::type{
return std::forward<T>(first); return std::forward<T>(first);
} }
template <ProgressBarOption Id, typename Default, typename T, typename... Args> template <ProgressBarOption Id, typename Default, typename T, typename... Args>
auto get_impl(Default&& def, T&& first, Args&&... tail) -> typename std::enable_if< auto get_impl(Default &&def, T &&first, Args &&... tail) ->
(std::decay<T>::type::id != Id), typename std::enable_if<(std::decay<T>::type::id != Id),
decltype(get_impl<Id>(std::forward<Default>(def), std::forward<Args>(tail)...))>::type{ decltype(get_impl<Id>(std::forward<Default>(def),
std::forward<Args>(tail)...))>::type {
return get_impl<Id>(std::forward<Default>(def), std::forward<Args>(tail)...); return get_impl<Id>(std::forward<Default>(def), std::forward<Args>(tail)...);
} }
template <ProgressBarOption Id, typename Default, typename... Args, typename = typename std::enable_if<are_settings<Args...>::value, void>::type> template <ProgressBarOption Id, typename Default, typename... Args,
auto get(Default&& def, Args&&... args) -> decltype(details::get_impl<Id>(std::forward<Default>(def), std::forward<Args>(args)...)){ typename = typename std::enable_if<are_settings<Args...>::value, void>::type>
auto get(Default &&def, Args &&... args)
-> decltype(details::get_impl<Id>(std::forward<Default>(def), std::forward<Args>(args)...)) {
return details::get_impl<Id>(std::forward<Default>(def), std::forward<Args>(args)...); return details::get_impl<Id>(std::forward<Default>(def), std::forward<Args>(args)...);
} }
template <ProgressBarOption Id> template <ProgressBarOption Id> using StringSetting = Setting<std::string, Id>;
using StringSetting = Setting<std::string, Id>;
template <ProgressBarOption Id> template <ProgressBarOption Id> using IntegerSetting = Setting<std::size_t, Id>;
using IntegerSetting = Setting<std::size_t, Id>;
template <ProgressBarOption Id> template <ProgressBarOption Id> using BooleanSetting = Setting<bool, Id>;
using BooleanSetting = Setting<bool, Id>;
template <ProgressBarOption Id, typename Tuple, std::size_t counter =0> template <ProgressBarOption Id, typename Tuple, std::size_t counter = 0> struct option_idx;
struct option_idx;
template <ProgressBarOption Id, typename T, typename... Settings, std::size_t counter> template <ProgressBarOption Id, typename T, typename... Settings, std::size_t counter>
struct option_idx<Id, std::tuple<T, Settings...>, counter> : if_else_type<(Id == T::id), struct option_idx<Id, std::tuple<T, Settings...>, counter>
std::integral_constant<std::size_t, counter>, : if_else_type<(Id == T::id), std::integral_constant<std::size_t, counter>,
option_idx<Id, std::tuple<Settings...>, counter + 1>>::type {}; option_idx<Id, std::tuple<Settings...>, counter + 1>>::type {};
template <ProgressBarOption Id, std::size_t counter> template <ProgressBarOption Id, std::size_t counter> struct option_idx<Id, std::tuple<>, counter> {
struct option_idx<Id, std::tuple<>, counter>{
static_assert(always_true<(ProgressBarOption)Id>::value, "No such option was found"); static_assert(always_true<(ProgressBarOption)Id>::value, "No such option was found");
}; };
template <ProgressBarOption Id, typename Settings> template <ProgressBarOption Id, typename Settings>
auto get_value(Settings&& settings) -> decltype((std::get<option_idx<Id, typename std::decay<Settings>::type>::value>(std::declval<Settings&&>()))){ auto get_value(Settings &&settings)
return std::get<option_idx<Id, typename std::decay<Settings>::type>::value>(std::forward<Settings>(settings)); -> decltype((std::get<option_idx<Id, typename std::decay<Settings>::type>::value>(
} std::declval<Settings &&>()))) {
return std::get<option_idx<Id, typename std::decay<Settings>::type>::value>(
std::forward<Settings>(settings));
} }
} // namespace details
namespace option { namespace option {
using BarWidth = details::IntegerSetting<details::ProgressBarOption::bar_width>; using BarWidth = details::IntegerSetting<details::ProgressBarOption::bar_width>;
@@ -217,6 +194,7 @@ namespace option{
using SavedStartTime = details::BooleanSetting<details::ProgressBarOption::saved_start_time>; using SavedStartTime = details::BooleanSetting<details::ProgressBarOption::saved_start_time>;
using ForegroundColor = details::Setting<Color, details::ProgressBarOption::foreground_color>; using ForegroundColor = details::Setting<Color, details::ProgressBarOption::foreground_color>;
using ShowSpinner = details::BooleanSetting<details::ProgressBarOption::spinner_show>; using ShowSpinner = details::BooleanSetting<details::ProgressBarOption::spinner_show>;
using SpinnerStates = details::Setting<std::vector<std::string>, details::ProgressBarOption::spinner_states>; using SpinnerStates =
} details::Setting<std::vector<std::string>, details::ProgressBarOption::spinner_states>;
} } // namespace option
} // namespace indicators

View File

@@ -7,9 +7,7 @@ int main() {
// Hide cursor // Hide cursor
std::cout << "\e[?25l"; std::cout << "\e[?25l";
indicators::BlockProgressBar bar{ indicators::BlockProgressBar bar{indicators::option::BarWidth{80}};
indicators::option::BarWidth {80}
};
// Update bar state // Update bar state
auto progress = 0.0f; auto progress = 0.0f;

View File

@@ -3,29 +3,17 @@
int main() { int main() {
using namespace indicators; using namespace indicators;
BlockProgressBar bar1{ BlockProgressBar bar1{option::BarWidth{50}, option::ForegroundColor{Color::yellow},
option::BarWidth{50}, option::ShowElapsedTime{true}, option::ShowRemainingTime{true},
option::ForegroundColor{Color::yellow}, option::PrefixText{"Progress Bar #1 "}};
option::ShowElapsedTime{true},
option::ShowRemainingTime{true},
option::PrefixText{"Progress Bar #1 "}
};
BlockProgressBar bar2{ BlockProgressBar bar2{option::BarWidth{50}, option::ForegroundColor{Color::cyan},
option::BarWidth{50}, option::ShowElapsedTime{true}, option::ShowRemainingTime{true},
option::ForegroundColor{Color::cyan}, option::PrefixText{"Progress Bar #2 "}};
option::ShowElapsedTime{true},
option::ShowRemainingTime{true},
option::PrefixText{"Progress Bar #2 "}
};
BlockProgressBar bar3{ BlockProgressBar bar3{option::BarWidth{50}, option::ForegroundColor{Color::red},
option::BarWidth{50}, option::ShowElapsedTime{true}, option::ShowRemainingTime{true},
option::ForegroundColor{Color::red}, option::PrefixText{"Progress Bar #3 "}};
option::ShowElapsedTime{true},
option::ShowRemainingTime{true},
option::PrefixText{"Progress Bar #3 "}
};
indicators::MultiProgress<indicators::BlockProgressBar, 3> bars(bar1, bar2, bar3); indicators::MultiProgress<indicators::BlockProgressBar, 3> bars(bar1, bar2, bar3);

View File

@@ -3,8 +3,7 @@
int main() { int main() {
indicators::ProgressBar bar1{ indicators::ProgressBar bar1{indicators::option::BarWidth{50},
indicators::option::BarWidth{50},
indicators::option::Start{"["}, indicators::option::Start{"["},
indicators::option::Fill{""}, indicators::option::Fill{""},
indicators::option::Lead{""}, indicators::option::Lead{""},
@@ -13,11 +12,9 @@ int main() {
indicators::option::ForegroundColor{indicators::Color::yellow}, indicators::option::ForegroundColor{indicators::Color::yellow},
indicators::option::ShowElapsedTime{true}, indicators::option::ShowElapsedTime{true},
indicators::option::ShowRemainingTime{true}, indicators::option::ShowRemainingTime{true},
indicators::option::PrefixText{"Progress Bar #1 "} indicators::option::PrefixText{"Progress Bar #1 "}};
};
indicators::ProgressBar bar2{ indicators::ProgressBar bar2{indicators::option::BarWidth{50},
indicators::option::BarWidth{50},
indicators::option::Start{"["}, indicators::option::Start{"["},
indicators::option::Fill{"="}, indicators::option::Fill{"="},
indicators::option::Lead{">"}, indicators::option::Lead{">"},
@@ -26,11 +23,9 @@ int main() {
indicators::option::ForegroundColor{indicators::Color::cyan}, indicators::option::ForegroundColor{indicators::Color::cyan},
indicators::option::ShowElapsedTime{true}, indicators::option::ShowElapsedTime{true},
indicators::option::ShowRemainingTime{true}, indicators::option::ShowRemainingTime{true},
indicators::option::PrefixText{"Progress Bar #2 "} indicators::option::PrefixText{"Progress Bar #2 "}};
};
indicators::ProgressBar bar3{ indicators::ProgressBar bar3{indicators::option::BarWidth{50},
indicators::option::BarWidth{50},
indicators::option::Start{"["}, indicators::option::Start{"["},
indicators::option::Fill{"#"}, indicators::option::Fill{"#"},
indicators::option::Lead{"#"}, indicators::option::Lead{"#"},
@@ -39,8 +34,7 @@ int main() {
indicators::option::ForegroundColor{indicators::Color::red}, indicators::option::ForegroundColor{indicators::Color::red},
indicators::option::ShowElapsedTime{true}, indicators::option::ShowElapsedTime{true},
indicators::option::ShowRemainingTime{true}, indicators::option::ShowRemainingTime{true},
indicators::option::PrefixText{"Progress Bar #3 "} indicators::option::PrefixText{"Progress Bar #3 "}};
};
indicators::MultiProgress<indicators::ProgressBar, 3> bars(bar1, bar2, bar3); indicators::MultiProgress<indicators::ProgressBar, 3> bars(bar1, bar2, bar3);

View File

@@ -8,7 +8,8 @@ int main() {
indicators::ProgressSpinner spinner{ indicators::ProgressSpinner spinner{
indicators::option::PostfixText{"Checking credentials"}, indicators::option::PostfixText{"Checking credentials"},
indicators::option::ForegroundColor{indicators::Color::yellow}, indicators::option::ForegroundColor{indicators::Color::yellow},
indicators::option::SpinnerStates{std::vector<std::string>{"", "", "", "", "", "", "", ""}}, indicators::option::SpinnerStates{
std::vector<std::string>{"", "", "", "", "", "", "", ""}},
}; };
// Update spinner state // Update spinner state

View File

@@ -31,22 +31,22 @@ SOFTWARE.
*/ */
#pragma once #pragma once
#include <algorithm> #include <algorithm>
#include <cassert>
#include <chrono> #include <chrono>
#include <cmath>
#include <iomanip> #include <iomanip>
#include <ostream> #include <ostream>
#include <string> #include <string>
#include <vector> #include <vector>
#include <cassert>
#include <cmath>
#define NOMINMAX #define NOMINMAX
#include <algorithm> #include <algorithm>
#include <atomic> #include <atomic>
#include <tuple> #include <cstddef>
#include <iostream> #include <iostream>
#include <mutex> #include <mutex>
#include <thread> #include <thread>
#include <tuple>
#include <type_traits> #include <type_traits>
#include <cstddef>
#include <utility> #include <utility>
namespace indicators { namespace indicators {
@@ -501,7 +501,6 @@ inline void win_change_attributes(std::ostream &stream, int foreground, int back
#endif // TERMCOLOR_HPP_ #endif // TERMCOLOR_HPP_
namespace indicators { namespace indicators {
namespace details { namespace details {
@@ -558,13 +557,9 @@ inline std::ostream &write_duration(std::ostream &os, std::chrono::nanoseconds n
return os; return os;
} }
class BlockProgressScaleWriter class BlockProgressScaleWriter {
{
public: public:
BlockProgressScaleWriter(std::ostream& os, size_t bar_width) BlockProgressScaleWriter(std::ostream &os, size_t bar_width) : os(os), bar_width(bar_width) {}
: os(os)
, bar_width(bar_width)
{}
std::ostream &write(float progress) { std::ostream &write(float progress) {
std::string fill_text{""}; std::string fill_text{""};
@@ -583,25 +578,17 @@ public:
os << " "; os << " ";
return os; return os;
} }
private: private:
std::ostream &os; std::ostream &os;
size_t bar_width = 0; size_t bar_width = 0;
}; };
class ProgressScaleWriter class ProgressScaleWriter {
{
public: public:
ProgressScaleWriter(std::ostream& os, ProgressScaleWriter(std::ostream &os, size_t bar_width, const std::string &fill,
size_t bar_width, const std::string &lead, const std::string &remainder)
const std::string& fill, : os(os), bar_width(bar_width), fill(fill), lead(lead), remainder(remainder) {}
const std::string& lead,
const std::string& remainder)
: os(os)
, bar_width(bar_width)
, fill(fill)
, lead(lead)
, remainder(remainder)
{}
std::ostream &write(float progress) { std::ostream &write(float progress) {
auto pos = static_cast<size_t>(progress * static_cast<float>(bar_width) / 100.0); auto pos = static_cast<size_t>(progress * static_cast<float>(bar_width) / 100.0);
@@ -624,56 +611,44 @@ private:
std::string remainder; std::string remainder;
}; };
} } // namespace details
} } // namespace indicators
namespace indicators { namespace indicators {
namespace details { namespace details {
template <bool condition> template <bool condition> struct if_else;
struct if_else;
template<> template <> struct if_else<true> { using type = std::true_type; };
struct if_else<true>{
using type = std::true_type;
};
template<> template <> struct if_else<false> { using type = std::false_type; };
struct if_else<false>{
using type = std::false_type ;
};
template <bool condition, typename True, typename False> template <bool condition, typename True, typename False> struct if_else_type;
struct if_else_type;
template <typename True, typename False> template <typename True, typename False> struct if_else_type<true, True, False> {
struct if_else_type<true, True, False>{
using type = True; using type = True;
}; };
template <typename True, typename False> template <typename True, typename False> struct if_else_type<false, True, False> {
struct if_else_type<false, True, False>{
using type = False; using type = False;
}; };
template <typename... Ops> template <typename... Ops> struct conjuction;
struct conjuction;
template <> template <> struct conjuction<> : std::true_type {};
struct conjuction<> : std::true_type {};
template <typename Op, typename... TailOps> template <typename Op, typename... TailOps>
struct conjuction<Op, TailOps...> : if_else_type<!Op::value, std::false_type, conjuction<TailOps...>>::type {}; struct conjuction<Op, TailOps...>
: if_else_type<!Op::value, std::false_type, conjuction<TailOps...>>::type {};
template <typename... Ops> template <typename... Ops> struct disjunction;
struct disjunction;
template <> template <> struct disjunction<> : std::false_type {};
struct disjunction<> : std::false_type {};
template <typename Op, typename... TailOps> template <typename Op, typename... TailOps>
struct disjunction<Op, TailOps...> : if_else_type<Op::value, std::true_type, disjunction<TailOps...>>::type {}; struct disjunction<Op, TailOps...>
: if_else_type<Op::value, std::true_type, disjunction<TailOps...>>::type {};
enum class ProgressBarOption { enum class ProgressBarOption {
bar_width = 0, bar_width = 0,
@@ -695,9 +670,9 @@ enum class ProgressBarOption{
spinner_states spinner_states
}; };
template <typename T, ProgressBarOption Id> template <typename T, ProgressBarOption Id> struct Setting {
struct Setting{ template <typename... Args,
template <typename... Args, typename = typename std::enable_if<std::is_constructible<T, Args...>::value>::type> typename = typename std::enable_if<std::is_constructible<T, Args...>::value>::type>
explicit Setting(Args &&... args) : value(std::forward<Args>(args)...) {} explicit Setting(Args &&... args) : value(std::forward<Args>(args)...) {}
Setting(const Setting &) = default; Setting(const Setting &) = default;
Setting(Setting &&) = default; Setting(Setting &&) = default;
@@ -708,91 +683,81 @@ struct Setting{
T value{}; T value{};
}; };
template <typename T> template <typename T> struct is_setting : std::false_type {};
struct is_setting : std::false_type{};
template <ProgressBarOption Id, typename T> template <ProgressBarOption Id, typename T> struct is_setting<Setting<T, Id>> : std::true_type {};
struct is_setting<Setting<T, Id>> : std::true_type{};
template <typename... Args> template <typename... Args>
struct are_settings : if_else<conjuction<is_setting<Args>...>::value>::type {}; struct are_settings : if_else<conjuction<is_setting<Args>...>::value>::type {};
template <> template <> struct are_settings<> : std::true_type {};
struct are_settings<> : std::true_type{};
template<typename Setting, typename Tuple> template <typename Setting, typename Tuple> struct is_setting_from_tuple;
struct is_setting_from_tuple;
template<typename Setting> template <typename Setting> struct is_setting_from_tuple<Setting, std::tuple<>> : std::true_type {};
struct is_setting_from_tuple<Setting, std::tuple<>> : std::true_type {};
template <typename Setting, typename... TupleTypes> template <typename Setting, typename... TupleTypes>
struct is_setting_from_tuple<Setting, std::tuple<TupleTypes...>> : struct is_setting_from_tuple<Setting, std::tuple<TupleTypes...>>
if_else<disjunction<std::is_same<Setting, TupleTypes>...>::value>::type {}; : if_else<disjunction<std::is_same<Setting, TupleTypes>...>::value>::type {};
template <typename Tuple, typename... Settings> template <typename Tuple, typename... Settings>
struct are_settings_from_tuple : if_else<conjuction<is_setting_from_tuple<Settings, Tuple>...>::value>::type {}; struct are_settings_from_tuple
: if_else<conjuction<is_setting_from_tuple<Settings, Tuple>...>::value>::type {};
template <ProgressBarOption Id> struct always_true { static constexpr auto value = true; };
template <ProgressBarOption Id> template <ProgressBarOption Id, typename Default> Default &&get_impl(Default &&def) {
struct always_true{
static constexpr auto value = true;
};
template<ProgressBarOption Id, typename Default>
Default&& get_impl(Default&& def){
return std::forward<Default>(def); return std::forward<Default>(def);
} }
template <ProgressBarOption Id, typename Default, typename T, typename... Args> template <ProgressBarOption Id, typename Default, typename T, typename... Args>
auto get_impl(Default&& def, T&& first, Args&&... tail) -> typename std::enable_if< auto get_impl(Default &&def, T &&first, Args &&... tail) ->
(std::decay<T>::type::id == Id), typename std::enable_if<(std::decay<T>::type::id == Id),
decltype(std::forward<T>(first))> decltype(std::forward<T>(first))>::type {
::type{
return std::forward<T>(first); return std::forward<T>(first);
} }
template <ProgressBarOption Id, typename Default, typename T, typename... Args> template <ProgressBarOption Id, typename Default, typename T, typename... Args>
auto get_impl(Default&& def, T&& first, Args&&... tail) -> typename std::enable_if< auto get_impl(Default &&def, T &&first, Args &&... tail) ->
(std::decay<T>::type::id != Id), typename std::enable_if<(std::decay<T>::type::id != Id),
decltype(get_impl<Id>(std::forward<Default>(def), std::forward<Args>(tail)...))>::type{ decltype(get_impl<Id>(std::forward<Default>(def),
std::forward<Args>(tail)...))>::type {
return get_impl<Id>(std::forward<Default>(def), std::forward<Args>(tail)...); return get_impl<Id>(std::forward<Default>(def), std::forward<Args>(tail)...);
} }
template <ProgressBarOption Id, typename Default, typename... Args, typename = typename std::enable_if<are_settings<Args...>::value, void>::type> template <ProgressBarOption Id, typename Default, typename... Args,
auto get(Default&& def, Args&&... args) -> decltype(details::get_impl<Id>(std::forward<Default>(def), std::forward<Args>(args)...)){ typename = typename std::enable_if<are_settings<Args...>::value, void>::type>
auto get(Default &&def, Args &&... args)
-> decltype(details::get_impl<Id>(std::forward<Default>(def), std::forward<Args>(args)...)) {
return details::get_impl<Id>(std::forward<Default>(def), std::forward<Args>(args)...); return details::get_impl<Id>(std::forward<Default>(def), std::forward<Args>(args)...);
} }
template <ProgressBarOption Id> template <ProgressBarOption Id> using StringSetting = Setting<std::string, Id>;
using StringSetting = Setting<std::string, Id>;
template <ProgressBarOption Id> template <ProgressBarOption Id> using IntegerSetting = Setting<std::size_t, Id>;
using IntegerSetting = Setting<std::size_t, Id>;
template <ProgressBarOption Id> template <ProgressBarOption Id> using BooleanSetting = Setting<bool, Id>;
using BooleanSetting = Setting<bool, Id>;
template <ProgressBarOption Id, typename Tuple, std::size_t counter =0> template <ProgressBarOption Id, typename Tuple, std::size_t counter = 0> struct option_idx;
struct option_idx;
template <ProgressBarOption Id, typename T, typename... Settings, std::size_t counter> template <ProgressBarOption Id, typename T, typename... Settings, std::size_t counter>
struct option_idx<Id, std::tuple<T, Settings...>, counter> : if_else_type<(Id == T::id), struct option_idx<Id, std::tuple<T, Settings...>, counter>
std::integral_constant<std::size_t, counter>, : if_else_type<(Id == T::id), std::integral_constant<std::size_t, counter>,
option_idx<Id, std::tuple<Settings...>, counter + 1>>::type {}; option_idx<Id, std::tuple<Settings...>, counter + 1>>::type {};
template <ProgressBarOption Id, std::size_t counter> template <ProgressBarOption Id, std::size_t counter> struct option_idx<Id, std::tuple<>, counter> {
struct option_idx<Id, std::tuple<>, counter>{
static_assert(always_true<(ProgressBarOption)Id>::value, "No such option was found"); static_assert(always_true<(ProgressBarOption)Id>::value, "No such option was found");
}; };
template <ProgressBarOption Id, typename Settings> template <ProgressBarOption Id, typename Settings>
auto get_value(Settings&& settings) -> decltype((std::get<option_idx<Id, typename std::decay<Settings>::type>::value>(std::declval<Settings&&>()))){ auto get_value(Settings &&settings)
return std::get<option_idx<Id, typename std::decay<Settings>::type>::value>(std::forward<Settings>(settings)); -> decltype((std::get<option_idx<Id, typename std::decay<Settings>::type>::value>(
} std::declval<Settings &&>()))) {
return std::get<option_idx<Id, typename std::decay<Settings>::type>::value>(
std::forward<Settings>(settings));
} }
} // namespace details
namespace option { namespace option {
using BarWidth = details::IntegerSetting<details::ProgressBarOption::bar_width>; using BarWidth = details::IntegerSetting<details::ProgressBarOption::bar_width>;
@@ -811,67 +776,78 @@ namespace option{
using SavedStartTime = details::BooleanSetting<details::ProgressBarOption::saved_start_time>; using SavedStartTime = details::BooleanSetting<details::ProgressBarOption::saved_start_time>;
using ForegroundColor = details::Setting<Color, details::ProgressBarOption::foreground_color>; using ForegroundColor = details::Setting<Color, details::ProgressBarOption::foreground_color>;
using ShowSpinner = details::BooleanSetting<details::ProgressBarOption::spinner_show>; using ShowSpinner = details::BooleanSetting<details::ProgressBarOption::spinner_show>;
using SpinnerStates = details::Setting<std::vector<std::string>, details::ProgressBarOption::spinner_states>; using SpinnerStates =
} details::Setting<std::vector<std::string>, details::ProgressBarOption::spinner_states>;
} } // namespace option
} // namespace indicators
namespace indicators { namespace indicators {
class ProgressBar { class ProgressBar {
using Settings = std::tuple< using Settings =
option::BarWidth, std::tuple<option::BarWidth, option::PrefixText, option::PostfixText, option::Start,
option::PrefixText, option::End, option::Fill, option::Lead, option::Remainder,
option::PostfixText, option::MaxPostfixTextLen, option::Completed, option::ShowPercentage,
option::Start, option::ShowElapsedTime, option::ShowRemainingTime, option::SavedStartTime,
option::End, option::ForegroundColor>;
option::Fill,
option::Lead,
option::Remainder,
option::MaxPostfixTextLen,
option::Completed,
option::ShowPercentage,
option::ShowElapsedTime,
option::ShowRemainingTime,
option::SavedStartTime,
option::ForegroundColor
>;
public: public:
template <typename... Args, typename std::enable_if<details::are_settings_from_tuple<Settings, typename std::decay<Args>::type...>::value, void*>::type = nullptr> template <typename... Args,
explicit ProgressBar(Args&&... args) : typename std::enable_if<details::are_settings_from_tuple<
settings_( Settings, typename std::decay<Args>::type...>::value,
details::get<details::ProgressBarOption::bar_width>(option::BarWidth{100}, std::forward<Args>(args)...), void *>::type = nullptr>
details::get<details::ProgressBarOption::prefix_text>(option::PrefixText{}, std::forward<Args>(args)...), explicit ProgressBar(Args &&... args)
details::get<details::ProgressBarOption::postfix_text>(option::PostfixText{}, std::forward<Args>(args)...), : settings_(details::get<details::ProgressBarOption::bar_width>(option::BarWidth{100},
details::get<details::ProgressBarOption::start>(option::Start{"["}, std::forward<Args>(args)...), std::forward<Args>(args)...),
details::get<details::ProgressBarOption::end>(option::End{"]"}, std::forward<Args>(args)...), details::get<details::ProgressBarOption::prefix_text>(
details::get<details::ProgressBarOption::fill>(option::Fill{"="}, std::forward<Args>(args)...), option::PrefixText{}, std::forward<Args>(args)...),
details::get<details::ProgressBarOption::lead>(option::Lead{">"}, std::forward<Args>(args)...), details::get<details::ProgressBarOption::postfix_text>(
details::get<details::ProgressBarOption::remainder>(option::Remainder{" "}, std::forward<Args>(args)...), option::PostfixText{}, std::forward<Args>(args)...),
details::get<details::ProgressBarOption::max_postfix_text_len>(option::MaxPostfixTextLen{0}, std::forward<Args>(args)...), details::get<details::ProgressBarOption::start>(option::Start{"["},
details::get<details::ProgressBarOption::completed>(option::Completed{false}, std::forward<Args>(args)...), std::forward<Args>(args)...),
details::get<details::ProgressBarOption::show_percentage>(option::ShowPercentage{false} ,std::forward<Args>(args)...), details::get<details::ProgressBarOption::end>(option::End{"]"},
details::get<details::ProgressBarOption::show_elapsed_time>(option::ShowElapsedTime{false}, std::forward<Args>(args)...), std::forward<Args>(args)...),
details::get<details::ProgressBarOption::show_remaining_time>(option::ShowRemainingTime{false}, std::forward<Args>(args)...), details::get<details::ProgressBarOption::fill>(option::Fill{"="},
details::get<details::ProgressBarOption::saved_start_time>(option::SavedStartTime{false}, std::forward<Args>(args)...), std::forward<Args>(args)...),
details::get<details::ProgressBarOption::foreground_color>(option::ForegroundColor{Color::white}, std::forward<Args>(args)...) details::get<details::ProgressBarOption::lead>(option::Lead{">"},
) std::forward<Args>(args)...),
{} details::get<details::ProgressBarOption::remainder>(option::Remainder{" "},
std::forward<Args>(args)...),
details::get<details::ProgressBarOption::max_postfix_text_len>(
option::MaxPostfixTextLen{0}, std::forward<Args>(args)...),
details::get<details::ProgressBarOption::completed>(option::Completed{false},
std::forward<Args>(args)...),
details::get<details::ProgressBarOption::show_percentage>(
option::ShowPercentage{false}, std::forward<Args>(args)...),
details::get<details::ProgressBarOption::show_elapsed_time>(
option::ShowElapsedTime{false}, std::forward<Args>(args)...),
details::get<details::ProgressBarOption::show_remaining_time>(
option::ShowRemainingTime{false}, std::forward<Args>(args)...),
details::get<details::ProgressBarOption::saved_start_time>(
option::SavedStartTime{false}, std::forward<Args>(args)...),
details::get<details::ProgressBarOption::foreground_color>(
option::ForegroundColor{Color::white}, std::forward<Args>(args)...)) {}
template <typename T, details::ProgressBarOption id> template <typename T, details::ProgressBarOption id>
void set_option(details::Setting<T, id> &&setting) { void set_option(details::Setting<T, id> &&setting) {
static_assert(!std::is_same<T, typename std::decay<decltype(details::get_value<id>(std::declval<Settings>()))>::type>::value, "Setting has wrong type!"); static_assert(!std::is_same<T, typename std::decay<decltype(details::get_value<id>(
std::declval<Settings>()))>::type>::value,
"Setting has wrong type!");
std::lock_guard<std::mutex> lock(mutex_); std::lock_guard<std::mutex> lock(mutex_);
get_value<id>() = std::move(setting).value; get_value<id>() = std::move(setting).value;
} }
template <typename T, details::ProgressBarOption id> template <typename T, details::ProgressBarOption id>
void set_option(const details::Setting<T, id> &setting) { void set_option(const details::Setting<T, id> &setting) {
static_assert(!std::is_same<T, typename std::decay<decltype(details::get_value<id>(std::declval<Settings>()))>::type>::value, "Setting has wrong type!"); static_assert(!std::is_same<T, typename std::decay<decltype(details::get_value<id>(
std::declval<Settings>()))>::type>::value,
"Setting has wrong type!");
std::lock_guard<std::mutex> lock(mutex_); std::lock_guard<std::mutex> lock(mutex_);
get_value<id>() = setting.value; get_value<id>() = setting.value;
} }
void set_option(const details::Setting<std::string, details::ProgressBarOption::postfix_text>& setting){ void set_option(
const details::Setting<std::string, details::ProgressBarOption::postfix_text> &setting) {
std::lock_guard<std::mutex> lock(mutex_); std::lock_guard<std::mutex> lock(mutex_);
get_value<details::ProgressBarOption::postfix_text>() = setting.value; get_value<details::ProgressBarOption::postfix_text>() = setting.value;
if (setting.value.length() > get_value<details::ProgressBarOption::max_postfix_text_len>()) { if (setting.value.length() > get_value<details::ProgressBarOption::max_postfix_text_len>()) {
@@ -879,7 +855,8 @@ public:
} }
} }
void set_option(details::Setting<std::string, details::ProgressBarOption::postfix_text>&& setting){ void
set_option(details::Setting<std::string, details::ProgressBarOption::postfix_text> &&setting) {
std::lock_guard<std::mutex> lock(mutex_); std::lock_guard<std::mutex> lock(mutex_);
get_value<details::ProgressBarOption::postfix_text>() = std::move(setting).value; get_value<details::ProgressBarOption::postfix_text>() = std::move(setting).value;
auto &new_value = get_value<details::ProgressBarOption::postfix_text>(); auto &new_value = get_value<details::ProgressBarOption::postfix_text>();
@@ -920,14 +897,14 @@ public:
} }
private: private:
template <details::ProgressBarOption id> template <details::ProgressBarOption id>
auto get_value() -> decltype((details::get_value<id>(std::declval<Settings &>()).value)) { auto get_value() -> decltype((details::get_value<id>(std::declval<Settings &>()).value)) {
return details::get_value<id>(settings_).value; return details::get_value<id>(settings_).value;
} }
template <details::ProgressBarOption id> template <details::ProgressBarOption id>
auto get_value() const -> decltype((details::get_value<id>(std::declval<const Settings&>()).value)) { auto get_value() const
-> decltype((details::get_value<id>(std::declval<const Settings &>()).value)) {
return details::get_value<id>(settings_).value; return details::get_value<id>(settings_).value;
} }
@@ -968,7 +945,8 @@ private:
std::cout << get_value<details::ProgressBarOption::start>(); std::cout << get_value<details::ProgressBarOption::start>();
details::ProgressScaleWriter writer{std::cout, get_value<details::ProgressBarOption::bar_width>(), details::ProgressScaleWriter writer{std::cout,
get_value<details::ProgressBarOption::bar_width>(),
get_value<details::ProgressBarOption::fill>(), get_value<details::ProgressBarOption::fill>(),
get_value<details::ProgressBarOption::lead>(), get_value<details::ProgressBarOption::lead>(),
get_value<details::ProgressBarOption::remainder>()}; get_value<details::ProgressBarOption::remainder>()};
@@ -1002,12 +980,15 @@ private:
if (get_value<details::ProgressBarOption::max_postfix_text_len>() == 0) if (get_value<details::ProgressBarOption::max_postfix_text_len>() == 0)
get_value<details::ProgressBarOption::max_postfix_text_len>() = 10; get_value<details::ProgressBarOption::max_postfix_text_len>() = 10;
std::cout << " " << get_value<details::ProgressBarOption::postfix_text>() << std::string(get_value<details::ProgressBarOption::max_postfix_text_len>(), ' ') << "\r"; std::cout << " " << get_value<details::ProgressBarOption::postfix_text>()
<< std::string(get_value<details::ProgressBarOption::max_postfix_text_len>(), ' ')
<< "\r";
std::cout.flush(); std::cout.flush();
if (progress_ > 100.0) { if (progress_ > 100.0) {
get_value<details::ProgressBarOption::completed>() = true; get_value<details::ProgressBarOption::completed>() = true;
} }
if (get_value<details::ProgressBarOption::completed>() && !from_multi_progress) // Don't std::endl if calling from MultiProgress if (get_value<details::ProgressBarOption::completed>() &&
!from_multi_progress) // Don't std::endl if calling from MultiProgress
std::cout << termcolor::reset << std::endl; std::cout << termcolor::reset << std::endl;
} }
}; };
@@ -1017,51 +998,62 @@ private:
namespace indicators { namespace indicators {
class BlockProgressBar { class BlockProgressBar {
using Settings = std::tuple< using Settings = std::tuple<option::ForegroundColor, option::BarWidth, option::Start, option::End,
option::ForegroundColor, option::PrefixText, option::PostfixText, option::ShowPercentage,
option::BarWidth, option::ShowElapsedTime, option::ShowRemainingTime, option::Completed,
option::Start, option::SavedStartTime, option::MaxPostfixTextLen>;
option::End,
option::PrefixText,
option::PostfixText,
option::ShowPercentage,
option::ShowElapsedTime,
option::ShowRemainingTime,
option::Completed,
option::SavedStartTime,
option::MaxPostfixTextLen>;
public: public:
template <typename... Args, typename std::enable_if<details::are_settings_from_tuple<Settings, typename std::decay<Args>::type...>::value, void*>::type = nullptr> template <typename... Args,
explicit BlockProgressBar(Args&&... args) : settings_( typename std::enable_if<details::are_settings_from_tuple<
details::get<details::ProgressBarOption::foreground_color>(option::ForegroundColor{Color::white}, std::forward<Args>(args)...), Settings, typename std::decay<Args>::type...>::value,
details::get<details::ProgressBarOption::bar_width>(option::BarWidth{100}, std::forward<Args>(args)...), void *>::type = nullptr>
details::get<details::ProgressBarOption::start>(option::Start{"["}, std::forward<Args>(args)...), explicit BlockProgressBar(Args &&... args)
details::get<details::ProgressBarOption::end>(option::End{"]"}, std::forward<Args>(args)...), : settings_(details::get<details::ProgressBarOption::foreground_color>(
details::get<details::ProgressBarOption::prefix_text>(option::PrefixText{""}, std::forward<Args>(args)...), option::ForegroundColor{Color::white}, std::forward<Args>(args)...),
details::get<details::ProgressBarOption::postfix_text>(option::PostfixText{""}, std::forward<Args>(args)...), details::get<details::ProgressBarOption::bar_width>(option::BarWidth{100},
details::get<details::ProgressBarOption::show_percentage>(option::ShowPercentage{true}, std::forward<Args>(args)...), std::forward<Args>(args)...),
details::get<details::ProgressBarOption::show_elapsed_time>(option::ShowElapsedTime{false}, std::forward<Args>(args)...), details::get<details::ProgressBarOption::start>(option::Start{"["},
details::get<details::ProgressBarOption::show_remaining_time>(option::ShowRemainingTime{false}, std::forward<Args>(args)...), std::forward<Args>(args)...),
details::get<details::ProgressBarOption::completed>(option::Completed{false}, std::forward<Args>(args)...), details::get<details::ProgressBarOption::end>(option::End{"]"},
details::get<details::ProgressBarOption::saved_start_time>(option::SavedStartTime{false}, std::forward<Args>(args)...), std::forward<Args>(args)...),
details::get<details::ProgressBarOption::max_postfix_text_len>(option::MaxPostfixTextLen{0}, std::forward<Args>(args)...) details::get<details::ProgressBarOption::prefix_text>(
) {} option::PrefixText{""}, std::forward<Args>(args)...),
details::get<details::ProgressBarOption::postfix_text>(
option::PostfixText{""}, std::forward<Args>(args)...),
details::get<details::ProgressBarOption::show_percentage>(
option::ShowPercentage{true}, std::forward<Args>(args)...),
details::get<details::ProgressBarOption::show_elapsed_time>(
option::ShowElapsedTime{false}, std::forward<Args>(args)...),
details::get<details::ProgressBarOption::show_remaining_time>(
option::ShowRemainingTime{false}, std::forward<Args>(args)...),
details::get<details::ProgressBarOption::completed>(option::Completed{false},
std::forward<Args>(args)...),
details::get<details::ProgressBarOption::saved_start_time>(
option::SavedStartTime{false}, std::forward<Args>(args)...),
details::get<details::ProgressBarOption::max_postfix_text_len>(
option::MaxPostfixTextLen{0}, std::forward<Args>(args)...)) {}
template <typename T, details::ProgressBarOption id> template <typename T, details::ProgressBarOption id>
void set_option(details::Setting<T, id> &&setting) { void set_option(details::Setting<T, id> &&setting) {
static_assert(!std::is_same<T, typename std::decay<decltype(details::get_value<id>(std::declval<Settings>()))>::type>::value, "Setting has wrong type!"); static_assert(!std::is_same<T, typename std::decay<decltype(details::get_value<id>(
std::declval<Settings>()))>::type>::value,
"Setting has wrong type!");
std::lock_guard<std::mutex> lock(mutex_); std::lock_guard<std::mutex> lock(mutex_);
get_value<id>() = std::move(setting).value; get_value<id>() = std::move(setting).value;
} }
template <typename T, details::ProgressBarOption id> template <typename T, details::ProgressBarOption id>
void set_option(const details::Setting<T, id> &setting) { void set_option(const details::Setting<T, id> &setting) {
static_assert(!std::is_same<T, typename std::decay<decltype(details::get_value<id>(std::declval<Settings>()))>::type>::value, "Setting has wrong type!"); static_assert(!std::is_same<T, typename std::decay<decltype(details::get_value<id>(
std::declval<Settings>()))>::type>::value,
"Setting has wrong type!");
std::lock_guard<std::mutex> lock(mutex_); std::lock_guard<std::mutex> lock(mutex_);
get_value<id>() = setting.value; get_value<id>() = setting.value;
} }
void set_option(const details::Setting<std::string, details::ProgressBarOption::postfix_text>& setting){ void set_option(
const details::Setting<std::string, details::ProgressBarOption::postfix_text> &setting) {
std::lock_guard<std::mutex> lock(mutex_); std::lock_guard<std::mutex> lock(mutex_);
get_value<details::ProgressBarOption::postfix_text>() = setting.value; get_value<details::ProgressBarOption::postfix_text>() = setting.value;
if (setting.value.length() > get_value<details::ProgressBarOption::max_postfix_text_len>()) { if (setting.value.length() > get_value<details::ProgressBarOption::max_postfix_text_len>()) {
@@ -1069,7 +1061,8 @@ public:
} }
} }
void set_option(details::Setting<std::string, details::ProgressBarOption::postfix_text>&& setting){ void
set_option(details::Setting<std::string, details::ProgressBarOption::postfix_text> &&setting) {
std::lock_guard<std::mutex> lock(mutex_); std::lock_guard<std::mutex> lock(mutex_);
get_value<details::ProgressBarOption::postfix_text>() = std::move(setting).value; get_value<details::ProgressBarOption::postfix_text>() = std::move(setting).value;
auto &new_value = get_value<details::ProgressBarOption::postfix_text>(); auto &new_value = get_value<details::ProgressBarOption::postfix_text>();
@@ -1109,14 +1102,14 @@ public:
} }
private: private:
template <details::ProgressBarOption id> template <details::ProgressBarOption id>
auto get_value() -> decltype((details::get_value<id>(std::declval<Settings &>()).value)) { auto get_value() -> decltype((details::get_value<id>(std::declval<Settings &>()).value)) {
return details::get_value<id>(settings_).value; return details::get_value<id>(settings_).value;
} }
template <details::ProgressBarOption id> template <details::ProgressBarOption id>
auto get_value() const -> decltype((details::get_value<id>(std::declval<const Settings&>()).value)) { auto get_value() const
-> decltype((details::get_value<id>(std::declval<const Settings &>()).value)) {
return details::get_value<id>(settings_).value; return details::get_value<id>(settings_).value;
} }
@@ -1154,7 +1147,8 @@ private:
std::cout << get_value<details::ProgressBarOption::prefix_text>(); std::cout << get_value<details::ProgressBarOption::prefix_text>();
std::cout << get_value<details::ProgressBarOption::start>(); std::cout << get_value<details::ProgressBarOption::start>();
details::BlockProgressScaleWriter writer{std::cout, get_value<details::ProgressBarOption::bar_width>()}; details::BlockProgressScaleWriter writer{std::cout,
get_value<details::ProgressBarOption::bar_width>()};
writer.write(progress_); writer.write(progress_);
std::cout << get_value<details::ProgressBarOption::end>(); std::cout << get_value<details::ProgressBarOption::end>();
@@ -1184,12 +1178,15 @@ private:
if (get_value<details::ProgressBarOption::max_postfix_text_len>() == 0) if (get_value<details::ProgressBarOption::max_postfix_text_len>() == 0)
get_value<details::ProgressBarOption::max_postfix_text_len>() = 10; get_value<details::ProgressBarOption::max_postfix_text_len>() = 10;
std::cout << " " << get_value<details::ProgressBarOption::postfix_text>() << std::string(get_value<details::ProgressBarOption::max_postfix_text_len>(), ' ') << "\r"; std::cout << " " << get_value<details::ProgressBarOption::postfix_text>()
<< std::string(get_value<details::ProgressBarOption::max_postfix_text_len>(), ' ')
<< "\r";
std::cout.flush(); std::cout.flush();
if (progress_ > 100.0) { if (progress_ > 100.0) {
get_value<details::ProgressBarOption::completed>() = true; get_value<details::ProgressBarOption::completed>() = true;
} }
if (get_value<details::ProgressBarOption::completed>() && !from_multi_progress) // Don't std::endl if calling from MultiProgress if (get_value<details::ProgressBarOption::completed>() &&
!from_multi_progress) // Don't std::endl if calling from MultiProgress
std::cout << termcolor::reset << std::endl; std::cout << termcolor::reset << std::endl;
} }
}; };
@@ -1199,50 +1196,63 @@ private:
namespace indicators { namespace indicators {
class ProgressSpinner { class ProgressSpinner {
using Settings = std::tuple< using Settings =
option::ForegroundColor, std::tuple<option::ForegroundColor, option::PrefixText, option::PostfixText,
option::PrefixText, option::ShowPercentage, option::ShowElapsedTime, option::ShowRemainingTime,
option::PostfixText, option::ShowSpinner, option::SavedStartTime, option::Completed,
option::ShowPercentage, option::MaxPostfixTextLen, option::SpinnerStates>;
option::ShowElapsedTime,
option::ShowRemainingTime,
option::ShowSpinner,
option::SavedStartTime,
option::Completed,
option::MaxPostfixTextLen,
option::SpinnerStates
>;
public: public:
template <typename... Args, typename std::enable_if<details::are_settings_from_tuple<Settings, typename std::decay<Args>::type...>::value, void*>::type = nullptr> template <typename... Args,
explicit ProgressSpinner(Args&&... args) : settings_( typename std::enable_if<details::are_settings_from_tuple<
details::get<details::ProgressBarOption::foreground_color>(option::ForegroundColor{Color::white}, std::forward<Args>(args)...), Settings, typename std::decay<Args>::type...>::value,
details::get<details::ProgressBarOption::prefix_text>(option::PrefixText{}, std::forward<Args>(args)...), void *>::type = nullptr>
details::get<details::ProgressBarOption::postfix_text>(option::PostfixText{}, std::forward<Args>(args)...), explicit ProgressSpinner(Args &&... args)
details::get<details::ProgressBarOption::show_percentage>(option::ShowPercentage{true}, std::forward<Args>(args)...), : settings_(details::get<details::ProgressBarOption::foreground_color>(
details::get<details::ProgressBarOption::show_elapsed_time>(option::ShowElapsedTime{false}, std::forward<Args>(args)...), option::ForegroundColor{Color::white}, std::forward<Args>(args)...),
details::get<details::ProgressBarOption::show_remaining_time>(option::ShowRemainingTime{false}, std::forward<Args>(args)...), details::get<details::ProgressBarOption::prefix_text>(
details::get<details::ProgressBarOption::spinner_show>(option::ShowSpinner{true}, std::forward<Args>(args)...), option::PrefixText{}, std::forward<Args>(args)...),
details::get<details::ProgressBarOption::saved_start_time>(option::SavedStartTime{false}, std::forward<Args>(args)...), details::get<details::ProgressBarOption::postfix_text>(
details::get<details::ProgressBarOption::completed>(option::Completed{false}, std::forward<Args>(args)...), option::PostfixText{}, std::forward<Args>(args)...),
details::get<details::ProgressBarOption::max_postfix_text_len>(option::MaxPostfixTextLen{0}, std::forward<Args>(args)...), details::get<details::ProgressBarOption::show_percentage>(
details::get<details::ProgressBarOption::spinner_states>(option::SpinnerStates{std::vector<std::string>{"", "", "", "", "", "", "", "", "", ""}}, std::forward<Args>(args)...) option::ShowPercentage{true}, std::forward<Args>(args)...),
){} details::get<details::ProgressBarOption::show_elapsed_time>(
option::ShowElapsedTime{false}, std::forward<Args>(args)...),
details::get<details::ProgressBarOption::show_remaining_time>(
option::ShowRemainingTime{false}, std::forward<Args>(args)...),
details::get<details::ProgressBarOption::spinner_show>(
option::ShowSpinner{true}, std::forward<Args>(args)...),
details::get<details::ProgressBarOption::saved_start_time>(
option::SavedStartTime{false}, std::forward<Args>(args)...),
details::get<details::ProgressBarOption::completed>(option::Completed{false},
std::forward<Args>(args)...),
details::get<details::ProgressBarOption::max_postfix_text_len>(
option::MaxPostfixTextLen{0}, std::forward<Args>(args)...),
details::get<details::ProgressBarOption::spinner_states>(
option::SpinnerStates{std::vector<std::string>{"", "", "", "", "", "",
"", "", "", ""}},
std::forward<Args>(args)...)) {}
template <typename T, details::ProgressBarOption id> template <typename T, details::ProgressBarOption id>
void set_option(details::Setting<T, id> &&setting) { void set_option(details::Setting<T, id> &&setting) {
static_assert(!std::is_same<T, typename std::decay<decltype(details::get_value<id>(std::declval<Settings>()))>::type>::value, "Setting has wrong type!"); static_assert(!std::is_same<T, typename std::decay<decltype(details::get_value<id>(
std::declval<Settings>()))>::type>::value,
"Setting has wrong type!");
std::lock_guard<std::mutex> lock(mutex_); std::lock_guard<std::mutex> lock(mutex_);
get_value<id>() = std::move(setting).value; get_value<id>() = std::move(setting).value;
} }
template <typename T, details::ProgressBarOption id> template <typename T, details::ProgressBarOption id>
void set_option(const details::Setting<T, id> &setting) { void set_option(const details::Setting<T, id> &setting) {
static_assert(!std::is_same<T, typename std::decay<decltype(details::get_value<id>(std::declval<Settings>()))>::type>::value, "Setting has wrong type!"); static_assert(!std::is_same<T, typename std::decay<decltype(details::get_value<id>(
std::declval<Settings>()))>::type>::value,
"Setting has wrong type!");
std::lock_guard<std::mutex> lock(mutex_); std::lock_guard<std::mutex> lock(mutex_);
get_value<id>() = setting.value; get_value<id>() = setting.value;
} }
void set_option(const details::Setting<std::string, details::ProgressBarOption::postfix_text>& setting){ void set_option(
const details::Setting<std::string, details::ProgressBarOption::postfix_text> &setting) {
std::lock_guard<std::mutex> lock(mutex_); std::lock_guard<std::mutex> lock(mutex_);
get_value<details::ProgressBarOption::postfix_text>() = setting.value; get_value<details::ProgressBarOption::postfix_text>() = setting.value;
if (setting.value.length() > get_value<details::ProgressBarOption::max_postfix_text_len>()) { if (setting.value.length() > get_value<details::ProgressBarOption::max_postfix_text_len>()) {
@@ -1250,7 +1260,8 @@ public:
} }
} }
void set_option(details::Setting<std::string, details::ProgressBarOption::postfix_text>&& setting){ void
set_option(details::Setting<std::string, details::ProgressBarOption::postfix_text> &&setting) {
std::lock_guard<std::mutex> lock(mutex_); std::lock_guard<std::mutex> lock(mutex_);
get_value<details::ProgressBarOption::postfix_text>() = std::move(setting).value; get_value<details::ProgressBarOption::postfix_text>() = std::move(setting).value;
auto &new_value = get_value<details::ProgressBarOption::postfix_text>(); auto &new_value = get_value<details::ProgressBarOption::postfix_text>();
@@ -1302,7 +1313,8 @@ private:
} }
template <details::ProgressBarOption id> template <details::ProgressBarOption id>
auto get_value() const -> decltype((details::get_value<id>(std::declval<const Settings&>()).value)) { auto get_value() const
-> decltype((details::get_value<id>(std::declval<const Settings &>()).value)) {
return details::get_value<id>(settings_).value; return details::get_value<id>(settings_).value;
} }
@@ -1325,7 +1337,8 @@ private:
details::set_stream_color(std::cout, get_value<details::ProgressBarOption::foreground_color>()); details::set_stream_color(std::cout, get_value<details::ProgressBarOption::foreground_color>());
std::cout << get_value<details::ProgressBarOption::prefix_text>(); std::cout << get_value<details::ProgressBarOption::prefix_text>();
if (get_value<details::ProgressBarOption::spinner_show>()) if (get_value<details::ProgressBarOption::spinner_show>())
std::cout << get_value<details::ProgressBarOption::spinner_states>()[index_ % get_value<details::ProgressBarOption::spinner_states>().size()]; std::cout << get_value<details::ProgressBarOption::spinner_states>()
[index_ % get_value<details::ProgressBarOption::spinner_states>().size()];
if (get_value<details::ProgressBarOption::show_percentage>()) { if (get_value<details::ProgressBarOption::show_percentage>()) {
std::cout << " " << std::min(static_cast<size_t>(progress_), size_t(100)) << "%"; std::cout << " " << std::min(static_cast<size_t>(progress_), size_t(100)) << "%";
} }
@@ -1352,7 +1365,9 @@ private:
if (get_value<details::ProgressBarOption::max_postfix_text_len>() == 0) if (get_value<details::ProgressBarOption::max_postfix_text_len>() == 0)
get_value<details::ProgressBarOption::max_postfix_text_len>() = 10; get_value<details::ProgressBarOption::max_postfix_text_len>() = 10;
std::cout << " " << get_value<details::ProgressBarOption::postfix_text>() << std::string(get_value<details::ProgressBarOption::max_postfix_text_len>(), ' ') << "\r"; std::cout << " " << get_value<details::ProgressBarOption::postfix_text>()
<< std::string(get_value<details::ProgressBarOption::max_postfix_text_len>(), ' ')
<< "\r";
std::cout.flush(); std::cout.flush();
index_ += 1; index_ += 1;
if (progress_ > 100.0) { if (progress_ > 100.0) {