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

Generated by: LCOV version 1.15