Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 09:53:30

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