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