Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-09-13 08:52:47

0001 //
0002 // Copyright (c) 2019 Vinnie Falco (vinnie.falco@gmail.com)
0003 // Copyright (c) 2022 Alan de Freitas (alandefreitas@gmail.com)
0004 //
0005 // Distributed under the Boost Software License, Version 1.0. (See accompanying
0006 // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
0007 //
0008 // Official repository: https://github.com/boostorg/url
0009 //
0010 
0011 #ifndef BOOST_URL_URL_VIEW_BASE_HPP
0012 #define BOOST_URL_URL_VIEW_BASE_HPP
0013 
0014 #include <boost/url/detail/config.hpp>
0015 #include <boost/url/authority_view.hpp>
0016 #include <boost/url/host_type.hpp>
0017 #include <boost/url/ipv4_address.hpp>
0018 #include <boost/url/ipv6_address.hpp>
0019 #include <boost/url/params_view.hpp>
0020 #include <boost/url/params_encoded_view.hpp>
0021 #include <boost/url/pct_string_view.hpp>
0022 #include <boost/url/scheme.hpp>
0023 #include <boost/url/segments_encoded_view.hpp>
0024 #include <boost/url/segments_view.hpp>
0025 #include <boost/url/detail/url_impl.hpp>
0026 #include <boost/url/grammar/string_token.hpp>
0027 #include <boost/assert.hpp>
0028 #include <cstddef>
0029 #include <cstdint>
0030 #include <iosfwd>
0031 #include <memory>
0032 #include <string>
0033 #include <utility>
0034 
0035 namespace boost {
0036 namespace urls {
0037 
0038 #ifndef BOOST_URL_DOCS
0039 namespace detail {
0040 struct pattern;
0041 }
0042 #endif
0043 
0044 
0045 /** Common functionality for containers
0046 
0047     This base class is used by the library
0048     to provide common member functions for
0049     containers. This cannot be instantiated
0050     directly; Instead, use one of the
0051     containers or functions:
0052 
0053     @par Containers
0054         @li @ref url
0055         @li @ref url_view
0056         @li @ref static_url
0057 
0058     @par Functions
0059         @li @ref parse_absolute_uri
0060         @li @ref parse_origin_form
0061         @li @ref parse_relative_ref
0062         @li @ref parse_uri
0063         @li @ref parse_uri_reference
0064 */
0065 class BOOST_URL_DECL
0066     url_view_base
0067     : private detail::parts_base
0068 {
0069     detail::url_impl impl_;
0070     detail::url_impl const* pi_;
0071 
0072     friend class url;
0073     friend class url_base;
0074     friend class url_view;
0075     friend class static_url_base;
0076     friend class params_base;
0077     friend class params_encoded_base;
0078     friend class params_encoded_ref;
0079     friend class params_encoded_view;
0080     friend class params_ref;
0081     friend class params_view;
0082     friend class segments_base;
0083     friend class segments_encoded_base;
0084     friend class segments_encoded_ref;
0085     friend class segments_encoded_view;
0086     friend class segments_ref;
0087     friend class segments_view;
0088     friend struct detail::pattern;
0089 
0090     struct shared_impl;
0091 
0092     url_view_base() noexcept;
0093 
0094     explicit url_view_base(
0095         detail::url_impl const&) noexcept;
0096 
0097     ~url_view_base() = default;
0098 
0099     url_view_base(
0100         url_view_base const& o) noexcept
0101         : impl_(o.impl_)
0102         , pi_(o.pi_)
0103     {
0104         if (pi_ == &o.impl_)
0105             pi_ = &impl_;
0106     }
0107 
0108     url_view_base& operator=(
0109         url_view_base const&) = delete;
0110 
0111 protected:
0112     /** Calculate a hash of the url
0113 
0114         This function calculates a hash of the
0115         url as if it were always normalized.
0116 
0117         @par Complexity
0118         Linear in `this->size()`.
0119 
0120         @par Exception Safety
0121         Throws nothing.
0122 
0123         @param salt An initial value to add to
0124         the hash
0125 
0126         @return A hash value suitable for use
0127         in hash-based containers.
0128     */
0129     std::size_t
0130     digest(std::size_t salt = 0) const noexcept;
0131 
0132 public:
0133     //--------------------------------------------
0134     //
0135     // Observers
0136     //
0137     //--------------------------------------------
0138 
0139     /** Return the maximum number of characters possible
0140 
0141         This represents the largest number
0142         of characters that are theoretically
0143         possible to represent in a url,
0144         not including any null terminator.
0145         In practice the actual possible size
0146         may be lower than this number.
0147 
0148         @par Complexity
0149         Constant.
0150 
0151         @par Exception Safety
0152         Throws nothing.
0153 
0154         @return The maximum number of characters.
0155     */
0156     static
0157     constexpr
0158     std::size_t
0159     max_size() noexcept
0160     {
0161         return BOOST_URL_MAX_SIZE;
0162     }
0163 
0164     /** Return the number of characters in the url
0165 
0166         This function returns the number of
0167         characters in the url's encoded string,
0168         not including any null terminator,
0169         if present.
0170 
0171         @par Example
0172         @code
0173         assert( url_view( "file:///Program%20Files" ).size() == 23 );
0174         @endcode
0175 
0176         @par Complexity
0177         Constant.
0178 
0179         @par Exception Safety
0180         Throws nothing.
0181 
0182         @return The number of characters in the url.
0183     */
0184     std::size_t
0185     size() const noexcept
0186     {
0187         return pi_->offset(id_end);
0188     }
0189 
0190     /** Return true if the url is empty
0191 
0192         The empty string matches the
0193         <em>relative-ref</em> grammar.
0194 
0195         @par Example
0196         @code
0197         assert( url_view( "" ).empty() );
0198         @endcode
0199 
0200         @par Complexity
0201         Constant.
0202 
0203         @par Exception Safety
0204         Throws nothing.
0205 
0206         @par BNF
0207         @code
0208         relative-ref  = relative-part [ "?" query ] [ "#" fragment ]
0209 
0210         relative-part = "//" authority path-abempty
0211                       / path-absolute
0212                       / path-noscheme
0213                       / path-empty
0214         @endcode
0215 
0216         @par Specification
0217         @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-4.2">4.2.  Relative Reference (rfc3986)</a>
0218 
0219         @return `true` if the url is empty.
0220     */
0221     bool
0222     empty() const noexcept
0223     {
0224         return pi_->offset(id_end) == 0;
0225     }
0226 
0227     /** Return a pointer to the url's character buffer
0228 
0229         This function returns a pointer to
0230         the first character of the url, which
0231         is not guaranteed to be null-terminated.
0232 
0233         @par Complexity
0234         Constant.
0235 
0236         @par Exception Safety
0237         Throws nothing.
0238 
0239         @return A pointer to the first character.
0240     */
0241     char const*
0242     data() const noexcept
0243     {
0244         return pi_->cs_;
0245     }
0246 
0247     /** Return the url string
0248 
0249         This function returns the entire url,
0250         which may contain percent escapes.
0251 
0252         @par Example
0253         @code
0254         assert( url_view( "http://www.example.com" ).buffer() == "http://www.example.com" );
0255         @endcode
0256 
0257         @par Complexity
0258         Constant.
0259 
0260         @par Exception Safety
0261         Throws nothing.
0262 
0263         @return The url as a string.
0264     */
0265     core::string_view
0266     buffer() const noexcept
0267     {
0268         return core::string_view(
0269             data(), size());
0270     }
0271 
0272     /** Return the URL as a core::string_view
0273 
0274         @par Complexity
0275         Constant.
0276 
0277         @par Exception Safety
0278         Throws nothing.
0279 
0280         @return A string view of the URL.
0281     */
0282     operator core::string_view() const noexcept
0283     {
0284         return buffer();
0285     }
0286 
0287     /** Return a shared, persistent copy of the url
0288 
0289         This function returns a read-only copy of
0290         the url, with shared lifetime. The returned
0291         value owns (persists) the underlying string.
0292         The algorithm used to create the value
0293         minimizes the number of individual memory
0294         allocations, making it more efficient than
0295         when using direct standard library functions.
0296 
0297         @par Example
0298         @code
0299         std::shared_ptr< url_view const > sp;
0300         {
0301             std::string s( "http://example.com" );
0302             url_view u( s );                        // u references characters in s
0303 
0304             assert( u.data() == s.data() );         // same buffer
0305 
0306             sp = u.persist();
0307 
0308             assert( sp->data() != s.data() );       // different buffer
0309             assert( sp->buffer() == s);             // same contents
0310 
0311             // s is destroyed and thus u
0312             // becomes invalid, but sp remains valid.
0313         }
0314         @endcode
0315 
0316         @par Complexity
0317         Linear in `this->size()`.
0318 
0319         @par Exception Safety
0320         Calls to allocate may throw.
0321 
0322         @return A shared pointer to a read-only url_view.
0323     */
0324     std::shared_ptr<
0325         url_view const> persist() const;
0326 
0327     //--------------------------------------------
0328     //
0329     // Scheme
0330     //
0331     //--------------------------------------------
0332 
0333     /** Return true a scheme is present
0334 
0335         This function returns true if this
0336         contains a scheme.
0337 
0338         @par Example
0339         @code
0340         assert( url_view( "http://www.example.com" ).has_scheme() );
0341         @endcode
0342 
0343         @par Complexity
0344         Constant.
0345 
0346         @par Exception Safety
0347         Throws nothing.
0348 
0349         @par BNF
0350         @code
0351         URI             = scheme ":" hier-part [ "?" query ] [ "#" fragment ]
0352 
0353         absolute-URI    = scheme ":" hier-part [ "?" query ]
0354 
0355         scheme          = ALPHA *( ALPHA / DIGIT / "+" / "-" / "." )
0356         @endcode
0357 
0358         @par Specification
0359         @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.1">3.1. Scheme (rfc3986)</a>
0360 
0361         @see
0362             @ref scheme,
0363             @ref scheme_id.
0364 
0365         @return `true` if the url contains a scheme.
0366     */
0367     bool
0368     has_scheme() const noexcept;
0369 
0370     /** Return the scheme
0371 
0372         This function returns the scheme if it
0373         exists, without a trailing colon (':').
0374         Otherwise it returns an empty string.
0375         Note that schemes are case-insensitive,
0376         and the canonical form is lowercased.
0377 
0378         @par Example
0379         @code
0380         assert( url_view( "http://www.example.com" ).scheme() == "http" );
0381         @endcode
0382 
0383         @par Exception Safety
0384         Throws nothing.
0385 
0386         @par BNF
0387         @code
0388         scheme          = ALPHA *( ALPHA / DIGIT / "+" / "-" / "." )
0389 
0390         URI             = scheme ":" hier-part [ "?" query ] [ "#" fragment ]
0391 
0392         absolute-URI    = scheme ":" hier-part [ "?" query ]
0393         @endcode
0394 
0395         @par Specification
0396         @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.1">3.1. Scheme (rfc3986)</a>
0397 
0398         @see
0399             @ref has_scheme,
0400             @ref scheme_id.
0401 
0402         @return The scheme as a string.
0403     */
0404     core::string_view
0405     scheme() const noexcept;
0406 
0407     /** Return the scheme
0408 
0409         This function returns a value which
0410         depends on the scheme in the url:
0411 
0412         @li If the scheme is a well-known
0413         scheme, corresponding value from
0414         the enumeration @ref urls::scheme
0415         is returned.
0416 
0417         @li If a scheme is present but is not
0418         a well-known scheme, the value
0419         returned is @ref urls::scheme::unknown.
0420 
0421         @li Otherwise, if the scheme is absent
0422         the value returned is
0423         @ref urls::scheme::none.
0424 
0425         @par Example
0426         @code
0427         assert( url_view( "wss://www.example.com/crypto.cgi" ).scheme_id() == scheme::wss );
0428         @endcode
0429 
0430         @par Complexity
0431         Constant.
0432 
0433         @par Exception Safety
0434         Throws nothing.
0435 
0436         @par BNF
0437         @code
0438         URI             = scheme ":" hier-part [ "?" query ] [ "#" fragment ]
0439 
0440         absolute-URI    = scheme ":" hier-part [ "?" query ]
0441 
0442         scheme          = ALPHA *( ALPHA / DIGIT / "+" / "-" / "." )
0443         @endcode
0444 
0445         @par Specification
0446         @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.1">3.1. Scheme (rfc3986)</a>
0447 
0448         @see
0449             @ref has_scheme,
0450             @ref scheme.
0451 
0452         @return The scheme as an enumeration value.
0453     */
0454     urls::scheme
0455     scheme_id() const noexcept;
0456 
0457     //--------------------------------------------
0458     //
0459     // Authority
0460     //
0461     //--------------------------------------------
0462 
0463     /** Return true if an authority is present
0464 
0465         This function returns true if the url
0466         contains an authority. The presence of
0467         an authority is denoted by a double
0468         slash ("//") at the beginning or after
0469         the scheme.
0470 
0471         @par Example
0472         @code
0473         assert( url_view( "http://www.example.com/index.htm" ).has_authority() );
0474         @endcode
0475 
0476         @par Complexity
0477         Constant.
0478 
0479         @par Exception Safety
0480         Throws nothing.
0481 
0482         @par BNF
0483         @code
0484         authority       = [ userinfo "@" ] host [ ":" port ]
0485 
0486         URI             = scheme ":" hier-part [ "?" query ] [ "#" fragment ]
0487 
0488         absolute-URI    = scheme ":" hier-part [ "?" query ]
0489 
0490         URI-reference   = URI / relative-ref
0491 
0492         relative-ref    = relative-part [ "?" query ] [ "#" fragment ]
0493 
0494         hier-part       = "//" authority path-abempty
0495                         ; (more...)
0496 
0497         relative-part   = "//" authority path-abempty
0498                         ; (more...)
0499 
0500         @endcode
0501 
0502         @par Specification
0503         @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.2">3.2. Authority (rfc3986)</a>
0504 
0505         @see
0506             @ref authority,
0507             @ref encoded_authority.
0508 
0509         @return `true` if the url contains an authority.
0510     */
0511     bool
0512     has_authority() const noexcept
0513     {
0514         return pi_->len(id_user) > 0;
0515     }
0516 
0517     /** Return the authority
0518 
0519         This function returns the authority as
0520         an @ref authority_view.
0521 
0522         @par Example
0523         @code
0524         authority_view a = url_view( "https://www.example.com:8080/index.htm" ).authority();
0525         @endcode
0526 
0527         @par Complexity
0528         Constant.
0529 
0530         @par Exception Safety
0531         Throws nothing.
0532 
0533         @par BNF
0534         @code
0535         authority   = [ userinfo "@" ] host [ ":" port ]
0536         @endcode
0537 
0538         @par Specification
0539         @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.2">3.2. Authority (rfc3986)</a>
0540 
0541         @see
0542             @ref encoded_authority,
0543             @ref has_authority.
0544 
0545         @return An authority_view representing the authority.
0546     */
0547     authority_view
0548     authority() const noexcept;
0549 
0550     /** Return the authority.
0551 
0552         If present, this function returns a
0553         string representing the authority (which
0554         may be empty).
0555         Otherwise it returns an empty string.
0556         The returned string may contain
0557         percent escapes.
0558 
0559         @par Example
0560         @code
0561         assert( url_view( "file://Network%20Drive/My%2DFiles" ).encoded_authority() == "Network%20Drive" );
0562         @endcode
0563 
0564         @par Complexity
0565         Constant.
0566 
0567         @par Exception Safety
0568         Throws nothing.
0569 
0570         @par BNF
0571         @code
0572         authority   = [ userinfo "@" ] host [ ":" port ]
0573         @endcode
0574 
0575         @par Specification
0576         @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.2">3.2. Authority (rfc3986)</a>
0577 
0578         @see
0579             @ref authority,
0580             @ref has_authority.
0581 
0582         @return The authority as a string.
0583     */
0584     pct_string_view
0585     encoded_authority() const noexcept;
0586 
0587     //--------------------------------------------
0588     //
0589     // Userinfo
0590     //
0591     //--------------------------------------------
0592 
0593     /** Return true if a userinfo is present
0594 
0595         This function returns true if this
0596         contains a userinfo.
0597 
0598         @par Example
0599         @code
0600         assert( url_view( "http://jane%2Ddoe:pass@example.com" ).has_userinfo() );
0601         @endcode
0602 
0603         @par Complexity
0604         Constant.
0605 
0606         @par Exception Safety
0607         Throws nothing.
0608 
0609         @par BNF
0610         @code
0611         userinfo    = user [ ":" [ password ] ]
0612 
0613         authority   = [ userinfo "@" ] host [ ":" port ]
0614         @endcode
0615 
0616         @par Specification
0617         @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.2.1">3.2.1. User Information (rfc3986)</a>
0618 
0619         @see
0620             @ref has_password,
0621             @ref encoded_password,
0622             @ref encoded_user,
0623             @ref encoded_userinfo,
0624             @ref password,
0625             @ref user,
0626             @ref userinfo.
0627 
0628         @return `true` if the userinfo is present.
0629     */
0630     bool
0631     has_userinfo() const noexcept;
0632 
0633     /** Return true if a password is present
0634 
0635         This function returns true if the
0636         userinfo is present and contains
0637         a password.
0638 
0639         @par Example
0640         @code
0641         assert( url_view( "http://jane%2Ddoe:pass@example.com" ).has_password() );
0642         @endcode
0643 
0644         @par Complexity
0645         Constant.
0646 
0647         @par Exception Safety
0648         Throws nothing.
0649 
0650         @par BNF
0651         @code
0652         userinfo    = user [ ":" [ password ] ]
0653 
0654         user        = *( unreserved / pct-encoded / sub-delims )
0655         password    = *( unreserved / pct-encoded / sub-delims / ":" )
0656         @endcode
0657 
0658         @par Specification
0659         @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.2.1">3.2.1. User Information (rfc3986)</a>
0660 
0661         @see
0662             @ref has_userinfo,
0663             @ref encoded_password,
0664             @ref encoded_user,
0665             @ref encoded_userinfo,
0666             @ref password,
0667             @ref user,
0668             @ref userinfo.
0669 
0670         @return `true` if the userinfo contains a password.
0671     */
0672     bool
0673     has_password() const noexcept;
0674 
0675     /** Return the userinfo
0676 
0677         If present, this function returns a
0678         string representing the userinfo (which
0679         may be empty).
0680         Otherwise it returns an empty string.
0681         Any percent-escapes in the string are
0682         decoded first.
0683 
0684         @note
0685         This function uses the string token
0686         return type customization. Depending on
0687         the token passed, the return type and
0688         behavior of the function can be different.
0689         See @ref string_token::return_string
0690         for more information.
0691 
0692         @par Example
0693         @code
0694         assert( url_view( "http://jane%2Ddoe:pass@example.com" ).userinfo() == "jane-doe:pass" );
0695         @endcode
0696 
0697         @par Complexity
0698         Linear in `this->userinfo().size()`.
0699 
0700         @par Exception Safety
0701         Calls to allocate may throw.
0702 
0703         @return When called with no arguments,
0704         a value of type `std::string` is
0705         returned. Otherwise, the return type
0706         and meaning depends on the string token
0707         passed to the function.
0708 
0709         @par BNF
0710         @code
0711         userinfo    = user [ ":" [ password ] ]
0712 
0713         authority   = [ userinfo "@" ] host [ ":" port ]
0714         @endcode
0715 
0716         @par Specification
0717         @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.2.1">3.2.1. User Information (rfc3986)</a>
0718 
0719         @see
0720             @ref has_password,
0721             @ref has_userinfo,
0722             @ref encoded_password,
0723             @ref encoded_user,
0724             @ref encoded_userinfo,
0725             @ref password,
0726             @ref user.
0727 
0728         @param token The string token to use.
0729         @return The userinfo as a string.
0730     */
0731     template<BOOST_URL_STRTOK_TPARAM>
0732     BOOST_URL_STRTOK_RETURN
0733     userinfo(
0734         StringToken&& token = {}) const
0735     {
0736         encoding_opts opt;
0737         opt.space_as_plus = false;
0738         return encoded_userinfo().decode(
0739             opt, std::move(token));
0740     }
0741 
0742     /** Return the userinfo
0743 
0744         If present, this function returns a
0745         string representing the userinfo (which
0746         may be empty).
0747         Otherwise it returns an empty string.
0748         The returned string may contain
0749         percent escapes.
0750 
0751         @par Example
0752         @code
0753         assert( url_view( "http://jane%2Ddoe:pass@example.com" ).encoded_userinfo() == "jane%2Ddoe:pass" );
0754         @endcode
0755 
0756         @par Complexity
0757         Constant.
0758 
0759         @par Exception Safety
0760         Throws nothing
0761 
0762         @par BNF
0763         @code
0764         userinfo    = user [ ":" [ password ] ]
0765 
0766         authority   = [ userinfo "@" ] host [ ":" port ]
0767         @endcode
0768 
0769         @par Specification
0770         @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.2.1">3.2.1. User Information (rfc3986)</a>
0771 
0772         @see
0773             @ref has_password,
0774             @ref has_userinfo,
0775             @ref encoded_password,
0776             @ref encoded_user,
0777             @ref password,
0778             @ref user,
0779             @ref userinfo.
0780 
0781         @return The userinfo as a string.
0782     */
0783     pct_string_view
0784     encoded_userinfo() const noexcept;
0785 
0786     //--------------------------------------------
0787 
0788     /** Return the user
0789 
0790         If present, this function returns a
0791         string representing the user (which
0792         may be empty).
0793         Otherwise it returns an empty string.
0794         Any percent-escapes in the string are
0795         decoded first.
0796 
0797         @par Example
0798         @code
0799         assert( url_view( "http://jane%2Ddoe:pass@example.com" ).user() == "jane-doe" );
0800         @endcode
0801 
0802         @par Complexity
0803         Linear in `this->user().size()`.
0804 
0805         @par Exception Safety
0806         Calls to allocate may throw.
0807 
0808         @par BNF
0809         @code
0810         userinfo    = user [ ":" [ password ] ]
0811 
0812         user        = *( unreserved / pct-encoded / sub-delims )
0813         password    = *( unreserved / pct-encoded / sub-delims / ":" )
0814         @endcode
0815 
0816         @par Specification
0817         @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.2.1">3.2.1. User Information (rfc3986)</a>
0818 
0819         @see
0820             @ref has_password,
0821             @ref has_userinfo,
0822             @ref encoded_password,
0823             @ref encoded_user,
0824             @ref encoded_userinfo,
0825             @ref password,
0826             @ref userinfo.
0827 
0828         @param token The string token to use.
0829         @return The user as a string.
0830     */
0831     template<BOOST_URL_STRTOK_TPARAM>
0832     BOOST_URL_STRTOK_RETURN
0833     user(
0834         StringToken&& token = {}) const
0835     {
0836         encoding_opts opt;
0837         opt.space_as_plus = false;
0838         return encoded_user().decode(
0839             opt, std::move(token));
0840     }
0841 
0842     /** Return the user
0843 
0844         If present, this function returns a
0845         string representing the user (which
0846         may be empty).
0847         Otherwise it returns an empty string.
0848         The returned string may contain
0849         percent escapes.
0850 
0851         @par Example
0852         @code
0853         assert( url_view( "http://jane%2Ddoe:pass@example.com" ).encoded_user() == "jane%2Ddoe" );
0854         @endcode
0855 
0856         @par Complexity
0857         Constant.
0858 
0859         @par Exception Safety
0860         Throws nothing.
0861 
0862         @par BNF
0863         @code
0864         userinfo    = user [ ":" [ password ] ]
0865 
0866         user        = *( unreserved / pct-encoded / sub-delims )
0867         password    = *( unreserved / pct-encoded / sub-delims / ":" )
0868         @endcode
0869 
0870         @par Specification
0871         @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.2.1">3.2.1. User Information (rfc3986)</a>
0872 
0873         @see
0874             @ref has_password,
0875             @ref has_userinfo,
0876             @ref encoded_password,
0877             @ref encoded_userinfo,
0878             @ref password,
0879             @ref user,
0880             @ref userinfo.
0881 
0882         @return The user as a string.
0883     */
0884     pct_string_view
0885     encoded_user() const noexcept;
0886 
0887     /** Return the password
0888 
0889         If present, this function returns a
0890         string representing the password (which
0891         may be an empty string).
0892         Otherwise it returns an empty string.
0893         Any percent-escapes in the string are
0894         decoded first.
0895 
0896         @par Example
0897         @code
0898         assert( url_view( "http://jane%2Ddoe:pass@example.com" ).password() == "pass" );
0899         @endcode
0900 
0901         @par Complexity
0902         Linear in `this->password().size()`.
0903 
0904         @par Exception Safety
0905         Calls to allocate may throw.
0906 
0907         @par BNF
0908         @code
0909         userinfo    = user [ ":" [ password ] ]
0910 
0911         user        = *( unreserved / pct-encoded / sub-delims )
0912         password    = *( unreserved / pct-encoded / sub-delims / ":" )
0913         @endcode
0914 
0915         @par Specification
0916         @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.2.1">3.2.1. User Information (rfc3986)</a>
0917 
0918         @see
0919             @ref has_password,
0920             @ref has_userinfo,
0921             @ref encoded_password,
0922             @ref encoded_user,
0923             @ref encoded_userinfo,
0924             @ref user,
0925             @ref userinfo.
0926 
0927         @param token The string token to use.
0928         @return The password as a string.
0929     */
0930     template<BOOST_URL_STRTOK_TPARAM>
0931     BOOST_URL_STRTOK_RETURN
0932     password(
0933         StringToken&& token = {}) const
0934     {
0935         encoding_opts opt;
0936         opt.space_as_plus = false;
0937         return encoded_password().decode(
0938             opt, std::move(token));
0939     }
0940 
0941     /** Return the password
0942 
0943         This function returns the password portion
0944         of the userinfo as a percent-encoded string.
0945 
0946         @par Example
0947         @code
0948         assert( url_view( "http://jane%2Ddoe:pass@example.com" ).encoded_password() == "pass" );
0949         @endcode
0950 
0951         @par Complexity
0952         Constant.
0953 
0954         @par Exception Safety
0955         Throws nothing.
0956 
0957         @par BNF
0958         @code
0959         userinfo    = user [ ":" [ password ] ]
0960 
0961         user        = *( unreserved / pct-encoded / sub-delims )
0962         password    = *( unreserved / pct-encoded / sub-delims / ":" )
0963         @endcode
0964 
0965         @par Specification
0966         @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.2.1">3.2.1. User Information (rfc3986)</a>
0967 
0968         @see
0969             @ref has_password,
0970             @ref has_userinfo,
0971             @ref encoded_user,
0972             @ref encoded_userinfo,
0973             @ref password,
0974             @ref user,
0975             @ref userinfo.
0976 
0977         @return The password as a string.
0978     */
0979     pct_string_view
0980     encoded_password() const noexcept;
0981 
0982     //--------------------------------------------
0983     //
0984     // Host
0985     //
0986     //--------------------------------------------
0987 
0988     /** Return the host type
0989 
0990         This function returns one of the
0991         following constants representing the
0992         type of host present.
0993 
0994         @li @ref host_type::ipv4
0995         @li @ref host_type::ipv6
0996         @li @ref host_type::ipvfuture
0997         @li @ref host_type::name
0998         @li @ref host_type::none
0999 
1000         When @ref has_authority is false, the
1001         host type is @ref host_type::none.
1002 
1003         @par Example
1004         @code
1005         assert( url_view( "https://192.168.0.1/local.htm" ).host_type() == host_type::ipv4 );
1006         @endcode
1007 
1008         @par Complexity
1009         Constant.
1010 
1011         @par Exception Safety
1012         Throws nothing.
1013 
1014         @par Specification
1015         @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.2.2">3.2.2. Host (rfc3986)</a>
1016 
1017         @return The type of host present.
1018     */
1019     urls::host_type
1020     host_type() const noexcept
1021     {
1022         return pi_->host_type_;
1023     }
1024 
1025     /** Return the host
1026 
1027         This function returns the host portion
1028         of the authority as a string, or the
1029         empty string if there is no authority.
1030         Any percent-escapes in the string are
1031         decoded first.
1032 
1033         @par Example
1034         @code
1035         assert( url_view( "https://www%2droot.example.com/" ).host() == "www-root.example.com" );
1036         @endcode
1037 
1038         @par Complexity
1039         Linear in `this->host().size()`.
1040 
1041         @par Exception Safety
1042         Calls to allocate may throw.
1043 
1044         @par BNF
1045         @code
1046         host        = IP-literal / IPv4address / reg-name
1047 
1048         IP-literal  = "[" ( IPv6address / IPvFuture  ) "]"
1049 
1050         reg-name    = *( unreserved / pct-encoded / "-" / ".")
1051         @endcode
1052 
1053         @par Specification
1054         @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.2.2">3.2.2. Host (rfc3986)</a>
1055 
1056         @param token A string token customization
1057         @return The host address as a string.
1058     */
1059     template<BOOST_URL_STRTOK_TPARAM>
1060     BOOST_URL_STRTOK_RETURN
1061     host(
1062         StringToken&& token = {}) const
1063     {
1064         encoding_opts opt;
1065         opt.space_as_plus = false;
1066         return encoded_host().decode(
1067             opt, std::move(token));
1068     }
1069 
1070     /** Return the host
1071 
1072         This function returns the host portion
1073         of the authority as a string, or the
1074         empty string if there is no authority.
1075         The returned string may contain
1076         percent escapes.
1077 
1078         @par Example
1079         @code
1080         assert( url_view( "https://www%2droot.example.com/" ).encoded_host() == "www%2droot.example.com" );
1081         @endcode
1082 
1083         @par Complexity
1084         Constant.
1085 
1086         @par Exception Safety
1087         Throws nothing.
1088 
1089         @par BNF
1090         @code
1091         host        = IP-literal / IPv4address / reg-name
1092 
1093         IP-literal  = "[" ( IPv6address / IPvFuture  ) "]"
1094 
1095         reg-name    = *( unreserved / pct-encoded / "-" / ".")
1096         @endcode
1097 
1098         @par Specification
1099         @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.2.2">3.2.2. Host (rfc3986)</a>
1100 
1101         @return The host address as a string.
1102     */
1103     pct_string_view
1104     encoded_host() const noexcept;
1105 
1106     /** Return the host
1107 
1108         The value returned by this function
1109         depends on the type of host returned
1110         from the function @ref host_type.
1111 
1112         @li If the type is @ref host_type::ipv4,
1113         then the IPv4 address string is returned.
1114 
1115         @li If the type is @ref host_type::ipv6,
1116         then the IPv6 address string is returned,
1117         without any enclosing brackets.
1118 
1119         @li If the type is @ref host_type::ipvfuture,
1120         then the IPvFuture address string is returned,
1121         without any enclosing brackets.
1122 
1123         @li If the type is @ref host_type::name,
1124         then the host name string is returned.
1125         Any percent-escapes in the string are
1126         decoded first.
1127 
1128         @li If the type is @ref host_type::none,
1129         then an empty string is returned.
1130 
1131         @par Example
1132         @code
1133         assert( url_view( "https://[1::6:c0a8:1]/" ).host_address() == "1::6:c0a8:1" );
1134         @endcode
1135 
1136         @par Complexity
1137         Linear in `this->host_address().size()`.
1138 
1139         @par Exception Safety
1140         Calls to allocate may throw.
1141 
1142         @par BNF
1143         @code
1144         host        = IP-literal / IPv4address / reg-name
1145 
1146         IP-literal  = "[" ( IPv6address / IPvFuture  ) "]"
1147 
1148         reg-name    = *( unreserved / pct-encoded / "-" / ".")
1149         @endcode
1150 
1151         @par Specification
1152         @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.2.2">3.2.2. Host (rfc3986)</a>
1153 
1154         @param token A string token customization
1155         @return The host address as a string.
1156     */
1157     template<BOOST_URL_STRTOK_TPARAM>
1158     BOOST_URL_STRTOK_RETURN
1159     host_address(
1160         StringToken&& token = {}) const
1161     {
1162         encoding_opts opt;
1163         opt.space_as_plus = false;
1164         return encoded_host_address().decode(
1165             opt, std::move(token));
1166     }
1167 
1168     /** Return the host
1169 
1170         The value returned by this function
1171         depends on the type of host returned
1172         from the function @ref host_type.
1173 
1174         @li If the type is @ref host_type::ipv4,
1175         then the IPv4 address string is returned.
1176 
1177         @li If the type is @ref host_type::ipv6,
1178         then the IPv6 address string is returned,
1179         without any enclosing brackets.
1180 
1181         @li If the type is @ref host_type::ipvfuture,
1182         then the IPvFuture address string is returned,
1183         without any enclosing brackets.
1184 
1185         @li If the type is @ref host_type::name,
1186         then the host name string is returned.
1187         Any percent-escapes in the string are
1188         decoded first.
1189 
1190         @li If the type is @ref host_type::none,
1191         then an empty string is returned.
1192         The returned string may contain
1193         percent escapes.
1194 
1195         @par Example
1196         @code
1197         assert( url_view( "https://www%2droot.example.com/" ).encoded_host_address() == "www%2droot.example.com" );
1198         @endcode
1199 
1200         @par Complexity
1201         Constant.
1202 
1203         @par Exception Safety
1204         Throws nothing.
1205 
1206         @par BNF
1207         @code
1208         host        = IP-literal / IPv4address / reg-name
1209 
1210         IP-literal  = "[" ( IPv6address / IPvFuture  ) "]"
1211 
1212         reg-name    = *( unreserved / pct-encoded / "-" / ".")
1213         @endcode
1214 
1215         @par Specification
1216         @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.2.2">3.2.2. Host (rfc3986)</a>
1217 
1218         @return The host address as a string.
1219     */
1220     pct_string_view
1221     encoded_host_address() const noexcept;
1222 
1223     /** Return the host IPv4 address
1224 
1225         If the host type is @ref host_type::ipv4,
1226         this function returns the address as
1227         a value of type @ref ipv4_address.
1228         Otherwise, if the host type is not an IPv4
1229         address, it returns a default-constructed
1230         value which is equal to the unspecified
1231         address "0.0.0.0".
1232 
1233         @par Example
1234         @code
1235         assert( url_view( "http://127.0.0.1/index.htm?user=win95" ).host_ipv4_address() == ipv4_address( "127.0.0.1" ) );
1236         @endcode
1237 
1238         @par Complexity
1239         Constant.
1240 
1241         @par Exception Safety
1242         Throws nothing.
1243 
1244         @par BNF
1245         @code
1246         IPv4address = dec-octet "." dec-octet "." dec-octet "." dec-octet
1247 
1248         dec-octet   = DIGIT                 ; 0-9
1249                     / %x31-39 DIGIT         ; 10-99
1250                     / "1" 2DIGIT            ; 100-199
1251                     / "2" %x30-34 DIGIT     ; 200-249
1252                     / "25" %x30-35          ; 250-255
1253         @endcode
1254 
1255         @par Specification
1256         @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.2.2">3.2.2. Host (rfc3986)</a>
1257 
1258         @return The IPv4 address as a value of type @ref ipv4_address.
1259     */
1260     ipv4_address
1261     host_ipv4_address() const noexcept;
1262 
1263     /** Return the host IPv6 address
1264 
1265         If the host type is @ref host_type::ipv6,
1266         this function returns the address as
1267         a value of type @ref ipv6_address.
1268         Otherwise, if the host type is not an IPv6
1269         address, it returns a default-constructed
1270         value which is equal to the unspecified
1271         address "0:0:0:0:0:0:0:0".
1272 
1273         @par Example
1274         @code
1275         assert( url_view( "ftp://[::1]/" ).host_ipv6_address() == ipv6_address( "::1" ) );
1276         @endcode
1277 
1278         @par Complexity
1279         Constant.
1280 
1281         @par Exception Safety
1282         Throws nothing.
1283 
1284         @par BNF
1285         @code
1286         IPv6address =                            6( h16 ":" ) ls32
1287                     /                       "::" 5( h16 ":" ) ls32
1288                     / [               h16 ] "::" 4( h16 ":" ) ls32
1289                     / [ *1( h16 ":" ) h16 ] "::" 3( h16 ":" ) ls32
1290                     / [ *2( h16 ":" ) h16 ] "::" 2( h16 ":" ) ls32
1291                     / [ *3( h16 ":" ) h16 ] "::"    h16 ":"   ls32
1292                     / [ *4( h16 ":" ) h16 ] "::"              ls32
1293                     / [ *5( h16 ":" ) h16 ] "::"              h16
1294                     / [ *6( h16 ":" ) h16 ] "::"
1295 
1296         ls32        = ( h16 ":" h16 ) / IPv4address
1297                     ; least-significant 32 bits of address
1298 
1299         h16         = 1*4HEXDIG
1300                     ; 16 bits of address represented in hexadecimal
1301         @endcode
1302 
1303         @par Specification
1304         @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.2.2">3.2.2. Host (rfc3986)</a>
1305 
1306         @return The IPv6 address as a value of type @ref ipv6_address.
1307     */
1308     ipv6_address
1309     host_ipv6_address() const noexcept;
1310 
1311     /** Return the host IPvFuture address
1312 
1313         If the host type is @ref host_type::ipvfuture,
1314         this function returns the address as
1315         a string.
1316         Otherwise, if the host type is not an
1317         IPvFuture address, it returns an
1318         empty string.
1319 
1320         @par Example
1321         @code
1322         assert( url_view( "http://[v1fe.d:9]/index.htm" ).host_ipvfuture() == "v1fe.d:9" );
1323         @endcode
1324 
1325         @par Complexity
1326         Constant.
1327 
1328         @par Exception Safety
1329         Throws nothing.
1330 
1331         @par BNF
1332         @code
1333         IPvFuture  = "v" 1*HEXDIG "." 1*( unreserved / sub-delims / ":" )
1334         @endcode
1335 
1336         @par Specification
1337         @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.2.2">3.2.2. Host (rfc3986)</a>
1338 
1339         @return The IPvFuture address as a string.
1340     */
1341     core::string_view
1342     host_ipvfuture() const noexcept;
1343 
1344     /** Return the host name
1345 
1346         If the host type is @ref host_type::name,
1347         this function returns the name as
1348         a string. Otherwise an empty string is returned.
1349         Any percent-escapes in the string are
1350         decoded first.
1351 
1352         @par Example
1353         @code
1354         assert( url_view( "https://www%2droot.example.com/" ).host_name() == "www-root.example.com" );
1355         @endcode
1356 
1357         @par Complexity
1358         Linear in `this->host_name().size()`.
1359 
1360         @par Exception Safety
1361         Calls to allocate may throw.
1362 
1363         @par BNF
1364         @code
1365         host        = IP-literal / IPv4address / reg-name
1366 
1367         IP-literal  = "[" ( IPv6address / IPvFuture  ) "]"
1368 
1369         reg-name    = *( unreserved / pct-encoded / "-" / ".")
1370         @endcode
1371 
1372         @par Specification
1373         @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.2.2">3.2.2. Host (rfc3986)</a>
1374 
1375         @param token A string token customization.
1376         @return The host name as a string.
1377     */
1378     template<BOOST_URL_STRTOK_TPARAM>
1379     BOOST_URL_STRTOK_RETURN
1380     host_name(
1381         StringToken&& token = {}) const
1382     {
1383         encoding_opts opt;
1384         opt.space_as_plus = false;
1385         return encoded_host_name().decode(
1386             opt, std::move(token));
1387     }
1388 
1389     /** Return the host name
1390 
1391         If the host type is @ref host_type::name,
1392         this function returns the name as
1393         a string.
1394         Otherwise, if the host type is not an
1395         name, it returns an empty string.
1396         The returned string may contain
1397         percent escapes.
1398 
1399         @par Example
1400         @code
1401         assert( url_view( "https://www%2droot.example.com/" ).encoded_host_name() == "www%2droot.example.com" );
1402         @endcode
1403 
1404         @par Complexity
1405         Constant.
1406 
1407         @par Exception Safety
1408         Throws nothing.
1409 
1410         @par BNF
1411         @code
1412         host        = IP-literal / IPv4address / reg-name
1413 
1414         IP-literal  = "[" ( IPv6address / IPvFuture  ) "]"
1415 
1416         reg-name    = *( unreserved / pct-encoded / "-" / ".")
1417         @endcode
1418 
1419         @par Specification
1420         @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.2.2">3.2.2. Host (rfc3986)</a>
1421 
1422         @return The host name as a percent-encoded string.
1423     */
1424     pct_string_view
1425     encoded_host_name() const noexcept;
1426 
1427     /** Return the IPv6 Zone ID
1428 
1429         If the host type is @ref host_type::ipv6,
1430         this function returns the Zone ID as
1431         a string. Otherwise an empty string is returned.
1432         Any percent-escapes in the string are
1433         decoded first.
1434 
1435         @par Example
1436         @code
1437         assert( url_view( "http://[fe80::1%25eth0]/" ).zone_id() == "eth0" );
1438         @endcode
1439 
1440         @par Complexity
1441         Linear in `this->encoded_zone_id().size()`.
1442 
1443         @par Exception Safety
1444         Calls to allocate may throw.
1445 
1446         @par BNF
1447         @code
1448         host        = IP-literal / IPv4address / reg-name
1449 
1450         IP-literal = "[" ( IPv6address / IPv6addrz / IPvFuture  ) "]"
1451 
1452         ZoneID = 1*( unreserved / pct-encoded )
1453 
1454         IPv6addrz = IPv6address "%25" ZoneID
1455         @endcode
1456 
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>
1459 
1460         @param token A string token customization.
1461         @return The Zone ID as a string.
1462     */
1463     template<BOOST_URL_STRTOK_TPARAM>
1464     BOOST_URL_STRTOK_RETURN
1465     zone_id(
1466         StringToken&& token = {}) const
1467     {
1468         encoding_opts opt;
1469         opt.space_as_plus = false;
1470         return encoded_zone_id().decode(
1471             opt, std::move(token));
1472     }
1473 
1474     /** Return the IPv6 Zone ID
1475 
1476         If the host type is @ref host_type::ipv6,
1477         this function returns the Zone ID as
1478         a string. Otherwise an empty string is returned.
1479         The returned string may contain
1480         percent escapes.
1481 
1482         @par Example
1483         @code
1484         assert( url_view( "http://[fe80::1%25eth0]/" ).encoded_zone_id() == "eth0" );
1485         @endcode
1486 
1487         @par Complexity
1488         Constant.
1489 
1490         @par Exception Safety
1491         Throws nothing.
1492 
1493         @par BNF
1494         @code
1495         host        = IP-literal / IPv4address / reg-name
1496 
1497         IP-literal = "[" ( IPv6address / IPv6addrz / IPvFuture  ) "]"
1498 
1499         ZoneID = 1*( unreserved / pct-encoded )
1500 
1501         IPv6addrz = IPv6address "%25" ZoneID
1502         @endcode
1503 
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>
1506 
1507         @return The Zone ID as a percent-encoded string.
1508     */
1509     pct_string_view
1510     encoded_zone_id() const noexcept;
1511 
1512     //--------------------------------------------
1513     //
1514     // Port
1515     //
1516     //--------------------------------------------
1517 
1518     /** Return true if a port is present
1519 
1520         This function returns true if an
1521         authority is present and contains a port.
1522 
1523         @par Example
1524         @code
1525         assert( url_view( "wss://www.example.com:443" ).has_port() );
1526         @endcode
1527 
1528         @par Complexity
1529         Constant.
1530 
1531         @par Exception Safety
1532         Throws nothing.
1533 
1534         @par BNF
1535         @code
1536         authority   = [ userinfo "@" ] host [ ":" port ]
1537 
1538         port        = *DIGIT
1539         @endcode
1540 
1541         @par Specification
1542         @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.2.3">3.2.3. Port (rfc3986)</a>
1543 
1544         @see
1545             @ref encoded_host_and_port,
1546             @ref port,
1547             @ref port_number.
1548 
1549         @return `true` if a port is present, `false` otherwise.
1550     */
1551     bool
1552     has_port() const noexcept;
1553 
1554     /** Return the port
1555 
1556         If present, this function returns a
1557         string representing the port (which
1558         may be empty).
1559         Otherwise it returns an empty string.
1560 
1561         @par Example
1562         @code
1563         assert( url_view( "http://localhost.com:8080" ).port() == "8080" );
1564         @endcode
1565 
1566         @par Complexity
1567         Constant.
1568 
1569         @par Exception Safety
1570         Throws nothing.
1571 
1572         @par BNF
1573         @code
1574         port        = *DIGIT
1575         @endcode
1576 
1577         @par Specification
1578         @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.2.3">3.2.3. Port (rfc3986)</a>
1579 
1580         @see
1581             @ref encoded_host_and_port,
1582             @ref has_port,
1583             @ref port_number.
1584 
1585         @return The port as a string.
1586     */
1587     core::string_view
1588     port() const noexcept;
1589 
1590     /** Return the port
1591 
1592         If a port is present and the numerical
1593         value is representable, it is returned
1594         as an unsigned integer. Otherwise, the
1595         number zero is returned.
1596 
1597         @par Example
1598         @code
1599         assert( url_view( "http://localhost.com:8080" ).port_number() == 8080 );
1600         @endcode
1601 
1602         @par Complexity
1603         Constant.
1604 
1605         @par Exception Safety
1606         Throws nothing.
1607 
1608         @par BNF
1609         @code
1610         port        = *DIGIT
1611         @endcode
1612 
1613         @par Specification
1614         @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.2.3">3.2.3. Port (rfc3986)</a>
1615 
1616         @see
1617             @ref encoded_host_and_port,
1618             @ref has_port,
1619             @ref port.
1620 
1621         @return The port number as an unsigned integer.
1622     */
1623     std::uint16_t
1624     port_number() const noexcept;
1625 
1626     //--------------------------------------------
1627     //
1628     // Path
1629     //
1630     //--------------------------------------------
1631 
1632     /** Return true if the path is absolute
1633 
1634         This function returns true if the path
1635         begins with a forward slash ('/').
1636 
1637         @par Example
1638         @code
1639         assert( url_view( "/path/to/file.txt" ).is_path_absolute() );
1640         @endcode
1641 
1642         @par Complexity
1643         Constant.
1644 
1645         @par Exception Safety
1646         Throws nothing.
1647 
1648         @par BNF
1649         @code
1650         path          = path-abempty    ; begins with "/" or is empty
1651                       / path-absolute   ; begins with "/" but not "//"
1652                       / path-noscheme   ; begins with a non-colon segment
1653                       / path-rootless   ; begins with a segment
1654                       / path-empty      ; zero characters
1655 
1656         path-abempty  = *( "/" segment )
1657         path-absolute = "/" [ segment-nz *( "/" segment ) ]
1658         path-noscheme = segment-nz-nc *( "/" segment )
1659         path-rootless = segment-nz *( "/" segment )
1660         path-empty    = 0<pchar>
1661         @endcode
1662 
1663         @par Specification
1664         @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.3">3.3.  Path (rfc3986)</a>
1665 
1666         @see
1667             @ref encoded_path,
1668             @ref encoded_segments.
1669             @ref path,
1670             @ref segments.
1671 
1672         @return `true` if the path is absolute, `false` otherwise.
1673     */
1674     bool
1675     is_path_absolute() const noexcept
1676     {
1677         return
1678             pi_->len(id_path) > 0 &&
1679             pi_->cs_[pi_->offset(id_path)] == '/';
1680     }
1681 
1682     /** Return the path
1683 
1684         This function returns the path as a
1685         string. The path may be empty.
1686         Any percent-escapes in the string are
1687         decoded first.
1688 
1689         @par Example
1690         @code
1691         assert( url_view( "file:///Program%20Files/Games/config.ini" ).path() == "/Program Files/Games/config.ini" );
1692         @endcode
1693 
1694         @par Complexity
1695         Linear in `this->path().size()`.
1696 
1697         @par Exception Safety
1698         Calls to allocate may throw.
1699 
1700         @par BNF
1701         @code
1702         path          = path-abempty    ; begins with "/" or is empty
1703                       / path-absolute   ; begins with "/" but not "//"
1704                       / path-noscheme   ; begins with a non-colon segment
1705                       / path-rootless   ; begins with a segment
1706                       / path-empty      ; zero characters
1707 
1708         path-abempty  = *( "/" segment )
1709         path-absolute = "/" [ segment-nz *( "/" segment ) ]
1710         path-noscheme = segment-nz-nc *( "/" segment )
1711         path-rootless = segment-nz *( "/" segment )
1712         path-empty    = 0<pchar>
1713         @endcode
1714 
1715         @par Specification
1716         @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.3">3.3. Path (rfc3986)</a>
1717 
1718         @see
1719             @ref is_path_absolute,
1720             @ref encoded_path,
1721             @ref encoded_segments.
1722             @ref segments.
1723 
1724         @param token A string token to use for the result.
1725         @return The path as a string.
1726     */
1727     template<BOOST_URL_STRTOK_TPARAM>
1728     BOOST_URL_STRTOK_RETURN
1729     path(
1730         StringToken&& token = {}) const
1731     {
1732         encoding_opts opt;
1733         opt.space_as_plus = false;
1734         return encoded_path().decode(
1735             opt, std::move(token));
1736     }
1737 
1738     /** Return the path
1739 
1740         This function returns the path as a
1741         string. The path may be empty.
1742         Any percent-escapes in the string are
1743         decoded first.
1744 
1745         @par Example
1746         @code
1747         assert( url_view( "file:///Program%20Files/Games/config.ini" ).encoded_path() == "/Program%20Files/Games/config.ini" );
1748         @endcode
1749 
1750         @par Complexity
1751         Constant.
1752 
1753         @par Exception Safety
1754         Throws nothing.
1755 
1756         @par BNF
1757         @code
1758         path          = path-abempty    ; begins with "/" or is empty
1759                       / path-absolute   ; begins with "/" but not "//"
1760                       / path-noscheme   ; begins with a non-colon segment
1761                       / path-rootless   ; begins with a segment
1762                       / path-empty      ; zero characters
1763 
1764         path-abempty  = *( "/" segment )
1765         path-absolute = "/" [ segment-nz *( "/" segment ) ]
1766         path-noscheme = segment-nz-nc *( "/" segment )
1767         path-rootless = segment-nz *( "/" segment )
1768         path-empty    = 0<pchar>
1769         @endcode
1770 
1771         @par Specification
1772         @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.3">3.3. Path (rfc3986)</a>
1773 
1774         @see
1775             @ref is_path_absolute,
1776             @ref encoded_segments.
1777             @ref path,
1778             @ref segments.
1779 
1780         @return The path as a string.
1781     */
1782     pct_string_view
1783     encoded_path() const noexcept;
1784 
1785     /** Return the path as a container of segments
1786 
1787         This function returns a bidirectional
1788         view of strings over the path.
1789         The returned view references the same
1790         underlying character buffer; ownership
1791         is not transferred.
1792         Any percent-escapes in strings returned
1793         when iterating the view are decoded first.
1794 
1795         @par Example
1796         @code
1797         segments_view sv = url_view( "/path/to/file.txt" ).segments();
1798         @endcode
1799 
1800         @par Complexity
1801         Constant.
1802 
1803         @par Exception Safety
1804         Throws nothing.
1805 
1806         @par BNF
1807         @code
1808         path          = [ "/" ] segment *( "/" segment )
1809         @endcode
1810 
1811         @par Specification
1812         @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.3">3.3. Path (rfc3986)</a>
1813 
1814         @see
1815             @ref is_path_absolute,
1816             @ref encoded_path,
1817             @ref encoded_segments.
1818             @ref path,
1819             @ref segments_view.
1820 
1821         @return A bidirectional view of segments.
1822     */
1823     segments_view
1824     segments() const noexcept;
1825 
1826     /** Return the path as a container of segments
1827 
1828         This function returns a bidirectional
1829         view of strings over the path.
1830         The returned view references the same
1831         underlying character buffer; ownership
1832         is not transferred.
1833         Strings returned when iterating the
1834         range may contain percent escapes.
1835 
1836         @par Example
1837         @code
1838         segments_encoded_view sv = url_view( "/path/to/file.txt" ).encoded_segments();
1839         @endcode
1840 
1841         @par Complexity
1842         Constant.
1843 
1844         @par Exception Safety
1845         Throws nothing.
1846 
1847         @par BNF
1848         @code
1849         path          = path-abempty    ; begins with "/" or is empty
1850                       / path-absolute   ; begins with "/" but not "//"
1851                       / path-noscheme   ; begins with a non-colon segment
1852                       / path-rootless   ; begins with a segment
1853                       / path-empty      ; zero characters
1854 
1855         path-abempty  = *( "/" segment )
1856         path-absolute = "/" [ segment-nz *( "/" segment ) ]
1857         path-noscheme = segment-nz-nc *( "/" segment )
1858         path-rootless = segment-nz *( "/" segment )
1859         path-empty    = 0<pchar>
1860         @endcode
1861 
1862         @par Specification
1863         @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.3">3.3. Path (rfc3986)</a>
1864 
1865         @see
1866             @ref is_path_absolute,
1867             @ref encoded_path,
1868             @ref path,
1869             @ref segments,
1870             @ref segments_encoded_view.
1871 
1872         @return A bidirectional view of encoded segments.
1873     */
1874     segments_encoded_view
1875     encoded_segments() const noexcept;
1876 
1877     //--------------------------------------------
1878     //
1879     // Query
1880     //
1881     //--------------------------------------------
1882 
1883     /** Return true if a query is present
1884 
1885         This function returns true if this
1886         contains a query. An empty query is
1887         distinct from having no query.
1888 
1889         @par Example
1890         @code
1891         assert( url_view( "/sql?id=42&col=name&page-size=20" ).has_query() );
1892         @endcode
1893 
1894         @par Complexity
1895         Constant.
1896 
1897         @par Exception Safety
1898         Throws nothing.
1899 
1900         @par BNF
1901         @code
1902         query           = *( pchar / "/" / "?" )
1903 
1904         query-param     = key [ "=" value ]
1905         query-params    = [ query-param ] *( "&" query-param )
1906         @endcode
1907 
1908         @par Specification
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>
1911 
1912         @see
1913             @ref encoded_params,
1914             @ref encoded_query,
1915             @ref params,
1916             @ref query.
1917 
1918         @return `true` if a query is present.
1919     */
1920     bool
1921     has_query() const noexcept;
1922 
1923     /** Return the query
1924 
1925         If this contains a query, it is returned
1926         as a string (which may be empty).
1927         Otherwise, an empty string is returned.
1928         Any percent-escapes in the string are
1929         decoded first.
1930         <br>
1931         When plus signs appear in the query
1932         portion of the url, they are converted
1933         to spaces automatically upon decoding.
1934         This behavior can be changed by setting
1935         decode options.
1936 
1937         @par Example
1938         @code
1939         assert( url_view( "/sql?id=42&name=jane%2Ddoe&page+size=20" ).query() == "id=42&name=jane-doe&page size=20" );
1940         @endcode
1941 
1942         @par Complexity
1943         Linear in `this->query().size()`.
1944 
1945         @par Exception Safety
1946         Calls to allocate may throw.
1947 
1948         @par BNF
1949         @code
1950         query           = *( pchar / "/" / "?" )
1951 
1952         query-param     = key [ "=" value ]
1953         query-params    = [ query-param ] *( "&" query-param )
1954         @endcode
1955 
1956         @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://en.wikipedia.org/wiki/Query_string">Query string (Wikipedia)</a>
1959 
1960         @see
1961             @ref encoded_params,
1962             @ref encoded_query,
1963             @ref has_query,
1964             @ref params.
1965 
1966         @param token A token to use for the returned string.
1967         @return The query as a string.
1968     */
1969     template<BOOST_URL_STRTOK_TPARAM>
1970     BOOST_URL_STRTOK_RETURN
1971     query(
1972         StringToken&& token = {}) const
1973     {
1974         // When interacting with the query as
1975         // an intact string, we do not treat
1976         // the plus sign as an encoded space.
1977         encoding_opts opt;
1978         opt.space_as_plus = false;
1979         return encoded_query().decode(
1980             opt, std::move(token));
1981     }
1982 
1983     /** Return the query
1984 
1985         If this contains a query, it is returned
1986         as a string (which may be empty).
1987         Otherwise, an empty string is returned.
1988         The returned string may contain
1989         percent escapes.
1990 
1991         @par Example
1992         @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         @endcode
1995 
1996         @par Complexity
1997         Constant.
1998 
1999         @par Exception Safety
2000         Throws nothing.
2001 
2002         @par BNF
2003         @code
2004         query           = *( pchar / "/" / "?" )
2005 
2006         query-param     = key [ "=" value ]
2007         query-params    = [ query-param ] *( "&" query-param )
2008         @endcode
2009 
2010         @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://en.wikipedia.org/wiki/Query_string">Query string (Wikipedia)</a>
2013 
2014         @see
2015             @ref encoded_params,
2016             @ref has_query,
2017             @ref params,
2018             @ref query.
2019 
2020         @return The query as a string.
2021     */
2022     pct_string_view
2023     encoded_query() const noexcept;
2024 
2025     /** Return the query as a container of parameters
2026 
2027         This function returns a bidirectional
2028         view of key/value pairs over the query.
2029         The returned view references the same
2030         underlying character buffer; ownership
2031         is not transferred.
2032         Any percent-escapes in strings returned
2033         when iterating the view are decoded first.
2034 
2035         @par Example
2036         @code
2037         params_view pv = url_view( "/sql?id=42&name=jane%2Ddoe&page+size=20" ).params();
2038         @endcode
2039 
2040         @par Complexity
2041         Constant.
2042 
2043         @par Exception Safety
2044         Throws nothing.
2045 
2046         @par BNF
2047         @code
2048         query           = *( pchar / "/" / "?" )
2049 
2050         query-param     = key [ "=" value ]
2051         query-params    = [ query-param ] *( "&" query-param )
2052         @endcode
2053 
2054         @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://en.wikipedia.org/wiki/Query_string">Query string (Wikipedia)</a>
2057 
2058         @see
2059             @ref encoded_params,
2060             @ref encoded_query,
2061             @ref has_query,
2062             @ref query.
2063 
2064         @return A bidirectional view of key/value pairs.
2065     */
2066     params_view
2067     params() const noexcept;
2068 
2069     params_view
2070     params(encoding_opts opt) const noexcept;
2071 
2072     /** Return the query as a container of parameters
2073 
2074         This function returns a bidirectional
2075         view of key/value pairs over the query.
2076         The returned view references the same
2077         underlying character buffer; ownership
2078         is not transferred.
2079         Strings returned when iterating the
2080         range may contain percent escapes.
2081 
2082         @par Example
2083         @code
2084         params_encoded_view pv = url_view( "/sql?id=42&name=jane%2Ddoe&page+size=20" ).encoded_params();
2085         @endcode
2086 
2087         @par Complexity
2088         Constant.
2089 
2090         @par Exception Safety
2091         Throws nothing.
2092 
2093         @par BNF
2094         @code
2095         query           = *( pchar / "/" / "?" )
2096         query-param     = key [ "=" value ]
2097         query-params    = [ query-param ] *( "&" query-param )
2098         @endcode
2099 
2100         @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://en.wikipedia.org/wiki/Query_string">Query string (Wikipedia)</a>
2103 
2104         @see
2105             @ref encoded_query,
2106             @ref has_query,
2107             @ref params,
2108             @ref query.
2109 
2110         @return A bidirectional view of key/value pairs.
2111     */
2112     params_encoded_view
2113     encoded_params() const noexcept;
2114 
2115     //--------------------------------------------
2116     //
2117     // Fragment
2118     //
2119     //--------------------------------------------
2120 
2121     /** Return true if a fragment is present
2122 
2123         This function returns true if the url
2124         contains a fragment.
2125         An empty fragment is distinct from
2126         no fragment.
2127 
2128         @par Example
2129         @code
2130         assert( url_view( "http://www.example.com/index.htm#anchor" ).has_fragment() );
2131         @endcode
2132 
2133         @par Complexity
2134         Constant.
2135 
2136         @par Exception Safety
2137         Throws nothing.
2138 
2139         @par BNF
2140         @code
2141         URI           = scheme ":" hier-part [ "?" query ] [ "#" fragment ]
2142 
2143         relative-ref  = relative-part [ "?" query ] [ "#" fragment ]
2144         @endcode
2145 
2146         @par Specification
2147         @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.5">3.5. Fragment (rfc3986)</a>
2148 
2149         @see
2150             @ref encoded_fragment,
2151             @ref fragment.
2152 
2153         @return `true` if the url contains a fragment.
2154     */
2155     bool
2156     has_fragment() const noexcept;
2157 
2158     /** Return the fragment
2159 
2160         This function calculates the fragment
2161         of the url, with percent escapes decoded
2162         and without the leading pound sign ('#')
2163         whose presence indicates that the url
2164         contains a fragment.
2165 
2166         <br>
2167 
2168         This function accepts an optional
2169         <em>StringToken</em> parameter which
2170         controls the return type and behavior
2171         of the function:
2172 
2173         @li When called with no arguments,
2174         the return type of the function is
2175         `std::string`. Otherwise
2176 
2177         @li When called with a string token,
2178         the behavior and return type of the
2179         function depends on the type of string
2180         token being passed.
2181 
2182         @par Example
2183         @code
2184         assert( url_view( "http://www.example.com/index.htm#a%2D1" ).fragment() == "a-1" );
2185         @endcode
2186 
2187         @par Complexity
2188         Linear in `this->fragment().size()`.
2189 
2190         @par Exception Safety
2191         Calls to allocate may throw.
2192         String tokens may throw exceptions.
2193 
2194         @param token An optional string token to
2195         use. If this parameter is omitted, the
2196         function returns a new `std::string`.
2197 
2198         @return The fragment portion of the url.
2199 
2200         @par BNF
2201         @code
2202         fragment        = *( pchar / "/" / "?" )
2203 
2204         fragment-part   = [ "#" fragment ]
2205         @endcode
2206 
2207         @par Specification
2208         @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.5">3.5. Fragment (rfc3986)</a>
2209 
2210         @see
2211             @ref encoded_fragment,
2212             @ref has_fragment.
2213 
2214     */
2215     template<BOOST_URL_STRTOK_TPARAM>
2216     BOOST_URL_STRTOK_RETURN
2217     fragment(
2218         StringToken&& token = {}) const
2219     {
2220         encoding_opts opt;
2221         opt.space_as_plus = false;
2222         return encoded_fragment().decode(
2223             opt, std::move(token));
2224     }
2225 
2226     /** Return the fragment
2227 
2228         This function returns the fragment as a
2229         string with percent-escapes.
2230         Ownership is not transferred; the
2231         string returned references the underlying
2232         character buffer, which must remain valid
2233         or else undefined behavior occurs.
2234 
2235         @par Example
2236         @code
2237         assert( url_view( "http://www.example.com/index.htm#a%2D1" ).encoded_fragment() == "a%2D1" );
2238         @endcode
2239 
2240         @par Complexity
2241         Constant.
2242 
2243         @par Exception Safety
2244         Throws nothing.
2245 
2246         @par BNF
2247         @code
2248         fragment        = *( pchar / "/" / "?" )
2249 
2250         pchar           = unreserved / pct-encoded / sub-delims / ":" / "@"
2251         @endcode
2252 
2253         @par Specification
2254         @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.5">3.5. Fragment (rfc3986)</a>
2255 
2256         @see
2257             @ref fragment,
2258             @ref has_fragment.
2259 
2260         @return The fragment portion of the url.
2261     */
2262     pct_string_view
2263     encoded_fragment() const noexcept;
2264 
2265     //--------------------------------------------
2266     //
2267     // Compound Fields
2268     //
2269     //--------------------------------------------
2270 
2271     /** Return the host and port
2272 
2273         If an authority is present, this
2274         function returns the host and optional
2275         port as a string, which may be empty.
2276         Otherwise it returns an empty string.
2277         The returned string may contain
2278         percent escapes.
2279 
2280         @par Example
2281         @code
2282         assert( url_view( "http://www.example.com:8080/index.htm" ).encoded_host_and_port() == "www.example.com:8080" );
2283         @endcode
2284 
2285         @par Complexity
2286         Constant.
2287 
2288         @par Exception Safety
2289         Throws nothing.
2290 
2291         @par BNF
2292         @code
2293         authority   = [ userinfo "@" ] host [ ":" port ]
2294         @endcode
2295 
2296         @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.3">3.2.3. Port (rfc3986)</a>
2299 
2300         @see
2301             @ref has_port,
2302             @ref port,
2303             @ref port_number.
2304 
2305         @return The host and port portion of the url.
2306     */
2307     pct_string_view
2308     encoded_host_and_port() const noexcept;
2309 
2310     /** Return the origin
2311 
2312         If an authority is present, this
2313         function returns the scheme and
2314         authority portion of the url.
2315         Otherwise, an empty string is
2316         returned.
2317         The returned string may contain
2318         percent escapes.
2319 
2320         @par Example
2321         @code
2322         assert( url_view( "http://www.example.com:8080/index.htm?text=none#h1" ).encoded_origin() == "http://www.example.com:8080" );
2323         @endcode
2324 
2325         @par Complexity
2326         Constant.
2327 
2328         @par Exception Safety
2329         Throws nothing.
2330 
2331         @see
2332             @ref encoded_resource,
2333             @ref encoded_target.
2334 
2335         @return The origin portion of the url.
2336     */
2337     pct_string_view
2338     encoded_origin() const noexcept;
2339 
2340     /** Return the resource
2341 
2342         This function returns the resource, which
2343         is the portion of the url that includes
2344         only the path, query, and fragment.
2345         The returned string may contain
2346         percent escapes.
2347 
2348         @par Example
2349         @code
2350         assert( url_view( "http://www.example.com/index.html?query#frag" ).encoded_resource() == "/index.html?query#frag" );
2351         @endcode
2352 
2353         @par Complexity
2354         Constant.
2355 
2356         @par Exception Safety
2357         Throws nothing.
2358 
2359         @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.4">3.4. Query (rfc3986)</a>
2362 
2363         @see
2364             @ref encoded_origin,
2365             @ref encoded_target.
2366 
2367         @return The resource portion of the url.
2368     */
2369     pct_string_view
2370     encoded_resource() const noexcept;
2371 
2372     /** Return the target
2373 
2374         This function returns the target, which
2375         is the portion of the url that includes
2376         only the path and query.
2377         The returned string may contain
2378         percent escapes.
2379 
2380         @par Example
2381         @code
2382         assert( url_view( "http://www.example.com/index.html?query#frag" ).encoded_target() == "/index.html?query" );
2383         @endcode
2384 
2385         @par Complexity
2386         Constant.
2387 
2388         @par Exception Safety
2389         Throws nothing.
2390 
2391         @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.4">3.4. Query (rfc3986)</a>
2394 
2395         @see
2396             @ref encoded_origin,
2397             @ref encoded_resource.
2398 
2399         @return The target portion of the url.
2400     */
2401     pct_string_view
2402     encoded_target() const noexcept;
2403 
2404     //--------------------------------------------
2405     //
2406     // Comparison
2407     //
2408     //--------------------------------------------
2409 
2410     /** Return the result of comparing this with another url
2411 
2412         This function compares two URLs
2413         according to Syntax-Based comparison
2414         algorithm.
2415 
2416         @par Complexity
2417         Linear in `min( u0.size(), u1.size() )`
2418 
2419         @par Exception Safety
2420         Throws nothing.
2421 
2422         @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 
2425         @param other The url to compare
2426         @return -1 if `*this < other`, 0 if `this == other`, and 1 if `this > other`.
2427     */
2428     int
2429     compare(url_view_base const& other) const noexcept;
2430 
2431     /** Return the result of comparing two URLs
2432 
2433         The URLs are compared component by
2434         component as if they were first
2435         normalized.
2436 
2437         @par Example
2438         @code
2439         url_view u0( "http://www.a.com/index.htm" );
2440         url_view u1( "http://www.a.com/index.htm" );
2441         assert( u0 == u1 );
2442         @endcode
2443 
2444         @par Effects
2445         @code
2446         url a(u0);
2447         a.normalize();
2448         url b(u1);
2449         b.normalize();
2450         return a.buffer() == b.buffer();
2451         @endcode
2452 
2453         @par Complexity
2454         Linear in `min( u0.size(), u1.size() )`
2455 
2456         @par Exception Safety
2457         Throws nothing
2458 
2459         @param u0 The first url to compare
2460         @param u1 The second url to compare
2461         @return `true` if `u0 == u1`
2462 
2463         @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     */
2466     friend
2467     bool
2468     operator==(
2469         url_view_base const& u0,
2470         url_view_base const& u1) noexcept
2471     {
2472         return u0.compare(u1) == 0;
2473     }
2474 
2475     /** Return the result of comparing two URLs
2476 
2477         The URLs are compared component by
2478         component as if they were first
2479         normalized.
2480 
2481         @par Example
2482         @code
2483         url_view u0( "http://www.a.com/index.htm" );
2484         url_view u1( "http://www.b.com/index.htm" );
2485         assert( u0 != u1 );
2486         @endcode
2487 
2488         @par Effects
2489         @code
2490         url a(u0);
2491         a.normalize();
2492         url b(u1);
2493         b.normalize();
2494         return a.buffer() != b.buffer();
2495         @endcode
2496 
2497         @par Complexity
2498         Linear in `min( u0.size(), u1.size() )`
2499 
2500         @par Exception Safety
2501         Throws nothing
2502 
2503         @param u0 The first url to compare
2504         @param u1 The second url to compare
2505         @return `true` if `u0 != u1`
2506 
2507         @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     */
2510     friend
2511     bool
2512     operator!=(
2513         url_view_base const& u0,
2514         url_view_base const& u1) noexcept
2515     {
2516         return ! (u0 == u1);
2517     }
2518 
2519     /** Return the result of comparing two URLs
2520 
2521         The URLs are compared component by
2522         component as if they were first
2523         normalized.
2524 
2525         @par Example
2526         @code
2527         url_view u0( "http://www.a.com/index.htm" );
2528         url_view u1( "http://www.b.com/index.htm" );
2529         assert( u0 < u1 );
2530         @endcode
2531 
2532         @par Effects
2533         @code
2534         url a(u0);
2535         a.normalize();
2536         url b(u1);
2537         b.normalize();
2538         return a.buffer() < b.buffer();
2539         @endcode
2540 
2541         @par Complexity
2542         Linear in `min( u0.size(), u1.size() )`
2543 
2544         @par Exception Safety
2545         Throws nothing
2546 
2547         @param u0 The first url to compare
2548         @param u1 The second url to compare
2549         @return `true` if `u0 < u1`
2550 
2551         @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     */
2554     friend
2555     bool
2556     operator<(
2557         url_view_base const& u0,
2558         url_view_base const& u1) noexcept
2559     {
2560         return u0.compare(u1) < 0;
2561     }
2562 
2563     /** Return the result of comparing two URLs
2564 
2565         The URLs are compared component by
2566         component as if they were first
2567         normalized.
2568 
2569         @par Example
2570         @code
2571         url_view u0( "http://www.b.com/index.htm" );
2572         url_view u1( "http://www.b.com/index.htm" );
2573         assert( u0 <= u1 );
2574         @endcode
2575 
2576         @par Effects
2577         @code
2578         url a(u0);
2579         a.normalize();
2580         url b(u1);
2581         b.normalize();
2582         return a.buffer() <= b.buffer();
2583         @endcode
2584 
2585         @par Complexity
2586         Linear in `min( u0.size(), u1.size() )`
2587 
2588         @par Exception Safety
2589         Throws nothing
2590 
2591         @param u0 The first url to compare
2592         @param u1 The second url to compare
2593         @return `true` if `u0 <= u1`
2594 
2595         @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     */
2598     friend
2599     bool
2600     operator<=(
2601         url_view_base const& u0,
2602         url_view_base const& u1) noexcept
2603     {
2604         return u0.compare(u1) <= 0;
2605     }
2606 
2607     /** Return the result of comparing two URLs
2608 
2609         The URLs are compared component by
2610         component as if they were first
2611         normalized.
2612 
2613         @par Example
2614         @code
2615         url_view u0( "http://www.b.com/index.htm" );
2616         url_view u1( "http://www.a.com/index.htm" );
2617         assert( u0 > u1 );
2618         @endcode
2619 
2620         @par Effects
2621         @code
2622         url a(u0);
2623         a.normalize();
2624         url b(u1);
2625         b.normalize();
2626         return a.buffer() > b.buffer();
2627         @endcode
2628 
2629         @par Complexity
2630         Linear in `min( u0.size(), u1.size() )`
2631 
2632         @par Exception Safety
2633         Throws nothing
2634 
2635         @param u0 The first url to compare
2636         @param u1 The second url to compare
2637         @return `true` if `u0 > u1`
2638 
2639         @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     */
2642     friend
2643     bool
2644     operator>(
2645         url_view_base const& u0,
2646         url_view_base const& u1) noexcept
2647     {
2648         return u0.compare(u1) > 0;
2649     }
2650 
2651     /** Return the result of comparing two URLs
2652 
2653         The URLs are compared component by
2654         component as if they were first
2655         normalized.
2656 
2657         @par Example
2658         @code
2659         url_view u0( "http://www.a.com/index.htm" );
2660         url_view u1( "http://www.a.com/index.htm" );
2661         assert( u0 >= u1 );
2662         @endcode
2663 
2664         @par Effects
2665         @code
2666         url a(u0);
2667         a.normalize();
2668         url b(u1);
2669         b.normalize();
2670         return a.buffer() >= b.buffer();
2671         @endcode
2672 
2673         @par Complexity
2674         Linear in `min( u0.size(), u1.size() )`
2675 
2676         @par Exception Safety
2677         Throws nothing
2678 
2679         @param u0 The first url to compare
2680         @param u1 The second url to compare
2681         @return `true` if `u0 >= u1`
2682 
2683         @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     */
2686     friend
2687     bool
2688     operator>=(
2689         url_view_base const& u0,
2690         url_view_base const& u1) noexcept
2691     {
2692         return u0.compare(u1) >= 0;
2693     }
2694 
2695     /** Format the url to the output stream
2696 
2697         This function serializes the url to
2698         the specified output stream. Any
2699         percent-escapes are emitted as-is;
2700         no decoding is performed.
2701 
2702         @par Example
2703         @code
2704         url_view u( "http://www.example.com/index.htm" );
2705         std::stringstream ss;
2706         ss << u;
2707         assert( ss.str() == "http://www.example.com/index.htm" );
2708         @endcode
2709 
2710         @par Effects
2711         @code
2712         return os << u.buffer();
2713         @endcode
2714 
2715         @par Complexity
2716         Linear in `u.buffer().size()`
2717 
2718         @par Exception Safety
2719         Basic guarantee.
2720 
2721         @return A reference to the output stream, for chaining
2722 
2723         @param os The output stream to write to.
2724 
2725         @param u The url to write.
2726     */
2727     friend
2728     std::ostream&
2729     operator<<(
2730         std::ostream& os,
2731         url_view_base const& u)
2732     {
2733         return os << u.buffer();
2734     }
2735 
2736 private:
2737     //--------------------------------------------
2738     //
2739     // implementation
2740     //
2741     //--------------------------------------------
2742     static
2743     int
2744     segments_compare(
2745         segments_encoded_view seg0,
2746         segments_encoded_view seg1) noexcept;
2747 };
2748 
2749 //------------------------------------------------
2750 
2751 /** Format the url to the output stream
2752 
2753     This function serializes the url to
2754     the specified output stream. Any
2755     percent-escapes are emitted as-is;
2756     no decoding is performed.
2757 
2758     @par Example
2759     @code
2760     url_view u( "http://www.example.com/index.htm" );
2761     std::stringstream ss;
2762     ss << u;
2763     assert( ss.str() == "http://www.example.com/index.htm" );
2764     @endcode
2765 
2766     @par Effects
2767     @code
2768     return os << u.buffer();
2769     @endcode
2770 
2771     @par Complexity
2772     Linear in `u.buffer().size()`
2773 
2774     @par Exception Safety
2775     Basic guarantee.
2776 
2777     @return A reference to the output stream, for chaining
2778 
2779     @param os The output stream to write to.
2780 
2781     @param u The url to write.
2782 */
2783 std::ostream&
2784 operator<<(
2785     std::ostream& os,
2786     url_view_base const& u);
2787 
2788 } // urls
2789 } // boost
2790 
2791 #endif