GCC Code Coverage Report


Directory: libs/http_proto/
File: include/boost/http_proto/fields.hpp
Date: 2025-09-21 18:08:15
Exec Total Coverage
Lines: 12 12 100.0%
Functions: 4 4 100.0%
Branches: 0 0 -%

Line Branch Exec Source
1 //
2 // Copyright (c) 2021 Vinnie Falco (vinnie.falco@gmail.com)
3 // Copyright (c) 2024 Christian Mazakas
4 // Copyright (c) 2025 Mohammad Nejati
5 //
6 // Distributed under the Boost Software License, Version 1.0. (See accompanying
7 // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
8 //
9 // Official repository: https://github.com/cppalliance/http_proto
10 //
11
12 #ifndef BOOST_HTTP_PROTO_FIELDS_HPP
13 #define BOOST_HTTP_PROTO_FIELDS_HPP
14
15 #include <boost/http_proto/detail/config.hpp>
16 #include <boost/http_proto/fields_base.hpp>
17 #include <boost/http_proto/fields_view.hpp>
18 #include <boost/core/detail/string_view.hpp>
19
20 namespace boost {
21 namespace http_proto {
22
23 /** A modifiable container of HTTP fields.
24
25 This container owns a collection of HTTP
26 fields, represented by a buffer which is
27 managed by performing dynamic memory
28 allocations as needed. The contents may be
29 inspected and modified, and the implementation
30 maintains a useful invariant: changes to the
31 fields always leave it in a valid state.
32
33 @par Example
34 @code
35 fields fs;
36
37 fs.set(field::host, "example.com");
38 fs.set(field::accept_encoding, "gzip, deflate, br");
39 fs.set(field::cache_control, "no-cache");
40
41 assert(fs.buffer() ==
42 "Host: example.com\r\n"
43 "Accept-Encoding: gzip, deflate, br\r\n"
44 "Cache-Control: no-cache\r\n"
45 "\r\n");
46 @endcode
47
48 @see
49 @ref static_fields,
50 @ref fields_view.
51 */
52 class fields final
53 : public fields_base
54 {
55 public:
56
57 //--------------------------------------------
58 //
59 // Special Members
60 //
61 //--------------------------------------------
62
63 /** Constructor.
64
65 A default-constructed fields container
66 contain no name-value pairs.
67
68 @par Example
69 @code
70 fields fs;
71 @endcode
72
73 @par Postconditions
74 @code
75 this->buffer() == "\r\n"
76 @endcode
77
78 @par Complexity
79 Constant.
80 */
81 BOOST_HTTP_PROTO_DECL
82 fields() noexcept;
83
84 /** Constructor.
85
86 Constructs a fields container from the string
87 `s`, which must contain valid HTTP headers or
88 else an exception is thrown.
89 The new fields container retains ownership by
90 allocating a copy of the passed string.
91
92 @par Example
93 @code
94 fields f(
95 "Server: Boost.HttpProto\r\n"
96 "Content-Type: text/plain\r\n"
97 "Connection: close\r\n"
98 "Content-Length: 73\r\n"
99 "\r\n");
100 @endcode
101
102 @par Postconditions
103 @code
104 this->buffer() == s && this->buffer().data() != s.data()
105 @endcode
106
107 @par Complexity
108 Linear in `s.size()`.
109
110 @par Exception Safety
111 Calls to allocate may throw.
112 Exception thrown on invalid input.
113
114 @throw system_error
115 Input is invalid.
116
117 @param s The string to parse.
118 */
119 BOOST_HTTP_PROTO_DECL
120 explicit
121 fields(
122 core::string_view s);
123
124 /** Constructor.
125
126 Allocates `cap` bytes initially, with an
127 upper limit of `max_cap`. Growing beyond
128 `max_cap` will throw an exception.
129
130 Useful when an estimated initial size is
131 known, but further growth up to a
132 maximum is allowed.
133
134 @par Preconditions
135 @code
136 max_cap >= cap
137 @endcode
138
139 @par Exception Safety
140 Calls to allocate may throw.
141 Exception thrown on invalid input.
142
143 @throw system_error
144 Input is invalid.
145
146 @param cap Initial capacity in bytes (may be `0`).
147
148 @param max_cap Maximum allowed capacity in bytes.
149 */
150 BOOST_HTTP_PROTO_DECL
151 explicit
152 fields(
153 std::size_t cap,
154 std::size_t max_cap = std::size_t(-1));
155
156 /** Constructor.
157
158 The contents of `f` are transferred
159 to the newly constructed object,
160 which includes the underlying
161 character buffer.
162 After construction, the moved-from
163 object is as if default-constructed.
164
165 @par Postconditions
166 @code
167 f.buffer() == "\r\n"
168 @endcode
169
170 @par Complexity
171 Constant.
172
173 @param f The fields to move from.
174 */
175 BOOST_HTTP_PROTO_DECL
176 fields(fields&& f) noexcept;
177
178 /** Constructor.
179
180 The newly constructed object contains
181 a copy of `f`.
182
183 @par Postconditions
184 @code
185 this->buffer() == f.buffer() && this->buffer().data() != f.buffer().data()
186 @endcode
187
188 @par Complexity
189 Linear in `f.size()`.
190
191 @par Exception Safety
192 Calls to allocate may throw.
193
194 @param f The fields to copy.
195 */
196 BOOST_HTTP_PROTO_DECL
197 fields(fields const& f);
198
199 /** Constructor.
200
201 The newly constructed object contains
202 a copy of `f`.
203
204 @par Postconditions
205 @code
206 this->buffer() == f.buffer() && this->buffer().data() != f.buffer().data()
207 @endcode
208
209 @par Complexity
210 Linear in `f.size()`.
211
212 @par Exception Safety
213 Strong guarantee.
214 Calls to allocate may throw.
215
216 @param f The fields to copy.
217 */
218 BOOST_HTTP_PROTO_DECL
219 fields(fields_view const& f);
220
221 /** Assignment.
222
223 The contents of `f` are transferred to
224 `this`, including the underlying
225 character buffer. The previous contents
226 of `this` are destroyed.
227 After assignment, the moved-from
228 object is as if default-constructed.
229
230 @par Postconditions
231 @code
232 f.buffer() == "\r\n"
233 @endcode
234
235 @par Complexity
236 Constant.
237
238 @param f The fields to assign from.
239
240 @return A reference to this object.
241 */
242 BOOST_HTTP_PROTO_DECL
243 fields&
244 operator=(fields&& f) noexcept;
245
246 /** Assignment.
247
248 The contents of `f` are copied and
249 the previous contents of `this` are
250 discarded.
251
252 @par Postconditions
253 @code
254 this->buffer() == f.buffer() && this->buffer().data() != f.buffer().data()
255 @endcode
256
257 @par Complexity
258 Linear in `f.size()`.
259
260 @par Exception Safety
261 Strong guarantee.
262 Calls to allocate may throw.
263 Exception thrown if max capacity exceeded.
264
265 @throw std::length_error
266 Max capacity would be exceeded.
267
268 @return A reference to this object.
269
270 @param f The fields to copy.
271 */
272 fields&
273 4 operator=(fields const& f) noexcept
274 {
275 4 copy_impl(*f.ph_);
276 4 return *this;
277 }
278
279 /** Assignment.
280
281 The contents of `f` are copied and
282 the previous contents of `this` are
283 discarded.
284
285 @par Postconditions
286 @code
287 this->buffer() == f.buffer() && this->buffer().data() != f.buffer().data()
288 @endcode
289
290 @par Complexity
291 Linear in `r.size()`.
292
293 @par Exception Safety
294 Strong guarantee.
295 Calls to allocate may throw.
296 Exception thrown if max capacity exceeded.
297
298 @throw std::length_error
299 Max capacity would be exceeded.
300
301 @return A reference to this object.
302
303 @param f The fields to copy.
304 */
305 fields&
306 4 operator=(fields_view const& f)
307 {
308 4 copy_impl(*f.ph_);
309 4 return *this;
310 }
311
312 /** Conversion.
313
314 @see
315 @ref fields_view.
316
317 @return A view of the fields.
318 */
319 4 operator fields_view() const noexcept
320 {
321 4 return fields_view(ph_);
322 }
323
324 //--------------------------------------------
325
326 /** Swap.
327
328 Exchanges the contents of this fields
329 object with another. All views, iterators
330 and references remain valid.
331
332 If `this == &other`, this function call has no effect.
333
334 @par Example
335 @code
336 fields f1;
337 f1.set(field::accept, "text/html");
338 fields f2;
339 f2.set(field::connection, "keep-alive");
340 f1.swap(f2);
341 assert(f1.buffer() == "Connection: keep-alive\r\n\r\n" );
342 assert(f2.buffer() == "Accept: text/html\r\n\r\n" );
343 @endcode
344
345 @par Complexity
346 Constant.
347
348 @param other The object to swap with.
349 */
350 void
351 10 swap(fields& other) noexcept
352 {
353 10 h_.swap(other.h_);
354 10 std::swap(max_cap_, other.max_cap_);
355 10 }
356
357 /** Swap.
358
359 Exchanges the contents of `v0` with
360 another `v1`. All views, iterators and
361 references remain valid.
362
363 If `&v0 == &v1`, this function call has no effect.
364
365 @par Example
366 @code
367 fields f1;
368 f1.set(field::accept, "text/html");
369 fields f2;
370 f2.set(field::connection, "keep-alive");
371 std::swap(f1, f2);
372 assert(f1.buffer() == "Connection: keep-alive\r\n\r\n" );
373 assert(f2.buffer() == "Accept: text/html\r\n\r\n" );
374 @endcode
375
376 @par Effects
377 @code
378 v0.swap(v1);
379 @endcode
380
381 @par Complexity
382 Constant.
383
384 @param v0 The first object to swap.
385 @param v1 The second object to swap.
386
387 @see
388 @ref fields::swap.
389 */
390 friend
391 void
392 swap(
393 fields& v0,
394 fields& v1) noexcept
395 {
396 v0.swap(v1);
397 }
398 };
399
400 } // http_proto
401 } // boost
402
403 #endif
404