GCC Code Coverage Report


Directory: libs/http_proto/
File: include/boost/http_proto/fields_base.hpp
Date: 2025-09-21 18:08:15
Exec Total Coverage
Lines: 60 60 100.0%
Functions: 13 13 100.0%
Branches: 29 36 80.6%

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_BASE_HPP
13 #define BOOST_HTTP_PROTO_FIELDS_BASE_HPP
14
15 #include <boost/http_proto/detail/config.hpp>
16 #include <boost/http_proto/detail/except.hpp>
17 #include <boost/http_proto/fields_view_base.hpp>
18 #include <boost/core/detail/string_view.hpp>
19
20 namespace boost {
21 namespace http_proto {
22
23 /** Mixin for modifiable HTTP fields.
24
25 @par Iterators
26
27 Iterators obtained from @ref fields
28 containers are not invalidated when
29 the underlying container is modified.
30
31 @note HTTP field names are case-insensitive.
32 */
33 class fields_base
34 : public virtual fields_view_base
35 {
36 detail::header h_;
37 std::size_t max_cap_ =
38 std::numeric_limits<std::size_t>::max();
39 bool external_storage_ = false;
40
41 using entry =
42 detail::header::entry;
43 using offset_type =
44 detail::header::offset_type;
45 using table =
46 detail::header::table;
47
48 class op_t;
49 class prefix_op_t
50 {
51 fields_base& self_;
52 offset_type new_prefix_;
53 char* buf_ = nullptr;
54
55 public:
56 prefix_op_t(
57 fields_base& self,
58 std::size_t new_prefix,
59 core::string_view* s0 = nullptr,
60 core::string_view* s1 = nullptr);
61
62 ~prefix_op_t();
63 };
64
65 friend class fields;
66 template<std::size_t>
67 friend class static_fields;
68 friend class request_base;
69 friend class request;
70 template<std::size_t>
71 friend class static_request;
72 friend class response_base;
73 friend class response;
74 template<std::size_t>
75 friend class static_response;
76 friend class message_base;
77
78 BOOST_HTTP_PROTO_DECL
79 explicit
80 fields_base(
81 detail::kind k) noexcept;
82
83 BOOST_HTTP_PROTO_DECL
84 fields_base(
85 detail::kind k,
86 char* storage,
87 std::size_t cap) noexcept;
88
89 BOOST_HTTP_PROTO_DECL
90 fields_base(
91 detail::kind k,
92 core::string_view s);
93
94 BOOST_HTTP_PROTO_DECL
95 fields_base(
96 detail::kind k,
97 char* storage,
98 std::size_t cap,
99 core::string_view s);
100
101 BOOST_HTTP_PROTO_DECL
102 explicit
103 fields_base(
104 detail::header const& h);
105
106 BOOST_HTTP_PROTO_DECL
107 fields_base(
108 detail::header const& h,
109 char* storage,
110 std::size_t cap);
111
112 public:
113 /** Destructor.
114 */
115 BOOST_HTTP_PROTO_DECL
116 ~fields_base();
117
118 //--------------------------------------------
119 //
120 // Capacity
121 //
122 //--------------------------------------------
123
124 /** Return the maximum allowed capacity in bytes.
125 */
126 std::size_t
127 24 max_capacity_in_bytes() noexcept
128 {
129 24 return max_cap_;
130 }
131
132 /** Return the total number of bytes allocated by the container.
133 */
134 std::size_t
135 119 capacity_in_bytes() const noexcept
136 {
137 119 return h_.cap;
138 }
139
140 /** Clear contents while preserving the capacity.
141
142 In the case of response and request
143 containers the start-line also resets to
144 default.
145
146 @par Postconditions
147 @code
148 this->size() == 0
149 @endcode
150
151 @par Complexity
152 Constant.
153 */
154 BOOST_HTTP_PROTO_DECL
155 void
156 clear() noexcept;
157
158 /** Adjust the capacity without changing the size.
159
160 This function adjusts the capacity
161 of the container in bytes, without
162 affecting the current contents. Has
163 no effect if `n <= this->capacity_in_bytes()`.
164
165 @par Postconditions
166 @code
167 this->capacity_in_bytes() >= n
168 @endcode
169
170 @par Exception Safety
171 Strong guarantee.
172 Calls to allocate may throw.
173 Exception thrown if max capacity exceeded.
174
175 @throw std::length_error
176 Max capacity would be exceeded.
177
178 @param n The capacity in bytes.
179 */
180 BOOST_HTTP_PROTO_DECL
181 void
182 reserve_bytes(std::size_t n);
183
184 /** Set the maximum allowed capacity in bytes.
185
186 Prevents the container from growing beyond
187 `n` bytes. Exceeding this limit will throw
188 an exception.
189
190 @par Preconditions
191 @code
192 this->capacity_in_bytes() <= n
193 @endcode
194
195 @par Postconditions
196 @code
197 this->max_capacity_in_bytes() == n
198 @endcode
199
200 @par Exception Safety
201 Strong guarantee.
202 Exception thrown on invalid input.
203
204 @throw std::invalid_argument
205 `n < this->capacity_in_bytes()`
206
207 @param n The maximum allowed capacity in bytes.
208 */
209 BOOST_HTTP_PROTO_DECL
210 void
211 set_max_capacity_in_bytes(std::size_t n);
212
213 /** Remove excess capacity.
214
215 @par Exception Safety
216 Strong guarantee.
217 Calls to allocate may throw.
218 */
219 BOOST_HTTP_PROTO_DECL
220 void
221 shrink_to_fit();
222
223 //--------------------------------------------
224 //
225 // Modifiers
226 //
227 //--------------------------------------------
228
229 /** Append a header.
230
231 This function appends a new header.
232 Existing headers with the same name are
233 not changed.
234
235 Any leading or trailing whitespace in the
236 value is ignored.
237
238 No iterators are invalidated.
239
240 @par Example
241 @code
242 request req;
243
244 req.append( field::user_agent, "Boost" );
245 @endcode
246
247 @par Complexity
248 Linear in `to_string( id ).size() + value.size()`.
249
250 @par Exception Safety
251 Strong guarantee.
252 Calls to allocate may throw.
253 Exception thrown on invalid input.
254 Exception thrown if max capacity exceeded.
255
256 @throw system_error
257 Input is invalid.
258
259 @throw std::length_error
260 Max capacity would be exceeded.
261
262 @param id The field name constant.
263
264 @param value The value which must be semantically
265 valid for the message.
266 */
267 void
268 96 append(
269 field id,
270 core::string_view value)
271 {
272 96 system::error_code ec;
273
2/2
✓ Branch 1 taken 91 times.
✓ Branch 2 taken 5 times.
96 append(id, value, ec);
274
2/2
✓ Branch 1 taken 3 times.
✓ Branch 2 taken 88 times.
91 if(ec.failed())
275 3 detail::throw_system_error(ec);
276 88 }
277
278 /** Append a header.
279
280 This function appends a new header.
281 Existing headers with the same name are
282 not changed.
283
284 Any leading or trailing whitespace in the
285 value is ignored.
286
287 No iterators are invalidated.
288
289 @par Example
290 @code
291 request req;
292
293 req.append( field::user_agent, "Boost" );
294 @endcode
295
296 @par Complexity
297 Linear in `to_string( id ).size() + value.size()`.
298
299 @par Exception Safety
300 Strong guarantee.
301 Calls to allocate may throw.
302 Exception thrown if max capacity exceeded.
303
304 @throw std::length_error
305 Max capacity would be exceeded.
306
307 @param id The field name constant.
308
309 @param value The value which must be semantically
310 valid for the message.
311
312 @param ec Set to the error if input is invalid.
313 */
314 void
315 96 append(
316 field id,
317 core::string_view value,
318 system::error_code& ec)
319 {
320
3/4
✓ Branch 1 taken 96 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 91 times.
✓ Branch 5 taken 5 times.
96 insert_impl(
321 id,
322 to_string(id),
323 value,
324 96 h_.count,
325 ec);
326 91 }
327
328 /** Append a header.
329
330 This function appends a new header.
331 Existing headers with the same name are
332 not changed.
333
334 Any leading or trailing whitespace in the
335 value is ignored.
336
337 No iterators are invalidated.
338
339 @par Example
340 @code
341 request req;
342
343 req.append( "User-Agent", "Boost" );
344 @endcode
345
346 @par Complexity
347 Linear in `name.size() + value.size()`.
348
349 @par Exception Safety
350 Strong guarantee.
351 Calls to allocate may throw.
352 Exception thrown on invalid input.
353 Exception thrown if max capacity exceeded.
354
355 @throw system_error
356 Input is invalid.
357
358 @throw std::length_error
359 Max capacity would be exceeded.
360
361 @param name The header name.
362
363 @param value The header value, which must
364 be semantically valid for the message.
365 */
366 void
367 59 append(
368 core::string_view name,
369 core::string_view value)
370 {
371 59 system::error_code ec;
372
2/2
✓ Branch 1 taken 57 times.
✓ Branch 2 taken 2 times.
59 append(name, value, ec);
373
2/2
✓ Branch 1 taken 1 times.
✓ Branch 2 taken 56 times.
57 if(ec.failed())
374 1 detail::throw_system_error(ec);
375 56 }
376
377 /** Append a header.
378
379 This function appends a new header.
380 Existing headers with the same name are
381 not changed.
382
383 Any leading or trailing whitespace in the
384 value is ignored.
385
386 No iterators are invalidated.
387
388 @par Example
389 @code
390 request req;
391
392 req.append( "User-Agent", "Boost" );
393 @endcode
394
395 @par Complexity
396 Linear in `name.size() + value.size()`.
397
398 @par Exception Safety
399 Strong guarantee.
400 Calls to allocate may throw.
401 Exception thrown if max capacity exceeded.
402
403 @throw std::length_error
404 Max capacity would be exceeded.
405
406 @param name The header name.
407
408 @param value The value which must be semantically
409 valid for the message.
410
411 @param ec Set to the error if input is invalid.
412 */
413 void
414 72 append(
415 core::string_view name,
416 core::string_view value,
417 system::error_code& ec)
418 {
419 72 insert_impl(
420 string_to_field(name),
421 name,
422 value,
423 72 h_.count,
424 ec);
425 70 }
426
427 /** Insert a header.
428
429 If a matching header with the same name
430 exists, it is not replaced. Instead, an
431 additional header with the same name is
432 inserted. Names are not case-sensitive.
433 Any leading or trailing whitespace in
434 the new value is ignored.
435
436 All iterators that are equal to `before`
437 or come after are invalidated.
438
439 @par Example
440 @code
441 request req;
442
443 req.insert( req.begin(), field::user_agent, "Boost" );
444 @endcode
445
446 @par Complexity
447 Linear in `to_string( id ).size() + value.size()`.
448
449 @par Exception Safety
450 Strong guarantee.
451 Calls to allocate may throw.
452 Exception thrown on invalid input.
453 Exception thrown if max capacity exceeded.
454
455 @throw system_error
456 Input is invalid.
457
458 @throw std::length_error
459 Max capacity would be exceeded.
460
461 @return An iterator to the newly inserted header.
462
463 @param before Position to insert before.
464
465 @param id The field name constant.
466
467 @param value The value which must be semantically
468 valid for the message.
469 */
470 iterator
471 26 insert(
472 iterator before,
473 field id,
474 core::string_view value)
475 {
476 26 system::error_code ec;
477
1/2
✓ Branch 1 taken 26 times.
✗ Branch 2 not taken.
26 auto const it = insert(
478 before, id, value, ec);
479
2/2
✓ Branch 1 taken 1 times.
✓ Branch 2 taken 25 times.
26 if(ec.failed())
480 1 detail::throw_system_error(ec);
481 25 return it;
482 }
483
484 /** Insert a header.
485
486 If a matching header with the same name
487 exists, it is not replaced. Instead, an
488 additional header with the same name is
489 inserted. Names are not case-sensitive.
490
491 Any leading or trailing whitespace in
492 the new value is ignored.
493
494 All iterators that are equal to `before`
495 or come after are invalidated.
496
497 @par Example
498 @code
499 request req;
500
501 req.insert( req.begin(), field::user_agent, "Boost" );
502 @endcode
503
504 @par Complexity
505 Linear in `to_string( id ).size() + value.size()`.
506
507 @par Exception Safety
508 Strong guarantee.
509 Calls to allocate may throw.
510 Exception thrown if max capacity exceeded.
511
512 @throw std::length_error
513 Max capacity would be exceeded.
514
515 @return An iterator to the newly inserted header.
516
517 @param before Position to insert before.
518
519 @param id The field name constant.
520
521 @param value The value which must be semantically
522 valid for the message.
523
524 @param ec Set to the error if input is invalid.
525 */
526 iterator
527 33 insert(
528 iterator before,
529 field id,
530 core::string_view value,
531 system::error_code& ec)
532 {
533
2/4
✓ Branch 2 taken 33 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 33 times.
✗ Branch 6 not taken.
33 insert_impl(
534 id,
535 to_string(id),
536 value,
537 before.i_,
538 ec);
539 33 return before;
540 }
541
542 /** Insert a header.
543
544 If a matching header with the same name
545 exists, it is not replaced. Instead, an
546 additional header with the same name is
547 inserted. Names are not case-sensitive.
548
549 Any leading or trailing whitespace in
550 the new value is ignored.
551
552 All iterators that are equal to `before`
553 or come after are invalidated.
554
555 @par Example
556 @code
557 request req;
558
559 req.insert( req.begin(), "User-Agent", "Boost" );
560 @endcode
561
562 @par Complexity
563 Linear in `name.size() + value.size()`.
564
565 @par Exception Safety
566 Strong guarantee.
567 Calls to allocate may throw.
568 Exception thrown on invalid input.
569 Exception thrown if max capacity exceeded.
570
571 @throw system_error
572 Input is invalid.
573
574 @throw std::length_error
575 Max capacity would be exceeded.
576
577 @return An iterator to the newly inserted header.
578
579 @param before Position to insert before.
580
581 @param name The header name.
582
583 @param value The value which must be semantically
584 valid for the message.
585 */
586 iterator
587 13 insert(
588 iterator before,
589 core::string_view name,
590 core::string_view value)
591 {
592 13 system::error_code ec;
593
1/2
✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
13 insert(before, name, value, ec);
594
2/2
✓ Branch 1 taken 1 times.
✓ Branch 2 taken 12 times.
13 if(ec.failed())
595 1 detail::throw_system_error(ec);
596 12 return before;
597 }
598
599 /** Insert a header.
600
601 If a matching header with the same name
602 exists, it is not replaced. Instead, an
603 additional header with the same name is
604 inserted. Names are not case-sensitive.
605
606 Any leading or trailing whitespace in
607 the new value is ignored.
608
609 All iterators that are equal to `before`
610 or come after are invalidated.
611
612 @par Example
613 @code
614 request req;
615
616 req.insert( req.begin(), "User-Agent", "Boost" );
617 @endcode
618
619 @par Complexity
620 Linear in `name.size() + value.size()`.
621
622 @par Exception Safety
623 Strong guarantee.
624 Calls to allocate may throw.
625 Exception thrown if max capacity exceeded.
626
627 @throw std::length_error
628 Max capacity would be exceeded.
629
630 @return An iterator to the newly inserted header.
631
632 @param before Position to insert before.
633
634 @param name The header name.
635
636 @param value The value which must be semantically
637 valid for the message.
638
639 @param ec Set to the error if input is invalid.
640 */
641 iterator
642 16 insert(
643 iterator before,
644 core::string_view name,
645 core::string_view value,
646 system::error_code& ec)
647 {
648 16 insert_impl(
649 string_to_field(name),
650 name,
651 value,
652 before.i_,
653 ec);
654 16 return before;
655 }
656
657 //--------------------------------------------
658
659 /** Erase headers.
660
661 This function removes the header pointed
662 to by `it`.
663
664 All iterators that are equal to `it`
665 or come after are invalidated.
666
667 @par Complexity
668 Linear in `name.size() + value.size()`.
669
670 @return An iterator to one past the
671 removed element.
672
673 @param it The iterator to the element
674 to erase.
675 */
676 BOOST_HTTP_PROTO_DECL
677 iterator
678 erase(iterator it) noexcept;
679
680 /** Erase headers.
681
682 This removes all headers whose name
683 constant is equal to `id`.
684
685 If any headers are erased, then all
686 iterators equal to or that come after
687 the first erased element are invalidated.
688 Otherwise, no iterators are invalidated.
689
690 @par Complexity
691 Linear in `this->string().size()`.
692
693 @return The number of headers erased.
694
695 @param id The field name constant.
696 */
697 BOOST_HTTP_PROTO_DECL
698 std::size_t
699 erase(field id) noexcept;
700
701 /** Erase all matching fields.
702
703 This removes all headers with a matching
704 name, using a case-insensitive comparison.
705
706 If any headers are erased, then all
707 iterators equal to or that come after
708 the first erased element are invalidated.
709 Otherwise, no iterators are invalidated.
710
711 @par Complexity
712 Linear in `this->string().size()`.
713
714 @return The number of fields erased
715
716 @param name The header name.
717 */
718 BOOST_HTTP_PROTO_DECL
719 std::size_t
720 erase(
721 core::string_view name) noexcept;
722
723 //--------------------------------------------
724
725 /** Set a header value.
726
727 Uses the given value to overwrite the
728 current one in the header field pointed to
729 by the iterator. The value must be
730 syntactically valid or else an error is
731 returned.
732
733 Any leading or trailing whitespace in the
734 new value is ignored.
735
736 @par Complexity
737
738 @par Exception Safety
739 Strong guarantee.
740 Calls to allocate may throw.
741 Exception thrown on invalid input.
742 Exception thrown if max capacity exceeded.
743
744 @throw system_error
745 Input is invalid.
746
747 @throw std::length_error
748 Max capacity would be exceeded.
749
750 @param it The iterator to the header.
751
752 @param value The value which must be semantically
753 valid for the message.
754 */
755 void
756 27 set(
757 iterator it,
758 core::string_view value)
759 {
760 27 system::error_code ec;
761
1/2
✓ Branch 1 taken 27 times.
✗ Branch 2 not taken.
27 set(it, value, ec);
762
2/2
✓ Branch 1 taken 2 times.
✓ Branch 2 taken 25 times.
27 if(ec.failed())
763 2 detail::throw_system_error(ec);
764 25 }
765
766 /** Set a header value.
767
768 Uses the given value to overwrite the
769 current one in the header field pointed to
770 by the iterator. The value must be
771 syntactically valid or else an error is
772 returned.
773
774 Any leading or trailing whitespace in the
775 new value is ignored.
776
777 @par Complexity
778
779 @par Exception Safety
780 Strong guarantee.
781 Calls to allocate may throw.
782 Exception thrown if max capacity exceeded.
783
784 @throw std::length_error
785 Max capacity would be exceeded.
786
787 @param it The iterator to the header.
788
789 @param value The value which must be semantically
790 valid for the message.
791
792 @param ec Set to the error if input is invalid.
793 */
794 BOOST_HTTP_PROTO_DECL
795 void
796 set(
797 iterator it,
798 core::string_view value,
799 system::error_code& ec);
800
801 /** Set a header value.
802
803 The container is modified to contain
804 exactly one field with the specified id
805 set to the given value, which must be
806 syntactically valid or else an error is
807 returned.
808
809 Any leading or trailing whitespace in the
810 new value is ignored.
811
812 @par Postconditions
813 @code
814 this->count( id ) == 1 && this->at( id ) == value
815 @endcode
816
817 @par Complexity
818
819 @par Exception Safety
820 Strong guarantee.
821 Calls to allocate may throw.
822 Exception thrown on invalid input.
823 Exception thrown if max capacity exceeded.
824
825 @throw system_error
826 Input is invalid.
827
828 @throw std::length_error
829 Max capacity would be exceeded.
830
831 @param id The field constant of the header
832 to set.
833
834 @param value The value which must be semantically
835 valid for the message.
836 */
837 void
838 104 set(
839 field id,
840 core::string_view value)
841 {
842 104 system::error_code ec;
843
1/2
✓ Branch 1 taken 104 times.
✗ Branch 2 not taken.
104 set(id, value, ec);
844
2/2
✓ Branch 1 taken 2 times.
✓ Branch 2 taken 102 times.
104 if(ec.failed())
845 2 detail::throw_system_error(ec);
846 102 }
847
848 /** Set a header value.
849
850 The container is modified to contain
851 exactly one field with the specified id
852 set to the given value, which must be
853 syntactically valid or else an error is
854 returned.
855
856 Any leading or trailing whitespace in the
857 new value is ignored.
858
859 @par Postconditions
860 @code
861 this->count( id ) == 1 && this->at( id ) == value
862 @endcode
863
864 @par Complexity
865
866 @par Exception Safety
867 Strong guarantee.
868 Calls to allocate may throw.
869 Exception thrown if max capacity exceeded.
870
871 @throw std::length_error
872 Max capacity would be exceeded.
873
874 @param id The field name constant.
875
876 @param value The value which must be semantically
877 valid for the message.
878
879 @param ec Set to the error if input is invalid.
880 */
881 BOOST_HTTP_PROTO_DECL
882 void
883 set(
884 field id,
885 core::string_view value,
886 system::error_code& ec);
887
888 /** Set a header value.
889
890 The container is modified to contain
891 exactly one field with the specified name
892 set to the given value, which must be
893 syntactically valid or else an error is
894 returned.
895
896 Any leading or trailing whitespace in the
897 new value is ignored.
898
899 @par Postconditions
900 @code
901 this->count( name ) == 1 && this->at( name ) == value
902 @endcode
903
904 @par Complexity
905
906 @par Exception Safety
907 Strong guarantee.
908 Calls to allocate may throw.
909 Exception thrown on invalid input.
910 Exception thrown if max capacity exceeded.
911
912 @throw system_error
913 Input is invalid.
914
915 @throw std::length_error
916 Max capacity would be exceeded.
917
918 @param name The field name.
919
920 @param value The value which must be semantically
921 valid for the message.
922 */
923 void
924 29 set(
925 core::string_view name,
926 core::string_view value)
927 {
928 29 system::error_code ec;
929
2/2
✓ Branch 1 taken 28 times.
✓ Branch 2 taken 1 times.
29 set(name, value, ec);
930
2/2
✓ Branch 1 taken 4 times.
✓ Branch 2 taken 24 times.
28 if(ec.failed())
931 4 detail::throw_system_error(ec);
932 24 }
933
934 /** Set a header value.
935
936 The container is modified to contain
937 exactly one field with the specified name
938 set to the given value, which must be
939 syntactically valid or else an error is
940 returned.
941
942 Any leading or trailing whitespace in the
943 new value is ignored.
944
945 @par Postconditions
946 @code
947 this->count( name ) == 1 && this->at( name ) == value
948 @endcode
949
950 @par Complexity
951
952 @par Exception Safety
953 Strong guarantee.
954 Calls to allocate may throw.
955 Exception thrown if max capacity exceeded.
956
957 @throw std::length_error
958 Max capacity would be exceeded.
959
960 @param name The field name.
961
962 @param value The value which must be semantically
963 valid for the message.
964
965 @param ec Set to the error if input is invalid.
966 */
967 BOOST_HTTP_PROTO_DECL
968 void
969 set(
970 core::string_view name,
971 core::string_view value,
972 system::error_code& ec);
973
974 private:
975 BOOST_HTTP_PROTO_DECL
976 void
977 copy_impl(
978 detail::header const&);
979
980 BOOST_HTTP_PROTO_DECL
981 void
982 insert_impl(
983 optional<field> id,
984 core::string_view name,
985 core::string_view value,
986 std::size_t before,
987 system::error_code& ec);
988
989 void
990 insert_unchecked(
991 optional<field> id,
992 core::string_view name,
993 core::string_view value,
994 std::size_t before,
995 bool has_obs_fold);
996
997 void
998 raw_erase(
999 std::size_t) noexcept;
1000
1001 void
1002 raw_erase_n(field, std::size_t) noexcept;
1003
1004 std::size_t
1005 erase_all(
1006 std::size_t i0,
1007 field id) noexcept;
1008
1009 std::size_t
1010 erase_all(
1011 std::size_t i0,
1012 core::string_view name) noexcept;
1013
1014 std::size_t
1015 offset(
1016 std::size_t i) const noexcept;
1017
1018 std::size_t
1019 length(
1020 std::size_t i) const noexcept;
1021 };
1022
1023 } // http_proto
1024 } // boost
1025
1026 #endif
1027