$include_dir="/home/hyper-archives/boost-commit/include"; include("$include_dir/msg-header.inc") ?>
Subject: [Boost-commit] svn:boost r85221 - in trunk: boost/spirit/home/karma/numeric boost/spirit/home/karma/numeric/detail libs/spirit/test/karma
From: hartmut.kaiser_at_[hidden]
Date: 2013-08-06 09:36:39
Author: hkaiser
Date: 2013-08-06 09:36:38 EDT (Tue, 06 Aug 2013)
New Revision: 85221
URL: http://svn.boost.org/trac/boost/changeset/85221
Log:
Fixed #8970: Karma fails to output a sign with a user-defined real number policy
Added:
   trunk/libs/spirit/test/karma/regression_real_policy_sign.cpp   (contents, props changed)
Text files modified: 
   trunk/boost/spirit/home/karma/numeric/detail/numeric_utils.hpp |    16 ++++++++------                          
   trunk/boost/spirit/home/karma/numeric/detail/real_utils.hpp    |     4 ++                                      
   trunk/boost/spirit/home/karma/numeric/real_policies.hpp        |    13 ++++++-----                             
   trunk/libs/spirit/test/karma/regression_real_policy_sign.cpp   |    43 ++++++++++++++++++++++++++++++++++++++++
   4 files changed, 62 insertions(+), 14 deletions(-)
Modified: trunk/boost/spirit/home/karma/numeric/detail/numeric_utils.hpp
==============================================================================
--- trunk/boost/spirit/home/karma/numeric/detail/numeric_utils.hpp	Tue Aug  6 04:30:33 2013	(r85220)
+++ trunk/boost/spirit/home/karma/numeric/detail/numeric_utils.hpp	2013-08-06 09:36:38 EDT (Tue, 06 Aug 2013)	(r85221)
@@ -707,10 +707,11 @@
     {
         template <typename OutputIterator>
         static bool
-        call_noforce(OutputIterator& sink, bool /*is_zero*/, bool is_negative)
+        call_noforce(OutputIterator& sink, bool is_zero, bool is_negative,
+            bool sign_if_zero)
         {
             // generate a sign for negative numbers only
-            if (is_negative) {
+            if (is_negative || (is_zero && sign_if_zero)) {
                 *sink = '-';
                 ++sink;
             }
@@ -719,10 +720,11 @@
 
         template <typename OutputIterator>
         static bool
-        call_force(OutputIterator& sink, bool is_zero, bool is_negative)
+        call_force(OutputIterator& sink, bool is_zero, bool is_negative,
+            bool sign_if_zero)
         {
             // generate a sign for all numbers except zero
-            if (!is_zero)
+            if (!is_zero || sign_if_zero)
                 *sink = is_negative ? '-' : '+';
             else
                 *sink = ' ';
@@ -734,11 +736,11 @@
         template <typename OutputIterator>
         static bool
         call(OutputIterator& sink, bool is_zero, bool is_negative
-          , bool forcesign)
+          , bool forcesign, bool sign_if_zero = false)
         {
             return forcesign ?
-                call_force(sink, is_zero, is_negative) :
-                call_noforce(sink, is_zero, is_negative);
+                call_force(sink, is_zero, is_negative, sign_if_zero) :
+                call_noforce(sink, is_zero, is_negative, sign_if_zero);
         }
     };
 
Modified: trunk/boost/spirit/home/karma/numeric/detail/real_utils.hpp
==============================================================================
--- trunk/boost/spirit/home/karma/numeric/detail/real_utils.hpp	Tue Aug  6 04:30:33 2013	(r85220)
+++ trunk/boost/spirit/home/karma/numeric/detail/real_utils.hpp	2013-08-06 09:36:38 EDT (Tue, 06 Aug 2013)	(r85221)
@@ -152,10 +152,12 @@
             }
 
         // call the actual generating functions to output the different parts
-            if (sign_val && traits::test_zero(long_int_part) && 
+            if ((force_sign || sign_val) &&
+                traits::test_zero(long_int_part) &&
                 traits::test_zero(long_frac_part))
             {
                 sign_val = false;     // result is zero, no sign please
+                force_sign = false;
             }
 
         // generate integer part
Modified: trunk/boost/spirit/home/karma/numeric/real_policies.hpp
==============================================================================
--- trunk/boost/spirit/home/karma/numeric/real_policies.hpp	Tue Aug  6 04:30:33 2013	(r85220)
+++ trunk/boost/spirit/home/karma/numeric/real_policies.hpp	2013-08-06 09:36:38 EDT (Tue, 06 Aug 2013)	(r85221)
@@ -175,19 +175,20 @@
         //  Generate the integer part of the number.
         //
         //      sink       The output iterator to use for generation
-        //      n          The absolute value of the integer part of the floating 
-        //                 point number to convert (always non-negative). 
-        //      sign       The sign of the overall floating point number to 
+        //      n          The absolute value of the integer part of the floating
+        //                 point number to convert (always non-negative).
+        //      sign       The sign of the overall floating point number to
         //                 convert.
-        //      force_sign Whether a sign has to be generated even for 
-        //                 non-negative numbers
+        //      force_sign Whether a sign has to be generated even for
+        //                 non-negative numbers. Note, that force_sign will be
+        //                 set to false for zero floating point values.
         ///////////////////////////////////////////////////////////////////////
         template <typename OutputIterator>
         static bool integer_part (OutputIterator& sink, T n, bool sign
           , bool force_sign)
         {
             return sign_inserter::call(
-                      sink, traits::test_zero(n), sign, force_sign) &&
+                      sink, traits::test_zero(n), sign, force_sign, force_sign) &&
                    int_inserter<10>::call(sink, n);
         }
 
Added: trunk/libs/spirit/test/karma/regression_real_policy_sign.cpp
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ trunk/libs/spirit/test/karma/regression_real_policy_sign.cpp	2013-08-06 09:36:38 EDT (Tue, 06 Aug 2013)	(r85221)
@@ -0,0 +1,43 @@
+//   Copyright (c) 2013 Alex Korobka
+// 
+//   Distributed under the Boost Software License, Version 1.0. (See accompanying
+//   file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// This test checks whether #8970 was fixed
+
+#include <boost/config/warning_disable.hpp>
+#include <boost/detail/lightweight_test.hpp>
+#include <iostream>
+#include <boost/spirit/include/karma.hpp>
+
+#include "test.hpp"
+
+using namespace spirit_test;
+using namespace boost::spirit;
+
+template <typename Num>
+struct signed_policy : karma::real_policies<Num>
+{
+    static bool force_sign(Num n) { return true; }
+};
+
+int main()
+{
+    karma::real_generator<double, signed_policy<double> > const force_sign_double =
+        karma::real_generator<double, signed_policy<double> >();
+
+    BOOST_TEST(test("-0.123", force_sign_double, -0.123));
+    BOOST_TEST(test("-1.123", force_sign_double, -1.123));
+    BOOST_TEST(test("0.0", force_sign_double, 0));
+    BOOST_TEST(test("+0.123", force_sign_double, 0.123));
+    BOOST_TEST(test("+1.123", force_sign_double, 1.123));
+
+    using karma::double_;
+    BOOST_TEST(test("-0.123", double_, -0.123));
+    BOOST_TEST(test("-1.123", double_, -1.123));
+    BOOST_TEST(test("0.0", double_, 0));
+    BOOST_TEST(test("0.123", double_, 0.123));
+    BOOST_TEST(test("1.123", double_, 1.123));
+
+    return boost::report_errors();
+}