/*============================================================================= Copyright (c) 2001-2011 Joel de Guzman Copyright (c) 2011 Thomas Bernard Distributed under the Boost Software License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) =============================================================================*/ #if !defined(SPIRIT_KEYWORDS_DETAIL_MARCH_13_2007_1145PM) #define SPIRIT_KEYWORDS_DETAIL_MARCH_13_2007_1145PM #if defined(_MSC_VER) #pragma once #endif namespace boost { namespace spirit { namespace repository { namespace qi { namespace detail { // This helper class enables jumping over intermediate directives // down the kwd parser iteration count checking policy struct register_successful_parse { template static bool call(Subject const &subject,bool &flag, int &counter) { return subject.iter.register_successful_parse(flag,counter); } template static bool call(spirit::qi::action const &subject,bool &flag, int &counter) { return subject.subject.iter.register_successful_parse(flag,counter); } template static bool call(spirit::qi::hold_directive const &subject,bool &flag, int &counter) { return subject.subject.iter.register_successful_parse(flag,counter); } }; // Variant visitor class which handles dispatching the parsing to the selected parser // This also handles passing the correct attributes and flags/counters to the subject parsers template < typename Elements, typename Iterator ,typename Context ,typename Skipper ,typename Flags ,typename Counters ,typename Attribute, typename NoCasePass> class parse_dispatcher : public boost::static_visitor { public: parse_dispatcher(const Elements &elements,Iterator& first, Iterator const& last , Context& context, Skipper const& skipper , Flags &flags, Counters &counters, Attribute& attr) : elements(elements), first(first), last(last) , context(context), skipper(skipper) , flags(flags),counters(counters), attr(attr) {} template bool operator()(T& idx) const { return call(idx,typename traits::not_is_unused::type()); } template bool call_subject_unused( Subject const &subject, Iterator &first, Iterator const &last , Context& context, Skipper const& skipper , Index& idx ) const { Iterator save = first; skipper_keyword_marker marked_skipper(skipper,flags[Index::value],counters[Index::value]); if(subject.parse(first,last,context,marked_skipper,unused)) { return true; } save = save; return false; } template bool call_subject( Subject const &subject, Iterator &first, Iterator const &last , Context& context, Skipper const& skipper , Index& idx ) const { Iterator save = first; skipper_keyword_marker marked_skipper(skipper,flags[Index::value],counters[Index::value]); if(subject.parse(first,last,context,marked_skipper,fusion::at_c(attr))) { return true; } save = save; return false; } // Handle unused attributes template bool call(T &idx, mpl::false_) const{ return call_subject_unused(fusion::at_c(elements), first, last, context, skipper, idx ); } // Handle normal attributes template bool call(T &idx, mpl::true_) const{ return call_subject(fusion::at_c(elements), first, last, context, skipper, idx); } const Elements &elements; Iterator &first; const Iterator &last; Context & context; const Skipper &skipper; Flags &flags; Counters &counters; Attribute &attr; }; }}}}} #endif