GCC Code Coverage Report


Directory: libs/url/
File: boost/url/params_ref.hpp
Date: 2024-03-08 17:32:04
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 */
184 params_ref&
185 operator=(
186 params_ref const& other);
187
188 /** Assignment
189
190 After assignment, the previous contents
191 of the query parameters are replaced by
192 the contents of the initializer-list.
193
194 @par Preconditions
195 None of character buffers referenced by
196 `init` may overlap the character buffer of
197 the underlying url, or else the behavior
198 is undefined.
199
200 @par Effects
201 @code
202 this->assign( init );
203 @endcode
204
205 @par Complexity
206 Linear in `init.size()`.
207
208 @par Exception Safety
209 Strong guarantee.
210 Calls to allocate may throw.
211
212 @param init The list of params to assign.
213 */
214 params_ref&
215 operator=(
216 std::initializer_list<
217 param_view> init);
218
219 /** Conversion
220 */
221 operator
222 params_view() const noexcept;
223
224 //--------------------------------------------
225 //
226 // Observers
227 //
228 //--------------------------------------------
229
230 /** Return the referenced url
231
232 This function returns the url referenced
233 by the view.
234
235 @par Example
236 @code
237 url u( "?key=value" );
238
239 assert( &u.segments().url() == &u );
240 @endcode
241
242 @par Exception Safety
243 @code
244 Throws nothing.
245 @endcode
246 */
247 url_base&
248 10 url() const noexcept
249 {
250 10 return *u_;
251 }
252
253 //--------------------------------------------
254 //
255 // Modifiers
256 //
257 //--------------------------------------------
258
259 /** Clear the contents of the container
260
261 <br>
262 All iterators are invalidated.
263
264 @par Effects
265 @code
266 this->url().remove_query();
267 @endcode
268
269 @par Postconditions
270 @code
271 this->empty() == true && this->url().has_query() == false
272 @endcode
273
274 @par Complexity
275 Constant.
276
277 @par Exception Safety
278 Throws nothing.
279 */
280 void
281 clear() noexcept;
282
283 //--------------------------------------------
284
285 /** Assign elements
286
287 This function replaces the entire
288 contents of the view with the params
289 in the <em>initializer-list</em>.
290
291 <br>
292 All iterators are invalidated.
293
294 @note
295 The strings referenced by the inputs
296 must not come from the underlying url,
297 or else the behavior is undefined.
298
299 @par Example
300 @code
301 url u;
302
303 u.params().assign( {{ "first", "John" }, { "last", "Doe" }} );
304 @endcode
305
306 @par Complexity
307 Linear in `init.size()`.
308
309 @par Exception Safety
310 Strong guarantee.
311 Calls to allocate may throw.
312
313 @param init The list of params to assign.
314 */
315 void
316 assign(
317 std::initializer_list<
318 param_view> init);
319
320 /** Assign elements
321
322 This function replaces the entire
323 contents of the view with the params
324 in the range.
325
326 <br>
327 All iterators are invalidated.
328
329 @note
330 The strings referenced by the inputs
331 must not come from the underlying url,
332 or else the behavior is undefined.
333
334 @par Mandates
335 @code
336 std::is_convertible< std::iterator_traits< FwdIt >::reference_type, param_view >::value == true
337 @endcode
338
339 @par Complexity
340 Linear in the size of the range.
341
342 @par Exception Safety
343 Strong guarantee.
344 Calls to allocate may throw.
345
346 @param first, last The range of params
347 to assign.
348 */
349 template<class FwdIt>
350 void
351 assign(FwdIt first, FwdIt last);
352
353 //--------------------------------------------
354
355 /** Append elements
356
357 This function appends a param to the view.
358
359 <br>
360 The `end()` iterator is invalidated.
361
362 @par Example
363 @code
364 url u;
365
366 u.params().append( { "first", "John" } );
367 @endcode
368
369 @par Complexity
370 Linear in `this->url().encoded_query().size()`.
371
372 @par Exception Safety
373 Strong guarantee.
374 Calls to allocate may throw.
375
376 @return An iterator to the new element.
377
378 @param p The param to append.
379 */
380 iterator
381 append(
382 param_view const& p);
383
384 /** Append elements
385
386 This function appends the params in
387 an <em>initializer-list</em> to the view.
388
389 <br>
390 The `end()` iterator is invalidated.
391
392 @par Example
393 @code
394 url u;
395
396 u.params().append({ { "first", "John" }, { "last", "Doe" } });
397 @endcode
398
399 @par Complexity
400 Linear in `this->url().encoded_query().size()`.
401
402 @par Exception Safety
403 Strong guarantee.
404 Calls to allocate may throw.
405
406 @return An iterator to the first new element.
407
408 @param init The list of params to append.
409 */
410 iterator
411 append(
412 std::initializer_list<
413 param_view> init);
414
415 /** Append elements
416
417 This function appends a range of params
418 to the view.
419
420 <br>
421 The `end()` iterator is invalidated.
422
423 @note
424 The strings referenced by the inputs
425 must not come from the underlying url,
426 or else the behavior is undefined.
427
428 @par Mandates
429 @code
430 std::is_convertible< std::iterator_traits< FwdIt >::reference_type, param_view >::value == true
431 @endcode
432
433 @par Complexity
434 Linear in `this->url().encoded_query().size()`.
435
436 @par Exception Safety
437 Strong guarantee.
438 Calls to allocate may throw.
439
440 @return An iterator to the first new element.
441
442 @param first, last The range of params
443 to append.
444 */
445 template<class FwdIt>
446 iterator
447 append(
448 FwdIt first, FwdIt last);
449
450 //--------------------------------------------
451
452 /** Insert elements
453
454 This function inserts a param
455 before the specified position.
456
457 <br>
458 All iterators that are equal to
459 `before` or come after are invalidated.
460
461 @par Complexity
462 Linear in `this->url().encoded_query().size()`.
463
464 @par Exception Safety
465 Strong guarantee.
466 Calls to allocate may throw.
467
468 @return An iterator to the inserted
469 element.
470
471 @param before An iterator before which
472 the param is inserted. This may
473 be equal to `end()`.
474
475 @param p The param to insert.
476 */
477 iterator
478 insert(
479 iterator before,
480 param_view const& p);
481
482 /** Insert elements
483
484 This function inserts the params in
485 an <em>initializer-list</em> before
486 the specified position.
487
488 <br>
489 All iterators that are equal to
490 `before` or come after are invalidated.
491
492 @note
493 The strings referenced by the inputs
494 must not come from the underlying url,
495 or else the behavior is undefined.
496
497 @par Complexity
498 Linear in `this->url().encoded_query().size()`.
499
500 @par Exception Safety
501 Strong guarantee.
502 Calls to allocate may throw.
503
504 @return An iterator to the first
505 element inserted, or `before` if
506 `init.size() == 0`.
507
508 @param before An iterator before which
509 the element is inserted. This may
510 be equal to `end()`.
511
512 @param init The list of params to insert.
513 */
514 iterator
515 insert(
516 iterator before,
517 std::initializer_list<
518 param_view> init);
519
520 /** Insert elements
521
522 This function inserts a range of
523 params before the specified position.
524
525 <br>
526 All iterators that are equal to
527 `before` or come after are invalidated.
528
529 @note
530 The strings referenced by the inputs
531 must not come from the underlying url,
532 or else the behavior is undefined.
533
534 @par Mandates
535 @code
536 std::is_convertible< std::iterator_traits< FwdIt >::reference_type, param_view >::value == true
537 @endcode
538
539 @par Complexity
540 Linear in `this->url().encoded_query().size()`.
541
542 @par Exception Safety
543 Strong guarantee.
544 Calls to allocate may throw.
545
546 @return An iterator to the first
547 element inserted, or `before` if
548 `first == last`.
549
550 @param before An iterator before which
551 the element is inserted. This may
552 be equal to `end()`.
553
554 @param first, last The range of params
555 to insert.
556 */
557 template<class FwdIt>
558 iterator
559 insert(
560 iterator before,
561 FwdIt first,
562 FwdIt last);
563
564 //--------------------------------------------
565
566 /** Erase elements
567
568 This function removes an element from
569 the container.
570
571 <br>
572 All iterators that are equal to
573 `pos` or come after are invalidated.
574
575 @par Example
576 @code
577 url u( "?first=John&last=Doe" );
578
579 params_ref::iterator it = u.params().erase( u.params().begin() );
580
581 assert( u.encoded_query() == "last=Doe" );
582 @endcode
583
584 @par Complexity
585 Linear in `this->url().encoded_query().size()`.
586
587 @par Exception Safety
588 Throws nothing.
589
590 @return An iterator to one past
591 the removed element.
592
593 @param pos An iterator to the element.
594 */
595 iterator
596 erase(iterator pos) noexcept;
597
598 /** Erase elements
599
600 This function removes a range of elements
601 from the container.
602
603 <br>
604 All iterators that are equal to
605 `first` or come after are invalidated.
606
607 @par Complexity
608 Linear in `this->url().encoded_query().size()`.
609
610 @par Exception Safety
611 Throws nothing.
612
613 @return An iterator to one past
614 the removed range.
615
616 @param first, last The range of
617 elements to erase.
618 */
619 iterator
620 erase(
621 iterator first,
622 iterator last) noexcept;
623
624 /** Erase elements
625
626 <br>
627 All iterators are invalidated.
628
629 @par Postconditions
630 @code
631 this->count( key, ic ) == 0
632 @endcode
633
634 @par Complexity
635 Linear in `this->url().encoded_query().size()`.
636
637 @par Exception Safety
638 Throws nothing.
639
640 @return The number of elements removed
641 from the container.
642
643 @param key The key to match.
644 By default, a case-sensitive
645 comparison is used.
646
647 @param ic An optional parameter. If
648 the value @ref ignore_case is passed
649 here, the comparison is
650 case-insensitive.
651 */
652 std::size_t
653 erase(
654 core::string_view key,
655 ignore_case_param ic = {}) noexcept;
656
657 //--------------------------------------------
658
659 /** Replace elements
660
661 This function replaces the contents
662 of the element at `pos` with the
663 specified param.
664
665 <br>
666 All iterators that are equal to
667 `pos` or come after are invalidated.
668
669 @par Example
670 @code
671 url u( "?first=John&last=Doe" );
672
673 u.params().replace( u.params().begin(), { "title", "Mr" });
674
675 assert( u.encoded_query() == "title=Mr&last=Doe" );
676 @endcode
677
678 @par Complexity
679 Linear in `this->url().encoded_query().size()`.
680
681 @par Exception Safety
682 Strong guarantee.
683 Calls to allocate may throw.
684
685 @return An iterator to the element.
686
687 @param pos An iterator to the element.
688
689 @param p The param to assign.
690 */
691 iterator
692 replace(
693 iterator pos,
694 param_view const& p);
695
696 /** Replace elements
697
698 This function replaces a range of
699 elements with the params in an
700 <em>initializer-list</em>.
701
702 <br>
703 All iterators that are equal to
704 `from` or come after are invalidated.
705
706 @note
707 The strings referenced by the inputs
708 must not come from the underlying url,
709 or else the behavior is undefined.
710
711 @par Complexity
712 Linear in `this->url().encoded_query().size()`.
713
714 @par Exception Safety
715 Strong guarantee.
716 Calls to allocate may throw.
717
718 @return An iterator to the first
719 element inserted, or one past `to` if
720 `init.size() == 0`.
721
722 @param from,to The range of elements
723 to replace.
724
725 @param init The list of params to assign.
726 */
727 iterator
728 replace(
729 iterator from,
730 iterator to,
731 std::initializer_list<
732 param_view> init);
733
734 /** Replace elements
735
736 This function replaces a range of
737 elements with a range of params.
738
739 <br>
740 All iterators that are equal to
741 `from` or come after are invalidated.
742
743 @note
744 The strings referenced by the inputs
745 must not come from the underlying url,
746 or else the behavior is undefined.
747
748 @par Mandates
749 @code
750 std::is_convertible< std::iterator_traits< FwdIt >::reference_type, param_view >::value == true
751 @endcode
752
753 @par Complexity
754 Linear in `this->url().encoded_query().size()`.
755
756 @par Exception Safety
757 Strong guarantee.
758 Calls to allocate may throw.
759
760 @return An iterator to the first
761 element inserted, or one past `to` if
762 `first == last`.
763
764 @param from,to The range of elements to
765 replace.
766
767 @param first, last The range of params
768 to assign.
769 */
770 template<class FwdIt>
771 iterator
772 replace(
773 iterator from,
774 iterator to,
775 FwdIt first,
776 FwdIt last);
777
778 //--------------------------------------------
779
780 /** Remove the value on an element
781
782 This function removes the value of
783 an element at the specified position.
784 After the call returns, `has_value`
785 for the element is false.
786
787 <br>
788 All iterators that are equal to
789 `pos` or come after are invalidated.
790
791 @par Example
792 @code
793 url u( "?first=John&last=Doe" );
794
795 u.params().unset( u.params().begin() );
796
797 assert( u.encoded_query() == "first&last=Doe" );
798 @endcode
799
800 @par Complexity
801 Linear in `this->url().encoded_query().size()`.
802
803 @par Exception Safety
804 Throws nothing.
805
806 @return An iterator to the element.
807
808 @param pos An iterator to the element.
809 */
810 iterator
811 unset(
812 iterator pos) noexcept;
813
814 /** Set a value
815
816 This function replaces the value of an
817 element at the specified position.
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( "?id=42&id=69" );
826
827 u.params().set( u.params().begin(), "none" );
828
829 assert( u.encoded_query() == "id=none&id=69" );
830 @endcode
831
832 @par Complexity
833 Linear in `this->url().encoded_query().size()`.
834
835 @par Exception Safety
836 Strong guarantee.
837 Calls to allocate may throw.
838
839 @return An iterator to the element.
840
841 @param pos An iterator to the element.
842
843 @param value The value to assign. The
844 empty string still counts as a value.
845 That is, `has_value` for the element
846 is true.
847 */
848 iterator
849 set(
850 iterator pos,
851 core::string_view value);
852
853 /** Set a value
854
855 This function performs one of two
856 actions depending on the value of
857 `this->contains( key, ic )`.
858
859 @li If key is contained in the view
860 then one of the matching elements has
861 its value changed to the specified value.
862 The remaining elements with a matching
863 key are erased. Otherwise,
864
865 @li If `key` is not contained in the
866 view, then the function apppends the
867 param `{ key, value }`.
868
869 <br>
870 All iterators are invalidated.
871
872 @par Example
873 @code
874 url u( "?id=42&id=69" );
875
876 u.params().set( "id", "none" );
877
878 assert( u.params().count( "id" ) == 1 );
879 @endcode
880
881 @par Postconditions
882 @code
883 this->count( key, ic ) == 1 && this->find( key, ic )->value == value
884 @endcode
885
886 @par Complexity
887 Linear in `this->url().encoded_query().size()`.
888
889 @par Exception Safety
890 Strong guarantee.
891 Calls to allocate may throw.
892
893 @return An iterator to the appended
894 or modified element.
895
896 @param key The key to match.
897 By default, a case-sensitive
898 comparison is used.
899
900 @param value The value to assign. The
901 empty string still counts as a value.
902 That is, `has_value` for the element
903 is true.
904
905 @param ic An optional parameter. If
906 the value @ref ignore_case is passed
907 here, the comparison is
908 case-insensitive.
909 */
910 iterator
911 set(
912 core::string_view key,
913 core::string_view value,
914 ignore_case_param ic = {});
915
916 //--------------------------------------------
917
918 private:
919 template<class FwdIt>
920 void
921 assign(FwdIt first, FwdIt last,
922 std::forward_iterator_tag);
923
924 // Doxygen cannot render ` = delete`
925 template<class FwdIt>
926 void
927 assign(FwdIt first, FwdIt last,
928 std::input_iterator_tag) = delete;
929
930 template<class FwdIt>
931 iterator
932 insert(
933 iterator before,
934 FwdIt first,
935 FwdIt last,
936 std::forward_iterator_tag);
937
938 // Doxygen cannot render ` = delete`
939 template<class FwdIt>
940 iterator
941 insert(
942 iterator before,
943 FwdIt first,
944 FwdIt last,
945 std::input_iterator_tag) = delete;
946 };
947
948 } // urls
949 } // boost
950
951 // This is in <boost/url/url_base.hpp>
952 //
953 // #include <boost/url/impl/params_ref.hpp>
954
955 #endif
956