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