]> git.proxmox.com Git - ceph.git/blob - ceph/src/boost/libs/lexical_cast/test/integral_types_test.cpp
update ceph source to reef 18.1.2
[ceph.git] / ceph / src / boost / libs / lexical_cast / test / integral_types_test.cpp
1 // Unit test for boost::lexical_cast.
2 //
3 // See http://www.boost.org for most recent version, including documentation.
4 //
5 // Copyright Terje Sletteb and Kevlin Henney, 2005.
6 // Copyright Alexander Nasonov, 2006.
7 // Copyright Antony Polukhin, 2011-2022.
8 //
9 // Distributed under the Boost
10 // Software License, Version 1.0. (See accompanying file
11 // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt).
12 //
13 // Note: The unit test no longer compile on MSVC 6, but lexical_cast itself works for it.
14
15 //
16 // We need this #define before any #includes: otherwise msvc will emit warnings
17 // deep within std::string, resulting from our (perfectly legal) use of basic_string
18 // with a custom traits class:
19 //
20 #define _SCL_SECURE_NO_WARNINGS
21
22 #include <boost/config.hpp>
23
24 #if defined(__INTEL_COMPILER)
25 #pragma warning(disable: 193 383 488 981 1418 1419)
26 #elif defined(BOOST_MSVC)
27 #pragma warning(disable: 4097 4100 4121 4127 4146 4244 4245 4511 4512 4701 4800)
28 #endif
29
30 #include <boost/lexical_cast.hpp>
31
32 #include <boost/cstdint.hpp>
33 #include <boost/test/unit_test.hpp>
34 #include <boost/test/tools/floating_point_comparison.hpp>
35
36 #include <boost/type_traits/integral_promotion.hpp>
37 #include <boost/type_traits/make_unsigned.hpp>
38 #include <string>
39 #include <vector>
40 #include <memory>
41
42 #if (defined(BOOST_HAS_LONG_LONG) || defined(BOOST_HAS_MS_INT64)) \
43 && !(defined(BOOST_MSVC) && BOOST_MSVC < 1300)
44 #define LCAST_TEST_LONGLONG
45 #endif
46
47 #if defined(BOOST_NO_STRINGSTREAM) || defined(BOOST_NO_STD_WSTRING)
48 #define BOOST_LCAST_NO_WCHAR_T
49 #endif
50
51 #if defined(BOOST_HAS_INT128) && !defined(BOOST_LEXICAL_CAST_TEST_NO_128_INTS)
52 # define BOOST_LCAST_TEST_128 1
53 #endif
54
55 // Test all 65536 values if true:
56 bool const lcast_test_small_integral_types_completely = false;
57
58 // lcast_integral_test_counter: use when testing all values of an integral
59 // types is not possible. Max. portable value is 32767.
60 int const lcast_integral_test_counter=500;
61
62 using namespace boost;
63
64
65
66 void test_conversion_from_to_short();
67 void test_conversion_from_to_ushort();
68 void test_conversion_from_to_int();
69 void test_conversion_from_to_uint();
70 void test_conversion_from_to_long();
71 void test_conversion_from_to_ulong();
72 void test_conversion_from_to_intmax_t();
73 void test_conversion_from_to_uintmax_t();
74 #ifdef LCAST_TEST_LONGLONG
75 void test_conversion_from_to_longlong();
76 void test_conversion_from_to_ulonglong();
77 #endif
78 #ifdef BOOST_LCAST_TEST_128
79 void test_conversion_from_to_int128();
80 void test_conversion_from_to_uint128();
81 #endif
82 void test_integral_conversions_on_min_max();
83
84
85 unit_test::test_suite *init_unit_test_suite(int, char *[])
86 {
87 unit_test::test_suite *suite =
88 BOOST_TEST_SUITE("lexical_cast unit test on integral types");
89
90 suite->add(BOOST_TEST_CASE(&test_conversion_from_to_short));
91 suite->add(BOOST_TEST_CASE(&test_conversion_from_to_ushort));
92 suite->add(BOOST_TEST_CASE(&test_conversion_from_to_int));
93 suite->add(BOOST_TEST_CASE(&test_conversion_from_to_uint));
94 suite->add(BOOST_TEST_CASE(&test_conversion_from_to_long));
95 suite->add(BOOST_TEST_CASE(&test_conversion_from_to_ulong));
96 suite->add(BOOST_TEST_CASE(&test_conversion_from_to_intmax_t));
97 suite->add(BOOST_TEST_CASE(&test_conversion_from_to_uintmax_t));
98 #ifdef LCAST_TEST_LONGLONG
99 suite->add(BOOST_TEST_CASE(&test_conversion_from_to_longlong));
100 suite->add(BOOST_TEST_CASE(&test_conversion_from_to_ulonglong));
101 #endif
102 #ifdef BOOST_LCAST_TEST_128
103 suite->add(BOOST_TEST_CASE(&test_conversion_from_to_int128));
104 suite->add(BOOST_TEST_CASE(&test_conversion_from_to_uint128));
105 #endif
106 suite->add(BOOST_TEST_CASE(&test_integral_conversions_on_min_max));
107
108 return suite;
109 }
110
111 template<class T, class CharT>
112 void test_conversion_from_integral_to_char(CharT zero)
113 {
114 BOOST_CHECK(lexical_cast<CharT>(static_cast<T>(0)) == zero + 0);
115 BOOST_CHECK(lexical_cast<CharT>(static_cast<T>(1)) == zero + 1);
116 BOOST_CHECK(lexical_cast<CharT>(static_cast<T>(2)) == zero + 2);
117 BOOST_CHECK(lexical_cast<CharT>(static_cast<T>(3)) == zero + 3);
118 BOOST_CHECK(lexical_cast<CharT>(static_cast<T>(4)) == zero + 4);
119 BOOST_CHECK(lexical_cast<CharT>(static_cast<T>(5)) == zero + 5);
120 BOOST_CHECK(lexical_cast<CharT>(static_cast<T>(6)) == zero + 6);
121 BOOST_CHECK(lexical_cast<CharT>(static_cast<T>(7)) == zero + 7);
122 BOOST_CHECK(lexical_cast<CharT>(static_cast<T>(8)) == zero + 8);
123 BOOST_CHECK(lexical_cast<CharT>(static_cast<T>(9)) == zero + 9);
124
125 BOOST_CHECK_THROW(lexical_cast<CharT>(static_cast<T>(10)), bad_lexical_cast);
126
127 T t = (std::numeric_limits<T>::max)();
128 BOOST_CHECK_THROW(lexical_cast<CharT>(t), bad_lexical_cast);
129 }
130
131 template<class T, class CharT>
132 void test_conversion_from_char_to_integral(CharT zero)
133 {
134 BOOST_CHECK(lexical_cast<T>( static_cast<CharT>(zero + 0)) == static_cast<T>(0) );
135 BOOST_CHECK(lexical_cast<T>( static_cast<CharT>(zero + 1)) == static_cast<T>(1) );
136 BOOST_CHECK(lexical_cast<T>( static_cast<CharT>(zero + 2)) == static_cast<T>(2) );
137 BOOST_CHECK(lexical_cast<T>( static_cast<CharT>(zero + 3)) == static_cast<T>(3) );
138 BOOST_CHECK(lexical_cast<T>( static_cast<CharT>(zero + 4)) == static_cast<T>(4) );
139 BOOST_CHECK(lexical_cast<T>( static_cast<CharT>(zero + 5)) == static_cast<T>(5) );
140 BOOST_CHECK(lexical_cast<T>( static_cast<CharT>(zero + 6)) == static_cast<T>(6) );
141 BOOST_CHECK(lexical_cast<T>( static_cast<CharT>(zero + 7)) == static_cast<T>(7) );
142 BOOST_CHECK(lexical_cast<T>( static_cast<CharT>(zero + 8)) == static_cast<T>(8) );
143 BOOST_CHECK(lexical_cast<T>( static_cast<CharT>(zero + 9)) == static_cast<T>(9) );
144
145 BOOST_CHECK_THROW(lexical_cast<T>( static_cast<CharT>(zero + 10)), bad_lexical_cast);
146 BOOST_CHECK_THROW(lexical_cast<T>( static_cast<CharT>(zero - 1)), bad_lexical_cast);
147 }
148
149 template<class T>
150 void test_conversion_from_integral_to_integral()
151 {
152 T t = 0;
153 BOOST_CHECK(lexical_cast<T>(t) == t);
154
155 // Next two variables are used to suppress warnings.
156 int st = 32767; unsigned int ut = st;
157 t = st;
158 BOOST_CHECK(lexical_cast<short>(t) == st);
159 BOOST_CHECK(lexical_cast<unsigned short>(t) == ut);
160 BOOST_CHECK(lexical_cast<int>(t) == st);
161 BOOST_CHECK(lexical_cast<unsigned int>(t) == ut);
162 BOOST_CHECK(lexical_cast<long>(t) == st);
163 BOOST_CHECK(lexical_cast<unsigned long>(t) == ut);
164
165 t = (std::numeric_limits<T>::max)();
166 BOOST_CHECK(lexical_cast<T>(t) == t);
167
168 t = (std::numeric_limits<T>::min)();
169 BOOST_CHECK(lexical_cast<T>(t) == t);
170 }
171
172
173
174
175 // Replace "-,999" with "-999".
176 template<class CharT>
177 std::basic_string<CharT> to_str_gcc_workaround(std::basic_string<CharT> str)
178 {
179 std::locale loc;
180 std::numpunct<CharT> const& np = BOOST_USE_FACET(std::numpunct<CharT>, loc);
181 std::ctype<CharT> const& ct = BOOST_USE_FACET(std::ctype<CharT>, loc);
182
183 if(np.grouping().empty())
184 return str;
185
186 CharT prefix[3] = { ct.widen('-'), np.thousands_sep(), CharT() };
187
188 if(str.find(prefix) != 0)
189 return str;
190
191 prefix[1] = CharT();
192 str.replace(0, 2, prefix);
193 return str;
194 }
195
196 template<class CharT, class T>
197 std::basic_string<CharT> to_str(T t)
198 {
199 std::basic_ostringstream<CharT> o;
200 o << t;
201 return to_str_gcc_workaround(o.str());
202 }
203
204
205 template<class T, class CharT>
206 void test_conversion_from_integral_to_string(CharT)
207 {
208 typedef std::numeric_limits<T> limits;
209 typedef std::basic_string<CharT> string_type;
210
211 T t;
212
213 t = (limits::min)();
214 BOOST_CHECK(lexical_cast<string_type>(t) == to_str<CharT>(t));
215
216 t = (limits::max)();
217 BOOST_CHECK(lexical_cast<string_type>(t) == to_str<CharT>(t));
218
219 if(limits::digits <= 16 && lcast_test_small_integral_types_completely)
220 // min and max have already been tested.
221 for(t = 1 + (limits::min)(); t != (limits::max)(); ++t)
222 BOOST_CHECK(lexical_cast<string_type>(t) == to_str<CharT>(t));
223 else
224 {
225 T const min_val = (limits::min)();
226 T const max_val = (limits::max)();
227 T const half_max_val = max_val / 2;
228 T const cnt = lcast_integral_test_counter; // to suppress warnings
229 unsigned int const counter = cnt < half_max_val ? cnt : half_max_val;
230
231 unsigned int i;
232
233 // Test values around min:
234 t = min_val;
235 for(i = 0; i < counter; ++i, ++t)
236 BOOST_CHECK(lexical_cast<string_type>(t) == to_str<CharT>(t));
237
238 // Test values around max:
239 t = max_val;
240 for(i = 0; i < counter; ++i, --t)
241 BOOST_CHECK(lexical_cast<string_type>(t) == to_str<CharT>(t));
242
243 // Test values around zero:
244 if(limits::is_signed)
245 for(t = static_cast<T>(-counter); t < static_cast<T>(counter); ++t)
246 BOOST_CHECK(lexical_cast<string_type>(t) == to_str<CharT>(t));
247
248 // Test values around 100, 1000, 10000, ...
249 T ten_power = 100;
250 for(int e = 2; e < limits::digits10; ++e, ten_power *= 10)
251 {
252 // ten_power + 100 probably never overflows
253 for(t = ten_power - 100; t != ten_power + 100; ++t)
254 BOOST_CHECK(lexical_cast<string_type>(t) == to_str<CharT>(t));
255 }
256 }
257 }
258
259 template<class T, class CharT>
260 void test_conversion_from_string_to_integral(CharT)
261 {
262 typedef std::numeric_limits<T> limits;
263 typedef std::basic_string<CharT> string_type;
264
265 string_type s;
266 string_type const zero = to_str<CharT>(0);
267 string_type const nine = to_str<CharT>(9);
268 T const min_val = (limits::min)();
269 T const max_val = (limits::max)();
270
271 s = to_str<CharT>(min_val);
272 BOOST_CHECK_EQUAL(lexical_cast<T>(s), min_val);
273 if(limits::is_signed)
274 {
275 BOOST_CHECK_THROW(lexical_cast<T>(s + zero), bad_lexical_cast);
276 BOOST_CHECK_THROW(lexical_cast<T>(s + nine), bad_lexical_cast);
277 }
278
279 s = to_str<CharT>(max_val);
280 BOOST_CHECK_EQUAL(lexical_cast<T>(s), max_val);
281 {
282 BOOST_CHECK_THROW(lexical_cast<T>(s + zero), bad_lexical_cast);
283 BOOST_CHECK_THROW(lexical_cast<T>(s + nine), bad_lexical_cast);
284
285 s = to_str<CharT>(max_val);
286 for (int i =1; i <=10; ++i) {
287 s[s.size()-1] += 1;
288 BOOST_CHECK_THROW(lexical_cast<T>( s ), bad_lexical_cast);
289 }
290
291 s = to_str<CharT>(max_val);
292 std::locale loc;
293 typedef std::numpunct<char> numpunct;
294 if ( BOOST_USE_FACET(numpunct, loc).grouping().empty() ) {
295 // Following tests work well for locale C
296 BOOST_CHECK_EQUAL(lexical_cast<T>(to_str<CharT>(0)+s), max_val);
297 BOOST_CHECK_EQUAL(lexical_cast<T>(to_str<CharT>(0)+to_str<CharT>(0)+s), max_val);
298 BOOST_CHECK_EQUAL(lexical_cast<T>(to_str<CharT>(0)+to_str<CharT>(0)+to_str<CharT>(0)+s), max_val);
299 }
300
301 for (int i =1; i <=256; ++i) {
302 BOOST_CHECK_THROW(lexical_cast<T>( to_str<CharT>(i)+s ), bad_lexical_cast);
303 }
304
305 typedef BOOST_DEDUCED_TYPENAME boost::integral_promotion<T>::type promoted;
306 if ( !(boost::is_same<T, promoted>::value) )
307 {
308 promoted prom = max_val;
309 s = to_str<CharT>(max_val);
310 for (int i =1; i <=256; ++i) {
311 BOOST_CHECK_THROW(lexical_cast<T>( to_str<CharT>(prom+i) ), bad_lexical_cast);
312 BOOST_CHECK_THROW(lexical_cast<T>( to_str<CharT>(i)+s ), bad_lexical_cast);
313 }
314 }
315 }
316
317 if(limits::digits <= 16 && lcast_test_small_integral_types_completely)
318 // min and max have already been tested.
319 for(T t = 1 + min_val; t != max_val; ++t)
320 BOOST_CHECK(lexical_cast<T>(to_str<CharT>(t)) == t);
321 else
322 {
323 T const half_max_val = max_val / 2;
324 T const cnt = lcast_integral_test_counter; // to suppress warnings
325 unsigned int const counter = cnt < half_max_val ? cnt : half_max_val;
326
327 T t;
328 unsigned int i;
329
330 // Test values around min:
331 t = min_val;
332 for(i = 0; i < counter; ++i, ++t)
333 BOOST_CHECK(lexical_cast<T>(to_str<CharT>(t)) == t);
334
335 // Test values around max:
336 t = max_val;
337 for(i = 0; i < counter; ++i, --t)
338 BOOST_CHECK(lexical_cast<T>(to_str<CharT>(t)) == t);
339
340 // Test values around zero:
341 if(limits::is_signed)
342 for(t = static_cast<T>(-counter); t < static_cast<T>(counter); ++t)
343 BOOST_CHECK(lexical_cast<T>(to_str<CharT>(t)) == t);
344
345 // Test values around 100, 1000, 10000, ...
346 T ten_power = 100;
347 for(int e = 2; e < limits::digits10; ++e, ten_power *= 10)
348 {
349 // ten_power + 100 probably never overflows
350 for(t = ten_power - 100; t != ten_power + 100; ++t)
351 BOOST_CHECK(lexical_cast<T>(to_str<CharT>(t)) == t);
352 }
353 }
354 }
355
356 template<class T>
357 void test_conversion_from_to_integral_for_locale()
358 {
359 std::locale current_locale;
360 typedef std::numpunct<char> numpunct;
361 numpunct const& np = BOOST_USE_FACET(numpunct, current_locale);
362 if ( !np.grouping().empty() )
363 {
364 BOOST_CHECK_THROW(
365 lexical_cast<T>( std::string("100") + np.thousands_sep() + np.thousands_sep() + "0" )
366 , bad_lexical_cast);
367 BOOST_CHECK_THROW(lexical_cast<T>( std::string("100") + np.thousands_sep() ), bad_lexical_cast);
368 BOOST_CHECK_THROW(lexical_cast<T>( np.thousands_sep() + std::string("100") ), bad_lexical_cast);
369
370 // Exception must not be thrown, when we are using no separators at all
371 BOOST_CHECK( lexical_cast<T>("30000") == static_cast<T>(30000) );
372 }
373
374
375 test_conversion_from_integral_to_integral<T>();
376
377 // This is a part of test_conversion_from_integral_to_string<T>('0') method,
378 // but with BOOST_CHECK_EQUAL instead of BOOST_CHECK. It is required to see
379 // what is produced by the to_str<char>(t) method in situations when result
380 // is different. BOOST_CHECK does not work with wchar_t.
381 typedef std::numeric_limits<T> limits;
382 T t = (limits::min)();
383 BOOST_CHECK_EQUAL(lexical_cast<std::string>(t), to_str<char>(t));
384
385 test_conversion_from_integral_to_string<T>('0');
386 test_conversion_from_string_to_integral<T>('0');
387 #if !defined(BOOST_LCAST_NO_WCHAR_T)
388 if (lexical_cast<std::wstring>(t) != to_str<wchar_t>(t)) {
389 // Something went wrong, and now we are attempting to find and print the
390 // difference.
391 std::wstring wstr = to_str<wchar_t>(t);
392 std::string lcast_str = lexical_cast<std::string>(t);
393 std::string str;
394 str.reserve(wstr.size());
395 for (std::size_t i = 0; i < wstr.size(); ++i) {
396 str.push_back(static_cast<char>(wstr[i]));
397 }
398
399 BOOST_CHECK_EQUAL(lcast_str.length(), lexical_cast<std::wstring>(t).length());
400 BOOST_CHECK_EQUAL(to_str<char>(t), str);
401 BOOST_CHECK_EQUAL(lcast_str, str);
402 }
403
404 test_conversion_from_integral_to_string<T>(L'0');
405 test_conversion_from_string_to_integral<T>(L'0');
406 #endif
407 }
408
409 struct restore_oldloc
410 {
411 std::locale oldloc;
412 ~restore_oldloc() { std::locale::global(oldloc); }
413 };
414
415 template<class T>
416 void test_conversion_from_to_integral_minimal()
417 {
418 char const zero = '0';
419 signed char const szero = '0';
420 unsigned char const uzero = '0';
421 test_conversion_from_integral_to_char<T>(zero);
422 test_conversion_from_char_to_integral<T>(zero);
423 test_conversion_from_integral_to_char<T>(szero);
424 test_conversion_from_char_to_integral<T>(szero);
425 test_conversion_from_integral_to_char<T>(uzero);
426 test_conversion_from_char_to_integral<T>(uzero);
427 #if !defined(BOOST_LCAST_NO_WCHAR_T) && !defined(BOOST_NO_INTRINSIC_WCHAR_T)
428 wchar_t const wzero = L'0';
429 test_conversion_from_integral_to_char<T>(wzero);
430 test_conversion_from_char_to_integral<T>(wzero);
431 #endif
432 #if !defined(BOOST_NO_CXX11_CHAR16_T) && !defined(BOOST_NO_CXX11_UNICODE_LITERALS) && !defined(_LIBCPP_VERSION) && !defined(BOOST_MSVC)
433 char16_t const u16zero = u'0';
434 test_conversion_from_integral_to_char<T>(u16zero);
435 test_conversion_from_char_to_integral<T>(u16zero);
436 #endif
437 #if !defined(BOOST_NO_CXX11_CHAR32_T) && !defined(BOOST_NO_CXX11_UNICODE_LITERALS) && !defined(_LIBCPP_VERSION) && !defined(BOOST_MSVC)
438 char32_t const u32zero = u'0';
439 test_conversion_from_integral_to_char<T>(u32zero);
440 test_conversion_from_char_to_integral<T>(u32zero);
441 #endif
442
443 BOOST_CHECK(lexical_cast<T>("-1") == static_cast<T>(-1));
444 BOOST_CHECK(lexical_cast<T>("-9") == static_cast<T>(-9));
445 BOOST_CHECK(lexical_cast<T>(-1) == static_cast<T>(-1));
446 BOOST_CHECK(lexical_cast<T>(-9) == static_cast<T>(-9));
447
448 BOOST_CHECK_THROW(lexical_cast<T>("-1.0"), bad_lexical_cast);
449 BOOST_CHECK_THROW(lexical_cast<T>("-9.0"), bad_lexical_cast);
450 BOOST_CHECK(lexical_cast<T>(-1.0) == static_cast<T>(-1));
451 BOOST_CHECK(lexical_cast<T>(-9.0) == static_cast<T>(-9));
452
453 BOOST_CHECK(lexical_cast<T>(static_cast<T>(1)) == static_cast<T>(1));
454 BOOST_CHECK(lexical_cast<T>(static_cast<T>(9)) == static_cast<T>(9));
455 BOOST_CHECK_THROW(lexical_cast<T>(1.1f), bad_lexical_cast);
456 BOOST_CHECK_THROW(lexical_cast<T>(1.1), bad_lexical_cast);
457 BOOST_CHECK_THROW(lexical_cast<T>(1.1L), bad_lexical_cast);
458 BOOST_CHECK_THROW(lexical_cast<T>(1.0001f), bad_lexical_cast);
459 BOOST_CHECK_THROW(lexical_cast<T>(1.0001), bad_lexical_cast);
460 BOOST_CHECK_THROW(lexical_cast<T>(1.0001L), bad_lexical_cast);
461
462 BOOST_CHECK(lexical_cast<T>("+1") == static_cast<T>(1) );
463 BOOST_CHECK(lexical_cast<T>("+9") == static_cast<T>(9) );
464 BOOST_CHECK(lexical_cast<T>("+10") == static_cast<T>(10) );
465 BOOST_CHECK(lexical_cast<T>("+90") == static_cast<T>(90) );
466 BOOST_CHECK_THROW(lexical_cast<T>("++1"), bad_lexical_cast);
467 BOOST_CHECK_THROW(lexical_cast<T>("-+9"), bad_lexical_cast);
468 BOOST_CHECK_THROW(lexical_cast<T>("--1"), bad_lexical_cast);
469 BOOST_CHECK_THROW(lexical_cast<T>("+-9"), bad_lexical_cast);
470 // test_conversion_from_to_integral_for_locale
471
472 // Overflow test case from David W. Birdsall
473 std::string must_owerflow_str = (sizeof(T) < 16 ? "160000000000000000000" : "1600000000000000000000000000000000000000");
474 std::string must_owerflow_negative_str = (sizeof(T) < 16 ? "-160000000000000000000" : "-1600000000000000000000000000000000000000");
475 for (int i = 0; i < 15; ++i) {
476 BOOST_CHECK_THROW(lexical_cast<T>(must_owerflow_str), bad_lexical_cast);
477 BOOST_CHECK_THROW(lexical_cast<T>(must_owerflow_negative_str), bad_lexical_cast);
478
479 must_owerflow_str += '0';
480 must_owerflow_negative_str += '0';
481 }
482 }
483
484 template<class T>
485 void test_conversion_from_to_integral()
486 {
487 test_conversion_from_to_integral_minimal<T>();
488 typedef std::numpunct<char> numpunct;
489
490 restore_oldloc guard;
491 std::locale const& oldloc = guard.oldloc;
492
493 std::string grouping1 = BOOST_USE_FACET(numpunct, oldloc).grouping();
494 std::string grouping2(grouping1);
495
496 test_conversion_from_to_integral_for_locale<T>();
497
498 try
499 {
500 std::locale newloc("");
501 std::locale::global(newloc);
502
503 grouping2 = BOOST_USE_FACET(numpunct, newloc).grouping();
504 }
505 catch(std::exception const& ex)
506 {
507 std::string msg("Failed to set system locale: ");
508 msg += ex.what();
509 BOOST_TEST_MESSAGE(msg);
510 }
511
512 if(grouping1 != grouping2)
513 test_conversion_from_to_integral_for_locale<T>();
514
515 if(grouping1.empty() && grouping2.empty())
516 BOOST_TEST_MESSAGE("Formatting with thousands_sep has not been tested");
517 }
518
519 void test_conversion_from_to_short()
520 {
521 test_conversion_from_to_integral<short>();
522 }
523
524 void test_conversion_from_to_ushort()
525 {
526 test_conversion_from_to_integral<unsigned short>();
527 }
528
529 void test_conversion_from_to_int()
530 {
531 test_conversion_from_to_integral<int>();
532 }
533
534 void test_conversion_from_to_uint()
535 {
536 test_conversion_from_to_integral<unsigned int>();
537 }
538
539 void test_conversion_from_to_long()
540 {
541 test_conversion_from_to_integral<long>();
542 }
543
544 void test_conversion_from_to_ulong()
545 {
546 test_conversion_from_to_integral<unsigned long>();
547 }
548
549 void test_conversion_from_to_intmax_t()
550 {
551 test_conversion_from_to_integral<boost::intmax_t>();
552 }
553
554 void test_conversion_from_to_uintmax_t()
555 {
556 test_conversion_from_to_integral<boost::uintmax_t>();
557 }
558
559 #if defined(BOOST_HAS_LONG_LONG)
560
561 void test_conversion_from_to_longlong()
562 {
563 test_conversion_from_to_integral<boost::long_long_type>();
564 }
565
566 void test_conversion_from_to_ulonglong()
567 {
568 test_conversion_from_to_integral<boost::ulong_long_type>();
569 }
570
571 #elif defined(BOOST_HAS_MS_INT64)
572
573 void test_conversion_from_to_longlong()
574 {
575 test_conversion_from_to_integral<__int64>();
576 }
577
578 void test_conversion_from_to_ulonglong()
579 {
580 test_conversion_from_to_integral<unsigned __int64>();
581 }
582
583 #endif
584
585
586 #ifdef BOOST_LCAST_TEST_128
587
588 template <bool Specialized, class T>
589 struct test_if_specialized {
590 static void test() {}
591 };
592
593 template <class T>
594 struct test_if_specialized<true, T> {
595 static void test() {
596 test_conversion_from_to_integral_minimal<T>();
597 }
598 };
599
600 void test_conversion_from_to_int128()
601 {
602 test_if_specialized<
603 std::numeric_limits<boost::int128_type>::is_specialized,
604 boost::int128_type
605 >::test();
606 }
607
608 void test_conversion_from_to_uint128()
609 {
610 test_if_specialized<
611 std::numeric_limits<boost::int128_type>::is_specialized,
612 boost::uint128_type
613 >::test();
614 }
615 #endif
616
617 template <typename SignedT>
618 void test_integral_conversions_on_min_max_impl()
619 {
620 typedef SignedT signed_t;
621 typedef BOOST_DEDUCED_TYPENAME boost::make_unsigned<signed_t>::type unsigned_t;
622
623 typedef std::numeric_limits<signed_t> s_limits;
624 typedef std::numeric_limits<unsigned_t> uns_limits;
625
626 BOOST_CHECK_EQUAL(lexical_cast<unsigned_t>((uns_limits::max)()), (uns_limits::max)());
627 BOOST_CHECK_EQUAL(lexical_cast<unsigned_t>((uns_limits::min)()), (uns_limits::min)());
628
629 BOOST_CHECK_EQUAL(lexical_cast<signed_t>((s_limits::max)()), (s_limits::max)());
630 BOOST_CHECK_EQUAL(lexical_cast<signed_t>((uns_limits::min)()), static_cast<signed_t>((uns_limits::min)()));
631
632 BOOST_CHECK_EQUAL(lexical_cast<unsigned_t>((s_limits::max)()), static_cast<unsigned_t>((s_limits::max)()));
633 BOOST_CHECK_EQUAL(lexical_cast<unsigned_t>((s_limits::min)()), static_cast<unsigned_t>((s_limits::min)()));
634 }
635
636 void test_integral_conversions_on_min_max()
637 {
638 test_integral_conversions_on_min_max_impl<int>();
639 test_integral_conversions_on_min_max_impl<short>();
640
641 #ifdef _MSC_VER
642 test_integral_conversions_on_min_max_impl<long int>();
643
644 #if defined(BOOST_HAS_LONG_LONG)
645 test_integral_conversions_on_min_max_impl<boost::long_long_type>();
646 #elif defined(BOOST_HAS_MS_INT64)
647 test_integral_conversions_on_min_max_impl<__int64>();
648 #endif
649
650 #ifdef BOOST_LCAST_TEST_128
651 test_integral_conversions_on_min_max_impl<boost::int128_type>();
652 #endif
653 #endif
654
655 }
656
657