From 6e0753579e6cdf0f551cdcfcb2bff3059d0d3c2b Mon Sep 17 00:00:00 2001 From: Sven Willner Date: Sat, 17 Jun 2017 21:08:17 +0200 Subject: [PATCH 1/2] fixed unicode output --- .gitignore | 1 + include/tqdm/tqdm.h | 50 +++++++++++++++++++++++-------------------- include/tqdm/utils.h | 9 -------- test/test-example.cpp | 13 +++++++++-- 4 files changed, 39 insertions(+), 34 deletions(-) diff --git a/.gitignore b/.gitignore index 840d8fb..8f81ffc 100644 --- a/.gitignore +++ b/.gitignore @@ -2,3 +2,4 @@ obj/ bin/ lib/ src/stdafx.h.gch +build/ diff --git a/include/tqdm/tqdm.h b/include/tqdm/tqdm.h index 914882c..80d1bc7 100644 --- a/include/tqdm/tqdm.h +++ b/include/tqdm/tqdm.h @@ -31,7 +31,9 @@ Includes a default range iterator printing to stderr. #include // is_pointer, ... #include // swap #include // function -// #include // wchar_t (TODO: stdafx, use for unicode!) +#include +#include +#include #include "tqdm/utils.h" namespace tqdm { @@ -131,17 +133,11 @@ template class Tqdm : public IteratorWrapper<_Iterator> { sp["\n"]; } - template ::value || - std::is_same::value>::type> - // TODO - static String format_meter(difference_type n, difference_type total, - float elapsed, int ncols, const String &prefix, - const String &ascii, const String &unit, +static std::string format_meter(difference_type n, difference_type total, + float elapsed, int ncols, const std::string &prefix, + const std::string &ascii, const std::string &unit, bool unit_scale, float rate, - const String &bar_format) { - typedef typename String::value_type Char; + const std::string &bar_format) { // sanity check: total if (n > total) total = -1; @@ -194,13 +190,13 @@ template class Tqdm : public IteratorWrapper<_Iterator> { rate <= 0 ? "?" : format_interval(size_t((total - n) / rate)); // format the stats displayed to the left and right sides of the bar - String l_bar; + std::string l_bar; char reserve[256]; sprintf_s(reserve, "%s%3.0f%%%s", prefix.empty() ? "" : (prefix + ": ").c_str(), percentage, ncols > 0 ? "|" : ""); l_bar = reserve; - String r_bar = String(ncols > 0 ? "|" : "") + " " + n_fmt + "/" + + std::string r_bar = std::string(ncols > 0 ? "|" : "") + " " + n_fmt + "/" + total_fmt + " [" + elapsed_str + "<" + remaining_str + ", " + rate_fmt + "]"; if (ncols <= 0) @@ -251,33 +247,41 @@ template class Tqdm : public IteratorWrapper<_Iterator> { : 10; int bar_length, frac_bar_length; - String bar; - Char frac_bar; + std::string bar; + std::string frac_bar; // format bar depending on availability of unicode/ascii chars if (!ascii.empty()) { std::tie(bar_length, frac_bar_length) = divmod(int(frac * N_BARS * int(ascii.size() - 1)), int(ascii.size() - 1)); - bar = String(bar_length, Char(ascii.back())); + bar = std::string(bar_length, ascii.back()); frac_bar = frac_bar_length ? 48 + frac_bar_length : ' '; } else { std::tie(bar_length, frac_bar_length) = divmod(int(frac * N_BARS * 8), 8); - bar = String(bar_length, Char(0x2588)); - frac_bar = frac_bar_length ? Char(0x2590 - frac_bar_length) : ' '; + for (int i = 0; i < bar_length; ++i) { + bar += "\u2588"; + } + if (frac_bar_length) { + char u[4] = "\u2590"; + u[2] -= frac_bar_length; + frac_bar = u; + } else { + frac_bar = ' '; + } } - String full_bar; + std::string full_bar; // whitespace padding if (bar_length < N_BARS) full_bar = bar + frac_bar + - String(std::max(N_BARS - bar_length - 1, 0), ' '); + std::string(std::max(N_BARS - bar_length - 1, 0), ' '); else - full_bar = bar + String(std::max(N_BARS - bar_length, 0), ' '); + full_bar = bar + std::string(std::max(N_BARS - bar_length, 0), ' '); // Piece together the bar parts - return String(l_bar.c_str()) + full_bar + r_bar; + return std::string(l_bar.c_str()) + full_bar + r_bar; } } @@ -401,7 +405,7 @@ template class Tqdm : public IteratorWrapper<_Iterator> { throw std::out_of_range( "exhausted"); // TODO: don't throw, just double total if (n < 0) { - printf("n (%s) cannot be negative", _s(n)); + std::cerr << "n (" << n << ") cannot be negative"; throw std::out_of_range("negative step in forward iterator"); } else if (!n) return; diff --git a/include/tqdm/utils.h b/include/tqdm/utils.h index 5ed1796..9f8fabf 100644 --- a/include/tqdm/utils.h +++ b/include/tqdm/utils.h @@ -110,15 +110,6 @@ inline T diff(const time_point &to, const time_point &from) { return std::chrono::duration_cast>(to - from).count(); } -#ifndef _s -/** -Converts anything to a c-string. -* TODO: could this cause a memory leak? -@author Casper da Costa-Luis -*/ -#define _s(obj) std::to_string(obj).c_str() -#endif // _S - template /** Wrapper for pointers and std containter iterators. diff --git a/test/test-example.cpp b/test/test-example.cpp index c2d2fff..9d2be99 100644 --- a/test/test-example.cpp +++ b/test/test-example.cpp @@ -28,7 +28,7 @@ int main() { // if (i) printf("\r%d", i); if (i < 0) printf(" \b"); - + { tqdm::Params p; p.desc = "range-based array"; p.miniters = 1; @@ -39,10 +39,19 @@ int main() { for (auto &i : tqdm::tqdm(a, p)) if (i < 0) printf(" \b"); + } + tqdm::Params p; + p.desc = "range-based array (unicode)"; + p.ascii = ""; + p.dynamic_ncols = true; + for (auto &i : tqdm::tqdm(a, p)) { + if (i < 0) + printf(" \b"); + } printf("iterator-based pythonic range()\n"); for (auto it = tqdm::range(N); !it.ended(); ++it) - ; + ; printf("ye moste pythonic range(), auto type inference\n"); float m = 2, n = float(N), s = 2; From 3b2fb76a66d73bef0aefb7f7e5bb175a40ba9a7b Mon Sep 17 00:00:00 2001 From: Sven Willner Date: Tue, 20 Jun 2017 00:23:57 +0200 Subject: [PATCH 2/2] fixed range --- include/tqdm/tqdm.h | 8 ++++---- include/tqdm/utils.h | 10 +++------- 2 files changed, 7 insertions(+), 11 deletions(-) diff --git a/include/tqdm/tqdm.h b/include/tqdm/tqdm.h index 80d1bc7..78b9904 100644 --- a/include/tqdm/tqdm.h +++ b/include/tqdm/tqdm.h @@ -498,19 +498,19 @@ template using RangeTqdm = Tqdm>; template RangeTqdm range(SizeType n, Params p = Params()) { - return RangeTqdm(RangeIterator(n), - RangeIterator(n), p); +return RangeTqdm(RangeIterator(0, n), + RangeIterator(n, n), p); } template RangeTqdm range(SizeType start, SizeType end, Params p = Params()) { return RangeTqdm(RangeIterator(start, end), - RangeIterator(start, end), p); + RangeIterator(end, end), p); } template RangeTqdm range(SizeType start, SizeType end, SizeType step, Params p = Params()) { return RangeTqdm(RangeIterator(start, end, step), - RangeIterator(start, end, step), p); + RangeIterator(end, end, step), p); } } // tqdm diff --git a/include/tqdm/utils.h b/include/tqdm/utils.h index 9f8fabf..1999630 100644 --- a/include/tqdm/utils.h +++ b/include/tqdm/utils.h @@ -270,19 +270,15 @@ class RangeIterator return (total - current) / step; } - /** here be dragons */ inline bool operator==(const RangeIterator &rhs) const { - return current == rhs.total; + return current == rhs.current; } inline bool operator<(const RangeIterator &rhs) const { - return current < rhs.total; + return current < rhs.current; } inline noconst_value_type operator-(const RangeIterator &rhs) const { - // it's used in `end - begin`, but `end` is only a sentinel - // so let's use `begin `to be consistent - return rhs.size_remaining(); + return current - rhs.current; } - /** end of dubious section */ inline bool operator!=(const RangeIterator &rhs) const { return !(*this == rhs);