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
20using namespace boost;
21
22#if defined(BOOST_NO_STRINGSTREAM) || defined(BOOST_NO_STD_WSTRING)
23#define BOOST_LCAST_NO_WCHAR_T
24#endif
25
26template <class T>
27void 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
46void 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
71void 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
98void 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
107namespace std {
108inline 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
117void 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
127struct my_string {
128 friend std::ostream &operator<<(std::ostream& sout, my_string const&/* st*/) {
129 return sout << "";
130 }
131};
132
133void 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
140int 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

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