LCOV - code coverage report
Current view: top level - boost/url/decode_view.hpp (source / functions) Coverage Total Hit
Test: coverage_filtered.info Lines: 100.0 % 36 36
Test Date: 2025-04-22 15:26:24 Functions: 100.0 % 47 47

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

Generated by: LCOV version 2.1