1 | /*============================================================================= |
2 | Copyright (c) 2001-2010 Joel de Guzman |
3 | |
4 | Distributed under the Boost Software License, Version 1.0. (See accompanying |
5 | file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) |
6 | =============================================================================*/ |
7 | #include <boost/spirit/home/qi/string/tst.hpp> |
8 | #include <boost/spirit/home/qi/string/tst_map.hpp> |
9 | |
10 | #include <boost/core/lightweight_test.hpp> |
11 | #include <string> |
12 | #include <cctype> |
13 | #include <iostream> |
14 | |
15 | namespace |
16 | { |
17 | template <typename TST, typename Char> |
18 | void add(TST& tst, Char const* s, int data) |
19 | { |
20 | Char const* last = s; |
21 | while (*last) |
22 | last++; |
23 | tst.add(s, last, data); |
24 | } |
25 | |
26 | template <typename TST, typename Char> |
27 | void remove(TST& tst, Char const* s) |
28 | { |
29 | Char const* last = s; |
30 | while (*last) |
31 | last++; |
32 | tst.remove(s, last); |
33 | } |
34 | |
35 | template <typename TST, typename Char> |
36 | void docheck(TST const& tst, Char const* s, bool expected, int N = 0, int val = -1) |
37 | { |
38 | Char const* first = s; |
39 | Char const* last = s; |
40 | while (*last) |
41 | last++; |
42 | int* r = tst.find(s, last); |
43 | BOOST_TEST((r != 0) == expected); |
44 | BOOST_TEST((s-first) == N); |
45 | if (r) |
46 | BOOST_TEST(*r == val); |
47 | } |
48 | |
49 | struct printer |
50 | { |
51 | template <typename String, typename Data> |
52 | void operator()(String const& s, Data const& data) |
53 | { |
54 | std::cout << " " << s << ": " << data << std::endl; |
55 | } |
56 | }; |
57 | |
58 | template <typename TST> |
59 | void print(TST const& tst) |
60 | { |
61 | std::cout << '[' << std::endl; |
62 | tst.for_each(printer()); |
63 | std::cout << ']' << std::endl; |
64 | } |
65 | |
66 | struct no_case_filter |
67 | { |
68 | template <typename Char> |
69 | Char operator()(Char ch) const |
70 | { |
71 | return static_cast<Char>(std::tolower(ch)); |
72 | } |
73 | }; |
74 | |
75 | template <typename TST, typename Char> |
76 | void nc_check(TST const& tst, Char const* s, bool expected, int N = 0, int val = -1) |
77 | { |
78 | Char const* first = s; |
79 | Char const* last = s; |
80 | while (*last) |
81 | last++; |
82 | int* r = tst.find(s, last, no_case_filter()); |
83 | BOOST_TEST((r != 0) == expected); |
84 | if (r != 0) |
85 | BOOST_TEST((s-first) == N); |
86 | if (r) |
87 | BOOST_TEST(*r == val); |
88 | } |
89 | } |
90 | |
91 | template <typename Lookup, typename WideLookup> |
92 | void tests() |
93 | { |
94 | { // basic tests |
95 | Lookup lookup; |
96 | |
97 | docheck(lookup, "not-yet-there" , false); |
98 | docheck(lookup, "" , false); |
99 | |
100 | add(lookup, "apple" , 123); |
101 | docheck(lookup, "apple" , true, 5, 123); // full match |
102 | docheck(lookup, "banana" , false); // no-match |
103 | docheck(lookup, "applexxx" , true, 5, 123); // partial match |
104 | |
105 | add(lookup, "applepie" , 456); |
106 | docheck(lookup, "applepie" , true, 8, 456); // full match |
107 | docheck(lookup, "banana" , false); // no-match |
108 | docheck(lookup, "applepiexxx" , true, 8, 456); // partial match |
109 | docheck(lookup, "apple" , true, 5, 123); // full match |
110 | docheck(lookup, "applexxx" , true, 5, 123); // partial match |
111 | docheck(lookup, "adam" , false); // no-match |
112 | |
113 | add(lookup, "a" , 101); |
114 | docheck(lookup, "applepie" , true, 8, 456); // full match |
115 | docheck(lookup, "banana" , false); // no-match |
116 | docheck(lookup, "applepiexxx" , true, 8, 456); // partial match |
117 | docheck(lookup, "apple" , true, 5, 123); // full match |
118 | docheck(lookup, "applexxx" , true, 5, 123); // partial match |
119 | docheck(lookup, "adam" , true, 1, 101); // partial match |
120 | } |
121 | |
122 | { // variation of above |
123 | Lookup lookup; |
124 | |
125 | add(lookup, "applepie" , 456); |
126 | add(lookup, "apple" , 123); |
127 | |
128 | docheck(lookup, "applepie" , true, 8, 456); // full match |
129 | docheck(lookup, "banana" , false); // no-match |
130 | docheck(lookup, "applepiexxx" , true, 8, 456); // partial match |
131 | docheck(lookup, "apple" , true, 5, 123); // full match |
132 | docheck(lookup, "applexxx" , true, 5, 123); // partial match |
133 | } |
134 | { // variation of above |
135 | Lookup lookup; |
136 | |
137 | add(lookup, "applepie" , 456); |
138 | add(lookup, "apple" , 123); |
139 | |
140 | docheck(lookup, "applepie" , true, 8, 456); // full match |
141 | docheck(lookup, "banana" , false); // no-match |
142 | docheck(lookup, "applepiexxx" , true, 8, 456); // partial match |
143 | docheck(lookup, "apple" , true, 5, 123); // full match |
144 | docheck(lookup, "applexxx" , true, 5, 123); // partial match |
145 | } |
146 | |
147 | { // narrow char tests |
148 | Lookup lookup; |
149 | add(lookup, "pineapple" , 1); |
150 | add(lookup, "orange" , 2); |
151 | add(lookup, "banana" , 3); |
152 | add(lookup, "applepie" , 4); |
153 | add(lookup, "apple" , 5); |
154 | |
155 | docheck(lookup, "pineapple" , true, 9, 1); |
156 | docheck(lookup, "orange" , true, 6, 2); |
157 | docheck(lookup, "banana" , true, 6, 3); |
158 | docheck(lookup, "apple" , true, 5, 5); |
159 | docheck(lookup, "pizza" , false); |
160 | docheck(lookup, "steak" , false); |
161 | docheck(lookup, "applepie" , true, 8, 4); |
162 | docheck(lookup, "bananarama" , true, 6, 3); |
163 | docheck(lookup, "applet" , true, 5, 5); |
164 | docheck(lookup, "applepi" , true, 5, 5); |
165 | docheck(lookup, "appl" , false); |
166 | |
167 | docheck(lookup, "pineapplez" , true, 9, 1); |
168 | docheck(lookup, "orangez" , true, 6, 2); |
169 | docheck(lookup, "bananaz" , true, 6, 3); |
170 | docheck(lookup, "applez" , true, 5, 5); |
171 | docheck(lookup, "pizzaz" , false); |
172 | docheck(lookup, "steakz" , false); |
173 | docheck(lookup, "applepiez" , true, 8, 4); |
174 | docheck(lookup, "bananaramaz" , true, 6, 3); |
175 | docheck(lookup, "appletz" , true, 5, 5); |
176 | docheck(lookup, "applepix" , true, 5, 5); |
177 | } |
178 | |
179 | { // wide char tests |
180 | WideLookup lookup; |
181 | add(lookup, L"pineapple" , 1); |
182 | add(lookup, L"orange" , 2); |
183 | add(lookup, L"banana" , 3); |
184 | add(lookup, L"applepie" , 4); |
185 | add(lookup, L"apple" , 5); |
186 | |
187 | docheck(lookup, L"pineapple" , true, 9, 1); |
188 | docheck(lookup, L"orange" , true, 6, 2); |
189 | docheck(lookup, L"banana" , true, 6, 3); |
190 | docheck(lookup, L"apple" , true, 5, 5); |
191 | docheck(lookup, L"pizza" , false); |
192 | docheck(lookup, L"steak" , false); |
193 | docheck(lookup, L"applepie" , true, 8, 4); |
194 | docheck(lookup, L"bananarama" , true, 6, 3); |
195 | docheck(lookup, L"applet" , true, 5, 5); |
196 | docheck(lookup, L"applepi" , true, 5, 5); |
197 | docheck(lookup, L"appl" , false); |
198 | |
199 | docheck(lookup, L"pineapplez" , true, 9, 1); |
200 | docheck(lookup, L"orangez" , true, 6, 2); |
201 | docheck(lookup, L"bananaz" , true, 6, 3); |
202 | docheck(lookup, L"applez" , true, 5, 5); |
203 | docheck(lookup, L"pizzaz" , false); |
204 | docheck(lookup, L"steakz" , false); |
205 | docheck(lookup, L"applepiez" , true, 8, 4); |
206 | docheck(lookup, L"bananaramaz" , true, 6, 3); |
207 | docheck(lookup, L"appletz" , true, 5, 5); |
208 | docheck(lookup, L"applepix" , true, 5, 5); |
209 | } |
210 | |
211 | { // test remove |
212 | Lookup lookup; |
213 | add(lookup, "pineapple" , 1); |
214 | add(lookup, "orange" , 2); |
215 | add(lookup, "banana" , 3); |
216 | add(lookup, "applepie" , 4); |
217 | add(lookup, "apple" , 5); |
218 | |
219 | docheck(lookup, "pineapple" , true, 9, 1); |
220 | docheck(lookup, "orange" , true, 6, 2); |
221 | docheck(lookup, "banana" , true, 6, 3); |
222 | docheck(lookup, "apple" , true, 5, 5); |
223 | docheck(lookup, "applepie" , true, 8, 4); |
224 | docheck(lookup, "bananarama" , true, 6, 3); |
225 | docheck(lookup, "applet" , true, 5, 5); |
226 | docheck(lookup, "applepi" , true, 5, 5); |
227 | docheck(lookup, "appl" , false); |
228 | |
229 | remove(lookup, "banana" ); |
230 | docheck(lookup, "pineapple" , true, 9, 1); |
231 | docheck(lookup, "orange" , true, 6, 2); |
232 | docheck(lookup, "banana" , false); |
233 | docheck(lookup, "apple" , true, 5, 5); |
234 | docheck(lookup, "applepie" , true, 8, 4); |
235 | docheck(lookup, "bananarama" , false); |
236 | docheck(lookup, "applet" , true, 5, 5); |
237 | docheck(lookup, "applepi" , true, 5, 5); |
238 | docheck(lookup, "appl" , false); |
239 | |
240 | remove(lookup, "apple" ); |
241 | docheck(lookup, "pineapple" , true, 9, 1); |
242 | docheck(lookup, "orange" , true, 6, 2); |
243 | docheck(lookup, "apple" , false); |
244 | docheck(lookup, "applepie" , true, 8, 4); |
245 | docheck(lookup, "applet" , false); |
246 | docheck(lookup, "applepi" , false); |
247 | docheck(lookup, "appl" , false); |
248 | |
249 | remove(lookup, "orange" ); |
250 | docheck(lookup, "pineapple" , true, 9, 1); |
251 | docheck(lookup, "orange" , false); |
252 | docheck(lookup, "applepie" , true, 8, 4); |
253 | |
254 | remove(lookup, "pineapple" ); |
255 | docheck(lookup, "pineapple" , false); |
256 | docheck(lookup, "orange" , false); |
257 | docheck(lookup, "applepie" , true, 8, 4); |
258 | |
259 | remove(lookup, "applepie" ); |
260 | docheck(lookup, "applepie" , false); |
261 | } |
262 | |
263 | { // copy/assign/clear test |
264 | Lookup lookupa; |
265 | add(lookupa, "pineapple" , 1); |
266 | add(lookupa, "orange" , 2); |
267 | add(lookupa, "banana" , 3); |
268 | add(lookupa, "applepie" , 4); |
269 | add(lookupa, "apple" , 5); |
270 | |
271 | Lookup lookupb(lookupa); // copy ctor |
272 | docheck(lookupb, "pineapple" , true, 9, 1); |
273 | docheck(lookupb, "orange" , true, 6, 2); |
274 | docheck(lookupb, "banana" , true, 6, 3); |
275 | docheck(lookupb, "apple" , true, 5, 5); |
276 | docheck(lookupb, "pizza" , false); |
277 | docheck(lookupb, "steak" , false); |
278 | docheck(lookupb, "applepie" , true, 8, 4); |
279 | docheck(lookupb, "bananarama" , true, 6, 3); |
280 | docheck(lookupb, "applet" , true, 5, 5); |
281 | docheck(lookupb, "applepi" , true, 5, 5); |
282 | docheck(lookupb, "appl" , false); |
283 | |
284 | lookupb.clear(); // clear |
285 | docheck(lookupb, "pineapple" , false); |
286 | docheck(lookupb, "orange" , false); |
287 | docheck(lookupb, "banana" , false); |
288 | docheck(lookupb, "apple" , false); |
289 | docheck(lookupb, "applepie" , false); |
290 | docheck(lookupb, "bananarama" , false); |
291 | docheck(lookupb, "applet" , false); |
292 | docheck(lookupb, "applepi" , false); |
293 | docheck(lookupb, "appl" , false); |
294 | |
295 | lookupb = lookupa; // assign |
296 | docheck(lookupb, "pineapple" , true, 9, 1); |
297 | docheck(lookupb, "orange" , true, 6, 2); |
298 | docheck(lookupb, "banana" , true, 6, 3); |
299 | docheck(lookupb, "apple" , true, 5, 5); |
300 | docheck(lookupb, "pizza" , false); |
301 | docheck(lookupb, "steak" , false); |
302 | docheck(lookupb, "applepie" , true, 8, 4); |
303 | docheck(lookupb, "bananarama" , true, 6, 3); |
304 | docheck(lookupb, "applet" , true, 5, 5); |
305 | docheck(lookupb, "applepi" , true, 5, 5); |
306 | docheck(lookupb, "appl" , false); |
307 | } |
308 | |
309 | { // test for_each |
310 | Lookup lookup; |
311 | add(lookup, "pineapple" , 1); |
312 | add(lookup, "orange" , 2); |
313 | add(lookup, "banana" , 3); |
314 | add(lookup, "applepie" , 4); |
315 | add(lookup, "apple" , 5); |
316 | |
317 | print(lookup); |
318 | } |
319 | |
320 | { // case insensitive tests |
321 | Lookup lookup; |
322 | |
323 | // NOTE: make sure all entries are in lower-case!!! |
324 | add(lookup, "pineapple" , 1); |
325 | add(lookup, "orange" , 2); |
326 | add(lookup, "banana" , 3); |
327 | add(lookup, "applepie" , 4); |
328 | add(lookup, "apple" , 5); |
329 | |
330 | nc_check(lookup, "pineapple" , true, 9, 1); |
331 | nc_check(lookup, "orange" , true, 6, 2); |
332 | nc_check(lookup, "banana" , true, 6, 3); |
333 | nc_check(lookup, "apple" , true, 5, 5); |
334 | nc_check(lookup, "applepie" , true, 8, 4); |
335 | |
336 | nc_check(lookup, "PINEAPPLE" , true, 9, 1); |
337 | nc_check(lookup, "ORANGE" , true, 6, 2); |
338 | nc_check(lookup, "BANANA" , true, 6, 3); |
339 | nc_check(lookup, "APPLE" , true, 5, 5); |
340 | nc_check(lookup, "APPLEPIE" , true, 8, 4); |
341 | |
342 | nc_check(lookup, "pineApple" , true, 9, 1); |
343 | nc_check(lookup, "orangE" , true, 6, 2); |
344 | nc_check(lookup, "Banana" , true, 6, 3); |
345 | nc_check(lookup, "aPPLe" , true, 5, 5); |
346 | nc_check(lookup, "ApplePie" , true, 8, 4); |
347 | |
348 | print(lookup); |
349 | } |
350 | } |
351 | |
352 | int main() |
353 | { |
354 | using boost::spirit::qi::tst; |
355 | using boost::spirit::qi::tst_map; |
356 | |
357 | tests<tst<char, int>, tst<wchar_t, int> >(); |
358 | tests<tst_map<char, int>, tst_map<wchar_t, int> >(); |
359 | |
360 | return boost::report_errors(); |
361 | } |
362 | |
363 | |