]> git.proxmox.com Git - ceph.git/blob - ceph/src/boost/libs/spirit/include/boost/spirit/home/classic/dynamic/if.hpp
bump version to 12.2.2-pve1
[ceph.git] / ceph / src / boost / libs / spirit / include / boost / spirit / home / classic / dynamic / if.hpp
1 /*=============================================================================
2 Copyright (c) 2002-2003 Joel de Guzman
3 Copyright (c) 2002 Juan Carlos Arevalo-Baeza
4 Copyright (c) 2002-2003 Martin Wille
5 http://spirit.sourceforge.net/
6
7 Distributed under the Boost Software License, Version 1.0. (See accompanying
8 file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
9 =============================================================================*/
10 #ifndef BOOST_SPIRIT_IF_HPP
11 #define BOOST_SPIRIT_IF_HPP
12
13 #include <boost/spirit/home/classic/namespace.hpp>
14 #include <boost/spirit/home/classic/core/parser.hpp>
15 #include <boost/spirit/home/classic/core/composite/composite.hpp>
16 #include <boost/spirit/home/classic/dynamic/impl/conditions.ipp>
17
18 namespace boost { namespace spirit {
19
20 BOOST_SPIRIT_CLASSIC_NAMESPACE_BEGIN
21
22 namespace impl {
23
24 //////////////////////////////////
25 // if-else-parser, holds two alternative parsers and a conditional functor
26 // that selects between them.
27 template <typename ParsableTrueT, typename ParsableFalseT, typename CondT>
28 struct if_else_parser
29 : public condition_evaluator<typename as_parser<CondT>::type>
30 , public binary
31 <
32 typename as_parser<ParsableTrueT>::type,
33 typename as_parser<ParsableFalseT>::type,
34 parser< if_else_parser<ParsableTrueT, ParsableFalseT, CondT> >
35 >
36 {
37 typedef if_else_parser<ParsableTrueT, ParsableFalseT, CondT> self_t;
38
39 typedef as_parser<ParsableTrueT> as_parser_true_t;
40 typedef as_parser<ParsableFalseT> as_parser_false_t;
41 typedef typename as_parser_true_t::type parser_true_t;
42 typedef typename as_parser_false_t::type parser_false_t;
43 typedef as_parser<CondT> cond_as_parser_t;
44 typedef typename cond_as_parser_t::type condition_t;
45
46 typedef binary<parser_true_t, parser_false_t, parser<self_t> > base_t;
47 typedef condition_evaluator<condition_t> eval_t;
48
49 if_else_parser
50 (
51 ParsableTrueT const& p_true,
52 ParsableFalseT const& p_false,
53 CondT const& cond_
54 )
55 : eval_t(cond_as_parser_t::convert(cond_))
56 , base_t
57 (
58 as_parser_true_t::convert(p_true),
59 as_parser_false_t::convert(p_false)
60 )
61 { }
62
63 template <typename ScannerT>
64 struct result
65 {
66 typedef typename match_result<ScannerT, nil_t>::type type;
67 };
68
69 template <typename ScannerT>
70 typename parser_result<self_t, ScannerT>::type
71 parse(ScannerT const& scan) const
72 {
73 typedef typename parser_result
74 <parser_true_t, ScannerT>::type then_result_t;
75 typedef typename parser_result
76 <parser_false_t, ScannerT>::type else_result_t;
77
78 typename ScannerT::iterator_t const save(scan.first);
79
80 std::ptrdiff_t length = this->evaluate(scan);
81 if (length >= 0)
82 {
83 then_result_t then_result(this->left().parse(scan));
84 if (then_result)
85 {
86 length += then_result.length();
87 return scan.create_match(std::size_t(length), nil_t(), save, scan.first);
88 }
89 }
90 else
91 {
92 else_result_t else_result(this->right().parse(scan));
93 if (else_result)
94 {
95 length = else_result.length();
96 return scan.create_match(std::size_t(length), nil_t(), save, scan.first);
97 }
98 }
99 return scan.no_match();
100 }
101 };
102
103 //////////////////////////////////
104 // if-else-parser generator, takes the false-parser in brackets
105 // and returns the if-else-parser.
106 template <typename ParsableTrueT, typename CondT>
107 struct if_else_parser_gen
108 {
109 if_else_parser_gen(ParsableTrueT const& p_true_, CondT const& cond_)
110 : p_true(p_true_)
111 , cond(cond_) {}
112
113 template <typename ParsableFalseT>
114 if_else_parser
115 <
116 ParsableTrueT,
117 ParsableFalseT,
118 CondT
119 >
120 operator[](ParsableFalseT const& p_false) const
121 {
122 return if_else_parser<ParsableTrueT, ParsableFalseT, CondT>
123 (
124 p_true,
125 p_false,
126 cond
127 );
128 }
129
130 ParsableTrueT const &p_true;
131 CondT const &cond;
132 };
133
134 //////////////////////////////////
135 // if-parser, conditionally runs a parser is a functor condition is true.
136 // If the condition is fales, it fails the parse.
137 // It can optionally become an if-else-parser through the member else_p.
138 template <typename ParsableT, typename CondT>
139 struct if_parser
140 : public condition_evaluator<typename as_parser<CondT>::type>
141 , public unary
142 <
143 typename as_parser<ParsableT>::type,
144 parser<if_parser<ParsableT, CondT> > >
145 {
146 typedef if_parser<ParsableT, CondT> self_t;
147 typedef as_parser<ParsableT> as_parser_t;
148 typedef typename as_parser_t::type parser_t;
149
150 typedef as_parser<CondT> cond_as_parser_t;
151 typedef typename cond_as_parser_t::type condition_t;
152 typedef condition_evaluator<condition_t> eval_t;
153 typedef unary<parser_t, parser<self_t> > base_t;
154
155 if_parser(ParsableT const& p, CondT const& cond_)
156 : eval_t(cond_as_parser_t::convert(cond_))
157 , base_t(as_parser_t::convert(p))
158 , else_p(p, cond_)
159 {}
160
161 template <typename ScannerT>
162 struct result
163 {
164 typedef typename match_result<ScannerT, nil_t>::type type;
165 };
166
167 template <typename ScannerT>
168 typename parser_result<self_t, ScannerT>::type
169 parse(ScannerT const& scan) const
170 {
171 typedef typename parser_result<parser_t, ScannerT>::type t_result_t;
172 typename ScannerT::iterator_t const save(scan.first);
173
174 std::ptrdiff_t length = this->evaluate(scan);
175 if (length >= 0)
176 {
177 t_result_t then_result(this->subject().parse(scan));
178 if (then_result)
179 {
180 length += then_result.length();
181 return scan.create_match(std::size_t(length), nil_t(), save, scan.first);
182 }
183 return scan.no_match();
184 }
185 return scan.empty_match();
186 }
187
188 if_else_parser_gen<ParsableT, CondT> else_p;
189 };
190
191 //////////////////////////////////
192 // if-parser generator, takes the true-parser in brackets and returns the
193 // if-parser.
194 template <typename CondT>
195 struct if_parser_gen
196 {
197 if_parser_gen(CondT const& cond_) : cond(cond_) {}
198
199 template <typename ParsableT>
200 if_parser
201 <
202 ParsableT,
203 CondT
204 >
205 operator[](ParsableT const& subject) const
206 {
207 return if_parser<ParsableT, CondT>(subject, cond);
208 }
209
210 CondT const &cond;
211 };
212
213 } // namespace impl
214
215 //////////////////////////////////
216 // if_p function, returns "if" parser generator
217
218 template <typename CondT>
219 impl::if_parser_gen<CondT>
220 if_p(CondT const& cond)
221 {
222 return impl::if_parser_gen<CondT>(cond);
223 }
224
225 BOOST_SPIRIT_CLASSIC_NAMESPACE_END
226
227 }} // namespace BOOST_SPIRIT_CLASSIC_NS
228
229 #endif // BOOST_SPIRIT_IF_HPP