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

source code of boost/libs/lexical_cast/test/lexical_cast_test.cpp