Line data Source code
1 : //
2 : // Copyright (c) 2021 Vinnie Falco (vinnie.falco@gmail.com)
3 : //
4 : // Distributed under the Boost Software License, Version 1.0. (See accompanying
5 : // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
6 : //
7 : // Official repository: https://github.com/cppalliance/http_proto
8 : //
9 :
10 : #ifndef BOOST_HTTP_PROTO_IMPL_FIELDS_VIEW_BASE_HPP
11 : #define BOOST_HTTP_PROTO_IMPL_FIELDS_VIEW_BASE_HPP
12 :
13 : #include <boost/core/detail/string_view.hpp>
14 : #include <boost/assert.hpp>
15 :
16 : namespace boost {
17 : namespace http_proto {
18 :
19 : //------------------------------------------------
20 : //
21 : // iterator
22 : //
23 : //------------------------------------------------
24 :
25 : class fields_view_base::iterator
26 : {
27 : detail::header const* ph_ = nullptr;
28 : std::size_t i_ = 0;
29 :
30 : friend class fields_base;
31 : friend class fields_view_base;
32 :
33 1704 : iterator(
34 : detail::header const* ph,
35 : std::size_t i) noexcept
36 1704 : : ph_(ph)
37 1704 : , i_(i)
38 : {
39 1704 : }
40 :
41 : public:
42 : using value_type =
43 : fields_view_base::value_type;
44 : using reference =
45 : fields_view_base::reference;
46 : using pointer = reference;
47 : using difference_type =
48 : std::ptrdiff_t;
49 : using iterator_category =
50 : std::bidirectional_iterator_tag;
51 :
52 2 : iterator() = default;
53 : iterator(iterator const&) = default;
54 : iterator& operator=(
55 : iterator const&) = default;
56 :
57 : bool
58 1966 : operator==(
59 : iterator const& other) const noexcept
60 : {
61 : // If this assert goes off, it means you
62 : // are trying to compare iterators from
63 : // different containers, which is undefined!
64 1966 : BOOST_ASSERT(ph_ == other.ph_);
65 :
66 1966 : return i_ == other.i_;
67 : }
68 :
69 : bool
70 1797 : operator!=(
71 : iterator const& other) const noexcept
72 : {
73 1797 : return !(*this == other);
74 : }
75 :
76 : BOOST_HTTP_PROTO_DECL
77 : reference
78 : operator*() const noexcept;
79 :
80 : pointer
81 1837 : operator->() const noexcept
82 : {
83 1837 : return *(*this);
84 : }
85 :
86 : iterator&
87 1162 : operator++() noexcept
88 : {
89 1162 : BOOST_ASSERT(i_ < ph_->count);
90 1162 : ++i_;
91 1162 : return *this;
92 : }
93 :
94 : iterator
95 1 : operator++(int) noexcept
96 : {
97 1 : auto temp = *this;
98 1 : ++(*this);
99 1 : return temp;
100 : }
101 :
102 : iterator&
103 133 : operator--() noexcept
104 : {
105 133 : BOOST_ASSERT(i_ > 0);
106 133 : --i_;
107 133 : return *this;
108 : }
109 :
110 : iterator
111 1 : operator--(int) noexcept
112 : {
113 1 : auto temp = *this;
114 1 : --(*this);
115 1 : return temp;
116 : }
117 : };
118 :
119 : //------------------------------------------------
120 :
121 : class fields_view_base::reverse_iterator
122 : {
123 : detail::header const* ph_ = nullptr;
124 : std::size_t i_ = 0;
125 :
126 : friend class fields_base;
127 : friend class fields_view_base;
128 :
129 : reverse_iterator(
130 : detail::header const* ph,
131 : std::size_t i) noexcept
132 : : ph_(ph)
133 : , i_(i)
134 : {
135 : }
136 :
137 : public:
138 : using value_type =
139 : fields_view_base::value_type;
140 : using reference =
141 : fields_view_base::reference;
142 : using pointer = reference;
143 : using difference_type =
144 : std::ptrdiff_t;
145 : using iterator_category =
146 : std::bidirectional_iterator_tag;
147 :
148 2 : reverse_iterator() = default;
149 : reverse_iterator(reverse_iterator const&) = default;
150 : reverse_iterator& operator=(
151 : reverse_iterator const&) = default;
152 :
153 : explicit
154 5 : reverse_iterator(
155 : iterator it) noexcept
156 5 : : ph_(it.ph_)
157 5 : , i_(it.i_)
158 : {
159 5 : }
160 :
161 : bool
162 5 : operator==(
163 : reverse_iterator const& other) const noexcept
164 : {
165 : // If this assert goes off, it means you
166 : // are trying to compare iterators from
167 : // different containers, which is undefined!
168 5 : BOOST_ASSERT(ph_ == other.ph_);
169 :
170 5 : return i_ == other.i_;
171 : }
172 :
173 : bool
174 1 : operator!=(
175 : reverse_iterator const& other) const noexcept
176 : {
177 1 : return !(*this == other);
178 : }
179 :
180 : BOOST_HTTP_PROTO_DECL
181 : reference
182 : operator*() const noexcept;
183 :
184 : pointer
185 24 : operator->() const noexcept
186 : {
187 24 : return *(*this);
188 : }
189 :
190 : reverse_iterator&
191 3 : operator++() noexcept
192 : {
193 3 : BOOST_ASSERT(i_ > 0);
194 3 : --i_;
195 3 : return *this;
196 : }
197 :
198 : reverse_iterator
199 1 : operator++(int) noexcept
200 : {
201 1 : auto temp = *this;
202 1 : ++(*this);
203 1 : return temp;
204 : }
205 :
206 : reverse_iterator&
207 3 : operator--() noexcept
208 : {
209 3 : BOOST_ASSERT(i_ < ph_->count);
210 3 : ++i_;
211 3 : return *this;
212 : }
213 :
214 : reverse_iterator
215 1 : operator--(int) noexcept
216 : {
217 1 : auto temp = *this;
218 1 : --(*this);
219 1 : return temp;
220 : }
221 : };
222 :
223 : //------------------------------------------------
224 : //
225 : // subrange
226 : //
227 : //------------------------------------------------
228 :
229 : class fields_view_base::subrange
230 : {
231 : detail::header const* ph_ = nullptr;
232 : std::size_t i_ = 0;
233 :
234 : friend class fields_view;
235 : friend class fields_view_base;
236 : friend struct detail::header;
237 :
238 138 : subrange(
239 : detail::header const* ph,
240 : std::size_t i) noexcept
241 138 : : ph_(ph)
242 138 : , i_(i)
243 : {
244 138 : }
245 :
246 : public:
247 : class iterator;
248 : //class reverse_iterator;
249 : using const_iterator = iterator;
250 : using value_type = std::string;
251 : using reference = core::string_view;
252 : using const_reference = reference;
253 : using size_type = std::size_t;
254 : using difference_type = std::ptrdiff_t;
255 :
256 : /** Constructor
257 :
258 : Default-constructed subranges are empty.
259 : */
260 : subrange() noexcept = default;
261 :
262 : subrange(subrange const&) noexcept = default;
263 : subrange& operator=(
264 : subrange const&) noexcept = default;
265 :
266 : iterator begin() const noexcept;
267 : iterator end() const noexcept;
268 : };
269 :
270 : //------------------------------------------------
271 : //
272 : // subrange::iterator
273 : //
274 : //------------------------------------------------
275 :
276 : class fields_view_base::subrange::
277 : iterator
278 : {
279 : detail::header const* ph_ = nullptr;
280 : std::size_t i_ = 0;
281 :
282 : friend class fields_view_base::subrange;
283 :
284 : BOOST_HTTP_PROTO_DECL
285 : iterator(
286 : detail::header const* ph,
287 : std::size_t i) noexcept;
288 :
289 : // end
290 : BOOST_HTTP_PROTO_DECL
291 : iterator(
292 : detail::header const* ph) noexcept;
293 :
294 : public:
295 : using value_type = std::string;
296 : using reference = core::string_view;
297 : using pointer = void const*;
298 : using difference_type =
299 : std::ptrdiff_t;
300 : using iterator_category =
301 : std::forward_iterator_tag;
302 :
303 : iterator() = default;
304 : iterator(iterator const&) = default;
305 : iterator& operator=(
306 : iterator const&) = default;
307 :
308 : // conversion to regular iterator
309 : operator
310 : fields_view_base::
311 : iterator() const noexcept
312 : {
313 : return {ph_, i_};
314 : }
315 :
316 : bool
317 303 : operator==(
318 : iterator const& other) const noexcept
319 : {
320 : // If this assert goes off, it means you
321 : // are trying to compare iterators from
322 : // different containers, which is undefined!
323 303 : BOOST_ASSERT(ph_ == other.ph_);
324 :
325 303 : return i_ == other.i_;
326 : }
327 :
328 : bool
329 303 : operator!=(
330 : iterator const& other) const noexcept
331 : {
332 303 : return !(*this == other);
333 : }
334 :
335 : BOOST_HTTP_PROTO_DECL
336 : reference const
337 : operator*() const noexcept;
338 :
339 : reference const
340 : operator->() const noexcept
341 : {
342 : return *(*this);
343 : }
344 :
345 : BOOST_HTTP_PROTO_DECL
346 : iterator&
347 : operator++() noexcept;
348 :
349 : iterator
350 : operator++(int) noexcept
351 : {
352 : auto temp = *this;
353 : ++(*this);
354 : return temp;
355 : }
356 : };
357 :
358 : inline
359 : auto
360 138 : fields_view_base::
361 : subrange::
362 : begin() const noexcept ->
363 : iterator
364 : {
365 138 : return {ph_, i_};
366 : }
367 :
368 : inline
369 : auto
370 138 : fields_view_base::
371 : subrange::
372 : end() const noexcept ->
373 : iterator
374 : {
375 138 : return {ph_};
376 : }
377 :
378 : //------------------------------------------------
379 :
380 : inline
381 : fields_view_base::
382 : value_type::
383 : operator
384 : fields_view_base::
385 : reference() const noexcept
386 : {
387 : return reference{
388 : id, name, value};
389 : }
390 :
391 : //------------------------------------------------
392 :
393 : inline
394 : auto
395 785 : fields_view_base::
396 : begin() const noexcept ->
397 : iterator
398 : {
399 785 : return iterator(ph_, 0);
400 : }
401 :
402 : inline
403 : auto
404 919 : fields_view_base::
405 : end() const noexcept ->
406 : iterator
407 : {
408 919 : return iterator(ph_, ph_->count);
409 : }
410 :
411 : inline
412 : auto
413 3 : fields_view_base::
414 : rbegin() const noexcept ->
415 : reverse_iterator
416 : {
417 3 : return reverse_iterator(end());
418 : }
419 :
420 : inline
421 : auto
422 2 : fields_view_base::
423 : rend() const noexcept ->
424 : reverse_iterator
425 : {
426 2 : return reverse_iterator(begin());
427 : }
428 :
429 : } // http_proto
430 : } // boost
431 :
432 : #endif
|