1 /*============================================================================= 2 Copyright (c) 2001-2011 Joel de Guzman 3 4 Distributed under the Boost Software License, Version 1.0. (See accompanying 5 file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) 6 =============================================================================*/ 7 #ifndef BOOST_SPIRIT_QI_DETAIL_EXPECT_FUNCTION_HPP 8 #define BOOST_SPIRIT_QI_DETAIL_EXPECT_FUNCTION_HPP 9 10 #if defined(_MSC_VER) 11 #pragma once 12 #endif 13 14 #include <boost/spirit/home/support/unused.hpp> 15 #include <boost/spirit/home/support/multi_pass_wrapper.hpp> 16 #include <boost/throw_exception.hpp> 17 18 namespace boost { namespace spirit { namespace qi { namespace detail 19 { 20 template < 21 typename Iterator, typename Context 22 , typename Skipper, typename Exception> 23 struct expect_function 24 { 25 typedef Iterator iterator_type; 26 typedef Context context_type; 27 expect_functionboost::spirit::qi::detail::expect_function28 expect_function( 29 Iterator& first_, Iterator const& last_ 30 , Context& context_, Skipper const& skipper_) 31 : first(first_) 32 , last(last_) 33 , context(context_) 34 , skipper(skipper_) 35 , is_first(true) 36 { 37 } 38 39 template <typename Component, typename Attribute> operator ()boost::spirit::qi::detail::expect_function40 bool operator()(Component const& component, Attribute& attr) const 41 { 42 // if this is not the first component in the expect chain we 43 // need to flush any multi_pass iterator we might be acting on 44 if (!is_first) 45 spirit::traits::clear_queue(first); 46 47 // if we are testing the first component in the sequence, 48 // return true if the parser fails, if this is not the first 49 // component, throw exception if the parser fails 50 if (!component.parse(first, last, context, skipper, attr)) 51 { 52 if (is_first) 53 { 54 is_first = false; 55 return true; // true means the match failed 56 } 57 boost::throw_exception(Exception(first, last, component.what(context))); 58 #if defined(BOOST_NO_EXCEPTIONS) 59 return true; // for systems not supporting exceptions 60 #endif 61 } 62 is_first = false; 63 return false; 64 } 65 66 template <typename Component> operator ()boost::spirit::qi::detail::expect_function67 bool operator()(Component const& component) const 68 { 69 // if this is not the first component in the expect chain we 70 // need to flush any multi_pass iterator we might be acting on 71 if (!is_first) 72 spirit::traits::clear_queue(first); 73 74 // if we are testing the first component in the sequence, 75 // return true if the parser fails, if this not the first 76 // component, throw exception if the parser fails 77 if (!component.parse(first, last, context, skipper, unused)) 78 { 79 if (is_first) 80 { 81 is_first = false; 82 return true; 83 } 84 boost::throw_exception(Exception(first, last, component.what(context))); 85 #if defined(BOOST_NO_EXCEPTIONS) 86 return false; // for systems not supporting exceptions 87 #endif 88 } 89 is_first = false; 90 return false; 91 } 92 93 Iterator& first; 94 Iterator const& last; 95 Context& context; 96 Skipper const& skipper; 97 mutable bool is_first; 98 99 // silence MSVC warning C4512: assignment operator could not be generated 100 BOOST_DELETED_FUNCTION(expect_function& operator= (expect_function const&)) 101 }; 102 }}}} 103 104 #endif 105