Imported Upstream version 1.51.0
[platform/upstream/boost.git] / libs / conversion / lexical_cast_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-2012.
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/floating_point_comparison.hpp>
35
36 #include <boost/type_traits/integral_promotion.hpp>
37 #include <string>
38 #include <vector>
39 #include <memory>
40
41 #if (defined(BOOST_HAS_LONG_LONG) || defined(BOOST_HAS_MS_INT64)) \
42     && !(defined(BOOST_MSVC) && BOOST_MSVC < 1300)
43 #define LCAST_TEST_LONGLONG
44 #endif
45
46 #if defined(BOOST_NO_STRINGSTREAM) || defined(BOOST_NO_STD_WSTRING)
47 #define BOOST_LCAST_NO_WCHAR_T
48 #endif
49
50 template<class CharT>
51 struct my_traits : std::char_traits<CharT>
52 {
53 };
54
55 template<class CharT>
56 struct my_allocator : std::allocator<CharT>
57 {
58 };
59
60 using namespace boost;
61
62 void test_conversion_to_char();
63 void test_conversion_to_int();
64 void test_conversion_to_double();
65 void test_conversion_to_bool();
66 void test_conversion_with_nonconst_char();
67 void test_conversion_to_string();
68 void test_conversion_from_to_wchar_t_alias();
69 void test_conversion_to_pointer();
70 void test_conversion_from_wchar_t();
71 void test_conversion_to_wchar_t();
72 void test_conversion_from_wstring();
73 void test_conversion_to_wstring();
74 void test_bad_lexical_cast();
75 void test_no_whitespace_stripping();
76 #ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
77 void test_traits();
78 void test_wtraits();
79 void test_allocator();
80 void test_wallocator();
81 #endif
82 void test_char_types_conversions();
83 void operators_overload_test();
84 #if !defined(BOOST_NO_CHAR16_T) && !defined(BOOST_NO_UNICODE_LITERALS)
85 void test_char16_conversions();
86 #endif
87 #if !defined(BOOST_NO_CHAR32_T) && !defined(BOOST_NO_UNICODE_LITERALS)
88 void test_char32_conversions();
89 #endif
90
91 unit_test::test_suite *init_unit_test_suite(int, char *[])
92 {
93     unit_test::test_suite *suite =
94         BOOST_TEST_SUITE("lexical_cast unit test");
95     suite->add(BOOST_TEST_CASE(test_conversion_to_char));
96     suite->add(BOOST_TEST_CASE(test_conversion_to_int));
97     suite->add(BOOST_TEST_CASE(test_conversion_to_double));
98     suite->add(BOOST_TEST_CASE(test_conversion_to_bool));
99     suite->add(BOOST_TEST_CASE(test_conversion_from_to_wchar_t_alias));
100     suite->add(BOOST_TEST_CASE(test_conversion_to_pointer));
101     suite->add(BOOST_TEST_CASE(test_conversion_to_string));
102     suite->add(BOOST_TEST_CASE(test_conversion_with_nonconst_char));
103 #ifndef BOOST_LCAST_NO_WCHAR_T
104     suite->add(BOOST_TEST_CASE(test_conversion_from_wchar_t));
105     suite->add(BOOST_TEST_CASE(test_conversion_to_wchar_t));
106     suite->add(BOOST_TEST_CASE(test_conversion_from_wstring));
107     suite->add(BOOST_TEST_CASE(test_conversion_to_wstring));
108 #endif
109     suite->add(BOOST_TEST_CASE(test_bad_lexical_cast));
110     suite->add(BOOST_TEST_CASE(test_no_whitespace_stripping));
111 #ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
112     suite->add(BOOST_TEST_CASE(&test_traits));
113     suite->add(BOOST_TEST_CASE(&test_wtraits));
114     suite->add(BOOST_TEST_CASE(&test_allocator));
115     suite->add(BOOST_TEST_CASE(&test_wallocator));
116 #endif
117
118     suite->add(BOOST_TEST_CASE(&test_char_types_conversions));
119     suite->add(BOOST_TEST_CASE(&operators_overload_test));
120 #if !defined(BOOST_NO_CHAR16_T) && !defined(BOOST_NO_UNICODE_LITERALS)
121     suite->add(BOOST_TEST_CASE(&test_char16_conversions));
122 #endif
123 #if !defined(BOOST_NO_CHAR32_T) && !defined(BOOST_NO_UNICODE_LITERALS)
124     suite->add(BOOST_TEST_CASE(&test_char32_conversions));
125 #endif
126
127     return suite;
128 }
129
130 void test_conversion_to_char()
131 {
132     BOOST_CHECK_EQUAL('A', lexical_cast<char>('A'));
133     BOOST_CHECK_EQUAL(' ', lexical_cast<char>(' '));
134     BOOST_CHECK_EQUAL('1', lexical_cast<char>(1));
135     BOOST_CHECK_EQUAL('0', lexical_cast<char>(0));
136     BOOST_CHECK_THROW(lexical_cast<char>(123), bad_lexical_cast);
137     BOOST_CHECK_EQUAL('1', lexical_cast<char>(1.0));
138     BOOST_CHECK_EQUAL('1', lexical_cast<char>(true));
139     BOOST_CHECK_EQUAL('0', lexical_cast<char>(false));
140     BOOST_CHECK_EQUAL('A', lexical_cast<char>("A"));
141     BOOST_CHECK_EQUAL(' ', lexical_cast<char>(" "));
142     BOOST_CHECK_THROW(lexical_cast<char>(""), bad_lexical_cast);
143     BOOST_CHECK_THROW(lexical_cast<char>("Test"), bad_lexical_cast);
144     BOOST_CHECK_EQUAL('A', lexical_cast<char>(std::string("A")));
145     BOOST_CHECK_EQUAL(' ', lexical_cast<char>(std::string(" ")));
146     BOOST_CHECK_THROW(
147         lexical_cast<char>(std::string("")), bad_lexical_cast);
148     BOOST_CHECK_THROW(
149         lexical_cast<char>(std::string("Test")), bad_lexical_cast);
150 }
151
152 void test_conversion_to_int()
153 {
154     BOOST_CHECK_EQUAL(1, lexical_cast<int>('1'));
155     BOOST_CHECK_EQUAL(0, lexical_cast<int>('0'));
156     BOOST_CHECK_THROW(lexical_cast<int>('A'), bad_lexical_cast);
157     BOOST_CHECK_EQUAL(1, lexical_cast<int>(1));
158     BOOST_CHECK_EQUAL(1, lexical_cast<int>(1.0));
159
160     BOOST_CHECK_EQUAL(
161         (std::numeric_limits<int>::max)(),
162         lexical_cast<int>((std::numeric_limits<int>::max)()));
163
164     BOOST_CHECK_EQUAL(
165         (std::numeric_limits<int>::min)(),
166         lexical_cast<int>((std::numeric_limits<int>::min)()));
167
168     BOOST_CHECK_THROW(lexical_cast<int>(1.23), bad_lexical_cast);
169
170     BOOST_CHECK_THROW(lexical_cast<int>(1e20), bad_lexical_cast);
171     BOOST_CHECK_EQUAL(1, lexical_cast<int>(true));
172     BOOST_CHECK_EQUAL(0, lexical_cast<int>(false));
173     BOOST_CHECK_EQUAL(123, lexical_cast<int>("123"));
174     BOOST_CHECK_THROW(
175         lexical_cast<int>(" 123"), bad_lexical_cast);
176     BOOST_CHECK_THROW(lexical_cast<int>(""), bad_lexical_cast);
177     BOOST_CHECK_THROW(lexical_cast<int>("Test"), bad_lexical_cast);
178     BOOST_CHECK_EQUAL(123, lexical_cast<int>("123"));
179     BOOST_CHECK_EQUAL(123, lexical_cast<int>(std::string("123")));
180     BOOST_CHECK_THROW(
181         lexical_cast<int>(std::string(" 123")), bad_lexical_cast);
182     BOOST_CHECK_THROW(
183         lexical_cast<int>(std::string("")), bad_lexical_cast);
184     BOOST_CHECK_THROW(
185         lexical_cast<int>(std::string("Test")), bad_lexical_cast);
186 }
187
188 void test_conversion_with_nonconst_char()
189 {
190     std::vector<char> buffer;
191     buffer.push_back('1');
192     buffer.push_back('\0');
193     BOOST_CHECK_EQUAL(boost::lexical_cast<int>(&buffer[0]), 1);
194
195     std::vector<unsigned char> buffer2;
196     buffer2.push_back('1');
197     buffer2.push_back('\0');
198     BOOST_CHECK_EQUAL(boost::lexical_cast<int>(&buffer2[0]), 1);
199
200     std::vector<unsigned char> buffer3;
201     buffer3.push_back('1');
202     buffer3.push_back('\0');
203     BOOST_CHECK_EQUAL(boost::lexical_cast<int>(&buffer3[0]), 1);
204
205 #ifndef BOOST_LCAST_NO_WCHAR_T
206     std::vector<wchar_t> buffer4;
207     buffer4.push_back(L'1');
208     buffer4.push_back(L'\0');
209     BOOST_CHECK_EQUAL(boost::lexical_cast<int>(&buffer4[0]), 1);
210 #endif
211 }
212
213 void test_conversion_to_double()
214 {
215     BOOST_CHECK_CLOSE_FRACTION(1.0, lexical_cast<double>('1'), (std::numeric_limits<double>::epsilon()));
216     BOOST_CHECK_THROW(lexical_cast<double>('A'), bad_lexical_cast);
217     BOOST_CHECK_CLOSE_FRACTION(1.0, lexical_cast<double>(1), (std::numeric_limits<double>::epsilon()));
218     BOOST_CHECK_CLOSE_FRACTION(1.23, lexical_cast<double>(1.23), (std::numeric_limits<double>::epsilon()));
219     BOOST_CHECK_CLOSE_FRACTION(1.234567890, lexical_cast<double>(1.234567890), std::numeric_limits<double>::epsilon());
220     BOOST_CHECK_CLOSE_FRACTION(1.234567890, lexical_cast<double>("1.234567890"), std::numeric_limits<double>::epsilon());
221     BOOST_CHECK_CLOSE_FRACTION(1.0, lexical_cast<double>(true), (std::numeric_limits<double>::epsilon()));
222     BOOST_CHECK_CLOSE_FRACTION(0.0, lexical_cast<double>(false), (std::numeric_limits<double>::epsilon()));
223     BOOST_CHECK_CLOSE_FRACTION(1.23, lexical_cast<double>("1.23"), (std::numeric_limits<double>::epsilon()));
224     BOOST_CHECK_THROW(lexical_cast<double>(""), bad_lexical_cast);
225     BOOST_CHECK_THROW(lexical_cast<double>("Test"), bad_lexical_cast);
226     BOOST_CHECK_CLOSE_FRACTION(1.23, lexical_cast<double>(std::string("1.23")), (std::numeric_limits<double>::epsilon()));
227     BOOST_CHECK_THROW(
228         lexical_cast<double>(std::string("")), bad_lexical_cast);
229     BOOST_CHECK_THROW(
230         lexical_cast<double>(std::string("Test")), bad_lexical_cast);
231 }
232
233 void test_conversion_to_bool()
234 {
235     BOOST_CHECK_EQUAL(true, lexical_cast<bool>('1'));
236     BOOST_CHECK_EQUAL(false, lexical_cast<bool>('0'));
237     BOOST_CHECK_THROW(lexical_cast<bool>('A'), bad_lexical_cast);
238     BOOST_CHECK_EQUAL(true, lexical_cast<bool>(1));
239     BOOST_CHECK_EQUAL(false, lexical_cast<bool>(0));
240     BOOST_CHECK_THROW(lexical_cast<bool>(123), bad_lexical_cast);
241     BOOST_CHECK_EQUAL(true, lexical_cast<bool>(1.0));
242     BOOST_CHECK_EQUAL(false, lexical_cast<bool>(0.0));
243     BOOST_CHECK_EQUAL(true, lexical_cast<bool>(true));
244     BOOST_CHECK_EQUAL(false, lexical_cast<bool>(false));
245     BOOST_CHECK_EQUAL(true, lexical_cast<bool>("1"));
246     BOOST_CHECK_EQUAL(false, lexical_cast<bool>("0"));
247     BOOST_CHECK_THROW(lexical_cast<bool>(""), bad_lexical_cast);
248     BOOST_CHECK_THROW(lexical_cast<bool>("Test"), bad_lexical_cast);
249     BOOST_CHECK_EQUAL(true, lexical_cast<bool>("1"));
250     BOOST_CHECK_EQUAL(false, lexical_cast<bool>("0"));
251     BOOST_CHECK_EQUAL(true, lexical_cast<bool>(std::string("1")));
252     BOOST_CHECK_EQUAL(false, lexical_cast<bool>(std::string("0")));
253
254     BOOST_CHECK_THROW(lexical_cast<bool>(1.0001L), bad_lexical_cast);
255     BOOST_CHECK_THROW(lexical_cast<bool>(2), bad_lexical_cast);
256     BOOST_CHECK_THROW(lexical_cast<bool>(2u), bad_lexical_cast);
257     BOOST_CHECK_THROW(lexical_cast<bool>(-1), bad_lexical_cast);
258     BOOST_CHECK_THROW(lexical_cast<bool>(-2), bad_lexical_cast);
259
260
261     BOOST_CHECK_THROW(
262         lexical_cast<bool>(std::string("")), bad_lexical_cast);
263     BOOST_CHECK_THROW(
264         lexical_cast<bool>(std::string("Test")), bad_lexical_cast);
265
266     BOOST_CHECK(lexical_cast<bool>("+1") == true );
267     BOOST_CHECK(lexical_cast<bool>("+0") == false );
268     BOOST_CHECK(lexical_cast<bool>("-0") == false );
269     BOOST_CHECK_THROW(lexical_cast<bool>("--0"), bad_lexical_cast);
270     BOOST_CHECK_THROW(lexical_cast<bool>("-+-0"), bad_lexical_cast);
271 }
272
273 void test_conversion_to_string()
274 {
275     char buf[] = "hello";
276     char* str = buf;
277     BOOST_CHECK_EQUAL(str, lexical_cast<std::string>(str));
278     BOOST_CHECK_EQUAL("A", lexical_cast<std::string>('A'));
279     BOOST_CHECK_EQUAL(" ", lexical_cast<std::string>(' '));
280     BOOST_CHECK_EQUAL("123", lexical_cast<std::string>(123));
281     BOOST_CHECK_EQUAL("1.23", lexical_cast<std::string>(1.23));
282     BOOST_CHECK_EQUAL("1.111111111", lexical_cast<std::string>(1.111111111));
283     BOOST_CHECK_EQUAL("1", lexical_cast<std::string>(true));
284     BOOST_CHECK_EQUAL("0", lexical_cast<std::string>(false));
285     BOOST_CHECK_EQUAL("Test", lexical_cast<std::string>("Test"));
286     BOOST_CHECK_EQUAL(" ", lexical_cast<std::string>(" "));
287     BOOST_CHECK_EQUAL("", lexical_cast<std::string>(""));
288     BOOST_CHECK_EQUAL("Test", lexical_cast<std::string>(std::string("Test")));
289     BOOST_CHECK_EQUAL(" ", lexical_cast<std::string>(std::string(" ")));
290     BOOST_CHECK_EQUAL("", lexical_cast<std::string>(std::string("")));
291 }
292
293 void test_conversion_from_to_wchar_t_alias()
294 {
295     BOOST_CHECK_EQUAL(123u, lexical_cast<unsigned short>("123"));
296     BOOST_CHECK_EQUAL(123u, lexical_cast<unsigned int>("123"));
297     BOOST_CHECK_EQUAL(123u, lexical_cast<unsigned long>("123"));
298     BOOST_CHECK_EQUAL(std::string("123"),
299         lexical_cast<std::string>(static_cast<unsigned short>(123)));
300     BOOST_CHECK_EQUAL(std::string("123"), lexical_cast<std::string>(123u));
301     BOOST_CHECK_EQUAL(std::string("123"), lexical_cast<std::string>(123ul));
302 }
303
304 void test_conversion_to_pointer()
305 {
306     BOOST_CHECK_THROW(lexical_cast<char *>("Test"), bad_lexical_cast);
307 #ifndef BOOST_LCAST_NO_WCHAR_T
308     BOOST_CHECK_THROW(lexical_cast<wchar_t *>("Test"), bad_lexical_cast);
309 #endif
310 }
311
312 void test_conversion_from_wchar_t()
313 {
314 #ifndef BOOST_LCAST_NO_WCHAR_T
315 #if !defined(BOOST_NO_INTRINSIC_WCHAR_T)
316     BOOST_CHECK_EQUAL(1, lexical_cast<int>(L'1'));
317     BOOST_CHECK_THROW(lexical_cast<int>(L'A'), bad_lexical_cast);
318 #endif
319
320     BOOST_CHECK_EQUAL(123, lexical_cast<int>(L"123"));
321     BOOST_CHECK_THROW(lexical_cast<int>(L""), bad_lexical_cast);
322     BOOST_CHECK_THROW(lexical_cast<int>(L"Test"), bad_lexical_cast);
323
324 #if !defined(BOOST_NO_INTRINSIC_WCHAR_T)
325     BOOST_CHECK_EQUAL(1.0, lexical_cast<double>(L'1'));
326     BOOST_CHECK_THROW(lexical_cast<double>(L'A'), bad_lexical_cast);
327 #endif
328
329     BOOST_CHECK_EQUAL(1.23, lexical_cast<double>(L"1.23"));
330     BOOST_CHECK_THROW(lexical_cast<double>(L""), bad_lexical_cast);
331     BOOST_CHECK_THROW(lexical_cast<double>(L"Test"), bad_lexical_cast);
332
333 #if !defined(BOOST_NO_INTRINSIC_WCHAR_T)
334     BOOST_CHECK_EQUAL(true, lexical_cast<bool>(L'1'));
335     BOOST_CHECK_EQUAL(false, lexical_cast<bool>(L'0'));
336     BOOST_CHECK_THROW(lexical_cast<bool>(L'A'), bad_lexical_cast);
337 #endif
338     BOOST_CHECK_EQUAL(true, lexical_cast<bool>(L"1"));
339     BOOST_CHECK_EQUAL(false, lexical_cast<bool>(L"0"));
340     BOOST_CHECK_THROW(lexical_cast<bool>(L""), bad_lexical_cast);
341     BOOST_CHECK_THROW(lexical_cast<bool>(L"Test"), bad_lexical_cast);
342 #endif
343 }
344
345 void test_conversion_to_wchar_t()
346 {
347 #if !defined(BOOST_LCAST_NO_WCHAR_T) && !defined(BOOST_NO_INTRINSIC_WCHAR_T)
348     BOOST_CHECK_EQUAL(L'1', lexical_cast<wchar_t>(1));
349     BOOST_CHECK_EQUAL(L'0', lexical_cast<wchar_t>(0));
350     BOOST_CHECK_EQUAL(L'1', lexical_cast<wchar_t>('1'));
351     BOOST_CHECK_EQUAL(L'0', lexical_cast<wchar_t>('0'));
352     BOOST_CHECK_THROW(lexical_cast<wchar_t>(123), bad_lexical_cast);
353     BOOST_CHECK_EQUAL(L'1', lexical_cast<wchar_t>(1.0));
354     BOOST_CHECK_EQUAL(L'0', lexical_cast<wchar_t>(0.0));
355     BOOST_CHECK_EQUAL(L'1', lexical_cast<wchar_t>(true));
356     BOOST_CHECK_EQUAL(L'0', lexical_cast<wchar_t>(false));
357     BOOST_CHECK_EQUAL(L'A', lexical_cast<wchar_t>(L'A'));
358     BOOST_CHECK_EQUAL(L' ', lexical_cast<wchar_t>(L' '));
359     BOOST_CHECK_EQUAL(L'A', lexical_cast<wchar_t>(L"A"));
360     BOOST_CHECK_EQUAL(L' ', lexical_cast<wchar_t>(L" "));
361     BOOST_CHECK_THROW(lexical_cast<wchar_t>(L""), bad_lexical_cast);
362     BOOST_CHECK_THROW(lexical_cast<wchar_t>(L"Test"), bad_lexical_cast);
363     BOOST_CHECK_EQUAL(L'A', lexical_cast<wchar_t>(std::wstring(L"A")));
364     BOOST_CHECK_EQUAL(L' ', lexical_cast<wchar_t>(std::wstring(L" ")));
365     BOOST_CHECK_THROW(
366         lexical_cast<wchar_t>(std::wstring(L"")), bad_lexical_cast);
367     BOOST_CHECK_THROW(
368         lexical_cast<wchar_t>(std::wstring(L"Test")), bad_lexical_cast);
369 #endif
370     BOOST_CHECK(true);
371 }
372
373 void test_conversion_from_wstring()
374 {
375 #ifndef BOOST_LCAST_NO_WCHAR_T
376     BOOST_CHECK_EQUAL(123, lexical_cast<int>(std::wstring(L"123")));
377     BOOST_CHECK_THROW(
378         lexical_cast<int>(std::wstring(L"")), bad_lexical_cast);
379     BOOST_CHECK_THROW(
380         lexical_cast<int>(std::wstring(L"Test")), bad_lexical_cast);
381
382     BOOST_CHECK_EQUAL(true, lexical_cast<bool>(std::wstring(L"1")));
383     BOOST_CHECK_EQUAL(false, lexical_cast<bool>(std::wstring(L"0")));
384     BOOST_CHECK_THROW(
385         lexical_cast<bool>(std::wstring(L"")), bad_lexical_cast);
386     BOOST_CHECK_THROW(
387         lexical_cast<bool>(std::wstring(L"Test")), bad_lexical_cast);
388 #endif
389     BOOST_CHECK(true);
390 }
391
392 void test_conversion_to_wstring()
393 {
394 #ifndef BOOST_LCAST_NO_WCHAR_T
395     wchar_t buf[] = L"hello";
396     wchar_t* str = buf;
397     BOOST_CHECK(str == lexical_cast<std::wstring>(str));
398     BOOST_CHECK(L"123" == lexical_cast<std::wstring>(123));
399     BOOST_CHECK(L"1.23" == lexical_cast<std::wstring>(1.23));
400     BOOST_CHECK(L"1" == lexical_cast<std::wstring>(true));
401     BOOST_CHECK(L"0" == lexical_cast<std::wstring>(false));
402 #if !defined(BOOST_NO_INTRINSIC_WCHAR_T)
403     BOOST_CHECK(L"A" == lexical_cast<std::wstring>(L'A'));
404     BOOST_CHECK(L" " == lexical_cast<std::wstring>(L' '));
405     BOOST_CHECK(L"A" == lexical_cast<std::wstring>('A'));
406 #endif
407     BOOST_CHECK(L"Test" == lexical_cast<std::wstring>(L"Test"));
408     BOOST_CHECK(L" " == lexical_cast<std::wstring>(L" "));
409     BOOST_CHECK(L"" == lexical_cast<std::wstring>(L""));
410     BOOST_CHECK(L"Test" == lexical_cast<std::wstring>(std::wstring(L"Test")));
411     BOOST_CHECK(L" " == lexical_cast<std::wstring>(std::wstring(L" ")));
412     BOOST_CHECK(L"" == lexical_cast<std::wstring>(std::wstring(L"")));
413 #endif
414     BOOST_CHECK(true);
415 }
416
417 void test_bad_lexical_cast()
418 {
419     try
420     {
421         lexical_cast<int>(std::string("Test"));
422
423         BOOST_CHECK(false); // Exception expected
424     }
425     catch(const bad_lexical_cast &e)
426     {
427         BOOST_CHECK(e.source_type() == typeid(std::string));
428         BOOST_CHECK(e.target_type() == typeid(int));
429     }
430 }
431
432 void test_no_whitespace_stripping()
433 {
434     BOOST_CHECK_THROW(lexical_cast<int>(" 123"), bad_lexical_cast);
435     BOOST_CHECK_THROW(lexical_cast<int>("123 "), bad_lexical_cast);
436 }
437
438
439 #ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
440 void test_traits()
441 {
442     typedef std::basic_string<char, my_traits<char> > my_string;
443
444     my_string const s("s");
445     BOOST_CHECK(boost::lexical_cast<char>(s) == s[0]);
446     BOOST_CHECK(boost::lexical_cast<my_string>(s) == s);
447     BOOST_CHECK(boost::lexical_cast<my_string>(-1) == "-1");
448 }
449
450 void test_wtraits()
451 {
452     typedef std::basic_string<wchar_t, my_traits<wchar_t> > my_string;
453
454     my_string const s(L"s");
455     BOOST_CHECK(boost::lexical_cast<wchar_t>(s) == s[0]);
456     BOOST_CHECK(boost::lexical_cast<my_string>(s) == s);
457     //BOOST_CHECK(boost::lexical_cast<my_string>(-1) == L"-1");
458     // Commented out because gcc 3.3 doesn't support this:
459     // basic_ostream<wchar_t, my_traits<wchar_t> > o; o << -1;
460 }
461
462 void test_allocator()
463 {
464     typedef std::basic_string< char
465                              , std::char_traits<char>
466                              , my_allocator<char>
467                              > my_string;
468
469     my_string s("s");
470     BOOST_CHECK(boost::lexical_cast<char>(s) == s[0]);
471     BOOST_CHECK(boost::lexical_cast<std::string>(s) == "s");
472     BOOST_CHECK(boost::lexical_cast<my_string>(s) == s);
473     BOOST_CHECK(boost::lexical_cast<my_string>(1) == "1");
474     BOOST_CHECK(boost::lexical_cast<my_string>("s") == s);
475     BOOST_CHECK(boost::lexical_cast<my_string>(std::string("s")) == s);
476 }
477
478 void test_wallocator()
479 {
480     typedef std::basic_string< wchar_t
481                              , std::char_traits<wchar_t>
482                              , my_allocator<wchar_t>
483                              > my_string;
484
485     my_string s(L"s");
486     BOOST_CHECK(boost::lexical_cast<wchar_t>(s) == s[0]);
487     BOOST_CHECK(boost::lexical_cast<std::wstring>(s) == L"s");
488     BOOST_CHECK(boost::lexical_cast<my_string>(s) == s);
489     BOOST_CHECK(boost::lexical_cast<my_string>(1) == L"1");
490     BOOST_CHECK(boost::lexical_cast<my_string>(L"s") == s);
491     BOOST_CHECK(boost::lexical_cast<my_string>(std::wstring(L"s")) == s);
492 }
493
494 #endif
495
496
497 void test_char_types_conversions()
498 {
499     const char c_arr[]            = "Test array of chars";
500     const unsigned char uc_arr[]  = "Test array of chars";
501     const signed char sc_arr[]    = "Test array of chars";
502
503     BOOST_CHECK(boost::lexical_cast<std::string>(c_arr) == std::string(c_arr));
504     BOOST_CHECK(boost::lexical_cast<std::string>(uc_arr) == std::string(c_arr));
505     BOOST_CHECK(boost::lexical_cast<std::string>(sc_arr) == std::string(c_arr));
506
507     BOOST_CHECK(boost::lexical_cast<char>(c_arr[0]) == c_arr[0]);
508     BOOST_CHECK(boost::lexical_cast<char>(uc_arr[0]) == c_arr[0]);
509     BOOST_CHECK(boost::lexical_cast<char>(sc_arr[0]) == c_arr[0]);
510
511     BOOST_CHECK(boost::lexical_cast<unsigned char>(c_arr[0]) == uc_arr[0]);
512     BOOST_CHECK(boost::lexical_cast<unsigned char>(uc_arr[0]) == uc_arr[0]);
513     BOOST_CHECK(boost::lexical_cast<unsigned char>(sc_arr[0]) == uc_arr[0]);
514
515     BOOST_CHECK(boost::lexical_cast<signed char>(c_arr[0]) == sc_arr[0]);
516     BOOST_CHECK(boost::lexical_cast<signed char>(uc_arr[0]) == sc_arr[0]);
517     BOOST_CHECK(boost::lexical_cast<signed char>(sc_arr[0]) == sc_arr[0]);
518
519 #ifndef BOOST_LCAST_NO_WCHAR_T
520     const wchar_t wc_arr[]=L"Test array of chars";
521
522     BOOST_CHECK(boost::lexical_cast<std::wstring>(wc_arr) == std::wstring(wc_arr));
523     BOOST_CHECK(boost::lexical_cast<wchar_t>(wc_arr[0]) == wc_arr[0]);
524
525 #endif
526 }
527
528
529
530 struct foo_operators_test
531 {
532   foo_operators_test() : f(2) {}
533   int f;
534 };
535
536 template <typename OStream>
537 OStream& operator<<(OStream& ostr, const foo_operators_test& foo)
538 {
539   ostr << foo.f;
540   return ostr;
541 }
542
543 template <typename IStream>
544 IStream& operator>>(IStream& istr, foo_operators_test& foo)
545 {
546   istr >> foo.f;
547   return istr;
548 }
549
550 void operators_overload_test()
551 {
552     foo_operators_test foo;
553     BOOST_CHECK_EQUAL(boost::lexical_cast<std::string>(foo), "2");
554     BOOST_CHECK_EQUAL((boost::lexical_cast<foo_operators_test>("2")).f, 2);
555
556     // Must compile
557     (void)boost::lexical_cast<foo_operators_test>(foo);
558 }
559
560
561 #if !defined(BOOST_NO_CHAR16_T) && !defined(BOOST_NO_UNICODE_LITERALS)
562 void test_char16_conversions()
563 {
564     BOOST_CHECK(u"100" == lexical_cast<std::u16string>(u"100"));
565     BOOST_CHECK(u"1" == lexical_cast<std::u16string>(u'1'));
566 }
567 #endif
568
569 #if !defined(BOOST_NO_CHAR16_T) && !defined(BOOST_NO_UNICODE_LITERALS)
570 void test_char32_conversions()
571 {
572     BOOST_CHECK(U"100" == lexical_cast<std::u32string>(U"100"));
573     BOOST_CHECK(U"1" == lexical_cast<std::u32string>(U'1'));
574 }
575 #endif
576
577