• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 //  Testing boost::lexical_cast with boost::container::string.
2 //
3 //  See http://www.boost.org for most recent version, including documentation.
4 //
5 //  Copyright Antony Polukhin, 2012-2020.
6 //
7 //  Distributed under the Boost
8 //  Software License, Version 1.0. (See accompanying file
9 //  LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt).
10 
11 #include <boost/lexical_cast.hpp>
12 
13 #include <boost/test/unit_test.hpp>
14 
15 #include <boost/array.hpp>
16 
17 void testing_boost_array_output_conversion();
18 void testing_std_array_output_conversion();
19 
20 void testing_boost_array_input_conversion();
21 void testing_std_array_input_conversion();
22 
23 using namespace boost;
24 
25 #if !defined(BOOST_NO_CXX11_CHAR16_T) && !defined(BOOST_NO_CXX11_UNICODE_LITERALS) && !defined(_LIBCPP_VERSION) && !defined(BOOST_MSVC)
26 #define BOOST_LC_RUNU16
27 #endif
28 
29 #if !defined(BOOST_NO_CXX11_CHAR32_T) && !defined(BOOST_NO_CXX11_UNICODE_LITERALS) && !defined(_LIBCPP_VERSION) && !defined(BOOST_MSVC)
30 #define BOOST_LC_RUNU32
31 #endif
32 
init_unit_test_suite(int,char * [])33 boost::unit_test::test_suite *init_unit_test_suite(int, char *[])
34 {
35     unit_test::test_suite *suite =
36         BOOST_TEST_SUITE("Testing boost::lexical_cast with boost::array and std::array");
37 
38     suite->add(BOOST_TEST_CASE(testing_boost_array_output_conversion));
39     suite->add(BOOST_TEST_CASE(testing_std_array_output_conversion));
40     suite->add(BOOST_TEST_CASE(testing_boost_array_input_conversion));
41     suite->add(BOOST_TEST_CASE(testing_std_array_input_conversion));
42 
43     return suite;
44 }
45 
46 template <template <class, std::size_t> class ArrayT, class T>
testing_template_array_output_on_spec_value(T val)47 static void testing_template_array_output_on_spec_value(T val)
48 {
49     typedef ArrayT<char, 300>             arr_type;
50     typedef ArrayT<char, 1>               short_arr_type;
51     typedef ArrayT<unsigned char, 300>    uarr_type;
52     typedef ArrayT<unsigned char, 1>      ushort_arr_type;
53     typedef ArrayT<signed char, 4>        sarr_type;
54     typedef ArrayT<signed char, 3>        sshort_arr_type;
55 
56     std::string ethalon("100");
57     using namespace std;
58 
59     {
60         arr_type res1 = lexical_cast<arr_type>(val);
61         BOOST_CHECK_EQUAL(&res1[0], ethalon);
62         const arr_type res2 = lexical_cast<arr_type>(val);
63         BOOST_CHECK_EQUAL(&res2[0], ethalon);
64         BOOST_CHECK_THROW(lexical_cast<short_arr_type>(val), boost::bad_lexical_cast);
65     }
66 
67     {
68         uarr_type res1 = lexical_cast<uarr_type>(val);
69         BOOST_CHECK_EQUAL(reinterpret_cast<char*>(&res1[0]), ethalon);
70         const uarr_type res2 = lexical_cast<uarr_type>(val);
71         BOOST_CHECK_EQUAL(reinterpret_cast<const char*>(&res2[0]), ethalon);
72         BOOST_CHECK_THROW(lexical_cast<ushort_arr_type>(val), boost::bad_lexical_cast);
73     }
74 
75     {
76         sarr_type res1 = lexical_cast<sarr_type>(val);
77         BOOST_CHECK_EQUAL(reinterpret_cast<char*>(&res1[0]), ethalon);
78         const sarr_type res2 = lexical_cast<sarr_type>(val);
79         BOOST_CHECK_EQUAL(reinterpret_cast<const char*>(&res2[0]), ethalon);
80         BOOST_CHECK_THROW(lexical_cast<sshort_arr_type>(val), boost::bad_lexical_cast);
81     }
82 
83 #if !defined(BOOST_NO_STRINGSTREAM) && !defined(BOOST_NO_STD_WSTRING)
84     typedef ArrayT<wchar_t, 300> warr_type;
85     typedef ArrayT<wchar_t, 3> wshort_arr_type;
86     std::wstring wethalon(L"100");
87 
88     {
89         warr_type res = lexical_cast<warr_type>(val);
90         BOOST_CHECK(&res[0] == wethalon);
91     }
92 
93     {
94         const warr_type res = lexical_cast<warr_type>(val);
95         BOOST_CHECK(&res[0] == wethalon);
96     }
97 
98     BOOST_CHECK_THROW(lexical_cast<wshort_arr_type>(val), boost::bad_lexical_cast);
99 
100 #endif
101 
102 #ifdef BOOST_LC_RUNU16
103     typedef ArrayT<char16_t, 300> u16arr_type;
104     typedef ArrayT<char16_t, 3> u16short_arr_type;
105     std::u16string u16ethalon(u"100");
106 
107     {
108         u16arr_type res = lexical_cast<u16arr_type>(val);
109         BOOST_CHECK(&res[0] == u16ethalon);
110     }
111 
112     {
113         const u16arr_type res = lexical_cast<u16arr_type>(val);
114         BOOST_CHECK(&res[0] == u16ethalon);
115     }
116 
117     BOOST_CHECK_THROW(lexical_cast<u16short_arr_type>(val), boost::bad_lexical_cast);
118 #endif
119 
120 #ifdef BOOST_LC_RUNU32
121     typedef ArrayT<char32_t, 300> u32arr_type;
122     typedef ArrayT<char32_t, 3> u32short_arr_type;
123     std::u32string u32ethalon(U"100");
124 
125     {
126         u32arr_type res = lexical_cast<u32arr_type>(val);
127         BOOST_CHECK(&res[0] == u32ethalon);
128     }
129 
130     {
131         const u32arr_type res = lexical_cast<u32arr_type>(val);
132         BOOST_CHECK(&res[0] == u32ethalon);
133     }
134 
135     BOOST_CHECK_THROW(lexical_cast<u32short_arr_type>(val), boost::bad_lexical_cast);
136 #endif
137 }
138 
139 
140 template <template <class, std::size_t> class ArrayT>
testing_template_array_output_on_char_value()141 static void testing_template_array_output_on_char_value()
142 {
143     typedef ArrayT<char, 300>             arr_type;
144     typedef ArrayT<char, 1>               short_arr_type;
145     typedef ArrayT<unsigned char, 300>    uarr_type;
146     typedef ArrayT<unsigned char, 1>      ushort_arr_type;
147     typedef ArrayT<signed char, 4>        sarr_type;
148     typedef ArrayT<signed char, 3>        sshort_arr_type;
149 
150     const char val[] = "100";
151     std::string ethalon("100");
152     using namespace std;
153 
154     {
155         arr_type res1 = lexical_cast<arr_type>(val);
156         BOOST_CHECK_EQUAL(&res1[0], ethalon);
157         const arr_type res2 = lexical_cast<arr_type>(val);
158         BOOST_CHECK_EQUAL(&res2[0], ethalon);
159         BOOST_CHECK_THROW(lexical_cast<short_arr_type>(val), boost::bad_lexical_cast);
160     }
161 
162     {
163         uarr_type res1 = lexical_cast<uarr_type>(val);
164         BOOST_CHECK_EQUAL(reinterpret_cast<char*>(&res1[0]), ethalon);
165         const uarr_type res2 = lexical_cast<uarr_type>(val);
166         BOOST_CHECK_EQUAL(reinterpret_cast<const char*>(&res2[0]), ethalon);
167         BOOST_CHECK_THROW(lexical_cast<ushort_arr_type>(val), boost::bad_lexical_cast);
168     }
169 
170     {
171         sarr_type res1 = lexical_cast<sarr_type>(val);
172         BOOST_CHECK_EQUAL(reinterpret_cast<char*>(&res1[0]), ethalon);
173         const sarr_type res2 = lexical_cast<sarr_type>(val);
174         BOOST_CHECK_EQUAL(reinterpret_cast<const char*>(&res2[0]), ethalon);
175         BOOST_CHECK_THROW(lexical_cast<sshort_arr_type>(val), boost::bad_lexical_cast);
176     }
177 
178 #if !defined(BOOST_NO_STRINGSTREAM) && !defined(BOOST_NO_STD_WSTRING)
179     typedef ArrayT<wchar_t, 4> warr_type;
180     typedef ArrayT<wchar_t, 3> wshort_arr_type;
181     std::wstring wethalon(L"100");
182 
183     {
184         warr_type res = lexical_cast<warr_type>(val);
185         BOOST_CHECK(&res[0] == wethalon);
186         warr_type res3 = lexical_cast<warr_type>(wethalon);
187         BOOST_CHECK(&res3[0] == wethalon);
188     }
189 
190     {
191         const warr_type res = lexical_cast<warr_type>(val);
192         BOOST_CHECK(&res[0] == wethalon);
193         const warr_type res3 = lexical_cast<warr_type>(wethalon);
194         BOOST_CHECK(&res3[0] == wethalon);
195     }
196 
197     BOOST_CHECK_THROW(lexical_cast<wshort_arr_type>(val), boost::bad_lexical_cast);
198 
199 #endif
200 
201 #ifdef BOOST_LC_RUNU16
202     typedef ArrayT<char16_t, 300> u16arr_type;
203     typedef ArrayT<char16_t, 3> u16short_arr_type;
204     std::u16string u16ethalon(u"100");
205 
206     {
207 #ifdef BOOST_STL_SUPPORTS_NEW_UNICODE_LOCALES
208         u16arr_type res = lexical_cast<u16arr_type>(val);
209         BOOST_CHECK(&res[0] == u16ethalon);
210 #endif
211 
212         u16arr_type res3 = lexical_cast<u16arr_type>(u16ethalon);
213         BOOST_CHECK(&res3[0] == u16ethalon);
214     }
215 
216     {
217 #ifdef BOOST_STL_SUPPORTS_NEW_UNICODE_LOCALES
218         const u16arr_type res = lexical_cast<u16arr_type>(val);
219         BOOST_CHECK(&res[0] == u16ethalon);
220 #endif
221         const u16arr_type res3 = lexical_cast<u16arr_type>(u16ethalon);
222         BOOST_CHECK(&res3[0] == u16ethalon);
223     }
224 
225     // Some compillers may throw std::bad_alloc here
226     BOOST_CHECK_THROW(lexical_cast<u16short_arr_type>(val), std::exception);
227 #endif
228 
229 #ifdef BOOST_LC_RUNU32
230     typedef ArrayT<char32_t, 300> u32arr_type;
231     typedef ArrayT<char32_t, 3> u32short_arr_type;
232     std::u32string u32ethalon(U"100");
233 
234     {
235 #ifdef BOOST_STL_SUPPORTS_NEW_UNICODE_LOCALES
236         u32arr_type res = lexical_cast<u32arr_type>(val);
237         BOOST_CHECK(&res[0] == u32ethalon);
238 #endif
239         u32arr_type res3 = lexical_cast<u32arr_type>(u32ethalon);
240         BOOST_CHECK(&res3[0] == u32ethalon);
241     }
242 
243     {
244 #ifdef BOOST_STL_SUPPORTS_NEW_UNICODE_LOCALES
245         const u32arr_type res = lexical_cast<u32arr_type>(val);
246         BOOST_CHECK(&res[0] == u32ethalon);
247 #endif
248         const u32arr_type res3 = lexical_cast<u32arr_type>(u32ethalon);
249         BOOST_CHECK(&res3[0] == u32ethalon);
250     }
251 
252     // Some compillers may throw std::bad_alloc here
253     BOOST_CHECK_THROW(lexical_cast<u32short_arr_type>(val), std::exception);
254 #endif
255 }
256 
257 
testing_boost_array_output_conversion()258 void testing_boost_array_output_conversion()
259 {
260     testing_template_array_output_on_char_value<boost::array>();
261     testing_template_array_output_on_spec_value<boost::array>(100);
262     testing_template_array_output_on_spec_value<boost::array>(static_cast<short>(100));
263     testing_template_array_output_on_spec_value<boost::array>(static_cast<unsigned short>(100));
264     testing_template_array_output_on_spec_value<boost::array>(static_cast<unsigned int>(100));
265 }
266 
testing_std_array_output_conversion()267 void testing_std_array_output_conversion()
268 {
269 #ifndef BOOST_NO_CXX11_HDR_ARRAY
270     testing_template_array_output_on_char_value<std::array>();
271     testing_template_array_output_on_spec_value<std::array>(100);
272     testing_template_array_output_on_spec_value<std::array>(static_cast<short>(100));
273     testing_template_array_output_on_spec_value<std::array>(static_cast<unsigned short>(100));
274     testing_template_array_output_on_spec_value<std::array>(static_cast<unsigned int>(100));
275 #endif
276 
277     BOOST_CHECK(true);
278 }
279 
280 template <template <class, std::size_t> class ArrayT>
testing_generic_array_input_conversion()281 static void testing_generic_array_input_conversion()
282 {
283     {
284         ArrayT<char, 4> var_zero_terminated = {{ '1', '0', '0', '\0'}};
285         BOOST_CHECK_EQUAL(lexical_cast<std::string>(var_zero_terminated), "100");
286         BOOST_CHECK_EQUAL(lexical_cast<int>(var_zero_terminated), 100);
287 
288         ArrayT<char, 3> var_none_terminated = {{ '1', '0', '0'}};
289         BOOST_CHECK_EQUAL(lexical_cast<std::string>(var_none_terminated), "100");
290         BOOST_CHECK_EQUAL(lexical_cast<short>(var_none_terminated), static_cast<short>(100));
291 
292         ArrayT<const char, 4> var_zero_terminated_const_char = {{ '1', '0', '0', '\0'}};
293         BOOST_CHECK_EQUAL(lexical_cast<std::string>(var_zero_terminated_const_char), "100");
294 
295         ArrayT<const char, 3> var_none_terminated_const_char = {{ '1', '0', '0'}};
296         BOOST_CHECK_EQUAL(lexical_cast<std::string>(var_none_terminated_const_char), "100");
297 
298         const ArrayT<char, 4> var_zero_terminated_const_var = {{ '1', '0', '0', '\0'}};
299         BOOST_CHECK_EQUAL(lexical_cast<std::string>(var_zero_terminated_const_var), "100");
300 
301         const ArrayT<char, 3> var_none_terminated_const_var = {{ '1', '0', '0'}};
302         BOOST_CHECK_EQUAL(lexical_cast<std::string>(var_none_terminated_const_var), "100");
303 
304         const ArrayT<const char, 4> var_zero_terminated_const_var_const_char = {{ '1', '0', '0', '\0'}};
305         BOOST_CHECK_EQUAL(lexical_cast<std::string>(var_zero_terminated_const_var_const_char), "100");
306 
307         const ArrayT<const char, 3> var_none_terminated_const_var_const_char = {{ '1', '0', '0'}};
308         BOOST_CHECK_EQUAL(lexical_cast<std::string>(var_none_terminated_const_var_const_char), "100");
309         BOOST_CHECK_EQUAL(lexical_cast<int>(var_none_terminated_const_var_const_char), 100);
310     }
311 
312     {
313         const ArrayT<const unsigned char, 4> var_zero_terminated_const_var_const_char = {{ '1', '0', '0', '\0'}};
314         BOOST_CHECK_EQUAL(lexical_cast<std::string>(var_zero_terminated_const_var_const_char), "100");
315 
316         const ArrayT<const unsigned char, 3> var_none_terminated_const_var_const_char = {{ '1', '0', '0'}};
317         BOOST_CHECK_EQUAL(lexical_cast<std::string>(var_none_terminated_const_var_const_char), "100");
318     }
319 
320     {
321         const ArrayT<const signed char, 4> var_zero_terminated_const_var_const_char = {{ '1', '0', '0', '\0'}};
322         BOOST_CHECK_EQUAL(lexical_cast<std::string>(var_zero_terminated_const_var_const_char), "100");
323 
324         const ArrayT<const signed char, 3> var_none_terminated_const_var_const_char = {{ '1', '0', '0'}};
325         BOOST_CHECK_EQUAL(lexical_cast<std::string>(var_none_terminated_const_var_const_char), "100");
326         BOOST_CHECK_EQUAL(lexical_cast<unsigned int>(var_none_terminated_const_var_const_char), 100u);
327     }
328 
329 
330 #if !defined(BOOST_NO_STRINGSTREAM) && !defined(BOOST_NO_STD_WSTRING)
331     {
332         const ArrayT<const wchar_t, 4> var_zero_terminated_const_var_const_char = {{ L'1', L'0', L'0', L'\0'}};
333         BOOST_CHECK(lexical_cast<std::wstring>(var_zero_terminated_const_var_const_char) == L"100");
334 
335         const ArrayT<const wchar_t, 3> var_none_terminated_const_var_const_char = {{ L'1', L'0', L'0'}};
336         BOOST_CHECK(lexical_cast<std::wstring>(var_none_terminated_const_var_const_char) == L"100");
337         BOOST_CHECK_EQUAL(lexical_cast<int>(var_none_terminated_const_var_const_char), 100);
338     }
339 #endif
340 
341 #ifdef BOOST_LC_RUNU16
342     {
343         const ArrayT<const char16_t, 4> var_zero_terminated_const_var_const_char = {{ u'1', u'0', u'0', u'\0'}};
344         BOOST_CHECK(lexical_cast<std::u16string>(var_zero_terminated_const_var_const_char) == u"100");
345         BOOST_CHECK_EQUAL(lexical_cast<unsigned short>(var_zero_terminated_const_var_const_char), static_cast<unsigned short>(100));
346 
347         const ArrayT<const char16_t, 3> var_none_terminated_const_var_const_char = {{ u'1', u'0', u'0'}};
348         BOOST_CHECK(lexical_cast<std::u16string>(var_none_terminated_const_var_const_char) == u"100");
349     }
350 #endif
351 
352 #ifdef BOOST_LC_RUNU32
353     {
354         const ArrayT<const char32_t, 4> var_zero_terminated_const_var_const_char = {{ U'1', U'0', U'0', U'\0'}};
355         BOOST_CHECK(lexical_cast<std::u32string>(var_zero_terminated_const_var_const_char) == U"100");
356 
357         const ArrayT<const char32_t, 3> var_none_terminated_const_var_const_char = {{ U'1', U'0', U'0'}};
358         BOOST_CHECK(lexical_cast<std::u32string>(var_none_terminated_const_var_const_char) == U"100");
359         BOOST_CHECK_EQUAL(lexical_cast<int>(var_none_terminated_const_var_const_char), 100);
360     }
361 #endif
362 }
363 
testing_boost_array_input_conversion()364 void testing_boost_array_input_conversion()
365 {
366     testing_generic_array_input_conversion<boost::array>();
367 }
368 
testing_std_array_input_conversion()369 void testing_std_array_input_conversion()
370 {
371 #ifndef BOOST_NO_CXX11_HDR_ARRAY
372     testing_generic_array_input_conversion<std::array>();
373 #endif
374 
375     BOOST_CHECK(true);
376 }
377 
378