Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 09:52:29

0001 /*=============================================================================
0002     Copyright (c) 2001-2011 Joel de Guzman
0003     Copyright (c) 2011 Thomas Bernard
0004 
0005     Distributed under the Boost Software License, Version 1.0. (See accompanying
0006     file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
0007 =============================================================================*/
0008 #ifndef BOOST_SPIRIT_REPOSITORY_QI_DIRECTIVE_KWD_HPP
0009 #define BOOST_SPIRIT_REPOSITORY_QI_DIRECTIVE_KWD_HPP
0010 
0011 #if defined(_MSC_VER)
0012 #pragma once
0013 #endif
0014 
0015 #include <boost/spirit/home/qi/meta_compiler.hpp>
0016 #include <boost/spirit/home/qi/parser.hpp>
0017 #include <boost/spirit/home/qi/auxiliary/lazy.hpp>
0018 #include <boost/spirit/home/qi/operator/kleene.hpp>
0019 #include <boost/spirit/home/qi/string/lit.hpp>
0020 #include <boost/spirit/home/support/container.hpp>
0021 #include <boost/spirit/home/qi/detail/attributes.hpp>
0022 #include <boost/spirit/home/qi/detail/fail_function.hpp>
0023 #include <boost/spirit/home/support/info.hpp>
0024 #include <boost/spirit/repository/home/support/kwd.hpp>
0025 #include <boost/fusion/include/at.hpp>
0026 #include <vector>
0027 
0028 #if defined(_MSC_VER)
0029 # pragma warning(push)
0030 # pragma warning(disable: 4127) // conditional expression is constant
0031 # pragma warning(disable: 4512) // assignment operator could not be generated.
0032 #endif
0033 
0034 namespace boost { namespace spirit
0035 {
0036     ///////////////////////////////////////////////////////////////////////////
0037     // Enablers
0038     ///////////////////////////////////////////////////////////////////////////
0039 
0040     template < typename T>
0041     struct use_directive<qi::domain
0042       , terminal_ex<repository::tag::kwd                     // enables kwd(key)[p]
0043         , fusion::vector1<T > >
0044     > : mpl::true_ {};
0045 
0046     template < typename T>
0047     struct use_directive<qi::domain
0048       , terminal_ex<repository::tag::ikwd                     // enables ikwd(key)[p]
0049         , fusion::vector1<T > >
0050     > : mpl::true_ {};
0051 
0052     template < typename T>
0053     struct use_directive<qi::domain
0054       , terminal_ex<repository::tag::dkwd                     // enables dkwd(key)[p]
0055         , fusion::vector1<T > >
0056     > : mpl::true_ {};
0057 
0058     template < typename T>
0059     struct use_directive<qi::domain
0060       , terminal_ex<repository::tag::idkwd                     // enables idkwd(key)[p]
0061         , fusion::vector1<T > >
0062     > : mpl::true_ {};
0063 
0064 
0065     template < typename T1, typename T2>
0066     struct use_directive<qi::domain
0067       , terminal_ex<repository::tag::kwd                     // enables kwd(key,exact)[p]
0068         , fusion::vector2< T1, T2 > >
0069     > : mpl::true_ {};
0070 
0071     template < typename T1, typename T2>
0072     struct use_directive<qi::domain
0073       , terminal_ex<repository::tag::ikwd                     // enables ikwd(key,exact)[p]
0074         , fusion::vector2< T1, T2 > >
0075     > : mpl::true_ {};
0076 
0077     template < typename T1, typename T2>
0078     struct use_directive<qi::domain
0079       , terminal_ex<repository::tag::dkwd                     // enables dkwd(key,exact)[p]
0080         , fusion::vector2< T1, T2 > >
0081     > : mpl::true_ {};
0082 
0083     template < typename T1, typename T2>
0084     struct use_directive<qi::domain
0085       , terminal_ex<repository::tag::idkwd                     // enables idkwd(key,exact)[p]
0086         , fusion::vector2< T1, T2 > >
0087     > : mpl::true_ {};
0088 
0089    template < typename T1, typename T2>
0090     struct use_directive<qi::domain
0091       , terminal_ex<repository::tag::kwd                     // enables kwd(min, max)[p]
0092         , fusion::vector3< T1, T2, T2 > >
0093     > : mpl::true_ {};
0094 
0095     template < typename T1, typename T2>
0096     struct use_directive<qi::domain
0097       , terminal_ex<repository::tag::ikwd                     // enables ikwd(min, max)[p]
0098         , fusion::vector3< T1, T2, T2 > >
0099     > : mpl::true_ {};
0100 
0101     template < typename T1, typename T2>
0102     struct use_directive<qi::domain
0103       , terminal_ex<repository::tag::dkwd                     // enables dkwd(min, max)[p]
0104         , fusion::vector3< T1, T2, T2 > >
0105     > : mpl::true_ {};
0106 
0107     template < typename T1, typename T2>
0108     struct use_directive<qi::domain
0109       , terminal_ex<repository::tag::idkwd                     // enables idkwd(min, max)[p]
0110         , fusion::vector3< T1, T2, T2 > >
0111     > : mpl::true_ {};
0112 
0113    template < typename T1, typename T2>
0114     struct use_directive<qi::domain
0115       , terminal_ex<repository::tag::kwd                     // enables kwd(min, inf)[p]
0116         , fusion::vector3<T1, T2, inf_type > >
0117     > : mpl::true_ {};
0118 
0119     template < typename T1, typename T2>
0120     struct use_directive<qi::domain
0121       , terminal_ex<repository::tag::ikwd                     // enables ikwd(min, inf)[p]
0122         , fusion::vector3<T1, T2, inf_type > >
0123     > : mpl::true_ {};
0124 
0125    template < typename T1, typename T2>
0126     struct use_directive<qi::domain
0127       , terminal_ex<repository::tag::dkwd                     // enables dkwd(min, inf)[p]
0128         , fusion::vector3<T1, T2, inf_type > >
0129     > : mpl::true_ {};
0130 
0131     template < typename T1, typename T2>
0132     struct use_directive<qi::domain
0133       , terminal_ex<repository::tag::idkwd                     // enables idkwd(min, inf)[p]
0134         , fusion::vector3<T1, T2, inf_type > >
0135     > : mpl::true_ {};
0136 
0137 
0138   /*  template <>                                     // enables *lazy* kwd(exact)[p]
0139     struct use_lazy_directive<
0140         qi::domain
0141       , tag::kwd
0142       , 1 // arity
0143     > : mpl::true_ {};
0144 
0145     template <>                                     // enables *lazy* kwd(min, max)[p]
0146     struct use_lazy_directive<                      // and kwd(min, inf)[p]
0147         qi::domain
0148       , tag::kwd
0149       , 2 // arity
0150     > : mpl::true_ {};
0151 */
0152 
0153 }}
0154 
0155 namespace boost { namespace spirit { namespace repository { namespace qi
0156 {
0157 #ifndef BOOST_SPIRIT_NO_PREDEFINED_TERMINALS
0158     using repository::kwd;
0159     using repository::ikwd;
0160     using repository::dkwd;
0161     using repository::idkwd;
0162     using spirit::inf;
0163 #endif
0164     using repository::kwd_type;
0165     using repository::ikwd_type;
0166     using repository::dkwd_type;
0167     using repository::idkwd_type;
0168     using spirit::inf_type;
0169 
0170 template <typename T>
0171     struct kwd_pass_iterator // handles kwd(exact)[p]
0172     {
0173         kwd_pass_iterator() {}
0174         bool flag_init() const { return true; }
0175         bool register_successful_parse(bool &flag,T &/*i*/) const {
0176             flag=true;
0177             return true;
0178         }
0179     };
0180 
0181     template <typename T>
0182     struct kwd_exact_iterator // handles kwd(exact)[p]
0183     {
0184         kwd_exact_iterator(T const exact)
0185           : exact(exact){}
0186 
0187         typedef T type;
0188         bool flag_init() const { return false; }
0189         bool register_successful_parse(bool &flag,T &i) const {
0190             i++;
0191             if(i<exact)
0192             {
0193                 flag=false;
0194                 return true;
0195             }
0196             else if(i==exact)
0197             {
0198                 flag=true;
0199                 return true;
0200             }
0201             else
0202                 return flag=false;
0203 
0204         }
0205         T const exact;
0206     };
0207 
0208     template <typename T>
0209     struct kwd_finite_iterator // handles kwd(min, max)[p]
0210     {
0211         kwd_finite_iterator(T const min, T const max)
0212           : min BOOST_PREVENT_MACRO_SUBSTITUTION (min)
0213           , max BOOST_PREVENT_MACRO_SUBSTITUTION (max)
0214             {}
0215 
0216         typedef T type;
0217         bool flag_init() const { return min==0; }
0218         bool register_successful_parse(bool &flag,T &i) const {
0219             i++;
0220             if(i<min)
0221             {
0222                 flag=false;
0223                 return true;
0224             }
0225             else if(i>=min && i<=max)
0226             {
0227                 return flag=true;
0228             }
0229             else
0230                 return flag=false;
0231         }
0232         T const min;
0233         T const max;
0234     };
0235 
0236     template <typename T>
0237     struct kwd_infinite_iterator // handles kwd(min, inf)[p]
0238     {
0239         kwd_infinite_iterator(T const min)
0240           : min BOOST_PREVENT_MACRO_SUBSTITUTION (min) {}
0241 
0242         typedef T type;
0243         bool flag_init() const { return min==0; }
0244         bool register_successful_parse(bool &flag,T &i) const {
0245             i++;
0246             flag = i>=min;
0247             return true;
0248         }
0249         T const min;
0250     };
0251 
0252     // This class enables the transportation of parameters needed to call
0253     // the occurrence constraint checker from higher level calls
0254     // It also serves to select the correct parse function call
0255     // of the keyword parser. The implementation changes depending if it is
0256     // called form a keyword parsing loop or not.
0257     template <typename Skipper, typename NoCasePass>
0258     struct skipper_keyword_marker
0259     {
0260         typedef NoCasePass no_case_pass;
0261 
0262         skipper_keyword_marker(Skipper const &skipper,bool &flag,int &counter) :
0263               skipper(skipper)
0264             , flag(flag)
0265             , counter(counter)
0266             {}
0267 
0268         const Skipper &skipper;
0269         bool &flag;
0270         int &counter;
0271     };
0272 
0273     template <typename Subject, typename KeywordType, typename LoopIter , typename NoCase, typename Distinct >
0274     struct kwd_parser : spirit::qi::unary_parser<kwd_parser<Subject, KeywordType, LoopIter , NoCase, Distinct > >
0275     {
0276         struct kwd_parser_id;
0277 
0278         typedef Subject subject_type;
0279         typedef NoCase no_case_keyword;
0280         typedef Distinct distinct;
0281 
0282         typedef typename
0283             remove_const<typename traits::char_type_of<KeywordType>::type>::type
0284         char_type;
0285 
0286         typedef std::basic_string<char_type> keyword_type;
0287 
0288         template <typename Context, typename Iterator>
0289         struct attribute
0290         {
0291             typedef typename
0292             traits::build_std_vector<
0293                 typename traits::attribute_of<
0294                 Subject, Context, Iterator>::type
0295                         >::type
0296                 type;
0297         };
0298 
0299 
0300         kwd_parser(Subject const& subject
0301            , typename add_reference<KeywordType>::type keyword
0302            , LoopIter const& iter)
0303           : subject(subject), iter(iter), keyword(keyword) {}
0304 
0305         template<typename CharEncoding>
0306         kwd_parser(Subject const& subject
0307            , typename add_reference<KeywordType>::type keyword
0308            , LoopIter const& iter, CharEncoding encoding)
0309           : subject(subject), iter(iter), keyword(keyword,encoding) {}
0310 
0311 
0312         // Call the subject parser on a non container attribute
0313         template <typename Iterator, typename Context
0314           , typename Skipper, typename Attribute>
0315         bool parse_impl(Iterator& first, Iterator const& last
0316           , Context& context, Skipper const& skipper
0317           , Attribute& attr,mpl::false_) const
0318         {
0319             return subject.parse(first,last,context,skipper,attr);
0320         }
0321 
0322         // Call the subject parser on a container attribute
0323         template <typename Iterator, typename Context
0324           , typename Skipper, typename Attribute>
0325         bool parse_impl(Iterator& first, Iterator const& last
0326           , Context& context, Skipper const& skipper
0327           , Attribute& attr,mpl::true_) const
0328         {
0329 
0330             // synthesized attribute needs to be default constructed
0331             typename traits::container_value<Attribute>::type val =
0332                 typename traits::container_value<Attribute>::type();
0333 
0334             Iterator save = first;
0335             bool r = subject.parse(first,last,context,skipper, val);
0336             if (r)
0337             {
0338                 // push the parsed value into our attribute
0339                 r = traits::push_back(attr, val);
0340                 if (!r)
0341                     first = save;
0342             }
0343             return r;
0344         }
0345 
0346        template <typename Iterator, typename Context
0347           , typename Skipper, typename Attribute,typename NoCasePass>
0348         bool parse(Iterator& first, Iterator const& last
0349           , Context& context, skipper_keyword_marker<Skipper,NoCasePass> const& skipper
0350           , Attribute &attr) const
0351         {
0352 
0353             typedef typename traits::attribute_of<
0354                 Subject, Context, Iterator>::type
0355                 subject_attribute;
0356 
0357             typedef typename mpl::and_<
0358              traits::is_container<Attribute>
0359             , mpl::not_< traits::is_weak_substitute< subject_attribute,Attribute > >
0360             >::type predicate;
0361 
0362             if((no_case_keyword::value && NoCasePass::value) || !NoCasePass::value)
0363             {
0364                 if(parse_impl(first,last,context,skipper.skipper,attr, predicate()))
0365                     return iter.register_successful_parse(skipper.flag,skipper.counter);
0366             }
0367             return false;
0368         }
0369 
0370         template <typename Iterator, typename Context
0371           , typename Skipper, typename Attribute>
0372         bool parse(Iterator& first, Iterator const& last
0373           , Context& context, Skipper const& skipper
0374           , Attribute& attr) const
0375           {
0376               typedef typename traits::attribute_of<
0377                 Subject, Context, Iterator>::type
0378                 subject_attribute;
0379 
0380             typedef typename mpl::and_<
0381             traits::is_container<Attribute>
0382             , mpl::not_< traits::is_weak_substitute< subject_attribute,Attribute > >
0383             >::type predicate;
0384 
0385 
0386             // Parse the keyword
0387             bool flag = iter.flag_init();
0388             int counter = 0;
0389             Iterator save = first;
0390             spirit::qi::skip_over(first, last, skipper);
0391             if(keyword.parse(first,last,context,skipper,unused)){
0392                 if((!distinct::value) || skipper.parse(first,last,unused,unused,unused)){
0393                   // Followed by the subject parser
0394                   spirit::qi::skip_over(first, last, skipper);
0395                   if(parse_impl(first,last,context,skipper,attr, predicate()))
0396                   {
0397                       return iter.register_successful_parse(flag,counter);
0398                   }
0399                 }
0400             }
0401             first = save;
0402             return flag;
0403           }
0404 
0405 
0406         template <typename Context>
0407           info what(Context& context) const
0408           {
0409             if(distinct::value){
0410               if(no_case_keyword::value)
0411                 return info("idkwd", subject.what(context));
0412               else
0413                 return info("dkwd", subject.what(context));
0414             }
0415             else
0416             {
0417               if(no_case_keyword::value)
0418                 return info("ikwd", subject.what(context));
0419               else
0420                 return info("kwd", subject.what(context));
0421             }
0422         }
0423 
0424         Subject subject;
0425         LoopIter iter;
0426 
0427         typedef typename mpl::if_<
0428                 no_case_keyword,
0429                 spirit::qi::no_case_literal_string< KeywordType, true>,
0430                 spirit::qi::literal_string<KeywordType, true> >::type keyword_string_type;
0431         keyword_string_type keyword;
0432 
0433     private:
0434         template <typename Iterator, typename Context, typename Skipper>
0435         static spirit::qi::detail::fail_function<Iterator, Context, Skipper>
0436         fail_function(
0437             Iterator& first, Iterator const& last
0438           , Context& context, Skipper const& skipper)
0439         {
0440             return spirit::qi::detail::fail_function<Iterator, Context, Skipper>
0441                 (first, last, context, skipper);
0442         }
0443 
0444 
0445     };
0446 
0447 template <typename Subject, typename KeywordType, typename LoopIter, typename Distinct>
0448     struct complex_kwd_parser : spirit::qi::unary_parser<complex_kwd_parser<Subject, KeywordType, LoopIter, Distinct > >
0449     {
0450         struct complex_kwd_parser_id;
0451         typedef Subject subject_type;
0452         typedef Distinct distinct;
0453 
0454         template <typename Context, typename Iterator>
0455         struct attribute
0456         {
0457             typedef typename
0458             traits::build_std_vector<
0459                 typename traits::attribute_of<
0460                 Subject, Context, Iterator>::type
0461                         >::type
0462                 type;
0463         };
0464 
0465 
0466         complex_kwd_parser(Subject const& subject
0467            , typename add_reference<KeywordType>::type keyword
0468            , LoopIter const& iter)
0469           : subject(subject), iter(iter), keyword(keyword) {}
0470 
0471         // Call the subject parser on a non container attribute
0472         template <typename Iterator, typename Context
0473           , typename Skipper, typename Attribute>
0474         bool parse_impl(Iterator& first, Iterator const& last
0475           , Context& context, Skipper const& skipper
0476           , Attribute& attr,mpl::false_) const
0477         {
0478             return subject.parse(first,last,context,skipper,attr);
0479         }
0480 
0481         // Call the subject parser on a container attribute
0482         template <typename Iterator, typename Context
0483           , typename Skipper, typename Attribute>
0484         bool parse_impl(Iterator& first, Iterator const& last
0485           , Context& context, Skipper const& skipper
0486           , Attribute& attr,mpl::true_) const
0487         {
0488 
0489             // synthesized attribute needs to be default constructed
0490             typename traits::container_value<Attribute>::type val =
0491                 typename traits::container_value<Attribute>::type();
0492 
0493             Iterator save = first;
0494             bool r = subject.parse(first,last,context,skipper, val);
0495             if (r)
0496             {
0497                 // push the parsed value into our attribute
0498                 r = traits::push_back(attr, val);
0499                 if (!r)
0500                     first = save;
0501             }
0502             return r;
0503         }
0504 
0505        template <typename Iterator, typename Context
0506           , typename Skipper, typename Attribute,typename NoCasePass>
0507         bool parse(Iterator& first, Iterator const& last
0508           , Context& context, skipper_keyword_marker<Skipper,NoCasePass> const& skipper
0509           , Attribute &attr) const
0510         {
0511 
0512             typedef typename traits::attribute_of<
0513                 Subject, Context, Iterator>::type
0514                 subject_attribute;
0515 
0516             typedef typename mpl::and_<
0517              traits::is_container<Attribute>
0518             , mpl::not_< traits::is_weak_substitute< subject_attribute,Attribute > >
0519             >::type predicate;
0520 
0521             if(parse_impl(first,last,context,skipper.skipper,attr, predicate()))
0522                 return iter.register_successful_parse(skipper.flag,skipper.counter);
0523             return false;
0524         }
0525 
0526         template <typename Iterator, typename Context
0527           , typename Skipper, typename Attribute>
0528         bool parse(Iterator& first, Iterator const& last
0529           , Context& context, Skipper const& skipper
0530           , Attribute& attr) const
0531           {
0532               typedef typename traits::attribute_of<
0533                 Subject, Context, Iterator>::type
0534                 subject_attribute;
0535 
0536             typedef typename mpl::and_<
0537             traits::is_container<Attribute>
0538             , mpl::not_< traits::is_weak_substitute< subject_attribute,Attribute > >
0539             >::type predicate;
0540 
0541 
0542             // Parse the keyword
0543             bool flag = iter.flag_init();
0544             int counter = 0;
0545             Iterator save = first;
0546             spirit::qi::skip_over(first, last, skipper);
0547             if(keyword.parse(first,last,context,skipper,unused)){
0548               if( !distinct::value || skipper.parse(first,last,unused,unused,unused)){
0549                 // Followed by the subject parser
0550                 spirit::qi::skip_over(first, last, skipper);
0551                 if(parse_impl(first,last,context,skipper,attr, predicate()))
0552                 {
0553                   return iter.register_successful_parse(flag,counter);
0554                 }
0555               }
0556             }
0557             first = save;
0558             return flag;
0559           }
0560 
0561 
0562         template <typename Context>
0563         info what(Context& context) const
0564         {
0565            if(distinct::value)
0566             return info("dkwd", subject.what(context));
0567            else
0568             return info("kwd", subject.what(context));
0569         }
0570 
0571         Subject subject;
0572         LoopIter iter;
0573 
0574         KeywordType keyword;
0575 
0576     private:
0577         template <typename Iterator, typename Context, typename Skipper>
0578         static spirit::qi::detail::fail_function<Iterator, Context, Skipper>
0579         fail_function(
0580             Iterator& first, Iterator const& last
0581           , Context& context, Skipper const& skipper)
0582         {
0583             return spirit::qi::detail::fail_function<Iterator, Context, Skipper>
0584                 (first, last, context, skipper);
0585         }
0586 
0587     };
0588 
0589 }}}}
0590 
0591 ///////////////////////////////////////////////////////////////////////////////
0592 namespace boost { namespace spirit { namespace qi
0593 {
0594 
0595     ///////////////////////////////////////////////////////////////////////////
0596     // Parser generators: make_xxx function (objects)
0597     ///////////////////////////////////////////////////////////////////////////
0598 
0599     template <typename T1, typename T2,  typename Subject, typename Modifiers, typename Distinct, typename MakeDirectiveHelper>
0600     struct make_directive_internal_2_args
0601     {
0602 
0603         // is the keyword a string keyword ?
0604         typedef typename traits::is_string<T1> is_string_kwd_type;
0605         // make the keyword type
0606         typedef typename mpl::if_< is_string_kwd_type ,
0607                                    T1 ,
0608                                    typename result_of::compile<qi::domain, T1>::type
0609                                  >::type keyword_type;
0610 
0611         typedef typename add_const<keyword_type>::type const_keyword;
0612         // select the pass iterator type
0613         typedef typename MakeDirectiveHelper::iterator_type iterator_type;
0614         // determine if a no case modifier applies to the context
0615         typedef has_modifier<Modifiers, tag::char_code_base<tag::no_case> > no_case;
0616         // Determine the full type of the kwd / complex_kwd directive
0617         typedef typename
0618              mpl::if_<
0619                 is_string_kwd_type,
0620                 repository::qi::kwd_parser<Subject, const_keyword, iterator_type, no_case, Distinct >,
0621                 repository::qi::complex_kwd_parser<Subject, const_keyword, iterator_type, Distinct >
0622                      >::type result_type;
0623 
0624         // Return a kwd parser object
0625         template <typename Terminal>
0626         result_type create_kwd_string(Terminal const &term, Subject const & subject, boost::mpl::true_ ) const
0627         {
0628             typename spirit::detail::get_encoding<Modifiers,
0629                 spirit::char_encoding::standard>::type encoding;
0630            return result_type(subject
0631                         ,MakeDirectiveHelper::make_iterator(term.args)
0632                         ,encoding
0633                         );
0634         }
0635         template <typename Terminal>
0636         result_type create_kwd_string(Terminal const &term, Subject const & subject, boost::mpl::false_ ) const
0637         {
0638            return result_type(subject
0639                         ,fusion::at_c<0>(term.args)
0640                         ,MakeDirectiveHelper::make_iterator(term.args)
0641                         );
0642         }
0643         template <typename Terminal>
0644         result_type create_kwd(Terminal const &term, Subject const & subject, Modifiers const& /*modifiers*/, boost::mpl::true_ ) const
0645         {
0646            return create_kwd_string(term,subject,no_case());
0647         }
0648         // Return a complex_kwd parser object
0649         template <typename Terminal>
0650         result_type create_kwd(Terminal const &term , Subject const & subject, Modifiers const& modifiers, boost::mpl::false_ ) const
0651         {
0652            return result_type(subject
0653                         ,compile<qi::domain>(fusion::at_c<0>(term.args),modifiers)
0654                         ,MakeDirectiveHelper::make_iterator(term.args)                        
0655                         );
0656         }
0657         // Select which object type to return
0658         template <typename Terminal>
0659         result_type operator()(
0660             Terminal const& term, Subject const& subject, Modifiers const& modifiers) const
0661         {
0662             return create_kwd(term, subject, modifiers, is_string_kwd_type());
0663         }
0664 
0665     };
0666 
0667      // Directive kwd(key)[p]
0668     template <typename T1,  typename Subject, typename Modifiers, typename Distinct>
0669     struct make_directive_internal
0670     {
0671         // is the keyword a string keyword ?
0672         typedef typename traits::is_string<T1> is_string_kwd_type;
0673         // make the keyword type
0674         typedef typename mpl::if_< is_string_kwd_type ,
0675                                    T1 ,
0676                                    typename result_of::compile<qi::domain, T1, Modifiers>::type
0677                                  >::type keyword_type;
0678 
0679         typedef typename add_const<keyword_type>::type const_keyword;
0680         // select the pass iterator type
0681         typedef repository::qi::kwd_pass_iterator<int> iterator_type;
0682         // determine if a no case modifier applies to the context
0683         typedef has_modifier<Modifiers, tag::char_code_base<tag::no_case> > no_case;
0684         // Determine the full type of the kwd / complex_kwd directive
0685         typedef typename
0686              mpl::if_<
0687                 is_string_kwd_type,
0688                 repository::qi::kwd_parser<Subject, const_keyword, iterator_type, no_case, Distinct >,
0689                 repository::qi::complex_kwd_parser<Subject, const_keyword, iterator_type, Distinct>
0690                      >::type result_type;
0691 
0692         // Return a kwd parser object
0693         template <typename Terminal>
0694         result_type create_kwd_string(Terminal const &term, Subject const & subject, boost::mpl::true_) const
0695         {
0696             typename spirit::detail::get_encoding<Modifiers,
0697                 spirit::char_encoding::standard>::type encoding;
0698 
0699             return result_type(subject
0700                         ,fusion::at_c<0>(term.args)
0701                         ,iterator_type()
0702                         ,encoding
0703                         );
0704 
0705         }
0706         template <typename Terminal>
0707         result_type create_kwd_string(Terminal const &term, Subject const & subject, boost::mpl::false_) const
0708         {
0709             return result_type(subject
0710                         ,fusion::at_c<0>(term.args)
0711                         ,iterator_type()
0712                         );
0713         }
0714         template <typename Terminal>
0715         result_type create_kwd(Terminal const &term, Subject const & subject, Modifiers const& /*modifiers*/, boost::mpl::true_ ) const
0716         {
0717            return create_kwd_string(term,subject,no_case());
0718         }
0719         // Return a complex_kwd parser object
0720         template <typename Terminal>
0721         result_type create_kwd(Terminal const &term , Subject const & subject, Modifiers const& modifiers, boost::mpl::false_ ) const
0722         {
0723            return result_type(subject
0724                         ,compile<qi::domain>(fusion::at_c<0>(term.args),modifiers)
0725                         ,iterator_type()
0726                         );
0727         }
0728         // Select which object type to return
0729         template <typename Terminal>
0730         result_type operator()(
0731             Terminal const& term, Subject const& subject, Modifiers const& modifiers ) const
0732         {
0733             return create_kwd(term, subject, modifiers, is_string_kwd_type());
0734         }
0735     };
0736 
0737     template <typename T1,  typename Subject, typename Modifiers>
0738     struct make_directive<
0739         terminal_ex<repository::tag::kwd, fusion::vector1<T1> >, Subject, Modifiers>
0740     {
0741         typedef make_directive_internal<T1, Subject, Modifiers, mpl::false_> make_directive_type;
0742         typedef typename make_directive_type::result_type result_type;
0743         template <typename Terminal>
0744         result_type operator()(
0745             Terminal const& term, Subject const& subject, Modifiers const& modifiers) const
0746         {
0747 
0748             return make_directive_type()(term, subject, modifiers);
0749         }
0750 
0751     };
0752  
0753    template <typename T1,  typename Subject, typename Modifiers>
0754     struct make_directive<
0755         terminal_ex<repository::tag::dkwd, fusion::vector1<T1> >, Subject, Modifiers>
0756     {
0757         typedef make_directive_internal<T1, Subject, Modifiers, mpl::true_> make_directive_type;
0758         typedef typename make_directive_type::result_type result_type;
0759         template <typename Terminal>
0760         result_type operator()(
0761             Terminal const& term, Subject const& subject, Modifiers const& modifiers) const
0762         {
0763 
0764             return make_directive_type()(term, subject, modifiers);
0765         }
0766 
0767     };
0768  
0769 
0770 
0771     // Directive ikwd(key)[p]
0772     template <typename T1,  typename Subject, typename Modifiers>
0773     struct make_directive<
0774         terminal_ex<repository::tag::ikwd, fusion::vector1<T1> >, Subject, Modifiers>
0775     {
0776         typedef typename add_const<T1>::type const_keyword;
0777         typedef repository::qi::kwd_pass_iterator<int> iterator_type;
0778 
0779         typedef repository::qi::kwd_parser<Subject, const_keyword, iterator_type, mpl::true_, mpl::false_ > result_type;
0780 
0781         template <typename Terminal>
0782         result_type operator()(
0783             Terminal const& term, Subject const& subject,  unused_type) const
0784         {
0785             typename spirit::detail::get_encoding<Modifiers,
0786                 spirit::char_encoding::standard>::type encoding;
0787 
0788             return result_type(subject
0789                         ,fusion::at_c<0>(term.args)
0790                         ,iterator_type()
0791                         ,encoding
0792                         );
0793         }
0794     };
0795 
0796     template <typename T1,  typename Subject, typename Modifiers>
0797     struct make_directive<
0798         terminal_ex<repository::tag::idkwd, fusion::vector1<T1> >, Subject, Modifiers>
0799     {
0800         typedef typename add_const<T1>::type const_keyword;
0801         typedef repository::qi::kwd_pass_iterator<int> iterator_type;
0802 
0803         typedef repository::qi::kwd_parser<Subject, const_keyword, iterator_type, mpl::true_, mpl::true_ > result_type;
0804 
0805         template <typename Terminal>
0806         result_type operator()(
0807             Terminal const& term, Subject const& subject, unused_type) const
0808         {
0809             typename spirit::detail::get_encoding<Modifiers,
0810                 spirit::char_encoding::standard>::type encoding;
0811 
0812             return result_type(subject
0813                         ,fusion::at_c<0>(term.args)
0814                         ,iterator_type()
0815                         ,encoding
0816                         );
0817         }
0818     };
0819 
0820     // Directive kwd(key,exact)[p]
0821         template <typename T>
0822     struct make_exact_helper
0823     { 
0824         typedef repository::qi::kwd_exact_iterator<T> iterator_type;
0825         template<typename Args>
0826         static iterator_type make_iterator(Args const& args)
0827         {
0828           return iterator_type(fusion::at_c<1>(args));
0829         }
0830     };
0831 
0832     template <typename T1, typename T2,  typename Subject, typename Modifiers>
0833     struct make_directive<
0834         terminal_ex<repository::tag::kwd, fusion::vector2<T1,T2> >, Subject, Modifiers>
0835     {
0836         typedef make_directive_internal_2_args< T1
0837                                               , T2
0838                                               , Subject
0839                                               , Modifiers
0840                                               , mpl::false_
0841                                               , make_exact_helper<T2>
0842                                               > make_directive_type;
0843         typedef typename make_directive_type::result_type result_type;
0844         template <typename Terminal>
0845         result_type operator()(
0846             Terminal const& term, Subject const& subject, Modifiers const& modifiers) const
0847         {
0848 
0849             return make_directive_type()(term,subject, modifiers);
0850         }
0851 
0852     };
0853   
0854     template <typename T1, typename T2,  typename Subject, typename Modifiers>
0855     struct make_directive<
0856         terminal_ex<repository::tag::dkwd, fusion::vector2<T1,T2> >, Subject, Modifiers>
0857     {
0858          typedef make_directive_internal_2_args< T1
0859                                               , T2
0860                                               , Subject
0861                                               , Modifiers
0862                                               , mpl::true_
0863                                               , make_exact_helper<T2>
0864                                               > make_directive_type;
0865         
0866         typedef typename make_directive_type::result_type result_type;
0867         template <typename Terminal>
0868         result_type operator()(
0869             Terminal const& term, Subject const& subject, Modifiers const& modifiers) const
0870         {
0871 
0872             return make_directive_type()(term, subject, modifiers);
0873         }
0874 
0875     };
0876   
0877 
0878     // Directive ikwd(key,exact)[p]
0879     template <typename T1, typename T2,  typename Subject, typename Modifiers>
0880     struct make_directive<
0881         terminal_ex<repository::tag::ikwd, fusion::vector2<T1,T2> >, Subject, Modifiers>
0882     {
0883         typedef typename add_const<T1>::type const_keyword;
0884         typedef repository::qi::kwd_exact_iterator<T2> iterator_type;
0885 
0886         typedef repository::qi::kwd_parser<Subject, const_keyword, iterator_type, mpl::true_, mpl::false_ > result_type;
0887 
0888         template <typename Terminal>
0889         result_type operator()(
0890             Terminal const& term, Subject const& subject, Modifiers const& /*modifiers*/) const
0891         {
0892             typename spirit::detail::get_encoding<Modifiers,
0893                 spirit::char_encoding::standard>::type encoding;
0894             return result_type(subject
0895                         , fusion::at_c<0>(term.args)
0896                         , fusion::at_c<1>(term.args)
0897                         , encoding
0898                         );
0899         }
0900     };
0901 
0902     template <typename T1, typename T2,  typename Subject, typename Modifiers>
0903     struct make_directive<
0904         terminal_ex<repository::tag::idkwd, fusion::vector2<T1,T2> >, Subject, Modifiers>
0905     {
0906         typedef typename add_const<T1>::type const_keyword;
0907         typedef repository::qi::kwd_exact_iterator<T2> iterator_type;
0908 
0909         typedef repository::qi::kwd_parser<Subject, const_keyword, iterator_type, mpl::true_, mpl::true_ > result_type;
0910 
0911         template <typename Terminal>
0912         result_type operator()(
0913             Terminal const& term, Subject const& subject, Modifiers const& /*modifiers*/) const
0914         {
0915             typename spirit::detail::get_encoding<Modifiers,
0916                 spirit::char_encoding::standard>::type encoding;
0917             return result_type(subject
0918                         , fusion::at_c<0>(term.args)
0919                         , fusion::at_c<1>(term.args)
0920                         , encoding
0921                         );
0922         }
0923     };
0924 
0925 
0926     // Directive kwd(min, max)[p]
0927 
0928     template <typename T>
0929     struct make_finite_helper
0930     { 
0931         typedef repository::qi::kwd_finite_iterator<T> iterator_type;
0932         template<typename Args>
0933         static iterator_type make_iterator(Args const& args)
0934         {
0935           return iterator_type(fusion::at_c<1>(args),fusion::at_c<2>(args));
0936         }
0937 
0938     };
0939 
0940     template <typename T1, typename T2,  typename Subject, typename Modifiers>
0941     struct make_directive<
0942         terminal_ex<repository::tag::kwd, fusion::vector3<T1,T2,T2> >, Subject, Modifiers>
0943     {
0944         typedef make_directive_internal_2_args< T1
0945                                               , T2
0946                                               , Subject
0947                                               , Modifiers
0948                                               , mpl::false_
0949                                               , make_finite_helper<T2>
0950                                               > make_directive_type;
0951         
0952         
0953         typedef typename make_directive_type::result_type result_type;
0954         template <typename Terminal>
0955         result_type operator()(
0956             Terminal const& term, Subject const& subject, Modifiers const& modifiers) const
0957         {
0958 
0959             return make_directive_type()(term,subject, modifiers);
0960         }
0961 
0962     };
0963   
0964     template <typename T1, typename T2,  typename Subject, typename Modifiers>
0965     struct make_directive<
0966         terminal_ex<repository::tag::dkwd, fusion::vector3<T1,T2,T2> >, Subject, Modifiers>
0967     {
0968        
0969         typedef make_directive_internal_2_args< T1
0970                                               , T2
0971                                               , Subject
0972                                               , Modifiers
0973                                               , mpl::true_
0974                                               , make_finite_helper<T2>
0975                                               > make_directive_type;
0976  
0977         typedef typename make_directive_type::result_type result_type;
0978         template <typename Terminal>
0979         result_type operator()(
0980             Terminal const& term, Subject const& subject, Modifiers const& modifiers) const
0981         {
0982 
0983             return make_directive_type()(term,subject, modifiers);
0984         }
0985 
0986     };
0987 
0988     // Directive ikwd(min, max)[p]
0989     template <typename T1, typename T2, typename Subject, typename Modifiers>
0990     struct make_directive<
0991         terminal_ex<repository::tag::ikwd, fusion::vector3< T1, T2, T2> >, Subject, Modifiers>
0992     {
0993         typedef typename add_const<T1>::type const_keyword;
0994         typedef repository::qi::kwd_finite_iterator<T2> iterator_type;
0995 
0996         typedef repository::qi::kwd_parser<Subject, const_keyword, iterator_type, mpl::true_, mpl::false_ > result_type;
0997 
0998         template <typename Terminal>
0999         result_type operator()(
1000             Terminal const& term, Subject const& subject, unused_type) const
1001         {
1002 
1003             typename spirit::detail::get_encoding<Modifiers,
1004                 spirit::char_encoding::standard>::type encoding;
1005             return result_type(subject, fusion::at_c<0>(term.args),
1006                 iterator_type(
1007                     fusion::at_c<1>(term.args)
1008                   , fusion::at_c<2>(term.args)
1009                   , encoding
1010                 )
1011             );
1012         }
1013     };
1014 
1015     template <typename T1, typename T2, typename Subject, typename Modifiers>
1016     struct make_directive<
1017         terminal_ex<repository::tag::idkwd, fusion::vector3< T1, T2, T2> >, Subject, Modifiers>
1018     {
1019         typedef typename add_const<T1>::type const_keyword;
1020         typedef repository::qi::kwd_finite_iterator<T2> iterator_type;
1021 
1022         typedef repository::qi::kwd_parser<Subject, const_keyword, iterator_type, mpl::true_, mpl::true_ > result_type;
1023 
1024         template <typename Terminal>
1025         result_type operator()(
1026             Terminal const& term, Subject const& subject, unused_type) const
1027         {
1028 
1029             typename spirit::detail::get_encoding<Modifiers,
1030                 spirit::char_encoding::standard>::type encoding;
1031             return result_type(subject, fusion::at_c<0>(term.args),
1032                 iterator_type(
1033                     fusion::at_c<1>(term.args)
1034                   , fusion::at_c<2>(term.args)
1035                   , encoding
1036                 )
1037             );
1038         }
1039     };
1040 
1041 
1042     // Directive kwd(min, inf)[p]
1043 
1044     template <typename T>
1045     struct make_infinite_helper
1046     { 
1047         typedef repository::qi::kwd_infinite_iterator<T> iterator_type;
1048         template<typename Args>
1049         static iterator_type make_iterator(Args const& args)
1050         {
1051           return iterator_type(fusion::at_c<1>(args));
1052         }
1053 
1054     };
1055 
1056 
1057     template <typename T1, typename T2,  typename Subject, typename Modifiers>
1058     struct make_directive<
1059         terminal_ex<repository::tag::kwd, fusion::vector3<T1,T2,inf_type> >, Subject, Modifiers>
1060     {
1061          typedef make_directive_internal_2_args< T1
1062                                               , T2
1063                                               , Subject
1064                                               , Modifiers
1065                                               , mpl::false_
1066                                               , make_infinite_helper<T2>
1067                                               > make_directive_type;
1068         
1069         typedef typename make_directive_type::result_type result_type;
1070         template <typename Terminal>
1071         result_type operator()(
1072             Terminal const& term, Subject const& subject, unused_type) const
1073         {
1074 
1075             return make_directive_type()(term,subject, unused_type());
1076         }
1077 
1078     };
1079   
1080     template <typename T1, typename T2,  typename Subject, typename Modifiers>
1081     struct make_directive<
1082         terminal_ex<repository::tag::dkwd, fusion::vector3<T1,T2,inf_type> >, Subject, Modifiers>
1083     {
1084       typedef make_directive_internal_2_args< T1
1085                                               , T2
1086                                               , Subject
1087                                               , Modifiers
1088                                               , mpl::false_
1089                                               , make_infinite_helper<T2>
1090                                               > make_directive_type;
1091     
1092         typedef typename make_directive_type::result_type result_type;
1093         template <typename Terminal>
1094         result_type operator()(
1095             Terminal const& term, Subject const& subject, unused_type) const
1096         {
1097 
1098             return make_directive_type()(term,subject, unused_type());
1099         }
1100 
1101     };
1102 
1103 
1104     // Directive ikwd(min, inf)[p]
1105     template <typename T1, typename T2, typename Subject, typename Modifiers>
1106     struct make_directive<
1107         terminal_ex<repository::tag::ikwd
1108         , fusion::vector3<T1, T2, inf_type> >, Subject, Modifiers>
1109     {
1110         typedef typename add_const<T1>::type const_keyword;
1111         typedef repository::qi::kwd_infinite_iterator<T2> iterator_type;
1112 
1113         typedef repository::qi::kwd_parser<Subject, const_keyword, iterator_type, mpl::true_, mpl::false_ > result_type;
1114 
1115         template <typename Terminal>
1116         result_type operator()(
1117             Terminal const& term, Subject const& subject, unused_type) const
1118         {
1119             typename spirit::detail::get_encoding<Modifiers,
1120                 spirit::char_encoding::standard>::type encoding;
1121 
1122             return result_type(subject
1123                 , fusion::at_c<0>(term.args)
1124                 , fusion::at_c<1>(term.args)
1125                 , encoding
1126                 );
1127         }
1128     };
1129 
1130   template <typename T1, typename T2, typename Subject, typename Modifiers>
1131     struct make_directive<
1132         terminal_ex<repository::tag::idkwd
1133         , fusion::vector3<T1, T2, inf_type> >, Subject, Modifiers>
1134     {
1135         typedef typename add_const<T1>::type const_keyword;
1136         typedef repository::qi::kwd_infinite_iterator<T2> iterator_type;
1137 
1138         typedef repository::qi::kwd_parser<Subject, const_keyword, iterator_type, mpl::true_, mpl::true_ > result_type;
1139 
1140         template <typename Terminal>
1141         result_type operator()(
1142             Terminal const& term, Subject const& subject, unused_type) const
1143         {
1144             typename spirit::detail::get_encoding<Modifiers,
1145                 spirit::char_encoding::standard>::type encoding;
1146 
1147             return result_type(subject
1148                 , fusion::at_c<0>(term.args)
1149                 , fusion::at_c<1>(term.args)
1150                 , encoding
1151                 );
1152         }
1153     };
1154 
1155 
1156 }}}
1157 
1158 namespace boost { namespace spirit { namespace traits
1159 {
1160     template <typename Subject, typename KeywordType
1161             , typename LoopIter, typename NoCase , typename Distinct>
1162     struct has_semantic_action<
1163             repository::qi::kwd_parser< Subject, KeywordType, LoopIter, NoCase, Distinct > >
1164       : unary_has_semantic_action<Subject> {};
1165 
1166     template <typename Subject, typename KeywordType
1167             , typename LoopIter, typename Distinct >
1168     struct has_semantic_action<
1169             repository::qi::complex_kwd_parser< Subject, KeywordType, LoopIter, Distinct > >
1170       : unary_has_semantic_action<Subject> {};
1171 
1172     template <typename Subject, typename KeywordType
1173               , typename LoopIter, typename NoCase, typename Attribute, typename Context
1174                 , typename Iterator, typename Distinct>
1175     struct handles_container<repository::qi::kwd_parser<Subject, KeywordType, LoopIter, NoCase, Distinct>, Attribute
1176         , Context, Iterator>
1177       : unary_handles_container<Subject, Attribute, Context, Iterator> {};
1178 
1179     template <typename Subject, typename KeywordType
1180                 , typename LoopIter
1181                 , typename Attribute, typename Context
1182                 , typename Iterator, typename Distinct>
1183     struct handles_container<repository::qi::complex_kwd_parser<Subject, KeywordType, LoopIter, Distinct>, Attribute
1184         , Context, Iterator>
1185       : unary_handles_container<Subject, Attribute, Context, Iterator> {};
1186 
1187 }}}
1188 
1189 #if defined(_MSC_VER)
1190 # pragma warning(pop)
1191 #endif
1192 
1193 #endif
1194