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-01-10 18:07:09 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        22879 : to_lower(char c) noexcept
      56              : {
      57        22879 :     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          189 : to_upper(char c) noexcept
      86              : {
      87          189 :     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              :     @par Example
     152              :     @code
     153              :     assert( ci_is_equal( "Boost", "boost" ) );
     154              :     @endcode
     155              : 
     156              :     @see
     157              :         @ref ci_compare,
     158              :         @ref ci_is_less.
     159              : */
     160              : template<
     161              :     class String0,
     162              :     class String1>
     163              : auto
     164          252 : ci_is_equal(
     165              :     String0 const& s0,
     166              :     String1 const& s1) ->
     167              :         typename std::enable_if<
     168              :             ! std::is_convertible<
     169              :                 String0, core::string_view>::value ||
     170              :             ! std::is_convertible<
     171              :                 String1, core::string_view>::value,
     172              :         bool>::type
     173              : {
     174              :     // this overload supports forward iterators and
     175              :     // does not assume the existence core::string_view::size
     176          504 :     if( detail::type_id<String0>() >
     177          252 :         detail::type_id<String1>())
     178            0 :         return detail::ci_is_equal(s1, s0);
     179          252 :     return detail::ci_is_equal(s0, s1);
     180              : }
     181              : 
     182              : /** Return true if s0 equals s1 using case-insensitive comparison
     183              : 
     184              :     The function is defined only for strings
     185              :     containing low-ASCII characters.
     186              : 
     187              :     @par Example
     188              :     @code
     189              :     assert( ci_is_equal( "Boost", "boost" ) );
     190              :     @endcode
     191              : 
     192              :     @see
     193              :         @ref ci_compare,
     194              :         @ref ci_is_less.
     195              : */
     196              : inline
     197              : bool
     198           10 : ci_is_equal(
     199              :     core::string_view s0,
     200              :     core::string_view s1) noexcept
     201              : {
     202              :     // this overload is faster as it makes use of
     203              :     // core::string_view::size
     204           10 :     if(s0.size() != s1.size())
     205            3 :         return false;
     206            7 :     return detail::ci_is_equal(s0, s1);
     207              : }
     208              : 
     209              : /** Return true if s0 is less than s1 using case-insensitive comparison 
     210              : 
     211              :     The comparison algorithm implements a
     212              :     case-insensitive total order on the set
     213              :     of all strings; however, it is not a
     214              :     lexicographical comparison.
     215              :     The function is defined only for strings
     216              :     containing low-ASCII characters.
     217              : 
     218              :     @par Example
     219              :     @code
     220              :     assert( ! ci_is_less( "Boost", "boost" ) );
     221              :     @endcode
     222              : 
     223              :     @see
     224              :         @ref ci_compare,
     225              :         @ref ci_is_equal.
     226              : */
     227              : inline
     228              : bool
     229            9 : ci_is_less(
     230              :     core::string_view s0,
     231              :     core::string_view s1) noexcept
     232              : {
     233            9 :     if(s0.size() != s1.size())
     234            4 :         return s0.size() < s1.size();
     235            5 :     return detail::ci_is_less(s0, s1);
     236              : }
     237              : 
     238              : //------------------------------------------------
     239              : 
     240              : namespace implementation_defined {
     241              : struct ci_hash
     242              : {
     243              :     using is_transparent = void;
     244              : 
     245              :     std::size_t
     246            6 :     operator()(
     247              :         core::string_view s) const noexcept
     248              :     {
     249            6 :         return ci_digest(s);
     250              :     }
     251              : };
     252              : }
     253              : 
     254              : /** A case-insensitive hash function object for strings
     255              : 
     256              :     The hash function is non-cryptographic and
     257              :     not hardened against algorithmic complexity
     258              :     attacks.
     259              :     This is a suitable hash function for
     260              :     unordered containers.
     261              :     The function is defined only for strings
     262              :     containing low-ASCII characters.
     263              : 
     264              :     @par Example
     265              :     @code
     266              :     boost::unordered_map< std::string, std::string, ci_hash, ci_equal > m1;
     267              : 
     268              :     std::unordered_map  < std::string, std::string, ci_hash, ci_equal > m2; // (since C++20)
     269              :     @endcode
     270              : 
     271              :     @see
     272              :         @ref ci_equal,
     273              :         @ref ci_less.
     274              : */
     275              : using ci_hash = implementation_defined::ci_hash;
     276              : 
     277              : namespace implementation_defined {
     278              : struct ci_equal
     279              : {
     280              :     using is_transparent = void;
     281              : 
     282              :     template<
     283              :         class String0, class String1>
     284              :     bool
     285            3 :     operator()(
     286              :         String0 s0,
     287              :         String1 s1) const noexcept
     288              :     {
     289            3 :         return ci_is_equal(s0, s1);
     290              :     }
     291              : };
     292              : } // implementation_defined
     293              : 
     294              : /** A case-insensitive equals predicate for strings
     295              : 
     296              :     The function object returns `true` when
     297              :     two strings are equal, ignoring case.
     298              :     This is a suitable equality predicate for
     299              :     unordered containers.
     300              :     The function is defined only for strings
     301              :     containing low-ASCII characters.
     302              : 
     303              :     @par Example
     304              :     @code
     305              :     boost::unordered_map< std::string, std::string, ci_hash, ci_equal > m1;
     306              : 
     307              :     std::unordered_map  < std::string, std::string, ci_hash, ci_equal > m2; // (since C++20)
     308              :     @endcode
     309              : 
     310              :     @see
     311              :         @ref ci_hash,
     312              :         @ref ci_less.
     313              : */
     314              : using ci_equal = implementation_defined::ci_equal;
     315              : 
     316              : namespace implementation_defined {
     317              : struct ci_less
     318              : {
     319              :     using is_transparent = void;
     320              : 
     321              :     std::size_t
     322            4 :     operator()(
     323              :         core::string_view s0,
     324              :         core::string_view s1) const noexcept
     325              :     {
     326            4 :         return ci_is_less(s0, s1);
     327              :     }
     328              : };
     329              : }
     330              : 
     331              : /** A case-insensitive less predicate for strings
     332              : 
     333              :     The comparison algorithm implements a
     334              :     case-insensitive total order on the set
     335              :     of all ASCII strings; however, it is
     336              :     not a lexicographical comparison.
     337              :     This is a suitable predicate for
     338              :     ordered containers.
     339              :     The function is defined only for strings
     340              :     containing low-ASCII characters.
     341              : 
     342              :     @par Example
     343              :     @code
     344              :     boost::container::map< std::string, std::string, ci_less > m1;
     345              : 
     346              :     std::map< std::string, std::string, ci_less > m2; // (since C++14)
     347              :     @endcode
     348              : 
     349              :     @see
     350              :         @ref ci_equal,
     351              :         @ref ci_hash.
     352              : */
     353              : using ci_less = implementation_defined::ci_less;
     354              : 
     355              : } // grammar
     356              : } // urls
     357              : } // boost
     358              : 
     359              : #endif
        

Generated by: LCOV version 2.1