LCOV - code coverage report
Current view: top level - boost/url/grammar/ci_string.hpp (source / functions) Coverage Total Hit
Test: coverage_filtered.info Lines: 95.7 % 23 22
Test Date: 2025-11-10 19:06:20 Functions: 90.9 % 11 10

            Line data    Source code
       1              : //
       2              : // Copyright (c) 2016-2019 Vinnie Falco (vinnie dot falco at gmail dot com)
       3              : // Copyright (c) 2022 Alan de Freitas (alandefreitas@gmail.com)
       4              : //
       5              : // Distributed under the Boost Software License, Version 1.0. (See accompanying
       6              : // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
       7              : //
       8              : // Official repository: https://github.com/boostorg/url
       9              : //
      10              : 
      11              : #ifndef BOOST_URL_GRAMMAR_CI_STRING_HPP
      12              : #define BOOST_URL_GRAMMAR_CI_STRING_HPP
      13              : 
      14              : #include <boost/url/detail/config.hpp>
      15              : #include <boost/core/detail/string_view.hpp>
      16              : #include <boost/url/grammar/detail/ci_string.hpp>
      17              : #include <cstdlib>
      18              : 
      19              : namespace boost {
      20              : namespace urls {
      21              : namespace grammar {
      22              : 
      23              : // Algorithms for interacting with low-ASCII
      24              : // characters and strings, for implementing
      25              : // semantics in RFCs. These routines do not
      26              : // use std::locale.
      27              : 
      28              : //------------------------------------------------
      29              : 
      30              : /** Return c converted to lowercase
      31              : 
      32              :     This function returns the character,
      33              :     converting it to lowercase if it is
      34              :     uppercase.
      35              :     The function is defined only for
      36              :     low-ASCII characters.
      37              : 
      38              :     @par Example
      39              :     @code
      40              :     assert( to_lower( 'A' ) == 'a' );
      41              :     @endcode
      42              : 
      43              :     @par Exception Safety
      44              :     Throws nothing.
      45              : 
      46              :     @return The converted character
      47              : 
      48              :     @param c The character to convert
      49              : 
      50              :     @see
      51              :         @ref to_upper.
      52              : */
      53              : constexpr
      54              : char
      55        23172 : to_lower(char c) noexcept
      56              : {
      57        23172 :     return detail::to_lower(c);
      58              : }
      59              : 
      60              : /** Return c converted to uppercase
      61              : 
      62              :     This function returns the character,
      63              :     converting it to uppercase if it is
      64              :     lowercase.
      65              :     The function is defined only for
      66              :     low-ASCII characters.
      67              : 
      68              :     @par Example
      69              :     @code
      70              :     assert( to_upper( 'a' ) == 'A' );
      71              :     @endcode
      72              : 
      73              :     @par Exception Safety
      74              :     Throws nothing.
      75              : 
      76              :     @return The converted character
      77              : 
      78              :     @param c The character to convert
      79              : 
      80              :     @see
      81              :         @ref to_lower.
      82              : */
      83              : constexpr
      84              : char
      85          209 : to_upper(char c) noexcept
      86              : {
      87          209 :     return detail::to_upper(c);
      88              : }
      89              : 
      90              : //------------------------------------------------
      91              : 
      92              : /** Return the case-insensitive comparison of s0 and s1
      93              : 
      94              :     This returns the lexicographical comparison
      95              :     of two strings, ignoring case.
      96              :     The function is defined only for strings
      97              :     containing low-ASCII characters.
      98              : 
      99              :     @par Example
     100              :     @code
     101              :     assert( ci_compare( "boost", "Boost" ) == 0 );
     102              :     @endcode
     103              : 
     104              :     @par Exception Safety
     105              :     Throws nothing.
     106              : 
     107              :     @return 0 if the strings are equal, -1 if
     108              :     `s0` is less than `s1`, or 1 if `s0` is
     109              :     greater than s1.
     110              : 
     111              :     @param s0 The first string
     112              : 
     113              :     @param s1 The second string
     114              : 
     115              :     @see
     116              :         @ref ci_is_equal,
     117              :         @ref ci_is_less.
     118              : */
     119              : BOOST_URL_DECL
     120              : int
     121              : ci_compare(
     122              :     core::string_view s0,
     123              :     core::string_view s1) noexcept;
     124              : 
     125              : /** Return the case-insensitive digest of a string
     126              : 
     127              :     The hash function is non-cryptographic and
     128              :     not hardened against algorithmic complexity
     129              :     attacks.
     130              :     Returned digests are suitable for usage in
     131              :     unordered containers.
     132              :     The function is defined only for strings
     133              :     containing low-ASCII characters.
     134              : 
     135              :     @return The digest
     136              : 
     137              :     @param s The string
     138              : */
     139              : BOOST_URL_DECL
     140              : std::size_t
     141              : ci_digest(
     142              :     core::string_view s) noexcept;
     143              : 
     144              : //------------------------------------------------
     145              : 
     146              : /** Return true if s0 equals s1 using case-insensitive comparison
     147              : 
     148              :     The function is defined only for strings
     149              :     containing low-ASCII characters.
     150              : 
     151              :     @param s0 The first string
     152              :     @param s1 The second string
     153              :     @return `true` if `s0` case-insensitively equals `s1`, otherwise `false`
     154              : 
     155              :     @par Example
     156              :     @code
     157              :     assert( ci_is_equal( "Boost", "boost" ) );
     158              :     @endcode
     159              : 
     160              :     @see
     161              :         @ref ci_compare,
     162              :         @ref ci_is_less.
     163              : */
     164              : template<
     165              :     class String0,
     166              :     class String1>
     167              : auto
     168          252 : ci_is_equal(
     169              :     String0 const& s0,
     170              :     String1 const& s1) ->
     171              :         typename std::enable_if<
     172              :             ! std::is_convertible<
     173              :                 String0, core::string_view>::value ||
     174              :             ! std::is_convertible<
     175              :                 String1, core::string_view>::value,
     176              :         bool>::type
     177              : {
     178              :     // this overload supports forward iterators and
     179              :     // does not assume the existence core::string_view::size
     180          504 :     if( detail::type_id<String0>() >
     181          252 :         detail::type_id<String1>())
     182            0 :         return detail::ci_is_equal(s1, s0);
     183          252 :     return detail::ci_is_equal(s0, s1);
     184              : }
     185              : 
     186              : /** Return true if s0 equals s1 using case-insensitive comparison
     187              : 
     188              :     The function is defined only for strings
     189              :     containing low-ASCII characters.
     190              : 
     191              :     @param s0 The first string
     192              :     @param s1 The second string
     193              :     @return `true` if `s0` case-insensitively equals `s1`, otherwise `false`
     194              : 
     195              :     @par Example
     196              :     @code
     197              :     assert( ci_is_equal( "Boost", "boost" ) );
     198              :     @endcode
     199              : 
     200              :     @see
     201              :         @ref ci_compare,
     202              :         @ref ci_is_less.
     203              : */
     204              : inline
     205              : bool
     206           10 : ci_is_equal(
     207              :     core::string_view s0,
     208              :     core::string_view s1) noexcept
     209              : {
     210              :     // this overload is faster as it makes use of
     211              :     // core::string_view::size
     212           10 :     if(s0.size() != s1.size())
     213            3 :         return false;
     214            7 :     return detail::ci_is_equal(s0, s1);
     215              : }
     216              : 
     217              : /** Return true if s0 is less than s1 using case-insensitive comparison 
     218              : 
     219              :     The comparison algorithm implements a
     220              :     case-insensitive total order on the set
     221              :     of all strings; however, it is not a
     222              :     lexicographical comparison.
     223              :     The function is defined only for strings
     224              :     containing low-ASCII characters.
     225              : 
     226              :     @param s0 The first string
     227              :     @param s1 The second string
     228              :     @return `true` if `s0` is case-insensitively less than `s1`, otherwise `false`
     229              : 
     230              :     @par Example
     231              :     @code
     232              :     assert( ! ci_is_less( "Boost", "boost" ) );
     233              :     @endcode
     234              : 
     235              :     @see
     236              :         @ref ci_compare,
     237              :         @ref ci_is_equal.
     238              : */
     239              : inline
     240              : bool
     241            9 : ci_is_less(
     242              :     core::string_view s0,
     243              :     core::string_view s1) noexcept
     244              : {
     245            9 :     if(s0.size() != s1.size())
     246            4 :         return s0.size() < s1.size();
     247            5 :     return detail::ci_is_less(s0, s1);
     248              : }
     249              : 
     250              : //------------------------------------------------
     251              : 
     252              : namespace implementation_defined {
     253              : struct ci_hash
     254              : {
     255              :     using is_transparent = void;
     256              : 
     257              :     std::size_t
     258            6 :     operator()(
     259              :         core::string_view s) const noexcept
     260              :     {
     261            6 :         return ci_digest(s);
     262              :     }
     263              : };
     264              : }
     265              : 
     266              : /** A case-insensitive hash function object for strings
     267              : 
     268              :     The hash function is non-cryptographic and
     269              :     not hardened against algorithmic complexity
     270              :     attacks.
     271              :     This is a suitable hash function for
     272              :     unordered containers.
     273              :     The function is defined only for strings
     274              :     containing low-ASCII characters.
     275              : 
     276              :     @par Example
     277              :     @code
     278              :     boost::unordered_map< std::string, std::string, ci_hash, ci_equal > m1;
     279              : 
     280              :     std::unordered_map  < std::string, std::string, ci_hash, ci_equal > m2; // (since C++20)
     281              :     @endcode
     282              : 
     283              :     @see
     284              :         @ref ci_equal,
     285              :         @ref ci_less.
     286              : */
     287              : using ci_hash = implementation_defined::ci_hash;
     288              : 
     289              : namespace implementation_defined {
     290              : struct ci_equal
     291              : {
     292              :     using is_transparent = void;
     293              : 
     294              :     template<
     295              :         class String0, class String1>
     296              :     bool
     297            3 :     operator()(
     298              :         String0 s0,
     299              :         String1 s1) const noexcept
     300              :     {
     301            3 :         return ci_is_equal(s0, s1);
     302              :     }
     303              : };
     304              : } // implementation_defined
     305              : 
     306              : /** A case-insensitive equals predicate for strings
     307              : 
     308              :     The function object returns `true` when
     309              :     two strings are equal, ignoring case.
     310              :     This is a suitable equality predicate for
     311              :     unordered containers.
     312              :     The function is defined only for strings
     313              :     containing low-ASCII characters.
     314              : 
     315              :     @par Example
     316              :     @code
     317              :     boost::unordered_map< std::string, std::string, ci_hash, ci_equal > m1;
     318              : 
     319              :     std::unordered_map  < std::string, std::string, ci_hash, ci_equal > m2; // (since C++20)
     320              :     @endcode
     321              : 
     322              :     @see
     323              :         @ref ci_hash,
     324              :         @ref ci_less.
     325              : */
     326              : using ci_equal = implementation_defined::ci_equal;
     327              : 
     328              : namespace implementation_defined {
     329              : struct ci_less
     330              : {
     331              :     using is_transparent = void;
     332              : 
     333              :     std::size_t
     334            4 :     operator()(
     335              :         core::string_view s0,
     336              :         core::string_view s1) const noexcept
     337              :     {
     338            4 :         return ci_is_less(s0, s1);
     339              :     }
     340              : };
     341              : }
     342              : 
     343              : /** A case-insensitive less predicate for strings
     344              : 
     345              :     The comparison algorithm implements a
     346              :     case-insensitive total order on the set
     347              :     of all ASCII strings; however, it is
     348              :     not a lexicographical comparison.
     349              :     This is a suitable predicate for
     350              :     ordered containers.
     351              :     The function is defined only for strings
     352              :     containing low-ASCII characters.
     353              : 
     354              :     @par Example
     355              :     @code
     356              :     boost::container::map< std::string, std::string, ci_less > m1;
     357              : 
     358              :     std::map< std::string, std::string, ci_less > m2; // (since C++14)
     359              :     @endcode
     360              : 
     361              :     @see
     362              :         @ref ci_equal,
     363              :         @ref ci_hash.
     364              : */
     365              : using ci_less = implementation_defined::ci_less;
     366              : 
     367              : } // grammar
     368              : } // urls
     369              : } // boost
     370              : 
     371              : #endif
        

Generated by: LCOV version 2.1