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

9  

10  
#ifndef BOOST_URL_STATIC_URL_HPP
10  
#ifndef BOOST_URL_STATIC_URL_HPP
11  
#define BOOST_URL_STATIC_URL_HPP
11  
#define BOOST_URL_STATIC_URL_HPP
12  

12  

13  
#include <boost/url/detail/config.hpp>
13  
#include <boost/url/detail/config.hpp>
14  
#include <boost/url/url_base.hpp>
14  
#include <boost/url/url_base.hpp>
15  
#include <boost/align/align_up.hpp>
15  
#include <boost/align/align_up.hpp>
16  
#include <boost/core/detail/static_assert.hpp>
16  
#include <boost/core/detail/static_assert.hpp>
17  
#include <cstddef>
17  
#include <cstddef>
18  

18  

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

21  

22  
#ifndef BOOST_URL_DOCS
22  
#ifndef BOOST_URL_DOCS
23  
template<std::size_t Capacity>
23  
template<std::size_t Capacity>
24  
class static_url;
24  
class static_url;
25  
#endif
25  
#endif
26  

26  

27  
// VFALCO This class is for reducing
27  
// VFALCO This class is for reducing
28  
// the number of template instantiations,
28  
// the number of template instantiations,
29  
// and keep definitions in the library
29  
// and keep definitions in the library
30  

30  

31  
/** Common implementation for all static URLs
31  
/** Common implementation for all static URLs
32  

32  

33  
    This base class is used by the library
33  
    This base class is used by the library
34  
    to provide common functionality for
34  
    to provide common functionality for
35  
    static URLs. Users should not use this
35  
    static URLs. Users should not use this
36  
    class directly. Instead, construct an
36  
    class directly. Instead, construct an
37  
    instance of one of the containers
37  
    instance of one of the containers
38  
    or call a parsing function.
38  
    or call a parsing function.
39  

39  

40  
    @par Containers
40  
    @par Containers
41  
        @li @ref url
41  
        @li @ref url
42  
        @li @ref url_view
42  
        @li @ref url_view
43  
        @li @ref static_url
43  
        @li @ref static_url
44  

44  

45  
    @par Parsing Functions
45  
    @par Parsing Functions
46  
        @li @ref parse_absolute_uri
46  
        @li @ref parse_absolute_uri
47  
        @li @ref parse_origin_form
47  
        @li @ref parse_origin_form
48  
        @li @ref parse_relative_ref
48  
        @li @ref parse_relative_ref
49  
        @li @ref parse_uri
49  
        @li @ref parse_uri
50  
        @li @ref parse_uri_reference
50  
        @li @ref parse_uri_reference
51  
*/
51  
*/
52  
class BOOST_SYMBOL_VISIBLE static_url_base
52  
class BOOST_SYMBOL_VISIBLE static_url_base
53  
    : public url_base
53  
    : public url_base
54  
{
54  
{
55  
    template<std::size_t>
55  
    template<std::size_t>
56  
    friend class static_url;
56  
    friend class static_url;
57  

57  

58  
    ~static_url_base() = default;
58  
    ~static_url_base() = default;
59  
    static_url_base(
59  
    static_url_base(
60  
        char* buf, std::size_t cap) noexcept;
60  
        char* buf, std::size_t cap) noexcept;
61  
    static_url_base(
61  
    static_url_base(
62  
        char* buf, std::size_t cap, core::string_view s);
62  
        char* buf, std::size_t cap, core::string_view s);
63  
    void clear_impl() noexcept override;
63  
    void clear_impl() noexcept override;
64  
    void reserve_impl(std::size_t, op_t&) override;
64  
    void reserve_impl(std::size_t, op_t&) override;
65  
    void cleanup(op_t&) override;
65  
    void cleanup(op_t&) override;
66  

66  

67  
    void
67  
    void
68  
    copy(url_view_base const& u)
68  
    copy(url_view_base const& u)
69  
    {
69  
    {
70  
        this->url_base::copy(u);
70  
        this->url_base::copy(u);
71  
    }
71  
    }
72  

72  

73  
};
73  
};
74  

74  

75  
//------------------------------------------------
75  
//------------------------------------------------
76  

76  

77  
/** A modifiable container for a URL.
77  
/** A modifiable container for a URL.
78  

78  

79  
    This container owns a url, represented
79  
    This container owns a url, represented
80  
    by an inline, null-terminated character
80  
    by an inline, null-terminated character
81  
    buffer with fixed capacity.
81  
    buffer with fixed capacity.
82  
    The contents may be inspected and modified,
82  
    The contents may be inspected and modified,
83  
    and the implementation maintains a useful
83  
    and the implementation maintains a useful
84  
    invariant: changes to the url always
84  
    invariant: changes to the url always
85  
    leave it in a valid state.
85  
    leave it in a valid state.
86  

86  

87  
    @par Example
87  
    @par Example
88  
    @code
88  
    @code
89  
    static_url< 1024 > u( "https://www.example.com" );
89  
    static_url< 1024 > u( "https://www.example.com" );
90  
    @endcode
90  
    @endcode
91  

91  

92  
    @par Invariants
92  
    @par Invariants
93  
    @code
93  
    @code
94  
    this->capacity() == Capacity + 1
94  
    this->capacity() == Capacity + 1
95  
    @endcode
95  
    @endcode
96  

96  

97  
    @tparam Capacity The maximum capacity
97  
    @tparam Capacity The maximum capacity
98  
    in characters, not including the
98  
    in characters, not including the
99  
    null terminator.
99  
    null terminator.
100  

100  

101  
    @see
101  
    @see
102  
        @ref url,
102  
        @ref url,
103  
        @ref url_view.
103  
        @ref url_view.
104  
*/
104  
*/
105  
template<std::size_t Capacity>
105  
template<std::size_t Capacity>
106  
class static_url
106  
class static_url
107  
    : public static_url_base
107  
    : public static_url_base
108  
{
108  
{
109  
    char buf_[Capacity + 1];
109  
    char buf_[Capacity + 1];
110  

110  

111  
    friend std::hash<static_url>;
111  
    friend std::hash<static_url>;
112  
    using url_view_base::digest;
112  
    using url_view_base::digest;
113  

113  

114  
public:
114  
public:
115  
    //--------------------------------------------
115  
    //--------------------------------------------
116  
    //
116  
    //
117  
    // Special Members
117  
    // Special Members
118  
    //
118  
    //
119  
    //--------------------------------------------
119  
    //--------------------------------------------
120  

120  

121  
    /** Destructor
121  
    /** Destructor
122  

122  

123  
        Any params, segments, iterators, or
123  
        Any params, segments, iterators, or
124  
        views which reference this object are
124  
        views which reference this object are
125  
        invalidated. The underlying character
125  
        invalidated. The underlying character
126  
        buffer is destroyed, invalidating all
126  
        buffer is destroyed, invalidating all
127  
        references to it.
127  
        references to it.
128  
    */
128  
    */
129  
    ~static_url() = default;
129  
    ~static_url() = default;
130  

130  

131  
    /** Constructor
131  
    /** Constructor
132  

132  

133  
        Default constructed urls contain
133  
        Default constructed urls contain
134  
        a zero-length string. This matches
134  
        a zero-length string. This matches
135  
        the grammar for a relative-ref with
135  
        the grammar for a relative-ref with
136  
        an empty path and no query or
136  
        an empty path and no query or
137  
        fragment.
137  
        fragment.
138  

138  

139  
        @par Example
139  
        @par Example
140  
        @code
140  
        @code
141  
        static_url< 1024 > u;
141  
        static_url< 1024 > u;
142  
        @endcode
142  
        @endcode
143  

143  

144  
        @par Postconditions
144  
        @par Postconditions
145  
        @code
145  
        @code
146  
        this->empty() == true
146  
        this->empty() == true
147  
        @endcode
147  
        @endcode
148  

148  

149  
        @par Complexity
149  
        @par Complexity
150  
        Constant.
150  
        Constant.
151  

151  

152  
        @par Exception Safety
152  
        @par Exception Safety
153  
        Throws nothing.
153  
        Throws nothing.
154  

154  

155  
        @par BNF
155  
        @par BNF
156  
        @code
156  
        @code
157  
        relative-ref  = relative-part [ "?" query ] [ "#" fragment ]
157  
        relative-ref  = relative-part [ "?" query ] [ "#" fragment ]
158  
        @endcode
158  
        @endcode
159  

159  

160  
        @par Specification
160  
        @par Specification
161  
        <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-4.2"
161  
        <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-4.2"
162  
            >4.2. Relative Reference (rfc3986)</a>
162  
            >4.2. Relative Reference (rfc3986)</a>
163  
    */
163  
    */
164  
    static_url() noexcept
164  
    static_url() noexcept
165  
        : static_url_base(
165  
        : static_url_base(
166  
            buf_, sizeof(buf_))
166  
            buf_, sizeof(buf_))
167  
    {
167  
    {
168  
    }
168  
    }
169  

169  

170  
    /** Constructor
170  
    /** Constructor
171  

171  

172  
        This function constructs a url from
172  
        This function constructs a url from
173  
        the string `s`, which must contain a
173  
        the string `s`, which must contain a
174  
        valid <em>URI</em> or <em>relative-ref</em>
174  
        valid <em>URI</em> or <em>relative-ref</em>
175  
        or else an exception is thrown.
175  
        or else an exception is thrown.
176  
        The new url retains ownership by
176  
        The new url retains ownership by
177  
        making a copy of the passed string.
177  
        making a copy of the passed string.
178  

178  

179  
        @par Example
179  
        @par Example
180  
        @code
180  
        @code
181  
        static_url< 1024 > u( "https://www.example.com" );
181  
        static_url< 1024 > u( "https://www.example.com" );
182  
        @endcode
182  
        @endcode
183  

183  

184  
        @par Effects
184  
        @par Effects
185  
        @code
185  
        @code
186  
        return static_url( parse_uri_reference( s ).value() );
186  
        return static_url( parse_uri_reference( s ).value() );
187  
        @endcode
187  
        @endcode
188  

188  

189  
        @par Postconditions
189  
        @par Postconditions
190  
        @code
190  
        @code
191  
        this->buffer().data() != s.data()
191  
        this->buffer().data() != s.data()
192  
        @endcode
192  
        @endcode
193  

193  

194  
        @par Complexity
194  
        @par Complexity
195  
        Linear in `s.size()`.
195  
        Linear in `s.size()`.
196  

196  

197  
        @par Exception Safety
197  
        @par Exception Safety
198  
        Exceptions thrown on invalid input.
198  
        Exceptions thrown on invalid input.
199  

199  

200  
        @throw system_error
200  
        @throw system_error
201  
        The input does not contain a valid url.
201  
        The input does not contain a valid url.
202  

202  

203  
        @param s The string to parse.
203  
        @param s The string to parse.
204  

204  

205  
        @par BNF
205  
        @par BNF
206  
        @code
206  
        @code
207  
        URI           = scheme ":" hier-part [ "?" query ] [ "#" fragment ]
207  
        URI           = scheme ":" hier-part [ "?" query ] [ "#" fragment ]
208  

208  

209  
        relative-ref  = relative-part [ "?" query ] [ "#" fragment ]
209  
        relative-ref  = relative-part [ "?" query ] [ "#" fragment ]
210  
        @endcode
210  
        @endcode
211  

211  

212  
        @par Specification
212  
        @par Specification
213  
        @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-4.1"
213  
        @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-4.1"
214  
            >4.1. URI Reference</a>
214  
            >4.1. URI Reference</a>
215  
    */
215  
    */
216  
    explicit
216  
    explicit
217  
    static_url(
217  
    static_url(
218  
        core::string_view s)
218  
        core::string_view s)
219  
        : static_url_base(
219  
        : static_url_base(
220  
            buf_, sizeof(buf_), s)
220  
            buf_, sizeof(buf_), s)
221  
    {
221  
    {
222  
    }
222  
    }
223  

223  

224  
    /** Constructor
224  
    /** Constructor
225  

225  

226  
        The newly constructed object contains
226  
        The newly constructed object contains
227  
        a copy of `u`.
227  
        a copy of `u`.
228  

228  

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

233  

234  
        @par Complexity
234  
        @par Complexity
235  
        Linear in `u.size()`.
235  
        Linear in `u.size()`.
236  

236  

237  
        @par Exception Safety
237  
        @par Exception Safety
238  
        Throws nothing.
238  
        Throws nothing.
239  

239  

240  
        @param u The url to copy.
240  
        @param u The url to copy.
241  
    */
241  
    */
242  
    static_url(
242  
    static_url(
243  
        static_url const& u) noexcept
243  
        static_url const& u) noexcept
244  
        : static_url()
244  
        : static_url()
245  
    {
245  
    {
246  
        copy(u);
246  
        copy(u);
247  
    }
247  
    }
248  

248  

249  
    /** Constructor
249  
    /** Constructor
250  

250  

251  
        The newly constructed object contains
251  
        The newly constructed object contains
252  
        a copy of `u`.
252  
        a copy of `u`.
253  

253  

254  
        @par Postconditions
254  
        @par Postconditions
255  
        @code
255  
        @code
256  
        this->buffer() == u.buffer() && this->buffer.data() != u.buffer().data()
256  
        this->buffer() == u.buffer() && this->buffer.data() != u.buffer().data()
257  
        @endcode
257  
        @endcode
258  

258  

259  
        @par Complexity
259  
        @par Complexity
260  
        Linear in `u.size()`.
260  
        Linear in `u.size()`.
261  

261  

262  
        @par Exception Safety
262  
        @par Exception Safety
263  
        Exception thrown if capacity exceeded.
263  
        Exception thrown if capacity exceeded.
264  

264  

265  
        @throw system_error
265  
        @throw system_error
266  
        Capacity would be exceeded.
266  
        Capacity would be exceeded.
267  

267  

268  
        @param u The url to copy.
268  
        @param u The url to copy.
269  
    */
269  
    */
270  
    static_url(
270  
    static_url(
271  
        url_view_base const& u)
271  
        url_view_base const& u)
272  
        : static_url()
272  
        : static_url()
273  
    {
273  
    {
274  
        copy(u);
274  
        copy(u);
275  
    }
275  
    }
276  

276  

277  
    /** Assignment
277  
    /** Assignment
278  

278  

279  
        The contents of `u` are copied and
279  
        The contents of `u` are copied and
280  
        the previous contents of `this` are
280  
        the previous contents of `this` are
281  
        discarded.
281  
        discarded.
282  
        Capacity remains unchanged.
282  
        Capacity remains unchanged.
283  

283  

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

288  

289  
        @par Complexity
289  
        @par Complexity
290  
        Linear in `u.size()`.
290  
        Linear in `u.size()`.
291  

291  

292  
        @par Exception Safety
292  
        @par Exception Safety
293  
        Throws nothing.
293  
        Throws nothing.
294  

294  

295  
        @param u The url to copy.
295  
        @param u The url to copy.
296  
        @return A reference to this object.
296  
        @return A reference to this object.
297  
    */
297  
    */
298  
    static_url&
298  
    static_url&
299  
    operator=(
299  
    operator=(
300  
        static_url const& u) noexcept
300  
        static_url const& u) noexcept
301  
    {
301  
    {
302  
        if (this != &u)
302  
        if (this != &u)
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  
        discarded.
311  
        discarded.
312  

312  

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

317  

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

320  

321  
        @par Exception Safety
321  
        @par Exception Safety
322  
        Strong guarantee.
322  
        Strong guarantee.
323  
        Exception thrown if capacity exceeded.
323  
        Exception thrown if capacity exceeded.
324  

324  

325  
        @throw system_error
325  
        @throw system_error
326  
        Capacity would be exceeded.
326  
        Capacity would be exceeded.
327  

327  

328  
        @param u The url to copy.
328  
        @param u The url to copy.
329  
        @return A reference to this object.
329  
        @return A reference to this object.
330  
    */
330  
    */
331  
    static_url&
331  
    static_url&
332  
    operator=(
332  
    operator=(
333  
        url_view_base const& u)
333  
        url_view_base const& u)
334  
    {
334  
    {
335  
        copy(u);
335  
        copy(u);
336  
        return *this;
336  
        return *this;
337  
    }
337  
    }
338  

338  

339  

339  

340  
    //--------------------------------------------
340  
    //--------------------------------------------
341  
    //
341  
    //
342  
    // fluent api
342  
    // fluent api
343  
    //
343  
    //
344  

344  

345  
    /// @copydoc url_base::set_scheme
345  
    /// @copydoc url_base::set_scheme
346  
    static_url& set_scheme(core::string_view s) { url_base::set_scheme(s); return *this; }
346  
    static_url& set_scheme(core::string_view s) { url_base::set_scheme(s); return *this; }
347  
    /// @copydoc url_base::set_scheme_id
347  
    /// @copydoc url_base::set_scheme_id
348  
    static_url& set_scheme_id(urls::scheme id) { url_base::set_scheme_id(id); return *this; }
348  
    static_url& set_scheme_id(urls::scheme id) { url_base::set_scheme_id(id); return *this; }
349  
    /// @copydoc url_base::remove_scheme
349  
    /// @copydoc url_base::remove_scheme
350  
    static_url& remove_scheme() { url_base::remove_scheme(); return *this; }
350  
    static_url& remove_scheme() { url_base::remove_scheme(); return *this; }
351  

351  

352  
    /// @copydoc url_base::set_encoded_authority
352  
    /// @copydoc url_base::set_encoded_authority
353  
    static_url& set_encoded_authority(pct_string_view s) { url_base::set_encoded_authority(s); return *this; }
353  
    static_url& set_encoded_authority(pct_string_view s) { url_base::set_encoded_authority(s); return *this; }
354  
    /// @copydoc url_base::remove_authority
354  
    /// @copydoc url_base::remove_authority
355  
    static_url& remove_authority() { url_base::remove_authority(); return *this; }
355  
    static_url& remove_authority() { url_base::remove_authority(); return *this; }
356  

356  

357  
    /// @copydoc url_base::set_userinfo
357  
    /// @copydoc url_base::set_userinfo
358  
    static_url& set_userinfo(core::string_view s) { url_base::set_userinfo(s); return *this; }
358  
    static_url& set_userinfo(core::string_view s) { url_base::set_userinfo(s); return *this; }
359  
    /// @copydoc url_base::set_encoded_userinfo
359  
    /// @copydoc url_base::set_encoded_userinfo
360  
    static_url& set_encoded_userinfo(pct_string_view s) { url_base::set_encoded_userinfo(s); return *this; }
360  
    static_url& set_encoded_userinfo(pct_string_view s) { url_base::set_encoded_userinfo(s); return *this; }
361  
    /// @copydoc url_base::remove_userinfo
361  
    /// @copydoc url_base::remove_userinfo
362  
    static_url& remove_userinfo() noexcept { url_base::remove_userinfo(); return *this; }
362  
    static_url& remove_userinfo() noexcept { url_base::remove_userinfo(); return *this; }
363  
    /// @copydoc url_base::set_user
363  
    /// @copydoc url_base::set_user
364  
    static_url& set_user(core::string_view s) { url_base::set_user(s); return *this; }
364  
    static_url& set_user(core::string_view s) { url_base::set_user(s); return *this; }
365  
    /// @copydoc url_base::set_encoded_user
365  
    /// @copydoc url_base::set_encoded_user
366  
    static_url& set_encoded_user(pct_string_view s) { url_base::set_encoded_user(s); return *this; }
366  
    static_url& set_encoded_user(pct_string_view s) { url_base::set_encoded_user(s); return *this; }
367  
    /// @copydoc url_base::set_password
367  
    /// @copydoc url_base::set_password
368  
    static_url& set_password(core::string_view s) { url_base::set_password(s); return *this; }
368  
    static_url& set_password(core::string_view s) { url_base::set_password(s); return *this; }
369  
    /// @copydoc url_base::set_encoded_password
369  
    /// @copydoc url_base::set_encoded_password
370  
    static_url& set_encoded_password(pct_string_view s) { url_base::set_encoded_password(s); return *this; }
370  
    static_url& set_encoded_password(pct_string_view s) { url_base::set_encoded_password(s); return *this; }
371  
    /// @copydoc url_base::remove_password
371  
    /// @copydoc url_base::remove_password
372  
    static_url& remove_password() noexcept { url_base::remove_password(); return *this; }
372  
    static_url& remove_password() noexcept { url_base::remove_password(); return *this; }
373  

373  

374  
    /// @copydoc url_base::set_host
374  
    /// @copydoc url_base::set_host
375  
    static_url& set_host(core::string_view s) { url_base::set_host(s); return *this; }
375  
    static_url& set_host(core::string_view s) { url_base::set_host(s); return *this; }
376  
    /// @copydoc url_base::set_encoded_host
376  
    /// @copydoc url_base::set_encoded_host
377  
    static_url& set_encoded_host(pct_string_view s) { url_base::set_encoded_host(s); return *this; }
377  
    static_url& set_encoded_host(pct_string_view s) { url_base::set_encoded_host(s); return *this; }
378  
    /// @copydoc url_base::set_host_address
378  
    /// @copydoc url_base::set_host_address
379  
    static_url& set_host_address(core::string_view s) { url_base::set_host_address(s); return *this; }
379  
    static_url& set_host_address(core::string_view s) { url_base::set_host_address(s); return *this; }
380  
    /// @copydoc url_base::set_encoded_host_address
380  
    /// @copydoc url_base::set_encoded_host_address
381  
    static_url& set_encoded_host_address(pct_string_view s) { url_base::set_encoded_host_address(s); return *this; }
381  
    static_url& set_encoded_host_address(pct_string_view s) { url_base::set_encoded_host_address(s); return *this; }
382  
    /// @copydoc url_base::set_host_ipv4
382  
    /// @copydoc url_base::set_host_ipv4
383  
    static_url& set_host_ipv4(ipv4_address const& addr) { url_base::set_host_ipv4(addr); return *this; }
383  
    static_url& set_host_ipv4(ipv4_address const& addr) { url_base::set_host_ipv4(addr); return *this; }
384  
    /// @copydoc url_base::set_host_ipv6
384  
    /// @copydoc url_base::set_host_ipv6
385  
    static_url& set_host_ipv6(ipv6_address const& addr) { url_base::set_host_ipv6(addr); return *this; }
385  
    static_url& set_host_ipv6(ipv6_address const& addr) { url_base::set_host_ipv6(addr); return *this; }
386  
    /// @copydoc url_base::set_zone_id
386  
    /// @copydoc url_base::set_zone_id
387  
    static_url& set_zone_id(core::string_view s) { url_base::set_zone_id(s); return *this; }
387  
    static_url& set_zone_id(core::string_view s) { url_base::set_zone_id(s); return *this; }
388  
    /// @copydoc url_base::set_encoded_zone_id
388  
    /// @copydoc url_base::set_encoded_zone_id
389  
    static_url& set_encoded_zone_id(pct_string_view const& s) { url_base::set_encoded_zone_id(s); return *this; }
389  
    static_url& set_encoded_zone_id(pct_string_view const& s) { url_base::set_encoded_zone_id(s); return *this; }
390  
    /// @copydoc url_base::set_host_ipvfuture
390  
    /// @copydoc url_base::set_host_ipvfuture
391  
    static_url& set_host_ipvfuture(core::string_view s) { url_base::set_host_ipvfuture(s); return *this; }
391  
    static_url& set_host_ipvfuture(core::string_view s) { url_base::set_host_ipvfuture(s); return *this; }
392  
    /// @copydoc url_base::set_host_name
392  
    /// @copydoc url_base::set_host_name
393  
    static_url& set_host_name(core::string_view s) { url_base::set_host_name(s); return *this; }
393  
    static_url& set_host_name(core::string_view s) { url_base::set_host_name(s); return *this; }
394  
    /// @copydoc url_base::set_encoded_host_name
394  
    /// @copydoc url_base::set_encoded_host_name
395  
    static_url& set_encoded_host_name(pct_string_view s) { url_base::set_encoded_host_name(s); return *this; }
395  
    static_url& set_encoded_host_name(pct_string_view s) { url_base::set_encoded_host_name(s); return *this; }
396  
    /// @copydoc url_base::set_port_number
396  
    /// @copydoc url_base::set_port_number
397  
    static_url& set_port_number(std::uint16_t n) { url_base::set_port_number(n); return *this; }
397  
    static_url& set_port_number(std::uint16_t n) { url_base::set_port_number(n); return *this; }
398  
    /// @copydoc url_base::set_port
398  
    /// @copydoc url_base::set_port
399  
    static_url& set_port(core::string_view s) { url_base::set_port(s); return *this; }
399  
    static_url& set_port(core::string_view s) { url_base::set_port(s); return *this; }
400  
    /// @copydoc url_base::remove_port
400  
    /// @copydoc url_base::remove_port
401  
    static_url& remove_port() noexcept { url_base::remove_port(); return *this; }
401  
    static_url& remove_port() noexcept { url_base::remove_port(); return *this; }
402  

402  

403  
    /// @copydoc url_base::set_path_absolute
403  
    /// @copydoc url_base::set_path_absolute
404  
    //bool set_path_absolute(bool absolute);
404  
    //bool set_path_absolute(bool absolute);
405  
    /// @copydoc url_base::set_path
405  
    /// @copydoc url_base::set_path
406  
    static_url& set_path(core::string_view s) { url_base::set_path(s); return *this; }
406  
    static_url& set_path(core::string_view s) { url_base::set_path(s); return *this; }
407  
    /// @copydoc url_base::set_encoded_path
407  
    /// @copydoc url_base::set_encoded_path
408  
    static_url& set_encoded_path(pct_string_view s) { url_base::set_encoded_path(s); return *this; }
408  
    static_url& set_encoded_path(pct_string_view s) { url_base::set_encoded_path(s); return *this; }
409  

409  

410  
    /// @copydoc url_base::set_query
410  
    /// @copydoc url_base::set_query
411  
    static_url& set_query(core::string_view s) { url_base::set_query(s); return *this; }
411  
    static_url& set_query(core::string_view s) { url_base::set_query(s); return *this; }
412  
    /// @copydoc url_base::set_encoded_query
412  
    /// @copydoc url_base::set_encoded_query
413  
    static_url& set_encoded_query(pct_string_view s) { url_base::set_encoded_query(s); return *this; }
413  
    static_url& set_encoded_query(pct_string_view s) { url_base::set_encoded_query(s); return *this; }
414  
    /// @copydoc url_base::set_params
414  
    /// @copydoc url_base::set_params
415  
    static_url& set_params(std::initializer_list<param_view> ps, encoding_opts opts = {}) { url_base::set_params(ps, opts); return *this; }
415  
    static_url& set_params(std::initializer_list<param_view> ps, encoding_opts opts = {}) { url_base::set_params(ps, opts); return *this; }
416  
    /// @copydoc url_base::remove_query
416  
    /// @copydoc url_base::remove_query
417  
    static_url& remove_query() noexcept { url_base::remove_query(); return *this; }
417  
    static_url& remove_query() noexcept { url_base::remove_query(); return *this; }
418  

418  

419  
    /// @copydoc url_base::remove_fragment
419  
    /// @copydoc url_base::remove_fragment
420  
    static_url& remove_fragment() noexcept { url_base::remove_fragment(); return *this; }
420  
    static_url& remove_fragment() noexcept { url_base::remove_fragment(); return *this; }
421  
    /// @copydoc url_base::set_fragment
421  
    /// @copydoc url_base::set_fragment
422  
    static_url& set_fragment(core::string_view s) { url_base::set_fragment(s); return *this; }
422  
    static_url& set_fragment(core::string_view s) { url_base::set_fragment(s); return *this; }
423  
    /// @copydoc url_base::set_encoded_fragment
423  
    /// @copydoc url_base::set_encoded_fragment
424  
    static_url& set_encoded_fragment(pct_string_view s) { url_base::set_encoded_fragment(s); return *this; }
424  
    static_url& set_encoded_fragment(pct_string_view s) { url_base::set_encoded_fragment(s); return *this; }
425  

425  

426  
    /// @copydoc url_base::remove_origin
426  
    /// @copydoc url_base::remove_origin
427  
    static_url& remove_origin() { url_base::remove_origin(); return *this; }
427  
    static_url& remove_origin() { url_base::remove_origin(); return *this; }
428  

428  

429  
    /// @copydoc url_base::normalize
429  
    /// @copydoc url_base::normalize
430  
    static_url& normalize() { url_base::normalize(); return *this; }
430  
    static_url& normalize() { url_base::normalize(); return *this; }
431  
    /// @copydoc url_base::normalize_scheme
431  
    /// @copydoc url_base::normalize_scheme
432  
    static_url& normalize_scheme() { url_base::normalize_scheme(); return *this; }
432  
    static_url& normalize_scheme() { url_base::normalize_scheme(); return *this; }
433  
    /// @copydoc url_base::normalize_authority
433  
    /// @copydoc url_base::normalize_authority
434  
    static_url& normalize_authority() { url_base::normalize_authority(); return *this; }
434  
    static_url& normalize_authority() { url_base::normalize_authority(); return *this; }
435  
    /// @copydoc url_base::normalize_path
435  
    /// @copydoc url_base::normalize_path
436  
    static_url& normalize_path() { url_base::normalize_path(); return *this; }
436  
    static_url& normalize_path() { url_base::normalize_path(); return *this; }
437  
    /// @copydoc url_base::normalize_query
437  
    /// @copydoc url_base::normalize_query
438  
    static_url& normalize_query() { url_base::normalize_query(); return *this; }
438  
    static_url& normalize_query() { url_base::normalize_query(); return *this; }
439  
    /// @copydoc url_base::normalize_fragment
439  
    /// @copydoc url_base::normalize_fragment
440  
    static_url& normalize_fragment() { url_base::normalize_fragment(); return *this; }
440  
    static_url& normalize_fragment() { url_base::normalize_fragment(); return *this; }
441  

441  

442  
    //--------------------------------------------
442  
    //--------------------------------------------
443  
};
443  
};
444  

444  

445  
} // urls
445  
} // urls
446  
} // boost
446  
} // boost
447  

447  

448  
//------------------------------------------------
448  
//------------------------------------------------
449  

449  

450  
// std::hash specialization
450  
// std::hash specialization
451  
#ifndef BOOST_URL_DOCS
451  
#ifndef BOOST_URL_DOCS
452  
namespace std {
452  
namespace std {
453  
template<std::size_t N>
453  
template<std::size_t N>
454  
struct hash< ::boost::urls::static_url<N> >
454  
struct hash< ::boost::urls::static_url<N> >
455  
{
455  
{
456  
    hash() = default;
456  
    hash() = default;
457  
    hash(hash const&) = default;
457  
    hash(hash const&) = default;
458  
    hash& operator=(hash const&) = default;
458  
    hash& operator=(hash const&) = default;
459  

459  

460  
    explicit
460  
    explicit
461  
    hash(std::size_t salt) noexcept
461  
    hash(std::size_t salt) noexcept
462  
        : salt_(salt)
462  
        : salt_(salt)
463  
    {
463  
    {
464  
    }
464  
    }
465  

465  

466  
    std::size_t
466  
    std::size_t
467  
    operator()(::boost::urls::static_url<N> const& u) const noexcept
467  
    operator()(::boost::urls::static_url<N> const& u) const noexcept
468  
    {
468  
    {
469  
        return u.digest(salt_);
469  
        return u.digest(salt_);
470  
    }
470  
    }
471  

471  

472  
private:
472  
private:
473  
    std::size_t salt_ = 0;
473  
    std::size_t salt_ = 0;
474  
};
474  
};
475  
} // std
475  
} // std
476  
#endif
476  
#endif
477  

477  

478  
#include <boost/url/parse.hpp>
478  
#include <boost/url/parse.hpp>
479  
#include <boost/url/impl/static_url.hpp>
479  
#include <boost/url/impl/static_url.hpp>
480  

480  

481  
#endif
481  
#endif