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

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

Generated by: LCOV version 1.15