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_URL_BASE_HPP
11  
#ifndef BOOST_URL_URL_BASE_HPP
12  
#define BOOST_URL_URL_BASE_HPP
12  
#define BOOST_URL_URL_BASE_HPP
13  

13  

14  
#include <boost/url/detail/config.hpp>
14  
#include <boost/url/detail/config.hpp>
15  
#include <boost/url/ipv4_address.hpp>
15  
#include <boost/url/ipv4_address.hpp>
16  
#include <boost/url/ipv6_address.hpp>
16  
#include <boost/url/ipv6_address.hpp>
17  
#include <boost/url/params_encoded_ref.hpp>
17  
#include <boost/url/params_encoded_ref.hpp>
18  
#include <boost/url/params_ref.hpp>
18  
#include <boost/url/params_ref.hpp>
19  
#include <boost/url/pct_string_view.hpp>
19  
#include <boost/url/pct_string_view.hpp>
20  
#include <boost/url/scheme.hpp>
20  
#include <boost/url/scheme.hpp>
21  
#include <boost/url/segments_encoded_ref.hpp>
21  
#include <boost/url/segments_encoded_ref.hpp>
22  
#include <boost/url/segments_ref.hpp>
22  
#include <boost/url/segments_ref.hpp>
23  
#include <boost/url/url_view_base.hpp>
23  
#include <boost/url/url_view_base.hpp>
24  
#include <cstdint>
24  
#include <cstdint>
25  
#include <initializer_list>
25  
#include <initializer_list>
26  
#include <memory>
26  
#include <memory>
27  
#include <string>
27  
#include <string>
28  
#include <utility>
28  
#include <utility>
29  

29  

30  
namespace boost {
30  
namespace boost {
31  
namespace urls {
31  
namespace urls {
32  

32  

33  
namespace detail {
33  
namespace detail {
34  
struct any_params_iter;
34  
struct any_params_iter;
35  
struct any_segments_iter;
35  
struct any_segments_iter;
36  
struct params_iter_impl;
36  
struct params_iter_impl;
37  
struct segments_iter_impl;
37  
struct segments_iter_impl;
38  
struct pattern;
38  
struct pattern;
39  
}
39  
}
40  

40  

41  
/** Common functionality for containers
41  
/** Common functionality for containers
42  

42  

43  
    This base class is used by the library
43  
    This base class is used by the library
44  
    to provide common member functions for
44  
    to provide common member functions for
45  
    containers. This cannot be instantiated
45  
    containers. This cannot be instantiated
46  
    directly; Instead, use one of the
46  
    directly; Instead, use one of the
47  
    containers or functions:
47  
    containers or functions:
48  

48  

49  
    @par Containers
49  
    @par Containers
50  
        @li @ref url
50  
        @li @ref url
51  
        @li @ref url_view
51  
        @li @ref url_view
52  
        @li @ref static_url
52  
        @li @ref static_url
53  

53  

54  
    @par Functions
54  
    @par Functions
55  
        @li @ref parse_absolute_uri
55  
        @li @ref parse_absolute_uri
56  
        @li @ref parse_origin_form
56  
        @li @ref parse_origin_form
57  
        @li @ref parse_relative_ref
57  
        @li @ref parse_relative_ref
58  
        @li @ref parse_uri
58  
        @li @ref parse_uri
59  
        @li @ref parse_uri_reference
59  
        @li @ref parse_uri_reference
60  
*/
60  
*/
61  
class BOOST_URL_DECL
61  
class BOOST_URL_DECL
62  
    url_base
62  
    url_base
63  
    : public url_view_base
63  
    : public url_view_base
64  
{
64  
{
65  
    char* s_ = nullptr;
65  
    char* s_ = nullptr;
66  
    std::size_t cap_ = 0;
66  
    std::size_t cap_ = 0;
67  

67  

68  
    friend class url;
68  
    friend class url;
69  
    friend class static_url_base;
69  
    friend class static_url_base;
70  
    friend class params_ref;
70  
    friend class params_ref;
71  
    friend class segments_ref;
71  
    friend class segments_ref;
72  
    friend class segments_encoded_ref;
72  
    friend class segments_encoded_ref;
73  
    friend class params_encoded_ref;
73  
    friend class params_encoded_ref;
74  
    friend struct detail::pattern;
74  
    friend struct detail::pattern;
75  

75  

76  
    struct op_t
76  
    struct op_t
77  
    {
77  
    {
78  
        ~op_t();
78  
        ~op_t();
79  
        op_t(url_base&,
79  
        op_t(url_base&,
80  
            core::string_view* = nullptr,
80  
            core::string_view* = nullptr,
81  
            core::string_view* = nullptr) noexcept;
81  
            core::string_view* = nullptr) noexcept;
82  
        void move(char*, char const*,
82  
        void move(char*, char const*,
83  
            std::size_t) noexcept;
83  
            std::size_t) noexcept;
84  

84  

85  
        url_base& u;
85  
        url_base& u;
86  
        core::string_view* s0 = nullptr;
86  
        core::string_view* s0 = nullptr;
87  
        core::string_view* s1 = nullptr;
87  
        core::string_view* s1 = nullptr;
88  
        char* old = nullptr;
88  
        char* old = nullptr;
89  
    };
89  
    };
90  

90  

91  
    virtual ~url_base() noexcept = default;
91  
    virtual ~url_base() noexcept = default;
92  
    url_base() noexcept = default;
92  
    url_base() noexcept = default;
93  
    url_base(detail::url_impl const&) noexcept;
93  
    url_base(detail::url_impl const&) noexcept;
94  
    explicit url_base(core::string_view);
94  
    explicit url_base(core::string_view);
95  
    void reserve_impl(std::size_t n);
95  
    void reserve_impl(std::size_t n);
96  
    void copy(url_view_base const&);
96  
    void copy(url_view_base const&);
97  
    virtual void clear_impl() noexcept = 0;
97  
    virtual void clear_impl() noexcept = 0;
98  
    virtual void reserve_impl(
98  
    virtual void reserve_impl(
99  
        std::size_t, op_t&) = 0;
99  
        std::size_t, op_t&) = 0;
100  
    virtual void cleanup(op_t&) = 0;
100  
    virtual void cleanup(op_t&) = 0;
101  

101  

102  
public:
102  
public:
103  
    //--------------------------------------------
103  
    //--------------------------------------------
104  
    //
104  
    //
105  
    // Observers
105  
    // Observers
106  
    //
106  
    //
107  
    //--------------------------------------------
107  
    //--------------------------------------------
108  

108  

109  
    /** Return the url as a null-terminated string
109  
    /** Return the url as a null-terminated string
110  

110  

111  
        This function returns a pointer to a null
111  
        This function returns a pointer to a null
112  
        terminated string representing the url,
112  
        terminated string representing the url,
113  
        which may contain percent escapes.
113  
        which may contain percent escapes.
114  

114  

115  
        @return A pointer to a null-terminated string containing the URL.
115  
        @return A pointer to a null-terminated string containing the URL.
116  

116  

117  
        @par Example
117  
        @par Example
118  
        @code
118  
        @code
119  
        assert( std::strlen( url( "http://www.example.com" ).c_str() ) == 22 );
119  
        assert( std::strlen( url( "http://www.example.com" ).c_str() ) == 22 );
120  
        @endcode
120  
        @endcode
121  

121  

122  
        @par Complexity
122  
        @par Complexity
123  
        Constant.
123  
        Constant.
124  

124  

125  
        @par Exception Safety
125  
        @par Exception Safety
126  
        Throws nothing.
126  
        Throws nothing.
127  
    */
127  
    */
128  
    char const*
128  
    char const*
129  
    c_str() const noexcept
129  
    c_str() const noexcept
130  
    {
130  
    {
131  
        return pi_->cs_;
131  
        return pi_->cs_;
132  
    }
132  
    }
133  

133  

134  
    /** Return the number of characters that can be stored without reallocating
134  
    /** Return the number of characters that can be stored without reallocating
135  

135  

136  
        This does not include the null terminator,
136  
        This does not include the null terminator,
137  
        which is always present.
137  
        which is always present.
138  

138  

139  
        @return `*this`
139  
        @return `*this`
140  

140  

141  
        @par Complexity
141  
        @par Complexity
142  
        Constant.
142  
        Constant.
143  

143  

144  
        @par Exception Safety
144  
        @par Exception Safety
145  
        Throws nothing.
145  
        Throws nothing.
146  
    */
146  
    */
147  
    std::size_t
147  
    std::size_t
148  
    capacity() const noexcept
148  
    capacity() const noexcept
149  
    {
149  
    {
150  
        return cap_;
150  
        return cap_;
151  
    }
151  
    }
152  

152  

153  
    /** Clear the contents while preserving the capacity
153  
    /** Clear the contents while preserving the capacity
154  

154  

155  
        @par Postconditions
155  
        @par Postconditions
156  
        @code
156  
        @code
157  
        this->empty() == true
157  
        this->empty() == true
158  
        @endcode
158  
        @endcode
159  

159  

160  
        @par Complexity
160  
        @par Complexity
161  
        Constant.
161  
        Constant.
162  

162  

163  
        @par Exception Safety
163  
        @par Exception Safety
164  
        No-throw guarantee.
164  
        No-throw guarantee.
165  
    */
165  
    */
166  
    void
166  
    void
167  
    clear() noexcept
167  
    clear() noexcept
168  
    {
168  
    {
169  
        this->clear_impl();
169  
        this->clear_impl();
170  
    }
170  
    }
171  

171  

172  
    /** Adjust the capacity without changing the size
172  
    /** Adjust the capacity without changing the size
173  

173  

174  
        This function adjusts the capacity
174  
        This function adjusts the capacity
175  
        of the container in characters, without
175  
        of the container in characters, without
176  
        affecting the current contents. Has
176  
        affecting the current contents. Has
177  
        no effect if `n <= this->capacity()`.
177  
        no effect if `n <= this->capacity()`.
178  

178  

179  
        @par Exception Safety
179  
        @par Exception Safety
180  
        Strong guarantee.
180  
        Strong guarantee.
181  
        Calls to allocate may throw.
181  
        Calls to allocate may throw.
182  

182  

183  
        @throw bad_alloc Allocation failure
183  
        @throw bad_alloc Allocation failure
184  

184  

185  
        @param n The capacity in characters,
185  
        @param n The capacity in characters,
186  
        excluding any null terminator.
186  
        excluding any null terminator.
187  
    */
187  
    */
188  
    void
188  
    void
189  
    reserve(std::size_t n)
189  
    reserve(std::size_t n)
190  
    {
190  
    {
191  
        reserve_impl(n);
191  
        reserve_impl(n);
192  
    }
192  
    }
193  

193  

194  
    //--------------------------------------------
194  
    //--------------------------------------------
195  
    //
195  
    //
196  
    // Fluent API
196  
    // Fluent API
197  
    //
197  
    //
198  

198  

199  
    //--------------------------------------------
199  
    //--------------------------------------------
200  
    //
200  
    //
201  
    // Scheme
201  
    // Scheme
202  
    //
202  
    //
203  
    //--------------------------------------------
203  
    //--------------------------------------------
204  

204  

205  
    /** Set the scheme
205  
    /** Set the scheme
206  

206  

207  
        The scheme is set to the specified
207  
        The scheme is set to the specified
208  
        string, which must contain a valid
208  
        string, which must contain a valid
209  
        scheme without any trailing colon
209  
        scheme without any trailing colon
210  
        (':').
210  
        (':').
211  
        Note that schemes are case-insensitive,
211  
        Note that schemes are case-insensitive,
212  
        and the canonical form is lowercased.
212  
        and the canonical form is lowercased.
213  

213  

214  
        @par Example
214  
        @par Example
215  
        @code
215  
        @code
216  
        assert( url( "http://www.example.com" ).set_scheme( "https" ).scheme_id() == scheme::https );
216  
        assert( url( "http://www.example.com" ).set_scheme( "https" ).scheme_id() == scheme::https );
217  
        @endcode
217  
        @endcode
218  

218  

219  
        @par Complexity
219  
        @par Complexity
220  
        Linear in `this->size() + s.size()`.
220  
        Linear in `this->size() + s.size()`.
221  

221  

222  
        @par Exception Safety
222  
        @par Exception Safety
223  
        Strong guarantee.
223  
        Strong guarantee.
224  
        Calls to allocate may throw.
224  
        Calls to allocate may throw.
225  
        Exceptions thrown on invalid input.
225  
        Exceptions thrown on invalid input.
226  

226  

227  
        @throw system_error
227  
        @throw system_error
228  
        `s` contains an invalid scheme.
228  
        `s` contains an invalid scheme.
229  

229  

230  
        @param s The scheme to set.
230  
        @param s The scheme to set.
231  

231  

232  
        @return `*this`
232  
        @return `*this`
233  

233  

234  
        @par BNF
234  
        @par BNF
235  
        @code
235  
        @code
236  
        scheme        = ALPHA *( ALPHA / DIGIT / "+" / "-" / "." )
236  
        scheme        = ALPHA *( ALPHA / DIGIT / "+" / "-" / "." )
237  
        @endcode
237  
        @endcode
238  

238  

239  
        @par Specification
239  
        @par Specification
240  
        @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.1">
240  
        @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.1">
241  
            3.1. Scheme (rfc3986)</a>
241  
            3.1. Scheme (rfc3986)</a>
242  

242  

243  
        @see
243  
        @see
244  
            @ref remove_scheme.
244  
            @ref remove_scheme.
245  
    */
245  
    */
246  
    url_base&
246  
    url_base&
247  
    set_scheme(core::string_view s);
247  
    set_scheme(core::string_view s);
248  

248  

249  
    /** Set the scheme
249  
    /** Set the scheme
250  

250  

251  
        This function sets the scheme to the specified
251  
        This function sets the scheme to the specified
252  
        known @ref urls::scheme id, which may not be
252  
        known @ref urls::scheme id, which may not be
253  
        @ref scheme::unknown or else an exception is
253  
        @ref scheme::unknown or else an exception is
254  
        thrown. If the id is @ref scheme::none, this
254  
        thrown. If the id is @ref scheme::none, this
255  
        function behaves as if @ref remove_scheme
255  
        function behaves as if @ref remove_scheme
256  
        were called.
256  
        were called.
257  

257  

258  
        @par Example
258  
        @par Example
259  
        @code
259  
        @code
260  
        assert( url( "http://example.com/echo.cgi" ).set_scheme_id( scheme::wss ).buffer() == "wss://example.com/echo.cgi" );
260  
        assert( url( "http://example.com/echo.cgi" ).set_scheme_id( scheme::wss ).buffer() == "wss://example.com/echo.cgi" );
261  
        @endcode
261  
        @endcode
262  

262  

263  
        @par Complexity
263  
        @par Complexity
264  
        Linear in `this->size()`.
264  
        Linear in `this->size()`.
265  

265  

266  
        @par Exception Safety
266  
        @par Exception Safety
267  
        Strong guarantee.
267  
        Strong guarantee.
268  
        Calls to allocate may throw.
268  
        Calls to allocate may throw.
269  
        Exceptions thrown on invalid input.
269  
        Exceptions thrown on invalid input.
270  

270  

271  
        @throw system_error
271  
        @throw system_error
272  
        The scheme is invalid.
272  
        The scheme is invalid.
273  

273  

274  
        @param id The scheme to set.
274  
        @param id The scheme to set.
275  
        @return `*this`
275  
        @return `*this`
276  

276  

277  
        @par Specification
277  
        @par Specification
278  
        @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.1">
278  
        @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.1">
279  
            3.1. Scheme (rfc3986)</a>
279  
            3.1. Scheme (rfc3986)</a>
280  
    */
280  
    */
281  
    url_base&
281  
    url_base&
282  
    set_scheme_id(urls::scheme id);
282  
    set_scheme_id(urls::scheme id);
283  

283  

284  
    /** Remove the scheme
284  
    /** Remove the scheme
285  

285  

286  
        This function removes the scheme if it
286  
        This function removes the scheme if it
287  
        is present.
287  
        is present.
288  

288  

289  
        @par Example
289  
        @par Example
290  
        @code
290  
        @code
291  
        assert( url("http://www.example.com/index.htm" ).remove_scheme().buffer() == "//www.example.com/index.htm" );
291  
        assert( url("http://www.example.com/index.htm" ).remove_scheme().buffer() == "//www.example.com/index.htm" );
292  
        @endcode
292  
        @endcode
293  

293  

294  
        @par Postconditions
294  
        @par Postconditions
295  
        @code
295  
        @code
296  
        this->has_scheme() == false && this->scheme_id() == scheme::none
296  
        this->has_scheme() == false && this->scheme_id() == scheme::none
297  
        @endcode
297  
        @endcode
298  

298  

299  
        @par Complexity
299  
        @par Complexity
300  
        Linear in `this->size()`.
300  
        Linear in `this->size()`.
301  

301  

302  
        @par Exception Safety
302  
        @par Exception Safety
303  
        Throws nothing.
303  
        Throws nothing.
304  

304  

305  
        @return `*this`
305  
        @return `*this`
306  

306  

307  
        @par BNF
307  
        @par BNF
308  
        @code
308  
        @code
309  
        URI           = scheme ":" hier-part [ "?" query ] [ "#" fragment ]
309  
        URI           = scheme ":" hier-part [ "?" query ] [ "#" fragment ]
310  
        @endcode
310  
        @endcode
311  

311  

312  
        @par Specification
312  
        @par Specification
313  
        @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.1">
313  
        @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.1">
314  
            3.1. Scheme (rfc3986)</a>
314  
            3.1. Scheme (rfc3986)</a>
315  

315  

316  
        @see
316  
        @see
317  
            @ref set_scheme.
317  
            @ref set_scheme.
318  
    */
318  
    */
319  
    url_base&
319  
    url_base&
320  
    remove_scheme();
320  
    remove_scheme();
321  

321  

322  
    //--------------------------------------------
322  
    //--------------------------------------------
323  
    //
323  
    //
324  
    // Authority
324  
    // Authority
325  
    //
325  
    //
326  
    //--------------------------------------------
326  
    //--------------------------------------------
327  

327  

328  
    /** Set the authority
328  
    /** Set the authority
329  

329  

330  
        This function sets the authority
330  
        This function sets the authority
331  
        to the specified string.
331  
        to the specified string.
332  
        The string may contain percent-escapes.
332  
        The string may contain percent-escapes.
333  

333  

334  
        @par Example
334  
        @par Example
335  
        @code
335  
        @code
336  
        assert( url().set_encoded_authority( "My%20Computer" ).has_authority() );
336  
        assert( url().set_encoded_authority( "My%20Computer" ).has_authority() );
337  
        @endcode
337  
        @endcode
338  

338  

339  
        @par Exception Safety
339  
        @par Exception Safety
340  
        Strong guarantee.
340  
        Strong guarantee.
341  
        Calls to allocate may throw.
341  
        Calls to allocate may throw.
342  
        Exceptions thrown on invalid input.
342  
        Exceptions thrown on invalid input.
343  

343  

344  
        @throw system_eror
344  
        @throw system_eror
345  
        The string contains an invalid percent-encoding.
345  
        The string contains an invalid percent-encoding.
346  

346  

347  
        @param s The authority string to set.
347  
        @param s The authority string to set.
348  
        @return `*this`
348  
        @return `*this`
349  

349  

350  
        @par BNF
350  
        @par BNF
351  
        @code
351  
        @code
352  
        authority     = [ userinfo "@" ] host [ ":" port ]
352  
        authority     = [ userinfo "@" ] host [ ":" port ]
353  

353  

354  
        userinfo      = *( unreserved / pct-encoded / sub-delims / ":" )
354  
        userinfo      = *( unreserved / pct-encoded / sub-delims / ":" )
355  
        host          = IP-literal / IPv4address / reg-name
355  
        host          = IP-literal / IPv4address / reg-name
356  
        port          = *DIGIT
356  
        port          = *DIGIT
357  
        @endcode
357  
        @endcode
358  

358  

359  
        @par Specification
359  
        @par Specification
360  
        @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.2">
360  
        @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.2">
361  
            3.2. Authority (rfc3986)</a>
361  
            3.2. Authority (rfc3986)</a>
362  
        @see
362  
        @see
363  
            @ref remove_authority.
363  
            @ref remove_authority.
364  
    */
364  
    */
365  
    url_base&
365  
    url_base&
366  
    set_encoded_authority(
366  
    set_encoded_authority(
367  
        pct_string_view s);
367  
        pct_string_view s);
368  

368  

369  
    /** Remove the authority
369  
    /** Remove the authority
370  

370  

371  
        This function removes the authority,
371  
        This function removes the authority,
372  
        which includes the userinfo, host, and
372  
        which includes the userinfo, host, and
373  
        a port if present.
373  
        a port if present.
374  

374  

375  
        @par Example
375  
        @par Example
376  
        @code
376  
        @code
377  
        assert( url( "http://example.com/echo.cgi" ).remove_authority().buffer() == "http:/echo.cgi" );
377  
        assert( url( "http://example.com/echo.cgi" ).remove_authority().buffer() == "http:/echo.cgi" );
378  
        @endcode
378  
        @endcode
379  

379  

380  
        @par Postconditions
380  
        @par Postconditions
381  
        @code
381  
        @code
382  
        this->has_authority() == false && this->has_userinfo() == false && this->has_port() == false
382  
        this->has_authority() == false && this->has_userinfo() == false && this->has_port() == false
383  
        @endcode
383  
        @endcode
384  

384  

385  
        @par Complexity
385  
        @par Complexity
386  
        Linear in `this->size()`.
386  
        Linear in `this->size()`.
387  

387  

388  
        @par Exception Safety
388  
        @par Exception Safety
389  
        Throws nothing.
389  
        Throws nothing.
390  

390  

391  
        @return `*this`
391  
        @return `*this`
392  

392  

393  
        @par BNF
393  
        @par BNF
394  
        @code
394  
        @code
395  
        authority     = [ userinfo "@" ] host [ ":" port ]
395  
        authority     = [ userinfo "@" ] host [ ":" port ]
396  

396  

397  
        userinfo      = *( unreserved / pct-encoded / sub-delims / ":" )
397  
        userinfo      = *( unreserved / pct-encoded / sub-delims / ":" )
398  
        host          = IP-literal / IPv4address / reg-name
398  
        host          = IP-literal / IPv4address / reg-name
399  
        port          = *DIGIT
399  
        port          = *DIGIT
400  
        @endcode
400  
        @endcode
401  

401  

402  
        @par Specification
402  
        @par Specification
403  
        @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.2">
403  
        @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.2">
404  
            3.2. Authority (rfc3986)</a>
404  
            3.2. Authority (rfc3986)</a>
405  

405  

406  
        @see
406  
        @see
407  
            @ref set_encoded_authority.
407  
            @ref set_encoded_authority.
408  
    */
408  
    */
409  
    url_base&
409  
    url_base&
410  
    remove_authority();
410  
    remove_authority();
411  

411  

412  
    //--------------------------------------------
412  
    //--------------------------------------------
413  
    //
413  
    //
414  
    // Userinfo
414  
    // Userinfo
415  
    //
415  
    //
416  
    //--------------------------------------------
416  
    //--------------------------------------------
417  

417  

418  
    /** Set the userinfo
418  
    /** Set the userinfo
419  

419  

420  
        The userinfo is set to the given string,
420  
        The userinfo is set to the given string,
421  
        which may contain percent-escapes.
421  
        which may contain percent-escapes.
422  
        Any special or reserved characters in the
422  
        Any special or reserved characters in the
423  
        string are automatically percent-encoded.
423  
        string are automatically percent-encoded.
424  
        The effects on the user and password
424  
        The effects on the user and password
425  
        depend on the presence of a colon (':')
425  
        depend on the presence of a colon (':')
426  
        in the string:
426  
        in the string:
427  

427  

428  
        @li If an unescaped colon exists, the
428  
        @li If an unescaped colon exists, the
429  
        characters up to the colon become
429  
        characters up to the colon become
430  
        the user and the rest of the characters
430  
        the user and the rest of the characters
431  
        after the colon become the password.
431  
        after the colon become the password.
432  
        In this case @ref has_password returns
432  
        In this case @ref has_password returns
433  
        true. Otherwise,
433  
        true. Otherwise,
434  

434  

435  
        @li If there is no colon, the user is
435  
        @li If there is no colon, the user is
436  
        set to the string. The function
436  
        set to the string. The function
437  
        @ref has_password returns false.
437  
        @ref has_password returns false.
438  

438  

439  
        @note
439  
        @note
440  
        The interpretation of the userinfo as
440  
        The interpretation of the userinfo as
441  
        individual user and password components
441  
        individual user and password components
442  
        is scheme-dependent. Transmitting
442  
        is scheme-dependent. Transmitting
443  
        passwords in URLs is deprecated.
443  
        passwords in URLs is deprecated.
444  

444  

445  
        @par Example
445  
        @par Example
446  
        @code
446  
        @code
447  
        assert( url( "http://example.com" ).set_userinfo( "user:pass" ).encoded_user() == "user" );
447  
        assert( url( "http://example.com" ).set_userinfo( "user:pass" ).encoded_user() == "user" );
448  
        @endcode
448  
        @endcode
449  

449  

450  
        @par Complexity
450  
        @par Complexity
451  
        Linear in `this->size() + s.size()`.
451  
        Linear in `this->size() + s.size()`.
452  

452  

453  
        @par Exception Safety
453  
        @par Exception Safety
454  
        Strong guarantee.
454  
        Strong guarantee.
455  
        Calls to allocate may throw.
455  
        Calls to allocate may throw.
456  

456  

457  
        @param s The string to set.
457  
        @param s The string to set.
458  
        @return `*this`
458  
        @return `*this`
459  

459  

460  
        @par BNF
460  
        @par BNF
461  
        @code
461  
        @code
462  
        userinfo      = [ [ user ] [ ':' password ] ]
462  
        userinfo      = [ [ user ] [ ':' password ] ]
463  

463  

464  
        user          = *( unreserved / pct-encoded / sub-delims )
464  
        user          = *( unreserved / pct-encoded / sub-delims )
465  
        password      = *( unreserved / pct-encoded / sub-delims / ":" )
465  
        password      = *( unreserved / pct-encoded / sub-delims / ":" )
466  
        @endcode
466  
        @endcode
467  

467  

468  
        @par Specification
468  
        @par Specification
469  
        @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.2.1">
469  
        @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.2.1">
470  
            3.2.1. User Information (rfc3986)</a>
470  
            3.2.1. User Information (rfc3986)</a>
471  

471  

472  
        @see
472  
        @see
473  
            @ref remove_userinfo,
473  
            @ref remove_userinfo,
474  
            @ref set_encoded_userinfo.
474  
            @ref set_encoded_userinfo.
475  
    */
475  
    */
476  
    url_base&
476  
    url_base&
477  
    set_userinfo(
477  
    set_userinfo(
478  
        core::string_view s);
478  
        core::string_view s);
479  

479  

480  
    /** Set the userinfo.
480  
    /** Set the userinfo.
481  

481  

482  
        The userinfo is set to the given string,
482  
        The userinfo is set to the given string,
483  
        which may contain percent-escapes.
483  
        which may contain percent-escapes.
484  
        Escapes in the string are preserved,
484  
        Escapes in the string are preserved,
485  
        and reserved characters in the string
485  
        and reserved characters in the string
486  
        are percent-escaped in the result.
486  
        are percent-escaped in the result.
487  
        The effects on the user and password
487  
        The effects on the user and password
488  
        depend on the presence of a colon (':')
488  
        depend on the presence of a colon (':')
489  
        in the string:
489  
        in the string:
490  

490  

491  
        @li If an unescaped colon exists, the
491  
        @li If an unescaped colon exists, the
492  
        characters up to the colon become
492  
        characters up to the colon become
493  
        the user and the rest of the characters
493  
        the user and the rest of the characters
494  
        after the colon become the password.
494  
        after the colon become the password.
495  
        In this case @ref has_password returns
495  
        In this case @ref has_password returns
496  
        true. Otherwise,
496  
        true. Otherwise,
497  

497  

498  
        @li If there is no colon, the user is
498  
        @li If there is no colon, the user is
499  
        set to the string. The function
499  
        set to the string. The function
500  
        @ref has_password returns false.
500  
        @ref has_password returns false.
501  

501  

502  
        @note
502  
        @note
503  
        The interpretation of the userinfo as
503  
        The interpretation of the userinfo as
504  
        individual user and password components
504  
        individual user and password components
505  
        is scheme-dependent. Transmitting
505  
        is scheme-dependent. Transmitting
506  
        passwords in URLs is deprecated.
506  
        passwords in URLs is deprecated.
507  

507  

508  
        @par Example
508  
        @par Example
509  
        @code
509  
        @code
510  
        assert( url( "http://example.com" ).set_encoded_userinfo( "john%20doe" ).user() == "john doe" );
510  
        assert( url( "http://example.com" ).set_encoded_userinfo( "john%20doe" ).user() == "john doe" );
511  
        @endcode
511  
        @endcode
512  

512  

513  
        @par Complexity
513  
        @par Complexity
514  
        Linear in `this->size() + s.size()`.
514  
        Linear in `this->size() + s.size()`.
515  

515  

516  
        @par Exception Safety
516  
        @par Exception Safety
517  
        Strong guarantee.
517  
        Strong guarantee.
518  
        Calls to allocate may throw.
518  
        Calls to allocate may throw.
519  
        Exceptions thrown on invalid input.
519  
        Exceptions thrown on invalid input.
520  

520  

521  
        @throw system_error
521  
        @throw system_error
522  
        `s` contains an invalid percent-encoding.
522  
        `s` contains an invalid percent-encoding.
523  

523  

524  
        @param s The string to set.
524  
        @param s The string to set.
525  
        @return `*this`
525  
        @return `*this`
526  

526  

527  
        @par BNF
527  
        @par BNF
528  
        @code
528  
        @code
529  
        userinfo      = [ [ user ] [ ':' password ] ]
529  
        userinfo      = [ [ user ] [ ':' password ] ]
530  

530  

531  
        user          = *( unreserved / pct-encoded / sub-delims )
531  
        user          = *( unreserved / pct-encoded / sub-delims )
532  
        password      = *( unreserved / pct-encoded / sub-delims / ":" )
532  
        password      = *( unreserved / pct-encoded / sub-delims / ":" )
533  
        @endcode
533  
        @endcode
534  

534  

535  
        @par Specification
535  
        @par Specification
536  
        @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.2.1">
536  
        @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.2.1">
537  
            3.2.1. User Information (rfc3986)</a>
537  
            3.2.1. User Information (rfc3986)</a>
538  

538  

539  
        @see
539  
        @see
540  
            @ref remove_userinfo,
540  
            @ref remove_userinfo,
541  
            @ref set_userinfo.
541  
            @ref set_userinfo.
542  
    */
542  
    */
543  
    url_base&
543  
    url_base&
544  
    set_encoded_userinfo(
544  
    set_encoded_userinfo(
545  
        pct_string_view s);
545  
        pct_string_view s);
546  

546  

547  
    /** Remove the userinfo
547  
    /** Remove the userinfo
548  

548  

549  
        This function removes the userinfo if
549  
        This function removes the userinfo if
550  
        present, without removing any authority.
550  
        present, without removing any authority.
551  

551  

552  
        @par Example
552  
        @par Example
553  
        @code
553  
        @code
554  
        assert( url( "http://user@example.com" ).remove_userinfo().has_userinfo() == false );
554  
        assert( url( "http://user@example.com" ).remove_userinfo().has_userinfo() == false );
555  
        @endcode
555  
        @endcode
556  

556  

557  
        @par Postconditions
557  
        @par Postconditions
558  
        @code
558  
        @code
559  
        this->has_userinfo() == false && this->encoded_userinfo().empty == true
559  
        this->has_userinfo() == false && this->encoded_userinfo().empty == true
560  
        @endcode
560  
        @endcode
561  

561  

562  
        @par Complexity
562  
        @par Complexity
563  
        Linear in `this->size()`.
563  
        Linear in `this->size()`.
564  

564  

565  
        @par Exception Safety
565  
        @par Exception Safety
566  
        Throws nothing.
566  
        Throws nothing.
567  

567  

568  
        @return `*this`
568  
        @return `*this`
569  

569  

570  
        @par BNF
570  
        @par BNF
571  
        @code
571  
        @code
572  
        userinfo      = [ [ user ] [ ':' password ] ]
572  
        userinfo      = [ [ user ] [ ':' password ] ]
573  

573  

574  
        user          = *( unreserved / pct-encoded / sub-delims )
574  
        user          = *( unreserved / pct-encoded / sub-delims )
575  
        password      = *( unreserved / pct-encoded / sub-delims / ":" )
575  
        password      = *( unreserved / pct-encoded / sub-delims / ":" )
576  
        @endcode
576  
        @endcode
577  

577  

578  
        @par Specification
578  
        @par Specification
579  
        @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.2.1">
579  
        @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.2.1">
580  
            3.2.1. User Information (rfc3986)</a>
580  
            3.2.1. User Information (rfc3986)</a>
581  

581  

582  
        @see
582  
        @see
583  
            @ref set_encoded_userinfo,
583  
            @ref set_encoded_userinfo,
584  
            @ref set_userinfo.
584  
            @ref set_userinfo.
585  
    */
585  
    */
586  
    url_base&
586  
    url_base&
587  
    remove_userinfo() noexcept;
587  
    remove_userinfo() noexcept;
588  

588  

589  
    //--------------------------------------------
589  
    //--------------------------------------------
590  

590  

591  
    /** Set the user
591  
    /** Set the user
592  

592  

593  
        This function sets the user part of the
593  
        This function sets the user part of the
594  
        userinfo to the string.
594  
        userinfo to the string.
595  
        Any special or reserved characters in the
595  
        Any special or reserved characters in the
596  
        string are automatically percent-encoded.
596  
        string are automatically percent-encoded.
597  

597  

598  
        @par Example
598  
        @par Example
599  
        @code
599  
        @code
600  
        assert( url().set_user("john doe").encoded_userinfo() == "john%20doe" );
600  
        assert( url().set_user("john doe").encoded_userinfo() == "john%20doe" );
601  
        @endcode
601  
        @endcode
602  

602  

603  
        @par Postconditions
603  
        @par Postconditions
604  
        @code
604  
        @code
605  
        this->has_authority() == true && this->has_userinfo() == true
605  
        this->has_authority() == true && this->has_userinfo() == true
606  
        @endcode
606  
        @endcode
607  

607  

608  
        @par Complexity
608  
        @par Complexity
609  
        Linear in `this->size() + s.size()`.
609  
        Linear in `this->size() + s.size()`.
610  

610  

611  
        @par Exception Safety
611  
        @par Exception Safety
612  
        Strong guarantee.
612  
        Strong guarantee.
613  
        Calls to allocate may throw.
613  
        Calls to allocate may throw.
614  

614  

615  
        @param s The string to set.
615  
        @param s The string to set.
616  
        @return `*this`
616  
        @return `*this`
617  

617  

618  
        @par BNF
618  
        @par BNF
619  
        @code
619  
        @code
620  
        userinfo      = [ [ user ] [ ':' password ] ]
620  
        userinfo      = [ [ user ] [ ':' password ] ]
621  

621  

622  
        user          = *( unreserved / pct-encoded / sub-delims )
622  
        user          = *( unreserved / pct-encoded / sub-delims )
623  
        password      = *( unreserved / pct-encoded / sub-delims / ":" )
623  
        password      = *( unreserved / pct-encoded / sub-delims / ":" )
624  
        @endcode
624  
        @endcode
625  

625  

626  
        @par Specification
626  
        @par Specification
627  
        @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.2.1">
627  
        @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.2.1">
628  
            3.2.1. User Information (rfc3986)</a>
628  
            3.2.1. User Information (rfc3986)</a>
629  

629  

630  
        @see
630  
        @see
631  
            @ref remove_password,
631  
            @ref remove_password,
632  
            @ref set_encoded_password,
632  
            @ref set_encoded_password,
633  
            @ref set_encoded_user,
633  
            @ref set_encoded_user,
634  
            @ref set_password.
634  
            @ref set_password.
635  
    */
635  
    */
636  
    url_base&
636  
    url_base&
637  
    set_user(
637  
    set_user(
638  
        core::string_view s);
638  
        core::string_view s);
639  

639  

640  
    /** Set the user
640  
    /** Set the user
641  

641  

642  
        This function sets the user part of the
642  
        This function sets the user part of the
643  
        userinfo the the string, which may
643  
        userinfo the the string, which may
644  
        contain percent-escapes.
644  
        contain percent-escapes.
645  
        Escapes in the string are preserved,
645  
        Escapes in the string are preserved,
646  
        and reserved characters in the string
646  
        and reserved characters in the string
647  
        are percent-escaped in the result.
647  
        are percent-escaped in the result.
648  

648  

649  
        @par Example
649  
        @par Example
650  
        @code
650  
        @code
651  
        assert( url().set_encoded_user("john%20doe").userinfo() == "john doe" );
651  
        assert( url().set_encoded_user("john%20doe").userinfo() == "john doe" );
652  
        @endcode
652  
        @endcode
653  

653  

654  
        @par Postconditions
654  
        @par Postconditions
655  
        @code
655  
        @code
656  
        this->has_authority() == true && this->has_userinfo() == true
656  
        this->has_authority() == true && this->has_userinfo() == true
657  
        @endcode
657  
        @endcode
658  

658  

659  
        @par Complexity
659  
        @par Complexity
660  
        Linear in `this->size() + s.size()`.
660  
        Linear in `this->size() + s.size()`.
661  

661  

662  
        @par Exception Safety
662  
        @par Exception Safety
663  
        Strong guarantee.
663  
        Strong guarantee.
664  
        Calls to allocate may throw.
664  
        Calls to allocate may throw.
665  

665  

666  
        @throw system_error
666  
        @throw system_error
667  
        `s` contains an invalid percent-encoding.
667  
        `s` contains an invalid percent-encoding.
668  

668  

669  
        @param s The string to set.
669  
        @param s The string to set.
670  

670  

671  
        @return `*this`
671  
        @return `*this`
672  

672  

673  
        @return `*this`
673  
        @return `*this`
674  

674  

675  
        @par BNF
675  
        @par BNF
676  
        @code
676  
        @code
677  
        userinfo      = [ [ user ] [ ':' password ] ]
677  
        userinfo      = [ [ user ] [ ':' password ] ]
678  

678  

679  
        user          = *( unreserved / pct-encoded / sub-delims )
679  
        user          = *( unreserved / pct-encoded / sub-delims )
680  
        password      = *( unreserved / pct-encoded / sub-delims / ":" )
680  
        password      = *( unreserved / pct-encoded / sub-delims / ":" )
681  
        @endcode
681  
        @endcode
682  

682  

683  
        @par Specification
683  
        @par Specification
684  
        @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.2.1">
684  
        @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.2.1">
685  
            3.2.1. User Information (rfc3986)</a>
685  
            3.2.1. User Information (rfc3986)</a>
686  

686  

687  
        @see
687  
        @see
688  
            @ref remove_password,
688  
            @ref remove_password,
689  
            @ref set_encoded_password,
689  
            @ref set_encoded_password,
690  
            @ref set_password,
690  
            @ref set_password,
691  
            @ref set_user.
691  
            @ref set_user.
692  
    */
692  
    */
693  
    url_base&
693  
    url_base&
694  
    set_encoded_user(
694  
    set_encoded_user(
695  
        pct_string_view s);
695  
        pct_string_view s);
696  

696  

697  
    /** Set the password.
697  
    /** Set the password.
698  

698  

699  
        This function sets the password in
699  
        This function sets the password in
700  
        the userinfo to the string.
700  
        the userinfo to the string.
701  
        Reserved characters in the string are
701  
        Reserved characters in the string are
702  
        percent-escaped in the result.
702  
        percent-escaped in the result.
703  

703  

704  
        @note
704  
        @note
705  
        The interpretation of the userinfo as
705  
        The interpretation of the userinfo as
706  
        individual user and password components
706  
        individual user and password components
707  
        is scheme-dependent. Transmitting
707  
        is scheme-dependent. Transmitting
708  
        passwords in URLs is deprecated.
708  
        passwords in URLs is deprecated.
709  

709  

710  
        @par Example
710  
        @par Example
711  
        @code
711  
        @code
712  
        assert( url("http://user@example.com").set_password( "pass" ).encoded_userinfo() == "user:pass" );
712  
        assert( url("http://user@example.com").set_password( "pass" ).encoded_userinfo() == "user:pass" );
713  
        @endcode
713  
        @endcode
714  

714  

715  
        @par Postconditions
715  
        @par Postconditions
716  
        @code
716  
        @code
717  
        this->has_password() == true && this->password() == s
717  
        this->has_password() == true && this->password() == s
718  
        @endcode
718  
        @endcode
719  

719  

720  
        @par Exception Safety
720  
        @par Exception Safety
721  
        Strong guarantee.
721  
        Strong guarantee.
722  
        Calls to allocate may throw.
722  
        Calls to allocate may throw.
723  

723  

724  
        @param s The string to set. This string may
724  
        @param s The string to set. This string may
725  
        contain any characters, including nulls.
725  
        contain any characters, including nulls.
726  

726  

727  
        @return `*this`
727  
        @return `*this`
728  

728  

729  
        @par BNF
729  
        @par BNF
730  
        @code
730  
        @code
731  
        userinfo      = [ [ user ] [ ':' password ] ]
731  
        userinfo      = [ [ user ] [ ':' password ] ]
732  

732  

733  
        user          = *( unreserved / pct-encoded / sub-delims )
733  
        user          = *( unreserved / pct-encoded / sub-delims )
734  
        password      = *( unreserved / pct-encoded / sub-delims / ":" )
734  
        password      = *( unreserved / pct-encoded / sub-delims / ":" )
735  
        @endcode
735  
        @endcode
736  

736  

737  
        @par Specification
737  
        @par Specification
738  
        @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.2.1">
738  
        @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.2.1">
739  
            3.2.1. User Information (rfc3986)</a>
739  
            3.2.1. User Information (rfc3986)</a>
740  

740  

741  
        @see
741  
        @see
742  
            @ref remove_password,
742  
            @ref remove_password,
743  
            @ref set_encoded_password,
743  
            @ref set_encoded_password,
744  
            @ref set_encoded_user,
744  
            @ref set_encoded_user,
745  
            @ref set_user.
745  
            @ref set_user.
746  
    */
746  
    */
747  
    url_base&
747  
    url_base&
748  
    set_password(
748  
    set_password(
749  
        core::string_view s);
749  
        core::string_view s);
750  

750  

751  
    /** Set the password.
751  
    /** Set the password.
752  

752  

753  
        This function sets the password in
753  
        This function sets the password in
754  
        the userinfo to the string, which
754  
        the userinfo to the string, which
755  
        may contain percent-escapes.
755  
        may contain percent-escapes.
756  
        Escapes in the string are preserved,
756  
        Escapes in the string are preserved,
757  
        and reserved characters in the string
757  
        and reserved characters in the string
758  
        are percent-escaped in the result.
758  
        are percent-escaped in the result.
759  

759  

760  
        @note
760  
        @note
761  
        The interpretation of the userinfo as
761  
        The interpretation of the userinfo as
762  
        individual user and password components
762  
        individual user and password components
763  
        is scheme-dependent. Transmitting
763  
        is scheme-dependent. Transmitting
764  
        passwords in URLs is deprecated.
764  
        passwords in URLs is deprecated.
765  

765  

766  
        @par Example
766  
        @par Example
767  
        @code
767  
        @code
768  
        assert( url("http://user@example.com").set_encoded_password( "pass" ).encoded_userinfo() == "user:pass" );
768  
        assert( url("http://user@example.com").set_encoded_password( "pass" ).encoded_userinfo() == "user:pass" );
769  
        @endcode
769  
        @endcode
770  

770  

771  
        @par Postconditions
771  
        @par Postconditions
772  
        @code
772  
        @code
773  
        this->has_password() == true
773  
        this->has_password() == true
774  
        @endcode
774  
        @endcode
775  

775  

776  
        @par Exception Safety
776  
        @par Exception Safety
777  
        Strong guarantee.
777  
        Strong guarantee.
778  
        Calls to allocate may throw.
778  
        Calls to allocate may throw.
779  

779  

780  
        @throw system_error
780  
        @throw system_error
781  
        `s` contains an invalid percent-encoding.
781  
        `s` contains an invalid percent-encoding.
782  

782  

783  
        @param s The string to set. This string may
783  
        @param s The string to set. This string may
784  
        contain any characters, including nulls.
784  
        contain any characters, including nulls.
785  
        @return `*this`
785  
        @return `*this`
786  

786  

787  
        @par BNF
787  
        @par BNF
788  
        @code
788  
        @code
789  
        userinfo      = [ [ user ] [ ':' password ] ]
789  
        userinfo      = [ [ user ] [ ':' password ] ]
790  

790  

791  
        user          = *( unreserved / pct-encoded / sub-delims )
791  
        user          = *( unreserved / pct-encoded / sub-delims )
792  
        password      = *( unreserved / pct-encoded / sub-delims / ":" )
792  
        password      = *( unreserved / pct-encoded / sub-delims / ":" )
793  
        @endcode
793  
        @endcode
794  

794  

795  
        @par Specification
795  
        @par Specification
796  
        @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.2.1">
796  
        @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.2.1">
797  
            3.2.1. User Information (rfc3986)</a>
797  
            3.2.1. User Information (rfc3986)</a>
798  

798  

799  
        @see
799  
        @see
800  
            @ref remove_password,
800  
            @ref remove_password,
801  
            @ref set_encoded_password,
801  
            @ref set_encoded_password,
802  
            @ref set_encoded_user,
802  
            @ref set_encoded_user,
803  
            @ref set_user.
803  
            @ref set_user.
804  
    */
804  
    */
805  
    url_base&
805  
    url_base&
806  
    set_encoded_password(
806  
    set_encoded_password(
807  
        pct_string_view s);
807  
        pct_string_view s);
808  

808  

809  
    /** Remove the password
809  
    /** Remove the password
810  

810  

811  
        This function removes the password from
811  
        This function removes the password from
812  
        the userinfo if a password exists. If
812  
        the userinfo if a password exists. If
813  
        there is no userinfo or no authority,
813  
        there is no userinfo or no authority,
814  
        the call has no effect.
814  
        the call has no effect.
815  

815  

816  
        @note
816  
        @note
817  
        The interpretation of the userinfo as
817  
        The interpretation of the userinfo as
818  
        individual user and password components
818  
        individual user and password components
819  
        is scheme-dependent. Transmitting
819  
        is scheme-dependent. Transmitting
820  
        passwords in URLs is deprecated.
820  
        passwords in URLs is deprecated.
821  

821  

822  
        @par Example
822  
        @par Example
823  
        @code
823  
        @code
824  
        assert( url( "http://user:pass@example.com" ).remove_password().authority().buffer() == "user@example.com" );
824  
        assert( url( "http://user:pass@example.com" ).remove_password().authority().buffer() == "user@example.com" );
825  
        @endcode
825  
        @endcode
826  

826  

827  
        @par Postconditions
827  
        @par Postconditions
828  
        @code
828  
        @code
829  
        this->has_password() == false && this->encoded_password().empty() == true
829  
        this->has_password() == false && this->encoded_password().empty() == true
830  
        @endcode
830  
        @endcode
831  

831  

832  
        @par Complexity
832  
        @par Complexity
833  
        Linear in `this->size()`.
833  
        Linear in `this->size()`.
834  

834  

835  
        @par Exception Safety
835  
        @par Exception Safety
836  
        Throws nothing.
836  
        Throws nothing.
837  

837  

838  
        @par BNF
838  
        @par BNF
839  
        @code
839  
        @code
840  
        userinfo      = [ [ user ] [ ':' password ] ]
840  
        userinfo      = [ [ user ] [ ':' password ] ]
841  

841  

842  
        user          = *( unreserved / pct-encoded / sub-delims )
842  
        user          = *( unreserved / pct-encoded / sub-delims )
843  
        password      = *( unreserved / pct-encoded / sub-delims / ":" )
843  
        password      = *( unreserved / pct-encoded / sub-delims / ":" )
844  
        @endcode
844  
        @endcode
845  

845  

846  
        @return `*this`
846  
        @return `*this`
847  

847  

848  
        @par Specification
848  
        @par Specification
849  
        @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.2.1">
849  
        @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.2.1">
850  
            3.2.1. User Information (rfc3986)</a>
850  
            3.2.1. User Information (rfc3986)</a>
851  

851  

852  
        @see
852  
        @see
853  
            @ref set_encoded_password,
853  
            @ref set_encoded_password,
854  
            @ref set_encoded_user,
854  
            @ref set_encoded_user,
855  
            @ref set_password,
855  
            @ref set_password,
856  
            @ref set_user.
856  
            @ref set_user.
857  
    */
857  
    */
858  
    url_base&
858  
    url_base&
859  
    remove_password() noexcept;
859  
    remove_password() noexcept;
860  

860  

861  
    //--------------------------------------------
861  
    //--------------------------------------------
862  
    //
862  
    //
863  
    // Host
863  
    // Host
864  
    //
864  
    //
865  
    //--------------------------------------------
865  
    //--------------------------------------------
866  

866  

867  
    /** Set the host
867  
    /** Set the host
868  

868  

869  
        Depending on the contents of the passed
869  
        Depending on the contents of the passed
870  
        string, this function sets the host:
870  
        string, this function sets the host:
871  

871  

872  
        @li If the string is a valid IPv4 address,
872  
        @li If the string is a valid IPv4 address,
873  
        then the host is set to the address.
873  
        then the host is set to the address.
874  
        The host type is @ref host_type::ipv4.
874  
        The host type is @ref host_type::ipv4.
875  

875  

876  
        @li If the string is a valid IPv6 address
876  
        @li If the string is a valid IPv6 address
877  
        enclosed in square brackets, then the
877  
        enclosed in square brackets, then the
878  
        host is set to that address.
878  
        host is set to that address.
879  
        The host type is @ref host_type::ipv6.
879  
        The host type is @ref host_type::ipv6.
880  

880  

881  
        @li If the string is a valid IPvFuture
881  
        @li If the string is a valid IPvFuture
882  
        address enclosed in square brackets, then
882  
        address enclosed in square brackets, then
883  
        the host is set to that address.
883  
        the host is set to that address.
884  
        The host type is @ref host_type::ipvfuture.
884  
        The host type is @ref host_type::ipvfuture.
885  

885  

886  
        @li Otherwise, the host name is set to
886  
        @li Otherwise, the host name is set to
887  
        the string, which may be empty.
887  
        the string, which may be empty.
888  
        Reserved characters in the string are
888  
        Reserved characters in the string are
889  
        percent-escaped in the result.
889  
        percent-escaped in the result.
890  
        The host type is @ref host_type::name.
890  
        The host type is @ref host_type::name.
891  

891  

892  
        In all cases, when this function returns,
892  
        In all cases, when this function returns,
893  
        the URL contains an authority.
893  
        the URL contains an authority.
894  

894  

895  
        @par Example
895  
        @par Example
896  
        @code
896  
        @code
897  
        assert( url( "http://www.example.com" ).set_host( "127.0.0.1" ).buffer() == "http://127.0.0.1" );
897  
        assert( url( "http://www.example.com" ).set_host( "127.0.0.1" ).buffer() == "http://127.0.0.1" );
898  
        @endcode
898  
        @endcode
899  

899  

900  
        @par Postconditions
900  
        @par Postconditions
901  
        @code
901  
        @code
902  
        this->has_authority() == true
902  
        this->has_authority() == true
903  
        @endcode
903  
        @endcode
904  

904  

905  
        @par Complexity
905  
        @par Complexity
906  
        Linear in `this->size() + s.size()`.
906  
        Linear in `this->size() + s.size()`.
907  

907  

908  
        @par Exception Safety
908  
        @par Exception Safety
909  
        Strong guarantee.
909  
        Strong guarantee.
910  
        Calls to allocate may throw.
910  
        Calls to allocate may throw.
911  

911  

912  
        @par BNF
912  
        @par BNF
913  
        @code
913  
        @code
914  
        host        = IP-literal / IPv4address / reg-name
914  
        host        = IP-literal / IPv4address / reg-name
915  

915  

916  
        IP-literal  = "[" ( IPv6address / IPvFuture  ) "]"
916  
        IP-literal  = "[" ( IPv6address / IPvFuture  ) "]"
917  

917  

918  
        reg-name    = *( unreserved / pct-encoded / "-" / ".")
918  
        reg-name    = *( unreserved / pct-encoded / "-" / ".")
919  
        @endcode
919  
        @endcode
920  

920  

921  
        @param s The string to set.
921  
        @param s The string to set.
922  
        @return `*this`
922  
        @return `*this`
923  

923  

924  
        @par Specification
924  
        @par Specification
925  
        @li <a href="https://en.wikipedia.org/wiki/IPv4"
925  
        @li <a href="https://en.wikipedia.org/wiki/IPv4"
926  
            >IPv4 (Wikipedia)</a>
926  
            >IPv4 (Wikipedia)</a>
927  
        @li <a href="https://datatracker.ietf.org/doc/html/rfc4291"
927  
        @li <a href="https://datatracker.ietf.org/doc/html/rfc4291"
928  
            >IP Version 6 Addressing Architecture (rfc4291)</a>
928  
            >IP Version 6 Addressing Architecture (rfc4291)</a>
929  
        @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.2.2">
929  
        @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.2.2">
930  
            3.2.2. Host (rfc3986)</a>
930  
            3.2.2. Host (rfc3986)</a>
931  

931  

932  
        @see
932  
        @see
933  
            @ref set_encoded_host,
933  
            @ref set_encoded_host,
934  
            @ref set_encoded_host_address,
934  
            @ref set_encoded_host_address,
935  
            @ref set_encoded_host_name,
935  
            @ref set_encoded_host_name,
936  
            @ref set_host_address,
936  
            @ref set_host_address,
937  
            @ref set_host_ipv4,
937  
            @ref set_host_ipv4,
938  
            @ref set_host_ipv6,
938  
            @ref set_host_ipv6,
939  
            @ref set_host_ipvfuture,
939  
            @ref set_host_ipvfuture,
940  
            @ref set_host_name.
940  
            @ref set_host_name.
941  
    */
941  
    */
942  
    url_base&
942  
    url_base&
943  
    set_host(
943  
    set_host(
944  
        core::string_view s);
944  
        core::string_view s);
945  

945  

946  
    /** Set the host
946  
    /** Set the host
947  

947  

948  
        Depending on the contents of the passed
948  
        Depending on the contents of the passed
949  
        string, this function sets the host:
949  
        string, this function sets the host:
950  

950  

951  
        @li If the string is a valid IPv4 address,
951  
        @li If the string is a valid IPv4 address,
952  
        then the host is set to the address.
952  
        then the host is set to the address.
953  
        The host type is @ref host_type::ipv4.
953  
        The host type is @ref host_type::ipv4.
954  

954  

955  
        @li If the string is a valid IPv6 address
955  
        @li If the string is a valid IPv6 address
956  
        enclosed in square brackets, then the
956  
        enclosed in square brackets, then the
957  
        host is set to that address.
957  
        host is set to that address.
958  
        The host type is @ref host_type::ipv6.
958  
        The host type is @ref host_type::ipv6.
959  

959  

960  
        @li If the string is a valid IPvFuture
960  
        @li If the string is a valid IPvFuture
961  
        address enclosed in square brackets, then
961  
        address enclosed in square brackets, then
962  
        the host is set to that address.
962  
        the host is set to that address.
963  
        The host type is @ref host_type::ipvfuture.
963  
        The host type is @ref host_type::ipvfuture.
964  

964  

965  
        @li Otherwise, the host name is set to
965  
        @li Otherwise, the host name is set to
966  
        the string. This string can contain percent
966  
        the string. This string can contain percent
967  
        escapes, or can be empty.
967  
        escapes, or can be empty.
968  
        Escapes in the string are preserved,
968  
        Escapes in the string are preserved,
969  
        and reserved characters in the string
969  
        and reserved characters in the string
970  
        are percent-escaped in the result.
970  
        are percent-escaped in the result.
971  
        The host type is @ref host_type::name.
971  
        The host type is @ref host_type::name.
972  

972  

973  
        In all cases, when this function returns,
973  
        In all cases, when this function returns,
974  
        the URL contains an authority.
974  
        the URL contains an authority.
975  

975  

976  
        @par Example
976  
        @par Example
977  
        @code
977  
        @code
978  
        assert( url( "http://www.example.com" ).set_host( "127.0.0.1" ).buffer() == "http://127.0.0.1" );
978  
        assert( url( "http://www.example.com" ).set_host( "127.0.0.1" ).buffer() == "http://127.0.0.1" );
979  
        @endcode
979  
        @endcode
980  

980  

981  
        @par Postconditions
981  
        @par Postconditions
982  
        @code
982  
        @code
983  
        this->has_authority() == true
983  
        this->has_authority() == true
984  
        @endcode
984  
        @endcode
985  

985  

986  
        @par Complexity
986  
        @par Complexity
987  
        Linear in `this->size() + s.size()`.
987  
        Linear in `this->size() + s.size()`.
988  

988  

989  
        @par Exception Safety
989  
        @par Exception Safety
990  
        Strong guarantee.
990  
        Strong guarantee.
991  
        Calls to allocate may throw.
991  
        Calls to allocate may throw.
992  
        Exceptions thrown on invalid input.
992  
        Exceptions thrown on invalid input.
993  

993  

994  
        @throw system_error
994  
        @throw system_error
995  
        `s` contains an invalid percent-encoding.
995  
        `s` contains an invalid percent-encoding.
996  

996  

997  
        @param s The string to set.
997  
        @param s The string to set.
998  

998  

999  
        @return `*this`
999  
        @return `*this`
1000  

1000  

1001  
        @par BNF
1001  
        @par BNF
1002  
        @code
1002  
        @code
1003  
        host        = IP-literal / IPv4address / reg-name
1003  
        host        = IP-literal / IPv4address / reg-name
1004  

1004  

1005  
        IP-literal  = "[" ( IPv6address / IPvFuture  ) "]"
1005  
        IP-literal  = "[" ( IPv6address / IPvFuture  ) "]"
1006  

1006  

1007  
        reg-name    = *( unreserved / pct-encoded / "-" / ".")
1007  
        reg-name    = *( unreserved / pct-encoded / "-" / ".")
1008  
        @endcode
1008  
        @endcode
1009  

1009  

1010  
        @par Specification
1010  
        @par Specification
1011  
        @li <a href="https://en.wikipedia.org/wiki/IPv4"
1011  
        @li <a href="https://en.wikipedia.org/wiki/IPv4"
1012  
            >IPv4 (Wikipedia)</a>
1012  
            >IPv4 (Wikipedia)</a>
1013  
        @li <a href="https://datatracker.ietf.org/doc/html/rfc4291"
1013  
        @li <a href="https://datatracker.ietf.org/doc/html/rfc4291"
1014  
            >IP Version 6 Addressing Architecture (rfc4291)</a>
1014  
            >IP Version 6 Addressing Architecture (rfc4291)</a>
1015  
        @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.2.2">
1015  
        @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.2.2">
1016  
            3.2.2. Host (rfc3986)</a>
1016  
            3.2.2. Host (rfc3986)</a>
1017  

1017  

1018  
        @see
1018  
        @see
1019  
            @ref set_encoded_host_address,
1019  
            @ref set_encoded_host_address,
1020  
            @ref set_encoded_host_name,
1020  
            @ref set_encoded_host_name,
1021  
            @ref set_host,
1021  
            @ref set_host,
1022  
            @ref set_host_address,
1022  
            @ref set_host_address,
1023  
            @ref set_host_ipv4,
1023  
            @ref set_host_ipv4,
1024  
            @ref set_host_ipv6,
1024  
            @ref set_host_ipv6,
1025  
            @ref set_host_ipvfuture,
1025  
            @ref set_host_ipvfuture,
1026  
            @ref set_host_name.
1026  
            @ref set_host_name.
1027  
    */
1027  
    */
1028  
    url_base&
1028  
    url_base&
1029  
    set_encoded_host(pct_string_view s);
1029  
    set_encoded_host(pct_string_view s);
1030  

1030  

1031  
    /** Set the host to an address
1031  
    /** Set the host to an address
1032  

1032  

1033  
        Depending on the contents of the passed
1033  
        Depending on the contents of the passed
1034  
        string, this function sets the host:
1034  
        string, this function sets the host:
1035  

1035  

1036  
        @li If the string is a valid IPv4 address,
1036  
        @li If the string is a valid IPv4 address,
1037  
        then the host is set to the address.
1037  
        then the host is set to the address.
1038  
        The host type is @ref host_type::ipv4.
1038  
        The host type is @ref host_type::ipv4.
1039  

1039  

1040  
        @li If the string is a valid IPv6 address,
1040  
        @li If the string is a valid IPv6 address,
1041  
        then the host is set to that address.
1041  
        then the host is set to that address.
1042  
        The host type is @ref host_type::ipv6.
1042  
        The host type is @ref host_type::ipv6.
1043  

1043  

1044  
        @li If the string is a valid IPvFuture,
1044  
        @li If the string is a valid IPvFuture,
1045  
        then the host is set to that address.
1045  
        then the host is set to that address.
1046  
        The host type is @ref host_type::ipvfuture.
1046  
        The host type is @ref host_type::ipvfuture.
1047  

1047  

1048  
        @li Otherwise, the host name is set to
1048  
        @li Otherwise, the host name is set to
1049  
        the string, which may be empty.
1049  
        the string, which may be empty.
1050  
        Reserved characters in the string are
1050  
        Reserved characters in the string are
1051  
        percent-escaped in the result.
1051  
        percent-escaped in the result.
1052  
        The host type is @ref host_type::name.
1052  
        The host type is @ref host_type::name.
1053  

1053  

1054  
        In all cases, when this function returns,
1054  
        In all cases, when this function returns,
1055  
        the URL contains an authority.
1055  
        the URL contains an authority.
1056  

1056  

1057  
        @par Example
1057  
        @par Example
1058  
        @code
1058  
        @code
1059  
        assert( url( "http://www.example.com" ).set_host_address( "127.0.0.1" ).buffer() == "http://127.0.0.1" );
1059  
        assert( url( "http://www.example.com" ).set_host_address( "127.0.0.1" ).buffer() == "http://127.0.0.1" );
1060  
        @endcode
1060  
        @endcode
1061  

1061  

1062  
        @par Postconditions
1062  
        @par Postconditions
1063  
        @code
1063  
        @code
1064  
        this->has_authority() == true
1064  
        this->has_authority() == true
1065  
        @endcode
1065  
        @endcode
1066  

1066  

1067  
        @par Complexity
1067  
        @par Complexity
1068  
        Linear in `s.size()`.
1068  
        Linear in `s.size()`.
1069  

1069  

1070  
        @par Exception Safety
1070  
        @par Exception Safety
1071  
        Strong guarantee.
1071  
        Strong guarantee.
1072  
        Calls to allocate may throw.
1072  
        Calls to allocate may throw.
1073  

1073  

1074  
        @par BNF
1074  
        @par BNF
1075  
        @code
1075  
        @code
1076  
        IPv4address = dec-octet "." dec-octet "." dec-octet "." dec-octet
1076  
        IPv4address = dec-octet "." dec-octet "." dec-octet "." dec-octet
1077  

1077  

1078  
        dec-octet   = DIGIT                 ; 0-9
1078  
        dec-octet   = DIGIT                 ; 0-9
1079  
                    / %x31-39 DIGIT         ; 10-99
1079  
                    / %x31-39 DIGIT         ; 10-99
1080  
                    / "1" 2DIGIT            ; 100-199
1080  
                    / "1" 2DIGIT            ; 100-199
1081  
                    / "2" %x30-34 DIGIT     ; 200-249
1081  
                    / "2" %x30-34 DIGIT     ; 200-249
1082  
                    / "25" %x30-35          ; 250-255
1082  
                    / "25" %x30-35          ; 250-255
1083  

1083  

1084  
        IPv6address =                            6( h16 ":" ) ls32
1084  
        IPv6address =                            6( h16 ":" ) ls32
1085  
                    /                       "::" 5( h16 ":" ) ls32
1085  
                    /                       "::" 5( h16 ":" ) ls32
1086  
                    / [               h16 ] "::" 4( h16 ":" ) ls32
1086  
                    / [               h16 ] "::" 4( h16 ":" ) ls32
1087  
                    / [ *1( h16 ":" ) h16 ] "::" 3( h16 ":" ) ls32
1087  
                    / [ *1( h16 ":" ) h16 ] "::" 3( h16 ":" ) ls32
1088  
                    / [ *2( h16 ":" ) h16 ] "::" 2( h16 ":" ) ls32
1088  
                    / [ *2( h16 ":" ) h16 ] "::" 2( h16 ":" ) ls32
1089  
                    / [ *3( h16 ":" ) h16 ] "::"    h16 ":"   ls32
1089  
                    / [ *3( h16 ":" ) h16 ] "::"    h16 ":"   ls32
1090  
                    / [ *4( h16 ":" ) h16 ] "::"              ls32
1090  
                    / [ *4( h16 ":" ) h16 ] "::"              ls32
1091  
                    / [ *5( h16 ":" ) h16 ] "::"              h16
1091  
                    / [ *5( h16 ":" ) h16 ] "::"              h16
1092  
                    / [ *6( h16 ":" ) h16 ] "::"
1092  
                    / [ *6( h16 ":" ) h16 ] "::"
1093  

1093  

1094  
        ls32        = ( h16 ":" h16 ) / IPv4address
1094  
        ls32        = ( h16 ":" h16 ) / IPv4address
1095  
                    ; least-significant 32 bits of address
1095  
                    ; least-significant 32 bits of address
1096  

1096  

1097  
        h16         = 1*4HEXDIG
1097  
        h16         = 1*4HEXDIG
1098  
                    ; 16 bits of address represented in hexadecimal
1098  
                    ; 16 bits of address represented in hexadecimal
1099  

1099  

1100  
        IPvFuture     = "v" 1*HEXDIG "." 1*( unreserved / sub-delims / ":" )
1100  
        IPvFuture     = "v" 1*HEXDIG "." 1*( unreserved / sub-delims / ":" )
1101  

1101  

1102  
        reg-name    = *( unreserved / pct-encoded / "-" / ".")
1102  
        reg-name    = *( unreserved / pct-encoded / "-" / ".")
1103  
        @endcode
1103  
        @endcode
1104  

1104  

1105  
        @param s The string to set.
1105  
        @param s The string to set.
1106  
        @return `*this`
1106  
        @return `*this`
1107  

1107  

1108  
        @par Specification
1108  
        @par Specification
1109  
        @li <a href="https://en.wikipedia.org/wiki/IPv4"
1109  
        @li <a href="https://en.wikipedia.org/wiki/IPv4"
1110  
            >IPv4 (Wikipedia)</a>
1110  
            >IPv4 (Wikipedia)</a>
1111  
        @li <a href="https://datatracker.ietf.org/doc/html/rfc4291"
1111  
        @li <a href="https://datatracker.ietf.org/doc/html/rfc4291"
1112  
            >IP Version 6 Addressing Architecture (rfc4291)</a>
1112  
            >IP Version 6 Addressing Architecture (rfc4291)</a>
1113  
        @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.2.2">
1113  
        @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.2.2">
1114  
            3.2.2. Host (rfc3986)</a>
1114  
            3.2.2. Host (rfc3986)</a>
1115  

1115  

1116  
        @see
1116  
        @see
1117  
            @ref set_encoded_host,
1117  
            @ref set_encoded_host,
1118  
            @ref set_encoded_host_address,
1118  
            @ref set_encoded_host_address,
1119  
            @ref set_encoded_host_name,
1119  
            @ref set_encoded_host_name,
1120  
            @ref set_host,
1120  
            @ref set_host,
1121  
            @ref set_host_address,
1121  
            @ref set_host_address,
1122  
            @ref set_host_ipv4,
1122  
            @ref set_host_ipv4,
1123  
            @ref set_host_ipv6,
1123  
            @ref set_host_ipv6,
1124  
            @ref set_host_ipvfuture,
1124  
            @ref set_host_ipvfuture,
1125  
            @ref set_host_name.
1125  
            @ref set_host_name.
1126  
    */
1126  
    */
1127  
    url_base&
1127  
    url_base&
1128  
    set_host_address(core::string_view s);
1128  
    set_host_address(core::string_view s);
1129  

1129  

1130  
    /** Set the host to an address
1130  
    /** Set the host to an address
1131  

1131  

1132  
        Depending on the contents of the passed
1132  
        Depending on the contents of the passed
1133  
        string, this function sets the host:
1133  
        string, this function sets the host:
1134  

1134  

1135  
        @li If the string is a valid IPv4 address,
1135  
        @li If the string is a valid IPv4 address,
1136  
        then the host is set to the address.
1136  
        then the host is set to the address.
1137  
        The host type is @ref host_type::ipv4.
1137  
        The host type is @ref host_type::ipv4.
1138  

1138  

1139  
        @li If the string is a valid IPv6 address,
1139  
        @li If the string is a valid IPv6 address,
1140  
        then the host is set to that address.
1140  
        then the host is set to that address.
1141  
        The host type is @ref host_type::ipv6.
1141  
        The host type is @ref host_type::ipv6.
1142  

1142  

1143  
        @li If the string is a valid IPvFuture,
1143  
        @li If the string is a valid IPvFuture,
1144  
        then the host is set to that address.
1144  
        then the host is set to that address.
1145  
        The host type is @ref host_type::ipvfuture.
1145  
        The host type is @ref host_type::ipvfuture.
1146  

1146  

1147  
        @li Otherwise, the host name is set to
1147  
        @li Otherwise, the host name is set to
1148  
        the string. This string can contain percent
1148  
        the string. This string can contain percent
1149  
        escapes, or can be empty.
1149  
        escapes, or can be empty.
1150  
        Escapes in the string are preserved,
1150  
        Escapes in the string are preserved,
1151  
        and reserved characters in the string
1151  
        and reserved characters in the string
1152  
        are percent-escaped in the result.
1152  
        are percent-escaped in the result.
1153  
        The host type is @ref host_type::name.
1153  
        The host type is @ref host_type::name.
1154  

1154  

1155  
        In all cases, when this function returns,
1155  
        In all cases, when this function returns,
1156  
        the URL contains an authority.
1156  
        the URL contains an authority.
1157  

1157  

1158  
        @par Example
1158  
        @par Example
1159  
        @code
1159  
        @code
1160  
        assert( url( "http://www.example.com" ).set_host( "127.0.0.1" ).buffer() == "http://127.0.0.1" );
1160  
        assert( url( "http://www.example.com" ).set_host( "127.0.0.1" ).buffer() == "http://127.0.0.1" );
1161  
        @endcode
1161  
        @endcode
1162  

1162  

1163  
        @par Postconditions
1163  
        @par Postconditions
1164  
        @code
1164  
        @code
1165  
        this->has_authority() == true
1165  
        this->has_authority() == true
1166  
        @endcode
1166  
        @endcode
1167  

1167  

1168  
        @par Complexity
1168  
        @par Complexity
1169  
        Linear in `this->size() + s.size()`.
1169  
        Linear in `this->size() + s.size()`.
1170  

1170  

1171  
        @par Exception Safety
1171  
        @par Exception Safety
1172  
        Strong guarantee.
1172  
        Strong guarantee.
1173  
        Calls to allocate may throw.
1173  
        Calls to allocate may throw.
1174  
        Exceptions thrown on invalid input.
1174  
        Exceptions thrown on invalid input.
1175  

1175  

1176  
        @throw system_error
1176  
        @throw system_error
1177  
        `s` contains an invalid percent-encoding.
1177  
        `s` contains an invalid percent-encoding.
1178  

1178  

1179  
        @par BNF
1179  
        @par BNF
1180  
        @code
1180  
        @code
1181  
        IPv4address = dec-octet "." dec-octet "." dec-octet "." dec-octet
1181  
        IPv4address = dec-octet "." dec-octet "." dec-octet "." dec-octet
1182  

1182  

1183  
        dec-octet   = DIGIT                 ; 0-9
1183  
        dec-octet   = DIGIT                 ; 0-9
1184  
                    / %x31-39 DIGIT         ; 10-99
1184  
                    / %x31-39 DIGIT         ; 10-99
1185  
                    / "1" 2DIGIT            ; 100-199
1185  
                    / "1" 2DIGIT            ; 100-199
1186  
                    / "2" %x30-34 DIGIT     ; 200-249
1186  
                    / "2" %x30-34 DIGIT     ; 200-249
1187  
                    / "25" %x30-35          ; 250-255
1187  
                    / "25" %x30-35          ; 250-255
1188  

1188  

1189  
        IPv6address =                            6( h16 ":" ) ls32
1189  
        IPv6address =                            6( h16 ":" ) ls32
1190  
                    /                       "::" 5( h16 ":" ) ls32
1190  
                    /                       "::" 5( h16 ":" ) ls32
1191  
                    / [               h16 ] "::" 4( h16 ":" ) ls32
1191  
                    / [               h16 ] "::" 4( h16 ":" ) ls32
1192  
                    / [ *1( h16 ":" ) h16 ] "::" 3( h16 ":" ) ls32
1192  
                    / [ *1( h16 ":" ) h16 ] "::" 3( h16 ":" ) ls32
1193  
                    / [ *2( h16 ":" ) h16 ] "::" 2( h16 ":" ) ls32
1193  
                    / [ *2( h16 ":" ) h16 ] "::" 2( h16 ":" ) ls32
1194  
                    / [ *3( h16 ":" ) h16 ] "::"    h16 ":"   ls32
1194  
                    / [ *3( h16 ":" ) h16 ] "::"    h16 ":"   ls32
1195  
                    / [ *4( h16 ":" ) h16 ] "::"              ls32
1195  
                    / [ *4( h16 ":" ) h16 ] "::"              ls32
1196  
                    / [ *5( h16 ":" ) h16 ] "::"              h16
1196  
                    / [ *5( h16 ":" ) h16 ] "::"              h16
1197  
                    / [ *6( h16 ":" ) h16 ] "::"
1197  
                    / [ *6( h16 ":" ) h16 ] "::"
1198  

1198  

1199  
        ls32        = ( h16 ":" h16 ) / IPv4address
1199  
        ls32        = ( h16 ":" h16 ) / IPv4address
1200  
                    ; least-significant 32 bits of address
1200  
                    ; least-significant 32 bits of address
1201  

1201  

1202  
        h16         = 1*4HEXDIG
1202  
        h16         = 1*4HEXDIG
1203  
                    ; 16 bits of address represented in hexadecimal
1203  
                    ; 16 bits of address represented in hexadecimal
1204  

1204  

1205  
        IPvFuture     = "v" 1*HEXDIG "." 1*( unreserved / sub-delims / ":" )
1205  
        IPvFuture     = "v" 1*HEXDIG "." 1*( unreserved / sub-delims / ":" )
1206  

1206  

1207  
        reg-name    = *( unreserved / pct-encoded / "-" / ".")
1207  
        reg-name    = *( unreserved / pct-encoded / "-" / ".")
1208  
        @endcode
1208  
        @endcode
1209  

1209  

1210  
        @param s The string to set.
1210  
        @param s The string to set.
1211  
        @return `*this`
1211  
        @return `*this`
1212  

1212  

1213  
        @par Specification
1213  
        @par Specification
1214  
        @li <a href="https://en.wikipedia.org/wiki/IPv4"
1214  
        @li <a href="https://en.wikipedia.org/wiki/IPv4"
1215  
            >IPv4 (Wikipedia)</a>
1215  
            >IPv4 (Wikipedia)</a>
1216  
        @li <a href="https://datatracker.ietf.org/doc/html/rfc4291"
1216  
        @li <a href="https://datatracker.ietf.org/doc/html/rfc4291"
1217  
            >IP Version 6 Addressing Architecture (rfc4291)</a>
1217  
            >IP Version 6 Addressing Architecture (rfc4291)</a>
1218  
        @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.2.2">
1218  
        @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.2.2">
1219  
            3.2.2. Host (rfc3986)</a>
1219  
            3.2.2. Host (rfc3986)</a>
1220  

1220  

1221  
        @see
1221  
        @see
1222  
            @ref set_encoded_host,
1222  
            @ref set_encoded_host,
1223  
            @ref set_encoded_host_name,
1223  
            @ref set_encoded_host_name,
1224  
            @ref set_host,
1224  
            @ref set_host,
1225  
            @ref set_host_address,
1225  
            @ref set_host_address,
1226  
            @ref set_host_ipv4,
1226  
            @ref set_host_ipv4,
1227  
            @ref set_host_ipv6,
1227  
            @ref set_host_ipv6,
1228  
            @ref set_host_ipvfuture,
1228  
            @ref set_host_ipvfuture,
1229  
            @ref set_host_name.
1229  
            @ref set_host_name.
1230  
    */
1230  
    */
1231  
    url_base&
1231  
    url_base&
1232  
    set_encoded_host_address(
1232  
    set_encoded_host_address(
1233  
        pct_string_view s);
1233  
        pct_string_view s);
1234  

1234  

1235  
    /** Set the host to an address
1235  
    /** Set the host to an address
1236  

1236  

1237  
        The host is set to the specified IPv4
1237  
        The host is set to the specified IPv4
1238  
        address.
1238  
        address.
1239  
        The host type is @ref host_type::ipv4.
1239  
        The host type is @ref host_type::ipv4.
1240  

1240  

1241  
        @par Example
1241  
        @par Example
1242  
        @code
1242  
        @code
1243  
        assert( url("http://www.example.com").set_host_ipv4( ipv4_address( "127.0.0.1" ) ).buffer() == "http://127.0.0.1" );
1243  
        assert( url("http://www.example.com").set_host_ipv4( ipv4_address( "127.0.0.1" ) ).buffer() == "http://127.0.0.1" );
1244  
        @endcode
1244  
        @endcode
1245  

1245  

1246  
        @par Complexity
1246  
        @par Complexity
1247  
        Linear in `this->size()`.
1247  
        Linear in `this->size()`.
1248  

1248  

1249  
        @par Postconditions
1249  
        @par Postconditions
1250  
        @code
1250  
        @code
1251  
        this->has_authority() == true && this->host_ipv4_address() == addr && this->host_type() == host_type::ipv4
1251  
        this->has_authority() == true && this->host_ipv4_address() == addr && this->host_type() == host_type::ipv4
1252  
        @endcode
1252  
        @endcode
1253  

1253  

1254  
        @par Exception Safety
1254  
        @par Exception Safety
1255  
        Strong guarantee.
1255  
        Strong guarantee.
1256  
        Calls to allocate may throw.
1256  
        Calls to allocate may throw.
1257  

1257  

1258  
        @param addr The address to set.
1258  
        @param addr The address to set.
1259  
        @return `*this`
1259  
        @return `*this`
1260  

1260  

1261  
        @par BNF
1261  
        @par BNF
1262  
        @code
1262  
        @code
1263  
        IPv4address = dec-octet "." dec-octet "." dec-octet "." dec-octet
1263  
        IPv4address = dec-octet "." dec-octet "." dec-octet "." dec-octet
1264  

1264  

1265  
        dec-octet   = DIGIT                 ; 0-9
1265  
        dec-octet   = DIGIT                 ; 0-9
1266  
                    / %x31-39 DIGIT         ; 10-99
1266  
                    / %x31-39 DIGIT         ; 10-99
1267  
                    / "1" 2DIGIT            ; 100-199
1267  
                    / "1" 2DIGIT            ; 100-199
1268  
                    / "2" %x30-34 DIGIT     ; 200-249
1268  
                    / "2" %x30-34 DIGIT     ; 200-249
1269  
                    / "25" %x30-35          ; 250-255
1269  
                    / "25" %x30-35          ; 250-255
1270  
        @endcode
1270  
        @endcode
1271  

1271  

1272  
        @par Specification
1272  
        @par Specification
1273  
        @li <a href="https://en.wikipedia.org/wiki/IPv4"
1273  
        @li <a href="https://en.wikipedia.org/wiki/IPv4"
1274  
            >IPv4 (Wikipedia)</a>
1274  
            >IPv4 (Wikipedia)</a>
1275  
        @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.2.2">
1275  
        @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.2.2">
1276  
            3.2.2. Host (rfc3986)</a>
1276  
            3.2.2. Host (rfc3986)</a>
1277  

1277  

1278  
        @see
1278  
        @see
1279  
            @ref set_encoded_host,
1279  
            @ref set_encoded_host,
1280  
            @ref set_encoded_host_address,
1280  
            @ref set_encoded_host_address,
1281  
            @ref set_encoded_host_name,
1281  
            @ref set_encoded_host_name,
1282  
            @ref set_host,
1282  
            @ref set_host,
1283  
            @ref set_host_address,
1283  
            @ref set_host_address,
1284  
            @ref set_host_ipv6,
1284  
            @ref set_host_ipv6,
1285  
            @ref set_host_ipvfuture,
1285  
            @ref set_host_ipvfuture,
1286  
            @ref set_host_name.
1286  
            @ref set_host_name.
1287  
    */
1287  
    */
1288  
    url_base&
1288  
    url_base&
1289  
    set_host_ipv4(
1289  
    set_host_ipv4(
1290  
        ipv4_address const& addr);
1290  
        ipv4_address const& addr);
1291  

1291  

1292  
    /** Set the host to an address
1292  
    /** Set the host to an address
1293  

1293  

1294  
        The host is set to the specified IPv6
1294  
        The host is set to the specified IPv6
1295  
        address.
1295  
        address.
1296  
        The host type is @ref host_type::ipv6.
1296  
        The host type is @ref host_type::ipv6.
1297  

1297  

1298  
        @par Example
1298  
        @par Example
1299  
        @code
1299  
        @code
1300  
        assert( url().set_host_ipv6( ipv6_address( "1::6:c0a8:1" ) ).authority().buffer() == "[1::6:c0a8:1]" );
1300  
        assert( url().set_host_ipv6( ipv6_address( "1::6:c0a8:1" ) ).authority().buffer() == "[1::6:c0a8:1]" );
1301  
        @endcode
1301  
        @endcode
1302  

1302  

1303  
        @par Postconditions
1303  
        @par Postconditions
1304  
        @code
1304  
        @code
1305  
        this->has_authority() == true && this->host_ipv6_address() == addr && this->host_type() == host_type::ipv6
1305  
        this->has_authority() == true && this->host_ipv6_address() == addr && this->host_type() == host_type::ipv6
1306  
        @endcode
1306  
        @endcode
1307  

1307  

1308  
        @par Complexity
1308  
        @par Complexity
1309  
        Linear in `this->size()`.
1309  
        Linear in `this->size()`.
1310  

1310  

1311  
        @par Exception Safety
1311  
        @par Exception Safety
1312  
        Strong guarantee.
1312  
        Strong guarantee.
1313  
        Calls to allocate may throw.
1313  
        Calls to allocate may throw.
1314  

1314  

1315  
        @param addr The address to set.
1315  
        @param addr The address to set.
1316  

1316  

1317  
        @return `*this`
1317  
        @return `*this`
1318  

1318  

1319  
        @par BNF
1319  
        @par BNF
1320  
        @code
1320  
        @code
1321  
        IPv6address =                            6( h16 ":" ) ls32
1321  
        IPv6address =                            6( h16 ":" ) ls32
1322  
                    /                       "::" 5( h16 ":" ) ls32
1322  
                    /                       "::" 5( h16 ":" ) ls32
1323  
                    / [               h16 ] "::" 4( h16 ":" ) ls32
1323  
                    / [               h16 ] "::" 4( h16 ":" ) ls32
1324  
                    / [ *1( h16 ":" ) h16 ] "::" 3( h16 ":" ) ls32
1324  
                    / [ *1( h16 ":" ) h16 ] "::" 3( h16 ":" ) ls32
1325  
                    / [ *2( h16 ":" ) h16 ] "::" 2( h16 ":" ) ls32
1325  
                    / [ *2( h16 ":" ) h16 ] "::" 2( h16 ":" ) ls32
1326  
                    / [ *3( h16 ":" ) h16 ] "::"    h16 ":"   ls32
1326  
                    / [ *3( h16 ":" ) h16 ] "::"    h16 ":"   ls32
1327  
                    / [ *4( h16 ":" ) h16 ] "::"              ls32
1327  
                    / [ *4( h16 ":" ) h16 ] "::"              ls32
1328  
                    / [ *5( h16 ":" ) h16 ] "::"              h16
1328  
                    / [ *5( h16 ":" ) h16 ] "::"              h16
1329  
                    / [ *6( h16 ":" ) h16 ] "::"
1329  
                    / [ *6( h16 ":" ) h16 ] "::"
1330  

1330  

1331  
        ls32        = ( h16 ":" h16 ) / IPv4address
1331  
        ls32        = ( h16 ":" h16 ) / IPv4address
1332  
                    ; least-significant 32 bits of address
1332  
                    ; least-significant 32 bits of address
1333  

1333  

1334  
        h16         = 1*4HEXDIG
1334  
        h16         = 1*4HEXDIG
1335  
                    ; 16 bits of address represented in hexadecimal
1335  
                    ; 16 bits of address represented in hexadecimal
1336  
        @endcode
1336  
        @endcode
1337  

1337  

1338  
        @par Specification
1338  
        @par Specification
1339  
        @li <a href="https://datatracker.ietf.org/doc/html/rfc4291"
1339  
        @li <a href="https://datatracker.ietf.org/doc/html/rfc4291"
1340  
            >IP Version 6 Addressing Architecture (rfc4291)</a>
1340  
            >IP Version 6 Addressing Architecture (rfc4291)</a>
1341  
        @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.2.2">
1341  
        @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.2.2">
1342  
            3.2.2. Host (rfc3986)</a>
1342  
            3.2.2. Host (rfc3986)</a>
1343  

1343  

1344  
        @see
1344  
        @see
1345  
            @ref set_encoded_host,
1345  
            @ref set_encoded_host,
1346  
            @ref set_encoded_host_address,
1346  
            @ref set_encoded_host_address,
1347  
            @ref set_encoded_host_name,
1347  
            @ref set_encoded_host_name,
1348  
            @ref set_host,
1348  
            @ref set_host,
1349  
            @ref set_host_address,
1349  
            @ref set_host_address,
1350  
            @ref set_host_ipv4,
1350  
            @ref set_host_ipv4,
1351  
            @ref set_host_ipvfuture,
1351  
            @ref set_host_ipvfuture,
1352  
            @ref set_host_name.
1352  
            @ref set_host_name.
1353  
    */
1353  
    */
1354  
    url_base&
1354  
    url_base&
1355  
    set_host_ipv6(
1355  
    set_host_ipv6(
1356  
        ipv6_address const& addr);
1356  
        ipv6_address const& addr);
1357  

1357  

1358  
    /** Set the zone ID for an IPv6 address.
1358  
    /** Set the zone ID for an IPv6 address.
1359  

1359  

1360  
        This function sets the zone ID for the host if the host is an IPv6 address.
1360  
        This function sets the zone ID for the host if the host is an IPv6 address.
1361  
        Reserved characters in the string are percent-escaped in the result.
1361  
        Reserved characters in the string are percent-escaped in the result.
1362  

1362  

1363  
        @par Example
1363  
        @par Example
1364  
        @code
1364  
        @code
1365  
        assert( u.set_host_ipv6( ipv6_address( "fe80::1" ) ).set_zone_id( "eth0" ).buffer() == "https://[fe80::1%25eth0]" );
1365  
        assert( u.set_host_ipv6( ipv6_address( "fe80::1" ) ).set_zone_id( "eth0" ).buffer() == "https://[fe80::1%25eth0]" );
1366  
        @endcode
1366  
        @endcode
1367  

1367  

1368  
        @par Complexity
1368  
        @par Complexity
1369  
        Linear in `this->size()`.
1369  
        Linear in `this->size()`.
1370  

1370  

1371  
        @par Exception Safety
1371  
        @par Exception Safety
1372  
        Strong guarantee. Calls to allocate may throw.
1372  
        Strong guarantee. Calls to allocate may throw.
1373  

1373  

1374  
        @param s The zone ID to set.
1374  
        @param s The zone ID to set.
1375  
        @return `*this`
1375  
        @return `*this`
1376  

1376  

1377  
        @par Specification
1377  
        @par Specification
1378  
        @li <a href="https://datatracker.ietf.org/doc/html/rfc6874">RFC 6874</a>
1378  
        @li <a href="https://datatracker.ietf.org/doc/html/rfc6874">RFC 6874</a>
1379  

1379  

1380  
    */
1380  
    */
1381  
    url_base&
1381  
    url_base&
1382  
    set_zone_id(core::string_view s);
1382  
    set_zone_id(core::string_view s);
1383  

1383  

1384  
    /** Set the zone ID for an IPv6 address (percent-encoded).
1384  
    /** Set the zone ID for an IPv6 address (percent-encoded).
1385  

1385  

1386  
        This function sets the zone ID for the host if the host is an IPv6 address.
1386  
        This function sets the zone ID for the host if the host is an IPv6 address.
1387  
        Escapes in the string are preserved, and reserved characters in the string
1387  
        Escapes in the string are preserved, and reserved characters in the string
1388  
        are percent-escaped in the result.
1388  
        are percent-escaped in the result.
1389  

1389  

1390  
        @par Example
1390  
        @par Example
1391  
        @code
1391  
        @code
1392  
        assert( u.set_host_ipv6( ipv6_address( "fe80::1" ) ).set_encoded_zone_id( "eth0" ).buffer() == "https://[fe80::1%25eth0]" );
1392  
        assert( u.set_host_ipv6( ipv6_address( "fe80::1" ) ).set_encoded_zone_id( "eth0" ).buffer() == "https://[fe80::1%25eth0]" );
1393  
        @endcode
1393  
        @endcode
1394  

1394  

1395  
        @par Complexity
1395  
        @par Complexity
1396  
        Linear in `this->size()`.
1396  
        Linear in `this->size()`.
1397  

1397  

1398  
        @par Exception Safety
1398  
        @par Exception Safety
1399  
        Strong guarantee. Calls to allocate may throw.
1399  
        Strong guarantee. Calls to allocate may throw.
1400  
        Exceptions thrown on invalid input.
1400  
        Exceptions thrown on invalid input.
1401  

1401  

1402  
        @throw system_error
1402  
        @throw system_error
1403  
        `s` contains an invalid percent-encoding.
1403  
        `s` contains an invalid percent-encoding.
1404  

1404  

1405  
        @param s The zone ID to set.
1405  
        @param s The zone ID to set.
1406  
        @return `*this`
1406  
        @return `*this`
1407  

1407  

1408  
        @par Specification
1408  
        @par Specification
1409  
        @li <a href="https://datatracker.ietf.org/doc/html/rfc6874">RFC 6874</a>
1409  
        @li <a href="https://datatracker.ietf.org/doc/html/rfc6874">RFC 6874</a>
1410  

1410  

1411  
    */
1411  
    */
1412  
    url_base&
1412  
    url_base&
1413  
    set_encoded_zone_id(pct_string_view s);
1413  
    set_encoded_zone_id(pct_string_view s);
1414  

1414  

1415  
    /** Set the host to an address
1415  
    /** Set the host to an address
1416  

1416  

1417  
        The host is set to the specified IPvFuture
1417  
        The host is set to the specified IPvFuture
1418  
        string.
1418  
        string.
1419  
        The host type is @ref host_type::ipvfuture.
1419  
        The host type is @ref host_type::ipvfuture.
1420  

1420  

1421  
        @par Example
1421  
        @par Example
1422  
        @code
1422  
        @code
1423  
        assert( url().set_host_ipvfuture( "v42.bis" ).buffer() == "//[v42.bis]" );
1423  
        assert( url().set_host_ipvfuture( "v42.bis" ).buffer() == "//[v42.bis]" );
1424  
        @endcode
1424  
        @endcode
1425  

1425  

1426  
        @par Complexity
1426  
        @par Complexity
1427  
        Linear in `this->size() + s.size()`.
1427  
        Linear in `this->size() + s.size()`.
1428  

1428  

1429  
        @par Postconditions
1429  
        @par Postconditions
1430  
        @code
1430  
        @code
1431  
        this->has_authority() == true && this->host_ipvfuture) == s && this->host_type() == host_type::ipvfuture
1431  
        this->has_authority() == true && this->host_ipvfuture) == s && this->host_type() == host_type::ipvfuture
1432  
        @endcode
1432  
        @endcode
1433  

1433  

1434  
        @par Exception Safety
1434  
        @par Exception Safety
1435  
        Strong guarantee.
1435  
        Strong guarantee.
1436  
        Calls to allocate may throw.
1436  
        Calls to allocate may throw.
1437  
        Exceptions thrown on invalid input.
1437  
        Exceptions thrown on invalid input.
1438  

1438  

1439  
        @throw system_error
1439  
        @throw system_error
1440  
        `s` contains an invalid percent-encoding.
1440  
        `s` contains an invalid percent-encoding.
1441  

1441  

1442  
        @param s The string to set.
1442  
        @param s The string to set.
1443  

1443  

1444  
        @return `*this`
1444  
        @return `*this`
1445  

1445  

1446  
        @par BNF
1446  
        @par BNF
1447  
        @code
1447  
        @code
1448  
        IPvFuture     = "v" 1*HEXDIG "." 1*( unreserved / sub-delims / ":" )
1448  
        IPvFuture     = "v" 1*HEXDIG "." 1*( unreserved / sub-delims / ":" )
1449  
        @endcode
1449  
        @endcode
1450  

1450  

1451  
        @par Specification
1451  
        @par Specification
1452  
        @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.2.2">
1452  
        @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.2.2">
1453  
            3.2.2. Host (rfc3986)</a>
1453  
            3.2.2. Host (rfc3986)</a>
1454  

1454  

1455  
        @see
1455  
        @see
1456  
            @ref set_encoded_host,
1456  
            @ref set_encoded_host,
1457  
            @ref set_encoded_host_address,
1457  
            @ref set_encoded_host_address,
1458  
            @ref set_encoded_host_name,
1458  
            @ref set_encoded_host_name,
1459  
            @ref set_host,
1459  
            @ref set_host,
1460  
            @ref set_host_address,
1460  
            @ref set_host_address,
1461  
            @ref set_host_ipv4,
1461  
            @ref set_host_ipv4,
1462  
            @ref set_host_ipv6,
1462  
            @ref set_host_ipv6,
1463  
            @ref set_host_name.
1463  
            @ref set_host_name.
1464  
    */
1464  
    */
1465  
    url_base&
1465  
    url_base&
1466  
    set_host_ipvfuture(
1466  
    set_host_ipvfuture(
1467  
        core::string_view s);
1467  
        core::string_view s);
1468  

1468  

1469  
    /** Set the host to a name
1469  
    /** Set the host to a name
1470  

1470  

1471  
        The host is set to the specified string,
1471  
        The host is set to the specified string,
1472  
        which may be empty.
1472  
        which may be empty.
1473  
        Reserved characters in the string are
1473  
        Reserved characters in the string are
1474  
        percent-escaped in the result.
1474  
        percent-escaped in the result.
1475  
        The host type is @ref host_type::name.
1475  
        The host type is @ref host_type::name.
1476  

1476  

1477  
        @par Example
1477  
        @par Example
1478  
        @code
1478  
        @code
1479  
        assert( url( "http://www.example.com/index.htm").set_host_name( "localhost" ).host_address() == "localhost" );
1479  
        assert( url( "http://www.example.com/index.htm").set_host_name( "localhost" ).host_address() == "localhost" );
1480  
        @endcode
1480  
        @endcode
1481  

1481  

1482  
        @par Postconditions
1482  
        @par Postconditions
1483  
        @code
1483  
        @code
1484  
        this->has_authority() == true && this->host_ipv6_address() == addr && this->host_type() == host_type::name
1484  
        this->has_authority() == true && this->host_ipv6_address() == addr && this->host_type() == host_type::name
1485  
        @endcode
1485  
        @endcode
1486  

1486  

1487  
        @par Exception Safety
1487  
        @par Exception Safety
1488  
        Strong guarantee.
1488  
        Strong guarantee.
1489  
        Calls to allocate may throw.
1489  
        Calls to allocate may throw.
1490  

1490  

1491  
        @param s The string to set.
1491  
        @param s The string to set.
1492  
        @return `*this`
1492  
        @return `*this`
1493  

1493  

1494  
        @par BNF
1494  
        @par BNF
1495  
        @code
1495  
        @code
1496  
        reg-name    = *( unreserved / pct-encoded / "-" / ".")
1496  
        reg-name    = *( unreserved / pct-encoded / "-" / ".")
1497  
        @endcode
1497  
        @endcode
1498  

1498  

1499  
        @par Specification
1499  
        @par Specification
1500  
        @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.2.2">
1500  
        @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.2.2">
1501  
            3.2.2. Host (rfc3986)</a>
1501  
            3.2.2. Host (rfc3986)</a>
1502  

1502  

1503  
        @see
1503  
        @see
1504  
            @ref set_encoded_host,
1504  
            @ref set_encoded_host,
1505  
            @ref set_encoded_host_address,
1505  
            @ref set_encoded_host_address,
1506  
            @ref set_encoded_host_name,
1506  
            @ref set_encoded_host_name,
1507  
            @ref set_host,
1507  
            @ref set_host,
1508  
            @ref set_host_address,
1508  
            @ref set_host_address,
1509  
            @ref set_host_ipv4,
1509  
            @ref set_host_ipv4,
1510  
            @ref set_host_ipv6,
1510  
            @ref set_host_ipv6,
1511  
            @ref set_host_ipvfuture.
1511  
            @ref set_host_ipvfuture.
1512  
    */
1512  
    */
1513  
    url_base&
1513  
    url_base&
1514  
    set_host_name(
1514  
    set_host_name(
1515  
        core::string_view s);
1515  
        core::string_view s);
1516  

1516  

1517  
    /** Set the host to a name
1517  
    /** Set the host to a name
1518  

1518  

1519  
        The host is set to the specified string,
1519  
        The host is set to the specified string,
1520  
        which may contain percent-escapes and
1520  
        which may contain percent-escapes and
1521  
        can be empty.
1521  
        can be empty.
1522  
        Escapes in the string are preserved,
1522  
        Escapes in the string are preserved,
1523  
        and reserved characters in the string
1523  
        and reserved characters in the string
1524  
        are percent-escaped in the result.
1524  
        are percent-escaped in the result.
1525  
        The host type is @ref host_type::name.
1525  
        The host type is @ref host_type::name.
1526  

1526  

1527  
        @par Example
1527  
        @par Example
1528  
        @code
1528  
        @code
1529  
        assert( url( "http://www.example.com/index.htm").set_encoded_host_name( "localhost" ).host_address() == "localhost" );
1529  
        assert( url( "http://www.example.com/index.htm").set_encoded_host_name( "localhost" ).host_address() == "localhost" );
1530  
        @endcode
1530  
        @endcode
1531  

1531  

1532  
        @par Postconditions
1532  
        @par Postconditions
1533  
        @code
1533  
        @code
1534  
        this->has_authority() == true && this->host_ipv6_address() == addr && this->host_type() == host_type::name
1534  
        this->has_authority() == true && this->host_ipv6_address() == addr && this->host_type() == host_type::name
1535  
        @endcode
1535  
        @endcode
1536  

1536  

1537  
        @par Exception Safety
1537  
        @par Exception Safety
1538  
        Strong guarantee.
1538  
        Strong guarantee.
1539  
        Calls to allocate may throw.
1539  
        Calls to allocate may throw.
1540  
        Exceptions thrown on invalid input.
1540  
        Exceptions thrown on invalid input.
1541  

1541  

1542  
        @throw system_error
1542  
        @throw system_error
1543  
        `s` contains an invalid percent-encoding.
1543  
        `s` contains an invalid percent-encoding.
1544  

1544  

1545  
        @param s The string to set.
1545  
        @param s The string to set.
1546  
        @return `*this`
1546  
        @return `*this`
1547  

1547  

1548  
        @par BNF
1548  
        @par BNF
1549  
        @code
1549  
        @code
1550  
        reg-name    = *( unreserved / pct-encoded / "-" / ".")
1550  
        reg-name    = *( unreserved / pct-encoded / "-" / ".")
1551  
        @endcode
1551  
        @endcode
1552  

1552  

1553  
        @par Specification
1553  
        @par Specification
1554  
        @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.2.2">
1554  
        @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.2.2">
1555  
            3.2.2. Host (rfc3986)</a>
1555  
            3.2.2. Host (rfc3986)</a>
1556  

1556  

1557  
        @see
1557  
        @see
1558  
            @ref set_encoded_host,
1558  
            @ref set_encoded_host,
1559  
            @ref set_encoded_host_address,
1559  
            @ref set_encoded_host_address,
1560  
            @ref set_host,
1560  
            @ref set_host,
1561  
            @ref set_host_address,
1561  
            @ref set_host_address,
1562  
            @ref set_host_ipv4,
1562  
            @ref set_host_ipv4,
1563  
            @ref set_host_ipv6,
1563  
            @ref set_host_ipv6,
1564  
            @ref set_host_ipvfuture,
1564  
            @ref set_host_ipvfuture,
1565  
            @ref set_host_name.
1565  
            @ref set_host_name.
1566  
    */
1566  
    */
1567  
    url_base&
1567  
    url_base&
1568  
    set_encoded_host_name(
1568  
    set_encoded_host_name(
1569  
        pct_string_view s);
1569  
        pct_string_view s);
1570  

1570  

1571  
    //--------------------------------------------
1571  
    //--------------------------------------------
1572  

1572  

1573  
    /** Set the port
1573  
    /** Set the port
1574  

1574  

1575  
        The port is set to the specified integer.
1575  
        The port is set to the specified integer.
1576  

1576  

1577  
        @par Example
1577  
        @par Example
1578  
        @code
1578  
        @code
1579  
        assert( url( "http://www.example.com" ).set_port_number( 8080 ).authority().buffer() == "www.example.com:8080" );
1579  
        assert( url( "http://www.example.com" ).set_port_number( 8080 ).authority().buffer() == "www.example.com:8080" );
1580  
        @endcode
1580  
        @endcode
1581  

1581  

1582  
        @par Postconditions
1582  
        @par Postconditions
1583  
        @code
1583  
        @code
1584  
        this->has_authority() == true && this->has_port() == true && this->port_number() == n
1584  
        this->has_authority() == true && this->has_port() == true && this->port_number() == n
1585  
        @endcode
1585  
        @endcode
1586  

1586  

1587  
        @par Complexity
1587  
        @par Complexity
1588  
        Linear in `this->size()`.
1588  
        Linear in `this->size()`.
1589  

1589  

1590  
        @par Exception Safety
1590  
        @par Exception Safety
1591  
        Strong guarantee.
1591  
        Strong guarantee.
1592  
        Calls to allocate may throw.
1592  
        Calls to allocate may throw.
1593  

1593  

1594  
        @param n The port number to set.
1594  
        @param n The port number to set.
1595  

1595  

1596  
        @return `*this`
1596  
        @return `*this`
1597  

1597  

1598  
        @par BNF
1598  
        @par BNF
1599  
        @code
1599  
        @code
1600  
        authority     = [ userinfo "@" ] host [ ":" port ]
1600  
        authority     = [ userinfo "@" ] host [ ":" port ]
1601  

1601  

1602  
        port          = *DIGIT
1602  
        port          = *DIGIT
1603  
        @endcode
1603  
        @endcode
1604  

1604  

1605  
        @par Specification
1605  
        @par Specification
1606  
        @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.2.3">
1606  
        @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.2.3">
1607  
            3.2.3. Port (rfc3986)</a>
1607  
            3.2.3. Port (rfc3986)</a>
1608  

1608  

1609  
        @see
1609  
        @see
1610  
            @ref remove_port,
1610  
            @ref remove_port,
1611  
            @ref set_port.
1611  
            @ref set_port.
1612  
    */
1612  
    */
1613  
    url_base&
1613  
    url_base&
1614  
    set_port_number(std::uint16_t n);
1614  
    set_port_number(std::uint16_t n);
1615  

1615  

1616  
    /** Set the port
1616  
    /** Set the port
1617  

1617  

1618  
        This port is set to the string, which
1618  
        This port is set to the string, which
1619  
        must contain only digits or be empty.
1619  
        must contain only digits or be empty.
1620  
        An empty port string is distinct from
1620  
        An empty port string is distinct from
1621  
        having no port.
1621  
        having no port.
1622  

1622  

1623  
        @par Example
1623  
        @par Example
1624  
        @code
1624  
        @code
1625  
        assert( url( "http://www.example.com" ).set_port( "8080" ).authority().buffer() == "www.example.com:8080" );
1625  
        assert( url( "http://www.example.com" ).set_port( "8080" ).authority().buffer() == "www.example.com:8080" );
1626  
        @endcode
1626  
        @endcode
1627  

1627  

1628  
        @par Postconditions
1628  
        @par Postconditions
1629  
        @code
1629  
        @code
1630  
        this->has_port() == true && this->port_number() == n && this->port() == std::to_string(n)
1630  
        this->has_port() == true && this->port_number() == n && this->port() == std::to_string(n)
1631  
        @endcode
1631  
        @endcode
1632  

1632  

1633  
        @par Exception Safety
1633  
        @par Exception Safety
1634  
        Strong guarantee.
1634  
        Strong guarantee.
1635  
        Calls to allocate may throw.
1635  
        Calls to allocate may throw.
1636  
        Exceptions thrown on invalid input.
1636  
        Exceptions thrown on invalid input.
1637  

1637  

1638  
        @throw system_error
1638  
        @throw system_error
1639  
        `s` does not contain a valid port.
1639  
        `s` does not contain a valid port.
1640  

1640  

1641  
        @param s The port string to set.
1641  
        @param s The port string to set.
1642  
        @return `*this`
1642  
        @return `*this`
1643  

1643  

1644  
        @par BNF
1644  
        @par BNF
1645  
        @code
1645  
        @code
1646  
        port          = *DIGIT
1646  
        port          = *DIGIT
1647  
        @endcode
1647  
        @endcode
1648  

1648  

1649  
        @par Specification
1649  
        @par Specification
1650  
        @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.2.3">
1650  
        @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.2.3">
1651  
            3.2.3. Port (rfc3986)</a>
1651  
            3.2.3. Port (rfc3986)</a>
1652  

1652  

1653  
        @see
1653  
        @see
1654  
            @ref remove_port,
1654  
            @ref remove_port,
1655  
            @ref set_port.
1655  
            @ref set_port.
1656  
    */
1656  
    */
1657  
    url_base&
1657  
    url_base&
1658  
    set_port(core::string_view s);
1658  
    set_port(core::string_view s);
1659  

1659  

1660  
    /** Remove the port
1660  
    /** Remove the port
1661  

1661  

1662  
        If a port exists, it is removed. The rest
1662  
        If a port exists, it is removed. The rest
1663  
        of the authority is unchanged.
1663  
        of the authority is unchanged.
1664  

1664  

1665  
        @return `*this`
1665  
        @return `*this`
1666  

1666  

1667  
        @par Example
1667  
        @par Example
1668  
        @code
1668  
        @code
1669  
        assert( url( "http://www.example.com:80" ).remove_port().authority().buffer() == "www.example.com" );
1669  
        assert( url( "http://www.example.com:80" ).remove_port().authority().buffer() == "www.example.com" );
1670  
        @endcode
1670  
        @endcode
1671  

1671  

1672  
        @par Postconditions
1672  
        @par Postconditions
1673  
        @code
1673  
        @code
1674  
        this->has_port() == false && this->port_number() == 0 && this->port() == ""
1674  
        this->has_port() == false && this->port_number() == 0 && this->port() == ""
1675  
        @endcode
1675  
        @endcode
1676  

1676  

1677  
        @par Complexity
1677  
        @par Complexity
1678  
        Linear in `this->size()`.
1678  
        Linear in `this->size()`.
1679  

1679  

1680  
        @par Exception Safety
1680  
        @par Exception Safety
1681  
        Throws nothing.
1681  
        Throws nothing.
1682  

1682  

1683  
        @par BNF
1683  
        @par BNF
1684  
        @code
1684  
        @code
1685  
        authority     = [ userinfo "@" ] host [ ":" port ]
1685  
        authority     = [ userinfo "@" ] host [ ":" port ]
1686  

1686  

1687  
        port          = *DIGIT
1687  
        port          = *DIGIT
1688  
        @endcode
1688  
        @endcode
1689  

1689  

1690  
        @par Specification
1690  
        @par Specification
1691  
        @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.2.3">
1691  
        @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.2.3">
1692  
            3.2.3. Port (rfc3986)</a>
1692  
            3.2.3. Port (rfc3986)</a>
1693  

1693  

1694  
        @see
1694  
        @see
1695  
            @ref set_port.
1695  
            @ref set_port.
1696  
    */
1696  
    */
1697  
    url_base&
1697  
    url_base&
1698  
    remove_port() noexcept;
1698  
    remove_port() noexcept;
1699  

1699  

1700  
    //--------------------------------------------
1700  
    //--------------------------------------------
1701  
    //
1701  
    //
1702  
    // Path
1702  
    // Path
1703  
    //
1703  
    //
1704  
    //--------------------------------------------
1704  
    //--------------------------------------------
1705  

1705  

1706  
    /** Set if the path is absolute
1706  
    /** Set if the path is absolute
1707  

1707  

1708  
        This function adjusts the path to make
1708  
        This function adjusts the path to make
1709  
        it absolute or not, depending on the
1709  
        it absolute or not, depending on the
1710  
        parameter.
1710  
        parameter.
1711  

1711  

1712  
        @note
1712  
        @note
1713  
        If an authority is present, the path
1713  
        If an authority is present, the path
1714  
        is always absolute. In this case, the
1714  
        is always absolute. In this case, the
1715  
        function has no effect.
1715  
        function has no effect.
1716  

1716  

1717  
        @par Example
1717  
        @par Example
1718  
        @code
1718  
        @code
1719  
        url u( "path/to/file.txt" );
1719  
        url u( "path/to/file.txt" );
1720  
        assert( u.set_path_absolute( true ) );
1720  
        assert( u.set_path_absolute( true ) );
1721  
        assert( u.buffer() == "/path/to/file.txt" );
1721  
        assert( u.buffer() == "/path/to/file.txt" );
1722  
        @endcode
1722  
        @endcode
1723  

1723  

1724  
        @par Postconditions
1724  
        @par Postconditions
1725  
        @code
1725  
        @code
1726  
        this->is_path_absolute() == true && this->encoded_path().front() == '/'
1726  
        this->is_path_absolute() == true && this->encoded_path().front() == '/'
1727  
        @endcode
1727  
        @endcode
1728  

1728  

1729  
        @param absolute If `true`, the path is made absolute.
1729  
        @param absolute If `true`, the path is made absolute.
1730  

1730  

1731  
        @return true on success.
1731  
        @return true on success.
1732  

1732  

1733  
        @par Complexity
1733  
        @par Complexity
1734  
        Linear in `this->size()`.
1734  
        Linear in `this->size()`.
1735  

1735  

1736  
        @par BNF
1736  
        @par BNF
1737  
        @code
1737  
        @code
1738  
        path          = path-abempty    ; begins with "/" or is empty
1738  
        path          = path-abempty    ; begins with "/" or is empty
1739  
                      / path-absolute   ; begins with "/" but not "//"
1739  
                      / path-absolute   ; begins with "/" but not "//"
1740  
                      / path-noscheme   ; begins with a non-colon segment
1740  
                      / path-noscheme   ; begins with a non-colon segment
1741  
                      / path-rootless   ; begins with a segment
1741  
                      / path-rootless   ; begins with a segment
1742  
                      / path-empty      ; zero characters
1742  
                      / path-empty      ; zero characters
1743  

1743  

1744  
        path-abempty  = *( "/" segment )
1744  
        path-abempty  = *( "/" segment )
1745  
        path-absolute = "/" [ segment-nz *( "/" segment ) ]
1745  
        path-absolute = "/" [ segment-nz *( "/" segment ) ]
1746  
        path-noscheme = segment-nz-nc *( "/" segment )
1746  
        path-noscheme = segment-nz-nc *( "/" segment )
1747  
        path-rootless = segment-nz *( "/" segment )
1747  
        path-rootless = segment-nz *( "/" segment )
1748  
        path-empty    = 0<pchar>
1748  
        path-empty    = 0<pchar>
1749  
        @endcode
1749  
        @endcode
1750  

1750  

1751  
        @par Specification
1751  
        @par Specification
1752  
        @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.3"
1752  
        @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.3"
1753  
            >3.3.  Path (rfc3986)</a>
1753  
            >3.3.  Path (rfc3986)</a>
1754  

1754  

1755  
        @see
1755  
        @see
1756  
            @ref encoded_segments,
1756  
            @ref encoded_segments,
1757  
            @ref segments,
1757  
            @ref segments,
1758  
            @ref set_encoded_path,
1758  
            @ref set_encoded_path,
1759  
            @ref set_path.
1759  
            @ref set_path.
1760  
    */
1760  
    */
1761  
    bool
1761  
    bool
1762  
    set_path_absolute(bool absolute);
1762  
    set_path_absolute(bool absolute);
1763  

1763  

1764  
    /** Set the path.
1764  
    /** Set the path.
1765  

1765  

1766  
        This function sets the path to the
1766  
        This function sets the path to the
1767  
        string, which may be empty.
1767  
        string, which may be empty.
1768  
        Reserved characters in the string are
1768  
        Reserved characters in the string are
1769  
        percent-escaped in the result.
1769  
        percent-escaped in the result.
1770  

1770  

1771  
        @note
1771  
        @note
1772  
        The library may adjust the final result
1772  
        The library may adjust the final result
1773  
        to ensure that no other parts of the URL
1773  
        to ensure that no other parts of the URL
1774  
        are semantically affected.
1774  
        are semantically affected.
1775  

1775  

1776  
        @note
1776  
        @note
1777  
        This function does not encode '/' chars, which
1777  
        This function does not encode '/' chars, which
1778  
        are unreserved for paths but reserved for
1778  
        are unreserved for paths but reserved for
1779  
        path segments. If a path segment should include
1779  
        path segments. If a path segment should include
1780  
        encoded '/'s to differentiate it from path separators,
1780  
        encoded '/'s to differentiate it from path separators,
1781  
        the functions @ref set_encoded_path or @ref segments
1781  
        the functions @ref set_encoded_path or @ref segments
1782  
        should be used instead.
1782  
        should be used instead.
1783  

1783  

1784  
        @par Example
1784  
        @par Example
1785  
        @code
1785  
        @code
1786  
        url u( "http://www.example.com" );
1786  
        url u( "http://www.example.com" );
1787  

1787  

1788  
        u.set_path( "path/to/file.txt" );
1788  
        u.set_path( "path/to/file.txt" );
1789  

1789  

1790  
        assert( u.path() == "/path/to/file.txt" );
1790  
        assert( u.path() == "/path/to/file.txt" );
1791  
        @endcode
1791  
        @endcode
1792  

1792  

1793  
        @par Complexity
1793  
        @par Complexity
1794  
        Linear in `this->size() + s.size()`.
1794  
        Linear in `this->size() + s.size()`.
1795  

1795  

1796  
        @par Exception Safety
1796  
        @par Exception Safety
1797  
        Strong guarantee.
1797  
        Strong guarantee.
1798  
        Calls to allocate may throw.
1798  
        Calls to allocate may throw.
1799  

1799  

1800  
        @param s The string to set.
1800  
        @param s The string to set.
1801  
        @return `*this`
1801  
        @return `*this`
1802  

1802  

1803  
        @par BNF
1803  
        @par BNF
1804  
        @code
1804  
        @code
1805  
        path          = path-abempty    ; begins with "/" or is empty
1805  
        path          = path-abempty    ; begins with "/" or is empty
1806  
                      / path-absolute   ; begins with "/" but not "//"
1806  
                      / path-absolute   ; begins with "/" but not "//"
1807  
                      / path-noscheme   ; begins with a non-colon segment
1807  
                      / path-noscheme   ; begins with a non-colon segment
1808  
                      / path-rootless   ; begins with a segment
1808  
                      / path-rootless   ; begins with a segment
1809  
                      / path-empty      ; zero characters
1809  
                      / path-empty      ; zero characters
1810  

1810  

1811  
        path-abempty  = *( "/" segment )
1811  
        path-abempty  = *( "/" segment )
1812  
        path-absolute = "/" [ segment-nz *( "/" segment ) ]
1812  
        path-absolute = "/" [ segment-nz *( "/" segment ) ]
1813  
        path-noscheme = segment-nz-nc *( "/" segment )
1813  
        path-noscheme = segment-nz-nc *( "/" segment )
1814  
        path-rootless = segment-nz *( "/" segment )
1814  
        path-rootless = segment-nz *( "/" segment )
1815  
        path-empty    = 0<pchar>
1815  
        path-empty    = 0<pchar>
1816  
        @endcode
1816  
        @endcode
1817  

1817  

1818  
        @par Specification
1818  
        @par Specification
1819  
        @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.3"
1819  
        @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.3"
1820  
            >3.3.  Path (rfc3986)</a>
1820  
            >3.3.  Path (rfc3986)</a>
1821  

1821  

1822  
        @see
1822  
        @see
1823  
            @ref encoded_segments,
1823  
            @ref encoded_segments,
1824  
            @ref segments,
1824  
            @ref segments,
1825  
            @ref set_encoded_path,
1825  
            @ref set_encoded_path,
1826  
            @ref set_path_absolute.
1826  
            @ref set_path_absolute.
1827  
    */
1827  
    */
1828  
    url_base&
1828  
    url_base&
1829  
    set_path(
1829  
    set_path(
1830  
        core::string_view s);
1830  
        core::string_view s);
1831  

1831  

1832  
    /** Set the path.
1832  
    /** Set the path.
1833  

1833  

1834  
        This function sets the path to the
1834  
        This function sets the path to the
1835  
        string, which may contain percent-escapes
1835  
        string, which may contain percent-escapes
1836  
        and can be empty.
1836  
        and can be empty.
1837  
        Escapes in the string are preserved,
1837  
        Escapes in the string are preserved,
1838  
        and reserved characters in the string
1838  
        and reserved characters in the string
1839  
        are percent-escaped in the result.
1839  
        are percent-escaped in the result.
1840  

1840  

1841  
        @note
1841  
        @note
1842  
        The library may adjust the final result
1842  
        The library may adjust the final result
1843  
        to ensure that no other parts of the url
1843  
        to ensure that no other parts of the url
1844  
        is semantically affected.
1844  
        is semantically affected.
1845  

1845  

1846  
        @par Example
1846  
        @par Example
1847  
        @code
1847  
        @code
1848  
        url u( "http://www.example.com" );
1848  
        url u( "http://www.example.com" );
1849  

1849  

1850  
        u.set_encoded_path( "path/to/file.txt" );
1850  
        u.set_encoded_path( "path/to/file.txt" );
1851  

1851  

1852  
        assert( u.encoded_path() == "/path/to/file.txt" );
1852  
        assert( u.encoded_path() == "/path/to/file.txt" );
1853  
        @endcode
1853  
        @endcode
1854  

1854  

1855  
        @par Complexity
1855  
        @par Complexity
1856  
        Linear in `this->size() + s.size()`.
1856  
        Linear in `this->size() + s.size()`.
1857  

1857  

1858  
        @par Exception Safety
1858  
        @par Exception Safety
1859  
        Strong guarantee.
1859  
        Strong guarantee.
1860  
        Calls to allocate may throw.
1860  
        Calls to allocate may throw.
1861  
        Exceptions thrown on invalid input.
1861  
        Exceptions thrown on invalid input.
1862  

1862  

1863  
        @throw system_error
1863  
        @throw system_error
1864  
        `s` contains an invalid percent-encoding.
1864  
        `s` contains an invalid percent-encoding.
1865  

1865  

1866  
        @param s The string to set.
1866  
        @param s The string to set.
1867  

1867  

1868  
        @return `*this`
1868  
        @return `*this`
1869  

1869  

1870  
        @par BNF
1870  
        @par BNF
1871  
        @code
1871  
        @code
1872  
        path          = path-abempty    ; begins with "/" or is empty
1872  
        path          = path-abempty    ; begins with "/" or is empty
1873  
                      / path-absolute   ; begins with "/" but not "//"
1873  
                      / path-absolute   ; begins with "/" but not "//"
1874  
                      / path-noscheme   ; begins with a non-colon segment
1874  
                      / path-noscheme   ; begins with a non-colon segment
1875  
                      / path-rootless   ; begins with a segment
1875  
                      / path-rootless   ; begins with a segment
1876  
                      / path-empty      ; zero characters
1876  
                      / path-empty      ; zero characters
1877  

1877  

1878  
        path-abempty  = *( "/" segment )
1878  
        path-abempty  = *( "/" segment )
1879  
        path-absolute = "/" [ segment-nz *( "/" segment ) ]
1879  
        path-absolute = "/" [ segment-nz *( "/" segment ) ]
1880  
        path-noscheme = segment-nz-nc *( "/" segment )
1880  
        path-noscheme = segment-nz-nc *( "/" segment )
1881  
        path-rootless = segment-nz *( "/" segment )
1881  
        path-rootless = segment-nz *( "/" segment )
1882  
        path-empty    = 0<pchar>
1882  
        path-empty    = 0<pchar>
1883  
        @endcode
1883  
        @endcode
1884  

1884  

1885  
        @par Specification
1885  
        @par Specification
1886  
        @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.3"
1886  
        @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.3"
1887  
            >3.3.  Path (rfc3986)</a>
1887  
            >3.3.  Path (rfc3986)</a>
1888  

1888  

1889  
        @see
1889  
        @see
1890  
            @ref encoded_segments,
1890  
            @ref encoded_segments,
1891  
            @ref segments,
1891  
            @ref segments,
1892  
            @ref set_path,
1892  
            @ref set_path,
1893  
            @ref set_path_absolute.
1893  
            @ref set_path_absolute.
1894  
    */
1894  
    */
1895  
    url_base&
1895  
    url_base&
1896  
    set_encoded_path(
1896  
    set_encoded_path(
1897  
        pct_string_view s);
1897  
        pct_string_view s);
1898  

1898  

1899  
    /** Return the path as a container of segments
1899  
    /** Return the path as a container of segments
1900  

1900  

1901  
        This function returns a bidirectional
1901  
        This function returns a bidirectional
1902  
        view of segments over the path.
1902  
        view of segments over the path.
1903  
        The returned view references the same
1903  
        The returned view references the same
1904  
        underlying character buffer; ownership
1904  
        underlying character buffer; ownership
1905  
        is not transferred.
1905  
        is not transferred.
1906  
        Any percent-escapes in strings returned
1906  
        Any percent-escapes in strings returned
1907  
        when iterating the view are decoded first.
1907  
        when iterating the view are decoded first.
1908  
        The container is modifiable; changes
1908  
        The container is modifiable; changes
1909  
        to the container are reflected in the
1909  
        to the container are reflected in the
1910  
        underlying URL.
1910  
        underlying URL.
1911  

1911  

1912  
        @return `*this`
1912  
        @return `*this`
1913  

1913  

1914  
        @par Example
1914  
        @par Example
1915  
        @code
1915  
        @code
1916  
        url u( "http://example.com/path/to/file.txt" );
1916  
        url u( "http://example.com/path/to/file.txt" );
1917  

1917  

1918  
        segments sv = u.segments();
1918  
        segments sv = u.segments();
1919  
        @endcode
1919  
        @endcode
1920  

1920  

1921  
        @par Complexity
1921  
        @par Complexity
1922  
        Constant.
1922  
        Constant.
1923  

1923  

1924  
        @par Exception Safety
1924  
        @par Exception Safety
1925  
        Throws nothing.
1925  
        Throws nothing.
1926  

1926  

1927  
        @par BNF
1927  
        @par BNF
1928  
        @code
1928  
        @code
1929  
        path          = path-abempty    ; begins with "/" or is empty
1929  
        path          = path-abempty    ; begins with "/" or is empty
1930  
                      / path-absolute   ; begins with "/" but not "//"
1930  
                      / path-absolute   ; begins with "/" but not "//"
1931  
                      / path-noscheme   ; begins with a non-colon segment
1931  
                      / path-noscheme   ; begins with a non-colon segment
1932  
                      / path-rootless   ; begins with a segment
1932  
                      / path-rootless   ; begins with a segment
1933  
                      / path-empty      ; zero characters
1933  
                      / path-empty      ; zero characters
1934  

1934  

1935  
        path-abempty  = *( "/" segment )
1935  
        path-abempty  = *( "/" segment )
1936  
        path-absolute = "/" [ segment-nz *( "/" segment ) ]
1936  
        path-absolute = "/" [ segment-nz *( "/" segment ) ]
1937  
        path-noscheme = segment-nz-nc *( "/" segment )
1937  
        path-noscheme = segment-nz-nc *( "/" segment )
1938  
        path-rootless = segment-nz *( "/" segment )
1938  
        path-rootless = segment-nz *( "/" segment )
1939  
        path-empty    = 0<pchar>
1939  
        path-empty    = 0<pchar>
1940  
        @endcode
1940  
        @endcode
1941  

1941  

1942  
        @par Specification
1942  
        @par Specification
1943  
        @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.3"
1943  
        @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.3"
1944  
            >3.3.  Path (rfc3986)</a>
1944  
            >3.3.  Path (rfc3986)</a>
1945  

1945  

1946  
        @see
1946  
        @see
1947  
            @ref encoded_segments,
1947  
            @ref encoded_segments,
1948  
            @ref set_encoded_path,
1948  
            @ref set_encoded_path,
1949  
            @ref set_path,
1949  
            @ref set_path,
1950  
            @ref set_path_absolute.
1950  
            @ref set_path_absolute.
1951  
    */
1951  
    */
1952  
    urls::segments_ref
1952  
    urls::segments_ref
1953  
    segments() noexcept;
1953  
    segments() noexcept;
1954  

1954  

1955  
    /// @copydoc url_view_base::segments
1955  
    /// @copydoc url_view_base::segments
1956  
    segments_view
1956  
    segments_view
1957  
    segments() const noexcept
1957  
    segments() const noexcept
1958  
    {
1958  
    {
1959  
        return url_view_base::segments();
1959  
        return url_view_base::segments();
1960  
    }
1960  
    }
1961  

1961  

1962  
    /** Return the path as a container of segments
1962  
    /** Return the path as a container of segments
1963  

1963  

1964  
        This function returns a bidirectional
1964  
        This function returns a bidirectional
1965  
        view of segments over the path.
1965  
        view of segments over the path.
1966  
        The returned view references the same
1966  
        The returned view references the same
1967  
        underlying character buffer; ownership
1967  
        underlying character buffer; ownership
1968  
        is not transferred.
1968  
        is not transferred.
1969  
        Strings returned when iterating the
1969  
        Strings returned when iterating the
1970  
        range may contain percent escapes.
1970  
        range may contain percent escapes.
1971  
        The container is modifiable; changes
1971  
        The container is modifiable; changes
1972  
        to the container are reflected in the
1972  
        to the container are reflected in the
1973  
        underlying URL.
1973  
        underlying URL.
1974  

1974  

1975  
        @return `*this`
1975  
        @return `*this`
1976  

1976  

1977  
        @par Example
1977  
        @par Example
1978  
        @code
1978  
        @code
1979  
        url u( "http://example.com/path/to/file.txt" );
1979  
        url u( "http://example.com/path/to/file.txt" );
1980  

1980  

1981  
        segments_encoded_ref sv = u.encoded_segments();
1981  
        segments_encoded_ref sv = u.encoded_segments();
1982  
        @endcode
1982  
        @endcode
1983  

1983  

1984  
        @par Complexity
1984  
        @par Complexity
1985  
        Constant.
1985  
        Constant.
1986  

1986  

1987  
        @par Exception Safety
1987  
        @par Exception Safety
1988  
        Throws nothing.
1988  
        Throws nothing.
1989  

1989  

1990  
        @par BNF
1990  
        @par BNF
1991  
        @code
1991  
        @code
1992  
        path          = path-abempty    ; begins with "/" or is empty
1992  
        path          = path-abempty    ; begins with "/" or is empty
1993  
                      / path-absolute   ; begins with "/" but not "//"
1993  
                      / path-absolute   ; begins with "/" but not "//"
1994  
                      / path-noscheme   ; begins with a non-colon segment
1994  
                      / path-noscheme   ; begins with a non-colon segment
1995  
                      / path-rootless   ; begins with a segment
1995  
                      / path-rootless   ; begins with a segment
1996  
                      / path-empty      ; zero characters
1996  
                      / path-empty      ; zero characters
1997  

1997  

1998  
        path-abempty  = *( "/" segment )
1998  
        path-abempty  = *( "/" segment )
1999  
        path-absolute = "/" [ segment-nz *( "/" segment ) ]
1999  
        path-absolute = "/" [ segment-nz *( "/" segment ) ]
2000  
        path-noscheme = segment-nz-nc *( "/" segment )
2000  
        path-noscheme = segment-nz-nc *( "/" segment )
2001  
        path-rootless = segment-nz *( "/" segment )
2001  
        path-rootless = segment-nz *( "/" segment )
2002  
        path-empty    = 0<pchar>
2002  
        path-empty    = 0<pchar>
2003  
        @endcode
2003  
        @endcode
2004  

2004  

2005  
        @par Specification
2005  
        @par Specification
2006  
        @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.3"
2006  
        @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.3"
2007  
            >3.3.  Path (rfc3986)</a>
2007  
            >3.3.  Path (rfc3986)</a>
2008  

2008  

2009  
        @see
2009  
        @see
2010  
            @ref encoded_segments,
2010  
            @ref encoded_segments,
2011  
            @ref set_encoded_path,
2011  
            @ref set_encoded_path,
2012  
            @ref set_path,
2012  
            @ref set_path,
2013  
            @ref set_path_absolute.
2013  
            @ref set_path_absolute.
2014  
    */
2014  
    */
2015  
    segments_encoded_ref
2015  
    segments_encoded_ref
2016  
    encoded_segments() noexcept;
2016  
    encoded_segments() noexcept;
2017  

2017  

2018  
    /// @copydoc url_view_base::encoded_segments
2018  
    /// @copydoc url_view_base::encoded_segments
2019  
    segments_encoded_view
2019  
    segments_encoded_view
2020  
    encoded_segments() const noexcept
2020  
    encoded_segments() const noexcept
2021  
    {
2021  
    {
2022  
        return url_view_base::encoded_segments();
2022  
        return url_view_base::encoded_segments();
2023  
    }
2023  
    }
2024  

2024  

2025  
    //--------------------------------------------
2025  
    //--------------------------------------------
2026  
    //
2026  
    //
2027  
    // Query
2027  
    // Query
2028  
    //
2028  
    //
2029  
    //--------------------------------------------
2029  
    //--------------------------------------------
2030  

2030  

2031  
    /** Set the query
2031  
    /** Set the query
2032  

2032  

2033  
        This sets the query to the string, which
2033  
        This sets the query to the string, which
2034  
        can be empty.
2034  
        can be empty.
2035  
        An empty query is distinct from having
2035  
        An empty query is distinct from having
2036  
        no query.
2036  
        no query.
2037  
        Reserved characters in the string are
2037  
        Reserved characters in the string are
2038  
        percent-escaped in the result.
2038  
        percent-escaped in the result.
2039  

2039  

2040  
        @par Example
2040  
        @par Example
2041  
        @code
2041  
        @code
2042  
        assert( url( "http://example.com" ).set_query( "id=42" ).query() == "id=42" );
2042  
        assert( url( "http://example.com" ).set_query( "id=42" ).query() == "id=42" );
2043  
        @endcode
2043  
        @endcode
2044  

2044  

2045  
        @par Postconditions
2045  
        @par Postconditions
2046  
        @code
2046  
        @code
2047  
        this->has_query() == true && this->query() == s
2047  
        this->has_query() == true && this->query() == s
2048  
        @endcode
2048  
        @endcode
2049  

2049  

2050  
        @par Exception Safety
2050  
        @par Exception Safety
2051  
        Strong guarantee.
2051  
        Strong guarantee.
2052  
        Calls to allocate may throw.
2052  
        Calls to allocate may throw.
2053  

2053  

2054  
        @param s The string to set.
2054  
        @param s The string to set.
2055  
        @return `*this`
2055  
        @return `*this`
2056  

2056  

2057  
        @par BNF
2057  
        @par BNF
2058  
        @code
2058  
        @code
2059  
        query           = *( pchar / "/" / "?" )
2059  
        query           = *( pchar / "/" / "?" )
2060  

2060  

2061  
        query-param     = key [ "=" value ]
2061  
        query-param     = key [ "=" value ]
2062  
        query-params    = [ query-param ] *( "&" query-param )
2062  
        query-params    = [ query-param ] *( "&" query-param )
2063  
        @endcode
2063  
        @endcode
2064  

2064  

2065  
        @par Specification
2065  
        @par Specification
2066  
        @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.4"
2066  
        @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.4"
2067  
            >3.4.  Query (rfc3986)</a>
2067  
            >3.4.  Query (rfc3986)</a>
2068  
        @li <a href="https://en.wikipedia.org/wiki/Query_string"
2068  
        @li <a href="https://en.wikipedia.org/wiki/Query_string"
2069  
            >Query string (Wikipedia)</a>
2069  
            >Query string (Wikipedia)</a>
2070  

2070  

2071  
        @see
2071  
        @see
2072  
            @ref encoded_params,
2072  
            @ref encoded_params,
2073  
            @ref params,
2073  
            @ref params,
2074  
            @ref remove_query,
2074  
            @ref remove_query,
2075  
            @ref set_encoded_query.
2075  
            @ref set_encoded_query.
2076  
    */
2076  
    */
2077  
    url_base&
2077  
    url_base&
2078  
    set_query(
2078  
    set_query(
2079  
        core::string_view s);
2079  
        core::string_view s);
2080  

2080  

2081  
    /** Set the query
2081  
    /** Set the query
2082  

2082  

2083  
        This sets the query to the string, which
2083  
        This sets the query to the string, which
2084  
        may contain percent-escapes and can be
2084  
        may contain percent-escapes and can be
2085  
        empty.
2085  
        empty.
2086  
        An empty query is distinct from having
2086  
        An empty query is distinct from having
2087  
        no query.
2087  
        no query.
2088  
        Escapes in the string are preserved,
2088  
        Escapes in the string are preserved,
2089  
        and reserved characters in the string
2089  
        and reserved characters in the string
2090  
        are percent-escaped in the result.
2090  
        are percent-escaped in the result.
2091  

2091  

2092  
        @par Example
2092  
        @par Example
2093  
        @code
2093  
        @code
2094  
        assert( url( "http://example.com" ).set_encoded_query( "id=42" ).encoded_query() == "id=42" );
2094  
        assert( url( "http://example.com" ).set_encoded_query( "id=42" ).encoded_query() == "id=42" );
2095  
        @endcode
2095  
        @endcode
2096  

2096  

2097  
        @par Postconditions
2097  
        @par Postconditions
2098  
        @code
2098  
        @code
2099  
        this->has_query() == true && this->query() == decode_view( s );
2099  
        this->has_query() == true && this->query() == decode_view( s );
2100  
        @endcode
2100  
        @endcode
2101  

2101  

2102  
        @par Exception Safety
2102  
        @par Exception Safety
2103  
        Strong guarantee.
2103  
        Strong guarantee.
2104  
        Calls to allocate may throw.
2104  
        Calls to allocate may throw.
2105  
        Exceptions thrown on invalid input.
2105  
        Exceptions thrown on invalid input.
2106  

2106  

2107  
        @param s The string to set.
2107  
        @param s The string to set.
2108  
        @return `*this`
2108  
        @return `*this`
2109  

2109  

2110  
        @throws system_error
2110  
        @throws system_error
2111  
        `s` contains an invalid percent-encoding.
2111  
        `s` contains an invalid percent-encoding.
2112  

2112  

2113  
        @par BNF
2113  
        @par BNF
2114  
        @code
2114  
        @code
2115  
        query           = *( pchar / "/" / "?" )
2115  
        query           = *( pchar / "/" / "?" )
2116  

2116  

2117  
        query-param     = key [ "=" value ]
2117  
        query-param     = key [ "=" value ]
2118  
        query-params    = [ query-param ] *( "&" query-param )
2118  
        query-params    = [ query-param ] *( "&" query-param )
2119  
        @endcode
2119  
        @endcode
2120  

2120  

2121  
        @par Specification
2121  
        @par Specification
2122  
        @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.4"
2122  
        @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.4"
2123  
            >3.4.  Query (rfc3986)</a>
2123  
            >3.4.  Query (rfc3986)</a>
2124  
        @li <a href="https://en.wikipedia.org/wiki/Query_string"
2124  
        @li <a href="https://en.wikipedia.org/wiki/Query_string"
2125  
            >Query string (Wikipedia)</a>
2125  
            >Query string (Wikipedia)</a>
2126  

2126  

2127  
        @see
2127  
        @see
2128  
            @ref encoded_params,
2128  
            @ref encoded_params,
2129  
            @ref params,
2129  
            @ref params,
2130  
            @ref remove_query,
2130  
            @ref remove_query,
2131  
            @ref set_query.
2131  
            @ref set_query.
2132  
    */
2132  
    */
2133  
    url_base&
2133  
    url_base&
2134  
    set_encoded_query(
2134  
    set_encoded_query(
2135  
        pct_string_view s);
2135  
        pct_string_view s);
2136  

2136  

2137  
    /** Return the query as a container of parameters
2137  
    /** Return the query as a container of parameters
2138  

2138  

2139  
        This function returns a bidirectional
2139  
        This function returns a bidirectional
2140  
        view of key/value pairs over the query.
2140  
        view of key/value pairs over the query.
2141  
        The returned view references the same
2141  
        The returned view references the same
2142  
        underlying character buffer; ownership
2142  
        underlying character buffer; ownership
2143  
        is not transferred.
2143  
        is not transferred.
2144  
        Any percent-escapes in strings returned
2144  
        Any percent-escapes in strings returned
2145  
        when iterating the view are decoded first.
2145  
        when iterating the view are decoded first.
2146  
        The container is modifiable; changes
2146  
        The container is modifiable; changes
2147  
        to the container are reflected in the
2147  
        to the container are reflected in the
2148  
        underlying URL.
2148  
        underlying URL.
2149  

2149  

2150  
        @return `*this`
2150  
        @return `*this`
2151  

2151  

2152  
        @par Example
2152  
        @par Example
2153  
        @code
2153  
        @code
2154  
        params_ref pv = url( "/sql?id=42&name=jane%2Ddoe&page+size=20" ).params();
2154  
        params_ref pv = url( "/sql?id=42&name=jane%2Ddoe&page+size=20" ).params();
2155  
        @endcode
2155  
        @endcode
2156  

2156  

2157  
        @par Complexity
2157  
        @par Complexity
2158  
        Constant.
2158  
        Constant.
2159  

2159  

2160  
        @par Exception Safety
2160  
        @par Exception Safety
2161  
        Throws nothing.
2161  
        Throws nothing.
2162  

2162  

2163  
        @par BNF
2163  
        @par BNF
2164  
        @code
2164  
        @code
2165  
        query           = *( pchar / "/" / "?" )
2165  
        query           = *( pchar / "/" / "?" )
2166  

2166  

2167  
        query-param     = key [ "=" value ]
2167  
        query-param     = key [ "=" value ]
2168  
        query-params    = [ query-param ] *( "&" query-param )
2168  
        query-params    = [ query-param ] *( "&" query-param )
2169  
        @endcode
2169  
        @endcode
2170  

2170  

2171  
        @par Specification
2171  
        @par Specification
2172  
        @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.4"
2172  
        @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.4"
2173  
            >3.4.  Query (rfc3986)</a>
2173  
            >3.4.  Query (rfc3986)</a>
2174  
        @li <a href="https://en.wikipedia.org/wiki/Query_string"
2174  
        @li <a href="https://en.wikipedia.org/wiki/Query_string"
2175  
            >Query string (Wikipedia)</a>
2175  
            >Query string (Wikipedia)</a>
2176  

2176  

2177  
        @see
2177  
        @see
2178  
            @ref encoded_params,
2178  
            @ref encoded_params,
2179  
            @ref remove_query,
2179  
            @ref remove_query,
2180  
            @ref set_encoded_query,
2180  
            @ref set_encoded_query,
2181  
            @ref set_query.
2181  
            @ref set_query.
2182  
    */
2182  
    */
2183  
    params_ref
2183  
    params_ref
2184  
    params() noexcept;
2184  
    params() noexcept;
2185  

2185  

2186  
    /// @copydoc url_view_base::params
2186  
    /// @copydoc url_view_base::params
2187  
    params_view
2187  
    params_view
2188  
    params() const noexcept
2188  
    params() const noexcept
2189  
    {
2189  
    {
2190  
        return url_view_base::params();
2190  
        return url_view_base::params();
2191  
    }
2191  
    }
2192  

2192  

2193  
    /** Return the query as a container of parameters
2193  
    /** Return the query as a container of parameters
2194  

2194  

2195  
        This function returns a bidirectional
2195  
        This function returns a bidirectional
2196  
        view of key/value pairs over the query.
2196  
        view of key/value pairs over the query.
2197  
        The returned view references the same
2197  
        The returned view references the same
2198  
        underlying character buffer; ownership
2198  
        underlying character buffer; ownership
2199  
        is not transferred.
2199  
        is not transferred.
2200  
        Any percent-escapes in strings returned
2200  
        Any percent-escapes in strings returned
2201  
        when iterating the view are decoded first.
2201  
        when iterating the view are decoded first.
2202  
        The container is modifiable; changes
2202  
        The container is modifiable; changes
2203  
        to the container are reflected in the
2203  
        to the container are reflected in the
2204  
        underlying URL.
2204  
        underlying URL.
2205  

2205  

2206  
        @par Example
2206  
        @par Example
2207  
        @code
2207  
        @code
2208  
        encoding_opts opt;
2208  
        encoding_opts opt;
2209  
        opt.space_as_plus = true;
2209  
        opt.space_as_plus = true;
2210  
        params_ref pv = url( "/sql?id=42&name=jane+doe&page+size=20" ).params(opt);
2210  
        params_ref pv = url( "/sql?id=42&name=jane+doe&page+size=20" ).params(opt);
2211  
        @endcode
2211  
        @endcode
2212  

2212  

2213  
        @par Complexity
2213  
        @par Complexity
2214  
        Constant.
2214  
        Constant.
2215  

2215  

2216  
        @par Exception Safety
2216  
        @par Exception Safety
2217  
        Throws nothing.
2217  
        Throws nothing.
2218  

2218  

2219  
        @param opt The options for decoding. If
2219  
        @param opt The options for decoding. If
2220  
        this parameter is omitted, the `space_as_plus`
2220  
        this parameter is omitted, the `space_as_plus`
2221  
        is used.
2221  
        is used.
2222  

2222  

2223  
        @return A range of references to the parameters.
2223  
        @return A range of references to the parameters.
2224  

2224  

2225  
        @par BNF
2225  
        @par BNF
2226  
        @code
2226  
        @code
2227  
        query           = *( pchar / "/" / "?" )
2227  
        query           = *( pchar / "/" / "?" )
2228  

2228  

2229  
        query-param     = key [ "=" value ]
2229  
        query-param     = key [ "=" value ]
2230  
        query-params    = [ query-param ] *( "&" query-param )
2230  
        query-params    = [ query-param ] *( "&" query-param )
2231  
        @endcode
2231  
        @endcode
2232  

2232  

2233  
        @par Specification
2233  
        @par Specification
2234  
        @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.4"
2234  
        @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.4"
2235  
            >3.4.  Query (rfc3986)</a>
2235  
            >3.4.  Query (rfc3986)</a>
2236  
        @li <a href="https://en.wikipedia.org/wiki/Query_string"
2236  
        @li <a href="https://en.wikipedia.org/wiki/Query_string"
2237  
            >Query string (Wikipedia)</a>
2237  
            >Query string (Wikipedia)</a>
2238  

2238  

2239  
        @see
2239  
        @see
2240  
            @ref encoded_params,
2240  
            @ref encoded_params,
2241  
            @ref remove_query,
2241  
            @ref remove_query,
2242  
            @ref set_encoded_query,
2242  
            @ref set_encoded_query,
2243  
            @ref set_query.
2243  
            @ref set_query.
2244  
    */
2244  
    */
2245  
    params_ref
2245  
    params_ref
2246  
    params(encoding_opts opt) noexcept;
2246  
    params(encoding_opts opt) noexcept;
2247  

2247  

2248  
    /// @copydoc url_view_base::encoded_params
2248  
    /// @copydoc url_view_base::encoded_params
2249  
    params_encoded_view
2249  
    params_encoded_view
2250  
    encoded_params() const noexcept
2250  
    encoded_params() const noexcept
2251  
    {
2251  
    {
2252  
        return url_view_base::encoded_params();
2252  
        return url_view_base::encoded_params();
2253  
    }
2253  
    }
2254  

2254  

2255  
    /** Return the query as a container of parameters
2255  
    /** Return the query as a container of parameters
2256  

2256  

2257  
        This function returns a bidirectional
2257  
        This function returns a bidirectional
2258  
        view of key/value pairs over the query.
2258  
        view of key/value pairs over the query.
2259  
        The returned view references the same
2259  
        The returned view references the same
2260  
        underlying character buffer; ownership
2260  
        underlying character buffer; ownership
2261  
        is not transferred.
2261  
        is not transferred.
2262  
        Strings returned when iterating the
2262  
        Strings returned when iterating the
2263  
        range may contain percent escapes.
2263  
        range may contain percent escapes.
2264  
        The container is modifiable; changes
2264  
        The container is modifiable; changes
2265  
        to the container are reflected in the
2265  
        to the container are reflected in the
2266  
        underlying URL.
2266  
        underlying URL.
2267  

2267  

2268  
        @return `*this`
2268  
        @return `*this`
2269  

2269  

2270  
        @par Example
2270  
        @par Example
2271  
        @code
2271  
        @code
2272  
        params_encoded_ref pv = url( "/sql?id=42&name=jane%2Ddoe&page+size=20" ).encoded_params();
2272  
        params_encoded_ref pv = url( "/sql?id=42&name=jane%2Ddoe&page+size=20" ).encoded_params();
2273  
        @endcode
2273  
        @endcode
2274  

2274  

2275  
        @par Complexity
2275  
        @par Complexity
2276  
        Constant.
2276  
        Constant.
2277  

2277  

2278  
        @par Exception Safety
2278  
        @par Exception Safety
2279  
        Throws nothing.
2279  
        Throws nothing.
2280  

2280  

2281  
        @par BNF
2281  
        @par BNF
2282  
        @code
2282  
        @code
2283  
        query           = *( pchar / "/" / "?" )
2283  
        query           = *( pchar / "/" / "?" )
2284  

2284  

2285  
        query-param     = key [ "=" value ]
2285  
        query-param     = key [ "=" value ]
2286  
        query-params    = [ query-param ] *( "&" query-param )
2286  
        query-params    = [ query-param ] *( "&" query-param )
2287  
        @endcode
2287  
        @endcode
2288  

2288  

2289  
        @par Specification
2289  
        @par Specification
2290  
        @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.4"
2290  
        @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.4"
2291  
            >3.4.  Query (rfc3986)</a>
2291  
            >3.4.  Query (rfc3986)</a>
2292  
        @li <a href="https://en.wikipedia.org/wiki/Query_string"
2292  
        @li <a href="https://en.wikipedia.org/wiki/Query_string"
2293  
            >Query string (Wikipedia)</a>
2293  
            >Query string (Wikipedia)</a>
2294  

2294  

2295  
        @see
2295  
        @see
2296  
            @ref params,
2296  
            @ref params,
2297  
            @ref remove_query,
2297  
            @ref remove_query,
2298  
            @ref set_encoded_query,
2298  
            @ref set_encoded_query,
2299  
            @ref set_query.
2299  
            @ref set_query.
2300  
    */
2300  
    */
2301  
    params_encoded_ref
2301  
    params_encoded_ref
2302  
    encoded_params() noexcept;
2302  
    encoded_params() noexcept;
2303  

2303  

2304  
    /** Set the query params
2304  
    /** Set the query params
2305  

2305  

2306  
        This sets the query params to the list
2306  
        This sets the query params to the list
2307  
        of param_view, which can be empty.
2307  
        of param_view, which can be empty.
2308  

2308  

2309  
        An empty list of params is distinct from
2309  
        An empty list of params is distinct from
2310  
        having no params.
2310  
        having no params.
2311  

2311  

2312  
        Reserved characters in the string are
2312  
        Reserved characters in the string are
2313  
        percent-escaped in the result.
2313  
        percent-escaped in the result.
2314  

2314  

2315  
        @par Example
2315  
        @par Example
2316  
        @code
2316  
        @code
2317  
        assert( url( "http://example.com" ).set_params( {"id", "42"} ).query() == "id=42" );
2317  
        assert( url( "http://example.com" ).set_params( {"id", "42"} ).query() == "id=42" );
2318  
        @endcode
2318  
        @endcode
2319  

2319  

2320  
        @par Postconditions
2320  
        @par Postconditions
2321  
        @code
2321  
        @code
2322  
        this->has_query() == true
2322  
        this->has_query() == true
2323  
        @endcode
2323  
        @endcode
2324  

2324  

2325  
        @par Exception Safety
2325  
        @par Exception Safety
2326  
        Strong guarantee.
2326  
        Strong guarantee.
2327  
        Calls to allocate may throw.
2327  
        Calls to allocate may throw.
2328  

2328  

2329  
        @par Complexity
2329  
        @par Complexity
2330  
        Linear.
2330  
        Linear.
2331  

2331  

2332  
        @param ps The params to set.
2332  
        @param ps The params to set.
2333  
        @param opts The options for encoding.
2333  
        @param opts The options for encoding.
2334  
        @return `*this`
2334  
        @return `*this`
2335  

2335  

2336  
        @par BNF
2336  
        @par BNF
2337  
        @code
2337  
        @code
2338  
        query           = *( pchar / "/" / "?" )
2338  
        query           = *( pchar / "/" / "?" )
2339  

2339  

2340  
        query-param     = key [ "=" value ]
2340  
        query-param     = key [ "=" value ]
2341  
        query-params    = [ query-param ] *( "&" query-param )
2341  
        query-params    = [ query-param ] *( "&" query-param )
2342  
        @endcode
2342  
        @endcode
2343  

2343  

2344  
        @par Specification
2344  
        @par Specification
2345  
        @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.4
2345  
        @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.4
2346  
            >3.4.  Query (rfc3986)</a>
2346  
            >3.4.  Query (rfc3986)</a>
2347  
        @li <a href="https://en.wikipedia.org/wiki/Query_string"
2347  
        @li <a href="https://en.wikipedia.org/wiki/Query_string"
2348  
            >Query string (Wikipedia)</a>
2348  
            >Query string (Wikipedia)</a>
2349  

2349  

2350  
        @see
2350  
        @see
2351  
            @ref encoded_params,
2351  
            @ref encoded_params,
2352  
            @ref remove_query,
2352  
            @ref remove_query,
2353  
            @ref set_encoded_query,
2353  
            @ref set_encoded_query,
2354  
            @ref set_query.
2354  
            @ref set_query.
2355  
    */
2355  
    */
2356  
    url_base&
2356  
    url_base&
2357  
    set_params(
2357  
    set_params(
2358  
        std::initializer_list<param_view> ps,
2358  
        std::initializer_list<param_view> ps,
2359  
        encoding_opts opts = {}) noexcept;
2359  
        encoding_opts opts = {}) noexcept;
2360  

2360  

2361  
    /** Set the query params
2361  
    /** Set the query params
2362  

2362  

2363  
        This sets the query params to the elements
2363  
        This sets the query params to the elements
2364  
        in the list, which may contain
2364  
        in the list, which may contain
2365  
        percent-escapes and can be empty.
2365  
        percent-escapes and can be empty.
2366  

2366  

2367  
        An empty list of params is distinct from
2367  
        An empty list of params is distinct from
2368  
        having no query.
2368  
        having no query.
2369  

2369  

2370  
        Escapes in the string are preserved,
2370  
        Escapes in the string are preserved,
2371  
        and reserved characters in the string
2371  
        and reserved characters in the string
2372  
        are percent-escaped in the result.
2372  
        are percent-escaped in the result.
2373  

2373  

2374  
        @par Example
2374  
        @par Example
2375  
        @code
2375  
        @code
2376  
        assert( url( "http://example.com" ).set_encoded_params( {"id", "42"} ).encoded_query() == "id=42" );
2376  
        assert( url( "http://example.com" ).set_encoded_params( {"id", "42"} ).encoded_query() == "id=42" );
2377  
        @endcode
2377  
        @endcode
2378  

2378  

2379  
        @par Postconditions
2379  
        @par Postconditions
2380  
        @code
2380  
        @code
2381  
        this->has_query() == true
2381  
        this->has_query() == true
2382  
        @endcode
2382  
        @endcode
2383  

2383  

2384  
        @par Complexity
2384  
        @par Complexity
2385  
        Linear.
2385  
        Linear.
2386  

2386  

2387  
        @par Exception Safety
2387  
        @par Exception Safety
2388  
        Strong guarantee.
2388  
        Strong guarantee.
2389  
        Calls to allocate may throw.
2389  
        Calls to allocate may throw.
2390  
        Exceptions thrown on invalid input.
2390  
        Exceptions thrown on invalid input.
2391  

2391  

2392  
        @param ps The params to set.
2392  
        @param ps The params to set.
2393  

2393  

2394  
        @return `*this`
2394  
        @return `*this`
2395  

2395  

2396  
        @throws system_error
2396  
        @throws system_error
2397  
        some element in `ps` contains an invalid percent-encoding.
2397  
        some element in `ps` contains an invalid percent-encoding.
2398  

2398  

2399  
        @par BNF
2399  
        @par BNF
2400  
        @code
2400  
        @code
2401  
        query           = *( pchar / "/" / "?" )
2401  
        query           = *( pchar / "/" / "?" )
2402  

2402  

2403  
        query-param     = key [ "=" value ]
2403  
        query-param     = key [ "=" value ]
2404  
        query-params    = [ query-param ] *( "&" query-param )
2404  
        query-params    = [ query-param ] *( "&" query-param )
2405  
        @endcode
2405  
        @endcode
2406  

2406  

2407  
        @par Specification
2407  
        @par Specification
2408  
        @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.4"
2408  
        @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.4"
2409  
            >3.4. Query (rfc3986)</a>
2409  
            >3.4. Query (rfc3986)</a>
2410  
        @li <a href="https://en.wikipedia.org/wiki/Query_string"
2410  
        @li <a href="https://en.wikipedia.org/wiki/Query_string"
2411  
            >Query string (Wikipedia)</a>
2411  
            >Query string (Wikipedia)</a>
2412  

2412  

2413  
        @see
2413  
        @see
2414  
            @ref set_params,
2414  
            @ref set_params,
2415  
            @ref params,
2415  
            @ref params,
2416  
            @ref remove_query,
2416  
            @ref remove_query,
2417  
            @ref set_encoded_query,
2417  
            @ref set_encoded_query,
2418  
            @ref set_query.
2418  
            @ref set_query.
2419  
    */
2419  
    */
2420  
    url_base&
2420  
    url_base&
2421  
    set_encoded_params( std::initializer_list< param_pct_view > ps ) noexcept;
2421  
    set_encoded_params( std::initializer_list< param_pct_view > ps ) noexcept;
2422  

2422  

2423  
    /** Remove the query
2423  
    /** Remove the query
2424  

2424  

2425  
        If a query is present, it is removed.
2425  
        If a query is present, it is removed.
2426  
        An empty query is distinct from having
2426  
        An empty query is distinct from having
2427  
        no query.
2427  
        no query.
2428  

2428  

2429  
        @return `*this`
2429  
        @return `*this`
2430  

2430  

2431  
        @par Example
2431  
        @par Example
2432  
        @code
2432  
        @code
2433  
        assert( url( "http://www.example.com?id=42" ).remove_query().buffer() == "http://www.example.com" );
2433  
        assert( url( "http://www.example.com?id=42" ).remove_query().buffer() == "http://www.example.com" );
2434  
        @endcode
2434  
        @endcode
2435  

2435  

2436  
        @par Postconditions
2436  
        @par Postconditions
2437  
        @code
2437  
        @code
2438  
        this->has_query() == false && this->params().empty()
2438  
        this->has_query() == false && this->params().empty()
2439  
        @endcode
2439  
        @endcode
2440  

2440  

2441  
        @par Exception Safety
2441  
        @par Exception Safety
2442  
        Throws nothing.
2442  
        Throws nothing.
2443  

2443  

2444  
        @par BNF
2444  
        @par BNF
2445  
        @code
2445  
        @code
2446  
        query           = *( pchar / "/" / "?" )
2446  
        query           = *( pchar / "/" / "?" )
2447  

2447  

2448  
        query-param     = key [ "=" value ]
2448  
        query-param     = key [ "=" value ]
2449  
        query-params    = [ query-param ] *( "&" query-param )
2449  
        query-params    = [ query-param ] *( "&" query-param )
2450  
        @endcode
2450  
        @endcode
2451  

2451  

2452  
        @par Specification
2452  
        @par Specification
2453  
        @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.4"
2453  
        @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.4"
2454  
            >3.4.  Query (rfc3986)</a>
2454  
            >3.4.  Query (rfc3986)</a>
2455  
        @li <a href="https://en.wikipedia.org/wiki/Query_string"
2455  
        @li <a href="https://en.wikipedia.org/wiki/Query_string"
2456  
            >Query string (Wikipedia)</a>
2456  
            >Query string (Wikipedia)</a>
2457  

2457  

2458  
        @see
2458  
        @see
2459  
            @ref encoded_params,
2459  
            @ref encoded_params,
2460  
            @ref params,
2460  
            @ref params,
2461  
            @ref set_encoded_query,
2461  
            @ref set_encoded_query,
2462  
            @ref set_query.
2462  
            @ref set_query.
2463  
    */
2463  
    */
2464  
    url_base&
2464  
    url_base&
2465  
    remove_query() noexcept;
2465  
    remove_query() noexcept;
2466  

2466  

2467  
    //--------------------------------------------
2467  
    //--------------------------------------------
2468  
    //
2468  
    //
2469  
    // Fragment
2469  
    // Fragment
2470  
    //
2470  
    //
2471  
    //--------------------------------------------
2471  
    //--------------------------------------------
2472  

2472  

2473  
    /** Remove the fragment
2473  
    /** Remove the fragment
2474  

2474  

2475  
        This function removes the fragment.
2475  
        This function removes the fragment.
2476  
        An empty fragment is distinct from
2476  
        An empty fragment is distinct from
2477  
        having no fragment.
2477  
        having no fragment.
2478  

2478  

2479  
        @return `*this`
2479  
        @return `*this`
2480  

2480  

2481  
        @par Example
2481  
        @par Example
2482  
        @code
2482  
        @code
2483  
        assert( url( "?first=john&last=doe#anchor" ).remove_fragment().buffer() == "?first=john&last=doe" );
2483  
        assert( url( "?first=john&last=doe#anchor" ).remove_fragment().buffer() == "?first=john&last=doe" );
2484  
        @endcode
2484  
        @endcode
2485  

2485  

2486  
        @par Postconditions
2486  
        @par Postconditions
2487  
        @code
2487  
        @code
2488  
        this->has_fragment() == false && this->encoded_fragment() == ""
2488  
        this->has_fragment() == false && this->encoded_fragment() == ""
2489  
        @endcode
2489  
        @endcode
2490  

2490  

2491  
        @par Complexity
2491  
        @par Complexity
2492  
        Constant.
2492  
        Constant.
2493  

2493  

2494  
        @par Exception Safety
2494  
        @par Exception Safety
2495  
        Throws nothing.
2495  
        Throws nothing.
2496  

2496  

2497  
        @par BNF
2497  
        @par BNF
2498  
        @code
2498  
        @code
2499  
        fragment    = *( pchar / "/" / "?" )
2499  
        fragment    = *( pchar / "/" / "?" )
2500  
        @endcode
2500  
        @endcode
2501  

2501  

2502  
        @par Specification
2502  
        @par Specification
2503  
        @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.5"
2503  
        @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.5"
2504  
            >3.5.  Fragment</a>
2504  
            >3.5.  Fragment</a>
2505  

2505  

2506  
        @see
2506  
        @see
2507  
            @ref remove_fragment,
2507  
            @ref remove_fragment,
2508  
            @ref set_encoded_fragment,
2508  
            @ref set_encoded_fragment,
2509  
            @ref set_fragment.
2509  
            @ref set_fragment.
2510  
    */
2510  
    */
2511  
    url_base&
2511  
    url_base&
2512  
    remove_fragment() noexcept;
2512  
    remove_fragment() noexcept;
2513  

2513  

2514  
    /** Set the fragment.
2514  
    /** Set the fragment.
2515  

2515  

2516  
        This function sets the fragment to the
2516  
        This function sets the fragment to the
2517  
        specified string, which may be empty.
2517  
        specified string, which may be empty.
2518  
        An empty fragment is distinct from
2518  
        An empty fragment is distinct from
2519  
        having no fragment.
2519  
        having no fragment.
2520  
        Reserved characters in the string are
2520  
        Reserved characters in the string are
2521  
        percent-escaped in the result.
2521  
        percent-escaped in the result.
2522  

2522  

2523  
        @par Example
2523  
        @par Example
2524  
        @code
2524  
        @code
2525  
        assert( url("?first=john&last=doe" ).set_encoded_fragment( "john doe" ).encoded_fragment() == "john%20doe" );
2525  
        assert( url("?first=john&last=doe" ).set_encoded_fragment( "john doe" ).encoded_fragment() == "john%20doe" );
2526  
        @endcode
2526  
        @endcode
2527  

2527  

2528  
        @par Postconditions
2528  
        @par Postconditions
2529  
        @code
2529  
        @code
2530  
        this->has_fragment() == true && this->fragment() == s
2530  
        this->has_fragment() == true && this->fragment() == s
2531  
        @endcode
2531  
        @endcode
2532  

2532  

2533  
        @par Complexity
2533  
        @par Complexity
2534  
        Linear in `this->size() + s.size()`.
2534  
        Linear in `this->size() + s.size()`.
2535  

2535  

2536  
        @par Exception Safety
2536  
        @par Exception Safety
2537  
        Strong guarantee.
2537  
        Strong guarantee.
2538  
        Calls to allocate may throw.
2538  
        Calls to allocate may throw.
2539  

2539  

2540  
        @param s The string to set.
2540  
        @param s The string to set.
2541  

2541  

2542  
        @return `*this`
2542  
        @return `*this`
2543  

2543  

2544  
        @par BNF
2544  
        @par BNF
2545  
        @code
2545  
        @code
2546  
        fragment    = *( pchar / "/" / "?" )
2546  
        fragment    = *( pchar / "/" / "?" )
2547  
        @endcode
2547  
        @endcode
2548  

2548  

2549  
        @par Specification
2549  
        @par Specification
2550  
        @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.5"
2550  
        @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.5"
2551  
            >3.5.  Fragment</a>
2551  
            >3.5.  Fragment</a>
2552  

2552  

2553  
        @see
2553  
        @see
2554  
            @ref remove_fragment,
2554  
            @ref remove_fragment,
2555  
            @ref set_encoded_fragment.
2555  
            @ref set_encoded_fragment.
2556  
    */
2556  
    */
2557  
    url_base&
2557  
    url_base&
2558  
    set_fragment(
2558  
    set_fragment(
2559  
        core::string_view s);
2559  
        core::string_view s);
2560  

2560  

2561  
    /** Set the fragment.
2561  
    /** Set the fragment.
2562  

2562  

2563  
        This function sets the fragment to the
2563  
        This function sets the fragment to the
2564  
        specified string, which may contain
2564  
        specified string, which may contain
2565  
        percent-escapes and which may be empty.
2565  
        percent-escapes and which may be empty.
2566  
        An empty fragment is distinct from
2566  
        An empty fragment is distinct from
2567  
        having no fragment.
2567  
        having no fragment.
2568  
        Escapes in the string are preserved,
2568  
        Escapes in the string are preserved,
2569  
        and reserved characters in the string
2569  
        and reserved characters in the string
2570  
        are percent-escaped in the result.
2570  
        are percent-escaped in the result.
2571  

2571  

2572  
        @return `*this`
2572  
        @return `*this`
2573  

2573  

2574  
        @par Example
2574  
        @par Example
2575  
        @code
2575  
        @code
2576  
        assert( url("?first=john&last=doe" ).set_encoded_fragment( "john%2Ddoe" ).fragment() == "john-doe" );
2576  
        assert( url("?first=john&last=doe" ).set_encoded_fragment( "john%2Ddoe" ).fragment() == "john-doe" );
2577  
        @endcode
2577  
        @endcode
2578  

2578  

2579  
        @par Postconditions
2579  
        @par Postconditions
2580  
        @code
2580  
        @code
2581  
        this->has_fragment() == true && this->fragment() == decode_view( s )
2581  
        this->has_fragment() == true && this->fragment() == decode_view( s )
2582  
        @endcode
2582  
        @endcode
2583  

2583  

2584  
        @par Complexity
2584  
        @par Complexity
2585  
        Linear in `this->size() + s.size()`.
2585  
        Linear in `this->size() + s.size()`.
2586  

2586  

2587  
        @par Exception Safety
2587  
        @par Exception Safety
2588  
        Strong guarantee.
2588  
        Strong guarantee.
2589  
        Calls to allocate may throw.
2589  
        Calls to allocate may throw.
2590  
        Exceptions thrown on invalid input.
2590  
        Exceptions thrown on invalid input.
2591  

2591  

2592  
        @throw system_error
2592  
        @throw system_error
2593  
        `s` contains an invalid percent-encoding.
2593  
        `s` contains an invalid percent-encoding.
2594  

2594  

2595  
        @param s The string to set.
2595  
        @param s The string to set.
2596  

2596  

2597  
        @return `*this`
2597  
        @return `*this`
2598  

2598  

2599  
        @par BNF
2599  
        @par BNF
2600  
        @code
2600  
        @code
2601  
        fragment    = *( pchar / "/" / "?" )
2601  
        fragment    = *( pchar / "/" / "?" )
2602  
        @endcode
2602  
        @endcode
2603  

2603  

2604  
        @par Specification
2604  
        @par Specification
2605  
        @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.5"
2605  
        @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.5"
2606  
            >3.5.  Fragment</a>
2606  
            >3.5.  Fragment</a>
2607  

2607  

2608  
        @see
2608  
        @see
2609  
            @ref remove_fragment,
2609  
            @ref remove_fragment,
2610  
            @ref set_fragment.
2610  
            @ref set_fragment.
2611  
    */
2611  
    */
2612  
    url_base&
2612  
    url_base&
2613  
    set_encoded_fragment(
2613  
    set_encoded_fragment(
2614  
        pct_string_view s);
2614  
        pct_string_view s);
2615  

2615  

2616  
    //--------------------------------------------
2616  
    //--------------------------------------------
2617  
    //
2617  
    //
2618  
    // Compound Fields
2618  
    // Compound Fields
2619  
    //
2619  
    //
2620  
    //--------------------------------------------
2620  
    //--------------------------------------------
2621  

2621  

2622  
    /** Remove the origin component
2622  
    /** Remove the origin component
2623  

2623  

2624  
        This function removes the origin, which
2624  
        This function removes the origin, which
2625  
        consists of the scheme and authority.
2625  
        consists of the scheme and authority.
2626  

2626  

2627  
        @return `*this`
2627  
        @return `*this`
2628  

2628  

2629  
        @par Example
2629  
        @par Example
2630  
        @code
2630  
        @code
2631  
        assert( url( "http://www.example.com/index.htm" ).remove_origin().buffer() == "/index.htm" );
2631  
        assert( url( "http://www.example.com/index.htm" ).remove_origin().buffer() == "/index.htm" );
2632  
        @endcode
2632  
        @endcode
2633  

2633  

2634  
        @par Postconditions
2634  
        @par Postconditions
2635  
        @code
2635  
        @code
2636  
        this->scheme_id() == scheme::none && this->has_authority() == false
2636  
        this->scheme_id() == scheme::none && this->has_authority() == false
2637  
        @endcode
2637  
        @endcode
2638  

2638  

2639  
        @par Complexity
2639  
        @par Complexity
2640  
        Linear in `this->size()`.
2640  
        Linear in `this->size()`.
2641  

2641  

2642  
        @par Exception Safety
2642  
        @par Exception Safety
2643  
        Throws nothing.
2643  
        Throws nothing.
2644  
    */
2644  
    */
2645  
    url_base&
2645  
    url_base&
2646  
    remove_origin();
2646  
    remove_origin();
2647  

2647  

2648  
    //--------------------------------------------
2648  
    //--------------------------------------------
2649  
    //
2649  
    //
2650  
    // Normalization
2650  
    // Normalization
2651  
    //
2651  
    //
2652  
    //--------------------------------------------
2652  
    //--------------------------------------------
2653  

2653  

2654  
    /** Normalize the URL components
2654  
    /** Normalize the URL components
2655  

2655  

2656  
        Applies Syntax-based normalization to
2656  
        Applies Syntax-based normalization to
2657  
        all components of the URL.
2657  
        all components of the URL.
2658  

2658  

2659  
        The scheme is normalized to lowercase.
2659  
        The scheme is normalized to lowercase.
2660  

2660  

2661  
        @code
2661  
        @code
2662  
        assert( url( "HTTP://www.example.com" ).normalize().buffer() == "http://www.example.com" );
2662  
        assert( url( "HTTP://www.example.com" ).normalize().buffer() == "http://www.example.com" );
2663  
        @endcode
2663  
        @endcode
2664  

2664  

2665  
        The host is normalized to lowercase.
2665  
        The host is normalized to lowercase.
2666  
        Percent-encoding triplets are normalized
2666  
        Percent-encoding triplets are normalized
2667  
        to uppercase letters. Percent-encoded
2667  
        to uppercase letters. Percent-encoded
2668  
        octets that correspond to unreserved
2668  
        octets that correspond to unreserved
2669  
        characters are decoded.
2669  
        characters are decoded.
2670  

2670  

2671  
        @code
2671  
        @code
2672  
        assert( url( "http://www.Example.com" ).normalize().buffer() == "http://www.example.com" );
2672  
        assert( url( "http://www.Example.com" ).normalize().buffer() == "http://www.example.com" );
2673  
        assert( url( "http://www.%65xample.com" ).normalize().buffer() == "http://www.example.com" );
2673  
        assert( url( "http://www.%65xample.com" ).normalize().buffer() == "http://www.example.com" );
2674  
        @endcode
2674  
        @endcode
2675  

2675  

2676  
        Percent-encoding triplets in the path
2676  
        Percent-encoding triplets in the path
2677  
        are normalized to uppercase letters.
2677  
        are normalized to uppercase letters.
2678  
        Percent-encoded octets that correspond
2678  
        Percent-encoded octets that correspond
2679  
        to unreserved characters are decoded.
2679  
        to unreserved characters are decoded.
2680  
        Redundant path-segments "." and ".."
2680  
        Redundant path-segments "." and ".."
2681  
        are removed.
2681  
        are removed.
2682  

2682  

2683  
        @code
2683  
        @code
2684  
        assert( url( "http://www.example.com/a/b/../c" ).normalize().buffer() == "http://www.example.com/a/c" );
2684  
        assert( url( "http://www.example.com/a/b/../c" ).normalize().buffer() == "http://www.example.com/a/c" );
2685  
        assert( url( "http://www.example.com/a/./b" ).normalize().buffer() == "http://www.example.com/a/b" );
2685  
        assert( url( "http://www.example.com/a/./b" ).normalize().buffer() == "http://www.example.com/a/b" );
2686  
        assert( url( "http://www.example.com/%63ss" ).normalize().buffer() == "http://www.example.com/css" );
2686  
        assert( url( "http://www.example.com/%63ss" ).normalize().buffer() == "http://www.example.com/css" );
2687  
        @endcode
2687  
        @endcode
2688  

2688  

2689  
        Percent-encoding triplets in the query
2689  
        Percent-encoding triplets in the query
2690  
        are normalized to uppercase letters.
2690  
        are normalized to uppercase letters.
2691  
        Percent-encoded octets that correspond
2691  
        Percent-encoded octets that correspond
2692  
        to unreserved characters are decoded.
2692  
        to unreserved characters are decoded.
2693  

2693  

2694  
        @code
2694  
        @code
2695  
        assert( url( "http://www.example.com?a=%62" ).normalize().buffer() == "http://www.example.com?a=b" );
2695  
        assert( url( "http://www.example.com?a=%62" ).normalize().buffer() == "http://www.example.com?a=b" );
2696  
        @endcode
2696  
        @endcode
2697  

2697  

2698  
        Percent-encoding triplets in the fragment
2698  
        Percent-encoding triplets in the fragment
2699  
        are normalized to uppercase letters.
2699  
        are normalized to uppercase letters.
2700  
        Percent-encoded octets that correspond
2700  
        Percent-encoded octets that correspond
2701  
        to unreserved characters are decoded.
2701  
        to unreserved characters are decoded.
2702  

2702  

2703  
        @code
2703  
        @code
2704  
        assert( url( "http://www.example.com#%61bc" ).normalize().buffer() == "http://www.example.com#abc" );
2704  
        assert( url( "http://www.example.com#%61bc" ).normalize().buffer() == "http://www.example.com#abc" );
2705  
        @endcode
2705  
        @endcode
2706  

2706  

2707  
        Applying normalization to a URL with all
2707  
        Applying normalization to a URL with all
2708  
        components percent-encoded:
2708  
        components percent-encoded:
2709  

2709  

2710  
        @code
2710  
        @code
2711  
        assert( url( "HTTP://www.Example.com/%70ath?%71uery#%66rag" ).normalize().buffer() == "http://www.example.com/path?query#frag" );
2711  
        assert( url( "HTTP://www.Example.com/%70ath?%71uery#%66rag" ).normalize().buffer() == "http://www.example.com/path?query#frag" );
2712  
        @endcode
2712  
        @endcode
2713  

2713  

2714  
        @return `*this`
2714  
        @return `*this`
2715  

2715  

2716  
        @par Exception Safety
2716  
        @par Exception Safety
2717  
        Strong guarantee.
2717  
        Strong guarantee.
2718  
        Calls to allocate may throw.
2718  
        Calls to allocate may throw.
2719  

2719  

2720  
        @par Specification
2720  
        @par Specification
2721  
        @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-6.2.2"
2721  
        @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-6.2.2"
2722  
            >6.2.2 Syntax-Based Normalization (rfc3986)</a>
2722  
            >6.2.2 Syntax-Based Normalization (rfc3986)</a>
2723  

2723  

2724  
        @see
2724  
        @see
2725  
            @ref normalize_scheme,
2725  
            @ref normalize_scheme,
2726  
            @ref normalize_authority,
2726  
            @ref normalize_authority,
2727  
            @ref normalize_path,
2727  
            @ref normalize_path,
2728  
            @ref normalize_query,
2728  
            @ref normalize_query,
2729  
            @ref normalize_fragment
2729  
            @ref normalize_fragment
2730  

2730  

2731  
    */
2731  
    */
2732  
    url_base&
2732  
    url_base&
2733  
    normalize();
2733  
    normalize();
2734  

2734  

2735  
    /** Normalize the URL scheme
2735  
    /** Normalize the URL scheme
2736  

2736  

2737  
        Applies Syntax-based normalization to the
2737  
        Applies Syntax-based normalization to the
2738  
        URL scheme.
2738  
        URL scheme.
2739  

2739  

2740  
        The scheme is normalized to lowercase.
2740  
        The scheme is normalized to lowercase.
2741  

2741  

2742  
        @code
2742  
        @code
2743  
        assert( url( "HTTP://www.example.com" ).normalize_scheme().buffer() == "http://www.example.com" );
2743  
        assert( url( "HTTP://www.example.com" ).normalize_scheme().buffer() == "http://www.example.com" );
2744  
        @endcode
2744  
        @endcode
2745  

2745  

2746  
        @return `*this`
2746  
        @return `*this`
2747  

2747  

2748  
        @par Exception Safety
2748  
        @par Exception Safety
2749  
        Strong guarantee.
2749  
        Strong guarantee.
2750  
        Calls to allocate may throw.
2750  
        Calls to allocate may throw.
2751  

2751  

2752  
        @par Specification
2752  
        @par Specification
2753  
        @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-6.2.2"
2753  
        @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-6.2.2"
2754  
            >6.2.2 Syntax-Based Normalization (rfc3986)</a>
2754  
            >6.2.2 Syntax-Based Normalization (rfc3986)</a>
2755  

2755  

2756  
    */
2756  
    */
2757  
    url_base&
2757  
    url_base&
2758  
    normalize_scheme();
2758  
    normalize_scheme();
2759  

2759  

2760  
    /** Normalize the URL authority
2760  
    /** Normalize the URL authority
2761  

2761  

2762  
        Applies Syntax-based normalization to the
2762  
        Applies Syntax-based normalization to the
2763  
        URL authority.
2763  
        URL authority.
2764  

2764  

2765  
        The host is normalized to lowercase.
2765  
        The host is normalized to lowercase.
2766  
        Percent-encoding triplets are normalized
2766  
        Percent-encoding triplets are normalized
2767  
        to uppercase letters. Percent-encoded
2767  
        to uppercase letters. Percent-encoded
2768  
        octets that correspond to unreserved
2768  
        octets that correspond to unreserved
2769  
        characters are decoded.
2769  
        characters are decoded.
2770  

2770  

2771  
        @code
2771  
        @code
2772  
        assert( url( "http://www.Example.com" ).normalize_authority().buffer() == "http://www.example.com" );
2772  
        assert( url( "http://www.Example.com" ).normalize_authority().buffer() == "http://www.example.com" );
2773  
        assert( url( "http://www.%65xample.com" ).normalize_authority().buffer() == "http://www.example.com" );
2773  
        assert( url( "http://www.%65xample.com" ).normalize_authority().buffer() == "http://www.example.com" );
2774  
        @endcode
2774  
        @endcode
2775  

2775  

2776  
        @return `*this`
2776  
        @return `*this`
2777  

2777  

2778  
        @par Exception Safety
2778  
        @par Exception Safety
2779  
        Strong guarantee.
2779  
        Strong guarantee.
2780  
        Calls to allocate may throw.
2780  
        Calls to allocate may throw.
2781  

2781  

2782  
        @par Specification
2782  
        @par Specification
2783  
        @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-6.2.2"
2783  
        @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-6.2.2"
2784  
            >6.2.2 Syntax-Based Normalization (rfc3986)</a>
2784  
            >6.2.2 Syntax-Based Normalization (rfc3986)</a>
2785  

2785  

2786  
    */
2786  
    */
2787  
    url_base&
2787  
    url_base&
2788  
    normalize_authority();
2788  
    normalize_authority();
2789  

2789  

2790  
    /** Normalize the URL path
2790  
    /** Normalize the URL path
2791  

2791  

2792  
        Applies Syntax-based normalization to the
2792  
        Applies Syntax-based normalization to the
2793  
        URL path.
2793  
        URL path.
2794  

2794  

2795  
        Percent-encoding triplets are normalized
2795  
        Percent-encoding triplets are normalized
2796  
        to uppercase letters. Percent-encoded
2796  
        to uppercase letters. Percent-encoded
2797  
        octets that correspond to unreserved
2797  
        octets that correspond to unreserved
2798  
        characters are decoded. Redundant
2798  
        characters are decoded. Redundant
2799  
        path-segments "." and ".." are removed.
2799  
        path-segments "." and ".." are removed.
2800  

2800  

2801  
        @code
2801  
        @code
2802  
        assert( url( "http://www.example.com/a/b/../c" ).normalize_path().buffer() == "http://www.example.com/a/c" );
2802  
        assert( url( "http://www.example.com/a/b/../c" ).normalize_path().buffer() == "http://www.example.com/a/c" );
2803  
        assert( url( "http://www.example.com/a/./b" ).normalize_path().buffer() == "http://www.example.com/a/b" );
2803  
        assert( url( "http://www.example.com/a/./b" ).normalize_path().buffer() == "http://www.example.com/a/b" );
2804  
        assert( url( "http://www.example.com/%63ss" ).normalize_path().buffer() == "http://www.example.com/css" );
2804  
        assert( url( "http://www.example.com/%63ss" ).normalize_path().buffer() == "http://www.example.com/css" );
2805  
        @endcode
2805  
        @endcode
2806  

2806  

2807  
        @return `*this`
2807  
        @return `*this`
2808  

2808  

2809  
        @par Exception Safety
2809  
        @par Exception Safety
2810  
        Strong guarantee.
2810  
        Strong guarantee.
2811  
        Calls to allocate may throw.
2811  
        Calls to allocate may throw.
2812  

2812  

2813  
        @par Specification
2813  
        @par Specification
2814  
        @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-6.2.2"
2814  
        @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-6.2.2"
2815  
            >6.2.2 Syntax-Based Normalization (rfc3986)</a>
2815  
            >6.2.2 Syntax-Based Normalization (rfc3986)</a>
2816  

2816  

2817  
    */
2817  
    */
2818  
    url_base&
2818  
    url_base&
2819  
    normalize_path();
2819  
    normalize_path();
2820  

2820  

2821  
    /** Normalize the URL query
2821  
    /** Normalize the URL query
2822  

2822  

2823  
        Applies Syntax-based normalization to the
2823  
        Applies Syntax-based normalization to the
2824  
        URL query.
2824  
        URL query.
2825  

2825  

2826  
        Percent-encoding triplets are normalized
2826  
        Percent-encoding triplets are normalized
2827  
        to uppercase letters. Percent-encoded
2827  
        to uppercase letters. Percent-encoded
2828  
        octets that correspond to unreserved
2828  
        octets that correspond to unreserved
2829  
        characters are decoded.
2829  
        characters are decoded.
2830  

2830  

2831  
        @code
2831  
        @code
2832  
        assert( url( "http://www.example.com?a=%62" ).normalize_query().buffer() == "http://www.example.com?a=b" );
2832  
        assert( url( "http://www.example.com?a=%62" ).normalize_query().buffer() == "http://www.example.com?a=b" );
2833  
        @endcode
2833  
        @endcode
2834  

2834  

2835  
        @return `*this`
2835  
        @return `*this`
2836  

2836  

2837  
        @par Exception Safety
2837  
        @par Exception Safety
2838  
        Strong guarantee.
2838  
        Strong guarantee.
2839  
        Calls to allocate may throw.
2839  
        Calls to allocate may throw.
2840  

2840  

2841  
        @par Specification
2841  
        @par Specification
2842  
        @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-6.2.2"
2842  
        @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-6.2.2"
2843  
            >6.2.2 Syntax-Based Normalization (rfc3986)</a>
2843  
            >6.2.2 Syntax-Based Normalization (rfc3986)</a>
2844  

2844  

2845  
    */
2845  
    */
2846  
    url_base&
2846  
    url_base&
2847  
    normalize_query();
2847  
    normalize_query();
2848  

2848  

2849  
    /** Normalize the URL fragment
2849  
    /** Normalize the URL fragment
2850  

2850  

2851  
        Applies Syntax-based normalization to the
2851  
        Applies Syntax-based normalization to the
2852  
        URL fragment.
2852  
        URL fragment.
2853  

2853  

2854  
        Percent-encoding triplets are normalized
2854  
        Percent-encoding triplets are normalized
2855  
        to uppercase letters. Percent-encoded
2855  
        to uppercase letters. Percent-encoded
2856  
        octets that correspond to unreserved
2856  
        octets that correspond to unreserved
2857  
        characters are decoded.
2857  
        characters are decoded.
2858  

2858  

2859  
        @code
2859  
        @code
2860  
        assert( url( "http://www.example.com#%61bc" ).normalize_fragment().buffer() == "http://www.example.com#abc" );
2860  
        assert( url( "http://www.example.com#%61bc" ).normalize_fragment().buffer() == "http://www.example.com#abc" );
2861  
        @endcode
2861  
        @endcode
2862  

2862  

2863  
        @return `*this`
2863  
        @return `*this`
2864  

2864  

2865  
        @par Exception Safety
2865  
        @par Exception Safety
2866  
        Strong guarantee.
2866  
        Strong guarantee.
2867  
        Calls to allocate may throw.
2867  
        Calls to allocate may throw.
2868  

2868  

2869  
        @par Specification
2869  
        @par Specification
2870  
        @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-6.2.2"
2870  
        @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-6.2.2"
2871  
            >6.2.2 Syntax-Based Normalization (rfc3986)</a>
2871  
            >6.2.2 Syntax-Based Normalization (rfc3986)</a>
2872  

2872  

2873  
    */
2873  
    */
2874  
    url_base&
2874  
    url_base&
2875  
    normalize_fragment();
2875  
    normalize_fragment();
2876  

2876  

2877  
    //
2877  
    //
2878  
    // (end of fluent API)
2878  
    // (end of fluent API)
2879  
    //
2879  
    //
2880  
    //--------------------------------------------
2880  
    //--------------------------------------------
2881  

2881  

2882  
    //--------------------------------------------
2882  
    //--------------------------------------------
2883  
    //
2883  
    //
2884  
    // Resolution
2884  
    // Resolution
2885  
    //
2885  
    //
2886  
    //--------------------------------------------
2886  
    //--------------------------------------------
2887  

2887  

2888  
    /** Resolve a URL reference against this base URL
2888  
    /** Resolve a URL reference against this base URL
2889  

2889  

2890  
        This function attempts to resolve a URL
2890  
        This function attempts to resolve a URL
2891  
        reference `ref` against this base URL
2891  
        reference `ref` against this base URL
2892  
        in a manner similar to that of a web browser
2892  
        in a manner similar to that of a web browser
2893  
        resolving an anchor tag.
2893  
        resolving an anchor tag.
2894  

2894  

2895  
        This URL must satisfy the <em>URI</em>
2895  
        This URL must satisfy the <em>URI</em>
2896  
        grammar. In other words, it must contain
2896  
        grammar. In other words, it must contain
2897  
        a scheme.
2897  
        a scheme.
2898  

2898  

2899  
        Relative references are only usable when
2899  
        Relative references are only usable when
2900  
        in the context of a base absolute URI.
2900  
        in the context of a base absolute URI.
2901  
        This process of resolving a relative
2901  
        This process of resolving a relative
2902  
        <em>reference</em> within the context of
2902  
        <em>reference</em> within the context of
2903  
        a <em>base</em> URI is defined in detail
2903  
        a <em>base</em> URI is defined in detail
2904  
        in rfc3986 (see below).
2904  
        in rfc3986 (see below).
2905  

2905  

2906  
        The resolution process works as if the
2906  
        The resolution process works as if the
2907  
        relative reference is appended to the base
2907  
        relative reference is appended to the base
2908  
        URI and the result is normalized.
2908  
        URI and the result is normalized.
2909  

2909  

2910  
        Given the input base URL, this function
2910  
        Given the input base URL, this function
2911  
        resolves the relative reference
2911  
        resolves the relative reference
2912  
        as if performing the following steps:
2912  
        as if performing the following steps:
2913  

2913  

2914  
        @li Ensure the base URI has at least a scheme
2914  
        @li Ensure the base URI has at least a scheme
2915  
        @li Normalizing the reference path
2915  
        @li Normalizing the reference path
2916  
        @li Merge base and reference paths
2916  
        @li Merge base and reference paths
2917  
        @li Normalize the merged path
2917  
        @li Normalize the merged path
2918  

2918  

2919  
        This function places the result of the
2919  
        This function places the result of the
2920  
        resolution into this URL in place.
2920  
        resolution into this URL in place.
2921  

2921  

2922  
        If an error occurs, the contents of
2922  
        If an error occurs, the contents of
2923  
        this URL are unspecified and a `boost::system::result`
2923  
        this URL are unspecified and a `boost::system::result`
2924  
        with an `system::error_code` is returned.
2924  
        with an `system::error_code` is returned.
2925  

2925  

2926  
        @note Abnormal hrefs where the number of ".."
2926  
        @note Abnormal hrefs where the number of ".."
2927  
        segments exceeds the number of segments in
2927  
        segments exceeds the number of segments in
2928  
        the base path are handled by including the
2928  
        the base path are handled by including the
2929  
        unmatched ".." segments in the result, as described
2929  
        unmatched ".." segments in the result, as described
2930  
        in <a href="https://www.rfc-editor.org/errata/eid4547"
2930  
        in <a href="https://www.rfc-editor.org/errata/eid4547"
2931  
        >Errata 4547</a>.
2931  
        >Errata 4547</a>.
2932  

2932  

2933  
        @par Example
2933  
        @par Example
2934  
        @code
2934  
        @code
2935  
        url base1( "/one/two/three" );
2935  
        url base1( "/one/two/three" );
2936  
        base1.resolve("four");
2936  
        base1.resolve("four");
2937  
        assert( base1.buffer() == "/one/two/four" );
2937  
        assert( base1.buffer() == "/one/two/four" );
2938  

2938  

2939  
        url base2( "http://example.com/" )
2939  
        url base2( "http://example.com/" )
2940  
        base2.resolve("/one");
2940  
        base2.resolve("/one");
2941  
        assert( base2.buffer() == "http://example.com/one" );
2941  
        assert( base2.buffer() == "http://example.com/one" );
2942  

2942  

2943  
        url base3( "http://example.com/one" );
2943  
        url base3( "http://example.com/one" );
2944  
        base3.resolve("/two");
2944  
        base3.resolve("/two");
2945  
        assert( base3.buffer() == "http://example.com/two" );
2945  
        assert( base3.buffer() == "http://example.com/two" );
2946  

2946  

2947  
        url base4( "http://a/b/c/d;p?q" );
2947  
        url base4( "http://a/b/c/d;p?q" );
2948  
        base4.resolve("g#s");
2948  
        base4.resolve("g#s");
2949  
        assert( base4.buffer() == "http://a/b/c/g#s" );
2949  
        assert( base4.buffer() == "http://a/b/c/g#s" );
2950  
        @endcode
2950  
        @endcode
2951  

2951  

2952  
        @par BNF
2952  
        @par BNF
2953  
        @code
2953  
        @code
2954  
        absolute-URI  = scheme ":" hier-part [ "?" query ]
2954  
        absolute-URI  = scheme ":" hier-part [ "?" query ]
2955  
        @endcode
2955  
        @endcode
2956  

2956  

2957  
        @par Exception Safety
2957  
        @par Exception Safety
2958  
        Basic guarantee.
2958  
        Basic guarantee.
2959  
        Calls to allocate may throw.
2959  
        Calls to allocate may throw.
2960  

2960  

2961  
        @return An empty `boost::system::result` upon success,
2961  
        @return An empty `boost::system::result` upon success,
2962  
        otherwise an error code if `!base.has_scheme()`.
2962  
        otherwise an error code if `!base.has_scheme()`.
2963  

2963  

2964  
        @param ref The URL reference to resolve.
2964  
        @param ref The URL reference to resolve.
2965  

2965  

2966  
        @par Specification
2966  
        @par Specification
2967  
        <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-5"
2967  
        <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-5"
2968  
            >5. Reference Resolution (rfc3986)</a>
2968  
            >5. Reference Resolution (rfc3986)</a>
2969  

2969  

2970  
        @see
2970  
        @see
2971  
            @ref url,
2971  
            @ref url,
2972  
            @ref url_view.
2972  
            @ref url_view.
2973  
    */
2973  
    */
2974  
    system::result<void>
2974  
    system::result<void>
2975  
    resolve(
2975  
    resolve(
2976  
        url_view_base const& ref);
2976  
        url_view_base const& ref);
2977  

2977  

2978  
    friend
2978  
    friend
2979  
    system::result<void>
2979  
    system::result<void>
2980  
    resolve(
2980  
    resolve(
2981  
        url_view_base const& base,
2981  
        url_view_base const& base,
2982  
        url_view_base const& ref,
2982  
        url_view_base const& ref,
2983  
        url_base& dest);
2983  
        url_base& dest);
2984  

2984  

2985  
private:
2985  
private:
2986  
    //--------------------------------------------
2986  
    //--------------------------------------------
2987  
    //
2987  
    //
2988  
    // implementation
2988  
    // implementation
2989  
    //
2989  
    //
2990  
    //--------------------------------------------
2990  
    //--------------------------------------------
2991  

2991  

2992  
    void  check_invariants() const noexcept;
2992  
    void  check_invariants() const noexcept;
2993  

2993  

2994  
    char* resize_impl(int, std::size_t, op_t&);
2994  
    char* resize_impl(int, std::size_t, op_t&);
2995  
    char* resize_impl(int, int, std::size_t, op_t&);
2995  
    char* resize_impl(int, int, std::size_t, op_t&);
2996  
    char* shrink_impl(int, std::size_t, op_t&);
2996  
    char* shrink_impl(int, std::size_t, op_t&);
2997  
    char* shrink_impl(int, int, std::size_t, op_t&);
2997  
    char* shrink_impl(int, int, std::size_t, op_t&);
2998  

2998  

2999  
    void  set_scheme_impl(core::string_view, urls::scheme);
2999  
    void  set_scheme_impl(core::string_view, urls::scheme);
3000  
    char* set_user_impl(std::size_t n, op_t& op);
3000  
    char* set_user_impl(std::size_t n, op_t& op);
3001  
    char* set_password_impl(std::size_t n, op_t& op);
3001  
    char* set_password_impl(std::size_t n, op_t& op);
3002  
    char* set_userinfo_impl(std::size_t n, op_t& op);
3002  
    char* set_userinfo_impl(std::size_t n, op_t& op);
3003  
    char* set_host_impl(std::size_t n, op_t& op);
3003  
    char* set_host_impl(std::size_t n, op_t& op);
3004  
    char* set_port_impl(std::size_t n, op_t& op);
3004  
    char* set_port_impl(std::size_t n, op_t& op);
3005  
    char* set_path_impl(std::size_t n, op_t& op);
3005  
    char* set_path_impl(std::size_t n, op_t& op);
3006  

3006  

3007  
    void
3007  
    void
3008  
    set_host_ipv6_and_zone_id(
3008  
    set_host_ipv6_and_zone_id(
3009  
        ipv6_address const& addr,
3009  
        ipv6_address const& addr,
3010  
        core::string_view zone_id);
3010  
        core::string_view zone_id);
3011  

3011  

3012  
    void
3012  
    void
3013  
    set_host_ipv6_and_encoded_zone_id(
3013  
    set_host_ipv6_and_encoded_zone_id(
3014  
        ipv6_address const& addr,
3014  
        ipv6_address const& addr,
3015  
        pct_string_view zone_id);
3015  
        pct_string_view zone_id);
3016  

3016  

3017  
    core::string_view
3017  
    core::string_view
3018  
    first_segment() const noexcept;
3018  
    first_segment() const noexcept;
3019  

3019  

3020  
    detail::segments_iter_impl
3020  
    detail::segments_iter_impl
3021  
    edit_segments(
3021  
    edit_segments(
3022  
        detail::segments_iter_impl const&,
3022  
        detail::segments_iter_impl const&,
3023  
        detail::segments_iter_impl const&,
3023  
        detail::segments_iter_impl const&,
3024  
        detail::any_segments_iter&& it0,
3024  
        detail::any_segments_iter&& it0,
3025  
        int absolute = -1);
3025  
        int absolute = -1);
3026  

3026  

3027  
    auto
3027  
    auto
3028  
    edit_params(
3028  
    edit_params(
3029  
        detail::params_iter_impl const&,
3029  
        detail::params_iter_impl const&,
3030  
        detail::params_iter_impl const&,
3030  
        detail::params_iter_impl const&,
3031  
        detail::any_params_iter&&) ->
3031  
        detail::any_params_iter&&) ->
3032  
            detail::params_iter_impl;
3032  
            detail::params_iter_impl;
3033  

3033  

3034  
    // Decode any unnecessary percent-escapes
3034  
    // Decode any unnecessary percent-escapes
3035  
    // and ensures hexadecimals are uppercase.
3035  
    // and ensures hexadecimals are uppercase.
3036  
    // The encoding of ignored characters is
3036  
    // The encoding of ignored characters is
3037  
    // preserved.
3037  
    // preserved.
3038  
    template
3038  
    template
3039  
        <class AllowedCharSet,
3039  
        <class AllowedCharSet,
3040  
         class IgnoredCharSet>
3040  
         class IgnoredCharSet>
3041  
    void
3041  
    void
3042  
    normalize_octets_impl(
3042  
    normalize_octets_impl(
3043  
        int,
3043  
        int,
3044  
        AllowedCharSet const& allowed,
3044  
        AllowedCharSet const& allowed,
3045  
        IgnoredCharSet const& ignored,
3045  
        IgnoredCharSet const& ignored,
3046  
        op_t&) noexcept;
3046  
        op_t&) noexcept;
3047  

3047  

3048  
    template<class CharSet>
3048  
    template<class CharSet>
3049  
    void
3049  
    void
3050  
    normalize_octets_impl(
3050  
    normalize_octets_impl(
3051  
        int,
3051  
        int,
3052  
        CharSet const& allowed,
3052  
        CharSet const& allowed,
3053  
        op_t&) noexcept;
3053  
        op_t&) noexcept;
3054  

3054  

3055  
    void decoded_to_lower_impl(int id) noexcept;
3055  
    void decoded_to_lower_impl(int id) noexcept;
3056  
    void to_lower_impl(int id) noexcept;
3056  
    void to_lower_impl(int id) noexcept;
3057  
};
3057  
};
3058  

3058  

3059  
//------------------------------------------------
3059  
//------------------------------------------------
3060  

3060  

3061  
/** Resolve a URL reference against a base URL
3061  
/** Resolve a URL reference against a base URL
3062  

3062  

3063  
    This function attempts to resolve a URL
3063  
    This function attempts to resolve a URL
3064  
    reference `ref` against the base URL `base`
3064  
    reference `ref` against the base URL `base`
3065  
    in a manner similar to that of a web browser
3065  
    in a manner similar to that of a web browser
3066  
    resolving an anchor tag.
3066  
    resolving an anchor tag.
3067  

3067  

3068  
    The base URL must satisfy the <em>URI</em>
3068  
    The base URL must satisfy the <em>URI</em>
3069  
    grammar. In other words, it must contain
3069  
    grammar. In other words, it must contain
3070  
    a scheme.
3070  
    a scheme.
3071  

3071  

3072  
    Relative references are only usable when
3072  
    Relative references are only usable when
3073  
    in the context of a base absolute URI.
3073  
    in the context of a base absolute URI.
3074  
    This process of resolving a relative
3074  
    This process of resolving a relative
3075  
    <em>reference</em> within the context of
3075  
    <em>reference</em> within the context of
3076  
    a <em>base</em> URI is defined in detail
3076  
    a <em>base</em> URI is defined in detail
3077  
    in rfc3986 (see below).
3077  
    in rfc3986 (see below).
3078  

3078  

3079  
    The resolution process works as if the
3079  
    The resolution process works as if the
3080  
    relative reference is appended to the base
3080  
    relative reference is appended to the base
3081  
    URI and the result is normalized.
3081  
    URI and the result is normalized.
3082  

3082  

3083  
    Given the input base URL, this function
3083  
    Given the input base URL, this function
3084  
    resolves the relative reference
3084  
    resolves the relative reference
3085  
    as if performing the following steps:
3085  
    as if performing the following steps:
3086  

3086  

3087  
    @li Ensure the base URI has at least a scheme
3087  
    @li Ensure the base URI has at least a scheme
3088  
    @li Normalizing the reference path
3088  
    @li Normalizing the reference path
3089  
    @li Merge base and reference paths
3089  
    @li Merge base and reference paths
3090  
    @li Normalize the merged path
3090  
    @li Normalize the merged path
3091  

3091  

3092  
    This function places the result of the
3092  
    This function places the result of the
3093  
    resolution into `dest`, which can be
3093  
    resolution into `dest`, which can be
3094  
    any of the url containers that inherit
3094  
    any of the url containers that inherit
3095  
    from @ref url_base.
3095  
    from @ref url_base.
3096  

3096  

3097  
    If an error occurs, the contents of
3097  
    If an error occurs, the contents of
3098  
    `dest` is unspecified and `ec` is set.
3098  
    `dest` is unspecified and `ec` is set.
3099  

3099  

3100  
    @note Abnormal hrefs where the number of ".."
3100  
    @note Abnormal hrefs where the number of ".."
3101  
    segments exceeds the number of segments in
3101  
    segments exceeds the number of segments in
3102  
    the base path are handled by including the
3102  
    the base path are handled by including the
3103  
    unmatched ".." segments in the result, as described
3103  
    unmatched ".." segments in the result, as described
3104  
    in <a href="https://www.rfc-editor.org/errata/eid4547"
3104  
    in <a href="https://www.rfc-editor.org/errata/eid4547"
3105  
    >Errata 4547</a>.
3105  
    >Errata 4547</a>.
3106  

3106  

3107  
    @par Example
3107  
    @par Example
3108  
    @code
3108  
    @code
3109  
    url dest;
3109  
    url dest;
3110  
    system::error_code ec;
3110  
    system::error_code ec;
3111  

3111  

3112  
    resolve("/one/two/three", "four", dest, ec);
3112  
    resolve("/one/two/three", "four", dest, ec);
3113  
    assert( dest.str() == "/one/two/four" );
3113  
    assert( dest.str() == "/one/two/four" );
3114  

3114  

3115  
    resolve("http://example.com/", "/one", dest, ec);
3115  
    resolve("http://example.com/", "/one", dest, ec);
3116  
    assert( dest.str() == "http://example.com/one" );
3116  
    assert( dest.str() == "http://example.com/one" );
3117  

3117  

3118  
    resolve("http://example.com/one", "/two", dest, ec);
3118  
    resolve("http://example.com/one", "/two", dest, ec);
3119  
    assert( dest.str() == "http://example.com/two" );
3119  
    assert( dest.str() == "http://example.com/two" );
3120  

3120  

3121  
    resolve("http://a/b/c/d;p?q", "g#s", dest, ec);
3121  
    resolve("http://a/b/c/d;p?q", "g#s", dest, ec);
3122  
    assert( dest.str() == "http://a/b/c/g#s" );
3122  
    assert( dest.str() == "http://a/b/c/g#s" );
3123  
    @endcode
3123  
    @endcode
3124  

3124  

3125  
    @par BNF
3125  
    @par BNF
3126  
    @code
3126  
    @code
3127  
    absolute-URI  = scheme ":" hier-part [ "?" query ]
3127  
    absolute-URI  = scheme ":" hier-part [ "?" query ]
3128  
    @endcode
3128  
    @endcode
3129  

3129  

3130  
    @par Exception Safety
3130  
    @par Exception Safety
3131  
    Basic guarantee.
3131  
    Basic guarantee.
3132  
    Calls to allocate may throw.
3132  
    Calls to allocate may throw.
3133  

3133  

3134  
    @return An empty `boost::system::result` upon success,
3134  
    @return An empty `boost::system::result` upon success,
3135  
    otherwise an error code if `!base.has_scheme()`.
3135  
    otherwise an error code if `!base.has_scheme()`.
3136  

3136  

3137  
    @param base The base URL to resolve against.
3137  
    @param base The base URL to resolve against.
3138  

3138  

3139  
    @param ref The URL reference to resolve.
3139  
    @param ref The URL reference to resolve.
3140  

3140  

3141  
    @param dest The container where the result
3141  
    @param dest The container where the result
3142  
    is written, upon success.
3142  
    is written, upon success.
3143  

3143  

3144  
    @par Specification
3144  
    @par Specification
3145  
    <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-5"
3145  
    <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-5"
3146  
        >5. Reference Resolution (rfc3986)</a>
3146  
        >5. Reference Resolution (rfc3986)</a>
3147  

3147  

3148  
    @see
3148  
    @see
3149  
        @ref url,
3149  
        @ref url,
3150  
        @ref url_view.
3150  
        @ref url_view.
3151  
*/
3151  
*/
3152  
inline
3152  
inline
3153  
system::result<void>
3153  
system::result<void>
3154  
resolve(
3154  
resolve(
3155  
    url_view_base const& base,
3155  
    url_view_base const& base,
3156  
    url_view_base const& ref,
3156  
    url_view_base const& ref,
3157  
    url_base& dest)
3157  
    url_base& dest)
3158  
{
3158  
{
3159  
    if (&dest != &base)
3159  
    if (&dest != &base)
3160  
        dest.copy(base);
3160  
        dest.copy(base);
3161  
    return dest.resolve(ref);
3161  
    return dest.resolve(ref);
3162  
}
3162  
}
3163  

3163  

3164  
} // urls
3164  
} // urls
3165  
} // boost
3165  
} // boost
3166  

3166  

3167  
// These are here because of circular references
3167  
// These are here because of circular references
3168  
#include <boost/url/impl/params_ref.hpp>
3168  
#include <boost/url/impl/params_ref.hpp>
3169  
#include <boost/url/impl/params_encoded_ref.hpp>
3169  
#include <boost/url/impl/params_encoded_ref.hpp>
3170  
#include <boost/url/impl/segments_ref.hpp>
3170  
#include <boost/url/impl/segments_ref.hpp>
3171  
#include <boost/url/impl/segments_encoded_ref.hpp>
3171  
#include <boost/url/impl/segments_encoded_ref.hpp>
3172  

3172  

3173  
#endif
3173  
#endif