1// Copyright (c) 2001-2011 Hartmut Kaiser
2//
3// Distributed under the Boost Software License, Version 1.0. (See accompanying
4// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
5
6#if !defined(BOOST_SPIRIT_KARMA_TEST_FEB_23_2007_1221PM)
7#define BOOST_SPIRIT_KARMA_TEST_FEB_23_2007_1221PM
8
9#include <cstring>
10#include <string>
11#include <iterator>
12#include <iostream>
13#include <iomanip>
14#include <typeinfo>
15
16#include <boost/spirit/include/karma_generate.hpp>
17#include <boost/spirit/include/karma_what.hpp>
18
19#include <boost/core/lightweight_test.hpp>
20
21namespace spirit_test
22{
23 ///////////////////////////////////////////////////////////////////////////
24 struct display_type
25 {
26 template<typename T>
27 void operator()(T const &) const
28 {
29 std::cout << typeid(T).name() << std::endl;
30 }
31
32 template<typename T>
33 static void print()
34 {
35 std::cout << typeid(T).name() << std::endl;
36 }
37 };
38
39 display_type const display = {};
40
41 ///////////////////////////////////////////////////////////////////////////
42 template <typename Char>
43 struct output_iterator
44 {
45 typedef std::basic_string<Char> string_type;
46 typedef std::back_insert_iterator<string_type> type;
47 };
48
49 ///////////////////////////////////////////////////////////////////////////
50 template <typename Char, typename T>
51 void print_if_failed(char const* func, bool result
52 , std::basic_string<Char> const& generated, T const& expected)
53 {
54 if (!result)
55 std::cerr << "in " << func << ": result is false" << std::endl;
56 else if (generated != expected)
57 {
58 std::cerr << "in " << func << ": generated \"";
59 for (std::size_t i = 0, len = generated.size(); i < len; ++i) {
60 typename boost::make_unsigned<Char>::type c(generated[i]);
61 if (c >= 32 && c < 127)
62 std::cerr << static_cast<char>(static_cast<unsigned char>(c));
63 else
64 std::cerr << "\\x" << std::hex << +c;
65 }
66 std::cerr << "\"\n";
67 }
68 }
69
70 ///////////////////////////////////////////////////////////////////////////
71 template <typename Char, typename T>
72 void print_binary_if_failed(char const* func, bool result
73 , std::basic_string<Char> const& generated, T const& expected)
74 {
75 if (!result)
76 std::cerr << "in " << func << ": result is false" << std::endl;
77 else if (generated.size() != expected.size() ||
78 std::memcmp(s1: generated.c_str(), s2: expected.c_str(), n: generated.size()))
79 {
80 std::cerr << "in " << func << ": generated \"";
81 for (std::size_t i = 0, len = generated.size(); i < len; ++i)
82 std::cerr << "\\x" << std::hex << std::setfill('0') << std::setw(2) << +generated[i];
83 std::cerr << "\"" << std::endl;
84 }
85 }
86
87 ///////////////////////////////////////////////////////////////////////////
88 template <typename Char, typename Generator>
89 inline bool test(Char const *expected, Generator const& g)
90 {
91 namespace karma = boost::spirit::karma;
92 typedef std::basic_string<Char> string_type;
93
94 // we don't care about the result of the "what" function.
95 // we only care that all generators have it:
96 karma::what(g);
97
98 string_type generated;
99 std::back_insert_iterator<string_type> outit(generated);
100 bool result = karma::generate(outit, g);
101
102 print_if_failed("test", result, generated, expected);
103 return result && generated == expected;
104 }
105
106 template <typename Char, typename Generator>
107 inline bool test(std::basic_string<Char> const& expected, Generator const& g)
108 {
109 namespace karma = boost::spirit::karma;
110 typedef std::basic_string<Char> string_type;
111
112 // we don't care about the result of the "what" function.
113 // we only care that all generators have it:
114 karma::what(g);
115
116 string_type generated;
117 std::back_insert_iterator<string_type> outit(generated);
118 bool result = karma::generate(outit, g);
119
120 print_if_failed("test", result, generated, expected);
121 return result && generated == expected;
122 }
123
124 ///////////////////////////////////////////////////////////////////////////
125 template <typename Char, typename Generator, typename Attribute>
126 inline bool test(Char const *expected, Generator const& g,
127 Attribute const &attrib)
128 {
129 namespace karma = boost::spirit::karma;
130 typedef std::basic_string<Char> string_type;
131
132 // we don't care about the result of the "what" function.
133 // we only care that all generators have it:
134 karma::what(g);
135
136 string_type generated;
137 std::back_insert_iterator<string_type> outit(generated);
138 bool result = karma::generate(outit, g, attrib);
139
140 print_if_failed("test", result, generated, expected);
141 return result && generated == expected;
142 }
143
144 template <typename Char, typename Generator, typename Attribute>
145 inline bool test(std::basic_string<Char> const& expected, Generator const& g,
146 Attribute const &attrib)
147 {
148 namespace karma = boost::spirit::karma;
149 typedef std::basic_string<Char> string_type;
150
151 // we don't care about the result of the "what" function.
152 // we only care that all generators have it:
153 karma::what(g);
154
155 string_type generated;
156 std::back_insert_iterator<string_type> outit(generated);
157 bool result = karma::generate(outit, g, attrib);
158
159 print_if_failed("test", result, generated, expected);
160 return result && generated == expected;
161 }
162
163 ///////////////////////////////////////////////////////////////////////////
164 template <typename Char, typename Generator, typename Delimiter>
165 inline bool test_delimited(Char const *expected, Generator const& g,
166 Delimiter const& d)
167 {
168 namespace karma = boost::spirit::karma;
169 typedef std::basic_string<Char> string_type;
170
171 // we don't care about the result of the "what" function.
172 // we only care that all generators have it:
173 karma::what(g);
174
175 string_type generated;
176 std::back_insert_iterator<string_type> outit(generated);
177 bool result = karma::generate_delimited(outit, g, d);
178
179 print_if_failed("test_delimited", result, generated, expected);
180 return result && generated == expected;
181 }
182
183 template <typename Char, typename Generator, typename Delimiter>
184 inline bool test_delimited(std::basic_string<Char> const& expected,
185 Generator const& g, Delimiter const& d)
186 {
187 namespace karma = boost::spirit::karma;
188 typedef std::basic_string<Char> string_type;
189
190 // we don't care about the result of the "what" function.
191 // we only care that all generators have it:
192 karma::what(g);
193
194 string_type generated;
195 std::back_insert_iterator<string_type> outit(generated);
196 bool result = karma::generate_delimited(outit, g, d);
197
198 print_if_failed("test_delimited", result, generated, expected);
199 return result && generated == expected;
200 }
201
202 ///////////////////////////////////////////////////////////////////////////
203 template <typename Char, typename Generator, typename Attribute,
204 typename Delimiter>
205 inline bool test_delimited(Char const *expected, Generator const& g,
206 Attribute const &attrib, Delimiter const& d)
207 {
208 namespace karma = boost::spirit::karma;
209 typedef std::basic_string<Char> string_type;
210
211 // we don't care about the result of the "what" function.
212 // we only care that all generators have it:
213 karma::what(g);
214
215 string_type generated;
216 std::back_insert_iterator<string_type> outit(generated);
217 bool result = karma::generate_delimited(outit, g, d, attrib);
218
219 print_if_failed("test_delimited", result, generated, expected);
220 return result && generated == expected;
221 }
222
223 template <typename Char, typename Generator, typename Attribute,
224 typename Delimiter>
225 inline bool test_delimited(std::basic_string<Char> const& expected,
226 Generator const& g, Attribute const &attrib, Delimiter const& d)
227 {
228 namespace karma = boost::spirit::karma;
229 typedef std::basic_string<Char> string_type;
230
231 // we don't care about the result of the "what" function.
232 // we only care that all generators have it:
233 karma::what(g);
234
235 string_type generated;
236 std::back_insert_iterator<string_type> outit(generated);
237 bool result = karma::generate_delimited(outit, g, d, attrib);
238
239 print_if_failed("test_delimited", result, generated, expected);
240 return result && generated == expected;
241 }
242
243 ///////////////////////////////////////////////////////////////////////////
244 template <typename Generator>
245 inline bool
246 binary_test(char const *expected, std::size_t size,
247 Generator const& g)
248 {
249 namespace karma = boost::spirit::karma;
250 typedef std::basic_string<char> string_type;
251
252 // we don't care about the result of the "what" function.
253 // we only care that all generators have it:
254 karma::what(g);
255
256 string_type generated;
257 std::back_insert_iterator<string_type> outit(generated);
258 bool result = karma::generate(outit, g);
259
260 print_binary_if_failed(func: "binary_test", result, generated
261 , expected: std::string(expected, size));
262 return result && generated.size() == size
263 && !std::memcmp(s1: generated.c_str(), s2: expected, n: size);
264 }
265
266 ///////////////////////////////////////////////////////////////////////////
267 template <typename Generator, typename Attribute>
268 inline bool
269 binary_test(char const *expected, std::size_t size,
270 Generator const& g, Attribute const &attrib)
271 {
272 namespace karma = boost::spirit::karma;
273 typedef std::basic_string<char> string_type;
274
275 // we don't care about the result of the "what" function.
276 // we only care that all generators have it:
277 karma::what(g);
278
279 string_type generated;
280 std::back_insert_iterator<string_type> outit(generated);
281 bool result = karma::generate(outit, g, attrib);
282
283 print_binary_if_failed(func: "binary_test", result, generated
284 , expected: std::string(expected, size));
285 return result && generated.size() == size
286 && !std::memcmp(s1: generated.c_str(), s2: expected, n: size);
287 }
288
289 ///////////////////////////////////////////////////////////////////////////
290 template <typename Generator, typename Delimiter>
291 inline bool
292 binary_test_delimited(char const *expected, std::size_t size,
293 Generator const& g, Delimiter const& d)
294 {
295 namespace karma = boost::spirit::karma;
296 typedef std::basic_string<char> string_type;
297
298 // we don't care about the result of the "what" function.
299 // we only care that all generators have it:
300 karma::what(g);
301
302 string_type generated;
303 std::back_insert_iterator<string_type> outit(generated);
304 bool result = karma::generate_delimited(outit, g, d);
305
306 print_binary_if_failed(func: "binary_test_delimited", result, generated
307 , expected: std::string(expected, size));
308 return result && generated.size() == size
309 && !std::memcmp(s1: generated.c_str(), s2: expected, n: size);
310 }
311
312 ///////////////////////////////////////////////////////////////////////////
313 template <typename Generator, typename Attribute, typename Delimiter>
314 inline bool
315 binary_test_delimited(char const *expected, std::size_t size,
316 Generator const& g, Attribute const &attrib, Delimiter const& d)
317 {
318 namespace karma = boost::spirit::karma;
319 typedef std::basic_string<char> string_type;
320
321 // we don't care about the result of the "what" function.
322 // we only care that all generators have it:
323 karma::what(g);
324
325 string_type generated;
326 std::back_insert_iterator<string_type> outit(generated);
327 bool result = karma::generate_delimited(outit, g, d, attrib);
328
329 print_binary_if_failed(func: "binary_test_delimited", result, generated
330 , expected: std::string(expected, size));
331 return result && generated.size() == size
332 && !std::memcmp(s1: generated.c_str(), s2: expected, n: size);
333 }
334
335} // namespace spirit_test
336
337#endif // !BOOST_SPIRIT_KARMA_TEST_FEB_23_2007_1221PM
338

source code of boost/libs/spirit/test/karma/test.hpp