/*============================================================================= Copyright (c) 2002-2003 Martin Wille http://spirit.sourceforge.net/ Use, modification and distribution is subject to 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) =============================================================================*/ #ifndef BOOST_SPIRIT_CONDITIONS_IPP #define BOOST_SPIRIT_CONDITIONS_IPP /////////////////////////////////////////////////////////////////////////////// #include #include /////////////////////////////////////////////////////////////////////////////// namespace boost { namespace spirit { namespace impl { /////////////////////////////////////////////////////////////////////////////// // // condition evaluation // /////////////////////////////////////////////////////////////////////////////// ////////////////////////////////// // condition_parser_selector, decides which parser to use for a condition // If the template argument is a parser then that parser is used. // If the template argument is a functor then a condition parser using // the functor is chosen template struct embed_t_accessor { typedef typename T::embed_t type; }; #if defined(BOOST_MSVC) && BOOST_MSVC <= 1300 template <> struct embed_t_accessor { typedef int type; }; #endif template struct condition_parser_selector { typedef typename mpl::if_< is_parser, ConditionT, condition_parser >::type type; typedef typename embed_t_accessor::type embed_t; }; ////////////////////////////////// // condition_evaluator, uses a parser to check wether a condition is met // takes a parser or a functor that can be evaluated in boolean context // as template parameter. // JDG 4-15-03 refactored template struct condition_evaluator { typedef condition_parser_selector selector_t; typedef typename selector_t::type selected_t; typedef typename selector_t::embed_t cond_embed_t; typedef typename boost::call_traits::param_type param_t; condition_evaluator(param_t s) : cond(s) {} ///////////////////////////// // evaluate, checks wether condition is met // returns length of a match or a negative number for no-match template std::ptrdiff_t evaluate(ScannerT const &scan) const { typedef typename ScannerT::iterator_t iterator_t; typedef typename parser_result::type cres_t; iterator_t save(scan.first); cres_t result = cond.parse(scan); if (!result) // reset the position if evaluation scan.first = save; // fails. return result.length(); } cond_embed_t cond; }; /////////////////////////////////////////////////////////////////////////////// } // namespace impl }} // namespace boost::spirit #endif