The Battle for Wesnoth  1.15.1+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 #include <boost/test/test_case_template.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
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*";
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  bool
160  , unsigned char
161  , unsigned short
162  , unsigned int
164 
166  test_lexical_cast_unsigned, T, test_lexical_cast_unsigned_types)
167 {
168  result = "specialized - To unsigned - From (const) char*";
170  const char* value = "test";
171  BOOST_CHECK_EXCEPTION(lexical_cast<T>(
172  value), const char*, validate);
173  BOOST_CHECK_EXCEPTION(lexical_cast<T>(
174  const_cast<char*>(value)), const char*, validate);
175 
176  result = "specialized - To unsigned - From std::string";
177 
178  BOOST_CHECK_EXCEPTION(lexical_cast<T>(
179  std::string(value)), const char*, validate);
180 
181 }
182 
183 BOOST_AUTO_TEST_CASE(test_lexical_cast_unsigned_long_long)
184 {
185  result = "specialized - To unsigned long long - From (const) char*";
186 
187  const char* value = "test";
188  BOOST_CHECK_EXCEPTION(lexical_cast<unsigned long long>(
189  value), const char*, validate);
190  BOOST_CHECK_EXCEPTION(lexical_cast<unsigned long long>(
191  const_cast<char*>(value)), const char*, validate);
192 
193  result = "specialized - To unsigned long long - From std::string";
195  BOOST_CHECK_EXCEPTION(lexical_cast<unsigned long long>(
196  std::string(value)), const char*, validate);
197 }
198 
199 typedef boost::mpl::vector<
200  float
201  , double
203 
205  test_lexical_cast_floating_point, T, test_lexical_cast_floating_point_types)
206 {
207  result = "specialized - To floating point - From (const) char*";
208 
209  const char* value = "test";
210  BOOST_CHECK_EXCEPTION(lexical_cast<T>(
211  value), const char*, validate);
212  BOOST_CHECK_EXCEPTION(lexical_cast<T>(
213  const_cast<char*>(value)), const char*, validate);
214 
215  result = "specialized - To floating point - From std::string";
216 
217  BOOST_CHECK_EXCEPTION(lexical_cast<T>(
218  std::string(value)), const char*, validate);
219 }
220 
221 } // namespace test_throw
222 
223 BOOST_AUTO_TEST_CASE(test_lexical_cast_result)
224 {
225  BOOST_CHECK_EQUAL(lexical_cast<std::string>(true), "1");
226  BOOST_CHECK_EQUAL(lexical_cast<std::string>(false), "0");
227 
228  BOOST_CHECK_EQUAL(lexical_cast<std::string>(1), "1");
229  BOOST_CHECK_EQUAL(lexical_cast<std::string>(1u), "1");
230 
231  BOOST_CHECK_EQUAL(lexical_cast<std::string>(1.2f), "1.2");
232  BOOST_CHECK_EQUAL(lexical_cast<std::string>(1.2), "1.2");
233 
234  BOOST_CHECK_EQUAL(lexical_cast<int>("1"), 1);
235  BOOST_CHECK_EQUAL(lexical_cast<int>("-1"), -1);
236  BOOST_CHECK_EQUAL(lexical_cast<unsigned>("1"), 1);
237  BOOST_CHECK_EQUAL(lexical_cast<double>("1.2"), 1.2);
238  BOOST_CHECK_THROW(lexical_cast<double>("0x11"), bad_lexical_cast);
239 
240  std::string a = "01234567890123456789";
241  BOOST_CHECK_EQUAL(lexical_cast<long long>(a), 1234567890123456789ll);
242  BOOST_CHECK_THROW(lexical_cast<int>(a), bad_lexical_cast);
243  BOOST_CHECK_EQUAL(lexical_cast<double>(a), 1.23456789012345678e18);
244  BOOST_CHECK_EQUAL(lexical_cast_default<long long>(a, 0ll), 1234567890123456789ll);
245  BOOST_CHECK_EQUAL(lexical_cast_default<int>(a, 0), 0);
246  BOOST_CHECK_EQUAL(lexical_cast_default<double>(a, 0.0), 1.23456789012345678e18);
247 
248  std::string b = "99999999999999999999";
249  BOOST_CHECK_THROW(lexical_cast<long long>(b), bad_lexical_cast);
250  BOOST_CHECK_THROW(lexical_cast<int>(b), bad_lexical_cast);
251  BOOST_CHECK_EQUAL(lexical_cast<double>(b), 1e20);
252  BOOST_CHECK_EQUAL(lexical_cast_default<long long>(b, 0ll), 0ll);
253  BOOST_CHECK_EQUAL(lexical_cast_default<int>(b, 0), 0);
254  BOOST_CHECK_EQUAL(lexical_cast_default<double>(b, 0.0), 1e20);
255 }
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
#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
boost::mpl::vector< bool, unsigned char, unsigned short, unsigned int, unsigned long > test_lexical_cast_unsigned_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:425
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