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

Generated by: LCOV version 2.3