GCC Code Coverage Report


Directory: libs/http_proto/
File: include/boost/http_proto/impl/fields_base.hpp
Date: 2025-10-12 23:51:57
Exec Total Coverage
Lines: 77 77 100.0%
Functions: 27 27 100.0%
Branches: 7 14 50.0%

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