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