Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 09:53:27

0001 //
0002 // Copyright (c) 2016-2019 Vinnie Falco (vinnie dot falco at gmail dot com)
0003 // Copyright (c) 2022 Alan de Freitas (alandefreitas@gmail.com)
0004 //
0005 // Distributed under the Boost Software License, Version 1.0. (See accompanying
0006 // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
0007 //
0008 // Official repository: https://github.com/boostorg/url
0009 //
0010 
0011 #ifndef BOOST_URL_GRAMMAR_CI_STRING_HPP
0012 #define BOOST_URL_GRAMMAR_CI_STRING_HPP
0013 
0014 #include <boost/url/detail/config.hpp>
0015 #include <boost/core/detail/string_view.hpp>
0016 #include <boost/url/grammar/detail/ci_string.hpp>
0017 #include <cstdlib>
0018 
0019 namespace boost {
0020 namespace urls {
0021 namespace grammar {
0022 
0023 // Algorithms for interacting with low-ASCII
0024 // characters and strings, for implementing
0025 // semantics in RFCs. These routines do not
0026 // use std::locale.
0027 
0028 //------------------------------------------------
0029 
0030 /** Return c converted to lowercase
0031 
0032     This function returns the character,
0033     converting it to lowercase if it is
0034     uppercase.
0035     The function is defined only for
0036     low-ASCII characters.
0037 
0038     @par Example
0039     @code
0040     assert( to_lower( 'A' ) == 'a' );
0041     @endcode
0042 
0043     @par Exception Safety
0044     Throws nothing.
0045 
0046     @return The converted character
0047 
0048     @param c The character to convert
0049 
0050     @see
0051         @ref to_upper.
0052 */
0053 constexpr
0054 char
0055 to_lower(char c) noexcept
0056 {
0057     return detail::to_lower(c);
0058 }
0059 
0060 /** Return c converted to uppercase
0061 
0062     This function returns the character,
0063     converting it to uppercase if it is
0064     lowercase.
0065     The function is defined only for
0066     low-ASCII characters.
0067 
0068     @par Example
0069     @code
0070     assert( to_upper( 'a' ) == 'A' );
0071     @endcode
0072 
0073     @par Exception Safety
0074     Throws nothing.
0075 
0076     @return The converted character
0077 
0078     @param c The character to convert
0079 
0080     @see
0081         @ref to_lower.
0082 */
0083 constexpr
0084 char
0085 to_upper(char c) noexcept
0086 {
0087     return detail::to_upper(c);
0088 }
0089 
0090 //------------------------------------------------
0091 
0092 /** Return the case-insensitive comparison of s0 and s1
0093 
0094     This returns the lexicographical comparison
0095     of two strings, ignoring case.
0096     The function is defined only for strings
0097     containing low-ASCII characters.
0098 
0099     @par Example
0100     @code
0101     assert( ci_compare( "boost", "Boost" ) == 0 );
0102     @endcode
0103 
0104     @par Exception Safety
0105     Throws nothing.
0106 
0107     @return 0 if the strings are equal, -1 if
0108     `s0` is less than `s1`, or 1 if `s0` is
0109     greater than s1.
0110 
0111     @param s0 The first string
0112 
0113     @param s1 The second string
0114 
0115     @see
0116         @ref ci_is_equal,
0117         @ref ci_is_less.
0118 */
0119 BOOST_URL_DECL
0120 int
0121 ci_compare(
0122     core::string_view s0,
0123     core::string_view s1) noexcept;
0124 
0125 /** Return the case-insensitive digest of a string
0126 
0127     The hash function is non-cryptographic and
0128     not hardened against algorithmic complexity
0129     attacks.
0130     Returned digests are suitable for usage in
0131     unordered containers.
0132     The function is defined only for strings
0133     containing low-ASCII characters.
0134 
0135     @return The digest
0136 
0137     @param s The string
0138 */
0139 BOOST_URL_DECL
0140 std::size_t
0141 ci_digest(
0142     core::string_view s) noexcept;
0143 
0144 //------------------------------------------------
0145 
0146 /** Return true if s0 equals s1 using case-insensitive comparison
0147 
0148     The function is defined only for strings
0149     containing low-ASCII characters.
0150 
0151     @par Example
0152     @code
0153     assert( ci_is_equal( "Boost", "boost" ) );
0154     @endcode
0155 
0156     @see
0157         @ref ci_compare,
0158         @ref ci_is_less.
0159 */
0160 #ifdef BOOST_URL_DOCS
0161 template<
0162     class String0,
0163     class String1>
0164 bool
0165 ci_is_equal(
0166     String0 const& s0,
0167     String1 const& s1);
0168 #else
0169 
0170 template<
0171     class String0,
0172     class String1>
0173 auto
0174 ci_is_equal(
0175     String0 const& s0,
0176     String1 const& s1) ->
0177         typename std::enable_if<
0178             ! std::is_convertible<
0179                 String0, core::string_view>::value ||
0180             ! std::is_convertible<
0181                 String1, core::string_view>::value,
0182         bool>::type
0183 {
0184     // this overload supports forward iterators and
0185     // does not assume the existence core::string_view::size
0186     if( detail::type_id<String0>() >
0187         detail::type_id<String1>())
0188         return detail::ci_is_equal(s1, s0);
0189     return detail::ci_is_equal(s0, s1);
0190 }
0191 
0192 inline
0193 bool
0194 ci_is_equal(
0195     core::string_view s0,
0196     core::string_view s1) noexcept
0197 {
0198     // this overload is faster as it makes use of
0199     // core::string_view::size
0200     if(s0.size() != s1.size())
0201         return false;
0202     return detail::ci_is_equal(s0, s1);
0203 }
0204 #endif
0205 
0206 /** Return true if s0 is less than s1 using case-insensitive comparison 
0207 
0208     The comparison algorithm implements a
0209     case-insensitive total order on the set
0210     of all strings; however, it is not a
0211     lexicographical comparison.
0212     The function is defined only for strings
0213     containing low-ASCII characters.
0214 
0215     @par Example
0216     @code
0217     assert( ! ci_is_less( "Boost", "boost" ) );
0218     @endcode
0219 
0220     @see
0221         @ref ci_compare,
0222         @ref ci_is_equal.
0223 */
0224 inline
0225 bool
0226 ci_is_less(
0227     core::string_view s0,
0228     core::string_view s1) noexcept
0229 {
0230     if(s0.size() != s1.size())
0231         return s0.size() < s1.size();
0232     return detail::ci_is_less(s0, s1);
0233 }
0234 
0235 //------------------------------------------------
0236 
0237 /** A case-insensitive hash function object for strings
0238 
0239     The hash function is non-cryptographic and
0240     not hardened against algorithmic complexity
0241     attacks.
0242     This is a suitable hash function for
0243     unordered containers.
0244     The function is defined only for strings
0245     containing low-ASCII characters.
0246 
0247     @par Example
0248     @code
0249     boost::unordered_map< std::string, std::string, ci_hash, ci_equal > m1;
0250 
0251     std::unordered_map  < std::string, std::string, ci_hash, ci_equal > m2; // (since C++20)
0252     @endcode
0253 
0254     @see
0255         @ref ci_equal,
0256         @ref ci_less.
0257 */
0258 #ifdef BOOST_URL_DOCS
0259 using ci_hash = __see_below__;
0260 #else
0261 struct ci_hash
0262 {
0263     using is_transparent = void;
0264 
0265     std::size_t
0266     operator()(
0267         core::string_view s) const noexcept
0268     {
0269         return ci_digest(s);
0270     }
0271 };
0272 #endif
0273 
0274 /** A case-insensitive equals predicate for strings
0275 
0276     The function object returns `true` when
0277     two strings are equal, ignoring case.
0278     This is a suitable equality predicate for
0279     unordered containers.
0280     The function is defined only for strings
0281     containing low-ASCII characters.
0282 
0283     @par Example
0284     @code
0285     boost::unordered_map< std::string, std::string, ci_hash, ci_equal > m1;
0286 
0287     std::unordered_map  < std::string, std::string, ci_hash, ci_equal > m2; // (since C++20)
0288     @endcode
0289 
0290     @see
0291         @ref ci_hash,
0292         @ref ci_less.
0293 */
0294 #ifdef BOOST_URL_DOCS
0295 using ci_equal = __see_below__;
0296 #else
0297 struct ci_equal
0298 {
0299     using is_transparent = void;
0300 
0301     template<
0302         class String0, class String1>
0303     bool
0304     operator()(
0305         String0 s0,
0306         String1 s1) const noexcept
0307     {
0308         return ci_is_equal(s0, s1);
0309     }
0310 };
0311 #endif
0312 
0313 /** A case-insensitive less predicate for strings
0314 
0315     The comparison algorithm implements a
0316     case-insensitive total order on the set
0317     of all ASCII strings; however, it is
0318     not a lexicographical comparison.
0319     This is a suitable predicate for
0320     ordered containers.
0321     The function is defined only for strings
0322     containing low-ASCII characters.
0323 
0324     @par Example
0325     @code
0326     boost::container::map< std::string, std::string, ci_less > m1;
0327 
0328     std::map< std::string, std::string, ci_less > m2; // (since C++14)
0329     @endcode
0330 
0331     @see
0332         @ref ci_equal,
0333         @ref ci_hash.
0334 */
0335 #ifdef BOOST_URL_DOCS
0336 using ci_less = __see_below__;
0337 #else
0338 struct ci_less
0339 {
0340     using is_transparent = void;
0341 
0342     std::size_t
0343     operator()(
0344         core::string_view s0,
0345         core::string_view s1) const noexcept
0346     {
0347         return ci_is_less(s0, s1);
0348     }
0349 };
0350 #endif
0351 
0352 } // grammar
0353 } // urls
0354 } // boost
0355 
0356 #endif