]>
Commit | Line | Data |
---|---|---|
7c673cae FG |
1 | /*============================================================================= |
2 | Copyright (c) 2001-2011 Hartmut Kaiser | |
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(BOOST_SPIRIT_MATCH_MANIP_MAY_05_2007_1203PM) | |
8 | #define BOOST_SPIRIT_MATCH_MANIP_MAY_05_2007_1203PM | |
9 | ||
10 | #if defined(_MSC_VER) | |
11 | #pragma once | |
12 | #endif | |
13 | ||
14 | #include <boost/spirit/home/qi/parse.hpp> | |
15 | #include <boost/spirit/home/support/iterators/istream_iterator.hpp> | |
16 | #include <boost/spirit/home/support/unused.hpp> | |
17 | #include <boost/mpl/bool.hpp> | |
18 | ||
19 | #include <iterator> | |
20 | #include <string> | |
21 | ||
22 | /////////////////////////////////////////////////////////////////////////////// | |
23 | namespace boost { namespace spirit { namespace qi { namespace detail | |
24 | { | |
25 | /////////////////////////////////////////////////////////////////////////// | |
26 | template <typename Expr | |
27 | , typename CopyExpr = mpl::false_, typename CopyAttr = mpl::false_ | |
28 | , typename Skipper = unused_type, typename Attribute = unused_type const> | |
29 | struct match_manip | |
30 | { | |
31 | // This assertion makes sure we don't hit the only code path which is | |
32 | // not implemented (because it isn't needed), where both, the | |
33 | // expression and the attribute need to be held as a copy. | |
34 | BOOST_SPIRIT_ASSERT_MSG(!CopyExpr::value || !CopyAttr::value | |
35 | , error_invalid_should_not_happen, ()); | |
36 | ||
37 | match_manip(Expr const& xpr, Skipper const& s, Attribute& a) | |
38 | : expr(xpr), skipper(s), attr(a), post_skip(skip_flag::postskip) {} | |
39 | ||
40 | match_manip(Expr const& xpr, Skipper const& s | |
41 | , BOOST_SCOPED_ENUM(skip_flag) ps, Attribute& a) | |
42 | : expr(xpr), skipper(s), attr(a), post_skip(ps) {} | |
43 | ||
44 | Expr const& expr; | |
45 | Skipper const& skipper; | |
46 | Attribute& attr; | |
47 | BOOST_SCOPED_ENUM(skip_flag) const post_skip; | |
48 | ||
7c673cae | 49 | // silence MSVC warning C4512: assignment operator could not be generated |
92f5a8d4 | 50 | BOOST_DELETED_FUNCTION(match_manip& operator= (match_manip const&)) |
7c673cae FG |
51 | }; |
52 | ||
53 | template <typename Expr, typename Skipper, typename Attribute> | |
54 | struct match_manip<Expr, mpl::false_, mpl::true_, Skipper, Attribute> | |
55 | { | |
56 | match_manip(Expr const& xpr, Skipper const& s, Attribute& a) | |
57 | : expr(xpr), skipper(s), attr(a), post_skip(skip_flag::postskip) {} | |
58 | ||
59 | match_manip(Expr const& xpr, Skipper const& s | |
60 | , BOOST_SCOPED_ENUM(skip_flag) ps, Attribute& a) | |
61 | : expr(xpr), skipper(s), attr(a), post_skip(ps) {} | |
62 | ||
63 | Expr const& expr; | |
64 | Skipper const& skipper; | |
65 | Attribute attr; | |
66 | BOOST_SCOPED_ENUM(skip_flag) const post_skip; | |
67 | ||
7c673cae | 68 | // silence MSVC warning C4512: assignment operator could not be generated |
92f5a8d4 | 69 | BOOST_DELETED_FUNCTION(match_manip& operator= (match_manip const&)) |
7c673cae FG |
70 | }; |
71 | ||
72 | template <typename Expr, typename Skipper, typename Attribute> | |
73 | struct match_manip<Expr, mpl::true_, mpl::false_, Skipper, Attribute> | |
74 | { | |
75 | match_manip(Expr const& xpr, Skipper const& s, Attribute& a) | |
76 | : expr(xpr), skipper(s), attr(a), post_skip(skip_flag::postskip) {} | |
77 | ||
78 | match_manip(Expr const& xpr, Skipper const& s | |
79 | , BOOST_SCOPED_ENUM(skip_flag) ps, Attribute& a) | |
80 | : expr(xpr), skipper(s), attr(a), post_skip(ps) {} | |
81 | ||
82 | Expr expr; | |
83 | Skipper const& skipper; | |
84 | Attribute& attr; | |
85 | BOOST_SCOPED_ENUM(skip_flag) const post_skip; | |
86 | ||
7c673cae | 87 | // silence MSVC warning C4512: assignment operator could not be generated |
92f5a8d4 | 88 | BOOST_DELETED_FUNCTION(match_manip& operator= (match_manip const&)) |
7c673cae FG |
89 | }; |
90 | ||
91 | /////////////////////////////////////////////////////////////////////////// | |
92 | template <typename Expr, typename Enable = void> | |
93 | struct match | |
94 | { | |
95 | // Report invalid expression error as early as possible. | |
96 | // If you got an error_invalid_expression error message here, | |
97 | // then the expression (expr) is not a valid spirit qi expression. | |
98 | // Did you intend to use the auto_ facilities while forgetting to | |
99 | // #include <boost/spirit/include/qi_match_auto.hpp>? | |
100 | BOOST_SPIRIT_ASSERT_MATCH(qi::domain, Expr); | |
101 | }; | |
102 | ||
103 | template <typename Expr> | |
104 | struct match<Expr | |
105 | , typename enable_if<traits::matches<qi::domain, Expr> >::type> | |
106 | { | |
107 | typedef match_manip<Expr> type; | |
108 | ||
109 | static type call(Expr const& expr) | |
110 | { | |
111 | return type(expr, unused, unused); | |
112 | } | |
113 | }; | |
114 | ||
115 | /////////////////////////////////////////////////////////////////////////// | |
116 | template <typename Expr, typename Skipper, typename Enable = void> | |
117 | struct phrase_match | |
118 | { | |
119 | // Report invalid expression error as early as possible. | |
120 | // If you got an error_invalid_expression error message here, | |
121 | // then the expression (expr) is not a valid spirit qi expression. | |
122 | // Did you intend to use the auto_ facilities while forgetting to | |
123 | // #include <boost/spirit/include/qi_match_auto.hpp>? | |
124 | BOOST_SPIRIT_ASSERT_MATCH(qi::domain, Expr); | |
125 | }; | |
126 | ||
127 | template <typename Expr, typename Skipper> | |
128 | struct phrase_match<Expr, Skipper | |
129 | , typename enable_if<traits::matches<qi::domain, Expr> >::type> | |
130 | { | |
131 | typedef match_manip<Expr, mpl::false_, mpl::false_, Skipper> type; | |
132 | ||
133 | static type call( | |
134 | Expr const& expr | |
135 | , Skipper const& skipper | |
136 | , BOOST_SCOPED_ENUM(skip_flag) post_skip) | |
137 | { | |
138 | // Report invalid expression error as early as possible. | |
139 | // If you got an error_invalid_expression error message here, | |
140 | // then the delimiter is not a valid spirit karma expression. | |
141 | BOOST_SPIRIT_ASSERT_MATCH(qi::domain, Skipper); | |
142 | return type(expr, skipper, post_skip, unused); | |
143 | } | |
144 | }; | |
145 | ||
146 | /////////////////////////////////////////////////////////////////////////// | |
147 | template<typename Char, typename Traits, typename Expr | |
148 | , typename CopyExpr, typename CopyAttr> | |
149 | inline std::basic_istream<Char, Traits> & | |
150 | operator>>(std::basic_istream<Char, Traits> &is, | |
151 | match_manip<Expr, CopyExpr, CopyAttr> const& fm) | |
152 | { | |
153 | typedef spirit::basic_istream_iterator<Char, Traits> input_iterator; | |
154 | ||
155 | input_iterator f(is); | |
156 | input_iterator l; | |
157 | if (!qi::parse(f, l, fm.expr)) | |
158 | { | |
159 | is.setstate(std::ios_base::failbit); | |
160 | } | |
161 | return is; | |
162 | } | |
163 | ||
164 | /////////////////////////////////////////////////////////////////////////// | |
165 | template<typename Char, typename Traits, typename Expr | |
166 | , typename CopyExpr, typename CopyAttr | |
167 | , typename Attribute> | |
168 | inline std::basic_istream<Char, Traits> & | |
169 | operator>>(std::basic_istream<Char, Traits> &is, | |
170 | match_manip<Expr, CopyExpr, CopyAttr, unused_type, Attribute> const& fm) | |
171 | { | |
172 | typedef spirit::basic_istream_iterator<Char, Traits> input_iterator; | |
173 | ||
174 | input_iterator f(is); | |
175 | input_iterator l; | |
176 | if (!qi::parse(f, l, fm.expr, fm.attr)) | |
177 | { | |
178 | is.setstate(std::ios_base::failbit); | |
179 | } | |
180 | return is; | |
181 | } | |
182 | ||
183 | /////////////////////////////////////////////////////////////////////////// | |
184 | template<typename Char, typename Traits, typename Expr | |
185 | , typename CopyExpr, typename CopyAttr | |
186 | , typename Skipper> | |
187 | inline std::basic_istream<Char, Traits> & | |
188 | operator>>(std::basic_istream<Char, Traits> &is, | |
189 | match_manip<Expr, CopyExpr, CopyAttr, Skipper> const& fm) | |
190 | { | |
191 | typedef spirit::basic_istream_iterator<Char, Traits> input_iterator; | |
192 | ||
193 | input_iterator f(is); | |
194 | input_iterator l; | |
195 | if (!qi::phrase_parse( | |
196 | f, l, fm.expr, fm.skipper, fm.post_skip)) | |
197 | { | |
198 | is.setstate(std::ios_base::failbit); | |
199 | } | |
200 | return is; | |
201 | } | |
202 | ||
203 | /////////////////////////////////////////////////////////////////////////// | |
204 | template<typename Char, typename Traits, typename Expr | |
205 | , typename CopyExpr, typename CopyAttr | |
206 | , typename Attribute, typename Skipper | |
207 | > | |
208 | inline std::basic_istream<Char, Traits> & | |
209 | operator>>( | |
210 | std::basic_istream<Char, Traits> &is, | |
211 | match_manip<Expr, CopyExpr, CopyAttr, Attribute, Skipper> const& fm) | |
212 | { | |
213 | typedef spirit::basic_istream_iterator<Char, Traits> input_iterator; | |
214 | ||
215 | input_iterator f(is); | |
216 | input_iterator l; | |
217 | if (!qi::phrase_parse( | |
218 | f, l, fm.expr, fm.skipper, fm.post_skip, fm.attr)) | |
219 | { | |
220 | is.setstate(std::ios_base::failbit); | |
221 | } | |
222 | return is; | |
223 | } | |
224 | ||
225 | }}}} | |
226 | ||
227 | #endif |