lexical_cast_test.cpp 25 KB

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