Boost logo

Boost-Commit :

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();
+}


Boost-Commit list run by bdawes at acm.org, david.abrahams at rcn.com, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk