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