| /*============================================================================= |
| 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 <boost/spirit/home/classic/meta/parser_traits.hpp> |
| #include <boost/spirit/home/classic/core/composite/epsilon.hpp> |
| |
| /////////////////////////////////////////////////////////////////////////////// |
| namespace boost { namespace spirit { |
| |
| BOOST_SPIRIT_CLASSIC_NAMESPACE_BEGIN |
| |
| 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 <typename T> struct embed_t_accessor |
| { |
| typedef typename T::embed_t type; |
| }; |
| |
| #if defined(BOOST_MSVC) && BOOST_MSVC <= 1300 |
| template <> struct embed_t_accessor<int> |
| { |
| typedef int type; |
| }; |
| #endif |
| |
| template <typename ConditionT> |
| struct condition_parser_selector |
| { |
| typedef |
| typename mpl::if_< |
| is_parser<ConditionT>, |
| ConditionT, |
| condition_parser<ConditionT> |
| >::type |
| type; |
| |
| typedef typename embed_t_accessor<type>::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 <typename ConditionT> |
| struct condition_evaluator |
| { |
| typedef condition_parser_selector<ConditionT> selector_t; |
| typedef typename selector_t::type selected_t; |
| typedef typename selector_t::embed_t cond_embed_t; |
| |
| typedef typename boost::call_traits<cond_embed_t>::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 <typename ScannerT> |
| std::ptrdiff_t |
| evaluate(ScannerT const &scan) const |
| { |
| typedef typename ScannerT::iterator_t iterator_t; |
| typedef typename parser_result<selected_t, ScannerT>::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 |
| |
| BOOST_SPIRIT_CLASSIC_NAMESPACE_END |
| |
| }} // namespace boost::spirit |
| |
| #endif |