mirror of
https://github.com/boostorg/conversion.git
synced 2026-08-06 13:34:14 +02:00
Compare commits
14 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 053f330b0a | |||
| 6c5f31e7a5 | |||
| 1f7147d24b | |||
| a385c3ec99 | |||
| 701d5f0bf0 | |||
| b5583b88fa | |||
| 5b6e39b2b8 | |||
| 04f73e5a89 | |||
| 65328d9716 | |||
| dc151d2b5a | |||
| 23949682c1 | |||
| 5055e842cf | |||
| 9e764f3e49 | |||
| a3e690da32 |
@@ -1,22 +0,0 @@
|
||||
#----------------------------------------------------------------------------
|
||||
# This file was automatically generated from the original CMakeLists.txt file
|
||||
# Add a variable to hold the headers for the library
|
||||
set (lib_headers
|
||||
|
||||
)
|
||||
|
||||
# Add a library target to the build system
|
||||
boost_library_project(
|
||||
conversion
|
||||
# SRCDIRS
|
||||
TESTDIRS test
|
||||
# HEADERS ${lib_headers}
|
||||
# DOCDIRS
|
||||
DESCRIPTION "Polymorphic and lexical casts"
|
||||
# MODULARIZED
|
||||
AUTHORS "David Abrahams <dave -at- boost-consulting.com>"
|
||||
"Kevlin Henney"
|
||||
# MAINTAINERS
|
||||
)
|
||||
|
||||
|
||||
@@ -173,8 +173,8 @@ inline void lcast_set_precision(std::ios_base& stream, T*)
|
||||
template<class Source, class Target>
|
||||
inline void lcast_set_precision(std::ios_base& stream, Source*, Target*)
|
||||
{
|
||||
std::streamsize const s = lcast_get_precision((Source*)0);
|
||||
std::streamsize const t = lcast_get_precision((Target*)0);
|
||||
std::streamsize const s = lcast_get_precision(static_cast<Source*>(0));
|
||||
std::streamsize const t = lcast_get_precision(static_cast<Target*>(0));
|
||||
stream.precision(s > t ? s : t);
|
||||
}
|
||||
|
||||
|
||||
Executable → Regular
+733
-100
File diff suppressed because it is too large
Load Diff
+101
-20
@@ -26,6 +26,8 @@
|
||||
<a href="#references">References</a></li>
|
||||
<li>
|
||||
<a href="#changes">Changes</a></li>
|
||||
<li>
|
||||
<a href="#performance">Performance</a></li>
|
||||
</ul>
|
||||
<hr>
|
||||
<h2><a name="motivation">Motivation</a></h2>
|
||||
@@ -87,7 +89,7 @@
|
||||
For a good discussion of the options and issues involved in string-based
|
||||
formatting, including comparison of <code>stringstream</code>, <code>lexical_cast</code>,
|
||||
and others, see Herb Sutter's article, <a href="http://www.gotw.ca/publications/mill19.htm">
|
||||
<i>The String Formatters of Manor Farm</i></a>.
|
||||
<i>The String Formatters of Manor Farm</i></a>. Also, take a look at the <a href="#performance">Performance</a> section.
|
||||
<p>
|
||||
<hr>
|
||||
<h2><a name="examples">Examples</a></h2>
|
||||
@@ -194,35 +196,85 @@ public:
|
||||
</pre>
|
||||
</blockquote>Exception used to indicate runtime <a href="#lexical_cast"><code>lexical_cast</code></a>
|
||||
failure.
|
||||
<hr>
|
||||
|
||||
<h2><a name="faq">Frequently Asked Questions</h2>
|
||||
<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>.
|
||||
<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<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
|
||||
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>:
|
||||
|
||||
<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>
|
||||
</tr>
|
||||
<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>
|
||||
</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: What does <code>lexical_cast<std::string></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<std::string>(static_cast<int>(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>></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 <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>
|
||||
<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,
|
||||
<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>
|
||||
</ul>
|
||||
<h2><a name="changes">Changes</a></h2>
|
||||
<h3>May 2011:</h3>
|
||||
<ul type="square">
|
||||
<li>Optimizations for "C" and other locales without number grouping.</li>
|
||||
<li>Better performance and less memory usage for unsigned char and signed char conversions.</li>
|
||||
<li>Better performance and less memory usage for conversions to arithmetic types.</li>
|
||||
<li>Better performance and less memory usage for conversions from arithmetic type to arithmetic type.</li>
|
||||
<li>Directly construct <code>Target</code> from <code>Source</code> on some conversions (like conversions from string to string, from char array to string, from char to char and others).</li>
|
||||
</ul>
|
||||
<h3>August, October 2006:</h3>
|
||||
<ul type="square">
|
||||
<li>Better performance for many combinations of <code>Source</code> and <code>Target</code>
|
||||
@@ -264,7 +316,36 @@ public:
|
||||
</ul>
|
||||
<p>
|
||||
<hr>
|
||||
|
||||
<div align="right"><small><i>© Copyright Kevlin Henney, 2000–2005</i></small></div>
|
||||
|
||||
<h2><a name="performance">Performance</a></h2>
|
||||
This table shows the execution time in milliseconds for 100000 calls of the following string formatters:
|
||||
|
||||
<table border="1" width="100%">
|
||||
<tr>
|
||||
<tr><td>From->To</td><td> <code>lexical_cast</code> </td><td><code>std::stringstream</code><br>with construction</td><td><code>std::stringstream</code><br>without construction</td><td><code>sscanf</code>/<code>sprintf</code></td></tr>
|
||||
<tr><td>string->char</td><td bgcolor="#00C000"><1</td><td>91</td><td>7</td><td>10</td></tr>
|
||||
<tr><td>string->int</td><td bgcolor="#00C000">7</td><td>115</td><td>23</td><td>18</td></tr>
|
||||
<tr><td>string->unsigned int</td><td bgcolor="#00C000">7</td><td>117</td><td>22</td><td>17</td></tr>
|
||||
<tr><td>string->bool</td><td bgcolor="#00C000"><1</td><td>104</td><td>19</td><td>10</td></tr>
|
||||
<tr><td>string->float</td><td>85</td><td>172</td><td>60</td><td bgcolor="#00C000">33</td></tr>
|
||||
<tr><td>char->string</td><td bgcolor="#00C000">7</td><td>105</td><td>16</td><td>12</td></tr>
|
||||
<tr><td>int->string</td><td bgcolor="#00C000">15</td><td>131</td><td>21</td><td>17</td></tr>
|
||||
<tr><td>unsigned int->string</td><td bgcolor="#00C000">14</td><td>125</td><td>21</td><td>17</td></tr>
|
||||
<tr><td>bool->string</td><td bgcolor="#00C000">7</td><td>122</td><td>24</td><td>12</td></tr>
|
||||
<tr><td>float->string</td><td>124</td><td>223</td><td>115</td><td bgcolor="#00C000">48</td></tr>
|
||||
<tr><td>char*->string</td><td bgcolor="#00C000">9</td><td>123</td><td>20</td><td>---</td></tr>
|
||||
<tr><td>int->int</td><td bgcolor="#00C000"><1</td><td>120</td><td>26</td><td>---</td></tr>
|
||||
<tr><td>float->float</td><td bgcolor="#00C000"><1</td><td>262</td><td>142</td><td>---</td></tr>
|
||||
</table>
|
||||
|
||||
Fastest results are highlitened with green.
|
||||
<hr>
|
||||
<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>
|
||||
</html>
|
||||
|
||||
+266
-36
@@ -2,8 +2,9 @@
|
||||
//
|
||||
// See http://www.boost.org for most recent version, including documentation.
|
||||
//
|
||||
// Copyright Terje Slettebø and Kevlin Henney, 2005.
|
||||
// Copyright Terje Sletteb and Kevlin Henney, 2005.
|
||||
// Copyright Alexander Nasonov, 2006.
|
||||
// Copyright Antony Polukhin, 2011.
|
||||
//
|
||||
// Distributed under the Boost
|
||||
// Software License, Version 1.0. (See accompanying file
|
||||
@@ -11,6 +12,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)
|
||||
@@ -21,18 +29,14 @@
|
||||
|
||||
#include <boost/lexical_cast.hpp>
|
||||
|
||||
#include <boost/cstdint.hpp>
|
||||
#include <boost/test/unit_test.hpp>
|
||||
#include <boost/test/floating_point_comparison.hpp>
|
||||
|
||||
#include <boost/type_traits/integral_promotion.hpp>
|
||||
#include <string>
|
||||
#include <memory>
|
||||
|
||||
#if defined(BOOST_NO_STRINGSTREAM) || \
|
||||
defined(BOOST_NO_STD_WSTRING) || \
|
||||
defined(BOOST_NO_STD_LOCALE)
|
||||
#define DISABLE_WIDE_CHAR_SUPPORT
|
||||
#endif
|
||||
|
||||
#if (defined(BOOST_HAS_LONG_LONG) || defined(BOOST_HAS_MS_INT64)) \
|
||||
&& !(defined(BOOST_MSVC) && BOOST_MSVC < 1300)
|
||||
#define LCAST_TEST_LONGLONG
|
||||
@@ -76,16 +80,22 @@ void test_conversion_from_to_int();
|
||||
void test_conversion_from_to_uint();
|
||||
void test_conversion_from_to_long();
|
||||
void test_conversion_from_to_ulong();
|
||||
void test_conversion_from_to_intmax_t();
|
||||
void test_conversion_from_to_uintmax_t();
|
||||
#ifdef LCAST_TEST_LONGLONG
|
||||
void test_conversion_from_to_longlong();
|
||||
void test_conversion_from_to_ulonglong();
|
||||
#endif
|
||||
void test_conversion_from_to_float();
|
||||
void test_conversion_from_to_double();
|
||||
void test_conversion_from_to_long_double();
|
||||
#ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
|
||||
void test_traits();
|
||||
void test_wtraits();
|
||||
void test_allocator();
|
||||
void test_wallocator();
|
||||
#endif
|
||||
void test_char_types_conversions();
|
||||
|
||||
unit_test::test_suite *init_unit_test_suite(int, char *[])
|
||||
{
|
||||
@@ -98,30 +108,37 @@ unit_test::test_suite *init_unit_test_suite(int, char *[])
|
||||
suite->add(BOOST_TEST_CASE(test_conversion_from_to_wchar_t_alias));
|
||||
suite->add(BOOST_TEST_CASE(test_conversion_to_pointer));
|
||||
suite->add(BOOST_TEST_CASE(test_conversion_to_string));
|
||||
#ifndef DISABLE_WIDE_CHAR_SUPPORT
|
||||
#ifndef BOOST_LCAST_NO_WCHAR_T
|
||||
suite->add(BOOST_TEST_CASE(test_conversion_from_wchar_t));
|
||||
suite->add(BOOST_TEST_CASE(test_conversion_to_wchar_t));
|
||||
suite->add(BOOST_TEST_CASE(test_conversion_from_wstring));
|
||||
suite->add(BOOST_TEST_CASE(test_conversion_to_wstring));
|
||||
#endif
|
||||
#endif
|
||||
suite->add(BOOST_TEST_CASE(test_bad_lexical_cast));
|
||||
suite->add(BOOST_TEST_CASE(test_no_whitespace_stripping));
|
||||
suite->add(BOOST_TEST_CASE(&test_conversion_from_to_short));
|
||||
suite->add(BOOST_TEST_CASE(&test_conversion_from_to_ushort));
|
||||
suite->add(BOOST_TEST_CASE(&test_conversion_from_to_int));
|
||||
suite->add(BOOST_TEST_CASE(&test_conversion_from_to_uint));
|
||||
suite->add(BOOST_TEST_CASE(&test_conversion_from_to_ulong));
|
||||
suite->add(BOOST_TEST_CASE(&test_conversion_from_to_long));
|
||||
#ifdef LCAST_TEST_LONGLONG
|
||||
suite->add(BOOST_TEST_CASE(&test_conversion_from_to_ulong));
|
||||
suite->add(BOOST_TEST_CASE(&test_conversion_from_to_intmax_t));
|
||||
suite->add(BOOST_TEST_CASE(&test_conversion_from_to_uintmax_t));
|
||||
#ifdef LCAST_TEST_LONGLONG
|
||||
suite->add(BOOST_TEST_CASE(&test_conversion_from_to_longlong));
|
||||
suite->add(BOOST_TEST_CASE(&test_conversion_from_to_ulonglong));
|
||||
#endif
|
||||
#ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
|
||||
#endif
|
||||
suite->add(BOOST_TEST_CASE(&test_conversion_from_to_float));
|
||||
suite->add(BOOST_TEST_CASE(&test_conversion_from_to_double));
|
||||
suite->add(BOOST_TEST_CASE(&test_conversion_from_to_long_double));
|
||||
#ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
|
||||
suite->add(BOOST_TEST_CASE(&test_traits));
|
||||
suite->add(BOOST_TEST_CASE(&test_wtraits));
|
||||
suite->add(BOOST_TEST_CASE(&test_allocator));
|
||||
suite->add(BOOST_TEST_CASE(&test_wallocator));
|
||||
#endif
|
||||
#endif
|
||||
|
||||
suite->add(BOOST_TEST_CASE(&test_char_types_conversions));
|
||||
|
||||
return suite;
|
||||
}
|
||||
@@ -223,10 +240,24 @@ void test_conversion_to_bool()
|
||||
BOOST_CHECK_EQUAL(false, lexical_cast<bool>("0"));
|
||||
BOOST_CHECK_EQUAL(true, lexical_cast<bool>(std::string("1")));
|
||||
BOOST_CHECK_EQUAL(false, lexical_cast<bool>(std::string("0")));
|
||||
|
||||
BOOST_CHECK_THROW(lexical_cast<bool>(1.0001L), bad_lexical_cast);
|
||||
BOOST_CHECK_THROW(lexical_cast<bool>(2), bad_lexical_cast);
|
||||
BOOST_CHECK_THROW(lexical_cast<bool>(2u), bad_lexical_cast);
|
||||
BOOST_CHECK_THROW(lexical_cast<bool>(-1), bad_lexical_cast);
|
||||
BOOST_CHECK_THROW(lexical_cast<bool>(-2), bad_lexical_cast);
|
||||
|
||||
|
||||
BOOST_CHECK_THROW(
|
||||
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()
|
||||
@@ -263,14 +294,14 @@ void test_conversion_from_to_wchar_t_alias()
|
||||
void test_conversion_to_pointer()
|
||||
{
|
||||
BOOST_CHECK_THROW(lexical_cast<char *>("Test"), bad_lexical_cast);
|
||||
#ifndef DISABLE_WIDE_CHAR_SUPPORT
|
||||
#ifndef BOOST_LCAST_NO_WCHAR_T
|
||||
BOOST_CHECK_THROW(lexical_cast<wchar_t *>("Test"), bad_lexical_cast);
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
|
||||
void test_conversion_from_wchar_t()
|
||||
{
|
||||
#ifndef DISABLE_WIDE_CHAR_SUPPORT
|
||||
#ifndef BOOST_LCAST_NO_WCHAR_T
|
||||
#if !defined(BOOST_NO_INTRINSIC_WCHAR_T)
|
||||
BOOST_CHECK_EQUAL(1, lexical_cast<int>(L'1'));
|
||||
BOOST_CHECK_THROW(lexical_cast<int>(L'A'), bad_lexical_cast);
|
||||
@@ -303,7 +334,7 @@ void test_conversion_from_wchar_t()
|
||||
|
||||
void test_conversion_to_wchar_t()
|
||||
{
|
||||
#if !defined(DISABLE_WIDE_CHAR_SUPPORT) && !defined(BOOST_NO_INTRINSIC_WCHAR_T)
|
||||
#if !defined(BOOST_LCAST_NO_WCHAR_T) && !defined(BOOST_NO_INTRINSIC_WCHAR_T)
|
||||
BOOST_CHECK_EQUAL(L'1', lexical_cast<wchar_t>(1));
|
||||
BOOST_CHECK_EQUAL(L'0', lexical_cast<wchar_t>(0));
|
||||
BOOST_CHECK_EQUAL(L'1', lexical_cast<wchar_t>('1'));
|
||||
@@ -325,12 +356,12 @@ void test_conversion_to_wchar_t()
|
||||
lexical_cast<wchar_t>(std::wstring(L"")), bad_lexical_cast);
|
||||
BOOST_CHECK_THROW(
|
||||
lexical_cast<wchar_t>(std::wstring(L"Test")), bad_lexical_cast);
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
|
||||
void test_conversion_from_wstring()
|
||||
{
|
||||
#ifndef DISABLE_WIDE_CHAR_SUPPORT
|
||||
#ifndef BOOST_LCAST_NO_WCHAR_T
|
||||
BOOST_CHECK_EQUAL(123, lexical_cast<int>(std::wstring(L"123")));
|
||||
BOOST_CHECK_THROW(
|
||||
lexical_cast<int>(std::wstring(L"")), bad_lexical_cast);
|
||||
@@ -343,12 +374,12 @@ void test_conversion_from_wstring()
|
||||
lexical_cast<bool>(std::wstring(L"")), bad_lexical_cast);
|
||||
BOOST_CHECK_THROW(
|
||||
lexical_cast<bool>(std::wstring(L"Test")), bad_lexical_cast);
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
|
||||
void test_conversion_to_wstring()
|
||||
{
|
||||
#ifndef DISABLE_WIDE_CHAR_SUPPORT
|
||||
#ifndef BOOST_LCAST_NO_WCHAR_T
|
||||
wchar_t buf[] = L"hello";
|
||||
wchar_t* str = buf;
|
||||
BOOST_CHECK(str == lexical_cast<std::wstring>(str));
|
||||
@@ -368,7 +399,7 @@ void test_conversion_to_wstring()
|
||||
BOOST_CHECK(L"Test" == lexical_cast<std::wstring>(std::wstring(L"Test")));
|
||||
BOOST_CHECK(L" " == lexical_cast<std::wstring>(std::wstring(L" ")));
|
||||
BOOST_CHECK(L"" == lexical_cast<std::wstring>(std::wstring(L"")));
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
|
||||
void test_bad_lexical_cast()
|
||||
@@ -441,6 +472,24 @@ void test_conversion_from_integral_to_char(CharT zero)
|
||||
BOOST_CHECK_THROW(lexical_cast<CharT>(t), bad_lexical_cast);
|
||||
}
|
||||
|
||||
template<class T, class CharT>
|
||||
void test_conversion_from_char_to_integral(CharT zero)
|
||||
{
|
||||
BOOST_CHECK(lexical_cast<T>( static_cast<CharT>(zero + 0)) == static_cast<T>(0) );
|
||||
BOOST_CHECK(lexical_cast<T>( static_cast<CharT>(zero + 1)) == static_cast<T>(1) );
|
||||
BOOST_CHECK(lexical_cast<T>( static_cast<CharT>(zero + 2)) == static_cast<T>(2) );
|
||||
BOOST_CHECK(lexical_cast<T>( static_cast<CharT>(zero + 3)) == static_cast<T>(3) );
|
||||
BOOST_CHECK(lexical_cast<T>( static_cast<CharT>(zero + 4)) == static_cast<T>(4) );
|
||||
BOOST_CHECK(lexical_cast<T>( static_cast<CharT>(zero + 5)) == static_cast<T>(5) );
|
||||
BOOST_CHECK(lexical_cast<T>( static_cast<CharT>(zero + 6)) == static_cast<T>(6) );
|
||||
BOOST_CHECK(lexical_cast<T>( static_cast<CharT>(zero + 7)) == static_cast<T>(7) );
|
||||
BOOST_CHECK(lexical_cast<T>( static_cast<CharT>(zero + 8)) == static_cast<T>(8) );
|
||||
BOOST_CHECK(lexical_cast<T>( static_cast<CharT>(zero + 9)) == static_cast<T>(9) );
|
||||
|
||||
BOOST_CHECK_THROW(lexical_cast<T>( static_cast<CharT>(zero + 10)), bad_lexical_cast);
|
||||
BOOST_CHECK_THROW(lexical_cast<T>( static_cast<CharT>(zero - 1)), bad_lexical_cast);
|
||||
}
|
||||
|
||||
template<class T>
|
||||
void test_conversion_from_integral_to_integral()
|
||||
{
|
||||
@@ -522,27 +571,71 @@ template<class T, class CharT>
|
||||
void test_conversion_from_string_to_integral(CharT)
|
||||
{
|
||||
typedef std::numeric_limits<T> limits;
|
||||
typedef std::basic_string<CharT> string_type;
|
||||
|
||||
T t;
|
||||
string_type s;
|
||||
string_type const zero = to_str<CharT>(0);
|
||||
string_type const nine = to_str<CharT>(9);
|
||||
T const min_val = (limits::min)();
|
||||
T const max_val = (limits::max)();
|
||||
|
||||
t = (limits::min)();
|
||||
BOOST_CHECK(lexical_cast<T>(to_str<CharT>(t)) == t);
|
||||
s = to_str<CharT>(min_val);
|
||||
BOOST_CHECK_EQUAL(lexical_cast<T>(s), min_val);
|
||||
if(limits::is_signed)
|
||||
{
|
||||
BOOST_CHECK_THROW(lexical_cast<T>(s + zero), bad_lexical_cast);
|
||||
BOOST_CHECK_THROW(lexical_cast<T>(s + nine), bad_lexical_cast);
|
||||
}
|
||||
|
||||
t = (limits::max)();
|
||||
BOOST_CHECK(lexical_cast<T>(to_str<CharT>(t)) == t);
|
||||
s = to_str<CharT>(max_val);
|
||||
BOOST_CHECK_EQUAL(lexical_cast<T>(s), max_val);
|
||||
{
|
||||
BOOST_CHECK_THROW(lexical_cast<T>(s + zero), bad_lexical_cast);
|
||||
BOOST_CHECK_THROW(lexical_cast<T>(s + nine), bad_lexical_cast);
|
||||
|
||||
s = to_str<CharT>(max_val);
|
||||
for (int i =1; i <=10; ++i) {
|
||||
s[s.size()-1] += 1;
|
||||
BOOST_CHECK_THROW(lexical_cast<T>( s ), bad_lexical_cast);
|
||||
}
|
||||
|
||||
s = to_str<CharT>(max_val);
|
||||
std::locale loc;
|
||||
typedef std::numpunct<char> numpunct;
|
||||
if ( BOOST_USE_FACET(numpunct, loc).grouping().empty() ) {
|
||||
// Following tests work well for locale C
|
||||
BOOST_CHECK_EQUAL(lexical_cast<T>(to_str<CharT>(0)+s), max_val);
|
||||
BOOST_CHECK_EQUAL(lexical_cast<T>(to_str<CharT>(0)+to_str<CharT>(0)+s), max_val);
|
||||
BOOST_CHECK_EQUAL(lexical_cast<T>(to_str<CharT>(0)+to_str<CharT>(0)+to_str<CharT>(0)+s), max_val);
|
||||
}
|
||||
|
||||
for (int i =1; i <=256; ++i) {
|
||||
BOOST_CHECK_THROW(lexical_cast<T>( to_str<CharT>(i)+s ), bad_lexical_cast);
|
||||
}
|
||||
|
||||
typedef BOOST_DEDUCED_TYPENAME boost::integral_promotion<T>::type promoted;
|
||||
if ( !(boost::is_same<T, promoted>::value) )
|
||||
{
|
||||
promoted prom = max_val;
|
||||
s = to_str<CharT>(max_val);
|
||||
for (int i =1; i <=256; ++i) {
|
||||
BOOST_CHECK_THROW(lexical_cast<T>( to_str<CharT>(prom+i) ), bad_lexical_cast);
|
||||
BOOST_CHECK_THROW(lexical_cast<T>( to_str<CharT>(i)+s ), bad_lexical_cast);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(limits::digits <= 16 && lcast_test_small_integral_types_completely)
|
||||
// min and max have already been tested.
|
||||
for(t = 1 + (limits::min)(); t != (limits::max)(); ++t)
|
||||
for(T t = 1 + min_val; t != max_val; ++t)
|
||||
BOOST_CHECK(lexical_cast<T>(to_str<CharT>(t)) == t);
|
||||
else
|
||||
{
|
||||
T const min_val = (limits::min)();
|
||||
T const max_val = (limits::max)();
|
||||
T const half_max_val = max_val / 2;
|
||||
T const cnt = lcast_integral_test_counter; // to supress warnings
|
||||
unsigned int const counter = cnt < half_max_val ? cnt : half_max_val;
|
||||
|
||||
T t;
|
||||
unsigned int i;
|
||||
|
||||
// Test values around min:
|
||||
@@ -574,10 +667,25 @@ void test_conversion_from_string_to_integral(CharT)
|
||||
template<class T>
|
||||
void test_conversion_from_to_integral_for_locale()
|
||||
{
|
||||
std::locale current_locale;
|
||||
typedef std::numpunct<char> numpunct;
|
||||
numpunct const& np = BOOST_USE_FACET(numpunct, current_locale);
|
||||
if ( !np.grouping().empty() )
|
||||
{
|
||||
BOOST_CHECK_THROW(
|
||||
lexical_cast<T>( std::string("100") + np.thousands_sep() + np.thousands_sep() + "0" )
|
||||
, bad_lexical_cast);
|
||||
BOOST_CHECK_THROW(lexical_cast<T>( std::string("100") + np.thousands_sep() ), bad_lexical_cast);
|
||||
BOOST_CHECK_THROW(lexical_cast<T>( np.thousands_sep() + std::string("100") ), bad_lexical_cast);
|
||||
|
||||
// Exception must not be thrown, when we are using no separators at all
|
||||
BOOST_CHECK( lexical_cast<T>("10000") == static_cast<T>(10000) );
|
||||
}
|
||||
|
||||
test_conversion_from_integral_to_integral<T>();
|
||||
test_conversion_from_integral_to_string<T>('0');
|
||||
test_conversion_from_string_to_integral<T>('0');
|
||||
#if !defined(DISABLE_WIDE_CHAR_SUPPORT) && !defined(BOOST_NO_INTRINSIC_WCHAR_T)
|
||||
#if !defined(BOOST_LCAST_NO_WCHAR_T)
|
||||
test_conversion_from_integral_to_string<T>(L'0');
|
||||
test_conversion_from_string_to_integral<T>(L'0');
|
||||
#endif
|
||||
@@ -596,13 +704,44 @@ void test_conversion_from_to_integral()
|
||||
signed char const szero = '0';
|
||||
unsigned char const uzero = '0';
|
||||
test_conversion_from_integral_to_char<T>(zero);
|
||||
test_conversion_from_char_to_integral<T>(zero);
|
||||
test_conversion_from_integral_to_char<T>(szero);
|
||||
test_conversion_from_char_to_integral<T>(szero);
|
||||
test_conversion_from_integral_to_char<T>(uzero);
|
||||
#if !defined(DISABLE_WIDE_CHAR_SUPPORT) && !defined(BOOST_NO_INTRINSIC_WCHAR_T)
|
||||
test_conversion_from_char_to_integral<T>(uzero);
|
||||
#if !defined(BOOST_LCAST_NO_WCHAR_T) && !defined(BOOST_NO_INTRINSIC_WCHAR_T)
|
||||
wchar_t const wzero = L'0';
|
||||
test_conversion_from_integral_to_char<T>(wzero);
|
||||
test_conversion_from_char_to_integral<T>(wzero);
|
||||
#endif
|
||||
|
||||
BOOST_CHECK(lexical_cast<T>("-1") == static_cast<T>(-1));
|
||||
BOOST_CHECK(lexical_cast<T>("-9") == static_cast<T>(-9));
|
||||
BOOST_CHECK(lexical_cast<T>(-1) == static_cast<T>(-1));
|
||||
BOOST_CHECK(lexical_cast<T>(-9) == static_cast<T>(-9));
|
||||
|
||||
BOOST_CHECK_THROW(lexical_cast<T>("-1.0"), bad_lexical_cast);
|
||||
BOOST_CHECK_THROW(lexical_cast<T>("-9.0"), bad_lexical_cast);
|
||||
BOOST_CHECK(lexical_cast<T>(-1.0) == static_cast<T>(-1));
|
||||
BOOST_CHECK(lexical_cast<T>(-9.0) == static_cast<T>(-9));
|
||||
|
||||
BOOST_CHECK(lexical_cast<T>(static_cast<T>(1)) == static_cast<T>(1));
|
||||
BOOST_CHECK(lexical_cast<T>(static_cast<T>(9)) == static_cast<T>(9));
|
||||
BOOST_CHECK_THROW(lexical_cast<T>(1.1f), bad_lexical_cast);
|
||||
BOOST_CHECK_THROW(lexical_cast<T>(1.1), bad_lexical_cast);
|
||||
BOOST_CHECK_THROW(lexical_cast<T>(1.1L), bad_lexical_cast);
|
||||
BOOST_CHECK_THROW(lexical_cast<T>(1.0001f), bad_lexical_cast);
|
||||
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) );
|
||||
BOOST_CHECK(lexical_cast<T>("+10") == static_cast<T>(10) );
|
||||
BOOST_CHECK(lexical_cast<T>("+90") == static_cast<T>(90) );
|
||||
BOOST_CHECK_THROW(lexical_cast<T>("++1"), bad_lexical_cast);
|
||||
BOOST_CHECK_THROW(lexical_cast<T>("-+9"), bad_lexical_cast);
|
||||
BOOST_CHECK_THROW(lexical_cast<T>("--1"), bad_lexical_cast);
|
||||
BOOST_CHECK_THROW(lexical_cast<T>("+-9"), bad_lexical_cast);
|
||||
// test_conversion_from_to_integral_for_locale
|
||||
|
||||
typedef std::numpunct<char> numpunct;
|
||||
@@ -636,6 +775,35 @@ void test_conversion_from_to_integral()
|
||||
BOOST_TEST_MESSAGE("Formatting with thousands_sep has not been tested");
|
||||
}
|
||||
|
||||
template<class T>
|
||||
void test_conversion_from_to_float()
|
||||
{
|
||||
char const zero = '0';
|
||||
signed char const szero = '0';
|
||||
unsigned char const uzero = '0';
|
||||
test_conversion_from_integral_to_char<T>(zero);
|
||||
test_conversion_from_char_to_integral<T>(zero);
|
||||
test_conversion_from_integral_to_char<T>(szero);
|
||||
test_conversion_from_char_to_integral<T>(szero);
|
||||
test_conversion_from_integral_to_char<T>(uzero);
|
||||
test_conversion_from_char_to_integral<T>(uzero);
|
||||
#if !defined(BOOST_LCAST_NO_WCHAR_T) && !defined(BOOST_NO_INTRINSIC_WCHAR_T)
|
||||
wchar_t const wzero = L'0';
|
||||
test_conversion_from_integral_to_char<T>(wzero);
|
||||
test_conversion_from_char_to_integral<T>(wzero);
|
||||
#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 );
|
||||
|
||||
BOOST_CHECK_THROW(lexical_cast<T>("++1"), bad_lexical_cast);
|
||||
BOOST_CHECK_THROW(lexical_cast<T>("-+9"), bad_lexical_cast);
|
||||
BOOST_CHECK_THROW(lexical_cast<T>("--1"), bad_lexical_cast);
|
||||
BOOST_CHECK_THROW(lexical_cast<T>("+-9"), bad_lexical_cast);
|
||||
}
|
||||
|
||||
void test_conversion_from_to_short()
|
||||
{
|
||||
test_conversion_from_to_integral<short>();
|
||||
@@ -656,14 +824,37 @@ void test_conversion_from_to_uint()
|
||||
test_conversion_from_to_integral<unsigned int>();
|
||||
}
|
||||
|
||||
void test_conversion_from_to_long()
|
||||
{
|
||||
test_conversion_from_to_integral<long>();
|
||||
}
|
||||
|
||||
void test_conversion_from_to_ulong()
|
||||
{
|
||||
test_conversion_from_to_integral<unsigned long>();
|
||||
}
|
||||
|
||||
void test_conversion_from_to_long()
|
||||
void test_conversion_from_to_intmax_t()
|
||||
{
|
||||
test_conversion_from_to_integral<long>();
|
||||
test_conversion_from_to_integral<boost::intmax_t>();
|
||||
}
|
||||
|
||||
void test_conversion_from_to_uintmax_t()
|
||||
{
|
||||
test_conversion_from_to_integral<boost::uintmax_t>();
|
||||
}
|
||||
|
||||
void test_conversion_from_to_float()
|
||||
{
|
||||
test_conversion_from_to_float<float>();
|
||||
}
|
||||
void test_conversion_from_to_double()
|
||||
{
|
||||
test_conversion_from_to_float<double>();
|
||||
}
|
||||
void test_conversion_from_to_long_double()
|
||||
{
|
||||
test_conversion_from_to_float<long double>();
|
||||
}
|
||||
|
||||
#if defined(BOOST_HAS_LONG_LONG)
|
||||
@@ -678,7 +869,7 @@ void test_conversion_from_to_ulonglong()
|
||||
test_conversion_from_to_integral<boost::ulong_long_type>();
|
||||
}
|
||||
|
||||
#elif defined(LCAST_TEST_LONGLONG)
|
||||
#elif defined(BOOST_HAS_MS_INT64)
|
||||
|
||||
void test_conversion_from_to_longlong()
|
||||
{
|
||||
@@ -749,3 +940,42 @@ void test_wallocator()
|
||||
|
||||
#endif
|
||||
|
||||
void test_char_types_conversions()
|
||||
{
|
||||
const char c_arr[] = "Test array of chars";
|
||||
const unsigned char uc_arr[] = "Test array of chars";
|
||||
const signed char sc_arr[] = "Test array of chars";
|
||||
|
||||
BOOST_CHECK(boost::lexical_cast<std::string>(c_arr) == std::string(c_arr));
|
||||
BOOST_CHECK(boost::lexical_cast<std::string>(uc_arr) == std::string(c_arr));
|
||||
BOOST_CHECK(boost::lexical_cast<std::string>(sc_arr) == std::string(c_arr));
|
||||
|
||||
BOOST_CHECK(boost::lexical_cast<char>(c_arr[0]) == c_arr[0]);
|
||||
BOOST_CHECK(boost::lexical_cast<char>(uc_arr[0]) == c_arr[0]);
|
||||
BOOST_CHECK(boost::lexical_cast<char>(sc_arr[0]) == c_arr[0]);
|
||||
|
||||
BOOST_CHECK(boost::lexical_cast<unsigned char>(c_arr[0]) == uc_arr[0]);
|
||||
BOOST_CHECK(boost::lexical_cast<unsigned char>(uc_arr[0]) == uc_arr[0]);
|
||||
BOOST_CHECK(boost::lexical_cast<unsigned char>(sc_arr[0]) == uc_arr[0]);
|
||||
|
||||
BOOST_CHECK(boost::lexical_cast<signed char>(c_arr[0]) == sc_arr[0]);
|
||||
BOOST_CHECK(boost::lexical_cast<signed char>(uc_arr[0]) == sc_arr[0]);
|
||||
BOOST_CHECK(boost::lexical_cast<signed char>(sc_arr[0]) == sc_arr[0]);
|
||||
|
||||
#ifndef BOOST_LCAST_NO_WCHAR_T
|
||||
const wchar_t wc_arr[]=L"Test array of chars";
|
||||
|
||||
BOOST_CHECK(boost::lexical_cast<std::wstring>(wc_arr) == std::wstring(wc_arr));
|
||||
BOOST_CHECK(boost::lexical_cast<std::wstring>(c_arr) == std::wstring(wc_arr));
|
||||
|
||||
BOOST_CHECK(boost::lexical_cast<std::wstring>(sc_arr) != std::wstring(wc_arr) );
|
||||
BOOST_CHECK(boost::lexical_cast<std::wstring>(uc_arr) != std::wstring(wc_arr) );
|
||||
|
||||
BOOST_CHECK(boost::lexical_cast<wchar_t>(c_arr[0]) == wc_arr[0]);
|
||||
BOOST_CHECK(boost::lexical_cast<wchar_t>(wc_arr[0]) == wc_arr[0]);
|
||||
|
||||
BOOST_CHECK_THROW(boost::lexical_cast<wchar_t>(uc_arr[0]), bad_lexical_cast);
|
||||
BOOST_CHECK_THROW(boost::lexical_cast<wchar_t>(sc_arr[0]), bad_lexical_cast);
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -1,14 +0,0 @@
|
||||
boost_additional_test_dependencies(conversion BOOST_DEPENDS test detail numeric)
|
||||
|
||||
boost_test_run(implicit_cast)
|
||||
boost_test_compile_fail(implicit_cast_fail)
|
||||
boost_test_run(cast_test ../cast_test.cpp)
|
||||
boost_test_run(numeric_cast_test ../numeric_cast_test.cpp)
|
||||
boost_test_run(
|
||||
lexical_cast_test
|
||||
../lexical_cast_test.cpp
|
||||
DEPENDS boost_unit_test_framework
|
||||
)
|
||||
|
||||
|
||||
|
||||
@@ -24,6 +24,7 @@ test-suite conversion
|
||||
[ run lexical_cast_loopback_test.cpp ../../test/build//boost_unit_test_framework/<link>static ]
|
||||
[ run lexical_cast_abstract_test.cpp ../../test/build//boost_unit_test_framework/<link>static ]
|
||||
[ run lexical_cast_noncopyable_test.cpp ../../test/build//boost_unit_test_framework/<link>static ]
|
||||
[ run lexical_cast_vc8_bug_test.cpp ../../test/build//boost_unit_test_framework/<link>static ]
|
||||
;
|
||||
|
||||
|
||||
|
||||
@@ -51,7 +51,7 @@ std::ostream &operator<<(std::ostream &O, const A &a)
|
||||
{
|
||||
a.out(O);
|
||||
return O;
|
||||
};
|
||||
}
|
||||
|
||||
void test_abstract()
|
||||
{
|
||||
|
||||
@@ -0,0 +1,67 @@
|
||||
// Unit test for boost::lexical_cast.
|
||||
//
|
||||
// See http://www.boost.org for most recent version, including documentation.
|
||||
//
|
||||
// Copyright Alexander Nasonov, 2007.
|
||||
//
|
||||
// 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 tests now must pass on vc8, because lexical_cast
|
||||
// implementation has changed and it does not use stringstream for casts
|
||||
// to integral types
|
||||
|
||||
#include <boost/config.hpp>
|
||||
#include <boost/lexical_cast.hpp>
|
||||
#include <boost/cstdint.hpp>
|
||||
#include <boost/test/unit_test.hpp>
|
||||
|
||||
#include <string>
|
||||
|
||||
using namespace boost;
|
||||
|
||||
// See also test_conversion_from_string_to_integral(CharT)
|
||||
// in libs/conversion/lexical_cast_test.cpp
|
||||
template<class T, class CharT>
|
||||
void test_too_long_number(CharT zero)
|
||||
{
|
||||
typedef std::numeric_limits<T> limits;
|
||||
|
||||
std::basic_string<CharT> s;
|
||||
|
||||
std::basic_ostringstream<CharT> o;
|
||||
o << (limits::max)() << zero;
|
||||
s = o.str();
|
||||
BOOST_CHECK_THROW(lexical_cast<T>(s), bad_lexical_cast);
|
||||
s[s.size()-1] += 9; // '0' -> '9'
|
||||
BOOST_CHECK_THROW(lexical_cast<T>(s), bad_lexical_cast);
|
||||
|
||||
if(limits::is_signed)
|
||||
{
|
||||
std::basic_ostringstream<CharT> o;
|
||||
o << (limits::min)() << zero;
|
||||
s = o.str();
|
||||
BOOST_CHECK_THROW(lexical_cast<T>(s), bad_lexical_cast);
|
||||
s[s.size()-1] += 9; // '0' -> '9'
|
||||
BOOST_CHECK_THROW(lexical_cast<T>(s), bad_lexical_cast);
|
||||
}
|
||||
}
|
||||
|
||||
void test_vc8_bug()
|
||||
{
|
||||
test_too_long_number<boost::intmax_t>('0');
|
||||
test_too_long_number<boost::uintmax_t>('0');
|
||||
#if !defined(BOOST_LCAST_NO_WCHAR_T)
|
||||
test_too_long_number<boost::intmax_t>(L'0');
|
||||
test_too_long_number<boost::uintmax_t>(L'0');
|
||||
#endif
|
||||
}
|
||||
|
||||
unit_test::test_suite *init_unit_test_suite(int, char *[])
|
||||
{
|
||||
unit_test_framework::test_suite *suite =
|
||||
BOOST_TEST_SUITE("lexical_cast vc8 bug unit test");
|
||||
suite->add(BOOST_TEST_CASE(test_vc8_bug));
|
||||
return suite;
|
||||
}
|
||||
Reference in New Issue
Block a user