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

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

Generated by: LCOV version 2.1