]> git.proxmox.com Git - ceph.git/blob - ceph/src/boost/tools/quickbook/test/unit/symbols_tests.cpp
add subtree-ish sources for 12.0.3
[ceph.git] / ceph / src / boost / tools / quickbook / test / unit / symbols_tests.cpp
1 /*=============================================================================
2 Copyright (c) 1998-2003 Joel de Guzman
3 Copyright (c) 2003 Martin Wille
4 http://spirit.sourceforge.net/
5
6 Use, modification and distribution is subject to the Boost Software
7 License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
8 http://www.boost.org/LICENSE_1_0.txt)
9 =============================================================================*/
10 #include <iostream>
11 #include <string>
12 #include <boost/detail/lightweight_test.hpp>
13 #include <boost/spirit/include/classic_core.hpp>
14 #include <boost/spirit/include/classic_symbols.hpp>
15 #include <boost/detail/lightweight_test.hpp>
16 #include <boost/swap.hpp>
17 #include "symbols.hpp"
18
19 ///////////////////////////////////////////////////////////////////////////////
20 using namespace std;
21 using namespace BOOST_SPIRIT_CLASSIC_NS;
22
23 ///////////////////////////////////////////////////////////////////////////////
24
25 template <typename IteratorT>
26 bool
27 equal(IteratorT p, IteratorT q)
28 {
29 while (*p && *p == *q)
30 {
31 ++p;
32 ++q;
33 }
34 return *p == *q;
35 }
36
37 template <class SymbolsT, typename CharT>
38 void
39 docheck
40 (
41 SymbolsT const &sym,
42 CharT const *candidate,
43 bool hit,
44 CharT const *result,
45 int length
46 )
47 {
48 parse_info<CharT const*> info = parse(candidate, sym);
49
50 #define correctly_matched hit == info.hit
51 #define correct_match_length unsigned(length) == info.length
52 #define correct_tail equal(candidate + (hit?1:0)*length, result)
53
54 BOOST_TEST(correctly_matched);
55
56 if (hit)
57 {
58 BOOST_TEST(correct_match_length);
59 BOOST_TEST(correct_tail);
60 }
61 else
62 {
63 BOOST_TEST(correct_tail);
64 }
65 }
66
67 template <typename T>
68 struct store_action
69 {
70 store_action(T const &v) : value(v) {}
71 void operator()(T &v) const { v = value; }
72 private:
73 T const value;
74 };
75
76 template <typename T>
77 store_action<T>
78 store(T const &v)
79 {
80 return v;
81 }
82
83 template <typename T>
84 struct check_action
85 {
86 check_action(T const &v) : value(v) {}
87
88 #define correct_value_stored (v==value)
89 void operator()(T const &v) const { BOOST_TEST(correct_value_stored); }
90 private:
91 T const value;
92 };
93
94 template <typename T>
95 check_action<T>
96 docheck(T const &v)
97 {
98 return v;
99 }
100
101 static void
102 default_constructible()
103 { // this actually a compile time test
104 symbols<int, char, quickbook::tst<int, char> > ns1;
105 symbols<int, wchar_t, quickbook::tst<int, wchar_t> > ws1;
106 symbols<std::string, char, quickbook::tst<std::string, char> > ns2;
107 symbols<std::string, wchar_t, quickbook::tst<std::string, wchar_t> > ws2;
108
109 (void)ns1; (void)ws1; (void)ns2; (void)ws2;
110 }
111
112 typedef symbols<int, char, quickbook::tst<int, char> > nsymbols;
113 typedef symbols<int, wchar_t, quickbook::tst<int, wchar_t> > wsymbols;
114
115 static void
116 narrow_match_tests()
117 {
118 nsymbols sym;
119 sym = "pineapple", "orange", "banana", "applepie", "apple";
120
121 docheck(sym, "pineapple", true, "", 9);
122 docheck(sym, "orange", true, "", 6);
123 docheck(sym, "banana", true, "", 6);
124 docheck(sym, "apple", true, "", 5);
125 docheck(sym, "pizza", false, "pizza", -1);
126 docheck(sym, "steak", false, "steak", -1);
127 docheck(sym, "applepie", true, "", 8);
128 docheck(sym, "bananarama", true, "rama", 6);
129 docheck(sym, "applet", true, "t", 5);
130 docheck(sym, "applepi", true, "pi", 5);
131 docheck(sym, "appl", false, "appl", -1);
132
133 docheck(sym, "pineapplez", true, "z", 9);
134 docheck(sym, "orangez", true, "z", 6);
135 docheck(sym, "bananaz", true, "z", 6);
136 docheck(sym, "applez", true, "z", 5);
137 docheck(sym, "pizzaz", false, "pizzaz", -1);
138 docheck(sym, "steakz", false, "steakz", -1);
139 docheck(sym, "applepiez", true, "z", 8);
140 docheck(sym, "bananaramaz", true, "ramaz", 6);
141 docheck(sym, "appletz", true, "tz", 5);
142 docheck(sym, "applepix", true, "pix", 5);
143 }
144
145 static void
146 narrow_copy_ctor_tests()
147 {
148 nsymbols sym;
149 sym = "pineapple", "orange", "banana", "applepie", "apple";
150
151 nsymbols sym2(sym);
152 docheck(sym2, "pineapple", true, "", 9);
153 docheck(sym2, "pizza", false, "pizza", -1);
154 docheck(sym2, "bananarama", true, "rama", 6);
155 }
156
157 static void
158 narrow_assigment_operator_tests()
159 {
160 nsymbols sym;
161 sym = "pineapple", "orange", "banana", "applepie", "apple";
162
163 nsymbols sym2;
164 sym2 = sym;
165
166 docheck(sym2, "pineapple", true, "", 9);
167 docheck(sym2, "pizza", false, "pizza", -1);
168 docheck(sym2, "bananarama", true, "rama", 6);
169 }
170
171 static void
172 narrow_swap_tests()
173 {
174 nsymbols sym, sym2;
175 sym = "pineapple", "orange", "banana", "applepie", "apple";
176 sym2 = "potato", "cucumber", "cauliflower", "carrot";
177
178 boost::swap(sym, sym2);
179
180 docheck(sym2, "pineapple", true, "", 9);
181 docheck(sym2, "pizza", false, "pizza", -1);
182 docheck(sym2, "bananarama", true, "rama", 6);
183 docheck(sym, "potatoe", true, "e", 6);
184 docheck(sym, "cauliflour", false, "cauliflour", -1);
185 }
186
187 static void
188 narrow_value_tests()
189 { // also tests the add member functions
190 nsymbols sym;
191
192 sym = "orange", "banana";
193 sym.add("pineapple",1234);
194 sym.add("lemon");
195
196 parse("orange", sym[store(12345)]);
197 parse("orange", sym[docheck(12345)]);
198 parse("pineapple", sym[docheck(1234)]);
199 parse("banana", sym[docheck(int())]);
200 parse("lemon", sym[docheck(int())]);
201 }
202
203 static void
204 narrow_free_functions_tests()
205 {
206 nsymbols sym;
207
208 #define add_returned_non_null_value (res!=0)
209 #define add_returned_null (res==0)
210 #define find_returned_non_null_value (res!=0)
211 #define find_returned_null (res==0)
212
213 int *res = add(sym,"pineapple");
214 BOOST_TEST(add_returned_non_null_value);
215 res = add(sym,"pineapple");
216 BOOST_TEST(add_returned_null);
217
218 res = find(sym, "pineapple");
219 BOOST_TEST(find_returned_non_null_value);
220 res = find(sym, "banana");
221 BOOST_TEST(find_returned_null);
222 }
223
224 static void
225 wide_match_tests()
226 {
227 wsymbols sym;
228 sym = L"pineapple", L"orange", L"banana", L"applepie", L"apple";
229
230 docheck(sym, L"pineapple", true, L"", 9);
231 docheck(sym, L"orange", true, L"", 6);
232 docheck(sym, L"banana", true, L"", 6);
233 docheck(sym, L"apple", true, L"", 5);
234 docheck(sym, L"pizza", false, L"pizza", -1);
235 docheck(sym, L"steak", false, L"steak", -1);
236 docheck(sym, L"applepie", true, L"", 8);
237 docheck(sym, L"bananarama", true, L"rama", 6);
238 docheck(sym, L"applet", true, L"t", 5);
239 docheck(sym, L"applepi", true, L"pi", 5);
240 docheck(sym, L"appl", false, L"appl", -1);
241
242 docheck(sym, L"pineapplez", true, L"z", 9);
243 docheck(sym, L"orangez", true, L"z", 6);
244 docheck(sym, L"bananaz", true, L"z", 6);
245 docheck(sym, L"applez", true, L"z", 5);
246 docheck(sym, L"pizzaz", false, L"pizzaz", -1);
247 docheck(sym, L"steakz", false, L"steakz", -1);
248 docheck(sym, L"applepiez", true, L"z", 8);
249 docheck(sym, L"bananaramaz", true, L"ramaz", 6);
250 docheck(sym, L"appletz", true, L"tz", 5);
251 docheck(sym, L"applepix", true, L"pix", 5);
252 }
253
254 static void
255 wide_copy_ctor_tests()
256 {
257 wsymbols sym;
258 sym = L"pineapple", L"orange", L"banana", L"applepie", L"apple";
259
260 wsymbols sym2(sym);
261 docheck(sym2, L"pineapple", true, L"", 9);
262 docheck(sym2, L"pizza", false, L"pizza", -1);
263 docheck(sym2, L"bananarama", true, L"rama", 6);
264 }
265
266 static void
267 wide_assigment_operator_tests()
268 {
269 wsymbols sym;
270 sym = L"pineapple", L"orange", L"banana", L"applepie", L"apple";
271
272 wsymbols sym2;
273 sym2 = sym;
274
275 docheck(sym2, L"pineapple", true, L"", 9);
276 docheck(sym2, L"pizza", false, L"pizza", -1);
277 docheck(sym2, L"bananarama", true, L"rama", 6);
278 }
279
280 static void
281 wide_swap_tests()
282 {
283 wsymbols sym, sym2;
284 sym = L"pineapple", L"orange", L"banana", L"applepie", L"apple";
285 sym2 = L"potato", L"cucumber", L"cauliflower", L"carrot";
286
287 boost::swap(sym, sym2);
288
289 docheck(sym2, L"pineapple", true, L"", 9);
290 docheck(sym2, L"pizza", false, L"pizza", -1);
291 docheck(sym2, L"bananarama", true, L"rama", 6);
292 docheck(sym, L"potatoe", true, L"e", 6);
293 docheck(sym, L"cauliflour", false, L"cauliflour", -1);
294 }
295
296 static void
297 wide_value_tests()
298 { // also tests the add member functions
299 wsymbols sym;
300
301 sym = L"orange", L"banana";
302 sym.add(L"pineapple",1234);
303 sym.add(L"lemon");
304
305 parse(L"orange", sym[store(12345)]);
306 parse(L"orange", sym[docheck(12345)]);
307 parse(L"pineapple", sym[docheck(1234)]);
308 parse(L"banana", sym[docheck(int())]);
309 parse(L"lemon", sym[docheck(int())]);
310 }
311
312 static void
313 wide_free_functions_tests()
314 {
315 wsymbols sym;
316
317 int *res = add(sym,L"pineapple");
318 BOOST_TEST(add_returned_non_null_value);
319 res = add(sym,L"pineapple");
320 BOOST_TEST(add_returned_null);
321
322 res = find(sym, L"pineapple");
323 BOOST_TEST(find_returned_non_null_value);
324 res = find(sym, L"banana");
325 BOOST_TEST(find_returned_null);
326 }
327
328 static
329 void free_add_find_functions_tests()
330 {
331 nsymbols sym;
332 BOOST_TEST(*add(sym, "a", 0) == 0);
333 BOOST_TEST(*add(sym, "a2", 1) == 1);
334 BOOST_TEST(add(sym, "a2", 2) == 0);
335 BOOST_TEST(find(sym, "a2"));
336 BOOST_TEST(find(sym, "a"));
337 }
338
339 // The original teneray search tree implementation contained a bug when
340 // inserting duplicate values. I want this implementation to be as
341 // close as possible to the original (so they can be easily switched)
342 // so check that the bug remains the same.
343
344 struct check_parse_value
345 {
346 explicit check_parse_value(int value) : value_(value){}
347
348 void operator()(int value) const { BOOST_TEST(value == value_); }
349
350 int value_;
351 };
352
353 // My version is different to the original, if there's an existing value
354 // it replaces it with the new one.
355
356 static
357 void duplicate_add_tests()
358 {
359 char const* foo1 = "foo";
360 char const* foo2 = foo1 + 3;
361
362 nsymbols sym;
363 sym.add(foo1, foo2, 1);
364 nsymbols sym2 = sym;
365 sym.add(foo1, foo2, 2);
366 sym2.add(foo1, foo2, 3);
367
368 BOOST_TEST(find(sym, "foo") && *find(sym, "foo") == 2);
369 BOOST_TEST(find(sym2, "foo") && *find(sym2, "foo") == 3);
370
371 parse_info<char const*> info;
372
373 info = parse("foo ", sym[check_parse_value(2)]);
374 BOOST_TEST(info.hit && info.length == 3);
375
376 info = parse("foo", sym[check_parse_value(2)]);
377 BOOST_TEST(info.hit && info.length == 3);
378
379 info = parse("foo ", sym2[check_parse_value(3)]);
380 BOOST_TEST(info.hit && info.length == 3);
381
382 info = parse("foo", sym2[check_parse_value(3)]);
383 BOOST_TEST(info.hit && info.length == 3);
384 }
385
386 int
387 main()
388 {
389 default_constructible();
390 narrow_match_tests();
391 narrow_copy_ctor_tests();
392 narrow_assigment_operator_tests();
393 narrow_swap_tests();
394 narrow_value_tests();
395 narrow_free_functions_tests();
396 wide_match_tests();
397 wide_copy_ctor_tests();
398 wide_assigment_operator_tests();
399 wide_swap_tests();
400 wide_value_tests();
401 wide_free_functions_tests();
402 free_add_find_functions_tests();
403 duplicate_add_tests();
404
405 return boost::report_errors();
406 }