]> git.proxmox.com Git - ceph.git/blame - ceph/src/boost/libs/spirit/include/boost/spirit/home/support/iterators/line_pos_iterator.hpp
bump version to 12.2.2-pve1
[ceph.git] / ceph / src / boost / libs / spirit / include / boost / spirit / home / support / iterators / line_pos_iterator.hpp
CommitLineData
7c673cae
FG
1/*==============================================================================
2 Copyright (c) 2001-2011 Joel de Guzman
3 Copyright (c) 2010 Bryce Lelbach
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
9#if !defined(BOOST_SPIRIT_SUPPORT_LINE_POS_ITERATOR)
10#define BOOST_SPIRIT_SUPPORT_LINE_POS_ITERATOR
11
12#include <boost/iterator/iterator_adaptor.hpp>
13#include <boost/range/iterator_range.hpp>
14
15namespace boost { namespace spirit
16{
17 //[line_pos_iterator_class
18 /*`The `line_pos_iterator` is a lightweight line position iterator.
19 This iterator adapter only stores the current line number, nothing else.
20 Unlike __classic__'s `position_iterator`, it does not store the
21 column number and does not need an end iterator. The current column can
22 be computed, if needed. */
23 //`[heading Class Reference]
24 template <class Iterator>
25 class line_pos_iterator : public boost::iterator_adaptor<
26 line_pos_iterator<Iterator> // Derived
27 , Iterator // Base
28 , boost::use_default // Value
29 , boost::forward_traversal_tag // CategoryOrTraversal
30 > {
31 public:
32 line_pos_iterator();
33
34 explicit line_pos_iterator(Iterator);
35
36 std::size_t position() const;
37
38 private:
39 friend class boost::iterator_core_access;
40
41 void increment();
42
43 std::size_t line; // The line position.
44 typename std::iterator_traits<Iterator>::value_type prev;
45 };
46 //]
47
48 template <class Iterator>
49 line_pos_iterator<Iterator>::line_pos_iterator() :
50 line_pos_iterator::iterator_adaptor_(), line(1), prev(0) { }
51
52 template <class Iterator>
53 line_pos_iterator<Iterator>::line_pos_iterator(Iterator base) :
54 line_pos_iterator::iterator_adaptor_(base), line(1), prev(0) { }
55
56 template <class Iterator>
57 std::size_t line_pos_iterator<Iterator>::position() const
58 {
59 return line;
60 }
61
62 template<class Iterator>
63 void line_pos_iterator<Iterator>::increment()
64 {
65 typename std::iterator_traits<Iterator>::reference
66 ref = *(this->base());
67
68 switch (ref) {
69 case '\r':
70 if (prev != '\n')
71 ++line;
72 break;
73 case '\n':
74 if (prev != '\r')
75 ++line;
76 break;
77 default:
78 break;
79 }
80
81 prev = ref;
82 ++this->base_reference();
83 }
84
85 //[line_pos_iterator_utilities
86 //`[heading get_line]
87 template <class Iterator>
88 inline std::size_t get_line(Iterator);
89 /*`Get the line position. Returns -1 if Iterator is not a
90 `line_pos_iterator`. */
91
92 //`[heading get_line_start]
93 template <class Iterator>
94 inline Iterator get_line_start(Iterator lower_bound, Iterator current);
95 /*`Get an iterator to the beginning of the line. Applicable to any
96 iterator. */
97
98 //`[heading get_current_line]
99 template <class Iterator>
100 inline iterator_range<Iterator>
101 get_current_line(Iterator lower_bound, Iterator current,
102 Iterator upper_bound);
103 /*`Get an `iterator_range` containing the current line. Applicable to any
104 iterator. */
105
106 //`[heading get_column]
107 template <class Iterator>
108 inline std::size_t get_column(Iterator lower_bound, Iterator current,
109 std::size_t tabs = 4);
110 /*`Get the current column. Applicable to any iterator. */
111 //]
112
113 template <class Iterator>
114 inline std::size_t get_line(Iterator)
115 {
116 return -1;
117 }
118
119 template <class Iterator>
120 inline std::size_t get_line(line_pos_iterator<Iterator> i)
121 {
122 return i.position();
123 }
124
125 template <class Iterator>
126 inline Iterator get_line_start(Iterator lower_bound, Iterator current)
127 {
128 Iterator latest = lower_bound;
129
130 for (Iterator i = lower_bound; i != current; ++i) {
131 switch (*i) {
132 case '\r':
133 case '\n':
134 latest = i;
135 }
136 }
137
138 return latest;
139 }
140
141 template <class Iterator>
142 inline iterator_range<Iterator>
143 get_current_line(Iterator lower_bound,
144 Iterator current,
145 Iterator upper_bound)
146 {
147 Iterator first = get_line_start(lower_bound, current);
148 Iterator last = get_line_start(current, upper_bound);
149
150 if (last == current)
151 last = upper_bound;
152
153 return iterator_range<Iterator>(first, last);
154 }
155
156 template <class Iterator>
157 inline std::size_t get_column(Iterator lower_bound,
158 Iterator current,
159 std::size_t tabs)
160 {
161 std::size_t column = 1;
162 Iterator first = get_line_start(lower_bound, current);
163
164 for (Iterator i = first; i != current; ++i) {
165 switch (*i) {
166 case '\t':
167 column += tabs - (column - 1) % tabs;
168 break;
169 default:
170 ++column;
171 }
172 }
173
174 return column;
175 }
176
177}}
178
179#endif // BOOST_SPIRIT_SUPPORT_LINE_POS_ITERATOR
180