Boost logo

Boost-Commit :

Subject: [Boost-commit] svn:boost r72071 - in trunk: boost libs/conversion
From: antoshkka_at_[hidden]
Date: 2011-05-22 07:35:01


Author: apolukhin
Date: 2011-05-22 07:35:00 EDT (Sun, 22 May 2011)
New Revision: 72071
URL: http://svn.boost.org/trac/boost/changeset/72071

Log:
Fixes #5557. Adds tests on #5557
Text files modified:
   trunk/boost/lexical_cast.hpp | 79 +++++++++++++++++++++++++++++++++------
   trunk/libs/conversion/lexical_cast_test.cpp | 11 +++++
   2 files changed, 77 insertions(+), 13 deletions(-)

Modified: trunk/boost/lexical_cast.hpp
==============================================================================
--- trunk/boost/lexical_cast.hpp (original)
+++ trunk/boost/lexical_cast.hpp 2011-05-22 07:35:00 EDT (Sun, 22 May 2011)
@@ -463,7 +463,7 @@
 #endif // #ifndef BOOST_LCAST_NO_COMPILE_TIME_PRECISION
     }
 
- namespace detail // '0' and '-' constants
+ namespace detail // '0', '+' and '-' constants
     {
         template<typename CharT> struct lcast_char_constants;
 
@@ -472,6 +472,7 @@
         {
             BOOST_STATIC_CONSTANT(char, zero = '0');
             BOOST_STATIC_CONSTANT(char, minus = '-');
+ BOOST_STATIC_CONSTANT(char, plus = '+');
         };
 
 #ifndef BOOST_LCAST_NO_WCHAR_T
@@ -480,6 +481,7 @@
         {
             BOOST_STATIC_CONSTANT(wchar_t, zero = L'0');
             BOOST_STATIC_CONSTANT(wchar_t, minus = L'-');
+ BOOST_STATIC_CONSTANT(wchar_t, plus = L'+');
         };
 #endif
     }
@@ -604,7 +606,9 @@
             std::string const& grouping = np.grouping();
             std::string::size_type const grouping_size = grouping.size();
 
- /* According to [22.2.2.1.2] of Programming languages — C++ we MUST check for correct grouping */
+ /* According to [22.2.2.1.2] of Programming languages - C++
+ * we MUST check for correct grouping
+ */
             if (grouping_size)
             {
                 unsigned char current_grouping = 0;
@@ -846,8 +850,20 @@
             bool input_operator_helper_unsigned(Type& output)
             {
                 CharT const minus = lcast_char_constants<CharT>::minus;
- bool const has_minus = Traits::eq(minus,*start);
- bool const succeed = lcast_ret_unsigned<Traits>(output, has_minus ? start+1 : start, finish);
+ CharT const plus = lcast_char_constants<CharT>::plus;
+ bool has_minus = false;
+
+ /* We won`t use `start' any more, so no need in decrementing it after */
+ if ( Traits::eq(minus,*start) )
+ {
+ ++start;
+ has_minus = true;
+ } else if ( Traits::eq( plus, *start ) )
+ {
+ ++start;
+ }
+
+ bool const succeed = lcast_ret_unsigned<Traits>(output, start, finish);
 #if (defined _MSC_VER)
 # pragma warning( push )
 // C4146: unary minus operator applied to unsigned type, result still unsigned
@@ -868,10 +884,22 @@
             bool input_operator_helper_signed(Type& output)
             {
                 CharT const minus = lcast_char_constants<CharT>::minus;
+ CharT const plus = lcast_char_constants<CharT>::plus;
                 typedef BOOST_DEDUCED_TYPENAME make_unsigned<Type>::type utype;
                 utype out_tmp =0;
- bool const has_minus = Traits::eq(minus,*start);
- bool succeed = lcast_ret_unsigned<Traits>(out_tmp, has_minus ? start+1 : start, finish);
+ bool has_minus = false;
+
+ /* We won`t use `start' any more, so no need in decrementing it after */
+ if ( Traits::eq(minus,*start) )
+ {
+ ++start;
+ has_minus = true;
+ } else if ( Traits::eq(plus, *start) )
+ {
+ ++start;
+ }
+
+ bool succeed = lcast_ret_unsigned<Traits>(out_tmp, start, finish);
                 if (has_minus) {
 #if (defined _MSC_VER)
 # pragma warning( push )
@@ -953,14 +981,38 @@
 
 #endif
 
+ /*
+ * case "-0" || "0" || "+0" : output = false; return true;
+ * case "1" || "+1": output = true; return true;
+ * default: return false;
+ */
             bool operator>>(bool& output)
             {
- output = (start[0] == lcast_char_constants<CharT>::zero + 1);
- return finish-start==1
- && (
- start[0] == lcast_char_constants<CharT>::zero
- || start[0] == lcast_char_constants<CharT>::zero + 1
- );
+ CharT const zero = lcast_char_constants<CharT>::zero;
+ CharT const plus = lcast_char_constants<CharT>::plus;
+ CharT const minus = lcast_char_constants<CharT>::minus;
+
+ switch(finish-start)
+ {
+ case 1:
+ output = Traits::eq(start[0], zero+1);
+ return output || Traits::eq(start[0], zero );
+ case 2:
+ if ( Traits::eq( plus, *start) )
+ {
+ ++start;
+ output = Traits::eq(start[0], zero +1);
+ return output || Traits::eq(start[0], zero );
+ } else
+ {
+ output = false;
+ return Traits::eq( minus, *start)
+ && Traits::eq( zero, start[1]);
+ }
+ default:
+ output = false; // Suppress warning about uninitalized variable
+ return false;
+ }
             }
 
 
@@ -1614,7 +1666,8 @@
>::value
> do_copy_type;
 
- typedef BOOST_DEDUCED_TYPENAME detail::is_arithmetic_and_not_xchars<Target, src> do_copy_with_dynamic_check_type;
+ typedef BOOST_DEDUCED_TYPENAME
+ detail::is_arithmetic_and_not_xchars<Target, src> do_copy_with_dynamic_check_type;
 
         typedef BOOST_DEDUCED_TYPENAME ::boost::mpl::if_c<
             do_copy_type::value,

Modified: trunk/libs/conversion/lexical_cast_test.cpp
==============================================================================
--- trunk/libs/conversion/lexical_cast_test.cpp (original)
+++ trunk/libs/conversion/lexical_cast_test.cpp 2011-05-22 07:35:00 EDT (Sun, 22 May 2011)
@@ -249,6 +249,12 @@
         lexical_cast<bool>(std::string("")), bad_lexical_cast);
     BOOST_CHECK_THROW(
         lexical_cast<bool>(std::string("Test")), bad_lexical_cast);
+
+ BOOST_CHECK(lexical_cast<bool>("+1") == true );
+ BOOST_CHECK(lexical_cast<bool>("+0") == false );
+ BOOST_CHECK(lexical_cast<bool>("-0") == false );
+ BOOST_CHECK_THROW(lexical_cast<bool>("--0"), bad_lexical_cast);
+ BOOST_CHECK_THROW(lexical_cast<bool>("-+-0"), bad_lexical_cast);
 }
 
 void test_conversion_to_string()
@@ -722,6 +728,8 @@
     BOOST_CHECK_THROW(lexical_cast<T>(1.0001), bad_lexical_cast);
     BOOST_CHECK_THROW(lexical_cast<T>(1.0001L), bad_lexical_cast);
 
+ BOOST_CHECK(lexical_cast<T>("+1") == static_cast<T>(1) );
+ BOOST_CHECK(lexical_cast<T>("+9") == static_cast<T>(9) );
     // test_conversion_from_to_integral_for_locale
 
     typedef std::numpunct<char> numpunct;
@@ -774,6 +782,9 @@
 #endif
 
     test_conversion_from_integral_to_integral<T>();
+
+ BOOST_CHECK_CLOSE(lexical_cast<T>("+1"), 1, std::numeric_limits<T>::epsilon() );
+ BOOST_CHECK_CLOSE(lexical_cast<T>("+9"), 9, std::numeric_limits<T>::epsilon()*9 );
 }
 
 void test_conversion_from_to_short()


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