[mathic] 46/62: Added support for dynamic column-width lines in ColumnPrinter.

Doug Torrance dtorrance-guest at moszumanska.debian.org
Wed Apr 1 11:36:23 UTC 2015


This is an automated email from the git hooks/post-receive script.

dtorrance-guest pushed a commit to branch master
in repository mathic.

commit 93dbb19ed4c0669f6ff38d28393337a36883f704
Author: Bjarke Hammersholt Roune <bjarkehr.code at gmail.com>
Date:   Tue Feb 5 12:50:14 2013 +0100

    Added support for dynamic column-width lines in ColumnPrinter.
---
 src/mathic/ColumnPrinter.cpp | 93 +++++++++++++++++++++++++++++++++++++-------
 src/mathic/ColumnPrinter.h   | 24 +++++++++---
 2 files changed, 98 insertions(+), 19 deletions(-)

diff --git a/src/mathic/ColumnPrinter.cpp b/src/mathic/ColumnPrinter.cpp
index a0d4708..6e51b39 100755
--- a/src/mathic/ColumnPrinter.cpp
+++ b/src/mathic/ColumnPrinter.cpp
@@ -4,14 +4,14 @@ namespace mathic {
   namespace {
 	size_t getLineWidth(const std::string& str, size_t pos) {
 	  size_t startPos = pos;
-	  while (pos < str.size() && str[pos] != '\n')
+	  while (pos < str.size() && str[pos] != '\n' && str[pos] != '\0')
 		++pos;
 	  return pos - startPos;
 	}
 
-	void printSpaces(std::ostream& out, size_t howMany) {
+	void printChars(std::ostream& out, size_t howMany, const char c) {
 	  while (howMany > 0) {
-		out << ' ';
+		out << c;
 		--howMany;
 	  }
 	}
@@ -35,7 +35,7 @@ namespace mathic {
 	_prefix = prefix;
   }
 
-  void ColumnPrinter::addColumn(bool flushLeft,
+  std::ostream& ColumnPrinter::addColumn(bool flushLeft,
 								const std::string& prefix,
 								const std::string& suffix) {
 	std::auto_ptr<Col> col(new Col());
@@ -45,6 +45,7 @@ namespace mathic {
 
 	_cols.push_back(0);
 	_cols.back() = col.release(); // push_back didn't throw, so safe to release
+    return _cols.back()->text;
   }
 
   size_t ColumnPrinter::getColumnCount() const {
@@ -56,11 +57,29 @@ namespace mathic {
 	return _cols[col]->text;
   }
 
+  void ColumnPrinter::repeatToEndOfLine(const char repeatThis, size_t col) {
+    MATHIC_ASSERT(col < getColumnCount());
+    (*this)[col] << '\0' << repeatThis;
+  }
+
+  void ColumnPrinter::repeatToEndOfLine(const char repeatThis) {
+    MATHIC_ASSERT(repeatThis != '\n');
+    for (size_t col = 0; col < getColumnCount(); ++col)
+      repeatToEndOfLine(repeatThis, col);
+  }
+
   void ColumnPrinter::print(std::ostream& out) const {
-	// Calculate the width of each column.
+    // stringstream::str() copies the string, so we need
+    // to extract all the strings and store them to avoid copying
+    // at every access.
+    std::vector<std::string> texts(getColumnCount());
+	for (size_t col = 0; col < getColumnCount(); ++col)
+      texts[col] = _cols[col]->text.str();
+    
+    // Calculate the width of each column.
 	std::vector<size_t> widths(getColumnCount());
 	for (size_t col = 0; col < getColumnCount(); ++col) {
-	  const std::string& text = _cols[col]->text.str();
+      const auto& text = texts[col];
 	  size_t maxWidth = 0;
 
 	  size_t pos = 0;
@@ -72,7 +91,14 @@ namespace mathic {
 		// We can't just increment pos unconditionally by width + 1, as
 		// that could result in an overflow.
 		pos += width;
-		if (text[pos] == '\n')
+        if (pos == text.size())
+          break;
+        if (text[pos] == '\0') {
+          ++pos;
+          if (pos == text.size())
+            break;
+          ++pos;
+        } else if (text[pos] == '\n')
 		  ++pos;
 	  }
 	  widths[col] = maxWidth;
@@ -83,7 +109,7 @@ namespace mathic {
 	while (true) {
 	  bool done = true;
 	  for (size_t col = 0; col < getColumnCount(); ++col) {
-		if (poses[col] < _cols[col]->text.str().size()) {
+		if (poses[col] < texts[col].size()) {
 		  done = false;
 		  break;
 		}
@@ -95,24 +121,41 @@ namespace mathic {
 	  for (size_t col = 0; col < getColumnCount(); ++col) {
 		out << _cols[col]->prefix;
 
-		const std::string& text = _cols[col]->text.str();
+		const std::string& text = texts[col];
 		size_t& pos = poses[col];
 		size_t width = getLineWidth(text, pos);
 
+        char padChar = ' ';
+        if (
+          pos + width < text.size() &&
+          text[pos + width] == '\0' &&
+          pos + width + 1 < text.size()
+        ) {
+          padChar = text[pos + width + 1];
+        }
+
 		if (!_cols[col]->flushLeft)
-		  printSpaces(out, widths[col] - width);
+		  printChars(out, widths[col] - width, padChar);
 
 		while (pos < text.size()) {
 		  if (text[pos] == '\n') {
 			++pos;
 			break;
 		  }
+          if (text[pos] == '\0') {
+            ++pos;
+            if (pos < text.size()) {
+              MATHIC_ASSERT(text[pos] == padChar);
+              ++pos;
+            }
+            break;
+          }
 		  out << text[pos];
 		  ++pos;
 		}
 
 		if (_cols[col]->flushLeft)
-		  printSpaces(out, widths[col] - width);
+		  printChars(out, widths[col] - width, padChar);
 
 		out << _cols[col]->suffix;
 	  }
@@ -123,10 +166,11 @@ namespace mathic {
   std::string ColumnPrinter::commafy(const unsigned long long l) {
     std::stringstream out;
     out << l;
+    const auto uncomma = out.str();
     std::string str;
-    for (size_t i = 0; i < out.str().size(); ++i) {
-      str += out.str()[i];
-      if (i != out.str().size() - 1 && ((out.str().size() - i) % 3) == 1)
+    for (size_t i = 0; i < uncomma.size(); ++i) {
+      str += uncomma[i];
+      if (i != uncomma.size() - 1 && ((uncomma.size() - i) % 3) == 1)
         str += ',';
     }
     return str;
@@ -139,6 +183,13 @@ namespace mathic {
     return ratio(numerator * 100, denominator) + '%';
   }
 
+  std::string ColumnPrinter::percent(
+    const double numerator,
+    const double denominator
+  ) {
+    return ratio(numerator * 100, denominator) + '%';
+  }
+
   std::string ColumnPrinter::percentFixed(
     const unsigned long long numerator,
     const unsigned long long denominator
@@ -165,6 +216,20 @@ namespace mathic {
     return oneDecimal(static_cast<double>(numerator) / denominator);
   }
 
+  std::string ColumnPrinter::ratio(
+    const double numerator,
+    const double denominator
+  ) {
+    const auto epsilon = 0.000000001;
+    if (-epsilon < denominator && denominator < epsilon) {
+      if (-epsilon < numerator && numerator < epsilon)
+        return "0/0";
+      else
+        return "?/0";
+    }
+    return oneDecimal(static_cast<double>(numerator) / denominator);
+  }
+
   std::string ColumnPrinter::oneDecimal(const double d) {
     std::ostringstream out;
     unsigned long long l = static_cast<unsigned long long>(d * 10 + 0.5);
diff --git a/src/mathic/ColumnPrinter.h b/src/mathic/ColumnPrinter.h
index 9282ece..5c46458 100755
--- a/src/mathic/ColumnPrinter.h
+++ b/src/mathic/ColumnPrinter.h
@@ -15,13 +15,22 @@ namespace mathic {
 	~ColumnPrinter();
 
 	void setPrefix(const std::string& prefix);
-	void addColumn(bool flushLeft = true,
-				   const std::string& prefix = "  ",
-				   const std::string& suffix = "");
+	std::ostream& addColumn(
+      bool flushLeft = true,
+	  const std::string& prefix = "  ",
+	  const std::string& suffix = ""
+    );
 	size_t getColumnCount() const;
 
 	std::ostream& operator[](size_t col);
 
+    /// Inserts a newline after padding the current line with repeatThis 
+    /// chars until it fills the column width.
+    void repeatToEndOfLine(const char repeatThis, size_t col);
+
+    /// Works on all columns.
+    void repeatToEndOfLine(const char repeatThis);
+
 	void print(std::ostream& out) const;
 
     /// Returns "123,456,789" for parameter value 123456789.
@@ -35,7 +44,9 @@ namespace mathic {
     /** returns (3,100) as "3.0%". */
     static std::string percent(
       unsigned long long numerator,
-      unsigned long long denominator);
+      unsigned long long denominator
+    );
+    static std::string percent(double numerator, double denominator);
 
     /** returns (3,100) as "  3.0%". The string always has the same length for
       ratios equal to or less than 999.9%. */
@@ -49,7 +60,9 @@ namespace mathic {
     /** Returns (7,4) as "1.8" */
     static std::string ratio(
       unsigned long long numerator,
-      unsigned long long denominator);
+      unsigned long long denominator
+    );
+    static std::string ratio(double numerator, double denominator);
 
 	/** Returns d as a string printed to 1 decimal place, rounding up at 0.5 */
     static std::string oneDecimal(double d);
@@ -63,6 +76,7 @@ namespace mathic {
 	  std::stringstream text;
 	  std::string suffix;
 	  bool flushLeft;
+      std::vector<std::pair<size_t, char> > repeatToEndOfLine;
 	};
 	std::vector<Col*> _cols;
 	std::string _prefix;

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/debian-science/packages/mathic.git



More information about the debian-science-commits mailing list