GCC Code Coverage Report


Directory: libs/http_proto/include/boost/http_proto/
File: boost/http_proto/impl/fields_view_base.hpp
Date: 2023-02-02 18:17:22
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 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