]>
Commit | Line | Data |
---|---|---|
7c673cae FG |
1 | /*============================================================================= |
2 | Copyright (c) 2001-2011 Joel de Guzman | |
3 | Copyright (c) 2011 Thomas Bernard | |
4 | ||
5 | Distributed under the Boost Software License, Version 1.0. (See accompanying | |
6 | file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) | |
7 | =============================================================================*/ | |
8 | #if !defined(SPIRIT_KWD_NOVEMBER_14_2008_1148AM) | |
9 | #define SPIRIT_KWD_NOVEMBER_14_2008_1148AM | |
10 | ||
11 | #if defined(_MSC_VER) | |
12 | #pragma once | |
13 | #endif | |
14 | ||
15 | #include <boost/spirit/home/qi/meta_compiler.hpp> | |
16 | #include <boost/spirit/home/qi/parser.hpp> | |
17 | #include <boost/spirit/home/qi/auxiliary/lazy.hpp> | |
18 | #include <boost/spirit/home/qi/operator/kleene.hpp> | |
19 | #include <boost/spirit/home/support/container.hpp> | |
20 | #include <boost/spirit/home/qi/detail/attributes.hpp> | |
21 | #include <boost/spirit/home/qi/detail/fail_function.hpp> | |
22 | #include <boost/spirit/home/support/info.hpp> | |
23 | #include <boost/spirit/repository/home/support/kwd.hpp> | |
24 | #include <boost/fusion/include/at.hpp> | |
25 | #include <boost/foreach.hpp> | |
26 | #include <vector> | |
27 | ||
28 | namespace boost { namespace spirit | |
29 | { | |
30 | /////////////////////////////////////////////////////////////////////////// | |
31 | // Enablers | |
32 | /////////////////////////////////////////////////////////////////////////// | |
33 | ||
34 | template < typename T> | |
35 | struct use_directive<qi::domain | |
36 | , terminal_ex<repository::tag::kwd // enables kwd(key)[p] | |
37 | , fusion::vector1<T > > | |
38 | > : mpl::true_ {}; | |
39 | ||
40 | template < typename T> | |
41 | struct use_directive<qi::domain | |
42 | , terminal_ex<repository::tag::ikwd // enables ikwd(key)[p] | |
43 | , fusion::vector1<T > > | |
44 | > : mpl::true_ {}; | |
45 | ||
46 | template < typename T> | |
47 | struct use_directive<qi::domain | |
48 | , terminal_ex<repository::tag::dkwd // enables dkwd(key)[p] | |
49 | , fusion::vector1<T > > | |
50 | > : mpl::true_ {}; | |
51 | ||
52 | template < typename T> | |
53 | struct use_directive<qi::domain | |
54 | , terminal_ex<repository::tag::idkwd // enables idkwd(key)[p] | |
55 | , fusion::vector1<T > > | |
56 | > : mpl::true_ {}; | |
57 | ||
58 | ||
59 | template < typename T1, typename T2> | |
60 | struct use_directive<qi::domain | |
61 | , terminal_ex<repository::tag::kwd // enables kwd(key,exact)[p] | |
62 | , fusion::vector2< T1, T2 > > | |
63 | > : mpl::true_ {}; | |
64 | ||
65 | template < typename T1, typename T2> | |
66 | struct use_directive<qi::domain | |
67 | , terminal_ex<repository::tag::ikwd // enables ikwd(key,exact)[p] | |
68 | , fusion::vector2< T1, T2 > > | |
69 | > : mpl::true_ {}; | |
70 | ||
71 | template < typename T1, typename T2> | |
72 | struct use_directive<qi::domain | |
73 | , terminal_ex<repository::tag::dkwd // enables dkwd(key,exact)[p] | |
74 | , fusion::vector2< T1, T2 > > | |
75 | > : mpl::true_ {}; | |
76 | ||
77 | template < typename T1, typename T2> | |
78 | struct use_directive<qi::domain | |
79 | , terminal_ex<repository::tag::idkwd // enables idkwd(key,exact)[p] | |
80 | , fusion::vector2< T1, T2 > > | |
81 | > : mpl::true_ {}; | |
82 | ||
83 | template < typename T1, typename T2> | |
84 | struct use_directive<qi::domain | |
85 | , terminal_ex<repository::tag::kwd // enables kwd(min, max)[p] | |
86 | , fusion::vector3< T1, T2, T2 > > | |
87 | > : mpl::true_ {}; | |
88 | ||
89 | template < typename T1, typename T2> | |
90 | struct use_directive<qi::domain | |
91 | , terminal_ex<repository::tag::ikwd // enables ikwd(min, max)[p] | |
92 | , fusion::vector3< T1, T2, T2 > > | |
93 | > : mpl::true_ {}; | |
94 | ||
95 | template < typename T1, typename T2> | |
96 | struct use_directive<qi::domain | |
97 | , terminal_ex<repository::tag::dkwd // enables dkwd(min, max)[p] | |
98 | , fusion::vector3< T1, T2, T2 > > | |
99 | > : mpl::true_ {}; | |
100 | ||
101 | template < typename T1, typename T2> | |
102 | struct use_directive<qi::domain | |
103 | , terminal_ex<repository::tag::idkwd // enables idkwd(min, max)[p] | |
104 | , fusion::vector3< T1, T2, T2 > > | |
105 | > : mpl::true_ {}; | |
106 | ||
107 | template < typename T1, typename T2> | |
108 | struct use_directive<qi::domain | |
109 | , terminal_ex<repository::tag::kwd // enables kwd(min, inf)[p] | |
110 | , fusion::vector3<T1, T2, inf_type > > | |
111 | > : mpl::true_ {}; | |
112 | ||
113 | template < typename T1, typename T2> | |
114 | struct use_directive<qi::domain | |
115 | , terminal_ex<repository::tag::ikwd // enables ikwd(min, inf)[p] | |
116 | , fusion::vector3<T1, T2, inf_type > > | |
117 | > : mpl::true_ {}; | |
118 | ||
119 | template < typename T1, typename T2> | |
120 | struct use_directive<qi::domain | |
121 | , terminal_ex<repository::tag::dkwd // enables dkwd(min, inf)[p] | |
122 | , fusion::vector3<T1, T2, inf_type > > | |
123 | > : mpl::true_ {}; | |
124 | ||
125 | template < typename T1, typename T2> | |
126 | struct use_directive<qi::domain | |
127 | , terminal_ex<repository::tag::idkwd // enables idkwd(min, inf)[p] | |
128 | , fusion::vector3<T1, T2, inf_type > > | |
129 | > : mpl::true_ {}; | |
130 | ||
131 | ||
132 | /* template <> // enables *lazy* kwd(exact)[p] | |
133 | struct use_lazy_directive< | |
134 | qi::domain | |
135 | , tag::kwd | |
136 | , 1 // arity | |
137 | > : mpl::true_ {}; | |
138 | ||
139 | template <> // enables *lazy* kwd(min, max)[p] | |
140 | struct use_lazy_directive< // and kwd(min, inf)[p] | |
141 | qi::domain | |
142 | , tag::kwd | |
143 | , 2 // arity | |
144 | > : mpl::true_ {}; | |
145 | */ | |
146 | ||
147 | }} | |
148 | ||
149 | namespace boost { namespace spirit { namespace repository { namespace qi | |
150 | { | |
151 | using repository::kwd; | |
152 | using repository::ikwd; | |
153 | using repository::dkwd; | |
154 | using repository::idkwd; | |
155 | using spirit::inf; | |
156 | using spirit::inf_type; | |
157 | ||
158 | template <typename T> | |
159 | struct kwd_pass_iterator // handles kwd(exact)[p] | |
160 | { | |
161 | kwd_pass_iterator() {} | |
162 | bool flag_init() const { return true; } | |
163 | bool register_successful_parse(bool &flag,T &i) const { | |
164 | flag=true; | |
165 | return true; | |
166 | } | |
167 | ||
168 | ||
169 | private: | |
170 | // silence MSVC warning C4512: assignment operator could not be generated | |
171 | kwd_pass_iterator& operator= (kwd_pass_iterator const&); | |
172 | }; | |
173 | ||
174 | template <typename T> | |
175 | struct kwd_exact_iterator // handles kwd(exact)[p] | |
176 | { | |
177 | kwd_exact_iterator(T const exact) | |
178 | : exact(exact){} | |
179 | ||
180 | typedef T type; | |
181 | bool flag_init() const { return false; } | |
182 | bool register_successful_parse(bool &flag,T &i) const { | |
183 | i++; | |
184 | if(i<exact) | |
185 | { | |
186 | flag=false; | |
187 | return true; | |
188 | } | |
189 | else if(i==exact) | |
190 | { | |
191 | flag=true; | |
192 | return true; | |
193 | } | |
194 | else | |
195 | return flag=false; | |
196 | ||
197 | } | |
198 | T const exact; | |
199 | ||
200 | private: | |
201 | // silence MSVC warning C4512: assignment operator could not be generated | |
202 | kwd_exact_iterator& operator= (kwd_exact_iterator const&); | |
203 | }; | |
204 | ||
205 | template <typename T> | |
206 | struct kwd_finite_iterator // handles kwd(min, max)[p] | |
207 | { | |
208 | kwd_finite_iterator(T const min, T const max) | |
209 | : min BOOST_PREVENT_MACRO_SUBSTITUTION (min) | |
210 | , max BOOST_PREVENT_MACRO_SUBSTITUTION (max) | |
211 | {} | |
212 | ||
213 | typedef T type; | |
214 | bool flag_init() const { return min==0; } | |
215 | bool register_successful_parse(bool &flag,T &i) const { | |
216 | i++; | |
217 | if(i<min) | |
218 | { | |
219 | flag=false; | |
220 | return true; | |
221 | } | |
222 | else if(i>=min && i<=max) | |
223 | { | |
224 | return flag=true; | |
225 | } | |
226 | else | |
227 | return flag=false; | |
228 | } | |
229 | T const min; | |
230 | T const max; | |
231 | ||
232 | private: | |
233 | // silence MSVC warning C4512: assignment operator could not be generated | |
234 | kwd_finite_iterator& operator= (kwd_finite_iterator const&); | |
235 | }; | |
236 | ||
237 | template <typename T> | |
238 | struct kwd_infinite_iterator // handles kwd(min, inf)[p] | |
239 | { | |
240 | kwd_infinite_iterator(T const min) | |
241 | : min BOOST_PREVENT_MACRO_SUBSTITUTION (min) {} | |
242 | ||
243 | typedef T type; | |
244 | bool flag_init() const { return min==0; } | |
245 | bool register_successful_parse(bool &flag,T &i) const { | |
246 | i++; | |
247 | flag = i>=min; | |
248 | return true; | |
249 | } | |
250 | T const min; | |
251 | ||
252 | private: | |
253 | // silence MSVC warning C4512: assignment operator could not be generated | |
254 | kwd_infinite_iterator& operator= (kwd_infinite_iterator const&); | |
255 | }; | |
256 | ||
257 | // This class enables the transportation of parameters needed to call | |
258 | // the occurrence constraint checker from higher level calls | |
259 | // It also serves to select the correct parse function call | |
260 | // of the keyword parser. The implementation changes depending if it is | |
261 | // called form a keyword parsing loop or not. | |
262 | template <typename Skipper, typename NoCasePass> | |
263 | struct skipper_keyword_marker | |
264 | { | |
265 | typedef NoCasePass no_case_pass; | |
266 | ||
267 | skipper_keyword_marker(Skipper const &skipper,bool &flag,int &counter) : | |
268 | skipper(skipper) | |
269 | , flag(flag) | |
270 | , counter(counter) | |
271 | {} | |
272 | ||
273 | const Skipper &skipper; | |
274 | bool &flag; | |
275 | int &counter; | |
276 | }; | |
277 | ||
278 | template <typename Subject, typename KeywordType, typename LoopIter , typename NoCase, typename Distinct > | |
279 | struct kwd_parser : spirit::qi::unary_parser<kwd_parser<Subject, KeywordType, LoopIter , NoCase, Distinct > > | |
280 | { | |
281 | struct kwd_parser_id; | |
282 | ||
283 | typedef Subject subject_type; | |
284 | typedef NoCase no_case_keyword; | |
285 | typedef Distinct distinct; | |
286 | ||
287 | typedef typename | |
288 | remove_const<typename traits::char_type_of<KeywordType>::type>::type | |
289 | char_type; | |
290 | ||
291 | typedef std::basic_string<char_type> keyword_type; | |
292 | ||
293 | template <typename Context, typename Iterator> | |
294 | struct attribute | |
295 | { | |
296 | typedef typename | |
297 | traits::build_std_vector< | |
298 | typename traits::attribute_of< | |
299 | Subject, Context, Iterator>::type | |
300 | >::type | |
301 | type; | |
302 | }; | |
303 | ||
304 | ||
305 | kwd_parser(Subject const& subject | |
306 | , typename add_reference<KeywordType>::type keyword | |
307 | , LoopIter const& iter) | |
308 | : subject(subject), iter(iter), keyword(keyword) {} | |
309 | ||
310 | template<typename CharEncoding> | |
311 | kwd_parser(Subject const& subject | |
312 | , typename add_reference<KeywordType>::type keyword | |
313 | , LoopIter const& iter, CharEncoding encoding) | |
314 | : subject(subject), iter(iter), keyword(keyword,encoding) {} | |
315 | ||
316 | ||
317 | // Call the subject parser on a non container attribute | |
318 | template <typename Iterator, typename Context | |
319 | , typename Skipper, typename Attribute> | |
320 | bool parse_impl(Iterator& first, Iterator const& last | |
321 | , Context& context, Skipper const& skipper | |
322 | , Attribute& attr,mpl::false_) const | |
323 | { | |
324 | return subject.parse(first,last,context,skipper,attr); | |
325 | } | |
326 | ||
327 | // Call the subject parser on a container attribute | |
328 | template <typename Iterator, typename Context | |
329 | , typename Skipper, typename Attribute> | |
330 | bool parse_impl(Iterator& first, Iterator const& last | |
331 | , Context& context, Skipper const& skipper | |
332 | , Attribute& attr,mpl::true_) const | |
333 | { | |
334 | ||
335 | // synthesized attribute needs to be default constructed | |
336 | typename traits::container_value<Attribute>::type val = | |
337 | typename traits::container_value<Attribute>::type(); | |
338 | ||
339 | Iterator save = first; | |
340 | bool r = subject.parse(first,last,context,skipper, val); | |
341 | if (r) | |
342 | { | |
343 | // push the parsed value into our attribute | |
344 | r = traits::push_back(attr, val); | |
345 | if (!r) | |
346 | first = save; | |
347 | } | |
348 | return r; | |
349 | } | |
350 | ||
351 | template <typename Iterator, typename Context | |
352 | , typename Skipper, typename Attribute,typename NoCasePass> | |
353 | bool parse(Iterator& first, Iterator const& last | |
354 | , Context& context, skipper_keyword_marker<Skipper,NoCasePass> const& skipper | |
355 | , Attribute &attr) const | |
356 | { | |
357 | ||
358 | typedef typename traits::attribute_of< | |
359 | Subject, Context, Iterator>::type | |
360 | subject_attribute; | |
361 | ||
362 | typedef typename mpl::and_< | |
363 | traits::is_container<Attribute> | |
364 | , mpl::not_< traits::is_weak_substitute< subject_attribute,Attribute > > | |
365 | >::type predicate; | |
366 | ||
367 | if((no_case_keyword::value && NoCasePass::value) || !NoCasePass::value) | |
368 | { | |
369 | if(parse_impl(first,last,context,skipper.skipper,attr, predicate())) | |
370 | return iter.register_successful_parse(skipper.flag,skipper.counter); | |
371 | } | |
372 | return false; | |
373 | } | |
374 | ||
375 | template <typename Iterator, typename Context | |
376 | , typename Skipper, typename Attribute> | |
377 | bool parse(Iterator& first, Iterator const& last | |
378 | , Context& context, Skipper const& skipper | |
379 | , Attribute& attr) const | |
380 | { | |
381 | typedef typename traits::attribute_of< | |
382 | Subject, Context, Iterator>::type | |
383 | subject_attribute; | |
384 | ||
385 | typedef typename mpl::and_< | |
386 | traits::is_container<Attribute> | |
387 | , mpl::not_< traits::is_weak_substitute< subject_attribute,Attribute > > | |
388 | >::type predicate; | |
389 | ||
390 | ||
391 | // Parse the keyword | |
392 | bool flag = iter.flag_init(); | |
393 | int counter = 0; | |
394 | Iterator save = first; | |
395 | spirit::qi::skip_over(first, last, skipper); | |
396 | if(keyword.parse(first,last,context,skipper,unused)){ | |
397 | if((!distinct::value) || skipper.parse(first,last,unused,unused,unused)){ | |
398 | // Followed by the subject parser | |
399 | spirit::qi::skip_over(first, last, skipper); | |
400 | if(parse_impl(first,last,context,skipper,attr, predicate())) | |
401 | { | |
402 | return iter.register_successful_parse(flag,counter); | |
403 | } | |
404 | } | |
405 | } | |
406 | first = save; | |
407 | return flag; | |
408 | } | |
409 | ||
410 | ||
411 | template <typename Context> | |
412 | info what(Context& context) const | |
413 | { | |
414 | if(distinct::value){ | |
415 | if(no_case_keyword::value) | |
416 | return info("idkwd", subject.what(context)); | |
417 | else | |
418 | return info("dkwd", subject.what(context)); | |
419 | } | |
420 | else | |
421 | { | |
422 | if(no_case_keyword::value) | |
423 | return info("ikwd", subject.what(context)); | |
424 | else | |
425 | return info("kwd", subject.what(context)); | |
426 | } | |
427 | } | |
428 | ||
429 | Subject subject; | |
430 | LoopIter iter; | |
431 | ||
432 | typedef typename mpl::if_< | |
433 | no_case_keyword, | |
434 | spirit::qi::no_case_literal_string< KeywordType, true>, | |
435 | spirit::qi::literal_string<KeywordType, true> >::type keyword_string_type; | |
436 | keyword_string_type keyword; | |
437 | private: | |
438 | // silence MSVC warning C4512: assignment operator could not be generated | |
439 | kwd_parser& operator= (kwd_parser const&); | |
440 | ||
441 | template <typename Iterator, typename Context, typename Skipper> | |
442 | static spirit::qi::detail::fail_function<Iterator, Context, Skipper> | |
443 | fail_function( | |
444 | Iterator& first, Iterator const& last | |
445 | , Context& context, Skipper const& skipper) | |
446 | { | |
447 | return spirit::qi::detail::fail_function<Iterator, Context, Skipper> | |
448 | (first, last, context, skipper); | |
449 | } | |
450 | ||
451 | ||
452 | }; | |
453 | ||
454 | template <typename Subject, typename KeywordType, typename LoopIter, typename Distinct> | |
455 | struct complex_kwd_parser : spirit::qi::unary_parser<complex_kwd_parser<Subject, KeywordType, LoopIter, Distinct > > | |
456 | { | |
457 | struct complex_kwd_parser_id; | |
458 | typedef Subject subject_type; | |
459 | typedef Distinct distinct; | |
460 | ||
461 | template <typename Context, typename Iterator> | |
462 | struct attribute | |
463 | { | |
464 | typedef typename | |
465 | traits::build_std_vector< | |
466 | typename traits::attribute_of< | |
467 | Subject, Context, Iterator>::type | |
468 | >::type | |
469 | type; | |
470 | }; | |
471 | ||
472 | ||
473 | complex_kwd_parser(Subject const& subject | |
474 | , typename add_reference<KeywordType>::type keyword | |
475 | , LoopIter const& iter) | |
476 | : subject(subject), iter(iter), keyword(keyword) {} | |
477 | ||
478 | // Call the subject parser on a non container attribute | |
479 | template <typename Iterator, typename Context | |
480 | , typename Skipper, typename Attribute> | |
481 | bool parse_impl(Iterator& first, Iterator const& last | |
482 | , Context& context, Skipper const& skipper | |
483 | , Attribute& attr,mpl::false_) const | |
484 | { | |
485 | return subject.parse(first,last,context,skipper,attr); | |
486 | } | |
487 | ||
488 | // Call the subject parser on a container attribute | |
489 | template <typename Iterator, typename Context | |
490 | , typename Skipper, typename Attribute> | |
491 | bool parse_impl(Iterator& first, Iterator const& last | |
492 | , Context& context, Skipper const& skipper | |
493 | , Attribute& attr,mpl::true_) const | |
494 | { | |
495 | ||
496 | // synthesized attribute needs to be default constructed | |
497 | typename traits::container_value<Attribute>::type val = | |
498 | typename traits::container_value<Attribute>::type(); | |
499 | ||
500 | Iterator save = first; | |
501 | bool r = subject.parse(first,last,context,skipper, val); | |
502 | if (r) | |
503 | { | |
504 | // push the parsed value into our attribute | |
505 | r = traits::push_back(attr, val); | |
506 | if (!r) | |
507 | first = save; | |
508 | } | |
509 | return r; | |
510 | } | |
511 | ||
512 | template <typename Iterator, typename Context | |
513 | , typename Skipper, typename Attribute,typename NoCasePass> | |
514 | bool parse(Iterator& first, Iterator const& last | |
515 | , Context& context, skipper_keyword_marker<Skipper,NoCasePass> const& skipper | |
516 | , Attribute &attr) const | |
517 | { | |
518 | ||
519 | typedef typename traits::attribute_of< | |
520 | Subject, Context, Iterator>::type | |
521 | subject_attribute; | |
522 | ||
523 | typedef typename mpl::and_< | |
524 | traits::is_container<Attribute> | |
525 | , mpl::not_< traits::is_weak_substitute< subject_attribute,Attribute > > | |
526 | >::type predicate; | |
527 | ||
528 | if(parse_impl(first,last,context,skipper.skipper,attr, predicate())) | |
529 | return iter.register_successful_parse(skipper.flag,skipper.counter); | |
530 | return false; | |
531 | } | |
532 | ||
533 | template <typename Iterator, typename Context | |
534 | , typename Skipper, typename Attribute> | |
535 | bool parse(Iterator& first, Iterator const& last | |
536 | , Context& context, Skipper const& skipper | |
537 | , Attribute& attr) const | |
538 | { | |
539 | typedef typename traits::attribute_of< | |
540 | Subject, Context, Iterator>::type | |
541 | subject_attribute; | |
542 | ||
543 | typedef typename mpl::and_< | |
544 | traits::is_container<Attribute> | |
545 | , mpl::not_< traits::is_weak_substitute< subject_attribute,Attribute > > | |
546 | >::type predicate; | |
547 | ||
548 | ||
549 | // Parse the keyword | |
550 | bool flag = iter.flag_init(); | |
551 | int counter = 0; | |
552 | Iterator save = first; | |
553 | spirit::qi::skip_over(first, last, skipper); | |
554 | if(keyword.parse(first,last,context,skipper,unused)){ | |
555 | if( !distinct::value || skipper.parse(first,last,unused,unused,unused)){ | |
556 | // Followed by the subject parser | |
557 | spirit::qi::skip_over(first, last, skipper); | |
558 | if(parse_impl(first,last,context,skipper,attr, predicate())) | |
559 | { | |
560 | return iter.register_successful_parse(flag,counter); | |
561 | } | |
562 | } | |
563 | } | |
564 | first = save; | |
565 | return flag; | |
566 | } | |
567 | ||
568 | ||
569 | template <typename Context> | |
570 | info what(Context& context) const | |
571 | { | |
572 | if(distinct::value) | |
573 | return info("dkwd", subject.what(context)); | |
574 | else | |
575 | return info("kwd", subject.what(context)); | |
576 | } | |
577 | ||
578 | Subject subject; | |
579 | LoopIter iter; | |
580 | ||
581 | KeywordType keyword; | |
582 | private: | |
583 | // silence MSVC warning C4512: assignment operator could not be generated | |
584 | complex_kwd_parser& operator= (complex_kwd_parser const&); | |
585 | ||
586 | template <typename Iterator, typename Context, typename Skipper> | |
587 | static spirit::qi::detail::fail_function<Iterator, Context, Skipper> | |
588 | fail_function( | |
589 | Iterator& first, Iterator const& last | |
590 | , Context& context, Skipper const& skipper) | |
591 | { | |
592 | return spirit::qi::detail::fail_function<Iterator, Context, Skipper> | |
593 | (first, last, context, skipper); | |
594 | } | |
595 | ||
596 | }; | |
597 | ||
598 | }}}} | |
599 | ||
600 | /////////////////////////////////////////////////////////////////////////////// | |
601 | namespace boost { namespace spirit { namespace qi | |
602 | { | |
603 | ||
604 | /////////////////////////////////////////////////////////////////////////// | |
605 | // Parser generators: make_xxx function (objects) | |
606 | /////////////////////////////////////////////////////////////////////////// | |
607 | ||
608 | template <typename T1, typename T2, typename Subject, typename Modifiers, typename Distinct, typename MakeDirectiveHelper> | |
609 | struct make_directive_internal_2_args | |
610 | { | |
611 | ||
612 | // is the keyword a string keyword ? | |
613 | typedef typename traits::is_string<T1> is_string_kwd_type; | |
614 | // make the keyword type | |
615 | typedef typename mpl::if_< is_string_kwd_type , | |
616 | T1 , | |
617 | typename result_of::compile<qi::domain, T1>::type | |
618 | >::type keyword_type; | |
619 | ||
620 | typedef typename add_const<keyword_type>::type const_keyword; | |
621 | // select the pass iterator type | |
622 | typedef typename MakeDirectiveHelper::iterator_type iterator_type; | |
623 | // determine if a no case modifier applies to the context | |
624 | typedef has_modifier<Modifiers, tag::char_code_base<tag::no_case> > no_case; | |
625 | // Determine the full type of the kwd / complex_kwd directive | |
626 | typedef typename | |
627 | mpl::if_< | |
628 | is_string_kwd_type, | |
629 | repository::qi::kwd_parser<Subject, const_keyword, iterator_type, no_case, Distinct >, | |
630 | repository::qi::complex_kwd_parser<Subject, const_keyword, iterator_type, Distinct > | |
631 | >::type result_type; | |
632 | ||
633 | // Return a kwd parser object | |
634 | template <typename Terminal> | |
635 | result_type create_kwd_string(Terminal const &term, Subject const & subject, boost::mpl::true_ ) const | |
636 | { | |
637 | typename spirit::detail::get_encoding<Modifiers, | |
638 | spirit::char_encoding::standard>::type encoding; | |
639 | return result_type(subject | |
640 | ,MakeDirectiveHelper::make_iterator(term.args) | |
641 | ,encoding | |
642 | ); | |
643 | } | |
644 | template <typename Terminal> | |
645 | result_type create_kwd_string(Terminal const &term, Subject const & subject, boost::mpl::false_ ) const | |
646 | { | |
647 | return result_type(subject | |
648 | ,fusion::at_c<0>(term.args) | |
649 | ,MakeDirectiveHelper::make_iterator(term.args) | |
650 | ); | |
651 | } | |
652 | template <typename Terminal> | |
653 | result_type create_kwd(Terminal const &term, Subject const & subject, Modifiers const& modifiers, boost::mpl::true_ ) const | |
654 | { | |
655 | return create_kwd_string(term,subject,no_case()); | |
656 | } | |
657 | // Return a complex_kwd parser object | |
658 | template <typename Terminal> | |
659 | result_type create_kwd(Terminal const &term , Subject const & subject, Modifiers const& modifiers, boost::mpl::false_ ) const | |
660 | { | |
661 | return result_type(subject | |
662 | ,compile<qi::domain>(fusion::at_c<0>(term.args),modifiers) | |
663 | ,MakeDirectiveHelper::make_iterator(term.args) | |
664 | ); | |
665 | } | |
666 | // Select which object type to return | |
667 | template <typename Terminal> | |
668 | result_type operator()( | |
669 | Terminal const& term, Subject const& subject, Modifiers const& modifiers) const | |
670 | { | |
671 | return create_kwd(term, subject, modifiers, is_string_kwd_type()); | |
672 | } | |
673 | ||
674 | }; | |
675 | ||
676 | // Directive kwd(key)[p] | |
677 | template <typename T1, typename Subject, typename Modifiers, typename Distinct> | |
678 | struct make_directive_internal | |
679 | { | |
680 | // is the keyword a string keyword ? | |
681 | typedef typename traits::is_string<T1> is_string_kwd_type; | |
682 | // make the keyword type | |
683 | typedef typename mpl::if_< is_string_kwd_type , | |
684 | T1 , | |
685 | typename result_of::compile<qi::domain, T1, Modifiers>::type | |
686 | >::type keyword_type; | |
687 | ||
688 | typedef typename add_const<keyword_type>::type const_keyword; | |
689 | // select the pass iterator type | |
690 | typedef repository::qi::kwd_pass_iterator<int> iterator_type; | |
691 | // determine if a no case modifier applies to the context | |
692 | typedef has_modifier<Modifiers, tag::char_code_base<tag::no_case> > no_case; | |
693 | // Determine the full type of the kwd / complex_kwd directive | |
694 | typedef typename | |
695 | mpl::if_< | |
696 | is_string_kwd_type, | |
697 | repository::qi::kwd_parser<Subject, const_keyword, iterator_type, no_case, Distinct >, | |
698 | repository::qi::complex_kwd_parser<Subject, const_keyword, iterator_type, Distinct> | |
699 | >::type result_type; | |
700 | ||
701 | // Return a kwd parser object | |
702 | template <typename Terminal> | |
703 | result_type create_kwd_string(Terminal const &term, Subject const & subject, boost::mpl::true_) const | |
704 | { | |
705 | typename spirit::detail::get_encoding<Modifiers, | |
706 | spirit::char_encoding::standard>::type encoding; | |
707 | ||
708 | return result_type(subject | |
709 | ,fusion::at_c<0>(term.args) | |
710 | ,iterator_type() | |
711 | ,encoding | |
712 | ); | |
713 | ||
714 | } | |
715 | template <typename Terminal> | |
716 | result_type create_kwd_string(Terminal const &term, Subject const & subject, boost::mpl::false_) const | |
717 | { | |
718 | return result_type(subject | |
719 | ,fusion::at_c<0>(term.args) | |
720 | ,iterator_type() | |
721 | ); | |
722 | } | |
723 | template <typename Terminal> | |
724 | result_type create_kwd(Terminal const &term, Subject const & subject, Modifiers const& modifiers, boost::mpl::true_ ) const | |
725 | { | |
726 | return create_kwd_string(term,subject,no_case()); | |
727 | } | |
728 | // Return a complex_kwd parser object | |
729 | template <typename Terminal> | |
730 | result_type create_kwd(Terminal const &term , Subject const & subject, Modifiers const& modifiers, boost::mpl::false_ ) const | |
731 | { | |
732 | return result_type(subject | |
733 | ,compile<qi::domain>(fusion::at_c<0>(term.args),modifiers) | |
734 | ,iterator_type() | |
735 | ); | |
736 | } | |
737 | // Select which object type to return | |
738 | template <typename Terminal> | |
739 | result_type operator()( | |
740 | Terminal const& term, Subject const& subject, Modifiers const& modifiers ) const | |
741 | { | |
742 | return create_kwd(term, subject, modifiers, is_string_kwd_type()); | |
743 | } | |
744 | }; | |
745 | ||
746 | template <typename T1, typename Subject, typename Modifiers> | |
747 | struct make_directive< | |
748 | terminal_ex<repository::tag::kwd, fusion::vector1<T1> >, Subject, Modifiers> | |
749 | { | |
750 | typedef make_directive_internal<T1, Subject, Modifiers, mpl::false_> make_directive_type; | |
751 | typedef typename make_directive_type::result_type result_type; | |
752 | template <typename Terminal> | |
753 | result_type operator()( | |
754 | Terminal const& term, Subject const& subject, Modifiers const& modifiers) const | |
755 | { | |
756 | ||
757 | return make_directive_type()(term, subject, modifiers); | |
758 | } | |
759 | ||
760 | }; | |
761 | ||
762 | template <typename T1, typename Subject, typename Modifiers> | |
763 | struct make_directive< | |
764 | terminal_ex<repository::tag::dkwd, fusion::vector1<T1> >, Subject, Modifiers> | |
765 | { | |
766 | typedef make_directive_internal<T1, Subject, Modifiers, mpl::true_> make_directive_type; | |
767 | typedef typename make_directive_type::result_type result_type; | |
768 | template <typename Terminal> | |
769 | result_type operator()( | |
770 | Terminal const& term, Subject const& subject, Modifiers const& modifiers) const | |
771 | { | |
772 | ||
773 | return make_directive_type()(term, subject, modifiers); | |
774 | } | |
775 | ||
776 | }; | |
777 | ||
778 | ||
779 | ||
780 | // Directive ikwd(key)[p] | |
781 | template <typename T1, typename Subject, typename Modifiers> | |
782 | struct make_directive< | |
783 | terminal_ex<repository::tag::ikwd, fusion::vector1<T1> >, Subject, Modifiers> | |
784 | { | |
785 | typedef typename add_const<T1>::type const_keyword; | |
786 | typedef repository::qi::kwd_pass_iterator<int> iterator_type; | |
787 | ||
788 | typedef repository::qi::kwd_parser<Subject, const_keyword, iterator_type, mpl::true_, mpl::false_ > result_type; | |
789 | ||
790 | template <typename Terminal> | |
791 | result_type operator()( | |
792 | Terminal const& term, Subject const& subject, unused_type) const | |
793 | { | |
794 | typename spirit::detail::get_encoding<Modifiers, | |
795 | spirit::char_encoding::standard>::type encoding; | |
796 | ||
797 | return result_type(subject | |
798 | ,fusion::at_c<0>(term.args) | |
799 | ,iterator_type() | |
800 | ,encoding | |
801 | ); | |
802 | } | |
803 | }; | |
804 | ||
805 | template <typename T1, typename Subject, typename Modifiers> | |
806 | struct make_directive< | |
807 | terminal_ex<repository::tag::idkwd, fusion::vector1<T1> >, Subject, Modifiers> | |
808 | { | |
809 | typedef typename add_const<T1>::type const_keyword; | |
810 | typedef repository::qi::kwd_pass_iterator<int> iterator_type; | |
811 | ||
812 | typedef repository::qi::kwd_parser<Subject, const_keyword, iterator_type, mpl::true_, mpl::true_ > result_type; | |
813 | ||
814 | template <typename Terminal> | |
815 | result_type operator()( | |
816 | Terminal const& term, Subject const& subject, unused_type) const | |
817 | { | |
818 | typename spirit::detail::get_encoding<Modifiers, | |
819 | spirit::char_encoding::standard>::type encoding; | |
820 | ||
821 | return result_type(subject | |
822 | ,fusion::at_c<0>(term.args) | |
823 | ,iterator_type() | |
824 | ,encoding | |
825 | ); | |
826 | } | |
827 | }; | |
828 | ||
829 | // Directive kwd(key,exact)[p] | |
830 | template <typename T> | |
831 | struct make_exact_helper | |
832 | { | |
833 | typedef repository::qi::kwd_exact_iterator<T> iterator_type; | |
834 | template<typename Args> | |
835 | static iterator_type make_iterator(Args const& args) | |
836 | { | |
837 | return iterator_type(fusion::at_c<1>(args)); | |
838 | } | |
839 | }; | |
840 | ||
841 | template <typename T1, typename T2, typename Subject, typename Modifiers> | |
842 | struct make_directive< | |
843 | terminal_ex<repository::tag::kwd, fusion::vector2<T1,T2> >, Subject, Modifiers> | |
844 | { | |
845 | typedef make_directive_internal_2_args< T1 | |
846 | , T2 | |
847 | , Subject | |
848 | , Modifiers | |
849 | , mpl::false_ | |
850 | , make_exact_helper<T2> | |
851 | > make_directive_type; | |
852 | typedef typename make_directive_type::result_type result_type; | |
853 | template <typename Terminal> | |
854 | result_type operator()( | |
855 | Terminal const& term, Subject const& subject, Modifiers const& modifiers) const | |
856 | { | |
857 | ||
858 | return make_directive_type()(term,subject, modifiers); | |
859 | } | |
860 | ||
861 | }; | |
862 | ||
863 | template <typename T1, typename T2, typename Subject, typename Modifiers> | |
864 | struct make_directive< | |
865 | terminal_ex<repository::tag::dkwd, fusion::vector2<T1,T2> >, Subject, Modifiers> | |
866 | { | |
867 | typedef make_directive_internal_2_args< T1 | |
868 | , T2 | |
869 | , Subject | |
870 | , Modifiers | |
871 | , mpl::true_ | |
872 | , make_exact_helper<T2> | |
873 | > make_directive_type; | |
874 | ||
875 | typedef typename make_directive_type::result_type result_type; | |
876 | template <typename Terminal> | |
877 | result_type operator()( | |
878 | Terminal const& term, Subject const& subject, Modifiers const& modifiers) const | |
879 | { | |
880 | ||
881 | return make_directive_type()(term, subject, modifiers); | |
882 | } | |
883 | ||
884 | }; | |
885 | ||
886 | ||
887 | // Directive ikwd(key,exact)[p] | |
888 | template <typename T1, typename T2, typename Subject, typename Modifiers> | |
889 | struct make_directive< | |
890 | terminal_ex<repository::tag::ikwd, fusion::vector2<T1,T2> >, Subject, Modifiers> | |
891 | { | |
892 | typedef typename add_const<T1>::type const_keyword; | |
893 | typedef repository::qi::kwd_exact_iterator<T2> iterator_type; | |
894 | ||
895 | typedef repository::qi::kwd_parser<Subject, const_keyword, iterator_type, mpl::true_, mpl::false_ > result_type; | |
896 | ||
897 | template <typename Terminal> | |
898 | result_type operator()( | |
899 | Terminal const& term, Subject const& subject, Modifiers const& modifiers) const | |
900 | { | |
901 | typename spirit::detail::get_encoding<Modifiers, | |
902 | spirit::char_encoding::standard>::type encoding; | |
903 | return result_type(subject | |
904 | , fusion::at_c<0>(term.args) | |
905 | , fusion::at_c<1>(term.args) | |
906 | , encoding | |
907 | ); | |
908 | } | |
909 | }; | |
910 | ||
911 | template <typename T1, typename T2, typename Subject, typename Modifiers> | |
912 | struct make_directive< | |
913 | terminal_ex<repository::tag::idkwd, fusion::vector2<T1,T2> >, Subject, Modifiers> | |
914 | { | |
915 | typedef typename add_const<T1>::type const_keyword; | |
916 | typedef repository::qi::kwd_exact_iterator<T2> iterator_type; | |
917 | ||
918 | typedef repository::qi::kwd_parser<Subject, const_keyword, iterator_type, mpl::true_, mpl::true_ > result_type; | |
919 | ||
920 | template <typename Terminal> | |
921 | result_type operator()( | |
922 | Terminal const& term, Subject const& subject, Modifiers const& modifiers) const | |
923 | { | |
924 | typename spirit::detail::get_encoding<Modifiers, | |
925 | spirit::char_encoding::standard>::type encoding; | |
926 | return result_type(subject | |
927 | , fusion::at_c<0>(term.args) | |
928 | , fusion::at_c<1>(term.args) | |
929 | , encoding | |
930 | ); | |
931 | } | |
932 | }; | |
933 | ||
934 | ||
935 | // Directive kwd(min, max)[p] | |
936 | ||
937 | template <typename T> | |
938 | struct make_finite_helper | |
939 | { | |
940 | typedef repository::qi::kwd_finite_iterator<T> iterator_type; | |
941 | template<typename Args> | |
942 | static iterator_type make_iterator(Args const& args) | |
943 | { | |
944 | return iterator_type(fusion::at_c<1>(args),fusion::at_c<2>(args)); | |
945 | } | |
946 | ||
947 | }; | |
948 | ||
949 | template <typename T1, typename T2, typename Subject, typename Modifiers> | |
950 | struct make_directive< | |
951 | terminal_ex<repository::tag::kwd, fusion::vector3<T1,T2,T2> >, Subject, Modifiers> | |
952 | { | |
953 | typedef make_directive_internal_2_args< T1 | |
954 | , T2 | |
955 | , Subject | |
956 | , Modifiers | |
957 | , mpl::false_ | |
958 | , make_finite_helper<T2> | |
959 | > make_directive_type; | |
960 | ||
961 | ||
962 | typedef typename make_directive_type::result_type result_type; | |
963 | template <typename Terminal> | |
964 | result_type operator()( | |
965 | Terminal const& term, Subject const& subject, Modifiers const& modifiers) const | |
966 | { | |
967 | ||
968 | return make_directive_type()(term,subject, modifiers); | |
969 | } | |
970 | ||
971 | }; | |
972 | ||
973 | template <typename T1, typename T2, typename Subject, typename Modifiers> | |
974 | struct make_directive< | |
975 | terminal_ex<repository::tag::dkwd, fusion::vector3<T1,T2,T2> >, Subject, Modifiers> | |
976 | { | |
977 | ||
978 | typedef make_directive_internal_2_args< T1 | |
979 | , T2 | |
980 | , Subject | |
981 | , Modifiers | |
982 | , mpl::true_ | |
983 | , make_finite_helper<T2> | |
984 | > make_directive_type; | |
985 | ||
986 | typedef typename make_directive_type::result_type result_type; | |
987 | template <typename Terminal> | |
988 | result_type operator()( | |
989 | Terminal const& term, Subject const& subject, Modifiers const& modifiers) const | |
990 | { | |
991 | ||
992 | return make_directive_type()(term,subject, modifiers); | |
993 | } | |
994 | ||
995 | }; | |
996 | ||
997 | // Directive ikwd(min, max)[p] | |
998 | template <typename T1, typename T2, typename Subject, typename Modifiers> | |
999 | struct make_directive< | |
1000 | terminal_ex<repository::tag::ikwd, fusion::vector3< T1, T2, T2> >, Subject, Modifiers> | |
1001 | { | |
1002 | typedef typename add_const<T1>::type const_keyword; | |
1003 | typedef repository::qi::kwd_finite_iterator<T2> iterator_type; | |
1004 | ||
1005 | typedef repository::qi::kwd_parser<Subject, const_keyword, iterator_type, mpl::true_, mpl::false_ > result_type; | |
1006 | ||
1007 | template <typename Terminal> | |
1008 | result_type operator()( | |
1009 | Terminal const& term, Subject const& subject, unused_type) const | |
1010 | { | |
1011 | ||
1012 | typename spirit::detail::get_encoding<Modifiers, | |
1013 | spirit::char_encoding::standard>::type encoding; | |
1014 | return result_type(subject, fusion::at_c<0>(term.args), | |
1015 | iterator_type( | |
1016 | fusion::at_c<1>(term.args) | |
1017 | , fusion::at_c<2>(term.args) | |
1018 | , encoding | |
1019 | ) | |
1020 | ); | |
1021 | } | |
1022 | }; | |
1023 | ||
1024 | template <typename T1, typename T2, typename Subject, typename Modifiers> | |
1025 | struct make_directive< | |
1026 | terminal_ex<repository::tag::idkwd, fusion::vector3< T1, T2, T2> >, Subject, Modifiers> | |
1027 | { | |
1028 | typedef typename add_const<T1>::type const_keyword; | |
1029 | typedef repository::qi::kwd_finite_iterator<T2> iterator_type; | |
1030 | ||
1031 | typedef repository::qi::kwd_parser<Subject, const_keyword, iterator_type, mpl::true_, mpl::true_ > result_type; | |
1032 | ||
1033 | template <typename Terminal> | |
1034 | result_type operator()( | |
1035 | Terminal const& term, Subject const& subject, unused_type) const | |
1036 | { | |
1037 | ||
1038 | typename spirit::detail::get_encoding<Modifiers, | |
1039 | spirit::char_encoding::standard>::type encoding; | |
1040 | return result_type(subject, fusion::at_c<0>(term.args), | |
1041 | iterator_type( | |
1042 | fusion::at_c<1>(term.args) | |
1043 | , fusion::at_c<2>(term.args) | |
1044 | , encoding | |
1045 | ) | |
1046 | ); | |
1047 | } | |
1048 | }; | |
1049 | ||
1050 | ||
1051 | // Directive kwd(min, inf)[p] | |
1052 | ||
1053 | template <typename T> | |
1054 | struct make_infinite_helper | |
1055 | { | |
1056 | typedef repository::qi::kwd_infinite_iterator<T> iterator_type; | |
1057 | template<typename Args> | |
1058 | static iterator_type make_iterator(Args const& args) | |
1059 | { | |
1060 | return iterator_type(fusion::at_c<1>(args)); | |
1061 | } | |
1062 | ||
1063 | }; | |
1064 | ||
1065 | ||
1066 | template <typename T1, typename T2, typename Subject, typename Modifiers> | |
1067 | struct make_directive< | |
1068 | terminal_ex<repository::tag::kwd, fusion::vector3<T1,T2,inf_type> >, Subject, Modifiers> | |
1069 | { | |
1070 | typedef make_directive_internal_2_args< T1 | |
1071 | , T2 | |
1072 | , Subject | |
1073 | , Modifiers | |
1074 | , mpl::false_ | |
1075 | , make_infinite_helper<T2> | |
1076 | > make_directive_type; | |
1077 | ||
1078 | typedef typename make_directive_type::result_type result_type; | |
1079 | template <typename Terminal> | |
1080 | result_type operator()( | |
1081 | Terminal const& term, Subject const& subject, unused_type) const | |
1082 | { | |
1083 | ||
1084 | return make_directive_type()(term,subject, unused_type()); | |
1085 | } | |
1086 | ||
1087 | }; | |
1088 | ||
1089 | template <typename T1, typename T2, typename Subject, typename Modifiers> | |
1090 | struct make_directive< | |
1091 | terminal_ex<repository::tag::dkwd, fusion::vector3<T1,T2,inf_type> >, Subject, Modifiers> | |
1092 | { | |
1093 | typedef make_directive_internal_2_args< T1 | |
1094 | , T2 | |
1095 | , Subject | |
1096 | , Modifiers | |
1097 | , mpl::false_ | |
1098 | , make_infinite_helper<T2> | |
1099 | > make_directive_type; | |
1100 | ||
1101 | typedef typename make_directive_type::result_type result_type; | |
1102 | template <typename Terminal> | |
1103 | result_type operator()( | |
1104 | Terminal const& term, Subject const& subject, unused_type) const | |
1105 | { | |
1106 | ||
1107 | return make_directive_type()(term,subject, unused_type()); | |
1108 | } | |
1109 | ||
1110 | }; | |
1111 | ||
1112 | ||
1113 | // Directive ikwd(min, inf)[p] | |
1114 | template <typename T1, typename T2, typename Subject, typename Modifiers> | |
1115 | struct make_directive< | |
1116 | terminal_ex<repository::tag::ikwd | |
1117 | , fusion::vector3<T1, T2, inf_type> >, Subject, Modifiers> | |
1118 | { | |
1119 | typedef typename add_const<T1>::type const_keyword; | |
1120 | typedef repository::qi::kwd_infinite_iterator<T2> iterator_type; | |
1121 | ||
1122 | typedef repository::qi::kwd_parser<Subject, const_keyword, iterator_type, mpl::true_, mpl::false_ > result_type; | |
1123 | ||
1124 | template <typename Terminal> | |
1125 | result_type operator()( | |
1126 | Terminal const& term, Subject const& subject, unused_type) const | |
1127 | { | |
1128 | typename spirit::detail::get_encoding<Modifiers, | |
1129 | spirit::char_encoding::standard>::type encoding; | |
1130 | ||
1131 | return result_type(subject | |
1132 | , fusion::at_c<0>(term.args) | |
1133 | , fusion::at_c<1>(term.args) | |
1134 | , encoding | |
1135 | ); | |
1136 | } | |
1137 | }; | |
1138 | ||
1139 | template <typename T1, typename T2, typename Subject, typename Modifiers> | |
1140 | struct make_directive< | |
1141 | terminal_ex<repository::tag::idkwd | |
1142 | , fusion::vector3<T1, T2, inf_type> >, Subject, Modifiers> | |
1143 | { | |
1144 | typedef typename add_const<T1>::type const_keyword; | |
1145 | typedef repository::qi::kwd_infinite_iterator<T2> iterator_type; | |
1146 | ||
1147 | typedef repository::qi::kwd_parser<Subject, const_keyword, iterator_type, mpl::true_, mpl::true_ > result_type; | |
1148 | ||
1149 | template <typename Terminal> | |
1150 | result_type operator()( | |
1151 | Terminal const& term, Subject const& subject, unused_type) const | |
1152 | { | |
1153 | typename spirit::detail::get_encoding<Modifiers, | |
1154 | spirit::char_encoding::standard>::type encoding; | |
1155 | ||
1156 | return result_type(subject | |
1157 | , fusion::at_c<0>(term.args) | |
1158 | , fusion::at_c<1>(term.args) | |
1159 | , encoding | |
1160 | ); | |
1161 | } | |
1162 | }; | |
1163 | ||
1164 | ||
1165 | }}} | |
1166 | ||
1167 | namespace boost { namespace spirit { namespace traits | |
1168 | { | |
1169 | template <typename Subject, typename KeywordType | |
1170 | , typename LoopIter, typename NoCase , typename Distinct> | |
1171 | struct has_semantic_action< | |
1172 | repository::qi::kwd_parser< Subject, KeywordType, LoopIter, NoCase, Distinct > > | |
1173 | : unary_has_semantic_action<Subject> {}; | |
1174 | ||
1175 | template <typename Subject, typename KeywordType | |
1176 | , typename LoopIter, typename Distinct > | |
1177 | struct has_semantic_action< | |
1178 | repository::qi::complex_kwd_parser< Subject, KeywordType, LoopIter, Distinct > > | |
1179 | : unary_has_semantic_action<Subject> {}; | |
1180 | ||
1181 | template <typename Subject, typename KeywordType | |
1182 | , typename LoopIter, typename NoCase, typename Attribute, typename Context | |
1183 | , typename Iterator, typename Distinct> | |
1184 | struct handles_container<repository::qi::kwd_parser<Subject, KeywordType, LoopIter, NoCase, Distinct>, Attribute | |
1185 | , Context, Iterator> | |
1186 | : unary_handles_container<Subject, Attribute, Context, Iterator> {}; | |
1187 | ||
1188 | template <typename Subject, typename KeywordType | |
1189 | , typename LoopIter | |
1190 | , typename Attribute, typename Context | |
1191 | , typename Iterator, typename Distinct> | |
1192 | struct handles_container<repository::qi::complex_kwd_parser<Subject, KeywordType, LoopIter, Distinct>, Attribute | |
1193 | , Context, Iterator> | |
1194 | : unary_handles_container<Subject, Attribute, Context, Iterator> {}; | |
1195 | ||
1196 | }}} | |
1197 | ||
1198 | #endif | |
1199 |