Compare commits

..

1 Commits

Author SHA1 Message Date
nobody ddcd4f4764 This commit was manufactured by cvs2svn to create tag
'Version_1_34_0'.

[SVN r37679]
2007-05-12 21:59:40 +00:00
11 changed files with 67 additions and 2910 deletions
+2 -2
View File
@@ -120,10 +120,10 @@ void f( Fruit * fruit ) {
<p><code>polymorphic_cast</code> was suggested by Bjarne Stroustrup in "The C++
Programming Language".<br>
<code>polymorphic_downcast</code> was contributed by <a href=
"http://www.boost.org/people/dave_abrahams.htm">Dave Abrahams</a>.<code><br>
"../../people/dave_abrahams.htm">Dave Abrahams</a>.<code><br>
An old
numeric_cast</code> that was contributed by <a href=
"http://www.boost.org/people/kevlin_henney.htm">Kevlin Henney</a> is now superseeded by the <a href="../numeric/conversion/doc/html/index.html">Boost Numeric Conversion Library</a></p>
"../../people/kevlin_henney.htm">Kevlin Henney</a> is now superseeded by the <a href="../numeric/conversion/doc/index.html">Boost Numeric Conversion Library</a></p>
<hr>
<p>Revised
-184
View File
@@ -1,184 +0,0 @@
// Copyright Alexander Nasonov & Paul A. Bristow 2006.
// Use, modification and distribution are subject to 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)
#ifndef BOOST_DETAIL_LCAST_PRECISION_HPP_INCLUDED
#define BOOST_DETAIL_LCAST_PRECISION_HPP_INCLUDED
#include <climits>
#include <ios>
#include <limits>
#include <boost/config.hpp>
#include <boost/integer_traits.hpp>
#ifndef BOOST_NO_IS_ABSTRACT
// Fix for SF:1358600 - lexical_cast & pure virtual functions & VC 8 STL
#include <boost/mpl/if.hpp>
#include <boost/type_traits/is_abstract.hpp>
#endif
#if defined(BOOST_NO_LIMITS_COMPILE_TIME_CONSTANTS) || \
(defined(BOOST_MSVC) && (BOOST_MSVC<1310))
#define BOOST_LCAST_NO_COMPILE_TIME_PRECISION
#endif
#ifdef BOOST_LCAST_NO_COMPILE_TIME_PRECISION
#include <boost/assert.hpp>
#else
#include <boost/static_assert.hpp>
#endif
namespace boost { namespace detail {
class lcast_abstract_stub {};
#ifndef BOOST_LCAST_NO_COMPILE_TIME_PRECISION
// Calculate an argument to pass to std::ios_base::precision from
// lexical_cast. See alternative implementation for broken standard
// libraries in lcast_get_precision below. Keep them in sync, please.
template<class T>
struct lcast_precision
{
#ifdef BOOST_NO_IS_ABSTRACT
typedef std::numeric_limits<T> limits; // No fix for SF:1358600.
#else
typedef BOOST_DEDUCED_TYPENAME boost::mpl::if_<
boost::is_abstract<T>
, std::numeric_limits<lcast_abstract_stub>
, std::numeric_limits<T>
>::type limits;
#endif
BOOST_STATIC_CONSTANT(bool, use_default_precision =
!limits::is_specialized || limits::is_exact
);
BOOST_STATIC_CONSTANT(bool, is_specialized_bin =
!use_default_precision &&
limits::radix == 2 && limits::digits > 0
);
BOOST_STATIC_CONSTANT(bool, is_specialized_dec =
!use_default_precision &&
limits::radix == 10 && limits::digits10 > 0
);
BOOST_STATIC_CONSTANT(std::streamsize, streamsize_max =
boost::integer_traits<std::streamsize>::const_max
);
BOOST_STATIC_CONSTANT(unsigned int, precision_dec = limits::digits10 + 1U);
BOOST_STATIC_ASSERT(!is_specialized_dec ||
precision_dec <= streamsize_max + 0UL
);
BOOST_STATIC_CONSTANT(unsigned long, precision_bin =
2UL + limits::digits * 30103UL / 100000UL
);
BOOST_STATIC_ASSERT(!is_specialized_bin ||
(limits::digits + 0UL < ULONG_MAX / 30103UL &&
precision_bin > limits::digits10 + 0UL &&
precision_bin <= streamsize_max + 0UL)
);
BOOST_STATIC_CONSTANT(std::streamsize, value =
is_specialized_bin ? precision_bin
: is_specialized_dec ? precision_dec : 6
);
};
#endif
template<class T>
inline std::streamsize lcast_get_precision(T* = 0)
{
#ifndef BOOST_LCAST_NO_COMPILE_TIME_PRECISION
return lcast_precision<T>::value;
#else // Follow lcast_precision algorithm at run-time:
#ifdef BOOST_NO_IS_ABSTRACT
typedef std::numeric_limits<T> limits; // No fix for SF:1358600.
#else
typedef BOOST_DEDUCED_TYPENAME boost::mpl::if_<
boost::is_abstract<T>
, std::numeric_limits<lcast_abstract_stub>
, std::numeric_limits<T>
>::type limits;
#endif
bool const use_default_precision =
!limits::is_specialized || limits::is_exact;
if(!use_default_precision)
{ // Includes all built-in floating-point types, float, double ...
// and UDT types for which digits (significand bits) is defined (not zero)
bool const is_specialized_bin =
limits::radix == 2 && limits::digits > 0;
bool const is_specialized_dec =
limits::radix == 10 && limits::digits10 > 0;
std::streamsize const streamsize_max =
(boost::integer_traits<std::streamsize>::max)();
if(is_specialized_bin)
{ // Floating-point types with
// limits::digits defined by the specialization.
unsigned long const digits = limits::digits;
unsigned long const precision = 2UL + digits * 30103UL / 100000UL;
// unsigned long is selected because it is at least 32-bits
// and thus ULONG_MAX / 30103UL is big enough for all types.
BOOST_ASSERT(
digits < ULONG_MAX / 30103UL &&
precision > limits::digits10 + 0UL &&
precision <= streamsize_max + 0UL
);
return precision;
}
else if(is_specialized_dec)
{ // Decimal Floating-point type, most likely a User Defined Type
// rather than a real floating-point hardware type.
unsigned int const precision = limits::digits10 + 1U;
BOOST_ASSERT(precision <= streamsize_max + 0UL);
return precision;
}
}
// Integral type (for which precision has no effect)
// or type T for which limits is NOT specialized,
// so assume stream precision remains the default 6 decimal digits.
// Warning: if your User-defined Floating-point type T is NOT specialized,
// then you may lose accuracy by only using 6 decimal digits.
// To avoid this, you need to specialize T with either
// radix == 2 and digits == the number of significand bits,
// OR
// radix = 10 and digits10 == the number of decimal digits.
return 6;
#endif
}
template<class T>
inline void lcast_set_precision(std::ios_base& stream, T*)
{
stream.precision(lcast_get_precision<T>());
}
template<class Source, class Target>
inline void lcast_set_precision(std::ios_base& stream, Source*, Target*)
{
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);
}
}}
#endif // BOOST_DETAIL_LCAST_PRECISION_HPP_INCLUDED
Regular → Executable
+1 -1
View File
@@ -23,7 +23,7 @@ inline T implicit_cast (typename mpl::identity<T>::type x) {
//template <typename T>
//void implicit_cast (...);
} // namespace boost
#endif // IMPLICIT_CAST_DWA200356_HPP
File diff suppressed because it is too large Load Diff
+7 -124
View File
@@ -20,14 +20,8 @@
<a href="#lexical_cast"><code>lexical_cast</code></a></li>
<li>
<a href="#bad_lexical_cast"><code>bad_lexical_cast</code></a></li>
<li>
<a href="#faq">Frequently Asked Questions</a></li>
<li>
<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>
@@ -83,13 +77,13 @@
conversions, such as where precision or formatting need tighter control than is
offered by the default behavior of <code>lexical_cast</code>, the conventional <code>
stringstream</code> approach is recommended. Where the conversions are
numeric to numeric, <code><a href="../numeric/conversion/doc/html/boost_numericconversion/improved_numeric_cast__.html">numeric_cast</a></code>
numeric to numeric, <code><a href="../numeric/conversion/doc/numeric_cast.html">numeric_cast</a></code>
may offer more reasonable behavior than <code>lexical_cast</code>.
<p>
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>. Also, take a look at the <a href="#performance">Performance</a> section.
<i>The String Formatters of Manor Farm</i></a>.
<p>
<hr>
<h2><a name="examples">Examples</a></h2>
@@ -166,7 +160,7 @@ void log_errno(int yoko)
and an instance of the result type on the right.
</li>
<li>
<code>Target</code> is <i>CopyConstructible</i> [20.1.3].
Both <code>Source</code> and <code>Target</code> are <i>CopyConstructible</i> [20.1.3].
</li>
<li>
<code>Target</code> is <i>DefaultConstructible</i>, meaning that it is possible
@@ -196,91 +190,9 @@ public:
</pre>
</blockquote>Exception used to indicate runtime <a href="#lexical_cast"><code>lexical_cast</code></a>
failure.
<hr>
<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.
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>&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 <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&gt;&gt;</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&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>
<h2><a name="references">References</a></h2>
<ul type="square">
<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://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>
types. Refer to <a href="#tuning">[Tuning]</a> for more details.
</li>
</ul>
<h3>June 2005:</h3>
<ul type="square">
<li>Call-by-const reference for the parameters. This requires partial specialization
@@ -316,36 +228,7 @@ Eliminate an overhead of <code>std::locale</code> if your program runs in the "C
</ul>
<p>
<hr>
<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 &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 <a href="../../LICENSE_1_0.txt" target="_top">http://www.boost.org/LICENSE_1_0.txt</a>)</i></small>
</div>
<div align="right"><small><i>&copy; Copyright Kevlin Henney, 2000&#150;2005</i></small></div>
</body>
</html>
</html>
+17 -678
View File
@@ -2,9 +2,7 @@
//
// See http://www.boost.org for most recent version, including documentation.
//
// Copyright Terje Sletteb and Kevlin Henney, 2005.
// Copyright Alexander Nasonov, 2006.
// Copyright Antony Polukhin, 2011.
// Copyright Terje Slettebø and Kevlin Henney, 2005.
//
// Distributed under the Boost
// Software License, Version 1.0. (See accompanying file
@@ -12,13 +10,6 @@
//
// 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)
@@ -29,36 +20,15 @@
#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_HAS_LONG_LONG) || defined(BOOST_HAS_MS_INT64)) \
&& !(defined(BOOST_MSVC) && BOOST_MSVC < 1300)
#define LCAST_TEST_LONGLONG
#if defined(BOOST_NO_STRINGSTREAM) || \
defined(BOOST_NO_STD_WSTRING) || \
defined(BOOST_NO_STD_LOCALE)
#define DISABLE_WIDE_CHAR_SUPPORT
#endif
template<class CharT>
struct my_traits : std::char_traits<CharT>
{
};
template<class CharT>
struct my_allocator : std::allocator<CharT>
{
};
// Test all 65536 values if true:
bool const lcast_test_small_integral_types_completely = false;
// lcast_integral_test_counter: use when testing all values of an integral
// types is not possible. Max. portable value is 32767.
int const lcast_integral_test_counter=1000;
using namespace boost;
void test_conversion_to_char();
@@ -74,28 +44,6 @@ void test_conversion_from_wstring();
void test_conversion_to_wstring();
void test_bad_lexical_cast();
void test_no_whitespace_stripping();
void test_conversion_from_to_short();
void test_conversion_from_to_ushort();
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 *[])
{
@@ -108,38 +56,14 @@ 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 BOOST_LCAST_NO_WCHAR_T
#ifndef DISABLE_WIDE_CHAR_SUPPORT
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_long));
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
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
suite->add(BOOST_TEST_CASE(&test_char_types_conversions));
return suite;
}
@@ -171,15 +95,10 @@ void test_conversion_to_int()
BOOST_CHECK_EQUAL(0, lexical_cast<int>('0'));
BOOST_CHECK_THROW(lexical_cast<int>('A'), bad_lexical_cast);
BOOST_CHECK_EQUAL(1, lexical_cast<int>(1));
BOOST_CHECK_EQUAL(1, lexical_cast<int>(1.0));
BOOST_CHECK_EQUAL(
(std::numeric_limits<int>::max)(),
lexical_cast<int>((std::numeric_limits<int>::max)()));
BOOST_CHECK_EQUAL(
(std::numeric_limits<int>::min)(),
lexical_cast<int>((std::numeric_limits<int>::min)()));
BOOST_CHECK_EQUAL(1, lexical_cast<int>(1.0));
BOOST_CHECK_THROW(lexical_cast<int>(1.23), bad_lexical_cast);
@@ -240,31 +159,14 @@ 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()
{
char buf[] = "hello";
char* str = buf;
BOOST_CHECK_EQUAL(str, lexical_cast<std::string>(str));
BOOST_CHECK_EQUAL("A", lexical_cast<std::string>('A'));
BOOST_CHECK_EQUAL(" ", lexical_cast<std::string>(' '));
BOOST_CHECK_EQUAL("123", lexical_cast<std::string>(123));
@@ -294,14 +196,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 BOOST_LCAST_NO_WCHAR_T
#ifndef DISABLE_WIDE_CHAR_SUPPORT
BOOST_CHECK_THROW(lexical_cast<wchar_t *>("Test"), bad_lexical_cast);
#endif
#endif
}
void test_conversion_from_wchar_t()
{
#ifndef BOOST_LCAST_NO_WCHAR_T
#ifndef DISABLE_WIDE_CHAR_SUPPORT
#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);
@@ -334,11 +236,9 @@ void test_conversion_from_wchar_t()
void test_conversion_to_wchar_t()
{
#if !defined(BOOST_LCAST_NO_WCHAR_T) && !defined(BOOST_NO_INTRINSIC_WCHAR_T)
#if !defined(DISABLE_WIDE_CHAR_SUPPORT) && !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'));
BOOST_CHECK_EQUAL(L'0', lexical_cast<wchar_t>('0'));
BOOST_CHECK_THROW(lexical_cast<wchar_t>(123), bad_lexical_cast);
BOOST_CHECK_EQUAL(L'1', lexical_cast<wchar_t>(1.0));
BOOST_CHECK_EQUAL(L'0', lexical_cast<wchar_t>(0.0));
@@ -356,12 +256,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 BOOST_LCAST_NO_WCHAR_T
#ifndef DISABLE_WIDE_CHAR_SUPPORT
BOOST_CHECK_EQUAL(123, lexical_cast<int>(std::wstring(L"123")));
BOOST_CHECK_THROW(
lexical_cast<int>(std::wstring(L"")), bad_lexical_cast);
@@ -374,15 +274,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 BOOST_LCAST_NO_WCHAR_T
wchar_t buf[] = L"hello";
wchar_t* str = buf;
BOOST_CHECK(str == lexical_cast<std::wstring>(str));
#ifndef DISABLE_WIDE_CHAR_SUPPORT
BOOST_CHECK(L"123" == lexical_cast<std::wstring>(123));
BOOST_CHECK(L"1.23" == lexical_cast<std::wstring>(1.23));
BOOST_CHECK(L"1.111111111" == lexical_cast<std::wstring>(1.111111111));
@@ -391,7 +288,6 @@ void test_conversion_to_wstring()
#if !defined(BOOST_NO_INTRINSIC_WCHAR_T)
BOOST_CHECK(L"A" == lexical_cast<std::wstring>(L'A'));
BOOST_CHECK(L" " == lexical_cast<std::wstring>(L' '));
BOOST_CHECK(L"A" == lexical_cast<std::wstring>('A'));
#endif
BOOST_CHECK(L"Test" == lexical_cast<std::wstring>(L"Test"));
BOOST_CHECK(L" " == lexical_cast<std::wstring>(L" "));
@@ -399,7 +295,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()
@@ -422,560 +318,3 @@ void test_no_whitespace_stripping()
BOOST_CHECK_THROW(lexical_cast<int>(" 123"), bad_lexical_cast);
BOOST_CHECK_THROW(lexical_cast<int>("123 "), bad_lexical_cast);
}
// Replace "-,999" with "-999".
template<class CharT>
std::basic_string<CharT> to_str_gcc_workaround(std::basic_string<CharT> str)
{
std::locale loc;
std::numpunct<CharT> const& np = BOOST_USE_FACET(std::numpunct<CharT>, loc);
std::ctype<CharT> const& ct = BOOST_USE_FACET(std::ctype<CharT>, loc);
if(np.grouping().empty())
return str;
CharT prefix[3] = { ct.widen('-'), np.thousands_sep(), CharT() };
if(str.find(prefix) != 0)
return str;
prefix[1] = CharT();
str.replace(0, 2, prefix);
return str;
}
template<class CharT, class T>
std::basic_string<CharT> to_str(T t)
{
std::basic_ostringstream<CharT> o;
o << t;
return to_str_gcc_workaround(o.str());
}
template<class T, class CharT>
void test_conversion_from_integral_to_char(CharT zero)
{
BOOST_CHECK(lexical_cast<CharT>(static_cast<T>(0)) == zero + 0);
BOOST_CHECK(lexical_cast<CharT>(static_cast<T>(1)) == zero + 1);
BOOST_CHECK(lexical_cast<CharT>(static_cast<T>(2)) == zero + 2);
BOOST_CHECK(lexical_cast<CharT>(static_cast<T>(3)) == zero + 3);
BOOST_CHECK(lexical_cast<CharT>(static_cast<T>(4)) == zero + 4);
BOOST_CHECK(lexical_cast<CharT>(static_cast<T>(5)) == zero + 5);
BOOST_CHECK(lexical_cast<CharT>(static_cast<T>(6)) == zero + 6);
BOOST_CHECK(lexical_cast<CharT>(static_cast<T>(7)) == zero + 7);
BOOST_CHECK(lexical_cast<CharT>(static_cast<T>(8)) == zero + 8);
BOOST_CHECK(lexical_cast<CharT>(static_cast<T>(9)) == zero + 9);
BOOST_CHECK_THROW(lexical_cast<CharT>(static_cast<T>(10)), bad_lexical_cast);
T t = (std::numeric_limits<T>::max)();
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()
{
T t = 0;
BOOST_CHECK(lexical_cast<T>(t) == t);
// Next two variables are used to supress warnings.
int st = 32767; unsigned int ut = st;
t = st;
BOOST_CHECK(lexical_cast<short>(t) == st);
BOOST_CHECK(lexical_cast<unsigned short>(t) == ut);
BOOST_CHECK(lexical_cast<int>(t) == st);
BOOST_CHECK(lexical_cast<unsigned int>(t) == ut);
BOOST_CHECK(lexical_cast<long>(t) == st);
BOOST_CHECK(lexical_cast<unsigned long>(t) == ut);
t = (std::numeric_limits<T>::max)();
BOOST_CHECK(lexical_cast<T>(t) == t);
t = (std::numeric_limits<T>::min)();
BOOST_CHECK(lexical_cast<T>(t) == t);
}
template<class T, class CharT>
void test_conversion_from_integral_to_string(CharT)
{
typedef std::numeric_limits<T> limits;
typedef std::basic_string<CharT> string_type;
T t;
t = (limits::min)();
BOOST_CHECK(lexical_cast<string_type>(t) == to_str<CharT>(t));
t = (limits::max)();
BOOST_CHECK(lexical_cast<string_type>(t) == to_str<CharT>(t));
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)
BOOST_CHECK(lexical_cast<string_type>(t) == to_str<CharT>(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;
unsigned int i;
// Test values around min:
t = min_val;
for(i = 0; i < counter; ++i, ++t)
BOOST_CHECK(lexical_cast<string_type>(t) == to_str<CharT>(t));
// Test values around max:
t = max_val;
for(i = 0; i < counter; ++i, --t)
BOOST_CHECK(lexical_cast<string_type>(t) == to_str<CharT>(t));
// Test values around zero:
if(limits::is_signed)
for(t = -counter; t < static_cast<T>(counter); ++t)
BOOST_CHECK(lexical_cast<string_type>(t) == to_str<CharT>(t));
// Test values around 100, 1000, 10000, ...
T ten_power = 100;
for(int e = 2; e <= limits::digits10; ++e, ten_power *= 10)
{
// ten_power + 100 probably never overflows
for(t = ten_power - 100; t != ten_power + 100; ++t)
BOOST_CHECK(lexical_cast<string_type>(t) == to_str<CharT>(t));
}
}
}
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;
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)();
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);
}
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 t = 1 + min_val; t != max_val; ++t)
BOOST_CHECK(lexical_cast<T>(to_str<CharT>(t)) == t);
else
{
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:
t = min_val;
for(i = 0; i < counter; ++i, ++t)
BOOST_CHECK(lexical_cast<T>(to_str<CharT>(t)) == t);
// Test values around max:
t = max_val;
for(i = 0; i < counter; ++i, --t)
BOOST_CHECK(lexical_cast<T>(to_str<CharT>(t)) == t);
// Test values around zero:
if(limits::is_signed)
for(t = -counter; t < static_cast<T>(counter); ++t)
BOOST_CHECK(lexical_cast<T>(to_str<CharT>(t)) == t);
// Test values around 100, 1000, 10000, ...
T ten_power = 100;
for(int e = 2; e <= limits::digits10; ++e, ten_power *= 10)
{
// ten_power + 100 probably never overflows
for(t = ten_power - 100; t != ten_power + 100; ++t)
BOOST_CHECK(lexical_cast<T>(to_str<CharT>(t)) == t);
}
}
}
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(BOOST_LCAST_NO_WCHAR_T)
test_conversion_from_integral_to_string<T>(L'0');
test_conversion_from_string_to_integral<T>(L'0');
#endif
}
struct restore_oldloc
{
std::locale oldloc;
~restore_oldloc() { std::locale::global(oldloc); }
};
template<class T>
void test_conversion_from_to_integral()
{
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
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;
restore_oldloc guard;
std::locale const& oldloc = guard.oldloc;
std::string grouping1 = BOOST_USE_FACET(numpunct, oldloc).grouping();
std::string grouping2(grouping1);
test_conversion_from_to_integral_for_locale<T>();
try
{
std::locale newloc("");
std::locale::global(newloc);
grouping2 = BOOST_USE_FACET(numpunct, newloc).grouping();
}
catch(std::exception const& ex)
{
std::string msg("Failed to set system locale: ");
msg += ex.what();
BOOST_TEST_MESSAGE(msg);
}
if(grouping1 != grouping2)
test_conversion_from_to_integral_for_locale<T>();
if(grouping1.empty() && grouping2.empty())
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>();
}
void test_conversion_from_to_ushort()
{
test_conversion_from_to_integral<unsigned short>();
}
void test_conversion_from_to_int()
{
test_conversion_from_to_integral<int>();
}
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_intmax_t()
{
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)
void test_conversion_from_to_longlong()
{
test_conversion_from_to_integral<boost::long_long_type>();
}
void test_conversion_from_to_ulonglong()
{
test_conversion_from_to_integral<boost::ulong_long_type>();
}
#elif defined(BOOST_HAS_MS_INT64)
void test_conversion_from_to_longlong()
{
test_conversion_from_to_integral<__int64>();
}
void test_conversion_from_to_ulonglong()
{
test_conversion_from_to_integral<unsigned __int64>();
}
#endif
#ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
void test_traits()
{
typedef std::basic_string<char, my_traits<char> > my_string;
my_string const s("s");
BOOST_CHECK(boost::lexical_cast<char>(s) == s[0]);
BOOST_CHECK(boost::lexical_cast<my_string>(s) == s);
BOOST_CHECK(boost::lexical_cast<my_string>(-1) == "-1");
}
void test_wtraits()
{
typedef std::basic_string<wchar_t, my_traits<wchar_t> > my_string;
my_string const s(L"s");
BOOST_CHECK(boost::lexical_cast<wchar_t>(s) == s[0]);
BOOST_CHECK(boost::lexical_cast<my_string>(s) == s);
//BOOST_CHECK(boost::lexical_cast<my_string>(-1) == L"-1");
// Commented out because gcc 3.3 doesn't support this:
// basic_ostream<wchar_t, my_traits<wchar_t> > o; o << -1;
}
void test_allocator()
{
typedef std::basic_string< char
, std::char_traits<char>
, my_allocator<char>
> my_string;
my_string s("s");
BOOST_CHECK(boost::lexical_cast<char>(s) == s[0]);
BOOST_CHECK(boost::lexical_cast<std::string>(s) == "s");
BOOST_CHECK(boost::lexical_cast<my_string>(s) == s);
BOOST_CHECK(boost::lexical_cast<my_string>(1) == "1");
BOOST_CHECK(boost::lexical_cast<my_string>("s") == s);
BOOST_CHECK(boost::lexical_cast<my_string>(std::string("s")) == s);
}
void test_wallocator()
{
typedef std::basic_string< wchar_t
, std::char_traits<wchar_t>
, my_allocator<wchar_t>
> my_string;
my_string s(L"s");
BOOST_CHECK(boost::lexical_cast<wchar_t>(s) == s[0]);
BOOST_CHECK(boost::lexical_cast<std::wstring>(s) == L"s");
BOOST_CHECK(boost::lexical_cast<my_string>(s) == s);
BOOST_CHECK(boost::lexical_cast<my_string>(1) == L"1");
BOOST_CHECK(boost::lexical_cast<my_string>(L"s") == s);
BOOST_CHECK(boost::lexical_cast<my_string>(std::wstring(L"s")) == s);
}
#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
}
-4
View File
@@ -21,10 +21,6 @@ test-suite conversion
[ run ../cast_test.cpp ]
[ run ../numeric_cast_test.cpp ]
[ run ../lexical_cast_test.cpp ../../test/build//boost_unit_test_framework/<link>static ]
[ 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 ]
;
-61
View File
@@ -1,61 +0,0 @@
// Unit test for boost::lexical_cast.
//
// See http://www.boost.org for most recent version, including documentation.
//
// Copyright Sergey Shandar 2005, 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).
//
// Test abstract class. Bug 1358600:
// http://sf.net/tracker/?func=detail&aid=1358600&group_id=7586&atid=107586
#include <boost/config.hpp>
#if defined(__INTEL_COMPILER)
#pragma warning(disable: 193 383 488 981 1418 1419)
#elif defined(BOOST_MSVC)
#pragma warning(disable: 4097 4100 4121 4127 4146 4244 4245 4511 4512 4701 4800)
#endif
#include <boost/lexical_cast.hpp>
#include <boost/test/unit_test.hpp>
using namespace boost;
void test_abstract();
unit_test::test_suite *init_unit_test_suite(int, char *[])
{
unit_test_framework::test_suite *suite =
BOOST_TEST_SUITE("lexical_cast unit test");
suite->add(BOOST_TEST_CASE(&test_abstract));
return suite;
}
class A
{
public:
virtual void out(std::ostream &) const = 0;
};
class B: public A
{
public:
virtual void out(std::ostream &O) const { O << "B"; }
};
std::ostream &operator<<(std::ostream &O, const A &a)
{
a.out(O);
return O;
}
void test_abstract()
{
const A &a = B();
BOOST_CHECK(boost::lexical_cast<std::string>(a) == "B");
}
-98
View File
@@ -1,98 +0,0 @@
// Unit test for boost::lexical_cast.
//
// See http://www.boost.org for most recent version, including documentation.
//
// Copyright Alexander Nasonov, 2006.
//
// 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).
//
// Test round-tripping conversion FPT -> string -> FPT,
// where FPT is Floating Point Type.
#include <boost/config.hpp>
#if defined(__INTEL_COMPILER)
#pragma warning(disable: 193 383 488 981 1418 1419)
#elif defined(BOOST_MSVC)
#pragma warning(disable: 4097 4100 4121 4127 4146 4244 4245 4511 4512 4701 4800)
#endif
#include <boost/lexical_cast.hpp>
#include <boost/test/unit_test.hpp>
using namespace boost;
void test_round_conversion_float();
void test_round_conversion_double();
void test_round_conversion_long_double();
unit_test::test_suite *init_unit_test_suite(int, char *[])
{
unit_test_framework::test_suite *suite =
BOOST_TEST_SUITE("lexical_cast unit test");
suite->add(BOOST_TEST_CASE(&test_round_conversion_float));
suite->add(BOOST_TEST_CASE(&test_round_conversion_double));
suite->add(BOOST_TEST_CASE(&test_round_conversion_long_double));
return suite;
}
template<class T>
void test_round_conversion()
{
T epsilon = std::numeric_limits<T>::epsilon();
std::string const epsilon_s = boost::lexical_cast<std::string>(epsilon);
BOOST_CHECK(epsilon == lexical_cast<T>(epsilon_s));
T max_ = (std::numeric_limits<T>::max)();
std::string const max_s = boost::lexical_cast<std::string>(max_);
BOOST_CHECK(max_ == lexical_cast<T>(max_s));
T min_ = (std::numeric_limits<T>::min)();
std::string const min_s = boost::lexical_cast<std::string>(min_);
BOOST_CHECK(min_ == lexical_cast<T>(min_s));
T max_div137 = max_ / 137;
std::string max_div137_s = boost::lexical_cast<std::string>(max_div137);
BOOST_CHECK(max_div137 == lexical_cast<T>(max_div137_s));
T epsilon_mult137 = epsilon * 137;
std::string epsilon_mult137_s(lexical_cast<std::string>(epsilon_mult137));
BOOST_CHECK(epsilon_mult137 == lexical_cast<T>(epsilon_mult137_s));
}
#if defined(BOOST_MSVC)
// See bug http://tinyurl.com/vhpvo
template<class T>
void test_msvc_magic_values()
{
T magic_msvc = 0.00010000433948393407;
std::string magic_msvc_s = boost::lexical_cast<std::string>(magic_msvc);
BOOST_CHECK(magic_msvc == lexical_cast<T>(magic_msvc_s));
}
#endif
void test_round_conversion_float()
{
test_round_conversion<float>();
}
void test_round_conversion_double()
{
test_round_conversion<double>();
#if defined(BOOST_MSVC)
test_msvc_magic_values<double>();
#endif
}
void test_round_conversion_long_double()
{
test_round_conversion<long double>();
#if defined(BOOST_MSVC)
test_msvc_magic_values<long double>();
#endif
}
-54
View File
@@ -1,54 +0,0 @@
// 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).
//
// Test that Source can be non-copyable.
#include <boost/config.hpp>
#if defined(__INTEL_COMPILER)
#pragma warning(disable: 193 383 488 981 1418 1419)
#elif defined(BOOST_MSVC)
#pragma warning(disable: 4097 4100 4121 4127 4146 4244 4245 4511 4512 4701 4800)
#endif
#include <boost/lexical_cast.hpp>
#include <boost/noncopyable.hpp>
#include <boost/test/unit_test.hpp>
using namespace boost;
void test_noncopyable();
unit_test::test_suite *init_unit_test_suite(int, char *[])
{
unit_test_framework::test_suite *suite =
BOOST_TEST_SUITE("lexical_cast unit test");
suite->add(BOOST_TEST_CASE(&test_noncopyable));
return suite;
}
class Noncopyable : private boost::noncopyable
{
public:
Noncopyable() {}
};
inline std::ostream &operator<<(std::ostream &out, const Noncopyable&)
{
return out << "Noncopyable";
}
void test_noncopyable()
{
Noncopyable x;
BOOST_CHECK(boost::lexical_cast<std::string>(x) == "Noncopyable");
}
-67
View File
@@ -1,67 +0,0 @@
// 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;
}