From 201ce9c4fb669049402ccd1b4bb4e1a9ed236b23 Mon Sep 17 00:00:00 2001
From: Pranav Srinivas Kumar
Date: Sat, 22 Feb 2020 11:13:04 +0530
Subject: [PATCH] Bumped to v1.8
---
CMakeLists.txt | 2 +-
README.md | 2 +-
single_include/indicators/indicators.hpp | 199 ++++++++++++++++++-----
3 files changed, 159 insertions(+), 44 deletions(-)
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 528bcfd..3965793 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -4,7 +4,7 @@ if(DEFINED PROJECT_NAME)
set(INDICATORS_SUBPROJECT ON)
endif()
-project(indicators VERSION 1.7.0 LANGUAGES CXX
+project(indicators VERSION 1.8.0 LANGUAGES CXX
HOMEPAGE_URL "https://github.com/p-ranav/indicators"
DESCRIPTION "Activity Indicators for Modern C++")
diff --git a/README.md b/README.md
index 528ce9f..1389b77 100644
--- a/README.md
+++ b/README.md
@@ -12,7 +12,7 @@
-
+
diff --git a/single_include/indicators/indicators.hpp b/single_include/indicators/indicators.hpp
index 42453cb..be0e964 100644
--- a/single_include/indicators/indicators.hpp
+++ b/single_include/indicators/indicators.hpp
@@ -502,6 +502,8 @@ inline void win_change_attributes(std::ostream &stream, int foreground, int back
#endif // TERMCOLOR_HPP_
+// details/stream_helper.hpp
+
namespace indicators {
namespace details {
@@ -591,8 +593,8 @@ public:
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) {
- auto pos = static_cast(progress * static_cast(bar_width) / 100.0);
+ std::ostream &write(size_t progress) {
+ auto pos = static_cast(progress * bar_width / 100.0);
for (size_t i = 0; i < bar_width; ++i) {
if (i < pos)
os << fill;
@@ -615,32 +617,9 @@ private:
} // namespace details
} // namespace indicators
-/*
-Activity Indicators for Modern C++
-https://github.com/p-ranav/indicators
-
-Licensed under the MIT License .
-SPDX-License-Identifier: MIT
-Copyright (c) 2019 Dawid Pilarski .
-
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in all
-copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
-SOFTWARE.
-*/
+//
+// setting.hpp
+//
namespace indicators {
@@ -695,7 +674,8 @@ enum class ProgressBarOption {
saved_start_time,
foreground_color,
spinner_show,
- spinner_states
+ spinner_states,
+ hide_bar_when_complete
};
template struct Setting {
@@ -806,9 +786,15 @@ using ForegroundColor = details::Setting;
using SpinnerStates =
details::Setting, details::ProgressBarOption::spinner_states>;
+using HideBarWhenComplete =
+ details::BooleanSetting;
} // namespace option
} // namespace indicators
+//
+// progress_bar.hpp
+//
+
namespace indicators {
class ProgressBar {
@@ -893,9 +879,9 @@ public:
}
}
- void set_progress(float new_progress) {
+ void set_progress(size_t new_progress) {
{
- std::lock_guard lck(mutex_);
+ std::lock_guard lock(mutex_);
progress_ = new_progress;
}
@@ -914,7 +900,7 @@ public:
size_t current() {
std::lock_guard lock{mutex_};
- return std::min(static_cast(progress_), size_t(100));
+ return std::min(progress_, size_t(100));
}
bool is_completed() const { return get_value(); }
@@ -936,13 +922,14 @@ private:
return details::get_value(settings_).value;
}
- float progress_{0};
+ size_t progress_{0};
Settings settings_;
std::chrono::nanoseconds elapsed_;
std::chrono::time_point start_time_point_;
std::mutex mutex_;
template friend class MultiProgress;
+ template friend class DynamicProgress;
std::atomic multi_progress_mode_{false};
void save_start_time() {
@@ -956,13 +943,13 @@ private:
}
void print_progress(bool from_multi_progress = false) {
+ std::lock_guard lock{mutex_};
if (multi_progress_mode_ && !from_multi_progress) {
- if (progress_ > 100.0) {
+ if (progress_ > 100) {
get_value() = true;
}
return;
}
- std::lock_guard lock{mutex_};
auto now = std::chrono::high_resolution_clock::now();
if (!get_value())
elapsed_ = std::chrono::duration_cast(now - start_time_point_);
@@ -983,7 +970,7 @@ private:
std::cout << get_value();
if (get_value()) {
- std::cout << " " << std::min(static_cast(progress_), size_t(100)) << "%";
+ std::cout << " " << std::min(progress_, size_t(100)) << "%";
}
if (get_value()) {
@@ -1012,7 +999,7 @@ private:
<< std::string(get_value(), ' ')
<< "\r";
std::cout.flush();
- if (progress_ > 100.0) {
+ if (progress_ > 100) {
get_value() = true;
}
if (get_value() &&
@@ -1023,6 +1010,10 @@ private:
} // namespace indicators
+//
+// block_progress_bar.hpp
+//
+
namespace indicators {
class BlockProgressBar {
@@ -1147,6 +1138,7 @@ private:
std::mutex mutex_;
template friend class MultiProgress;
+ template friend class DynamicProgress;
std::atomic multi_progress_mode_{false};
void save_start_time() {
@@ -1221,6 +1213,10 @@ private:
} // namespace indicators
+//
+// progress_spinner.hpp
+//
+
namespace indicators {
class ProgressSpinner {
@@ -1298,7 +1294,7 @@ public:
}
}
- void set_progress(float value) {
+ void set_progress(size_t value) {
{
std::lock_guard lock{mutex_};
progress_ = value;
@@ -1318,7 +1314,7 @@ public:
size_t current() {
std::lock_guard lock{mutex_};
- return std::min(static_cast(progress_), size_t(100));
+ return std::min(progress_, size_t(100));
}
bool is_completed() const { return get_value(); }
@@ -1330,7 +1326,7 @@ public:
private:
Settings settings_;
- float progress_{0.0};
+ size_t progress_{0};
size_t index_{0};
std::chrono::time_point start_time_point_;
std::mutex mutex_;
@@ -1368,7 +1364,7 @@ private:
std::cout << get_value()
[index_ % get_value().size()];
if (get_value()) {
- std::cout << " " << std::min(static_cast(progress_), size_t(100)) << "%";
+ std::cout << " " << std::min(progress_, size_t(100)) << "%";
}
if (get_value()) {
@@ -1398,7 +1394,7 @@ private:
<< "\r";
std::cout.flush();
index_ += 1;
- if (progress_ > 100.0) {
+ if (progress_ > 100) {
get_value() = true;
}
if (get_value())
@@ -1408,6 +1404,10 @@ private:
} // namespace indicators
+//
+// multi_progress.hpp
+//
+
namespace indicators {
template class MultiProgress {
@@ -1421,6 +1421,13 @@ public:
}
}
+ template
+ typename std::enable_if<(index >= 0 && index < count), void>::type set_progress(size_t value) {
+ if (!bars_[index].get().is_completed())
+ bars_[index].get().set_progress(value);
+ print_progress();
+ }
+
template
typename std::enable_if<(index >= 0 && index < count), void>::type set_progress(float value) {
if (!bars_[index].get().is_completed())
@@ -1468,3 +1475,111 @@ private:
};
} // namespace indicators
+
+//
+// dynamic_progress.hpp
+//
+
+namespace indicators {
+
+template class DynamicProgress {
+ using Settings = std::tuple;
+
+public:
+ template explicit DynamicProgress(Indicators &... bars) {
+ bars_ = {bars...};
+ for (auto &bar : bars_) {
+ bar.get().multi_progress_mode_ = true;
+ ++total_count_;
+ ++incomplete_count_;
+ }
+ }
+
+ Indicator &operator[](size_t index) {
+ print_progress();
+ std::lock_guard lock{mutex_};
+ return bars_[index].get();
+ }
+
+ size_t push_back(Indicator &bar) {
+ std::lock_guard lock{mutex_};
+ bar.multi_progress_mode_ = true;
+ bars_.push_back(bar);
+ return bars_.size() - 1;
+ }
+
+ template
+ void set_option(details::Setting &&setting) {
+ static_assert(!std::is_same(
+ std::declval()))>::type>::value,
+ "Setting has wrong type!");
+ std::lock_guard lock(mutex_);
+ get_value() = std::move(setting).value;
+ }
+
+ template
+ void set_option(const details::Setting &setting) {
+ static_assert(!std::is_same(
+ std::declval()))>::type>::value,
+ "Setting has wrong type!");
+ std::lock_guard lock(mutex_);
+ get_value() = setting.value;
+ }
+
+private:
+ Settings settings_;
+ std::atomic started_{false};
+ std::mutex mutex_;
+ std::vector> bars_;
+ std::atomic total_count_{0};
+ std::atomic incomplete_count_{0};
+
+ template
+ auto get_value() -> decltype((details::get_value(std::declval()).value)) {
+ return details::get_value(settings_).value;
+ }
+
+ template
+ auto get_value() const
+ -> decltype((details::get_value(std::declval()).value)) {
+ return details::get_value(settings_).value;
+ }
+
+ void print_progress() {
+ std::lock_guard lock{mutex_};
+ auto &hide_bar_when_complete = get_value();
+ if (hide_bar_when_complete) {
+ // Hide completed bars
+ if (started_) {
+ for (size_t i = 0; i < incomplete_count_; ++i)
+ std::cout << "\033[A\r\033[K" << std::flush;
+ }
+ incomplete_count_ = 0;
+ for (auto &bar : bars_) {
+ if (!bar.get().is_completed()) {
+ bar.get().print_progress(true);
+ std::cout << "\n";
+ ++incomplete_count_;
+ }
+ }
+ if (!started_)
+ started_ = true;
+ } else {
+ // Don't hide any bars
+ if (started_) {
+ for (size_t i = 0; i < total_count_; ++i)
+ std::cout << "\x1b[A";
+ }
+ for (auto &bar : bars_) {
+ bar.get().print_progress(true);
+ std::cout << "\n";
+ }
+ if (!started_)
+ started_ = true;
+ }
+ total_count_ = bars_.size();
+ std::cout << termcolor::reset;
+ }
+};
+
+} // namespace indicators