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