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

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

Generated by: LCOV version 1.15