LCOV - code coverage report
Current view: top level - url - decode_view.hpp (source / functions) Coverage Total Hit
Test: coverage_remapped.info Lines: 100.0 % 36 36
Test Date: 2026-02-25 21:00:01 Functions: 100.0 % 55 55

           TLA  Line data    Source code
       1                 : //
       2                 : // Copyright (c) 2022 Alan de Freitas (alandefreitas@gmail.com)
       3                 : //
       4                 : // Distributed under the Boost Software License, Version 1.0. (See accompanying
       5                 : // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
       6                 : //
       7                 : // Official repository: https://github.com/boostorg/url
       8                 : //
       9                 : 
      10                 : #ifndef BOOST_URL_DECODE_VIEW_HPP
      11                 : #define BOOST_URL_DECODE_VIEW_HPP
      12                 : 
      13                 : #include <boost/url/detail/config.hpp>
      14                 : #include <boost/core/detail/string_view.hpp>
      15                 : #include <boost/url/encoding_opts.hpp>
      16                 : #include <boost/url/pct_string_view.hpp>
      17                 : #include <type_traits>
      18                 : #include <iterator>
      19                 : #include <iosfwd>
      20                 : 
      21                 : namespace boost {
      22                 : namespace urls {
      23                 : 
      24                 : //------------------------------------------------
      25                 : 
      26                 : class decode_view;
      27                 : 
      28                 : namespace detail {
      29                 : 
      30                 : // unchecked
      31                 : template<class... Args>
      32                 : decode_view
      33                 : make_decode_view(
      34                 :     Args&&... args) noexcept;
      35                 : 
      36                 : } // detail
      37                 : 
      38                 : //------------------------------------------------
      39                 : 
      40                 : /** A reference to a valid, percent-encoded string
      41                 : 
      42                 :     These views reference strings in parts of URLs
      43                 :     or other components that are percent-encoded.
      44                 :     The special characters (those not in the
      45                 :     allowed character set) are stored as three
      46                 :     character escapes that consist of a percent
      47                 :     sign ('%%') followed by a two-digit hexadecimal
      48                 :     number of the corresponding unescaped character
      49                 :     code, which may be part of a UTF-8 code point
      50                 :     depending on the context.
      51                 : 
      52                 :     The view refers to the original character
      53                 :     buffer and only decodes escaped sequences when
      54                 :     needed. In particular these operations perform
      55                 :     percent-decoding automatically without the
      56                 :     need to allocate memory:
      57                 : 
      58                 :     @li Iteration of the string
      59                 :     @li Accessing the encoded character buffer
      60                 :     @li Comparison to encoded or plain strings
      61                 : 
      62                 :     These objects can only be constructed from
      63                 :     strings that have a valid percent-encoding,
      64                 :     otherwise construction fails. The caller is
      65                 :     responsible for ensuring that the lifetime
      66                 :     of the character buffer from which the view
      67                 :     is constructed extends unmodified until the
      68                 :     view is no longer accessed.
      69                 : */
      70                 : class decode_view
      71                 : {
      72                 :     char const* p_ = nullptr;
      73                 :     std::size_t n_ = 0;
      74                 :     std::size_t dn_ = 0;
      75                 :     bool space_as_plus_ = true;
      76                 : 
      77                 :     template<class... Args>
      78                 :     friend
      79                 :     decode_view
      80                 :     detail::make_decode_view(
      81                 :         Args&&... args) noexcept;
      82                 : 
      83                 :     // unchecked
      84                 :     BOOST_CXX14_CONSTEXPR
      85                 :     explicit
      86 HIT        3903 :     decode_view(
      87                 :         core::string_view s,
      88                 :         std::size_t n,
      89                 :         encoding_opts opt) noexcept
      90            3903 :         : p_(s.data())
      91            3903 :         , n_(s.size())
      92            3903 :         , dn_(n)
      93            3903 :         , space_as_plus_(
      94            3903 :             opt.space_as_plus)
      95            3903 :     {}
      96                 : 
      97                 : public:
      98                 :     /** The value type
      99                 :     */
     100                 :     using value_type = char;
     101                 : 
     102                 :     /** The reference type
     103                 :     */
     104                 :     using reference = char;
     105                 : 
     106                 :     /// @copydoc reference
     107                 :     using const_reference = char;
     108                 : 
     109                 :     /** The unsigned integer type
     110                 :     */
     111                 :     using size_type = std::size_t;
     112                 : 
     113                 :     /** The signed integer type
     114                 :     */
     115                 :     using difference_type = std::ptrdiff_t;
     116                 : 
     117                 :     /** An iterator of constant, decoded characters.
     118                 : 
     119                 :         This iterator is used to access the encoded
     120                 :         string as a *bidirectional* range of characters
     121                 :         with percent-decoding applied. Escape sequences
     122                 :         are not decoded until the iterator is
     123                 :         dereferenced.
     124                 :     */
     125                 :     class iterator;
     126                 : 
     127                 :     /// @copydoc iterator
     128                 :     using const_iterator = iterator;
     129                 : 
     130                 :     //--------------------------------------------
     131                 :     //
     132                 :     // Special Members
     133                 :     //
     134                 :     //--------------------------------------------
     135                 : 
     136                 :     /** Constructor
     137                 : 
     138                 :         Default-constructed views represent
     139                 :         empty strings.
     140                 : 
     141                 :         @par Example
     142                 :         @code
     143                 :         decode_view ds;
     144                 :         @endcode
     145                 : 
     146                 :         @par Postconditions
     147                 :         @code
     148                 :         this->empty() == true
     149                 :         @endcode
     150                 : 
     151                 :         @par Complexity
     152                 :         Constant.
     153                 : 
     154                 :         @par Exception Safety
     155                 :         Throws nothing.
     156                 :     */
     157                 :     BOOST_CXX14_CONSTEXPR
     158                 :     decode_view() noexcept = default;
     159                 : 
     160                 :     /** Constructor
     161                 : 
     162                 :         This constructs a view from the character
     163                 :         buffer `s`, which must remain valid and
     164                 :         unmodified until the view is no longer
     165                 :         accessed.
     166                 : 
     167                 :         @par Example
     168                 :         @code
     169                 :         decode_view ds( "Program%20Files" );
     170                 :         @endcode
     171                 : 
     172                 :         @par Postconditions
     173                 :         @code
     174                 :         this->encoded() == s
     175                 :         @endcode
     176                 : 
     177                 :         @par Complexity
     178                 :         Linear in `s.size()`.
     179                 : 
     180                 :         @par Exception Safety
     181                 :         Although this function does not throw exceptions,
     182                 :         implicitly constructing a @ref pct_string_view
     183                 :         for the first argument can throw exceptions
     184                 :         on invalid input.
     185                 : 
     186                 :         @param s A percent-encoded string that has
     187                 :         already been validated. Implicit conversion
     188                 :         from other string types is supported but
     189                 :         may throw exceptions.
     190                 : 
     191                 :         @param opt The options for decoding. If
     192                 :         this parameter is omitted, the default
     193                 :         options are used.
     194                 :     */
     195                 :     BOOST_CXX14_CONSTEXPR
     196                 :     explicit
     197            3903 :     decode_view(
     198                 :         pct_string_view s,
     199                 :         encoding_opts opt = {}) noexcept
     200            3903 :         : decode_view(
     201                 :             detail::to_sv(s),
     202                 :             s.decoded_size(),
     203            3903 :             opt)
     204                 :     {
     205            3903 :     }
     206                 : 
     207                 :     //--------------------------------------------
     208                 :     //
     209                 :     // Observers
     210                 :     //
     211                 :     //--------------------------------------------
     212                 : 
     213                 :     /** Return true if the string is empty
     214                 : 
     215                 :         @par Example
     216                 :         @code
     217                 :         assert( decode_view( "" ).empty() );
     218                 :         @endcode
     219                 : 
     220                 :         @par Complexity
     221                 :         Constant.
     222                 : 
     223                 :         @par Exception Safety
     224                 :         Throws nothing.
     225                 : 
     226                 :         @return `true` if the string is empty
     227                 :     */
     228                 :     bool
     229              25 :     empty() const noexcept
     230                 :     {
     231              25 :         return n_ == 0;
     232                 :     }
     233                 : 
     234                 :     /** Return the number of decoded characters
     235                 : 
     236                 :         @par Example
     237                 :         @code
     238                 :         assert( decode_view( "Program%20Files" ).size() == 13 );
     239                 :         @endcode
     240                 : 
     241                 :         @par Effects
     242                 :         @code
     243                 :         return std::distance( this->begin(), this->end() );
     244                 :         @endcode
     245                 : 
     246                 :         @par Complexity
     247                 :         Constant.
     248                 : 
     249                 :         @par Exception Safety
     250                 :         Throws nothing.
     251                 : 
     252                 :         @return The number of decoded characters
     253                 :     */
     254                 :     size_type
     255            4056 :     size() const noexcept
     256                 :     {
     257            4056 :         return dn_;
     258                 :     }
     259                 : 
     260                 :     /** Return an iterator to the beginning
     261                 : 
     262                 :         @par Example
     263                 :         @code
     264                 :         auto it = this->begin();
     265                 :         @endcode
     266                 : 
     267                 :         @par Complexity
     268                 :         Constant.
     269                 : 
     270                 :         @par Exception Safety
     271                 :         Throws nothing.
     272                 : 
     273                 :         @return An iterator to the first decoded character
     274                 :     */
     275                 :     iterator
     276                 :     begin() const noexcept;
     277                 : 
     278                 :     /** Return an iterator to the end
     279                 : 
     280                 :         @par Example
     281                 :         @code
     282                 :         auto it = this->end();
     283                 :         @endcode
     284                 : 
     285                 :         @par Complexity
     286                 :         Constant.
     287                 : 
     288                 :         @par Exception Safety
     289                 :         Throws nothing.
     290                 : 
     291                 :         @return An iterator to one past the last decoded character
     292                 :     */
     293                 :     iterator
     294                 :     end() const noexcept;
     295                 : 
     296                 :     /** Return the first character
     297                 : 
     298                 :         @par Example
     299                 :         @code
     300                 :         assert( decode_view( "Program%20Files" ).front() == 'P' );
     301                 :         @endcode
     302                 : 
     303                 :         @par Preconditions
     304                 :         @code
     305                 :         not this->empty()
     306                 :         @endcode
     307                 : 
     308                 :         @par Complexity
     309                 :         Constant.
     310                 : 
     311                 :         @par Exception Safety
     312                 :         Throws nothing.
     313                 : 
     314                 :         @return The first decoded character
     315                 :     */
     316                 :     reference
     317                 :     front() const noexcept;
     318                 : 
     319                 :     /** Return the last character
     320                 : 
     321                 :         @par Example
     322                 :         @code
     323                 :         assert( decode_view( "Program%20Files" ).back() == 's' );
     324                 :         @endcode
     325                 : 
     326                 :         @par Preconditions
     327                 :         @code
     328                 :         not this->empty()
     329                 :         @endcode
     330                 : 
     331                 :         @par Complexity
     332                 :         Constant.
     333                 : 
     334                 :         @par Exception Safety
     335                 :         Throws nothing.
     336                 : 
     337                 :         @return The last decoded character
     338                 :     */
     339                 :     reference
     340                 :     back() const noexcept;
     341                 : 
     342                 :     /** Checks if the string begins with the given prefix
     343                 : 
     344                 :         @par Example
     345                 :         @code
     346                 :         assert( decode_view( "Program%20Files" ).starts_with("Program") );
     347                 :         @endcode
     348                 : 
     349                 :         @par Complexity
     350                 :         Linear.
     351                 : 
     352                 :         @par Exception Safety
     353                 :         Throws nothing.
     354                 : 
     355                 :         @param s The string to search for
     356                 :         @return `true` if the decoded string starts with `s`
     357                 :     */
     358                 :     BOOST_URL_DECL
     359                 :     bool
     360                 :     starts_with( core::string_view s ) const noexcept;
     361                 : 
     362                 :     /** Checks if the string ends with the given prefix
     363                 : 
     364                 :         @par Example
     365                 :         @code
     366                 :         assert( decode_view( "Program%20Files" ).ends_with("Files") );
     367                 :         @endcode
     368                 : 
     369                 :         @par Complexity
     370                 :         Linear.
     371                 : 
     372                 :         @par Exception Safety
     373                 :         Throws nothing.
     374                 : 
     375                 :         @param s The string to search for
     376                 :         @return `true` if the decoded string ends with `s`
     377                 :     */
     378                 :     BOOST_URL_DECL
     379                 :     bool
     380                 :     ends_with( core::string_view s ) const noexcept;
     381                 : 
     382                 :     /** Checks if the string begins with the given prefix
     383                 : 
     384                 :         @par Example
     385                 :         @code
     386                 :         assert( decode_view( "Program%20Files" ).starts_with('P') );
     387                 :         @endcode
     388                 : 
     389                 :         @par Complexity
     390                 :         Constant.
     391                 : 
     392                 :         @par Exception Safety
     393                 :         Throws nothing.
     394                 : 
     395                 :         @param ch The character to search for
     396                 :         @return `true` if the decoded string starts with `ch`
     397                 :     */
     398                 :     BOOST_URL_DECL
     399                 :     bool
     400                 :     starts_with( char ch ) const noexcept;
     401                 : 
     402                 :     /** Checks if the string ends with the given prefix
     403                 : 
     404                 :         @par Example
     405                 :         @code
     406                 :         assert( decode_view( "Program%20Files" ).ends_with('s') );
     407                 :         @endcode
     408                 : 
     409                 :         @par Complexity
     410                 :         Constant.
     411                 : 
     412                 :         @par Exception Safety
     413                 :         Throws nothing.
     414                 : 
     415                 :         @param ch The character to search for
     416                 :         @return `true` if the decoded string ends with `ch`
     417                 :     */
     418                 :     BOOST_URL_DECL
     419                 :     bool
     420                 :     ends_with( char ch ) const noexcept;
     421                 : 
     422                 :     /** Finds the first occurrence of character in this view
     423                 : 
     424                 :         @par Complexity
     425                 :         Linear.
     426                 : 
     427                 :         @par Exception Safety
     428                 :         Throws nothing.
     429                 : 
     430                 :         @param ch The character to search for
     431                 :         @return An iterator to the first decoded occurrence of `ch` or `end()`
     432                 :     */
     433                 :     BOOST_URL_DECL
     434                 :     const_iterator
     435                 :     find( char ch ) const noexcept;
     436                 : 
     437                 :     /** Finds the first occurrence of character in this view
     438                 : 
     439                 :         @par Complexity
     440                 :         Linear.
     441                 : 
     442                 :         @par Exception Safety
     443                 :         Throws nothing.
     444                 : 
     445                 :         @param ch The character to search for
     446                 :         @return An iterator to the last occurrence of `ch` or `end()`
     447                 :     */
     448                 :     BOOST_URL_DECL
     449                 :     const_iterator
     450                 :     rfind( char ch ) const noexcept;
     451                 : 
     452                 :     /** Remove the first characters
     453                 : 
     454                 :         @par Example
     455                 :         @code
     456                 :         decode_view d( "Program%20Files" );
     457                 :         d.remove_prefix( 8 );
     458                 :         assert( d == "Files" );
     459                 :         @endcode
     460                 : 
     461                 :         @par Preconditions
     462                 :         @code
     463                 :         n <= this->size()
     464                 :         @endcode
     465                 : 
     466                 :         @par Complexity
     467                 :         Linear.
     468                 : 
     469                 :         @param n The number of characters to remove
     470                 :     */
     471                 :     BOOST_URL_DECL
     472                 :     void
     473                 :     remove_prefix( size_type n );
     474                 : 
     475                 :     /** Remove the last characters
     476                 : 
     477                 :         @par Example
     478                 :         @code
     479                 :         decode_view d( "Program%20Files" );
     480                 :         d.remove_suffix( 6 );
     481                 :         assert( d == "Program" );
     482                 :         @endcode
     483                 : 
     484                 :         @par Preconditions
     485                 :         @code
     486                 :         n <= this->size()
     487                 :         @endcode
     488                 : 
     489                 :         @par Complexity
     490                 :         Linear.
     491                 : 
     492                 :         @param n The number of characters to remove
     493                 :     */
     494                 :     BOOST_URL_DECL
     495                 :     void
     496                 :     remove_suffix( size_type n );
     497                 : 
     498                 :     /** Return the decoding options
     499                 : 
     500                 :         @return The decoding options used by this view
     501                 :      */
     502                 :     encoding_opts
     503                 :     options() const noexcept
     504                 :     {
     505                 :         encoding_opts opt;
     506                 :         opt.space_as_plus = space_as_plus_;
     507                 :         return opt;
     508                 :     }
     509                 : 
     510                 :     //--------------------------------------------
     511                 :     //
     512                 :     // Comparison
     513                 :     //
     514                 :     //--------------------------------------------
     515                 : 
     516                 :     /** Return the result of comparing to another string
     517                 : 
     518                 :         The length of the sequences to compare is the smaller of
     519                 :         `size()` and `other.size()`.
     520                 : 
     521                 :         The function compares the two strings as if by calling
     522                 :         `char_traits<char>::compare(to_string().data(), v.data(), rlen)`.
     523                 :         This means the comparison is performed with
     524                 :         percent-decoding applied to the current string.
     525                 : 
     526                 :         @param other string to compare
     527                 : 
     528                 :         @return Negative value if this string is less than the other
     529                 :         character sequence, zero if the both character sequences are
     530                 :         equal, positive value if this string is greater than the other
     531                 :         character sequence
     532                 :     */
     533                 :     BOOST_CXX14_CONSTEXPR
     534                 :     int
     535                 :     compare(core::string_view other) const noexcept;
     536                 : 
     537                 :     /** Return the result of comparing to another string
     538                 : 
     539                 :         The length of the sequences to compare is the smaller of
     540                 :         `size()` and `other.size()`.
     541                 : 
     542                 :         The function compares the two strings as if by calling
     543                 :         `char_traits<char>::compare(to_string().data(), v.to_string().data(), rlen)`.
     544                 :         This means the comparison is performed with
     545                 :         percent-decoding applied to the current string.
     546                 : 
     547                 :         @param other string to compare
     548                 : 
     549                 :         @return Negative value if this string is less than the other
     550                 :         character sequence, zero if the both character sequences are
     551                 :         equal, positive value if this string is greater than the other
     552                 :         character sequence
     553                 :     */
     554                 :     BOOST_CXX14_CONSTEXPR
     555                 :     int
     556                 :     compare(decode_view other) const noexcept;
     557                 : 
     558                 :     //--------------------------------------------
     559                 : 
     560                 :     // relational operators
     561                 : private:
     562                 :     template<class S0, class S1>
     563                 :     using is_match = std::integral_constant<bool,
     564                 :         // both decode_view or convertible to core::string_view
     565                 :         (
     566                 :             std::is_same<typename std::decay<S0>::type, decode_view>::value ||
     567                 :             std::is_convertible<S0, core::string_view>::value) &&
     568                 :         (
     569                 :             std::is_same<typename std::decay<S1>::type, decode_view>::value ||
     570                 :             std::is_convertible<S1, core::string_view>::value) &&
     571                 :         // not both are convertible to string view
     572                 :         (
     573                 :             !std::is_convertible<S0, core::string_view>::value ||
     574                 :             !std::is_convertible<S1, core::string_view>::value)>;
     575                 : 
     576                 :     BOOST_CXX14_CONSTEXPR
     577                 :     static
     578                 :     int
     579             332 :     decode_compare(decode_view s0, decode_view s1) noexcept
     580                 :     {
     581             332 :         return s0.compare(s1);
     582                 :     }
     583                 : 
     584                 :     template <class S>
     585                 :     BOOST_CXX14_CONSTEXPR
     586                 :     static
     587                 :     int
     588            2981 :     decode_compare(decode_view s0, S const& s1) noexcept
     589                 :     {
     590            2981 :         return s0.compare(s1);
     591                 :     }
     592                 : 
     593                 :     template <class S>
     594                 :     BOOST_CXX14_CONSTEXPR
     595                 :     static
     596                 :     int
     597                 :     decode_compare(S const& s0, decode_view s1) noexcept
     598                 :     {
     599                 :         return -s1.compare(s0);
     600                 :     }
     601                 : 
     602                 : public:
     603                 : #ifndef BOOST_URL_HAS_CONCEPTS
     604                 :     /** Compare two decode views for equality
     605                 : 
     606                 :         @param lhs The left-hand-side decode view to compare
     607                 :         @param rhs The right-hand-side decode view to compare
     608                 :         @return `true` if decoded `lhs` is equal to the decoded `rhs`
     609                 :      */
     610                 :     template<class S0, class S1>
     611            2528 :     BOOST_CXX14_CONSTEXPR friend auto operator==(
     612                 :         S0 const& lhs, S1 const& rhs) noexcept ->
     613                 :         typename std::enable_if<
     614                 :             is_match<S0, S1>::value, bool>::type
     615                 :     {
     616            2528 :         return decode_compare(lhs, rhs) == 0;
     617                 :     }
     618                 : #else
     619                 :     /** Compare two decode views for equality
     620                 : 
     621                 :         @param lhs The left-hand-side decode view to compare
     622                 :         @param rhs The right-hand-side decode view to compare
     623                 :         @return `true` if decoded `lhs` is equal to the decoded `rhs`
     624                 :      */
     625                 :     BOOST_CXX14_CONSTEXPR
     626                 :     friend
     627                 :     bool
     628                 :     operator==(
     629                 :         decode_view const& lhs,
     630                 :         decode_view const& rhs) noexcept
     631                 :     {
     632                 :         return decode_compare(lhs, rhs) == 0;
     633                 :     }
     634                 : 
     635                 :     /** Compare two decode views for equality
     636                 : 
     637                 :         @param lhs The left-hand-side decode view to compare
     638                 :         @param rhs The right-hand-side decode view to compare
     639                 :         @return `true` if decoded `lhs` is equal to the decoded `rhs`
     640                 :      */
     641                 :     template <std::convertible_to<core::string_view> S>
     642                 :     BOOST_CXX14_CONSTEXPR
     643                 :     friend
     644                 :     bool
     645                 :     operator==(
     646                 :         decode_view const& lhs,
     647                 :         S const& rhs) noexcept
     648                 :     {
     649                 :         return decode_compare(lhs, rhs) == 0;
     650                 :     }
     651                 : 
     652                 :     /** Compare two decode views for equality
     653                 : 
     654                 :         @param lhs The left-hand-side decode view to compare
     655                 :         @param rhs The right-hand-side decode view to compare
     656                 :         @return `true` if decoded `lhs` is equal to the decoded `rhs`
     657                 :      */
     658                 :     template <std::convertible_to<core::string_view> S>
     659                 :     BOOST_CXX14_CONSTEXPR
     660                 :     friend
     661                 :     bool
     662                 :     operator==(
     663                 :         S const& lhs,
     664                 :         decode_view const& rhs) noexcept
     665                 :     {
     666                 :         return decode_compare(lhs, rhs) == 0;
     667                 :     }
     668                 : #endif
     669                 : 
     670                 : #ifndef BOOST_URL_HAS_CONCEPTS
     671                 :     /** Compare two decode views for inequality
     672                 : 
     673                 :         @param lhs The left-hand-side decode view to compare
     674                 :         @param rhs The right-hand-side decode view to compare
     675                 :         @return `true` if decoded `lhs` is not equal to the decoded `rhs`
     676                 :      */
     677                 :     template<class S0, class S1>
     678             753 :     BOOST_CXX14_CONSTEXPR friend auto operator!=(
     679                 :         S0 const& lhs, S1 const& rhs) noexcept ->
     680                 :         typename std::enable_if<
     681                 :             is_match<S0, S1>::value, bool>::type
     682                 :     {
     683             753 :         return decode_compare(lhs, rhs) != 0;
     684                 :     }
     685                 : #else
     686                 :     /** Compare two decode views for inequality
     687                 : 
     688                 :         @param lhs The left-hand-side decode view to compare
     689                 :         @param rhs The right-hand-side decode view to compare
     690                 :         @return `true` if decoded `lhs` is not equal to the decoded `rhs`
     691                 :      */
     692                 :     BOOST_CXX14_CONSTEXPR
     693                 :     friend
     694                 :     bool
     695                 :     operator!=(
     696                 :         decode_view const& lhs,
     697                 :         decode_view const& rhs) noexcept
     698                 :     {
     699                 :         return decode_compare(lhs, rhs) != 0;
     700                 :     }
     701                 : 
     702                 :     /** Compare two decode views for inequality
     703                 : 
     704                 :         @param lhs The left-hand-side decode view to compare
     705                 :         @param rhs The right-hand-side decode view to compare
     706                 :         @return `true` if decoded `lhs` is not equal to the decoded `rhs`
     707                 :      */
     708                 :     template <std::convertible_to<core::string_view> S>
     709                 :     BOOST_CXX14_CONSTEXPR
     710                 :     friend
     711                 :     bool
     712                 :     operator!=(
     713                 :         decode_view const& lhs,
     714                 :         S const& rhs) noexcept
     715                 :     {
     716                 :         return decode_compare(lhs, rhs) != 0;
     717                 :     }
     718                 : 
     719                 :     /** Compare two decode views for inequality
     720                 : 
     721                 :         @param lhs The left-hand-side decode view to compare
     722                 :         @param rhs The right-hand-side decode view to compare
     723                 :         @return `true` if decoded `lhs` is not equal to the decoded `rhs`
     724                 :      */
     725                 :     template <std::convertible_to<core::string_view> S>
     726                 :     BOOST_CXX14_CONSTEXPR
     727                 :     friend
     728                 :     bool
     729                 :     operator!=(
     730                 :         S const& lhs,
     731                 :         decode_view const& rhs) noexcept
     732                 :     {
     733                 :         return decode_compare(lhs, rhs) != 0;
     734                 :     }
     735                 : #endif
     736                 : 
     737                 : #ifndef BOOST_URL_HAS_CONCEPTS
     738                 :     /** Compare two decode views for less than
     739                 : 
     740                 :         @param lhs The left-hand-side decode view to compare
     741                 :         @param rhs The right-hand-side decode view to compare
     742                 :         @return `true` if decoded `lhs` is less than to the decoded `rhs`
     743                 :      */
     744                 :     template<class S0, class S1>
     745               8 :     BOOST_CXX14_CONSTEXPR friend auto operator<(
     746                 :         S0 const& lhs, S1 const& rhs) noexcept ->
     747                 :         typename std::enable_if<
     748                 :             is_match<S0, S1>::value, bool>::type
     749                 :     {
     750               8 :         return decode_compare(lhs, rhs) < 0;
     751                 :     }
     752                 : #else
     753                 :     /** Compare two decode views for less than
     754                 : 
     755                 :         @param lhs The left-hand-side decode view to compare
     756                 :         @param rhs The right-hand-side decode view to compare
     757                 :         @return `true` if decoded `lhs` is less than to the decoded `rhs`
     758                 :      */
     759                 :     BOOST_CXX14_CONSTEXPR
     760                 :     friend
     761                 :     bool
     762                 :     operator<(
     763                 :         decode_view const& lhs,
     764                 :         decode_view const& rhs) noexcept
     765                 :     {
     766                 :         return decode_compare(lhs, rhs) < 0;
     767                 :     }
     768                 : 
     769                 :     /** Compare two decode views for less than
     770                 : 
     771                 :         @param lhs The left-hand-side decode view to compare
     772                 :         @param rhs The right-hand-side decode view to compare
     773                 :         @return `true` if decoded `lhs` is less than to the decoded `rhs`
     774                 :      */
     775                 :     template <std::convertible_to<core::string_view> S>
     776                 :     BOOST_CXX14_CONSTEXPR
     777                 :     friend
     778                 :     bool
     779                 :     operator<(
     780                 :         decode_view const& lhs,
     781                 :         S const& rhs) noexcept
     782                 :     {
     783                 :         return decode_compare(lhs, rhs) < 0;
     784                 :     }
     785                 : 
     786                 :     /** Compare two decode views for less than
     787                 : 
     788                 :         @param lhs The left-hand-side decode view to compare
     789                 :         @param rhs The right-hand-side decode view to compare
     790                 :         @return `true` if decoded `lhs` is less than to the decoded `rhs`
     791                 :      */
     792                 :     template <std::convertible_to<core::string_view> S>
     793                 :     BOOST_CXX14_CONSTEXPR
     794                 :     friend
     795                 :     bool
     796                 :     operator<(
     797                 :         S const& lhs,
     798                 :         decode_view const& rhs) noexcept
     799                 :     {
     800                 :         return decode_compare(lhs, rhs) < 0;
     801                 :     }
     802                 : #endif
     803                 : 
     804                 : #ifndef BOOST_URL_HAS_CONCEPTS
     805                 :     /** Compare two decode views for less than or equal
     806                 : 
     807                 :         @param lhs The left-hand-side decode view to compare
     808                 :         @param rhs The right-hand-side decode view to compare
     809                 :         @return `true` if decoded `lhs` is less than or equal to the decoded `rhs`
     810                 :      */
     811                 :     template<class S0, class S1>
     812               8 :     BOOST_CXX14_CONSTEXPR friend auto operator<=(
     813                 :         S0 const& lhs, S1 const& rhs) noexcept ->
     814                 :         typename std::enable_if<
     815                 :             is_match<S0, S1>::value, bool>::type
     816                 :     {
     817               8 :         return decode_compare(lhs, rhs) <= 0;
     818                 :     }
     819                 : #else
     820                 :     /** Compare two decode views for less than or equal
     821                 : 
     822                 :         @param lhs The left-hand-side decode view to compare
     823                 :         @param rhs The right-hand-side decode view to compare
     824                 :         @return `true` if decoded `lhs` is less than or equal to the decoded `rhs`
     825                 :      */
     826                 :     BOOST_CXX14_CONSTEXPR
     827                 :     friend
     828                 :     bool
     829                 :     operator<=(
     830                 :         decode_view const& lhs,
     831                 :         decode_view const& rhs) noexcept
     832                 :     {
     833                 :         return decode_compare(lhs, rhs) <= 0;
     834                 :     }
     835                 : 
     836                 :     /** Compare two decode views for less than or equal
     837                 : 
     838                 :         @param lhs The left-hand-side decode view to compare
     839                 :         @param rhs The right-hand-side decode view to compare
     840                 :         @return `true` if decoded `lhs` is less than or equal to the decoded `rhs`
     841                 :      */
     842                 :     template <std::convertible_to<core::string_view> S>
     843                 :     BOOST_CXX14_CONSTEXPR
     844                 :     friend
     845                 :     bool
     846                 :     operator<=(
     847                 :         decode_view const& lhs,
     848                 :         S const& rhs) noexcept
     849                 :     {
     850                 :         return decode_compare(lhs, rhs) <= 0;
     851                 :     }
     852                 : 
     853                 :     /** Compare two decode views for less than or equal
     854                 : 
     855                 :         @param lhs The left-hand-side decode view to compare
     856                 :         @param rhs The right-hand-side decode view to compare
     857                 :         @return `true` if decoded `lhs` is less than or equal to the decoded `rhs`
     858                 :      */
     859                 :     template <std::convertible_to<core::string_view> S>
     860                 :     BOOST_CXX14_CONSTEXPR
     861                 :     friend
     862                 :     bool
     863                 :     operator<=(
     864                 :         S const& lhs,
     865                 :         decode_view const& rhs) noexcept
     866                 :     {
     867                 :         return decode_compare(lhs, rhs) <= 0;
     868                 :     }
     869                 : #endif
     870                 : 
     871                 : #ifndef BOOST_URL_HAS_CONCEPTS
     872                 :     /** Compare two decode views for greater than
     873                 : 
     874                 :         @param lhs The left-hand-side decode view to compare
     875                 :         @param rhs The right-hand-side decode view to compare
     876                 :         @return `true` if decoded `lhs` is greater than to the decoded `rhs`
     877                 :      */
     878                 :     template<class S0, class S1>
     879               8 :     BOOST_CXX14_CONSTEXPR friend auto operator>(
     880                 :         S0 const& lhs, S1 const& rhs) noexcept ->
     881                 :         typename std::enable_if<
     882                 :             is_match<S0, S1>::value, bool>::type
     883                 :     {
     884               8 :         return decode_compare(lhs, rhs) > 0;
     885                 :     }
     886                 : #else
     887                 :     /** Compare two decode views for greater than
     888                 : 
     889                 :         @param lhs The left-hand-side decode view to compare
     890                 :         @param rhs The right-hand-side decode view to compare
     891                 :         @return `true` if decoded `lhs` is greater than to the decoded `rhs`
     892                 :      */
     893                 :     BOOST_CXX14_CONSTEXPR
     894                 :     friend
     895                 :     bool
     896                 :     operator>(
     897                 :         decode_view const& lhs,
     898                 :         decode_view const& rhs) noexcept
     899                 :     {
     900                 :         return decode_compare(lhs, rhs) > 0;
     901                 :     }
     902                 : 
     903                 :     /** Compare two decode views for greater than
     904                 : 
     905                 :         @param lhs The left-hand-side decode view to compare
     906                 :         @param rhs The right-hand-side decode view to compare
     907                 :         @return `true` if decoded `lhs` is greater than to the decoded `rhs`
     908                 :      */
     909                 :     template <std::convertible_to<core::string_view> S>
     910                 :     BOOST_CXX14_CONSTEXPR
     911                 :     friend
     912                 :     bool
     913                 :     operator>(
     914                 :         decode_view const& lhs,
     915                 :         S const& rhs) noexcept
     916                 :     {
     917                 :         return decode_compare(lhs, rhs) > 0;
     918                 :     }
     919                 : 
     920                 :     /** Compare two decode views for greater than
     921                 : 
     922                 :         @param lhs The left-hand-side decode view to compare
     923                 :         @param rhs The right-hand-side decode view to compare
     924                 :         @return `true` if decoded `lhs` is greater than to the decoded `rhs`
     925                 :      */
     926                 :     template <std::convertible_to<core::string_view> S>
     927                 :     BOOST_CXX14_CONSTEXPR
     928                 :     friend
     929                 :     bool
     930                 :     operator>(
     931                 :         S const& lhs,
     932                 :         decode_view const& rhs) noexcept
     933                 :     {
     934                 :         return decode_compare(lhs, rhs) > 0;
     935                 :     }
     936                 : #endif
     937                 : 
     938                 : #ifndef BOOST_URL_HAS_CONCEPTS
     939                 :     /** Compare two decode views for greater than or equal
     940                 : 
     941                 :         @param lhs The left-hand-side decode view to compare
     942                 :         @param rhs The right-hand-side decode view to compare
     943                 :         @return `true` if decoded `lhs` is greater than or equal to the decoded `rhs`
     944                 :      */
     945                 :     template<class S0, class S1>
     946               8 :     BOOST_CXX14_CONSTEXPR friend auto operator>=(
     947                 :         S0 const& lhs, S1 const& rhs) noexcept ->
     948                 :         typename std::enable_if<
     949                 :             is_match<S0, S1>::value, bool>::type
     950                 :     {
     951               8 :         return decode_compare(lhs, rhs) >= 0;
     952                 :     }
     953                 : #else
     954                 :     /** Compare two decode views for greater than or equal
     955                 : 
     956                 :         @param lhs The left-hand-side decode view to compare
     957                 :         @param rhs The right-hand-side decode view to compare
     958                 :         @return `true` if decoded `lhs` is greater than or equal to the decoded `rhs`
     959                 :      */
     960                 :     BOOST_CXX14_CONSTEXPR
     961                 :     friend
     962                 :     bool
     963                 :     operator>=(
     964                 :         decode_view const& lhs,
     965                 :         decode_view const& rhs) noexcept
     966                 :     {
     967                 :         return decode_compare(lhs, rhs) >= 0;
     968                 :     }
     969                 : 
     970                 :     /** Compare two decode views for greater than or equal
     971                 : 
     972                 :         @param lhs The left-hand-side decode view to compare
     973                 :         @param rhs The right-hand-side decode view to compare
     974                 :         @return `true` if decoded `lhs` is greater than or equal to the decoded `rhs`
     975                 :      */
     976                 :     template <std::convertible_to<core::string_view> S>
     977                 :     BOOST_CXX14_CONSTEXPR
     978                 :     friend
     979                 :     bool
     980                 :     operator>=(
     981                 :         decode_view const& lhs,
     982                 :         S const& rhs) noexcept
     983                 :     {
     984                 :         return decode_compare(lhs, rhs) >= 0;
     985                 :     }
     986                 : 
     987                 :     /** Compare two decode views for greater than or equal
     988                 : 
     989                 :         @param lhs The left-hand-side decode view to compare
     990                 :         @param rhs The right-hand-side decode view to compare
     991                 :         @return `true` if decoded `lhs` is greater than or equal to the decoded `rhs`
     992                 :      */
     993                 :     template <std::convertible_to<core::string_view> S>
     994                 :     BOOST_CXX14_CONSTEXPR
     995                 :     friend
     996                 :     bool
     997                 :     operator>=(
     998                 :         S const& lhs,
     999                 :         decode_view const& rhs) noexcept
    1000                 :     {
    1001                 :         return decode_compare(lhs, rhs) >= 0;
    1002                 :     }
    1003                 : #endif
    1004                 : 
    1005                 :     /** Format the string with percent-decoding applied to the output stream
    1006                 : 
    1007                 :         This hidden friend function serializes the decoded view
    1008                 :         to the output stream.
    1009                 : 
    1010                 :         @return A reference to the output stream, for chaining
    1011                 : 
    1012                 :         @param os The output stream to write to
    1013                 : 
    1014                 :         @param s The decoded view to write
    1015                 :     */
    1016                 :     friend
    1017                 :     std::ostream&
    1018              21 :     operator<<(
    1019                 :         std::ostream& os,
    1020                 :         decode_view const& s)
    1021                 :     {
    1022                 :         // hidden friend
    1023              21 :         s.write(os);
    1024              21 :         return os;
    1025                 :     }
    1026                 : 
    1027                 : private:
    1028                 :     BOOST_URL_DECL
    1029                 :     void
    1030                 :     write(std::ostream& os) const;
    1031                 : };
    1032                 : 
    1033                 : /** Format the string with percent-decoding applied to the output stream
    1034                 : 
    1035                 :     This function serializes the decoded view
    1036                 :     to the output stream.
    1037                 : 
    1038                 :     @return A reference to the output stream, for chaining
    1039                 : 
    1040                 :     @param os The output stream to write to
    1041                 : 
    1042                 :     @param s The decoded view to write
    1043                 : */
    1044                 : inline
    1045                 : std::ostream&
    1046                 : operator<<(
    1047                 :     std::ostream& os,
    1048                 :     decode_view const& s);
    1049                 : 
    1050                 : //------------------------------------------------
    1051                 : 
    1052                 : inline
    1053                 : decode_view
    1054            3798 : pct_string_view::operator*() const noexcept
    1055                 : {
    1056            3798 :     return decode_view(*this);
    1057                 : }
    1058                 : 
    1059                 : namespace detail {
    1060                 : template<class... Args>
    1061                 : decode_view
    1062                 : make_decode_view(
    1063                 :     Args&&... args) noexcept
    1064                 : {
    1065                 :     return decode_view(
    1066                 :         std::forward<Args>(args)...);
    1067                 : }
    1068                 : } // detail
    1069                 : 
    1070                 : //------------------------------------------------
    1071                 : 
    1072                 : } // urls
    1073                 : } // boost
    1074                 : 
    1075                 : #include <boost/url/impl/decode_view.hpp>
    1076                 : 
    1077                 : //------------------------------------------------
    1078                 : //
    1079                 : // std::ranges::enable_borrowed_range
    1080                 : //
    1081                 : //------------------------------------------------
    1082                 : 
    1083                 : #ifdef BOOST_URL_HAS_CONCEPTS
    1084                 : #include <ranges>
    1085                 : namespace std::ranges {
    1086                 :     template<>
    1087                 :     inline constexpr bool
    1088                 :         enable_borrowed_range<
    1089                 :             boost::urls::decode_view> = true;
    1090                 : } // std::ranges
    1091                 : #endif
    1092                 : 
    1093                 : #endif
        

Generated by: LCOV version 2.3