GCC Code Coverage Report


Directory: libs/url/
File: include/boost/url/params_encoded_ref.hpp
Date: 2025-11-10 19:06:22
Exec Total Coverage
Lines: 2 2 100.0%
Functions: 1 1 100.0%
Branches: 0 0 -%

Line Branch Exec Source
1 //
2 // Copyright (c) 2019 Vinnie Falco (vinnie.falco@gmail.com)
3 // Copyright (c) 2022 Alan de Freitas (alandefreitas@gmail.com)
4 //
5 // Distributed under the Boost Software License, Version 1.0. (See accompanying
6 // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
7 //
8 // Official repository: https://github.com/boostorg/url
9 //
10
11 #ifndef BOOST_URL_PARAMS_ENCODED_REF_HPP
12 #define BOOST_URL_PARAMS_ENCODED_REF_HPP
13
14 #include <boost/url/detail/config.hpp>
15 #include <boost/url/ignore_case.hpp>
16 #include <boost/url/params_encoded_view.hpp>
17 #include <initializer_list>
18
19 namespace boost {
20 namespace urls {
21
22 #ifndef BOOST_URL_DOCS
23 class url_base;
24 class params_encoded_view;
25 #endif
26
27 /** A view representing query parameters in a URL
28
29 Objects of this type are used to interpret
30 the query parameters as a bidirectional view
31 of key value pairs.
32
33 The view does not retain ownership of the
34 elements and instead references the original
35 url. The caller is responsible for ensuring
36 that the lifetime of the referenced url
37 extends until it is no longer referenced.
38
39 The view is modifiable; calling non-const
40 members causes changes to the referenced
41 url.
42
43 @par Example
44 @code
45 url u( "?first=John&last=Doe" );
46
47 params_encoded_ref p = u.encoded_params();
48 @endcode
49
50 Strings produced when elements are returned
51 have type @ref param_pct_view and represent
52 encoded strings. Strings passed to member
53 functions may contain percent escapes, and
54 throw exceptions on invalid inputs.
55
56 @par Iterator Invalidation
57 Changes to the underlying character buffer
58 can invalidate iterators which reference it.
59 Modifications made through the container
60 invalidate some iterators to the underlying
61 character buffer:
62 @li @ref append : Only `end()`.
63 @li @ref assign, @ref clear,
64 `operator=` : All params.
65 @li @ref erase : Erased params and all
66 params after (including `end()`).
67 @li @ref insert : All params at or after
68 the insertion point (including `end()`).
69 @li @ref replace, @ref set : Modified
70 params and all params
71 after (including `end()`).
72 */
73 class BOOST_URL_DECL params_encoded_ref
74 : public params_encoded_base
75 {
76 friend class url_base;
77
78 url_base* u_ = nullptr;
79
80 params_encoded_ref(
81 url_base& u) noexcept;
82
83 public:
84 //--------------------------------------------
85 //
86 // Special Members
87 //
88 //--------------------------------------------
89
90 /** Constructor
91
92 After construction, both views
93 reference the same url. Ownership is not
94 transferred; the caller is responsible
95 for ensuring the lifetime of the url
96 extends until it is no longer
97 referenced.
98
99 @par Postconditions
100 @code
101 &this->url() == &other.url();
102 @endcode
103
104 @par Complexity
105 Constant.
106
107 @par Exception Safety
108 Throws nothing.
109
110 @param other The other view.
111 */
112 params_encoded_ref(
113 params_encoded_ref const& other) = default;
114
115 /** Assignment
116
117 The previous contents of this are
118 replaced by the contents of `other.
119
120 <br>
121 All iterators are invalidated.
122
123 @note
124 The strings referenced by `other`
125 must not come from the underlying url,
126 or else the behavior is undefined.
127
128 @par Effects
129 @code
130 this->assign( other.begin(), other.end() );
131 @endcode
132
133 @par Complexity
134 Linear in `other.buffer().size()`.
135
136 @par Exception Safety
137 Strong guarantee.
138 Calls to allocate may throw.
139
140 @param other The params to assign.
141 @return `*this`
142 */
143 params_encoded_ref&
144 operator=(
145 params_encoded_ref const& other);
146
147 /** Assignment
148
149 After assignment, the previous contents
150 of the query parameters are replaced by
151 the contents of the initializer-list.
152
153 <br>
154 All iterators are invalidated.
155
156 @par Preconditions
157 None of character buffers referenced by
158 `init` may overlap the character buffer of
159 the underlying url, or else the behavior
160 is undefined.
161
162 @par Effects
163 @code
164 this->assign( init.begin(), init.end() );
165 @endcode
166
167 @par Complexity
168 Linear in `init.size()`.
169
170 @par Exception Safety
171 Strong guarantee.
172 Calls to allocate may throw.
173 Exceptions thrown on invalid input.
174
175 @throw system_error
176 `init` contains an invalid percent-encoding.
177
178 @param init The list of params to assign.
179 @return `*this`
180 */
181 params_encoded_ref&
182 operator=(std::initializer_list<
183 param_pct_view> init);
184
185 /** Conversion
186
187 @par Complexity
188 Constant.
189
190 @par Exception Safety
191 Throws nothing.
192
193 @return A view of the params.
194 */
195 operator
196 params_encoded_view() const noexcept;
197
198 //--------------------------------------------
199 //
200 // Observers
201 //
202 //--------------------------------------------
203
204 /** Return the referenced url
205
206 This function returns the url referenced
207 by the view.
208
209 @par Example
210 @code
211 url u( "?key=value" );
212
213 assert( &u.encoded_params().url() == &u );
214 @endcode
215
216 @par Exception Safety
217 @code
218 Throws nothing.
219 @endcode
220
221 @return A reference to the url.
222 */
223 url_base&
224 7 url() const noexcept
225 {
226 7 return *u_;
227 }
228
229 //--------------------------------------------
230 //
231 // Modifiers
232 //
233 //--------------------------------------------
234
235 /** Clear the contents of the container
236
237 <br>
238 All iterators are invalidated.
239
240 @par Effects
241 @code
242 this->url().remove_query();
243 @endcode
244
245 @par Postconditions
246 @code
247 this->empty() == true && this->url().has_query() == false
248 @endcode
249
250 @par Complexity
251 Constant.
252
253 @par Exception Safety
254 Throws nothing.
255 */
256 void
257 clear() noexcept;
258
259 //--------------------------------------------
260
261 /** Assign params
262
263 This function replaces the entire
264 contents of the view with the params
265 in the <em>initializer-list</em>.
266
267 <br>
268 All iterators are invalidated.
269
270 @note
271 The strings referenced by the inputs
272 must not come from the underlying url,
273 or else the behavior is undefined.
274
275 @par Example
276 @code
277 url u;
278
279 u.encoded_params().assign({ { "first", "John" }, { "last", "Doe" } });
280 @endcode
281
282 @par Complexity
283 Linear in `init.size()`.
284
285 @par Exception Safety
286 Strong guarantee.
287 Calls to allocate may throw.
288 Exceptions thrown on invalid input.
289
290 @throw system_error
291 `init` contains an invalid percent-encoding.
292
293 @param init The list of params to assign.
294 */
295 void
296 assign(
297 std::initializer_list<
298 param_pct_view> init);
299
300 /** Assign params
301
302 This function replaces the entire
303 contents of the view with the params
304 in the range.
305
306 <br>
307 All iterators are invalidated.
308
309 @note
310 The strings referenced by the inputs
311 must not come from the underlying url,
312 or else the behavior is undefined.
313
314 @par Mandates
315 @code
316 std::is_convertible< std::iterator_traits< FwdIt >::reference_type, param_pct_view >::value == true
317 @endcode
318
319 @par Complexity
320 Linear in the size of the range.
321
322 @par Exception Safety
323 Strong guarantee.
324 Calls to allocate may throw.
325 Exceptions thrown on invalid input.
326
327 @throw system_error
328 The range contains an invalid percent-encoding.
329
330 @param first The first element to assign.
331 @param last One past the last element to assign.
332 */
333 template<class FwdIt>
334 void
335 assign(FwdIt first, FwdIt last);
336
337 //--------------------------------------------
338
339 /** Append params
340
341 This function appends a param to the view.
342
343 <br>
344 The `end()` iterator is invalidated.
345
346 @par Example
347 @code
348 url u;
349
350 u.encoded_params().append( { "first", "John" } );
351 @endcode
352
353 @par Complexity
354 Linear in `this->url().encoded_query().size()`.
355
356 @par Exception Safety
357 Strong guarantee.
358 Calls to allocate may throw.
359 Exceptions thrown on invalid input.
360
361 @throw system_error
362 `p` contains an invalid percent-encoding.
363
364 @return An iterator to the new element.
365
366 @param p The param to append.
367 */
368 iterator
369 append(
370 param_pct_view const& p);
371
372 /** Append params
373
374 This function appends the params in
375 an <em>initializer-list</em> to the view.
376
377 <br>
378 The `end()` iterator is invalidated.
379
380 @par Example
381 @code
382 url u;
383
384 u.encoded_params().append({ {"first", "John"}, {"last", "Doe"} });
385 @endcode
386
387 @par Complexity
388 Linear in `this->url().encoded_query().size()`.
389
390 @par Exception Safety
391 Strong guarantee.
392 Calls to allocate may throw.
393 Exceptions thrown on invalid input.
394
395 @throw system_error
396 `init` contains an invalid percent-encoding.
397
398 @return An iterator to the first new element.
399
400 @param init The list of params to append.
401 */
402 iterator
403 append(
404 std::initializer_list<
405 param_pct_view> init);
406
407 /** Append params
408
409 This function appends a range of params
410 to the view.
411
412 <br>
413 The `end()` iterator is invalidated.
414
415 @note
416 The strings referenced by the inputs
417 must not come from the underlying url,
418 or else the behavior is undefined.
419
420 @par Mandates
421 @code
422 std::is_convertible< std::iterator_traits< FwdIt >::reference_type, param_pct_view >::value == true
423 @endcode
424
425 @par Complexity
426 Linear in `this->url().encoded_query().size()`.
427
428 @par Exception Safety
429 Strong guarantee.
430 Calls to allocate may throw.
431 Exceptions thrown on invalid input.
432
433 @throw system_error
434 The range contains an invalid percent-encoding.
435
436 @return An iterator to the first new element.
437
438 @param first The first element to append.
439 @param last One past the last element to append.
440 @return An iterator to the first new element.
441 */
442 template<class FwdIt>
443 iterator
444 append(
445 FwdIt first, FwdIt last);
446
447 //--------------------------------------------
448
449 /** Insert params
450
451 This function inserts a param
452 before the specified position.
453
454 <br>
455 All iterators that are equal to
456 `before` or come after are invalidated.
457
458 @par Complexity
459 Linear in `this->url().encoded_query().size()`.
460
461 @par Exception Safety
462 Strong guarantee.
463 Calls to allocate may throw.
464 Exceptions thrown on invalid input.
465
466 @throw system_error
467 `p` contains an invalid percent-encoding.
468
469 @return An iterator to the inserted
470 element.
471
472 @param before An iterator before which
473 the param is inserted. This may
474 be equal to `end()`.
475
476 @param p The param to insert.
477 */
478 iterator
479 insert(
480 iterator before,
481 param_pct_view const& p);
482
483 /** Insert params
484
485 This function inserts the params in
486 an <em>initializer-list</em> before
487 the specified position.
488
489 <br>
490 All iterators that are equal to
491 `before` or come after are invalidated.
492
493 @note
494 The strings referenced by the inputs
495 must not come from the underlying url,
496 or else the behavior is undefined.
497
498 @par Complexity
499 Linear in `this->url().encoded_query().size()`.
500
501 @par Exception Safety
502 Strong guarantee.
503 Calls to allocate may throw.
504 Exceptions thrown on invalid input.
505
506 @throw system_error
507 `init` contains an invalid percent-encoding.
508
509 @return An iterator to the first
510 element inserted, or `before` if
511 `init.size() == 0`.
512
513 @param before An iterator before which
514 the element is inserted. This may
515 be equal to `end()`.
516
517 @param init The list of params to insert.
518 */
519 iterator
520 insert(
521 iterator before,
522 std::initializer_list<
523 param_pct_view> init);
524
525 /** Insert params
526
527 This function inserts a range of
528 params before the specified position.
529
530 <br>
531 All iterators that are equal to
532 `before` or come after are invalidated.
533
534 @note
535 The strings referenced by the inputs
536 must not come from the underlying url,
537 or else the behavior is undefined.
538
539 @par Mandates
540 @code
541 std::is_convertible< std::iterator_traits< FwdIt >::reference_type, param_pct_view >::value == true
542 @endcode
543
544 @par Complexity
545 Linear in `this->url().encoded_query().size()`.
546
547 @par Exception Safety
548 Strong guarantee.
549 Calls to allocate may throw.
550 Exceptions thrown on invalid input.
551
552 @throw system_error
553 The range contains an invalid percent-encoding.
554
555 @return An iterator to the first
556 element inserted, or `before` if
557 `first == last`.
558
559 @param before An iterator before which
560 the element is inserted. This may
561 be equal to `end()`.
562
563 @param first The first element to insert.
564 @param last One past the last element to insert.
565 @return An iterator to the first element inserted.
566 */
567 template<class FwdIt>
568 iterator
569 insert(
570 iterator before,
571 FwdIt first,
572 FwdIt last);
573
574 //--------------------------------------------
575
576 /** Erase params
577
578 This function removes an element from
579 the container.
580
581 <br>
582 All iterators that are equal to
583 `pos` or come after are invalidated.
584
585 @par Example
586 @code
587 url u( "?first=John&last=Doe" );
588
589 params_encoded_ref::iterator it = u.encoded_params().erase( u.encoded_params().begin() );
590
591 assert( u.encoded_query() == "last=Doe" );
592 @endcode
593
594 @par Complexity
595 Linear in `this->url().encoded_query().size()`.
596
597 @par Exception Safety
598 Throws nothing.
599
600 @return An iterator to one past
601 the removed element.
602
603 @param pos An iterator to the element.
604 */
605 iterator
606 erase(iterator pos) noexcept;
607
608 /** Erase params
609
610 This function removes a range of params
611 from the container.
612
613 <br>
614 All iterators that are equal to
615 `first` or come after are invalidated.
616
617 @par Complexity
618 Linear in `this->url().encoded_query().size()`.
619
620 @par Exception Safety
621 Throws nothing.
622
623 @return An iterator to one past
624 the removed range.
625
626 @param first The first element to remove.
627 @param last One past the last element to remove.
628 @return An iterator to one past the removed range.
629 */
630 iterator
631 erase(
632 iterator first,
633 iterator last) noexcept;
634
635 /** Erase params
636
637 <br>
638 All iterators are invalidated.
639
640 @par Postconditions
641 @code
642 this->count( key, ic ) == 0
643 @endcode
644
645 @par Complexity
646 Linear in `this->url().encoded_query().size()`.
647
648 @par Exception Safety
649 Exceptions thrown on invalid input.
650
651 @throw system_error
652 `key` contains an invalid percent-encoding.
653
654 @return The number of params removed
655 from the container.
656
657 @param key The key to match.
658 By default, a case-sensitive
659 comparison is used.
660
661 @param ic An optional parameter. If
662 the value @ref ignore_case is passed
663 here, the comparison is
664 case-insensitive.
665 */
666 std::size_t
667 erase(
668 pct_string_view key,
669 ignore_case_param ic = {}) noexcept;
670
671 //--------------------------------------------
672
673 /** Replace params
674
675 This function replaces the contents
676 of the element at `pos` with the
677 specified param.
678
679 <br>
680 All iterators that are equal to
681 `pos` or come after are invalidated.
682
683 @note
684 The strings passed in must not come
685 from the element being replaced,
686 or else the behavior is undefined.
687
688 @par Example
689 @code
690 url u( "?first=John&last=Doe" );
691
692 u.encoded_params().replace( u.encoded_params().begin(), { "title", "Mr" });
693
694 assert( u.encoded_query() == "title=Mr&last=Doe" );
695 @endcode
696
697 @par Complexity
698 Linear in `this->url().encoded_query().size()`.
699
700 @par Exception Safety
701 Strong guarantee.
702 Calls to allocate may throw.
703 Exceptions thrown on invalid input.
704
705 @throw system_error
706 `p` contains an invalid percent-encoding.
707
708 @return An iterator to the element.
709
710 @param pos An iterator to the element.
711
712 @param p The param to assign.
713 */
714 iterator
715 replace(
716 iterator pos,
717 param_pct_view const& p);
718
719 /** Replace params
720
721 This function replaces a range of
722 params with the params in an
723 <em>initializer-list</em>.
724
725 <br>
726 All iterators that are equal to
727 `from` or come after are invalidated.
728
729 @note
730 The strings referenced by the inputs
731 must not come from the underlying url,
732 or else the behavior is undefined.
733
734 @par Complexity
735 Linear in `this->url().encoded_query().size()`.
736
737 @par Exception Safety
738 Strong guarantee.
739 Calls to allocate may throw.
740 Exceptions thrown on invalid input.
741
742 @throw system_error
743 `init` contains an invalid percent-encoding.
744
745 @return An iterator to the first
746 element inserted, or one past `to` if
747 `init.size() == 0`.
748
749 @param from,to The range of params
750 to replace.
751
752 @param init The list of params to assign.
753 */
754 iterator
755 replace(
756 iterator from,
757 iterator to,
758 std::initializer_list<
759 param_pct_view> init);
760
761 /** Replace params
762
763 This function replaces a range of
764 params with a range of params.
765
766 <br>
767 All iterators that are equal to
768 `from` or come after are invalidated.
769
770 @note
771 The strings referenced by the inputs
772 must not come from the underlying url,
773 or else the behavior is undefined.
774
775 @par Mandates
776 @code
777 std::is_convertible< std::iterator_traits< FwdIt >::reference_type, param_pct_view >::value == true
778 @endcode
779
780 @par Complexity
781 Linear in `this->url().encoded_query().size()`.
782
783 @par Exception Safety
784 Strong guarantee.
785 Calls to allocate may throw.
786 Exceptions thrown on invalid input.
787
788 @throw system_error
789 The range contains an invalid percent-encoding.
790
791 @return An iterator to the first
792 element inserted, or one past `to` if
793 `first == last`.
794
795 @param from The first element to replace.
796 @param to One past the last element to replace.
797 @param first The first element to insert.
798 @param last One past the last element to insert.
799 @return An iterator to the first element inserted, or
800 one past `to` if `first == last`.
801 */
802 template<class FwdIt>
803 iterator
804 replace(
805 iterator from,
806 iterator to,
807 FwdIt first,
808 FwdIt last);
809
810 //--------------------------------------------
811
812 /** Remove the value on an element
813
814 This function removes the value of
815 an element at the specified position.
816 After the call returns, `has_value`
817 for the element is false.
818
819 <br>
820 All iterators that are equal to
821 `pos` or come after are invalidated.
822
823 @par Example
824 @code
825 url u( "?first=John&last=Doe" );
826
827 u.encoded_params().unset( u.encoded_params().begin() );
828
829 assert( u.encoded_query() == "first&last=Doe" );
830 @endcode
831
832 @par Complexity
833 Linear in `this->url().encoded_query().size()`.
834
835 @par Exception Safety
836 Throws nothing.
837
838 @return An iterator to the element.
839
840 @param pos An iterator to the element.
841 */
842 iterator
843 unset(
844 iterator pos) noexcept;
845
846 /** Set a value
847
848 This function replaces the value of an
849 element at the specified position.
850
851 <br>
852 All iterators that are equal to
853 `pos` or come after are invalidated.
854
855 @note
856 The string passed in must not come
857 from the element being replaced,
858 or else the behavior is undefined.
859
860 @par Example
861 @code
862 url u( "?id=42&id=69" );
863
864 u.encoded_params().set( u.encoded_params().begin(), "none" );
865
866 assert( u.encoded_query() == "id=none&id=69" );
867 @endcode
868
869 @par Complexity
870 Linear in `this->url().encoded_query().size()`.
871
872 @par Exception Safety
873 Strong guarantee.
874 Calls to allocate may throw.
875 Exceptions thrown on invalid input.
876
877 @throw system_error
878 `value` contains an invalid percent-encoding.
879
880 @return An iterator to the element.
881
882 @param pos An iterator to the element.
883
884 @param value The value to assign. The
885 empty string still counts as a value.
886 That is, `has_value` for the element
887 is true.
888 */
889 iterator
890 set(
891 iterator pos,
892 pct_string_view value);
893
894 /** Set a value
895
896 This function performs one of two
897 actions depending on the value of
898 `this->contains( key, ic )`.
899
900 @li If key is contained in the view
901 then one of the matching params has
902 its value changed to the specified value.
903 The remaining params with a matching
904 key are erased. Otherwise,
905
906 @li If `key` is not contained in the
907 view, then the function apppends the
908 param `{ key, value }`.
909
910 <br>
911 All iterators are invalidated.
912
913 @note
914 The strings passed in must not come
915 from the element being replaced,
916 or else the behavior is undefined.
917
918 @par Example
919 @code
920 url u( "?id=42&id=69" );
921
922 u.encoded_params().set( "id", "none" );
923
924 assert( u.encoded_params().count( "id" ) == 1 );
925 @endcode
926
927 @par Postconditions
928 @code
929 this->count( key, ic ) == 1 && this->find( key, ic )->value == value
930 @endcode
931
932 @par Complexity
933 Linear in `this->url().encoded_query().size()`.
934
935 @par Exception Safety
936 Strong guarantee.
937 Calls to allocate may throw.
938 Exceptions thrown on invalid input.
939
940 @throw system_error
941 `key` or `value` contain an invalid
942 percent-encoding.
943
944 @return An iterator to the appended
945 or modified element.
946
947 @param key The key to match.
948 By default, a case-sensitive
949 comparison is used.
950
951 @param value The value to assign. The
952 empty string still counts as a value.
953 That is, `has_value` for the element
954 is true.
955
956 @param ic An optional parameter. If
957 the value @ref ignore_case is passed
958 here, the comparison is
959 case-insensitive.
960 */
961 iterator
962 set(
963 pct_string_view key,
964 pct_string_view value,
965 ignore_case_param ic = {});
966
967 private:
968 template<class FwdIt>
969 void
970 assign(FwdIt first, FwdIt last,
971 std::forward_iterator_tag);
972
973 // Doxygen cannot render ` = delete`
974 template<class FwdIt>
975 void
976 assign(FwdIt first, FwdIt last,
977 std::input_iterator_tag) = delete;
978
979 template<class FwdIt>
980 iterator
981 insert(
982 iterator before,
983 FwdIt first,
984 FwdIt last,
985 std::forward_iterator_tag);
986
987 // Doxygen cannot render ` = delete`
988 template<class FwdIt>
989 iterator
990 insert(
991 iterator before,
992 FwdIt first,
993 FwdIt last,
994 std::input_iterator_tag) = delete;
995 };
996
997 } // urls
998 } // boost
999
1000 // This is in <boost/url/url_base.hpp>
1001 //
1002 // #include <boost/url/impl/params_encoded_ref.hpp>
1003
1004 #endif
1005