The Battle for Wesnoth  1.17.0-dev
test_lexical_cast.cpp
Go to the documentation of this file.
1 /*
2  Copyright (C) 2009 - 2021
3  by Mark de Wever <koraq@xs4all.nl>
4  Part of the Battle for Wesnoth Project https://www.wesnoth.org/
5 
6  This program is free software; you can redistribute it and/or modify
7  it under the terms of the GNU General Public License as published by
8  the Free Software Foundation; either version 2 of the License, or
9  (at your option) any later version.
10  This program is distributed in the hope that it will be useful,
11  but WITHOUT ANY WARRANTY.
12 
13  See the COPYING file for more details.
14 */
15 
16 #define GETTEXT_DOMAIN "wesnoth-test"
17 
18 #include "lexical_cast.hpp"
19 
20 #include <boost/test/unit_test.hpp>
21 
22 #include <boost/mpl/vector.hpp>
23 #include <boost/mpl/copy.hpp>
24 #include <boost/mpl/back_inserter.hpp>
25 #include <boost/mpl/contains.hpp>
26 
27 #include <iostream>
28 
29 namespace test_throw {
30 
31 #ifdef _MSC_VER
32 #pragma warning(push)
33 #pragma warning(disable:4702)
34 #endif
35 
36 #define LEXICAL_CAST_DEBUG
37 #include "lexical_cast.hpp"
38 
39 #ifdef _MSC_VER
40 #pragma warning(pop)
41 #endif
42 
43 typedef boost::mpl::vector<
44  /* note Wesnoth's coding style doesn't allow w_char so ignore them. */
45 
46  bool,
47 
48  /*
49  * We don't want chars to match since a string cast of a char is
50  * ambiguous; does the user want it interpreted as a char or as a number?
51  * But as long as that hasn't been fixed, leave the char.
52  */
53  char, signed char, unsigned char,
54  short, int, long, long long,
55  unsigned short, unsigned int, unsigned long, unsigned long long
57 
58 typedef boost::mpl::vector<
59  float, double, long double
61 
62 typedef boost::mpl::copy<
64  boost::mpl::back_inserter<test_match_types>
66 
67 
68 namespace {
69 
70  std::string result;
71 
72 bool validate(const char* str)
73 {
74  if(str != result) {
75  std::cerr << "Received " << str << '\n'
76  << "Expected " << result << '\n';
77  return false;
78  } else {
79  return true;
80  }
81 }
82 
83 } // namespace
84 
85 #define TEST_CASE(type_send, initializer) \
86  { \
87  type_send val = initializer value; \
88  \
89  BOOST_CHECK_EXCEPTION( \
90  lexical_cast<std::string>(val), const char*, validate); \
91  }
92 
93 BOOST_AUTO_TEST_CASE_TEMPLATE(test_lexical_cast_throw, T, test_types)
94 {
95  T value = T();
96 
99 
100  result = typeid(test) == typeid(match)
101  ? "specialized - To std::string - From integral (pointer)"
102  : "generic";
103 
104  TEST_CASE(T, );
105  TEST_CASE(const T, );
106 
107  TEST_CASE(T&, );
108  TEST_CASE(const T&, );
109 
110  TEST_CASE(T*, &);
111  TEST_CASE(const T*, &);
112 
113  TEST_CASE(T* const, &);
114  TEST_CASE(const T* const, &);
115 }
117 #undef TEST_CASE
118 
119 typedef boost::mpl::vector<
120  signed char
121  , short
122  , int
124 
126  test_lexical_cast_signed, T, test_lexical_cast_signed_types)
127 {
128  result = "specialized - To signed - From (const) char*";
129 
130  const char* value = "test";
131  BOOST_CHECK_EXCEPTION(lexical_cast<T>(
132  value), const char*, validate);
133  BOOST_CHECK_EXCEPTION(lexical_cast<T>(
134  const_cast<char*>(value)), const char*, validate);
135 
136  result = "specialized - To signed - From std::string";
137 
138  BOOST_CHECK_EXCEPTION(lexical_cast<T>(
139  std::string(value)), const char*, validate);
140 }
141 
142 BOOST_AUTO_TEST_CASE(test_lexical_cast_long_long)
143 {
144  result = "specialized - To long long - From (const) char*";
145 
146  const char* value = "test";
147  BOOST_CHECK_EXCEPTION(lexical_cast<long long>(
148  value), const char*, validate);
149  BOOST_CHECK_EXCEPTION(lexical_cast<long long>(
150  const_cast<char*>(value)), const char*, validate);
151 
152  result = "specialized - To long long - From std::string";
153 
154  BOOST_CHECK_EXCEPTION(lexical_cast<long long>(
155  std::string(value)), const char*, validate);
156 }
157 
158 typedef boost::mpl::vector<
159  unsigned char
160  , unsigned short
161  , unsigned int
163 
165  test_lexical_cast_unsigned, T, test_lexical_cast_unsigned_types)
166 {
167  result = "specialized - To unsigned - From (const) char*";
168 
169  const char* value = "test";
170  BOOST_CHECK_EXCEPTION(lexical_cast<T>(
171  value), const char*, validate);
172  BOOST_CHECK_EXCEPTION(lexical_cast<T>(
173  const_cast<char*>(value)), const char*, validate);
175  result = "specialized - To unsigned - From std::string";
176 
177  BOOST_CHECK_EXCEPTION(lexical_cast<T>(
178  std::string(value)), const char*, validate);
179 
180 }
181 
182 BOOST_AUTO_TEST_CASE(test_lexical_cast_unsigned_long_long)
183 {
184  result = "specialized - To unsigned long long - From (const) char*";
185 
186  const char* value = "test";
187  BOOST_CHECK_EXCEPTION(lexical_cast<unsigned long long>(
188  value), const char*, validate);
189  BOOST_CHECK_EXCEPTION(lexical_cast<unsigned long long>(
190  const_cast<char*>(value)), const char*, validate);
191 
192  result = "specialized - To unsigned long long - From std::string";
193 
194  BOOST_CHECK_EXCEPTION(lexical_cast<unsigned long long>(
195  std::string(value)), const char*, validate);
196 }
197 
198 BOOST_AUTO_TEST_CASE(test_lexical_cast_bool)
199 {
200  result = "specialized - To bool - From (const) char*";
201 
202  const char* value = "test";
203  BOOST_CHECK_EXCEPTION(lexical_cast<bool>(
204  value), const char*, validate);
205  BOOST_CHECK_EXCEPTION(lexical_cast<bool>(
206  const_cast<char*>(value)), const char*, validate);
207 
208  result = "specialized - To bool - From std::string";
209 
210  BOOST_CHECK_EXCEPTION(lexical_cast<bool>(
211  std::string(value)), const char*, validate);
212 }
213 
214 typedef boost::mpl::vector<
215  float
216  , double
218 
220  test_lexical_cast_floating_point, T, test_lexical_cast_floating_point_types)
221 {
222  result = "specialized - To floating point - From (const) char*";
223 
224  const char* value = "test";
225  BOOST_CHECK_EXCEPTION(lexical_cast<T>(
226  value), const char*, validate);
227  BOOST_CHECK_EXCEPTION(lexical_cast<T>(
228  const_cast<char*>(value)), const char*, validate);
229 
230  result = "specialized - To floating point - From std::string";
231 
232  BOOST_CHECK_EXCEPTION(lexical_cast<T>(
233  std::string(value)), const char*, validate);
234 }
235 
236 } // namespace test_throw
237 
238 BOOST_AUTO_TEST_CASE(test_lexical_cast_result)
239 {
240  BOOST_CHECK_EQUAL(lexical_cast<std::string>(true), "1");
241  BOOST_CHECK_EQUAL(lexical_cast<std::string>(false), "0");
242 
243  BOOST_CHECK_EQUAL(lexical_cast<std::string>(1), "1");
244  BOOST_CHECK_EQUAL(lexical_cast<std::string>(1u), "1");
245 
246  BOOST_CHECK_EQUAL(lexical_cast<std::string>(1.2f), "1.2");
247  BOOST_CHECK_EQUAL(lexical_cast<std::string>(1.2), "1.2");
249  BOOST_CHECK_EQUAL(lexical_cast<int>("1"), 1);
250  BOOST_CHECK_EQUAL(lexical_cast<int>("-1"), -1);
251  BOOST_CHECK_EQUAL(lexical_cast<unsigned>("1"), 1);
252  BOOST_CHECK_EQUAL(lexical_cast<double>("1.2"), 1.2);
253  BOOST_CHECK_THROW(lexical_cast<double>("0x11"), bad_lexical_cast);
254 
255  std::string a = "01234567890123456789";
256  BOOST_CHECK_EQUAL(lexical_cast<long long>(a), 1234567890123456789ll);
257  BOOST_CHECK_THROW(lexical_cast<int>(a), bad_lexical_cast);
258  BOOST_CHECK_EQUAL(lexical_cast<double>(a), 1.23456789012345678e18);
259  BOOST_CHECK_EQUAL(lexical_cast_default<long long>(a, 0ll), 1234567890123456789ll);
260  BOOST_CHECK_EQUAL(lexical_cast_default<int>(a, 0), 0);
261  BOOST_CHECK_EQUAL(lexical_cast_default<double>(a, 0.0), 1.23456789012345678e18);
262 
263  std::string b = "99999999999999999999";
264  BOOST_CHECK_THROW(lexical_cast<long long>(b), bad_lexical_cast);
265  BOOST_CHECK_THROW(lexical_cast<int>(b), bad_lexical_cast);
266  BOOST_CHECK_EQUAL(lexical_cast<double>(b), 1e20);
267  BOOST_CHECK_EQUAL(lexical_cast_default<long long>(b, 0ll), 0ll);
268  BOOST_CHECK_EQUAL(lexical_cast_default<int>(b, 0), 0);
269  BOOST_CHECK_EQUAL(lexical_cast_default<double>(b, 0.0), 1e20);
270 }
BOOST_AUTO_TEST_CASE(test_lexical_cast_long_long)
BOOST_AUTO_TEST_CASE_TEMPLATE(test_lexical_cast_throw, T, test_types)
New lexcical_cast header.
#define a
#define b
boost::mpl::vector< unsigned char, unsigned short, unsigned int, unsigned long > test_lexical_cast_unsigned_types
#define TEST_CASE(type_send, initializer)
boost::mpl::vector< float, double, long double > test_lexical_cast_floating_point_types
boost::mpl::vector< signed char, short, int, long > test_lexical_cast_signed_types
static void validate(boost::any &v, const std::vector< std::string > &values, two_strings *, int)
boost::mpl::vector< float, double, long double > test_nomatch_types
boost::mpl::copy< test_nomatch_types, boost::mpl::back_inserter< test_match_types > >::type test_types
Thrown when a lexical_cast fails.
#define f
static const char * match(MatchState *ms, const char *s, const char *p)
Definition: lstrlib.cpp:567
boost::mpl::vector< bool, char, signed char, unsigned char, short, int, long, long long, unsigned short, unsigned int, unsigned long, unsigned long long > test_match_types