mirror of
https://github.com/boostorg/conversion.git
synced 2025-08-02 22:14:28 +02:00
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. [SVN r71923]
This commit is contained in:
@@ -55,7 +55,13 @@
|
|||||||
namespace boost
|
namespace boost
|
||||||
{
|
{
|
||||||
// exception used to indicate runtime lexical_cast failure
|
// 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 )
|
#if defined(__BORLANDC__) && BOOST_WORKAROUND( __BORLANDC__, < 0x560 )
|
||||||
// under bcc32 5.5.1 bad_cast doesn't derive from exception
|
// under bcc32 5.5.1 bad_cast doesn't derive from exception
|
||||||
@@ -521,11 +527,10 @@ namespace boost
|
|||||||
std::string::size_type const grouping_size = grouping.size();
|
std::string::size_type const grouping_size = grouping.size();
|
||||||
CharT thousands_sep = grouping_size ? np.thousands_sep() : 0;
|
CharT thousands_sep = grouping_size ? np.thousands_sep() : 0;
|
||||||
std::string::size_type group = 0; // current group number
|
std::string::size_type group = 0; // current group number
|
||||||
char last_grp_size = grouping[0] <= 0 ? CHAR_MAX : grouping[0];
|
char last_grp_size =
|
||||||
// a) Since grouping is const, grouping[grouping.size()] returns 0.
|
grouping_size == 0 || grouping[0] <= 0 ? CHAR_MAX : grouping[0];
|
||||||
// b) It's safe to assume here and below that CHAR_MAX
|
|
||||||
// is equivalent to unlimited grouping:
|
|
||||||
#ifndef BOOST_NO_LIMITS_COMPILE_TIME_CONSTANTS
|
#ifndef BOOST_NO_LIMITS_COMPILE_TIME_CONSTANTS
|
||||||
|
// Check that ulimited group is unreachable:
|
||||||
BOOST_STATIC_ASSERT(std::numeric_limits<T>::digits10 < CHAR_MAX);
|
BOOST_STATIC_ASSERT(std::numeric_limits<T>::digits10 < CHAR_MAX);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -1120,6 +1125,7 @@ namespace boost
|
|||||||
# pragma warning( push )
|
# pragma warning( push )
|
||||||
# pragma warning( disable : 4701 ) // possible use of ... before initialization
|
# pragma warning( disable : 4701 ) // possible use of ... before initialization
|
||||||
# pragma warning( disable : 4702 ) // unreachable code
|
# pragma warning( disable : 4702 ) // unreachable code
|
||||||
|
# pragma warning( disable : 4267 ) // conversion from 'size_t' to 'unsigned int'
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
template< typename Target
|
template< typename Target
|
||||||
@@ -1191,11 +1197,7 @@ namespace boost
|
|||||||
Target result;
|
Target result;
|
||||||
|
|
||||||
if(!(interpreter << arg && interpreter >> result))
|
if(!(interpreter << arg && interpreter >> result))
|
||||||
#ifndef BOOST_NO_TYPEID
|
BOOST_LCAST_THROW_BAD_CAST(Source, Target);
|
||||||
throw_exception(bad_lexical_cast(typeid(Source), typeid(Target)));
|
|
||||||
#else
|
|
||||||
throw_exception(bad_lexical_cast());
|
|
||||||
#endif
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -194,32 +194,74 @@ public:
|
|||||||
</pre>
|
</pre>
|
||||||
</blockquote>Exception used to indicate runtime <a href="#lexical_cast"><code>lexical_cast</code></a>
|
</blockquote>Exception used to indicate runtime <a href="#lexical_cast"><code>lexical_cast</code></a>
|
||||||
failure.
|
failure.
|
||||||
<hr>
|
|
||||||
|
|
||||||
<h2><a name="faq">Frequently Asked Questions</h2>
|
<hr>
|
||||||
<p> Q: Why does <code>lexical_cast<int8_t>("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>.
|
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<int8_t>("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
|
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.
|
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 <a href="../../libs/numeric/conversion/doc/html/boost_numericconversion/improved_numeric_cast__.html">numeric_cast</a>:
|
is important, you can also call <a href="../../libs/numeric/conversion/doc/html/boost_numericconversion/improved_numeric_cast__.html">numeric_cast</a>:
|
||||||
|
|
||||||
<pre><a href="../../libs/numeric/conversion/doc/html/boost_numericconversion/improved_numeric_cast__.html">numeric_cast</a><int8_t>(lexical_cast<int>("127"));</pre>
|
<pre><a href="../../libs/numeric/conversion/doc/html/boost_numericconversion/improved_numeric_cast__.html">numeric_cast</a><int8_t>(lexical_cast<int>("127"));</pre>
|
||||||
|
</td>
|
||||||
<p> Q: What does <code>lexical_cast<std::string></code> of an <code>int8_t</code> or <code>uint8_t</code> not do what I expect?
|
</tr>
|
||||||
<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:
|
<tr>
|
||||||
|
<td valign="top"><b>Question:</b></td><td>What does <code>lexical_cast<std::string></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<std::string>(static_cast<int>(n));</pre>
|
<pre>lexical_cast<std::string>(static_cast<int>(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>></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 <a href="#n1973">[N1973]</a> to reset the flag but remember that <a href="#n1973">[N1973]</a> is not yet accepted by the committee. By the way, it's a great opportunity to make your <code>operator>></code> conform to the standard. Read a good C++ book, study <code>std::sentry</code> and <a href="../../libs/io/doc/ios_state.html">ios_state_saver</a>.
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td valign="top"><b>Question:</b></td>
|
||||||
|
<td>Why <code>std::cout << boost::lexical_cast<unsigned int>("-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 — 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: The implementation always resets the <code>ios_base::skipws</code> flag of an underlying stream object. It breaks my <code>operator>></code> that works only in presence of this flag. Can you remove code that resets the flag?
|
<h2><a name="references">References</a></h2>
|
||||||
<br> A: May be in a future version. There is no requirement in <a href="#n1973">[N1973]</a> to reset the flag but remember that <a href="#n1973">[N1973]</a> is not yet accepted by the committee. By the way, it's a great opportunity to make your <code>operator>></code> conform to the standard. Read a good C++ book, study <code>std::sentry</code> and <a href="../../libs/io/doc/ios_state.html">ios_state_saver</a>.
|
|
||||||
</ul>
|
|
||||||
<h2><a name="references">References</h2>
|
|
||||||
<ul type="square">
|
<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 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,
|
<a name="tuning"></a><li> [Tuning] Alexander Nasonov, Fine Tuning for lexical_cast,
|
||||||
<a href="http://www.accu.org/var/uploads/journals/overload74.pdf">Overload #74</a>,
|
<a href="http://accu.org/index.php/journals/1375">Overload #74</a> (<a href="http://www.accu.org/var/uploads/journals/overload74.pdf">PDF</a>),
|
||||||
August 2006.</li>
|
August 2006.</li>
|
||||||
</ul>
|
</ul>
|
||||||
<h2><a name="changes">Changes</a></h2>
|
<h2><a name="changes">Changes</a></h2>
|
||||||
@@ -265,6 +307,12 @@ public:
|
|||||||
<p>
|
<p>
|
||||||
<hr>
|
<hr>
|
||||||
|
|
||||||
<div align="right"><small><i>© Copyright Kevlin Henney, 2000–2005</i></small></div>
|
<div align="right"><small><i>Copyright © Kevlin Henney, 2000-2005</i></small></div>
|
||||||
|
<div align="right"><small><i>Copyright © Alexander Nasonov, 2006-2010</i></small></div>
|
||||||
|
<div align="right"><small><i>Copyright © 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 <a href="/LICENSE_1_0.txt" target="_top">http://www.boost.org/LICENSE_1_0.txt</a>)</i></small>
|
||||||
|
</div>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
@@ -11,6 +11,13 @@
|
|||||||
//
|
//
|
||||||
// Note: The unit test no longer compile on MSVC 6, but lexical_cast itself works for it.
|
// 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>
|
#include <boost/config.hpp>
|
||||||
|
|
||||||
#if defined(__INTEL_COMPILER)
|
#if defined(__INTEL_COMPILER)
|
||||||
|
Reference in New Issue
Block a user