• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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-2021.
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/config.hpp>
12 
13 #if defined(__INTEL_COMPILER)
14 #pragma warning(disable: 193 383 488 981 1418 1419)
15 #elif defined(BOOST_MSVC)
16 #pragma warning(disable: 4097 4100 4121 4127 4146 4244 4245 4511 4512 4701 4800)
17 #endif
18 
19 #include <boost/lexical_cast.hpp>
20 
21 #include <boost/test/unit_test.hpp>
22 #include <boost/range/iterator_range.hpp>
23 
24 using namespace boost;
25 
26 #if defined(BOOST_NO_STRINGSTREAM) || defined(BOOST_NO_STD_WSTRING)
27 #define BOOST_LCAST_NO_WCHAR_T
28 #endif
29 
30 
31 #if !defined(BOOST_NO_CXX11_CHAR16_T) && !defined(BOOST_NO_CXX11_UNICODE_LITERALS) && !defined(_LIBCPP_VERSION) && !defined(BOOST_MSVC)
32 #define BOOST_LC_RUNU16
33 #endif
34 
35 #if !defined(BOOST_NO_CXX11_CHAR32_T) && !defined(BOOST_NO_CXX11_UNICODE_LITERALS) && !defined(_LIBCPP_VERSION) && !defined(BOOST_MSVC)
36 #define BOOST_LC_RUNU32
37 #endif
38 
39 struct class_with_user_defined_sream_operators {
40     int i;
41 
operator intclass_with_user_defined_sream_operators42     operator int() const {
43         return i;
44     }
45 };
46 
47 template <class CharT>
operator >>(std::basic_istream<CharT> & istr,class_with_user_defined_sream_operators & rhs)48 inline std::basic_istream<CharT>& operator >> (std::basic_istream<CharT>& istr, class_with_user_defined_sream_operators& rhs)
49 {
50     return istr >> rhs.i;
51 }
52 
53 
54 template <class RngT>
do_test_iterator_range_impl(const RngT & rng)55 void do_test_iterator_range_impl(const RngT& rng)
56 {
57     BOOST_CHECK_EQUAL(lexical_cast<int>(rng), 1);
58     BOOST_CHECK_EQUAL(lexical_cast<int>(rng.begin(), rng.size()), 1);
59     BOOST_CHECK_EQUAL(lexical_cast<unsigned int>(rng), 1u);
60     BOOST_CHECK_EQUAL(lexical_cast<unsigned int>(rng.begin(), rng.size()), 1u);
61     BOOST_CHECK_EQUAL(lexical_cast<short>(rng), 1);
62     BOOST_CHECK_EQUAL(lexical_cast<short>(rng.begin(), rng.size()), 1);
63     BOOST_CHECK_EQUAL(lexical_cast<unsigned short>(rng), 1u);
64     BOOST_CHECK_EQUAL(lexical_cast<unsigned short>(rng.begin(), rng.size()), 1u);
65     BOOST_CHECK_EQUAL(lexical_cast<long int>(rng), 1);
66     BOOST_CHECK_EQUAL(lexical_cast<long int>(rng.begin(), rng.size()), 1);
67     BOOST_CHECK_EQUAL(lexical_cast<unsigned long int>(rng), 1u);
68     BOOST_CHECK_EQUAL(lexical_cast<unsigned long int>(rng.begin(), rng.size()), 1u);
69 
70 #ifdef BOOST_STL_SUPPORTS_NEW_UNICODE_LOCALES
71     BOOST_CHECK_EQUAL(lexical_cast<float>(rng), 1.0f);
72     BOOST_CHECK_EQUAL(lexical_cast<float>(rng.begin(), rng.size()), 1.0f);
73     BOOST_CHECK_EQUAL(lexical_cast<double>(rng), 1.0);
74     BOOST_CHECK_EQUAL(lexical_cast<double>(rng.begin(), rng.size()), 1.0);
75 #ifndef BOOST_MATH_NO_LONG_DOUBLE_MATH_FUNCTIONS
76     BOOST_CHECK_EQUAL(lexical_cast<long double>(rng), 1.0L);
77     BOOST_CHECK_EQUAL(lexical_cast<long double>(rng.begin(), rng.size()), 1.0L);
78 #endif
79     BOOST_CHECK_EQUAL(lexical_cast<class_with_user_defined_sream_operators>(rng), 1);
80 #endif
81 #if defined(BOOST_HAS_LONG_LONG)
82     BOOST_CHECK_EQUAL(lexical_cast<boost::ulong_long_type>(rng), 1u);
83     BOOST_CHECK_EQUAL(lexical_cast<boost::ulong_long_type>(rng.begin(), rng.size()), 1u);
84     BOOST_CHECK_EQUAL(lexical_cast<boost::long_long_type>(rng), 1);
85     BOOST_CHECK_EQUAL(lexical_cast<boost::long_long_type>(rng.begin(), rng.size()), 1);
86 #elif defined(BOOST_HAS_MS_INT64)
87     BOOST_CHECK_EQUAL(lexical_cast<unsigned __int64>(rng), 1u);
88     BOOST_CHECK_EQUAL(lexical_cast<unsigned __int64>(rng.begin(), rng.size()), 1u);
89     BOOST_CHECK_EQUAL(lexical_cast<__int64>(rng), 1);
90     BOOST_CHECK_EQUAL(lexical_cast<__int64>(rng.begin(), rng.size()), 1);
91 #endif
92 }
93 
94 template <class CharT>
test_it_range_using_any_chars(CharT * one,CharT * eleven)95 void test_it_range_using_any_chars(CharT* one, CharT* eleven)
96 {
97     typedef CharT test_char_type;
98 
99     // Zero terminated
100     iterator_range<test_char_type*> rng1(one, one + 1);
101     do_test_iterator_range_impl(rng1);
102 
103     iterator_range<const test_char_type*> crng1(one, one + 1);
104     do_test_iterator_range_impl(crng1);
105 
106     // Non zero terminated
107     iterator_range<test_char_type*> rng2(eleven, eleven + 1);
108     do_test_iterator_range_impl(rng2);
109 
110     iterator_range<const test_char_type*> crng2(eleven, eleven + 1);
111     do_test_iterator_range_impl(crng2);
112 }
113 
114 template <class CharT>
test_it_range_using_char(CharT * one,CharT * eleven)115 void test_it_range_using_char(CharT* one, CharT* eleven)
116 {
117     typedef CharT test_char_type;
118 
119     iterator_range<test_char_type*> rng1(one, one + 1);
120     BOOST_CHECK_EQUAL(lexical_cast<std::string>(rng1), "1");
121 
122     iterator_range<const test_char_type*> crng1(one, one + 1);
123     BOOST_CHECK_EQUAL(lexical_cast<std::string>(crng1), "1");
124 
125     iterator_range<test_char_type*> rng2(eleven, eleven + 1);
126     BOOST_CHECK_EQUAL(lexical_cast<std::string>(rng2), "1");
127 
128     iterator_range<const test_char_type*> crng2(eleven, eleven + 1);
129     BOOST_CHECK_EQUAL(lexical_cast<std::string>(crng2), "1");
130 
131     BOOST_CHECK_EQUAL(lexical_cast<float>(rng1), 1.0f);
132     BOOST_CHECK_EQUAL(lexical_cast<double>(rng1), 1.0);
133 #ifndef BOOST_MATH_NO_LONG_DOUBLE_MATH_FUNCTIONS
134     BOOST_CHECK_EQUAL(lexical_cast<long double>(rng1), 1.0L);
135 #endif
136     BOOST_CHECK_EQUAL(lexical_cast<class_with_user_defined_sream_operators>(rng1), 1);
137 
138     BOOST_CHECK_EQUAL(lexical_cast<float>(crng2), 1.0f);
139     BOOST_CHECK_EQUAL(lexical_cast<double>(crng2), 1.0);
140 #ifndef BOOST_MATH_NO_LONG_DOUBLE_MATH_FUNCTIONS
141     BOOST_CHECK_EQUAL(lexical_cast<long double>(crng2), 1.0L);
142 #endif
143     BOOST_CHECK_EQUAL(lexical_cast<class_with_user_defined_sream_operators>(crng2), 1);
144 
145 #ifndef BOOST_LCAST_NO_WCHAR_T
146     BOOST_CHECK(lexical_cast<std::wstring>(rng1) == L"1");
147     BOOST_CHECK(lexical_cast<std::wstring>(crng1) == L"1");
148     BOOST_CHECK(lexical_cast<std::wstring>(rng2) == L"1");
149     BOOST_CHECK(lexical_cast<std::wstring>(crng2) == L"1");
150 #endif
151 
152 #if defined(BOOST_LC_RUNU16) && defined(BOOST_STL_SUPPORTS_NEW_UNICODE_LOCALES)
153     typedef std::basic_string<char16_t> my_char16_string;
154     BOOST_CHECK(lexical_cast<my_char16_string>(rng1) == u"1");
155     BOOST_CHECK(lexical_cast<my_char16_string>(crng1) == u"1");
156     BOOST_CHECK(lexical_cast<my_char16_string>(rng2) == u"1");
157     BOOST_CHECK(lexical_cast<my_char16_string>(crng2) == u"1");
158 #endif
159 
160 #if defined(BOOST_LC_RUNU32) && defined(BOOST_STL_SUPPORTS_NEW_UNICODE_LOCALES)
161     typedef std::basic_string<char32_t> my_char32_string;
162     BOOST_CHECK(lexical_cast<my_char32_string>(rng1) == U"1");
163     BOOST_CHECK(lexical_cast<my_char32_string>(crng1) == U"1");
164     BOOST_CHECK(lexical_cast<my_char32_string>(rng2) == U"1");
165     BOOST_CHECK(lexical_cast<my_char32_string>(crng2) == U"1");
166 #endif
167 }
168 
test_char_iterator_ranges()169 void test_char_iterator_ranges()
170 {
171     typedef char test_char_type;
172     test_char_type data1[] = "1";
173     test_char_type data2[] = "11";
174     test_it_range_using_any_chars(data1, data2);
175     test_it_range_using_char(data1, data2);
176 }
177 
178 
179 
test_unsigned_char_iterator_ranges()180 void test_unsigned_char_iterator_ranges()
181 {
182     typedef unsigned char test_char_type;
183     test_char_type data1[] = "1";
184     test_char_type data2[] = "11";
185     test_it_range_using_any_chars(data1, data2);
186     test_it_range_using_char(data1, data2);
187 }
188 
test_signed_char_iterator_ranges()189 void test_signed_char_iterator_ranges()
190 {
191     typedef signed char test_char_type;
192     test_char_type data1[] = "1";
193     test_char_type data2[] = "11";
194     test_it_range_using_any_chars(data1, data2);
195     test_it_range_using_char(data1, data2);
196 }
197 
test_wchar_iterator_ranges()198 void test_wchar_iterator_ranges()
199 {
200 #ifndef BOOST_LCAST_NO_WCHAR_T
201     typedef wchar_t test_char_type;
202     test_char_type data1[] = L"1";
203     test_char_type data2[] = L"11";
204     test_it_range_using_any_chars(data1, data2);
205 #endif
206 
207     BOOST_CHECK(true);
208 }
209 
test_char16_iterator_ranges()210 void test_char16_iterator_ranges()
211 {
212 #if defined(BOOST_LC_RUNU16)
213     typedef char16_t test_char_type;
214     test_char_type data1[] = u"1";
215     test_char_type data2[] = u"11";
216     test_it_range_using_any_chars(data1, data2);
217 #endif
218 
219     BOOST_CHECK(true);
220 }
221 
test_char32_iterator_ranges()222 void test_char32_iterator_ranges()
223 {
224 #if defined(BOOST_LC_RUNU32)
225     typedef char32_t test_char_type;
226     test_char_type data1[] = U"1";
227     test_char_type data2[] = U"11";
228     test_it_range_using_any_chars(data1, data2);
229 #endif
230 
231     BOOST_CHECK(true);
232 }
233 
init_unit_test_suite(int,char * [])234 unit_test::test_suite *init_unit_test_suite(int, char *[])
235 {
236     unit_test::test_suite *suite = BOOST_TEST_SUITE("lexical_cast. Testing conversions using iterator_range<>");
237     suite->add(BOOST_TEST_CASE(&test_char_iterator_ranges));
238     suite->add(BOOST_TEST_CASE(&test_unsigned_char_iterator_ranges));
239     suite->add(BOOST_TEST_CASE(&test_signed_char_iterator_ranges));
240     suite->add(BOOST_TEST_CASE(&test_wchar_iterator_ranges));
241     suite->add(BOOST_TEST_CASE(&test_char16_iterator_ranges));
242     suite->add(BOOST_TEST_CASE(&test_char32_iterator_ranges));
243 
244     return suite;
245 }
246