Line | Branch | Exec | Source |
---|---|---|---|
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 | 1632 | iterator( | |
34 | detail::header const* ph, | ||
35 | std::size_t i) noexcept | ||
36 | 1632 | : ph_(ph) | |
37 | 1632 | , i_(i) | |
38 | { | ||
39 | 1632 | } | |
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 | 1930 | 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 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 1930 times.
|
1930 | BOOST_ASSERT(ph_ == other.ph_); |
65 | |||
66 | 1930 | return i_ == other.i_; | |
67 | } | ||
68 | |||
69 | bool | ||
70 | 1761 | operator!=( | |
71 | iterator const& other) const noexcept | ||
72 | { | ||
73 | 1761 | return !(*this == other); | |
74 | } | ||
75 | |||
76 | BOOST_HTTP_PROTO_DECL | ||
77 | reference | ||
78 | operator*() const noexcept; | ||
79 | |||
80 | pointer | ||
81 | 1801 | operator->() const noexcept | |
82 | { | ||
83 | 1801 | return *(*this); | |
84 | } | ||
85 | |||
86 | iterator& | ||
87 | 1162 | operator++() noexcept | |
88 | { | ||
89 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 1162 times.
|
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 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 133 times.
|
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 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 5 times.
|
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 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 3 times.
|
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 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 3 times.
|
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 | 66 | subrange( | |
239 | detail::header const* ph, | ||
240 | std::size_t i) noexcept | ||
241 | 66 | : ph_(ph) | |
242 | 66 | , i_(i) | |
243 | { | ||
244 | 66 | } | |
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 | 145 | 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 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 145 times.
|
145 | BOOST_ASSERT(ph_ == other.ph_); |
324 | |||
325 | 145 | return i_ == other.i_; | |
326 | } | ||
327 | |||
328 | bool | ||
329 | 145 | operator!=( | |
330 | iterator const& other) const noexcept | ||
331 | { | ||
332 | 145 | 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 | 66 | fields_view_base:: | |
361 | subrange:: | ||
362 | begin() const noexcept -> | ||
363 | iterator | ||
364 | { | ||
365 | 66 | return {ph_, i_}; | |
366 | } | ||
367 | |||
368 | inline | ||
369 | auto | ||
370 | 66 | fields_view_base:: | |
371 | subrange:: | ||
372 | end() const noexcept -> | ||
373 | iterator | ||
374 | { | ||
375 | 66 | 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 | 749 | fields_view_base:: | |
396 | begin() const noexcept -> | ||
397 | iterator | ||
398 | { | ||
399 | 749 | return iterator(ph_, 0); | |
400 | } | ||
401 | |||
402 | inline | ||
403 | auto | ||
404 | 883 | fields_view_base:: | |
405 | end() const noexcept -> | ||
406 | iterator | ||
407 | { | ||
408 | 883 | 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 | ||
433 |