Back to home page

EIC code displayed by LXR

 
 

    


Warning, file /include/boost/url/url_base.hpp was not indexed or was modified since last indexation (in which case cross-reference links may be missing, inaccurate or erroneous).

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