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: 2024-08-19 20:08:54 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        22869 : to_lower(char c) noexcept
      56              : {
      57        22869 :     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              : #ifdef BOOST_URL_DOCS
     161              : template<
     162              :     class String0,
     163              :     class String1>
     164              : bool
     165              : ci_is_equal(
     166              :     String0 const& s0,
     167              :     String1 const& s1);
     168              : #else
     169              : 
     170              : /** Return true if s0 equals s1 using case-insensitive comparison
     171              : 
     172              :     The function is defined only for strings
     173              :     containing low-ASCII characters.
     174              : 
     175              :     @par Example
     176              :     @code
     177              :     assert( ci_is_equal( "Boost", "boost" ) );
     178              :     @endcode
     179              : 
     180              :     @see
     181              :         @ref ci_compare,
     182              :         @ref ci_is_less.
     183              : */
     184              : template<
     185              :     class String0,
     186              :     class String1>
     187              : auto
     188          252 : ci_is_equal(
     189              :     String0 const& s0,
     190              :     String1 const& s1) ->
     191              :         typename std::enable_if<
     192              :             ! std::is_convertible<
     193              :                 String0, core::string_view>::value ||
     194              :             ! std::is_convertible<
     195              :                 String1, core::string_view>::value,
     196              :         bool>::type
     197              : {
     198              :     // this overload supports forward iterators and
     199              :     // does not assume the existence core::string_view::size
     200          504 :     if( detail::type_id<String0>() >
     201          252 :         detail::type_id<String1>())
     202            0 :         return detail::ci_is_equal(s1, s0);
     203          252 :     return detail::ci_is_equal(s0, s1);
     204              : }
     205              : 
     206              : /** Return true if s0 equals s1 using case-insensitive comparison
     207              : 
     208              :     The function is defined only for strings
     209              :     containing low-ASCII characters.
     210              : 
     211              :     @par Example
     212              :     @code
     213              :     assert( ci_is_equal( "Boost", "boost" ) );
     214              :     @endcode
     215              : 
     216              :     @see
     217              :         @ref ci_compare,
     218              :         @ref ci_is_less.
     219              : */
     220              : inline
     221              : bool
     222           10 : ci_is_equal(
     223              :     core::string_view s0,
     224              :     core::string_view s1) noexcept
     225              : {
     226              :     // this overload is faster as it makes use of
     227              :     // core::string_view::size
     228           10 :     if(s0.size() != s1.size())
     229            3 :         return false;
     230            7 :     return detail::ci_is_equal(s0, s1);
     231              : }
     232              : #endif
     233              : 
     234              : /** Return true if s0 is less than s1 using case-insensitive comparison 
     235              : 
     236              :     The comparison algorithm implements a
     237              :     case-insensitive total order on the set
     238              :     of all strings; however, it is not a
     239              :     lexicographical comparison.
     240              :     The function is defined only for strings
     241              :     containing low-ASCII characters.
     242              : 
     243              :     @par Example
     244              :     @code
     245              :     assert( ! ci_is_less( "Boost", "boost" ) );
     246              :     @endcode
     247              : 
     248              :     @see
     249              :         @ref ci_compare,
     250              :         @ref ci_is_equal.
     251              : */
     252              : inline
     253              : bool
     254            9 : ci_is_less(
     255              :     core::string_view s0,
     256              :     core::string_view s1) noexcept
     257              : {
     258            9 :     if(s0.size() != s1.size())
     259            4 :         return s0.size() < s1.size();
     260            5 :     return detail::ci_is_less(s0, s1);
     261              : }
     262              : 
     263              : //------------------------------------------------
     264              : 
     265              : /** A case-insensitive hash function object for strings
     266              : 
     267              :     The hash function is non-cryptographic and
     268              :     not hardened against algorithmic complexity
     269              :     attacks.
     270              :     This is a suitable hash function for
     271              :     unordered containers.
     272              :     The function is defined only for strings
     273              :     containing low-ASCII characters.
     274              : 
     275              :     @par Example
     276              :     @code
     277              :     boost::unordered_map< std::string, std::string, ci_hash, ci_equal > m1;
     278              : 
     279              :     std::unordered_map  < std::string, std::string, ci_hash, ci_equal > m2; // (since C++20)
     280              :     @endcode
     281              : 
     282              :     @see
     283              :         @ref ci_equal,
     284              :         @ref ci_less.
     285              : */
     286              : #ifdef BOOST_URL_DOCS
     287              : using ci_hash = __see_below__;
     288              : #else
     289              : namespace see_below {
     290              : struct ci_hash
     291              : {
     292              :     using is_transparent = void;
     293              : 
     294              :     std::size_t
     295            6 :     operator()(
     296              :         core::string_view s) const noexcept
     297              :     {
     298            6 :         return ci_digest(s);
     299              :     }
     300              : };
     301              : }
     302              : 
     303              : /** A case-insensitive hash function object for strings
     304              : 
     305              :     The hash function is non-cryptographic and
     306              :     not hardened against algorithmic complexity
     307              :     attacks.
     308              :     This is a suitable hash function for
     309              :     unordered containers.
     310              :     The function is defined only for strings
     311              :     containing low-ASCII characters.
     312              : 
     313              :     @par Example
     314              :     @code
     315              :     boost::unordered_map< std::string, std::string, ci_hash, ci_equal > m1;
     316              : 
     317              :     std::unordered_map  < std::string, std::string, ci_hash, ci_equal > m2; // (since C++20)
     318              :     @endcode
     319              : 
     320              :     @see
     321              :         @ref ci_equal,
     322              :         @ref ci_less.
     323              : */
     324              : using ci_hash = see_below::ci_hash;
     325              : #endif
     326              : 
     327              : /** A case-insensitive equals predicate for strings
     328              : 
     329              :     The function object returns `true` when
     330              :     two strings are equal, ignoring case.
     331              :     This is a suitable equality predicate for
     332              :     unordered containers.
     333              :     The function is defined only for strings
     334              :     containing low-ASCII characters.
     335              : 
     336              :     @par Example
     337              :     @code
     338              :     boost::unordered_map< std::string, std::string, ci_hash, ci_equal > m1;
     339              : 
     340              :     std::unordered_map  < std::string, std::string, ci_hash, ci_equal > m2; // (since C++20)
     341              :     @endcode
     342              : 
     343              :     @see
     344              :         @ref ci_hash,
     345              :         @ref ci_less.
     346              : */
     347              : #ifdef BOOST_URL_DOCS
     348              : using ci_equal = __see_below__;
     349              : #else
     350              : namespace see_below {
     351              : struct ci_equal
     352              : {
     353              :     using is_transparent = void;
     354              : 
     355              :     template<
     356              :         class String0, class String1>
     357              :     bool
     358            3 :     operator()(
     359              :         String0 s0,
     360              :         String1 s1) const noexcept
     361              :     {
     362            3 :         return ci_is_equal(s0, s1);
     363              :     }
     364              : };
     365              : } // see_below
     366              : 
     367              : /** A case-insensitive equals predicate for strings
     368              : 
     369              :     The function object returns `true` when
     370              :     two strings are equal, ignoring case.
     371              :     This is a suitable equality predicate for
     372              :     unordered containers.
     373              :     The function is defined only for strings
     374              :     containing low-ASCII characters.
     375              : 
     376              :     @par Example
     377              :     @code
     378              :     boost::unordered_map< std::string, std::string, ci_hash, ci_equal > m1;
     379              : 
     380              :     std::unordered_map  < std::string, std::string, ci_hash, ci_equal > m2; // (since C++20)
     381              :     @endcode
     382              : 
     383              :     @see
     384              :         @ref ci_hash,
     385              :         @ref ci_less.
     386              : */
     387              : using ci_equal = see_below::ci_equal;
     388              : #endif
     389              : 
     390              : /** A case-insensitive less predicate for strings
     391              : 
     392              :     The comparison algorithm implements a
     393              :     case-insensitive total order on the set
     394              :     of all ASCII strings; however, it is
     395              :     not a lexicographical comparison.
     396              :     This is a suitable predicate for
     397              :     ordered containers.
     398              :     The function is defined only for strings
     399              :     containing low-ASCII characters.
     400              : 
     401              :     @par Example
     402              :     @code
     403              :     boost::container::map< std::string, std::string, ci_less > m1;
     404              : 
     405              :     std::map< std::string, std::string, ci_less > m2; // (since C++14)
     406              :     @endcode
     407              : 
     408              :     @see
     409              :         @ref ci_equal,
     410              :         @ref ci_hash.
     411              : */
     412              : #ifdef BOOST_URL_DOCS
     413              : using ci_less = __see_below__;
     414              : #else
     415              : namespace see_below {
     416              : struct ci_less
     417              : {
     418              :     using is_transparent = void;
     419              : 
     420              :     std::size_t
     421            4 :     operator()(
     422              :         core::string_view s0,
     423              :         core::string_view s1) const noexcept
     424              :     {
     425            4 :         return ci_is_less(s0, s1);
     426              :     }
     427              : };
     428              : }
     429              : 
     430              : /** A case-insensitive less predicate for strings
     431              : 
     432              :     The comparison algorithm implements a
     433              :     case-insensitive total order on the set
     434              :     of all ASCII strings; however, it is
     435              :     not a lexicographical comparison.
     436              :     This is a suitable predicate for
     437              :     ordered containers.
     438              :     The function is defined only for strings
     439              :     containing low-ASCII characters.
     440              : 
     441              :     @par Example
     442              :     @code
     443              :     boost::container::map< std::string, std::string, ci_less > m1;
     444              : 
     445              :     std::map< std::string, std::string, ci_less > m2; // (since C++14)
     446              :     @endcode
     447              : 
     448              :     @see
     449              :         @ref ci_equal,
     450              :         @ref ci_hash.
     451              : */
     452              : using ci_less = see_below::ci_less;
     453              : #endif
     454              : 
     455              : } // grammar
     456              : } // urls
     457              : } // boost
     458              : 
     459              : #endif
        

Generated by: LCOV version 2.1