Back to home page

EIC code displayed by LXR

 
 

    


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

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