Boost logo

Boost-Commit :

Subject: [Boost-commit] svn:boost r71923 - in branches/release: boost libs/conversion
From: antoshkka_at_[hidden]
Date: 2011-05-13 13:44:52


Author: apolukhin
Date: 2011-05-13 13:44:51 EDT (Fri, 13 May 2011)
New Revision: 71923
URL: http://svn.boost.org/trac/boost/changeset/71923

Log:
Merged from trunk revision 71922. Most part of this modifications of lexical_cast library were made and successfully tested during the year 2009.
Later commits affected only documentation bugs.
Text files modified:
   branches/release/boost/lexical_cast.hpp | 24 ++++++-----
   branches/release/libs/conversion/lexical_cast.htm | 84 +++++++++++++++++++++++++++++++--------
   branches/release/libs/conversion/lexical_cast_test.cpp | 7 +++
   3 files changed, 86 insertions(+), 29 deletions(-)

Modified: branches/release/boost/lexical_cast.hpp
==============================================================================
--- branches/release/boost/lexical_cast.hpp (original)
+++ branches/release/boost/lexical_cast.hpp 2011-05-13 13:44:51 EDT (Fri, 13 May 2011)
@@ -55,7 +55,13 @@
 namespace boost
 {
     // exception used to indicate runtime lexical_cast failure
- class bad_lexical_cast : public std::bad_cast
+ class bad_lexical_cast :
+ // workaround MSVC bug with std::bad_cast when _HAS_EXCEPTIONS == 0
+#if defined(BOOST_MSVC) && defined(_HAS_EXCEPTIONS) && !_HAS_EXCEPTIONS
+ public std::exception
+#else
+ public std::bad_cast
+#endif
 
 #if defined(__BORLANDC__) && BOOST_WORKAROUND( __BORLANDC__, < 0x560 )
         // under bcc32 5.5.1 bad_cast doesn't derive from exception
@@ -521,11 +527,10 @@
             std::string::size_type const grouping_size = grouping.size();
             CharT thousands_sep = grouping_size ? np.thousands_sep() : 0;
             std::string::size_type group = 0; // current group number
- char last_grp_size = grouping[0] <= 0 ? CHAR_MAX : grouping[0];
- // a) Since grouping is const, grouping[grouping.size()] returns 0.
- // b) It's safe to assume here and below that CHAR_MAX
- // is equivalent to unlimited grouping:
+ char last_grp_size =
+ grouping_size == 0 || grouping[0] <= 0 ? CHAR_MAX : grouping[0];
 #ifndef BOOST_NO_LIMITS_COMPILE_TIME_CONSTANTS
+ // Check that ulimited group is unreachable:
             BOOST_STATIC_ASSERT(std::numeric_limits<T>::digits10 < CHAR_MAX);
 #endif
 
@@ -1120,6 +1125,7 @@
 # pragma warning( push )
 # pragma warning( disable : 4701 ) // possible use of ... before initialization
 # pragma warning( disable : 4702 ) // unreachable code
+# pragma warning( disable : 4267 ) // conversion from 'size_t' to 'unsigned int'
 #endif
 
         template< typename Target
@@ -1149,7 +1155,7 @@
 
             Target result;
             if(!(interpreter << arg && interpreter >> result))
- BOOST_LCAST_THROW_BAD_CAST(Source, Target);
+ BOOST_LCAST_THROW_BAD_CAST(Source, Target);
             return result;
         }
 #if (defined _MSC_VER)
@@ -1191,11 +1197,7 @@
         Target result;
 
         if(!(interpreter << arg && interpreter >> result))
-#ifndef BOOST_NO_TYPEID
- throw_exception(bad_lexical_cast(typeid(Source), typeid(Target)));
-#else
- throw_exception(bad_lexical_cast());
-#endif
+ BOOST_LCAST_THROW_BAD_CAST(Source, Target);
         return result;
     }
 

Modified: branches/release/libs/conversion/lexical_cast.htm
==============================================================================
--- branches/release/libs/conversion/lexical_cast.htm (original)
+++ branches/release/libs/conversion/lexical_cast.htm 2011-05-13 13:44:51 EDT (Fri, 13 May 2011)
@@ -194,32 +194,74 @@
 </pre>
                         </blockquote>Exception used to indicate runtime lexical_cast
                 failure.
- <hr>
                 
-<h2><a name="faq">Frequently Asked Questions</h2>
- <p> Q: Why does <code>lexical_cast&lt;int8_t&gt;("127")</code> throw <code>bad_lexical_cast</code>?
- <br> A: The type <code>int8_t</code> is a typedef to <code>char</code> or <code>signed char</code>.
+<hr>
+<!--
+The original design of lexical_cast library does not supports throwing/nonthrowing behaviour, default values,
+locales... BOOST_LEXICAL_CAST_ASSUME_C_LOCALE is a good optimization, but it breaks down the original design.
+-->
+<!--
+ <h2><a name="BOOST_LEXICAL_CAST_ASSUME_C_LOCALE"><code>BOOST_LEXICAL_CAST_ASSUME_C_LOCALE</code></a></h2>
+ <blockquote><pre>#define BOOST_LEXICAL_CAST_ASSUME_C_LOCALE</blockquote></pre>
+or,
+ <blockquote><pre>g++ -DBOOST_LEXICAL_CAST_ASSUME_C_LOCALE ... (gcc on Linux/Unix)</blockquote></pre>
+ <blockquote><pre>cl.exe /DBOOST_LEXICAL_CAST_ASSUME_C_LOCALE ... (Visual C++ on Windows)</blockquote></pre>
+</pre>
+Eliminate an overhead of <code>std::locale</code> if your program runs in the "C" locale. If the option is set but a program runs in other locale, <code>lexical_cast</code> result is unspecified.
+<hr>
+-->
+
+<h2><a name="faq">Frequently Asked Questions</a></h2>
+
+<table>
+ <tr>
+ <td valign="top"><b>Question:</b></td>
+ <td>Why does <code>lexical_cast&lt;int8_t&gt;("127")</code> throw <code>bad_lexical_cast</code>?</td>
+ </tr>
+ <tr>
+ <td valign="top"><b>Answer:</b></td>
+ <td>The type <code>int8_t</code> is a typedef to <code>char</code> or <code>signed char</code>.
     Lexical conversion to these types is simply reading a byte from source but since the source has
     more than one byte, the exception is thrown.
- <p>Please use other integer types such as <code>int</code> or <code>short int</code>. If bounds checking
+ Please use other integer types such as <code>int</code> or <code>short int</code>. If bounds checking
     is important, you can also call numeric_cast:
-
 <pre>numeric_cast&lt;int8_t&gt;(lexical_cast&lt;int&gt;("127"));</pre>
+ </td>
+ </tr>
+ <tr>
+ <td valign="top"><b>Question:</b></td><td>What does <code>lexical_cast&lt;std::string&gt;</code> of an <code>int8_t</code> or <code>uint8_t</code> not do what I expect?</td>
+ </tr>
+ <tr>
+ <td valign="top"><b>Answer:</b></td><td>As above, note that <code>int8_t</code> and <code>uint8_t</code> are actually chars and are formatted as such. To avoid this, cast to an integer type first:
+ <pre>lexical_cast&lt;std::string&gt;(static_cast&lt;int&gt;(n));</pre>
+ </td>
+ </tr>
+ <tr>
+ <td valign="top"><b>Question:</b></td>
+ <td>The implementation always resets the <code>ios_base::skipws</code> flag of an underlying stream object. It breaks my <code>operator&gt;&gt;</code> that works only in presence of this flag. Can you remove code that resets the flag?</td>
+ </tr>
+ <tr>
+ <td valign="top"><b>Answer:</b></td>
+ <td>May be in a future version. There is no requirement in [N1973] to reset the flag but remember that [N1973] is not yet accepted by the committee. By the way, it's a great opportunity to make your <code>operator&gt;&gt;</code> conform to the standard. Read a good C++ book, study <code>std::sentry</code> and ios_state_saver.
+ </td>
+ </tr>
+ <tr>
+ <td valign="top"><b>Question:</b></td>
+ <td>Why <code>std::cout << boost::lexical_cast&lt;unsigned int&gt;("-1");</code> does not throw, but outputs 4294967295?</td>
+ </tr>
+ <tr>
+ <td valign="top"><b>Answer:</b></td>
+ <td><code>boost::lexical_cast</code> has the behavior of <code>stringstream</code>, which uses <code>num_get</code> functions of <code>std::locale</code> to convert numbers. If we look at the [22.2.2.1.2] of Programming languages &mdash; C++, we'll see, that <code>num_get</code> uses the rules of <code>scanf</code> for conversions. And in the C99 standard for unsigned input value minus sign is optional, so if a negative number is read, no errors will arise and the result will be the two's complement.
+ </td>
+ </tr>
+</table>
 
- <p> Q: What does <code>lexical_cast&lt;std::string&gt;</code> of an <code>int8_t</code> or <code>uint8_t</code> not do what I expect?
- <br> A: As above, note that <code>int8_t</code> and <code>uint8_t</code> are actually chars and are formatted as such. To avoid this, cast to an integer type first:
-
-<pre>lexical_cast&lt;std::string&gt;(static_cast&lt;int&gt;(n));</pre>
-
- <p> Q: The implementation always resets the <code>ios_base::skipws</code> flag of an underlying stream object. It breaks my <code>operator&gt;&gt;</code> that works only in presence of this flag. Can you remove code that resets the flag?
- <br> A: May be in a future version. There is no requirement in [N1973] to reset the flag but remember that [N1973] is not yet accepted by the committee. By the way, it's a great opportunity to make your <code>operator&gt;&gt;</code> conform to the standard. Read a good C++ book, study <code>std::sentry</code> and ios_state_saver.
-</ul>
-<h2><a name="references">References</h2>
+<h2><a name="references">References</a></h2>
 <ul type="square">
- <a name="n1973"></a><li> [N1973] Kevlin Henney, Beman Dawes, Lexical Conversion Library Proposal for TR2,
+ <li><a name="n1973"></a>[N1973] Kevlin Henney, Beman Dawes, Lexical Conversion Library Proposal for TR2,
       <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2006/n1973.html">N1973</a>.
       <a name="tuning"></a><li> [Tuning] Alexander Nasonov, Fine Tuning for lexical_cast,
- Overload #74,
+ Overload #74 (PDF),
       August 2006.</li>
 </ul>
 <h2><a name="changes">Changes</a></h2>
@@ -265,6 +307,12 @@
         <p>
                         <hr>
                         
-<div align="right"><small><i>&copy; Copyright Kevlin Henney, 2000&#150;2005</i></small></div>
+<div align="right"><small><i>Copyright &copy; Kevlin Henney, 2000-2005</i></small></div>
+<div align="right"><small><i>Copyright &copy; Alexander Nasonov, 2006-2010</i></small></div>
+<div align="right"><small><i>Copyright &copy; Antony Polukhin, 2011</i></small></div>
+<div align="right"><small><i>
+ 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)</i></small>
+</div>
         </body>
 </html>

Modified: branches/release/libs/conversion/lexical_cast_test.cpp
==============================================================================
--- branches/release/libs/conversion/lexical_cast_test.cpp (original)
+++ branches/release/libs/conversion/lexical_cast_test.cpp 2011-05-13 13:44:51 EDT (Fri, 13 May 2011)
@@ -11,6 +11,13 @@
 //
 // Note: The unit test no longer compile on MSVC 6, but lexical_cast itself works for it.
 
+//
+// We need this #define before any #includes: otherwise msvc will emit warnings
+// deep within std::string, resulting from our (perfectly legal) use of basic_string
+// with a custom traits class:
+//
+#define _SCL_SECURE_NO_WARNINGS
+
 #include <boost/config.hpp>
 
 #if defined(__INTEL_COMPILER)


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