Mercurial > hg > vamp-build-and-test
comparison DEPENDENCIES/generic/include/boost/spirit/home/qi/char/char.hpp @ 16:2665513ce2d3
Add boost headers
author | Chris Cannam |
---|---|
date | Tue, 05 Aug 2014 11:11:38 +0100 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
15:663ca0da4350 | 16:2665513ce2d3 |
---|---|
1 /*============================================================================= | |
2 Copyright (c) 2001-2011 Joel de Guzman | |
3 Copyright (c) 2001-2011 Hartmut Kaiser | |
4 Copyright (c) 2010 Bryce Lelbach | |
5 | |
6 Distributed under the Boost Software License, Version 1.0. (See accompanying | |
7 file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) | |
8 ==============================================================================*/ | |
9 #if !defined(BOOST_SPIRIT_CHAR_APRIL_16_2006_1051AM) | |
10 #define BOOST_SPIRIT_CHAR_APRIL_16_2006_1051AM | |
11 | |
12 #if defined(_MSC_VER) | |
13 #pragma once | |
14 #endif | |
15 | |
16 #include <boost/spirit/home/support/common_terminals.hpp> | |
17 #include <boost/spirit/home/support/string_traits.hpp> | |
18 #include <boost/spirit/home/support/info.hpp> | |
19 #include <boost/spirit/home/support/detail/get_encoding.hpp> | |
20 #include <boost/spirit/home/support/char_set/basic_chset.hpp> | |
21 #include <boost/spirit/home/qi/char/char_parser.hpp> | |
22 #include <boost/spirit/home/qi/char/char_class.hpp> | |
23 #include <boost/spirit/home/qi/meta_compiler.hpp> | |
24 #include <boost/spirit/home/qi/auxiliary/lazy.hpp> | |
25 #include <boost/spirit/home/qi/detail/enable_lit.hpp> | |
26 #include <boost/fusion/include/at.hpp> | |
27 #include <boost/mpl/if.hpp> | |
28 #include <boost/mpl/assert.hpp> | |
29 #include <boost/mpl/identity.hpp> | |
30 #include <boost/utility/enable_if.hpp> | |
31 #include <boost/type_traits/remove_const.hpp> | |
32 #include <string> | |
33 | |
34 #if defined(_MSC_VER) | |
35 #pragma once | |
36 #endif | |
37 | |
38 namespace boost { namespace spirit | |
39 { | |
40 /////////////////////////////////////////////////////////////////////////// | |
41 // Enablers | |
42 /////////////////////////////////////////////////////////////////////////// | |
43 template <typename CharEncoding> | |
44 struct use_terminal<qi::domain | |
45 , terminal< | |
46 tag::char_code<tag::char_, CharEncoding> // enables char_ | |
47 > | |
48 > : mpl::true_ {}; | |
49 | |
50 template <typename CharEncoding, typename A0> | |
51 struct use_terminal<qi::domain | |
52 , terminal_ex< | |
53 tag::char_code<tag::char_, CharEncoding> // enables char_('x'), char_("x") | |
54 , fusion::vector1<A0> // and char_("a-z0-9") | |
55 > | |
56 > : mpl::true_ {}; | |
57 | |
58 template <typename CharEncoding, typename A0, typename A1> | |
59 struct use_terminal<qi::domain | |
60 , terminal_ex< | |
61 tag::char_code<tag::char_, CharEncoding> // enables char_('a','z') | |
62 , fusion::vector2<A0, A1> | |
63 > | |
64 > : mpl::true_ {}; | |
65 | |
66 template <typename CharEncoding> // enables *lazy* char_('x'), char_("x") | |
67 struct use_lazy_terminal< // and char_("a-z0-9") | |
68 qi::domain | |
69 , tag::char_code<tag::char_, CharEncoding> | |
70 , 1 // arity | |
71 > : mpl::true_ {}; | |
72 | |
73 template <typename CharEncoding> // enables *lazy* char_('a','z') | |
74 struct use_lazy_terminal< | |
75 qi::domain | |
76 , tag::char_code<tag::char_, CharEncoding> | |
77 , 2 // arity | |
78 > : mpl::true_ {}; | |
79 | |
80 template <> | |
81 struct use_terminal<qi::domain, char> // enables 'x' | |
82 : mpl::true_ {}; | |
83 | |
84 template <> | |
85 struct use_terminal<qi::domain, char[2]> // enables "x" | |
86 : mpl::true_ {}; | |
87 | |
88 template <> | |
89 struct use_terminal<qi::domain, wchar_t> // enables wchar_t | |
90 : mpl::true_ {}; | |
91 | |
92 template <> | |
93 struct use_terminal<qi::domain, wchar_t[2]> // enables L"x" | |
94 : mpl::true_ {}; | |
95 | |
96 // enables lit(...) | |
97 template <typename A0> | |
98 struct use_terminal<qi::domain | |
99 , terminal_ex<tag::lit, fusion::vector1<A0> > | |
100 , typename enable_if<traits::is_char<A0> >::type> | |
101 : mpl::true_ {}; | |
102 }} | |
103 | |
104 namespace boost { namespace spirit { namespace qi | |
105 { | |
106 #ifndef BOOST_SPIRIT_NO_PREDEFINED_TERMINALS | |
107 using spirit::lit; // lit('x') is equivalent to 'x' | |
108 #endif | |
109 using spirit::lit_type; | |
110 | |
111 /////////////////////////////////////////////////////////////////////////// | |
112 // Parser for a single character | |
113 /////////////////////////////////////////////////////////////////////////// | |
114 template <typename CharEncoding, bool no_attribute, bool no_case = false> | |
115 struct literal_char | |
116 : char_parser< | |
117 literal_char<CharEncoding, no_attribute, false> | |
118 , typename CharEncoding::char_type | |
119 , typename mpl::if_c<no_attribute, unused_type | |
120 , typename CharEncoding::char_type>::type> | |
121 { | |
122 typedef typename CharEncoding::char_type char_type; | |
123 typedef CharEncoding char_encoding; | |
124 | |
125 template <typename Char> | |
126 literal_char(Char ch_) | |
127 : ch(static_cast<char_type>(ch_)) {} | |
128 | |
129 template <typename Context, typename Iterator> | |
130 struct attribute | |
131 { | |
132 typedef typename mpl::if_c< | |
133 no_attribute, unused_type, char_type>::type | |
134 type; | |
135 }; | |
136 | |
137 template <typename CharParam, typename Context> | |
138 bool test(CharParam ch_, Context&) const | |
139 { | |
140 return traits::ischar<CharParam, char_encoding>::call(ch_) && | |
141 ch == char_type(ch_); | |
142 } | |
143 | |
144 template <typename Context> | |
145 info what(Context& /*context*/) const | |
146 { | |
147 return info("literal-char", char_encoding::toucs4(ch)); | |
148 } | |
149 | |
150 char_type ch; | |
151 }; | |
152 | |
153 template <typename CharEncoding, bool no_attribute> | |
154 struct literal_char<CharEncoding, no_attribute, true> // case insensitive | |
155 : char_parser< | |
156 literal_char<CharEncoding, no_attribute, true> | |
157 , typename mpl::if_c<no_attribute, unused_type | |
158 , typename CharEncoding::char_type>::type> | |
159 { | |
160 typedef typename CharEncoding::char_type char_type; | |
161 typedef CharEncoding char_encoding; | |
162 | |
163 literal_char(char_type ch) | |
164 : lo(static_cast<char_type>(char_encoding::tolower(ch))) | |
165 , hi(static_cast<char_type>(char_encoding::toupper(ch))) {} | |
166 | |
167 template <typename Context, typename Iterator> | |
168 struct attribute | |
169 { | |
170 typedef typename mpl::if_c< | |
171 no_attribute, unused_type, char_type>::type | |
172 type; | |
173 }; | |
174 | |
175 template <typename CharParam, typename Context> | |
176 bool test(CharParam ch_, Context&) const | |
177 { | |
178 if (!traits::ischar<CharParam, char_encoding>::call(ch_)) | |
179 return false; | |
180 | |
181 char_type ch = char_type(ch_); // optimize for token based parsing | |
182 return this->lo == ch || this->hi == ch; | |
183 } | |
184 | |
185 template <typename Context> | |
186 info what(Context& /*context*/) const | |
187 { | |
188 return info("no-case-literal-char", char_encoding::toucs4(lo)); | |
189 } | |
190 | |
191 char_type lo, hi; | |
192 }; | |
193 | |
194 /////////////////////////////////////////////////////////////////////////// | |
195 // Parser for a character range | |
196 /////////////////////////////////////////////////////////////////////////// | |
197 template <typename CharEncoding, bool no_case = false> | |
198 struct char_range | |
199 : char_parser<char_range<CharEncoding, false>, typename CharEncoding::char_type> | |
200 { | |
201 typedef typename CharEncoding::char_type char_type; | |
202 typedef CharEncoding char_encoding; | |
203 | |
204 char_range(char_type from_, char_type to_) | |
205 : from(from_), to(to_) {} | |
206 | |
207 template <typename CharParam, typename Context> | |
208 bool test(CharParam ch_, Context&) const | |
209 { | |
210 if (!traits::ischar<CharParam, char_encoding>::call(ch_)) | |
211 return false; | |
212 | |
213 char_type ch = char_type(ch_); // optimize for token based parsing | |
214 return !(ch < from) && !(to < ch); | |
215 } | |
216 | |
217 template <typename Context> | |
218 info what(Context& /*context*/) const | |
219 { | |
220 info result("char-range", char_encoding::toucs4(from)); | |
221 boost::get<std::string>(result.value) += '-'; | |
222 boost::get<std::string>(result.value) += to_utf8(char_encoding::toucs4(to)); | |
223 return result; | |
224 } | |
225 | |
226 char_type from, to; | |
227 }; | |
228 | |
229 template <typename CharEncoding> | |
230 struct char_range<CharEncoding, true> // case insensitive | |
231 : char_parser<char_range<CharEncoding, true>, typename CharEncoding::char_type> | |
232 { | |
233 typedef typename CharEncoding::char_type char_type; | |
234 typedef CharEncoding char_encoding; | |
235 | |
236 char_range(char_type from, char_type to) | |
237 : from_lo(static_cast<char_type>(char_encoding::tolower(from))) | |
238 , to_lo(static_cast<char_type>(char_encoding::tolower(to))) | |
239 , from_hi(static_cast<char_type>(char_encoding::toupper(from))) | |
240 , to_hi(static_cast<char_type>(char_encoding::toupper(to))) | |
241 {} | |
242 | |
243 template <typename CharParam, typename Context> | |
244 bool test(CharParam ch_, Context&) const | |
245 { | |
246 if (!traits::ischar<CharParam, char_encoding>::call(ch_)) | |
247 return false; | |
248 | |
249 char_type ch = char_type(ch_); // optimize for token based parsing | |
250 return (!(ch < from_lo) && !(to_lo < ch)) | |
251 || (!(ch < from_hi) && !(to_hi < ch)) | |
252 ; | |
253 } | |
254 | |
255 template <typename Context> | |
256 info what(Context& /*context*/) const | |
257 { | |
258 info result("no-case-char-range", char_encoding::toucs4(from_lo)); | |
259 boost::get<std::string>(result.value) += '-'; | |
260 boost::get<std::string>(result.value) += to_utf8(char_encoding::toucs4(to_lo)); | |
261 return result; | |
262 } | |
263 | |
264 char_type from_lo, to_lo, from_hi, to_hi; | |
265 }; | |
266 | |
267 /////////////////////////////////////////////////////////////////////////// | |
268 // Parser for a character set | |
269 /////////////////////////////////////////////////////////////////////////// | |
270 template <typename CharEncoding, bool no_attribute, bool no_case = false> | |
271 struct char_set | |
272 : char_parser<char_set<CharEncoding, no_attribute, false> | |
273 , typename mpl::if_c<no_attribute, unused_type | |
274 , typename CharEncoding::char_type>::type> | |
275 { | |
276 typedef typename CharEncoding::char_type char_type; | |
277 typedef CharEncoding char_encoding; | |
278 | |
279 template <typename String> | |
280 char_set(String const& str) | |
281 { | |
282 using spirit::detail::cast_char; | |
283 | |
284 typedef typename | |
285 remove_const< | |
286 typename traits::char_type_of<String>::type | |
287 >::type | |
288 in_type; | |
289 | |
290 BOOST_SPIRIT_ASSERT_MSG(( | |
291 (sizeof(char_type) >= sizeof(in_type)) | |
292 ), cannot_convert_string, (String)); | |
293 | |
294 in_type const* definition = | |
295 (in_type const*)traits::get_c_string(str); | |
296 in_type ch = *definition++; | |
297 while (ch) | |
298 { | |
299 in_type next = *definition++; | |
300 if (next == '-') | |
301 { | |
302 next = *definition++; | |
303 if (next == 0) | |
304 { | |
305 chset.set(cast_char<char_type>(ch)); | |
306 chset.set('-'); | |
307 break; | |
308 } | |
309 chset.set( | |
310 cast_char<char_type>(ch), | |
311 cast_char<char_type>(next) | |
312 ); | |
313 } | |
314 else | |
315 { | |
316 chset.set(cast_char<char_type>(ch)); | |
317 } | |
318 ch = next; | |
319 } | |
320 } | |
321 | |
322 template <typename CharParam, typename Context> | |
323 bool test(CharParam ch, Context&) const | |
324 { | |
325 return traits::ischar<CharParam, char_encoding>::call(ch) && | |
326 chset.test(char_type(ch)); | |
327 } | |
328 | |
329 template <typename Context> | |
330 info what(Context& /*context*/) const | |
331 { | |
332 return info("char-set"); | |
333 } | |
334 | |
335 support::detail::basic_chset<char_type> chset; | |
336 }; | |
337 | |
338 template <typename CharEncoding, bool no_attribute> | |
339 struct char_set<CharEncoding, no_attribute, true> // case insensitive | |
340 : char_parser<char_set<CharEncoding, no_attribute, true> | |
341 , typename mpl::if_c<no_attribute, unused_type | |
342 , typename CharEncoding::char_type>::type> | |
343 { | |
344 typedef typename CharEncoding::char_type char_type; | |
345 typedef CharEncoding char_encoding; | |
346 | |
347 template <typename String> | |
348 char_set(String const& str) | |
349 { | |
350 typedef typename traits::char_type_of<String>::type in_type; | |
351 | |
352 BOOST_SPIRIT_ASSERT_MSG(( | |
353 (sizeof(char_type) == sizeof(in_type)) | |
354 ), cannot_convert_string, (String)); | |
355 | |
356 char_type const* definition = | |
357 (char_type const*)traits::get_c_string(str); | |
358 char_type ch = *definition++; | |
359 while (ch) | |
360 { | |
361 char_type next = *definition++; | |
362 if (next == '-') | |
363 { | |
364 next = *definition++; | |
365 if (next == 0) | |
366 { | |
367 chset.set(static_cast<char_type>(CharEncoding::tolower(ch))); | |
368 chset.set(static_cast<char_type>(CharEncoding::toupper(ch))); | |
369 chset.set('-'); | |
370 break; | |
371 } | |
372 chset.set(static_cast<char_type>(CharEncoding::tolower(ch)) | |
373 , static_cast<char_type>(CharEncoding::tolower(next))); | |
374 chset.set(static_cast<char_type>(CharEncoding::toupper(ch)) | |
375 , static_cast<char_type>(CharEncoding::toupper(next))); | |
376 } | |
377 else | |
378 { | |
379 chset.set(static_cast<char_type>(CharEncoding::tolower(ch))); | |
380 chset.set(static_cast<char_type>(CharEncoding::toupper(ch))); | |
381 } | |
382 ch = next; | |
383 } | |
384 } | |
385 | |
386 template <typename CharParam, typename Context> | |
387 bool test(CharParam ch, Context&) const | |
388 { | |
389 return traits::ischar<CharParam, char_encoding>::call(ch) && | |
390 chset.test(char_type(ch)); | |
391 } | |
392 | |
393 template <typename Context> | |
394 info what(Context& /*context*/) const | |
395 { | |
396 return info("no-case-char-set"); | |
397 } | |
398 | |
399 support::detail::basic_chset<char_type> chset; | |
400 }; | |
401 | |
402 /////////////////////////////////////////////////////////////////////////// | |
403 // Parser generators: make_xxx function (objects) | |
404 /////////////////////////////////////////////////////////////////////////// | |
405 namespace detail | |
406 { | |
407 template <typename Modifiers, typename Encoding> | |
408 struct basic_literal | |
409 { | |
410 static bool const no_case = | |
411 has_modifier< | |
412 Modifiers | |
413 , tag::char_code_base<tag::no_case> | |
414 >::value; | |
415 | |
416 static bool const no_attr = | |
417 !has_modifier< | |
418 Modifiers | |
419 , tag::lazy_eval | |
420 >::value; | |
421 | |
422 typedef literal_char< | |
423 typename spirit::detail::get_encoding_with_case< | |
424 Modifiers, Encoding, no_case>::type | |
425 , no_attr | |
426 , no_case> | |
427 result_type; | |
428 | |
429 template <typename Char> | |
430 result_type operator()(Char ch, unused_type) const | |
431 { | |
432 return result_type(ch); | |
433 } | |
434 | |
435 template <typename Char> | |
436 result_type operator()(Char const* str, unused_type) const | |
437 { | |
438 return result_type(str[0]); | |
439 } | |
440 }; | |
441 } | |
442 | |
443 template <typename Modifiers> | |
444 struct make_primitive<char, Modifiers> | |
445 : detail::basic_literal<Modifiers, char_encoding::standard> {}; | |
446 | |
447 template <typename Modifiers> | |
448 struct make_primitive<char const(&)[2], Modifiers> | |
449 : detail::basic_literal<Modifiers, char_encoding::standard> {}; | |
450 | |
451 template <typename Modifiers> | |
452 struct make_primitive<wchar_t, Modifiers> | |
453 : detail::basic_literal<Modifiers, char_encoding::standard_wide> {}; | |
454 | |
455 template <typename Modifiers> | |
456 struct make_primitive<wchar_t const(&)[2], Modifiers> | |
457 : detail::basic_literal<Modifiers, char_encoding::standard_wide> {}; | |
458 | |
459 template <typename CharEncoding, typename Modifiers> | |
460 struct make_primitive< | |
461 terminal<tag::char_code<tag::char_, CharEncoding> >, Modifiers> | |
462 { | |
463 typedef typename | |
464 spirit::detail::get_encoding<Modifiers, CharEncoding>::type | |
465 char_encoding; | |
466 | |
467 typedef tag::char_code<tag::char_, char_encoding> tag; | |
468 typedef char_class<tag> result_type; | |
469 result_type operator()(unused_type, unused_type) const | |
470 { | |
471 return result_type(); | |
472 } | |
473 }; | |
474 | |
475 /////////////////////////////////////////////////////////////////////////// | |
476 // char_('x') | |
477 template <typename CharEncoding, typename Modifiers, typename A0> | |
478 struct make_primitive< | |
479 terminal_ex< | |
480 tag::char_code<tag::char_, CharEncoding> | |
481 , fusion::vector1<A0> > | |
482 , Modifiers> | |
483 { | |
484 static bool const no_case = | |
485 has_modifier<Modifiers, tag::char_code_base<tag::no_case> >::value; | |
486 | |
487 typedef typename | |
488 spirit::detail::get_encoding<Modifiers, CharEncoding>::type | |
489 char_encoding; | |
490 | |
491 typedef typename | |
492 mpl::if_< | |
493 traits::is_string<A0> | |
494 , char_set<char_encoding, false, no_case> | |
495 , literal_char<char_encoding, false, no_case> | |
496 >::type | |
497 result_type; | |
498 | |
499 template <typename Terminal> | |
500 result_type operator()(Terminal const& term, unused_type) const | |
501 { | |
502 return result_type(fusion::at_c<0>(term.args)); | |
503 } | |
504 }; | |
505 | |
506 // lit('x') | |
507 template <typename Modifiers, typename A0> | |
508 struct make_primitive< | |
509 terminal_ex<tag::lit, fusion::vector1<A0> > | |
510 , Modifiers | |
511 , typename enable_if<traits::is_char<A0> >::type> | |
512 { | |
513 static bool const no_case = | |
514 has_modifier< | |
515 Modifiers | |
516 , tag::char_code_base<tag::no_case> | |
517 >::value; | |
518 | |
519 typedef typename traits::char_encoding_from_char< | |
520 typename traits::char_type_of<A0>::type>::type encoding; | |
521 | |
522 typedef literal_char< | |
523 typename spirit::detail::get_encoding_with_case< | |
524 Modifiers, encoding, no_case>::type | |
525 , true, no_case> | |
526 result_type; | |
527 | |
528 template <typename Terminal> | |
529 result_type operator()(Terminal const& term, unused_type) const | |
530 { | |
531 return result_type(fusion::at_c<0>(term.args)); | |
532 } | |
533 }; | |
534 | |
535 /////////////////////////////////////////////////////////////////////////// | |
536 template <typename CharEncoding, typename Modifiers, typename Char> | |
537 struct make_primitive< | |
538 terminal_ex< | |
539 tag::char_code<tag::char_, CharEncoding> | |
540 , fusion::vector1<Char(&)[2]> // For single char strings | |
541 > | |
542 , Modifiers> | |
543 { | |
544 static bool const no_case = | |
545 has_modifier<Modifiers, tag::char_code_base<tag::no_case> >::value; | |
546 | |
547 typedef typename | |
548 spirit::detail::get_encoding<Modifiers, CharEncoding>::type | |
549 char_encoding; | |
550 | |
551 typedef literal_char<char_encoding, false, no_case> result_type; | |
552 | |
553 template <typename Terminal> | |
554 result_type operator()(Terminal const& term, unused_type) const | |
555 { | |
556 return result_type(fusion::at_c<0>(term.args)[0]); | |
557 } | |
558 }; | |
559 | |
560 template <typename CharEncoding, typename Modifiers, typename A0, typename A1> | |
561 struct make_primitive< | |
562 terminal_ex< | |
563 tag::char_code<tag::char_, CharEncoding> | |
564 , fusion::vector2<A0, A1> | |
565 > | |
566 , Modifiers> | |
567 { | |
568 static bool const no_case = | |
569 has_modifier<Modifiers, tag::char_code_base<tag::no_case> >::value; | |
570 | |
571 typedef typename | |
572 spirit::detail::get_encoding<Modifiers, CharEncoding>::type | |
573 char_encoding; | |
574 | |
575 typedef char_range<char_encoding, no_case> result_type; | |
576 | |
577 template <typename Terminal> | |
578 result_type operator()(Terminal const& term, unused_type) const | |
579 { | |
580 return result_type( | |
581 fusion::at_c<0>(term.args) | |
582 , fusion::at_c<1>(term.args) | |
583 ); | |
584 } | |
585 }; | |
586 | |
587 template <typename CharEncoding, typename Modifiers, typename Char> | |
588 struct make_primitive< | |
589 terminal_ex< | |
590 tag::char_code<tag::char_, CharEncoding> | |
591 , fusion::vector2<Char(&)[2], Char(&)[2]> // For single char strings | |
592 > | |
593 , Modifiers> | |
594 { | |
595 static bool const no_case = | |
596 has_modifier<Modifiers, tag::char_code_base<tag::no_case> >::value; | |
597 | |
598 typedef typename | |
599 spirit::detail::get_encoding<Modifiers, CharEncoding>::type | |
600 char_encoding; | |
601 | |
602 typedef char_range<char_encoding, no_case> result_type; | |
603 | |
604 template <typename Terminal> | |
605 result_type operator()(Terminal const& term, unused_type) const | |
606 { | |
607 return result_type( | |
608 fusion::at_c<0>(term.args)[0] | |
609 , fusion::at_c<1>(term.args)[0] | |
610 ); | |
611 } | |
612 }; | |
613 }}} | |
614 | |
615 #endif |