LCOV - code coverage report
Current view: top level - boost/url/url_base.hpp (source / functions) Coverage Total Hit
Test: coverage_filtered.info Lines: 100.0 % 24 24
Test Date: 2024-07-10 02:48:26 Functions: 91.7 % 12 11

            Line data    Source code
       1              : //
       2              : // Copyright (c) 2019 Vinnie Falco (vinnie.falco@gmail.com)
       3              : // Copyright (c) 2022 Alan de Freitas (alandefreitas@gmail.com)
       4              : //
       5              : // Distributed under the Boost Software License, Version 1.0. (See accompanying
       6              : // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
       7              : //
       8              : // Official repository: https://github.com/boostorg/url
       9              : //
      10              : 
      11              : #ifndef BOOST_URL_URL_BASE_HPP
      12              : #define BOOST_URL_URL_BASE_HPP
      13              : 
      14              : #include <boost/url/detail/config.hpp>
      15              : #include <boost/url/ipv4_address.hpp>
      16              : #include <boost/url/ipv6_address.hpp>
      17              : #include <boost/url/params_encoded_ref.hpp>
      18              : #include <boost/url/params_ref.hpp>
      19              : #include <boost/url/pct_string_view.hpp>
      20              : #include <boost/url/scheme.hpp>
      21              : #include <boost/url/segments_encoded_ref.hpp>
      22              : #include <boost/url/segments_ref.hpp>
      23              : #include <boost/url/url_view_base.hpp>
      24              : #include <cstdint>
      25              : #include <initializer_list>
      26              : #include <memory>
      27              : #include <string>
      28              : #include <utility>
      29              : 
      30              : namespace boost {
      31              : namespace urls {
      32              : 
      33              : #ifndef BOOST_URL_DOCS
      34              : namespace detail {
      35              : struct any_params_iter;
      36              : struct any_segments_iter;
      37              : struct params_iter_impl;
      38              : struct segments_iter_impl;
      39              : struct pattern;
      40              : }
      41              : #endif
      42              : 
      43              : /** Common functionality for containers
      44              : 
      45              :     This base class is used by the library
      46              :     to provide common member functions for
      47              :     containers. This cannot be instantiated
      48              :     directly; Instead, use one of the
      49              :     containers or functions:
      50              : 
      51              :     @par Containers
      52              :         @li @ref url
      53              :         @li @ref url_view
      54              :         @li @ref static_url
      55              : 
      56              :     @par Functions
      57              :         @li @ref parse_absolute_uri
      58              :         @li @ref parse_origin_form
      59              :         @li @ref parse_relative_ref
      60              :         @li @ref parse_uri
      61              :         @li @ref parse_uri_reference
      62              : */
      63              : class BOOST_URL_DECL
      64              :     url_base
      65              :     : public url_view_base
      66              : {
      67              :     char* s_ = nullptr;
      68              :     std::size_t cap_ = 0;
      69              : 
      70              :     friend class url;
      71              :     friend class static_url_base;
      72              :     friend class params_ref;
      73              :     friend class segments_ref;
      74              :     friend class segments_encoded_ref;
      75              :     friend class params_encoded_ref;
      76              : #ifndef BOOST_URL_DOCS
      77              :     friend struct detail::pattern;
      78              : #endif
      79              : 
      80              :     struct op_t
      81              :     {
      82              :         ~op_t();
      83              :         op_t(url_base&,
      84              :             core::string_view* = nullptr,
      85              :             core::string_view* = nullptr) noexcept;
      86              :         void move(char*, char const*,
      87              :             std::size_t) noexcept;
      88              : 
      89              :         url_base& u;
      90              :         core::string_view* s0 = nullptr;
      91              :         core::string_view* s1 = nullptr;
      92              :         char* old = nullptr;
      93              :     };
      94              : 
      95         5559 :     virtual ~url_base() noexcept = default;
      96         4059 :     url_base() noexcept = default;
      97              :     url_base(detail::url_impl const&) noexcept;
      98              :     explicit url_base(core::string_view);
      99              :     void reserve_impl(std::size_t n);
     100              :     void copy(url_view_base const&);
     101              :     virtual void clear_impl() noexcept = 0;
     102              :     virtual void reserve_impl(
     103              :         std::size_t, op_t&) = 0;
     104              :     virtual void cleanup(op_t&) = 0;
     105              : 
     106              : public:
     107              :     //--------------------------------------------
     108              :     //
     109              :     // Observers
     110              :     //
     111              :     //--------------------------------------------
     112              : 
     113              :     /** Return the url as a null-terminated string
     114              : 
     115              :         This function returns a pointer to a null
     116              :         terminated string representing the url,
     117              :         which may contain percent escapes.
     118              : 
     119              :         @par Example
     120              :         @code
     121              :         assert( std::strlen( url( "http://www.example.com" ).c_str() ) == 22 );
     122              :         @endcode
     123              : 
     124              :         @par Complexity
     125              :         Constant.
     126              : 
     127              :         @par Exception Safety
     128              :         Throws nothing.
     129              :     */
     130              :     char const*
     131        17769 :     c_str() const noexcept
     132              :     {
     133        17769 :         return pi_->cs_;
     134              :     }
     135              : 
     136              :     /** Return the number of characters that can be stored without reallocating
     137              : 
     138              :         This does not include the null terminator,
     139              :         which is always present.
     140              : 
     141              :         @par Complexity
     142              :         Constant.
     143              : 
     144              :         @par Exception Safety
     145              :         Throws nothing.
     146              :     */
     147              :     std::size_t
     148           10 :     capacity() const noexcept
     149              :     {
     150           10 :         return cap_;
     151              :     }
     152              : 
     153              :     /** Clear the contents while preserving the capacity
     154              : 
     155              :         @par Postconditions
     156              :         @code
     157              :         this->empty() == true
     158              :         @endcode
     159              : 
     160              :         @par Complexity
     161              :         Constant.
     162              : 
     163              :         @par Exception Safety
     164              :         No-throw guarantee.
     165              :     */
     166              :     void
     167          120 :     clear() noexcept
     168              :     {
     169          120 :         this->clear_impl();
     170          120 :     }
     171              : 
     172              :     /** Adjust the capacity without changing the size
     173              : 
     174              :         This function adjusts the capacity
     175              :         of the container in characters, without
     176              :         affecting the current contents. Has
     177              :         no effect if `n <= this->capacity()`.
     178              : 
     179              :         @par Exception Safety
     180              :         Strong guarantee.
     181              :         Calls to allocate may throw.
     182              : 
     183              :         @throw bad_alloc Allocation failure
     184              : 
     185              :         @param n The capacity in characters,
     186              :         excluding any null terminator.
     187              :     */
     188              :     void
     189          150 :     reserve(std::size_t n)
     190              :     {
     191          150 :         reserve_impl(n);
     192          149 :     }
     193              : 
     194              :     //--------------------------------------------
     195              :     //
     196              :     // Fluent API
     197              :     //
     198              : 
     199              :     //--------------------------------------------
     200              :     //
     201              :     // Scheme
     202              :     //
     203              :     //--------------------------------------------
     204              : 
     205              :     /** Set the scheme
     206              : 
     207              :         The scheme is set to the specified
     208              :         string, which must contain a valid
     209              :         scheme without any trailing colon
     210              :         (':').
     211              :         Note that schemes are case-insensitive,
     212              :         and the canonical form is lowercased.
     213              : 
     214              :         @par Example
     215              :         @code
     216              :         assert( url( "http://www.example.com" ).set_scheme( "https" ).scheme_id() == scheme::https );
     217              :         @endcode
     218              : 
     219              :         @par Complexity
     220              :         Linear in `this->size() + s.size()`.
     221              : 
     222              :         @par Exception Safety
     223              :         Strong guarantee.
     224              :         Calls to allocate may throw.
     225              :         Exceptions thrown on invalid input.
     226              : 
     227              :         @throw system_error
     228              :         `s` contains an invalid scheme.
     229              : 
     230              :         @param s The scheme to set.
     231              : 
     232              :         @par BNF
     233              :         @code
     234              :         scheme        = ALPHA *( ALPHA / DIGIT / "+" / "-" / "." )
     235              :         @endcode
     236              : 
     237              :         @par Specification
     238              :         @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.1">
     239              :             3.1. Scheme (rfc3986)</a>
     240              : 
     241              :         @see
     242              :             @ref remove_scheme.
     243              :     */
     244              :     url_base&
     245              :     set_scheme(core::string_view s);
     246              : 
     247              :     /** Set the scheme
     248              : 
     249              :         This function sets the scheme to the specified
     250              :         known @ref urls::scheme id, which may not be
     251              :         @ref scheme::unknown or else an exception is
     252              :         thrown. If the id is @ref scheme::none, this
     253              :         function behaves as if @ref remove_scheme
     254              :         were called.
     255              : 
     256              :         @par Example
     257              :         @code
     258              :         assert( url( "http://example.com/echo.cgi" ).set_scheme_id( scheme::wss ).buffer() == "wss://example.com/echo.cgi" );
     259              :         @endcode
     260              : 
     261              :         @par Complexity
     262              :         Linear in `this->size()`.
     263              : 
     264              :         @par Exception Safety
     265              :         Strong guarantee.
     266              :         Calls to allocate may throw.
     267              :         Exceptions thrown on invalid input.
     268              : 
     269              :         @throw system_error
     270              :         The scheme is invalid.
     271              : 
     272              :         @param id The scheme to set.
     273              : 
     274              :         @par Specification
     275              :         @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.1">
     276              :             3.1. Scheme (rfc3986)</a>
     277              :     */
     278              :     url_base&
     279              : #ifndef BOOST_URL_DOCS
     280              :     set_scheme_id(urls::scheme id);
     281              : #else
     282              :     set_scheme_id(scheme id);
     283              : #endif
     284              : 
     285              :     /** Remove the scheme
     286              : 
     287              :         This function removes the scheme if it
     288              :         is present.
     289              : 
     290              :         @par Example
     291              :         @code
     292              :         assert( url("http://www.example.com/index.htm" ).remove_scheme().buffer() == "//www.example.com/index.htm" );
     293              :         @endcode
     294              : 
     295              :         @par Postconditions
     296              :         @code
     297              :         this->has_scheme() == false && this->scheme_id() == scheme::none
     298              :         @endcode
     299              : 
     300              :         @par Complexity
     301              :         Linear in `this->size()`.
     302              : 
     303              :         @par Exception Safety
     304              :         Throws nothing.
     305              : 
     306              :         @par BNF
     307              :         @code
     308              :         URI           = scheme ":" hier-part [ "?" query ] [ "#" fragment ]
     309              :         @endcode
     310              : 
     311              :         @par Specification
     312              :         @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.1">
     313              :             3.1. Scheme (rfc3986)</a>
     314              : 
     315              :         @see
     316              :             @ref set_scheme.
     317              :     */
     318              :     url_base&
     319              :     remove_scheme();
     320              : 
     321              :     //--------------------------------------------
     322              :     //
     323              :     // Authority
     324              :     //
     325              :     //--------------------------------------------
     326              : 
     327              :     /** Set the authority
     328              : 
     329              :         This function sets the authority
     330              :         to the specified string.
     331              :         The string may contain percent-escapes.
     332              : 
     333              :         @par Example
     334              :         @code
     335              :         assert( url().set_encoded_authority( "My%20Computer" ).has_authority() );
     336              :         @endcode
     337              : 
     338              :         @par Exception Safety
     339              :         Strong guarantee.
     340              :         Calls to allocate may throw.
     341              :         Exceptions thrown on invalid input.
     342              : 
     343              :         @throw system_eror
     344              :         The string contains an invalid percent-encoding.
     345              : 
     346              :         @param s The authority string to set.
     347              : 
     348              :         @par BNF
     349              :         @code
     350              :         authority     = [ userinfo "@" ] host [ ":" port ]
     351              : 
     352              :         userinfo      = *( unreserved / pct-encoded / sub-delims / ":" )
     353              :         host          = IP-literal / IPv4address / reg-name
     354              :         port          = *DIGIT
     355              :         @endcode
     356              : 
     357              :         @par Specification
     358              :         @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.2">
     359              :             3.2. Authority (rfc3986)</a>
     360              :         @see
     361              :             @ref remove_authority.
     362              :     */
     363              :     url_base&
     364              :     set_encoded_authority(
     365              :         pct_string_view s);
     366              : 
     367              :     /** Remove the authority
     368              : 
     369              :         This function removes the authority,
     370              :         which includes the userinfo, host, and
     371              :         a port if present.
     372              : 
     373              :         @par Example
     374              :         @code
     375              :         assert( url( "http://example.com/echo.cgi" ).remove_authority().buffer() == "http:/echo.cgi" );
     376              :         @endcode
     377              : 
     378              :         @par Postconditions
     379              :         @code
     380              :         this->has_authority() == false && this->has_userinfo() == false && this->has_port() == false
     381              :         @endcode
     382              : 
     383              :         @par Complexity
     384              :         Linear in `this->size()`.
     385              : 
     386              :         @par Exception Safety
     387              :         Throws nothing.
     388              : 
     389              :         @par BNF
     390              :         @code
     391              :         authority     = [ userinfo "@" ] host [ ":" port ]
     392              : 
     393              :         userinfo      = *( unreserved / pct-encoded / sub-delims / ":" )
     394              :         host          = IP-literal / IPv4address / reg-name
     395              :         port          = *DIGIT
     396              :         @endcode
     397              : 
     398              :         @par Specification
     399              :         @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.2">
     400              :             3.2. Authority (rfc3986)</a>
     401              : 
     402              :         @see
     403              :             @ref set_encoded_authority.
     404              :     */
     405              :     url_base&
     406              :     remove_authority();
     407              : 
     408              :     //--------------------------------------------
     409              :     //
     410              :     // Userinfo
     411              :     //
     412              :     //--------------------------------------------
     413              : 
     414              :     /** Set the userinfo
     415              : 
     416              :         The userinfo is set to the given string,
     417              :         which may contain percent-escapes.
     418              :         Any special or reserved characters in the
     419              :         string are automatically percent-encoded.
     420              :         The effects on the user and password
     421              :         depend on the presence of a colon (':')
     422              :         in the string:
     423              : 
     424              :         @li If an unescaped colon exists, the
     425              :         characters up to the colon become
     426              :         the user and the rest of the characters
     427              :         after the colon become the password.
     428              :         In this case @ref has_password returns
     429              :         true. Otherwise,
     430              : 
     431              :         @li If there is no colon, the user is
     432              :         set to the string. The function
     433              :         @ref has_password returns false.
     434              : 
     435              :         @note
     436              :         The interpretation of the userinfo as
     437              :         individual user and password components
     438              :         is scheme-dependent. Transmitting
     439              :         passwords in URLs is deprecated.
     440              : 
     441              :         @par Example
     442              :         @code
     443              :         assert( url( "http://example.com" ).set_userinfo( "user:pass" ).encoded_user() == "user" );
     444              :         @endcode
     445              : 
     446              :         @par Complexity
     447              :         Linear in `this->size() + s.size()`.
     448              : 
     449              :         @par Exception Safety
     450              :         Strong guarantee.
     451              :         Calls to allocate may throw.
     452              : 
     453              :         @param s The string to set.
     454              : 
     455              :         @par BNF
     456              :         @code
     457              :         userinfo      = [ [ user ] [ ':' password ] ]
     458              : 
     459              :         user          = *( unreserved / pct-encoded / sub-delims )
     460              :         password      = *( unreserved / pct-encoded / sub-delims / ":" )
     461              :         @endcode
     462              : 
     463              :         @par Specification
     464              :         @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.2.1">
     465              :             3.2.1. User Information (rfc3986)</a>
     466              : 
     467              :         @see
     468              :             @ref remove_userinfo,
     469              :             @ref set_encoded_userinfo.
     470              :     */
     471              :     url_base&
     472              :     set_userinfo(
     473              :         core::string_view s);
     474              : 
     475              :     /** Set the userinfo.
     476              : 
     477              :         The userinfo is set to the given string,
     478              :         which may contain percent-escapes.
     479              :         Escapes in the string are preserved,
     480              :         and reserved characters in the string
     481              :         are percent-escaped in the result.
     482              :         The effects on the user and password
     483              :         depend on the presence of a colon (':')
     484              :         in the string:
     485              : 
     486              :         @li If an unescaped colon exists, the
     487              :         characters up to the colon become
     488              :         the user and the rest of the characters
     489              :         after the colon become the password.
     490              :         In this case @ref has_password returns
     491              :         true. Otherwise,
     492              : 
     493              :         @li If there is no colon, the user is
     494              :         set to the string. The function
     495              :         @ref has_password returns false.
     496              : 
     497              :         @note
     498              :         The interpretation of the userinfo as
     499              :         individual user and password components
     500              :         is scheme-dependent. Transmitting
     501              :         passwords in URLs is deprecated.
     502              : 
     503              :         @par Example
     504              :         @code
     505              :         assert( url( "http://example.com" ).set_encoded_userinfo( "john%20doe" ).user() == "john doe" );
     506              :         @endcode
     507              : 
     508              :         @par Complexity
     509              :         Linear in `this->size() + s.size()`.
     510              : 
     511              :         @par Exception Safety
     512              :         Strong guarantee.
     513              :         Calls to allocate may throw.
     514              :         Exceptions thrown on invalid input.
     515              : 
     516              :         @throw system_error
     517              :         `s` contains an invalid percent-encoding.
     518              : 
     519              :         @param s The string to set.
     520              : 
     521              :         @par BNF
     522              :         @code
     523              :         userinfo      = [ [ user ] [ ':' password ] ]
     524              : 
     525              :         user          = *( unreserved / pct-encoded / sub-delims )
     526              :         password      = *( unreserved / pct-encoded / sub-delims / ":" )
     527              :         @endcode
     528              : 
     529              :         @par Specification
     530              :         @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.2.1">
     531              :             3.2.1. User Information (rfc3986)</a>
     532              : 
     533              :         @see
     534              :             @ref remove_userinfo,
     535              :             @ref set_userinfo.
     536              :     */
     537              :     url_base&
     538              :     set_encoded_userinfo(
     539              :         pct_string_view s);
     540              : 
     541              :     /** Remove the userinfo
     542              : 
     543              :         This function removes the userinfo if
     544              :         present, without removing any authority.
     545              : 
     546              :         @par Example
     547              :         @code
     548              :         assert( url( "http://user@example.com" ).remove_userinfo().has_userinfo() == false );
     549              :         @endcode
     550              : 
     551              :         @par Postconditions
     552              :         @code
     553              :         this->has_userinfo() == false && this->encoded_userinfo().empty == true
     554              :         @endcode
     555              : 
     556              :         @par Complexity
     557              :         Linear in `this->size()`.
     558              : 
     559              :         @par Exception Safety
     560              :         Throws nothing.
     561              : 
     562              :         @par BNF
     563              :         @code
     564              :         userinfo      = [ [ user ] [ ':' password ] ]
     565              : 
     566              :         user          = *( unreserved / pct-encoded / sub-delims )
     567              :         password      = *( unreserved / pct-encoded / sub-delims / ":" )
     568              :         @endcode
     569              : 
     570              :         @par Specification
     571              :         @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.2.1">
     572              :             3.2.1. User Information (rfc3986)</a>
     573              : 
     574              :         @see
     575              :             @ref set_encoded_userinfo,
     576              :             @ref set_userinfo.
     577              :     */
     578              :     url_base&
     579              :     remove_userinfo() noexcept;
     580              : 
     581              :     //--------------------------------------------
     582              : 
     583              :     /** Set the user
     584              : 
     585              :         This function sets the user part of the
     586              :         userinfo to the string.
     587              :         Any special or reserved characters in the
     588              :         string are automatically percent-encoded.
     589              : 
     590              :         @par Example
     591              :         @code
     592              :         assert( url().set_user("john doe").encoded_userinfo() == "john%20doe" );
     593              :         @endcode
     594              : 
     595              :         @par Postconditions
     596              :         @code
     597              :         this->has_authority() == true && this->has_userinfo() == true
     598              :         @endcode
     599              : 
     600              :         @par Complexity
     601              :         Linear in `this->size() + s.size()`.
     602              : 
     603              :         @par Exception Safety
     604              :         Strong guarantee.
     605              :         Calls to allocate may throw.
     606              : 
     607              :         @param s The string to set.
     608              : 
     609              :         @par BNF
     610              :         @code
     611              :         userinfo      = [ [ user ] [ ':' password ] ]
     612              : 
     613              :         user          = *( unreserved / pct-encoded / sub-delims )
     614              :         password      = *( unreserved / pct-encoded / sub-delims / ":" )
     615              :         @endcode
     616              : 
     617              :         @par Specification
     618              :         @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.2.1">
     619              :             3.2.1. User Information (rfc3986)</a>
     620              : 
     621              :         @see
     622              :             @ref remove_password,
     623              :             @ref set_encoded_password,
     624              :             @ref set_encoded_user,
     625              :             @ref set_password.
     626              :     */
     627              :     url_base&
     628              :     set_user(
     629              :         core::string_view s);
     630              : 
     631              :     /** Set the user
     632              : 
     633              :         This function sets the user part of the
     634              :         userinfo the the string, which may
     635              :         contain percent-escapes.
     636              :         Escapes in the string are preserved,
     637              :         and reserved characters in the string
     638              :         are percent-escaped in the result.
     639              : 
     640              :         @par Example
     641              :         @code
     642              :         assert( url().set_encoded_user("john%20doe").userinfo() == "john doe" );
     643              :         @endcode
     644              : 
     645              :         @par Postconditions
     646              :         @code
     647              :         this->has_authority() == true && this->has_userinfo() == true
     648              :         @endcode
     649              : 
     650              :         @par Complexity
     651              :         Linear in `this->size() + s.size()`.
     652              : 
     653              :         @par Exception Safety
     654              :         Strong guarantee.
     655              :         Calls to allocate may throw.
     656              : 
     657              :         @throw system_error
     658              :         `s` contains an invalid percent-encoding.
     659              : 
     660              :         @param s The string to set.
     661              : 
     662              :         @par BNF
     663              :         @code
     664              :         userinfo      = [ [ user ] [ ':' password ] ]
     665              : 
     666              :         user          = *( unreserved / pct-encoded / sub-delims )
     667              :         password      = *( unreserved / pct-encoded / sub-delims / ":" )
     668              :         @endcode
     669              : 
     670              :         @par Specification
     671              :         @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.2.1">
     672              :             3.2.1. User Information (rfc3986)</a>
     673              : 
     674              :         @see
     675              :             @ref remove_password,
     676              :             @ref set_encoded_password,
     677              :             @ref set_password,
     678              :             @ref set_user.
     679              :     */
     680              :     url_base&
     681              :     set_encoded_user(
     682              :         pct_string_view s);
     683              : 
     684              :     /** Set the password.
     685              : 
     686              :         This function sets the password in
     687              :         the userinfo to the string.
     688              :         Reserved characters in the string are
     689              :         percent-escaped in the result.
     690              : 
     691              :         @note
     692              :         The interpretation of the userinfo as
     693              :         individual user and password components
     694              :         is scheme-dependent. Transmitting
     695              :         passwords in URLs is deprecated.
     696              : 
     697              :         @par Example
     698              :         @code
     699              :         assert( url("http://user@example.com").set_password( "pass" ).encoded_userinfo() == "user:pass" );
     700              :         @endcode
     701              : 
     702              :         @par Postconditions
     703              :         @code
     704              :         this->has_password() == true && this->password() == s
     705              :         @endcode
     706              : 
     707              :         @par Exception Safety
     708              :         Strong guarantee.
     709              :         Calls to allocate may throw.
     710              : 
     711              :         @param s The string to set. This string may
     712              :         contain any characters, including nulls.
     713              : 
     714              :         @par BNF
     715              :         @code
     716              :         userinfo      = [ [ user ] [ ':' password ] ]
     717              : 
     718              :         user          = *( unreserved / pct-encoded / sub-delims )
     719              :         password      = *( unreserved / pct-encoded / sub-delims / ":" )
     720              :         @endcode
     721              : 
     722              :         @par Specification
     723              :         @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.2.1">
     724              :             3.2.1. User Information (rfc3986)</a>
     725              : 
     726              :         @see
     727              :             @ref remove_password,
     728              :             @ref set_encoded_password,
     729              :             @ref set_encoded_user,
     730              :             @ref set_user.
     731              :     */
     732              :     url_base&
     733              :     set_password(
     734              :         core::string_view s);
     735              : 
     736              :     /** Set the password.
     737              : 
     738              :         This function sets the password in
     739              :         the userinfo to the string, which
     740              :         may contain percent-escapes.
     741              :         Escapes in the string are preserved,
     742              :         and reserved characters in the string
     743              :         are percent-escaped in the result.
     744              : 
     745              :         @note
     746              :         The interpretation of the userinfo as
     747              :         individual user and password components
     748              :         is scheme-dependent. Transmitting
     749              :         passwords in URLs is deprecated.
     750              : 
     751              :         @par Example
     752              :         @code
     753              :         assert( url("http://user@example.com").set_encoded_password( "pass" ).encoded_userinfo() == "user:pass" );
     754              :         @endcode
     755              : 
     756              :         @par Postconditions
     757              :         @code
     758              :         this->has_password() == true
     759              :         @endcode
     760              : 
     761              :         @par Exception Safety
     762              :         Strong guarantee.
     763              :         Calls to allocate may throw.
     764              : 
     765              :         @throw system_error
     766              :         `s` contains an invalid percent-encoding.
     767              : 
     768              :         @param s The string to set. This string may
     769              :         contain any characters, including nulls.
     770              : 
     771              :         @par BNF
     772              :         @code
     773              :         userinfo      = [ [ user ] [ ':' password ] ]
     774              : 
     775              :         user          = *( unreserved / pct-encoded / sub-delims )
     776              :         password      = *( unreserved / pct-encoded / sub-delims / ":" )
     777              :         @endcode
     778              : 
     779              :         @par Specification
     780              :         @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.2.1">
     781              :             3.2.1. User Information (rfc3986)</a>
     782              : 
     783              :         @see
     784              :             @ref remove_password,
     785              :             @ref set_encoded_password,
     786              :             @ref set_encoded_user,
     787              :             @ref set_user.
     788              :     */
     789              :     url_base&
     790              :     set_encoded_password(
     791              :         pct_string_view s);
     792              : 
     793              :     /** Remove the password
     794              : 
     795              :         This function removes the password from
     796              :         the userinfo if a password exists. If
     797              :         there is no userinfo or no authority,
     798              :         the call has no effect.
     799              : 
     800              :         @note
     801              :         The interpretation of the userinfo as
     802              :         individual user and password components
     803              :         is scheme-dependent. Transmitting
     804              :         passwords in URLs is deprecated.
     805              : 
     806              :         @par Example
     807              :         @code
     808              :         assert( url( "http://user:pass@example.com" ).remove_password().authority().buffer() == "user@example.com" );
     809              :         @endcode
     810              : 
     811              :         @par Postconditions
     812              :         @code
     813              :         this->has_password() == false && this->encoded_password().empty() == true
     814              :         @endcode
     815              : 
     816              :         @par Complexity
     817              :         Linear in `this->size()`.
     818              : 
     819              :         @par Exception Safety
     820              :         Throws nothing.
     821              : 
     822              :         @par BNF
     823              :         @code
     824              :         userinfo      = [ [ user ] [ ':' password ] ]
     825              : 
     826              :         user          = *( unreserved / pct-encoded / sub-delims )
     827              :         password      = *( unreserved / pct-encoded / sub-delims / ":" )
     828              :         @endcode
     829              : 
     830              :         @par Specification
     831              :         @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.2.1">
     832              :             3.2.1. User Information (rfc3986)</a>
     833              : 
     834              :         @see
     835              :             @ref set_encoded_password,
     836              :             @ref set_encoded_user,
     837              :             @ref set_password,
     838              :             @ref set_user.
     839              :     */
     840              :     url_base&
     841              :     remove_password() noexcept;
     842              : 
     843              :     //--------------------------------------------
     844              :     //
     845              :     // Host
     846              :     //
     847              :     //--------------------------------------------
     848              : 
     849              :     /** Set the host
     850              : 
     851              :         Depending on the contents of the passed
     852              :         string, this function sets the host:
     853              : 
     854              :         @li If the string is a valid IPv4 address,
     855              :         then the host is set to the address.
     856              :         The host type is @ref host_type::ipv4.
     857              : 
     858              :         @li If the string is a valid IPv6 address
     859              :         enclosed in square brackets, then the
     860              :         host is set to that address.
     861              :         The host type is @ref host_type::ipv6.
     862              : 
     863              :         @li If the string is a valid IPvFuture
     864              :         address enclosed in square brackets, then
     865              :         the host is set to that address.
     866              :         The host type is @ref host_type::ipvfuture.
     867              : 
     868              :         @li Otherwise, the host name is set to
     869              :         the string, which may be empty.
     870              :         Reserved characters in the string are
     871              :         percent-escaped in the result.
     872              :         The host type is @ref host_type::name.
     873              : 
     874              :         In all cases, when this function returns,
     875              :         the URL contains an authority.
     876              : 
     877              :         @par Example
     878              :         @code
     879              :         assert( url( "http://www.example.com" ).set_host( "127.0.0.1" ).buffer() == "http://127.0.0.1" );
     880              :         @endcode
     881              : 
     882              :         @par Postconditions
     883              :         @code
     884              :         this->has_authority() == true
     885              :         @endcode
     886              : 
     887              :         @par Complexity
     888              :         Linear in `this->size() + s.size()`.
     889              : 
     890              :         @par Exception Safety
     891              :         Strong guarantee.
     892              :         Calls to allocate may throw.
     893              : 
     894              :         @param s The string to set.
     895              : 
     896              :         @par BNF
     897              :         @code
     898              :         host        = IP-literal / IPv4address / reg-name
     899              : 
     900              :         IP-literal  = "[" ( IPv6address / IPvFuture  ) "]"
     901              : 
     902              :         reg-name    = *( unreserved / pct-encoded / "-" / ".")
     903              :         @endcode
     904              : 
     905              :         @par Specification
     906              :         @li <a href="https://en.wikipedia.org/wiki/IPv4"
     907              :             >IPv4 (Wikipedia)</a>
     908              :         @li <a href="https://datatracker.ietf.org/doc/html/rfc4291"
     909              :             >IP Version 6 Addressing Architecture (rfc4291)</a>
     910              :         @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.2.2">
     911              :             3.2.2. Host (rfc3986)</a>
     912              : 
     913              :         @see
     914              :             @ref set_encoded_host,
     915              :             @ref set_encoded_host_address,
     916              :             @ref set_encoded_host_name,
     917              :             @ref set_host_address,
     918              :             @ref set_host_ipv4,
     919              :             @ref set_host_ipv6,
     920              :             @ref set_host_ipvfuture,
     921              :             @ref set_host_name.
     922              :     */
     923              :     url_base&
     924              :     set_host(
     925              :         core::string_view s);
     926              : 
     927              :     /** Set the host
     928              : 
     929              :         Depending on the contents of the passed
     930              :         string, this function sets the host:
     931              : 
     932              :         @li If the string is a valid IPv4 address,
     933              :         then the host is set to the address.
     934              :         The host type is @ref host_type::ipv4.
     935              : 
     936              :         @li If the string is a valid IPv6 address
     937              :         enclosed in square brackets, then the
     938              :         host is set to that address.
     939              :         The host type is @ref host_type::ipv6.
     940              : 
     941              :         @li If the string is a valid IPvFuture
     942              :         address enclosed in square brackets, then
     943              :         the host is set to that address.
     944              :         The host type is @ref host_type::ipvfuture.
     945              : 
     946              :         @li Otherwise, the host name is set to
     947              :         the string. This string can contain percent
     948              :         escapes, or can be empty.
     949              :         Escapes in the string are preserved,
     950              :         and reserved characters in the string
     951              :         are percent-escaped in the result.
     952              :         The host type is @ref host_type::name.
     953              : 
     954              :         In all cases, when this function returns,
     955              :         the URL contains an authority.
     956              : 
     957              :         @par Example
     958              :         @code
     959              :         assert( url( "http://www.example.com" ).set_host( "127.0.0.1" ).buffer() == "http://127.0.0.1" );
     960              :         @endcode
     961              : 
     962              :         @par Postconditions
     963              :         @code
     964              :         this->has_authority() == true
     965              :         @endcode
     966              : 
     967              :         @par Complexity
     968              :         Linear in `this->size() + s.size()`.
     969              : 
     970              :         @par Exception Safety
     971              :         Strong guarantee.
     972              :         Calls to allocate may throw.
     973              :         Exceptions thrown on invalid input.
     974              : 
     975              :         @throw system_error
     976              :         `s` contains an invalid percent-encoding.
     977              : 
     978              :         @param s The string to set.
     979              : 
     980              :         @par BNF
     981              :         @code
     982              :         host        = IP-literal / IPv4address / reg-name
     983              : 
     984              :         IP-literal  = "[" ( IPv6address / IPvFuture  ) "]"
     985              : 
     986              :         reg-name    = *( unreserved / pct-encoded / "-" / ".")
     987              :         @endcode
     988              : 
     989              :         @par Specification
     990              :         @li <a href="https://en.wikipedia.org/wiki/IPv4"
     991              :             >IPv4 (Wikipedia)</a>
     992              :         @li <a href="https://datatracker.ietf.org/doc/html/rfc4291"
     993              :             >IP Version 6 Addressing Architecture (rfc4291)</a>
     994              :         @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.2.2">
     995              :             3.2.2. Host (rfc3986)</a>
     996              : 
     997              :         @see
     998              :             @ref set_encoded_host_address,
     999              :             @ref set_encoded_host_name,
    1000              :             @ref set_host,
    1001              :             @ref set_host_address,
    1002              :             @ref set_host_ipv4,
    1003              :             @ref set_host_ipv6,
    1004              :             @ref set_host_ipvfuture,
    1005              :             @ref set_host_name.
    1006              :     */
    1007              :     url_base&
    1008              :     set_encoded_host(pct_string_view s);
    1009              : 
    1010              :     /** Set the host to an address
    1011              : 
    1012              :         Depending on the contents of the passed
    1013              :         string, this function sets the host:
    1014              : 
    1015              :         @li If the string is a valid IPv4 address,
    1016              :         then the host is set to the address.
    1017              :         The host type is @ref host_type::ipv4.
    1018              : 
    1019              :         @li If the string is a valid IPv6 address,
    1020              :         then the host is set to that address.
    1021              :         The host type is @ref host_type::ipv6.
    1022              : 
    1023              :         @li If the string is a valid IPvFuture,
    1024              :         then the host is set to that address.
    1025              :         The host type is @ref host_type::ipvfuture.
    1026              : 
    1027              :         @li Otherwise, the host name is set to
    1028              :         the string, which may be empty.
    1029              :         Reserved characters in the string are
    1030              :         percent-escaped in the result.
    1031              :         The host type is @ref host_type::name.
    1032              : 
    1033              :         In all cases, when this function returns,
    1034              :         the URL contains an authority.
    1035              : 
    1036              :         @par Example
    1037              :         @code
    1038              :         assert( url( "http://www.example.com" ).set_host_address( "127.0.0.1" ).buffer() == "http://127.0.0.1" );
    1039              :         @endcode
    1040              : 
    1041              :         @par Postconditions
    1042              :         @code
    1043              :         this->has_authority() == true
    1044              :         @endcode
    1045              : 
    1046              :         @par Complexity
    1047              :         Linear in `s.size()`.
    1048              : 
    1049              :         @par Exception Safety
    1050              :         Strong guarantee.
    1051              :         Calls to allocate may throw.
    1052              : 
    1053              :         @param s The string to set.
    1054              : 
    1055              :         @par BNF
    1056              :         @code
    1057              :         IPv4address = dec-octet "." dec-octet "." dec-octet "." dec-octet
    1058              : 
    1059              :         dec-octet   = DIGIT                 ; 0-9
    1060              :                     / %x31-39 DIGIT         ; 10-99
    1061              :                     / "1" 2DIGIT            ; 100-199
    1062              :                     / "2" %x30-34 DIGIT     ; 200-249
    1063              :                     / "25" %x30-35          ; 250-255
    1064              : 
    1065              :         IPv6address =                            6( h16 ":" ) ls32
    1066              :                     /                       "::" 5( h16 ":" ) ls32
    1067              :                     / [               h16 ] "::" 4( h16 ":" ) ls32
    1068              :                     / [ *1( h16 ":" ) h16 ] "::" 3( h16 ":" ) ls32
    1069              :                     / [ *2( h16 ":" ) h16 ] "::" 2( h16 ":" ) ls32
    1070              :                     / [ *3( h16 ":" ) h16 ] "::"    h16 ":"   ls32
    1071              :                     / [ *4( h16 ":" ) h16 ] "::"              ls32
    1072              :                     / [ *5( h16 ":" ) h16 ] "::"              h16
    1073              :                     / [ *6( h16 ":" ) h16 ] "::"
    1074              : 
    1075              :         ls32        = ( h16 ":" h16 ) / IPv4address
    1076              :                     ; least-significant 32 bits of address
    1077              : 
    1078              :         h16         = 1*4HEXDIG
    1079              :                     ; 16 bits of address represented in hexadecimal
    1080              : 
    1081              :         IPvFuture     = "v" 1*HEXDIG "." 1*( unreserved / sub-delims / ":" )
    1082              : 
    1083              :         reg-name    = *( unreserved / pct-encoded / "-" / ".")
    1084              :         @endcode
    1085              : 
    1086              :         @par Specification
    1087              :         @li <a href="https://en.wikipedia.org/wiki/IPv4"
    1088              :             >IPv4 (Wikipedia)</a>
    1089              :         @li <a href="https://datatracker.ietf.org/doc/html/rfc4291"
    1090              :             >IP Version 6 Addressing Architecture (rfc4291)</a>
    1091              :         @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.2.2">
    1092              :             3.2.2. Host (rfc3986)</a>
    1093              : 
    1094              :         @see
    1095              :             @ref set_encoded_host,
    1096              :             @ref set_encoded_host_address,
    1097              :             @ref set_encoded_host_name,
    1098              :             @ref set_host,
    1099              :             @ref set_host_address,
    1100              :             @ref set_host_ipv4,
    1101              :             @ref set_host_ipv6,
    1102              :             @ref set_host_ipvfuture,
    1103              :             @ref set_host_name.
    1104              :     */
    1105              :     url_base&
    1106              :     set_host_address(core::string_view s);
    1107              : 
    1108              :     /** Set the host to an address
    1109              : 
    1110              :         Depending on the contents of the passed
    1111              :         string, this function sets the host:
    1112              : 
    1113              :         @li If the string is a valid IPv4 address,
    1114              :         then the host is set to the address.
    1115              :         The host type is @ref host_type::ipv4.
    1116              : 
    1117              :         @li If the string is a valid IPv6 address,
    1118              :         then the host is set to that address.
    1119              :         The host type is @ref host_type::ipv6.
    1120              : 
    1121              :         @li If the string is a valid IPvFuture,
    1122              :         then the host is set to that address.
    1123              :         The host type is @ref host_type::ipvfuture.
    1124              : 
    1125              :         @li Otherwise, the host name is set to
    1126              :         the string. This string can contain percent
    1127              :         escapes, or can be empty.
    1128              :         Escapes in the string are preserved,
    1129              :         and reserved characters in the string
    1130              :         are percent-escaped in the result.
    1131              :         The host type is @ref host_type::name.
    1132              : 
    1133              :         In all cases, when this function returns,
    1134              :         the URL contains an authority.
    1135              : 
    1136              :         @par Example
    1137              :         @code
    1138              :         assert( url( "http://www.example.com" ).set_host( "127.0.0.1" ).buffer() == "http://127.0.0.1" );
    1139              :         @endcode
    1140              : 
    1141              :         @par Postconditions
    1142              :         @code
    1143              :         this->has_authority() == true
    1144              :         @endcode
    1145              : 
    1146              :         @par Complexity
    1147              :         Linear in `this->size() + s.size()`.
    1148              : 
    1149              :         @par Exception Safety
    1150              :         Strong guarantee.
    1151              :         Calls to allocate may throw.
    1152              :         Exceptions thrown on invalid input.
    1153              : 
    1154              :         @throw system_error
    1155              :         `s` contains an invalid percent-encoding.
    1156              : 
    1157              :         @param s The string to set.
    1158              : 
    1159              :         @par BNF
    1160              :         @code
    1161              :         IPv4address = dec-octet "." dec-octet "." dec-octet "." dec-octet
    1162              : 
    1163              :         dec-octet   = DIGIT                 ; 0-9
    1164              :                     / %x31-39 DIGIT         ; 10-99
    1165              :                     / "1" 2DIGIT            ; 100-199
    1166              :                     / "2" %x30-34 DIGIT     ; 200-249
    1167              :                     / "25" %x30-35          ; 250-255
    1168              : 
    1169              :         IPv6address =                            6( h16 ":" ) ls32
    1170              :                     /                       "::" 5( h16 ":" ) ls32
    1171              :                     / [               h16 ] "::" 4( h16 ":" ) ls32
    1172              :                     / [ *1( h16 ":" ) h16 ] "::" 3( h16 ":" ) ls32
    1173              :                     / [ *2( h16 ":" ) h16 ] "::" 2( h16 ":" ) ls32
    1174              :                     / [ *3( h16 ":" ) h16 ] "::"    h16 ":"   ls32
    1175              :                     / [ *4( h16 ":" ) h16 ] "::"              ls32
    1176              :                     / [ *5( h16 ":" ) h16 ] "::"              h16
    1177              :                     / [ *6( h16 ":" ) h16 ] "::"
    1178              : 
    1179              :         ls32        = ( h16 ":" h16 ) / IPv4address
    1180              :                     ; least-significant 32 bits of address
    1181              : 
    1182              :         h16         = 1*4HEXDIG
    1183              :                     ; 16 bits of address represented in hexadecimal
    1184              : 
    1185              :         IPvFuture     = "v" 1*HEXDIG "." 1*( unreserved / sub-delims / ":" )
    1186              : 
    1187              :         reg-name    = *( unreserved / pct-encoded / "-" / ".")
    1188              :         @endcode
    1189              : 
    1190              :         @par Specification
    1191              :         @li <a href="https://en.wikipedia.org/wiki/IPv4"
    1192              :             >IPv4 (Wikipedia)</a>
    1193              :         @li <a href="https://datatracker.ietf.org/doc/html/rfc4291"
    1194              :             >IP Version 6 Addressing Architecture (rfc4291)</a>
    1195              :         @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.2.2">
    1196              :             3.2.2. Host (rfc3986)</a>
    1197              : 
    1198              :         @see
    1199              :             @ref set_encoded_host,
    1200              :             @ref set_encoded_host_name,
    1201              :             @ref set_host,
    1202              :             @ref set_host_address,
    1203              :             @ref set_host_ipv4,
    1204              :             @ref set_host_ipv6,
    1205              :             @ref set_host_ipvfuture,
    1206              :             @ref set_host_name.
    1207              :     */
    1208              :     url_base&
    1209              :     set_encoded_host_address(
    1210              :         pct_string_view s);
    1211              : 
    1212              :     /** Set the host to an address
    1213              : 
    1214              :         The host is set to the specified IPv4
    1215              :         address.
    1216              :         The host type is @ref host_type::ipv4.
    1217              : 
    1218              :         @par Example
    1219              :         @code
    1220              :         assert( url("http://www.example.com").set_host_ipv4( ipv4_address( "127.0.0.1" ) ).buffer() == "http://127.0.0.1" );
    1221              :         @endcode
    1222              : 
    1223              :         @par Complexity
    1224              :         Linear in `this->size()`.
    1225              : 
    1226              :         @par Postconditions
    1227              :         @code
    1228              :         this->has_authority() == true && this->host_ipv4_address() == addr && this->host_type() == host_type::ipv4
    1229              :         @endcode
    1230              : 
    1231              :         @par Exception Safety
    1232              :         Strong guarantee.
    1233              :         Calls to allocate may throw.
    1234              : 
    1235              :         @param addr The address to set.
    1236              : 
    1237              :         @par BNF
    1238              :         @code
    1239              :         IPv4address = dec-octet "." dec-octet "." dec-octet "." dec-octet
    1240              : 
    1241              :         dec-octet   = DIGIT                 ; 0-9
    1242              :                     / %x31-39 DIGIT         ; 10-99
    1243              :                     / "1" 2DIGIT            ; 100-199
    1244              :                     / "2" %x30-34 DIGIT     ; 200-249
    1245              :                     / "25" %x30-35          ; 250-255
    1246              :         @endcode
    1247              : 
    1248              :         @par Specification
    1249              :         @li <a href="https://en.wikipedia.org/wiki/IPv4"
    1250              :             >IPv4 (Wikipedia)</a>
    1251              :         @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.2.2">
    1252              :             3.2.2. Host (rfc3986)</a>
    1253              : 
    1254              :         @see
    1255              :             @ref set_encoded_host,
    1256              :             @ref set_encoded_host_address,
    1257              :             @ref set_encoded_host_name,
    1258              :             @ref set_host,
    1259              :             @ref set_host_address,
    1260              :             @ref set_host_ipv6,
    1261              :             @ref set_host_ipvfuture,
    1262              :             @ref set_host_name.
    1263              :     */
    1264              :     url_base&
    1265              :     set_host_ipv4(
    1266              :         ipv4_address const& addr);
    1267              : 
    1268              :     /** Set the host to an address
    1269              : 
    1270              :         The host is set to the specified IPv6
    1271              :         address.
    1272              :         The host type is @ref host_type::ipv6.
    1273              : 
    1274              :         @par Example
    1275              :         @code
    1276              :         assert( url().set_host_ipv6( ipv6_address( "1::6:c0a8:1" ) ).authority().buffer() == "[1::6:c0a8:1]" );
    1277              :         @endcode
    1278              : 
    1279              :         @par Postconditions
    1280              :         @code
    1281              :         this->has_authority() == true && this->host_ipv6_address() == addr && this->host_type() == host_type::ipv6
    1282              :         @endcode
    1283              : 
    1284              :         @par Complexity
    1285              :         Linear in `this->size()`.
    1286              : 
    1287              :         @par Exception Safety
    1288              :         Strong guarantee.
    1289              :         Calls to allocate may throw.
    1290              : 
    1291              :         @param addr The address to set.
    1292              : 
    1293              :         @par BNF
    1294              :         @code
    1295              :         IPv6address =                            6( h16 ":" ) ls32
    1296              :                     /                       "::" 5( h16 ":" ) ls32
    1297              :                     / [               h16 ] "::" 4( h16 ":" ) ls32
    1298              :                     / [ *1( h16 ":" ) h16 ] "::" 3( h16 ":" ) ls32
    1299              :                     / [ *2( h16 ":" ) h16 ] "::" 2( h16 ":" ) ls32
    1300              :                     / [ *3( h16 ":" ) h16 ] "::"    h16 ":"   ls32
    1301              :                     / [ *4( h16 ":" ) h16 ] "::"              ls32
    1302              :                     / [ *5( h16 ":" ) h16 ] "::"              h16
    1303              :                     / [ *6( h16 ":" ) h16 ] "::"
    1304              : 
    1305              :         ls32        = ( h16 ":" h16 ) / IPv4address
    1306              :                     ; least-significant 32 bits of address
    1307              : 
    1308              :         h16         = 1*4HEXDIG
    1309              :                     ; 16 bits of address represented in hexadecimal
    1310              :         @endcode
    1311              : 
    1312              :         @par Specification
    1313              :         @li <a href="https://datatracker.ietf.org/doc/html/rfc4291"
    1314              :             >IP Version 6 Addressing Architecture (rfc4291)</a>
    1315              :         @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.2.2">
    1316              :             3.2.2. Host (rfc3986)</a>
    1317              : 
    1318              :         @see
    1319              :             @ref set_encoded_host,
    1320              :             @ref set_encoded_host_address,
    1321              :             @ref set_encoded_host_name,
    1322              :             @ref set_host,
    1323              :             @ref set_host_address,
    1324              :             @ref set_host_ipv4,
    1325              :             @ref set_host_ipvfuture,
    1326              :             @ref set_host_name.
    1327              :     */
    1328              :     url_base&
    1329              :     set_host_ipv6(
    1330              :         ipv6_address const& addr);
    1331              : 
    1332              :     /** Set the host to an address
    1333              : 
    1334              :         The host is set to the specified IPvFuture
    1335              :         string.
    1336              :         The host type is @ref host_type::ipvfuture.
    1337              : 
    1338              :         @par Example
    1339              :         @code
    1340              :         assert( url().set_host_ipvfuture( "v42.bis" ).buffer() == "//[v42.bis]" );
    1341              :         @endcode
    1342              : 
    1343              :         @par Complexity
    1344              :         Linear in `this->size() + s.size()`.
    1345              : 
    1346              :         @par Postconditions
    1347              :         @code
    1348              :         this->has_authority() == true && this->host_ipvfuture) == s && this->host_type() == host_type::ipvfuture
    1349              :         @endcode
    1350              : 
    1351              :         @par Exception Safety
    1352              :         Strong guarantee.
    1353              :         Calls to allocate may throw.
    1354              :         Exceptions thrown on invalid input.
    1355              : 
    1356              :         @throw system_error
    1357              :         `s` contains an invalid percent-encoding.
    1358              : 
    1359              :         @param s The string to set.
    1360              : 
    1361              :         @par BNF
    1362              :         @code
    1363              :         IPvFuture     = "v" 1*HEXDIG "." 1*( unreserved / sub-delims / ":" )
    1364              :         @endcode
    1365              : 
    1366              :         @par Specification
    1367              :         @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.2.2">
    1368              :             3.2.2. Host (rfc3986)</a>
    1369              : 
    1370              :         @see
    1371              :             @ref set_encoded_host,
    1372              :             @ref set_encoded_host_address,
    1373              :             @ref set_encoded_host_name,
    1374              :             @ref set_host,
    1375              :             @ref set_host_address,
    1376              :             @ref set_host_ipv4,
    1377              :             @ref set_host_ipv6,
    1378              :             @ref set_host_name.
    1379              :     */
    1380              :     url_base&
    1381              :     set_host_ipvfuture(
    1382              :         core::string_view s);
    1383              : 
    1384              :     /** Set the host to a name
    1385              : 
    1386              :         The host is set to the specified string,
    1387              :         which may be empty.
    1388              :         Reserved characters in the string are
    1389              :         percent-escaped in the result.
    1390              :         The host type is @ref host_type::name.
    1391              : 
    1392              :         @par Example
    1393              :         @code
    1394              :         assert( url( "http://www.example.com/index.htm").set_host_name( "localhost" ).host_address() == "localhost" );
    1395              :         @endcode
    1396              : 
    1397              :         @par Postconditions
    1398              :         @code
    1399              :         this->has_authority() == true && this->host_ipv6_address() == addr && this->host_type() == host_type::name
    1400              :         @endcode
    1401              : 
    1402              :         @par Exception Safety
    1403              :         Strong guarantee.
    1404              :         Calls to allocate may throw.
    1405              : 
    1406              :         @param s The string to set.
    1407              : 
    1408              :         @par BNF
    1409              :         @code
    1410              :         reg-name    = *( unreserved / pct-encoded / "-" / ".")
    1411              :         @endcode
    1412              : 
    1413              :         @par Specification
    1414              :         @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.2.2">
    1415              :             3.2.2. Host (rfc3986)</a>
    1416              : 
    1417              :         @see
    1418              :             @ref set_encoded_host,
    1419              :             @ref set_encoded_host_address,
    1420              :             @ref set_encoded_host_name,
    1421              :             @ref set_host,
    1422              :             @ref set_host_address,
    1423              :             @ref set_host_ipv4,
    1424              :             @ref set_host_ipv6,
    1425              :             @ref set_host_ipvfuture.
    1426              :     */
    1427              :     url_base&
    1428              :     set_host_name(
    1429              :         core::string_view s);
    1430              : 
    1431              :     /** Set the host to a name
    1432              : 
    1433              :         The host is set to the specified string,
    1434              :         which may contain percent-escapes and
    1435              :         can be empty.
    1436              :         Escapes in the string are preserved,
    1437              :         and reserved characters in the string
    1438              :         are percent-escaped in the result.
    1439              :         The host type is @ref host_type::name.
    1440              : 
    1441              :         @par Example
    1442              :         @code
    1443              :         assert( url( "http://www.example.com/index.htm").set_encoded_host_name( "localhost" ).host_address() == "localhost" );
    1444              :         @endcode
    1445              : 
    1446              :         @par Postconditions
    1447              :         @code
    1448              :         this->has_authority() == true && this->host_ipv6_address() == addr && this->host_type() == host_type::name
    1449              :         @endcode
    1450              : 
    1451              :         @par Exception Safety
    1452              :         Strong guarantee.
    1453              :         Calls to allocate may throw.
    1454              :         Exceptions thrown on invalid input.
    1455              : 
    1456              :         @throw system_error
    1457              :         `s` contains an invalid percent-encoding.
    1458              : 
    1459              :         @param s The string to set.
    1460              : 
    1461              :         @par BNF
    1462              :         @code
    1463              :         reg-name    = *( unreserved / pct-encoded / "-" / ".")
    1464              :         @endcode
    1465              : 
    1466              :         @par Specification
    1467              :         @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.2.2">
    1468              :             3.2.2. Host (rfc3986)</a>
    1469              : 
    1470              :         @see
    1471              :             @ref set_encoded_host,
    1472              :             @ref set_encoded_host_address,
    1473              :             @ref set_host,
    1474              :             @ref set_host_address,
    1475              :             @ref set_host_ipv4,
    1476              :             @ref set_host_ipv6,
    1477              :             @ref set_host_ipvfuture,
    1478              :             @ref set_host_name.
    1479              :     */
    1480              :     url_base&
    1481              :     set_encoded_host_name(
    1482              :         pct_string_view s);
    1483              : 
    1484              :     //--------------------------------------------
    1485              : 
    1486              :     /** Set the port
    1487              : 
    1488              :         The port is set to the specified integer.
    1489              : 
    1490              :         @par Example
    1491              :         @code
    1492              :         assert( url( "http://www.example.com" ).set_port_number( 8080 ).authority().buffer() == "www.example.com:8080" );
    1493              :         @endcode
    1494              : 
    1495              :         @par Postconditions
    1496              :         @code
    1497              :         this->has_authority() == true && this->has_port() == true && this->port_number() == n
    1498              :         @endcode
    1499              : 
    1500              :         @par Complexity
    1501              :         Linear in `this->size()`.
    1502              : 
    1503              :         @par Exception Safety
    1504              :         Strong guarantee.
    1505              :         Calls to allocate may throw.
    1506              : 
    1507              :         @param n The port number to set.
    1508              : 
    1509              :         @par BNF
    1510              :         @code
    1511              :         authority     = [ userinfo "@" ] host [ ":" port ]
    1512              : 
    1513              :         port          = *DIGIT
    1514              :         @endcode
    1515              : 
    1516              :         @par Specification
    1517              :         @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.2.3">
    1518              :             3.2.3. Port (rfc3986)</a>
    1519              : 
    1520              :         @see
    1521              :             @ref remove_port,
    1522              :             @ref set_port.
    1523              :     */
    1524              :     url_base&
    1525              :     set_port_number(std::uint16_t n);
    1526              : 
    1527              :     /** Set the port
    1528              : 
    1529              :         This port is set to the string, which
    1530              :         must contain only digits or be empty.
    1531              :         An empty port string is distinct from
    1532              :         having no port.
    1533              : 
    1534              :         @par Example
    1535              :         @code
    1536              :         assert( url( "http://www.example.com" ).set_port( "8080" ).authority().buffer() == "www.example.com:8080" );
    1537              :         @endcode
    1538              : 
    1539              :         @par Postconditions
    1540              :         @code
    1541              :         this->has_port() == true && this->port_number() == n && this->port() == std::to_string(n)
    1542              :         @endcode
    1543              : 
    1544              :         @par Exception Safety
    1545              :         Strong guarantee.
    1546              :         Calls to allocate may throw.
    1547              :         Exceptions thrown on invalid input.
    1548              : 
    1549              :         @throw system_error
    1550              :         `s` does not contain a valid port.
    1551              : 
    1552              :         @param s The port string to set.
    1553              : 
    1554              :         @par BNF
    1555              :         @code
    1556              :         port          = *DIGIT
    1557              :         @endcode
    1558              : 
    1559              :         @par Specification
    1560              :         @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.2.3">
    1561              :             3.2.3. Port (rfc3986)</a>
    1562              : 
    1563              :         @see
    1564              :             @ref remove_port,
    1565              :             @ref set_port.
    1566              :     */
    1567              :     url_base&
    1568              :     set_port(core::string_view s);
    1569              : 
    1570              :     /** Remove the port
    1571              : 
    1572              :         If a port exists, it is removed. The rest
    1573              :         of the authority is unchanged.
    1574              : 
    1575              :         @par Example
    1576              :         @code
    1577              :         assert( url( "http://www.example.com:80" ).remove_port().authority().buffer() == "www.example.com" );
    1578              :         @endcode
    1579              : 
    1580              :         @par Postconditions
    1581              :         @code
    1582              :         this->has_port() == false && this->port_number() == 0 && this->port() == ""
    1583              :         @endcode
    1584              : 
    1585              :         @par Complexity
    1586              :         Linear in `this->size()`.
    1587              : 
    1588              :         @par Exception Safety
    1589              :         Throws nothing.
    1590              : 
    1591              :         @par BNF
    1592              :         @code
    1593              :         authority     = [ userinfo "@" ] host [ ":" port ]
    1594              : 
    1595              :         port          = *DIGIT
    1596              :         @endcode
    1597              : 
    1598              :         @par Specification
    1599              :         @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.2.3">
    1600              :             3.2.3. Port (rfc3986)</a>
    1601              : 
    1602              :         @see
    1603              :             @ref set_port.
    1604              :     */
    1605              :     url_base&
    1606              :     remove_port() noexcept;
    1607              : 
    1608              :     //--------------------------------------------
    1609              :     //
    1610              :     // Path
    1611              :     //
    1612              :     //--------------------------------------------
    1613              : 
    1614              :     /** Set if the path is absolute
    1615              : 
    1616              :         This function adjusts the path to make
    1617              :         it absolute or not, depending on the
    1618              :         parameter.
    1619              : 
    1620              :         @note
    1621              :         If an authority is present, the path
    1622              :         is always absolute. In this case, the
    1623              :         function has no effect.
    1624              : 
    1625              :         @par Example
    1626              :         @code
    1627              :         url u( "path/to/file.txt" );
    1628              :         assert( u.set_path_absolute( true ) );
    1629              :         assert( u.buffer() == "/path/to/file.txt" );
    1630              :         @endcode
    1631              : 
    1632              :         @par Postconditions
    1633              :         @code
    1634              :         this->is_path_absolute() == true && this->encoded_path().front() == '/'
    1635              :         @endcode
    1636              : 
    1637              :         @return true on success.
    1638              : 
    1639              :         @par Complexity
    1640              :         Linear in `this->size()`.
    1641              : 
    1642              :         @par BNF
    1643              :         @code
    1644              :         path          = path-abempty    ; begins with "/" or is empty
    1645              :                       / path-absolute   ; begins with "/" but not "//"
    1646              :                       / path-noscheme   ; begins with a non-colon segment
    1647              :                       / path-rootless   ; begins with a segment
    1648              :                       / path-empty      ; zero characters
    1649              : 
    1650              :         path-abempty  = *( "/" segment )
    1651              :         path-absolute = "/" [ segment-nz *( "/" segment ) ]
    1652              :         path-noscheme = segment-nz-nc *( "/" segment )
    1653              :         path-rootless = segment-nz *( "/" segment )
    1654              :         path-empty    = 0<pchar>
    1655              :         @endcode
    1656              : 
    1657              :         @par Specification
    1658              :         @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.3"
    1659              :             >3.3.  Path (rfc3986)</a>
    1660              : 
    1661              :         @see
    1662              :             @ref encoded_segments,
    1663              :             @ref segments,
    1664              :             @ref set_encoded_path,
    1665              :             @ref set_path.
    1666              :     */
    1667              :     bool
    1668              :     set_path_absolute(bool absolute);
    1669              : 
    1670              :     /** Set the path.
    1671              : 
    1672              :         This function sets the path to the
    1673              :         string, which may be empty.
    1674              :         Reserved characters in the string are
    1675              :         percent-escaped in the result.
    1676              : 
    1677              :         @note
    1678              :         The library may adjust the final result
    1679              :         to ensure that no other parts of the url
    1680              :         is semantically affected.
    1681              : 
    1682              :         @note
    1683              :         This function does not encode '/' chars, which
    1684              :         are unreserved for paths but reserved for
    1685              :         path segments. If a path segment should include
    1686              :         encoded '/'s to differentiate it from path separators,
    1687              :         the functions @ref set_encoded_path or @ref segments
    1688              :         should be used instead.
    1689              : 
    1690              :         @par Example
    1691              :         @code
    1692              :         url u( "http://www.example.com" );
    1693              : 
    1694              :         u.set_path( "path/to/file.txt" );
    1695              : 
    1696              :         assert( u.path() == "/path/to/file.txt" );
    1697              :         @endcode
    1698              : 
    1699              :         @par Complexity
    1700              :         Linear in `this->size() + s.size()`.
    1701              : 
    1702              :         @par Exception Safety
    1703              :         Strong guarantee.
    1704              :         Calls to allocate may throw.
    1705              : 
    1706              :         @param s The string to set.
    1707              : 
    1708              :         @par BNF
    1709              :         @code
    1710              :         path          = path-abempty    ; begins with "/" or is empty
    1711              :                       / path-absolute   ; begins with "/" but not "//"
    1712              :                       / path-noscheme   ; begins with a non-colon segment
    1713              :                       / path-rootless   ; begins with a segment
    1714              :                       / path-empty      ; zero characters
    1715              : 
    1716              :         path-abempty  = *( "/" segment )
    1717              :         path-absolute = "/" [ segment-nz *( "/" segment ) ]
    1718              :         path-noscheme = segment-nz-nc *( "/" segment )
    1719              :         path-rootless = segment-nz *( "/" segment )
    1720              :         path-empty    = 0<pchar>
    1721              :         @endcode
    1722              : 
    1723              :         @par Specification
    1724              :         @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.3"
    1725              :             >3.3.  Path (rfc3986)</a>
    1726              : 
    1727              :         @see
    1728              :             @ref encoded_segments,
    1729              :             @ref segments,
    1730              :             @ref set_encoded_path,
    1731              :             @ref set_path_absolute.
    1732              :     */
    1733              :     url_base&
    1734              :     set_path(
    1735              :         core::string_view s);
    1736              : 
    1737              :     /** Set the path.
    1738              : 
    1739              :         This function sets the path to the
    1740              :         string, which may contain percent-escapes
    1741              :         and can be empty.
    1742              :         Escapes in the string are preserved,
    1743              :         and reserved characters in the string
    1744              :         are percent-escaped in the result.
    1745              : 
    1746              :         @note
    1747              :         The library may adjust the final result
    1748              :         to ensure that no other parts of the url
    1749              :         is semantically affected.
    1750              : 
    1751              :         @par Example
    1752              :         @code
    1753              :         url u( "http://www.example.com" );
    1754              : 
    1755              :         u.set_encoded_path( "path/to/file.txt" );
    1756              : 
    1757              :         assert( u.encoded_path() == "/path/to/file.txt" );
    1758              :         @endcode
    1759              : 
    1760              :         @par Complexity
    1761              :         Linear in `this->size() + s.size()`.
    1762              : 
    1763              :         @par Exception Safety
    1764              :         Strong guarantee.
    1765              :         Calls to allocate may throw.
    1766              :         Exceptions thrown on invalid input.
    1767              : 
    1768              :         @throw system_error
    1769              :         `s` contains an invalid percent-encoding.
    1770              : 
    1771              :         @param s The string to set.
    1772              : 
    1773              :         @par BNF
    1774              :         @code
    1775              :         path          = path-abempty    ; begins with "/" or is empty
    1776              :                       / path-absolute   ; begins with "/" but not "//"
    1777              :                       / path-noscheme   ; begins with a non-colon segment
    1778              :                       / path-rootless   ; begins with a segment
    1779              :                       / path-empty      ; zero characters
    1780              : 
    1781              :         path-abempty  = *( "/" segment )
    1782              :         path-absolute = "/" [ segment-nz *( "/" segment ) ]
    1783              :         path-noscheme = segment-nz-nc *( "/" segment )
    1784              :         path-rootless = segment-nz *( "/" segment )
    1785              :         path-empty    = 0<pchar>
    1786              :         @endcode
    1787              : 
    1788              :         @par Specification
    1789              :         @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.3"
    1790              :             >3.3.  Path (rfc3986)</a>
    1791              : 
    1792              :         @see
    1793              :             @ref encoded_segments,
    1794              :             @ref segments,
    1795              :             @ref set_path,
    1796              :             @ref set_path_absolute.
    1797              :     */
    1798              :     url_base&
    1799              :     set_encoded_path(
    1800              :         pct_string_view s);
    1801              : 
    1802              :     /** Return the path as a container of segments
    1803              : 
    1804              :         This function returns a bidirectional
    1805              :         view of segments over the path.
    1806              :         The returned view references the same
    1807              :         underlying character buffer; ownership
    1808              :         is not transferred.
    1809              :         Any percent-escapes in strings returned
    1810              :         when iterating the view are decoded first.
    1811              :         The container is modifiable; changes
    1812              :         to the container are reflected in the
    1813              :         underlying URL.
    1814              : 
    1815              :         @par Example
    1816              :         @code
    1817              :         url u( "http://example.com/path/to/file.txt" );
    1818              : 
    1819              :         segments sv = u.segments();
    1820              :         @endcode
    1821              : 
    1822              :         @par Complexity
    1823              :         Constant.
    1824              : 
    1825              :         @par Exception Safety
    1826              :         Throws nothing.
    1827              : 
    1828              :         @par BNF
    1829              :         @code
    1830              :         path          = path-abempty    ; begins with "/" or is empty
    1831              :                       / path-absolute   ; begins with "/" but not "//"
    1832              :                       / path-noscheme   ; begins with a non-colon segment
    1833              :                       / path-rootless   ; begins with a segment
    1834              :                       / path-empty      ; zero characters
    1835              : 
    1836              :         path-abempty  = *( "/" segment )
    1837              :         path-absolute = "/" [ segment-nz *( "/" segment ) ]
    1838              :         path-noscheme = segment-nz-nc *( "/" segment )
    1839              :         path-rootless = segment-nz *( "/" segment )
    1840              :         path-empty    = 0<pchar>
    1841              :         @endcode
    1842              : 
    1843              :         @par Specification
    1844              :         @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.3"
    1845              :             >3.3.  Path (rfc3986)</a>
    1846              : 
    1847              :         @see
    1848              :             @ref encoded_segments,
    1849              :             @ref set_encoded_path,
    1850              :             @ref set_path,
    1851              :             @ref set_path_absolute.
    1852              :     */
    1853              :     urls::segments_ref
    1854              :     segments() noexcept;
    1855              : 
    1856              :     /// @copydoc url_view_base::segments
    1857              :     segments_view
    1858            1 :     segments() const noexcept
    1859              :     {
    1860            1 :         return url_view_base::segments();
    1861              :     }
    1862              : 
    1863              :     /** Return the path as a container of segments
    1864              : 
    1865              :         This function returns a bidirectional
    1866              :         view of segments over the path.
    1867              :         The returned view references the same
    1868              :         underlying character buffer; ownership
    1869              :         is not transferred.
    1870              :         Strings returned when iterating the
    1871              :         range may contain percent escapes.
    1872              :         The container is modifiable; changes
    1873              :         to the container are reflected in the
    1874              :         underlying URL.
    1875              : 
    1876              :         @par Example
    1877              :         @code
    1878              :         url u( "http://example.com/path/to/file.txt" );
    1879              : 
    1880              :         segments_encoded_ref sv = u.encoded_segments();
    1881              :         @endcode
    1882              : 
    1883              :         @par Complexity
    1884              :         Constant.
    1885              : 
    1886              :         @par Exception Safety
    1887              :         Throws nothing.
    1888              : 
    1889              :         @par BNF
    1890              :         @code
    1891              :         path          = path-abempty    ; begins with "/" or is empty
    1892              :                       / path-absolute   ; begins with "/" but not "//"
    1893              :                       / path-noscheme   ; begins with a non-colon segment
    1894              :                       / path-rootless   ; begins with a segment
    1895              :                       / path-empty      ; zero characters
    1896              : 
    1897              :         path-abempty  = *( "/" segment )
    1898              :         path-absolute = "/" [ segment-nz *( "/" segment ) ]
    1899              :         path-noscheme = segment-nz-nc *( "/" segment )
    1900              :         path-rootless = segment-nz *( "/" segment )
    1901              :         path-empty    = 0<pchar>
    1902              :         @endcode
    1903              : 
    1904              :         @par Specification
    1905              :         @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.3"
    1906              :             >3.3.  Path (rfc3986)</a>
    1907              : 
    1908              :         @see
    1909              :             @ref encoded_segments,
    1910              :             @ref set_encoded_path,
    1911              :             @ref set_path,
    1912              :             @ref set_path_absolute.
    1913              :     */
    1914              :     segments_encoded_ref
    1915              :     encoded_segments() noexcept;
    1916              : 
    1917              :     /// @copydoc url_view_base::encoded_segments
    1918              :     segments_encoded_view
    1919            1 :     encoded_segments() const noexcept
    1920              :     {
    1921            1 :         return url_view_base::encoded_segments();
    1922              :     }
    1923              : 
    1924              :     //--------------------------------------------
    1925              :     //
    1926              :     // Query
    1927              :     //
    1928              :     //--------------------------------------------
    1929              : 
    1930              :     /** Set the query
    1931              : 
    1932              :         This sets the query to the string, which
    1933              :         can be empty.
    1934              :         An empty query is distinct from having
    1935              :         no query.
    1936              :         Reserved characters in the string are
    1937              :         percent-escaped in the result.
    1938              : 
    1939              :         @par Example
    1940              :         @code
    1941              :         assert( url( "http://example.com" ).set_query( "id=42" ).query() == "id=42" );
    1942              :         @endcode
    1943              : 
    1944              :         @par Postconditions
    1945              :         @code
    1946              :         this->has_query() == true && this->query() == s
    1947              :         @endcode
    1948              : 
    1949              :         @par Exception Safety
    1950              :         Strong guarantee.
    1951              :         Calls to allocate may throw.
    1952              : 
    1953              :         @param s The string to set.
    1954              : 
    1955              :         @par BNF
    1956              :         @code
    1957              :         query           = *( pchar / "/" / "?" )
    1958              : 
    1959              :         query-param     = key [ "=" value ]
    1960              :         query-params    = [ query-param ] *( "&" query-param )
    1961              :         @endcode
    1962              : 
    1963              :         @par Specification
    1964              :         @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.4"
    1965              :             >3.4.  Query (rfc3986)</a>
    1966              :         @li <a href="https://en.wikipedia.org/wiki/Query_string"
    1967              :             >Query string (Wikipedia)</a>
    1968              : 
    1969              :         @see
    1970              :             @ref encoded_params,
    1971              :             @ref params,
    1972              :             @ref remove_query,
    1973              :             @ref set_encoded_query.
    1974              :     */
    1975              :     url_base&
    1976              :     set_query(
    1977              :         core::string_view s);
    1978              : 
    1979              :     /** Set the query
    1980              : 
    1981              :         This sets the query to the string, which
    1982              :         may contain percent-escapes and can be
    1983              :         empty.
    1984              :         An empty query is distinct from having
    1985              :         no query.
    1986              :         Escapes in the string are preserved,
    1987              :         and reserved characters in the string
    1988              :         are percent-escaped in the result.
    1989              : 
    1990              :         @par Example
    1991              :         @code
    1992              :         assert( url( "http://example.com" ).set_encoded_query( "id=42" ).encoded_query() == "id=42" );
    1993              :         @endcode
    1994              : 
    1995              :         @par Postconditions
    1996              :         @code
    1997              :         this->has_query() == true && this->query() == decode_view( s );
    1998              :         @endcode
    1999              : 
    2000              :         @par Exception Safety
    2001              :         Strong guarantee.
    2002              :         Calls to allocate may throw.
    2003              :         Exceptions thrown on invalid input.
    2004              : 
    2005              :         @param s The string to set.
    2006              : 
    2007              :         @throws system_error
    2008              :         `s` contains an invalid percent-encoding.
    2009              : 
    2010              :         @par BNF
    2011              :         @code
    2012              :         query           = *( pchar / "/" / "?" )
    2013              : 
    2014              :         query-param     = key [ "=" value ]
    2015              :         query-params    = [ query-param ] *( "&" query-param )
    2016              :         @endcode
    2017              : 
    2018              :         @par Specification
    2019              :         @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.4"
    2020              :             >3.4.  Query (rfc3986)</a>
    2021              :         @li <a href="https://en.wikipedia.org/wiki/Query_string"
    2022              :             >Query string (Wikipedia)</a>
    2023              : 
    2024              :         @see
    2025              :             @ref encoded_params,
    2026              :             @ref params,
    2027              :             @ref remove_query,
    2028              :             @ref set_query.
    2029              :     */
    2030              :     url_base&
    2031              :     set_encoded_query(
    2032              :         pct_string_view s);
    2033              : 
    2034              :     /** Return the query as a container of parameters
    2035              : 
    2036              :         This function returns a bidirectional
    2037              :         view of key/value pairs over the query.
    2038              :         The returned view references the same
    2039              :         underlying character buffer; ownership
    2040              :         is not transferred.
    2041              :         Any percent-escapes in strings returned
    2042              :         when iterating the view are decoded first.
    2043              :         The container is modifiable; changes
    2044              :         to the container are reflected in the
    2045              :         underlying URL.
    2046              : 
    2047              :         @par Example
    2048              :         @code
    2049              :         params_ref pv = url( "/sql?id=42&name=jane%2Ddoe&page+size=20" ).params();
    2050              :         @endcode
    2051              : 
    2052              :         @par Complexity
    2053              :         Constant.
    2054              : 
    2055              :         @par Exception Safety
    2056              :         Throws nothing.
    2057              : 
    2058              :         @par BNF
    2059              :         @code
    2060              :         query           = *( pchar / "/" / "?" )
    2061              : 
    2062              :         query-param     = key [ "=" value ]
    2063              :         query-params    = [ query-param ] *( "&" query-param )
    2064              :         @endcode
    2065              : 
    2066              :         @par Specification
    2067              :         @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.4"
    2068              :             >3.4.  Query (rfc3986)</a>
    2069              :         @li <a href="https://en.wikipedia.org/wiki/Query_string"
    2070              :             >Query string (Wikipedia)</a>
    2071              : 
    2072              :         @see
    2073              :             @ref encoded_params,
    2074              :             @ref remove_query,
    2075              :             @ref set_encoded_query,
    2076              :             @ref set_query.
    2077              :     */
    2078              :     params_ref
    2079              :     params() noexcept;
    2080              : 
    2081              :     /// @copydoc url_view_base::params
    2082              :     params_view
    2083            1 :     params() const noexcept
    2084              :     {
    2085            1 :         return url_view_base::params();
    2086              :     }
    2087              : 
    2088              :     /** Return the query as a container of parameters
    2089              : 
    2090              :         This function returns a bidirectional
    2091              :         view of key/value pairs over the query.
    2092              :         The returned view references the same
    2093              :         underlying character buffer; ownership
    2094              :         is not transferred.
    2095              :         Any percent-escapes in strings returned
    2096              :         when iterating the view are decoded first.
    2097              :         The container is modifiable; changes
    2098              :         to the container are reflected in the
    2099              :         underlying URL.
    2100              : 
    2101              :         @par Example
    2102              :         @code
    2103              :         encoding_opts opt;
    2104              :         opt.space_as_plus = true;
    2105              :         params_ref pv = url( "/sql?id=42&name=jane+doe&page+size=20" ).params(opt);
    2106              :         @endcode
    2107              : 
    2108              :         @par Complexity
    2109              :         Constant.
    2110              : 
    2111              :         @par Exception Safety
    2112              :         Throws nothing.
    2113              : 
    2114              :         @param opt The options for decoding. If
    2115              :         this parameter is omitted, the `space_as_plus`
    2116              :         is used.
    2117              : 
    2118              :         @par BNF
    2119              :         @code
    2120              :         query           = *( pchar / "/" / "?" )
    2121              : 
    2122              :         query-param     = key [ "=" value ]
    2123              :         query-params    = [ query-param ] *( "&" query-param )
    2124              :         @endcode
    2125              : 
    2126              :         @par Specification
    2127              :         @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.4"
    2128              :             >3.4.  Query (rfc3986)</a>
    2129              :         @li <a href="https://en.wikipedia.org/wiki/Query_string"
    2130              :             >Query string (Wikipedia)</a>
    2131              : 
    2132              :         @see
    2133              :             @ref encoded_params,
    2134              :             @ref remove_query,
    2135              :             @ref set_encoded_query,
    2136              :             @ref set_query.
    2137              :     */
    2138              :     params_ref
    2139              :     params(encoding_opts opt) noexcept;
    2140              : 
    2141              :     /// @copydoc url_view_base::encoded_params
    2142              :     params_encoded_view
    2143            1 :     encoded_params() const noexcept
    2144              :     {
    2145            1 :         return url_view_base::encoded_params();
    2146              :     }
    2147              : 
    2148              :     /** Return the query as a container of parameters
    2149              : 
    2150              :         This function returns a bidirectional
    2151              :         view of key/value pairs over the query.
    2152              :         The returned view references the same
    2153              :         underlying character buffer; ownership
    2154              :         is not transferred.
    2155              :         Strings returned when iterating the
    2156              :         range may contain percent escapes.
    2157              :         The container is modifiable; changes
    2158              :         to the container are reflected in the
    2159              :         underlying URL.
    2160              : 
    2161              :         @par Example
    2162              :         @code
    2163              :         params_encoded_ref pv = url( "/sql?id=42&name=jane%2Ddoe&page+size=20" ).encoded_params();
    2164              :         @endcode
    2165              : 
    2166              :         @par Complexity
    2167              :         Constant.
    2168              : 
    2169              :         @par Exception Safety
    2170              :         Throws nothing.
    2171              : 
    2172              :         @par BNF
    2173              :         @code
    2174              :         query           = *( pchar / "/" / "?" )
    2175              : 
    2176              :         query-param     = key [ "=" value ]
    2177              :         query-params    = [ query-param ] *( "&" query-param )
    2178              :         @endcode
    2179              : 
    2180              :         @par Specification
    2181              :         @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.4"
    2182              :             >3.4.  Query (rfc3986)</a>
    2183              :         @li <a href="https://en.wikipedia.org/wiki/Query_string"
    2184              :             >Query string (Wikipedia)</a>
    2185              : 
    2186              :         @see
    2187              :             @ref params,
    2188              :             @ref remove_query,
    2189              :             @ref set_encoded_query,
    2190              :             @ref set_query.
    2191              :     */
    2192              :     params_encoded_ref
    2193              :     encoded_params() noexcept;
    2194              : 
    2195              :     /** Set the query params
    2196              : 
    2197              :         This sets the query params to the list
    2198              :         of param_view, which can be empty.
    2199              : 
    2200              :         An empty list of params is distinct from
    2201              :         having no params.
    2202              : 
    2203              :         Reserved characters in the string are
    2204              :         percent-escaped in the result.
    2205              : 
    2206              :         @par Example
    2207              :         @code
    2208              :         assert( url( "http://example.com" ).set_params( {"id", "42"} ).query() == "id=42" );
    2209              :         @endcode
    2210              : 
    2211              :         @par Postconditions
    2212              :         @code
    2213              :         this->has_query() == true
    2214              :         @endcode
    2215              : 
    2216              :         @par Exception Safety
    2217              :         Strong guarantee.
    2218              :         Calls to allocate may throw.
    2219              : 
    2220              :         @par Complexity
    2221              :         Linear.
    2222              : 
    2223              :         @param ps The params to set.
    2224              : 
    2225              :         @par BNF
    2226              :         @code
    2227              :         query           = *( pchar / "/" / "?" )
    2228              : 
    2229              :         query-param     = key [ "=" value ]
    2230              :         query-params    = [ query-param ] *( "&" query-param )
    2231              :         @endcode
    2232              : 
    2233              :         @par Specification
    2234              :         @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.4
    2235              :             >3.4.  Query (rfc3986)</a>
    2236              :         @li <a href="https://en.wikipedia.org/wiki/Query_string"
    2237              :             >Query string (Wikipedia)</a>
    2238              : 
    2239              :         @see
    2240              :             @ref encoded_params,
    2241              :             @ref remove_query,
    2242              :             @ref set_encoded_query,
    2243              :             @ref set_query.
    2244              :     */
    2245              :     url_base&
    2246              :     set_params( std::initializer_list<param_view> ps ) noexcept;
    2247              : 
    2248              :     /** Set the query params
    2249              : 
    2250              :         This sets the query params to the elements
    2251              :         in the list, which may contain
    2252              :         percent-escapes and can be empty.
    2253              : 
    2254              :         An empty list of params is distinct from
    2255              :         having no query.
    2256              : 
    2257              :         Escapes in the string are preserved,
    2258              :         and reserved characters in the string
    2259              :         are percent-escaped in the result.
    2260              : 
    2261              :         @par Example
    2262              :         @code
    2263              :         assert( url( "http://example.com" ).set_encoded_params( {"id", "42"} ).encoded_query() == "id=42" );
    2264              :         @endcode
    2265              : 
    2266              :         @par Postconditions
    2267              :         @code
    2268              :         this->has_query() == true
    2269              :         @endcode
    2270              : 
    2271              :         @par Complexity
    2272              :         Linear.
    2273              : 
    2274              :         @par Exception Safety
    2275              :         Strong guarantee.
    2276              :         Calls to allocate may throw.
    2277              :         Exceptions thrown on invalid input.
    2278              : 
    2279              :         @param ps The params to set.
    2280              : 
    2281              :         @throws system_error
    2282              :         some element in `ps` contains an invalid percent-encoding.
    2283              : 
    2284              :         @par BNF
    2285              :         @code
    2286              :         query           = *( pchar / "/" / "?" )
    2287              : 
    2288              :         query-param     = key [ "=" value ]
    2289              :         query-params    = [ query-param ] *( "&" query-param )
    2290              :         @endcode
    2291              : 
    2292              :         @par Specification
    2293              :         @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.4"
    2294              :             >3.4. Query (rfc3986)</a>
    2295              :         @li <a href="https://en.wikipedia.org/wiki/Query_string"
    2296              :             >Query string (Wikipedia)</a>
    2297              : 
    2298              :         @see
    2299              :             @ref set_params,
    2300              :             @ref params,
    2301              :             @ref remove_query,
    2302              :             @ref set_encoded_query,
    2303              :             @ref set_query.
    2304              :     */
    2305              :     url_base&
    2306              :     set_encoded_params( std::initializer_list< param_pct_view > ps ) noexcept;
    2307              : 
    2308              :     /** Remove the query
    2309              : 
    2310              :         If a query is present, it is removed.
    2311              :         An empty query is distinct from having
    2312              :         no query.
    2313              : 
    2314              :         @par Example
    2315              :         @code
    2316              :         assert( url( "http://www.example.com?id=42" ).remove_query().buffer() == "http://www.example.com" );
    2317              :         @endcode
    2318              : 
    2319              :         @par Postconditions
    2320              :         @code
    2321              :         this->has_query() == false && this->params().empty()
    2322              :         @endcode
    2323              : 
    2324              :         @par Exception Safety
    2325              :         Throws nothing.
    2326              : 
    2327              :         @par BNF
    2328              :         @code
    2329              :         query           = *( pchar / "/" / "?" )
    2330              : 
    2331              :         query-param     = key [ "=" value ]
    2332              :         query-params    = [ query-param ] *( "&" query-param )
    2333              :         @endcode
    2334              : 
    2335              :         @par Specification
    2336              :         @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.4"
    2337              :             >3.4.  Query (rfc3986)</a>
    2338              :         @li <a href="https://en.wikipedia.org/wiki/Query_string"
    2339              :             >Query string (Wikipedia)</a>
    2340              : 
    2341              :         @see
    2342              :             @ref encoded_params,
    2343              :             @ref params,
    2344              :             @ref set_encoded_query,
    2345              :             @ref set_query.
    2346              :     */
    2347              :     url_base&
    2348              :     remove_query() noexcept;
    2349              : 
    2350              :     //--------------------------------------------
    2351              :     //
    2352              :     // Fragment
    2353              :     //
    2354              :     //--------------------------------------------
    2355              : 
    2356              :     /** Remove the fragment
    2357              : 
    2358              :         This function removes the fragment.
    2359              :         An empty fragment is distinct from
    2360              :         having no fragment.
    2361              : 
    2362              :         @par Example
    2363              :         @code
    2364              :         assert( url( "?first=john&last=doe#anchor" ).remove_fragment().buffer() == "?first=john&last=doe" );
    2365              :         @endcode
    2366              : 
    2367              :         @par Postconditions
    2368              :         @code
    2369              :         this->has_fragment() == false && this->encoded_fragment() == ""
    2370              :         @endcode
    2371              : 
    2372              :         @par Complexity
    2373              :         Constant.
    2374              : 
    2375              :         @par Exception Safety
    2376              :         Throws nothing.
    2377              : 
    2378              :         @par BNF
    2379              :         @code
    2380              :         fragment    = *( pchar / "/" / "?" )
    2381              :         @endcode
    2382              : 
    2383              :         @par Specification
    2384              :         @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.5"
    2385              :             >3.5.  Fragment</a>
    2386              : 
    2387              :         @see
    2388              :             @ref remove_fragment,
    2389              :             @ref set_encoded_fragment,
    2390              :             @ref set_fragment.
    2391              :     */
    2392              :     url_base&
    2393              :     remove_fragment() noexcept;
    2394              : 
    2395              :     /** Set the fragment.
    2396              : 
    2397              :         This function sets the fragment to the
    2398              :         specified string, which may be empty.
    2399              :         An empty fragment is distinct from
    2400              :         having no fragment.
    2401              :         Reserved characters in the string are
    2402              :         percent-escaped in the result.
    2403              : 
    2404              :         @par Example
    2405              :         @code
    2406              :         assert( url("?first=john&last=doe" ).set_encoded_fragment( "john doe" ).encoded_fragment() == "john%20doe" );
    2407              :         @endcode
    2408              : 
    2409              :         @par Postconditions
    2410              :         @code
    2411              :         this->has_fragment() == true && this->fragment() == s
    2412              :         @endcode
    2413              : 
    2414              :         @par Complexity
    2415              :         Linear in `this->size() + s.size()`.
    2416              : 
    2417              :         @par Exception Safety
    2418              :         Strong guarantee.
    2419              :         Calls to allocate may throw.
    2420              : 
    2421              :         @param s The string to set.
    2422              : 
    2423              :         @par BNF
    2424              :         @code
    2425              :         fragment    = *( pchar / "/" / "?" )
    2426              :         @endcode
    2427              : 
    2428              :         @par Specification
    2429              :         @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.5"
    2430              :             >3.5.  Fragment</a>
    2431              : 
    2432              :         @see
    2433              :             @ref remove_fragment,
    2434              :             @ref set_encoded_fragment.
    2435              :     */
    2436              :     url_base&
    2437              :     set_fragment(
    2438              :         core::string_view s);
    2439              : 
    2440              :     /** Set the fragment.
    2441              : 
    2442              :         This function sets the fragment to the
    2443              :         specified string, which may contain
    2444              :         percent-escapes and which may be empty.
    2445              :         An empty fragment is distinct from
    2446              :         having no fragment.
    2447              :         Escapes in the string are preserved,
    2448              :         and reserved characters in the string
    2449              :         are percent-escaped in the result.
    2450              : 
    2451              :         @par Example
    2452              :         @code
    2453              :         assert( url("?first=john&last=doe" ).set_encoded_fragment( "john%2Ddoe" ).fragment() == "john-doe" );
    2454              :         @endcode
    2455              : 
    2456              :         @par Postconditions
    2457              :         @code
    2458              :         this->has_fragment() == true && this->fragment() == decode_view( s )
    2459              :         @endcode
    2460              : 
    2461              :         @par Complexity
    2462              :         Linear in `this->size() + s.size()`.
    2463              : 
    2464              :         @par Exception Safety
    2465              :         Strong guarantee.
    2466              :         Calls to allocate may throw.
    2467              :         Exceptions thrown on invalid input.
    2468              : 
    2469              :         @throw system_error
    2470              :         `s` contains an invalid percent-encoding.
    2471              : 
    2472              :         @param s The string to set.
    2473              : 
    2474              :         @par BNF
    2475              :         @code
    2476              :         fragment    = *( pchar / "/" / "?" )
    2477              :         @endcode
    2478              : 
    2479              :         @par Specification
    2480              :         @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.5"
    2481              :             >3.5.  Fragment</a>
    2482              : 
    2483              :         @see
    2484              :             @ref remove_fragment,
    2485              :             @ref set_fragment.
    2486              :     */
    2487              :     url_base&
    2488              :     set_encoded_fragment(
    2489              :         pct_string_view s);
    2490              : 
    2491              :     //--------------------------------------------
    2492              :     //
    2493              :     // Compound Fields
    2494              :     //
    2495              :     //--------------------------------------------
    2496              : 
    2497              :     /** Remove the origin component
    2498              : 
    2499              :         This function removes the origin, which
    2500              :         consists of the scheme and authority.
    2501              : 
    2502              :         @par Example
    2503              :         @code
    2504              :         assert( url( "http://www.example.com/index.htm" ).remove_origin().buffer() == "/index.htm" );
    2505              :         @endcode
    2506              : 
    2507              :         @par Postconditions
    2508              :         @code
    2509              :         this->scheme_id() == scheme::none && this->has_authority() == false
    2510              :         @endcode
    2511              : 
    2512              :         @par Complexity
    2513              :         Linear in `this->size()`.
    2514              : 
    2515              :         @par Exception Safety
    2516              :         Throws nothing.
    2517              :     */
    2518              :     url_base&
    2519              :     remove_origin();
    2520              : 
    2521              :     //--------------------------------------------
    2522              :     //
    2523              :     // Normalization
    2524              :     //
    2525              :     //--------------------------------------------
    2526              : 
    2527              :     /** Normalize the URL components
    2528              : 
    2529              :         Applies Syntax-based normalization to
    2530              :         all components of the URL.
    2531              : 
    2532              :         @par Exception Safety
    2533              :         Strong guarantee.
    2534              :         Calls to allocate may throw.
    2535              : 
    2536              :         @par Specification
    2537              :         @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-6.2.2"
    2538              :             >6.2.2 Syntax-Based Normalization (rfc3986)</a>
    2539              : 
    2540              :     */
    2541              :     url_base&
    2542              :     normalize();
    2543              : 
    2544              :     /** Normalize the URL scheme
    2545              : 
    2546              :         Applies Syntax-based normalization to the
    2547              :         URL scheme.
    2548              : 
    2549              :         The scheme is normalized to lowercase.
    2550              : 
    2551              :         @par Exception Safety
    2552              :         Strong guarantee.
    2553              :         Calls to allocate may throw.
    2554              : 
    2555              :         @par Specification
    2556              :         @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-6.2.2"
    2557              :             >6.2.2 Syntax-Based Normalization (rfc3986)</a>
    2558              : 
    2559              :     */
    2560              :     url_base&
    2561              :     normalize_scheme();
    2562              : 
    2563              :     /** Normalize the URL authority
    2564              : 
    2565              :         Applies Syntax-based normalization to the
    2566              :         URL authority.
    2567              : 
    2568              :         Percent-encoding triplets are normalized
    2569              :         to uppercase letters. Percent-encoded
    2570              :         octets that correspond to unreserved
    2571              :         characters are decoded.
    2572              : 
    2573              :         @par Exception Safety
    2574              :         Strong guarantee.
    2575              :         Calls to allocate may throw.
    2576              : 
    2577              :         @par Specification
    2578              :         @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-6.2.2"
    2579              :             >6.2.2 Syntax-Based Normalization (rfc3986)</a>
    2580              : 
    2581              :     */
    2582              :     url_base&
    2583              :     normalize_authority();
    2584              : 
    2585              :     /** Normalize the URL path
    2586              : 
    2587              :         Applies Syntax-based normalization to the
    2588              :         URL path.
    2589              : 
    2590              :         Percent-encoding triplets are normalized
    2591              :         to uppercase letters. Percent-encoded
    2592              :         octets that correspond to unreserved
    2593              :         characters are decoded. Redundant
    2594              :         path-segments are removed.
    2595              : 
    2596              :         @par Exception Safety
    2597              :         Strong guarantee.
    2598              :         Calls to allocate may throw.
    2599              : 
    2600              :         @par Specification
    2601              :         @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-6.2.2"
    2602              :             >6.2.2 Syntax-Based Normalization (rfc3986)</a>
    2603              : 
    2604              :     */
    2605              :     url_base&
    2606              :     normalize_path();
    2607              : 
    2608              :     /** Normalize the URL query
    2609              : 
    2610              :         Applies Syntax-based normalization to the
    2611              :         URL query.
    2612              : 
    2613              :         Percent-encoding triplets are normalized
    2614              :         to uppercase letters. Percent-encoded
    2615              :         octets that correspond to unreserved
    2616              :         characters are decoded.
    2617              : 
    2618              :         @par Exception Safety
    2619              :         Strong guarantee.
    2620              :         Calls to allocate may throw.
    2621              : 
    2622              :         @par Specification
    2623              :         @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-6.2.2"
    2624              :             >6.2.2 Syntax-Based Normalization (rfc3986)</a>
    2625              : 
    2626              :     */
    2627              :     url_base&
    2628              :     normalize_query();
    2629              : 
    2630              :     /** Normalize the URL fragment
    2631              : 
    2632              :         Applies Syntax-based normalization to the
    2633              :         URL fragment.
    2634              : 
    2635              :         Percent-encoding triplets are normalized
    2636              :         to uppercase letters. Percent-encoded
    2637              :         octets that correspond to unreserved
    2638              :         characters are decoded.
    2639              : 
    2640              :         @par Exception Safety
    2641              :         Strong guarantee.
    2642              :         Calls to allocate may throw.
    2643              : 
    2644              :         @par Specification
    2645              :         @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-6.2.2"
    2646              :             >6.2.2 Syntax-Based Normalization (rfc3986)</a>
    2647              : 
    2648              :     */
    2649              :     url_base&
    2650              :     normalize_fragment();
    2651              : 
    2652              :     //
    2653              :     // (end of fluent API)
    2654              :     //
    2655              :     //--------------------------------------------
    2656              : 
    2657              :     //--------------------------------------------
    2658              :     //
    2659              :     // Resolution
    2660              :     //
    2661              :     //--------------------------------------------
    2662              : 
    2663              :     /** Resolve a URL reference against this base URL
    2664              : 
    2665              :         This function attempts to resolve a URL
    2666              :         reference `ref` against this base URL
    2667              :         in a manner similar to that of a web browser
    2668              :         resolving an anchor tag.
    2669              : 
    2670              :         This URL must satisfy the <em>URI</em>
    2671              :         grammar. In other words, it must contain
    2672              :         a scheme.
    2673              : 
    2674              :         Relative references are only usable when
    2675              :         in the context of a base absolute URI.
    2676              :         This process of resolving a relative
    2677              :         <em>reference</em> within the context of
    2678              :         a <em>base</em> URI is defined in detail
    2679              :         in rfc3986 (see below).
    2680              : 
    2681              :         The resolution process works as if the
    2682              :         relative reference is appended to the base
    2683              :         URI and the result is normalized.
    2684              : 
    2685              :         Given the input base URL, this function
    2686              :         resolves the relative reference
    2687              :         as if performing the following steps:
    2688              : 
    2689              :         @li Ensure the base URI has at least a scheme
    2690              :         @li Normalizing the reference path
    2691              :         @li Merge base and reference paths
    2692              :         @li Normalize the merged path
    2693              : 
    2694              :         This function places the result of the
    2695              :         resolution into this URL in place.
    2696              : 
    2697              :         If an error occurs, the contents of
    2698              :         this URL are unspecified and a @ref result
    2699              :         with an `system::error_code` is returned.
    2700              : 
    2701              :         @note Abnormal hrefs where the number of ".."
    2702              :         segments exceeds the number of segments in
    2703              :         the base path are handled by including the
    2704              :         unmatched ".." segments in the result, as described
    2705              :         in <a href="https://www.rfc-editor.org/errata/eid4547"
    2706              :         >Errata 4547</a>.
    2707              : 
    2708              :         @par Example
    2709              :         @code
    2710              :         url base1( "/one/two/three" );
    2711              :         base1.resolve("four");
    2712              :         assert( base1.buffer() == "/one/two/four" );
    2713              : 
    2714              :         url base2( "http://example.com/" )
    2715              :         base2.resolve("/one");
    2716              :         assert( base2.buffer() == "http://example.com/one" );
    2717              : 
    2718              :         url base3( "http://example.com/one" );
    2719              :         base3.resolve("/two");
    2720              :         assert( base3.buffer() == "http://example.com/two" );
    2721              : 
    2722              :         url base4( "http://a/b/c/d;p?q" );
    2723              :         base4.resolve("g#s");
    2724              :         assert( base4.buffer() == "http://a/b/c/g#s" );
    2725              :         @endcode
    2726              : 
    2727              :         @par BNF
    2728              :         @code
    2729              :         absolute-URI  = scheme ":" hier-part [ "?" query ]
    2730              :         @endcode
    2731              : 
    2732              :         @par Exception Safety
    2733              :         Basic guarantee.
    2734              :         Calls to allocate may throw.
    2735              : 
    2736              :         @return An empty @ref result upon success,
    2737              :         otherwise an error code if `!base.has_scheme()`.
    2738              : 
    2739              :         @param ref The URL reference to resolve.
    2740              : 
    2741              :         @par Specification
    2742              :         <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-5"
    2743              :             >5. Reference Resolution (rfc3986)</a>
    2744              : 
    2745              :         @see
    2746              :             @ref url,
    2747              :             @ref url_view.
    2748              :     */
    2749              :     system::result<void>
    2750              :     resolve(
    2751              :         url_view_base const& ref);
    2752              : 
    2753              :     friend
    2754              :     system::result<void>
    2755              :     resolve(
    2756              :         url_view_base const& base,
    2757              :         url_view_base const& ref,
    2758              :         url_base& dest);
    2759              : 
    2760              : private:
    2761              :     //--------------------------------------------
    2762              :     //
    2763              :     // implementation
    2764              :     //
    2765              :     //--------------------------------------------
    2766              : 
    2767              :     void  check_invariants() const noexcept;
    2768              : 
    2769              :     char* resize_impl(int, std::size_t, op_t&);
    2770              :     char* resize_impl(int, int, std::size_t, op_t&);
    2771              :     char* shrink_impl(int, std::size_t, op_t&);
    2772              :     char* shrink_impl(int, int, std::size_t, op_t&);
    2773              : 
    2774              :     void  set_scheme_impl(core::string_view, urls::scheme);
    2775              :     char* set_user_impl(std::size_t n, op_t& op);
    2776              :     char* set_password_impl(std::size_t n, op_t& op);
    2777              :     char* set_userinfo_impl(std::size_t n, op_t& op);
    2778              :     char* set_host_impl(std::size_t n, op_t& op);
    2779              :     char* set_port_impl(std::size_t n, op_t& op);
    2780              :     char* set_path_impl(std::size_t n, op_t& op);
    2781              : 
    2782              :     core::string_view
    2783              :     first_segment() const noexcept;
    2784              : 
    2785              :     detail::segments_iter_impl
    2786              :     edit_segments(
    2787              :         detail::segments_iter_impl const&,
    2788              :         detail::segments_iter_impl const&,
    2789              :         detail::any_segments_iter&& it0,
    2790              :         int absolute = -1);
    2791              : 
    2792              :     auto
    2793              :     edit_params(
    2794              :         detail::params_iter_impl const&,
    2795              :         detail::params_iter_impl const&,
    2796              :         detail::any_params_iter&&) ->
    2797              :             detail::params_iter_impl;
    2798              : 
    2799              :     system::result<void>
    2800              :     resolve_impl(
    2801              :         url_view_base const& base,
    2802              :         url_view_base const& ref);
    2803              : 
    2804              :     template<class CharSet>
    2805              :     void normalize_octets_impl(int,
    2806              :         CharSet const& allowed, op_t&) noexcept;
    2807              :     void decoded_to_lower_impl(int id) noexcept;
    2808              :     void to_lower_impl(int id) noexcept;
    2809              : };
    2810              : 
    2811              : //------------------------------------------------
    2812              : 
    2813              : /** Resolve a URL reference against a base URL
    2814              : 
    2815              :     This function attempts to resolve a URL
    2816              :     reference `ref` against the base URL `base`
    2817              :     in a manner similar to that of a web browser
    2818              :     resolving an anchor tag.
    2819              : 
    2820              :     The base URL must satisfy the <em>URI</em>
    2821              :     grammar. In other words, it must contain
    2822              :     a scheme.
    2823              : 
    2824              :     Relative references are only usable when
    2825              :     in the context of a base absolute URI.
    2826              :     This process of resolving a relative
    2827              :     <em>reference</em> within the context of
    2828              :     a <em>base</em> URI is defined in detail
    2829              :     in rfc3986 (see below).
    2830              : 
    2831              :     The resolution process works as if the
    2832              :     relative reference is appended to the base
    2833              :     URI and the result is normalized.
    2834              : 
    2835              :     Given the input base URL, this function
    2836              :     resolves the relative reference
    2837              :     as if performing the following steps:
    2838              : 
    2839              :     @li Ensure the base URI has at least a scheme
    2840              :     @li Normalizing the reference path
    2841              :     @li Merge base and reference paths
    2842              :     @li Normalize the merged path
    2843              : 
    2844              :     This function places the result of the
    2845              :     resolution into `dest`, which can be
    2846              :     any of the url containers that inherit
    2847              :     from @ref url_base.
    2848              : 
    2849              :     If an error occurs, the contents of
    2850              :     `dest` is unspecified and `ec` is set.
    2851              : 
    2852              :     @note Abnormal hrefs where the number of ".."
    2853              :     segments exceeds the number of segments in
    2854              :     the base path are handled by including the
    2855              :     unmatched ".." segments in the result, as described
    2856              :     in <a href="https://www.rfc-editor.org/errata/eid4547"
    2857              :     >Errata 4547</a>.
    2858              : 
    2859              :     @par Example
    2860              :     @code
    2861              :     url dest;
    2862              :     system::error_code ec;
    2863              : 
    2864              :     resolve("/one/two/three", "four", dest, ec);
    2865              :     assert( dest.str() == "/one/two/four" );
    2866              : 
    2867              :     resolve("http://example.com/", "/one", dest, ec);
    2868              :     assert( dest.str() == "http://example.com/one" );
    2869              : 
    2870              :     resolve("http://example.com/one", "/two", dest, ec);
    2871              :     assert( dest.str() == "http://example.com/two" );
    2872              : 
    2873              :     resolve("http://a/b/c/d;p?q", "g#s", dest, ec);
    2874              :     assert( dest.str() == "http://a/b/c/g#s" );
    2875              :     @endcode
    2876              : 
    2877              :     @par BNF
    2878              :     @code
    2879              :     absolute-URI  = scheme ":" hier-part [ "?" query ]
    2880              :     @endcode
    2881              : 
    2882              :     @par Exception Safety
    2883              :     Basic guarantee.
    2884              :     Calls to allocate may throw.
    2885              : 
    2886              :     @return An empty @ref result upon success,
    2887              :     otherwise an error code if `!base.has_scheme()`.
    2888              : 
    2889              :     @param base The base URL to resolve against.
    2890              : 
    2891              :     @param ref The URL reference to resolve.
    2892              : 
    2893              :     @param dest The container where the result
    2894              :     is written, upon success.
    2895              : 
    2896              :     @par Specification
    2897              :     <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-5"
    2898              :         >5. Reference Resolution (rfc3986)</a>
    2899              : 
    2900              :     @see
    2901              :         @ref url,
    2902              :         @ref url_view.
    2903              : */
    2904              : inline
    2905              : system::result<void>
    2906          404 : resolve(
    2907              :     url_view_base const& base,
    2908              :     url_view_base const& ref,
    2909              :     url_base& dest)
    2910              : {
    2911          404 :     if (&dest != &base)
    2912          403 :         dest.copy(base);
    2913          404 :     return dest.resolve(ref);
    2914              : }
    2915              : 
    2916              : } // urls
    2917              : } // boost
    2918              : 
    2919              : // These are here because of circular references
    2920              : #include <boost/url/impl/params_ref.hpp>
    2921              : #include <boost/url/impl/params_encoded_ref.hpp>
    2922              : #include <boost/url/impl/segments_ref.hpp>
    2923              : #include <boost/url/impl/segments_encoded_ref.hpp>
    2924              : 
    2925              : #endif
        

Generated by: LCOV version 2.1