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>
29 # pragma warning(push)
30 # pragma warning(disable: 4127) // conditional expression is constant
33 namespace boost { namespace spirit
35 ///////////////////////////////////////////////////////////////////////////
37 ///////////////////////////////////////////////////////////////////////////
39 template < typename T>
40 struct use_directive<qi::domain
41 , terminal_ex<repository::tag::kwd // enables kwd(key)[p]
42 , fusion::vector1<T > >
45 template < typename T>
46 struct use_directive<qi::domain
47 , terminal_ex<repository::tag::ikwd // enables ikwd(key)[p]
48 , fusion::vector1<T > >
51 template < typename T>
52 struct use_directive<qi::domain
53 , terminal_ex<repository::tag::dkwd // enables dkwd(key)[p]
54 , fusion::vector1<T > >
57 template < typename T>
58 struct use_directive<qi::domain
59 , terminal_ex<repository::tag::idkwd // enables idkwd(key)[p]
60 , fusion::vector1<T > >
64 template < typename T1, typename T2>
65 struct use_directive<qi::domain
66 , terminal_ex<repository::tag::kwd // enables kwd(key,exact)[p]
67 , fusion::vector2< T1, T2 > >
70 template < typename T1, typename T2>
71 struct use_directive<qi::domain
72 , terminal_ex<repository::tag::ikwd // enables ikwd(key,exact)[p]
73 , fusion::vector2< T1, T2 > >
76 template < typename T1, typename T2>
77 struct use_directive<qi::domain
78 , terminal_ex<repository::tag::dkwd // enables dkwd(key,exact)[p]
79 , fusion::vector2< T1, T2 > >
82 template < typename T1, typename T2>
83 struct use_directive<qi::domain
84 , terminal_ex<repository::tag::idkwd // enables idkwd(key,exact)[p]
85 , fusion::vector2< T1, T2 > >
88 template < typename T1, typename T2>
89 struct use_directive<qi::domain
90 , terminal_ex<repository::tag::kwd // enables kwd(min, max)[p]
91 , fusion::vector3< T1, T2, T2 > >
94 template < typename T1, typename T2>
95 struct use_directive<qi::domain
96 , terminal_ex<repository::tag::ikwd // enables ikwd(min, max)[p]
97 , fusion::vector3< T1, T2, T2 > >
100 template < typename T1, typename T2>
101 struct use_directive<qi::domain
102 , terminal_ex<repository::tag::dkwd // enables dkwd(min, max)[p]
103 , fusion::vector3< T1, T2, T2 > >
106 template < typename T1, typename T2>
107 struct use_directive<qi::domain
108 , terminal_ex<repository::tag::idkwd // enables idkwd(min, max)[p]
109 , fusion::vector3< T1, T2, T2 > >
112 template < typename T1, typename T2>
113 struct use_directive<qi::domain
114 , terminal_ex<repository::tag::kwd // enables kwd(min, inf)[p]
115 , fusion::vector3<T1, T2, inf_type > >
118 template < typename T1, typename T2>
119 struct use_directive<qi::domain
120 , terminal_ex<repository::tag::ikwd // enables ikwd(min, inf)[p]
121 , fusion::vector3<T1, T2, inf_type > >
124 template < typename T1, typename T2>
125 struct use_directive<qi::domain
126 , terminal_ex<repository::tag::dkwd // enables dkwd(min, inf)[p]
127 , fusion::vector3<T1, T2, inf_type > >
130 template < typename T1, typename T2>
131 struct use_directive<qi::domain
132 , terminal_ex<repository::tag::idkwd // enables idkwd(min, inf)[p]
133 , fusion::vector3<T1, T2, inf_type > >
137 /* template <> // enables *lazy* kwd(exact)[p]
138 struct use_lazy_directive<
144 template <> // enables *lazy* kwd(min, max)[p]
145 struct use_lazy_directive< // and kwd(min, inf)[p]
154 namespace boost { namespace spirit { namespace repository { namespace qi
156 #ifndef BOOST_SPIRIT_NO_PREDEFINED_TERMINALS
157 using repository::kwd;
158 using repository::ikwd;
159 using repository::dkwd;
160 using repository::idkwd;
163 using repository::kwd_type;
164 using repository::ikwd_type;
165 using repository::dkwd_type;
166 using repository::idkwd_type;
167 using spirit::inf_type;
169 template <typename T>
170 struct kwd_pass_iterator // handles kwd(exact)[p]
172 kwd_pass_iterator() {}
173 bool flag_init() const { return true; }
174 bool register_successful_parse(bool &flag,T &/*i*/) const {
180 // silence MSVC warning C4512: assignment operator could not be generated
181 BOOST_DELETED_FUNCTION(kwd_pass_iterator& operator= (kwd_pass_iterator const&))
184 template <typename T>
185 struct kwd_exact_iterator // handles kwd(exact)[p]
187 kwd_exact_iterator(T const exact)
191 bool flag_init() const { return false; }
192 bool register_successful_parse(bool &flag,T &i) const {
210 // silence MSVC warning C4512: assignment operator could not be generated
211 BOOST_DELETED_FUNCTION(kwd_exact_iterator& operator= (kwd_exact_iterator const&))
214 template <typename T>
215 struct kwd_finite_iterator // handles kwd(min, max)[p]
217 kwd_finite_iterator(T const min, T const max)
218 : min BOOST_PREVENT_MACRO_SUBSTITUTION (min)
219 , max BOOST_PREVENT_MACRO_SUBSTITUTION (max)
223 bool flag_init() const { return min==0; }
224 bool register_successful_parse(bool &flag,T &i) const {
231 else if(i>=min && i<=max)
241 // silence MSVC warning C4512: assignment operator could not be generated
242 BOOST_DELETED_FUNCTION(kwd_finite_iterator& operator= (kwd_finite_iterator const&))
245 template <typename T>
246 struct kwd_infinite_iterator // handles kwd(min, inf)[p]
248 kwd_infinite_iterator(T const min)
249 : min BOOST_PREVENT_MACRO_SUBSTITUTION (min) {}
252 bool flag_init() const { return min==0; }
253 bool register_successful_parse(bool &flag,T &i) const {
260 // silence MSVC warning C4512: assignment operator could not be generated
261 BOOST_DELETED_FUNCTION(kwd_infinite_iterator& operator= (kwd_infinite_iterator const&))
264 // This class enables the transportation of parameters needed to call
265 // the occurrence constraint checker from higher level calls
266 // It also serves to select the correct parse function call
267 // of the keyword parser. The implementation changes depending if it is
268 // called form a keyword parsing loop or not.
269 template <typename Skipper, typename NoCasePass>
270 struct skipper_keyword_marker
272 typedef NoCasePass no_case_pass;
274 skipper_keyword_marker(Skipper const &skipper,bool &flag,int &counter) :
280 const Skipper &skipper;
285 template <typename Subject, typename KeywordType, typename LoopIter , typename NoCase, typename Distinct >
286 struct kwd_parser : spirit::qi::unary_parser<kwd_parser<Subject, KeywordType, LoopIter , NoCase, Distinct > >
288 struct kwd_parser_id;
290 typedef Subject subject_type;
291 typedef NoCase no_case_keyword;
292 typedef Distinct distinct;
295 remove_const<typename traits::char_type_of<KeywordType>::type>::type
298 typedef std::basic_string<char_type> keyword_type;
300 template <typename Context, typename Iterator>
304 traits::build_std_vector<
305 typename traits::attribute_of<
306 Subject, Context, Iterator>::type
312 kwd_parser(Subject const& subject
313 , typename add_reference<KeywordType>::type keyword
314 , LoopIter const& iter)
315 : subject(subject), iter(iter), keyword(keyword) {}
317 template<typename CharEncoding>
318 kwd_parser(Subject const& subject
319 , typename add_reference<KeywordType>::type keyword
320 , LoopIter const& iter, CharEncoding encoding)
321 : subject(subject), iter(iter), keyword(keyword,encoding) {}
324 // Call the subject parser on a non container attribute
325 template <typename Iterator, typename Context
326 , typename Skipper, typename Attribute>
327 bool parse_impl(Iterator& first, Iterator const& last
328 , Context& context, Skipper const& skipper
329 , Attribute& attr,mpl::false_) const
331 return subject.parse(first,last,context,skipper,attr);
334 // Call the subject parser on a container attribute
335 template <typename Iterator, typename Context
336 , typename Skipper, typename Attribute>
337 bool parse_impl(Iterator& first, Iterator const& last
338 , Context& context, Skipper const& skipper
339 , Attribute& attr,mpl::true_) const
342 // synthesized attribute needs to be default constructed
343 typename traits::container_value<Attribute>::type val =
344 typename traits::container_value<Attribute>::type();
346 Iterator save = first;
347 bool r = subject.parse(first,last,context,skipper, val);
350 // push the parsed value into our attribute
351 r = traits::push_back(attr, val);
358 template <typename Iterator, typename Context
359 , typename Skipper, typename Attribute,typename NoCasePass>
360 bool parse(Iterator& first, Iterator const& last
361 , Context& context, skipper_keyword_marker<Skipper,NoCasePass> const& skipper
362 , Attribute &attr) const
365 typedef typename traits::attribute_of<
366 Subject, Context, Iterator>::type
369 typedef typename mpl::and_<
370 traits::is_container<Attribute>
371 , mpl::not_< traits::is_weak_substitute< subject_attribute,Attribute > >
374 if((no_case_keyword::value && NoCasePass::value) || !NoCasePass::value)
376 if(parse_impl(first,last,context,skipper.skipper,attr, predicate()))
377 return iter.register_successful_parse(skipper.flag,skipper.counter);
382 template <typename Iterator, typename Context
383 , typename Skipper, typename Attribute>
384 bool parse(Iterator& first, Iterator const& last
385 , Context& context, Skipper const& skipper
386 , Attribute& attr) const
388 typedef typename traits::attribute_of<
389 Subject, Context, Iterator>::type
392 typedef typename mpl::and_<
393 traits::is_container<Attribute>
394 , mpl::not_< traits::is_weak_substitute< subject_attribute,Attribute > >
399 bool flag = iter.flag_init();
401 Iterator save = first;
402 spirit::qi::skip_over(first, last, skipper);
403 if(keyword.parse(first,last,context,skipper,unused)){
404 if((!distinct::value) || skipper.parse(first,last,unused,unused,unused)){
405 // Followed by the subject parser
406 spirit::qi::skip_over(first, last, skipper);
407 if(parse_impl(first,last,context,skipper,attr, predicate()))
409 return iter.register_successful_parse(flag,counter);
418 template <typename Context>
419 info what(Context& context) const
422 if(no_case_keyword::value)
423 return info("idkwd", subject.what(context));
425 return info("dkwd", subject.what(context));
429 if(no_case_keyword::value)
430 return info("ikwd", subject.what(context));
432 return info("kwd", subject.what(context));
439 typedef typename mpl::if_<
441 spirit::qi::no_case_literal_string< KeywordType, true>,
442 spirit::qi::literal_string<KeywordType, true> >::type keyword_string_type;
443 keyword_string_type keyword;
445 // silence MSVC warning C4512: assignment operator could not be generated
446 BOOST_DELETED_FUNCTION(kwd_parser& operator= (kwd_parser const&))
449 template <typename Iterator, typename Context, typename Skipper>
450 static spirit::qi::detail::fail_function<Iterator, Context, Skipper>
452 Iterator& first, Iterator const& last
453 , Context& context, Skipper const& skipper)
455 return spirit::qi::detail::fail_function<Iterator, Context, Skipper>
456 (first, last, context, skipper);
462 template <typename Subject, typename KeywordType, typename LoopIter, typename Distinct>
463 struct complex_kwd_parser : spirit::qi::unary_parser<complex_kwd_parser<Subject, KeywordType, LoopIter, Distinct > >
465 struct complex_kwd_parser_id;
466 typedef Subject subject_type;
467 typedef Distinct distinct;
469 template <typename Context, typename Iterator>
473 traits::build_std_vector<
474 typename traits::attribute_of<
475 Subject, Context, Iterator>::type
481 complex_kwd_parser(Subject const& subject
482 , typename add_reference<KeywordType>::type keyword
483 , LoopIter const& iter)
484 : subject(subject), iter(iter), keyword(keyword) {}
486 // Call the subject parser on a non container attribute
487 template <typename Iterator, typename Context
488 , typename Skipper, typename Attribute>
489 bool parse_impl(Iterator& first, Iterator const& last
490 , Context& context, Skipper const& skipper
491 , Attribute& attr,mpl::false_) const
493 return subject.parse(first,last,context,skipper,attr);
496 // Call the subject parser on a container attribute
497 template <typename Iterator, typename Context
498 , typename Skipper, typename Attribute>
499 bool parse_impl(Iterator& first, Iterator const& last
500 , Context& context, Skipper const& skipper
501 , Attribute& attr,mpl::true_) const
504 // synthesized attribute needs to be default constructed
505 typename traits::container_value<Attribute>::type val =
506 typename traits::container_value<Attribute>::type();
508 Iterator save = first;
509 bool r = subject.parse(first,last,context,skipper, val);
512 // push the parsed value into our attribute
513 r = traits::push_back(attr, val);
520 template <typename Iterator, typename Context
521 , typename Skipper, typename Attribute,typename NoCasePass>
522 bool parse(Iterator& first, Iterator const& last
523 , Context& context, skipper_keyword_marker<Skipper,NoCasePass> const& skipper
524 , Attribute &attr) const
527 typedef typename traits::attribute_of<
528 Subject, Context, Iterator>::type
531 typedef typename mpl::and_<
532 traits::is_container<Attribute>
533 , mpl::not_< traits::is_weak_substitute< subject_attribute,Attribute > >
536 if(parse_impl(first,last,context,skipper.skipper,attr, predicate()))
537 return iter.register_successful_parse(skipper.flag,skipper.counter);
541 template <typename Iterator, typename Context
542 , typename Skipper, typename Attribute>
543 bool parse(Iterator& first, Iterator const& last
544 , Context& context, Skipper const& skipper
545 , Attribute& attr) const
547 typedef typename traits::attribute_of<
548 Subject, Context, Iterator>::type
551 typedef typename mpl::and_<
552 traits::is_container<Attribute>
553 , mpl::not_< traits::is_weak_substitute< subject_attribute,Attribute > >
558 bool flag = iter.flag_init();
560 Iterator save = first;
561 spirit::qi::skip_over(first, last, skipper);
562 if(keyword.parse(first,last,context,skipper,unused)){
563 if( !distinct::value || skipper.parse(first,last,unused,unused,unused)){
564 // Followed by the subject parser
565 spirit::qi::skip_over(first, last, skipper);
566 if(parse_impl(first,last,context,skipper,attr, predicate()))
568 return iter.register_successful_parse(flag,counter);
577 template <typename Context>
578 info what(Context& context) const
581 return info("dkwd", subject.what(context));
583 return info("kwd", subject.what(context));
591 // silence MSVC warning C4512: assignment operator could not be generated
592 BOOST_DELETED_FUNCTION(complex_kwd_parser& operator= (complex_kwd_parser const&))
595 template <typename Iterator, typename Context, typename Skipper>
596 static spirit::qi::detail::fail_function<Iterator, Context, Skipper>
598 Iterator& first, Iterator const& last
599 , Context& context, Skipper const& skipper)
601 return spirit::qi::detail::fail_function<Iterator, Context, Skipper>
602 (first, last, context, skipper);
609 ///////////////////////////////////////////////////////////////////////////////
610 namespace boost { namespace spirit { namespace qi
613 ///////////////////////////////////////////////////////////////////////////
614 // Parser generators: make_xxx function (objects)
615 ///////////////////////////////////////////////////////////////////////////
617 template <typename T1, typename T2, typename Subject, typename Modifiers, typename Distinct, typename MakeDirectiveHelper>
618 struct make_directive_internal_2_args
621 // is the keyword a string keyword ?
622 typedef typename traits::is_string<T1> is_string_kwd_type;
623 // make the keyword type
624 typedef typename mpl::if_< is_string_kwd_type ,
626 typename result_of::compile<qi::domain, T1>::type
627 >::type keyword_type;
629 typedef typename add_const<keyword_type>::type const_keyword;
630 // select the pass iterator type
631 typedef typename MakeDirectiveHelper::iterator_type iterator_type;
632 // determine if a no case modifier applies to the context
633 typedef has_modifier<Modifiers, tag::char_code_base<tag::no_case> > no_case;
634 // Determine the full type of the kwd / complex_kwd directive
638 repository::qi::kwd_parser<Subject, const_keyword, iterator_type, no_case, Distinct >,
639 repository::qi::complex_kwd_parser<Subject, const_keyword, iterator_type, Distinct >
642 // Return a kwd parser object
643 template <typename Terminal>
644 result_type create_kwd_string(Terminal const &term, Subject const & subject, boost::mpl::true_ ) const
646 typename spirit::detail::get_encoding<Modifiers,
647 spirit::char_encoding::standard>::type encoding;
648 return result_type(subject
649 ,MakeDirectiveHelper::make_iterator(term.args)
653 template <typename Terminal>
654 result_type create_kwd_string(Terminal const &term, Subject const & subject, boost::mpl::false_ ) const
656 return result_type(subject
657 ,fusion::at_c<0>(term.args)
658 ,MakeDirectiveHelper::make_iterator(term.args)
661 template <typename Terminal>
662 result_type create_kwd(Terminal const &term, Subject const & subject, Modifiers const& /*modifiers*/, boost::mpl::true_ ) const
664 return create_kwd_string(term,subject,no_case());
666 // Return a complex_kwd parser object
667 template <typename Terminal>
668 result_type create_kwd(Terminal const &term , Subject const & subject, Modifiers const& modifiers, boost::mpl::false_ ) const
670 return result_type(subject
671 ,compile<qi::domain>(fusion::at_c<0>(term.args),modifiers)
672 ,MakeDirectiveHelper::make_iterator(term.args)
675 // Select which object type to return
676 template <typename Terminal>
677 result_type operator()(
678 Terminal const& term, Subject const& subject, Modifiers const& modifiers) const
680 return create_kwd(term, subject, modifiers, is_string_kwd_type());
685 // Directive kwd(key)[p]
686 template <typename T1, typename Subject, typename Modifiers, typename Distinct>
687 struct make_directive_internal
689 // is the keyword a string keyword ?
690 typedef typename traits::is_string<T1> is_string_kwd_type;
691 // make the keyword type
692 typedef typename mpl::if_< is_string_kwd_type ,
694 typename result_of::compile<qi::domain, T1, Modifiers>::type
695 >::type keyword_type;
697 typedef typename add_const<keyword_type>::type const_keyword;
698 // select the pass iterator type
699 typedef repository::qi::kwd_pass_iterator<int> iterator_type;
700 // determine if a no case modifier applies to the context
701 typedef has_modifier<Modifiers, tag::char_code_base<tag::no_case> > no_case;
702 // Determine the full type of the kwd / complex_kwd directive
706 repository::qi::kwd_parser<Subject, const_keyword, iterator_type, no_case, Distinct >,
707 repository::qi::complex_kwd_parser<Subject, const_keyword, iterator_type, Distinct>
710 // Return a kwd parser object
711 template <typename Terminal>
712 result_type create_kwd_string(Terminal const &term, Subject const & subject, boost::mpl::true_) const
714 typename spirit::detail::get_encoding<Modifiers,
715 spirit::char_encoding::standard>::type encoding;
717 return result_type(subject
718 ,fusion::at_c<0>(term.args)
724 template <typename Terminal>
725 result_type create_kwd_string(Terminal const &term, Subject const & subject, boost::mpl::false_) const
727 return result_type(subject
728 ,fusion::at_c<0>(term.args)
732 template <typename Terminal>
733 result_type create_kwd(Terminal const &term, Subject const & subject, Modifiers const& /*modifiers*/, boost::mpl::true_ ) const
735 return create_kwd_string(term,subject,no_case());
737 // Return a complex_kwd parser object
738 template <typename Terminal>
739 result_type create_kwd(Terminal const &term , Subject const & subject, Modifiers const& modifiers, boost::mpl::false_ ) const
741 return result_type(subject
742 ,compile<qi::domain>(fusion::at_c<0>(term.args),modifiers)
746 // Select which object type to return
747 template <typename Terminal>
748 result_type operator()(
749 Terminal const& term, Subject const& subject, Modifiers const& modifiers ) const
751 return create_kwd(term, subject, modifiers, is_string_kwd_type());
755 template <typename T1, typename Subject, typename Modifiers>
756 struct make_directive<
757 terminal_ex<repository::tag::kwd, fusion::vector1<T1> >, Subject, Modifiers>
759 typedef make_directive_internal<T1, Subject, Modifiers, mpl::false_> make_directive_type;
760 typedef typename make_directive_type::result_type result_type;
761 template <typename Terminal>
762 result_type operator()(
763 Terminal const& term, Subject const& subject, Modifiers const& modifiers) const
766 return make_directive_type()(term, subject, modifiers);
771 template <typename T1, typename Subject, typename Modifiers>
772 struct make_directive<
773 terminal_ex<repository::tag::dkwd, fusion::vector1<T1> >, Subject, Modifiers>
775 typedef make_directive_internal<T1, Subject, Modifiers, mpl::true_> make_directive_type;
776 typedef typename make_directive_type::result_type result_type;
777 template <typename Terminal>
778 result_type operator()(
779 Terminal const& term, Subject const& subject, Modifiers const& modifiers) const
782 return make_directive_type()(term, subject, modifiers);
789 // Directive ikwd(key)[p]
790 template <typename T1, typename Subject, typename Modifiers>
791 struct make_directive<
792 terminal_ex<repository::tag::ikwd, fusion::vector1<T1> >, Subject, Modifiers>
794 typedef typename add_const<T1>::type const_keyword;
795 typedef repository::qi::kwd_pass_iterator<int> iterator_type;
797 typedef repository::qi::kwd_parser<Subject, const_keyword, iterator_type, mpl::true_, mpl::false_ > result_type;
799 template <typename Terminal>
800 result_type operator()(
801 Terminal const& term, Subject const& subject, unused_type) const
803 typename spirit::detail::get_encoding<Modifiers,
804 spirit::char_encoding::standard>::type encoding;
806 return result_type(subject
807 ,fusion::at_c<0>(term.args)
814 template <typename T1, typename Subject, typename Modifiers>
815 struct make_directive<
816 terminal_ex<repository::tag::idkwd, fusion::vector1<T1> >, Subject, Modifiers>
818 typedef typename add_const<T1>::type const_keyword;
819 typedef repository::qi::kwd_pass_iterator<int> iterator_type;
821 typedef repository::qi::kwd_parser<Subject, const_keyword, iterator_type, mpl::true_, mpl::true_ > result_type;
823 template <typename Terminal>
824 result_type operator()(
825 Terminal const& term, Subject const& subject, unused_type) const
827 typename spirit::detail::get_encoding<Modifiers,
828 spirit::char_encoding::standard>::type encoding;
830 return result_type(subject
831 ,fusion::at_c<0>(term.args)
838 // Directive kwd(key,exact)[p]
839 template <typename T>
840 struct make_exact_helper
842 typedef repository::qi::kwd_exact_iterator<T> iterator_type;
843 template<typename Args>
844 static iterator_type make_iterator(Args const& args)
846 return iterator_type(fusion::at_c<1>(args));
850 template <typename T1, typename T2, typename Subject, typename Modifiers>
851 struct make_directive<
852 terminal_ex<repository::tag::kwd, fusion::vector2<T1,T2> >, Subject, Modifiers>
854 typedef make_directive_internal_2_args< T1
859 , make_exact_helper<T2>
860 > make_directive_type;
861 typedef typename make_directive_type::result_type result_type;
862 template <typename Terminal>
863 result_type operator()(
864 Terminal const& term, Subject const& subject, Modifiers const& modifiers) const
867 return make_directive_type()(term,subject, modifiers);
872 template <typename T1, typename T2, typename Subject, typename Modifiers>
873 struct make_directive<
874 terminal_ex<repository::tag::dkwd, fusion::vector2<T1,T2> >, Subject, Modifiers>
876 typedef make_directive_internal_2_args< T1
881 , make_exact_helper<T2>
882 > make_directive_type;
884 typedef typename make_directive_type::result_type result_type;
885 template <typename Terminal>
886 result_type operator()(
887 Terminal const& term, Subject const& subject, Modifiers const& modifiers) const
890 return make_directive_type()(term, subject, modifiers);
896 // Directive ikwd(key,exact)[p]
897 template <typename T1, typename T2, typename Subject, typename Modifiers>
898 struct make_directive<
899 terminal_ex<repository::tag::ikwd, fusion::vector2<T1,T2> >, Subject, Modifiers>
901 typedef typename add_const<T1>::type const_keyword;
902 typedef repository::qi::kwd_exact_iterator<T2> iterator_type;
904 typedef repository::qi::kwd_parser<Subject, const_keyword, iterator_type, mpl::true_, mpl::false_ > result_type;
906 template <typename Terminal>
907 result_type operator()(
908 Terminal const& term, Subject const& subject, Modifiers const& /*modifiers*/) const
910 typename spirit::detail::get_encoding<Modifiers,
911 spirit::char_encoding::standard>::type encoding;
912 return result_type(subject
913 , fusion::at_c<0>(term.args)
914 , fusion::at_c<1>(term.args)
920 template <typename T1, typename T2, typename Subject, typename Modifiers>
921 struct make_directive<
922 terminal_ex<repository::tag::idkwd, fusion::vector2<T1,T2> >, Subject, Modifiers>
924 typedef typename add_const<T1>::type const_keyword;
925 typedef repository::qi::kwd_exact_iterator<T2> iterator_type;
927 typedef repository::qi::kwd_parser<Subject, const_keyword, iterator_type, mpl::true_, mpl::true_ > result_type;
929 template <typename Terminal>
930 result_type operator()(
931 Terminal const& term, Subject const& subject, Modifiers const& /*modifiers*/) const
933 typename spirit::detail::get_encoding<Modifiers,
934 spirit::char_encoding::standard>::type encoding;
935 return result_type(subject
936 , fusion::at_c<0>(term.args)
937 , fusion::at_c<1>(term.args)
944 // Directive kwd(min, max)[p]
946 template <typename T>
947 struct make_finite_helper
949 typedef repository::qi::kwd_finite_iterator<T> iterator_type;
950 template<typename Args>
951 static iterator_type make_iterator(Args const& args)
953 return iterator_type(fusion::at_c<1>(args),fusion::at_c<2>(args));
958 template <typename T1, typename T2, typename Subject, typename Modifiers>
959 struct make_directive<
960 terminal_ex<repository::tag::kwd, fusion::vector3<T1,T2,T2> >, Subject, Modifiers>
962 typedef make_directive_internal_2_args< T1
967 , make_finite_helper<T2>
968 > make_directive_type;
971 typedef typename make_directive_type::result_type result_type;
972 template <typename Terminal>
973 result_type operator()(
974 Terminal const& term, Subject const& subject, Modifiers const& modifiers) const
977 return make_directive_type()(term,subject, modifiers);
982 template <typename T1, typename T2, typename Subject, typename Modifiers>
983 struct make_directive<
984 terminal_ex<repository::tag::dkwd, fusion::vector3<T1,T2,T2> >, Subject, Modifiers>
987 typedef make_directive_internal_2_args< T1
992 , make_finite_helper<T2>
993 > make_directive_type;
995 typedef typename make_directive_type::result_type result_type;
996 template <typename Terminal>
997 result_type operator()(
998 Terminal const& term, Subject const& subject, Modifiers const& modifiers) const
1001 return make_directive_type()(term,subject, modifiers);
1006 // Directive ikwd(min, max)[p]
1007 template <typename T1, typename T2, typename Subject, typename Modifiers>
1008 struct make_directive<
1009 terminal_ex<repository::tag::ikwd, fusion::vector3< T1, T2, T2> >, Subject, Modifiers>
1011 typedef typename add_const<T1>::type const_keyword;
1012 typedef repository::qi::kwd_finite_iterator<T2> iterator_type;
1014 typedef repository::qi::kwd_parser<Subject, const_keyword, iterator_type, mpl::true_, mpl::false_ > result_type;
1016 template <typename Terminal>
1017 result_type operator()(
1018 Terminal const& term, Subject const& subject, unused_type) const
1021 typename spirit::detail::get_encoding<Modifiers,
1022 spirit::char_encoding::standard>::type encoding;
1023 return result_type(subject, fusion::at_c<0>(term.args),
1025 fusion::at_c<1>(term.args)
1026 , fusion::at_c<2>(term.args)
1033 template <typename T1, typename T2, typename Subject, typename Modifiers>
1034 struct make_directive<
1035 terminal_ex<repository::tag::idkwd, fusion::vector3< T1, T2, T2> >, Subject, Modifiers>
1037 typedef typename add_const<T1>::type const_keyword;
1038 typedef repository::qi::kwd_finite_iterator<T2> iterator_type;
1040 typedef repository::qi::kwd_parser<Subject, const_keyword, iterator_type, mpl::true_, mpl::true_ > result_type;
1042 template <typename Terminal>
1043 result_type operator()(
1044 Terminal const& term, Subject const& subject, unused_type) const
1047 typename spirit::detail::get_encoding<Modifiers,
1048 spirit::char_encoding::standard>::type encoding;
1049 return result_type(subject, fusion::at_c<0>(term.args),
1051 fusion::at_c<1>(term.args)
1052 , fusion::at_c<2>(term.args)
1060 // Directive kwd(min, inf)[p]
1062 template <typename T>
1063 struct make_infinite_helper
1065 typedef repository::qi::kwd_infinite_iterator<T> iterator_type;
1066 template<typename Args>
1067 static iterator_type make_iterator(Args const& args)
1069 return iterator_type(fusion::at_c<1>(args));
1075 template <typename T1, typename T2, typename Subject, typename Modifiers>
1076 struct make_directive<
1077 terminal_ex<repository::tag::kwd, fusion::vector3<T1,T2,inf_type> >, Subject, Modifiers>
1079 typedef make_directive_internal_2_args< T1
1084 , make_infinite_helper<T2>
1085 > make_directive_type;
1087 typedef typename make_directive_type::result_type result_type;
1088 template <typename Terminal>
1089 result_type operator()(
1090 Terminal const& term, Subject const& subject, unused_type) const
1093 return make_directive_type()(term,subject, unused_type());
1098 template <typename T1, typename T2, typename Subject, typename Modifiers>
1099 struct make_directive<
1100 terminal_ex<repository::tag::dkwd, fusion::vector3<T1,T2,inf_type> >, Subject, Modifiers>
1102 typedef make_directive_internal_2_args< T1
1107 , make_infinite_helper<T2>
1108 > make_directive_type;
1110 typedef typename make_directive_type::result_type result_type;
1111 template <typename Terminal>
1112 result_type operator()(
1113 Terminal const& term, Subject const& subject, unused_type) const
1116 return make_directive_type()(term,subject, unused_type());
1122 // Directive ikwd(min, inf)[p]
1123 template <typename T1, typename T2, typename Subject, typename Modifiers>
1124 struct make_directive<
1125 terminal_ex<repository::tag::ikwd
1126 , fusion::vector3<T1, T2, inf_type> >, Subject, Modifiers>
1128 typedef typename add_const<T1>::type const_keyword;
1129 typedef repository::qi::kwd_infinite_iterator<T2> iterator_type;
1131 typedef repository::qi::kwd_parser<Subject, const_keyword, iterator_type, mpl::true_, mpl::false_ > result_type;
1133 template <typename Terminal>
1134 result_type operator()(
1135 Terminal const& term, Subject const& subject, unused_type) const
1137 typename spirit::detail::get_encoding<Modifiers,
1138 spirit::char_encoding::standard>::type encoding;
1140 return result_type(subject
1141 , fusion::at_c<0>(term.args)
1142 , fusion::at_c<1>(term.args)
1148 template <typename T1, typename T2, typename Subject, typename Modifiers>
1149 struct make_directive<
1150 terminal_ex<repository::tag::idkwd
1151 , fusion::vector3<T1, T2, inf_type> >, Subject, Modifiers>
1153 typedef typename add_const<T1>::type const_keyword;
1154 typedef repository::qi::kwd_infinite_iterator<T2> iterator_type;
1156 typedef repository::qi::kwd_parser<Subject, const_keyword, iterator_type, mpl::true_, mpl::true_ > result_type;
1158 template <typename Terminal>
1159 result_type operator()(
1160 Terminal const& term, Subject const& subject, unused_type) const
1162 typename spirit::detail::get_encoding<Modifiers,
1163 spirit::char_encoding::standard>::type encoding;
1165 return result_type(subject
1166 , fusion::at_c<0>(term.args)
1167 , fusion::at_c<1>(term.args)
1176 namespace boost { namespace spirit { namespace traits
1178 template <typename Subject, typename KeywordType
1179 , typename LoopIter, typename NoCase , typename Distinct>
1180 struct has_semantic_action<
1181 repository::qi::kwd_parser< Subject, KeywordType, LoopIter, NoCase, Distinct > >
1182 : unary_has_semantic_action<Subject> {};
1184 template <typename Subject, typename KeywordType
1185 , typename LoopIter, typename Distinct >
1186 struct has_semantic_action<
1187 repository::qi::complex_kwd_parser< Subject, KeywordType, LoopIter, Distinct > >
1188 : unary_has_semantic_action<Subject> {};
1190 template <typename Subject, typename KeywordType
1191 , typename LoopIter, typename NoCase, typename Attribute, typename Context
1192 , typename Iterator, typename Distinct>
1193 struct handles_container<repository::qi::kwd_parser<Subject, KeywordType, LoopIter, NoCase, Distinct>, Attribute
1194 , Context, Iterator>
1195 : unary_handles_container<Subject, Attribute, Context, Iterator> {};
1197 template <typename Subject, typename KeywordType
1199 , typename Attribute, typename Context
1200 , typename Iterator, typename Distinct>
1201 struct handles_container<repository::qi::complex_kwd_parser<Subject, KeywordType, LoopIter, Distinct>, Attribute
1202 , Context, Iterator>
1203 : unary_handles_container<Subject, Attribute, Context, Iterator> {};
1207 #if defined(_MSC_VER)
1208 # pragma warning(pop)