]> git.proxmox.com Git - ceph.git/blob - ceph/src/boost/libs/spirit/include/boost/spirit/home/qi/auxiliary/lazy.hpp
add subtree-ish sources for 12.0.3
[ceph.git] / ceph / src / boost / libs / spirit / include / boost / spirit / home / qi / auxiliary / lazy.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(BOOST_SPIRIT_LAZY_MARCH_27_2007_1002AM)
8 #define BOOST_SPIRIT_LAZY_MARCH_27_2007_1002AM
9
10 #if defined(_MSC_VER)
11 #pragma once
12 #endif
13
14 #include <boost/spirit/home/qi/domain.hpp>
15 #include <boost/spirit/home/qi/skip_over.hpp>
16 #include <boost/spirit/home/qi/meta_compiler.hpp>
17 #include <boost/spirit/home/qi/detail/attributes.hpp>
18 #include <boost/spirit/home/support/unused.hpp>
19 #include <boost/spirit/home/support/info.hpp>
20 #include <boost/spirit/home/support/lazy.hpp>
21 #include <boost/spirit/include/phoenix_core.hpp>
22 #include <boost/fusion/include/at.hpp>
23 #include <boost/utility/result_of.hpp>
24 #include <boost/type_traits/remove_reference.hpp>
25 #include <boost/mpl/not.hpp>
26
27 namespace boost { namespace spirit
28 {
29 ///////////////////////////////////////////////////////////////////////////
30 // Enablers
31 ///////////////////////////////////////////////////////////////////////////
32 template <typename Eval>
33 struct use_terminal<qi::domain, phoenix::actor<Eval> > // enables phoenix actors
34 : mpl::true_ {};
35
36 // forward declaration
37 template <typename Terminal, typename Actor, int Arity>
38 struct lazy_terminal;
39 }}
40
41 namespace boost { namespace spirit { namespace qi
42 {
43 using spirit::lazy;
44 typedef modify<qi::domain> qi_modify;
45
46 namespace detail
47 {
48 template <typename Parser, typename Iterator, typename Context
49 , typename Skipper, typename Attribute>
50 bool lazy_parse_impl(Parser const& p
51 , Iterator& first, Iterator const& last
52 , Context& context, Skipper const& skipper
53 , Attribute& attr, mpl::false_)
54 {
55 return p.parse(first, last, context, skipper, attr);
56 }
57
58 template <typename Parser, typename Iterator, typename Context
59 , typename Skipper, typename Attribute>
60 bool lazy_parse_impl(Parser const& p
61 , Iterator& first, Iterator const& last
62 , Context& context, Skipper const& skipper
63 , Attribute& /*attr*/, mpl::true_)
64 {
65 // If DeducedAuto is false (semantic actions is present), the
66 // component's attribute is unused.
67 return p.parse(first, last, context, skipper, unused);
68 }
69
70 template <typename Parser, typename Iterator, typename Context
71 , typename Skipper, typename Attribute>
72 bool lazy_parse_impl_main(Parser const& p
73 , Iterator& first, Iterator const& last
74 , Context& context, Skipper const& skipper
75 , Attribute& attr)
76 {
77 // If DeducedAuto is true (no semantic action), we pass the parser's
78 // attribute on to the component.
79 typedef typename traits::has_semantic_action<Parser>::type auto_rule;
80 return lazy_parse_impl(p, first, last, context, skipper, attr, auto_rule());
81 }
82 }
83
84 template <typename Function, typename Modifiers>
85 struct lazy_parser : parser<lazy_parser<Function, Modifiers> >
86 {
87 template <typename Context, typename Iterator>
88 struct attribute
89 {
90 typedef typename
91 boost::result_of<qi_modify(tag::lazy_eval, Modifiers)>::type
92 modifier;
93
94 typedef typename
95 remove_reference<
96 typename boost::result_of<Function(unused_type, Context)>::type
97 >::type
98 expr_type;
99
100 // If you got an error_invalid_expression error message here,
101 // then the expression (expr_type) is not a valid spirit qi
102 // expression.
103 BOOST_SPIRIT_ASSERT_MATCH(qi::domain, expr_type);
104
105 typedef typename
106 result_of::compile<qi::domain, expr_type, modifier>::type
107 parser_type;
108
109 typedef typename
110 traits::attribute_of<parser_type, Context, Iterator>::type
111 type;
112 };
113
114 lazy_parser(Function const& function_, Modifiers const& modifiers_)
115 : function(function_), modifiers(modifiers_) {}
116
117 template <typename Iterator, typename Context
118 , typename Skipper, typename Attribute>
119 bool parse(Iterator& first, Iterator const& last
120 , Context& context, Skipper const& skipper
121 , Attribute& attr) const
122 {
123 return detail::lazy_parse_impl_main(
124 compile<qi::domain>(function(unused, context)
125 , qi_modify()(tag::lazy_eval(), modifiers))
126 , first, last, context, skipper, attr);
127 }
128
129 template <typename Context>
130 info what(Context& context) const
131 {
132 return info("lazy"
133 , compile<qi::domain>(function(unused, context)
134 , qi_modify()(tag::lazy_eval(), modifiers))
135 .what(context)
136 );
137 }
138
139 Function function;
140 Modifiers modifiers;
141 };
142
143
144 template <typename Function, typename Subject, typename Modifiers>
145 struct lazy_directive
146 : unary_parser<lazy_directive<Function, Subject, Modifiers> >
147 {
148 typedef Subject subject_type;
149
150 template <typename Context, typename Iterator>
151 struct attribute
152 {
153 typedef typename
154 boost::result_of<qi_modify(tag::lazy_eval, Modifiers)>::type
155 modifier;
156
157 typedef typename
158 remove_reference<
159 typename boost::result_of<Function(unused_type, Context)>::type
160 >::type
161 directive_expr_type;
162
163 typedef typename
164 proto::result_of::make_expr<
165 proto::tag::subscript
166 , directive_expr_type
167 , Subject
168 >::type
169 expr_type;
170
171 // If you got an error_invalid_expression error message here,
172 // then the expression (expr_type) is not a valid spirit qi
173 // expression.
174 BOOST_SPIRIT_ASSERT_MATCH(qi::domain, expr_type);
175
176 typedef typename
177 result_of::compile<qi::domain, expr_type, modifier>::type
178 parser_type;
179
180 typedef typename
181 traits::attribute_of<parser_type, Context, Iterator>::type
182 type;
183 };
184
185 lazy_directive(
186 Function const& function_
187 , Subject const& subject_
188 , Modifiers const& modifiers_)
189 : function(function_), subject(subject_), modifiers(modifiers_) {}
190
191 template <typename Iterator, typename Context
192 , typename Skipper, typename Attribute>
193 bool parse(Iterator& first, Iterator const& last
194 , Context& context, Skipper const& skipper
195 , Attribute& attr) const
196 {
197 return detail::lazy_parse_impl_main(compile<qi::domain>(
198 proto::make_expr<proto::tag::subscript>(
199 function(unused, context)
200 , subject)
201 , qi_modify()(tag::lazy_eval(), modifiers))
202 , first, last, context, skipper, attr);
203 }
204
205 template <typename Context>
206 info what(Context& context) const
207 {
208 return info("lazy-directive"
209 , compile<qi::domain>(
210 proto::make_expr<proto::tag::subscript>(
211 function(unused, context)
212 , subject
213 ), qi_modify()(tag::lazy_eval(), modifiers))
214 .what(context)
215 );
216 }
217
218 Function function;
219 Subject subject;
220 Modifiers modifiers;
221 };
222
223 ///////////////////////////////////////////////////////////////////////////
224 // Parser generators: make_xxx function (objects)
225 ///////////////////////////////////////////////////////////////////////////
226 template <typename Eval, typename Modifiers>
227 struct make_primitive<phoenix::actor<Eval>, Modifiers>
228 {
229 typedef lazy_parser<phoenix::actor<Eval>, Modifiers> result_type;
230 result_type operator()(phoenix::actor<Eval> const& f
231 , Modifiers const& modifiers) const
232 {
233 return result_type(f, modifiers);
234 }
235 };
236
237 template <typename Terminal, typename Actor, int Arity, typename Modifiers>
238 struct make_primitive<lazy_terminal<Terminal, Actor, Arity>, Modifiers>
239 {
240 typedef lazy_parser<Actor, Modifiers> result_type;
241 result_type operator()(
242 lazy_terminal<Terminal, Actor, Arity> const& lt
243 , Modifiers const& modifiers) const
244 {
245 return result_type(lt.actor, modifiers);
246 }
247 };
248
249 template <typename Terminal, typename Actor, int Arity, typename Subject, typename Modifiers>
250 struct make_directive<lazy_terminal<Terminal, Actor, Arity>, Subject, Modifiers>
251 {
252 typedef lazy_directive<Actor, Subject, Modifiers> result_type;
253 result_type operator()(
254 lazy_terminal<Terminal, Actor, Arity> const& lt
255 , Subject const& subject, Modifiers const& modifiers) const
256 {
257 return result_type(lt.actor, subject, modifiers);
258 }
259 };
260 }}}
261
262 namespace boost { namespace spirit { namespace traits
263 {
264 ///////////////////////////////////////////////////////////////////////////
265 template <typename Actor, typename Modifiers, typename Attribute
266 , typename Context, typename Iterator>
267 struct handles_container<
268 qi::lazy_parser<Actor, Modifiers>, Attribute, Context, Iterator>
269 : handles_container<
270 typename qi::lazy_parser<Actor, Modifiers>::template
271 attribute<Context, Iterator>::parser_type
272 , Attribute, Context, Iterator>
273 {};
274
275 template <typename Subject, typename Actor, typename Modifiers
276 , typename Attribute, typename Context, typename Iterator>
277 struct handles_container<
278 qi::lazy_directive<Actor, Subject, Modifiers>, Attribute
279 , Context, Iterator>
280 : handles_container<
281 typename qi::lazy_directive<Actor, Subject, Modifiers>::template
282 attribute<Context, Iterator>::parser_type
283 , Attribute, Context, Iterator>
284 {};
285 }}}
286
287 #endif