1 | // Unit test for boost::lexical_cast. |
2 | // |
3 | // See http://www.boost.org for most recent version, including documentation. |
4 | // |
5 | // Copyright Antony Polukhin, 2011-2024. |
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 | #include <boost/range/iterator_range.hpp> |
13 | |
14 | #include "escape_struct.hpp" |
15 | |
16 | #include <boost/core/lightweight_test.hpp> |
17 | |
18 | #include <vector> |
19 | |
20 | using namespace boost; |
21 | |
22 | #if defined(BOOST_NO_STRINGSTREAM) || defined(BOOST_NO_STD_WSTRING) |
23 | #define BOOST_LCAST_NO_WCHAR_T |
24 | #endif |
25 | |
26 | template <class T> |
27 | void do_test_on_empty_input(T& v) |
28 | { |
29 | BOOST_TEST_THROWS(lexical_cast<int>(v), bad_lexical_cast); |
30 | BOOST_TEST_THROWS(lexical_cast<float>(v), bad_lexical_cast); |
31 | BOOST_TEST_THROWS(lexical_cast<double>(v), bad_lexical_cast); |
32 | #ifndef BOOST_MATH_NO_LONG_DOUBLE_MATH_FUNCTIONS |
33 | BOOST_TEST_THROWS(lexical_cast<long double>(v), bad_lexical_cast); |
34 | #endif |
35 | BOOST_TEST_THROWS(lexical_cast<unsigned int>(v), bad_lexical_cast); |
36 | BOOST_TEST_THROWS(lexical_cast<unsigned short>(v), bad_lexical_cast); |
37 | #if defined(BOOST_HAS_LONG_LONG) |
38 | BOOST_TEST_THROWS(lexical_cast<boost::ulong_long_type>(v), bad_lexical_cast); |
39 | BOOST_TEST_THROWS(lexical_cast<boost::long_long_type>(v), bad_lexical_cast); |
40 | #elif defined(BOOST_HAS_MS_INT64) |
41 | BOOST_TEST_THROWS(lexical_cast<unsigned __int64>(v), bad_lexical_cast); |
42 | BOOST_TEST_THROWS(lexical_cast<__int64>(v), bad_lexical_cast); |
43 | #endif |
44 | } |
45 | |
46 | void test_empty_iterator_range() |
47 | { |
48 | |
49 | boost::iterator_range<char*> v; |
50 | do_test_on_empty_input(v); |
51 | BOOST_TEST_EQ(lexical_cast<std::string>(v), std::string()); |
52 | BOOST_TEST_THROWS(lexical_cast<char>(v), bad_lexical_cast); |
53 | BOOST_TEST_THROWS(lexical_cast<unsigned char>(v), bad_lexical_cast); |
54 | BOOST_TEST_THROWS(lexical_cast<signed char>(v), bad_lexical_cast); |
55 | |
56 | boost::iterator_range<const char*> cv; |
57 | do_test_on_empty_input(v&: cv); |
58 | BOOST_TEST_EQ(lexical_cast<std::string>(cv), std::string()); |
59 | BOOST_TEST_THROWS(lexical_cast<char>(cv), bad_lexical_cast); |
60 | BOOST_TEST_THROWS(lexical_cast<unsigned char>(cv), bad_lexical_cast); |
61 | BOOST_TEST_THROWS(lexical_cast<signed char>(cv), bad_lexical_cast); |
62 | |
63 | const boost::iterator_range<const char*> ccv; |
64 | do_test_on_empty_input(v: ccv); |
65 | BOOST_TEST_EQ(lexical_cast<std::string>(ccv), std::string()); |
66 | BOOST_TEST_THROWS(lexical_cast<char>(ccv), bad_lexical_cast); |
67 | BOOST_TEST_THROWS(lexical_cast<unsigned char>(ccv), bad_lexical_cast); |
68 | BOOST_TEST_THROWS(lexical_cast<signed char>(ccv), bad_lexical_cast); |
69 | } |
70 | |
71 | void test_empty_string() |
72 | { |
73 | std::string v; |
74 | do_test_on_empty_input(v); |
75 | BOOST_TEST_THROWS(lexical_cast<char>(v), bad_lexical_cast); |
76 | BOOST_TEST_THROWS(lexical_cast<unsigned char>(v), bad_lexical_cast); |
77 | BOOST_TEST_THROWS(lexical_cast<signed char>(v), bad_lexical_cast); |
78 | |
79 | #ifndef BOOST_LCAST_NO_WCHAR_T |
80 | std::wstring vw; |
81 | do_test_on_empty_input(v&: vw); |
82 | BOOST_TEST_THROWS(lexical_cast<wchar_t>(vw), bad_lexical_cast); |
83 | #endif |
84 | |
85 | // Currently, no compiler and STL library fully support char16_t and char32_t |
86 | //#ifndef BOOST_NO_CXX11_CHAR16_T |
87 | // std::basic_string<char16_t> v16w; |
88 | // do_test_on_empty_input(v16w); |
89 | // BOOST_TEST_THROWS(lexical_cast<char16_t>(v16w), bad_lexical_cast); |
90 | //#endif |
91 | //#ifndef BOOST_NO_CXX11_CHAR32_T |
92 | // std::basic_string<char32_t> v32w; |
93 | // do_test_on_empty_input(v32w); |
94 | // BOOST_TEST_THROWS(lexical_cast<char32_t>(v32w), bad_lexical_cast); |
95 | //#endif |
96 | } |
97 | |
98 | void test_empty_user_class() |
99 | { |
100 | EscapeStruct v("" ); |
101 | do_test_on_empty_input(v); |
102 | BOOST_TEST_THROWS(lexical_cast<char>(v), bad_lexical_cast); |
103 | BOOST_TEST_THROWS(lexical_cast<unsigned char>(v), bad_lexical_cast); |
104 | BOOST_TEST_THROWS(lexical_cast<signed char>(v), bad_lexical_cast); |
105 | } |
106 | |
107 | namespace std { |
108 | inline std::ostream & operator<<(std::ostream & out, const std::vector<long> & v) |
109 | { |
110 | std::ostream_iterator<long> it(out); |
111 | std::copy(first: v.begin(), last: v.end(), result: it); |
112 | BOOST_TEST(out); |
113 | return out; |
114 | } |
115 | } |
116 | |
117 | void test_empty_vector() |
118 | { |
119 | std::vector<long> v; |
120 | do_test_on_empty_input(v); |
121 | BOOST_TEST_THROWS(lexical_cast<char>(v), bad_lexical_cast); |
122 | BOOST_TEST_THROWS(lexical_cast<unsigned char>(v), bad_lexical_cast); |
123 | BOOST_TEST_THROWS(lexical_cast<signed char>(v), bad_lexical_cast); |
124 | } |
125 | |
126 | |
127 | struct my_string { |
128 | friend std::ostream &operator<<(std::ostream& sout, my_string const&/* st*/) { |
129 | return sout << "" ; |
130 | } |
131 | }; |
132 | |
133 | void test_empty_zero_terminated_string() |
134 | { |
135 | my_string st; |
136 | BOOST_TEST_EQ(boost::lexical_cast<std::string>(st), std::string());; |
137 | } |
138 | |
139 | |
140 | int main() |
141 | { |
142 | test_empty_iterator_range(); |
143 | test_empty_string(); |
144 | test_empty_user_class(); |
145 | test_empty_vector(); |
146 | test_empty_zero_terminated_string(); |
147 | |
148 | return boost::report_errors(); |
149 | } |
150 | |