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

Generated by: LCOV version 2.1