]> git.proxmox.com Git - ceph.git/blame - ceph/src/boost/libs/spirit/include/boost/spirit/home/classic/utility/loops.hpp
bump version to 12.2.2-pve1
[ceph.git] / ceph / src / boost / libs / spirit / include / boost / spirit / home / classic / utility / loops.hpp
CommitLineData
7c673cae
FG
1/*=============================================================================
2 Copyright (c) 1998-2003 Joel de Guzman
3 Copyright (c) 2002 Raghavendra Satish
4 Copyright (c) 2002 Jeff Westfahl
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#if !defined(BOOST_SPIRIT_LOOPS_HPP)
11#define BOOST_SPIRIT_LOOPS_HPP
12
13///////////////////////////////////////////////////////////////////////////////
14#include <boost/spirit/home/classic/namespace.hpp>
15#include <boost/spirit/home/classic/core/parser.hpp>
16#include <boost/spirit/home/classic/core/composite/composite.hpp>
17
18///////////////////////////////////////////////////////////////////////////////
19namespace boost { namespace spirit {
20
21BOOST_SPIRIT_CLASSIC_NAMESPACE_BEGIN
22
23 ///////////////////////////////////////////////////////////////////////////
24 //
25 // fixed_loop class
26 //
27 // This class takes care of the construct:
28 //
29 // repeat_p (exact) [p]
30 //
31 // where 'p' is a parser and 'exact' is the number of times to
32 // repeat. The parser iterates over the input exactly 'exact' times.
33 // The parse function fails if the parser does not match the input
34 // exactly 'exact' times.
35 //
36 // This class is parametizable and can accept constant arguments
37 // (e.g. repeat_p (5) [p]) as well as references to variables (e.g.
38 // repeat_p (ref (n)) [p]).
39 //
40 ///////////////////////////////////////////////////////////////////////////
41 template <typename ParserT, typename ExactT>
42 class fixed_loop
43 : public unary<ParserT, parser <fixed_loop <ParserT, ExactT> > >
44 {
45 public:
46
47 typedef fixed_loop<ParserT, ExactT> self_t;
48 typedef unary<ParserT, parser<self_t> > base_t;
49
50 fixed_loop (ParserT const & subject_, ExactT const & exact)
51 : base_t(subject_), m_exact(exact) {}
52
53 template <typename ScannerT>
54 typename parser_result <self_t, ScannerT>::type
55 parse (ScannerT const & scan) const
56 {
57 typedef typename parser_result<self_t, ScannerT>::type result_t;
58 result_t hit = scan.empty_match();
59 std::size_t n = m_exact;
60
61 for (std::size_t i = 0; i < n; ++i)
62 {
63 if (result_t next = this->subject().parse(scan))
64 {
65 scan.concat_match(hit, next);
66 }
67 else
68 {
69 return scan.no_match();
70 }
71 }
72
73 return hit;
74 }
75
76 template <typename ScannerT>
77 struct result
78 {
79 typedef typename match_result<ScannerT, nil_t>::type type;
80 };
81
82 private:
83
84 ExactT m_exact;
85 };
86
87 ///////////////////////////////////////////////////////////////////////////////
88 //
89 // finite_loop class
90 //
91 // This class takes care of the construct:
92 //
93 // repeat_p (min, max) [p]
94 //
95 // where 'p' is a parser, 'min' and 'max' specifies the minimum and
96 // maximum iterations over 'p'. The parser iterates over the input
97 // at least 'min' times and at most 'max' times. The parse function
98 // fails if the parser does not match the input at least 'min' times
99 // and at most 'max' times.
100 //
101 // This class is parametizable and can accept constant arguments
102 // (e.g. repeat_p (5, 10) [p]) as well as references to variables
103 // (e.g. repeat_p (ref (n1), ref (n2)) [p]).
104 //
105 ///////////////////////////////////////////////////////////////////////////////
106 template <typename ParserT, typename MinT, typename MaxT>
107 class finite_loop
108 : public unary<ParserT, parser<finite_loop<ParserT, MinT, MaxT> > >
109 {
110 public:
111
112 typedef finite_loop <ParserT, MinT, MaxT> self_t;
113 typedef unary<ParserT, parser<self_t> > base_t;
114
115 finite_loop (ParserT const & subject_, MinT const & min, MaxT const & max)
116 : base_t(subject_), m_min(min), m_max(max) {}
117
118 template <typename ScannerT>
119 typename parser_result <self_t, ScannerT>::type
120 parse(ScannerT const & scan) const
121 {
122 BOOST_SPIRIT_ASSERT(m_min <= m_max);
123 typedef typename parser_result<self_t, ScannerT>::type result_t;
124 result_t hit = scan.empty_match();
125
126 std::size_t n1 = m_min;
127 std::size_t n2 = m_max;
128
129 for (std::size_t i = 0; i < n2; ++i)
130 {
131 typename ScannerT::iterator_t save = scan.first;
132 result_t next = this->subject().parse(scan);
133
134 if (!next)
135 {
136 if (i >= n1)
137 {
138 scan.first = save;
139 break;
140 }
141 else
142 {
143 return scan.no_match();
144 }
145 }
146
147 scan.concat_match(hit, next);
148 }
149
150 return hit;
151 }
152
153 template <typename ScannerT>
154 struct result
155 {
156 typedef typename match_result<ScannerT, nil_t>::type type;
157 };
158
159 private:
160
161 MinT m_min;
162 MaxT m_max;
163 };
164
165 ///////////////////////////////////////////////////////////////////////////////
166 //
167 // infinite_loop class
168 //
169 // This class takes care of the construct:
170 //
171 // repeat_p (min, more) [p]
172 //
173 // where 'p' is a parser, 'min' is the minimum iteration over 'p'
174 // and more specifies that the iteration should proceed
175 // indefinitely. The parser iterates over the input at least 'min'
176 // times and continues indefinitely until 'p' fails or all of the
177 // input is parsed. The parse function fails if the parser does not
178 // match the input at least 'min' times.
179 //
180 // This class is parametizable and can accept constant arguments
181 // (e.g. repeat_p (5, more) [p]) as well as references to variables
182 // (e.g. repeat_p (ref (n), more) [p]).
183 //
184 ///////////////////////////////////////////////////////////////////////////////
185
186 struct more_t {};
187 more_t const more = more_t ();
188
189 template <typename ParserT, typename MinT>
190 class infinite_loop
191 : public unary<ParserT, parser<infinite_loop<ParserT, MinT> > >
192 {
193 public:
194
195 typedef infinite_loop <ParserT, MinT> self_t;
196 typedef unary<ParserT, parser<self_t> > base_t;
197
198 infinite_loop (
199 ParserT const& subject_,
200 MinT const& min,
201 more_t const&
202 )
203 : base_t(subject_), m_min(min) {}
204
205 template <typename ScannerT>
206 typename parser_result <self_t, ScannerT>::type
207 parse(ScannerT const & scan) const
208 {
209 typedef typename parser_result<self_t, ScannerT>::type result_t;
210 result_t hit = scan.empty_match();
211 std::size_t n = m_min;
212
213 for (std::size_t i = 0; ; ++i)
214 {
215 typename ScannerT::iterator_t save = scan.first;
216 result_t next = this->subject().parse(scan);
217
218 if (!next)
219 {
220 if (i >= n)
221 {
222 scan.first = save;
223 break;
224 }
225 else
226 {
227 return scan.no_match();
228 }
229 }
230
231 scan.concat_match(hit, next);
232 }
233
234 return hit;
235 }
236
237 template <typename ScannerT>
238 struct result
239 {
240 typedef typename match_result<ScannerT, nil_t>::type type;
241 };
242
243 private:
244
245 MinT m_min;
246 };
247
248 template <typename ExactT>
249 struct fixed_loop_gen
250 {
251 fixed_loop_gen (ExactT const & exact)
252 : m_exact (exact) {}
253
254 template <typename ParserT>
255 fixed_loop <ParserT, ExactT>
256 operator[](parser <ParserT> const & subject_) const
257 {
258 return fixed_loop <ParserT, ExactT> (subject_.derived (), m_exact);
259 }
260
261 ExactT m_exact;
262 };
263
264 namespace impl {
265
266 template <typename ParserT, typename MinT, typename MaxT>
267 struct loop_traits
268 {
269 typedef typename mpl::if_<
270 boost::is_same<MaxT, more_t>,
271 infinite_loop<ParserT, MinT>,
272 finite_loop<ParserT, MinT, MaxT>
273 >::type type;
274 };
275
276 } // namespace impl
277
278 template <typename MinT, typename MaxT>
279 struct nonfixed_loop_gen
280 {
281 nonfixed_loop_gen (MinT min, MaxT max)
282 : m_min (min), m_max (max) {}
283
284 template <typename ParserT>
285 typename impl::loop_traits<ParserT, MinT, MaxT>::type
286 operator[](parser <ParserT> const & subject_) const
287 {
288 typedef typename impl::loop_traits<ParserT, MinT, MaxT>::type ret_t;
289 return ret_t(
290 subject_.derived(),
291 m_min,
292 m_max);
293 }
294
295 MinT m_min;
296 MaxT m_max;
297 };
298
299 template <typename ExactT>
300 fixed_loop_gen <ExactT>
301 repeat_p(ExactT const & exact)
302 {
303 return fixed_loop_gen <ExactT> (exact);
304 }
305
306 template <typename MinT, typename MaxT>
307 nonfixed_loop_gen <MinT, MaxT>
308 repeat_p(MinT const & min, MaxT const & max)
309 {
310 return nonfixed_loop_gen <MinT, MaxT> (min, max);
311 }
312
313BOOST_SPIRIT_CLASSIC_NAMESPACE_END
314
315}} // namespace BOOST_SPIRIT_CLASSIC_NS
316
317#endif // #if !defined(BOOST_SPIRIT_LOOPS_HPP)