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_VIEW_BASE_HPP
11  
#ifndef BOOST_URL_URL_VIEW_BASE_HPP
12  
#define BOOST_URL_URL_VIEW_BASE_HPP
12  
#define BOOST_URL_URL_VIEW_BASE_HPP
13  

13  

14  
#include <boost/url/detail/config.hpp>
14  
#include <boost/url/detail/config.hpp>
15  
#include <boost/url/authority_view.hpp>
15  
#include <boost/url/authority_view.hpp>
16  
#include <boost/url/host_type.hpp>
16  
#include <boost/url/host_type.hpp>
17  
#include <boost/url/ipv4_address.hpp>
17  
#include <boost/url/ipv4_address.hpp>
18  
#include <boost/url/ipv6_address.hpp>
18  
#include <boost/url/ipv6_address.hpp>
19  
#include <boost/url/params_view.hpp>
19  
#include <boost/url/params_view.hpp>
20  
#include <boost/url/params_encoded_view.hpp>
20  
#include <boost/url/params_encoded_view.hpp>
21  
#include <boost/url/pct_string_view.hpp>
21  
#include <boost/url/pct_string_view.hpp>
22  
#include <boost/url/scheme.hpp>
22  
#include <boost/url/scheme.hpp>
23  
#include <boost/url/segments_encoded_view.hpp>
23  
#include <boost/url/segments_encoded_view.hpp>
24  
#include <boost/url/segments_view.hpp>
24  
#include <boost/url/segments_view.hpp>
25  
#include <boost/url/detail/url_impl.hpp>
25  
#include <boost/url/detail/url_impl.hpp>
26  
#include <boost/url/grammar/string_token.hpp>
26  
#include <boost/url/grammar/string_token.hpp>
27  
#include <boost/assert.hpp>
27  
#include <boost/assert.hpp>
28  
#include <cstddef>
28  
#include <cstddef>
29  
#include <cstdint>
29  
#include <cstdint>
30  
#include <iosfwd>
30  
#include <iosfwd>
31  
#include <memory>
31  
#include <memory>
32  
#include <string>
32  
#include <string>
33  
#include <utility>
33  
#include <utility>
34  

34  

35  
namespace boost {
35  
namespace boost {
36  
namespace urls {
36  
namespace urls {
37  

37  

38  
#ifndef BOOST_URL_DOCS
38  
#ifndef BOOST_URL_DOCS
39  
namespace detail {
39  
namespace detail {
40  
struct pattern;
40  
struct pattern;
41  
}
41  
}
42  
#endif
42  
#endif
43  

43  

44  

44  

45  
/** Common functionality for containers
45  
/** Common functionality for containers
46  

46  

47  
    This base class is used by the library
47  
    This base class is used by the library
48  
    to provide common member functions for
48  
    to provide common member functions for
49  
    containers. This cannot be instantiated
49  
    containers. This cannot be instantiated
50  
    directly; Instead, use one of the
50  
    directly; Instead, use one of the
51  
    containers or functions:
51  
    containers or functions:
52  

52  

53  
    @par Containers
53  
    @par Containers
54  
        @li @ref url
54  
        @li @ref url
55  
        @li @ref url_view
55  
        @li @ref url_view
56  
        @li @ref static_url
56  
        @li @ref static_url
57  

57  

58  
    @par Functions
58  
    @par Functions
59  
        @li @ref parse_absolute_uri
59  
        @li @ref parse_absolute_uri
60  
        @li @ref parse_origin_form
60  
        @li @ref parse_origin_form
61  
        @li @ref parse_relative_ref
61  
        @li @ref parse_relative_ref
62  
        @li @ref parse_uri
62  
        @li @ref parse_uri
63  
        @li @ref parse_uri_reference
63  
        @li @ref parse_uri_reference
64  
*/
64  
*/
65 -
class BOOST_URL_DECL
65 +
class url_view_base
66 -
    url_view_base
 
67  
    : private detail::parts_base
66  
    : private detail::parts_base
68  
{
67  
{
69  
    detail::url_impl impl_;
68  
    detail::url_impl impl_;
70 -
    detail::url_impl const* pi_;
69 +
    detail::url_impl const* external_impl_;
71  

70  

72  
    friend class url;
71  
    friend class url;
73  
    friend class url_base;
72  
    friend class url_base;
74  
    friend class url_view;
73  
    friend class url_view;
75  
    friend class static_url_base;
74  
    friend class static_url_base;
76  
    friend class params_base;
75  
    friend class params_base;
77  
    friend class params_encoded_base;
76  
    friend class params_encoded_base;
78  
    friend class params_encoded_ref;
77  
    friend class params_encoded_ref;
79  
    friend class params_encoded_view;
78  
    friend class params_encoded_view;
80  
    friend class params_ref;
79  
    friend class params_ref;
81  
    friend class params_view;
80  
    friend class params_view;
82  
    friend class segments_base;
81  
    friend class segments_base;
83  
    friend class segments_encoded_base;
82  
    friend class segments_encoded_base;
84  
    friend class segments_encoded_ref;
83  
    friend class segments_encoded_ref;
85  
    friend class segments_encoded_view;
84  
    friend class segments_encoded_view;
86  
    friend class segments_ref;
85  
    friend class segments_ref;
87  
    friend class segments_view;
86  
    friend class segments_view;
88  
    friend struct detail::pattern;
87  
    friend struct detail::pattern;
89  

88  

90  
    struct shared_impl;
89  
    struct shared_impl;
91  

90  

92 -
    url_view_base() noexcept;
91 +
    // Returns reference to the active implementation.
 
92 +
    // Uses external_impl_ if set, otherwise local impl_.
 
93 +
    BOOST_URL_CXX14_CONSTEXPR
 
94 +
    detail::url_impl const&
 
95 +
    impl() const noexcept
 
96 +
    {
 
97 +
        return external_impl_ ? *external_impl_ : impl_;
 
98 +
    }
93  

99  

 
100 +
    BOOST_URL_CXX14_CONSTEXPR
 
101 +
    url_view_base() noexcept
 
102 +
        : impl_(detail::url_impl::from::url)
 
103 +
        , external_impl_(nullptr)
 
104 +
    {
 
105 +
    }
 
106 +

 
107 +
    BOOST_URL_CXX14_CONSTEXPR
94  
    explicit url_view_base(
108  
    explicit url_view_base(
95 -
        detail::url_impl const&) noexcept;
109 +
        detail::url_impl const& impl) noexcept
 
110 +
        : impl_(impl)
 
111 +
        , external_impl_(nullptr)
 
112 +
    {
 
113 +
    }
96  

114  

97  
    ~url_view_base() = default;
115  
    ~url_view_base() = default;
98  

116  

 
117 +
    BOOST_URL_CXX14_CONSTEXPR
99  
    url_view_base(
118  
    url_view_base(
100 -
        url_view_base const& o) noexcept
119 +
        url_view_base const& o) noexcept = default;
101 -
        : impl_(o.impl_)
120 +

102 -
        , pi_(o.pi_)
121 +
    BOOST_URL_CXX14_CONSTEXPR
103 -
    {
122 +
    url_view_base(
104 -
        if (pi_ == &o.impl_)
123 +
        url_view_base&& o) noexcept = default;
105 -
            pi_ = &impl_;
 
106 -
    }
 
107  

124  

108  
    url_view_base& operator=(
125  
    url_view_base& operator=(
109  
        url_view_base const&) = delete;
126  
        url_view_base const&) = delete;
110  

127  

111  
protected:
128  
protected:
112  
    /** Calculate a hash of the url
129  
    /** Calculate a hash of the url
113  

130  

114  
        This function calculates a hash of the
131  
        This function calculates a hash of the
115  
        url as if it were always normalized.
132  
        url as if it were always normalized.
116  

133  

117  
        @par Complexity
134  
        @par Complexity
118  
        Linear in `this->size()`.
135  
        Linear in `this->size()`.
119  

136  

120  
        @par Exception Safety
137  
        @par Exception Safety
121  
        Throws nothing.
138  
        Throws nothing.
122  

139  

123  
        @param salt An initial value to add to
140  
        @param salt An initial value to add to
124  
        the hash
141  
        the hash
125  

142  

126  
        @return A hash value suitable for use
143  
        @return A hash value suitable for use
127  
        in hash-based containers.
144  
        in hash-based containers.
128  
    */
145  
    */
129  
    std::size_t
146  
    std::size_t
130  
    digest(std::size_t salt = 0) const noexcept;
147  
    digest(std::size_t salt = 0) const noexcept;
131  

148  

132  
public:
149  
public:
133  
    //--------------------------------------------
150  
    //--------------------------------------------
134  
    //
151  
    //
135  
    // Observers
152  
    // Observers
136  
    //
153  
    //
137  
    //--------------------------------------------
154  
    //--------------------------------------------
138  

155  

139  
    /** Return the maximum number of characters possible
156  
    /** Return the maximum number of characters possible
140  

157  

141  
        This represents the largest number
158  
        This represents the largest number
142  
        of characters that are theoretically
159  
        of characters that are theoretically
143  
        possible to represent in a url,
160  
        possible to represent in a url,
144  
        not including any null terminator.
161  
        not including any null terminator.
145  
        In practice the actual possible size
162  
        In practice the actual possible size
146  
        may be lower than this number.
163  
        may be lower than this number.
147  

164  

148  
        @par Complexity
165  
        @par Complexity
149  
        Constant.
166  
        Constant.
150  

167  

151  
        @par Exception Safety
168  
        @par Exception Safety
152  
        Throws nothing.
169  
        Throws nothing.
153  

170  

154  
        @return The maximum number of characters.
171  
        @return The maximum number of characters.
155  
    */
172  
    */
156  
    static
173  
    static
157  
    constexpr
174  
    constexpr
158  
    std::size_t
175  
    std::size_t
159  
    max_size() noexcept
176  
    max_size() noexcept
160  
    {
177  
    {
161  
        return BOOST_URL_MAX_SIZE;
178  
        return BOOST_URL_MAX_SIZE;
162  
    }
179  
    }
163  

180  

164  
    /** Return the number of characters in the url
181  
    /** Return the number of characters in the url
165  

182  

166  
        This function returns the number of
183  
        This function returns the number of
167  
        characters in the url's encoded string,
184  
        characters in the url's encoded string,
168  
        not including any null terminator,
185  
        not including any null terminator,
169  
        if present.
186  
        if present.
170  

187  

171  
        @par Example
188  
        @par Example
172  
        @code
189  
        @code
173  
        assert( url_view( "file:///Program%20Files" ).size() == 23 );
190  
        assert( url_view( "file:///Program%20Files" ).size() == 23 );
174  
        @endcode
191  
        @endcode
175  

192  

176  
        @par Complexity
193  
        @par Complexity
177  
        Constant.
194  
        Constant.
178  

195  

179  
        @par Exception Safety
196  
        @par Exception Safety
180  
        Throws nothing.
197  
        Throws nothing.
181  

198  

182  
        @return The number of characters in the url.
199  
        @return The number of characters in the url.
183  
    */
200  
    */
184  
    std::size_t
201  
    std::size_t
185  
    size() const noexcept
202  
    size() const noexcept
186  
    {
203  
    {
187 -
        return pi_->offset(id_end);
204 +
        return impl().offset(id_end);
188  
    }
205  
    }
189  

206  

190  
    /** Return true if the url is empty
207  
    /** Return true if the url is empty
191  

208  

192  
        The empty string matches the
209  
        The empty string matches the
193  
        <em>relative-ref</em> grammar.
210  
        <em>relative-ref</em> grammar.
194  

211  

195  
        @par Example
212  
        @par Example
196  
        @code
213  
        @code
197  
        assert( url_view( "" ).empty() );
214  
        assert( url_view( "" ).empty() );
198  
        @endcode
215  
        @endcode
199  

216  

200  
        @par Complexity
217  
        @par Complexity
201  
        Constant.
218  
        Constant.
202  

219  

203  
        @par Exception Safety
220  
        @par Exception Safety
204  
        Throws nothing.
221  
        Throws nothing.
205  

222  

206  
        @par BNF
223  
        @par BNF
207  
        @code
224  
        @code
208  
        relative-ref  = relative-part [ "?" query ] [ "#" fragment ]
225  
        relative-ref  = relative-part [ "?" query ] [ "#" fragment ]
209  

226  

210  
        relative-part = "//" authority path-abempty
227  
        relative-part = "//" authority path-abempty
211  
                      / path-absolute
228  
                      / path-absolute
212  
                      / path-noscheme
229  
                      / path-noscheme
213  
                      / path-empty
230  
                      / path-empty
214  
        @endcode
231  
        @endcode
215  

232  

216  
        @par Specification
233  
        @par Specification
217  
        @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-4.2">4.2.  Relative Reference (rfc3986)</a>
234  
        @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-4.2">4.2.  Relative Reference (rfc3986)</a>
218  

235  

219  
        @return `true` if the url is empty.
236  
        @return `true` if the url is empty.
220  
    */
237  
    */
221  
    bool
238  
    bool
222  
    empty() const noexcept
239  
    empty() const noexcept
223  
    {
240  
    {
224 -
        return pi_->offset(id_end) == 0;
241 +
        return impl().offset(id_end) == 0;
225  
    }
242  
    }
226  

243  

227  
    /** Return a pointer to the url's character buffer
244  
    /** Return a pointer to the url's character buffer
228  

245  

229  
        This function returns a pointer to
246  
        This function returns a pointer to
230  
        the first character of the url, which
247  
        the first character of the url, which
231  
        is not guaranteed to be null-terminated.
248  
        is not guaranteed to be null-terminated.
232  

249  

233  
        @par Complexity
250  
        @par Complexity
234  
        Constant.
251  
        Constant.
235  

252  

236  
        @par Exception Safety
253  
        @par Exception Safety
237  
        Throws nothing.
254  
        Throws nothing.
238  

255  

239  
        @return A pointer to the first character.
256  
        @return A pointer to the first character.
240  
    */
257  
    */
241  
    char const*
258  
    char const*
242  
    data() const noexcept
259  
    data() const noexcept
243  
    {
260  
    {
244 -
        return pi_->cs_;
261 +
        return impl().cs_;
245  
    }
262  
    }
246  

263  

247  
    /** Return the url string
264  
    /** Return the url string
248  

265  

249  
        This function returns the entire url,
266  
        This function returns the entire url,
250  
        which may contain percent escapes.
267  
        which may contain percent escapes.
251  

268  

252  
        @par Example
269  
        @par Example
253  
        @code
270  
        @code
254  
        assert( url_view( "http://www.example.com" ).buffer() == "http://www.example.com" );
271  
        assert( url_view( "http://www.example.com" ).buffer() == "http://www.example.com" );
255  
        @endcode
272  
        @endcode
256  

273  

257  
        @par Complexity
274  
        @par Complexity
258  
        Constant.
275  
        Constant.
259  

276  

260  
        @par Exception Safety
277  
        @par Exception Safety
261  
        Throws nothing.
278  
        Throws nothing.
262  

279  

263  
        @return The url as a string.
280  
        @return The url as a string.
264  
    */
281  
    */
265  
    core::string_view
282  
    core::string_view
266  
    buffer() const noexcept
283  
    buffer() const noexcept
267  
    {
284  
    {
268  
        return core::string_view(
285  
        return core::string_view(
269  
            data(), size());
286  
            data(), size());
270  
    }
287  
    }
271  

288  

272  
    /** Return the URL as a core::string_view
289  
    /** Return the URL as a core::string_view
273  

290  

274  
        @par Complexity
291  
        @par Complexity
275  
        Constant.
292  
        Constant.
276  

293  

277  
        @par Exception Safety
294  
        @par Exception Safety
278  
        Throws nothing.
295  
        Throws nothing.
279  

296  

280  
        @return A string view of the URL.
297  
        @return A string view of the URL.
281  
    */
298  
    */
282  
    operator core::string_view() const noexcept
299  
    operator core::string_view() const noexcept
283  
    {
300  
    {
284  
        return buffer();
301  
        return buffer();
285  
    }
302  
    }
286  

303  

287  
    /** Return a shared, persistent copy of the url
304  
    /** Return a shared, persistent copy of the url
288  

305  

289  
        This function returns a read-only copy of
306  
        This function returns a read-only copy of
290  
        the url, with shared lifetime. The returned
307  
        the url, with shared lifetime. The returned
291  
        value owns (persists) the underlying string.
308  
        value owns (persists) the underlying string.
292  
        The algorithm used to create the value
309  
        The algorithm used to create the value
293  
        minimizes the number of individual memory
310  
        minimizes the number of individual memory
294  
        allocations, making it more efficient than
311  
        allocations, making it more efficient than
295  
        when using direct standard library functions.
312  
        when using direct standard library functions.
296  

313  

297  
        @par Example
314  
        @par Example
298  
        @code
315  
        @code
299  
        std::shared_ptr< url_view const > sp;
316  
        std::shared_ptr< url_view const > sp;
300  
        {
317  
        {
301  
            std::string s( "http://example.com" );
318  
            std::string s( "http://example.com" );
302  
            url_view u( s );                        // u references characters in s
319  
            url_view u( s );                        // u references characters in s
303  

320  

304  
            assert( u.data() == s.data() );         // same buffer
321  
            assert( u.data() == s.data() );         // same buffer
305  

322  

306  
            sp = u.persist();
323  
            sp = u.persist();
307  

324  

308  
            assert( sp->data() != s.data() );       // different buffer
325  
            assert( sp->data() != s.data() );       // different buffer
309  
            assert( sp->buffer() == s);             // same contents
326  
            assert( sp->buffer() == s);             // same contents
310  

327  

311  
            // s is destroyed and thus u
328  
            // s is destroyed and thus u
312  
            // becomes invalid, but sp remains valid.
329  
            // becomes invalid, but sp remains valid.
313  
        }
330  
        }
314  
        @endcode
331  
        @endcode
315  

332  

316  
        @par Complexity
333  
        @par Complexity
317  
        Linear in `this->size()`.
334  
        Linear in `this->size()`.
318  

335  

319  
        @par Exception Safety
336  
        @par Exception Safety
320  
        Calls to allocate may throw.
337  
        Calls to allocate may throw.
321  

338  

322  
        @return A shared pointer to a read-only url_view.
339  
        @return A shared pointer to a read-only url_view.
323  
    */
340  
    */
324  
    std::shared_ptr<
341  
    std::shared_ptr<
325  
        url_view const> persist() const;
342  
        url_view const> persist() const;
326  

343  

327  
    //--------------------------------------------
344  
    //--------------------------------------------
328  
    //
345  
    //
329  
    // Scheme
346  
    // Scheme
330  
    //
347  
    //
331  
    //--------------------------------------------
348  
    //--------------------------------------------
332  

349  

333  
    /** Return true a scheme is present
350  
    /** Return true a scheme is present
334  

351  

335  
        This function returns true if this
352  
        This function returns true if this
336  
        contains a scheme.
353  
        contains a scheme.
337  

354  

338  
        @par Example
355  
        @par Example
339  
        @code
356  
        @code
340  
        assert( url_view( "http://www.example.com" ).has_scheme() );
357  
        assert( url_view( "http://www.example.com" ).has_scheme() );
341  
        @endcode
358  
        @endcode
342  

359  

343  
        @par Complexity
360  
        @par Complexity
344  
        Constant.
361  
        Constant.
345  

362  

346  
        @par Exception Safety
363  
        @par Exception Safety
347  
        Throws nothing.
364  
        Throws nothing.
348  

365  

349  
        @par BNF
366  
        @par BNF
350  
        @code
367  
        @code
351  
        URI             = scheme ":" hier-part [ "?" query ] [ "#" fragment ]
368  
        URI             = scheme ":" hier-part [ "?" query ] [ "#" fragment ]
352  

369  

353  
        absolute-URI    = scheme ":" hier-part [ "?" query ]
370  
        absolute-URI    = scheme ":" hier-part [ "?" query ]
354  

371  

355  
        scheme          = ALPHA *( ALPHA / DIGIT / "+" / "-" / "." )
372  
        scheme          = ALPHA *( ALPHA / DIGIT / "+" / "-" / "." )
356  
        @endcode
373  
        @endcode
357  

374  

358  
        @par Specification
375  
        @par Specification
359  
        @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.1">3.1. Scheme (rfc3986)</a>
376  
        @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.1">3.1. Scheme (rfc3986)</a>
360  

377  

361  
        @see
378  
        @see
362  
            @ref scheme,
379  
            @ref scheme,
363  
            @ref scheme_id.
380  
            @ref scheme_id.
364  

381  

365  
        @return `true` if the url contains a scheme.
382  
        @return `true` if the url contains a scheme.
366  
    */
383  
    */
367  
    bool
384  
    bool
368  
    has_scheme() const noexcept;
385  
    has_scheme() const noexcept;
369  

386  

370  
    /** Return the scheme
387  
    /** Return the scheme
371  

388  

372  
        This function returns the scheme if it
389  
        This function returns the scheme if it
373  
        exists, without a trailing colon (':').
390  
        exists, without a trailing colon (':').
374  
        Otherwise it returns an empty string.
391  
        Otherwise it returns an empty string.
375  
        Note that schemes are case-insensitive,
392  
        Note that schemes are case-insensitive,
376  
        and the canonical form is lowercased.
393  
        and the canonical form is lowercased.
377  

394  

378  
        @par Example
395  
        @par Example
379  
        @code
396  
        @code
380  
        assert( url_view( "http://www.example.com" ).scheme() == "http" );
397  
        assert( url_view( "http://www.example.com" ).scheme() == "http" );
381  
        @endcode
398  
        @endcode
382  

399  

383  
        @par Exception Safety
400  
        @par Exception Safety
384  
        Throws nothing.
401  
        Throws nothing.
385  

402  

386  
        @par BNF
403  
        @par BNF
387  
        @code
404  
        @code
388  
        scheme          = ALPHA *( ALPHA / DIGIT / "+" / "-" / "." )
405  
        scheme          = ALPHA *( ALPHA / DIGIT / "+" / "-" / "." )
389  

406  

390  
        URI             = scheme ":" hier-part [ "?" query ] [ "#" fragment ]
407  
        URI             = scheme ":" hier-part [ "?" query ] [ "#" fragment ]
391  

408  

392  
        absolute-URI    = scheme ":" hier-part [ "?" query ]
409  
        absolute-URI    = scheme ":" hier-part [ "?" query ]
393  
        @endcode
410  
        @endcode
394  

411  

395  
        @par Specification
412  
        @par Specification
396  
        @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.1">3.1. Scheme (rfc3986)</a>
413  
        @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.1">3.1. Scheme (rfc3986)</a>
397  

414  

398  
        @see
415  
        @see
399  
            @ref has_scheme,
416  
            @ref has_scheme,
400  
            @ref scheme_id.
417  
            @ref scheme_id.
401  

418  

402  
        @return The scheme as a string.
419  
        @return The scheme as a string.
403  
    */
420  
    */
404  
    core::string_view
421  
    core::string_view
405  
    scheme() const noexcept;
422  
    scheme() const noexcept;
406  

423  

407  
    /** Return the scheme
424  
    /** Return the scheme
408  

425  

409  
        This function returns a value which
426  
        This function returns a value which
410  
        depends on the scheme in the url:
427  
        depends on the scheme in the url:
411  

428  

412  
        @li If the scheme is a well-known
429  
        @li If the scheme is a well-known
413  
        scheme, corresponding value from
430  
        scheme, corresponding value from
414  
        the enumeration @ref urls::scheme
431  
        the enumeration @ref urls::scheme
415  
        is returned.
432  
        is returned.
416  

433  

417  
        @li If a scheme is present but is not
434  
        @li If a scheme is present but is not
418  
        a well-known scheme, the value
435  
        a well-known scheme, the value
419  
        returned is @ref urls::scheme::unknown.
436  
        returned is @ref urls::scheme::unknown.
420  

437  

421  
        @li Otherwise, if the scheme is absent
438  
        @li Otherwise, if the scheme is absent
422  
        the value returned is
439  
        the value returned is
423  
        @ref urls::scheme::none.
440  
        @ref urls::scheme::none.
424  

441  

425  
        @par Example
442  
        @par Example
426  
        @code
443  
        @code
427  
        assert( url_view( "wss://www.example.com/crypto.cgi" ).scheme_id() == scheme::wss );
444  
        assert( url_view( "wss://www.example.com/crypto.cgi" ).scheme_id() == scheme::wss );
428  
        @endcode
445  
        @endcode
429  

446  

430  
        @par Complexity
447  
        @par Complexity
431  
        Constant.
448  
        Constant.
432  

449  

433  
        @par Exception Safety
450  
        @par Exception Safety
434  
        Throws nothing.
451  
        Throws nothing.
435  

452  

436  
        @par BNF
453  
        @par BNF
437  
        @code
454  
        @code
438  
        URI             = scheme ":" hier-part [ "?" query ] [ "#" fragment ]
455  
        URI             = scheme ":" hier-part [ "?" query ] [ "#" fragment ]
439  

456  

440  
        absolute-URI    = scheme ":" hier-part [ "?" query ]
457  
        absolute-URI    = scheme ":" hier-part [ "?" query ]
441  

458  

442  
        scheme          = ALPHA *( ALPHA / DIGIT / "+" / "-" / "." )
459  
        scheme          = ALPHA *( ALPHA / DIGIT / "+" / "-" / "." )
443  
        @endcode
460  
        @endcode
444  

461  

445  
        @par Specification
462  
        @par Specification
446  
        @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.1">3.1. Scheme (rfc3986)</a>
463  
        @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.1">3.1. Scheme (rfc3986)</a>
447  

464  

448  
        @see
465  
        @see
449  
            @ref has_scheme,
466  
            @ref has_scheme,
450  
            @ref scheme.
467  
            @ref scheme.
451  

468  

452  
        @return The scheme as an enumeration value.
469  
        @return The scheme as an enumeration value.
453  
    */
470  
    */
454  
    urls::scheme
471  
    urls::scheme
455  
    scheme_id() const noexcept;
472  
    scheme_id() const noexcept;
456  

473  

457  
    //--------------------------------------------
474  
    //--------------------------------------------
458  
    //
475  
    //
459  
    // Authority
476  
    // Authority
460  
    //
477  
    //
461  
    //--------------------------------------------
478  
    //--------------------------------------------
462  

479  

463  
    /** Return true if an authority is present
480  
    /** Return true if an authority is present
464  

481  

465  
        This function returns true if the url
482  
        This function returns true if the url
466  
        contains an authority. The presence of
483  
        contains an authority. The presence of
467  
        an authority is denoted by a double
484  
        an authority is denoted by a double
468  
        slash ("//") at the beginning or after
485  
        slash ("//") at the beginning or after
469  
        the scheme.
486  
        the scheme.
470  

487  

471  
        @par Example
488  
        @par Example
472  
        @code
489  
        @code
473  
        assert( url_view( "http://www.example.com/index.htm" ).has_authority() );
490  
        assert( url_view( "http://www.example.com/index.htm" ).has_authority() );
474  
        @endcode
491  
        @endcode
475  

492  

476  
        @par Complexity
493  
        @par Complexity
477  
        Constant.
494  
        Constant.
478  

495  

479  
        @par Exception Safety
496  
        @par Exception Safety
480  
        Throws nothing.
497  
        Throws nothing.
481  

498  

482  
        @par BNF
499  
        @par BNF
483  
        @code
500  
        @code
484  
        authority       = [ userinfo "@" ] host [ ":" port ]
501  
        authority       = [ userinfo "@" ] host [ ":" port ]
485  

502  

486  
        URI             = scheme ":" hier-part [ "?" query ] [ "#" fragment ]
503  
        URI             = scheme ":" hier-part [ "?" query ] [ "#" fragment ]
487  

504  

488  
        absolute-URI    = scheme ":" hier-part [ "?" query ]
505  
        absolute-URI    = scheme ":" hier-part [ "?" query ]
489  

506  

490  
        URI-reference   = URI / relative-ref
507  
        URI-reference   = URI / relative-ref
491  

508  

492  
        relative-ref    = relative-part [ "?" query ] [ "#" fragment ]
509  
        relative-ref    = relative-part [ "?" query ] [ "#" fragment ]
493  

510  

494  
        hier-part       = "//" authority path-abempty
511  
        hier-part       = "//" authority path-abempty
495  
                        ; (more...)
512  
                        ; (more...)
496  

513  

497  
        relative-part   = "//" authority path-abempty
514  
        relative-part   = "//" authority path-abempty
498  
                        ; (more...)
515  
                        ; (more...)
499  

516  

500  
        @endcode
517  
        @endcode
501  

518  

502  
        @par Specification
519  
        @par Specification
503  
        @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.2">3.2. Authority (rfc3986)</a>
520  
        @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.2">3.2. Authority (rfc3986)</a>
504  

521  

505  
        @see
522  
        @see
506  
            @ref authority,
523  
            @ref authority,
507  
            @ref encoded_authority.
524  
            @ref encoded_authority.
508  

525  

509  
        @return `true` if the url contains an authority.
526  
        @return `true` if the url contains an authority.
510  
    */
527  
    */
511  
    bool
528  
    bool
512  
    has_authority() const noexcept
529  
    has_authority() const noexcept
513  
    {
530  
    {
514 -
        return pi_->len(id_user) > 0;
531 +
        return impl().len(id_user) > 0;
515  
    }
532  
    }
516  

533  

517  
    /** Return the authority
534  
    /** Return the authority
518  

535  

519  
        This function returns the authority as
536  
        This function returns the authority as
520  
        an @ref authority_view.
537  
        an @ref authority_view.
521  

538  

522  
        @par Example
539  
        @par Example
523  
        @code
540  
        @code
524  
        authority_view a = url_view( "https://www.example.com:8080/index.htm" ).authority();
541  
        authority_view a = url_view( "https://www.example.com:8080/index.htm" ).authority();
525  
        @endcode
542  
        @endcode
526  

543  

527  
        @par Complexity
544  
        @par Complexity
528  
        Constant.
545  
        Constant.
529  

546  

530  
        @par Exception Safety
547  
        @par Exception Safety
531  
        Throws nothing.
548  
        Throws nothing.
532  

549  

533  
        @par BNF
550  
        @par BNF
534  
        @code
551  
        @code
535  
        authority   = [ userinfo "@" ] host [ ":" port ]
552  
        authority   = [ userinfo "@" ] host [ ":" port ]
536  
        @endcode
553  
        @endcode
537  

554  

538  
        @par Specification
555  
        @par Specification
539  
        @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.2">3.2. Authority (rfc3986)</a>
556  
        @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.2">3.2. Authority (rfc3986)</a>
540  

557  

541  
        @see
558  
        @see
542  
            @ref encoded_authority,
559  
            @ref encoded_authority,
543  
            @ref has_authority.
560  
            @ref has_authority.
544  

561  

545  
        @return An authority_view representing the authority.
562  
        @return An authority_view representing the authority.
546  
    */
563  
    */
547  
    authority_view
564  
    authority_view
548  
    authority() const noexcept;
565  
    authority() const noexcept;
549  

566  

550  
    /** Return the authority.
567  
    /** Return the authority.
551  

568  

552  
        If present, this function returns a
569  
        If present, this function returns a
553  
        string representing the authority (which
570  
        string representing the authority (which
554  
        may be empty).
571  
        may be empty).
555  
        Otherwise it returns an empty string.
572  
        Otherwise it returns an empty string.
556  
        The returned string may contain
573  
        The returned string may contain
557  
        percent escapes.
574  
        percent escapes.
558  

575  

559  
        @par Example
576  
        @par Example
560  
        @code
577  
        @code
561  
        assert( url_view( "file://Network%20Drive/My%2DFiles" ).encoded_authority() == "Network%20Drive" );
578  
        assert( url_view( "file://Network%20Drive/My%2DFiles" ).encoded_authority() == "Network%20Drive" );
562  
        @endcode
579  
        @endcode
563  

580  

564  
        @par Complexity
581  
        @par Complexity
565  
        Constant.
582  
        Constant.
566  

583  

567  
        @par Exception Safety
584  
        @par Exception Safety
568  
        Throws nothing.
585  
        Throws nothing.
569  

586  

570  
        @par BNF
587  
        @par BNF
571  
        @code
588  
        @code
572  
        authority   = [ userinfo "@" ] host [ ":" port ]
589  
        authority   = [ userinfo "@" ] host [ ":" port ]
573  
        @endcode
590  
        @endcode
574  

591  

575  
        @par Specification
592  
        @par Specification
576  
        @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.2">3.2. Authority (rfc3986)</a>
593  
        @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.2">3.2. Authority (rfc3986)</a>
577  

594  

578  
        @see
595  
        @see
579  
            @ref authority,
596  
            @ref authority,
580  
            @ref has_authority.
597  
            @ref has_authority.
581  

598  

582  
        @return The authority as a string.
599  
        @return The authority as a string.
583  
    */
600  
    */
584  
    pct_string_view
601  
    pct_string_view
585  
    encoded_authority() const noexcept;
602  
    encoded_authority() const noexcept;
586  

603  

587  
    //--------------------------------------------
604  
    //--------------------------------------------
588  
    //
605  
    //
589  
    // Userinfo
606  
    // Userinfo
590  
    //
607  
    //
591  
    //--------------------------------------------
608  
    //--------------------------------------------
592  

609  

593  
    /** Return true if a userinfo is present
610  
    /** Return true if a userinfo is present
594  

611  

595  
        This function returns true if this
612  
        This function returns true if this
596  
        contains a userinfo.
613  
        contains a userinfo.
597  

614  

598  
        @par Example
615  
        @par Example
599  
        @code
616  
        @code
600  
        assert( url_view( "http://jane%2Ddoe:pass@example.com" ).has_userinfo() );
617  
        assert( url_view( "http://jane%2Ddoe:pass@example.com" ).has_userinfo() );
601  
        @endcode
618  
        @endcode
602  

619  

603  
        @par Complexity
620  
        @par Complexity
604  
        Constant.
621  
        Constant.
605  

622  

606  
        @par Exception Safety
623  
        @par Exception Safety
607  
        Throws nothing.
624  
        Throws nothing.
608  

625  

609  
        @par BNF
626  
        @par BNF
610  
        @code
627  
        @code
611  
        userinfo    = user [ ":" [ password ] ]
628  
        userinfo    = user [ ":" [ password ] ]
612  

629  

613  
        authority   = [ userinfo "@" ] host [ ":" port ]
630  
        authority   = [ userinfo "@" ] host [ ":" port ]
614  
        @endcode
631  
        @endcode
615  

632  

616  
        @par Specification
633  
        @par Specification
617  
        @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.2.1">3.2.1. User Information (rfc3986)</a>
634  
        @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.2.1">3.2.1. User Information (rfc3986)</a>
618  

635  

619  
        @see
636  
        @see
620  
            @ref has_password,
637  
            @ref has_password,
621  
            @ref encoded_password,
638  
            @ref encoded_password,
622  
            @ref encoded_user,
639  
            @ref encoded_user,
623  
            @ref encoded_userinfo,
640  
            @ref encoded_userinfo,
624  
            @ref password,
641  
            @ref password,
625  
            @ref user,
642  
            @ref user,
626  
            @ref userinfo.
643  
            @ref userinfo.
627  

644  

628  
        @return `true` if the userinfo is present.
645  
        @return `true` if the userinfo is present.
629  
    */
646  
    */
630  
    bool
647  
    bool
631  
    has_userinfo() const noexcept;
648  
    has_userinfo() const noexcept;
632  

649  

633  
    /** Return true if a password is present
650  
    /** Return true if a password is present
634  

651  

635  
        This function returns true if the
652  
        This function returns true if the
636  
        userinfo is present and contains
653  
        userinfo is present and contains
637  
        a password.
654  
        a password.
638  

655  

639  
        @par Example
656  
        @par Example
640  
        @code
657  
        @code
641  
        assert( url_view( "http://jane%2Ddoe:pass@example.com" ).has_password() );
658  
        assert( url_view( "http://jane%2Ddoe:pass@example.com" ).has_password() );
642  
        @endcode
659  
        @endcode
643  

660  

644  
        @par Complexity
661  
        @par Complexity
645  
        Constant.
662  
        Constant.
646  

663  

647  
        @par Exception Safety
664  
        @par Exception Safety
648  
        Throws nothing.
665  
        Throws nothing.
649  

666  

650  
        @par BNF
667  
        @par BNF
651  
        @code
668  
        @code
652  
        userinfo    = user [ ":" [ password ] ]
669  
        userinfo    = user [ ":" [ password ] ]
653  

670  

654  
        user        = *( unreserved / pct-encoded / sub-delims )
671  
        user        = *( unreserved / pct-encoded / sub-delims )
655  
        password    = *( unreserved / pct-encoded / sub-delims / ":" )
672  
        password    = *( unreserved / pct-encoded / sub-delims / ":" )
656  
        @endcode
673  
        @endcode
657  

674  

658  
        @par Specification
675  
        @par Specification
659  
        @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.2.1">3.2.1. User Information (rfc3986)</a>
676  
        @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.2.1">3.2.1. User Information (rfc3986)</a>
660  

677  

661  
        @see
678  
        @see
662  
            @ref has_userinfo,
679  
            @ref has_userinfo,
663  
            @ref encoded_password,
680  
            @ref encoded_password,
664  
            @ref encoded_user,
681  
            @ref encoded_user,
665  
            @ref encoded_userinfo,
682  
            @ref encoded_userinfo,
666  
            @ref password,
683  
            @ref password,
667  
            @ref user,
684  
            @ref user,
668  
            @ref userinfo.
685  
            @ref userinfo.
669  

686  

670  
        @return `true` if the userinfo contains a password.
687  
        @return `true` if the userinfo contains a password.
671  
    */
688  
    */
672  
    bool
689  
    bool
673  
    has_password() const noexcept;
690  
    has_password() const noexcept;
674  

691  

675  
    /** Return the userinfo
692  
    /** Return the userinfo
676  

693  

677  
        If present, this function returns a
694  
        If present, this function returns a
678  
        string representing the userinfo (which
695  
        string representing the userinfo (which
679  
        may be empty).
696  
        may be empty).
680  
        Otherwise it returns an empty string.
697  
        Otherwise it returns an empty string.
681  
        Any percent-escapes in the string are
698  
        Any percent-escapes in the string are
682  
        decoded first.
699  
        decoded first.
683  

700  

684  
        @note
701  
        @note
685  
        This function uses the string token
702  
        This function uses the string token
686  
        return type customization. Depending on
703  
        return type customization. Depending on
687  
        the token passed, the return type and
704  
        the token passed, the return type and
688  
        behavior of the function can be different.
705  
        behavior of the function can be different.
689  
        See @ref string_token::return_string
706  
        See @ref string_token::return_string
690  
        for more information.
707  
        for more information.
691  

708  

692  
        @par Example
709  
        @par Example
693  
        @code
710  
        @code
694  
        assert( url_view( "http://jane%2Ddoe:pass@example.com" ).userinfo() == "jane-doe:pass" );
711  
        assert( url_view( "http://jane%2Ddoe:pass@example.com" ).userinfo() == "jane-doe:pass" );
695  
        @endcode
712  
        @endcode
696  

713  

697  
        @par Complexity
714  
        @par Complexity
698  
        Linear in `this->userinfo().size()`.
715  
        Linear in `this->userinfo().size()`.
699  

716  

700  
        @par Exception Safety
717  
        @par Exception Safety
701  
        Calls to allocate may throw.
718  
        Calls to allocate may throw.
702  

719  

703  
        @return When called with no arguments,
720  
        @return When called with no arguments,
704  
        a value of type `std::string` is
721  
        a value of type `std::string` is
705  
        returned. Otherwise, the return type
722  
        returned. Otherwise, the return type
706  
        and meaning depends on the string token
723  
        and meaning depends on the string token
707  
        passed to the function.
724  
        passed to the function.
708  

725  

709  
        @par BNF
726  
        @par BNF
710  
        @code
727  
        @code
711  
        userinfo    = user [ ":" [ password ] ]
728  
        userinfo    = user [ ":" [ password ] ]
712  

729  

713  
        authority   = [ userinfo "@" ] host [ ":" port ]
730  
        authority   = [ userinfo "@" ] host [ ":" port ]
714  
        @endcode
731  
        @endcode
715  

732  

716  
        @par Specification
733  
        @par Specification
717  
        @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.2.1">3.2.1. User Information (rfc3986)</a>
734  
        @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.2.1">3.2.1. User Information (rfc3986)</a>
718  

735  

719  
        @see
736  
        @see
720  
            @ref has_password,
737  
            @ref has_password,
721  
            @ref has_userinfo,
738  
            @ref has_userinfo,
722  
            @ref encoded_password,
739  
            @ref encoded_password,
723  
            @ref encoded_user,
740  
            @ref encoded_user,
724  
            @ref encoded_userinfo,
741  
            @ref encoded_userinfo,
725  
            @ref password,
742  
            @ref password,
726  
            @ref user.
743  
            @ref user.
727  

744  

728  
        @param token The string token to use.
745  
        @param token The string token to use.
729  
        @return The userinfo as a string.
746  
        @return The userinfo as a string.
730  
    */
747  
    */
731  
    template<BOOST_URL_STRTOK_TPARAM>
748  
    template<BOOST_URL_STRTOK_TPARAM>
732  
    BOOST_URL_STRTOK_RETURN
749  
    BOOST_URL_STRTOK_RETURN
733  
    userinfo(
750  
    userinfo(
734  
        StringToken&& token = {}) const
751  
        StringToken&& token = {}) const
735  
    {
752  
    {
736  
        encoding_opts opt;
753  
        encoding_opts opt;
737  
        opt.space_as_plus = false;
754  
        opt.space_as_plus = false;
738  
        return encoded_userinfo().decode(
755  
        return encoded_userinfo().decode(
739  
            opt, std::forward<StringToken>(token));
756  
            opt, std::forward<StringToken>(token));
740  
    }
757  
    }
741  

758  

742  
    /** Return the userinfo
759  
    /** Return the userinfo
743  

760  

744  
        If present, this function returns a
761  
        If present, this function returns a
745  
        string representing the userinfo (which
762  
        string representing the userinfo (which
746  
        may be empty).
763  
        may be empty).
747  
        Otherwise it returns an empty string.
764  
        Otherwise it returns an empty string.
748  
        The returned string may contain
765  
        The returned string may contain
749  
        percent escapes.
766  
        percent escapes.
750  

767  

751  
        @par Example
768  
        @par Example
752  
        @code
769  
        @code
753  
        assert( url_view( "http://jane%2Ddoe:pass@example.com" ).encoded_userinfo() == "jane%2Ddoe:pass" );
770  
        assert( url_view( "http://jane%2Ddoe:pass@example.com" ).encoded_userinfo() == "jane%2Ddoe:pass" );
754  
        @endcode
771  
        @endcode
755  

772  

756  
        @par Complexity
773  
        @par Complexity
757  
        Constant.
774  
        Constant.
758  

775  

759  
        @par Exception Safety
776  
        @par Exception Safety
760  
        Throws nothing
777  
        Throws nothing
761  

778  

762  
        @par BNF
779  
        @par BNF
763  
        @code
780  
        @code
764  
        userinfo    = user [ ":" [ password ] ]
781  
        userinfo    = user [ ":" [ password ] ]
765  

782  

766  
        authority   = [ userinfo "@" ] host [ ":" port ]
783  
        authority   = [ userinfo "@" ] host [ ":" port ]
767  
        @endcode
784  
        @endcode
768  

785  

769  
        @par Specification
786  
        @par Specification
770  
        @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.2.1">3.2.1. User Information (rfc3986)</a>
787  
        @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.2.1">3.2.1. User Information (rfc3986)</a>
771  

788  

772  
        @see
789  
        @see
773  
            @ref has_password,
790  
            @ref has_password,
774  
            @ref has_userinfo,
791  
            @ref has_userinfo,
775  
            @ref encoded_password,
792  
            @ref encoded_password,
776  
            @ref encoded_user,
793  
            @ref encoded_user,
777  
            @ref password,
794  
            @ref password,
778  
            @ref user,
795  
            @ref user,
779  
            @ref userinfo.
796  
            @ref userinfo.
780  

797  

781  
        @return The userinfo as a string.
798  
        @return The userinfo as a string.
782  
    */
799  
    */
783  
    pct_string_view
800  
    pct_string_view
784  
    encoded_userinfo() const noexcept;
801  
    encoded_userinfo() const noexcept;
785  

802  

786  
    //--------------------------------------------
803  
    //--------------------------------------------
787  

804  

788  
    /** Return the user
805  
    /** Return the user
789  

806  

790  
        If present, this function returns a
807  
        If present, this function returns a
791  
        string representing the user (which
808  
        string representing the user (which
792  
        may be empty).
809  
        may be empty).
793  
        Otherwise it returns an empty string.
810  
        Otherwise it returns an empty string.
794  
        Any percent-escapes in the string are
811  
        Any percent-escapes in the string are
795  
        decoded first.
812  
        decoded first.
796  

813  

797  
        @par Example
814  
        @par Example
798  
        @code
815  
        @code
799  
        assert( url_view( "http://jane%2Ddoe:pass@example.com" ).user() == "jane-doe" );
816  
        assert( url_view( "http://jane%2Ddoe:pass@example.com" ).user() == "jane-doe" );
800  
        @endcode
817  
        @endcode
801  

818  

802  
        @par Complexity
819  
        @par Complexity
803  
        Linear in `this->user().size()`.
820  
        Linear in `this->user().size()`.
804  

821  

805  
        @par Exception Safety
822  
        @par Exception Safety
806  
        Calls to allocate may throw.
823  
        Calls to allocate may throw.
807  

824  

808  
        @par BNF
825  
        @par BNF
809  
        @code
826  
        @code
810  
        userinfo    = user [ ":" [ password ] ]
827  
        userinfo    = user [ ":" [ password ] ]
811  

828  

812  
        user        = *( unreserved / pct-encoded / sub-delims )
829  
        user        = *( unreserved / pct-encoded / sub-delims )
813  
        password    = *( unreserved / pct-encoded / sub-delims / ":" )
830  
        password    = *( unreserved / pct-encoded / sub-delims / ":" )
814  
        @endcode
831  
        @endcode
815  

832  

816  
        @par Specification
833  
        @par Specification
817  
        @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.2.1">3.2.1. User Information (rfc3986)</a>
834  
        @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.2.1">3.2.1. User Information (rfc3986)</a>
818  

835  

819  
        @see
836  
        @see
820  
            @ref has_password,
837  
            @ref has_password,
821  
            @ref has_userinfo,
838  
            @ref has_userinfo,
822  
            @ref encoded_password,
839  
            @ref encoded_password,
823  
            @ref encoded_user,
840  
            @ref encoded_user,
824  
            @ref encoded_userinfo,
841  
            @ref encoded_userinfo,
825  
            @ref password,
842  
            @ref password,
826  
            @ref userinfo.
843  
            @ref userinfo.
827  

844  

828  
        @param token The string token to use.
845  
        @param token The string token to use.
829  
        @return The user as a string.
846  
        @return The user as a string.
830  
    */
847  
    */
831  
    template<BOOST_URL_STRTOK_TPARAM>
848  
    template<BOOST_URL_STRTOK_TPARAM>
832  
    BOOST_URL_STRTOK_RETURN
849  
    BOOST_URL_STRTOK_RETURN
833  
    user(
850  
    user(
834  
        StringToken&& token = {}) const
851  
        StringToken&& token = {}) const
835  
    {
852  
    {
836  
        encoding_opts opt;
853  
        encoding_opts opt;
837  
        opt.space_as_plus = false;
854  
        opt.space_as_plus = false;
838  
        return encoded_user().decode(
855  
        return encoded_user().decode(
839  
            opt, std::forward<StringToken>(token));
856  
            opt, std::forward<StringToken>(token));
840  
    }
857  
    }
841  

858  

842  
    /** Return the user
859  
    /** Return the user
843  

860  

844  
        If present, this function returns a
861  
        If present, this function returns a
845  
        string representing the user (which
862  
        string representing the user (which
846  
        may be empty).
863  
        may be empty).
847  
        Otherwise it returns an empty string.
864  
        Otherwise it returns an empty string.
848  
        The returned string may contain
865  
        The returned string may contain
849  
        percent escapes.
866  
        percent escapes.
850  

867  

851  
        @par Example
868  
        @par Example
852  
        @code
869  
        @code
853  
        assert( url_view( "http://jane%2Ddoe:pass@example.com" ).encoded_user() == "jane%2Ddoe" );
870  
        assert( url_view( "http://jane%2Ddoe:pass@example.com" ).encoded_user() == "jane%2Ddoe" );
854  
        @endcode
871  
        @endcode
855  

872  

856  
        @par Complexity
873  
        @par Complexity
857  
        Constant.
874  
        Constant.
858  

875  

859  
        @par Exception Safety
876  
        @par Exception Safety
860  
        Throws nothing.
877  
        Throws nothing.
861  

878  

862  
        @par BNF
879  
        @par BNF
863  
        @code
880  
        @code
864  
        userinfo    = user [ ":" [ password ] ]
881  
        userinfo    = user [ ":" [ password ] ]
865  

882  

866  
        user        = *( unreserved / pct-encoded / sub-delims )
883  
        user        = *( unreserved / pct-encoded / sub-delims )
867  
        password    = *( unreserved / pct-encoded / sub-delims / ":" )
884  
        password    = *( unreserved / pct-encoded / sub-delims / ":" )
868  
        @endcode
885  
        @endcode
869  

886  

870  
        @par Specification
887  
        @par Specification
871  
        @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.2.1">3.2.1. User Information (rfc3986)</a>
888  
        @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.2.1">3.2.1. User Information (rfc3986)</a>
872  

889  

873  
        @see
890  
        @see
874  
            @ref has_password,
891  
            @ref has_password,
875  
            @ref has_userinfo,
892  
            @ref has_userinfo,
876  
            @ref encoded_password,
893  
            @ref encoded_password,
877  
            @ref encoded_userinfo,
894  
            @ref encoded_userinfo,
878  
            @ref password,
895  
            @ref password,
879  
            @ref user,
896  
            @ref user,
880  
            @ref userinfo.
897  
            @ref userinfo.
881  

898  

882  
        @return The user as a string.
899  
        @return The user as a string.
883  
    */
900  
    */
884  
    pct_string_view
901  
    pct_string_view
885  
    encoded_user() const noexcept;
902  
    encoded_user() const noexcept;
886  

903  

887  
    /** Return the password
904  
    /** Return the password
888  

905  

889  
        If present, this function returns a
906  
        If present, this function returns a
890  
        string representing the password (which
907  
        string representing the password (which
891  
        may be an empty string).
908  
        may be an empty string).
892  
        Otherwise it returns an empty string.
909  
        Otherwise it returns an empty string.
893  
        Any percent-escapes in the string are
910  
        Any percent-escapes in the string are
894  
        decoded first.
911  
        decoded first.
895  

912  

896  
        @par Example
913  
        @par Example
897  
        @code
914  
        @code
898  
        assert( url_view( "http://jane%2Ddoe:pass@example.com" ).password() == "pass" );
915  
        assert( url_view( "http://jane%2Ddoe:pass@example.com" ).password() == "pass" );
899  
        @endcode
916  
        @endcode
900  

917  

901  
        @par Complexity
918  
        @par Complexity
902  
        Linear in `this->password().size()`.
919  
        Linear in `this->password().size()`.
903  

920  

904  
        @par Exception Safety
921  
        @par Exception Safety
905  
        Calls to allocate may throw.
922  
        Calls to allocate may throw.
906  

923  

907  
        @par BNF
924  
        @par BNF
908  
        @code
925  
        @code
909  
        userinfo    = user [ ":" [ password ] ]
926  
        userinfo    = user [ ":" [ password ] ]
910  

927  

911  
        user        = *( unreserved / pct-encoded / sub-delims )
928  
        user        = *( unreserved / pct-encoded / sub-delims )
912  
        password    = *( unreserved / pct-encoded / sub-delims / ":" )
929  
        password    = *( unreserved / pct-encoded / sub-delims / ":" )
913  
        @endcode
930  
        @endcode
914  

931  

915  
        @par Specification
932  
        @par Specification
916  
        @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.2.1">3.2.1. User Information (rfc3986)</a>
933  
        @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.2.1">3.2.1. User Information (rfc3986)</a>
917  

934  

918  
        @see
935  
        @see
919  
            @ref has_password,
936  
            @ref has_password,
920  
            @ref has_userinfo,
937  
            @ref has_userinfo,
921  
            @ref encoded_password,
938  
            @ref encoded_password,
922  
            @ref encoded_user,
939  
            @ref encoded_user,
923  
            @ref encoded_userinfo,
940  
            @ref encoded_userinfo,
924  
            @ref user,
941  
            @ref user,
925  
            @ref userinfo.
942  
            @ref userinfo.
926  

943  

927  
        @param token The string token to use.
944  
        @param token The string token to use.
928  
        @return The password as a string.
945  
        @return The password as a string.
929  
    */
946  
    */
930  
    template<BOOST_URL_STRTOK_TPARAM>
947  
    template<BOOST_URL_STRTOK_TPARAM>
931  
    BOOST_URL_STRTOK_RETURN
948  
    BOOST_URL_STRTOK_RETURN
932  
    password(
949  
    password(
933  
        StringToken&& token = {}) const
950  
        StringToken&& token = {}) const
934  
    {
951  
    {
935  
        encoding_opts opt;
952  
        encoding_opts opt;
936  
        opt.space_as_plus = false;
953  
        opt.space_as_plus = false;
937  
        return encoded_password().decode(
954  
        return encoded_password().decode(
938  
            opt, std::forward<StringToken>(token));
955  
            opt, std::forward<StringToken>(token));
939  
    }
956  
    }
940  

957  

941  
    /** Return the password
958  
    /** Return the password
942  

959  

943  
        This function returns the password portion
960  
        This function returns the password portion
944  
        of the userinfo as a percent-encoded string.
961  
        of the userinfo as a percent-encoded string.
945  

962  

946  
        @par Example
963  
        @par Example
947  
        @code
964  
        @code
948  
        assert( url_view( "http://jane%2Ddoe:pass@example.com" ).encoded_password() == "pass" );
965  
        assert( url_view( "http://jane%2Ddoe:pass@example.com" ).encoded_password() == "pass" );
949  
        @endcode
966  
        @endcode
950  

967  

951  
        @par Complexity
968  
        @par Complexity
952  
        Constant.
969  
        Constant.
953  

970  

954  
        @par Exception Safety
971  
        @par Exception Safety
955  
        Throws nothing.
972  
        Throws nothing.
956  

973  

957  
        @par BNF
974  
        @par BNF
958  
        @code
975  
        @code
959  
        userinfo    = user [ ":" [ password ] ]
976  
        userinfo    = user [ ":" [ password ] ]
960  

977  

961  
        user        = *( unreserved / pct-encoded / sub-delims )
978  
        user        = *( unreserved / pct-encoded / sub-delims )
962  
        password    = *( unreserved / pct-encoded / sub-delims / ":" )
979  
        password    = *( unreserved / pct-encoded / sub-delims / ":" )
963  
        @endcode
980  
        @endcode
964  

981  

965  
        @par Specification
982  
        @par Specification
966  
        @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.2.1">3.2.1. User Information (rfc3986)</a>
983  
        @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.2.1">3.2.1. User Information (rfc3986)</a>
967  

984  

968  
        @see
985  
        @see
969  
            @ref has_password,
986  
            @ref has_password,
970  
            @ref has_userinfo,
987  
            @ref has_userinfo,
971  
            @ref encoded_user,
988  
            @ref encoded_user,
972  
            @ref encoded_userinfo,
989  
            @ref encoded_userinfo,
973  
            @ref password,
990  
            @ref password,
974  
            @ref user,
991  
            @ref user,
975  
            @ref userinfo.
992  
            @ref userinfo.
976  

993  

977  
        @return The password as a string.
994  
        @return The password as a string.
978  
    */
995  
    */
979  
    pct_string_view
996  
    pct_string_view
980  
    encoded_password() const noexcept;
997  
    encoded_password() const noexcept;
981  

998  

982  
    //--------------------------------------------
999  
    //--------------------------------------------
983  
    //
1000  
    //
984  
    // Host
1001  
    // Host
985  
    //
1002  
    //
986  
    //--------------------------------------------
1003  
    //--------------------------------------------
987  

1004  

988  
    /** Return the host type
1005  
    /** Return the host type
989  

1006  

990  
        This function returns one of the
1007  
        This function returns one of the
991  
        following constants representing the
1008  
        following constants representing the
992  
        type of host present.
1009  
        type of host present.
993  

1010  

994  
        @li @ref host_type::ipv4
1011  
        @li @ref host_type::ipv4
995  
        @li @ref host_type::ipv6
1012  
        @li @ref host_type::ipv6
996  
        @li @ref host_type::ipvfuture
1013  
        @li @ref host_type::ipvfuture
997  
        @li @ref host_type::name
1014  
        @li @ref host_type::name
998  
        @li @ref host_type::none
1015  
        @li @ref host_type::none
999  

1016  

1000  
        When @ref has_authority is false, the
1017  
        When @ref has_authority is false, the
1001  
        host type is @ref host_type::none.
1018  
        host type is @ref host_type::none.
1002  

1019  

1003  
        @par Example
1020  
        @par Example
1004  
        @code
1021  
        @code
1005  
        assert( url_view( "https://192.168.0.1/local.htm" ).host_type() == host_type::ipv4 );
1022  
        assert( url_view( "https://192.168.0.1/local.htm" ).host_type() == host_type::ipv4 );
1006  
        @endcode
1023  
        @endcode
1007  

1024  

1008  
        @par Complexity
1025  
        @par Complexity
1009  
        Constant.
1026  
        Constant.
1010  

1027  

1011  
        @par Exception Safety
1028  
        @par Exception Safety
1012  
        Throws nothing.
1029  
        Throws nothing.
1013  

1030  

1014  
        @par Specification
1031  
        @par Specification
1015  
        @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.2.2">3.2.2. Host (rfc3986)</a>
1032  
        @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.2.2">3.2.2. Host (rfc3986)</a>
1016  

1033  

1017  
        @return The type of host present.
1034  
        @return The type of host present.
1018  
    */
1035  
    */
1019  
    urls::host_type
1036  
    urls::host_type
1020  
    host_type() const noexcept
1037  
    host_type() const noexcept
1021  
    {
1038  
    {
1022 -
        return pi_->host_type_;
1039 +
        return impl().host_type_;
1023  
    }
1040  
    }
1024  

1041  

1025  
    /** Return the host
1042  
    /** Return the host
1026  

1043  

1027  
        This function returns the host portion
1044  
        This function returns the host portion
1028  
        of the authority as a string, or the
1045  
        of the authority as a string, or the
1029  
        empty string if there is no authority.
1046  
        empty string if there is no authority.
1030  
        Any percent-escapes in the string are
1047  
        Any percent-escapes in the string are
1031  
        decoded first.
1048  
        decoded first.
1032  

1049  

1033  
        @par Example
1050  
        @par Example
1034  
        @code
1051  
        @code
1035  
        assert( url_view( "https://www%2droot.example.com/" ).host() == "www-root.example.com" );
1052  
        assert( url_view( "https://www%2droot.example.com/" ).host() == "www-root.example.com" );
1036  
        @endcode
1053  
        @endcode
1037  

1054  

1038  
        @par Complexity
1055  
        @par Complexity
1039  
        Linear in `this->host().size()`.
1056  
        Linear in `this->host().size()`.
1040  

1057  

1041  
        @par Exception Safety
1058  
        @par Exception Safety
1042  
        Calls to allocate may throw.
1059  
        Calls to allocate may throw.
1043  

1060  

1044  
        @par BNF
1061  
        @par BNF
1045  
        @code
1062  
        @code
1046  
        host        = IP-literal / IPv4address / reg-name
1063  
        host        = IP-literal / IPv4address / reg-name
1047  

1064  

1048  
        IP-literal  = "[" ( IPv6address / IPvFuture  ) "]"
1065  
        IP-literal  = "[" ( IPv6address / IPvFuture  ) "]"
1049  

1066  

1050  
        reg-name    = *( unreserved / pct-encoded / "-" / ".")
1067  
        reg-name    = *( unreserved / pct-encoded / "-" / ".")
1051  
        @endcode
1068  
        @endcode
1052  

1069  

1053  
        @par Specification
1070  
        @par Specification
1054  
        @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.2.2">3.2.2. Host (rfc3986)</a>
1071  
        @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.2.2">3.2.2. Host (rfc3986)</a>
1055  

1072  

1056  
        @param token A string token customization
1073  
        @param token A string token customization
1057  
        @return The host address as a string.
1074  
        @return The host address as a string.
1058  
    */
1075  
    */
1059  
    template<BOOST_URL_STRTOK_TPARAM>
1076  
    template<BOOST_URL_STRTOK_TPARAM>
1060  
    BOOST_URL_STRTOK_RETURN
1077  
    BOOST_URL_STRTOK_RETURN
1061  
    host(
1078  
    host(
1062  
        StringToken&& token = {}) const
1079  
        StringToken&& token = {}) const
1063  
    {
1080  
    {
1064  
        encoding_opts opt;
1081  
        encoding_opts opt;
1065  
        opt.space_as_plus = false;
1082  
        opt.space_as_plus = false;
1066  
        return encoded_host().decode(
1083  
        return encoded_host().decode(
1067  
            opt, std::forward<StringToken>(token));
1084  
            opt, std::forward<StringToken>(token));
1068  
    }
1085  
    }
1069  

1086  

1070  
    /** Return the host
1087  
    /** Return the host
1071  

1088  

1072  
        This function returns the host portion
1089  
        This function returns the host portion
1073  
        of the authority as a string, or the
1090  
        of the authority as a string, or the
1074  
        empty string if there is no authority.
1091  
        empty string if there is no authority.
1075  
        The returned string may contain
1092  
        The returned string may contain
1076  
        percent escapes.
1093  
        percent escapes.
1077  

1094  

1078  
        @par Example
1095  
        @par Example
1079  
        @code
1096  
        @code
1080  
        assert( url_view( "https://www%2droot.example.com/" ).encoded_host() == "www%2droot.example.com" );
1097  
        assert( url_view( "https://www%2droot.example.com/" ).encoded_host() == "www%2droot.example.com" );
1081  
        @endcode
1098  
        @endcode
1082  

1099  

1083  
        @par Complexity
1100  
        @par Complexity
1084  
        Constant.
1101  
        Constant.
1085  

1102  

1086  
        @par Exception Safety
1103  
        @par Exception Safety
1087  
        Throws nothing.
1104  
        Throws nothing.
1088  

1105  

1089  
        @par BNF
1106  
        @par BNF
1090  
        @code
1107  
        @code
1091  
        host        = IP-literal / IPv4address / reg-name
1108  
        host        = IP-literal / IPv4address / reg-name
1092  

1109  

1093  
        IP-literal  = "[" ( IPv6address / IPvFuture  ) "]"
1110  
        IP-literal  = "[" ( IPv6address / IPvFuture  ) "]"
1094  

1111  

1095  
        reg-name    = *( unreserved / pct-encoded / "-" / ".")
1112  
        reg-name    = *( unreserved / pct-encoded / "-" / ".")
1096  
        @endcode
1113  
        @endcode
1097  

1114  

1098  
        @par Specification
1115  
        @par Specification
1099  
        @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.2.2">3.2.2. Host (rfc3986)</a>
1116  
        @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.2.2">3.2.2. Host (rfc3986)</a>
1100  

1117  

1101  
        @return The host address as a string.
1118  
        @return The host address as a string.
1102  
    */
1119  
    */
1103  
    pct_string_view
1120  
    pct_string_view
1104  
    encoded_host() const noexcept;
1121  
    encoded_host() const noexcept;
1105  

1122  

1106  
    /** Return the host
1123  
    /** Return the host
1107  

1124  

1108  
        The value returned by this function
1125  
        The value returned by this function
1109  
        depends on the type of host returned
1126  
        depends on the type of host returned
1110  
        from the function @ref host_type.
1127  
        from the function @ref host_type.
1111  

1128  

1112  
        @li If the type is @ref host_type::ipv4,
1129  
        @li If the type is @ref host_type::ipv4,
1113  
        then the IPv4 address string is returned.
1130  
        then the IPv4 address string is returned.
1114  

1131  

1115  
        @li If the type is @ref host_type::ipv6,
1132  
        @li If the type is @ref host_type::ipv6,
1116  
        then the IPv6 address string is returned,
1133  
        then the IPv6 address string is returned,
1117  
        without any enclosing brackets.
1134  
        without any enclosing brackets.
1118  

1135  

1119  
        @li If the type is @ref host_type::ipvfuture,
1136  
        @li If the type is @ref host_type::ipvfuture,
1120  
        then the IPvFuture address string is returned,
1137  
        then the IPvFuture address string is returned,
1121  
        without any enclosing brackets.
1138  
        without any enclosing brackets.
1122  

1139  

1123  
        @li If the type is @ref host_type::name,
1140  
        @li If the type is @ref host_type::name,
1124  
        then the host name string is returned.
1141  
        then the host name string is returned.
1125  
        Any percent-escapes in the string are
1142  
        Any percent-escapes in the string are
1126  
        decoded first.
1143  
        decoded first.
1127  

1144  

1128  
        @li If the type is @ref host_type::none,
1145  
        @li If the type is @ref host_type::none,
1129  
        then an empty string is returned.
1146  
        then an empty string is returned.
1130  

1147  

1131  
        @par Example
1148  
        @par Example
1132  
        @code
1149  
        @code
1133  
        assert( url_view( "https://[1::6:c0a8:1]/" ).host_address() == "1::6:c0a8:1" );
1150  
        assert( url_view( "https://[1::6:c0a8:1]/" ).host_address() == "1::6:c0a8:1" );
1134  
        @endcode
1151  
        @endcode
1135  

1152  

1136  
        @par Complexity
1153  
        @par Complexity
1137  
        Linear in `this->host_address().size()`.
1154  
        Linear in `this->host_address().size()`.
1138  

1155  

1139  
        @par Exception Safety
1156  
        @par Exception Safety
1140  
        Calls to allocate may throw.
1157  
        Calls to allocate may throw.
1141  

1158  

1142  
        @par BNF
1159  
        @par BNF
1143  
        @code
1160  
        @code
1144  
        host        = IP-literal / IPv4address / reg-name
1161  
        host        = IP-literal / IPv4address / reg-name
1145  

1162  

1146  
        IP-literal  = "[" ( IPv6address / IPvFuture  ) "]"
1163  
        IP-literal  = "[" ( IPv6address / IPvFuture  ) "]"
1147  

1164  

1148  
        reg-name    = *( unreserved / pct-encoded / "-" / ".")
1165  
        reg-name    = *( unreserved / pct-encoded / "-" / ".")
1149  
        @endcode
1166  
        @endcode
1150  

1167  

1151  
        @par Specification
1168  
        @par Specification
1152  
        @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.2.2">3.2.2. Host (rfc3986)</a>
1169  
        @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.2.2">3.2.2. Host (rfc3986)</a>
1153  

1170  

1154  
        @param token A string token customization
1171  
        @param token A string token customization
1155  
        @return The host address as a string.
1172  
        @return The host address as a string.
1156  
    */
1173  
    */
1157  
    template<BOOST_URL_STRTOK_TPARAM>
1174  
    template<BOOST_URL_STRTOK_TPARAM>
1158  
    BOOST_URL_STRTOK_RETURN
1175  
    BOOST_URL_STRTOK_RETURN
1159  
    host_address(
1176  
    host_address(
1160  
        StringToken&& token = {}) const
1177  
        StringToken&& token = {}) const
1161  
    {
1178  
    {
1162  
        encoding_opts opt;
1179  
        encoding_opts opt;
1163  
        opt.space_as_plus = false;
1180  
        opt.space_as_plus = false;
1164  
        return encoded_host_address().decode(
1181  
        return encoded_host_address().decode(
1165  
            opt, std::forward<StringToken>(token));
1182  
            opt, std::forward<StringToken>(token));
1166  
    }
1183  
    }
1167  

1184  

1168  
    /** Return the host
1185  
    /** Return the host
1169  

1186  

1170  
        The value returned by this function
1187  
        The value returned by this function
1171  
        depends on the type of host returned
1188  
        depends on the type of host returned
1172  
        from the function @ref host_type.
1189  
        from the function @ref host_type.
1173  

1190  

1174  
        @li If the type is @ref host_type::ipv4,
1191  
        @li If the type is @ref host_type::ipv4,
1175  
        then the IPv4 address string is returned.
1192  
        then the IPv4 address string is returned.
1176  

1193  

1177  
        @li If the type is @ref host_type::ipv6,
1194  
        @li If the type is @ref host_type::ipv6,
1178  
        then the IPv6 address string is returned,
1195  
        then the IPv6 address string is returned,
1179  
        without any enclosing brackets.
1196  
        without any enclosing brackets.
1180  

1197  

1181  
        @li If the type is @ref host_type::ipvfuture,
1198  
        @li If the type is @ref host_type::ipvfuture,
1182  
        then the IPvFuture address string is returned,
1199  
        then the IPvFuture address string is returned,
1183  
        without any enclosing brackets.
1200  
        without any enclosing brackets.
1184  

1201  

1185  
        @li If the type is @ref host_type::name,
1202  
        @li If the type is @ref host_type::name,
1186  
        then the host name string is returned.
1203  
        then the host name string is returned.
1187  
        Any percent-escapes in the string are
1204  
        Any percent-escapes in the string are
1188  
        decoded first.
1205  
        decoded first.
1189  

1206  

1190  
        @li If the type is @ref host_type::none,
1207  
        @li If the type is @ref host_type::none,
1191  
        then an empty string is returned.
1208  
        then an empty string is returned.
1192  
        The returned string may contain
1209  
        The returned string may contain
1193  
        percent escapes.
1210  
        percent escapes.
1194  

1211  

1195  
        @par Example
1212  
        @par Example
1196  
        @code
1213  
        @code
1197  
        assert( url_view( "https://www%2droot.example.com/" ).encoded_host_address() == "www%2droot.example.com" );
1214  
        assert( url_view( "https://www%2droot.example.com/" ).encoded_host_address() == "www%2droot.example.com" );
1198  
        @endcode
1215  
        @endcode
1199  

1216  

1200  
        @par Complexity
1217  
        @par Complexity
1201  
        Constant.
1218  
        Constant.
1202  

1219  

1203  
        @par Exception Safety
1220  
        @par Exception Safety
1204  
        Throws nothing.
1221  
        Throws nothing.
1205  

1222  

1206  
        @par BNF
1223  
        @par BNF
1207  
        @code
1224  
        @code
1208  
        host        = IP-literal / IPv4address / reg-name
1225  
        host        = IP-literal / IPv4address / reg-name
1209  

1226  

1210  
        IP-literal  = "[" ( IPv6address / IPvFuture  ) "]"
1227  
        IP-literal  = "[" ( IPv6address / IPvFuture  ) "]"
1211  

1228  

1212  
        reg-name    = *( unreserved / pct-encoded / "-" / ".")
1229  
        reg-name    = *( unreserved / pct-encoded / "-" / ".")
1213  
        @endcode
1230  
        @endcode
1214  

1231  

1215  
        @par Specification
1232  
        @par Specification
1216  
        @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.2.2">3.2.2. Host (rfc3986)</a>
1233  
        @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.2.2">3.2.2. Host (rfc3986)</a>
1217  

1234  

1218  
        @return The host address as a string.
1235  
        @return The host address as a string.
1219  
    */
1236  
    */
1220  
    pct_string_view
1237  
    pct_string_view
1221  
    encoded_host_address() const noexcept;
1238  
    encoded_host_address() const noexcept;
1222  

1239  

1223  
    /** Return the host IPv4 address
1240  
    /** Return the host IPv4 address
1224  

1241  

1225  
        If the host type is @ref host_type::ipv4,
1242  
        If the host type is @ref host_type::ipv4,
1226  
        this function returns the address as
1243  
        this function returns the address as
1227  
        a value of type @ref ipv4_address.
1244  
        a value of type @ref ipv4_address.
1228  
        Otherwise, if the host type is not an IPv4
1245  
        Otherwise, if the host type is not an IPv4
1229  
        address, it returns a default-constructed
1246  
        address, it returns a default-constructed
1230  
        value which is equal to the unspecified
1247  
        value which is equal to the unspecified
1231  
        address "0.0.0.0".
1248  
        address "0.0.0.0".
1232  

1249  

1233  
        @par Example
1250  
        @par Example
1234  
        @code
1251  
        @code
1235  
        assert( url_view( "http://127.0.0.1/index.htm?user=win95" ).host_ipv4_address() == ipv4_address( "127.0.0.1" ) );
1252  
        assert( url_view( "http://127.0.0.1/index.htm?user=win95" ).host_ipv4_address() == ipv4_address( "127.0.0.1" ) );
1236  
        @endcode
1253  
        @endcode
1237  

1254  

1238  
        @par Complexity
1255  
        @par Complexity
1239  
        Constant.
1256  
        Constant.
1240  

1257  

1241  
        @par Exception Safety
1258  
        @par Exception Safety
1242  
        Throws nothing.
1259  
        Throws nothing.
1243  

1260  

1244  
        @par BNF
1261  
        @par BNF
1245  
        @code
1262  
        @code
1246  
        IPv4address = dec-octet "." dec-octet "." dec-octet "." dec-octet
1263  
        IPv4address = dec-octet "." dec-octet "." dec-octet "." dec-octet
1247  

1264  

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

1271  

1255  
        @par Specification
1272  
        @par Specification
1256  
        @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.2.2">3.2.2. Host (rfc3986)</a>
1273  
        @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.2.2">3.2.2. Host (rfc3986)</a>
1257  

1274  

1258  
        @return The IPv4 address as a value of type @ref ipv4_address.
1275  
        @return The IPv4 address as a value of type @ref ipv4_address.
1259  
    */
1276  
    */
1260  
    ipv4_address
1277  
    ipv4_address
1261  
    host_ipv4_address() const noexcept;
1278  
    host_ipv4_address() const noexcept;
1262  

1279  

1263  
    /** Return the host IPv6 address
1280  
    /** Return the host IPv6 address
1264  

1281  

1265  
        If the host type is @ref host_type::ipv6,
1282  
        If the host type is @ref host_type::ipv6,
1266  
        this function returns the address as
1283  
        this function returns the address as
1267  
        a value of type @ref ipv6_address.
1284  
        a value of type @ref ipv6_address.
1268  
        Otherwise, if the host type is not an IPv6
1285  
        Otherwise, if the host type is not an IPv6
1269  
        address, it returns a default-constructed
1286  
        address, it returns a default-constructed
1270  
        value which is equal to the unspecified
1287  
        value which is equal to the unspecified
1271  
        address "0:0:0:0:0:0:0:0".
1288  
        address "0:0:0:0:0:0:0:0".
1272  

1289  

1273  
        @par Example
1290  
        @par Example
1274  
        @code
1291  
        @code
1275  
        assert( url_view( "ftp://[::1]/" ).host_ipv6_address() == ipv6_address( "::1" ) );
1292  
        assert( url_view( "ftp://[::1]/" ).host_ipv6_address() == ipv6_address( "::1" ) );
1276  
        @endcode
1293  
        @endcode
1277  

1294  

1278  
        @par Complexity
1295  
        @par Complexity
1279  
        Constant.
1296  
        Constant.
1280  

1297  

1281  
        @par Exception Safety
1298  
        @par Exception Safety
1282  
        Throws nothing.
1299  
        Throws nothing.
1283  

1300  

1284  
        @par BNF
1301  
        @par BNF
1285  
        @code
1302  
        @code
1286  
        IPv6address =                            6( h16 ":" ) ls32
1303  
        IPv6address =                            6( h16 ":" ) ls32
1287  
                    /                       "::" 5( h16 ":" ) ls32
1304  
                    /                       "::" 5( h16 ":" ) ls32
1288  
                    / [               h16 ] "::" 4( h16 ":" ) ls32
1305  
                    / [               h16 ] "::" 4( h16 ":" ) ls32
1289  
                    / [ *1( h16 ":" ) h16 ] "::" 3( h16 ":" ) ls32
1306  
                    / [ *1( h16 ":" ) h16 ] "::" 3( h16 ":" ) ls32
1290  
                    / [ *2( h16 ":" ) h16 ] "::" 2( h16 ":" ) ls32
1307  
                    / [ *2( h16 ":" ) h16 ] "::" 2( h16 ":" ) ls32
1291  
                    / [ *3( h16 ":" ) h16 ] "::"    h16 ":"   ls32
1308  
                    / [ *3( h16 ":" ) h16 ] "::"    h16 ":"   ls32
1292  
                    / [ *4( h16 ":" ) h16 ] "::"              ls32
1309  
                    / [ *4( h16 ":" ) h16 ] "::"              ls32
1293  
                    / [ *5( h16 ":" ) h16 ] "::"              h16
1310  
                    / [ *5( h16 ":" ) h16 ] "::"              h16
1294  
                    / [ *6( h16 ":" ) h16 ] "::"
1311  
                    / [ *6( h16 ":" ) h16 ] "::"
1295  

1312  

1296  
        ls32        = ( h16 ":" h16 ) / IPv4address
1313  
        ls32        = ( h16 ":" h16 ) / IPv4address
1297  
                    ; least-significant 32 bits of address
1314  
                    ; least-significant 32 bits of address
1298  

1315  

1299  
        h16         = 1*4HEXDIG
1316  
        h16         = 1*4HEXDIG
1300  
                    ; 16 bits of address represented in hexadecimal
1317  
                    ; 16 bits of address represented in hexadecimal
1301  
        @endcode
1318  
        @endcode
1302  

1319  

1303  
        @par Specification
1320  
        @par Specification
1304  
        @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.2.2">3.2.2. Host (rfc3986)</a>
1321  
        @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.2.2">3.2.2. Host (rfc3986)</a>
1305  

1322  

1306  
        @return The IPv6 address as a value of type @ref ipv6_address.
1323  
        @return The IPv6 address as a value of type @ref ipv6_address.
1307  
    */
1324  
    */
1308  
    ipv6_address
1325  
    ipv6_address
1309  
    host_ipv6_address() const noexcept;
1326  
    host_ipv6_address() const noexcept;
1310  

1327  

1311  
    /** Return the host IPvFuture address
1328  
    /** Return the host IPvFuture address
1312  

1329  

1313  
        If the host type is @ref host_type::ipvfuture,
1330  
        If the host type is @ref host_type::ipvfuture,
1314  
        this function returns the address as
1331  
        this function returns the address as
1315  
        a string.
1332  
        a string.
1316  
        Otherwise, if the host type is not an
1333  
        Otherwise, if the host type is not an
1317  
        IPvFuture address, it returns an
1334  
        IPvFuture address, it returns an
1318  
        empty string.
1335  
        empty string.
1319  

1336  

1320  
        @par Example
1337  
        @par Example
1321  
        @code
1338  
        @code
1322  
        assert( url_view( "http://[v1fe.d:9]/index.htm" ).host_ipvfuture() == "v1fe.d:9" );
1339  
        assert( url_view( "http://[v1fe.d:9]/index.htm" ).host_ipvfuture() == "v1fe.d:9" );
1323  
        @endcode
1340  
        @endcode
1324  

1341  

1325  
        @par Complexity
1342  
        @par Complexity
1326  
        Constant.
1343  
        Constant.
1327  

1344  

1328  
        @par Exception Safety
1345  
        @par Exception Safety
1329  
        Throws nothing.
1346  
        Throws nothing.
1330  

1347  

1331  
        @par BNF
1348  
        @par BNF
1332  
        @code
1349  
        @code
1333  
        IPvFuture  = "v" 1*HEXDIG "." 1*( unreserved / sub-delims / ":" )
1350  
        IPvFuture  = "v" 1*HEXDIG "." 1*( unreserved / sub-delims / ":" )
1334  
        @endcode
1351  
        @endcode
1335  

1352  

1336  
        @par Specification
1353  
        @par Specification
1337  
        @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.2.2">3.2.2. Host (rfc3986)</a>
1354  
        @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.2.2">3.2.2. Host (rfc3986)</a>
1338  

1355  

1339  
        @return The IPvFuture address as a string.
1356  
        @return The IPvFuture address as a string.
1340  
    */
1357  
    */
1341  
    core::string_view
1358  
    core::string_view
1342  
    host_ipvfuture() const noexcept;
1359  
    host_ipvfuture() const noexcept;
1343  

1360  

1344  
    /** Return the host name
1361  
    /** Return the host name
1345  

1362  

1346  
        If the host type is @ref host_type::name,
1363  
        If the host type is @ref host_type::name,
1347  
        this function returns the name as
1364  
        this function returns the name as
1348  
        a string. Otherwise an empty string is returned.
1365  
        a string. Otherwise an empty string is returned.
1349  
        Any percent-escapes in the string are
1366  
        Any percent-escapes in the string are
1350  
        decoded first.
1367  
        decoded first.
1351  

1368  

1352  
        @par Example
1369  
        @par Example
1353  
        @code
1370  
        @code
1354  
        assert( url_view( "https://www%2droot.example.com/" ).host_name() == "www-root.example.com" );
1371  
        assert( url_view( "https://www%2droot.example.com/" ).host_name() == "www-root.example.com" );
1355  
        @endcode
1372  
        @endcode
1356  

1373  

1357  
        @par Complexity
1374  
        @par Complexity
1358  
        Linear in `this->host_name().size()`.
1375  
        Linear in `this->host_name().size()`.
1359  

1376  

1360  
        @par Exception Safety
1377  
        @par Exception Safety
1361  
        Calls to allocate may throw.
1378  
        Calls to allocate may throw.
1362  

1379  

1363  
        @par BNF
1380  
        @par BNF
1364  
        @code
1381  
        @code
1365  
        host        = IP-literal / IPv4address / reg-name
1382  
        host        = IP-literal / IPv4address / reg-name
1366  

1383  

1367  
        IP-literal  = "[" ( IPv6address / IPvFuture  ) "]"
1384  
        IP-literal  = "[" ( IPv6address / IPvFuture  ) "]"
1368  

1385  

1369  
        reg-name    = *( unreserved / pct-encoded / "-" / ".")
1386  
        reg-name    = *( unreserved / pct-encoded / "-" / ".")
1370  
        @endcode
1387  
        @endcode
1371  

1388  

1372  
        @par Specification
1389  
        @par Specification
1373  
        @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.2.2">3.2.2. Host (rfc3986)</a>
1390  
        @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.2.2">3.2.2. Host (rfc3986)</a>
1374  

1391  

1375  
        @param token A string token customization.
1392  
        @param token A string token customization.
1376  
        @return The host name as a string.
1393  
        @return The host name as a string.
1377  
    */
1394  
    */
1378  
    template<BOOST_URL_STRTOK_TPARAM>
1395  
    template<BOOST_URL_STRTOK_TPARAM>
1379  
    BOOST_URL_STRTOK_RETURN
1396  
    BOOST_URL_STRTOK_RETURN
1380  
    host_name(
1397  
    host_name(
1381  
        StringToken&& token = {}) const
1398  
        StringToken&& token = {}) const
1382  
    {
1399  
    {
1383  
        encoding_opts opt;
1400  
        encoding_opts opt;
1384  
        opt.space_as_plus = false;
1401  
        opt.space_as_plus = false;
1385  
        return encoded_host_name().decode(
1402  
        return encoded_host_name().decode(
1386  
            opt, std::forward<StringToken>(token));
1403  
            opt, std::forward<StringToken>(token));
1387  
    }
1404  
    }
1388  

1405  

1389  
    /** Return the host name
1406  
    /** Return the host name
1390  

1407  

1391  
        If the host type is @ref host_type::name,
1408  
        If the host type is @ref host_type::name,
1392  
        this function returns the name as
1409  
        this function returns the name as
1393  
        a string.
1410  
        a string.
1394  
        Otherwise, if the host type is not an
1411  
        Otherwise, if the host type is not an
1395  
        name, it returns an empty string.
1412  
        name, it returns an empty string.
1396  
        The returned string may contain
1413  
        The returned string may contain
1397  
        percent escapes.
1414  
        percent escapes.
1398  

1415  

1399  
        @par Example
1416  
        @par Example
1400  
        @code
1417  
        @code
1401  
        assert( url_view( "https://www%2droot.example.com/" ).encoded_host_name() == "www%2droot.example.com" );
1418  
        assert( url_view( "https://www%2droot.example.com/" ).encoded_host_name() == "www%2droot.example.com" );
1402  
        @endcode
1419  
        @endcode
1403  

1420  

1404  
        @par Complexity
1421  
        @par Complexity
1405  
        Constant.
1422  
        Constant.
1406  

1423  

1407  
        @par Exception Safety
1424  
        @par Exception Safety
1408  
        Throws nothing.
1425  
        Throws nothing.
1409  

1426  

1410  
        @par BNF
1427  
        @par BNF
1411  
        @code
1428  
        @code
1412  
        host        = IP-literal / IPv4address / reg-name
1429  
        host        = IP-literal / IPv4address / reg-name
1413  

1430  

1414  
        IP-literal  = "[" ( IPv6address / IPvFuture  ) "]"
1431  
        IP-literal  = "[" ( IPv6address / IPvFuture  ) "]"
1415  

1432  

1416  
        reg-name    = *( unreserved / pct-encoded / "-" / ".")
1433  
        reg-name    = *( unreserved / pct-encoded / "-" / ".")
1417  
        @endcode
1434  
        @endcode
1418  

1435  

1419  
        @par Specification
1436  
        @par Specification
1420  
        @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.2.2">3.2.2. Host (rfc3986)</a>
1437  
        @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.2.2">3.2.2. Host (rfc3986)</a>
1421  

1438  

1422  
        @return The host name as a percent-encoded string.
1439  
        @return The host name as a percent-encoded string.
1423  
    */
1440  
    */
1424  
    pct_string_view
1441  
    pct_string_view
1425  
    encoded_host_name() const noexcept;
1442  
    encoded_host_name() const noexcept;
1426  

1443  

1427  
    /** Return the IPv6 Zone ID
1444  
    /** Return the IPv6 Zone ID
1428  

1445  

1429  
        If the host type is @ref host_type::ipv6,
1446  
        If the host type is @ref host_type::ipv6,
1430  
        this function returns the Zone ID as
1447  
        this function returns the Zone ID as
1431  
        a string. Otherwise an empty string is returned.
1448  
        a string. Otherwise an empty string is returned.
1432  
        Any percent-escapes in the string are
1449  
        Any percent-escapes in the string are
1433  
        decoded first.
1450  
        decoded first.
1434  

1451  

1435  
        @par Example
1452  
        @par Example
1436  
        @code
1453  
        @code
1437  
        assert( url_view( "http://[fe80::1%25eth0]/" ).zone_id() == "eth0" );
1454  
        assert( url_view( "http://[fe80::1%25eth0]/" ).zone_id() == "eth0" );
1438  
        @endcode
1455  
        @endcode
1439  

1456  

1440  
        @par Complexity
1457  
        @par Complexity
1441  
        Linear in `this->encoded_zone_id().size()`.
1458  
        Linear in `this->encoded_zone_id().size()`.
1442  

1459  

1443  
        @par Exception Safety
1460  
        @par Exception Safety
1444  
        Calls to allocate may throw.
1461  
        Calls to allocate may throw.
1445  

1462  

1446  
        @par BNF
1463  
        @par BNF
1447  
        @code
1464  
        @code
1448  
        host        = IP-literal / IPv4address / reg-name
1465  
        host        = IP-literal / IPv4address / reg-name
1449  

1466  

1450  
        IP-literal = "[" ( IPv6address / IPv6addrz / IPvFuture  ) "]"
1467  
        IP-literal = "[" ( IPv6address / IPv6addrz / IPvFuture  ) "]"
1451  

1468  

1452  
        ZoneID = 1*( unreserved / pct-encoded )
1469  
        ZoneID = 1*( unreserved / pct-encoded )
1453  

1470  

1454  
        IPv6addrz = IPv6address "%25" ZoneID
1471  
        IPv6addrz = IPv6address "%25" ZoneID
1455  
        @endcode
1472  
        @endcode
1456  

1473  

1457  
        @par Specification
1474  
        @par Specification
1458  
        @li <a href="https://datatracker.ietf.org/doc/html/rfc6874">Representing IPv6 Zone Identifiers in Address Literals and Uniform Resource Identifiers</a>
1475  
        @li <a href="https://datatracker.ietf.org/doc/html/rfc6874">Representing IPv6 Zone Identifiers in Address Literals and Uniform Resource Identifiers</a>
1459  

1476  

1460  
        @param token A string token customization.
1477  
        @param token A string token customization.
1461  
        @return The Zone ID as a string.
1478  
        @return The Zone ID as a string.
1462  
    */
1479  
    */
1463  
    template<BOOST_URL_STRTOK_TPARAM>
1480  
    template<BOOST_URL_STRTOK_TPARAM>
1464  
    BOOST_URL_STRTOK_RETURN
1481  
    BOOST_URL_STRTOK_RETURN
1465  
    zone_id(
1482  
    zone_id(
1466  
        StringToken&& token = {}) const
1483  
        StringToken&& token = {}) const
1467  
    {
1484  
    {
1468  
        encoding_opts opt;
1485  
        encoding_opts opt;
1469  
        opt.space_as_plus = false;
1486  
        opt.space_as_plus = false;
1470  
        return encoded_zone_id().decode(
1487  
        return encoded_zone_id().decode(
1471  
            opt, std::forward<StringToken>(token));
1488  
            opt, std::forward<StringToken>(token));
1472  
    }
1489  
    }
1473  

1490  

1474  
    /** Return the IPv6 Zone ID
1491  
    /** Return the IPv6 Zone ID
1475  

1492  

1476  
        If the host type is @ref host_type::ipv6,
1493  
        If the host type is @ref host_type::ipv6,
1477  
        this function returns the Zone ID as
1494  
        this function returns the Zone ID as
1478  
        a string. Otherwise an empty string is returned.
1495  
        a string. Otherwise an empty string is returned.
1479  
        The returned string may contain
1496  
        The returned string may contain
1480  
        percent escapes.
1497  
        percent escapes.
1481  

1498  

1482  
        @par Example
1499  
        @par Example
1483  
        @code
1500  
        @code
1484  
        assert( url_view( "http://[fe80::1%25eth0]/" ).encoded_zone_id() == "eth0" );
1501  
        assert( url_view( "http://[fe80::1%25eth0]/" ).encoded_zone_id() == "eth0" );
1485  
        @endcode
1502  
        @endcode
1486  

1503  

1487  
        @par Complexity
1504  
        @par Complexity
1488  
        Constant.
1505  
        Constant.
1489  

1506  

1490  
        @par Exception Safety
1507  
        @par Exception Safety
1491  
        Throws nothing.
1508  
        Throws nothing.
1492  

1509  

1493  
        @par BNF
1510  
        @par BNF
1494  
        @code
1511  
        @code
1495  
        host        = IP-literal / IPv4address / reg-name
1512  
        host        = IP-literal / IPv4address / reg-name
1496  

1513  

1497  
        IP-literal = "[" ( IPv6address / IPv6addrz / IPvFuture  ) "]"
1514  
        IP-literal = "[" ( IPv6address / IPv6addrz / IPvFuture  ) "]"
1498  

1515  

1499  
        ZoneID = 1*( unreserved / pct-encoded )
1516  
        ZoneID = 1*( unreserved / pct-encoded )
1500  

1517  

1501  
        IPv6addrz = IPv6address "%25" ZoneID
1518  
        IPv6addrz = IPv6address "%25" ZoneID
1502  
        @endcode
1519  
        @endcode
1503  

1520  

1504  
        @par Specification
1521  
        @par Specification
1505  
        @li <a href="https://datatracker.ietf.org/doc/html/rfc6874">Representing IPv6 Zone Identifiers in Address Literals and Uniform Resource Identifiers</a>
1522  
        @li <a href="https://datatracker.ietf.org/doc/html/rfc6874">Representing IPv6 Zone Identifiers in Address Literals and Uniform Resource Identifiers</a>
1506  

1523  

1507  
        @return The Zone ID as a percent-encoded string.
1524  
        @return The Zone ID as a percent-encoded string.
1508  
    */
1525  
    */
1509  
    pct_string_view
1526  
    pct_string_view
1510  
    encoded_zone_id() const noexcept;
1527  
    encoded_zone_id() const noexcept;
1511  

1528  

1512  
    //--------------------------------------------
1529  
    //--------------------------------------------
1513  
    //
1530  
    //
1514  
    // Port
1531  
    // Port
1515  
    //
1532  
    //
1516  
    //--------------------------------------------
1533  
    //--------------------------------------------
1517  

1534  

1518  
    /** Return true if a port is present
1535  
    /** Return true if a port is present
1519  

1536  

1520  
        This function returns true if an
1537  
        This function returns true if an
1521  
        authority is present and contains a port.
1538  
        authority is present and contains a port.
1522  

1539  

1523  
        @par Example
1540  
        @par Example
1524  
        @code
1541  
        @code
1525  
        assert( url_view( "wss://www.example.com:443" ).has_port() );
1542  
        assert( url_view( "wss://www.example.com:443" ).has_port() );
1526  
        @endcode
1543  
        @endcode
1527  

1544  

1528  
        @par Complexity
1545  
        @par Complexity
1529  
        Constant.
1546  
        Constant.
1530  

1547  

1531  
        @par Exception Safety
1548  
        @par Exception Safety
1532  
        Throws nothing.
1549  
        Throws nothing.
1533  

1550  

1534  
        @par BNF
1551  
        @par BNF
1535  
        @code
1552  
        @code
1536  
        authority   = [ userinfo "@" ] host [ ":" port ]
1553  
        authority   = [ userinfo "@" ] host [ ":" port ]
1537  

1554  

1538  
        port        = *DIGIT
1555  
        port        = *DIGIT
1539  
        @endcode
1556  
        @endcode
1540  

1557  

1541  
        @par Specification
1558  
        @par Specification
1542  
        @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.2.3">3.2.3. Port (rfc3986)</a>
1559  
        @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.2.3">3.2.3. Port (rfc3986)</a>
1543  

1560  

1544  
        @see
1561  
        @see
1545  
            @ref encoded_host_and_port,
1562  
            @ref encoded_host_and_port,
1546  
            @ref port,
1563  
            @ref port,
1547  
            @ref port_number.
1564  
            @ref port_number.
1548  

1565  

1549  
        @return `true` if a port is present, `false` otherwise.
1566  
        @return `true` if a port is present, `false` otherwise.
1550  
    */
1567  
    */
1551  
    bool
1568  
    bool
1552  
    has_port() const noexcept;
1569  
    has_port() const noexcept;
1553  

1570  

1554  
    /** Return the port
1571  
    /** Return the port
1555  

1572  

1556  
        If present, this function returns a
1573  
        If present, this function returns a
1557  
        string representing the port (which
1574  
        string representing the port (which
1558  
        may be empty).
1575  
        may be empty).
1559  
        Otherwise it returns an empty string.
1576  
        Otherwise it returns an empty string.
1560  

1577  

1561  
        @par Example
1578  
        @par Example
1562  
        @code
1579  
        @code
1563  
        assert( url_view( "http://localhost.com:8080" ).port() == "8080" );
1580  
        assert( url_view( "http://localhost.com:8080" ).port() == "8080" );
1564  
        @endcode
1581  
        @endcode
1565  

1582  

1566  
        @par Complexity
1583  
        @par Complexity
1567  
        Constant.
1584  
        Constant.
1568  

1585  

1569  
        @par Exception Safety
1586  
        @par Exception Safety
1570  
        Throws nothing.
1587  
        Throws nothing.
1571  

1588  

1572  
        @par BNF
1589  
        @par BNF
1573  
        @code
1590  
        @code
1574  
        port        = *DIGIT
1591  
        port        = *DIGIT
1575  
        @endcode
1592  
        @endcode
1576  

1593  

1577  
        @par Specification
1594  
        @par Specification
1578  
        @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.2.3">3.2.3. Port (rfc3986)</a>
1595  
        @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.2.3">3.2.3. Port (rfc3986)</a>
1579  

1596  

1580  
        @see
1597  
        @see
1581  
            @ref encoded_host_and_port,
1598  
            @ref encoded_host_and_port,
1582  
            @ref has_port,
1599  
            @ref has_port,
1583  
            @ref port_number.
1600  
            @ref port_number.
1584  

1601  

1585  
        @return The port as a string.
1602  
        @return The port as a string.
1586  
    */
1603  
    */
1587  
    core::string_view
1604  
    core::string_view
1588  
    port() const noexcept;
1605  
    port() const noexcept;
1589  

1606  

1590  
    /** Return the port
1607  
    /** Return the port
1591  

1608  

1592  
        If a port is present and the numerical
1609  
        If a port is present and the numerical
1593  
        value is representable, it is returned
1610  
        value is representable, it is returned
1594  
        as an unsigned integer. Otherwise, the
1611  
        as an unsigned integer. Otherwise, the
1595  
        number zero is returned.
1612  
        number zero is returned.
1596  

1613  

1597  
        @par Example
1614  
        @par Example
1598  
        @code
1615  
        @code
1599  
        assert( url_view( "http://localhost.com:8080" ).port_number() == 8080 );
1616  
        assert( url_view( "http://localhost.com:8080" ).port_number() == 8080 );
1600  
        @endcode
1617  
        @endcode
1601  

1618  

1602  
        @par Complexity
1619  
        @par Complexity
1603  
        Constant.
1620  
        Constant.
1604  

1621  

1605  
        @par Exception Safety
1622  
        @par Exception Safety
1606  
        Throws nothing.
1623  
        Throws nothing.
1607  

1624  

1608  
        @par BNF
1625  
        @par BNF
1609  
        @code
1626  
        @code
1610  
        port        = *DIGIT
1627  
        port        = *DIGIT
1611  
        @endcode
1628  
        @endcode
1612  

1629  

1613  
        @par Specification
1630  
        @par Specification
1614  
        @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.2.3">3.2.3. Port (rfc3986)</a>
1631  
        @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.2.3">3.2.3. Port (rfc3986)</a>
1615  

1632  

1616  
        @see
1633  
        @see
1617  
            @ref encoded_host_and_port,
1634  
            @ref encoded_host_and_port,
1618  
            @ref has_port,
1635  
            @ref has_port,
1619  
            @ref port.
1636  
            @ref port.
1620  

1637  

1621  
        @return The port number as an unsigned integer.
1638  
        @return The port number as an unsigned integer.
1622  
    */
1639  
    */
1623  
    std::uint16_t
1640  
    std::uint16_t
1624  
    port_number() const noexcept;
1641  
    port_number() const noexcept;
1625  

1642  

1626  
    //--------------------------------------------
1643  
    //--------------------------------------------
1627  
    //
1644  
    //
1628  
    // Path
1645  
    // Path
1629  
    //
1646  
    //
1630  
    //--------------------------------------------
1647  
    //--------------------------------------------
1631  

1648  

1632  
    /** Return true if the path is absolute
1649  
    /** Return true if the path is absolute
1633  

1650  

1634  
        This function returns true if the path
1651  
        This function returns true if the path
1635  
        begins with a forward slash ('/').
1652  
        begins with a forward slash ('/').
1636  

1653  

1637  
        @par Example
1654  
        @par Example
1638  
        @code
1655  
        @code
1639  
        assert( url_view( "/path/to/file.txt" ).is_path_absolute() );
1656  
        assert( url_view( "/path/to/file.txt" ).is_path_absolute() );
1640  
        @endcode
1657  
        @endcode
1641  

1658  

1642  
        @par Complexity
1659  
        @par Complexity
1643  
        Constant.
1660  
        Constant.
1644  

1661  

1645  
        @par Exception Safety
1662  
        @par Exception Safety
1646  
        Throws nothing.
1663  
        Throws nothing.
1647  

1664  

1648  
        @par BNF
1665  
        @par BNF
1649  
        @code
1666  
        @code
1650  
        path          = path-abempty    ; begins with "/" or is empty
1667  
        path          = path-abempty    ; begins with "/" or is empty
1651  
                      / path-absolute   ; begins with "/" but not "//"
1668  
                      / path-absolute   ; begins with "/" but not "//"
1652  
                      / path-noscheme   ; begins with a non-colon segment
1669  
                      / path-noscheme   ; begins with a non-colon segment
1653  
                      / path-rootless   ; begins with a segment
1670  
                      / path-rootless   ; begins with a segment
1654  
                      / path-empty      ; zero characters
1671  
                      / path-empty      ; zero characters
1655  

1672  

1656  
        path-abempty  = *( "/" segment )
1673  
        path-abempty  = *( "/" segment )
1657  
        path-absolute = "/" [ segment-nz *( "/" segment ) ]
1674  
        path-absolute = "/" [ segment-nz *( "/" segment ) ]
1658  
        path-noscheme = segment-nz-nc *( "/" segment )
1675  
        path-noscheme = segment-nz-nc *( "/" segment )
1659  
        path-rootless = segment-nz *( "/" segment )
1676  
        path-rootless = segment-nz *( "/" segment )
1660  
        path-empty    = 0<pchar>
1677  
        path-empty    = 0<pchar>
1661  
        @endcode
1678  
        @endcode
1662  

1679  

1663  
        @par Specification
1680  
        @par Specification
1664  
        @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.3">3.3.  Path (rfc3986)</a>
1681  
        @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.3">3.3.  Path (rfc3986)</a>
1665  

1682  

1666  
        @see
1683  
        @see
1667  
            @ref encoded_path,
1684  
            @ref encoded_path,
1668  
            @ref encoded_segments.
1685  
            @ref encoded_segments.
1669  
            @ref path,
1686  
            @ref path,
1670  
            @ref segments.
1687  
            @ref segments.
1671  

1688  

1672  
        @return `true` if the path is absolute, `false` otherwise.
1689  
        @return `true` if the path is absolute, `false` otherwise.
1673  
    */
1690  
    */
1674  
    bool
1691  
    bool
1675  
    is_path_absolute() const noexcept
1692  
    is_path_absolute() const noexcept
1676  
    {
1693  
    {
1677  
        return
1694  
        return
1678 -
            pi_->len(id_path) > 0 &&
1695 +
            impl().len(id_path) > 0 &&
1679 -
            pi_->cs_[pi_->offset(id_path)] == '/';
1696 +
            impl().cs_[impl().offset(id_path)] == '/';
1680  
    }
1697  
    }
1681  

1698  

1682  
    /** Return the path
1699  
    /** Return the path
1683  

1700  

1684  
        This function returns the path as a
1701  
        This function returns the path as a
1685  
        string. The path may be empty.
1702  
        string. The path may be empty.
1686  
        Any percent-escapes in the string are
1703  
        Any percent-escapes in the string are
1687  
        decoded first.
1704  
        decoded first.
1688  

1705  

1689  
        @par Example
1706  
        @par Example
1690  
        @code
1707  
        @code
1691  
        assert( url_view( "file:///Program%20Files/Games/config.ini" ).path() == "/Program Files/Games/config.ini" );
1708  
        assert( url_view( "file:///Program%20Files/Games/config.ini" ).path() == "/Program Files/Games/config.ini" );
1692  
        @endcode
1709  
        @endcode
1693  

1710  

1694  
        @par Complexity
1711  
        @par Complexity
1695  
        Linear in `this->path().size()`.
1712  
        Linear in `this->path().size()`.
1696  

1713  

1697  
        @par Exception Safety
1714  
        @par Exception Safety
1698  
        Calls to allocate may throw.
1715  
        Calls to allocate may throw.
1699  

1716  

1700  
        @par BNF
1717  
        @par BNF
1701  
        @code
1718  
        @code
1702  
        path          = path-abempty    ; begins with "/" or is empty
1719  
        path          = path-abempty    ; begins with "/" or is empty
1703  
                      / path-absolute   ; begins with "/" but not "//"
1720  
                      / path-absolute   ; begins with "/" but not "//"
1704  
                      / path-noscheme   ; begins with a non-colon segment
1721  
                      / path-noscheme   ; begins with a non-colon segment
1705  
                      / path-rootless   ; begins with a segment
1722  
                      / path-rootless   ; begins with a segment
1706  
                      / path-empty      ; zero characters
1723  
                      / path-empty      ; zero characters
1707  

1724  

1708  
        path-abempty  = *( "/" segment )
1725  
        path-abempty  = *( "/" segment )
1709  
        path-absolute = "/" [ segment-nz *( "/" segment ) ]
1726  
        path-absolute = "/" [ segment-nz *( "/" segment ) ]
1710  
        path-noscheme = segment-nz-nc *( "/" segment )
1727  
        path-noscheme = segment-nz-nc *( "/" segment )
1711  
        path-rootless = segment-nz *( "/" segment )
1728  
        path-rootless = segment-nz *( "/" segment )
1712  
        path-empty    = 0<pchar>
1729  
        path-empty    = 0<pchar>
1713  
        @endcode
1730  
        @endcode
1714  

1731  

1715  
        @par Specification
1732  
        @par Specification
1716  
        @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.3">3.3. Path (rfc3986)</a>
1733  
        @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.3">3.3. Path (rfc3986)</a>
1717  

1734  

1718  
        @see
1735  
        @see
1719  
            @ref is_path_absolute,
1736  
            @ref is_path_absolute,
1720  
            @ref encoded_path,
1737  
            @ref encoded_path,
1721  
            @ref encoded_segments.
1738  
            @ref encoded_segments.
1722  
            @ref segments.
1739  
            @ref segments.
1723  

1740  

1724  
        @param token A string token to use for the result.
1741  
        @param token A string token to use for the result.
1725  
        @return The path as a string.
1742  
        @return The path as a string.
1726  
    */
1743  
    */
1727  
    template<BOOST_URL_STRTOK_TPARAM>
1744  
    template<BOOST_URL_STRTOK_TPARAM>
1728  
    BOOST_URL_STRTOK_RETURN
1745  
    BOOST_URL_STRTOK_RETURN
1729  
    path(
1746  
    path(
1730  
        StringToken&& token = {}) const
1747  
        StringToken&& token = {}) const
1731  
    {
1748  
    {
1732  
        encoding_opts opt;
1749  
        encoding_opts opt;
1733  
        opt.space_as_plus = false;
1750  
        opt.space_as_plus = false;
1734  
        return encoded_path().decode(
1751  
        return encoded_path().decode(
1735  
            opt, std::forward<StringToken>(token));
1752  
            opt, std::forward<StringToken>(token));
1736  
    }
1753  
    }
1737  

1754  

1738  
    /** Return the path
1755  
    /** Return the path
1739  

1756  

1740  
        This function returns the path as a
1757  
        This function returns the path as a
1741  
        string. The path may be empty.
1758  
        string. The path may be empty.
1742  
        Any percent-escapes in the string are
1759  
        Any percent-escapes in the string are
1743  
        decoded first.
1760  
        decoded first.
1744  

1761  

1745  
        @par Example
1762  
        @par Example
1746  
        @code
1763  
        @code
1747  
        assert( url_view( "file:///Program%20Files/Games/config.ini" ).encoded_path() == "/Program%20Files/Games/config.ini" );
1764  
        assert( url_view( "file:///Program%20Files/Games/config.ini" ).encoded_path() == "/Program%20Files/Games/config.ini" );
1748  
        @endcode
1765  
        @endcode
1749  

1766  

1750  
        @par Complexity
1767  
        @par Complexity
1751  
        Constant.
1768  
        Constant.
1752  

1769  

1753  
        @par Exception Safety
1770  
        @par Exception Safety
1754  
        Throws nothing.
1771  
        Throws nothing.
1755  

1772  

1756  
        @par BNF
1773  
        @par BNF
1757  
        @code
1774  
        @code
1758  
        path          = path-abempty    ; begins with "/" or is empty
1775  
        path          = path-abempty    ; begins with "/" or is empty
1759  
                      / path-absolute   ; begins with "/" but not "//"
1776  
                      / path-absolute   ; begins with "/" but not "//"
1760  
                      / path-noscheme   ; begins with a non-colon segment
1777  
                      / path-noscheme   ; begins with a non-colon segment
1761  
                      / path-rootless   ; begins with a segment
1778  
                      / path-rootless   ; begins with a segment
1762  
                      / path-empty      ; zero characters
1779  
                      / path-empty      ; zero characters
1763  

1780  

1764  
        path-abempty  = *( "/" segment )
1781  
        path-abempty  = *( "/" segment )
1765  
        path-absolute = "/" [ segment-nz *( "/" segment ) ]
1782  
        path-absolute = "/" [ segment-nz *( "/" segment ) ]
1766  
        path-noscheme = segment-nz-nc *( "/" segment )
1783  
        path-noscheme = segment-nz-nc *( "/" segment )
1767  
        path-rootless = segment-nz *( "/" segment )
1784  
        path-rootless = segment-nz *( "/" segment )
1768  
        path-empty    = 0<pchar>
1785  
        path-empty    = 0<pchar>
1769  
        @endcode
1786  
        @endcode
1770  

1787  

1771  
        @par Specification
1788  
        @par Specification
1772  
        @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.3">3.3. Path (rfc3986)</a>
1789  
        @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.3">3.3. Path (rfc3986)</a>
1773  

1790  

1774  
        @see
1791  
        @see
1775  
            @ref is_path_absolute,
1792  
            @ref is_path_absolute,
1776  
            @ref encoded_segments.
1793  
            @ref encoded_segments.
1777  
            @ref path,
1794  
            @ref path,
1778  
            @ref segments.
1795  
            @ref segments.
1779  

1796  

1780  
        @return The path as a string.
1797  
        @return The path as a string.
1781  
    */
1798  
    */
1782  
    pct_string_view
1799  
    pct_string_view
1783  
    encoded_path() const noexcept;
1800  
    encoded_path() const noexcept;
1784  

1801  

1785  
    /** Return the path as a container of segments
1802  
    /** Return the path as a container of segments
1786  

1803  

1787  
        This function returns a bidirectional
1804  
        This function returns a bidirectional
1788  
        view of strings over the path.
1805  
        view of strings over the path.
1789  
        The returned view references the same
1806  
        The returned view references the same
1790  
        underlying character buffer; ownership
1807  
        underlying character buffer; ownership
1791  
        is not transferred.
1808  
        is not transferred.
1792  
        Any percent-escapes in strings returned
1809  
        Any percent-escapes in strings returned
1793  
        when iterating the view are decoded first.
1810  
        when iterating the view are decoded first.
1794  

1811  

1795  
        @par Example
1812  
        @par Example
1796  
        @code
1813  
        @code
1797  
        segments_view sv = url_view( "/path/to/file.txt" ).segments();
1814  
        segments_view sv = url_view( "/path/to/file.txt" ).segments();
1798  
        @endcode
1815  
        @endcode
1799  

1816  

1800  
        @par Complexity
1817  
        @par Complexity
1801  
        Constant.
1818  
        Constant.
1802  

1819  

1803  
        @par Exception Safety
1820  
        @par Exception Safety
1804  
        Throws nothing.
1821  
        Throws nothing.
1805  

1822  

1806  
        @par BNF
1823  
        @par BNF
1807  
        @code
1824  
        @code
1808  
        path          = [ "/" ] segment *( "/" segment )
1825  
        path          = [ "/" ] segment *( "/" segment )
1809  
        @endcode
1826  
        @endcode
1810  

1827  

1811  
        @par Specification
1828  
        @par Specification
1812  
        @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.3">3.3. Path (rfc3986)</a>
1829  
        @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.3">3.3. Path (rfc3986)</a>
1813  

1830  

1814  
        @see
1831  
        @see
1815  
            @ref is_path_absolute,
1832  
            @ref is_path_absolute,
1816  
            @ref encoded_path,
1833  
            @ref encoded_path,
1817  
            @ref encoded_segments.
1834  
            @ref encoded_segments.
1818  
            @ref path,
1835  
            @ref path,
1819  
            @ref segments_view.
1836  
            @ref segments_view.
1820  

1837  

1821  
        @return A bidirectional view of segments.
1838  
        @return A bidirectional view of segments.
1822  
    */
1839  
    */
1823  
    segments_view
1840  
    segments_view
1824  
    segments() const noexcept;
1841  
    segments() const noexcept;
1825  

1842  

1826  
    /** Return the path as a container of segments
1843  
    /** Return the path as a container of segments
1827  

1844  

1828  
        This function returns a bidirectional
1845  
        This function returns a bidirectional
1829  
        view of strings over the path.
1846  
        view of strings over the path.
1830  
        The returned view references the same
1847  
        The returned view references the same
1831  
        underlying character buffer; ownership
1848  
        underlying character buffer; ownership
1832  
        is not transferred.
1849  
        is not transferred.
1833  
        Strings returned when iterating the
1850  
        Strings returned when iterating the
1834  
        range may contain percent escapes.
1851  
        range may contain percent escapes.
1835  

1852  

1836  
        @par Example
1853  
        @par Example
1837  
        @code
1854  
        @code
1838  
        segments_encoded_view sv = url_view( "/path/to/file.txt" ).encoded_segments();
1855  
        segments_encoded_view sv = url_view( "/path/to/file.txt" ).encoded_segments();
1839  
        @endcode
1856  
        @endcode
1840  

1857  

1841  
        @par Complexity
1858  
        @par Complexity
1842  
        Constant.
1859  
        Constant.
1843  

1860  

1844  
        @par Exception Safety
1861  
        @par Exception Safety
1845  
        Throws nothing.
1862  
        Throws nothing.
1846  

1863  

1847  
        @par BNF
1864  
        @par BNF
1848  
        @code
1865  
        @code
1849  
        path          = path-abempty    ; begins with "/" or is empty
1866  
        path          = path-abempty    ; begins with "/" or is empty
1850  
                      / path-absolute   ; begins with "/" but not "//"
1867  
                      / path-absolute   ; begins with "/" but not "//"
1851  
                      / path-noscheme   ; begins with a non-colon segment
1868  
                      / path-noscheme   ; begins with a non-colon segment
1852  
                      / path-rootless   ; begins with a segment
1869  
                      / path-rootless   ; begins with a segment
1853  
                      / path-empty      ; zero characters
1870  
                      / path-empty      ; zero characters
1854  

1871  

1855  
        path-abempty  = *( "/" segment )
1872  
        path-abempty  = *( "/" segment )
1856  
        path-absolute = "/" [ segment-nz *( "/" segment ) ]
1873  
        path-absolute = "/" [ segment-nz *( "/" segment ) ]
1857  
        path-noscheme = segment-nz-nc *( "/" segment )
1874  
        path-noscheme = segment-nz-nc *( "/" segment )
1858  
        path-rootless = segment-nz *( "/" segment )
1875  
        path-rootless = segment-nz *( "/" segment )
1859  
        path-empty    = 0<pchar>
1876  
        path-empty    = 0<pchar>
1860  
        @endcode
1877  
        @endcode
1861  

1878  

1862  
        @par Specification
1879  
        @par Specification
1863  
        @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.3">3.3. Path (rfc3986)</a>
1880  
        @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.3">3.3. Path (rfc3986)</a>
1864  

1881  

1865  
        @see
1882  
        @see
1866  
            @ref is_path_absolute,
1883  
            @ref is_path_absolute,
1867  
            @ref encoded_path,
1884  
            @ref encoded_path,
1868  
            @ref path,
1885  
            @ref path,
1869  
            @ref segments,
1886  
            @ref segments,
1870  
            @ref segments_encoded_view.
1887  
            @ref segments_encoded_view.
1871  

1888  

1872  
        @return A bidirectional view of encoded segments.
1889  
        @return A bidirectional view of encoded segments.
1873  
    */
1890  
    */
1874  
    segments_encoded_view
1891  
    segments_encoded_view
1875  
    encoded_segments() const noexcept;
1892  
    encoded_segments() const noexcept;
1876  

1893  

1877  
    //--------------------------------------------
1894  
    //--------------------------------------------
1878  
    //
1895  
    //
1879  
    // Query
1896  
    // Query
1880  
    //
1897  
    //
1881  
    //--------------------------------------------
1898  
    //--------------------------------------------
1882  

1899  

1883  
    /** Return true if a query is present
1900  
    /** Return true if a query is present
1884  

1901  

1885  
        This function returns true if this
1902  
        This function returns true if this
1886  
        contains a query. An empty query is
1903  
        contains a query. An empty query is
1887  
        distinct from having no query.
1904  
        distinct from having no query.
1888  

1905  

1889  
        @par Example
1906  
        @par Example
1890  
        @code
1907  
        @code
1891  
        assert( url_view( "/sql?id=42&col=name&page-size=20" ).has_query() );
1908  
        assert( url_view( "/sql?id=42&col=name&page-size=20" ).has_query() );
1892  
        @endcode
1909  
        @endcode
1893  

1910  

1894  
        @par Complexity
1911  
        @par Complexity
1895  
        Constant.
1912  
        Constant.
1896  

1913  

1897  
        @par Exception Safety
1914  
        @par Exception Safety
1898  
        Throws nothing.
1915  
        Throws nothing.
1899  

1916  

1900  
        @par BNF
1917  
        @par BNF
1901  
        @code
1918  
        @code
1902  
        query           = *( pchar / "/" / "?" )
1919  
        query           = *( pchar / "/" / "?" )
1903  

1920  

1904  
        query-param     = key [ "=" value ]
1921  
        query-param     = key [ "=" value ]
1905  
        query-params    = [ query-param ] *( "&" query-param )
1922  
        query-params    = [ query-param ] *( "&" query-param )
1906  
        @endcode
1923  
        @endcode
1907  

1924  

1908  
        @par Specification
1925  
        @par Specification
1909  
        @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.4">3.4.  Query (rfc3986)</a>
1926  
        @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.4">3.4.  Query (rfc3986)</a>
1910  
        @li <a href="https://en.wikipedia.org/wiki/Query_string">Query string (Wikipedia)</a>
1927  
        @li <a href="https://en.wikipedia.org/wiki/Query_string">Query string (Wikipedia)</a>
1911  

1928  

1912  
        @see
1929  
        @see
1913  
            @ref encoded_params,
1930  
            @ref encoded_params,
1914  
            @ref encoded_query,
1931  
            @ref encoded_query,
1915  
            @ref params,
1932  
            @ref params,
1916  
            @ref query.
1933  
            @ref query.
1917  

1934  

1918  
        @return `true` if a query is present.
1935  
        @return `true` if a query is present.
1919  
    */
1936  
    */
1920  
    bool
1937  
    bool
1921  
    has_query() const noexcept;
1938  
    has_query() const noexcept;
1922  

1939  

1923  
    /** Return the query
1940  
    /** Return the query
1924  

1941  

1925  
        If this contains a query, it is returned
1942  
        If this contains a query, it is returned
1926  
        as a string (which may be empty).
1943  
        as a string (which may be empty).
1927  
        Otherwise, an empty string is returned.
1944  
        Otherwise, an empty string is returned.
1928  
        Any percent-escapes in the string are
1945  
        Any percent-escapes in the string are
1929  
        decoded first.
1946  
        decoded first.
1930  
        <br>
1947  
        <br>
1931  

1948  

1932  
        Literal plus signs remain unchanged by
1949  
        Literal plus signs remain unchanged by
1933  
        default to match RFC 3986. To treat '+'
1950  
        default to match RFC 3986. To treat '+'
1934  
        as a space, supply decoding options with
1951  
        as a space, supply decoding options with
1935  
        `space_as_plus = true` when calling this
1952  
        `space_as_plus = true` when calling this
1936  
        function.
1953  
        function.
1937  

1954  

1938  
        @par Example
1955  
        @par Example
1939  
        @code
1956  
        @code
1940  
        assert( url_view( "/sql?id=42&name=jane%2Ddoe&page+size=20" ).query() == "id=42&name=jane-doe&page size=20" );
1957  
        assert( url_view( "/sql?id=42&name=jane%2Ddoe&page+size=20" ).query() == "id=42&name=jane-doe&page size=20" );
1941  
        @endcode
1958  
        @endcode
1942  

1959  

1943  
        @par Complexity
1960  
        @par Complexity
1944  
        Linear in `this->query().size()`.
1961  
        Linear in `this->query().size()`.
1945  

1962  

1946  
        @par Exception Safety
1963  
        @par Exception Safety
1947  
        Calls to allocate may throw.
1964  
        Calls to allocate may throw.
1948  

1965  

1949  
        @par BNF
1966  
        @par BNF
1950  
        @code
1967  
        @code
1951  
        query           = *( pchar / "/" / "?" )
1968  
        query           = *( pchar / "/" / "?" )
1952  

1969  

1953  
        query-param     = key [ "=" value ]
1970  
        query-param     = key [ "=" value ]
1954  
        query-params    = [ query-param ] *( "&" query-param )
1971  
        query-params    = [ query-param ] *( "&" query-param )
1955  
        @endcode
1972  
        @endcode
1956  

1973  

1957  
        @par Specification
1974  
        @par Specification
1958  
        @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.4">3.4.  Query (rfc3986)</a>
1975  
        @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.4">3.4.  Query (rfc3986)</a>
1959  
        @li <a href="https://en.wikipedia.org/wiki/Query_string">Query string (Wikipedia)</a>
1976  
        @li <a href="https://en.wikipedia.org/wiki/Query_string">Query string (Wikipedia)</a>
1960  

1977  

1961  
        @see
1978  
        @see
1962  
            @ref encoded_params,
1979  
            @ref encoded_params,
1963  
            @ref encoded_query,
1980  
            @ref encoded_query,
1964  
            @ref has_query,
1981  
            @ref has_query,
1965  
            @ref params.
1982  
            @ref params.
1966  

1983  

1967  
        @param token A token to use for the returned string.
1984  
        @param token A token to use for the returned string.
1968  
        @return The query as a string.
1985  
        @return The query as a string.
1969  
    */
1986  
    */
1970  
    template<BOOST_URL_STRTOK_TPARAM>
1987  
    template<BOOST_URL_STRTOK_TPARAM>
1971  
    BOOST_URL_STRTOK_RETURN
1988  
    BOOST_URL_STRTOK_RETURN
1972  
    query(
1989  
    query(
1973  
        StringToken&& token = {}) const
1990  
        StringToken&& token = {}) const
1974  
    {
1991  
    {
1975  
        // When interacting with the query as
1992  
        // When interacting with the query as
1976  
        // an intact string, we do not treat
1993  
        // an intact string, we do not treat
1977  
        // the plus sign as an encoded space.
1994  
        // the plus sign as an encoded space.
1978  
        encoding_opts opt;
1995  
        encoding_opts opt;
1979  
        opt.space_as_plus = false;
1996  
        opt.space_as_plus = false;
1980  
        return encoded_query().decode(
1997  
        return encoded_query().decode(
1981  
            opt, std::forward<StringToken>(token));
1998  
            opt, std::forward<StringToken>(token));
1982  
    }
1999  
    }
1983  

2000  

1984  
    /** Return the query
2001  
    /** Return the query
1985  

2002  

1986  
        If this contains a query, it is returned
2003  
        If this contains a query, it is returned
1987  
        as a string (which may be empty).
2004  
        as a string (which may be empty).
1988  
        Otherwise, an empty string is returned.
2005  
        Otherwise, an empty string is returned.
1989  
        The returned string may contain
2006  
        The returned string may contain
1990  
        percent escapes.
2007  
        percent escapes.
1991  

2008  

1992  
        @par Example
2009  
        @par Example
1993  
        @code
2010  
        @code
1994  
        assert( url_view( "/sql?id=42&name=jane%2Ddoe&page+size=20" ).encoded_query() == "id=42&name=jane%2Ddoe&page+size=20" );
2011  
        assert( url_view( "/sql?id=42&name=jane%2Ddoe&page+size=20" ).encoded_query() == "id=42&name=jane%2Ddoe&page+size=20" );
1995  
        @endcode
2012  
        @endcode
1996  

2013  

1997  
        @par Complexity
2014  
        @par Complexity
1998  
        Constant.
2015  
        Constant.
1999  

2016  

2000  
        @par Exception Safety
2017  
        @par Exception Safety
2001  
        Throws nothing.
2018  
        Throws nothing.
2002  

2019  

2003  
        @par BNF
2020  
        @par BNF
2004  
        @code
2021  
        @code
2005  
        query           = *( pchar / "/" / "?" )
2022  
        query           = *( pchar / "/" / "?" )
2006  

2023  

2007  
        query-param     = key [ "=" value ]
2024  
        query-param     = key [ "=" value ]
2008  
        query-params    = [ query-param ] *( "&" query-param )
2025  
        query-params    = [ query-param ] *( "&" query-param )
2009  
        @endcode
2026  
        @endcode
2010  

2027  

2011  
        @par Specification
2028  
        @par Specification
2012  
        @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.4">3.4. Query (rfc3986)</a>
2029  
        @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.4">3.4. Query (rfc3986)</a>
2013  
        @li <a href="https://en.wikipedia.org/wiki/Query_string">Query string (Wikipedia)</a>
2030  
        @li <a href="https://en.wikipedia.org/wiki/Query_string">Query string (Wikipedia)</a>
2014  

2031  

2015  
        @see
2032  
        @see
2016  
            @ref encoded_params,
2033  
            @ref encoded_params,
2017  
            @ref has_query,
2034  
            @ref has_query,
2018  
            @ref params,
2035  
            @ref params,
2019  
            @ref query.
2036  
            @ref query.
2020  

2037  

2021  
        @return The query as a string.
2038  
        @return The query as a string.
2022  
    */
2039  
    */
2023  
    pct_string_view
2040  
    pct_string_view
2024  
    encoded_query() const noexcept;
2041  
    encoded_query() const noexcept;
2025  

2042  

2026  
    /** Return the query as a container of parameters
2043  
    /** Return the query as a container of parameters
2027  

2044  

2028  
        This function returns a bidirectional
2045  
        This function returns a bidirectional
2029  
        view of key/value pairs over the query.
2046  
        view of key/value pairs over the query.
2030  
        The returned view references the same
2047  
        The returned view references the same
2031  
        underlying character buffer; ownership
2048  
        underlying character buffer; ownership
2032  
        is not transferred.
2049  
        is not transferred.
2033  
        Any percent-escapes in strings returned
2050  
        Any percent-escapes in strings returned
2034  
        when iterating the view are decoded first.
2051  
        when iterating the view are decoded first.
2035  

2052  

2036  
        @par Example
2053  
        @par Example
2037  
        @code
2054  
        @code
2038  
        params_view pv = url_view( "/sql?id=42&name=jane%2Ddoe&page+size=20" ).params();
2055  
        params_view pv = url_view( "/sql?id=42&name=jane%2Ddoe&page+size=20" ).params();
2039  
        @endcode
2056  
        @endcode
2040  

2057  

2041  
        @par Complexity
2058  
        @par Complexity
2042  
        Constant.
2059  
        Constant.
2043  

2060  

2044  
        @par Exception Safety
2061  
        @par Exception Safety
2045  
        Throws nothing.
2062  
        Throws nothing.
2046  

2063  

2047  
        @par BNF
2064  
        @par BNF
2048  
        @code
2065  
        @code
2049  
        query           = *( pchar / "/" / "?" )
2066  
        query           = *( pchar / "/" / "?" )
2050  

2067  

2051  
        query-param     = key [ "=" value ]
2068  
        query-param     = key [ "=" value ]
2052  
        query-params    = [ query-param ] *( "&" query-param )
2069  
        query-params    = [ query-param ] *( "&" query-param )
2053  
        @endcode
2070  
        @endcode
2054  

2071  

2055  
        @par Specification
2072  
        @par Specification
2056  
        @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.4">3.4.  Query (rfc3986)</a>
2073  
        @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.4">3.4.  Query (rfc3986)</a>
2057  
        @li <a href="https://en.wikipedia.org/wiki/Query_string">Query string (Wikipedia)</a>
2074  
        @li <a href="https://en.wikipedia.org/wiki/Query_string">Query string (Wikipedia)</a>
2058  

2075  

2059  
        @see
2076  
        @see
2060  
            @ref encoded_params,
2077  
            @ref encoded_params,
2061  
            @ref encoded_query,
2078  
            @ref encoded_query,
2062  
            @ref has_query,
2079  
            @ref has_query,
2063  
            @ref query.
2080  
            @ref query.
2064  

2081  

2065  
        @return A bidirectional view of key/value pairs.
2082  
        @return A bidirectional view of key/value pairs.
2066  
    */
2083  
    */
2067  
    params_view
2084  
    params_view
2068  
    params() const noexcept;
2085  
    params() const noexcept;
2069  

2086  

2070  
    params_view
2087  
    params_view
2071  
    params(encoding_opts opt) const noexcept;
2088  
    params(encoding_opts opt) const noexcept;
2072  

2089  

2073  
    /** Return the query as a container of parameters
2090  
    /** Return the query as a container of parameters
2074  

2091  

2075  
        This function returns a bidirectional
2092  
        This function returns a bidirectional
2076  
        view of key/value pairs over the query.
2093  
        view of key/value pairs over the query.
2077  
        The returned view references the same
2094  
        The returned view references the same
2078  
        underlying character buffer; ownership
2095  
        underlying character buffer; ownership
2079  
        is not transferred.
2096  
        is not transferred.
2080  
        Strings returned when iterating the
2097  
        Strings returned when iterating the
2081  
        range may contain percent escapes.
2098  
        range may contain percent escapes.
2082  

2099  

2083  
        @par Example
2100  
        @par Example
2084  
        @code
2101  
        @code
2085  
        params_encoded_view pv = url_view( "/sql?id=42&name=jane%2Ddoe&page+size=20" ).encoded_params();
2102  
        params_encoded_view pv = url_view( "/sql?id=42&name=jane%2Ddoe&page+size=20" ).encoded_params();
2086  
        @endcode
2103  
        @endcode
2087  

2104  

2088  
        @par Complexity
2105  
        @par Complexity
2089  
        Constant.
2106  
        Constant.
2090  

2107  

2091  
        @par Exception Safety
2108  
        @par Exception Safety
2092  
        Throws nothing.
2109  
        Throws nothing.
2093  

2110  

2094  
        @par BNF
2111  
        @par BNF
2095  
        @code
2112  
        @code
2096  
        query           = *( pchar / "/" / "?" )
2113  
        query           = *( pchar / "/" / "?" )
2097  
        query-param     = key [ "=" value ]
2114  
        query-param     = key [ "=" value ]
2098  
        query-params    = [ query-param ] *( "&" query-param )
2115  
        query-params    = [ query-param ] *( "&" query-param )
2099  
        @endcode
2116  
        @endcode
2100  

2117  

2101  
        @par Specification
2118  
        @par Specification
2102  
        @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.4">3.4. Query (rfc3986)</a>
2119  
        @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.4">3.4. Query (rfc3986)</a>
2103  
        @li <a href="https://en.wikipedia.org/wiki/Query_string">Query string (Wikipedia)</a>
2120  
        @li <a href="https://en.wikipedia.org/wiki/Query_string">Query string (Wikipedia)</a>
2104  

2121  

2105  
        @see
2122  
        @see
2106  
            @ref encoded_query,
2123  
            @ref encoded_query,
2107  
            @ref has_query,
2124  
            @ref has_query,
2108  
            @ref params,
2125  
            @ref params,
2109  
            @ref query.
2126  
            @ref query.
2110  

2127  

2111  
        @return A bidirectional view of key/value pairs.
2128  
        @return A bidirectional view of key/value pairs.
2112  
    */
2129  
    */
2113  
    params_encoded_view
2130  
    params_encoded_view
2114  
    encoded_params() const noexcept;
2131  
    encoded_params() const noexcept;
2115  

2132  

2116  
    //--------------------------------------------
2133  
    //--------------------------------------------
2117  
    //
2134  
    //
2118  
    // Fragment
2135  
    // Fragment
2119  
    //
2136  
    //
2120  
    //--------------------------------------------
2137  
    //--------------------------------------------
2121  

2138  

2122  
    /** Return true if a fragment is present
2139  
    /** Return true if a fragment is present
2123  

2140  

2124  
        This function returns true if the url
2141  
        This function returns true if the url
2125  
        contains a fragment.
2142  
        contains a fragment.
2126  
        An empty fragment is distinct from
2143  
        An empty fragment is distinct from
2127  
        no fragment.
2144  
        no fragment.
2128  

2145  

2129  
        @par Example
2146  
        @par Example
2130  
        @code
2147  
        @code
2131  
        assert( url_view( "http://www.example.com/index.htm#anchor" ).has_fragment() );
2148  
        assert( url_view( "http://www.example.com/index.htm#anchor" ).has_fragment() );
2132  
        @endcode
2149  
        @endcode
2133  

2150  

2134  
        @par Complexity
2151  
        @par Complexity
2135  
        Constant.
2152  
        Constant.
2136  

2153  

2137  
        @par Exception Safety
2154  
        @par Exception Safety
2138  
        Throws nothing.
2155  
        Throws nothing.
2139  

2156  

2140  
        @par BNF
2157  
        @par BNF
2141  
        @code
2158  
        @code
2142  
        URI           = scheme ":" hier-part [ "?" query ] [ "#" fragment ]
2159  
        URI           = scheme ":" hier-part [ "?" query ] [ "#" fragment ]
2143  

2160  

2144  
        relative-ref  = relative-part [ "?" query ] [ "#" fragment ]
2161  
        relative-ref  = relative-part [ "?" query ] [ "#" fragment ]
2145  
        @endcode
2162  
        @endcode
2146  

2163  

2147  
        @par Specification
2164  
        @par Specification
2148  
        @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.5">3.5. Fragment (rfc3986)</a>
2165  
        @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.5">3.5. Fragment (rfc3986)</a>
2149  

2166  

2150  
        @see
2167  
        @see
2151  
            @ref encoded_fragment,
2168  
            @ref encoded_fragment,
2152  
            @ref fragment.
2169  
            @ref fragment.
2153  

2170  

2154  
        @return `true` if the url contains a fragment.
2171  
        @return `true` if the url contains a fragment.
2155  
    */
2172  
    */
2156  
    bool
2173  
    bool
2157  
    has_fragment() const noexcept;
2174  
    has_fragment() const noexcept;
2158  

2175  

2159  
    /** Return the fragment
2176  
    /** Return the fragment
2160  

2177  

2161  
        This function calculates the fragment
2178  
        This function calculates the fragment
2162  
        of the url, with percent escapes decoded
2179  
        of the url, with percent escapes decoded
2163  
        and without the leading pound sign ('#')
2180  
        and without the leading pound sign ('#')
2164  
        whose presence indicates that the url
2181  
        whose presence indicates that the url
2165  
        contains a fragment.
2182  
        contains a fragment.
2166  

2183  

2167  
        <br>
2184  
        <br>
2168  

2185  

2169  
        This function accepts an optional
2186  
        This function accepts an optional
2170  
        <em>StringToken</em> parameter which
2187  
        <em>StringToken</em> parameter which
2171  
        controls the return type and behavior
2188  
        controls the return type and behavior
2172  
        of the function:
2189  
        of the function:
2173  

2190  

2174  
        @li When called with no arguments,
2191  
        @li When called with no arguments,
2175  
        the return type of the function is
2192  
        the return type of the function is
2176  
        `std::string`. Otherwise
2193  
        `std::string`. Otherwise
2177  

2194  

2178  
        @li When called with a string token,
2195  
        @li When called with a string token,
2179  
        the behavior and return type of the
2196  
        the behavior and return type of the
2180  
        function depends on the type of string
2197  
        function depends on the type of string
2181  
        token being passed.
2198  
        token being passed.
2182  

2199  

2183  
        @par Example
2200  
        @par Example
2184  
        @code
2201  
        @code
2185  
        assert( url_view( "http://www.example.com/index.htm#a%2D1" ).fragment() == "a-1" );
2202  
        assert( url_view( "http://www.example.com/index.htm#a%2D1" ).fragment() == "a-1" );
2186  
        @endcode
2203  
        @endcode
2187  

2204  

2188  
        @par Complexity
2205  
        @par Complexity
2189  
        Linear in `this->fragment().size()`.
2206  
        Linear in `this->fragment().size()`.
2190  

2207  

2191  
        @par Exception Safety
2208  
        @par Exception Safety
2192  
        Calls to allocate may throw.
2209  
        Calls to allocate may throw.
2193  
        String tokens may throw exceptions.
2210  
        String tokens may throw exceptions.
2194  

2211  

2195  
        @param token An optional string token to
2212  
        @param token An optional string token to
2196  
        use. If this parameter is omitted, the
2213  
        use. If this parameter is omitted, the
2197  
        function returns a new `std::string`.
2214  
        function returns a new `std::string`.
2198  

2215  

2199  
        @return The fragment portion of the url.
2216  
        @return The fragment portion of the url.
2200  

2217  

2201  
        @par BNF
2218  
        @par BNF
2202  
        @code
2219  
        @code
2203  
        fragment        = *( pchar / "/" / "?" )
2220  
        fragment        = *( pchar / "/" / "?" )
2204  

2221  

2205  
        fragment-part   = [ "#" fragment ]
2222  
        fragment-part   = [ "#" fragment ]
2206  
        @endcode
2223  
        @endcode
2207  

2224  

2208  
        @par Specification
2225  
        @par Specification
2209  
        @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.5">3.5. Fragment (rfc3986)</a>
2226  
        @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.5">3.5. Fragment (rfc3986)</a>
2210  

2227  

2211  
        @see
2228  
        @see
2212  
            @ref encoded_fragment,
2229  
            @ref encoded_fragment,
2213  
            @ref has_fragment.
2230  
            @ref has_fragment.
2214  

2231  

2215  
    */
2232  
    */
2216  
    template<BOOST_URL_STRTOK_TPARAM>
2233  
    template<BOOST_URL_STRTOK_TPARAM>
2217  
    BOOST_URL_STRTOK_RETURN
2234  
    BOOST_URL_STRTOK_RETURN
2218  
    fragment(
2235  
    fragment(
2219  
        StringToken&& token = {}) const
2236  
        StringToken&& token = {}) const
2220  
    {
2237  
    {
2221  
        encoding_opts opt;
2238  
        encoding_opts opt;
2222  
        opt.space_as_plus = false;
2239  
        opt.space_as_plus = false;
2223  
        return encoded_fragment().decode(
2240  
        return encoded_fragment().decode(
2224  
            opt, std::forward<StringToken>(token));
2241  
            opt, std::forward<StringToken>(token));
2225  
    }
2242  
    }
2226  

2243  

2227  
    /** Return the fragment
2244  
    /** Return the fragment
2228  

2245  

2229  
        This function returns the fragment as a
2246  
        This function returns the fragment as a
2230  
        string with percent-escapes.
2247  
        string with percent-escapes.
2231  
        Ownership is not transferred; the
2248  
        Ownership is not transferred; the
2232  
        string returned references the underlying
2249  
        string returned references the underlying
2233  
        character buffer, which must remain valid
2250  
        character buffer, which must remain valid
2234  
        or else undefined behavior occurs.
2251  
        or else undefined behavior occurs.
2235  

2252  

2236  
        @par Example
2253  
        @par Example
2237  
        @code
2254  
        @code
2238  
        assert( url_view( "http://www.example.com/index.htm#a%2D1" ).encoded_fragment() == "a%2D1" );
2255  
        assert( url_view( "http://www.example.com/index.htm#a%2D1" ).encoded_fragment() == "a%2D1" );
2239  
        @endcode
2256  
        @endcode
2240  

2257  

2241  
        @par Complexity
2258  
        @par Complexity
2242  
        Constant.
2259  
        Constant.
2243  

2260  

2244  
        @par Exception Safety
2261  
        @par Exception Safety
2245  
        Throws nothing.
2262  
        Throws nothing.
2246  

2263  

2247  
        @par BNF
2264  
        @par BNF
2248  
        @code
2265  
        @code
2249  
        fragment        = *( pchar / "/" / "?" )
2266  
        fragment        = *( pchar / "/" / "?" )
2250  

2267  

2251  
        pchar           = unreserved / pct-encoded / sub-delims / ":" / "@"
2268  
        pchar           = unreserved / pct-encoded / sub-delims / ":" / "@"
2252  
        @endcode
2269  
        @endcode
2253  

2270  

2254  
        @par Specification
2271  
        @par Specification
2255  
        @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.5">3.5. Fragment (rfc3986)</a>
2272  
        @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.5">3.5. Fragment (rfc3986)</a>
2256  

2273  

2257  
        @see
2274  
        @see
2258  
            @ref fragment,
2275  
            @ref fragment,
2259  
            @ref has_fragment.
2276  
            @ref has_fragment.
2260  

2277  

2261  
        @return The fragment portion of the url.
2278  
        @return The fragment portion of the url.
2262  
    */
2279  
    */
2263  
    pct_string_view
2280  
    pct_string_view
2264  
    encoded_fragment() const noexcept;
2281  
    encoded_fragment() const noexcept;
2265  

2282  

2266  
    //--------------------------------------------
2283  
    //--------------------------------------------
2267  
    //
2284  
    //
2268  
    // Compound Fields
2285  
    // Compound Fields
2269  
    //
2286  
    //
2270  
    //--------------------------------------------
2287  
    //--------------------------------------------
2271  

2288  

2272  
    /** Return the host and port
2289  
    /** Return the host and port
2273  

2290  

2274  
        If an authority is present, this
2291  
        If an authority is present, this
2275  
        function returns the host and optional
2292  
        function returns the host and optional
2276  
        port as a string, which may be empty.
2293  
        port as a string, which may be empty.
2277  
        Otherwise it returns an empty string.
2294  
        Otherwise it returns an empty string.
2278  
        The returned string may contain
2295  
        The returned string may contain
2279  
        percent escapes.
2296  
        percent escapes.
2280  

2297  

2281  
        @par Example
2298  
        @par Example
2282  
        @code
2299  
        @code
2283  
        assert( url_view( "http://www.example.com:8080/index.htm" ).encoded_host_and_port() == "www.example.com:8080" );
2300  
        assert( url_view( "http://www.example.com:8080/index.htm" ).encoded_host_and_port() == "www.example.com:8080" );
2284  
        @endcode
2301  
        @endcode
2285  

2302  

2286  
        @par Complexity
2303  
        @par Complexity
2287  
        Constant.
2304  
        Constant.
2288  

2305  

2289  
        @par Exception Safety
2306  
        @par Exception Safety
2290  
        Throws nothing.
2307  
        Throws nothing.
2291  

2308  

2292  
        @par BNF
2309  
        @par BNF
2293  
        @code
2310  
        @code
2294  
        authority   = [ userinfo "@" ] host [ ":" port ]
2311  
        authority   = [ userinfo "@" ] host [ ":" port ]
2295  
        @endcode
2312  
        @endcode
2296  

2313  

2297  
        @par Specification
2314  
        @par Specification
2298  
        @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.2.2">3.2.2.  Host (rfc3986)</a>
2315  
        @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.2.2">3.2.2.  Host (rfc3986)</a>
2299  
        @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.2.3">3.2.3. Port (rfc3986)</a>
2316  
        @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.2.3">3.2.3. Port (rfc3986)</a>
2300  

2317  

2301  
        @see
2318  
        @see
2302  
            @ref has_port,
2319  
            @ref has_port,
2303  
            @ref port,
2320  
            @ref port,
2304  
            @ref port_number.
2321  
            @ref port_number.
2305  

2322  

2306  
        @return The host and port portion of the url.
2323  
        @return The host and port portion of the url.
2307  
    */
2324  
    */
2308  
    pct_string_view
2325  
    pct_string_view
2309  
    encoded_host_and_port() const noexcept;
2326  
    encoded_host_and_port() const noexcept;
2310  

2327  

2311  
    /** Return the origin
2328  
    /** Return the origin
2312  

2329  

2313  
        If an authority is present, this
2330  
        If an authority is present, this
2314  
        function returns the scheme and
2331  
        function returns the scheme and
2315  
        authority portion of the url.
2332  
        authority portion of the url.
2316  
        Otherwise, an empty string is
2333  
        Otherwise, an empty string is
2317  
        returned.
2334  
        returned.
2318  
        The returned string may contain
2335  
        The returned string may contain
2319  
        percent escapes.
2336  
        percent escapes.
2320  

2337  

2321  
        @par Example
2338  
        @par Example
2322  
        @code
2339  
        @code
2323  
        assert( url_view( "http://www.example.com:8080/index.htm?text=none#h1" ).encoded_origin() == "http://www.example.com:8080" );
2340  
        assert( url_view( "http://www.example.com:8080/index.htm?text=none#h1" ).encoded_origin() == "http://www.example.com:8080" );
2324  
        @endcode
2341  
        @endcode
2325  

2342  

2326  
        @par Complexity
2343  
        @par Complexity
2327  
        Constant.
2344  
        Constant.
2328  

2345  

2329  
        @par Exception Safety
2346  
        @par Exception Safety
2330  
        Throws nothing.
2347  
        Throws nothing.
2331  

2348  

2332  
        @see
2349  
        @see
2333  
            @ref encoded_resource,
2350  
            @ref encoded_resource,
2334  
            @ref encoded_target.
2351  
            @ref encoded_target.
2335  

2352  

2336  
        @return The origin portion of the url.
2353  
        @return The origin portion of the url.
2337  
    */
2354  
    */
2338  
    pct_string_view
2355  
    pct_string_view
2339  
    encoded_origin() const noexcept;
2356  
    encoded_origin() const noexcept;
2340  

2357  

2341  
    /** Return the resource
2358  
    /** Return the resource
2342  

2359  

2343  
        This function returns the resource, which
2360  
        This function returns the resource, which
2344  
        is the portion of the url that includes
2361  
        is the portion of the url that includes
2345  
        only the path, query, and fragment.
2362  
        only the path, query, and fragment.
2346  
        The returned string may contain
2363  
        The returned string may contain
2347  
        percent escapes.
2364  
        percent escapes.
2348  

2365  

2349  
        @par Example
2366  
        @par Example
2350  
        @code
2367  
        @code
2351  
        assert( url_view( "http://www.example.com/index.html?query#frag" ).encoded_resource() == "/index.html?query#frag" );
2368  
        assert( url_view( "http://www.example.com/index.html?query#frag" ).encoded_resource() == "/index.html?query#frag" );
2352  
        @endcode
2369  
        @endcode
2353  

2370  

2354  
        @par Complexity
2371  
        @par Complexity
2355  
        Constant.
2372  
        Constant.
2356  

2373  

2357  
        @par Exception Safety
2374  
        @par Exception Safety
2358  
        Throws nothing.
2375  
        Throws nothing.
2359  

2376  

2360  
        @par Specification
2377  
        @par Specification
2361  
        @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.3">3.3. Path (rfc3986)</a>
2378  
        @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.3">3.3. Path (rfc3986)</a>
2362  
        @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.4">3.4. Query (rfc3986)</a>
2379  
        @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.4">3.4. Query (rfc3986)</a>
2363  

2380  

2364  
        @see
2381  
        @see
2365  
            @ref encoded_origin,
2382  
            @ref encoded_origin,
2366  
            @ref encoded_target.
2383  
            @ref encoded_target.
2367  

2384  

2368  
        @return The resource portion of the url.
2385  
        @return The resource portion of the url.
2369  
    */
2386  
    */
2370  
    pct_string_view
2387  
    pct_string_view
2371  
    encoded_resource() const noexcept;
2388  
    encoded_resource() const noexcept;
2372  

2389  

2373  
    /** Return the target
2390  
    /** Return the target
2374  

2391  

2375  
        This function returns the target, which
2392  
        This function returns the target, which
2376  
        is the portion of the url that includes
2393  
        is the portion of the url that includes
2377  
        only the path and query.
2394  
        only the path and query.
2378  
        The returned string may contain
2395  
        The returned string may contain
2379  
        percent escapes.
2396  
        percent escapes.
2380  

2397  

2381  
        @par Example
2398  
        @par Example
2382  
        @code
2399  
        @code
2383  
        assert( url_view( "http://www.example.com/index.html?query#frag" ).encoded_target() == "/index.html?query" );
2400  
        assert( url_view( "http://www.example.com/index.html?query#frag" ).encoded_target() == "/index.html?query" );
2384  
        @endcode
2401  
        @endcode
2385  

2402  

2386  
        @par Complexity
2403  
        @par Complexity
2387  
        Constant.
2404  
        Constant.
2388  

2405  

2389  
        @par Exception Safety
2406  
        @par Exception Safety
2390  
        Throws nothing.
2407  
        Throws nothing.
2391  

2408  

2392  
        @par Specification
2409  
        @par Specification
2393  
        @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.3">3.3. Path (rfc3986)</a>
2410  
        @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.3">3.3. Path (rfc3986)</a>
2394  
        @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.4">3.4. Query (rfc3986)</a>
2411  
        @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.4">3.4. Query (rfc3986)</a>
2395  

2412  

2396  
        @see
2413  
        @see
2397  
            @ref encoded_origin,
2414  
            @ref encoded_origin,
2398  
            @ref encoded_resource.
2415  
            @ref encoded_resource.
2399  

2416  

2400  
        @return The target portion of the url.
2417  
        @return The target portion of the url.
2401  
    */
2418  
    */
2402  
    pct_string_view
2419  
    pct_string_view
2403  
    encoded_target() const noexcept;
2420  
    encoded_target() const noexcept;
2404  

2421  

2405  
    //--------------------------------------------
2422  
    //--------------------------------------------
2406  
    //
2423  
    //
2407  
    // Comparison
2424  
    // Comparison
2408  
    //
2425  
    //
2409  
    //--------------------------------------------
2426  
    //--------------------------------------------
2410  

2427  

2411  
    /** Return the result of comparing this with another url
2428  
    /** Return the result of comparing this with another url
2412  

2429  

2413  
        This function compares two URLs
2430  
        This function compares two URLs
2414  
        according to Syntax-Based comparison
2431  
        according to Syntax-Based comparison
2415  
        algorithm.
2432  
        algorithm.
2416  

2433  

2417  
        @par Complexity
2434  
        @par Complexity
2418  
        Linear in `min( u0.size(), u1.size() )`
2435  
        Linear in `min( u0.size(), u1.size() )`
2419  

2436  

2420  
        @par Exception Safety
2437  
        @par Exception Safety
2421  
        Throws nothing.
2438  
        Throws nothing.
2422  

2439  

2423  
        @par Specification
2440  
        @par Specification
2424  
        @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-6.2.2">6.2.2 Syntax-Based Normalization (rfc3986)</a>
2441  
        @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-6.2.2">6.2.2 Syntax-Based Normalization (rfc3986)</a>
2425  

2442  

2426  
        @param other The url to compare
2443  
        @param other The url to compare
2427  
        @return -1 if `*this < other`, 0 if `this == other`, and 1 if `this > other`.
2444  
        @return -1 if `*this < other`, 0 if `this == other`, and 1 if `this > other`.
2428  
    */
2445  
    */
2429  
    int
2446  
    int
2430  
    compare(url_view_base const& other) const noexcept;
2447  
    compare(url_view_base const& other) const noexcept;
2431  

2448  

2432  
    /** Return the result of comparing two URLs
2449  
    /** Return the result of comparing two URLs
2433  

2450  

2434  
        The URLs are compared component by
2451  
        The URLs are compared component by
2435  
        component as if they were first
2452  
        component as if they were first
2436  
        normalized.
2453  
        normalized.
2437  

2454  

2438  
        @par Example
2455  
        @par Example
2439  
        @code
2456  
        @code
2440  
        url_view u0( "http://www.a.com/index.htm" );
2457  
        url_view u0( "http://www.a.com/index.htm" );
2441  
        url_view u1( "http://www.a.com/index.htm" );
2458  
        url_view u1( "http://www.a.com/index.htm" );
2442  
        assert( u0 == u1 );
2459  
        assert( u0 == u1 );
2443  
        @endcode
2460  
        @endcode
2444  

2461  

2445  
        @par Effects
2462  
        @par Effects
2446  
        @code
2463  
        @code
2447  
        url a(u0);
2464  
        url a(u0);
2448  
        a.normalize();
2465  
        a.normalize();
2449  
        url b(u1);
2466  
        url b(u1);
2450  
        b.normalize();
2467  
        b.normalize();
2451  
        return a.buffer() == b.buffer();
2468  
        return a.buffer() == b.buffer();
2452  
        @endcode
2469  
        @endcode
2453  

2470  

2454  
        @par Complexity
2471  
        @par Complexity
2455  
        Linear in `min( u0.size(), u1.size() )`
2472  
        Linear in `min( u0.size(), u1.size() )`
2456  

2473  

2457  
        @par Exception Safety
2474  
        @par Exception Safety
2458  
        Throws nothing
2475  
        Throws nothing
2459  

2476  

2460  
        @param u0 The first url to compare
2477  
        @param u0 The first url to compare
2461  
        @param u1 The second url to compare
2478  
        @param u1 The second url to compare
2462  
        @return `true` if `u0 == u1`
2479  
        @return `true` if `u0 == u1`
2463  

2480  

2464  
        @par Specification
2481  
        @par Specification
2465  
        @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-6.2.2">6.2.2 Syntax-Based Normalization (rfc3986)</a>
2482  
        @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-6.2.2">6.2.2 Syntax-Based Normalization (rfc3986)</a>
2466  
    */
2483  
    */
2467  
    friend
2484  
    friend
2468  
    bool
2485  
    bool
2469  
    operator==(
2486  
    operator==(
2470  
        url_view_base const& u0,
2487  
        url_view_base const& u0,
2471  
        url_view_base const& u1) noexcept
2488  
        url_view_base const& u1) noexcept
2472  
    {
2489  
    {
2473  
        return u0.compare(u1) == 0;
2490  
        return u0.compare(u1) == 0;
2474  
    }
2491  
    }
2475  

2492  

2476  
    /** Return the result of comparing two URLs
2493  
    /** Return the result of comparing two URLs
2477  

2494  

2478  
        The URLs are compared component by
2495  
        The URLs are compared component by
2479  
        component as if they were first
2496  
        component as if they were first
2480  
        normalized.
2497  
        normalized.
2481  

2498  

2482  
        @par Example
2499  
        @par Example
2483  
        @code
2500  
        @code
2484  
        url_view u0( "http://www.a.com/index.htm" );
2501  
        url_view u0( "http://www.a.com/index.htm" );
2485  
        url_view u1( "http://www.b.com/index.htm" );
2502  
        url_view u1( "http://www.b.com/index.htm" );
2486  
        assert( u0 != u1 );
2503  
        assert( u0 != u1 );
2487  
        @endcode
2504  
        @endcode
2488  

2505  

2489  
        @par Effects
2506  
        @par Effects
2490  
        @code
2507  
        @code
2491  
        url a(u0);
2508  
        url a(u0);
2492  
        a.normalize();
2509  
        a.normalize();
2493  
        url b(u1);
2510  
        url b(u1);
2494  
        b.normalize();
2511  
        b.normalize();
2495  
        return a.buffer() != b.buffer();
2512  
        return a.buffer() != b.buffer();
2496  
        @endcode
2513  
        @endcode
2497  

2514  

2498  
        @par Complexity
2515  
        @par Complexity
2499  
        Linear in `min( u0.size(), u1.size() )`
2516  
        Linear in `min( u0.size(), u1.size() )`
2500  

2517  

2501  
        @par Exception Safety
2518  
        @par Exception Safety
2502  
        Throws nothing
2519  
        Throws nothing
2503  

2520  

2504  
        @param u0 The first url to compare
2521  
        @param u0 The first url to compare
2505  
        @param u1 The second url to compare
2522  
        @param u1 The second url to compare
2506  
        @return `true` if `u0 != u1`
2523  
        @return `true` if `u0 != u1`
2507  

2524  

2508  
        @par Specification
2525  
        @par Specification
2509  
        @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-6.2.2">6.2.2 Syntax-Based Normalization (rfc3986)</a>
2526  
        @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-6.2.2">6.2.2 Syntax-Based Normalization (rfc3986)</a>
2510  
    */
2527  
    */
2511  
    friend
2528  
    friend
2512  
    bool
2529  
    bool
2513  
    operator!=(
2530  
    operator!=(
2514  
        url_view_base const& u0,
2531  
        url_view_base const& u0,
2515  
        url_view_base const& u1) noexcept
2532  
        url_view_base const& u1) noexcept
2516  
    {
2533  
    {
2517  
        return ! (u0 == u1);
2534  
        return ! (u0 == u1);
2518  
    }
2535  
    }
2519  

2536  

2520  
    /** Return the result of comparing two URLs
2537  
    /** Return the result of comparing two URLs
2521  

2538  

2522  
        The URLs are compared component by
2539  
        The URLs are compared component by
2523  
        component as if they were first
2540  
        component as if they were first
2524  
        normalized.
2541  
        normalized.
2525  

2542  

2526  
        @par Example
2543  
        @par Example
2527  
        @code
2544  
        @code
2528  
        url_view u0( "http://www.a.com/index.htm" );
2545  
        url_view u0( "http://www.a.com/index.htm" );
2529  
        url_view u1( "http://www.b.com/index.htm" );
2546  
        url_view u1( "http://www.b.com/index.htm" );
2530  
        assert( u0 < u1 );
2547  
        assert( u0 < u1 );
2531  
        @endcode
2548  
        @endcode
2532  

2549  

2533  
        @par Effects
2550  
        @par Effects
2534  
        @code
2551  
        @code
2535  
        url a(u0);
2552  
        url a(u0);
2536  
        a.normalize();
2553  
        a.normalize();
2537  
        url b(u1);
2554  
        url b(u1);
2538  
        b.normalize();
2555  
        b.normalize();
2539  
        return a.buffer() < b.buffer();
2556  
        return a.buffer() < b.buffer();
2540  
        @endcode
2557  
        @endcode
2541  

2558  

2542  
        @par Complexity
2559  
        @par Complexity
2543  
        Linear in `min( u0.size(), u1.size() )`
2560  
        Linear in `min( u0.size(), u1.size() )`
2544  

2561  

2545  
        @par Exception Safety
2562  
        @par Exception Safety
2546  
        Throws nothing
2563  
        Throws nothing
2547  

2564  

2548  
        @param u0 The first url to compare
2565  
        @param u0 The first url to compare
2549  
        @param u1 The second url to compare
2566  
        @param u1 The second url to compare
2550  
        @return `true` if `u0 < u1`
2567  
        @return `true` if `u0 < u1`
2551  

2568  

2552  
        @par Specification
2569  
        @par Specification
2553  
        @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-6.2.2">6.2.2 Syntax-Based Normalization (rfc3986)</a>
2570  
        @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-6.2.2">6.2.2 Syntax-Based Normalization (rfc3986)</a>
2554  
    */
2571  
    */
2555  
    friend
2572  
    friend
2556  
    bool
2573  
    bool
2557  
    operator<(
2574  
    operator<(
2558  
        url_view_base const& u0,
2575  
        url_view_base const& u0,
2559  
        url_view_base const& u1) noexcept
2576  
        url_view_base const& u1) noexcept
2560  
    {
2577  
    {
2561  
        return u0.compare(u1) < 0;
2578  
        return u0.compare(u1) < 0;
2562  
    }
2579  
    }
2563  

2580  

2564  
    /** Return the result of comparing two URLs
2581  
    /** Return the result of comparing two URLs
2565  

2582  

2566  
        The URLs are compared component by
2583  
        The URLs are compared component by
2567  
        component as if they were first
2584  
        component as if they were first
2568  
        normalized.
2585  
        normalized.
2569  

2586  

2570  
        @par Example
2587  
        @par Example
2571  
        @code
2588  
        @code
2572  
        url_view u0( "http://www.b.com/index.htm" );
2589  
        url_view u0( "http://www.b.com/index.htm" );
2573  
        url_view u1( "http://www.b.com/index.htm" );
2590  
        url_view u1( "http://www.b.com/index.htm" );
2574  
        assert( u0 <= u1 );
2591  
        assert( u0 <= u1 );
2575  
        @endcode
2592  
        @endcode
2576  

2593  

2577  
        @par Effects
2594  
        @par Effects
2578  
        @code
2595  
        @code
2579  
        url a(u0);
2596  
        url a(u0);
2580  
        a.normalize();
2597  
        a.normalize();
2581  
        url b(u1);
2598  
        url b(u1);
2582  
        b.normalize();
2599  
        b.normalize();
2583  
        return a.buffer() <= b.buffer();
2600  
        return a.buffer() <= b.buffer();
2584  
        @endcode
2601  
        @endcode
2585  

2602  

2586  
        @par Complexity
2603  
        @par Complexity
2587  
        Linear in `min( u0.size(), u1.size() )`
2604  
        Linear in `min( u0.size(), u1.size() )`
2588  

2605  

2589  
        @par Exception Safety
2606  
        @par Exception Safety
2590  
        Throws nothing
2607  
        Throws nothing
2591  

2608  

2592  
        @param u0 The first url to compare
2609  
        @param u0 The first url to compare
2593  
        @param u1 The second url to compare
2610  
        @param u1 The second url to compare
2594  
        @return `true` if `u0 <= u1`
2611  
        @return `true` if `u0 <= u1`
2595  

2612  

2596  
        @par Specification
2613  
        @par Specification
2597  
        @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-6.2.2">6.2.2 Syntax-Based Normalization (rfc3986)</a>
2614  
        @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-6.2.2">6.2.2 Syntax-Based Normalization (rfc3986)</a>
2598  
    */
2615  
    */
2599  
    friend
2616  
    friend
2600  
    bool
2617  
    bool
2601  
    operator<=(
2618  
    operator<=(
2602  
        url_view_base const& u0,
2619  
        url_view_base const& u0,
2603  
        url_view_base const& u1) noexcept
2620  
        url_view_base const& u1) noexcept
2604  
    {
2621  
    {
2605  
        return u0.compare(u1) <= 0;
2622  
        return u0.compare(u1) <= 0;
2606  
    }
2623  
    }
2607  

2624  

2608  
    /** Return the result of comparing two URLs
2625  
    /** Return the result of comparing two URLs
2609  

2626  

2610  
        The URLs are compared component by
2627  
        The URLs are compared component by
2611  
        component as if they were first
2628  
        component as if they were first
2612  
        normalized.
2629  
        normalized.
2613  

2630  

2614  
        @par Example
2631  
        @par Example
2615  
        @code
2632  
        @code
2616  
        url_view u0( "http://www.b.com/index.htm" );
2633  
        url_view u0( "http://www.b.com/index.htm" );
2617  
        url_view u1( "http://www.a.com/index.htm" );
2634  
        url_view u1( "http://www.a.com/index.htm" );
2618  
        assert( u0 > u1 );
2635  
        assert( u0 > u1 );
2619  
        @endcode
2636  
        @endcode
2620  

2637  

2621  
        @par Effects
2638  
        @par Effects
2622  
        @code
2639  
        @code
2623  
        url a(u0);
2640  
        url a(u0);
2624  
        a.normalize();
2641  
        a.normalize();
2625  
        url b(u1);
2642  
        url b(u1);
2626  
        b.normalize();
2643  
        b.normalize();
2627  
        return a.buffer() > b.buffer();
2644  
        return a.buffer() > b.buffer();
2628  
        @endcode
2645  
        @endcode
2629  

2646  

2630  
        @par Complexity
2647  
        @par Complexity
2631  
        Linear in `min( u0.size(), u1.size() )`
2648  
        Linear in `min( u0.size(), u1.size() )`
2632  

2649  

2633  
        @par Exception Safety
2650  
        @par Exception Safety
2634  
        Throws nothing
2651  
        Throws nothing
2635  

2652  

2636  
        @param u0 The first url to compare
2653  
        @param u0 The first url to compare
2637  
        @param u1 The second url to compare
2654  
        @param u1 The second url to compare
2638  
        @return `true` if `u0 > u1`
2655  
        @return `true` if `u0 > u1`
2639  

2656  

2640  
        @par Specification
2657  
        @par Specification
2641  
        @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-6.2.2">6.2.2 Syntax-Based Normalization (rfc3986)</a>
2658  
        @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-6.2.2">6.2.2 Syntax-Based Normalization (rfc3986)</a>
2642  
    */
2659  
    */
2643  
    friend
2660  
    friend
2644  
    bool
2661  
    bool
2645  
    operator>(
2662  
    operator>(
2646  
        url_view_base const& u0,
2663  
        url_view_base const& u0,
2647  
        url_view_base const& u1) noexcept
2664  
        url_view_base const& u1) noexcept
2648  
    {
2665  
    {
2649  
        return u0.compare(u1) > 0;
2666  
        return u0.compare(u1) > 0;
2650  
    }
2667  
    }
2651  

2668  

2652  
    /** Return the result of comparing two URLs
2669  
    /** Return the result of comparing two URLs
2653  

2670  

2654  
        The URLs are compared component by
2671  
        The URLs are compared component by
2655  
        component as if they were first
2672  
        component as if they were first
2656  
        normalized.
2673  
        normalized.
2657  

2674  

2658  
        @par Example
2675  
        @par Example
2659  
        @code
2676  
        @code
2660  
        url_view u0( "http://www.a.com/index.htm" );
2677  
        url_view u0( "http://www.a.com/index.htm" );
2661  
        url_view u1( "http://www.a.com/index.htm" );
2678  
        url_view u1( "http://www.a.com/index.htm" );
2662  
        assert( u0 >= u1 );
2679  
        assert( u0 >= u1 );
2663  
        @endcode
2680  
        @endcode
2664  

2681  

2665  
        @par Effects
2682  
        @par Effects
2666  
        @code
2683  
        @code
2667  
        url a(u0);
2684  
        url a(u0);
2668  
        a.normalize();
2685  
        a.normalize();
2669  
        url b(u1);
2686  
        url b(u1);
2670  
        b.normalize();
2687  
        b.normalize();
2671  
        return a.buffer() >= b.buffer();
2688  
        return a.buffer() >= b.buffer();
2672  
        @endcode
2689  
        @endcode
2673  

2690  

2674  
        @par Complexity
2691  
        @par Complexity
2675  
        Linear in `min( u0.size(), u1.size() )`
2692  
        Linear in `min( u0.size(), u1.size() )`
2676  

2693  

2677  
        @par Exception Safety
2694  
        @par Exception Safety
2678  
        Throws nothing
2695  
        Throws nothing
2679  

2696  

2680  
        @param u0 The first url to compare
2697  
        @param u0 The first url to compare
2681  
        @param u1 The second url to compare
2698  
        @param u1 The second url to compare
2682  
        @return `true` if `u0 >= u1`
2699  
        @return `true` if `u0 >= u1`
2683  

2700  

2684  
        @par Specification
2701  
        @par Specification
2685  
        @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-6.2.2">6.2.2 Syntax-Based Normalization (rfc3986)</a>
2702  
        @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-6.2.2">6.2.2 Syntax-Based Normalization (rfc3986)</a>
2686  
    */
2703  
    */
2687  
    friend
2704  
    friend
2688  
    bool
2705  
    bool
2689  
    operator>=(
2706  
    operator>=(
2690  
        url_view_base const& u0,
2707  
        url_view_base const& u0,
2691  
        url_view_base const& u1) noexcept
2708  
        url_view_base const& u1) noexcept
2692  
    {
2709  
    {
2693  
        return u0.compare(u1) >= 0;
2710  
        return u0.compare(u1) >= 0;
2694  
    }
2711  
    }
2695  

2712  

2696  
    /** Format the url to the output stream
2713  
    /** Format the url to the output stream
2697  

2714  

2698  
        This function serializes the url to
2715  
        This function serializes the url to
2699  
        the specified output stream. Any
2716  
        the specified output stream. Any
2700  
        percent-escapes are emitted as-is;
2717  
        percent-escapes are emitted as-is;
2701  
        no decoding is performed.
2718  
        no decoding is performed.
2702  

2719  

2703  
        @par Example
2720  
        @par Example
2704  
        @code
2721  
        @code
2705  
        url_view u( "http://www.example.com/index.htm" );
2722  
        url_view u( "http://www.example.com/index.htm" );
2706  
        std::stringstream ss;
2723  
        std::stringstream ss;
2707  
        ss << u;
2724  
        ss << u;
2708  
        assert( ss.str() == "http://www.example.com/index.htm" );
2725  
        assert( ss.str() == "http://www.example.com/index.htm" );
2709  
        @endcode
2726  
        @endcode
2710  

2727  

2711  
        @par Effects
2728  
        @par Effects
2712  
        @code
2729  
        @code
2713  
        return os << u.buffer();
2730  
        return os << u.buffer();
2714  
        @endcode
2731  
        @endcode
2715  

2732  

2716  
        @par Complexity
2733  
        @par Complexity
2717  
        Linear in `u.buffer().size()`
2734  
        Linear in `u.buffer().size()`
2718  

2735  

2719  
        @par Exception Safety
2736  
        @par Exception Safety
2720  
        Basic guarantee.
2737  
        Basic guarantee.
2721  

2738  

2722  
        @return A reference to the output stream, for chaining
2739  
        @return A reference to the output stream, for chaining
2723  

2740  

2724  
        @param os The output stream to write to.
2741  
        @param os The output stream to write to.
2725  

2742  

2726  
        @param u The url to write.
2743  
        @param u The url to write.
2727  
    */
2744  
    */
2728  
    friend
2745  
    friend
2729  
    std::ostream&
2746  
    std::ostream&
2730  
    operator<<(
2747  
    operator<<(
2731  
        std::ostream& os,
2748  
        std::ostream& os,
2732  
        url_view_base const& u)
2749  
        url_view_base const& u)
2733  
    {
2750  
    {
2734  
        return os << u.buffer();
2751  
        return os << u.buffer();
2735  
    }
2752  
    }
2736  

2753  

2737  
private:
2754  
private:
2738  
    //--------------------------------------------
2755  
    //--------------------------------------------
2739  
    //
2756  
    //
2740  
    // implementation
2757  
    // implementation
2741  
    //
2758  
    //
2742  
    //--------------------------------------------
2759  
    //--------------------------------------------
2743  
    static
2760  
    static
2744  
    int
2761  
    int
2745  
    segments_compare(
2762  
    segments_compare(
2746  
        segments_encoded_view seg0,
2763  
        segments_encoded_view seg0,
2747  
        segments_encoded_view seg1) noexcept;
2764  
        segments_encoded_view seg1) noexcept;
2748  
};
2765  
};
2749  

2766  

2750  
//------------------------------------------------
2767  
//------------------------------------------------
2751  

2768  

2752  
/** Format the url to the output stream
2769  
/** Format the url to the output stream
2753  

2770  

2754  
    This function serializes the url to
2771  
    This function serializes the url to
2755  
    the specified output stream. Any
2772  
    the specified output stream. Any
2756  
    percent-escapes are emitted as-is;
2773  
    percent-escapes are emitted as-is;
2757  
    no decoding is performed.
2774  
    no decoding is performed.
2758  

2775  

2759  
    @par Example
2776  
    @par Example
2760  
    @code
2777  
    @code
2761  
    url_view u( "http://www.example.com/index.htm" );
2778  
    url_view u( "http://www.example.com/index.htm" );
2762  
    std::stringstream ss;
2779  
    std::stringstream ss;
2763  
    ss << u;
2780  
    ss << u;
2764  
    assert( ss.str() == "http://www.example.com/index.htm" );
2781  
    assert( ss.str() == "http://www.example.com/index.htm" );
2765  
    @endcode
2782  
    @endcode
2766  

2783  

2767  
    @par Effects
2784  
    @par Effects
2768  
    @code
2785  
    @code
2769  
    return os << u.buffer();
2786  
    return os << u.buffer();
2770  
    @endcode
2787  
    @endcode
2771  

2788  

2772  
    @par Complexity
2789  
    @par Complexity
2773  
    Linear in `u.buffer().size()`
2790  
    Linear in `u.buffer().size()`
2774  

2791  

2775  
    @par Exception Safety
2792  
    @par Exception Safety
2776  
    Basic guarantee.
2793  
    Basic guarantee.
2777  

2794  

2778  
    @return A reference to the output stream, for chaining
2795  
    @return A reference to the output stream, for chaining
2779  

2796  

2780  
    @param os The output stream to write to.
2797  
    @param os The output stream to write to.
2781  

2798  

2782  
    @param u The url to write.
2799  
    @param u The url to write.
2783  
*/
2800  
*/
2784  
std::ostream&
2801  
std::ostream&
2785  
operator<<(
2802  
operator<<(
2786  
    std::ostream& os,
2803  
    std::ostream& os,
2787  
    url_view_base const& u);
2804  
    url_view_base const& u);
2788  

2805  

2789  
} // urls
2806  
} // urls
2790  
} // boost
2807  
} // boost
 
2808 +

 
2809 +
#include <boost/url/impl/url_view_base.hpp>
2791  

2810  

2792  
#endif
2811  
#endif