GCC Code Coverage Report


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