$include_dir="/home/hyper-archives/boost-commit/include"; include("$include_dir/msg-header.inc") ?>
Subject: [Boost-commit] svn:boost r77268 - trunk/boost/math/special_functions
From: pbristow_at_[hidden]
Date: 2012-03-08 13:12:28
Author: pbristow
Date: 2012-03-08 13:12:28 EST (Thu, 08 Mar 2012)
New Revision: 77268
URL: http://svn.boost.org/trac/boost/changeset/77268
Log:
Version that passes new tests for both default and signed_zero flag set.
BUT had to suppress MSVC warning "C4244 conversion wchar_t* to char* may cause data loss." 
Text files modified: 
   trunk/boost/math/special_functions/nonfinite_num_facets.hpp |   158 ++++++++++++++++++++++++++------------- 
   1 files changed, 105 insertions(+), 53 deletions(-)
Modified: trunk/boost/math/special_functions/nonfinite_num_facets.hpp
==============================================================================
--- trunk/boost/math/special_functions/nonfinite_num_facets.hpp	(original)
+++ trunk/boost/math/special_functions/nonfinite_num_facets.hpp	2012-03-08 13:12:28 EST (Thu, 08 Mar 2012)
@@ -1,8 +1,9 @@
 #ifndef BOOST_MATH_NONFINITE_NUM_FACETS_HPP
 #define BOOST_MATH_NONFINITE_NUM_FACETS_HPP
 
-// Copyright (c) 2006 Johan Rade
-// Copyright 2011 Paul A. Bristow (comments)
+// Copyright 2006 Johan Rade
+// Copyright 2012 K R Walker
+// Copyright 2011, 2012 Paul A. Bristow 
 
 // Distributed under the Boost Software License, Version 1.0.
 // (See accompanying file LICENSE_1_0.txt
@@ -28,10 +29,10 @@
 #include <boost/math/special_functions/sign.hpp>
 
 #ifdef _MSC_VER
-#   pragma warning(push)
-#   pragma warning(disable : 4127) // conditional expression is constant.
-#   pragma warning(disable : 4706) // assignment within conditional expression.
-#   pragma warning(disable : 4224) // formal parameter 'version' was previously defined as a type.
+#  pragma warning(push)
+#  pragma warning(disable : 4127) // conditional expression is constant.
+#  pragma warning(disable : 4706) // assignment within conditional expression.
+#  pragma warning(disable : 4244) // TODO?  // Needs to be CharType version.
 #endif
 
 namespace boost {
@@ -65,16 +66,14 @@
 
     protected:
       virtual OutputIterator do_put(
-        OutputIterator it, std::ios_base& iosb,
-        CharType fill, double val) const
+        OutputIterator it, std::ios_base& iosb, CharType fill, double val) const
       {
         put_and_reset_width(it, iosb, fill, val);
         return it;
       }
 
       virtual OutputIterator do_put(
-        OutputIterator it, std::ios_base& iosb,
-        CharType fill, long double val) const
+        OutputIterator it, std::ios_base& iosb,  CharType fill, long double val) const
       {
         put_and_reset_width(it, iosb, fill, val);
         return it;
@@ -93,86 +92,138 @@
         OutputIterator& it, std::ios_base& iosb,
         CharType fill, ValType val) const
       {
-        switch((boost::math::fpclassify)(val)) {
+        switch((boost::math::fpclassify)(val))
+        {
 
         case FP_INFINITE:
           if(flags_ & trap_infinity)
+          {
             throw std::ios_base::failure("Infinity");
+          }
           else if((boost::math::signbit)(val))
-            put_num_and_fill(it, iosb, "-", "inf", fill);
+          { // negative infinity.
+            put_num_and_fill(it, iosb, "-", "inf", fill, val);
+          }
           else if(iosb.flags() & std::ios_base::showpos)
-            put_num_and_fill(it, iosb, "+", "inf", fill);
+          { // Explicit "+inf" wanted.
+            put_num_and_fill(it, iosb, "+", "inf", fill, val);
+          }
           else
-            put_num_and_fill(it, iosb, "", "inf", fill);
+          { // just "inf" wanted.
+            put_num_and_fill(it, iosb, "", "inf", fill, val);
+          }
           break;
 
         case FP_NAN:
           if(flags_ & trap_nan)
+          {
             throw std::ios_base::failure("NaN");
+          }
           else if((boost::math::signbit)(val))
-            put_num_and_fill(it, iosb, "-", "nan", fill);
+          { // negative so "-nan".
+            put_num_and_fill(it, iosb, "-", "nan", fill, val);
+          }
           else if(iosb.flags() & std::ios_base::showpos)
-            put_num_and_fill(it, iosb, "+", "nan", fill);
+          { // explicit "+nan" wanted.
+            put_num_and_fill(it, iosb, "+", "nan", fill, val);
+          }
           else
-            put_num_and_fill(it, iosb, "", "nan", fill);
+          { // Just "nan".
+            put_num_and_fill(it, iosb, "", "nan", fill, val);
+          }
           break;
 
         case FP_ZERO:
-          if(flags_ & signed_zero) {
-            if((boost::math::signbit)(val))
-              put_num_and_fill(it, iosb, "-", "0", fill);
-            else if(iosb.flags() & std::ios_base::showpos)
-              put_num_and_fill(it, iosb, "+", "0", fill);
-            else
-              put_num_and_fill(it, iosb, "", "0", fill);
+          if((flags_ & signed_zero) && ((boost::math::signbit)(val)))
+          { // Flag set to distinguish between positive and negative zero.
+            // But string "0" should have stuff after decimal point if setprecision and/or exp format. 
+
+            //std::basic_ostringstream<CharType> zeros; // Needs to be CharType version.
+
+            std::ostringstream zeros;
+                         
+            //std::cout << "iosb.flags() = " << std::hex << iosb.flags() << std::endl;
+            //std::cout << "iosb.precision() = " << std::hex << iosb.precision() << std::endl;
+            //std::cout << "iosb.width() = " << std::hex << iosb.width() << std::endl;
+            // Copy flags, fill, width and precision.
+            zeros.flags(iosb.flags());
+            zeros.unsetf(std::ios::showpos); // Ignore showpos because must be negative.
+            zeros.precision(iosb.precision());
+            //zeros.width is set by put_num_and_fill
+            zeros.fill(fill);
+            zeros << ValType(0);
+            // std::cout << "zeros.str() = "<< zeros.str() << std::endl;
+            //  put_num_and_fill(it, iosb, "-", zeros.str().c_str(), fill, val); 
+          
+            put_num_and_fill(it, iosb, "-", zeros.str().c_str(), fill, val);
           }
           else
-            put_num_and_fill(it, iosb, "", "0", fill);
+          { // Output the platform default for positive and negative zero.
+            put_num_and_fill(it, iosb, 0, 0, fill, val);
+          }
           break;
 
-        default:
-          it = std::num_put<CharType, OutputIterator>::do_put(
-            it, iosb, fill, val);
+        default:  // Normal non-zero finite value.
+          it = std::num_put<CharType, OutputIterator>::do_put(it, iosb, fill, val);
           break;
         }
       }
 
+      template<class ValType>
       void put_num_and_fill(
         OutputIterator& it, std::ios_base& iosb, const char* prefix,
-        const char* body, CharType fill) const
+          const char* body, CharType fill, ValType val) const
       {
-        int width = (int)std::strlen(prefix) + (int)std::strlen(body);
-        std::ios_base::fmtflags adjust
-          = iosb.flags() & std::ios_base::adjustfield;
+        int prefix_length = prefix ? (int)std::strlen(prefix) : 0;
+        int body_length = body ? (int)std::strlen(body) : 0;
+        int width = prefix_length + body_length;
+        std::ios_base::fmtflags adjust = iosb.flags() & std::ios_base::adjustfield;
         const std::ctype<CharType>& ct
           = std::use_facet<std::ctype<CharType> >(iosb.getloc());
 
-        if(adjust != std::ios_base::internal && adjust != std::ios_base::left)
-          put_fill(it, iosb, fill, width);
-
-        while(*prefix)
-          *it = ct.widen(*(prefix++));
-
-        if(adjust == std::ios_base::internal)
-          put_fill(it, iosb, fill, width);
+        if(body || prefix)
+        { // adjust == std::ios_base::right, so leading fill needed.
+          if(adjust != std::ios_base::internal && adjust != std::ios_base::left)
+            put_fill(it, iosb, fill, width);
+        }
+
+        if(prefix)
+        { // Adjust width for prefix.
+          while(*prefix)
+            *it = ct.widen(*(prefix++));
+          iosb.width( iosb.width() - prefix_length );
+          width -= prefix_length;
+        }
+
+        if(body)
+        { // 
+          if(adjust == std::ios_base::internal)
+          { // Put fill between sign and digits.
+            put_fill(it, iosb, fill, width);
+          }
+          if(iosb.flags() & std::ios_base::uppercase)
+          {
+              while(*body)
+                *it = ct.toupper(ct.widen(*(body++)));
+          }
+          else
+          {
+            while(*body)
+              *it = ct.widen(*(body++));
+          }
 
-        if(iosb.flags() & std::ios_base::uppercase) {
-          while(*body)
-            *it = ct.toupper(ct.widen(*(body++)));
+          if(adjust == std::ios_base::left)
+            put_fill(it, iosb, fill, width);
         }
-        else {
-          while(*body)
-            *it = ct.widen(*(body++));
+        else
+        {
+          it = std::num_put<CharType, OutputIterator>::do_put(it, iosb, fill, val);
         }
-
-        if(adjust == std::ios_base::left)
-          put_fill(it, iosb, fill, width);
       }
 
       void put_fill(
-        OutputIterator& it, std::ios_base& iosb,
-        CharType fill, int width) const
-      {
+        OutputIterator& it, std::ios_base& iosb, CharType fill, int width) const
+      { // Insert fill chars.
         for(std::streamsize i = iosb.width() - static_cast<std::streamsize>(width); i > 0; --i)
           *it = fill;
       }
@@ -540,4 +591,5 @@
 #   pragma warning(pop)
 #endif
 
-#endif
+#endif // BOOST_MATH_NONFINITE_NUM_FACETS_HPP
+