1  
//
1  
//
2  
// Copyright (c) 2019 Vinnie Falco (vinnie.falco@gmail.com)
2  
// Copyright (c) 2019 Vinnie Falco (vinnie.falco@gmail.com)
3  
// Copyright (c) 2022 Alan de Freitas (alandefreitas@gmail.com)
3  
// Copyright (c) 2022 Alan de Freitas (alandefreitas@gmail.com)
4  
//
4  
//
5  
// Distributed under the Boost Software License, Version 1.0. (See accompanying
5  
// Distributed under the Boost Software License, Version 1.0. (See accompanying
6  
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
6  
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
7  
//
7  
//
8  
// Official repository: https://github.com/boostorg/url
8  
// Official repository: https://github.com/boostorg/url
9  
//
9  
//
10  

10  

11  
#ifndef BOOST_URL_PARAMS_REF_HPP
11  
#ifndef BOOST_URL_PARAMS_REF_HPP
12  
#define BOOST_URL_PARAMS_REF_HPP
12  
#define BOOST_URL_PARAMS_REF_HPP
13  

13  

14  
#include <boost/url/detail/config.hpp>
14  
#include <boost/url/detail/config.hpp>
15  
#include <boost/url/ignore_case.hpp>
15  
#include <boost/url/ignore_case.hpp>
16  
#include <boost/url/params_base.hpp>
16  
#include <boost/url/params_base.hpp>
17  
#include <initializer_list>
17  
#include <initializer_list>
18  
#include <iterator>
18  
#include <iterator>
19  

19  

20  
namespace boost {
20  
namespace boost {
21  
namespace urls {
21  
namespace urls {
22  

22  

23  
#ifndef BOOST_URL_DOCS
23  
#ifndef BOOST_URL_DOCS
24  
class url_base;
24  
class url_base;
25  
class params_view;
25  
class params_view;
26  
#endif
26  
#endif
27  

27  

28  
/** Mutable decoded query parameter proxy
28  
/** Mutable decoded query parameter proxy
29  

29  

30  
    This container presents the decoded query
30  
    This container presents the decoded query
31  
    parameters of a @ref url_base as a bidirectional
31  
    parameters of a @ref url_base as a bidirectional
32  
    range whose modifying operations update the
32  
    range whose modifying operations update the
33  
    underlying URL in-place. It references (but
33  
    underlying URL in-place. It references (but
34  
    does not own) the character buffer, so the
34  
    does not own) the character buffer, so the
35  
    referenced URL must stay alive while the proxy
35  
    referenced URL must stay alive while the proxy
36  
    is used.
36  
    is used.
37  

37  

38  
    <br>
38  
    <br>
39  

39  

40  
    Percent escapes in strings returned when
40  
    Percent escapes in strings returned when
41  
    dereferencing iterators are automatically
41  
    dereferencing iterators are automatically
42  
    decoded.
42  
    decoded.
43  
    Reserved characters in strings supplied
43  
    Reserved characters in strings supplied
44  
    to modifier functions are automatically
44  
    to modifier functions are automatically
45  
    percent-escaped.
45  
    percent-escaped.
46  

46  

47  
    @par Example
47  
    @par Example
48  
    @code
48  
    @code
49  
    url u( "?first=John&last=Doe" );
49  
    url u( "?first=John&last=Doe" );
50  

50  

51  
    params_ref p = u.params();
51  
    params_ref p = u.params();
52  
    @endcode
52  
    @endcode
53  

53  

54  
    @par Iterator Invalidation
54  
    @par Iterator Invalidation
55  
    Changes to the underlying character buffer
55  
    Changes to the underlying character buffer
56  
    can invalidate iterators which reference it.
56  
    can invalidate iterators which reference it.
57  
    Modifications made through the container
57  
    Modifications made through the container
58  
    invalidate some or all iterators:
58  
    invalidate some or all iterators:
59  
    <br>
59  
    <br>
60  

60  

61  
    @li @ref append : Only `end()`.
61  
    @li @ref append : Only `end()`.
62  

62  

63  
    @li @ref assign, @ref clear,
63  
    @li @ref assign, @ref clear,
64  
        `operator=` : All elements.
64  
        `operator=` : All elements.
65  

65  

66  
    @li @ref erase : Erased elements and all
66  
    @li @ref erase : Erased elements and all
67  
        elements after (including `end()`).
67  
        elements after (including `end()`).
68  

68  

69  
    @li @ref insert : All elements at or after
69  
    @li @ref insert : All elements at or after
70  
        the insertion point (including `end()`).
70  
        the insertion point (including `end()`).
71  

71  

72  
    @li @ref replace, @ref set : Modified
72  
    @li @ref replace, @ref set : Modified
73  
        elements and all elements
73  
        elements and all elements
74  
        after (including `end()`).
74  
        after (including `end()`).
75  

75  

76  
    @par Reads vs. writes
76  
    @par Reads vs. writes
77  
    Although this is a mutable proxy, all
77  
    Although this is a mutable proxy, all
78  
    observer helpers inherited from
78  
    observer helpers inherited from
79  
    @ref params_base (such as @ref contains,
79  
    @ref params_base (such as @ref contains,
80  
    @ref find, and @ref get_or) operate in the
80  
    @ref find, and @ref get_or) operate in the
81  
    same way as they do on @ref params_view:
81  
    same way as they do on @ref params_view:
82  
    they perform their lookup against the
82  
    they perform their lookup against the
83  
    current contents of the referenced URL
83  
    current contents of the referenced URL
84  
    without modifying it.
84  
    without modifying it.
85  
*/
85  
*/
86  
class BOOST_URL_DECL params_ref
86  
class BOOST_URL_DECL params_ref
87  
    : public params_base
87  
    : public params_base
88  
{
88  
{
89  
    friend class url_base;
89  
    friend class url_base;
90  

90  

91  
    url_base* u_ = nullptr;
91  
    url_base* u_ = nullptr;
92  

92  

93  
    params_ref(
93  
    params_ref(
94  
        url_base& u,
94  
        url_base& u,
95  
        encoding_opts opt) noexcept;
95  
        encoding_opts opt) noexcept;
96  

96  

97  
public:
97  
public:
98  
    //--------------------------------------------
98  
    //--------------------------------------------
99  
    //
99  
    //
100  
    // Special Members
100  
    // Special Members
101  
    //
101  
    //
102  
    //--------------------------------------------
102  
    //--------------------------------------------
103  

103  

104  
    /** Constructor
104  
    /** Constructor
105  

105  

106  
        After construction, both views
106  
        After construction, both views
107  
        reference the same url. Ownership is not
107  
        reference the same url. Ownership is not
108  
        transferred; the caller is responsible
108  
        transferred; the caller is responsible
109  
        for ensuring the lifetime of the url
109  
        for ensuring the lifetime of the url
110  
        extends until it is no longer
110  
        extends until it is no longer
111  
        referenced.
111  
        referenced.
112  

112  

113  
        @par Postconditions
113  
        @par Postconditions
114  
        @code
114  
        @code
115  
        &this->url() == &other.url()
115  
        &this->url() == &other.url()
116  
        @endcode
116  
        @endcode
117  

117  

118  
        @par Complexity
118  
        @par Complexity
119  
        Constant.
119  
        Constant.
120  

120  

121  
        @par Exception Safety
121  
        @par Exception Safety
122  
        Throws nothing.
122  
        Throws nothing.
123  

123  

124  
        @param other The other view.
124  
        @param other The other view.
125  
    */
125  
    */
126  
    params_ref(
126  
    params_ref(
127  
        params_ref const& other) = default;
127  
        params_ref const& other) = default;
128  

128  

129  
    /** Constructor
129  
    /** Constructor
130  

130  

131  
        After construction, both views will
131  
        After construction, both views will
132  
        reference the same url but this
132  
        reference the same url but this
133  
        instance will use the specified
133  
        instance will use the specified
134  
        @ref encoding_opts when the values
134  
        @ref encoding_opts when the values
135  
        are decoded.
135  
        are decoded.
136  

136  

137  
        Ownership is not transferred; the
137  
        Ownership is not transferred; the
138  
        caller is responsible for ensuring
138  
        caller is responsible for ensuring
139  
        the lifetime of the url extends
139  
        the lifetime of the url extends
140  
        until it is no longer referenced.
140  
        until it is no longer referenced.
141  

141  

142  
        @par Postconditions
142  
        @par Postconditions
143  
        @code
143  
        @code
144  
        &this->url() == &other.url()
144  
        &this->url() == &other.url()
145  
        @endcode
145  
        @endcode
146  

146  

147  
        @par Complexity
147  
        @par Complexity
148  
        Constant.
148  
        Constant.
149  

149  

150  
        @par Exception Safety
150  
        @par Exception Safety
151  
        Throws nothing.
151  
        Throws nothing.
152  

152  

153  
        @param other The other view.
153  
        @param other The other view.
154  
        @param opt The options for decoding. If
154  
        @param opt The options for decoding. If
155  
        this parameter is omitted, `space_as_plus`
155  
        this parameter is omitted, `space_as_plus`
156  
        is used.
156  
        is used.
157  

157  

158  
    */
158  
    */
159  
    params_ref(
159  
    params_ref(
160  
        params_ref const& other,
160  
        params_ref const& other,
161  
        encoding_opts opt) noexcept;
161  
        encoding_opts opt) noexcept;
162  

162  

163  
    /** Assignment
163  
    /** Assignment
164  

164  

165  
        The previous contents of this are
165  
        The previous contents of this are
166  
        replaced by the contents of `other.
166  
        replaced by the contents of `other.
167  

167  

168  
        <br>
168  
        <br>
169  
        All iterators are invalidated.
169  
        All iterators are invalidated.
170  

170  

171  
        @note
171  
        @note
172  
        The strings referenced by `other`
172  
        The strings referenced by `other`
173  
        must not come from the underlying url,
173  
        must not come from the underlying url,
174  
        or else the behavior is undefined.
174  
        or else the behavior is undefined.
175  

175  

176  
        @par Effects
176  
        @par Effects
177  
        @code
177  
        @code
178  
        this->assign( other.begin(), other.end() );
178  
        this->assign( other.begin(), other.end() );
179  
        @endcode
179  
        @endcode
180  

180  

181  
        @par Complexity
181  
        @par Complexity
182  
        Linear in `other.buffer().size()`.
182  
        Linear in `other.buffer().size()`.
183  

183  

184  
        @par Exception Safety
184  
        @par Exception Safety
185  
        Strong guarantee.
185  
        Strong guarantee.
186  
        Calls to allocate may throw.
186  
        Calls to allocate may throw.
187  

187  

188  
        @param other The params to assign.
188  
        @param other The params to assign.
189  
        @return `*this`
189  
        @return `*this`
190  
    */
190  
    */
191  
    params_ref&
191  
    params_ref&
192  
    operator=(
192  
    operator=(
193  
        params_ref const& other);
193  
        params_ref const& other);
194  

194  

195  
    /** Assignment
195  
    /** Assignment
196  

196  

197  
        After assignment, the previous contents
197  
        After assignment, the previous contents
198  
        of the query parameters are replaced by
198  
        of the query parameters are replaced by
199  
        the contents of the initializer-list.
199  
        the contents of the initializer-list.
200  

200  

201  
        @par Preconditions
201  
        @par Preconditions
202  
        None of character buffers referenced by
202  
        None of character buffers referenced by
203  
        `init` may overlap the character buffer of
203  
        `init` may overlap the character buffer of
204  
        the underlying url, or else the behavior
204  
        the underlying url, or else the behavior
205  
        is undefined.
205  
        is undefined.
206  

206  

207  
        @par Effects
207  
        @par Effects
208  
        @code
208  
        @code
209  
        this->assign( init );
209  
        this->assign( init );
210  
        @endcode
210  
        @endcode
211  

211  

212  
        @par Complexity
212  
        @par Complexity
213  
        Linear in `init.size()`.
213  
        Linear in `init.size()`.
214  

214  

215  
        @par Exception Safety
215  
        @par Exception Safety
216  
        Strong guarantee.
216  
        Strong guarantee.
217  
        Calls to allocate may throw.
217  
        Calls to allocate may throw.
218  

218  

219  
        @param init The list of params to assign.
219  
        @param init The list of params to assign.
220  
        @return `*this`
220  
        @return `*this`
221  
    */
221  
    */
222  
    params_ref&
222  
    params_ref&
223  
    operator=(
223  
    operator=(
224  
        std::initializer_list<
224  
        std::initializer_list<
225  
            param_view> init);
225  
            param_view> init);
226  

226  

227  
    /** Conversion
227  
    /** Conversion
228  

228  

229  
        @return A view of the query parameters.
229  
        @return A view of the query parameters.
230  
    */
230  
    */
231  
    operator
231  
    operator
232  
    params_view() const noexcept;
232  
    params_view() const noexcept;
233  

233  

234  
    //--------------------------------------------
234  
    //--------------------------------------------
235  
    //
235  
    //
236  
    // Observers
236  
    // Observers
237  
    //
237  
    //
238  
    //--------------------------------------------
238  
    //--------------------------------------------
239  

239  

240  
    /** Return the referenced url
240  
    /** Return the referenced url
241  

241  

242  
        This function returns the url referenced
242  
        This function returns the url referenced
243  
        by the view.
243  
        by the view.
244  

244  

245  
        @par Example
245  
        @par Example
246  
        @code
246  
        @code
247  
        url u( "?key=value" );
247  
        url u( "?key=value" );
248  

248  

249  
        assert( &u.segments().url() == &u );
249  
        assert( &u.segments().url() == &u );
250  
        @endcode
250  
        @endcode
251  

251  

252  
        @par Exception Safety
252  
        @par Exception Safety
253  
        @code
253  
        @code
254  
        Throws nothing.
254  
        Throws nothing.
255  
        @endcode
255  
        @endcode
256  

256  

257  
        @return A reference to the url.
257  
        @return A reference to the url.
258  
    */
258  
    */
259  
    url_base&
259  
    url_base&
260  
    url() const noexcept
260  
    url() const noexcept
261  
    {
261  
    {
262  
        return *u_;
262  
        return *u_;
263  
    }
263  
    }
264  

264  

265  
    //--------------------------------------------
265  
    //--------------------------------------------
266  
    //
266  
    //
267  
    // Modifiers
267  
    // Modifiers
268  
    //
268  
    //
269  
    //--------------------------------------------
269  
    //--------------------------------------------
270  

270  

271  
    /** Clear the contents of the container
271  
    /** Clear the contents of the container
272  

272  

273  
        <br>
273  
        <br>
274  
        All iterators are invalidated.
274  
        All iterators are invalidated.
275  

275  

276  
        @par Effects
276  
        @par Effects
277  
        @code
277  
        @code
278  
        this->url().remove_query();
278  
        this->url().remove_query();
279  
        @endcode
279  
        @endcode
280  

280  

281  
        @par Postconditions
281  
        @par Postconditions
282  
        @code
282  
        @code
283  
        this->empty() == true && this->url().has_query() == false
283  
        this->empty() == true && this->url().has_query() == false
284  
        @endcode
284  
        @endcode
285  

285  

286  
        @par Complexity
286  
        @par Complexity
287  
        Constant.
287  
        Constant.
288  

288  

289  
        @par Exception Safety
289  
        @par Exception Safety
290  
        Throws nothing.
290  
        Throws nothing.
291  
    */
291  
    */
292  
    void
292  
    void
293  
    clear() noexcept;
293  
    clear() noexcept;
294  

294  

295  
    //--------------------------------------------
295  
    //--------------------------------------------
296  

296  

297  
    /** Assign elements
297  
    /** Assign elements
298  

298  

299  
        This function replaces the entire
299  
        This function replaces the entire
300  
        contents of the view with the params
300  
        contents of the view with the params
301  
        in the <em>initializer-list</em>.
301  
        in the <em>initializer-list</em>.
302  

302  

303  
        <br>
303  
        <br>
304  
        All iterators are invalidated.
304  
        All iterators are invalidated.
305  

305  

306  
        @note
306  
        @note
307  
        The strings referenced by the inputs
307  
        The strings referenced by the inputs
308  
        must not come from the underlying url,
308  
        must not come from the underlying url,
309  
        or else the behavior is undefined.
309  
        or else the behavior is undefined.
310  

310  

311  
        @par Example
311  
        @par Example
312  
        @code
312  
        @code
313  
        url u;
313  
        url u;
314  

314  

315  
        u.params().assign( {{ "first", "John" }, { "last", "Doe" }} );
315  
        u.params().assign( {{ "first", "John" }, { "last", "Doe" }} );
316  
        @endcode
316  
        @endcode
317  

317  

318  
        @par Complexity
318  
        @par Complexity
319  
        Linear in `init.size()`.
319  
        Linear in `init.size()`.
320  

320  

321  
        @par Exception Safety
321  
        @par Exception Safety
322  
        Strong guarantee.
322  
        Strong guarantee.
323  
        Calls to allocate may throw.
323  
        Calls to allocate may throw.
324  

324  

325  
        @param init The list of params to assign.
325  
        @param init The list of params to assign.
326  
    */
326  
    */
327  
    void
327  
    void
328  
    assign(
328  
    assign(
329  
        std::initializer_list<
329  
        std::initializer_list<
330  
            param_view> init);
330  
            param_view> init);
331  

331  

332  
    /** Assign elements
332  
    /** Assign elements
333  

333  

334  
        This function replaces the entire
334  
        This function replaces the entire
335  
        contents of the view with the params
335  
        contents of the view with the params
336  
        in the range.
336  
        in the range.
337  

337  

338  
        <br>
338  
        <br>
339  
        All iterators are invalidated.
339  
        All iterators are invalidated.
340  

340  

341  
        @note
341  
        @note
342  
        The strings referenced by the inputs
342  
        The strings referenced by the inputs
343  
        must not come from the underlying url,
343  
        must not come from the underlying url,
344  
        or else the behavior is undefined.
344  
        or else the behavior is undefined.
345  

345  

346  
        @par Mandates
346  
        @par Mandates
347  
        @code
347  
        @code
348  
        std::is_convertible< std::iterator_traits< FwdIt >::reference_type, param_view >::value == true
348  
        std::is_convertible< std::iterator_traits< FwdIt >::reference_type, param_view >::value == true
349  
        @endcode
349  
        @endcode
350  

350  

351  
        @par Complexity
351  
        @par Complexity
352  
        Linear in the size of the range.
352  
        Linear in the size of the range.
353  

353  

354  
        @par Exception Safety
354  
        @par Exception Safety
355  
        Strong guarantee.
355  
        Strong guarantee.
356  
        Calls to allocate may throw.
356  
        Calls to allocate may throw.
357  

357  

358  
        @param first The first element to assign.
358  
        @param first The first element to assign.
359  
        @param last One past the last element to assign.
359  
        @param last One past the last element to assign.
360  
    */
360  
    */
361  
    template<class FwdIt>
361  
    template<class FwdIt>
362  
    void
362  
    void
363  
    assign(FwdIt first, FwdIt last);
363  
    assign(FwdIt first, FwdIt last);
364  

364  

365  
    //--------------------------------------------
365  
    //--------------------------------------------
366  

366  

367  
    /** Append elements
367  
    /** Append elements
368  

368  

369  
        This function appends a param to the view.
369  
        This function appends a param to the view.
370  

370  

371  
        <br>
371  
        <br>
372  
        The `end()` iterator is invalidated.
372  
        The `end()` iterator is invalidated.
373  

373  

374  
        @par Example
374  
        @par Example
375  
        @code
375  
        @code
376  
        url u;
376  
        url u;
377  

377  

378  
        u.params().append( { "first", "John" } );
378  
        u.params().append( { "first", "John" } );
379  
        @endcode
379  
        @endcode
380  

380  

381  
        @par Complexity
381  
        @par Complexity
382  
        Linear in `this->url().encoded_query().size()`.
382  
        Linear in `this->url().encoded_query().size()`.
383  

383  

384  
        @par Exception Safety
384  
        @par Exception Safety
385  
        Strong guarantee.
385  
        Strong guarantee.
386  
        Calls to allocate may throw.
386  
        Calls to allocate may throw.
387  

387  

388  
        @return An iterator to the new element.
388  
        @return An iterator to the new element.
389  

389  

390  
        @param p The param to append.
390  
        @param p The param to append.
391  
    */
391  
    */
392  
    iterator
392  
    iterator
393  
    append(
393  
    append(
394  
        param_view const& p);
394  
        param_view const& p);
395  

395  

396  
    /** Append elements
396  
    /** Append elements
397  

397  

398  
        This function appends the params in
398  
        This function appends the params in
399  
        an <em>initializer-list</em> to the view.
399  
        an <em>initializer-list</em> to the view.
400  

400  

401  
        <br>
401  
        <br>
402  
        The `end()` iterator is invalidated.
402  
        The `end()` iterator is invalidated.
403  

403  

404  
        @par Example
404  
        @par Example
405  
        @code
405  
        @code
406  
        url u;
406  
        url u;
407  

407  

408  
        u.params().append({ { "first", "John" }, { "last", "Doe" } });
408  
        u.params().append({ { "first", "John" }, { "last", "Doe" } });
409  
        @endcode
409  
        @endcode
410  

410  

411  
        @par Complexity
411  
        @par Complexity
412  
        Linear in `this->url().encoded_query().size()`.
412  
        Linear in `this->url().encoded_query().size()`.
413  

413  

414  
        @par Exception Safety
414  
        @par Exception Safety
415  
        Strong guarantee.
415  
        Strong guarantee.
416  
        Calls to allocate may throw.
416  
        Calls to allocate may throw.
417  

417  

418  
        @return An iterator to the first new element.
418  
        @return An iterator to the first new element.
419  

419  

420  
        @param init The list of params to append.
420  
        @param init The list of params to append.
421  
    */
421  
    */
422  
    iterator
422  
    iterator
423  
    append(
423  
    append(
424  
        std::initializer_list<
424  
        std::initializer_list<
425  
            param_view> init);
425  
            param_view> init);
426  

426  

427  
    /** Append elements
427  
    /** Append elements
428  

428  

429  
        This function appends a range of params
429  
        This function appends a range of params
430  
        to the view.
430  
        to the view.
431  

431  

432  
        <br>
432  
        <br>
433  
        The `end()` iterator is invalidated.
433  
        The `end()` iterator is invalidated.
434  

434  

435  
        @note
435  
        @note
436  
        The strings referenced by the inputs
436  
        The strings referenced by the inputs
437  
        must not come from the underlying url,
437  
        must not come from the underlying url,
438  
        or else the behavior is undefined.
438  
        or else the behavior is undefined.
439  

439  

440  
        @par Mandates
440  
        @par Mandates
441  
        @code
441  
        @code
442  
        std::is_convertible< std::iterator_traits< FwdIt >::reference_type, param_view >::value == true
442  
        std::is_convertible< std::iterator_traits< FwdIt >::reference_type, param_view >::value == true
443  
        @endcode
443  
        @endcode
444  

444  

445  
        @par Complexity
445  
        @par Complexity
446  
        Linear in `this->url().encoded_query().size()`.
446  
        Linear in `this->url().encoded_query().size()`.
447  

447  

448  
        @par Exception Safety
448  
        @par Exception Safety
449  
        Strong guarantee.
449  
        Strong guarantee.
450  
        Calls to allocate may throw.
450  
        Calls to allocate may throw.
451  

451  

452  
        @param first The first element to append.
452  
        @param first The first element to append.
453  
        @param last One past the last element to append.
453  
        @param last One past the last element to append.
454  
        @return An iterator to the first new element.
454  
        @return An iterator to the first new element.
455  
    */
455  
    */
456  
    template<class FwdIt>
456  
    template<class FwdIt>
457  
    iterator
457  
    iterator
458  
    append(
458  
    append(
459  
        FwdIt first, FwdIt last);
459  
        FwdIt first, FwdIt last);
460  

460  

461  
    //--------------------------------------------
461  
    //--------------------------------------------
462  

462  

463  
    /** Insert elements
463  
    /** Insert elements
464  

464  

465  
        This function inserts a param
465  
        This function inserts a param
466  
        before the specified position.
466  
        before the specified position.
467  

467  

468  
        <br>
468  
        <br>
469  
        All iterators that are equal to
469  
        All iterators that are equal to
470  
        `before` or come after are invalidated.
470  
        `before` or come after are invalidated.
471  

471  

472  
        @par Complexity
472  
        @par Complexity
473  
        Linear in `this->url().encoded_query().size()`.
473  
        Linear in `this->url().encoded_query().size()`.
474  

474  

475  
        @par Exception Safety
475  
        @par Exception Safety
476  
        Strong guarantee.
476  
        Strong guarantee.
477  
        Calls to allocate may throw.
477  
        Calls to allocate may throw.
478  

478  

479  
        @return An iterator to the inserted
479  
        @return An iterator to the inserted
480  
        element.
480  
        element.
481  

481  

482  
        @param before An iterator before which
482  
        @param before An iterator before which
483  
        the param is inserted. This may
483  
        the param is inserted. This may
484  
        be equal to `end()`.
484  
        be equal to `end()`.
485  

485  

486  
        @param p The param to insert.
486  
        @param p The param to insert.
487  
    */
487  
    */
488  
    iterator
488  
    iterator
489  
    insert(
489  
    insert(
490  
        iterator before,
490  
        iterator before,
491  
        param_view const& p);
491  
        param_view const& p);
492  

492  

493  
    /** Insert elements
493  
    /** Insert elements
494  

494  

495  
        This function inserts the params in
495  
        This function inserts the params in
496  
        an <em>initializer-list</em> before
496  
        an <em>initializer-list</em> before
497  
        the specified position.
497  
        the specified position.
498  

498  

499  
        <br>
499  
        <br>
500  
        All iterators that are equal to
500  
        All iterators that are equal to
501  
        `before` or come after are invalidated.
501  
        `before` or come after are invalidated.
502  

502  

503  
        @note
503  
        @note
504  
        The strings referenced by the inputs
504  
        The strings referenced by the inputs
505  
        must not come from the underlying url,
505  
        must not come from the underlying url,
506  
        or else the behavior is undefined.
506  
        or else the behavior is undefined.
507  

507  

508  
        @par Complexity
508  
        @par Complexity
509  
        Linear in `this->url().encoded_query().size()`.
509  
        Linear in `this->url().encoded_query().size()`.
510  

510  

511  
        @par Exception Safety
511  
        @par Exception Safety
512  
        Strong guarantee.
512  
        Strong guarantee.
513  
        Calls to allocate may throw.
513  
        Calls to allocate may throw.
514  

514  

515  
        @return An iterator to the first
515  
        @return An iterator to the first
516  
        element inserted, or `before` if
516  
        element inserted, or `before` if
517  
        `init.size() == 0`.
517  
        `init.size() == 0`.
518  

518  

519  
        @param before An iterator before which
519  
        @param before An iterator before which
520  
        the element is inserted. This may
520  
        the element is inserted. This may
521  
        be equal to `end()`.
521  
        be equal to `end()`.
522  

522  

523  
        @param init The list of params to insert.
523  
        @param init The list of params to insert.
524  
    */
524  
    */
525  
    iterator
525  
    iterator
526  
    insert(
526  
    insert(
527  
        iterator before,
527  
        iterator before,
528  
        std::initializer_list<
528  
        std::initializer_list<
529  
            param_view> init);
529  
            param_view> init);
530  

530  

531  
    /** Insert elements
531  
    /** Insert elements
532  

532  

533  
        This function inserts a range of
533  
        This function inserts a range of
534  
        params before the specified position.
534  
        params before the specified position.
535  

535  

536  
        <br>
536  
        <br>
537  
        All iterators that are equal to
537  
        All iterators that are equal to
538  
        `before` or come after are invalidated.
538  
        `before` or come after are invalidated.
539  

539  

540  
        @note
540  
        @note
541  
        The strings referenced by the inputs
541  
        The strings referenced by the inputs
542  
        must not come from the underlying url,
542  
        must not come from the underlying url,
543  
        or else the behavior is undefined.
543  
        or else the behavior is undefined.
544  

544  

545  
        @par Mandates
545  
        @par Mandates
546  
        @code
546  
        @code
547  
        std::is_convertible< std::iterator_traits< FwdIt >::reference_type, param_view >::value == true
547  
        std::is_convertible< std::iterator_traits< FwdIt >::reference_type, param_view >::value == true
548  
        @endcode
548  
        @endcode
549  

549  

550  
        @par Complexity
550  
        @par Complexity
551  
        Linear in `this->url().encoded_query().size()`.
551  
        Linear in `this->url().encoded_query().size()`.
552  

552  

553  
        @par Exception Safety
553  
        @par Exception Safety
554  
        Strong guarantee.
554  
        Strong guarantee.
555  
        Calls to allocate may throw.
555  
        Calls to allocate may throw.
556  

556  

557  
        @return An iterator to the first
557  
        @return An iterator to the first
558  
        element inserted, or `before` if
558  
        element inserted, or `before` if
559  
        `first == last`.
559  
        `first == last`.
560  

560  

561  
        @param before An iterator before which
561  
        @param before An iterator before which
562  
        the element is inserted. This may
562  
        the element is inserted. This may
563  
        be equal to `end()`.
563  
        be equal to `end()`.
564  
        @param first The first element to insert.
564  
        @param first The first element to insert.
565  
        @param last One past the last element to insert.
565  
        @param last One past the last element to insert.
566  
        @return An iterator to the first element inserted, or `before` if `first == last`.
566  
        @return An iterator to the first element inserted, or `before` if `first == last`.
567  
    */
567  
    */
568  
    template<class FwdIt>
568  
    template<class FwdIt>
569  
    iterator
569  
    iterator
570  
    insert(
570  
    insert(
571  
        iterator before,
571  
        iterator before,
572  
        FwdIt first,
572  
        FwdIt first,
573  
        FwdIt last);
573  
        FwdIt last);
574  

574  

575  
    //--------------------------------------------
575  
    //--------------------------------------------
576  

576  

577  
    /** Erase elements
577  
    /** Erase elements
578  

578  

579  
        This function removes an element from
579  
        This function removes an element from
580  
        the container.
580  
        the container.
581  

581  

582  
        <br>
582  
        <br>
583  
        All iterators that are equal to
583  
        All iterators that are equal to
584  
        `pos` or come after are invalidated.
584  
        `pos` or come after are invalidated.
585  

585  

586  
        @par Example
586  
        @par Example
587  
        @code
587  
        @code
588  
        url u( "?first=John&last=Doe" );
588  
        url u( "?first=John&last=Doe" );
589  

589  

590  
        params_ref::iterator it = u.params().erase( u.params().begin() );
590  
        params_ref::iterator it = u.params().erase( u.params().begin() );
591  

591  

592  
        assert( u.encoded_query() == "last=Doe" );
592  
        assert( u.encoded_query() == "last=Doe" );
593  
        @endcode
593  
        @endcode
594  

594  

595  
        @par Complexity
595  
        @par Complexity
596  
        Linear in `this->url().encoded_query().size()`.
596  
        Linear in `this->url().encoded_query().size()`.
597  

597  

598  
        @par Exception Safety
598  
        @par Exception Safety
599  
        Throws nothing.
599  
        Throws nothing.
600  

600  

601  
        @return An iterator to one past
601  
        @return An iterator to one past
602  
        the removed element.
602  
        the removed element.
603  

603  

604  
        @param pos An iterator to the element.
604  
        @param pos An iterator to the element.
605  
    */
605  
    */
606  
    iterator
606  
    iterator
607  
    erase(iterator pos) noexcept;
607  
    erase(iterator pos) noexcept;
608  

608  

609  
    /** Erase elements
609  
    /** Erase elements
610  

610  

611  
        This function removes a range of elements
611  
        This function removes a range of elements
612  
        from the container.
612  
        from the container.
613  

613  

614  
        <br>
614  
        <br>
615  
        All iterators that are equal to
615  
        All iterators that are equal to
616  
        `first` or come after are invalidated.
616  
        `first` or come after are invalidated.
617  

617  

618  
        @par Complexity
618  
        @par Complexity
619  
        Linear in `this->url().encoded_query().size()`.
619  
        Linear in `this->url().encoded_query().size()`.
620  

620  

621  
        @par Exception Safety
621  
        @par Exception Safety
622  
        Throws nothing.
622  
        Throws nothing.
623  

623  

624  
        @param first The first element to remove.
624  
        @param first The first element to remove.
625  
        @param last One past the last element to remove.
625  
        @param last One past the last element to remove.
626  
        @return An iterator to one past the removed range.
626  
        @return An iterator to one past the removed range.
627  
    */
627  
    */
628  
    iterator
628  
    iterator
629  
    erase(
629  
    erase(
630  
        iterator first,
630  
        iterator first,
631  
        iterator last) noexcept;
631  
        iterator last) noexcept;
632  

632  

633  
    /** Erase elements
633  
    /** Erase elements
634  

634  

635  
        <br>
635  
        <br>
636  
        All iterators are invalidated.
636  
        All iterators are invalidated.
637  

637  

638  
        @par Postconditions
638  
        @par Postconditions
639  
        @code
639  
        @code
640  
        this->count( key, ic ) == 0
640  
        this->count( key, ic ) == 0
641  
        @endcode
641  
        @endcode
642  

642  

643  
        @par Complexity
643  
        @par Complexity
644  
        Linear in `this->url().encoded_query().size()`.
644  
        Linear in `this->url().encoded_query().size()`.
645  

645  

646  
        @par Exception Safety
646  
        @par Exception Safety
647  
        Throws nothing.
647  
        Throws nothing.
648  

648  

649  
        @return The number of elements removed
649  
        @return The number of elements removed
650  
        from the container.
650  
        from the container.
651  

651  

652  
        @param key The key to match.
652  
        @param key The key to match.
653  
        By default, a case-sensitive
653  
        By default, a case-sensitive
654  
        comparison is used.
654  
        comparison is used.
655  

655  

656  
        @param ic An optional parameter. If
656  
        @param ic An optional parameter. If
657  
        the value @ref ignore_case is passed
657  
        the value @ref ignore_case is passed
658  
        here, the comparison is
658  
        here, the comparison is
659  
        case-insensitive.
659  
        case-insensitive.
660  
    */
660  
    */
661  
    std::size_t
661  
    std::size_t
662  
    erase(
662  
    erase(
663  
        core::string_view key,
663  
        core::string_view key,
664  
        ignore_case_param ic = {}) noexcept;
664  
        ignore_case_param ic = {}) noexcept;
665  

665  

666  
    //--------------------------------------------
666  
    //--------------------------------------------
667  

667  

668  
    /** Replace elements
668  
    /** Replace elements
669  

669  

670  
        This function replaces the contents
670  
        This function replaces the contents
671  
        of the element at `pos` with the
671  
        of the element at `pos` with the
672  
        specified param.
672  
        specified param.
673  

673  

674  
        <br>
674  
        <br>
675  
        All iterators that are equal to
675  
        All iterators that are equal to
676  
        `pos` or come after are invalidated.
676  
        `pos` or come after are invalidated.
677  

677  

678  
        @par Example
678  
        @par Example
679  
        @code
679  
        @code
680  
        url u( "?first=John&last=Doe" );
680  
        url u( "?first=John&last=Doe" );
681  

681  

682  
        u.params().replace( u.params().begin(), { "title", "Mr" });
682  
        u.params().replace( u.params().begin(), { "title", "Mr" });
683  

683  

684  
        assert( u.encoded_query() == "title=Mr&last=Doe" );
684  
        assert( u.encoded_query() == "title=Mr&last=Doe" );
685  
        @endcode
685  
        @endcode
686  

686  

687  
        @par Complexity
687  
        @par Complexity
688  
        Linear in `this->url().encoded_query().size()`.
688  
        Linear in `this->url().encoded_query().size()`.
689  

689  

690  
        @par Exception Safety
690  
        @par Exception Safety
691  
        Strong guarantee.
691  
        Strong guarantee.
692  
        Calls to allocate may throw.
692  
        Calls to allocate may throw.
693  

693  

694  
        @return An iterator to the element.
694  
        @return An iterator to the element.
695  

695  

696  
        @param pos An iterator to the element.
696  
        @param pos An iterator to the element.
697  

697  

698  
        @param p The param to assign.
698  
        @param p The param to assign.
699  
    */
699  
    */
700  
    iterator
700  
    iterator
701  
    replace(
701  
    replace(
702  
        iterator pos,
702  
        iterator pos,
703  
        param_view const& p);
703  
        param_view const& p);
704  

704  

705  
    /** Replace elements
705  
    /** Replace elements
706  

706  

707  
        This function replaces a range of
707  
        This function replaces a range of
708  
        elements with the params in an
708  
        elements with the params in an
709  
        <em>initializer-list</em>.
709  
        <em>initializer-list</em>.
710  

710  

711  
        <br>
711  
        <br>
712  
        All iterators that are equal to
712  
        All iterators that are equal to
713  
        `from` or come after are invalidated.
713  
        `from` or come after are invalidated.
714  

714  

715  
        @note
715  
        @note
716  
        The strings referenced by the inputs
716  
        The strings referenced by the inputs
717  
        must not come from the underlying url,
717  
        must not come from the underlying url,
718  
        or else the behavior is undefined.
718  
        or else the behavior is undefined.
719  

719  

720  
        @par Complexity
720  
        @par Complexity
721  
        Linear in `this->url().encoded_query().size()`.
721  
        Linear in `this->url().encoded_query().size()`.
722  

722  

723  
        @par Exception Safety
723  
        @par Exception Safety
724  
        Strong guarantee.
724  
        Strong guarantee.
725  
        Calls to allocate may throw.
725  
        Calls to allocate may throw.
726  

726  

727  
        @return An iterator to the first
727  
        @return An iterator to the first
728  
        element inserted, or one past `to` if
728  
        element inserted, or one past `to` if
729  
        `init.size() == 0`.
729  
        `init.size() == 0`.
730  

730  

731  
        @param from,to The range of elements
731  
        @param from,to The range of elements
732  
        to replace.
732  
        to replace.
733  

733  

734  
        @param init The list of params to assign.
734  
        @param init The list of params to assign.
735  
    */
735  
    */
736  
    iterator
736  
    iterator
737  
    replace(
737  
    replace(
738  
        iterator from,
738  
        iterator from,
739  
        iterator to,
739  
        iterator to,
740  
        std::initializer_list<
740  
        std::initializer_list<
741  
            param_view> init);
741  
            param_view> init);
742  

742  

743  
    /** Replace elements
743  
    /** Replace elements
744  

744  

745  
        This function replaces a range of
745  
        This function replaces a range of
746  
        elements with a range of params.
746  
        elements with a range of params.
747  

747  

748  
        <br>
748  
        <br>
749  
        All iterators that are equal to
749  
        All iterators that are equal to
750  
        `from` or come after are invalidated.
750  
        `from` or come after are invalidated.
751  

751  

752  
        @note
752  
        @note
753  
        The strings referenced by the inputs
753  
        The strings referenced by the inputs
754  
        must not come from the underlying url,
754  
        must not come from the underlying url,
755  
        or else the behavior is undefined.
755  
        or else the behavior is undefined.
756  

756  

757  
        @par Mandates
757  
        @par Mandates
758  
        @code
758  
        @code
759  
        std::is_convertible< std::iterator_traits< FwdIt >::reference_type, param_view >::value == true
759  
        std::is_convertible< std::iterator_traits< FwdIt >::reference_type, param_view >::value == true
760  
        @endcode
760  
        @endcode
761  

761  

762  
        @par Complexity
762  
        @par Complexity
763  
        Linear in `this->url().encoded_query().size()`.
763  
        Linear in `this->url().encoded_query().size()`.
764  

764  

765  
        @par Exception Safety
765  
        @par Exception Safety
766  
        Strong guarantee.
766  
        Strong guarantee.
767  
        Calls to allocate may throw.
767  
        Calls to allocate may throw.
768  

768  

769  
        @return An iterator to the first
769  
        @return An iterator to the first
770  
        element inserted, or one past `to` if
770  
        element inserted, or one past `to` if
771  
        `first == last`.
771  
        `first == last`.
772  

772  

773  
        @param from The first element to replace.
773  
        @param from The first element to replace.
774  
        @param to One past the last element to replace.
774  
        @param to One past the last element to replace.
775  
        @param first The first element to insert.
775  
        @param first The first element to insert.
776  
        @param last One past the last element to insert.
776  
        @param last One past the last element to insert.
777  
        @return An iterator to the first element inserted, or one past `to` if `first == last`.
777  
        @return An iterator to the first element inserted, or one past `to` if `first == last`.
778  
    */
778  
    */
779  
    template<class FwdIt>
779  
    template<class FwdIt>
780  
    iterator
780  
    iterator
781  
    replace(
781  
    replace(
782  
        iterator from,
782  
        iterator from,
783  
        iterator to,
783  
        iterator to,
784  
        FwdIt first,
784  
        FwdIt first,
785  
        FwdIt last);
785  
        FwdIt last);
786  

786  

787  
    //--------------------------------------------
787  
    //--------------------------------------------
788  

788  

789  
    /** Remove the value on an element
789  
    /** Remove the value on an element
790  

790  

791  
        This function removes the value of
791  
        This function removes the value of
792  
        an element at the specified position.
792  
        an element at the specified position.
793  
        After the call returns, `has_value`
793  
        After the call returns, `has_value`
794  
        for the element is false.
794  
        for the element is false.
795  

795  

796  
        <br>
796  
        <br>
797  
        All iterators that are equal to
797  
        All iterators that are equal to
798  
        `pos` or come after are invalidated.
798  
        `pos` or come after are invalidated.
799  

799  

800  
        @par Example
800  
        @par Example
801  
        @code
801  
        @code
802  
        url u( "?first=John&last=Doe" );
802  
        url u( "?first=John&last=Doe" );
803  

803  

804  
        u.params().unset( u.params().begin() );
804  
        u.params().unset( u.params().begin() );
805  

805  

806  
        assert( u.encoded_query() == "first&last=Doe" );
806  
        assert( u.encoded_query() == "first&last=Doe" );
807  
        @endcode
807  
        @endcode
808  

808  

809  
        @par Complexity
809  
        @par Complexity
810  
        Linear in `this->url().encoded_query().size()`.
810  
        Linear in `this->url().encoded_query().size()`.
811  

811  

812  
        @par Exception Safety
812  
        @par Exception Safety
813  
        Throws nothing.
813  
        Throws nothing.
814  

814  

815  
        @return An iterator to the element.
815  
        @return An iterator to the element.
816  

816  

817  
        @param pos An iterator to the element.
817  
        @param pos An iterator to the element.
818  
    */
818  
    */
819  
    iterator
819  
    iterator
820  
    unset(
820  
    unset(
821  
        iterator pos) noexcept;
821  
        iterator pos) noexcept;
822  

822  

823  
    /** Set a value
823  
    /** Set a value
824  

824  

825  
        This function replaces the value of an
825  
        This function replaces the value of an
826  
        element at the specified position.
826  
        element at the specified position.
827  

827  

828  
        <br>
828  
        <br>
829  
        All iterators that are equal to
829  
        All iterators that are equal to
830  
        `pos` or come after are invalidated.
830  
        `pos` or come after are invalidated.
831  

831  

832  
        @par Example
832  
        @par Example
833  
        @code
833  
        @code
834  
        url u( "?id=42&id=69" );
834  
        url u( "?id=42&id=69" );
835  

835  

836  
        u.params().set( u.params().begin(), "none" );
836  
        u.params().set( u.params().begin(), "none" );
837  

837  

838  
        assert( u.encoded_query() == "id=none&id=69" );
838  
        assert( u.encoded_query() == "id=none&id=69" );
839  
        @endcode
839  
        @endcode
840  

840  

841  
        @par Complexity
841  
        @par Complexity
842  
        Linear in `this->url().encoded_query().size()`.
842  
        Linear in `this->url().encoded_query().size()`.
843  

843  

844  
        @par Exception Safety
844  
        @par Exception Safety
845  
        Strong guarantee.
845  
        Strong guarantee.
846  
        Calls to allocate may throw.
846  
        Calls to allocate may throw.
847  

847  

848  
        @return An iterator to the element.
848  
        @return An iterator to the element.
849  

849  

850  
        @param pos An iterator to the element.
850  
        @param pos An iterator to the element.
851  

851  

852  
        @param value The value to assign. The
852  
        @param value The value to assign. The
853  
        empty string still counts as a value.
853  
        empty string still counts as a value.
854  
        That is, `has_value` for the element
854  
        That is, `has_value` for the element
855  
        is true.
855  
        is true.
856  
    */
856  
    */
857  
    iterator
857  
    iterator
858  
    set(
858  
    set(
859  
        iterator pos,
859  
        iterator pos,
860  
        core::string_view value);
860  
        core::string_view value);
861  

861  

862  
    /** Set a value
862  
    /** Set a value
863  

863  

864  
        This function performs one of two
864  
        This function performs one of two
865  
        actions depending on the value of
865  
        actions depending on the value of
866  
        `this->contains( key, ic )`.
866  
        `this->contains( key, ic )`.
867  

867  

868  
        @li If key is contained in the view
868  
        @li If key is contained in the view
869  
        then one of the matching elements has
869  
        then one of the matching elements has
870  
        its value changed to the specified value.
870  
        its value changed to the specified value.
871  
        The remaining elements with a matching
871  
        The remaining elements with a matching
872  
        key are erased. Otherwise,
872  
        key are erased. Otherwise,
873  

873  

874  
        @li If `key` is not contained in the
874  
        @li If `key` is not contained in the
875  
        view, then the function apppends the
875  
        view, then the function apppends the
876  
        param `{ key, value }`.
876  
        param `{ key, value }`.
877  

877  

878  
        <br>
878  
        <br>
879  
        All iterators are invalidated.
879  
        All iterators are invalidated.
880  

880  

881  
        @par Example
881  
        @par Example
882  
        @code
882  
        @code
883  
        url u( "?id=42&id=69" );
883  
        url u( "?id=42&id=69" );
884  

884  

885  
        u.params().set( "id", "none" );
885  
        u.params().set( "id", "none" );
886  

886  

887  
        assert( u.params().count( "id" ) == 1 );
887  
        assert( u.params().count( "id" ) == 1 );
888  
        @endcode
888  
        @endcode
889  

889  

890  
        @par Postconditions
890  
        @par Postconditions
891  
        @code
891  
        @code
892  
        this->count( key, ic ) == 1 && this->find( key, ic )->value == value
892  
        this->count( key, ic ) == 1 && this->find( key, ic )->value == value
893  
        @endcode
893  
        @endcode
894  

894  

895  
        @par Complexity
895  
        @par Complexity
896  
        Linear in `this->url().encoded_query().size()`.
896  
        Linear in `this->url().encoded_query().size()`.
897  

897  

898  
        @par Exception Safety
898  
        @par Exception Safety
899  
        Strong guarantee.
899  
        Strong guarantee.
900  
        Calls to allocate may throw.
900  
        Calls to allocate may throw.
901  

901  

902  
        @return An iterator to the appended
902  
        @return An iterator to the appended
903  
        or modified element.
903  
        or modified element.
904  

904  

905  
        @param key The key to match.
905  
        @param key The key to match.
906  
        By default, a case-sensitive
906  
        By default, a case-sensitive
907  
        comparison is used.
907  
        comparison is used.
908  

908  

909  
        @param value The value to assign. The
909  
        @param value The value to assign. The
910  
        empty string still counts as a value.
910  
        empty string still counts as a value.
911  
        That is, `has_value` for the element
911  
        That is, `has_value` for the element
912  
        is true.
912  
        is true.
913  

913  

914  
        @param ic An optional parameter. If
914  
        @param ic An optional parameter. If
915  
        the value @ref ignore_case is passed
915  
        the value @ref ignore_case is passed
916  
        here, the comparison is
916  
        here, the comparison is
917  
        case-insensitive.
917  
        case-insensitive.
918  
    */
918  
    */
919  
    iterator
919  
    iterator
920  
    set(
920  
    set(
921  
        core::string_view key,
921  
        core::string_view key,
922  
        core::string_view value,
922  
        core::string_view value,
923  
        ignore_case_param ic = {});
923  
        ignore_case_param ic = {});
924  

924  

925  
    //--------------------------------------------
925  
    //--------------------------------------------
926  

926  

927  
private:
927  
private:
928  
    template<class FwdIt>
928  
    template<class FwdIt>
929  
    void
929  
    void
930  
    assign(FwdIt first, FwdIt last,
930  
    assign(FwdIt first, FwdIt last,
931  
        std::forward_iterator_tag);
931  
        std::forward_iterator_tag);
932  

932  

933  
    // Doxygen cannot render ` = delete`
933  
    // Doxygen cannot render ` = delete`
934  
    template<class FwdIt>
934  
    template<class FwdIt>
935  
    void
935  
    void
936  
    assign(FwdIt first, FwdIt last,
936  
    assign(FwdIt first, FwdIt last,
937  
        std::input_iterator_tag) = delete;
937  
        std::input_iterator_tag) = delete;
938  

938  

939  
    template<class FwdIt>
939  
    template<class FwdIt>
940  
    iterator
940  
    iterator
941  
    insert(
941  
    insert(
942  
        iterator before,
942  
        iterator before,
943  
        FwdIt first,
943  
        FwdIt first,
944  
        FwdIt last,
944  
        FwdIt last,
945  
        std::forward_iterator_tag);
945  
        std::forward_iterator_tag);
946  

946  

947  
    // Doxygen cannot render ` = delete`
947  
    // Doxygen cannot render ` = delete`
948  
    template<class FwdIt>
948  
    template<class FwdIt>
949  
    iterator
949  
    iterator
950  
    insert(
950  
    insert(
951  
        iterator before,
951  
        iterator before,
952  
        FwdIt first,
952  
        FwdIt first,
953  
        FwdIt last,
953  
        FwdIt last,
954  
        std::input_iterator_tag) = delete;
954  
        std::input_iterator_tag) = delete;
955  
};
955  
};
956  

956  

957  
} // urls
957  
} // urls
958  
} // boost
958  
} // boost
959  

959  

960  
// This is in <boost/url/url_base.hpp>
960  
// This is in <boost/url/url_base.hpp>
961  
//
961  
//
962  
// #include <boost/url/impl/params_ref.hpp>
962  
// #include <boost/url/impl/params_ref.hpp>
963  

963  

964  
//------------------------------------------------
964  
//------------------------------------------------
965  
//
965  
//
966  
// std::ranges::enable_borrowed_range
966  
// std::ranges::enable_borrowed_range
967  
//
967  
//
968  
//------------------------------------------------
968  
//------------------------------------------------
969  

969  

970  
#ifdef BOOST_URL_HAS_CONCEPTS
970  
#ifdef BOOST_URL_HAS_CONCEPTS
971  
#include <ranges>
971  
#include <ranges>
972  
namespace std::ranges {
972  
namespace std::ranges {
973  
    template<>
973  
    template<>
974  
    inline constexpr bool
974  
    inline constexpr bool
975  
        enable_borrowed_range<
975  
        enable_borrowed_range<
976  
            boost::urls::params_ref> = true;
976  
            boost::urls::params_ref> = true;
977  
} // std::ranges
977  
} // std::ranges
978  
#endif
978  
#endif
979  

979  

980  
#endif
980  
#endif