]> git.proxmox.com Git - ceph.git/blame - ceph/src/boost/libs/spirit/include/boost/spirit/home/classic/iterator/position_iterator.hpp
bump version to 12.2.2-pve1
[ceph.git] / ceph / src / boost / libs / spirit / include / boost / spirit / home / classic / iterator / position_iterator.hpp
CommitLineData
7c673cae
FG
1/*=============================================================================
2 Copyright (c) 2002 Juan Carlos Arevalo-Baeza
3 Copyright (c) 2002-2006 Hartmut Kaiser
4 Copyright (c) 2003 Giovanni Bajo
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_POSITION_ITERATOR_HPP
11#define BOOST_SPIRIT_POSITION_ITERATOR_HPP
12
13#include <string>
14#include <boost/config.hpp>
15#include <boost/concept_check.hpp>
16
17#include <boost/spirit/home/classic/namespace.hpp>
18#include <boost/spirit/home/classic/iterator/position_iterator_fwd.hpp>
19
20namespace boost { namespace spirit {
21
22BOOST_SPIRIT_CLASSIC_NAMESPACE_BEGIN
23
24///////////////////////////////////////////////////////////////////////////////
25//
26// file_position_without_column
27//
28// A structure to hold positional information. This includes the file,
29// and the line number
30//
31///////////////////////////////////////////////////////////////////////////////
32template <typename String>
33struct file_position_without_column_base {
34 String file;
35 int line;
36
37 file_position_without_column_base(String const& file_ = String(),
38 int line_ = 1):
39 file (file_),
40 line (line_)
41 {}
42
43 bool operator==(const file_position_without_column_base& fp) const
44 { return line == fp.line && file == fp.file; }
45};
46
47///////////////////////////////////////////////////////////////////////////////
48//
49// file_position
50//
51// This structure holds complete file position, including file name,
52// line and column number
53//
54///////////////////////////////////////////////////////////////////////////////
55template <typename String>
56struct file_position_base : public file_position_without_column_base<String> {
57 int column;
58
59 file_position_base(String const& file_ = String(),
60 int line_ = 1, int column_ = 1):
61 file_position_without_column_base<String> (file_, line_),
62 column (column_)
63 {}
64
65 bool operator==(const file_position_base& fp) const
66 { return column == fp.column && this->line == fp.line && this->file == fp.file; }
67};
68
69///////////////////////////////////////////////////////////////////////////////
70//
71// position_policy<>
72//
73// This template is the policy to handle the file position. It is specialized
74// on the position type. Providing a custom file_position also requires
75// providing a specialization of this class.
76//
77// Policy interface:
78//
79// Default constructor of the custom position class must be accessible.
80// set_tab_chars(unsigned int chars) - Set the tabstop width
81// next_char(PositionT& pos) - Notify that a new character has been
82// processed
83// tabulation(PositionT& pos) - Notify that a tab character has been
84// processed
85// next_line(PositionT& pos) - Notify that a new line delimiter has
86// been reached.
87//
88///////////////////////////////////////////////////////////////////////////////
89template <typename PositionT> class position_policy;
90
91///////////////////////////////////////////////////////////////////////////////
92BOOST_SPIRIT_CLASSIC_NAMESPACE_END
93
94}} /* namespace BOOST_SPIRIT_CLASSIC_NS */
95
96
97// This must be included here for full compatibility with old MSVC
98#include <boost/spirit/home/classic/iterator/impl/position_iterator.ipp>
99
100///////////////////////////////////////////////////////////////////////////////
101namespace boost { namespace spirit {
102
103BOOST_SPIRIT_CLASSIC_NAMESPACE_BEGIN
104
105///////////////////////////////////////////////////////////////////////////////
106//
107// position_iterator
108//
109// It wraps an iterator, and keeps track of the current position in the input,
110// as it gets incremented.
111//
112// The wrapped iterator must be at least a Forward iterator. The position
113// iterator itself will always be a non-mutable Forward iterator.
114//
115// In order to have begin/end iterators constructed, the end iterator must be
116// empty constructed. Similar to what happens with stream iterators. The begin
117// iterator must be constructed from both, the begin and end iterators of the
118// wrapped iterator type. This is necessary to implement the lookahead of
119// characters necessary to parse CRLF sequences.
120//
121// In order to extract the current positional data from the iterator, you may
122// use the get_position member function.
123//
124// You can also use the set_position member function to reset the current
125// position to something new.
126//
127// The structure that holds the current position can be customized through a
128// template parameter, and the class position_policy must be specialized
129// on the new type to define how to handle it. Currently, it's possible
130// to choose between the file_position and file_position_without_column
131// (which saves some overhead if managing current column is not required).
132//
133///////////////////////////////////////////////////////////////////////////////
134
135#if !defined(BOOST_ITERATOR_ADAPTORS_VERSION) || \
136 BOOST_ITERATOR_ADAPTORS_VERSION < 0x0200
137#error "Please use at least Boost V1.31.0 while compiling the position_iterator class!"
138#else // BOOST_ITERATOR_ADAPTORS_VERSION < 0x0200
139
140///////////////////////////////////////////////////////////////////////////////
141//
142// Uses the newer iterator_adaptor version (should be released with
143// Boost V1.31.0)
144//
145///////////////////////////////////////////////////////////////////////////////
146template <
147 typename ForwardIteratorT,
148 typename PositionT,
149 typename SelfT
150>
151class position_iterator
152: public iterator_::impl::position_iterator_base_generator<
153 SelfT,
154 ForwardIteratorT,
155 PositionT
156 >::type,
157 public position_policy<PositionT>
158{
159private:
160
161 typedef position_policy<PositionT> position_policy_t;
162 typedef typename iterator_::impl::position_iterator_base_generator<
163 SelfT,
164 ForwardIteratorT,
165 PositionT
166 >::type base_t;
167 typedef typename iterator_::impl::position_iterator_base_generator<
168 SelfT,
169 ForwardIteratorT,
170 PositionT
171 >::main_iter_t main_iter_t;
172
173public:
174
175 typedef PositionT position_t;
176
177 position_iterator()
178 : _isend(true)
179 {}
180
181 position_iterator(
182 const ForwardIteratorT& begin,
183 const ForwardIteratorT& end)
184 : base_t(begin), _end(end), _pos(PositionT()), _isend(begin == end)
185 {}
186
187 template <typename FileNameT>
188 position_iterator(
189 const ForwardIteratorT& begin,
190 const ForwardIteratorT& end,
191 FileNameT fileName)
192 : base_t(begin), _end(end), _pos(PositionT(fileName)),
193 _isend(begin == end)
194 {}
195
196 template <typename FileNameT, typename LineT>
197 position_iterator(
198 const ForwardIteratorT& begin,
199 const ForwardIteratorT& end,
200 FileNameT fileName, LineT line)
201 : base_t(begin), _end(end), _pos(PositionT(fileName, line)),
202 _isend(begin == end)
203 {}
204
205 template <typename FileNameT, typename LineT, typename ColumnT>
206 position_iterator(
207 const ForwardIteratorT& begin,
208 const ForwardIteratorT& end,
209 FileNameT fileName, LineT line, ColumnT column)
210 : base_t(begin), _end(end), _pos(PositionT(fileName, line, column)),
211 _isend(begin == end)
212 {}
213
214 position_iterator(
215 const ForwardIteratorT& begin,
216 const ForwardIteratorT& end,
217 const PositionT& pos)
218 : base_t(begin), _end(end), _pos(pos), _isend(begin == end)
219 {}
220
221 position_iterator(const position_iterator& iter)
222 : base_t(iter.base()), position_policy_t(iter),
223 _end(iter._end), _pos(iter._pos), _isend(iter._isend)
224 {}
225
226 position_iterator& operator=(const position_iterator& iter)
227 {
228 base_t::operator=(iter);
229 position_policy_t::operator=(iter);
230 _end = iter._end;
231 _pos = iter._pos;
232 _isend = iter._isend;
233 return *this;
234 }
235
236 void set_position(PositionT const& newpos) { _pos = newpos; }
237 PositionT& get_position() { return _pos; }
238 PositionT const& get_position() const { return _pos; }
239
240 void set_tabchars(unsigned int chars)
241 {
242 // This function (which comes from the position_policy) has a
243 // different name on purpose, to avoid messing with using
244 // declarations or qualified calls to access the base template
245 // function, which might break some compilers.
246 this->position_policy_t::set_tab_chars(chars);
247 }
248
249private:
250 friend class boost::iterator_core_access;
251
252 void increment()
253 {
254 typename base_t::reference val = *(this->base());
255 if (val == '\n') {
256 ++this->base_reference();
257 this->next_line(_pos);
258 static_cast<main_iter_t &>(*this).newline();
259 }
260 else if ( val == '\r') {
261 ++this->base_reference();
262 if (this->base_reference() == _end || *(this->base()) != '\n')
263 {
264 this->next_line(_pos);
265 static_cast<main_iter_t &>(*this).newline();
266 }
267 }
268 else if (val == '\t') {
269 this->tabulation(_pos);
270 ++this->base_reference();
271 }
272 else {
273 this->next_char(_pos);
274 ++this->base_reference();
275 }
276
277 // The iterator is at the end only if it's the same
278 // of the
279 _isend = (this->base_reference() == _end);
280 }
281
282 template <
283 typename OtherDerivedT, typename OtherIteratorT,
284 typename V, typename C, typename R, typename D
285 >
286 bool equal(iterator_adaptor<OtherDerivedT, OtherIteratorT, V, C, R, D>
287 const &x) const
288 {
289 OtherDerivedT const &rhs = static_cast<OtherDerivedT const &>(x);
290 bool x_is_end = rhs._isend;
291
292 return (_isend == x_is_end) && (_isend || this->base() == rhs.base());
293 }
294
295protected:
296
297 void newline(void)
298 {}
299
300 ForwardIteratorT _end;
301 PositionT _pos;
302 bool _isend;
303};
304
305#endif // BOOST_ITERATOR_ADAPTORS_VERSION < 0x0200
306
307///////////////////////////////////////////////////////////////////////////////
308//
309// position_iterator2
310//
311// Equivalent to position_iterator, but it is able to extract the current
312// line into a string. This is very handy for error reports.
313//
314// Notice that the footprint of this class is higher than position_iterator,
315// (how much depends on how bulky the underlying iterator is), so it should
316// be used only if necessary.
317//
318///////////////////////////////////////////////////////////////////////////////
319
320template
321<
322 typename ForwardIteratorT,
323 typename PositionT
324>
325class position_iterator2
326 : public position_iterator
327 <
328 ForwardIteratorT,
329 PositionT,
330 position_iterator2<ForwardIteratorT, PositionT>
331 >
332{
333 typedef position_iterator
334 <
335 ForwardIteratorT,
336 PositionT,
337 position_iterator2<ForwardIteratorT, PositionT> // JDG 4-15-03
338 > base_t;
339
340public:
341 typedef typename base_t::value_type value_type;
342 typedef PositionT position_t;
343
344 position_iterator2()
345 {}
346
347 position_iterator2(
348 const ForwardIteratorT& begin,
349 const ForwardIteratorT& end):
350 base_t(begin, end),
351 _startline(begin)
352 {}
353
354 template <typename FileNameT>
355 position_iterator2(
356 const ForwardIteratorT& begin,
357 const ForwardIteratorT& end,
358 FileNameT file):
359 base_t(begin, end, file),
360 _startline(begin)
361 {}
362
363 template <typename FileNameT, typename LineT>
364 position_iterator2(
365 const ForwardIteratorT& begin,
366 const ForwardIteratorT& end,
367 FileNameT file, LineT line):
368 base_t(begin, end, file, line),
369 _startline(begin)
370 {}
371
372 template <typename FileNameT, typename LineT, typename ColumnT>
373 position_iterator2(
374 const ForwardIteratorT& begin,
375 const ForwardIteratorT& end,
376 FileNameT file, LineT line, ColumnT column):
377 base_t(begin, end, file, line, column),
378 _startline(begin)
379 {}
380
381 position_iterator2(
382 const ForwardIteratorT& begin,
383 const ForwardIteratorT& end,
384 const PositionT& pos):
385 base_t(begin, end, pos),
386 _startline(begin)
387 {}
388
389 position_iterator2(const position_iterator2& iter)
390 : base_t(iter), _startline(iter._startline)
391 {}
392
393 position_iterator2& operator=(const position_iterator2& iter)
394 {
395 base_t::operator=(iter);
396 _startline = iter._startline;
397 return *this;
398 }
399
400 ForwardIteratorT get_currentline_begin(void) const
401 { return _startline; }
402
403 ForwardIteratorT get_currentline_end(void) const
404 { return get_endline(); }
405
406 std::basic_string<value_type> get_currentline(void) const
407 {
408 return std::basic_string<value_type>
409 (get_currentline_begin(), get_currentline_end());
410 }
411
412protected:
413 ForwardIteratorT _startline;
414
415 friend class position_iterator<ForwardIteratorT, PositionT,
416 position_iterator2<ForwardIteratorT, PositionT> >;
417
418 ForwardIteratorT get_endline() const
419 {
420 ForwardIteratorT endline = _startline;
421 while (endline != this->_end && *endline != '\r' && *endline != '\n')
422 {
423 ++endline;
424 }
425 return endline;
426 }
427
428 void newline(void)
429 { _startline = this->base(); }
430};
431
432BOOST_SPIRIT_CLASSIC_NAMESPACE_END
433
434}} // namespace BOOST_SPIRIT_CLASSIC_NS
435
436#endif