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