GCC Code Coverage Report


Directory: libs/http_proto/
File: boost/http_proto/impl/fields_view_base.hpp
Date: 2024-07-08 21:32:35
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_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
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1966 times.
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
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 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
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 303 times.
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
433