Back to home page

EIC code displayed by LXR

 
 

    


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

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