Imported Upstream version 1.57.0
[platform/upstream/boost.git] / boost / spirit / home / qi / detail / expect_function.hpp
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 #if !defined(SPIRIT_EXPECT_FUNCTION_APR_29_2007_0558PM)
8 #define SPIRIT_EXPECT_FUNCTION_APR_29_2007_0558PM
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
28         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>
40         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>
67         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     private:
100         // silence MSVC warning C4512: assignment operator could not be generated
101         expect_function& operator= (expect_function const&);
102     };
103 }}}}
104
105 #endif