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/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>
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 #ifndef BOOST_SPIRIT_NO_PREDEFINED_TERMINALS
152 using repository::kwd;
153 using repository::ikwd;
154 using repository::dkwd;
155 using repository::idkwd;
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;
164 template <typename T>
165 struct kwd_pass_iterator // handles kwd(exact)[p]
167 kwd_pass_iterator() {}
168 bool flag_init() const { return true; }
169 bool register_successful_parse(bool &flag,T &/*i*/) const {
176 // silence MSVC warning C4512: assignment operator could not be generated
177 kwd_pass_iterator& operator= (kwd_pass_iterator const&);
180 template <typename T>
181 struct kwd_exact_iterator // handles kwd(exact)[p]
183 kwd_exact_iterator(T const exact)
187 bool flag_init() const { return false; }
188 bool register_successful_parse(bool &flag,T &i) const {
207 // silence MSVC warning C4512: assignment operator could not be generated
208 kwd_exact_iterator& operator= (kwd_exact_iterator const&);
211 template <typename T>
212 struct kwd_finite_iterator // handles kwd(min, max)[p]
214 kwd_finite_iterator(T const min, T const max)
215 : min BOOST_PREVENT_MACRO_SUBSTITUTION (min)
216 , max BOOST_PREVENT_MACRO_SUBSTITUTION (max)
220 bool flag_init() const { return min==0; }
221 bool register_successful_parse(bool &flag,T &i) const {
228 else if(i>=min && i<=max)
239 // silence MSVC warning C4512: assignment operator could not be generated
240 kwd_finite_iterator& operator= (kwd_finite_iterator const&);
243 template <typename T>
244 struct kwd_infinite_iterator // handles kwd(min, inf)[p]
246 kwd_infinite_iterator(T const min)
247 : min BOOST_PREVENT_MACRO_SUBSTITUTION (min) {}
250 bool flag_init() const { return min==0; }
251 bool register_successful_parse(bool &flag,T &i) const {
259 // silence MSVC warning C4512: assignment operator could not be generated
260 kwd_infinite_iterator& operator= (kwd_infinite_iterator const&);
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
271 typedef NoCasePass no_case_pass;
273 skipper_keyword_marker(Skipper const &skipper,bool &flag,int &counter) :
279 const Skipper &skipper;
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 > >
287 struct kwd_parser_id;
289 typedef Subject subject_type;
290 typedef NoCase no_case_keyword;
291 typedef Distinct distinct;
294 remove_const<typename traits::char_type_of<KeywordType>::type>::type
297 typedef std::basic_string<char_type> keyword_type;
299 template <typename Context, typename Iterator>
303 traits::build_std_vector<
304 typename traits::attribute_of<
305 Subject, Context, Iterator>::type
311 kwd_parser(Subject const& subject
312 , typename add_reference<KeywordType>::type keyword
313 , LoopIter const& iter)
314 : subject(subject), iter(iter), keyword(keyword) {}
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) {}
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
330 return subject.parse(first,last,context,skipper,attr);
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
341 // synthesized attribute needs to be default constructed
342 typename traits::container_value<Attribute>::type val =
343 typename traits::container_value<Attribute>::type();
345 Iterator save = first;
346 bool r = subject.parse(first,last,context,skipper, val);
349 // push the parsed value into our attribute
350 r = traits::push_back(attr, val);
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
364 typedef typename traits::attribute_of<
365 Subject, Context, Iterator>::type
368 typedef typename mpl::and_<
369 traits::is_container<Attribute>
370 , mpl::not_< traits::is_weak_substitute< subject_attribute,Attribute > >
373 if((no_case_keyword::value && NoCasePass::value) || !NoCasePass::value)
375 if(parse_impl(first,last,context,skipper.skipper,attr, predicate()))
376 return iter.register_successful_parse(skipper.flag,skipper.counter);
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
387 typedef typename traits::attribute_of<
388 Subject, Context, Iterator>::type
391 typedef typename mpl::and_<
392 traits::is_container<Attribute>
393 , mpl::not_< traits::is_weak_substitute< subject_attribute,Attribute > >
398 bool flag = iter.flag_init();
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()))
408 return iter.register_successful_parse(flag,counter);
417 template <typename Context>
418 info what(Context& context) const
421 if(no_case_keyword::value)
422 return info("idkwd", subject.what(context));
424 return info("dkwd", subject.what(context));
428 if(no_case_keyword::value)
429 return info("ikwd", subject.what(context));
431 return info("kwd", subject.what(context));
438 typedef typename mpl::if_<
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;
444 // silence MSVC warning C4512: assignment operator could not be generated
445 kwd_parser& operator= (kwd_parser const&);
447 template <typename Iterator, typename Context, typename Skipper>
448 static spirit::qi::detail::fail_function<Iterator, Context, Skipper>
450 Iterator& first, Iterator const& last
451 , Context& context, Skipper const& skipper)
453 return spirit::qi::detail::fail_function<Iterator, Context, Skipper>
454 (first, last, context, skipper);
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 > >
463 struct complex_kwd_parser_id;
464 typedef Subject subject_type;
465 typedef Distinct distinct;
467 template <typename Context, typename Iterator>
471 traits::build_std_vector<
472 typename traits::attribute_of<
473 Subject, Context, Iterator>::type
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) {}
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
491 return subject.parse(first,last,context,skipper,attr);
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
502 // synthesized attribute needs to be default constructed
503 typename traits::container_value<Attribute>::type val =
504 typename traits::container_value<Attribute>::type();
506 Iterator save = first;
507 bool r = subject.parse(first,last,context,skipper, val);
510 // push the parsed value into our attribute
511 r = traits::push_back(attr, val);
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
525 typedef typename traits::attribute_of<
526 Subject, Context, Iterator>::type
529 typedef typename mpl::and_<
530 traits::is_container<Attribute>
531 , mpl::not_< traits::is_weak_substitute< subject_attribute,Attribute > >
534 if(parse_impl(first,last,context,skipper.skipper,attr, predicate()))
535 return iter.register_successful_parse(skipper.flag,skipper.counter);
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
545 typedef typename traits::attribute_of<
546 Subject, Context, Iterator>::type
549 typedef typename mpl::and_<
550 traits::is_container<Attribute>
551 , mpl::not_< traits::is_weak_substitute< subject_attribute,Attribute > >
556 bool flag = iter.flag_init();
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()))
566 return iter.register_successful_parse(flag,counter);
575 template <typename Context>
576 info what(Context& context) const
579 return info("dkwd", subject.what(context));
581 return info("kwd", subject.what(context));
589 // silence MSVC warning C4512: assignment operator could not be generated
590 complex_kwd_parser& operator= (complex_kwd_parser const&);
592 template <typename Iterator, typename Context, typename Skipper>
593 static spirit::qi::detail::fail_function<Iterator, Context, Skipper>
595 Iterator& first, Iterator const& last
596 , Context& context, Skipper const& skipper)
598 return spirit::qi::detail::fail_function<Iterator, Context, Skipper>
599 (first, last, context, skipper);
606 ///////////////////////////////////////////////////////////////////////////////
607 namespace boost { namespace spirit { namespace qi
610 ///////////////////////////////////////////////////////////////////////////
611 // Parser generators: make_xxx function (objects)
612 ///////////////////////////////////////////////////////////////////////////
614 template <typename T1, typename T2, typename Subject, typename Modifiers, typename Distinct, typename MakeDirectiveHelper>
615 struct make_directive_internal_2_args
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 ,
623 typename result_of::compile<qi::domain, T1>::type
624 >::type keyword_type;
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
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 >
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
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)
650 template <typename Terminal>
651 result_type create_kwd_string(Terminal const &term, Subject const & subject, boost::mpl::false_ ) const
653 return result_type(subject
654 ,fusion::at_c<0>(term.args)
655 ,MakeDirectiveHelper::make_iterator(term.args)
658 template <typename Terminal>
659 result_type create_kwd(Terminal const &term, Subject const & subject, Modifiers const& /*modifiers*/, boost::mpl::true_ ) const
661 return create_kwd_string(term,subject,no_case());
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
667 return result_type(subject
668 ,compile<qi::domain>(fusion::at_c<0>(term.args),modifiers)
669 ,MakeDirectiveHelper::make_iterator(term.args)
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
677 return create_kwd(term, subject, modifiers, is_string_kwd_type());
682 // Directive kwd(key)[p]
683 template <typename T1, typename Subject, typename Modifiers, typename Distinct>
684 struct make_directive_internal
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 ,
691 typename result_of::compile<qi::domain, T1, Modifiers>::type
692 >::type keyword_type;
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
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>
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
711 typename spirit::detail::get_encoding<Modifiers,
712 spirit::char_encoding::standard>::type encoding;
714 return result_type(subject
715 ,fusion::at_c<0>(term.args)
721 template <typename Terminal>
722 result_type create_kwd_string(Terminal const &term, Subject const & subject, boost::mpl::false_) const
724 return result_type(subject
725 ,fusion::at_c<0>(term.args)
729 template <typename Terminal>
730 result_type create_kwd(Terminal const &term, Subject const & subject, Modifiers const& /*modifiers*/, boost::mpl::true_ ) const
732 return create_kwd_string(term,subject,no_case());
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
738 return result_type(subject
739 ,compile<qi::domain>(fusion::at_c<0>(term.args),modifiers)
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
748 return create_kwd(term, subject, modifiers, is_string_kwd_type());
752 template <typename T1, typename Subject, typename Modifiers>
753 struct make_directive<
754 terminal_ex<repository::tag::kwd, fusion::vector1<T1> >, Subject, Modifiers>
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
763 return make_directive_type()(term, subject, modifiers);
768 template <typename T1, typename Subject, typename Modifiers>
769 struct make_directive<
770 terminal_ex<repository::tag::dkwd, fusion::vector1<T1> >, Subject, Modifiers>
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
779 return make_directive_type()(term, subject, modifiers);
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>
791 typedef typename add_const<T1>::type const_keyword;
792 typedef repository::qi::kwd_pass_iterator<int> iterator_type;
794 typedef repository::qi::kwd_parser<Subject, const_keyword, iterator_type, mpl::true_, mpl::false_ > result_type;
796 template <typename Terminal>
797 result_type operator()(
798 Terminal const& term, Subject const& subject, unused_type) const
800 typename spirit::detail::get_encoding<Modifiers,
801 spirit::char_encoding::standard>::type encoding;
803 return result_type(subject
804 ,fusion::at_c<0>(term.args)
811 template <typename T1, typename Subject, typename Modifiers>
812 struct make_directive<
813 terminal_ex<repository::tag::idkwd, fusion::vector1<T1> >, Subject, Modifiers>
815 typedef typename add_const<T1>::type const_keyword;
816 typedef repository::qi::kwd_pass_iterator<int> iterator_type;
818 typedef repository::qi::kwd_parser<Subject, const_keyword, iterator_type, mpl::true_, mpl::true_ > result_type;
820 template <typename Terminal>
821 result_type operator()(
822 Terminal const& term, Subject const& subject, unused_type) const
824 typename spirit::detail::get_encoding<Modifiers,
825 spirit::char_encoding::standard>::type encoding;
827 return result_type(subject
828 ,fusion::at_c<0>(term.args)
835 // Directive kwd(key,exact)[p]
836 template <typename T>
837 struct make_exact_helper
839 typedef repository::qi::kwd_exact_iterator<T> iterator_type;
840 template<typename Args>
841 static iterator_type make_iterator(Args const& args)
843 return iterator_type(fusion::at_c<1>(args));
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>
851 typedef make_directive_internal_2_args< T1
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
864 return make_directive_type()(term,subject, modifiers);
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>
873 typedef make_directive_internal_2_args< T1
878 , make_exact_helper<T2>
879 > make_directive_type;
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
887 return make_directive_type()(term, subject, modifiers);
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>
898 typedef typename add_const<T1>::type const_keyword;
899 typedef repository::qi::kwd_exact_iterator<T2> iterator_type;
901 typedef repository::qi::kwd_parser<Subject, const_keyword, iterator_type, mpl::true_, mpl::false_ > result_type;
903 template <typename Terminal>
904 result_type operator()(
905 Terminal const& term, Subject const& subject, Modifiers const& /*modifiers*/) const
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)
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>
921 typedef typename add_const<T1>::type const_keyword;
922 typedef repository::qi::kwd_exact_iterator<T2> iterator_type;
924 typedef repository::qi::kwd_parser<Subject, const_keyword, iterator_type, mpl::true_, mpl::true_ > result_type;
926 template <typename Terminal>
927 result_type operator()(
928 Terminal const& term, Subject const& subject, Modifiers const& /*modifiers*/) const
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)
941 // Directive kwd(min, max)[p]
943 template <typename T>
944 struct make_finite_helper
946 typedef repository::qi::kwd_finite_iterator<T> iterator_type;
947 template<typename Args>
948 static iterator_type make_iterator(Args const& args)
950 return iterator_type(fusion::at_c<1>(args),fusion::at_c<2>(args));
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>
959 typedef make_directive_internal_2_args< T1
964 , make_finite_helper<T2>
965 > make_directive_type;
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
974 return make_directive_type()(term,subject, modifiers);
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>
984 typedef make_directive_internal_2_args< T1
989 , make_finite_helper<T2>
990 > make_directive_type;
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
998 return make_directive_type()(term,subject, modifiers);
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>
1008 typedef typename add_const<T1>::type const_keyword;
1009 typedef repository::qi::kwd_finite_iterator<T2> iterator_type;
1011 typedef repository::qi::kwd_parser<Subject, const_keyword, iterator_type, mpl::true_, mpl::false_ > result_type;
1013 template <typename Terminal>
1014 result_type operator()(
1015 Terminal const& term, Subject const& subject, unused_type) const
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),
1022 fusion::at_c<1>(term.args)
1023 , fusion::at_c<2>(term.args)
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>
1034 typedef typename add_const<T1>::type const_keyword;
1035 typedef repository::qi::kwd_finite_iterator<T2> iterator_type;
1037 typedef repository::qi::kwd_parser<Subject, const_keyword, iterator_type, mpl::true_, mpl::true_ > result_type;
1039 template <typename Terminal>
1040 result_type operator()(
1041 Terminal const& term, Subject const& subject, unused_type) const
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),
1048 fusion::at_c<1>(term.args)
1049 , fusion::at_c<2>(term.args)
1057 // Directive kwd(min, inf)[p]
1059 template <typename T>
1060 struct make_infinite_helper
1062 typedef repository::qi::kwd_infinite_iterator<T> iterator_type;
1063 template<typename Args>
1064 static iterator_type make_iterator(Args const& args)
1066 return iterator_type(fusion::at_c<1>(args));
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>
1076 typedef make_directive_internal_2_args< T1
1081 , make_infinite_helper<T2>
1082 > make_directive_type;
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
1090 return make_directive_type()(term,subject, unused_type());
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>
1099 typedef make_directive_internal_2_args< T1
1104 , make_infinite_helper<T2>
1105 > make_directive_type;
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
1113 return make_directive_type()(term,subject, unused_type());
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>
1125 typedef typename add_const<T1>::type const_keyword;
1126 typedef repository::qi::kwd_infinite_iterator<T2> iterator_type;
1128 typedef repository::qi::kwd_parser<Subject, const_keyword, iterator_type, mpl::true_, mpl::false_ > result_type;
1130 template <typename Terminal>
1131 result_type operator()(
1132 Terminal const& term, Subject const& subject, unused_type) const
1134 typename spirit::detail::get_encoding<Modifiers,
1135 spirit::char_encoding::standard>::type encoding;
1137 return result_type(subject
1138 , fusion::at_c<0>(term.args)
1139 , fusion::at_c<1>(term.args)
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>
1150 typedef typename add_const<T1>::type const_keyword;
1151 typedef repository::qi::kwd_infinite_iterator<T2> iterator_type;
1153 typedef repository::qi::kwd_parser<Subject, const_keyword, iterator_type, mpl::true_, mpl::true_ > result_type;
1155 template <typename Terminal>
1156 result_type operator()(
1157 Terminal const& term, Subject const& subject, unused_type) const
1159 typename spirit::detail::get_encoding<Modifiers,
1160 spirit::char_encoding::standard>::type encoding;
1162 return result_type(subject
1163 , fusion::at_c<0>(term.args)
1164 , fusion::at_c<1>(term.args)
1173 namespace boost { namespace spirit { namespace traits
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> {};
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> {};
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> {};
1194 template <typename Subject, typename KeywordType
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> {};