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_HPP
11  
#ifndef BOOST_URL_URL_HPP
12  
#define BOOST_URL_URL_HPP
12  
#define BOOST_URL_URL_HPP
13  

13  

14  
#include <boost/url/detail/config.hpp>
14  
#include <boost/url/detail/config.hpp>
15  
#include <boost/url/url_base.hpp>
15  
#include <boost/url/url_base.hpp>
16  
#include <boost/assert.hpp>
16  
#include <boost/assert.hpp>
17  
#include <utility>
17  
#include <utility>
18  

18  

19  
namespace boost {
19  
namespace boost {
20  
namespace urls {
20  
namespace urls {
21  

21  

22  
/** A modifiable container for a URL.
22  
/** A modifiable container for a URL.
23  

23  

24  
    This container owns a url, represented
24  
    This container owns a url, represented
25  
    by a null-terminated character buffer
25  
    by a null-terminated character buffer
26  
    which is managed by performing dymamic
26  
    which is managed by performing dymamic
27  
    memory allocations as needed.
27  
    memory allocations as needed.
28  
    The contents may be inspected and modified,
28  
    The contents may be inspected and modified,
29  
    and the implementation maintains a useful
29  
    and the implementation maintains a useful
30  
    invariant: changes to the url always
30  
    invariant: changes to the url always
31  
    leave it in a valid state.
31  
    leave it in a valid state.
32  

32  

33  
    @par Exception Safety
33  
    @par Exception Safety
34  

34  

35  
    @li Functions marked `noexcept` provide the
35  
    @li Functions marked `noexcept` provide the
36  
    no-throw guarantee, otherwise:
36  
    no-throw guarantee, otherwise:
37  

37  

38  
    @li Functions which throw offer the strong
38  
    @li Functions which throw offer the strong
39  
    exception safety guarantee.
39  
    exception safety guarantee.
40  

40  

41  
    @par BNF
41  
    @par BNF
42  
    @code
42  
    @code
43  
    URI-reference = URI / relative-ref
43  
    URI-reference = URI / relative-ref
44  

44  

45  
    URI           = scheme ":" hier-part [ "?" query ] [ "#" fragment ]
45  
    URI           = scheme ":" hier-part [ "?" query ] [ "#" fragment ]
46  

46  

47  
    relative-ref  = relative-part [ "?" query ] [ "#" fragment ]
47  
    relative-ref  = relative-part [ "?" query ] [ "#" fragment ]
48  

48  

49  
    absolute-URI  = scheme ":" hier-part [ "?" query ]
49  
    absolute-URI  = scheme ":" hier-part [ "?" query ]
50  
    @endcode
50  
    @endcode
51  

51  

52  
    @par Specification
52  
    @par Specification
53  
    @li <a href="https://tools.ietf.org/html/rfc3986"
53  
    @li <a href="https://tools.ietf.org/html/rfc3986"
54  
        >Uniform Resource Identifier (URI): Generic Syntax (rfc3986)</a>
54  
        >Uniform Resource Identifier (URI): Generic Syntax (rfc3986)</a>
55  

55  

56  
    @see
56  
    @see
57  
        @ref parse_absolute_uri,
57  
        @ref parse_absolute_uri,
58  
        @ref parse_relative_ref,
58  
        @ref parse_relative_ref,
59  
        @ref parse_uri,
59  
        @ref parse_uri,
60  
        @ref parse_uri_reference,
60  
        @ref parse_uri_reference,
61  
        @ref resolve.
61  
        @ref resolve.
62  
*/
62  
*/
63  
class BOOST_URL_DECL url
63  
class BOOST_URL_DECL url
64  
    : public url_base
64  
    : public url_base
65  
{
65  
{
66  
    friend std::hash<url>;
66  
    friend std::hash<url>;
67  

67  

68  
    using url_view_base::digest;
68  
    using url_view_base::digest;
69  

69  

70  
public:
70  
public:
71  
    //--------------------------------------------
71  
    //--------------------------------------------
72  
    //
72  
    //
73  
    // Special Members
73  
    // Special Members
74  
    //
74  
    //
75  
    //--------------------------------------------
75  
    //--------------------------------------------
76  

76  

77  
    /** Destructor
77  
    /** Destructor
78  

78  

79  
        Any params, segments, iterators, or
79  
        Any params, segments, iterators, or
80  
        views which reference this object are
80  
        views which reference this object are
81  
        invalidated. The underlying character
81  
        invalidated. The underlying character
82  
        buffer is destroyed, invalidating all
82  
        buffer is destroyed, invalidating all
83  
        references to it.
83  
        references to it.
84  
    */
84  
    */
85  
    virtual ~url();
85  
    virtual ~url();
86  

86  

87  
    /** Constructor
87  
    /** Constructor
88  

88  

89  
        Default constructed urls contain
89  
        Default constructed urls contain
90  
        a zero-length string. This matches
90  
        a zero-length string. This matches
91  
        the grammar for a relative-ref with
91  
        the grammar for a relative-ref with
92  
        an empty path and no query or
92  
        an empty path and no query or
93  
        fragment.
93  
        fragment.
94  

94  

95  
        @par Example
95  
        @par Example
96  
        @code
96  
        @code
97  
        url u;
97  
        url u;
98  
        @endcode
98  
        @endcode
99  

99  

100  
        @par Postconditions
100  
        @par Postconditions
101  
        @code
101  
        @code
102  
        this->empty() == true
102  
        this->empty() == true
103  
        @endcode
103  
        @endcode
104  

104  

105  
        @par Complexity
105  
        @par Complexity
106  
        Constant.
106  
        Constant.
107  

107  

108  
        @par Exception Safety
108  
        @par Exception Safety
109  
        Throws nothing.
109  
        Throws nothing.
110  

110  

111  
        @par BNF
111  
        @par BNF
112  
        @code
112  
        @code
113  
        relative-ref  = relative-part [ "?" query ] [ "#" fragment ]
113  
        relative-ref  = relative-part [ "?" query ] [ "#" fragment ]
114  
        @endcode
114  
        @endcode
115  

115  

116  
        @par Specification
116  
        @par Specification
117  
        <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-4.2"
117  
        <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-4.2"
118  
            >4.2. Relative Reference (rfc3986)</a>
118  
            >4.2. Relative Reference (rfc3986)</a>
119  
    */
119  
    */
120  
    url() noexcept;
120  
    url() noexcept;
121  

121  

122  
    /** Constructor
122  
    /** Constructor
123  

123  

124  
        This function constructs a URL from
124  
        This function constructs a URL from
125  
        the string `s`, which must contain a
125  
        the string `s`, which must contain a
126  
        valid <em>URI</em> or <em>relative-ref</em>
126  
        valid <em>URI</em> or <em>relative-ref</em>
127  
        or else an exception is thrown.
127  
        or else an exception is thrown.
128  
        The new url retains ownership by
128  
        The new url retains ownership by
129  
        allocating a copy of the passed string.
129  
        allocating a copy of the passed string.
130  

130  

131  
        @par Example
131  
        @par Example
132  
        @code
132  
        @code
133  
        url u( "https://www.example.com" );
133  
        url u( "https://www.example.com" );
134  
        @endcode
134  
        @endcode
135  

135  

136  
        @par Effects
136  
        @par Effects
137  
        @code
137  
        @code
138  
        return url( parse_uri_reference( s ).value() );
138  
        return url( parse_uri_reference( s ).value() );
139  
        @endcode
139  
        @endcode
140  

140  

141  
        @par Postconditions
141  
        @par Postconditions
142  
        @code
142  
        @code
143  
        this->buffer().data() != s.data()
143  
        this->buffer().data() != s.data()
144  
        @endcode
144  
        @endcode
145  

145  

146  
        @par Complexity
146  
        @par Complexity
147  
        Linear in `s.size()`.
147  
        Linear in `s.size()`.
148  

148  

149  
        @par Exception Safety
149  
        @par Exception Safety
150  
        Calls to allocate may throw.
150  
        Calls to allocate may throw.
151  
        Exceptions thrown on invalid input.
151  
        Exceptions thrown on invalid input.
152  

152  

153  
        @throw system_error
153  
        @throw system_error
154  
        The input does not contain a valid url.
154  
        The input does not contain a valid url.
155  

155  

156  
        @param s The string to parse.
156  
        @param s The string to parse.
157  

157  

158  
        @par BNF
158  
        @par BNF
159  
        @code
159  
        @code
160  
        URI           = scheme ":" hier-part [ "?" query ] [ "#" fragment ]
160  
        URI           = scheme ":" hier-part [ "?" query ] [ "#" fragment ]
161  

161  

162  
        relative-ref  = relative-part [ "?" query ] [ "#" fragment ]
162  
        relative-ref  = relative-part [ "?" query ] [ "#" fragment ]
163  
        @endcode
163  
        @endcode
164  

164  

165  
        @par Specification
165  
        @par Specification
166  
        @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-4.1"
166  
        @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-4.1"
167  
            >4.1. URI Reference</a>
167  
            >4.1. URI Reference</a>
168  
    */
168  
    */
169  
    explicit
169  
    explicit
170  
    url(core::string_view s);
170  
    url(core::string_view s);
171  

171  

172  
    /** Constructor
172  
    /** Constructor
173  

173  

174  
        The contents of `u` are transferred
174  
        The contents of `u` are transferred
175  
        to the newly constructed object,
175  
        to the newly constructed object,
176  
        which includes the underlying
176  
        which includes the underlying
177  
        character buffer.
177  
        character buffer.
178  
        After construction, the moved-from
178  
        After construction, the moved-from
179  
        object is as if default constructed.
179  
        object is as if default constructed.
180  

180  

181  
        @par Postconditions
181  
        @par Postconditions
182  
        @code
182  
        @code
183  
        u.empty() == true
183  
        u.empty() == true
184  
        @endcode
184  
        @endcode
185  

185  

186  
        @par Complexity
186  
        @par Complexity
187  
        Constant.
187  
        Constant.
188  

188  

189  
        @par Exception Safety
189  
        @par Exception Safety
190  
        Throws nothing.
190  
        Throws nothing.
191  

191  

192  
        @param u The url to move from.
192  
        @param u The url to move from.
193  
    */
193  
    */
194  
    url(url&& u) noexcept;
194  
    url(url&& u) noexcept;
195  

195  

196  
    /** Constructor
196  
    /** Constructor
197  

197  

198  
        The newly constructed object
198  
        The newly constructed object
199  
        contains a copy of `u`.
199  
        contains a copy of `u`.
200  

200  

201  
        @par Postconditions
201  
        @par Postconditions
202  
        @code
202  
        @code
203  
        this->buffer() == u.buffer() && this->buffer().data() != u.buffer().data()
203  
        this->buffer() == u.buffer() && this->buffer().data() != u.buffer().data()
204  
        @endcode
204  
        @endcode
205  

205  

206  
        @par Complexity
206  
        @par Complexity
207  
        Linear in `u.size()`.
207  
        Linear in `u.size()`.
208  

208  

209  
        @par Exception Safety
209  
        @par Exception Safety
210  
        Strong guarantee.
210  
        Strong guarantee.
211  
        Calls to allocate may throw.
211  
        Calls to allocate may throw.
212  

212  

213  
        @throw std::length_error `u.size() > max_size()`.
213  
        @throw std::length_error `u.size() > max_size()`.
214  

214  

215  
        @param u The url to copy.
215  
        @param u The url to copy.
216  
    */
216  
    */
217  
    url(url_view_base const& u)
217  
    url(url_view_base const& u)
218  
    {
218  
    {
219  
        copy(u);
219  
        copy(u);
220  
    }
220  
    }
221  

221  

222  
    /** Constructor
222  
    /** Constructor
223  

223  

224  
        The newly constructed object
224  
        The newly constructed object
225  
        contains a copy of `u`.
225  
        contains a copy of `u`.
226  

226  

227  
        @par Postconditions
227  
        @par Postconditions
228  
        @code
228  
        @code
229  
        this->buffer() == u.buffer() && this->buffer().data() != u.buffer().data()
229  
        this->buffer() == u.buffer() && this->buffer().data() != u.buffer().data()
230  
        @endcode
230  
        @endcode
231  

231  

232  
        @par Complexity
232  
        @par Complexity
233  
        Linear in `u.size()`.
233  
        Linear in `u.size()`.
234  

234  

235  
        @par Exception Safety
235  
        @par Exception Safety
236  
        Strong guarantee.
236  
        Strong guarantee.
237  
        Calls to allocate may throw.
237  
        Calls to allocate may throw.
238  

238  

239  
        @throw std::length_error `u.size() > max_size()`.
239  
        @throw std::length_error `u.size() > max_size()`.
240  

240  

241  
        @param u The url to copy.
241  
        @param u The url to copy.
242  
    */
242  
    */
243  
    url(url const& u)
243  
    url(url const& u)
244  
        : url(static_cast<
244  
        : url(static_cast<
245  
            url_view_base const&>(u))
245  
            url_view_base const&>(u))
246  
    {
246  
    {
247  
    }
247  
    }
248  

248  

249  
    /** Assignment
249  
    /** Assignment
250  

250  

251  
        The contents of `u` are transferred to
251  
        The contents of `u` are transferred to
252  
        `this`, including the underlying
252  
        `this`, including the underlying
253  
        character buffer. The previous contents
253  
        character buffer. The previous contents
254  
        of `this` are destroyed.
254  
        of `this` are destroyed.
255  
        After assignment, the moved-from
255  
        After assignment, the moved-from
256  
        object is as if default constructed.
256  
        object is as if default constructed.
257  

257  

258  
        @par Postconditions
258  
        @par Postconditions
259  
        @code
259  
        @code
260  
        u.empty() == true
260  
        u.empty() == true
261  
        @endcode
261  
        @endcode
262  

262  

263  
        @par Complexity
263  
        @par Complexity
264  
        Constant.
264  
        Constant.
265  

265  

266  
        @par Exception Safety
266  
        @par Exception Safety
267  
        Throws nothing.
267  
        Throws nothing.
268  

268  

269  
        @param u The url to assign from.
269  
        @param u The url to assign from.
270  
        @return A reference to this object.
270  
        @return A reference to this object.
271  
    */
271  
    */
272  
    url&
272  
    url&
273  
    operator=(url&& u) noexcept;
273  
    operator=(url&& u) noexcept;
274  

274  

275  
    /** Assignment
275  
    /** Assignment
276  

276  

277  
        The contents of `u` are copied and
277  
        The contents of `u` are copied and
278  
        the previous contents of `this` are
278  
        the previous contents of `this` are
279  
        destroyed.
279  
        destroyed.
280  
        Capacity is preserved, or increases.
280  
        Capacity is preserved, or increases.
281  

281  

282  
        @par Postconditions
282  
        @par Postconditions
283  
        @code
283  
        @code
284  
        this->buffer() == u.buffer() && this->buffer().data() != u.buffer().data()
284  
        this->buffer() == u.buffer() && this->buffer().data() != u.buffer().data()
285  
        @endcode
285  
        @endcode
286  

286  

287  
        @par Complexity
287  
        @par Complexity
288  
        Linear in `u.size()`.
288  
        Linear in `u.size()`.
289  

289  

290  
        @par Exception Safety
290  
        @par Exception Safety
291  
        Strong guarantee.
291  
        Strong guarantee.
292  
        Calls to allocate may throw.
292  
        Calls to allocate may throw.
293  

293  

294  
        @throw std::length_error `u.size() > max_size()`.
294  
        @throw std::length_error `u.size() > max_size()`.
295  

295  

296  
        @param u The url to copy.
296  
        @param u The url to copy.
297  
        @return A reference to this object.
297  
        @return A reference to this object.
298  
    */
298  
    */
299  
    url&
299  
    url&
300  
    operator=(
300  
    operator=(
301  
        url_view_base const& u)
301  
        url_view_base const& u)
302  
    {
302  
    {
303  
        copy(u);
303  
        copy(u);
304  
        return *this;
304  
        return *this;
305  
    }
305  
    }
306  

306  

307  
    /** Assignment
307  
    /** Assignment
308  

308  

309  
        The contents of `u` are copied and
309  
        The contents of `u` are copied and
310  
        the previous contents of `this` are
310  
        the previous contents of `this` are
311  
        destroyed.
311  
        destroyed.
312  
        Capacity is preserved, or increases.
312  
        Capacity is preserved, or increases.
313  

313  

314  
        @par Postconditions
314  
        @par Postconditions
315  
        @code
315  
        @code
316  
        this->buffer() == u.buffer() && this->buffer().data() != u.buffer().data()
316  
        this->buffer() == u.buffer() && this->buffer().data() != u.buffer().data()
317  
        @endcode
317  
        @endcode
318  

318  

319  
        @par Complexity
319  
        @par Complexity
320  
        Linear in `u.size()`.
320  
        Linear in `u.size()`.
321  

321  

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

325  

326  
        @param u The url to copy.
326  
        @param u The url to copy.
327  
        @return A reference to this object.
327  
        @return A reference to this object.
328  
    */
328  
    */
329  
    url&
329  
    url&
330  
    operator=(url const& u)
330  
    operator=(url const& u)
331  
    {
331  
    {
332  
        return (*this)=static_cast<
332  
        return (*this)=static_cast<
333  
            url_view_base const&>(u);
333  
            url_view_base const&>(u);
334  
    }
334  
    }
335  

335  

336  
    //--------------------------------------------
336  
    //--------------------------------------------
337  

337  

338  
    /** Swap the contents.
338  
    /** Swap the contents.
339  

339  

340  
        Exchanges the contents of this url with another
340  
        Exchanges the contents of this url with another
341  
        url. All views, iterators and references remain valid.
341  
        url. All views, iterators and references remain valid.
342  

342  

343  
        If `this == &other`, this function call has no effect.
343  
        If `this == &other`, this function call has no effect.
344  

344  

345  
        @par Example
345  
        @par Example
346  
        @code
346  
        @code
347  
        url u1( "https://www.example.com" );
347  
        url u1( "https://www.example.com" );
348  
        url u2( "https://www.boost.org" );
348  
        url u2( "https://www.boost.org" );
349  
        u1.swap(u2);
349  
        u1.swap(u2);
350  
        assert(u1 == "https://www.boost.org" );
350  
        assert(u1 == "https://www.boost.org" );
351  
        assert(u2 == "https://www.example.com" );
351  
        assert(u2 == "https://www.example.com" );
352  
        @endcode
352  
        @endcode
353  

353  

354  
        @par Complexity
354  
        @par Complexity
355  
        Constant
355  
        Constant
356  

356  

357  
        @par Exception Safety
357  
        @par Exception Safety
358  
        Throws nothing.
358  
        Throws nothing.
359  

359  

360  
        @param other The object to swap with
360  
        @param other The object to swap with
361  

361  

362  
    */
362  
    */
363  
    void
363  
    void
364  
    swap(url& other) noexcept;
364  
    swap(url& other) noexcept;
365  

365  

366  
    /** Swap
366  
    /** Swap
367  

367  

368  
        Exchanges the contents of `v0` with another `v1`.
368  
        Exchanges the contents of `v0` with another `v1`.
369  
        All views, iterators and references remain
369  
        All views, iterators and references remain
370  
        valid.
370  
        valid.
371  

371  

372  
        If `&v0 == &v1`, this function call has no effect.
372  
        If `&v0 == &v1`, this function call has no effect.
373  

373  

374  
        @par Example
374  
        @par Example
375  
        @code
375  
        @code
376  
        url u1( "https://www.example.com" );
376  
        url u1( "https://www.example.com" );
377  
        url u2( "https://www.boost.org" );
377  
        url u2( "https://www.boost.org" );
378  
        std::swap(u1, u2);
378  
        std::swap(u1, u2);
379  
        assert(u1 == "https://www.boost.org" );
379  
        assert(u1 == "https://www.boost.org" );
380  
        assert(u2 == "https://www.example.com" );
380  
        assert(u2 == "https://www.example.com" );
381  
        @endcode
381  
        @endcode
382  

382  

383  
        @par Effects
383  
        @par Effects
384  
        @code
384  
        @code
385  
        v0.swap( v1 );
385  
        v0.swap( v1 );
386  
        @endcode
386  
        @endcode
387  

387  

388  
        @par Complexity
388  
        @par Complexity
389  
        Constant
389  
        Constant
390  

390  

391  
        @par Exception Safety
391  
        @par Exception Safety
392  
        Throws nothing
392  
        Throws nothing
393  

393  

394  
        @param v0 The first object to swap
394  
        @param v0 The first object to swap
395  
        @param v1 The second object to swap
395  
        @param v1 The second object to swap
396  

396  

397  
        @see
397  
        @see
398  
            @ref url::swap
398  
            @ref url::swap
399  
    */
399  
    */
400  
    friend
400  
    friend
401  
    void
401  
    void
402  
    swap(url& v0, url& v1) noexcept
402  
    swap(url& v0, url& v1) noexcept
403  
    {
403  
    {
404  
        v0.swap(v1);
404  
        v0.swap(v1);
405  
    }
405  
    }
406  

406  

407  
    //--------------------------------------------
407  
    //--------------------------------------------
408  
    //
408  
    //
409  
    // fluent api
409  
    // fluent api
410  
    //
410  
    //
411  

411  

412  
    /// @copydoc url_base::set_scheme
412  
    /// @copydoc url_base::set_scheme
413  
    url& set_scheme(core::string_view s) { url_base::set_scheme(s); return *this; }
413  
    url& set_scheme(core::string_view s) { url_base::set_scheme(s); return *this; }
414  
    /// @copydoc url_base::set_scheme_id
414  
    /// @copydoc url_base::set_scheme_id
415  
    url& set_scheme_id(urls::scheme id) { url_base::set_scheme_id(id); return *this; }
415  
    url& set_scheme_id(urls::scheme id) { url_base::set_scheme_id(id); return *this; }
416  
    /// @copydoc url_base::remove_scheme
416  
    /// @copydoc url_base::remove_scheme
417  
    url& remove_scheme() { url_base::remove_scheme(); return *this; }
417  
    url& remove_scheme() { url_base::remove_scheme(); return *this; }
418  

418  

419  
    /// @copydoc url_base::set_encoded_authority
419  
    /// @copydoc url_base::set_encoded_authority
420  
    url& set_encoded_authority(pct_string_view s) { url_base::set_encoded_authority(s); return *this; }
420  
    url& set_encoded_authority(pct_string_view s) { url_base::set_encoded_authority(s); return *this; }
421  
    /// @copydoc url_base::remove_authority
421  
    /// @copydoc url_base::remove_authority
422  
    url& remove_authority() { url_base::remove_authority(); return *this; }
422  
    url& remove_authority() { url_base::remove_authority(); return *this; }
423  

423  

424  
    /// @copydoc url_base::set_userinfo
424  
    /// @copydoc url_base::set_userinfo
425  
    url& set_userinfo(core::string_view s) { url_base::set_userinfo(s); return *this; }
425  
    url& set_userinfo(core::string_view s) { url_base::set_userinfo(s); return *this; }
426  
    /// @copydoc url_base::set_encoded_userinfo
426  
    /// @copydoc url_base::set_encoded_userinfo
427  
    url& set_encoded_userinfo(pct_string_view s) { url_base::set_encoded_userinfo(s); return *this; }
427  
    url& set_encoded_userinfo(pct_string_view s) { url_base::set_encoded_userinfo(s); return *this; }
428  
    /// @copydoc url_base::remove_userinfo
428  
    /// @copydoc url_base::remove_userinfo
429  
    url& remove_userinfo() noexcept { url_base::remove_userinfo(); return *this; }
429  
    url& remove_userinfo() noexcept { url_base::remove_userinfo(); return *this; }
430  
    /// @copydoc url_base::set_user
430  
    /// @copydoc url_base::set_user
431  
    url& set_user(core::string_view s) { url_base::set_user(s); return *this; }
431  
    url& set_user(core::string_view s) { url_base::set_user(s); return *this; }
432  
    /// @copydoc url_base::set_encoded_user
432  
    /// @copydoc url_base::set_encoded_user
433  
    url& set_encoded_user(pct_string_view s) { url_base::set_encoded_user(s); return *this; }
433  
    url& set_encoded_user(pct_string_view s) { url_base::set_encoded_user(s); return *this; }
434  
    /// @copydoc url_base::set_password
434  
    /// @copydoc url_base::set_password
435  
    url& set_password(core::string_view s) { url_base::set_password(s); return *this; }
435  
    url& set_password(core::string_view s) { url_base::set_password(s); return *this; }
436  
    /// @copydoc url_base::set_encoded_password
436  
    /// @copydoc url_base::set_encoded_password
437  
    url& set_encoded_password(pct_string_view s) { url_base::set_encoded_password(s); return *this; }
437  
    url& set_encoded_password(pct_string_view s) { url_base::set_encoded_password(s); return *this; }
438  
    /// @copydoc url_base::remove_password
438  
    /// @copydoc url_base::remove_password
439  
    url& remove_password() noexcept { url_base::remove_password(); return *this; }
439  
    url& remove_password() noexcept { url_base::remove_password(); return *this; }
440  

440  

441  
    /// @copydoc url_base::set_host
441  
    /// @copydoc url_base::set_host
442  
    url& set_host(core::string_view s) { url_base::set_host(s); return *this; }
442  
    url& set_host(core::string_view s) { url_base::set_host(s); return *this; }
443  
    /// @copydoc url_base::set_encoded_host
443  
    /// @copydoc url_base::set_encoded_host
444  
    url& set_encoded_host(pct_string_view s) { url_base::set_encoded_host(s); return *this; }
444  
    url& set_encoded_host(pct_string_view s) { url_base::set_encoded_host(s); return *this; }
445  
    /// @copydoc url_base::set_host_address
445  
    /// @copydoc url_base::set_host_address
446  
    url& set_host_address(core::string_view s) { url_base::set_host_address(s); return *this; }
446  
    url& set_host_address(core::string_view s) { url_base::set_host_address(s); return *this; }
447  
    /// @copydoc url_base::set_encoded_host_address
447  
    /// @copydoc url_base::set_encoded_host_address
448  
    url& set_encoded_host_address(pct_string_view s) { url_base::set_encoded_host_address(s); return *this; }
448  
    url& set_encoded_host_address(pct_string_view s) { url_base::set_encoded_host_address(s); return *this; }
449  
    /// @copydoc url_base::set_host_ipv4
449  
    /// @copydoc url_base::set_host_ipv4
450  
    url& set_host_ipv4(ipv4_address const& addr) { url_base::set_host_ipv4(addr); return *this; }
450  
    url& set_host_ipv4(ipv4_address const& addr) { url_base::set_host_ipv4(addr); return *this; }
451  
    /// @copydoc url_base::set_host_ipv6
451  
    /// @copydoc url_base::set_host_ipv6
452  
    url& set_host_ipv6(ipv6_address const& addr) { url_base::set_host_ipv6(addr); return *this; }
452  
    url& set_host_ipv6(ipv6_address const& addr) { url_base::set_host_ipv6(addr); return *this; }
453  
    /// @copydoc url_base::set_zone_id
453  
    /// @copydoc url_base::set_zone_id
454  
    url& set_zone_id(core::string_view s) { url_base::set_zone_id(s); return *this; }
454  
    url& set_zone_id(core::string_view s) { url_base::set_zone_id(s); return *this; }
455  
    /// @copydoc url_base::set_encoded_zone_id
455  
    /// @copydoc url_base::set_encoded_zone_id
456  
    url& set_encoded_zone_id(pct_string_view const& s) { url_base::set_encoded_zone_id(s); return *this; }
456  
    url& set_encoded_zone_id(pct_string_view const& s) { url_base::set_encoded_zone_id(s); return *this; }
457  
    /// @copydoc url_base::set_host_ipvfuture
457  
    /// @copydoc url_base::set_host_ipvfuture
458  
    url& set_host_ipvfuture(core::string_view s) { url_base::set_host_ipvfuture(s); return *this; }
458  
    url& set_host_ipvfuture(core::string_view s) { url_base::set_host_ipvfuture(s); return *this; }
459  
    /// @copydoc url_base::set_host_name
459  
    /// @copydoc url_base::set_host_name
460  
    url& set_host_name(core::string_view s) { url_base::set_host_name(s); return *this; }
460  
    url& set_host_name(core::string_view s) { url_base::set_host_name(s); return *this; }
461  
    /// @copydoc url_base::set_encoded_host_name
461  
    /// @copydoc url_base::set_encoded_host_name
462  
    url& set_encoded_host_name(pct_string_view s) { url_base::set_encoded_host_name(s); return *this; }
462  
    url& set_encoded_host_name(pct_string_view s) { url_base::set_encoded_host_name(s); return *this; }
463  
    /// @copydoc url_base::set_port_number
463  
    /// @copydoc url_base::set_port_number
464  
    url& set_port_number(std::uint16_t n) { url_base::set_port_number(n); return *this; }
464  
    url& set_port_number(std::uint16_t n) { url_base::set_port_number(n); return *this; }
465  
    /// @copydoc url_base::set_port
465  
    /// @copydoc url_base::set_port
466  
    url& set_port(core::string_view s) { url_base::set_port(s); return *this; }
466  
    url& set_port(core::string_view s) { url_base::set_port(s); return *this; }
467  
    /// @copydoc url_base::remove_port
467  
    /// @copydoc url_base::remove_port
468  
    url& remove_port() noexcept { url_base::remove_port(); return *this; }
468  
    url& remove_port() noexcept { url_base::remove_port(); return *this; }
469  

469  

470  
    /// @copydoc url_base::set_path_absolute
470  
    /// @copydoc url_base::set_path_absolute
471  
    //bool set_path_absolute(bool absolute);
471  
    //bool set_path_absolute(bool absolute);
472  
    /// @copydoc url_base::set_path
472  
    /// @copydoc url_base::set_path
473  
    url& set_path(core::string_view s) { url_base::set_path(s); return *this; }
473  
    url& set_path(core::string_view s) { url_base::set_path(s); return *this; }
474  
    /// @copydoc url_base::set_encoded_path
474  
    /// @copydoc url_base::set_encoded_path
475  
    url& set_encoded_path(pct_string_view s) { url_base::set_encoded_path(s); return *this; }
475  
    url& set_encoded_path(pct_string_view s) { url_base::set_encoded_path(s); return *this; }
476  

476  

477  
    /// @copydoc url_base::set_query
477  
    /// @copydoc url_base::set_query
478  
    url& set_query(core::string_view s) { url_base::set_query(s); return *this; }
478  
    url& set_query(core::string_view s) { url_base::set_query(s); return *this; }
479  
    /// @copydoc url_base::set_encoded_query
479  
    /// @copydoc url_base::set_encoded_query
480  
    url& set_encoded_query(pct_string_view s) { url_base::set_encoded_query(s); return *this; }
480  
    url& set_encoded_query(pct_string_view s) { url_base::set_encoded_query(s); return *this; }
481  
    /// @copydoc url_base::set_params
481  
    /// @copydoc url_base::set_params
482  
    url& set_params(std::initializer_list<param_view> ps, encoding_opts opts = {}) { url_base::set_params(ps, opts); return *this; }
482  
    url& set_params(std::initializer_list<param_view> ps, encoding_opts opts = {}) { url_base::set_params(ps, opts); return *this; }
483  
    /// @copydoc url_base::set_encoded_params
483  
    /// @copydoc url_base::set_encoded_params
484  
    url& set_encoded_params(std::initializer_list< param_pct_view > ps) { url_base::set_encoded_params(ps); return *this; }
484  
    url& set_encoded_params(std::initializer_list< param_pct_view > ps) { url_base::set_encoded_params(ps); return *this; }
485  
    /// @copydoc url_base::remove_query
485  
    /// @copydoc url_base::remove_query
486  
    url& remove_query() noexcept { url_base::remove_query(); return *this; }
486  
    url& remove_query() noexcept { url_base::remove_query(); return *this; }
487  

487  

488  
    /// @copydoc url_base::remove_fragment
488  
    /// @copydoc url_base::remove_fragment
489  
    url& remove_fragment() noexcept { url_base::remove_fragment(); return *this; }
489  
    url& remove_fragment() noexcept { url_base::remove_fragment(); return *this; }
490  
    /// @copydoc url_base::set_fragment
490  
    /// @copydoc url_base::set_fragment
491  
    url& set_fragment(core::string_view s) { url_base::set_fragment(s); return *this; }
491  
    url& set_fragment(core::string_view s) { url_base::set_fragment(s); return *this; }
492  
    /// @copydoc url_base::set_encoded_fragment
492  
    /// @copydoc url_base::set_encoded_fragment
493  
    url& set_encoded_fragment(pct_string_view s) { url_base::set_encoded_fragment(s); return *this; }
493  
    url& set_encoded_fragment(pct_string_view s) { url_base::set_encoded_fragment(s); return *this; }
494  

494  

495  
    /// @copydoc url_base::remove_origin
495  
    /// @copydoc url_base::remove_origin
496  
    url& remove_origin() { url_base::remove_origin(); return *this; }
496  
    url& remove_origin() { url_base::remove_origin(); return *this; }
497  

497  

498  
    /// @copydoc url_base::normalize
498  
    /// @copydoc url_base::normalize
499  
    url& normalize() { url_base::normalize(); return *this; }
499  
    url& normalize() { url_base::normalize(); return *this; }
500  
    /// @copydoc url_base::normalize_scheme
500  
    /// @copydoc url_base::normalize_scheme
501  
    url& normalize_scheme() { url_base::normalize_scheme(); return *this; }
501  
    url& normalize_scheme() { url_base::normalize_scheme(); return *this; }
502  
    /// @copydoc url_base::normalize_authority
502  
    /// @copydoc url_base::normalize_authority
503  
    url& normalize_authority() { url_base::normalize_authority(); return *this; }
503  
    url& normalize_authority() { url_base::normalize_authority(); return *this; }
504  
    /// @copydoc url_base::normalize_path
504  
    /// @copydoc url_base::normalize_path
505  
    url& normalize_path() { url_base::normalize_path(); return *this; }
505  
    url& normalize_path() { url_base::normalize_path(); return *this; }
506  
    /// @copydoc url_base::normalize_query
506  
    /// @copydoc url_base::normalize_query
507  
    url& normalize_query() { url_base::normalize_query(); return *this; }
507  
    url& normalize_query() { url_base::normalize_query(); return *this; }
508  
    /// @copydoc url_base::normalize_fragment
508  
    /// @copydoc url_base::normalize_fragment
509  
    url& normalize_fragment() { url_base::normalize_fragment(); return *this; }
509  
    url& normalize_fragment() { url_base::normalize_fragment(); return *this; }
510  

510  

511  
    //--------------------------------------------
511  
    //--------------------------------------------
512  

512  

513  
private:
513  
private:
514  
    char* allocate(std::size_t);
514  
    char* allocate(std::size_t);
515  
    void deallocate(char* s);
515  
    void deallocate(char* s);
516  

516  

517  
    void clear_impl() noexcept override;
517  
    void clear_impl() noexcept override;
518  
    void reserve_impl(std::size_t, op_t&) override;
518  
    void reserve_impl(std::size_t, op_t&) override;
519  
    void cleanup(op_t&) override;
519  
    void cleanup(op_t&) override;
520  
};
520  
};
521  

521  

522  
} // urls
522  
} // urls
523  
} // boost
523  
} // boost
524  

524  

525  
//------------------------------------------------
525  
//------------------------------------------------
526  

526  

527  
// std::hash specialization
527  
// std::hash specialization
528  
#ifndef BOOST_URL_DOCS
528  
#ifndef BOOST_URL_DOCS
529  
namespace std {
529  
namespace std {
530  
template<>
530  
template<>
531  
struct hash< ::boost::urls::url >
531  
struct hash< ::boost::urls::url >
532  
{
532  
{
533  
    hash() = default;
533  
    hash() = default;
534  
    hash(hash const&) = default;
534  
    hash(hash const&) = default;
535  
    hash& operator=(hash const&) = default;
535  
    hash& operator=(hash const&) = default;
536  

536  

537  
    explicit
537  
    explicit
538  
    hash(std::size_t salt) noexcept
538  
    hash(std::size_t salt) noexcept
539  
        : salt_(salt)
539  
        : salt_(salt)
540  
    {
540  
    {
541  
    }
541  
    }
542  

542  

543  
    std::size_t
543  
    std::size_t
544  
    operator()(::boost::urls::url const& u) const noexcept
544  
    operator()(::boost::urls::url const& u) const noexcept
545  
    {
545  
    {
546  
        return u.digest(salt_);
546  
        return u.digest(salt_);
547  
    }
547  
    }
548  

548  

549  
private:
549  
private:
550  
    std::size_t salt_ = 0;
550  
    std::size_t salt_ = 0;
551  
};
551  
};
552  
} // std
552  
} // std
553  
#endif
553  
#endif
554  

554  

555  
#endif
555  
#endif