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 BOOST_URL_DECL
66  
    url_view_base
66  
    url_view_base
67  
    : private detail::parts_base
67  
    : private detail::parts_base
68  
{
68  
{
69  
    detail::url_impl impl_;
69  
    detail::url_impl impl_;
70  
    detail::url_impl const* pi_;
70  
    detail::url_impl const* pi_;
71  

71  

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

89  

90  
    struct shared_impl;
90  
    struct shared_impl;
91  

91  

92  
    url_view_base() noexcept;
92  
    url_view_base() noexcept;
93  

93  

94  
    explicit url_view_base(
94  
    explicit url_view_base(
95  
        detail::url_impl const&) noexcept;
95  
        detail::url_impl const&) noexcept;
96  

96  

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

98  

99  
    url_view_base(
99  
    url_view_base(
100  
        url_view_base const& o) noexcept
100  
        url_view_base const& o) noexcept
101  
        : impl_(o.impl_)
101  
        : impl_(o.impl_)
102  
        , pi_(o.pi_)
102  
        , pi_(o.pi_)
103  
    {
103  
    {
104  
        if (pi_ == &o.impl_)
104  
        if (pi_ == &o.impl_)
105  
            pi_ = &impl_;
105  
            pi_ = &impl_;
106  
    }
106  
    }
107  

107  

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

110  

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

113  

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

116  

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

119  

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

122  

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

125  

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

131  

132  
public:
132  
public:
133  
    //--------------------------------------------
133  
    //--------------------------------------------
134  
    //
134  
    //
135  
    // Observers
135  
    // Observers
136  
    //
136  
    //
137  
    //--------------------------------------------
137  
    //--------------------------------------------
138  

138  

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

140  

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

147  

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

150  

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

153  

154  
        @return The maximum number of characters.
154  
        @return The maximum number of characters.
155  
    */
155  
    */
156  
    static
156  
    static
157  
    constexpr
157  
    constexpr
158  
    std::size_t
158  
    std::size_t
159  
    max_size() noexcept
159  
    max_size() noexcept
160  
    {
160  
    {
161  
        return BOOST_URL_MAX_SIZE;
161  
        return BOOST_URL_MAX_SIZE;
162  
    }
162  
    }
163  

163  

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

165  

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

170  

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

175  

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

178  

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

181  

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

189  

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

191  

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

194  

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

199  

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

202  

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

205  

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

209  

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

215  

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

218  

219  
        @return `true` if the url is empty.
219  
        @return `true` if the url is empty.
220  
    */
220  
    */
221  
    bool
221  
    bool
222  
    empty() const noexcept
222  
    empty() const noexcept
223  
    {
223  
    {
224  
        return pi_->offset(id_end) == 0;
224  
        return pi_->offset(id_end) == 0;
225  
    }
225  
    }
226  

226  

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

228  

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

232  

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

235  

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

238  

239  
        @return A pointer to the first character.
239  
        @return A pointer to the first character.
240  
    */
240  
    */
241  
    char const*
241  
    char const*
242  
    data() const noexcept
242  
    data() const noexcept
243  
    {
243  
    {
244  
        return pi_->cs_;
244  
        return pi_->cs_;
245  
    }
245  
    }
246  

246  

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

248  

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

251  

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

256  

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

259  

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

262  

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

271  

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

273  

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

276  

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

279  

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

286  

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

288  

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

296  

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

303  

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

305  

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

307  

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

310  

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

315  

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

318  

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

321  

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

326  

327  
    //--------------------------------------------
327  
    //--------------------------------------------
328  
    //
328  
    //
329  
    // Scheme
329  
    // Scheme
330  
    //
330  
    //
331  
    //--------------------------------------------
331  
    //--------------------------------------------
332  

332  

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

334  

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

337  

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

342  

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

345  

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

348  

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

352  

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

354  

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

357  

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

360  

361  
        @see
361  
        @see
362  
            @ref scheme,
362  
            @ref scheme,
363  
            @ref scheme_id.
363  
            @ref scheme_id.
364  

364  

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

369  

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

371  

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

377  

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

382  

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

385  

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

389  

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

391  

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

394  

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

397  

398  
        @see
398  
        @see
399  
            @ref has_scheme,
399  
            @ref has_scheme,
400  
            @ref scheme_id.
400  
            @ref scheme_id.
401  

401  

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

406  

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

408  

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

411  

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

416  

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

420  

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

424  

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

429  

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

432  

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

435  

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

439  

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

441  

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

444  

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

447  

448  
        @see
448  
        @see
449  
            @ref has_scheme,
449  
            @ref has_scheme,
450  
            @ref scheme.
450  
            @ref scheme.
451  

451  

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

456  

457  
    //--------------------------------------------
457  
    //--------------------------------------------
458  
    //
458  
    //
459  
    // Authority
459  
    // Authority
460  
    //
460  
    //
461  
    //--------------------------------------------
461  
    //--------------------------------------------
462  

462  

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

464  

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

470  

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

475  

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

478  

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

481  

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

485  

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

487  

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

489  

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

491  

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

493  

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

496  

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

499  

500  
        @endcode
500  
        @endcode
501  

501  

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

504  

505  
        @see
505  
        @see
506  
            @ref authority,
506  
            @ref authority,
507  
            @ref encoded_authority.
507  
            @ref encoded_authority.
508  

508  

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

516  

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

518  

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

521  

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

526  

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

529  

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

532  

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

537  

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

540  

541  
        @see
541  
        @see
542  
            @ref encoded_authority,
542  
            @ref encoded_authority,
543  
            @ref has_authority.
543  
            @ref has_authority.
544  

544  

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

549  

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

551  

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

558  

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

563  

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

566  

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

569  

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

574  

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

577  

578  
        @see
578  
        @see
579  
            @ref authority,
579  
            @ref authority,
580  
            @ref has_authority.
580  
            @ref has_authority.
581  

581  

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

586  

587  
    //--------------------------------------------
587  
    //--------------------------------------------
588  
    //
588  
    //
589  
    // Userinfo
589  
    // Userinfo
590  
    //
590  
    //
591  
    //--------------------------------------------
591  
    //--------------------------------------------
592  

592  

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

594  

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

597  

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

602  

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

605  

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

608  

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

612  

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

615  

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

618  

619  
        @see
619  
        @see
620  
            @ref has_password,
620  
            @ref has_password,
621  
            @ref encoded_password,
621  
            @ref encoded_password,
622  
            @ref encoded_user,
622  
            @ref encoded_user,
623  
            @ref encoded_userinfo,
623  
            @ref encoded_userinfo,
624  
            @ref password,
624  
            @ref password,
625  
            @ref user,
625  
            @ref user,
626  
            @ref userinfo.
626  
            @ref userinfo.
627  

627  

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

632  

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

634  

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

638  

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

643  

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

646  

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

649  

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

653  

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

657  

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

660  

661  
        @see
661  
        @see
662  
            @ref has_userinfo,
662  
            @ref has_userinfo,
663  
            @ref encoded_password,
663  
            @ref encoded_password,
664  
            @ref encoded_user,
664  
            @ref encoded_user,
665  
            @ref encoded_userinfo,
665  
            @ref encoded_userinfo,
666  
            @ref password,
666  
            @ref password,
667  
            @ref user,
667  
            @ref user,
668  
            @ref userinfo.
668  
            @ref userinfo.
669  

669  

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

674  

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

676  

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

683  

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

691  

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

696  

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

699  

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

702  

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

708  

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

712  

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

715  

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

718  

719  
        @see
719  
        @see
720  
            @ref has_password,
720  
            @ref has_password,
721  
            @ref has_userinfo,
721  
            @ref has_userinfo,
722  
            @ref encoded_password,
722  
            @ref encoded_password,
723  
            @ref encoded_user,
723  
            @ref encoded_user,
724  
            @ref encoded_userinfo,
724  
            @ref encoded_userinfo,
725  
            @ref password,
725  
            @ref password,
726  
            @ref user.
726  
            @ref user.
727  

727  

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

741  

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

743  

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

750  

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

755  

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

758  

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

761  

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

765  

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

768  

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

771  

772  
        @see
772  
        @see
773  
            @ref has_password,
773  
            @ref has_password,
774  
            @ref has_userinfo,
774  
            @ref has_userinfo,
775  
            @ref encoded_password,
775  
            @ref encoded_password,
776  
            @ref encoded_user,
776  
            @ref encoded_user,
777  
            @ref password,
777  
            @ref password,
778  
            @ref user,
778  
            @ref user,
779  
            @ref userinfo.
779  
            @ref userinfo.
780  

780  

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

785  

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

787  

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

789  

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

796  

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

801  

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

804  

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

807  

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

811  

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

815  

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

818  

819  
        @see
819  
        @see
820  
            @ref has_password,
820  
            @ref has_password,
821  
            @ref has_userinfo,
821  
            @ref has_userinfo,
822  
            @ref encoded_password,
822  
            @ref encoded_password,
823  
            @ref encoded_user,
823  
            @ref encoded_user,
824  
            @ref encoded_userinfo,
824  
            @ref encoded_userinfo,
825  
            @ref password,
825  
            @ref password,
826  
            @ref userinfo.
826  
            @ref userinfo.
827  

827  

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

841  

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

843  

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

850  

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

855  

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

858  

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

861  

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

865  

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

869  

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

872  

873  
        @see
873  
        @see
874  
            @ref has_password,
874  
            @ref has_password,
875  
            @ref has_userinfo,
875  
            @ref has_userinfo,
876  
            @ref encoded_password,
876  
            @ref encoded_password,
877  
            @ref encoded_userinfo,
877  
            @ref encoded_userinfo,
878  
            @ref password,
878  
            @ref password,
879  
            @ref user,
879  
            @ref user,
880  
            @ref userinfo.
880  
            @ref userinfo.
881  

881  

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

886  

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

888  

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

895  

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

900  

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

903  

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

906  

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

910  

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

914  

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

917  

918  
        @see
918  
        @see
919  
            @ref has_password,
919  
            @ref has_password,
920  
            @ref has_userinfo,
920  
            @ref has_userinfo,
921  
            @ref encoded_password,
921  
            @ref encoded_password,
922  
            @ref encoded_user,
922  
            @ref encoded_user,
923  
            @ref encoded_userinfo,
923  
            @ref encoded_userinfo,
924  
            @ref user,
924  
            @ref user,
925  
            @ref userinfo.
925  
            @ref userinfo.
926  

926  

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

940  

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

942  

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

945  

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

950  

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

953  

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

956  

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

960  

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

964  

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

967  

968  
        @see
968  
        @see
969  
            @ref has_password,
969  
            @ref has_password,
970  
            @ref has_userinfo,
970  
            @ref has_userinfo,
971  
            @ref encoded_user,
971  
            @ref encoded_user,
972  
            @ref encoded_userinfo,
972  
            @ref encoded_userinfo,
973  
            @ref password,
973  
            @ref password,
974  
            @ref user,
974  
            @ref user,
975  
            @ref userinfo.
975  
            @ref userinfo.
976  

976  

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

981  

982  
    //--------------------------------------------
982  
    //--------------------------------------------
983  
    //
983  
    //
984  
    // Host
984  
    // Host
985  
    //
985  
    //
986  
    //--------------------------------------------
986  
    //--------------------------------------------
987  

987  

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

989  

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

993  

994  
        @li @ref host_type::ipv4
994  
        @li @ref host_type::ipv4
995  
        @li @ref host_type::ipv6
995  
        @li @ref host_type::ipv6
996  
        @li @ref host_type::ipvfuture
996  
        @li @ref host_type::ipvfuture
997  
        @li @ref host_type::name
997  
        @li @ref host_type::name
998  
        @li @ref host_type::none
998  
        @li @ref host_type::none
999  

999  

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

1002  

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

1007  

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

1010  

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

1013  

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

1016  

1017  
        @return The type of host present.
1017  
        @return The type of host present.
1018  
    */
1018  
    */
1019  
    urls::host_type
1019  
    urls::host_type
1020  
    host_type() const noexcept
1020  
    host_type() const noexcept
1021  
    {
1021  
    {
1022  
        return pi_->host_type_;
1022  
        return pi_->host_type_;
1023  
    }
1023  
    }
1024  

1024  

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

1026  

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

1032  

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

1037  

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

1040  

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

1043  

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

1047  

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

1049  

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

1052  

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

1055  

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

1069  

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

1071  

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

1077  

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

1082  

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

1085  

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

1088  

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

1092  

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

1094  

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

1097  

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

1100  

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

1105  

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

1107  

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

1111  

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

1114  

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

1118  

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

1122  

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

1127  

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

1130  

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

1135  

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

1138  

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

1141  

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

1145  

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

1147  

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

1150  

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

1153  

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

1167  

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

1169  

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

1173  

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

1176  

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

1180  

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

1184  

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

1189  

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

1194  

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

1199  

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

1202  

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

1205  

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

1209  

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

1211  

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

1214  

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

1217  

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

1222  

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

1224  

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

1232  

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

1237  

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

1240  

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

1243  

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

1247  

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

1254  

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

1257  

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

1262  

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

1264  

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

1272  

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

1277  

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

1280  

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

1283  

1284  
        @par BNF
1284  
        @par BNF
1285  
        @code
1285  
        @code
1286  
        IPv6address =                            6( h16 ":" ) ls32
1286  
        IPv6address =                            6( h16 ":" ) ls32
1287  
                    /                       "::" 5( h16 ":" ) ls32
1287  
                    /                       "::" 5( h16 ":" ) ls32
1288  
                    / [               h16 ] "::" 4( h16 ":" ) ls32
1288  
                    / [               h16 ] "::" 4( h16 ":" ) ls32
1289  
                    / [ *1( h16 ":" ) h16 ] "::" 3( h16 ":" ) ls32
1289  
                    / [ *1( h16 ":" ) h16 ] "::" 3( h16 ":" ) ls32
1290  
                    / [ *2( h16 ":" ) h16 ] "::" 2( h16 ":" ) ls32
1290  
                    / [ *2( h16 ":" ) h16 ] "::" 2( h16 ":" ) ls32
1291  
                    / [ *3( h16 ":" ) h16 ] "::"    h16 ":"   ls32
1291  
                    / [ *3( h16 ":" ) h16 ] "::"    h16 ":"   ls32
1292  
                    / [ *4( h16 ":" ) h16 ] "::"              ls32
1292  
                    / [ *4( h16 ":" ) h16 ] "::"              ls32
1293  
                    / [ *5( h16 ":" ) h16 ] "::"              h16
1293  
                    / [ *5( h16 ":" ) h16 ] "::"              h16
1294  
                    / [ *6( h16 ":" ) h16 ] "::"
1294  
                    / [ *6( h16 ":" ) h16 ] "::"
1295  

1295  

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

1298  

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

1302  

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

1305  

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

1310  

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

1312  

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

1319  

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

1324  

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

1327  

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

1330  

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

1335  

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

1338  

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

1343  

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

1345  

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

1351  

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

1356  

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

1359  

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

1362  

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

1366  

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

1368  

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

1371  

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

1374  

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

1388  

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

1390  

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

1398  

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

1403  

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

1406  

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

1409  

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

1413  

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

1415  

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

1418  

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

1421  

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

1426  

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

1428  

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

1434  

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

1439  

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

1442  

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

1445  

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

1449  

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

1451  

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

1453  

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

1456  

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

1459  

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

1473  

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

1475  

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

1481  

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

1486  

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

1489  

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

1492  

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

1496  

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

1498  

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

1500  

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

1503  

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

1506  

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

1511  

1512  
    //--------------------------------------------
1512  
    //--------------------------------------------
1513  
    //
1513  
    //
1514  
    // Port
1514  
    // Port
1515  
    //
1515  
    //
1516  
    //--------------------------------------------
1516  
    //--------------------------------------------
1517  

1517  

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

1519  

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

1522  

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

1527  

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

1530  

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

1533  

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

1537  

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

1540  

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

1543  

1544  
        @see
1544  
        @see
1545  
            @ref encoded_host_and_port,
1545  
            @ref encoded_host_and_port,
1546  
            @ref port,
1546  
            @ref port,
1547  
            @ref port_number.
1547  
            @ref port_number.
1548  

1548  

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

1553  

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

1555  

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

1560  

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

1565  

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

1568  

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

1571  

1572  
        @par BNF
1572  
        @par BNF
1573  
        @code
1573  
        @code
1574  
        port        = *DIGIT
1574  
        port        = *DIGIT
1575  
        @endcode
1575  
        @endcode
1576  

1576  

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

1579  

1580  
        @see
1580  
        @see
1581  
            @ref encoded_host_and_port,
1581  
            @ref encoded_host_and_port,
1582  
            @ref has_port,
1582  
            @ref has_port,
1583  
            @ref port_number.
1583  
            @ref port_number.
1584  

1584  

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

1589  

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

1591  

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

1596  

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

1601  

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

1604  

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

1607  

1608  
        @par BNF
1608  
        @par BNF
1609  
        @code
1609  
        @code
1610  
        port        = *DIGIT
1610  
        port        = *DIGIT
1611  
        @endcode
1611  
        @endcode
1612  

1612  

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

1615  

1616  
        @see
1616  
        @see
1617  
            @ref encoded_host_and_port,
1617  
            @ref encoded_host_and_port,
1618  
            @ref has_port,
1618  
            @ref has_port,
1619  
            @ref port.
1619  
            @ref port.
1620  

1620  

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

1625  

1626  
    //--------------------------------------------
1626  
    //--------------------------------------------
1627  
    //
1627  
    //
1628  
    // Path
1628  
    // Path
1629  
    //
1629  
    //
1630  
    //--------------------------------------------
1630  
    //--------------------------------------------
1631  

1631  

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

1633  

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

1636  

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

1641  

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

1644  

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

1647  

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

1655  

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

1662  

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

1665  

1666  
        @see
1666  
        @see
1667  
            @ref encoded_path,
1667  
            @ref encoded_path,
1668  
            @ref encoded_segments.
1668  
            @ref encoded_segments.
1669  
            @ref path,
1669  
            @ref path,
1670  
            @ref segments.
1670  
            @ref segments.
1671  

1671  

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

1681  

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

1683  

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

1688  

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

1693  

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

1696  

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

1699  

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

1707  

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

1714  

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

1717  

1718  
        @see
1718  
        @see
1719  
            @ref is_path_absolute,
1719  
            @ref is_path_absolute,
1720  
            @ref encoded_path,
1720  
            @ref encoded_path,
1721  
            @ref encoded_segments.
1721  
            @ref encoded_segments.
1722  
            @ref segments.
1722  
            @ref segments.
1723  

1723  

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

1737  

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

1739  

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

1744  

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

1749  

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

1752  

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

1755  

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

1763  

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

1770  

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

1773  

1774  
        @see
1774  
        @see
1775  
            @ref is_path_absolute,
1775  
            @ref is_path_absolute,
1776  
            @ref encoded_segments.
1776  
            @ref encoded_segments.
1777  
            @ref path,
1777  
            @ref path,
1778  
            @ref segments.
1778  
            @ref segments.
1779  

1779  

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

1784  

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

1786  

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

1794  

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

1799  

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

1802  

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

1805  

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

1810  

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

1813  

1814  
        @see
1814  
        @see
1815  
            @ref is_path_absolute,
1815  
            @ref is_path_absolute,
1816  
            @ref encoded_path,
1816  
            @ref encoded_path,
1817  
            @ref encoded_segments.
1817  
            @ref encoded_segments.
1818  
            @ref path,
1818  
            @ref path,
1819  
            @ref segments_view.
1819  
            @ref segments_view.
1820  

1820  

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

1825  

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

1827  

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

1835  

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

1840  

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

1843  

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

1846  

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

1854  

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

1861  

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

1864  

1865  
        @see
1865  
        @see
1866  
            @ref is_path_absolute,
1866  
            @ref is_path_absolute,
1867  
            @ref encoded_path,
1867  
            @ref encoded_path,
1868  
            @ref path,
1868  
            @ref path,
1869  
            @ref segments,
1869  
            @ref segments,
1870  
            @ref segments_encoded_view.
1870  
            @ref segments_encoded_view.
1871  

1871  

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

1876  

1877  
    //--------------------------------------------
1877  
    //--------------------------------------------
1878  
    //
1878  
    //
1879  
    // Query
1879  
    // Query
1880  
    //
1880  
    //
1881  
    //--------------------------------------------
1881  
    //--------------------------------------------
1882  

1882  

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

1884  

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

1888  

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

1893  

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

1896  

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

1899  

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

1903  

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

1907  

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

1911  

1912  
        @see
1912  
        @see
1913  
            @ref encoded_params,
1913  
            @ref encoded_params,
1914  
            @ref encoded_query,
1914  
            @ref encoded_query,
1915  
            @ref params,
1915  
            @ref params,
1916  
            @ref query.
1916  
            @ref query.
1917  

1917  

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

1922  

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

1924  

1925  
        If this contains a query, it is returned
1925  
        If this contains a query, it is returned
1926  
        as a string (which may be empty).
1926  
        as a string (which may be empty).
1927  
        Otherwise, an empty string is returned.
1927  
        Otherwise, an empty string is returned.
1928  
        Any percent-escapes in the string are
1928  
        Any percent-escapes in the string are
1929  
        decoded first.
1929  
        decoded first.
1930  
        <br>
1930  
        <br>
1931 -
        When plus signs appear in the query
1931 +

1932 -
        portion of the url, they are converted
1932 +
        Literal plus signs remain unchanged by
1933 -
        to spaces automatically upon decoding.
1933 +
        default to match RFC 3986. To treat '+'
1934 -
        This behavior can be changed by setting
1934 +
        as a space, supply decoding options with
1935 -
        decode options.
1935 +
        `space_as_plus = true` when calling this
 
1936 +
        function.
1936  

1937  

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

1942  

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

1945  

1945  
        @par Exception Safety
1946  
        @par Exception Safety
1946  
        Calls to allocate may throw.
1947  
        Calls to allocate may throw.
1947  

1948  

1948  
        @par BNF
1949  
        @par BNF
1949  
        @code
1950  
        @code
1950  
        query           = *( pchar / "/" / "?" )
1951  
        query           = *( pchar / "/" / "?" )
1951  

1952  

1952  
        query-param     = key [ "=" value ]
1953  
        query-param     = key [ "=" value ]
1953  
        query-params    = [ query-param ] *( "&" query-param )
1954  
        query-params    = [ query-param ] *( "&" query-param )
1954  
        @endcode
1955  
        @endcode
1955  

1956  

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

1960  

1960  
        @see
1961  
        @see
1961  
            @ref encoded_params,
1962  
            @ref encoded_params,
1962  
            @ref encoded_query,
1963  
            @ref encoded_query,
1963  
            @ref has_query,
1964  
            @ref has_query,
1964  
            @ref params.
1965  
            @ref params.
1965  

1966  

1966  
        @param token A token to use for the returned string.
1967  
        @param token A token to use for the returned string.
1967  
        @return The query as a string.
1968  
        @return The query as a string.
1968  
    */
1969  
    */
1969  
    template<BOOST_URL_STRTOK_TPARAM>
1970  
    template<BOOST_URL_STRTOK_TPARAM>
1970  
    BOOST_URL_STRTOK_RETURN
1971  
    BOOST_URL_STRTOK_RETURN
1971  
    query(
1972  
    query(
1972  
        StringToken&& token = {}) const
1973  
        StringToken&& token = {}) const
1973  
    {
1974  
    {
1974  
        // When interacting with the query as
1975  
        // When interacting with the query as
1975  
        // an intact string, we do not treat
1976  
        // an intact string, we do not treat
1976  
        // the plus sign as an encoded space.
1977  
        // the plus sign as an encoded space.
1977  
        encoding_opts opt;
1978  
        encoding_opts opt;
1978  
        opt.space_as_plus = false;
1979  
        opt.space_as_plus = false;
1979  
        return encoded_query().decode(
1980  
        return encoded_query().decode(
1980  
            opt, std::forward<StringToken>(token));
1981  
            opt, std::forward<StringToken>(token));
1981  
    }
1982  
    }
1982  

1983  

1983  
    /** Return the query
1984  
    /** Return the query
1984  

1985  

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

1991  

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

1996  

1996  
        @par Complexity
1997  
        @par Complexity
1997  
        Constant.
1998  
        Constant.
1998  

1999  

1999  
        @par Exception Safety
2000  
        @par Exception Safety
2000  
        Throws nothing.
2001  
        Throws nothing.
2001  

2002  

2002  
        @par BNF
2003  
        @par BNF
2003  
        @code
2004  
        @code
2004  
        query           = *( pchar / "/" / "?" )
2005  
        query           = *( pchar / "/" / "?" )
2005  

2006  

2006  
        query-param     = key [ "=" value ]
2007  
        query-param     = key [ "=" value ]
2007  
        query-params    = [ query-param ] *( "&" query-param )
2008  
        query-params    = [ query-param ] *( "&" query-param )
2008  
        @endcode
2009  
        @endcode
2009  

2010  

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

2014  

2014  
        @see
2015  
        @see
2015  
            @ref encoded_params,
2016  
            @ref encoded_params,
2016  
            @ref has_query,
2017  
            @ref has_query,
2017  
            @ref params,
2018  
            @ref params,
2018  
            @ref query.
2019  
            @ref query.
2019  

2020  

2020  
        @return The query as a string.
2021  
        @return The query as a string.
2021  
    */
2022  
    */
2022  
    pct_string_view
2023  
    pct_string_view
2023  
    encoded_query() const noexcept;
2024  
    encoded_query() const noexcept;
2024  

2025  

2025  
    /** Return the query as a container of parameters
2026  
    /** Return the query as a container of parameters
2026  

2027  

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

2035  

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

2040  

2040  
        @par Complexity
2041  
        @par Complexity
2041  
        Constant.
2042  
        Constant.
2042  

2043  

2043  
        @par Exception Safety
2044  
        @par Exception Safety
2044  
        Throws nothing.
2045  
        Throws nothing.
2045  

2046  

2046  
        @par BNF
2047  
        @par BNF
2047  
        @code
2048  
        @code
2048  
        query           = *( pchar / "/" / "?" )
2049  
        query           = *( pchar / "/" / "?" )
2049  

2050  

2050  
        query-param     = key [ "=" value ]
2051  
        query-param     = key [ "=" value ]
2051  
        query-params    = [ query-param ] *( "&" query-param )
2052  
        query-params    = [ query-param ] *( "&" query-param )
2052  
        @endcode
2053  
        @endcode
2053  

2054  

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

2058  

2058  
        @see
2059  
        @see
2059  
            @ref encoded_params,
2060  
            @ref encoded_params,
2060  
            @ref encoded_query,
2061  
            @ref encoded_query,
2061  
            @ref has_query,
2062  
            @ref has_query,
2062  
            @ref query.
2063  
            @ref query.
2063  

2064  

2064  
        @return A bidirectional view of key/value pairs.
2065  
        @return A bidirectional view of key/value pairs.
2065  
    */
2066  
    */
2066  
    params_view
2067  
    params_view
2067  
    params() const noexcept;
2068  
    params() const noexcept;
2068  

2069  

2069  
    params_view
2070  
    params_view
2070  
    params(encoding_opts opt) const noexcept;
2071  
    params(encoding_opts opt) const noexcept;
2071  

2072  

2072  
    /** Return the query as a container of parameters
2073  
    /** Return the query as a container of parameters
2073  

2074  

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

2082  

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

2087  

2087  
        @par Complexity
2088  
        @par Complexity
2088  
        Constant.
2089  
        Constant.
2089  

2090  

2090  
        @par Exception Safety
2091  
        @par Exception Safety
2091  
        Throws nothing.
2092  
        Throws nothing.
2092  

2093  

2093  
        @par BNF
2094  
        @par BNF
2094  
        @code
2095  
        @code
2095  
        query           = *( pchar / "/" / "?" )
2096  
        query           = *( pchar / "/" / "?" )
2096  
        query-param     = key [ "=" value ]
2097  
        query-param     = key [ "=" value ]
2097  
        query-params    = [ query-param ] *( "&" query-param )
2098  
        query-params    = [ query-param ] *( "&" query-param )
2098  
        @endcode
2099  
        @endcode
2099  

2100  

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

2104  

2104  
        @see
2105  
        @see
2105  
            @ref encoded_query,
2106  
            @ref encoded_query,
2106  
            @ref has_query,
2107  
            @ref has_query,
2107  
            @ref params,
2108  
            @ref params,
2108  
            @ref query.
2109  
            @ref query.
2109  

2110  

2110  
        @return A bidirectional view of key/value pairs.
2111  
        @return A bidirectional view of key/value pairs.
2111  
    */
2112  
    */
2112  
    params_encoded_view
2113  
    params_encoded_view
2113  
    encoded_params() const noexcept;
2114  
    encoded_params() const noexcept;
2114  

2115  

2115  
    //--------------------------------------------
2116  
    //--------------------------------------------
2116  
    //
2117  
    //
2117  
    // Fragment
2118  
    // Fragment
2118  
    //
2119  
    //
2119  
    //--------------------------------------------
2120  
    //--------------------------------------------
2120  

2121  

2121  
    /** Return true if a fragment is present
2122  
    /** Return true if a fragment is present
2122  

2123  

2123  
        This function returns true if the url
2124  
        This function returns true if the url
2124  
        contains a fragment.
2125  
        contains a fragment.
2125  
        An empty fragment is distinct from
2126  
        An empty fragment is distinct from
2126  
        no fragment.
2127  
        no fragment.
2127  

2128  

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

2133  

2133  
        @par Complexity
2134  
        @par Complexity
2134  
        Constant.
2135  
        Constant.
2135  

2136  

2136  
        @par Exception Safety
2137  
        @par Exception Safety
2137  
        Throws nothing.
2138  
        Throws nothing.
2138  

2139  

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

2143  

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

2146  

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

2149  

2149  
        @see
2150  
        @see
2150  
            @ref encoded_fragment,
2151  
            @ref encoded_fragment,
2151  
            @ref fragment.
2152  
            @ref fragment.
2152  

2153  

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

2158  

2158  
    /** Return the fragment
2159  
    /** Return the fragment
2159  

2160  

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

2166  

2166  
        <br>
2167  
        <br>
2167  

2168  

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

2173  

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

2177  

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

2182  

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

2187  

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

2190  

2190  
        @par Exception Safety
2191  
        @par Exception Safety
2191  
        Calls to allocate may throw.
2192  
        Calls to allocate may throw.
2192  
        String tokens may throw exceptions.
2193  
        String tokens may throw exceptions.
2193  

2194  

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

2198  

2198  
        @return The fragment portion of the url.
2199  
        @return The fragment portion of the url.
2199  

2200  

2200  
        @par BNF
2201  
        @par BNF
2201  
        @code
2202  
        @code
2202  
        fragment        = *( pchar / "/" / "?" )
2203  
        fragment        = *( pchar / "/" / "?" )
2203  

2204  

2204  
        fragment-part   = [ "#" fragment ]
2205  
        fragment-part   = [ "#" fragment ]
2205  
        @endcode
2206  
        @endcode
2206  

2207  

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

2210  

2210  
        @see
2211  
        @see
2211  
            @ref encoded_fragment,
2212  
            @ref encoded_fragment,
2212  
            @ref has_fragment.
2213  
            @ref has_fragment.
2213  

2214  

2214  
    */
2215  
    */
2215  
    template<BOOST_URL_STRTOK_TPARAM>
2216  
    template<BOOST_URL_STRTOK_TPARAM>
2216  
    BOOST_URL_STRTOK_RETURN
2217  
    BOOST_URL_STRTOK_RETURN
2217  
    fragment(
2218  
    fragment(
2218  
        StringToken&& token = {}) const
2219  
        StringToken&& token = {}) const
2219  
    {
2220  
    {
2220  
        encoding_opts opt;
2221  
        encoding_opts opt;
2221  
        opt.space_as_plus = false;
2222  
        opt.space_as_plus = false;
2222  
        return encoded_fragment().decode(
2223  
        return encoded_fragment().decode(
2223  
            opt, std::forward<StringToken>(token));
2224  
            opt, std::forward<StringToken>(token));
2224  
    }
2225  
    }
2225  

2226  

2226  
    /** Return the fragment
2227  
    /** Return the fragment
2227  

2228  

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

2235  

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

2240  

2240  
        @par Complexity
2241  
        @par Complexity
2241  
        Constant.
2242  
        Constant.
2242  

2243  

2243  
        @par Exception Safety
2244  
        @par Exception Safety
2244  
        Throws nothing.
2245  
        Throws nothing.
2245  

2246  

2246  
        @par BNF
2247  
        @par BNF
2247  
        @code
2248  
        @code
2248  
        fragment        = *( pchar / "/" / "?" )
2249  
        fragment        = *( pchar / "/" / "?" )
2249  

2250  

2250  
        pchar           = unreserved / pct-encoded / sub-delims / ":" / "@"
2251  
        pchar           = unreserved / pct-encoded / sub-delims / ":" / "@"
2251  
        @endcode
2252  
        @endcode
2252  

2253  

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

2256  

2256  
        @see
2257  
        @see
2257  
            @ref fragment,
2258  
            @ref fragment,
2258  
            @ref has_fragment.
2259  
            @ref has_fragment.
2259  

2260  

2260  
        @return The fragment portion of the url.
2261  
        @return The fragment portion of the url.
2261  
    */
2262  
    */
2262  
    pct_string_view
2263  
    pct_string_view
2263  
    encoded_fragment() const noexcept;
2264  
    encoded_fragment() const noexcept;
2264  

2265  

2265  
    //--------------------------------------------
2266  
    //--------------------------------------------
2266  
    //
2267  
    //
2267  
    // Compound Fields
2268  
    // Compound Fields
2268  
    //
2269  
    //
2269  
    //--------------------------------------------
2270  
    //--------------------------------------------
2270  

2271  

2271  
    /** Return the host and port
2272  
    /** Return the host and port
2272  

2273  

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

2280  

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

2285  

2285  
        @par Complexity
2286  
        @par Complexity
2286  
        Constant.
2287  
        Constant.
2287  

2288  

2288  
        @par Exception Safety
2289  
        @par Exception Safety
2289  
        Throws nothing.
2290  
        Throws nothing.
2290  

2291  

2291  
        @par BNF
2292  
        @par BNF
2292  
        @code
2293  
        @code
2293  
        authority   = [ userinfo "@" ] host [ ":" port ]
2294  
        authority   = [ userinfo "@" ] host [ ":" port ]
2294  
        @endcode
2295  
        @endcode
2295  

2296  

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

2300  

2300  
        @see
2301  
        @see
2301  
            @ref has_port,
2302  
            @ref has_port,
2302  
            @ref port,
2303  
            @ref port,
2303  
            @ref port_number.
2304  
            @ref port_number.
2304  

2305  

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

2310  

2310  
    /** Return the origin
2311  
    /** Return the origin
2311  

2312  

2312  
        If an authority is present, this
2313  
        If an authority is present, this
2313  
        function returns the scheme and
2314  
        function returns the scheme and
2314  
        authority portion of the url.
2315  
        authority portion of the url.
2315  
        Otherwise, an empty string is
2316  
        Otherwise, an empty string is
2316  
        returned.
2317  
        returned.
2317  
        The returned string may contain
2318  
        The returned string may contain
2318  
        percent escapes.
2319  
        percent escapes.
2319  

2320  

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

2325  

2325  
        @par Complexity
2326  
        @par Complexity
2326  
        Constant.
2327  
        Constant.
2327  

2328  

2328  
        @par Exception Safety
2329  
        @par Exception Safety
2329  
        Throws nothing.
2330  
        Throws nothing.
2330  

2331  

2331  
        @see
2332  
        @see
2332  
            @ref encoded_resource,
2333  
            @ref encoded_resource,
2333  
            @ref encoded_target.
2334  
            @ref encoded_target.
2334  

2335  

2335  
        @return The origin portion of the url.
2336  
        @return The origin portion of the url.
2336  
    */
2337  
    */
2337  
    pct_string_view
2338  
    pct_string_view
2338  
    encoded_origin() const noexcept;
2339  
    encoded_origin() const noexcept;
2339  

2340  

2340  
    /** Return the resource
2341  
    /** Return the resource
2341  

2342  

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

2348  

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

2353  

2353  
        @par Complexity
2354  
        @par Complexity
2354  
        Constant.
2355  
        Constant.
2355  

2356  

2356  
        @par Exception Safety
2357  
        @par Exception Safety
2357  
        Throws nothing.
2358  
        Throws nothing.
2358  

2359  

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

2363  

2363  
        @see
2364  
        @see
2364  
            @ref encoded_origin,
2365  
            @ref encoded_origin,
2365  
            @ref encoded_target.
2366  
            @ref encoded_target.
2366  

2367  

2367  
        @return The resource portion of the url.
2368  
        @return The resource portion of the url.
2368  
    */
2369  
    */
2369  
    pct_string_view
2370  
    pct_string_view
2370  
    encoded_resource() const noexcept;
2371  
    encoded_resource() const noexcept;
2371  

2372  

2372  
    /** Return the target
2373  
    /** Return the target
2373  

2374  

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

2380  

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

2385  

2385  
        @par Complexity
2386  
        @par Complexity
2386  
        Constant.
2387  
        Constant.
2387  

2388  

2388  
        @par Exception Safety
2389  
        @par Exception Safety
2389  
        Throws nothing.
2390  
        Throws nothing.
2390  

2391  

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

2395  

2395  
        @see
2396  
        @see
2396  
            @ref encoded_origin,
2397  
            @ref encoded_origin,
2397  
            @ref encoded_resource.
2398  
            @ref encoded_resource.
2398  

2399  

2399  
        @return The target portion of the url.
2400  
        @return The target portion of the url.
2400  
    */
2401  
    */
2401  
    pct_string_view
2402  
    pct_string_view
2402  
    encoded_target() const noexcept;
2403  
    encoded_target() const noexcept;
2403  

2404  

2404  
    //--------------------------------------------
2405  
    //--------------------------------------------
2405  
    //
2406  
    //
2406  
    // Comparison
2407  
    // Comparison
2407  
    //
2408  
    //
2408  
    //--------------------------------------------
2409  
    //--------------------------------------------
2409  

2410  

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

2412  

2412  
        This function compares two URLs
2413  
        This function compares two URLs
2413  
        according to Syntax-Based comparison
2414  
        according to Syntax-Based comparison
2414  
        algorithm.
2415  
        algorithm.
2415  

2416  

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

2419  

2419  
        @par Exception Safety
2420  
        @par Exception Safety
2420  
        Throws nothing.
2421  
        Throws nothing.
2421  

2422  

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

2425  

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

2431  

2431  
    /** Return the result of comparing two URLs
2432  
    /** Return the result of comparing two URLs
2432  

2433  

2433  
        The URLs are compared component by
2434  
        The URLs are compared component by
2434  
        component as if they were first
2435  
        component as if they were first
2435  
        normalized.
2436  
        normalized.
2436  

2437  

2437  
        @par Example
2438  
        @par Example
2438  
        @code
2439  
        @code
2439  
        url_view u0( "http://www.a.com/index.htm" );
2440  
        url_view u0( "http://www.a.com/index.htm" );
2440  
        url_view u1( "http://www.a.com/index.htm" );
2441  
        url_view u1( "http://www.a.com/index.htm" );
2441  
        assert( u0 == u1 );
2442  
        assert( u0 == u1 );
2442  
        @endcode
2443  
        @endcode
2443  

2444  

2444  
        @par Effects
2445  
        @par Effects
2445  
        @code
2446  
        @code
2446  
        url a(u0);
2447  
        url a(u0);
2447  
        a.normalize();
2448  
        a.normalize();
2448  
        url b(u1);
2449  
        url b(u1);
2449  
        b.normalize();
2450  
        b.normalize();
2450  
        return a.buffer() == b.buffer();
2451  
        return a.buffer() == b.buffer();
2451  
        @endcode
2452  
        @endcode
2452  

2453  

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

2456  

2456  
        @par Exception Safety
2457  
        @par Exception Safety
2457  
        Throws nothing
2458  
        Throws nothing
2458  

2459  

2459  
        @param u0 The first url to compare
2460  
        @param u0 The first url to compare
2460  
        @param u1 The second url to compare
2461  
        @param u1 The second url to compare
2461  
        @return `true` if `u0 == u1`
2462  
        @return `true` if `u0 == u1`
2462  

2463  

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

2475  

2475  
    /** Return the result of comparing two URLs
2476  
    /** Return the result of comparing two URLs
2476  

2477  

2477  
        The URLs are compared component by
2478  
        The URLs are compared component by
2478  
        component as if they were first
2479  
        component as if they were first
2479  
        normalized.
2480  
        normalized.
2480  

2481  

2481  
        @par Example
2482  
        @par Example
2482  
        @code
2483  
        @code
2483  
        url_view u0( "http://www.a.com/index.htm" );
2484  
        url_view u0( "http://www.a.com/index.htm" );
2484  
        url_view u1( "http://www.b.com/index.htm" );
2485  
        url_view u1( "http://www.b.com/index.htm" );
2485  
        assert( u0 != u1 );
2486  
        assert( u0 != u1 );
2486  
        @endcode
2487  
        @endcode
2487  

2488  

2488  
        @par Effects
2489  
        @par Effects
2489  
        @code
2490  
        @code
2490  
        url a(u0);
2491  
        url a(u0);
2491  
        a.normalize();
2492  
        a.normalize();
2492  
        url b(u1);
2493  
        url b(u1);
2493  
        b.normalize();
2494  
        b.normalize();
2494  
        return a.buffer() != b.buffer();
2495  
        return a.buffer() != b.buffer();
2495  
        @endcode
2496  
        @endcode
2496  

2497  

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

2500  

2500  
        @par Exception Safety
2501  
        @par Exception Safety
2501  
        Throws nothing
2502  
        Throws nothing
2502  

2503  

2503  
        @param u0 The first url to compare
2504  
        @param u0 The first url to compare
2504  
        @param u1 The second url to compare
2505  
        @param u1 The second url to compare
2505  
        @return `true` if `u0 != u1`
2506  
        @return `true` if `u0 != u1`
2506  

2507  

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

2519  

2519  
    /** Return the result of comparing two URLs
2520  
    /** Return the result of comparing two URLs
2520  

2521  

2521  
        The URLs are compared component by
2522  
        The URLs are compared component by
2522  
        component as if they were first
2523  
        component as if they were first
2523  
        normalized.
2524  
        normalized.
2524  

2525  

2525  
        @par Example
2526  
        @par Example
2526  
        @code
2527  
        @code
2527  
        url_view u0( "http://www.a.com/index.htm" );
2528  
        url_view u0( "http://www.a.com/index.htm" );
2528  
        url_view u1( "http://www.b.com/index.htm" );
2529  
        url_view u1( "http://www.b.com/index.htm" );
2529  
        assert( u0 < u1 );
2530  
        assert( u0 < u1 );
2530  
        @endcode
2531  
        @endcode
2531  

2532  

2532  
        @par Effects
2533  
        @par Effects
2533  
        @code
2534  
        @code
2534  
        url a(u0);
2535  
        url a(u0);
2535  
        a.normalize();
2536  
        a.normalize();
2536  
        url b(u1);
2537  
        url b(u1);
2537  
        b.normalize();
2538  
        b.normalize();
2538  
        return a.buffer() < b.buffer();
2539  
        return a.buffer() < b.buffer();
2539  
        @endcode
2540  
        @endcode
2540  

2541  

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

2544  

2544  
        @par Exception Safety
2545  
        @par Exception Safety
2545  
        Throws nothing
2546  
        Throws nothing
2546  

2547  

2547  
        @param u0 The first url to compare
2548  
        @param u0 The first url to compare
2548  
        @param u1 The second url to compare
2549  
        @param u1 The second url to compare
2549  
        @return `true` if `u0 < u1`
2550  
        @return `true` if `u0 < u1`
2550  

2551  

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

2563  

2563  
    /** Return the result of comparing two URLs
2564  
    /** Return the result of comparing two URLs
2564  

2565  

2565  
        The URLs are compared component by
2566  
        The URLs are compared component by
2566  
        component as if they were first
2567  
        component as if they were first
2567  
        normalized.
2568  
        normalized.
2568  

2569  

2569  
        @par Example
2570  
        @par Example
2570  
        @code
2571  
        @code
2571  
        url_view u0( "http://www.b.com/index.htm" );
2572  
        url_view u0( "http://www.b.com/index.htm" );
2572  
        url_view u1( "http://www.b.com/index.htm" );
2573  
        url_view u1( "http://www.b.com/index.htm" );
2573  
        assert( u0 <= u1 );
2574  
        assert( u0 <= u1 );
2574  
        @endcode
2575  
        @endcode
2575  

2576  

2576  
        @par Effects
2577  
        @par Effects
2577  
        @code
2578  
        @code
2578  
        url a(u0);
2579  
        url a(u0);
2579  
        a.normalize();
2580  
        a.normalize();
2580  
        url b(u1);
2581  
        url b(u1);
2581  
        b.normalize();
2582  
        b.normalize();
2582  
        return a.buffer() <= b.buffer();
2583  
        return a.buffer() <= b.buffer();
2583  
        @endcode
2584  
        @endcode
2584  

2585  

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

2588  

2588  
        @par Exception Safety
2589  
        @par Exception Safety
2589  
        Throws nothing
2590  
        Throws nothing
2590  

2591  

2591  
        @param u0 The first url to compare
2592  
        @param u0 The first url to compare
2592  
        @param u1 The second url to compare
2593  
        @param u1 The second url to compare
2593  
        @return `true` if `u0 <= u1`
2594  
        @return `true` if `u0 <= u1`
2594  

2595  

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

2607  

2607  
    /** Return the result of comparing two URLs
2608  
    /** Return the result of comparing two URLs
2608  

2609  

2609  
        The URLs are compared component by
2610  
        The URLs are compared component by
2610  
        component as if they were first
2611  
        component as if they were first
2611  
        normalized.
2612  
        normalized.
2612  

2613  

2613  
        @par Example
2614  
        @par Example
2614  
        @code
2615  
        @code
2615  
        url_view u0( "http://www.b.com/index.htm" );
2616  
        url_view u0( "http://www.b.com/index.htm" );
2616  
        url_view u1( "http://www.a.com/index.htm" );
2617  
        url_view u1( "http://www.a.com/index.htm" );
2617  
        assert( u0 > u1 );
2618  
        assert( u0 > u1 );
2618  
        @endcode
2619  
        @endcode
2619  

2620  

2620  
        @par Effects
2621  
        @par Effects
2621  
        @code
2622  
        @code
2622  
        url a(u0);
2623  
        url a(u0);
2623  
        a.normalize();
2624  
        a.normalize();
2624  
        url b(u1);
2625  
        url b(u1);
2625  
        b.normalize();
2626  
        b.normalize();
2626  
        return a.buffer() > b.buffer();
2627  
        return a.buffer() > b.buffer();
2627  
        @endcode
2628  
        @endcode
2628  

2629  

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

2632  

2632  
        @par Exception Safety
2633  
        @par Exception Safety
2633  
        Throws nothing
2634  
        Throws nothing
2634  

2635  

2635  
        @param u0 The first url to compare
2636  
        @param u0 The first url to compare
2636  
        @param u1 The second url to compare
2637  
        @param u1 The second url to compare
2637  
        @return `true` if `u0 > u1`
2638  
        @return `true` if `u0 > u1`
2638  

2639  

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

2651  

2651  
    /** Return the result of comparing two URLs
2652  
    /** Return the result of comparing two URLs
2652  

2653  

2653  
        The URLs are compared component by
2654  
        The URLs are compared component by
2654  
        component as if they were first
2655  
        component as if they were first
2655  
        normalized.
2656  
        normalized.
2656  

2657  

2657  
        @par Example
2658  
        @par Example
2658  
        @code
2659  
        @code
2659  
        url_view u0( "http://www.a.com/index.htm" );
2660  
        url_view u0( "http://www.a.com/index.htm" );
2660  
        url_view u1( "http://www.a.com/index.htm" );
2661  
        url_view u1( "http://www.a.com/index.htm" );
2661  
        assert( u0 >= u1 );
2662  
        assert( u0 >= u1 );
2662  
        @endcode
2663  
        @endcode
2663  

2664  

2664  
        @par Effects
2665  
        @par Effects
2665  
        @code
2666  
        @code
2666  
        url a(u0);
2667  
        url a(u0);
2667  
        a.normalize();
2668  
        a.normalize();
2668  
        url b(u1);
2669  
        url b(u1);
2669  
        b.normalize();
2670  
        b.normalize();
2670  
        return a.buffer() >= b.buffer();
2671  
        return a.buffer() >= b.buffer();
2671  
        @endcode
2672  
        @endcode
2672  

2673  

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

2676  

2676  
        @par Exception Safety
2677  
        @par Exception Safety
2677  
        Throws nothing
2678  
        Throws nothing
2678  

2679  

2679  
        @param u0 The first url to compare
2680  
        @param u0 The first url to compare
2680  
        @param u1 The second url to compare
2681  
        @param u1 The second url to compare
2681  
        @return `true` if `u0 >= u1`
2682  
        @return `true` if `u0 >= u1`
2682  

2683  

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

2695  

2695  
    /** Format the url to the output stream
2696  
    /** Format the url to the output stream
2696  

2697  

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

2702  

2702  
        @par Example
2703  
        @par Example
2703  
        @code
2704  
        @code
2704  
        url_view u( "http://www.example.com/index.htm" );
2705  
        url_view u( "http://www.example.com/index.htm" );
2705  
        std::stringstream ss;
2706  
        std::stringstream ss;
2706  
        ss << u;
2707  
        ss << u;
2707  
        assert( ss.str() == "http://www.example.com/index.htm" );
2708  
        assert( ss.str() == "http://www.example.com/index.htm" );
2708  
        @endcode
2709  
        @endcode
2709  

2710  

2710  
        @par Effects
2711  
        @par Effects
2711  
        @code
2712  
        @code
2712  
        return os << u.buffer();
2713  
        return os << u.buffer();
2713  
        @endcode
2714  
        @endcode
2714  

2715  

2715  
        @par Complexity
2716  
        @par Complexity
2716  
        Linear in `u.buffer().size()`
2717  
        Linear in `u.buffer().size()`
2717  

2718  

2718  
        @par Exception Safety
2719  
        @par Exception Safety
2719  
        Basic guarantee.
2720  
        Basic guarantee.
2720  

2721  

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

2723  

2723  
        @param os The output stream to write to.
2724  
        @param os The output stream to write to.
2724  

2725  

2725  
        @param u The url to write.
2726  
        @param u The url to write.
2726  
    */
2727  
    */
2727  
    friend
2728  
    friend
2728  
    std::ostream&
2729  
    std::ostream&
2729  
    operator<<(
2730  
    operator<<(
2730  
        std::ostream& os,
2731  
        std::ostream& os,
2731  
        url_view_base const& u)
2732  
        url_view_base const& u)
2732  
    {
2733  
    {
2733  
        return os << u.buffer();
2734  
        return os << u.buffer();
2734  
    }
2735  
    }
2735  

2736  

2736  
private:
2737  
private:
2737  
    //--------------------------------------------
2738  
    //--------------------------------------------
2738  
    //
2739  
    //
2739  
    // implementation
2740  
    // implementation
2740  
    //
2741  
    //
2741  
    //--------------------------------------------
2742  
    //--------------------------------------------
2742  
    static
2743  
    static
2743  
    int
2744  
    int
2744  
    segments_compare(
2745  
    segments_compare(
2745  
        segments_encoded_view seg0,
2746  
        segments_encoded_view seg0,
2746  
        segments_encoded_view seg1) noexcept;
2747  
        segments_encoded_view seg1) noexcept;
2747  
};
2748  
};
2748  

2749  

2749  
//------------------------------------------------
2750  
//------------------------------------------------
2750  

2751  

2751  
/** Format the url to the output stream
2752  
/** Format the url to the output stream
2752  

2753  

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

2758  

2758  
    @par Example
2759  
    @par Example
2759  
    @code
2760  
    @code
2760  
    url_view u( "http://www.example.com/index.htm" );
2761  
    url_view u( "http://www.example.com/index.htm" );
2761  
    std::stringstream ss;
2762  
    std::stringstream ss;
2762  
    ss << u;
2763  
    ss << u;
2763  
    assert( ss.str() == "http://www.example.com/index.htm" );
2764  
    assert( ss.str() == "http://www.example.com/index.htm" );
2764  
    @endcode
2765  
    @endcode
2765  

2766  

2766  
    @par Effects
2767  
    @par Effects
2767  
    @code
2768  
    @code
2768  
    return os << u.buffer();
2769  
    return os << u.buffer();
2769  
    @endcode
2770  
    @endcode
2770  

2771  

2771  
    @par Complexity
2772  
    @par Complexity
2772  
    Linear in `u.buffer().size()`
2773  
    Linear in `u.buffer().size()`
2773  

2774  

2774  
    @par Exception Safety
2775  
    @par Exception Safety
2775  
    Basic guarantee.
2776  
    Basic guarantee.
2776  

2777  

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

2779  

2779  
    @param os The output stream to write to.
2780  
    @param os The output stream to write to.
2780  

2781  

2781  
    @param u The url to write.
2782  
    @param u The url to write.
2782  
*/
2783  
*/
2783  
std::ostream&
2784  
std::ostream&
2784  
operator<<(
2785  
operator<<(
2785  
    std::ostream& os,
2786  
    std::ostream& os,
2786  
    url_view_base const& u);
2787  
    url_view_base const& u);
2787  

2788  

2788  
} // urls
2789  
} // urls
2789  
} // boost
2790  
} // boost
2790  

2791  

2791  
#endif
2792  
#endif