1/*============================================================================= 2 Copyright (c) 2002-2003 Martin Wille 3 http://spirit.sourceforge.net/ 4 5 Use, modification and distribution is subject to the Boost Software 6 License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at 7 http://www.boost.org/LICENSE_1_0.txt) 8=============================================================================*/ 9#ifndef BOOST_SPIRIT_CONDITIONS_IPP 10#define BOOST_SPIRIT_CONDITIONS_IPP 11 12/////////////////////////////////////////////////////////////////////////////// 13#include <boost/spirit/home/classic/meta/parser_traits.hpp> 14#include <boost/spirit/home/classic/core/composite/epsilon.hpp> 15 16/////////////////////////////////////////////////////////////////////////////// 17namespace boost { namespace spirit { 18 19BOOST_SPIRIT_CLASSIC_NAMESPACE_BEGIN 20 21 namespace impl { 22 23/////////////////////////////////////////////////////////////////////////////// 24// 25// condition evaluation 26// 27/////////////////////////////////////////////////////////////////////////////// 28 ////////////////////////////////// 29 // condition_parser_selector, decides which parser to use for a condition 30 // If the template argument is a parser then that parser is used. 31 // If the template argument is a functor then a condition parser using 32 // the functor is chosen 33 34 template <typename T> struct embed_t_accessor 35 { 36 typedef typename T::embed_t type; 37 }; 38 39 template <typename ConditionT> 40 struct condition_parser_selector 41 { 42 typedef 43 typename mpl::if_< 44 is_parser<ConditionT>, 45 ConditionT, 46 condition_parser<ConditionT> 47 >::type 48 type; 49 50 typedef typename embed_t_accessor<type>::type embed_t; 51 }; 52 53 ////////////////////////////////// 54 // condition_evaluator, uses a parser to check wether a condition is met 55 // takes a parser or a functor that can be evaluated in boolean context 56 // as template parameter. 57 58 // JDG 4-15-03 refactored 59 template <typename ConditionT> 60 struct condition_evaluator 61 { 62 typedef condition_parser_selector<ConditionT> selector_t; 63 typedef typename selector_t::type selected_t; 64 typedef typename selector_t::embed_t cond_embed_t; 65 66 typedef typename boost::call_traits<cond_embed_t>::param_type 67 param_t; 68 69 condition_evaluator(param_t s) : cond(s) {} 70 71 ///////////////////////////// 72 // evaluate, checks wether condition is met 73 // returns length of a match or a negative number for no-match 74 template <typename ScannerT> 75 std::ptrdiff_t 76 evaluate(ScannerT const &scan) const 77 { 78 typedef typename ScannerT::iterator_t iterator_t; 79 typedef typename parser_result<selected_t, ScannerT>::type cres_t; 80 iterator_t save(scan.first); 81 cres_t result = cond.parse(scan); 82 if (!result) // reset the position if evaluation 83 scan.first = save; // fails. 84 return result.length(); 85 } 86 87 cond_embed_t cond; 88 }; 89 90/////////////////////////////////////////////////////////////////////////////// 91 } // namespace impl 92 93BOOST_SPIRIT_CLASSIC_NAMESPACE_END 94 95}} // namespace boost::spirit 96 97#endif 98