]> git.proxmox.com Git - ceph.git/blob - ceph/src/boost/libs/spirit/include/boost/spirit/repository/home/qi/directive/kwd.hpp
bump version to 12.2.2-pve1
[ceph.git] / ceph / src / boost / libs / spirit / include / boost / spirit / repository / home / qi / directive / kwd.hpp
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