]> git.proxmox.com Git - ceph.git/blob - ceph/src/boost/libs/wave/include/boost/wave/util/unput_queue_iterator.hpp
bump version to 12.2.2-pve1
[ceph.git] / ceph / src / boost / libs / wave / include / boost / wave / util / unput_queue_iterator.hpp
1 /*=============================================================================
2 Boost.Wave: A Standard compliant C++ preprocessor library
3
4 Definition of the unput queue iterator
5
6 http://www.boost.org/
7
8 Copyright (c) 2001-2012 Hartmut Kaiser. Distributed under the Boost
9 Software License, Version 1.0. (See accompanying file
10 LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
11 =============================================================================*/
12 #if !defined(UNPUT_QUEUE_ITERATOR_HPP_76DA23D0_4893_4AD5_ABCC_6CED7CFB89BC_INCLUDED)
13 #define UNPUT_QUEUE_ITERATOR_HPP_76DA23D0_4893_4AD5_ABCC_6CED7CFB89BC_INCLUDED
14
15 #include <list>
16
17 #include <boost/assert.hpp>
18 #include <boost/iterator_adaptors.hpp>
19
20 #include <boost/wave/wave_config.hpp>
21 #include <boost/wave/token_ids.hpp> // token_id
22
23 // this must occur after all of the includes and before any code appears
24 #ifdef BOOST_HAS_ABI_HEADERS
25 #include BOOST_ABI_PREFIX
26 #endif
27
28 ///////////////////////////////////////////////////////////////////////////////
29 namespace boost {
30 namespace wave {
31 namespace util {
32
33 ///////////////////////////////////////////////////////////////////////////////
34 //
35 // unput_queue_iterator
36 //
37 // The unput_queue_iterator templates encapsulates an unput_queue together
38 // with the direct input to be read after the unput queue is emptied
39 //
40 // This version is for the new iterator_adaptors (was released with
41 // Boost V1.31.0)
42 //
43 ///////////////////////////////////////////////////////////////////////////////
44 template <typename IteratorT, typename TokenT, typename ContainerT>
45 class unput_queue_iterator
46 : public boost::iterator_adaptor<
47 unput_queue_iterator<IteratorT, TokenT, ContainerT>,
48 IteratorT, TokenT const, std::forward_iterator_tag>
49 {
50 typedef boost::iterator_adaptor<
51 unput_queue_iterator<IteratorT, TokenT, ContainerT>,
52 IteratorT, TokenT const, std::forward_iterator_tag>
53 base_type;
54
55 public:
56 typedef ContainerT container_type;
57 typedef IteratorT iterator_type;
58
59 unput_queue_iterator(IteratorT const &it, ContainerT &queue)
60 : base_type(it), unput_queue(queue)
61 {}
62
63 ContainerT &get_unput_queue()
64 { return unput_queue; }
65 ContainerT const &get_unput_queue() const
66 { return unput_queue; }
67 IteratorT &get_base_iterator()
68 { return base_type::base_reference(); }
69 IteratorT const &get_base_iterator() const
70 { return base_type::base_reference(); }
71
72 unput_queue_iterator &operator= (unput_queue_iterator const &rhs)
73 {
74 if (this != &rhs) {
75 unput_queue = rhs.unput_queue;
76 base_type::operator=(rhs);
77 }
78 return *this;
79 }
80
81 typename base_type::reference dereference() const
82 {
83 if (!unput_queue.empty())
84 return unput_queue.front();
85 return *base_type::base_reference();
86 }
87
88 void increment()
89 {
90 if (!unput_queue.empty()) {
91 // there exist pending tokens in the unput queue
92 unput_queue.pop_front();
93 }
94 else {
95 // the unput_queue is empty, so advance the base iterator
96 ++base_type::base_reference();
97 }
98 }
99
100 template <
101 typename OtherDerivedT, typename OtherIteratorT,
102 typename V, typename C, typename R, typename D
103 >
104 bool equal(
105 boost::iterator_adaptor<OtherDerivedT, OtherIteratorT, V, C, R, D>
106 const &x) const
107 {
108 // two iterators are equal, if both begin() iterators of the queue
109 // objects are equal and the base iterators are equal as well
110 OtherDerivedT const &rhs = static_cast<OtherDerivedT const &>(x);
111 return
112 ((unput_queue.empty() && rhs.unput_queue.empty()) ||
113 (&unput_queue == &rhs.unput_queue &&
114 unput_queue.begin() == rhs.unput_queue.begin()
115 )
116 ) &&
117 (get_base_iterator() == rhs.get_base_iterator());
118 }
119
120 private:
121 ContainerT &unput_queue;
122 };
123
124 namespace impl {
125
126 ///////////////////////////////////////////////////////////////////////////
127 template <typename IteratorT, typename TokenT, typename ContainerT>
128 struct gen_unput_queue_iterator
129 {
130 typedef ContainerT container_type;
131 typedef IteratorT iterator_type;
132 typedef unput_queue_iterator<IteratorT, TokenT, ContainerT>
133 return_type;
134
135 static container_type last;
136
137 static return_type
138 generate(iterator_type const &it)
139 {
140 return return_type(it, last);
141 }
142
143 static return_type
144 generate(ContainerT &queue, iterator_type const &it)
145 {
146 return return_type(it, queue);
147 }
148 };
149
150 template <typename IteratorT, typename TokenT, typename ContainerT>
151 typename gen_unput_queue_iterator<IteratorT, TokenT, ContainerT>::
152 container_type
153 gen_unput_queue_iterator<IteratorT, TokenT, ContainerT>::last =
154 typename gen_unput_queue_iterator<IteratorT, TokenT, ContainerT>::
155 container_type();
156
157 ///////////////////////////////////////////////////////////////////////////
158 template <typename IteratorT, typename TokenT, typename ContainerT>
159 struct gen_unput_queue_iterator<
160 unput_queue_iterator<IteratorT, TokenT, ContainerT>,
161 TokenT, ContainerT>
162 {
163 typedef ContainerT container_type;
164 typedef unput_queue_iterator<IteratorT, TokenT, ContainerT>
165 iterator_type;
166 typedef unput_queue_iterator<IteratorT, TokenT, ContainerT>
167 return_type;
168
169 static container_type last;
170
171 static return_type
172 generate(iterator_type &it)
173 {
174 return return_type(it.base(), last);
175 }
176
177 static return_type
178 generate(ContainerT &queue, iterator_type &it)
179 {
180 return return_type(it.base(), queue);
181 }
182 };
183
184 ///////////////////////////////////////////////////////////////////////////
185 template <typename IteratorT>
186 struct assign_iterator
187 {
188 static void
189 do_ (IteratorT &dest, IteratorT const &src)
190 {
191 dest = src;
192 }
193 };
194
195 ///////////////////////////////////////////////////////////////////////////
196 //
197 // Look for the first non-whitespace token and return this token id.
198 // Note though, that the embedded unput_queues are not touched in any way!
199 //
200 template <typename IteratorT>
201 struct next_token
202 {
203 static boost::wave::token_id
204 peek(IteratorT it, IteratorT end, bool skip_whitespace = true)
205 {
206 using namespace boost::wave;
207 if (skip_whitespace) {
208 for (++it; it != end; ++it) {
209 if (!IS_CATEGORY(*it, WhiteSpaceTokenType) &&
210 T_NEWLINE != token_id(*it))
211 {
212 break; // stop at the first non-whitespace token
213 }
214 }
215 }
216 else {
217 ++it; // we have at least to look ahead
218 }
219 if (it != end)
220 return token_id(*it);
221 return T_EOI;
222 }
223 };
224
225 template <typename IteratorT, typename TokenT, typename ContainerT>
226 struct next_token<
227 unput_queue_iterator<IteratorT, TokenT, ContainerT> > {
228
229 typedef unput_queue_iterator<IteratorT, TokenT, ContainerT> iterator_type;
230
231 static boost::wave::token_id
232 peek(iterator_type it, iterator_type end, bool skip_whitespace = true)
233 {
234 using namespace boost::wave;
235
236 typename iterator_type::container_type &queue = it.get_unput_queue();
237
238 // first try to find it in the unput_queue
239 if (0 != queue.size()) {
240 typename iterator_type::container_type::iterator cit = queue.begin();
241 typename iterator_type::container_type::iterator cend = queue.end();
242
243 if (skip_whitespace) {
244 for (++cit; cit != cend; ++cit) {
245 if (!IS_CATEGORY(*cit, WhiteSpaceTokenType) &&
246 T_NEWLINE != token_id(*cit))
247 {
248 break; // stop at the first non-whitespace token
249 }
250 }
251 }
252 else {
253 ++cit; // we have at least to look ahead
254 }
255 if (cit != cend)
256 return token_id(*cit);
257 }
258
259 // second try to move on into the base iterator stream
260 typename iterator_type::iterator_type base_it = it.get_base_iterator();
261 typename iterator_type::iterator_type base_end = end.get_base_iterator();
262
263 if (0 == queue.size())
264 ++base_it; // advance, if the unput queue is empty
265
266 if (skip_whitespace) {
267 for (/**/; base_it != base_end; ++base_it) {
268 if (!IS_CATEGORY(*base_it, WhiteSpaceTokenType) &&
269 T_NEWLINE != token_id(*base_it))
270 {
271 break; // stop at the first non-whitespace token
272 }
273 }
274 }
275 if (base_it == base_end)
276 return T_EOI;
277
278 return token_id(*base_it);
279 }
280 };
281
282 ///////////////////////////////////////////////////////////////////////////////
283 } // namespace impl
284
285 ///////////////////////////////////////////////////////////////////////////////
286 } // namespace util
287 } // namespace wave
288 } // namespace boost
289
290 // the suffix header occurs after all of the code
291 #ifdef BOOST_HAS_ABI_HEADERS
292 #include BOOST_ABI_SUFFIX
293 #endif
294
295 #endif // !defined(UNPUT_QUEUE_ITERATOR_HPP_76DA23D0_4893_4AD5_ABCC_6CED7CFB89BC_INCLUDED)