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

66  

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

74  

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

83  

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

89  

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

100  

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

107  

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

109  

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

113  

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

115  

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

120  

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

123  

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

132  

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

134  

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

137  

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

139  

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

142  

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

151  

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

153  

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

158  

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

161  

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

170  

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

172  

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

177  

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

181  

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

183  

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

192  

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

197  

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

203  

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

205  

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

212  

213  
        @par Example
213  
        @par Example
214  
        @code
214  
        @code
215  
        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 );
216  
        @endcode
216  
        @endcode
217  

217  

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

220  

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

225  

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

228  

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

230  

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

232  

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

237  

238  
        @par Specification
238  
        @par Specification
239  
        @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">
240  
            3.1. Scheme (rfc3986)</a>
240  
            3.1. Scheme (rfc3986)</a>
241  

241  

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

247  

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

249  

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

256  

257  
        @par Example
257  
        @par Example
258  
        @code
258  
        @code
259  
        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" );
260  
        @endcode
260  
        @endcode
261  

261  

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

264  

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

269  

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

272  

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

275  

276  
        @par Specification
276  
        @par Specification
277  
        @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">
278  
            3.1. Scheme (rfc3986)</a>
278  
            3.1. Scheme (rfc3986)</a>
279  
    */
279  
    */
280  
    url_base&
280  
    url_base&
281  
    set_scheme_id(urls::scheme id);
281  
    set_scheme_id(urls::scheme id);
282  

282  

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

284  

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

287  

288  
        @par Example
288  
        @par Example
289  
        @code
289  
        @code
290  
        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" );
291  
        @endcode
291  
        @endcode
292  

292  

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

297  

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

300  

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

303  

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

305  

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

310  

311  
        @par Specification
311  
        @par Specification
312  
        @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">
313  
            3.1. Scheme (rfc3986)</a>
313  
            3.1. Scheme (rfc3986)</a>
314  

314  

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

320  

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

326  

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

328  

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

332  

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

337  

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

342  

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

345  

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

348  

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

352  

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

357  

358  
        @par Specification
358  
        @par Specification
359  
        @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">
360  
            3.2. Authority (rfc3986)</a>
360  
            3.2. Authority (rfc3986)</a>
361  
        @see
361  
        @see
362  
            @ref remove_authority.
362  
            @ref remove_authority.
363  
    */
363  
    */
364  
    url_base&
364  
    url_base&
365  
    set_encoded_authority(
365  
    set_encoded_authority(
366  
        pct_string_view s);
366  
        pct_string_view s);
367  

367  

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

369  

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

373  

374  
        @par Example
374  
        @par Example
375  
        @code
375  
        @code
376  
        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" );
377  
        @endcode
377  
        @endcode
378  

378  

379  
        @par Postconditions
379  
        @par Postconditions
380  
        @code
380  
        @code
381  
        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
382  
        @endcode
382  
        @endcode
383  

383  

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

386  

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

389  

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

391  

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

395  

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

400  

401  
        @par Specification
401  
        @par Specification
402  
        @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">
403  
            3.2. Authority (rfc3986)</a>
403  
            3.2. Authority (rfc3986)</a>
404  

404  

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

410  

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

416  

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

418  

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

426  

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

433  

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

437  

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

443  

444  
        @par Example
444  
        @par Example
445  
        @code
445  
        @code
446  
        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" );
447  
        @endcode
447  
        @endcode
448  

448  

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

451  

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

455  

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

458  

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

462  

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

466  

467  
        @par Specification
467  
        @par Specification
468  
        @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">
469  
            3.2.1. User Information (rfc3986)</a>
469  
            3.2.1. User Information (rfc3986)</a>
470  

470  

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

478  

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

480  

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

489  

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

496  

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

500  

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

506  

507  
        @par Example
507  
        @par Example
508  
        @code
508  
        @code
509  
        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" );
510  
        @endcode
510  
        @endcode
511  

511  

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

514  

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

519  

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

522  

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

525  

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

529  

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

533  

534  
        @par Specification
534  
        @par Specification
535  
        @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">
536  
            3.2.1. User Information (rfc3986)</a>
536  
            3.2.1. User Information (rfc3986)</a>
537  

537  

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

545  

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

547  

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

550  

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

555  

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

560  

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

563  

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

566  

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

568  

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

572  

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

576  

577  
        @par Specification
577  
        @par Specification
578  
        @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">
579  
            3.2.1. User Information (rfc3986)</a>
579  
            3.2.1. User Information (rfc3986)</a>
580  

580  

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

587  

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

589  

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

591  

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

596  

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

601  

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

606  

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

609  

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

613  

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

616  

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

620  

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

624  

625  
        @par Specification
625  
        @par Specification
626  
        @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">
627  
            3.2.1. User Information (rfc3986)</a>
627  
            3.2.1. User Information (rfc3986)</a>
628  

628  

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

638  

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

640  

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

647  

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

652  

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

657  

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

660  

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

664  

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

667  

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

669  

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

671  

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

673  

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

677  

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

681  

682  
        @par Specification
682  
        @par Specification
683  
        @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">
684  
            3.2.1. User Information (rfc3986)</a>
684  
            3.2.1. User Information (rfc3986)</a>
685  

685  

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

695  

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

697  

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

702  

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

708  

709  
        @par Example
709  
        @par Example
710  
        @code
710  
        @code
711  
        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" );
712  
        @endcode
712  
        @endcode
713  

713  

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

718  

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

722  

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

725  

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

727  

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

731  

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

735  

736  
        @par Specification
736  
        @par Specification
737  
        @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">
738  
            3.2.1. User Information (rfc3986)</a>
738  
            3.2.1. User Information (rfc3986)</a>
739  

739  

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

749  

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

751  

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

758  

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

764  

765  
        @par Example
765  
        @par Example
766  
        @code
766  
        @code
767  
        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" );
768  
        @endcode
768  
        @endcode
769  

769  

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

774  

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

778  

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

781  

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

785  

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

789  

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

793  

794  
        @par Specification
794  
        @par Specification
795  
        @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">
796  
            3.2.1. User Information (rfc3986)</a>
796  
            3.2.1. User Information (rfc3986)</a>
797  

797  

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

807  

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

809  

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

814  

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

820  

821  
        @par Example
821  
        @par Example
822  
        @code
822  
        @code
823  
        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" );
824  
        @endcode
824  
        @endcode
825  

825  

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

830  

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

833  

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

836  

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

840  

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

844  

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

846  

847  
        @par Specification
847  
        @par Specification
848  
        @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">
849  
            3.2.1. User Information (rfc3986)</a>
849  
            3.2.1. User Information (rfc3986)</a>
850  

850  

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

859  

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

865  

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

867  

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

870  

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

874  

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

879  

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

884  

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

890  

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

893  

894  
        @par Example
894  
        @par Example
895  
        @code
895  
        @code
896  
        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" );
897  
        @endcode
897  
        @endcode
898  

898  

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

903  

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

906  

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

910  

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

914  

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

916  

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

919  

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

922  

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

930  

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

944  

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

946  

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

949  

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

953  

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

958  

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

963  

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

971  

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

974  

975  
        @par Example
975  
        @par Example
976  
        @code
976  
        @code
977  
        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" );
978  
        @endcode
978  
        @endcode
979  

979  

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

984  

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

987  

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

992  

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

995  

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

997  

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

999  

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

1003  

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

1005  

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

1008  

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

1016  

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

1029  

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

1031  

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

1034  

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

1038  

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

1042  

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

1046  

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

1052  

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

1055  

1056  
        @par Example
1056  
        @par Example
1057  
        @code
1057  
        @code
1058  
        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" );
1059  
        @endcode
1059  
        @endcode
1060  

1060  

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

1065  

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

1068  

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

1072  

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

1076  

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

1082  

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

1092  

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

1095  

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

1098  

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

1100  

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

1103  

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

1106  

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

1114  

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

1128  

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

1130  

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

1133  

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

1137  

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

1141  

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

1145  

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

1153  

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

1156  

1157  
        @par Example
1157  
        @par Example
1158  
        @code
1158  
        @code
1159  
        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" );
1160  
        @endcode
1160  
        @endcode
1161  

1161  

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

1166  

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

1169  

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

1174  

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

1177  

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

1181  

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

1187  

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

1197  

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

1200  

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

1203  

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

1205  

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

1208  

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

1211  

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

1219  

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

1233  

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

1235  

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

1239  

1240  
        @par Example
1240  
        @par Example
1241  
        @code
1241  
        @code
1242  
        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" );
1243  
        @endcode
1243  
        @endcode
1244  

1244  

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

1247  

1248  
        @par Postconditions
1248  
        @par Postconditions
1249  
        @code
1249  
        @code
1250  
        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
1251  
        @endcode
1251  
        @endcode
1252  

1252  

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

1256  

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

1259  

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

1263  

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

1270  

1271  
        @par Specification
1271  
        @par Specification
1272  
        @li <a href="https://en.wikipedia.org/wiki/IPv4"
1272  
        @li <a href="https://en.wikipedia.org/wiki/IPv4"
1273  
            >IPv4 (Wikipedia)</a>
1273  
            >IPv4 (Wikipedia)</a>
1274  
        @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">
1275  
            3.2.2. Host (rfc3986)</a>
1275  
            3.2.2. Host (rfc3986)</a>
1276  

1276  

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

1290  

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

1292  

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

1296  

1297  
        @par Example
1297  
        @par Example
1298  
        @code
1298  
        @code
1299  
        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]" );
1300  
        @endcode
1300  
        @endcode
1301  

1301  

1302  
        @par Postconditions
1302  
        @par Postconditions
1303  
        @code
1303  
        @code
1304  
        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
1305  
        @endcode
1305  
        @endcode
1306  

1306  

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

1309  

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

1313  

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

1315  

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

1317  

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

1329  

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

1332  

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

1336  

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

1342  

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

1356  

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

1358  

1359  
        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.
1360  
        Reserved characters in the string are percent-escaped in the result.
1360  
        Reserved characters in the string are percent-escaped in the result.
1361  

1361  

1362  
        @par Example
1362  
        @par Example
1363  
        @code
1363  
        @code
1364  
        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]" );
1365  
        @endcode
1365  
        @endcode
1366  

1366  

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

1369  

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

1372  

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

1375  

1376  
        @par Specification
1376  
        @par Specification
1377  
        @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>
1378  

1378  

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

1382  

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

1384  

1385  
        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.
1386  
        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
1387  
        are percent-escaped in the result.
1387  
        are percent-escaped in the result.
1388  

1388  

1389  
        @par Example
1389  
        @par Example
1390  
        @code
1390  
        @code
1391  
        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]" );
1392  
        @endcode
1392  
        @endcode
1393  

1393  

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

1396  

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

1400  

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

1403  

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

1406  

1407  
        @par Specification
1407  
        @par Specification
1408  
        @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>
1409  

1409  

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

1413  

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

1415  

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

1419  

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

1424  

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

1427  

1428  
        @par Postconditions
1428  
        @par Postconditions
1429  
        @code
1429  
        @code
1430  
        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
1431  
        @endcode
1431  
        @endcode
1432  

1432  

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

1437  

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

1440  

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

1442  

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

1444  

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

1449  

1450  
        @par Specification
1450  
        @par Specification
1451  
        @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">
1452  
            3.2.2. Host (rfc3986)</a>
1452  
            3.2.2. Host (rfc3986)</a>
1453  

1453  

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

1467  

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

1469  

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

1475  

1476  
        @par Example
1476  
        @par Example
1477  
        @code
1477  
        @code
1478  
        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" );
1479  
        @endcode
1479  
        @endcode
1480  

1480  

1481  
        @par Postconditions
1481  
        @par Postconditions
1482  
        @code
1482  
        @code
1483  
        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
1484  
        @endcode
1484  
        @endcode
1485  

1485  

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

1489  

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

1492  

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

1497  

1498  
        @par Specification
1498  
        @par Specification
1499  
        @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">
1500  
            3.2.2. Host (rfc3986)</a>
1500  
            3.2.2. Host (rfc3986)</a>
1501  

1501  

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

1515  

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

1517  

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

1525  

1526  
        @par Example
1526  
        @par Example
1527  
        @code
1527  
        @code
1528  
        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" );
1529  
        @endcode
1529  
        @endcode
1530  

1530  

1531  
        @par Postconditions
1531  
        @par Postconditions
1532  
        @code
1532  
        @code
1533  
        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
1534  
        @endcode
1534  
        @endcode
1535  

1535  

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

1540  

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

1543  

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

1546  

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

1551  

1552  
        @par Specification
1552  
        @par Specification
1553  
        @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">
1554  
            3.2.2. Host (rfc3986)</a>
1554  
            3.2.2. Host (rfc3986)</a>
1555  

1555  

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

1569  

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

1571  

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

1573  

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

1575  

1576  
        @par Example
1576  
        @par Example
1577  
        @code
1577  
        @code
1578  
        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" );
1579  
        @endcode
1579  
        @endcode
1580  

1580  

1581  
        @par Postconditions
1581  
        @par Postconditions
1582  
        @code
1582  
        @code
1583  
        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
1584  
        @endcode
1584  
        @endcode
1585  

1585  

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

1588  

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

1592  

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

1594  

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

1596  

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

1600  

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

1603  

1604  
        @par Specification
1604  
        @par Specification
1605  
        @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">
1606  
            3.2.3. Port (rfc3986)</a>
1606  
            3.2.3. Port (rfc3986)</a>
1607  

1607  

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

1614  

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

1616  

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

1621  

1622  
        @par Example
1622  
        @par Example
1623  
        @code
1623  
        @code
1624  
        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" );
1625  
        @endcode
1625  
        @endcode
1626  

1626  

1627  
        @par Postconditions
1627  
        @par Postconditions
1628  
        @code
1628  
        @code
1629  
        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)
1630  
        @endcode
1630  
        @endcode
1631  

1631  

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

1636  

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

1639  

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

1642  

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

1647  

1648  
        @par Specification
1648  
        @par Specification
1649  
        @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">
1650  
            3.2.3. Port (rfc3986)</a>
1650  
            3.2.3. Port (rfc3986)</a>
1651  

1651  

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

1658  

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

1660  

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

1663  

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

1665  

1666  
        @par Example
1666  
        @par Example
1667  
        @code
1667  
        @code
1668  
        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" );
1669  
        @endcode
1669  
        @endcode
1670  

1670  

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

1675  

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

1678  

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

1681  

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

1685  

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

1688  

1689  
        @par Specification
1689  
        @par Specification
1690  
        @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">
1691  
            3.2.3. Port (rfc3986)</a>
1691  
            3.2.3. Port (rfc3986)</a>
1692  

1692  

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

1698  

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

1704  

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

1706  

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

1710  

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

1715  

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

1722  

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

1727  

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

1729  

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

1731  

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

1734  

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

1742  

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

1749  

1750  
        @par Specification
1750  
        @par Specification
1751  
        @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"
1752  
            >3.3.  Path (rfc3986)</a>
1752  
            >3.3.  Path (rfc3986)</a>
1753  

1753  

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

1762  

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

1764  

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

1769  

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

1774  

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

1782  

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

1786  

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

1788  

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

1791  

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

1794  

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

1798  

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

1801  

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

1809  

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

1816  

1817  
        @par Specification
1817  
        @par Specification
1818  
        @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"
1819  
            >3.3.  Path (rfc3986)</a>
1819  
            >3.3.  Path (rfc3986)</a>
1820  

1820  

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

1830  

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

1832  

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

1839  

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

1844  

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

1848  

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

1850  

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

1853  

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

1856  

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

1861  

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

1864  

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

1866  

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

1868  

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

1876  

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

1883  

1884  
        @par Specification
1884  
        @par Specification
1885  
        @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"
1886  
            >3.3.  Path (rfc3986)</a>
1886  
            >3.3.  Path (rfc3986)</a>
1887  

1887  

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

1897  

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

1899  

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

1910  

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

1912  

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

1916  

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

1919  

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

1922  

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

1925  

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

1933  

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

1940  

1941  
        @par Specification
1941  
        @par Specification
1942  
        @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"
1943  
            >3.3.  Path (rfc3986)</a>
1943  
            >3.3.  Path (rfc3986)</a>
1944  

1944  

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

1953  

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

1960  

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

1962  

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

1973  

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

1975  

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

1979  

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

1982  

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

1985  

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

1988  

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

1996  

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

2003  

2004  
        @par Specification
2004  
        @par Specification
2005  
        @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"
2006  
            >3.3.  Path (rfc3986)</a>
2006  
            >3.3.  Path (rfc3986)</a>
2007  

2007  

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

2016  

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

2023  

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

2029  

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

2031  

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

2038  

2039  
        @par Example
2039  
        @par Example
2040  
        @code
2040  
        @code
2041  
        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" );
2042  
        @endcode
2042  
        @endcode
2043  

2043  

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

2048  

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

2052  

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

2055  

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

2059  

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

2063  

2064  
        @par Specification
2064  
        @par Specification
2065  
        @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"
2066  
            >3.4.  Query (rfc3986)</a>
2066  
            >3.4.  Query (rfc3986)</a>
2067  
        @li <a href="https://en.wikipedia.org/wiki/Query_string"
2067  
        @li <a href="https://en.wikipedia.org/wiki/Query_string"
2068  
            >Query string (Wikipedia)</a>
2068  
            >Query string (Wikipedia)</a>
2069  

2069  

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

2079  

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

2081  

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

2090  

2091  
        @par Example
2091  
        @par Example
2092  
        @code
2092  
        @code
2093  
        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" );
2094  
        @endcode
2094  
        @endcode
2095  

2095  

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

2100  

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

2105  

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

2108  

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

2111  

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

2115  

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

2119  

2120  
        @par Specification
2120  
        @par Specification
2121  
        @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"
2122  
            >3.4.  Query (rfc3986)</a>
2122  
            >3.4.  Query (rfc3986)</a>
2123  
        @li <a href="https://en.wikipedia.org/wiki/Query_string"
2123  
        @li <a href="https://en.wikipedia.org/wiki/Query_string"
2124  
            >Query string (Wikipedia)</a>
2124  
            >Query string (Wikipedia)</a>
2125  

2125  

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

2135  

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

2137  

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

2148  

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

2150  

2151  
        @par Example
2151  
        @par Example
2152  
        @code
2152  
        @code
2153  
        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();
2154  
        @endcode
2154  
        @endcode
2155  

2155  

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

2158  

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

2161  

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

2165  

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

2169  

2170  
        @par Specification
2170  
        @par Specification
2171  
        @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"
2172  
            >3.4.  Query (rfc3986)</a>
2172  
            >3.4.  Query (rfc3986)</a>
2173  
        @li <a href="https://en.wikipedia.org/wiki/Query_string"
2173  
        @li <a href="https://en.wikipedia.org/wiki/Query_string"
2174  
            >Query string (Wikipedia)</a>
2174  
            >Query string (Wikipedia)</a>
2175  

2175  

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

2184  

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

2191  

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

2193  

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

2204  

2205  
        @par Example
2205  
        @par Example
2206  
        @code
2206  
        @code
2207  
        encoding_opts opt;
2207  
        encoding_opts opt;
2208  
        opt.space_as_plus = true;
2208  
        opt.space_as_plus = true;
2209  
        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);
2210  
        @endcode
2210  
        @endcode
2211  

2211  

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

2214  

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

2217  

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

2221  

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

2223  

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

2227  

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

2231  

2232  
        @par Specification
2232  
        @par Specification
2233  
        @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"
2234  
            >3.4.  Query (rfc3986)</a>
2234  
            >3.4.  Query (rfc3986)</a>
2235  
        @li <a href="https://en.wikipedia.org/wiki/Query_string"
2235  
        @li <a href="https://en.wikipedia.org/wiki/Query_string"
2236  
            >Query string (Wikipedia)</a>
2236  
            >Query string (Wikipedia)</a>
2237  

2237  

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

2246  

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

2253  

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

2255  

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

2266  

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

2268  

2269  
        @par Example
2269  
        @par Example
2270  
        @code
2270  
        @code
2271  
        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();
2272  
        @endcode
2272  
        @endcode
2273  

2273  

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

2276  

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

2279  

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

2283  

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

2287  

2288  
        @par Specification
2288  
        @par Specification
2289  
        @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"
2290  
            >3.4.  Query (rfc3986)</a>
2290  
            >3.4.  Query (rfc3986)</a>
2291  
        @li <a href="https://en.wikipedia.org/wiki/Query_string"
2291  
        @li <a href="https://en.wikipedia.org/wiki/Query_string"
2292  
            >Query string (Wikipedia)</a>
2292  
            >Query string (Wikipedia)</a>
2293  

2293  

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

2302  

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

2304  

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

2307  

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

2310  

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

2313  

2314  
        @par Example
2314  
        @par Example
2315  
        @code
2315  
        @code
2316  
        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" );
2317  
        @endcode
2317  
        @endcode
2318  

2318  

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

2323  

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

2327  

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

2330  

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

2334  

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

2338  

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

2342  

2343  
        @par Specification
2343  
        @par Specification
2344  
        @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
2345  
            >3.4.  Query (rfc3986)</a>
2345  
            >3.4.  Query (rfc3986)</a>
2346  
        @li <a href="https://en.wikipedia.org/wiki/Query_string"
2346  
        @li <a href="https://en.wikipedia.org/wiki/Query_string"
2347  
            >Query string (Wikipedia)</a>
2347  
            >Query string (Wikipedia)</a>
2348  

2348  

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

2359  

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

2361  

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

2365  

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

2368  

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

2372  

2373  
        @par Example
2373  
        @par Example
2374  
        @code
2374  
        @code
2375  
        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" );
2376  
        @endcode
2376  
        @endcode
2377  

2377  

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

2382  

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

2385  

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

2390  

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

2392  

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

2394  

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

2397  

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

2401  

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

2405  

2406  
        @par Specification
2406  
        @par Specification
2407  
        @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"
2408  
            >3.4. Query (rfc3986)</a>
2408  
            >3.4. Query (rfc3986)</a>
2409  
        @li <a href="https://en.wikipedia.org/wiki/Query_string"
2409  
        @li <a href="https://en.wikipedia.org/wiki/Query_string"
2410  
            >Query string (Wikipedia)</a>
2410  
            >Query string (Wikipedia)</a>
2411  

2411  

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

2421  

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

2423  

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

2427  

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

2429  

2430  
        @par Example
2430  
        @par Example
2431  
        @code
2431  
        @code
2432  
        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" );
2433  
        @endcode
2433  
        @endcode
2434  

2434  

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

2439  

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

2442  

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

2446  

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

2450  

2451  
        @par Specification
2451  
        @par Specification
2452  
        @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"
2453  
            >3.4.  Query (rfc3986)</a>
2453  
            >3.4.  Query (rfc3986)</a>
2454  
        @li <a href="https://en.wikipedia.org/wiki/Query_string"
2454  
        @li <a href="https://en.wikipedia.org/wiki/Query_string"
2455  
            >Query string (Wikipedia)</a>
2455  
            >Query string (Wikipedia)</a>
2456  

2456  

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

2465  

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

2471  

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

2473  

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

2477  

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

2479  

2480  
        @par Example
2480  
        @par Example
2481  
        @code
2481  
        @code
2482  
        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" );
2483  
        @endcode
2483  
        @endcode
2484  

2484  

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

2489  

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

2492  

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

2495  

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

2500  

2501  
        @par Specification
2501  
        @par Specification
2502  
        @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"
2503  
            >3.5.  Fragment</a>
2503  
            >3.5.  Fragment</a>
2504  

2504  

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

2512  

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

2514  

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

2521  

2522  
        @par Example
2522  
        @par Example
2523  
        @code
2523  
        @code
2524  
        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" );
2525  
        @endcode
2525  
        @endcode
2526  

2526  

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

2531  

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

2534  

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

2538  

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

2540  

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

2542  

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

2547  

2548  
        @par Specification
2548  
        @par Specification
2549  
        @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"
2550  
            >3.5.  Fragment</a>
2550  
            >3.5.  Fragment</a>
2551  

2551  

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

2559  

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

2561  

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

2570  

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

2572  

2573  
        @par Example
2573  
        @par Example
2574  
        @code
2574  
        @code
2575  
        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" );
2576  
        @endcode
2576  
        @endcode
2577  

2577  

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

2582  

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

2585  

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

2590  

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

2593  

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

2595  

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

2597  

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

2602  

2603  
        @par Specification
2603  
        @par Specification
2604  
        @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"
2605  
            >3.5.  Fragment</a>
2605  
            >3.5.  Fragment</a>
2606  

2606  

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

2614  

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

2620  

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

2622  

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

2625  

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

2627  

2628  
        @par Example
2628  
        @par Example
2629  
        @code
2629  
        @code
2630  
        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" );
2631  
        @endcode
2631  
        @endcode
2632  

2632  

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

2637  

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

2640  

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

2646  

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

2652  

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

2654  

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

2657  

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

2659  

2660  
        @code
2660  
        @code
2661  
        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" );
2662  
        @endcode
2662  
        @endcode
2663  

2663  

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

2669  

2670  
        @code
2670  
        @code
2671  
        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" );
2672  
        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" );
2673  
        @endcode
2673  
        @endcode
2674  

2674  

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

2681  

2682  
        @code
2682  
        @code
2683  
        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" );
2684  
        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" );
2685  
        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" );
2686  
        @endcode
2686  
        @endcode
2687  

2687  

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

2692  

2693  
        @code
2693  
        @code
2694  
        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" );
2695  
        @endcode
2695  
        @endcode
2696  

2696  

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

2701  

2702  
        @code
2702  
        @code
2703  
        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" );
2704  
        @endcode
2704  
        @endcode
2705  

2705  

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

2708  

2709  
        @code
2709  
        @code
2710  
        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" );
2711  
        @endcode
2711  
        @endcode
2712  

2712  

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

2714  

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

2718  

2719  
        @par Specification
2719  
        @par Specification
2720  
        @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"
2721  
            >6.2.2 Syntax-Based Normalization (rfc3986)</a>
2721  
            >6.2.2 Syntax-Based Normalization (rfc3986)</a>
2722  

2722  

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

2729  

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

2733  

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

2735  

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

2738  

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

2740  

2741  
        @code
2741  
        @code
2742  
        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" );
2743  
        @endcode
2743  
        @endcode
2744  

2744  

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

2746  

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

2750  

2751  
        @par Specification
2751  
        @par Specification
2752  
        @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"
2753  
            >6.2.2 Syntax-Based Normalization (rfc3986)</a>
2753  
            >6.2.2 Syntax-Based Normalization (rfc3986)</a>
2754  

2754  

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

2758  

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

2760  

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

2763  

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

2769  

2770  
        @code
2770  
        @code
2771  
        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" );
2772  
        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" );
2773  
        @endcode
2773  
        @endcode
2774  

2774  

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

2776  

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

2780  

2781  
        @par Specification
2781  
        @par Specification
2782  
        @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"
2783  
            >6.2.2 Syntax-Based Normalization (rfc3986)</a>
2783  
            >6.2.2 Syntax-Based Normalization (rfc3986)</a>
2784  

2784  

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

2788  

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

2790  

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

2793  

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

2799  

2800  
        @code
2800  
        @code
2801  
        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" );
2802  
        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" );
2803  
        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" );
2804  
        @endcode
2804  
        @endcode
2805  

2805  

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

2807  

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

2811  

2812  
        @par Specification
2812  
        @par Specification
2813  
        @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"
2814  
            >6.2.2 Syntax-Based Normalization (rfc3986)</a>
2814  
            >6.2.2 Syntax-Based Normalization (rfc3986)</a>
2815  

2815  

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

2819  

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

2821  

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

2824  

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

2829  

2830  
        @code
2830  
        @code
2831  
        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" );
2832  
        @endcode
2832  
        @endcode
2833  

2833  

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

2835  

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

2839  

2840  
        @par Specification
2840  
        @par Specification
2841  
        @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"
2842  
            >6.2.2 Syntax-Based Normalization (rfc3986)</a>
2842  
            >6.2.2 Syntax-Based Normalization (rfc3986)</a>
2843  

2843  

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

2847  

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

2849  

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

2852  

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

2857  

2858  
        @code
2858  
        @code
2859  
        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" );
2860  
        @endcode
2860  
        @endcode
2861  

2861  

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

2863  

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

2867  

2868  
        @par Specification
2868  
        @par Specification
2869  
        @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"
2870  
            >6.2.2 Syntax-Based Normalization (rfc3986)</a>
2870  
            >6.2.2 Syntax-Based Normalization (rfc3986)</a>
2871  

2871  

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

2875  

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

2880  

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

2886  

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

2888  

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

2893  

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

2897  

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

2904  

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

2908  

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

2912  

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

2917  

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

2920  

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

2924  

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

2931  

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

2937  

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

2941  

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

2945  

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

2950  

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

2955  

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

2959  

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

2962  

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

2964  

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

2968  

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

2976  

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

2983  

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

2990  

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

2992  

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

2997  

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

3005  

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

3010  

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

3015  

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

3018  

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

3025  

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

3032  

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

3046  

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

3053  

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

3057  

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

3059  

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

3061  

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

3066  

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

3070  

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

3077  

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

3081  

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

3085  

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

3090  

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

3095  

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

3098  

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

3105  

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

3110  

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

3113  

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

3116  

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

3119  

3120  
    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);
3121  
    assert( dest.str() == "http://a/b/c/g#s" );
3121  
    assert( dest.str() == "http://a/b/c/g#s" );
3122  
    @endcode
3122  
    @endcode
3123  

3123  

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

3128  

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

3132  

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

3135  

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

3137  

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

3139  

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

3142  

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

3146  

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

3162  

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

3165  

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