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

source code of boost/libs/lexical_cast/test/iterator_range_test.cpp