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_URL_DECL params_encoded_ref
77  
class BOOST_URL_DECL 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&
228  
    url() const noexcept
228  
    url() const noexcept
229  
    {
229  
    {
230  
        return *u_;
230  
        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