1 /*=============================================================================
2 Copyright (c) 2001-2011 Joel de Guzman
3 Copyright (c) 2011 Thomas Bernard
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
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>
28 namespace boost { namespace spirit
30 ///////////////////////////////////////////////////////////////////////////
32 ///////////////////////////////////////////////////////////////////////////
34 template < typename T>
35 struct use_directive<qi::domain
36 , terminal_ex<repository::tag::kwd // enables kwd(key)[p]
37 , fusion::vector1<T > >
40 template < typename T>
41 struct use_directive<qi::domain
42 , terminal_ex<repository::tag::ikwd // enables ikwd(key)[p]
43 , fusion::vector1<T > >
46 template < typename T>
47 struct use_directive<qi::domain
48 , terminal_ex<repository::tag::dkwd // enables dkwd(key)[p]
49 , fusion::vector1<T > >
52 template < typename T>
53 struct use_directive<qi::domain
54 , terminal_ex<repository::tag::idkwd // enables idkwd(key)[p]
55 , fusion::vector1<T > >
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 > >
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 > >
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 > >
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 > >
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 > >
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 > >
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 > >
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 > >
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 > >
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 > >
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 > >
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 > >
132 /* template <> // enables *lazy* kwd(exact)[p]
133 struct use_lazy_directive<
139 template <> // enables *lazy* kwd(min, max)[p]
140 struct use_lazy_directive< // and kwd(min, inf)[p]
149 namespace boost { namespace spirit { namespace repository { namespace qi
151 using repository::kwd;
152 using repository::ikwd;
153 using repository::dkwd;
154 using repository::idkwd;
156 using spirit::inf_type;
158 template <typename T>
159 struct kwd_pass_iterator // handles kwd(exact)[p]
161 kwd_pass_iterator() {}
162 bool flag_init() const { return true; }
163 bool register_successful_parse(bool &flag,T &i) const {
170 // silence MSVC warning C4512: assignment operator could not be generated
171 kwd_pass_iterator& operator= (kwd_pass_iterator const&);
174 template <typename T>
175 struct kwd_exact_iterator // handles kwd(exact)[p]
177 kwd_exact_iterator(T const exact)
181 bool flag_init() const { return false; }
182 bool register_successful_parse(bool &flag,T &i) const {
201 // silence MSVC warning C4512: assignment operator could not be generated
202 kwd_exact_iterator& operator= (kwd_exact_iterator const&);
205 template <typename T>
206 struct kwd_finite_iterator // handles kwd(min, max)[p]
208 kwd_finite_iterator(T const min, T const max)
209 : min BOOST_PREVENT_MACRO_SUBSTITUTION (min)
210 , max BOOST_PREVENT_MACRO_SUBSTITUTION (max)
214 bool flag_init() const { return min==0; }
215 bool register_successful_parse(bool &flag,T &i) const {
222 else if(i>=min && i<=max)
233 // silence MSVC warning C4512: assignment operator could not be generated
234 kwd_finite_iterator& operator= (kwd_finite_iterator const&);
237 template <typename T>
238 struct kwd_infinite_iterator // handles kwd(min, inf)[p]
240 kwd_infinite_iterator(T const min)
241 : min BOOST_PREVENT_MACRO_SUBSTITUTION (min) {}
244 bool flag_init() const { return min==0; }
245 bool register_successful_parse(bool &flag,T &i) const {
253 // silence MSVC warning C4512: assignment operator could not be generated
254 kwd_infinite_iterator& operator= (kwd_infinite_iterator const&);
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
265 typedef NoCasePass no_case_pass;
267 skipper_keyword_marker(Skipper const &skipper,bool &flag,int &counter) :
273 const Skipper &skipper;
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 > >
281 struct kwd_parser_id;
283 typedef Subject subject_type;
284 typedef NoCase no_case_keyword;
285 typedef Distinct distinct;
288 remove_const<typename traits::char_type_of<KeywordType>::type>::type
291 typedef std::basic_string<char_type> keyword_type;
293 template <typename Context, typename Iterator>
297 traits::build_std_vector<
298 typename traits::attribute_of<
299 Subject, Context, Iterator>::type
305 kwd_parser(Subject const& subject
306 , typename add_reference<KeywordType>::type keyword
307 , LoopIter const& iter)
308 : subject(subject), iter(iter), keyword(keyword) {}
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) {}
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
324 return subject.parse(first,last,context,skipper,attr);
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
335 // synthesized attribute needs to be default constructed
336 typename traits::container_value<Attribute>::type val =
337 typename traits::container_value<Attribute>::type();
339 Iterator save = first;
340 bool r = subject.parse(first,last,context,skipper, val);
343 // push the parsed value into our attribute
344 r = traits::push_back(attr, val);
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
358 typedef typename traits::attribute_of<
359 Subject, Context, Iterator>::type
362 typedef typename mpl::and_<
363 traits::is_container<Attribute>
364 , mpl::not_< traits::is_weak_substitute< subject_attribute,Attribute > >
367 if((no_case_keyword::value && NoCasePass::value) || !NoCasePass::value)
369 if(parse_impl(first,last,context,skipper.skipper,attr, predicate()))
370 return iter.register_successful_parse(skipper.flag,skipper.counter);
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
381 typedef typename traits::attribute_of<
382 Subject, Context, Iterator>::type
385 typedef typename mpl::and_<
386 traits::is_container<Attribute>
387 , mpl::not_< traits::is_weak_substitute< subject_attribute,Attribute > >
392 bool flag = iter.flag_init();
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()))
402 return iter.register_successful_parse(flag,counter);
411 template <typename Context>
412 info what(Context& context) const
415 if(no_case_keyword::value)
416 return info("idkwd", subject.what(context));
418 return info("dkwd", subject.what(context));
422 if(no_case_keyword::value)
423 return info("ikwd", subject.what(context));
425 return info("kwd", subject.what(context));
432 typedef typename mpl::if_<
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;
438 // silence MSVC warning C4512: assignment operator could not be generated
439 kwd_parser& operator= (kwd_parser const&);
441 template <typename Iterator, typename Context, typename Skipper>
442 static spirit::qi::detail::fail_function<Iterator, Context, Skipper>
444 Iterator& first, Iterator const& last
445 , Context& context, Skipper const& skipper)
447 return spirit::qi::detail::fail_function<Iterator, Context, Skipper>
448 (first, last, context, skipper);
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 > >
457 struct complex_kwd_parser_id;
458 typedef Subject subject_type;
459 typedef Distinct distinct;
461 template <typename Context, typename Iterator>
465 traits::build_std_vector<
466 typename traits::attribute_of<
467 Subject, Context, Iterator>::type
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) {}
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
485 return subject.parse(first,last,context,skipper,attr);
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
496 // synthesized attribute needs to be default constructed
497 typename traits::container_value<Attribute>::type val =
498 typename traits::container_value<Attribute>::type();
500 Iterator save = first;
501 bool r = subject.parse(first,last,context,skipper, val);
504 // push the parsed value into our attribute
505 r = traits::push_back(attr, val);
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
519 typedef typename traits::attribute_of<
520 Subject, Context, Iterator>::type
523 typedef typename mpl::and_<
524 traits::is_container<Attribute>
525 , mpl::not_< traits::is_weak_substitute< subject_attribute,Attribute > >
528 if(parse_impl(first,last,context,skipper.skipper,attr, predicate()))
529 return iter.register_successful_parse(skipper.flag,skipper.counter);
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
539 typedef typename traits::attribute_of<
540 Subject, Context, Iterator>::type
543 typedef typename mpl::and_<
544 traits::is_container<Attribute>
545 , mpl::not_< traits::is_weak_substitute< subject_attribute,Attribute > >
550 bool flag = iter.flag_init();
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()))
560 return iter.register_successful_parse(flag,counter);
569 template <typename Context>
570 info what(Context& context) const
573 return info("dkwd", subject.what(context));
575 return info("kwd", subject.what(context));
583 // silence MSVC warning C4512: assignment operator could not be generated
584 complex_kwd_parser& operator= (complex_kwd_parser const&);
586 template <typename Iterator, typename Context, typename Skipper>
587 static spirit::qi::detail::fail_function<Iterator, Context, Skipper>
589 Iterator& first, Iterator const& last
590 , Context& context, Skipper const& skipper)
592 return spirit::qi::detail::fail_function<Iterator, Context, Skipper>
593 (first, last, context, skipper);
600 ///////////////////////////////////////////////////////////////////////////////
601 namespace boost { namespace spirit { namespace qi
604 ///////////////////////////////////////////////////////////////////////////
605 // Parser generators: make_xxx function (objects)
606 ///////////////////////////////////////////////////////////////////////////
608 template <typename T1, typename T2, typename Subject, typename Modifiers, typename Distinct, typename MakeDirectiveHelper>
609 struct make_directive_internal_2_args
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 ,
617 typename result_of::compile<qi::domain, T1>::type
618 >::type keyword_type;
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
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 >
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
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)
644 template <typename Terminal>
645 result_type create_kwd_string(Terminal const &term, Subject const & subject, boost::mpl::false_ ) const
647 return result_type(subject
648 ,fusion::at_c<0>(term.args)
649 ,MakeDirectiveHelper::make_iterator(term.args)
652 template <typename Terminal>
653 result_type create_kwd(Terminal const &term, Subject const & subject, Modifiers const& modifiers, boost::mpl::true_ ) const
655 return create_kwd_string(term,subject,no_case());
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
661 return result_type(subject
662 ,compile<qi::domain>(fusion::at_c<0>(term.args),modifiers)
663 ,MakeDirectiveHelper::make_iterator(term.args)
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
671 return create_kwd(term, subject, modifiers, is_string_kwd_type());
676 // Directive kwd(key)[p]
677 template <typename T1, typename Subject, typename Modifiers, typename Distinct>
678 struct make_directive_internal
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 ,
685 typename result_of::compile<qi::domain, T1, Modifiers>::type
686 >::type keyword_type;
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
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>
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
705 typename spirit::detail::get_encoding<Modifiers,
706 spirit::char_encoding::standard>::type encoding;
708 return result_type(subject
709 ,fusion::at_c<0>(term.args)
715 template <typename Terminal>
716 result_type create_kwd_string(Terminal const &term, Subject const & subject, boost::mpl::false_) const
718 return result_type(subject
719 ,fusion::at_c<0>(term.args)
723 template <typename Terminal>
724 result_type create_kwd(Terminal const &term, Subject const & subject, Modifiers const& modifiers, boost::mpl::true_ ) const
726 return create_kwd_string(term,subject,no_case());
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
732 return result_type(subject
733 ,compile<qi::domain>(fusion::at_c<0>(term.args),modifiers)
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
742 return create_kwd(term, subject, modifiers, is_string_kwd_type());
746 template <typename T1, typename Subject, typename Modifiers>
747 struct make_directive<
748 terminal_ex<repository::tag::kwd, fusion::vector1<T1> >, Subject, Modifiers>
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
757 return make_directive_type()(term, subject, modifiers);
762 template <typename T1, typename Subject, typename Modifiers>
763 struct make_directive<
764 terminal_ex<repository::tag::dkwd, fusion::vector1<T1> >, Subject, Modifiers>
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
773 return make_directive_type()(term, subject, modifiers);
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>
785 typedef typename add_const<T1>::type const_keyword;
786 typedef repository::qi::kwd_pass_iterator<int> iterator_type;
788 typedef repository::qi::kwd_parser<Subject, const_keyword, iterator_type, mpl::true_, mpl::false_ > result_type;
790 template <typename Terminal>
791 result_type operator()(
792 Terminal const& term, Subject const& subject, unused_type) const
794 typename spirit::detail::get_encoding<Modifiers,
795 spirit::char_encoding::standard>::type encoding;
797 return result_type(subject
798 ,fusion::at_c<0>(term.args)
805 template <typename T1, typename Subject, typename Modifiers>
806 struct make_directive<
807 terminal_ex<repository::tag::idkwd, fusion::vector1<T1> >, Subject, Modifiers>
809 typedef typename add_const<T1>::type const_keyword;
810 typedef repository::qi::kwd_pass_iterator<int> iterator_type;
812 typedef repository::qi::kwd_parser<Subject, const_keyword, iterator_type, mpl::true_, mpl::true_ > result_type;
814 template <typename Terminal>
815 result_type operator()(
816 Terminal const& term, Subject const& subject, unused_type) const
818 typename spirit::detail::get_encoding<Modifiers,
819 spirit::char_encoding::standard>::type encoding;
821 return result_type(subject
822 ,fusion::at_c<0>(term.args)
829 // Directive kwd(key,exact)[p]
830 template <typename T>
831 struct make_exact_helper
833 typedef repository::qi::kwd_exact_iterator<T> iterator_type;
834 template<typename Args>
835 static iterator_type make_iterator(Args const& args)
837 return iterator_type(fusion::at_c<1>(args));
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>
845 typedef make_directive_internal_2_args< T1
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
858 return make_directive_type()(term,subject, modifiers);
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>
867 typedef make_directive_internal_2_args< T1
872 , make_exact_helper<T2>
873 > make_directive_type;
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
881 return make_directive_type()(term, subject, modifiers);
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>
892 typedef typename add_const<T1>::type const_keyword;
893 typedef repository::qi::kwd_exact_iterator<T2> iterator_type;
895 typedef repository::qi::kwd_parser<Subject, const_keyword, iterator_type, mpl::true_, mpl::false_ > result_type;
897 template <typename Terminal>
898 result_type operator()(
899 Terminal const& term, Subject const& subject, Modifiers const& modifiers) const
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)
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>
915 typedef typename add_const<T1>::type const_keyword;
916 typedef repository::qi::kwd_exact_iterator<T2> iterator_type;
918 typedef repository::qi::kwd_parser<Subject, const_keyword, iterator_type, mpl::true_, mpl::true_ > result_type;
920 template <typename Terminal>
921 result_type operator()(
922 Terminal const& term, Subject const& subject, Modifiers const& modifiers) const
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)
935 // Directive kwd(min, max)[p]
937 template <typename T>
938 struct make_finite_helper
940 typedef repository::qi::kwd_finite_iterator<T> iterator_type;
941 template<typename Args>
942 static iterator_type make_iterator(Args const& args)
944 return iterator_type(fusion::at_c<1>(args),fusion::at_c<2>(args));
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>
953 typedef make_directive_internal_2_args< T1
958 , make_finite_helper<T2>
959 > make_directive_type;
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
968 return make_directive_type()(term,subject, modifiers);
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>
978 typedef make_directive_internal_2_args< T1
983 , make_finite_helper<T2>
984 > make_directive_type;
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
992 return make_directive_type()(term,subject, modifiers);
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>
1002 typedef typename add_const<T1>::type const_keyword;
1003 typedef repository::qi::kwd_finite_iterator<T2> iterator_type;
1005 typedef repository::qi::kwd_parser<Subject, const_keyword, iterator_type, mpl::true_, mpl::false_ > result_type;
1007 template <typename Terminal>
1008 result_type operator()(
1009 Terminal const& term, Subject const& subject, unused_type) const
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),
1016 fusion::at_c<1>(term.args)
1017 , fusion::at_c<2>(term.args)
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>
1028 typedef typename add_const<T1>::type const_keyword;
1029 typedef repository::qi::kwd_finite_iterator<T2> iterator_type;
1031 typedef repository::qi::kwd_parser<Subject, const_keyword, iterator_type, mpl::true_, mpl::true_ > result_type;
1033 template <typename Terminal>
1034 result_type operator()(
1035 Terminal const& term, Subject const& subject, unused_type) const
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),
1042 fusion::at_c<1>(term.args)
1043 , fusion::at_c<2>(term.args)
1051 // Directive kwd(min, inf)[p]
1053 template <typename T>
1054 struct make_infinite_helper
1056 typedef repository::qi::kwd_infinite_iterator<T> iterator_type;
1057 template<typename Args>
1058 static iterator_type make_iterator(Args const& args)
1060 return iterator_type(fusion::at_c<1>(args));
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>
1070 typedef make_directive_internal_2_args< T1
1075 , make_infinite_helper<T2>
1076 > make_directive_type;
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
1084 return make_directive_type()(term,subject, unused_type());
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>
1093 typedef make_directive_internal_2_args< T1
1098 , make_infinite_helper<T2>
1099 > make_directive_type;
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
1107 return make_directive_type()(term,subject, unused_type());
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>
1119 typedef typename add_const<T1>::type const_keyword;
1120 typedef repository::qi::kwd_infinite_iterator<T2> iterator_type;
1122 typedef repository::qi::kwd_parser<Subject, const_keyword, iterator_type, mpl::true_, mpl::false_ > result_type;
1124 template <typename Terminal>
1125 result_type operator()(
1126 Terminal const& term, Subject const& subject, unused_type) const
1128 typename spirit::detail::get_encoding<Modifiers,
1129 spirit::char_encoding::standard>::type encoding;
1131 return result_type(subject
1132 , fusion::at_c<0>(term.args)
1133 , fusion::at_c<1>(term.args)
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>
1144 typedef typename add_const<T1>::type const_keyword;
1145 typedef repository::qi::kwd_infinite_iterator<T2> iterator_type;
1147 typedef repository::qi::kwd_parser<Subject, const_keyword, iterator_type, mpl::true_, mpl::true_ > result_type;
1149 template <typename Terminal>
1150 result_type operator()(
1151 Terminal const& term, Subject const& subject, unused_type) const
1153 typename spirit::detail::get_encoding<Modifiers,
1154 spirit::char_encoding::standard>::type encoding;
1156 return result_type(subject
1157 , fusion::at_c<0>(term.args)
1158 , fusion::at_c<1>(term.args)
1167 namespace boost { namespace spirit { namespace traits
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> {};
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> {};
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> {};
1188 template <typename Subject, typename KeywordType
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> {};