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

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

Generated by: LCOV version 2.1