GCC Code Coverage Report


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