12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697 |
- /*=============================================================================
- 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;
- };
- 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
|