LCOV - code coverage report
Current view: top level - url - url_base.hpp (source / functions) Coverage Total Hit Missed
Test: coverage_remapped.info Lines: 100.0 % 24 24
Test Date: 2026-02-25 21:00:01 Functions: 91.7 % 12 11 1

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

Generated by: LCOV version 2.3