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 url_base
62 -
    url_base
 
63  
    : public url_view_base
62  
    : public url_view_base
64  
{
63  
{
65  
    char* s_ = nullptr;
64  
    char* s_ = nullptr;
66  
    std::size_t cap_ = 0;
65  
    std::size_t cap_ = 0;
67  

66  

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

74  

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

83  

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

89  

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

100  

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

107  

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

109  

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

113  

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

115  

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

120  

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

123  

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

132  

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

134  

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

137  

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

139  

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

142  

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

151  

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

153  

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

158  

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

161  

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

170  

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

172  

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

177  

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

181  

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

183  

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

192  

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

197  

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

203  

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

205  

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

212  

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

217  

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

220  

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

225  

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

228  

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

230  

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

232  

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

237  

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

241  

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

247  

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

249  

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

256  

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

261  

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

264  

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

269  

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

272  

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

275  

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

282  

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

284  

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

287  

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

292  

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

297  

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

300  

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

303  

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

305  

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

310  

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

314  

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

320  

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

326  

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

328  

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

332  

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

337  

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

342  

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

345  

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

348  

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

352  

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

357  

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

367  

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

369  

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

373  

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

378  

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

383  

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

386  

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

389  

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

391  

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

395  

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

400  

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

404  

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

410  

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

416  

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

418  

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

426  

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

433  

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

437  

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

443  

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

448  

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

451  

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

455  

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

458  

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

462  

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

466  

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

470  

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

478  

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

480  

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

489  

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

496  

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

500  

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

506  

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

511  

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

514  

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

519  

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

522  

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

525  

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

529  

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

533  

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

537  

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

545  

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

547  

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

550  

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

555  

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

560  

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

563  

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

566  

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

568  

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

572  

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

576  

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

580  

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

587  

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

589  

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

591  

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

596  

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

601  

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

606  

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

609  

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

613  

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

616  

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

620  

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

624  

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

628  

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

638  

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

640  

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

647  

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

652  

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

657  

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

660  

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

664  

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

667  

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

669  

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

671  

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

673  

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

677  

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

681  

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

685  

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

695  

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

697  

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

702  

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

708  

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

713  

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

718  

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

722  

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

725  

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

727  

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

731  

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

735  

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

739  

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

749  

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

751  

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

758  

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

764  

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

769  

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

774  

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

778  

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

781  

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

785  

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

789  

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

793  

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

797  

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

807  

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

809  

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

814  

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

820  

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

825  

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

830  

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

833  

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

836  

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

840  

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

844  

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

846  

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

850  

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

859  

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

865  

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

867  

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

870  

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

874  

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

879  

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

884  

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

890  

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

893  

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

898  

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

903  

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

906  

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

910  

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

914  

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

916  

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

919  

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

922  

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

930  

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

944  

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

946  

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

949  

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

953  

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

958  

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

963  

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

971  

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

974  

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

979  

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

984  

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

987  

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

992  

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

995  

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

997  

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

999  

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

1003  

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

1005  

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

1008  

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

1016  

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

1029  

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

1031  

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

1034  

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

1038  

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

1042  

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

1046  

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

1052  

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

1055  

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

1060  

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

1065  

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

1068  

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

1072  

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

1076  

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

1082  

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

1092  

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

1095  

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

1098  

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

1100  

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

1103  

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

1106  

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

1114  

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

1128  

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

1130  

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

1133  

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

1137  

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

1141  

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

1145  

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

1153  

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

1156  

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

1161  

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

1166  

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

1169  

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

1174  

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

1177  

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

1181  

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

1187  

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

1197  

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

1200  

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

1203  

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

1205  

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

1208  

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

1211  

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

1219  

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

1233  

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

1235  

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

1239  

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

1244  

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

1247  

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

1252  

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

1256  

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

1259  

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

1263  

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

1270  

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

1276  

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

1290  

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

1292  

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

1296  

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

1301  

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

1306  

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

1309  

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

1313  

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

1315  

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

1317  

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

1329  

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

1332  

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

1336  

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

1342  

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

1356  

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

1358  

1360  
        This function sets the zone ID for the host if the host is an IPv6 address.
1359  
        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.
1360  
        Reserved characters in the string are percent-escaped in the result.
1362  

1361  

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

1366  

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

1369  

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

1372  

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

1375  

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

1378  

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

1382  

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

1384  

1386  
        This function sets the zone ID for the host if the host is an IPv6 address.
1385  
        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
1386  
        Escapes in the string are preserved, and reserved characters in the string
1388  
        are percent-escaped in the result.
1387  
        are percent-escaped in the result.
1389  

1388  

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

1393  

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

1396  

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

1400  

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

1403  

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

1406  

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

1409  

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

1413  

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

1415  

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

1419  

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

1424  

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

1427  

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

1432  

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

1437  

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

1440  

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

1442  

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

1444  

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

1449  

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

1453  

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

1467  

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

1469  

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

1475  

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

1480  

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

1485  

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

1489  

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

1492  

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

1497  

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

1501  

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

1515  

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

1517  

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

1525  

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

1530  

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

1535  

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

1540  

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

1543  

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

1546  

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

1551  

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

1555  

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

1569  

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

1571  

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

1573  

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

1575  

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

1580  

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

1585  

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

1588  

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

1592  

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

1594  

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

1596  

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

1600  

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

1603  

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

1607  

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

1614  

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

1616  

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

1621  

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

1626  

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

1631  

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

1636  

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

1639  

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

1642  

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

1647  

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

1651  

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

1658  

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

1660  

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

1663  

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

1665  

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

1670  

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

1675  

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

1678  

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

1681  

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

1685  

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

1688  

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

1692  

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

1698  

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

1704  

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

1706  

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

1710  

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

1715  

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

1722  

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

1727  

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

1729  

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

1731  

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

1734  

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

1742  

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

1749  

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

1753  

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

1762  

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

1764  

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

1769  

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

1774  

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

1782  

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

1786  

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

1788  

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

1791  

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

1794  

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

1798  

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

1801  

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

1809  

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

1816  

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

1820  

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

1830  

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

1832  

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

1839  

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

1844  

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

1848  

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

1850  

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

1853  

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

1856  

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

1861  

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

1864  

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

1866  

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

1868  

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

1876  

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

1883  

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

1887  

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

1897  

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

1899  

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

1910  

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

1912  

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

1916  

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

1919  

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

1922  

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

1925  

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

1933  

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

1940  

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

1944  

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

1953  

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

1960  

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

1962  

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

1973  

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

1975  

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

1979  

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

1982  

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

1985  

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

1988  

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

1996  

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

2003  

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

2007  

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

2016  

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

2023  

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

2029  

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

2031  

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

2038  

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

2043  

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

2048  

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

2052  

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

2055  

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

2059  

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

2063  

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

2069  

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

2079  

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

2081  

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

2090  

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

2095  

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

2100  

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

2105  

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

2108  

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

2111  

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

2115  

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

2119  

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

2125  

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

2135  

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

2137  

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

2148  

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

2150  

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

2155  

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

2158  

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

2161  

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

2165  

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

2169  

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

2175  

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

2184  

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

2191  

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

2193  

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

2204  

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

2211  

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

2214  

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

2217  

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

2221  

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

2223  

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

2227  

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

2231  

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

2237  

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

2246  

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

2253  

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

2255  

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

2266  

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

2268  

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

2273  

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

2276  

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

2279  

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

2283  

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

2287  

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

2293  

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

2302  

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

2304  

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

2307  

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

2310  

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

2313  

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

2318  

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

2323  

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

2327  

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

2330  

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

2334  

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

2338  

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

2342  

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

2348  

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

2359  

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

2361  

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

2365  

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

2368  

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

2372  

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

2377  

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

2382  

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

2385  

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

2390  

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

2392  

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

2394  

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

2397  

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

2401  

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

2405  

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

2411  

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

2421  

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

2423  

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

2427  

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

2429  

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

2434  

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

2439  

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

2442  

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

2446  

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

2450  

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

2456  

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

2465  

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

2471  

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

2473  

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

2477  

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

2479  

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

2484  

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

2489  

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

2492  

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

2495  

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

2500  

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

2504  

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

2512  

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

2514  

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

2521  

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

2526  

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

2531  

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

2534  

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

2538  

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

2540  

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

2542  

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

2547  

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

2551  

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

2559  

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

2561  

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

2570  

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

2572  

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

2577  

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

2582  

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

2585  

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

2590  

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

2593  

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

2595  

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

2597  

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

2602  

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

2606  

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

2614  

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

2620  

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

2622  

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

2625  

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

2627  

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

2632  

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

2637  

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

2640  

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

2646  

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

2652  

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

2654  

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

2657  

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

2659  

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

2663  

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

2669  

2671  
        @code
2670  
        @code
2672  
        assert( url( "http://www.Example.com" ).normalize().buffer() == "http://www.example.com" );
2671  
        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" );
2672  
        assert( url( "http://www.%65xample.com" ).normalize().buffer() == "http://www.example.com" );
2674  
        @endcode
2673  
        @endcode
2675  

2674  

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

2681  

2683  
        @code
2682  
        @code
2684  
        assert( url( "http://www.example.com/a/b/../c" ).normalize().buffer() == "http://www.example.com/a/c" );
2683  
        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" );
2684  
        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" );
2685  
        assert( url( "http://www.example.com/%63ss" ).normalize().buffer() == "http://www.example.com/css" );
2687  
        @endcode
2686  
        @endcode
2688  

2687  

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

2692  

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

2696  

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

2701  

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

2705  

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

2708  

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

2712  

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

2714  

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

2718  

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

2722  

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

2729  

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

2733  

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

2735  

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

2738  

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

2740  

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

2744  

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

2746  

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

2750  

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

2754  

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

2758  

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

2760  

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

2763  

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

2769  

2771  
        @code
2770  
        @code
2772  
        assert( url( "http://www.Example.com" ).normalize_authority().buffer() == "http://www.example.com" );
2771  
        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" );
2772  
        assert( url( "http://www.%65xample.com" ).normalize_authority().buffer() == "http://www.example.com" );
2774  
        @endcode
2773  
        @endcode
2775  

2774  

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

2776  

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

2780  

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

2784  

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

2788  

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

2790  

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

2793  

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

2799  

2801  
        @code
2800  
        @code
2802  
        assert( url( "http://www.example.com/a/b/../c" ).normalize_path().buffer() == "http://www.example.com/a/c" );
2801  
        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" );
2802  
        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" );
2803  
        assert( url( "http://www.example.com/%63ss" ).normalize_path().buffer() == "http://www.example.com/css" );
2805  
        @endcode
2804  
        @endcode
2806  

2805  

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

2807  

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

2811  

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

2815  

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

2819  

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

2821  

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

2824  

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

2829  

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

2833  

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

2835  

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

2839  

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

2843  

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

2847  

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

2849  

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

2852  

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

2857  

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

2861  

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

2863  

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

2867  

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

2871  

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

2875  

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

2880  

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

2886  

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

2888  

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

2893  

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

2897  

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

2904  

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

2908  

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

2912  

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

2917  

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

2920  

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

2924  

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

2931  

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

2937  

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

2941  

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

2945  

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

2950  

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

2955  

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

2959  

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

2962  

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

2964  

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

2968  

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

2976  

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

2983  

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

2990  

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

2992  

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

2997  

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

3005  

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

3010  

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

3015  

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

3018  

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

3025  

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

3032  

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

3046  

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

3053  

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

3057  

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

3059  

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

3061  

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

3066  

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

3070  

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

3077  

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

3081  

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

3085  

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

3090  

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

3095  

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

3098  

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

3105  

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

3110  

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

3113  

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

3116  

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

3119  

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

3123  

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

3128  

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

3132  

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

3135  

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

3137  

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

3139  

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

3142  

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

3146  

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

3162  

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

3165  

3167  
// These are here because of circular references
3166  
// These are here because of circular references
 
3167 +
#include <boost/url/impl/url_base.hpp>
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