$include_dir="/home/hyper-archives/boost-commit/include"; include("$include_dir/msg-header.inc") ?>
Subject: [Boost-commit] svn:boost r73475 - in sandbox/e_float/libs/e_float: src/e_float/efx test/real/cases
From: e_float_at_[hidden]
Date: 2011-08-01 10:15:49
Author: christopher_kormanyos
Date: 2011-08-01 10:15:48 EDT (Mon, 01 Aug 2011)
New Revision: 73475
URL: http://svn.boost.org/trac/boost/changeset/73475
Log:
- Added ostream-write handling for std::setw(...), std::setfill(...), std::left, std::right, std::internal.
Text files modified: 
   sandbox/e_float/libs/e_float/src/e_float/efx/e_float_efx.cpp                      |   170 +++++++++++++++++---------------------- 
   sandbox/e_float/libs/e_float/test/real/cases/test_case_0000y_write_to_ostream.cpp |    24 ++++                                    
   2 files changed, 96 insertions(+), 98 deletions(-)
Modified: sandbox/e_float/libs/e_float/src/e_float/efx/e_float_efx.cpp
==============================================================================
--- sandbox/e_float/libs/e_float/src/e_float/efx/e_float_efx.cpp	(original)
+++ sandbox/e_float/libs/e_float/src/e_float/efx/e_float_efx.cpp	2011-08-01 10:15:48 EDT (Mon, 01 Aug 2011)
@@ -43,9 +43,9 @@
   os_float_filed_type;
 
   // Emphasize: This template class can be used with native floating-point
-  // types like float, double and 10-byte long double. It will need to be
-  // extended for 16-byte long double because the mantissa will no longer
-  // fit in UINT64.
+  // types like float, double and 10-byte long double. Note: It would need
+  // to be extended for 16-byte long double because the mantissa would
+  // no longer fit in UINT64.
   template<typename native_float_type>
   class native_float_parts : private Util::noncopyable
   {
@@ -1236,7 +1236,7 @@
 
   std::stringstream ss;
 
-  ss << std::setprecision(static_cast<std::streamsize>(std::numeric_limits<double>::digits10 + 3))
+  ss << std::setprecision(static_cast<std::streamsize>(std::numeric_limits<double>::max_digits10 + 1))
      << std::scientific
      << *this;
 
@@ -1436,52 +1436,6 @@
   return val;
 }
 
-void efx::e_float::round_output_string(std::string& str, INT64& my_exp, const std::size_t number_of_digits)
-{
-  // Cut the output to the size of the precision.
-  if(str.length() > number_of_digits)
-  {
-    // Get the digit after the last needed digit for rounding
-    const UINT32 round = static_cast<UINT32>(static_cast<UINT32>(str.at(number_of_digits)) - static_cast<UINT32>('0'));
-
-    // Truncate the string
-    str = str.substr(static_cast<std::size_t>(0u), number_of_digits);
-
-    if(round >= static_cast<UINT32>(5u))
-    {
-      std::size_t ix = static_cast<std::size_t>(str.length() - 1u);
-
-      // Every trailing 9 must be rounded up
-      while(ix && (static_cast<INT32>(str.at(ix)) - static_cast<INT32>('0') == static_cast<INT32>(9)))
-      {
-        str.at(ix) = static_cast<char>('0');
-        --ix;
-      }
-
-      if(!ix)
-      {
-        // There were nothing but trailing nines.
-        if(static_cast<INT32>(static_cast<INT32>(str.at(ix)) - static_cast<INT32>(0x30)) == static_cast<INT32>(9))
-        {
-          // Increment up to the next order and adjust exponent.
-          str.at(ix) = static_cast<char>('1');
-          ++my_exp;
-        }
-        else
-        {
-          // Round up this digit
-          ++str.at(ix);
-        }
-      }
-      else
-      {
-        // Round up last digit.
-        ++str[ix];
-      }
-    }
-  }
-}
-
 void efx::e_float::wr_string(std::string& str, std::ostream& os) const
 {
   // Handle INF and NaN.
@@ -1513,34 +1467,19 @@
                                                                             : static_cast<std::size_t>(0u));
 
   // Assess the format flags.
-  const std::ios::fmtflags f = os.flags();
+  const std::ios::fmtflags my_flags = os.flags();
 
   os_float_filed_type my_float_field;
 
-  if((f & std::ios::scientific) != static_cast<std::ios::fmtflags>(0u))
-  {
-    my_float_field = os_float_field_scientific;
-  }
-  else if((f & std::ios::fixed) != static_cast<std::ios::fmtflags>(0u))
-  {
-    my_float_field = os_float_field_fixed;
-  }
-  else
-  {
-    my_float_field = os_float_field_none;
-  }
+  if     ((my_flags & std::ios::scientific) != static_cast<std::ios::fmtflags>(0u)) { my_float_field = os_float_field_scientific; }
+  else if((my_flags & std::ios::fixed) != static_cast<std::ios::fmtflags>(0u))      { my_float_field = os_float_field_fixed; }
+  else { my_float_field = os_float_field_none; }
 
   bool use_scientific = false;
   bool use_fixed = false;
 
-  if(my_float_field == os_float_field_scientific)
-  {
-    use_scientific = true;
-  }
-  else if(my_float_field == os_float_field_fixed)
-  {
-    use_fixed = true;
-  }
+  if     (my_float_field == os_float_field_scientific) { use_scientific = true; }
+  else if(my_float_field == os_float_field_fixed)      { use_fixed = true; }
   else // os_float_field_none
   {
     if(my_exp < static_cast<INT64>(-4))
@@ -1600,41 +1539,82 @@
   round_output_string(str, my_exp, the_number_of_digits_i_want_from_e_float);
 
   // Obtain additional format information.
-  const bool my_uppercase  = ((f & std::ios::uppercase)  != static_cast<std::ios::fmtflags>(0u));
-  const bool my_showpos    = ((f & std::ios::showpos)    != static_cast<std::ios::fmtflags>(0u));
-  const bool my_showpoint  = ((f & std::ios::showpoint)  != static_cast<std::ios::fmtflags>(0u));
+  const bool my_uppercase  = ((my_flags & std::ios::uppercase)  != static_cast<std::ios::fmtflags>(0u));
+  const bool my_showpos    = ((my_flags & std::ios::showpos)    != static_cast<std::ios::fmtflags>(0u));
+  const bool my_showpoint  = ((my_flags & std::ios::showpoint)  != static_cast<std::ios::fmtflags>(0u));
 
   // Write the output string in the desired format.
-  if(my_float_field == os_float_field_scientific)
-  {
-    wr_string_scientific(str, my_exp, os_precision, my_showpoint, my_uppercase);
-  }
-  else if(my_float_field == os_float_field_fixed)
-  {
-    wr_string_fixed(str, my_exp, os_precision, my_showpoint);
-  }
+  if     (my_float_field == os_float_field_scientific) { wr_string_scientific(str, my_exp, os_precision, my_showpoint, my_uppercase); }
+  else if(my_float_field == os_float_field_fixed)      { wr_string_fixed(str, my_exp, os_precision, my_showpoint); }
   else // os_float_field_none
   {
-    if(use_scientific)
-    {
-      wr_string_scientific(str, my_exp, os_precision, my_showpoint, my_uppercase, true);
-    }
-    else // use_fixed
-    {
-      wr_string_fixed(str, my_exp, os_precision, my_showpoint, true);
-    }
+    (use_scientific ? wr_string_scientific(str, my_exp, os_precision, my_showpoint, my_uppercase, true)
+                    : wr_string_fixed(str, my_exp, os_precision, my_showpoint, true));
   }
 
   // Append the sign.
-  if(isneg())
+  if     (isneg())    { str.insert(static_cast<std::size_t>(0u), "-"); }
+  else if(my_showpos) { str.insert(static_cast<std::size_t>(0u), "+"); }
+
+  // Handle std::setw(...), std::setfill(...), std::left, std::right, std::internal.
+  const std::size_t my_width = ((os.width() >= static_cast<std::streamsize>(0)) ? static_cast<std::size_t>(os.width())
+                                                                                : static_cast<std::size_t>(0u));
+
+  if(my_width > str.length())
   {
-    str.insert(static_cast<std::size_t>(0u), "-");
+    // Get the number of fill characters.
+    const std::size_t n_fill = static_cast<std::size_t>(my_width - str.length());
+
+    // Left-justify is the exception, std::right and std::internal justify right.
+    const bool my_left = ((my_flags & std::ios::left)  != static_cast<std::ios::fmtflags>(0u));
+
+    // Justify left or right and insert the fill characters.
+    str.insert((my_left ? str.end() : str.begin()), n_fill, os.fill());
   }
-  else
+}
+
+void efx::e_float::round_output_string(std::string& str, INT64& my_exp, const std::size_t number_of_digits)
+{
+  // Cut the output to the size of the precision.
+  if(str.length() > number_of_digits)
   {
-    if(my_showpos)
+    // Get the digit after the last needed digit for rounding
+    const UINT32 round = static_cast<UINT32>(static_cast<UINT32>(str.at(number_of_digits)) - static_cast<UINT32>('0'));
+
+    // Truncate the string
+    str = str.substr(static_cast<std::size_t>(0u), number_of_digits);
+
+    if(round >= static_cast<UINT32>(5u))
     {
-      str.insert(static_cast<std::size_t>(0u), "+");
+      std::size_t ix = static_cast<std::size_t>(str.length() - 1u);
+
+      // Every trailing 9 must be rounded up
+      while(ix && (static_cast<INT32>(str.at(ix)) - static_cast<INT32>('0') == static_cast<INT32>(9)))
+      {
+        str.at(ix) = static_cast<char>('0');
+        --ix;
+      }
+
+      if(!ix)
+      {
+        // There were nothing but trailing nines.
+        if(static_cast<INT32>(static_cast<INT32>(str.at(ix)) - static_cast<INT32>(0x30)) == static_cast<INT32>(9))
+        {
+          // Increment up to the next order and adjust exponent.
+          str.at(ix) = static_cast<char>('1');
+          ++my_exp;
+        }
+        else
+        {
+          // Round up this digit
+          ++str.at(ix);
+        }
+      }
+      else
+      {
+        // Round up last digit.
+        ++str[ix];
+      }
     }
   }
 }
Modified: sandbox/e_float/libs/e_float/test/real/cases/test_case_0000y_write_to_ostream.cpp
==============================================================================
--- sandbox/e_float/libs/e_float/test/real/cases/test_case_0000y_write_to_ostream.cpp	(original)
+++ sandbox/e_float/libs/e_float/test/real/cases/test_case_0000y_write_to_ostream.cpp	2011-08-01 10:15:48 EDT (Mon, 01 Aug 2011)
@@ -197,22 +197,40 @@
         ss << std::fixed << std::showpos << std::showpoint << std::setprecision(29) << ef::pi() / e_float("1e10");
         str = ss.str();
         data.push_back(e_float(str));
-        str_pi = ::make_pi_string(static_cast<std::size_t>(19));
+        str_pi = ::make_pi_string(static_cast<std::size_t>(19u));
         str_pi.erase(str_pi.begin() + 1u);
         my_test_result &= (str == (std::string("+0.") + (std::string(9u, static_cast<char>('0')) + str_pi)));
         ss.clear();
         ss.str("");
 
-        // Note negative sign.
+        // Note the negative sign.
         ss << std::fixed << std::showpos << std::showpoint << std::setprecision(19) << -ef::pi() * e_float("1e10");
         str = ss.str();
         data.push_back(e_float(str));
-        str_pi = ::make_pi_string(static_cast<std::size_t>(29));
+        str_pi = ::make_pi_string(static_cast<std::size_t>(29u));
         str_pi.erase(str_pi.begin() + 1u);
         str_pi.insert(str_pi.begin() + 11u, 1u, static_cast<char>('.'));
         my_test_result &= (str == (std::string("-") + str_pi));
         ss.clear();
         ss.str("");
+
+        // Test right-justify and fill.
+        ss << std::fixed << std::noshowpos << std::showpoint << std::setprecision(20) << std::setw(100) << std::setfill(static_cast<char>('$')) << ef::pi();
+        str = ss.str();
+        data.push_back(e_float(str));
+        static const std::string str_dollar(static_cast<std::size_t>(78u), static_cast<char>('$'));
+        my_test_result &= (str == (str_dollar + std::string("3.14159265358979323846")));
+        ss.clear();
+        ss.str("");
+
+        // Test left-justify and fill.
+        ss << std::fixed << std::noshowpos << std::showpoint << std::setprecision(20) << std::setw(100) << std::setfill(static_cast<char>('*')) << std::left << ef::pi();
+        str = ss.str();
+        data.push_back(e_float(str));
+        static const std::string str_star(static_cast<std::size_t>(78u), static_cast<char>('*'));
+        my_test_result &= (str == (std::string("3.14159265358979323846") + str_star));
+        ss.clear();
+        ss.str("");
       }
     };