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, 2012-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 | |
13 | #include <boost/core/lightweight_test.hpp> |
14 | #include <boost/range/iterator_range.hpp> |
15 | |
16 | #include "escape_struct.hpp" |
17 | |
18 | #include <vector> |
19 | |
20 | using namespace boost; |
21 | |
22 | // Testing compilation and some basic usage with BOOST_NO_STD_LOCALE |
23 | // Tests are mainly copyied from empty_input_test.cpp (something |
24 | // new added to test_empty_3) |
25 | |
26 | #ifndef BOOST_NO_STD_LOCALE |
27 | #error "This test must be compiled with -DBOOST_NO_STD_LOCALE" |
28 | #endif |
29 | |
30 | |
31 | template <class T> |
32 | void do_test_on_empty_input(T& v) |
33 | { |
34 | BOOST_TEST_THROWS(lexical_cast<int>(v), bad_lexical_cast); |
35 | BOOST_TEST_THROWS(lexical_cast<float>(v), bad_lexical_cast); |
36 | BOOST_TEST_THROWS(lexical_cast<double>(v), bad_lexical_cast); |
37 | #ifndef BOOST_MATH_NO_LONG_DOUBLE_MATH_FUNCTIONS |
38 | BOOST_TEST_THROWS(lexical_cast<long double>(v), bad_lexical_cast); |
39 | #endif |
40 | BOOST_TEST_THROWS(lexical_cast<unsigned int>(v), bad_lexical_cast); |
41 | BOOST_TEST_THROWS(lexical_cast<unsigned short>(v), bad_lexical_cast); |
42 | #if defined(BOOST_HAS_LONG_LONG) |
43 | BOOST_TEST_THROWS(lexical_cast<boost::ulong_long_type>(v), bad_lexical_cast); |
44 | BOOST_TEST_THROWS(lexical_cast<boost::long_long_type>(v), bad_lexical_cast); |
45 | #elif defined(BOOST_HAS_MS_INT64) |
46 | BOOST_TEST_THROWS(lexical_cast<unsigned __int64>(v), bad_lexical_cast); |
47 | BOOST_TEST_THROWS(lexical_cast<__int64>(v), bad_lexical_cast); |
48 | #endif |
49 | } |
50 | |
51 | void test_empty_1() |
52 | { |
53 | boost::iterator_range<char*> v; |
54 | do_test_on_empty_input(v); |
55 | BOOST_TEST_EQ(lexical_cast<std::string>(v), std::string()); |
56 | BOOST_TEST_THROWS(lexical_cast<char>(v), bad_lexical_cast); |
57 | BOOST_TEST_THROWS(lexical_cast<unsigned char>(v), bad_lexical_cast); |
58 | BOOST_TEST_THROWS(lexical_cast<signed char>(v), bad_lexical_cast); |
59 | |
60 | boost::iterator_range<const char*> cv; |
61 | do_test_on_empty_input(v&: cv); |
62 | BOOST_TEST_EQ(lexical_cast<std::string>(cv), std::string()); |
63 | BOOST_TEST_THROWS(lexical_cast<char>(cv), bad_lexical_cast); |
64 | BOOST_TEST_THROWS(lexical_cast<unsigned char>(cv), bad_lexical_cast); |
65 | BOOST_TEST_THROWS(lexical_cast<signed char>(cv), bad_lexical_cast); |
66 | |
67 | const boost::iterator_range<const char*> ccv; |
68 | do_test_on_empty_input(v: ccv); |
69 | BOOST_TEST_EQ(lexical_cast<std::string>(ccv), std::string()); |
70 | BOOST_TEST_THROWS(lexical_cast<char>(ccv), bad_lexical_cast); |
71 | BOOST_TEST_THROWS(lexical_cast<unsigned char>(ccv), bad_lexical_cast); |
72 | BOOST_TEST_THROWS(lexical_cast<signed char>(ccv), bad_lexical_cast); |
73 | } |
74 | |
75 | void test_empty_2() |
76 | { |
77 | std::string v; |
78 | do_test_on_empty_input(v); |
79 | BOOST_TEST_THROWS(lexical_cast<char>(v), bad_lexical_cast); |
80 | BOOST_TEST_THROWS(lexical_cast<unsigned char>(v), bad_lexical_cast); |
81 | BOOST_TEST_THROWS(lexical_cast<signed char>(v), bad_lexical_cast); |
82 | } |
83 | |
84 | void test_empty_3() |
85 | { |
86 | EscapeStruct v("" ); |
87 | do_test_on_empty_input(v); |
88 | |
89 | BOOST_TEST_THROWS(lexical_cast<char>(v), bad_lexical_cast); |
90 | BOOST_TEST_THROWS(lexical_cast<unsigned char>(v), bad_lexical_cast); |
91 | BOOST_TEST_THROWS(lexical_cast<signed char>(v), bad_lexical_cast); |
92 | |
93 | v = lexical_cast<EscapeStruct>(arg: 100); |
94 | BOOST_TEST_EQ(lexical_cast<int>(v), 100); |
95 | BOOST_TEST_EQ(lexical_cast<unsigned int>(v), 100u); |
96 | |
97 | v = lexical_cast<EscapeStruct>(arg: 0.0); |
98 | BOOST_TEST_EQ(lexical_cast<double>(v), 0.0); |
99 | } |
100 | |
101 | namespace std { |
102 | inline std::ostream & operator<<(std::ostream & out, const std::vector<long> & v) |
103 | { |
104 | std::ostream_iterator<long> it(out); |
105 | std::copy(first: v.begin(), last: v.end(), result: it); |
106 | BOOST_TEST(out); |
107 | return out; |
108 | } |
109 | } |
110 | |
111 | void test_empty_4() |
112 | { |
113 | std::vector<long> v; |
114 | do_test_on_empty_input(v); |
115 | BOOST_TEST_THROWS(lexical_cast<char>(v), bad_lexical_cast); |
116 | BOOST_TEST_THROWS(lexical_cast<unsigned char>(v), bad_lexical_cast); |
117 | BOOST_TEST_THROWS(lexical_cast<signed char>(v), bad_lexical_cast); |
118 | } |
119 | |
120 | |
121 | struct my_string { |
122 | friend std::ostream &operator<<(std::ostream& sout, my_string const&/* st*/) { |
123 | return sout << "" ; |
124 | } |
125 | }; |
126 | |
127 | void test_empty_5() |
128 | { |
129 | my_string st; |
130 | BOOST_TEST_EQ(boost::lexical_cast<std::string>(st), std::string());; |
131 | } |
132 | |
133 | int main() |
134 | { |
135 | test_empty_1(); |
136 | test_empty_2(); |
137 | test_empty_3(); |
138 | test_empty_4(); |
139 | test_empty_5(); |
140 | |
141 | return boost::report_errors(); |
142 | } |
143 | |
144 | |