]> git.proxmox.com Git - ceph.git/blame - ceph/src/boost/libs/spirit/include/boost/spirit/home/classic/meta/refactoring.hpp
bump version to 12.2.2-pve1
[ceph.git] / ceph / src / boost / libs / spirit / include / boost / spirit / home / classic / meta / refactoring.hpp
CommitLineData
7c673cae
FG
1/*=============================================================================
2 Copyright (c) 2002-2003 Hartmut Kaiser
3 http://spirit.sourceforge.net/
4
5 Distributed under the Boost Software License, Version 1.0. (See accompanying
6 file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
7=============================================================================*/
8#ifndef BOOST_SPIRIT_REFACTORING_HPP
9#define BOOST_SPIRIT_REFACTORING_HPP
10
11///////////////////////////////////////////////////////////////////////////////
12#include <boost/static_assert.hpp>
13#include <boost/spirit/home/classic/namespace.hpp>
14#include <boost/spirit/home/classic/meta/as_parser.hpp>
15#include <boost/spirit/home/classic/core/parser.hpp>
16#include <boost/spirit/home/classic/core/composite/composite.hpp>
17#include <boost/spirit/home/classic/meta/impl/refactoring.ipp>
18
19///////////////////////////////////////////////////////////////////////////////
20namespace boost { namespace spirit {
21
22BOOST_SPIRIT_CLASSIC_NAMESPACE_BEGIN
23
24#if BOOST_WORKAROUND(BOOST_MSVC, >= 1400)
25#pragma warning(push)
26#pragma warning(disable:4512) //assignment operator could not be generated
27#endif
28
29///////////////////////////////////////////////////////////////////////////////
30//
31// refactor_unary_parser class
32//
33// This helper template allows to attach an unary operation to a newly
34// constructed parser, which combines the subject of the left operand of
35// the original given parser (BinaryT) with the right operand of the
36// original binary parser through the original binary operation and
37// rewraps the resulting parser with the original unary operator.
38//
39// For instance given the parser:
40// *some_parser - another_parser
41//
42// will be refactored to:
43// *(some_parser - another_parser)
44//
45// If the parser to refactor is not a unary parser, no refactoring is done
46// at all.
47//
48// The original parser should be a binary_parser_category parser,
49// else the compilation will fail
50//
51///////////////////////////////////////////////////////////////////////////////
52
53template <typename NestedT = non_nested_refactoring>
54class refactor_unary_gen;
55
56template <typename BinaryT, typename NestedT = non_nested_refactoring>
57class refactor_unary_parser :
58 public parser<refactor_unary_parser<BinaryT, NestedT> > {
59
60public:
61 // the parser to refactor has to be at least a binary_parser_category
62 // parser
63 BOOST_STATIC_ASSERT((
64 boost::is_convertible<typename BinaryT::parser_category_t,
65 binary_parser_category>::value
66 ));
67
68 refactor_unary_parser(BinaryT const& binary_, NestedT const& nested_)
69 : binary(binary_), nested(nested_) {}
70
71 typedef refactor_unary_parser<BinaryT, NestedT> self_t;
72 typedef refactor_unary_gen<NestedT> parser_generator_t;
73 typedef typename BinaryT::left_t::parser_category_t parser_category_t;
74
75 template <typename ScannerT>
76 typename parser_result<self_t, ScannerT>::type
77 parse(ScannerT const& scan) const
78 {
79 return impl::refactor_unary_type<NestedT>::
80 parse(*this, scan, binary, nested);
81 }
82
83private:
84 typename as_parser<BinaryT>::type::embed_t binary;
85 typename NestedT::embed_t nested;
86};
87
88//////////////////////////////////
89template <typename NestedT>
90class refactor_unary_gen {
91
92public:
93 typedef refactor_unary_gen<NestedT> embed_t;
94
95 refactor_unary_gen(NestedT const& nested_ = non_nested_refactoring())
96 : nested(nested_) {}
97
98 template <typename ParserT>
99 refactor_unary_parser<ParserT, NestedT>
100 operator[](parser<ParserT> const& subject) const
101 {
102 return refactor_unary_parser<ParserT, NestedT>
103 (subject.derived(), nested);
104 }
105
106private:
107 typename NestedT::embed_t nested;
108};
109
110const refactor_unary_gen<> refactor_unary_d = refactor_unary_gen<>();
111
112///////////////////////////////////////////////////////////////////////////////
113//
114// refactor_action_parser class
115//
116// This helper template allows to attach an action taken from the left
117// operand of the given binary parser to a newly constructed parser,
118// which combines the subject of the left operand of the original binary
119// parser with the right operand of the original binary parser by means of
120// the original binary operator parser.
121//
122// For instance the parser:
123// some_parser[some_attached_functor] - another_parser
124//
125// will be refactored to:
126// (some_parser - another_parser)[some_attached_functor]
127//
128// If the left operand to refactor is not an action parser, no refactoring
129// is done at all.
130//
131// The original parser should be a binary_parser_category parser,
132// else the compilation will fail
133//
134///////////////////////////////////////////////////////////////////////////////
135
136template <typename NestedT = non_nested_refactoring>
137class refactor_action_gen;
138
139template <typename BinaryT, typename NestedT = non_nested_refactoring>
140class refactor_action_parser :
141 public parser<refactor_action_parser<BinaryT, NestedT> > {
142
143public:
144 // the parser to refactor has to be at least a binary_parser_category
145 // parser
146 BOOST_STATIC_ASSERT((
147 boost::is_convertible<typename BinaryT::parser_category_t,
148 binary_parser_category>::value
149 ));
150
151 refactor_action_parser(BinaryT const& binary_, NestedT const& nested_)
152 : binary(binary_), nested(nested_) {}
153
154 typedef refactor_action_parser<BinaryT, NestedT> self_t;
155 typedef refactor_action_gen<NestedT> parser_generator_t;
156 typedef typename BinaryT::left_t::parser_category_t parser_category_t;
157
158 template <typename ScannerT>
159 typename parser_result<self_t, ScannerT>::type
160 parse(ScannerT const& scan) const
161 {
162 return impl::refactor_action_type<NestedT>::
163 parse(*this, scan, binary, nested);
164 }
165
166private:
167 typename as_parser<BinaryT>::type::embed_t binary;
168 typename NestedT::embed_t nested;
169};
170
171//////////////////////////////////
172template <typename NestedT>
173class refactor_action_gen {
174
175public:
176 typedef refactor_action_gen<NestedT> embed_t;
177
178 refactor_action_gen(NestedT const& nested_ = non_nested_refactoring())
179 : nested(nested_) {}
180
181 template <typename ParserT>
182 refactor_action_parser<ParserT, NestedT>
183 operator[](parser<ParserT> const& subject) const
184 {
185 return refactor_action_parser<ParserT, NestedT>
186 (subject.derived(), nested);
187 }
188
189private:
190 typename NestedT::embed_t nested;
191};
192
193const refactor_action_gen<> refactor_action_d = refactor_action_gen<>();
194
195///////////////////////////////////////////////////////////////////////////////
196//
197// attach_action_parser class
198//
199// This helper template allows to attach an action given separately
200// to all parsers, out of which the given parser is constructed and
201// reconstructs a new parser having the same structure.
202//
203// For instance the parser:
204// (some_parser >> another_parser)[some_attached_functor]
205//
206// will be refactored to:
207// some_parser[some_attached_functor]
208// >> another_parser[some_attached_functor]
209//
210// The original parser should be a action_parser_category parser,
211// else the compilation will fail.
212//
213// If the parser, to which the action is attached is not an binary parser,
214// no refactoring is done at all.
215//
216///////////////////////////////////////////////////////////////////////////////
217
218template <typename NestedT = non_nested_refactoring>
219class attach_action_gen;
220
221template <typename ActionT, typename NestedT = non_nested_refactoring>
222class attach_action_parser :
223 public parser<attach_action_parser<ActionT, NestedT> > {
224
225public:
226 // the parser to refactor has to be at least a action_parser_category
227 // parser
228 BOOST_STATIC_ASSERT((
229 boost::is_convertible<typename ActionT::parser_category_t,
230 action_parser_category>::value
231 ));
232
233 attach_action_parser(ActionT const& actor_, NestedT const& nested_)
234 : actor(actor_), nested(nested_) {}
235
236 typedef attach_action_parser<ActionT, NestedT> self_t;
237 typedef attach_action_gen<NestedT> parser_generator_t;
238 typedef typename ActionT::parser_category_t parser_category_t;
239
240 template <typename ScannerT>
241 typename parser_result<self_t, ScannerT>::type
242 parse(ScannerT const& scan) const
243 {
244 return impl::attach_action_type<NestedT>::
245 parse(*this, scan, actor, nested);
246 }
247
248private:
249 typename as_parser<ActionT>::type::embed_t actor;
250 typename NestedT::embed_t nested;
251};
252
253//////////////////////////////////
254template <typename NestedT>
255class attach_action_gen {
256
257public:
258 typedef attach_action_gen<NestedT> embed_t;
259
260 attach_action_gen(NestedT const& nested_ = non_nested_refactoring())
261 : nested(nested_) {}
262
263 template <typename ParserT, typename ActionT>
264 attach_action_parser<action<ParserT, ActionT>, NestedT>
265 operator[](action<ParserT, ActionT> const& actor) const
266 {
267 return attach_action_parser<action<ParserT, ActionT>, NestedT>
268 (actor, nested);
269 }
270
271private:
272 typename NestedT::embed_t nested;
273};
274
275const attach_action_gen<> attach_action_d = attach_action_gen<>();
276
277#if BOOST_WORKAROUND(BOOST_MSVC, >= 1400)
278#pragma warning(pop)
279#endif
280
281///////////////////////////////////////////////////////////////////////////////
282BOOST_SPIRIT_CLASSIC_NAMESPACE_END
283
284}} // namespace BOOST_SPIRIT_CLASSIC_NS
285
286#endif // BOOST_SPIRIT_REFACTORING_HPP
287