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