change support python version
[platform/upstream/boost.git] / libs / lexical_cast / test / 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-2019.
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 <algorithm> // std::transform
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 template<class CharT>
52 struct my_traits : std::char_traits<CharT>
53 {
54 };
55
56 template<class CharT>
57 struct my_allocator : std::allocator<CharT>
58 {
59     typedef std::allocator<CharT> base_t;
60
61     my_allocator(){}
62     template <class U> my_allocator(const my_allocator<U>& v) : base_t(v) {}
63
64     template <class U> struct rebind { typedef my_allocator<U> other; };
65 };
66
67 using namespace boost;
68
69 void test_conversion_to_char();
70 void test_conversion_to_int();
71 void test_conversion_to_double();
72 void test_conversion_to_bool();
73 void test_conversion_with_nonconst_char();
74 void test_conversion_to_string();
75 void test_conversion_from_to_wchar_t_alias();
76 void test_conversion_from_wchar_t();
77 void test_conversion_to_wchar_t();
78 void test_conversion_from_wstring();
79 void test_conversion_to_wstring();
80 void test_bad_lexical_cast();
81 void test_no_whitespace_stripping();
82 void test_volatile_types_conversions();
83 #ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
84 void test_traits();
85 void test_wtraits();
86 void test_allocator();
87 void test_wallocator();
88 #endif
89 void test_char_types_conversions();
90 void operators_overload_test();
91 #if !defined(BOOST_NO_CXX11_CHAR16_T) && !defined(BOOST_NO_CXX11_UNICODE_LITERALS)
92 void test_char16_conversions();
93 #endif
94 #if !defined(BOOST_NO_CXX11_CHAR32_T) && !defined(BOOST_NO_CXX11_UNICODE_LITERALS)
95 void test_char32_conversions();
96 #endif
97 void test_getting_pointer_to_function();
98
99 unit_test::test_suite *init_unit_test_suite(int, char *[])
100 {
101     unit_test::test_suite *suite =
102         BOOST_TEST_SUITE("lexical_cast unit test");
103     suite->add(BOOST_TEST_CASE(test_conversion_to_char));
104     suite->add(BOOST_TEST_CASE(test_conversion_to_int));
105     suite->add(BOOST_TEST_CASE(test_conversion_to_double));
106     suite->add(BOOST_TEST_CASE(test_conversion_to_bool));
107     suite->add(BOOST_TEST_CASE(test_conversion_from_to_wchar_t_alias));
108     suite->add(BOOST_TEST_CASE(test_conversion_to_string));
109     suite->add(BOOST_TEST_CASE(test_conversion_with_nonconst_char));
110 #ifndef BOOST_LCAST_NO_WCHAR_T
111     suite->add(BOOST_TEST_CASE(test_conversion_from_wchar_t));
112     suite->add(BOOST_TEST_CASE(test_conversion_to_wchar_t));
113     suite->add(BOOST_TEST_CASE(test_conversion_from_wstring));
114     suite->add(BOOST_TEST_CASE(test_conversion_to_wstring));
115 #endif
116     suite->add(BOOST_TEST_CASE(test_bad_lexical_cast));
117     suite->add(BOOST_TEST_CASE(test_no_whitespace_stripping));
118     suite->add(BOOST_TEST_CASE(test_volatile_types_conversions));
119 #ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
120     suite->add(BOOST_TEST_CASE(&test_traits));
121     suite->add(BOOST_TEST_CASE(&test_wtraits));
122     suite->add(BOOST_TEST_CASE(&test_allocator));
123     suite->add(BOOST_TEST_CASE(&test_wallocator));
124 #endif
125
126     suite->add(BOOST_TEST_CASE(&test_char_types_conversions));
127     suite->add(BOOST_TEST_CASE(&operators_overload_test));
128 #if !defined(BOOST_NO_CXX11_CHAR16_T) && !defined(BOOST_NO_CXX11_UNICODE_LITERALS)
129     suite->add(BOOST_TEST_CASE(&test_char16_conversions));
130 #endif
131 #if !defined(BOOST_NO_CXX11_CHAR32_T) && !defined(BOOST_NO_CXX11_UNICODE_LITERALS)
132     suite->add(BOOST_TEST_CASE(&test_char32_conversions));
133 #endif
134     suite->add(BOOST_TEST_CASE(&test_getting_pointer_to_function));
135
136     return suite;
137 }
138
139 void test_conversion_to_char()
140 {
141     BOOST_CHECK_EQUAL('A', lexical_cast<char>('A'));
142     BOOST_CHECK_EQUAL(' ', lexical_cast<char>(' '));
143     BOOST_CHECK_EQUAL('1', lexical_cast<char>(1));
144     BOOST_CHECK_EQUAL('0', lexical_cast<char>(0));
145     BOOST_CHECK_THROW(lexical_cast<char>(123), bad_lexical_cast);
146     BOOST_CHECK_EQUAL('1', lexical_cast<char>(1.0));
147     BOOST_CHECK_EQUAL('1', lexical_cast<char>(true));
148     BOOST_CHECK_EQUAL('0', lexical_cast<char>(false));
149     BOOST_CHECK_EQUAL('A', lexical_cast<char>("A"));
150     BOOST_CHECK_EQUAL(' ', lexical_cast<char>(" "));
151     BOOST_CHECK_THROW(lexical_cast<char>(""), bad_lexical_cast);
152     BOOST_CHECK_THROW(lexical_cast<char>("Test"), bad_lexical_cast);
153     BOOST_CHECK_EQUAL('A', lexical_cast<char>(std::string("A")));
154     BOOST_CHECK_EQUAL(' ', lexical_cast<char>(std::string(" ")));
155     BOOST_CHECK_THROW(
156         lexical_cast<char>(std::string("")), bad_lexical_cast);
157     BOOST_CHECK_THROW(
158         lexical_cast<char>(std::string("Test")), bad_lexical_cast);
159 }
160
161 void test_conversion_to_int()
162 {
163     BOOST_CHECK_EQUAL(1, lexical_cast<int>('1'));
164     BOOST_CHECK_EQUAL(0, lexical_cast<int>('0'));
165     BOOST_CHECK_THROW(lexical_cast<int>('A'), bad_lexical_cast);
166     BOOST_CHECK_EQUAL(1, lexical_cast<int>(1));
167     BOOST_CHECK_EQUAL(1, lexical_cast<int>(1.0));
168
169     BOOST_CHECK_EQUAL(
170         (std::numeric_limits<int>::max)(),
171         lexical_cast<int>((std::numeric_limits<int>::max)()));
172
173     BOOST_CHECK_EQUAL(
174         (std::numeric_limits<int>::min)(),
175         lexical_cast<int>((std::numeric_limits<int>::min)()));
176
177     BOOST_CHECK_THROW(lexical_cast<int>(1.23), bad_lexical_cast);
178
179     BOOST_CHECK_THROW(lexical_cast<int>(1e20), bad_lexical_cast);
180     BOOST_CHECK_EQUAL(1, lexical_cast<int>(true));
181     BOOST_CHECK_EQUAL(0, lexical_cast<int>(false));
182     BOOST_CHECK_EQUAL(123, lexical_cast<int>("123"));
183     BOOST_CHECK_THROW(
184         lexical_cast<int>(" 123"), bad_lexical_cast);
185     BOOST_CHECK_THROW(lexical_cast<int>(""), bad_lexical_cast);
186     BOOST_CHECK_THROW(lexical_cast<int>("Test"), bad_lexical_cast);
187     BOOST_CHECK_EQUAL(123, lexical_cast<int>("123"));
188     BOOST_CHECK_EQUAL(123, lexical_cast<int>(std::string("123")));
189     BOOST_CHECK_THROW(
190         lexical_cast<int>(std::string(" 123")), bad_lexical_cast);
191     BOOST_CHECK_THROW(
192         lexical_cast<int>(std::string("")), bad_lexical_cast);
193     BOOST_CHECK_THROW(
194         lexical_cast<int>(std::string("Test")), bad_lexical_cast);
195 }
196
197 void test_conversion_with_nonconst_char()
198 {
199     std::vector<char> buffer;
200     buffer.push_back('1');
201     buffer.push_back('\0');
202     BOOST_CHECK_EQUAL(boost::lexical_cast<int>(&buffer[0]), 1);
203
204     std::vector<unsigned char> buffer2;
205     buffer2.push_back('1');
206     buffer2.push_back('\0');
207     BOOST_CHECK_EQUAL(boost::lexical_cast<int>(&buffer2[0]), 1);
208
209     std::vector<unsigned char> buffer3;
210     buffer3.push_back('1');
211     buffer3.push_back('\0');
212     BOOST_CHECK_EQUAL(boost::lexical_cast<int>(&buffer3[0]), 1);
213
214 #ifndef BOOST_LCAST_NO_WCHAR_T
215     std::vector<wchar_t> buffer4;
216     buffer4.push_back(L'1');
217     buffer4.push_back(L'\0');
218     BOOST_CHECK_EQUAL(boost::lexical_cast<int>(&buffer4[0]), 1);
219 #endif
220 }
221
222 void test_conversion_to_double()
223 {
224     BOOST_CHECK_CLOSE_FRACTION(1.0, lexical_cast<double>('1'), (std::numeric_limits<double>::epsilon()));
225     BOOST_CHECK_THROW(lexical_cast<double>('A'), bad_lexical_cast);
226     BOOST_CHECK_CLOSE_FRACTION(1.0, lexical_cast<double>(1), (std::numeric_limits<double>::epsilon()));
227     BOOST_CHECK_CLOSE_FRACTION(1.23, lexical_cast<double>(1.23), (std::numeric_limits<double>::epsilon()));
228     BOOST_CHECK_CLOSE_FRACTION(1.234567890, lexical_cast<double>(1.234567890), std::numeric_limits<double>::epsilon());
229     BOOST_CHECK_CLOSE_FRACTION(1.234567890, lexical_cast<double>("1.234567890"), std::numeric_limits<double>::epsilon());
230     BOOST_CHECK_CLOSE_FRACTION(1.0, lexical_cast<double>(true), (std::numeric_limits<double>::epsilon()));
231     BOOST_CHECK_CLOSE_FRACTION(0.0, lexical_cast<double>(false), (std::numeric_limits<double>::epsilon()));
232     BOOST_CHECK_CLOSE_FRACTION(1.23, lexical_cast<double>("1.23"), (std::numeric_limits<double>::epsilon()));
233     BOOST_CHECK_THROW(lexical_cast<double>(""), bad_lexical_cast);
234     BOOST_CHECK_THROW(lexical_cast<double>("Test"), bad_lexical_cast);
235     BOOST_CHECK_CLOSE_FRACTION(1.23, lexical_cast<double>(std::string("1.23")), (std::numeric_limits<double>::epsilon()));
236     BOOST_CHECK_THROW(
237         lexical_cast<double>(std::string("")), bad_lexical_cast);
238     BOOST_CHECK_THROW(
239         lexical_cast<double>(std::string("Test")), bad_lexical_cast);
240 }
241
242 void test_conversion_to_bool()
243 {
244     BOOST_CHECK_EQUAL(true, lexical_cast<bool>('1'));
245     BOOST_CHECK_EQUAL(false, lexical_cast<bool>('0'));
246     BOOST_CHECK_THROW(lexical_cast<bool>('A'), bad_lexical_cast);
247     BOOST_CHECK_EQUAL(true, lexical_cast<bool>(1));
248     BOOST_CHECK_EQUAL(false, lexical_cast<bool>(0));
249     BOOST_CHECK_THROW(lexical_cast<bool>(123), bad_lexical_cast);
250     BOOST_CHECK_EQUAL(true, lexical_cast<bool>(1.0));
251     BOOST_CHECK_THROW(lexical_cast<bool>(-123), bad_lexical_cast);
252     BOOST_CHECK_EQUAL(false, lexical_cast<bool>(0.0));
253     BOOST_CHECK_THROW(lexical_cast<bool>(1234), bad_lexical_cast);
254 #if !defined(_CRAYC)
255     // Looks like a bug in CRAY compiler (throws bad_lexical_cast)
256     // TODO: localize the bug and report it to developers.
257     BOOST_CHECK_EQUAL(true, lexical_cast<bool>(true));
258     BOOST_CHECK_EQUAL(false, lexical_cast<bool>(false));
259 #endif
260     BOOST_CHECK_EQUAL(true, lexical_cast<bool>("1"));
261     BOOST_CHECK_EQUAL(false, lexical_cast<bool>("0"));
262     BOOST_CHECK_THROW(lexical_cast<bool>(""), bad_lexical_cast);
263     BOOST_CHECK_THROW(lexical_cast<bool>("Test"), bad_lexical_cast);
264     BOOST_CHECK_EQUAL(true, lexical_cast<bool>("1"));
265     BOOST_CHECK_EQUAL(false, lexical_cast<bool>("0"));
266     BOOST_CHECK_EQUAL(true, lexical_cast<bool>(std::string("1")));
267     BOOST_CHECK_EQUAL(false, lexical_cast<bool>(std::string("0")));
268
269     BOOST_CHECK_THROW(lexical_cast<bool>(1.0001L), bad_lexical_cast);
270     BOOST_CHECK_THROW(lexical_cast<bool>(2), bad_lexical_cast);
271     BOOST_CHECK_THROW(lexical_cast<bool>(2u), bad_lexical_cast);
272     BOOST_CHECK_THROW(lexical_cast<bool>(-1), bad_lexical_cast);
273     BOOST_CHECK_THROW(lexical_cast<bool>(-2), bad_lexical_cast);
274
275
276     BOOST_CHECK_THROW(
277         lexical_cast<bool>(std::string("")), bad_lexical_cast);
278     BOOST_CHECK_THROW(
279         lexical_cast<bool>(std::string("Test")), bad_lexical_cast);
280
281     BOOST_CHECK(lexical_cast<bool>("+1") == true);
282     BOOST_CHECK(lexical_cast<bool>("+0") == false);
283     BOOST_CHECK(lexical_cast<bool>("-0") == false);
284     BOOST_CHECK_THROW(lexical_cast<bool>("--0"), bad_lexical_cast);
285     BOOST_CHECK_THROW(lexical_cast<bool>("-+-0"), bad_lexical_cast);
286
287     BOOST_CHECK(lexical_cast<bool>("0") == false);
288     BOOST_CHECK(lexical_cast<bool>("1") == true);
289     BOOST_CHECK(lexical_cast<bool>("00") == false);
290     BOOST_CHECK(lexical_cast<bool>("00000000000") == false);
291     BOOST_CHECK(lexical_cast<bool>("000000000001") == true);
292     BOOST_CHECK(lexical_cast<bool>("+00") == false );
293     BOOST_CHECK(lexical_cast<bool>("-00") == false );
294     BOOST_CHECK(lexical_cast<bool>("+00000000001") == true );
295
296     BOOST_CHECK_THROW(lexical_cast<bool>("020"), bad_lexical_cast);
297     BOOST_CHECK_THROW(lexical_cast<bool>("00200"), bad_lexical_cast);
298     BOOST_CHECK_THROW(lexical_cast<bool>("-00200"), bad_lexical_cast);
299     BOOST_CHECK_THROW(lexical_cast<bool>("+00200"), bad_lexical_cast);
300     BOOST_CHECK_THROW(lexical_cast<bool>("000000000002"), bad_lexical_cast);
301     BOOST_CHECK_THROW(lexical_cast<bool>("-1"), bad_lexical_cast);
302     BOOST_CHECK_THROW(lexical_cast<bool>("-0000000001"), bad_lexical_cast);
303     BOOST_CHECK_THROW(lexical_cast<bool>("00000000011"), bad_lexical_cast);
304     BOOST_CHECK_THROW(lexical_cast<bool>("001001"), bad_lexical_cast);
305     BOOST_CHECK_THROW(lexical_cast<bool>("-00000000010"), bad_lexical_cast);
306     BOOST_CHECK_THROW(lexical_cast<bool>("-000000000100"), bad_lexical_cast);
307 }
308
309 void test_conversion_to_string()
310 {
311     char buf[] = "hello";
312     char* str = buf;
313     BOOST_CHECK_EQUAL(str, lexical_cast<std::string>(str));
314     BOOST_CHECK_EQUAL("A", lexical_cast<std::string>('A'));
315     BOOST_CHECK_EQUAL(" ", lexical_cast<std::string>(' '));
316     BOOST_CHECK_EQUAL("123", lexical_cast<std::string>(123));
317     BOOST_CHECK_EQUAL("1.23", lexical_cast<std::string>(1.23));
318     BOOST_CHECK_EQUAL("1.111111111", lexical_cast<std::string>(1.111111111));
319     BOOST_CHECK_EQUAL("1", lexical_cast<std::string>(true));
320     BOOST_CHECK_EQUAL("0", lexical_cast<std::string>(false));
321     BOOST_CHECK_EQUAL("Test", lexical_cast<std::string>("Test"));
322     BOOST_CHECK_EQUAL(" ", lexical_cast<std::string>(" "));
323     BOOST_CHECK_EQUAL("", lexical_cast<std::string>(""));
324     BOOST_CHECK_EQUAL("Test", lexical_cast<std::string>(std::string("Test")));
325     BOOST_CHECK_EQUAL(" ", lexical_cast<std::string>(std::string(" ")));
326     BOOST_CHECK_EQUAL("", lexical_cast<std::string>(std::string("")));
327 }
328
329 void test_conversion_from_to_wchar_t_alias()
330 {
331     BOOST_CHECK_EQUAL(123u, lexical_cast<unsigned short>("123"));
332     BOOST_CHECK_EQUAL(123u, lexical_cast<unsigned int>("123"));
333     BOOST_CHECK_EQUAL(123u, lexical_cast<unsigned long>("123"));
334     BOOST_CHECK_EQUAL(std::string("123"),
335         lexical_cast<std::string>(static_cast<unsigned short>(123)));
336     BOOST_CHECK_EQUAL(std::string("123"), lexical_cast<std::string>(123u));
337     BOOST_CHECK_EQUAL(std::string("123"), lexical_cast<std::string>(123ul));
338 }
339
340 void test_conversion_from_wchar_t()
341 {
342 #ifndef BOOST_LCAST_NO_WCHAR_T
343 #if !defined(BOOST_NO_INTRINSIC_WCHAR_T)
344     BOOST_CHECK_EQUAL(1, lexical_cast<int>(L'1'));
345     BOOST_CHECK_THROW(lexical_cast<int>(L'A'), bad_lexical_cast);
346 #endif
347
348     BOOST_CHECK_EQUAL(123, lexical_cast<int>(L"123"));
349     BOOST_CHECK_THROW(lexical_cast<int>(L""), bad_lexical_cast);
350     BOOST_CHECK_THROW(lexical_cast<int>(L"Test"), bad_lexical_cast);
351
352 #if !defined(BOOST_NO_INTRINSIC_WCHAR_T)
353     BOOST_CHECK_EQUAL(1.0, lexical_cast<double>(L'1'));
354     BOOST_CHECK_THROW(lexical_cast<double>(L'A'), bad_lexical_cast);
355 #endif
356
357     BOOST_CHECK_EQUAL(1.23, lexical_cast<double>(L"1.23"));
358     BOOST_CHECK_THROW(lexical_cast<double>(L""), bad_lexical_cast);
359     BOOST_CHECK_THROW(lexical_cast<double>(L"Test"), bad_lexical_cast);
360
361 #if !defined(BOOST_NO_INTRINSIC_WCHAR_T)
362     BOOST_CHECK_EQUAL(true, lexical_cast<bool>(L'1'));
363     BOOST_CHECK_EQUAL(false, lexical_cast<bool>(L'0'));
364     BOOST_CHECK_THROW(lexical_cast<bool>(L'A'), bad_lexical_cast);
365 #endif
366     BOOST_CHECK_EQUAL(true, lexical_cast<bool>(L"1"));
367     BOOST_CHECK_EQUAL(false, lexical_cast<bool>(L"0"));
368     BOOST_CHECK_THROW(lexical_cast<bool>(L""), bad_lexical_cast);
369     BOOST_CHECK_THROW(lexical_cast<bool>(L"Test"), bad_lexical_cast);
370 #endif
371 }
372
373 void test_conversion_to_wchar_t()
374 {
375 #if !defined(BOOST_LCAST_NO_WCHAR_T) && !defined(BOOST_NO_INTRINSIC_WCHAR_T)
376     BOOST_CHECK_EQUAL(L'1', lexical_cast<wchar_t>(1));
377     BOOST_CHECK_EQUAL(L'0', lexical_cast<wchar_t>(0));
378     BOOST_CHECK_EQUAL(L'1', lexical_cast<wchar_t>('1'));
379     BOOST_CHECK_EQUAL(L'0', lexical_cast<wchar_t>('0'));
380     BOOST_CHECK_THROW(lexical_cast<wchar_t>(123), bad_lexical_cast);
381     BOOST_CHECK_EQUAL(L'1', lexical_cast<wchar_t>(1.0));
382     BOOST_CHECK_EQUAL(L'0', lexical_cast<wchar_t>(0.0));
383     BOOST_CHECK_EQUAL(L'1', lexical_cast<wchar_t>(true));
384     BOOST_CHECK_EQUAL(L'0', lexical_cast<wchar_t>(false));
385     BOOST_CHECK_EQUAL(L'A', lexical_cast<wchar_t>(L'A'));
386     BOOST_CHECK_EQUAL(L' ', lexical_cast<wchar_t>(L' '));
387     BOOST_CHECK_EQUAL(L'A', lexical_cast<wchar_t>(L"A"));
388     BOOST_CHECK_EQUAL(L' ', lexical_cast<wchar_t>(L" "));
389     BOOST_CHECK_THROW(lexical_cast<wchar_t>(L""), bad_lexical_cast);
390     BOOST_CHECK_THROW(lexical_cast<wchar_t>(L"Test"), bad_lexical_cast);
391     BOOST_CHECK_EQUAL(L'A', lexical_cast<wchar_t>(std::wstring(L"A")));
392     BOOST_CHECK_EQUAL(L' ', lexical_cast<wchar_t>(std::wstring(L" ")));
393     BOOST_CHECK_THROW(
394         lexical_cast<wchar_t>(std::wstring(L"")), bad_lexical_cast);
395     BOOST_CHECK_THROW(
396         lexical_cast<wchar_t>(std::wstring(L"Test")), bad_lexical_cast);
397 #endif
398     BOOST_CHECK(true);
399 }
400
401 void test_conversion_from_wstring()
402 {
403 #ifndef BOOST_LCAST_NO_WCHAR_T
404     BOOST_CHECK_EQUAL(123, lexical_cast<int>(std::wstring(L"123")));
405     BOOST_CHECK_THROW(
406         lexical_cast<int>(std::wstring(L"")), bad_lexical_cast);
407     BOOST_CHECK_THROW(
408         lexical_cast<int>(std::wstring(L"Test")), bad_lexical_cast);
409
410     BOOST_CHECK_EQUAL(true, lexical_cast<bool>(std::wstring(L"1")));
411     BOOST_CHECK_EQUAL(false, lexical_cast<bool>(std::wstring(L"0")));
412     BOOST_CHECK_THROW(
413         lexical_cast<bool>(std::wstring(L"")), bad_lexical_cast);
414     BOOST_CHECK_THROW(
415         lexical_cast<bool>(std::wstring(L"Test")), bad_lexical_cast);
416 #endif
417     BOOST_CHECK(true);
418 }
419
420 void test_conversion_to_wstring()
421 {
422 #ifndef BOOST_LCAST_NO_WCHAR_T
423     wchar_t buf[] = L"hello";
424     wchar_t* str = buf;
425     BOOST_CHECK(str == lexical_cast<std::wstring>(str));
426     BOOST_CHECK(L"123" == lexical_cast<std::wstring>(123));
427     BOOST_CHECK(L"1.23" == lexical_cast<std::wstring>(1.23));
428     BOOST_CHECK(L"1" == lexical_cast<std::wstring>(true));
429     BOOST_CHECK(L"0" == lexical_cast<std::wstring>(false));
430 #if !defined(BOOST_NO_INTRINSIC_WCHAR_T)
431     BOOST_CHECK(L"A" == lexical_cast<std::wstring>(L'A'));
432     BOOST_CHECK(L" " == lexical_cast<std::wstring>(L' '));
433     BOOST_CHECK(L"A" == lexical_cast<std::wstring>('A'));
434 #endif
435     BOOST_CHECK(L"Test" == lexical_cast<std::wstring>(L"Test"));
436     BOOST_CHECK(L" " == lexical_cast<std::wstring>(L" "));
437     BOOST_CHECK(L"" == lexical_cast<std::wstring>(L""));
438     BOOST_CHECK(L"Test" == lexical_cast<std::wstring>(std::wstring(L"Test")));
439     BOOST_CHECK(L" " == lexical_cast<std::wstring>(std::wstring(L" ")));
440     BOOST_CHECK(L"" == lexical_cast<std::wstring>(std::wstring(L"")));
441 #endif
442     BOOST_CHECK(true);
443 }
444
445 void test_bad_lexical_cast()
446 {
447     try
448     {
449         lexical_cast<int>(std::string("Test"));
450
451         BOOST_CHECK(false); // Exception expected
452     }
453     catch(const bad_lexical_cast &e)
454     {
455         BOOST_CHECK(e.source_type() == typeid(std::string));
456         BOOST_CHECK(e.target_type() == typeid(int));
457     }
458 }
459
460 void test_no_whitespace_stripping()
461 {
462     BOOST_CHECK_THROW(lexical_cast<int>(" 123"), bad_lexical_cast);
463     BOOST_CHECK_THROW(lexical_cast<int>("123 "), bad_lexical_cast);
464 }
465
466 void test_volatile_types_conversions()
467 {
468     volatile int i1 = 100000;
469     BOOST_CHECK_EQUAL("100000", boost::lexical_cast<std::string>(i1));
470
471     volatile const int i2 = 100000;
472     BOOST_CHECK_EQUAL("100000", boost::lexical_cast<std::string>(i2));
473
474     volatile const long int i3 = 1000000;
475     BOOST_CHECK_EQUAL("1000000", boost::lexical_cast<std::string>(i3));
476 }
477
478 #ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
479 void test_traits()
480 {
481     typedef std::basic_string<char, my_traits<char> > my_string;
482
483     my_string const s("s");
484     BOOST_CHECK(boost::lexical_cast<char>(s) == s[0]);
485     BOOST_CHECK(boost::lexical_cast<my_string>(s) == s);
486     BOOST_CHECK(boost::lexical_cast<my_string>(-1) == "-1");
487 }
488
489 void test_wtraits()
490 {
491     typedef std::basic_string<wchar_t, my_traits<wchar_t> > my_string;
492
493     my_string const s(L"s");
494     BOOST_CHECK(boost::lexical_cast<wchar_t>(s) == s[0]);
495     BOOST_CHECK(boost::lexical_cast<my_string>(s) == s);
496     //BOOST_CHECK(boost::lexical_cast<my_string>(-1) == L"-1");
497     // Commented out because gcc 3.3 doesn't support this:
498     // basic_ostream<wchar_t, my_traits<wchar_t> > o; o << -1;
499 }
500
501 void test_allocator()
502 {
503 // Following test cause compilation error on MSVC2012:
504 // (Reason: cannot convert from 'std::_Wrap_alloc<_Alloc>' to 'const my_allocator<CharT>')
505 // 
506 // MSVC developer is notified about this issue
507 #if !defined(_MSC_VER) || (_MSC_VER < 1700)
508     typedef std::basic_string< char
509                              , std::char_traits<char>
510                              , my_allocator<char>
511                              > my_string;
512
513     my_string s("s");
514     BOOST_CHECK(boost::lexical_cast<char>(s) == s[0]);
515     BOOST_CHECK(boost::lexical_cast<std::string>(s) == "s");
516     BOOST_CHECK(boost::lexical_cast<my_string>(s) == s);
517     BOOST_CHECK(boost::lexical_cast<my_string>(1) == "1");
518     BOOST_CHECK(boost::lexical_cast<my_string>("s") == s);
519     BOOST_CHECK(boost::lexical_cast<my_string>(std::string("s")) == s);
520 #endif
521 }
522
523 void test_wallocator()
524 {
525 // Following test cause compilation error on MSVC2012:
526 // (Reason: cannot convert from 'std::_Wrap_alloc<_Alloc>' to 'const my_allocator<CharT>')
527 // 
528 // MSVC developer is notified about this issue
529 #if !defined(_MSC_VER) || (_MSC_VER < 1700)
530     typedef std::basic_string< wchar_t
531                              , std::char_traits<wchar_t>
532                              , my_allocator<wchar_t>
533                              > my_string;
534
535     my_string s(L"s");
536     BOOST_CHECK(boost::lexical_cast<wchar_t>(s) == s[0]);
537     BOOST_CHECK(boost::lexical_cast<std::wstring>(s) == L"s");
538     BOOST_CHECK(boost::lexical_cast<my_string>(s) == s);
539     BOOST_CHECK(boost::lexical_cast<my_string>(1) == L"1");
540     BOOST_CHECK(boost::lexical_cast<my_string>(L"s") == s);
541     BOOST_CHECK(boost::lexical_cast<my_string>(std::wstring(L"s")) == s);
542 #endif
543 }
544
545 #endif
546
547
548 void test_char_types_conversions()
549 {
550     const char c_arr[]            = "Test array of chars";
551     const unsigned char uc_arr[]  = "Test array of chars";
552     const signed char sc_arr[]    = "Test array of chars";
553
554     BOOST_CHECK(boost::lexical_cast<std::string>(c_arr) == std::string(c_arr));
555     BOOST_CHECK(boost::lexical_cast<std::string>(uc_arr) == std::string(c_arr));
556     BOOST_CHECK(boost::lexical_cast<std::string>(sc_arr) == std::string(c_arr));
557
558     BOOST_CHECK(boost::lexical_cast<char>(c_arr[0]) == c_arr[0]);
559     BOOST_CHECK(boost::lexical_cast<char>(uc_arr[0]) == c_arr[0]);
560     BOOST_CHECK(boost::lexical_cast<char>(sc_arr[0]) == c_arr[0]);
561
562     BOOST_CHECK(boost::lexical_cast<unsigned char>(c_arr[0]) == uc_arr[0]);
563     BOOST_CHECK(boost::lexical_cast<unsigned char>(uc_arr[0]) == uc_arr[0]);
564     BOOST_CHECK(boost::lexical_cast<unsigned char>(sc_arr[0]) == uc_arr[0]);
565
566     BOOST_CHECK(boost::lexical_cast<signed char>(c_arr[0]) == sc_arr[0]);
567     BOOST_CHECK(boost::lexical_cast<signed char>(uc_arr[0]) == sc_arr[0]);
568     BOOST_CHECK(boost::lexical_cast<signed char>(sc_arr[0]) == sc_arr[0]);
569
570 #ifndef BOOST_LCAST_NO_WCHAR_T
571     const wchar_t wc_arr[]=L"Test array of chars";
572
573     BOOST_CHECK(boost::lexical_cast<std::wstring>(wc_arr) == std::wstring(wc_arr));
574     BOOST_CHECK(boost::lexical_cast<wchar_t>(wc_arr[0]) == wc_arr[0]);
575
576 #endif
577 }
578
579
580
581 struct foo_operators_test
582 {
583   foo_operators_test() : f(2) {}
584   int f;
585 };
586
587 template <typename OStream>
588 OStream& operator<<(OStream& ostr, const foo_operators_test& foo)
589 {
590   ostr << foo.f;
591   return ostr;
592 }
593
594 template <typename IStream>
595 IStream& operator>>(IStream& istr, foo_operators_test& foo)
596 {
597   istr >> foo.f;
598   return istr;
599 }
600
601 void operators_overload_test()
602 {
603     foo_operators_test foo;
604     BOOST_CHECK_EQUAL(boost::lexical_cast<std::string>(foo), "2");
605     BOOST_CHECK_EQUAL((boost::lexical_cast<foo_operators_test>("2")).f, 2);
606
607     // Must compile
608     (void)boost::lexical_cast<foo_operators_test>(foo);
609 }
610
611
612 #if !defined(BOOST_NO_CXX11_CHAR16_T) && !defined(BOOST_NO_CXX11_UNICODE_LITERALS)
613 void test_char16_conversions()
614 {
615     BOOST_CHECK(u"100" == lexical_cast<std::u16string>(u"100"));
616     BOOST_CHECK(u"1" == lexical_cast<std::u16string>(u'1'));
617 }
618 #endif
619
620 #if !defined(BOOST_NO_CXX11_CHAR16_T) && !defined(BOOST_NO_CXX11_UNICODE_LITERALS)
621 void test_char32_conversions()
622 {
623     BOOST_CHECK(U"100" == lexical_cast<std::u32string>(U"100"));
624     BOOST_CHECK(U"1" == lexical_cast<std::u32string>(U'1'));
625 }
626 #endif
627
628 void test_getting_pointer_to_function()
629 {
630     // Just checking that &lexical_cast<To, From> is not ambiguous
631     typedef char char_arr[4];    
632     typedef int(*f1)(const char_arr&);
633     f1 p1 = &boost::lexical_cast<int, char_arr>;
634     BOOST_CHECK(p1);
635
636     typedef int(*f2)(const std::string&);
637     f2 p2 = &boost::lexical_cast<int, std::string>;
638     BOOST_CHECK(p2);
639
640     typedef std::string(*f3)(const int&);
641     f3 p3 = &boost::lexical_cast<std::string, int>;
642     BOOST_CHECK(p3);
643
644     std::vector<int> values;
645     std::vector<std::string> ret;
646     std::transform(values.begin(), values.end(), ret.begin(), boost::lexical_cast<std::string, int>);
647 }
648
649