1 // Unit test for boost::lexical_cast.
3 // See http://www.boost.org for most recent version, including documentation.
5 // Copyright Antony Polukhin, 2011-2020.
7 // Distributed under the Boost
8 // Software License, Version 1.0. (See accompanying file
9 // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt).
11 #include <boost/config.hpp>
13 #if defined(__INTEL_COMPILER)
14 #pragma warning(disable: 193 383 488 981 1418 1419)
15 #elif defined(BOOST_MSVC)
16 #pragma warning(disable: 4097 4100 4121 4127 4146 4244 4245 4511 4512 4701 4800)
19 #include <boost/lexical_cast.hpp>
21 #include <boost/cstdint.hpp>
22 #include <boost/test/unit_test.hpp>
23 #include <boost/test/tools/floating_point_comparison.hpp>
24 #include <boost/math/tools/precision.hpp>
26 void test_conversion_from_to_float();
27 void test_conversion_from_to_double();
28 void test_conversion_from_to_long_double();
30 using namespace boost
;
33 unit_test::test_suite
*init_unit_test_suite(int, char *[])
35 unit_test::test_suite
*suite
=
36 BOOST_TEST_SUITE("lexical_cast float types unit test");
37 suite
->add(BOOST_TEST_CASE(&test_conversion_from_to_float
));
38 suite
->add(BOOST_TEST_CASE(&test_conversion_from_to_double
));
39 suite
->add(BOOST_TEST_CASE(&test_conversion_from_to_long_double
));
45 // Replace "-,999" with "-999".
47 std::basic_string
<CharT
> to_str_gcc_workaround(std::basic_string
<CharT
> str
)
50 std::numpunct
<CharT
> const& np
= BOOST_USE_FACET(std::numpunct
<CharT
>, loc
);
51 std::ctype
<CharT
> const& ct
= BOOST_USE_FACET(std::ctype
<CharT
>, loc
);
53 if(np
.grouping().empty())
56 CharT prefix
[3] = { ct
.widen('-'), np
.thousands_sep(), CharT() };
58 if(str
.find(prefix
) != 0)
62 str
.replace(0, 2, prefix
);
66 template<class CharT
, class T
>
67 std::basic_string
<CharT
> to_str(T t
)
69 std::basic_ostringstream
<CharT
> o
;
71 return to_str_gcc_workaround(o
.str());
76 void test_conversion_from_to_float_for_locale()
78 std::locale current_locale
;
79 typedef std::numpunct
<char> numpunct
;
80 numpunct
const& np
= BOOST_USE_FACET(numpunct
, current_locale
);
81 if ( !np
.grouping().empty() )
84 lexical_cast
<T
>( std::string("100") + np
.thousands_sep() + np
.thousands_sep() + "0" )
86 BOOST_CHECK_THROW(lexical_cast
<T
>( std::string("100") + np
.thousands_sep() ), bad_lexical_cast
);
87 BOOST_CHECK_THROW(lexical_cast
<T
>( np
.thousands_sep() + std::string("100") ), bad_lexical_cast
);
88 BOOST_CHECK_THROW(lexical_cast
<T
>( std::string("1") + np
.thousands_sep() + np
.decimal_point() + "e10" ), bad_lexical_cast
);
89 BOOST_CHECK_THROW(lexical_cast
<T
>( std::string("1e10") + np
.thousands_sep() ), bad_lexical_cast
);
90 BOOST_CHECK_THROW(lexical_cast
<T
>( std::string("1") + np
.thousands_sep() + "e10" ), bad_lexical_cast
);
92 BOOST_CHECK_CLOSE_FRACTION(lexical_cast
<T
>( to_str
< char >(100000) ), 100000, (boost::math::tools::epsilon
<T
>()) );
93 BOOST_CHECK_CLOSE_FRACTION(lexical_cast
<T
>( to_str
< char >(10000000u) ), 10000000u, (boost::math::tools::epsilon
<T
>()) );
94 BOOST_CHECK_CLOSE_FRACTION(lexical_cast
<T
>( to_str
< char >(100) ), 100, (boost::math::tools::epsilon
<T
>()) );
95 #if !defined(BOOST_LCAST_NO_WCHAR_T) && !defined(BOOST_NO_INTRINSIC_WCHAR_T)
96 BOOST_CHECK_CLOSE_FRACTION(lexical_cast
<T
>( to_str
< wchar_t >(100000) ), 100000, (boost::math::tools::epsilon
<T
>()) );
97 BOOST_CHECK_CLOSE_FRACTION(lexical_cast
<T
>( to_str
< wchar_t >(10000000u) ), 10000000u, (boost::math::tools::epsilon
<T
>()) );
98 BOOST_CHECK_CLOSE_FRACTION(lexical_cast
<T
>( to_str
< wchar_t >(100) ), 100, (boost::math::tools::epsilon
<T
>()) );
100 // Exception must not be thrown, when we are using no separators at all
101 BOOST_CHECK_CLOSE_FRACTION( lexical_cast
<T
>("30000"), static_cast<T
>(30000), (boost::math::tools::epsilon
<T
>()) );
109 * Converts char* [and wchar_t*] to float number type and checks, that generated
110 * number does not exceeds allowed epsilon.
112 #ifndef BOOST_LCAST_NO_WCHAR_T
113 #define CHECK_CLOSE_ABS_DIFF(VAL,PREFIX) \
114 converted_val = lexical_cast<test_t>(#VAL); \
115 BOOST_CHECK_CLOSE_FRACTION( (static_cast<bool>(VAL ## L)? VAL ## L : boost::math::tools::epsilon<test_t>()), \
116 (converted_val ? converted_val : boost::math::tools::epsilon<test_t>()),\
117 boost::math::tools::epsilon<test_t>() \
119 BOOST_CHECK_EQUAL(converted_val, lexical_cast<test_t>(L## #VAL) );
122 #define CHECK_CLOSE_ABS_DIFF(VAL,TYPE) \
123 converted_val = lexical_cast<test_t>(#VAL); \
124 BOOST_CHECK_CLOSE_FRACTION( (static_cast<bool>(VAL ## L)? VAL ## L : boost::math::tools::epsilon<test_t>()), \
125 (converted_val ? converted_val : boost::math::tools::epsilon<test_t>()),\
126 boost::math::tools::epsilon<test_t>() \
130 template <class TestType
>
131 void test_converion_to_float_types()
133 typedef TestType test_t
;
134 test_t converted_val
;
136 BOOST_CHECK_CLOSE_FRACTION(1.0, lexical_cast
<test_t
>('1'), (boost::math::tools::epsilon
<test_t
>()));
137 BOOST_CHECK_EQUAL(0.0, lexical_cast
<test_t
>('0'));
139 unsigned char const uc_one
= '1';
140 unsigned char const uc_zero
='0';
141 BOOST_CHECK_CLOSE_FRACTION(1.0, lexical_cast
<test_t
>(uc_one
), (boost::math::tools::epsilon
<test_t
>()));
142 BOOST_CHECK_EQUAL(0.0, lexical_cast
<test_t
>(uc_zero
));
144 signed char const sc_one
= '1';
145 signed char const sc_zero
='0';
146 BOOST_CHECK_CLOSE_FRACTION(1.0, lexical_cast
<test_t
>(sc_one
), (boost::math::tools::epsilon
<test_t
>()));
147 BOOST_CHECK_EQUAL(0.0, lexical_cast
<test_t
>(sc_zero
));
149 BOOST_CHECK_CLOSE_FRACTION(1e34L
, lexical_cast
<test_t
>( "10000000000000000000000000000000000"), (boost::math::tools::epsilon
<test_t
>()) );
151 // VC failes the next test
152 // BOOST_CHECK_CLOSE_FRACTION(1e-35L, lexical_cast<test_t>("0.00000000000000000000000000000000001"), (boost::math::tools::epsilon<test_t>()) );
153 BOOST_CHECK_CLOSE_FRACTION(
154 0.1111111111111111111111111111111111111111111111111111111111111111111111111L
155 , lexical_cast
<test_t
>("0.1111111111111111111111111111111111111111111111111111111111111111111111111")
156 , (boost::math::tools::epsilon
<test_t
>()) );
158 CHECK_CLOSE_ABS_DIFF(1,test_t
);
159 BOOST_CHECK_EQUAL(0,lexical_cast
<test_t
>("0"));
160 CHECK_CLOSE_ABS_DIFF(-1,test_t
);
162 CHECK_CLOSE_ABS_DIFF(1.0, test_t
);
163 CHECK_CLOSE_ABS_DIFF(0.0, test_t
);
164 CHECK_CLOSE_ABS_DIFF(-1.0,test_t
);
166 CHECK_CLOSE_ABS_DIFF(1e1
, test_t
);
167 CHECK_CLOSE_ABS_DIFF(0e1
, test_t
);
168 CHECK_CLOSE_ABS_DIFF(-1e1
,test_t
);
170 CHECK_CLOSE_ABS_DIFF(1.0e1
, test_t
);
171 CHECK_CLOSE_ABS_DIFF(0.0e1
, test_t
);
172 CHECK_CLOSE_ABS_DIFF(-1.0e1
,test_t
);
174 CHECK_CLOSE_ABS_DIFF(1e-1, test_t
);
175 CHECK_CLOSE_ABS_DIFF(0e-1, test_t
);
176 CHECK_CLOSE_ABS_DIFF(-1e-1,test_t
);
178 CHECK_CLOSE_ABS_DIFF(1.0e-1, test_t
);
179 CHECK_CLOSE_ABS_DIFF(0.0e-1, test_t
);
180 CHECK_CLOSE_ABS_DIFF(-1.0e-1,test_t
);
182 CHECK_CLOSE_ABS_DIFF(1E1
, test_t
);
183 CHECK_CLOSE_ABS_DIFF(0E1
, test_t
);
184 CHECK_CLOSE_ABS_DIFF(-1E1
,test_t
);
186 CHECK_CLOSE_ABS_DIFF(1.0E1
, test_t
);
187 CHECK_CLOSE_ABS_DIFF(0.0E1
, test_t
);
188 CHECK_CLOSE_ABS_DIFF(-1.0E1
,test_t
);
190 CHECK_CLOSE_ABS_DIFF(1E-1, test_t
);
191 CHECK_CLOSE_ABS_DIFF(0E-1, test_t
);
192 CHECK_CLOSE_ABS_DIFF(-1E-1,test_t
);
194 CHECK_CLOSE_ABS_DIFF(1.0E-1, test_t
);
195 CHECK_CLOSE_ABS_DIFF(0.0E-1, test_t
);
196 CHECK_CLOSE_ABS_DIFF(-1.0E-1, test_t
);
198 CHECK_CLOSE_ABS_DIFF(.0E-1, test_t
);
199 CHECK_CLOSE_ABS_DIFF(.0E-1, test_t
);
200 CHECK_CLOSE_ABS_DIFF(-.0E-1, test_t
);
202 CHECK_CLOSE_ABS_DIFF(10.0, test_t
);
203 CHECK_CLOSE_ABS_DIFF(00.0, test_t
);
204 CHECK_CLOSE_ABS_DIFF(-10.0,test_t
);
206 CHECK_CLOSE_ABS_DIFF(10e1
, test_t
);
207 CHECK_CLOSE_ABS_DIFF(00e1
, test_t
);
208 CHECK_CLOSE_ABS_DIFF(-10e1
,test_t
);
210 CHECK_CLOSE_ABS_DIFF(10.0e1
, test_t
);
211 CHECK_CLOSE_ABS_DIFF(00.0e1
, test_t
);
212 CHECK_CLOSE_ABS_DIFF(-10.0e1
,test_t
);
214 CHECK_CLOSE_ABS_DIFF(10e-1, test_t
);
215 CHECK_CLOSE_ABS_DIFF(00e-1, test_t
);
216 CHECK_CLOSE_ABS_DIFF(-10e-1,test_t
);
218 CHECK_CLOSE_ABS_DIFF(10.0e-1, test_t
);
219 CHECK_CLOSE_ABS_DIFF(00.0e-1, test_t
);
220 CHECK_CLOSE_ABS_DIFF(-10.0e-1,test_t
);
222 CHECK_CLOSE_ABS_DIFF(10E1
, test_t
);
223 CHECK_CLOSE_ABS_DIFF(00E1
, test_t
);
224 CHECK_CLOSE_ABS_DIFF(-10E1
,test_t
);
226 CHECK_CLOSE_ABS_DIFF(10.0E1
, test_t
);
227 CHECK_CLOSE_ABS_DIFF(00.0E1
, test_t
);
228 CHECK_CLOSE_ABS_DIFF(-10.0E1
,test_t
);
230 CHECK_CLOSE_ABS_DIFF(10E-1, test_t
);
231 CHECK_CLOSE_ABS_DIFF(00E-1, test_t
);
232 CHECK_CLOSE_ABS_DIFF(-10E-1,test_t
);
234 CHECK_CLOSE_ABS_DIFF(10.0E-1, test_t
);
235 CHECK_CLOSE_ABS_DIFF(00.0E-1, test_t
);
236 CHECK_CLOSE_ABS_DIFF(-10.0E-1, test_t
);
238 CHECK_CLOSE_ABS_DIFF(-10101.0E-011, test_t
);
239 CHECK_CLOSE_ABS_DIFF(-10101093, test_t
);
240 CHECK_CLOSE_ABS_DIFF(10101093, test_t
);
242 CHECK_CLOSE_ABS_DIFF(-.34, test_t
);
243 CHECK_CLOSE_ABS_DIFF(.34, test_t
);
244 CHECK_CLOSE_ABS_DIFF(.34e10
, test_t
);
246 BOOST_CHECK_THROW(lexical_cast
<test_t
>("-1.e"), bad_lexical_cast
);
247 BOOST_CHECK_THROW(lexical_cast
<test_t
>("-1.E"), bad_lexical_cast
);
248 BOOST_CHECK_THROW(lexical_cast
<test_t
>("1.e"), bad_lexical_cast
);
249 BOOST_CHECK_THROW(lexical_cast
<test_t
>("1.E"), bad_lexical_cast
);
251 BOOST_CHECK_THROW(lexical_cast
<test_t
>("1.0e"), bad_lexical_cast
);
252 BOOST_CHECK_THROW(lexical_cast
<test_t
>("1.0E"), bad_lexical_cast
);
253 BOOST_CHECK_THROW(lexical_cast
<test_t
>("10E"), bad_lexical_cast
);
254 BOOST_CHECK_THROW(lexical_cast
<test_t
>("10e"), bad_lexical_cast
);
255 BOOST_CHECK_THROW(lexical_cast
<test_t
>("1.0e-"), bad_lexical_cast
);
256 BOOST_CHECK_THROW(lexical_cast
<test_t
>("1.0E-"), bad_lexical_cast
);
257 BOOST_CHECK_THROW(lexical_cast
<test_t
>("10E-"), bad_lexical_cast
);
258 BOOST_CHECK_THROW(lexical_cast
<test_t
>("10e-"), bad_lexical_cast
);
259 BOOST_CHECK_THROW(lexical_cast
<test_t
>("e1"), bad_lexical_cast
);
260 BOOST_CHECK_THROW(lexical_cast
<test_t
>("e-1"), bad_lexical_cast
);
261 BOOST_CHECK_THROW(lexical_cast
<test_t
>("e-"), bad_lexical_cast
);
262 BOOST_CHECK_THROW(lexical_cast
<test_t
>(".e"), bad_lexical_cast
);
263 BOOST_CHECK_THROW(lexical_cast
<test_t
>(".11111111111111111111111111111111111111111111111111111111111111111111ee"), bad_lexical_cast
);
264 BOOST_CHECK_THROW(lexical_cast
<test_t
>(".11111111111111111111111111111111111111111111111111111111111111111111e-"), bad_lexical_cast
);
265 BOOST_CHECK_THROW(lexical_cast
<test_t
>("."), bad_lexical_cast
);
267 BOOST_CHECK_THROW(lexical_cast
<test_t
>("-B"), bad_lexical_cast
);
269 // Following two tests are not valid for C++11 compilers
270 //BOOST_CHECK_THROW(lexical_cast<test_t>("0xB"), bad_lexical_cast);
271 //BOOST_CHECK_THROW(lexical_cast<test_t>("0x0"), bad_lexical_cast);
273 BOOST_CHECK_THROW(lexical_cast
<test_t
>("--1.0"), bad_lexical_cast
);
274 BOOST_CHECK_THROW(lexical_cast
<test_t
>("1.0e--1"), bad_lexical_cast
);
275 BOOST_CHECK_THROW(lexical_cast
<test_t
>("1.0.0"), bad_lexical_cast
);
276 BOOST_CHECK_THROW(lexical_cast
<test_t
>("1e1e1"), bad_lexical_cast
);
277 BOOST_CHECK_THROW(lexical_cast
<test_t
>("1.0e-1e-1"), bad_lexical_cast
);
278 BOOST_CHECK_THROW(lexical_cast
<test_t
>(" 1.0"), bad_lexical_cast
);
279 BOOST_CHECK_THROW(lexical_cast
<test_t
>("1.0 "), bad_lexical_cast
);
280 BOOST_CHECK_THROW(lexical_cast
<test_t
>(""), bad_lexical_cast
);
281 BOOST_CHECK_THROW(lexical_cast
<test_t
>("-"), bad_lexical_cast
);
282 BOOST_CHECK_THROW(lexical_cast
<test_t
>('\0'), bad_lexical_cast
);
283 BOOST_CHECK_THROW(lexical_cast
<test_t
>('-'), bad_lexical_cast
);
284 BOOST_CHECK_THROW(lexical_cast
<test_t
>('.'), bad_lexical_cast
);
288 void test_float_typess_for_overflows()
291 test_t minvalue
= (std::numeric_limits
<test_t
>::min
)();
292 std::string s_min_value
= lexical_cast
<std::string
>(minvalue
);
293 BOOST_CHECK_CLOSE_FRACTION(minvalue
, lexical_cast
<test_t
>(minvalue
), (boost::math::tools::epsilon
<test_t
>()));
294 BOOST_CHECK_CLOSE_FRACTION(minvalue
, lexical_cast
<test_t
>(s_min_value
), (boost::math::tools::epsilon
<test_t
>() * 2));
296 test_t maxvalue
= (std::numeric_limits
<test_t
>::max
)();
297 std::string s_max_value
= lexical_cast
<std::string
>(maxvalue
);
298 BOOST_CHECK_CLOSE_FRACTION(maxvalue
, lexical_cast
<test_t
>(maxvalue
), (boost::math::tools::epsilon
<test_t
>()));
299 BOOST_CHECK_CLOSE_FRACTION(maxvalue
, lexical_cast
<test_t
>(s_max_value
), (boost::math::tools::epsilon
<test_t
>()));
301 #ifndef _LIBCPP_VERSION
302 // libc++ had a bug in implementation of stream conversions for values that must be represented as infinity.
303 // http://llvm.org/bugs/show_bug.cgi?id=15723#c4
304 BOOST_CHECK_THROW(lexical_cast
<test_t
>(s_max_value
+"1"), bad_lexical_cast
);
305 BOOST_CHECK_THROW(lexical_cast
<test_t
>(s_max_value
+"9"), bad_lexical_cast
);
307 // VC9 can fail the following tests on floats and doubles when using stingstream...
308 BOOST_CHECK_THROW(lexical_cast
<test_t
>("1"+s_max_value
), bad_lexical_cast
);
309 BOOST_CHECK_THROW(lexical_cast
<test_t
>("9"+s_max_value
), bad_lexical_cast
);
312 if ( is_same
<test_t
,float>::value
)
314 BOOST_CHECK_THROW(lexical_cast
<test_t
>( (std::numeric_limits
<double>::max
)() ), bad_lexical_cast
);
316 (std::numeric_limits
<double>::min
)() - boost::math::tools::epsilon
<test_t
>()
317 <= lexical_cast
<test_t
>( (std::numeric_limits
<double>::min
)() )
318 && lexical_cast
<test_t
>( (std::numeric_limits
<double>::min
)() )
319 <= (std::numeric_limits
<double>::min
)() + boost::math::tools::epsilon
<test_t
>()
323 if ( sizeof(test_t
) < sizeof(long double) )
325 BOOST_CHECK_THROW(lexical_cast
<test_t
>( (std::numeric_limits
<long double>::max
)() ), bad_lexical_cast
);
327 (std::numeric_limits
<long double>::min
)() - boost::math::tools::epsilon
<test_t
>()
328 <= lexical_cast
<test_t
>( (std::numeric_limits
<long double>::min
)() )
329 && lexical_cast
<test_t
>( (std::numeric_limits
<long double>::min
)() )
330 <= (std::numeric_limits
<long double>::min
)() + boost::math::tools::epsilon
<test_t
>()
335 #undef CHECK_CLOSE_ABS_DIFF
337 // Epsilon is multiplied by 2 because of two lexical conversions
338 #define TEST_TO_FROM_CAST_AROUND_TYPED(VAL,STRING_TYPE) \
339 test_value = VAL + boost::math::tools::epsilon<test_t>() * i ; \
340 converted_val = lexical_cast<test_t>( lexical_cast<STRING_TYPE>(test_value) ); \
341 BOOST_CHECK_CLOSE_FRACTION( \
344 boost::math::tools::epsilon<test_t>() * 2 \
348 * For interval [ from_mult*epsilon+VAL, to_mult*epsilon+VAL ], converts float type
349 * numbers to string[wstring] and then back to float type, then compares initial
350 * values and generated.
353 #ifndef BOOST_LCAST_NO_WCHAR_T
354 # define TEST_TO_FROM_CAST_AROUND(VAL) \
355 for(i=from_mult; i<=to_mult; ++i) { \
356 TEST_TO_FROM_CAST_AROUND_TYPED(VAL, std::string) \
357 TEST_TO_FROM_CAST_AROUND_TYPED(VAL, std::wstring) \
360 # define TEST_TO_FROM_CAST_AROUND(VAL) \
361 for(i=from_mult; i<=to_mult; ++i) { \
362 TEST_TO_FROM_CAST_AROUND_TYPED(VAL, std::string) \
366 template <class TestType
>
367 void test_converion_from_to_float_types()
369 typedef TestType test_t
;
371 test_t converted_val
;
377 TEST_TO_FROM_CAST_AROUND( 0.0 );
380 for(val1
= 1.0e-10L; val1
< 1e11
; val1
*=10 )
381 TEST_TO_FROM_CAST_AROUND( val1
);
384 for(val2
= -1.0e-10L; val2
> -1e11
; val2
*=10 )
385 TEST_TO_FROM_CAST_AROUND( val2
);
389 TEST_TO_FROM_CAST_AROUND( (std::numeric_limits
<test_t
>::max
)() );
393 TEST_TO_FROM_CAST_AROUND( (std::numeric_limits
<test_t
>::min
)() );
396 #undef TEST_TO_FROM_CAST_AROUND
397 #undef TEST_TO_FROM_CAST_AROUND_TYPED
400 template<class T
, class CharT
>
401 void test_conversion_from_float_to_char(CharT zero
)
403 BOOST_CHECK(lexical_cast
<CharT
>(static_cast<T
>(0)) == zero
+ 0);
404 BOOST_CHECK(lexical_cast
<CharT
>(static_cast<T
>(1)) == zero
+ 1);
405 BOOST_CHECK(lexical_cast
<CharT
>(static_cast<T
>(2)) == zero
+ 2);
406 BOOST_CHECK(lexical_cast
<CharT
>(static_cast<T
>(3)) == zero
+ 3);
407 BOOST_CHECK(lexical_cast
<CharT
>(static_cast<T
>(4)) == zero
+ 4);
408 BOOST_CHECK(lexical_cast
<CharT
>(static_cast<T
>(5)) == zero
+ 5);
409 BOOST_CHECK(lexical_cast
<CharT
>(static_cast<T
>(6)) == zero
+ 6);
410 BOOST_CHECK(lexical_cast
<CharT
>(static_cast<T
>(7)) == zero
+ 7);
411 BOOST_CHECK(lexical_cast
<CharT
>(static_cast<T
>(8)) == zero
+ 8);
412 BOOST_CHECK(lexical_cast
<CharT
>(static_cast<T
>(9)) == zero
+ 9);
414 BOOST_CHECK_THROW(lexical_cast
<CharT
>(static_cast<T
>(10)), bad_lexical_cast
);
416 T t
= (std::numeric_limits
<T
>::max
)();
417 BOOST_CHECK_THROW(lexical_cast
<CharT
>(t
), bad_lexical_cast
);
420 template<class T
, class CharT
>
421 void test_conversion_from_char_to_float(CharT zero
)
423 BOOST_CHECK_CLOSE_FRACTION(lexical_cast
<T
>( static_cast<CharT
>(zero
+ 0)), static_cast<T
>(0), (boost::math::tools::epsilon
<T
>()) );
424 BOOST_CHECK_CLOSE_FRACTION(lexical_cast
<T
>( static_cast<CharT
>(zero
+ 1)), static_cast<T
>(1), (boost::math::tools::epsilon
<T
>()) );
425 BOOST_CHECK_CLOSE_FRACTION(lexical_cast
<T
>( static_cast<CharT
>(zero
+ 2)), static_cast<T
>(2), (boost::math::tools::epsilon
<T
>()) );
426 BOOST_CHECK_CLOSE_FRACTION(lexical_cast
<T
>( static_cast<CharT
>(zero
+ 3)), static_cast<T
>(3), (boost::math::tools::epsilon
<T
>()) );
427 BOOST_CHECK_CLOSE_FRACTION(lexical_cast
<T
>( static_cast<CharT
>(zero
+ 4)), static_cast<T
>(4), (boost::math::tools::epsilon
<T
>()) );
428 BOOST_CHECK_CLOSE_FRACTION(lexical_cast
<T
>( static_cast<CharT
>(zero
+ 5)), static_cast<T
>(5), (boost::math::tools::epsilon
<T
>()) );
429 BOOST_CHECK_CLOSE_FRACTION(lexical_cast
<T
>( static_cast<CharT
>(zero
+ 6)), static_cast<T
>(6), (boost::math::tools::epsilon
<T
>()) );
430 BOOST_CHECK_CLOSE_FRACTION(lexical_cast
<T
>( static_cast<CharT
>(zero
+ 7)), static_cast<T
>(7), (boost::math::tools::epsilon
<T
>()) );
431 BOOST_CHECK_CLOSE_FRACTION(lexical_cast
<T
>( static_cast<CharT
>(zero
+ 8)), static_cast<T
>(8), (boost::math::tools::epsilon
<T
>()) );
432 BOOST_CHECK_CLOSE_FRACTION(lexical_cast
<T
>( static_cast<CharT
>(zero
+ 9)), static_cast<T
>(9), (boost::math::tools::epsilon
<T
>()) );
434 BOOST_CHECK_THROW(lexical_cast
<T
>( static_cast<CharT
>(zero
+ 10)), bad_lexical_cast
);
435 BOOST_CHECK_THROW(lexical_cast
<T
>( static_cast<CharT
>(zero
- 1)), bad_lexical_cast
);
438 struct restore_oldloc
441 ~restore_oldloc() { std::locale::global(oldloc
); }
445 void test_conversion_from_to_float()
446 { char const zero
= '0';
447 signed char const szero
= '0';
448 unsigned char const uzero
= '0';
449 test_conversion_from_float_to_char
<T
>(zero
);
450 test_conversion_from_char_to_float
<T
>(zero
);
451 test_conversion_from_float_to_char
<T
>(szero
);
452 test_conversion_from_char_to_float
<T
>(szero
);
453 test_conversion_from_float_to_char
<T
>(uzero
);
454 test_conversion_from_char_to_float
<T
>(uzero
);
455 #if !defined(BOOST_LCAST_NO_WCHAR_T) && !defined(BOOST_NO_INTRINSIC_WCHAR_T)
456 wchar_t const wzero
= L
'0';
457 test_conversion_from_float_to_char
<T
>(wzero
);
458 test_conversion_from_char_to_float
<T
>(wzero
);
461 BOOST_CHECK_CLOSE_FRACTION(lexical_cast
<T
>("+1"), 1, boost::math::tools::epsilon
<T
>());
462 BOOST_CHECK_CLOSE_FRACTION(lexical_cast
<T
>("+9"), 9, boost::math::tools::epsilon
<T
>());
464 BOOST_CHECK_THROW(lexical_cast
<T
>("++1"), bad_lexical_cast
);
465 BOOST_CHECK_THROW(lexical_cast
<T
>("-+9"), bad_lexical_cast
);
466 BOOST_CHECK_THROW(lexical_cast
<T
>("--1"), bad_lexical_cast
);
467 BOOST_CHECK_THROW(lexical_cast
<T
>("+-9"), bad_lexical_cast
);
469 test_converion_to_float_types
<T
>();
470 test_float_typess_for_overflows
<T
>();
471 test_converion_from_to_float_types
<T
>();
474 typedef std::numpunct
<char> numpunct
;
476 restore_oldloc guard
;
477 std::locale
const& oldloc
= guard
.oldloc
;
479 std::string grouping1
= BOOST_USE_FACET(numpunct
, oldloc
).grouping();
480 std::string
grouping2(grouping1
);
482 test_conversion_from_to_float_for_locale
<T
>();
486 std::locale
newloc("");
487 std::locale::global(newloc
);
489 grouping2
= BOOST_USE_FACET(numpunct
, newloc
).grouping();
491 catch(std::exception
const& ex
)
493 std::string
msg("Failed to set system locale: ");
495 BOOST_TEST_MESSAGE(msg
);
498 if(grouping1
!= grouping2
)
499 test_conversion_from_to_float_for_locale
<T
>();
501 if(grouping1
.empty() && grouping2
.empty())
502 BOOST_TEST_MESSAGE("Formatting with thousands_sep has not been tested");
506 void test_conversion_from_to_float()
508 test_conversion_from_to_float
<float>();
510 void test_conversion_from_to_double()
512 test_conversion_from_to_float
<double>();
514 void test_conversion_from_to_long_double()
516 // We do not run tests on compilers with bugs
517 #ifndef BOOST_MATH_NO_LONG_DOUBLE_MATH_FUNCTIONS
518 test_conversion_from_to_float
<long double>();