Back to home page

EIC code displayed by LXR

 
 

    


Warning, file /include/boost/spirit/repository/home/qi/operator/detail/keywords.hpp was not indexed or was modified since last indexation (in which case cross-reference links may be missing, inaccurate or erroneous).

0001 /*=============================================================================
0002   Copyright (c) 2011-2012 Thomas Bernard
0003 
0004   Distributed under the Boost Software License, Version 1.0. (See accompanying
0005   file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
0006   =============================================================================*/
0007 #ifndef BOOST_SPIRIT_REPOSITORY_QI_OPERATOR_DETAIL_KEYWORDS_HPP
0008 #define BOOST_SPIRIT_REPOSITORY_QI_OPERATOR_DETAIL_KEYWORDS_HPP
0009 
0010 #if defined(_MSC_VER)
0011 #pragma once
0012 #endif
0013 #include <boost/spirit/repository/home/qi/directive/kwd.hpp> // for skipper_keyword_marker
0014 #include <boost/spirit/home/qi/string/lit.hpp>
0015 #include <boost/fusion/include/at.hpp>
0016 #include <boost/fusion/include/any.hpp>
0017 
0018 namespace boost { namespace spirit { namespace repository { namespace qi { namespace detail {
0019     // Variant visitor class which handles dispatching the parsing to the selected parser
0020     // This also handles passing the correct attributes and flags/counters to the subject parsers
0021     template<typename T>
0022     struct is_distinct : T::distinct { };
0023     
0024     template<typename T, typename Action>
0025     struct is_distinct< spirit::qi::action<T,Action> > : T::distinct { };
0026 
0027     template<typename T>
0028     struct is_distinct< spirit::qi::hold_directive<T> > : T::distinct { };
0029 
0030 
0031 
0032     template < typename Elements, typename Iterator ,typename Context ,typename Skipper
0033         ,typename Flags ,typename Counters ,typename Attribute, typename NoCasePass>
0034         struct parse_dispatcher
0035         : public boost::static_visitor<bool>
0036         {
0037 
0038             typedef Iterator iterator_type;
0039             typedef Context context_type;
0040             typedef Skipper skipper_type;
0041             typedef Elements elements_type;
0042 
0043             typedef typename add_reference<Attribute>::type attr_reference;
0044             public:
0045             parse_dispatcher(const Elements &elements,Iterator& first, Iterator const& last
0046                     , Context& context, Skipper const& skipper
0047                     , Flags &flags, Counters &counters, attr_reference attr) :
0048                 elements(elements), first(first), last(last)
0049                 , context(context), skipper(skipper)
0050                 , flags(flags),counters(counters), attr(attr)
0051             {}
0052 
0053             template<typename T> bool operator()(T& idx) const
0054             {
0055                 return call(idx,typename traits::not_is_unused<Attribute>::type());
0056             }
0057 
0058             template <typename Subject,typename Index>
0059                 bool call_subject_unused(
0060                         Subject const &subject, Iterator &first, Iterator const &last
0061                         , Context& context, Skipper const& skipper
0062                         , Index& /*idx*/ ) const
0063                 {
0064                     Iterator save = first;
0065                     skipper_keyword_marker<Skipper,NoCasePass>
0066                         marked_skipper(skipper,flags[Index::value],counters[Index::value]);
0067 
0068                     if(subject.parse(first,last,context,marked_skipper,unused))
0069                     {
0070                         return true;
0071                     }
0072                     first = save;
0073                     return false;
0074                 }
0075 
0076 
0077             template <typename Subject,typename Index>
0078                 bool call_subject(
0079                         Subject const &subject, Iterator &first, Iterator const &last
0080                         , Context& context, Skipper const& skipper
0081                         , Index& /*idx*/ ) const
0082                 {
0083 
0084                     Iterator save = first;
0085                     skipper_keyword_marker<Skipper,NoCasePass> 
0086                         marked_skipper(skipper,flags[Index::value],counters[Index::value]);
0087                     typename fusion::result_of::at_c<typename remove_reference<Attribute>::type, Index::value>::type
0088                         attr_ = fusion::at_c<Index::value>(attr);
0089                     if(subject.parse(first,last,context,marked_skipper,attr_))
0090                     {
0091                         return true;
0092                     }
0093                     first = save;
0094                     return false;
0095                 }
0096 
0097 #if defined(_MSC_VER)
0098 # pragma warning(push)
0099 # pragma warning(disable: 4127) // conditional expression is constant
0100 #endif
0101             // Handle unused attributes
0102             template <typename T> bool call(T &idx, mpl::false_) const{
0103  
0104                 typedef typename mpl::at<Elements,T>::type ElementType;
0105                 if(
0106                        (!is_distinct<ElementType>::value)
0107                     || skipper.parse(first,last,unused,unused,unused)
0108                   ){
0109                       spirit::qi::skip_over(first, last, skipper);
0110                       return call_subject_unused(fusion::at_c<T::value>(elements), first, last, context, skipper, idx );
0111                     }
0112                 return false;
0113             }
0114             // Handle normal attributes
0115             template <typename T> bool call(T &idx, mpl::true_) const{
0116                  typedef typename mpl::at<Elements,T>::type ElementType;
0117                  if(
0118                        (!is_distinct<ElementType>::value)
0119                     || skipper.parse(first,last,unused,unused,unused)
0120                   ){
0121                       return call_subject(fusion::at_c<T::value>(elements), first, last, context, skipper, idx);
0122                   }
0123                 return false;
0124             }
0125 #if defined(_MSC_VER)
0126 # pragma warning(pop)
0127 #endif
0128 
0129             const Elements &elements;
0130             Iterator &first;
0131             const Iterator &last;
0132             Context & context;
0133             const Skipper &skipper;
0134             Flags &flags;
0135             Counters &counters;
0136             attr_reference attr;
0137         };
0138     // string keyword loop handler
0139     template <typename Elements, typename StringKeywords, typename IndexList, typename FlagsType, typename Modifiers>
0140         struct string_keywords
0141         {
0142             // Create a variant type to be able to store parser indexes in the embedded symbols parser
0143             typedef typename
0144                 spirit::detail::as_variant<
0145                 IndexList >::type        parser_index_type;
0146 
0147             ///////////////////////////////////////////////////////////////////////////
0148             // build_char_type_sequence
0149             //
0150             // Build a fusion sequence from the kwd directive specified character type.
0151             ///////////////////////////////////////////////////////////////////////////
0152             template <typename Sequence >
0153                 struct build_char_type_sequence
0154                 {
0155                     struct element_char_type
0156                     {
0157                         template <typename T>
0158                             struct result;
0159 
0160                         template <typename F, typename Element>
0161                             struct result<F(Element)>
0162                             {
0163                                 typedef typename Element::char_type type;
0164 
0165                             };
0166                         template <typename F, typename Element,typename Action>
0167                             struct result<F(spirit::qi::action<Element,Action>) >
0168                             {
0169                                 typedef typename Element::char_type type;
0170                             };
0171                         template <typename F, typename Element>
0172                             struct result<F(spirit::qi::hold_directive<Element>)>
0173                             {
0174                                 typedef typename Element::char_type type;
0175                             };
0176 
0177                         // never called, but needed for decltype-based result_of (C++0x)
0178 #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
0179                         template <typename Element>
0180                             typename result<element_char_type(Element)>::type
0181                             operator()(Element&&) const;
0182 #endif
0183                     };
0184 
0185                     // Compute the list of character types of the child kwd directives
0186                     typedef typename
0187                         fusion::result_of::transform<Sequence, element_char_type>::type
0188                         type;
0189                 };
0190 
0191 
0192             ///////////////////////////////////////////////////////////////////////////
0193             // get_keyword_char_type
0194             //
0195             // Collapses the character type coming from the subject kwd parsers and
0196             // and checks that they are all identical (necessary in order to be able
0197             // to build a tst parser to parse the keywords.
0198             ///////////////////////////////////////////////////////////////////////////
0199             template <typename Sequence>
0200                 struct get_keyword_char_type
0201                 {
0202                     // Make sure each of the types occur only once in the type list
0203                     typedef typename
0204                         mpl::fold<
0205                         Sequence, mpl::vector<>,
0206                         mpl::if_<
0207                             mpl::contains<mpl::_1, mpl::_2>,
0208                         mpl::_1, mpl::push_back<mpl::_1, mpl::_2>
0209                             >
0210                             >::type
0211                             no_duplicate_char_types;
0212 
0213                     // If the compiler traps here this means you mixed
0214                     // character type for the keywords specified in the
0215                     // kwd directive sequence.
0216                     BOOST_MPL_ASSERT_RELATION( mpl::size<no_duplicate_char_types>::value, ==, 1 );
0217 
0218                     typedef typename mpl::front<no_duplicate_char_types>::type type;
0219 
0220                 };
0221 
0222             // Get the character type for the tst parser
0223             typedef typename build_char_type_sequence< StringKeywords >::type char_types;
0224             typedef typename get_keyword_char_type<
0225                 typename mpl::if_<
0226                   mpl::equal_to<
0227                     typename mpl::size < char_types >::type
0228                     , mpl::int_<0>
0229                     >
0230                   , mpl::vector< boost::spirit::standard::char_type >
0231                   , char_types >::type
0232                 >::type  char_type;
0233 
0234             // Our symbols container
0235             typedef spirit::qi::tst< char_type, parser_index_type> keywords_type;
0236 
0237             // Filter functor used for case insensitive parsing
0238             template <typename CharEncoding>
0239                 struct no_case_filter
0240                 {
0241                     char_type operator()(char_type ch) const
0242                     {
0243                         return static_cast<char_type>(CharEncoding::tolower(ch));
0244                     }
0245                 };
0246 
0247             ///////////////////////////////////////////////////////////////////////////
0248             // build_case_type_sequence
0249             //
0250             // Build a fusion sequence from the kwd/ikwd directives
0251             // in order to determine if case sensitive and case insensitive
0252             // keywords have been mixed.
0253             ///////////////////////////////////////////////////////////////////////////
0254             template <typename Sequence >
0255                 struct build_case_type_sequence
0256                 {
0257                     struct element_case_type
0258                     {
0259                         template <typename T>
0260                             struct result;
0261 
0262                         template <typename F, typename Element>
0263                             struct result<F(Element)>
0264                             {
0265                                 typedef typename Element::no_case_keyword type;
0266 
0267                             };
0268                         template <typename F, typename Element,typename Action>
0269                             struct result<F(spirit::qi::action<Element,Action>) >
0270                             {
0271                                 typedef typename Element::no_case_keyword type;
0272                             };
0273                         template <typename F, typename Element>
0274                             struct result<F(spirit::qi::hold_directive<Element>)>
0275                             {
0276                                 typedef typename Element::no_case_keyword type;
0277                             };
0278 
0279                         // never called, but needed for decltype-based result_of (C++0x)
0280 #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
0281                         template <typename Element>
0282                             typename result<element_case_type(Element)>::type
0283                             operator()(Element&&) const;
0284 #endif
0285                     };
0286 
0287                     // Compute the list of character types of the child kwd directives
0288                     typedef typename
0289                         fusion::result_of::transform<Sequence, element_case_type>::type
0290                         type;
0291                 };
0292 
0293             ///////////////////////////////////////////////////////////////////////////
0294             // get_nb_case_types
0295             //
0296             // Counts the number of entries in the case type sequence matching the
0297             // CaseType parameter (mpl::true_  -> case insensitve
0298             //                   , mpl::false_ -> case sensitive
0299             ///////////////////////////////////////////////////////////////////////////
0300             template <typename Sequence,typename CaseType>
0301                 struct get_nb_case_types
0302                 {
0303                     // Make sure each of the types occur only once in the type list
0304                     typedef typename
0305                         mpl::count_if<
0306                         Sequence, mpl::equal_to<mpl::_,CaseType>
0307                         >::type type;
0308 
0309 
0310                 };
0311             // Build the case type sequence
0312             typedef typename build_case_type_sequence< StringKeywords >::type case_type_sequence;
0313             // Count the number of case sensitive entries and case insensitve entries
0314             typedef typename get_nb_case_types<case_type_sequence,mpl::true_>::type ikwd_count;
0315             typedef typename get_nb_case_types<case_type_sequence,mpl::false_>::type kwd_count;
0316             // Get the size of the original sequence
0317             typedef typename mpl::size<IndexList>::type nb_elements;
0318             // Determine if all the kwd directive are case sensitive/insensitive
0319             typedef typename mpl::and_<
0320                 typename mpl::greater< nb_elements, mpl::int_<0> >::type
0321                 , typename mpl::equal_to< ikwd_count, nb_elements>::type
0322                 >::type all_ikwd;
0323 
0324             typedef typename mpl::and_<
0325                 typename mpl::greater< nb_elements, mpl::int_<0> >::type
0326                 , typename mpl::equal_to< kwd_count, nb_elements>::type
0327                 >::type all_kwd;
0328 
0329             typedef typename mpl::or_< all_kwd, all_ikwd >::type all_directives_of_same_type;
0330 
0331             // Do we have a no case modifier
0332             typedef has_modifier<Modifiers, spirit::tag::char_code_base<spirit::tag::no_case> > no_case_modifier;
0333 
0334             // Should the no_case filter always be used ?
0335             typedef typename mpl::or_<
0336                 no_case_modifier,
0337                 mpl::and_<
0338                     all_directives_of_same_type
0339                     ,all_ikwd
0340                     >
0341                     >::type
0342                     no_case;
0343 
0344             typedef no_case_filter<
0345                 typename spirit::detail::get_encoding_with_case<
0346                 Modifiers
0347                 , char_encoding::standard
0348                 , no_case::value>::type>
0349                 nc_filter;
0350             // Determine the standard case filter type
0351             typedef typename mpl::if_<
0352                 no_case
0353                 , nc_filter
0354                 , spirit::qi::tst_pass_through >::type
0355                 first_pass_filter_type;
0356 
0357             typedef typename mpl::or_<
0358                     all_directives_of_same_type
0359                   , no_case_modifier
0360                 >::type requires_one_pass;
0361 
0362 
0363             // Functor which adds all the keywords/subject parser indexes
0364             // collected from the subject kwd directives to the keyword tst parser
0365             struct keyword_entry_adder
0366             {
0367                 typedef int result_type;
0368 
0369                 keyword_entry_adder(shared_ptr<keywords_type> lookup,FlagsType &flags, Elements &elements) :
0370                     lookup(lookup)
0371                     ,flags(flags)
0372                     ,elements(elements)
0373                 {}
0374 
0375                 template <typename T>
0376                     int operator()(const T &index) const
0377                     {
0378                         return call(fusion::at_c<T::value>(elements),index);
0379                     }
0380 
0381                 template <typename T, typename Position, typename Action>
0382                     int call(const spirit::qi::action<T,Action> &parser, const Position position ) const
0383                     {
0384 
0385                         // Make the keyword/parse index entry in the tst parser
0386                         lookup->add(
0387                                 traits::get_begin<char_type>(get_string(parser.subject.keyword)),
0388                                 traits::get_end<char_type>(get_string(parser.subject.keyword)),
0389                                 position
0390                                 );
0391                         // Get the initial state of the flags array and store it in the flags initializer
0392                         flags[Position::value]=parser.subject.iter.flag_init();
0393                         return 0;
0394                     }
0395 
0396                 template <typename T, typename Position>
0397                     int call( const T & parser, const Position position) const
0398                     {
0399                         // Make the keyword/parse index entry in the tst parser
0400                         lookup->add(
0401                                 traits::get_begin<char_type>(get_string(parser.keyword)),
0402                                 traits::get_end<char_type>(get_string(parser.keyword)),
0403                                 position
0404                                 );
0405                         // Get the initial state of the flags array and store it in the flags initializer
0406                         flags[Position::value]=parser.iter.flag_init();
0407                         return 0;
0408                     }
0409 
0410                 template <typename T, typename Position>
0411                     int call( const spirit::qi::hold_directive<T> & parser, const Position position) const
0412                     {
0413                         // Make the keyword/parse index entry in the tst parser
0414                         lookup->add(
0415                                 traits::get_begin<char_type>(get_string(parser.subject.keyword)),
0416                                 traits::get_end<char_type>(get_string(parser.subject.keyword)),
0417                                 position
0418                                 );
0419                         // Get the initial state of the flags array and store it in the flags initializer
0420                         flags[Position::value]=parser.subject.iter.flag_init();
0421                         return 0;
0422                     }
0423 
0424 
0425                 template <typename String, bool no_attribute>
0426                 const String get_string(const boost::spirit::qi::literal_string<String,no_attribute> &parser) const
0427                 {
0428                         return parser.str;
0429                 }
0430 
0431         template <typename String, bool no_attribute>
0432                 const typename boost::spirit::qi::no_case_literal_string<String,no_attribute>::string_type &
0433                         get_string(const boost::spirit::qi::no_case_literal_string<String,no_attribute> &parser) const
0434                 {
0435                         return parser.str_lo;
0436                 }
0437    
0438 
0439 
0440                 shared_ptr<keywords_type> lookup;
0441                 FlagsType & flags;
0442                 Elements &elements;
0443             };
0444 
0445             string_keywords(Elements &elements,FlagsType &flags_init) : lookup(new keywords_type())
0446             {
0447                 // Loop through all the subject parsers to build the keyword parser symbol parser
0448                 IndexList indexes;
0449                 keyword_entry_adder f1(lookup,flags_init,elements);
0450                 fusion::for_each(indexes,f1);
0451 
0452             }
0453             template <typename Iterator,typename ParseVisitor, typename Skipper>
0454                 bool parse(
0455                         Iterator &first,
0456                         const Iterator &last,
0457                         const ParseVisitor &parse_visitor,
0458                         const Skipper &/*skipper*/) const
0459                 {
0460                     if(parser_index_type* val_ptr =
0461                             lookup->find(first,last,first_pass_filter_type()))
0462                     {                        
0463                         if(!apply_visitor(parse_visitor,*val_ptr)){
0464                             return false;
0465                         }
0466             return true;
0467                     }
0468                     return false;
0469                 }
0470 
0471             template <typename Iterator,typename ParseVisitor, typename NoCaseParseVisitor,typename Skipper>
0472                 bool parse(
0473                         Iterator &first,
0474                         const Iterator &last,
0475                         const ParseVisitor &parse_visitor,
0476                         const NoCaseParseVisitor &no_case_parse_visitor,
0477                         const Skipper &/*skipper*/) const
0478                 {
0479                     Iterator saved_first = first;
0480                     if(parser_index_type* val_ptr =
0481                             lookup->find(first,last,first_pass_filter_type()))
0482                     {
0483                         if(!apply_visitor(parse_visitor,*val_ptr)){
0484                             return false;
0485                         }
0486             return true;
0487                     }
0488                     // Second pass case insensitive
0489                     if(parser_index_type* val_ptr
0490                             = lookup->find(saved_first,last,nc_filter()))
0491                     {
0492                         first = saved_first;
0493                         if(!apply_visitor(no_case_parse_visitor,*val_ptr)){
0494                             return false;
0495                         }
0496             return true;
0497                     }
0498                     return false;
0499                 }
0500             shared_ptr<keywords_type> lookup;
0501 
0502 
0503         };
0504 
0505     struct empty_keywords_list
0506     {
0507         typedef mpl::true_ requires_one_pass;
0508 
0509         empty_keywords_list()
0510         {}
0511         template<typename Elements>
0512         empty_keywords_list(const Elements &)
0513         {}
0514 
0515        template<typename Elements, typename FlagsInit>
0516         empty_keywords_list(const Elements &, const FlagsInit &)
0517         {}
0518 
0519         template <typename Iterator,typename ParseVisitor, typename NoCaseParseVisitor,typename Skipper>
0520         bool parse(
0521                         Iterator &/*first*/,
0522                         const Iterator &/*last*/,
0523                         const ParseVisitor &/*parse_visitor*/,
0524                         const NoCaseParseVisitor &/*no_case_parse_visitor*/,
0525                         const Skipper &/*skipper*/) const
0526                 {
0527                         return false;
0528                 }
0529 
0530         template <typename Iterator,typename ParseVisitor, typename Skipper>
0531                 bool parse(
0532                         Iterator &/*first*/,
0533                         const Iterator &/*last*/,
0534                         const ParseVisitor &/*parse_visitor*/,
0535                         const Skipper &/*skipper*/) const
0536                 {
0537                     return false;
0538                 }
0539 
0540         template <typename ParseFunction>
0541         bool parse( ParseFunction &/*function*/ ) const
0542                 {
0543                    return false;
0544                 }
0545     };
0546 
0547     template<typename ComplexKeywords>
0548     struct complex_keywords
0549     {
0550       // Functor which performs the flag initialization for the complex keyword parsers
0551       template <typename FlagsType, typename Elements>
0552             struct flag_init_value_setter
0553             {
0554                 typedef int result_type;
0555 
0556                 flag_init_value_setter(Elements &elements,FlagsType &flags)
0557           :flags(flags)
0558                     ,elements(elements)
0559                 {}
0560 
0561                 template <typename T>
0562                     int operator()(const T &index) const
0563                     {
0564                         return call(fusion::at_c<T::value>(elements),index);
0565                     }
0566 
0567                 template <typename T, typename Position, typename Action>
0568                     int call(const spirit::qi::action<T,Action> &parser, const Position /*position*/ ) const
0569                     {
0570                         // Get the initial state of the flags array and store it in the flags initializer
0571                         flags[Position::value]=parser.subject.iter.flag_init();
0572                         return 0;
0573                     }
0574 
0575                 template <typename T, typename Position>
0576                     int call( const T & parser, const Position /*position*/) const
0577                     {
0578                         // Get the initial state of the flags array and store it in the flags initializer
0579                         flags[Position::value]=parser.iter.flag_init();
0580                         return 0;
0581                     }
0582 
0583                 template <typename T, typename Position>
0584                     int call( const spirit::qi::hold_directive<T> & parser, const Position /*position*/) const
0585                     {
0586                         // Get the initial state of the flags array and store it in the flags initializer
0587                         flags[Position::value]=parser.subject.iter.flag_init();
0588                         return 0;
0589                     }
0590 
0591                 FlagsType & flags;
0592                 Elements &elements;
0593             };
0594 
0595     template <typename Elements, typename Flags>
0596         complex_keywords(Elements &elements, Flags &flags)
0597         {
0598       flag_init_value_setter<Flags,Elements> flag_initializer(elements,flags);
0599       fusion::for_each(complex_keywords_inst,flag_initializer);
0600     }
0601 
0602         template <typename ParseFunction>
0603         bool parse( ParseFunction &function ) const
0604                 {
0605                    return fusion::any(complex_keywords_inst,function);
0606                 }
0607 
0608         ComplexKeywords complex_keywords_inst;
0609     };
0610     // This helper class enables jumping over intermediate directives
0611     // down the kwd parser iteration count checking policy
0612     struct register_successful_parse
0613     {
0614         template <typename Subject>
0615             static bool call(Subject const &subject,bool &flag, int &counter)
0616             {
0617                 return subject.iter.register_successful_parse(flag,counter);
0618             }
0619         template <typename Subject, typename Action>
0620             static bool call(spirit::qi::action<Subject, Action> const &subject,bool &flag, int &counter)
0621             {
0622                 return subject.subject.iter.register_successful_parse(flag,counter);
0623             }
0624         template <typename Subject>
0625             static bool call(spirit::qi::hold_directive<Subject> const &subject,bool &flag, int &counter)
0626             {
0627                 return subject.subject.iter.register_successful_parse(flag,counter);
0628             }
0629     };
0630 
0631     // This helper class enables jumping over intermediate directives
0632     // down the kwd parser
0633     struct extract_keyword
0634     {
0635         template <typename Subject>
0636             static Subject const& call(Subject const &subject)
0637             {
0638                 return subject;
0639             }
0640         template <typename Subject, typename Action>
0641             static Subject const& call(spirit::qi::action<Subject, Action> const &subject)
0642             {
0643                 return subject.subject;
0644             }
0645         template <typename Subject>
0646             static Subject const& call(spirit::qi::hold_directive<Subject> const &subject)
0647             {
0648                 return subject.subject;
0649             }
0650     };
0651 
0652 #ifdef _MSC_VER
0653 #  pragma warning(push)
0654 #  pragma warning(disable: 4512) // assignment operator could not be generated.
0655 #endif
0656     template <typename ParseDispatcher>
0657         struct complex_kwd_function
0658         {
0659             typedef typename ParseDispatcher::iterator_type Iterator;
0660             typedef typename ParseDispatcher::context_type Context;
0661             typedef typename ParseDispatcher::skipper_type Skipper;
0662             complex_kwd_function(
0663                     Iterator& first, Iterator const& last
0664                     , Context& context, Skipper const& skipper, ParseDispatcher &dispatcher)
0665                 : first(first)
0666                   , last(last)
0667                   , context(context)
0668                   , skipper(skipper)
0669                   , dispatcher(dispatcher)
0670             {
0671             }
0672 
0673             template <typename Component>
0674                 bool operator()(Component const& component)
0675                 {
0676                     Iterator save = first;
0677                     if(
0678                         extract_keyword::call(
0679                                 fusion::at_c<
0680                                         Component::value
0681                                         ,typename ParseDispatcher::elements_type
0682                                 >(dispatcher.elements)
0683                                 )
0684                                 .keyword.parse(
0685                                         first
0686                                         ,last
0687                                         ,context
0688                                         ,skipper
0689                                         ,unused)
0690                     )
0691                     {
0692                         if(!dispatcher(component)){
0693                             first = save;
0694                             return false;
0695                         }
0696                         return true;
0697                     }
0698                     return false;
0699                 }
0700 
0701             Iterator& first;
0702             Iterator const& last;
0703             Context& context;
0704             Skipper const& skipper;
0705             ParseDispatcher const& dispatcher;
0706         };
0707 #ifdef _MSC_VER
0708 #  pragma warning(pop)
0709 #endif
0710 
0711 
0712 }}}}}
0713 
0714 #endif