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