Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-09-03 09:11:53

0001 //
0002 // Copyright (c) 2021 Vinnie Falco (vinnie dot falco at gmail dot com)
0003 //
0004 // Distributed under the Boost Software License, Version 1.0. (See accompanying
0005 // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
0006 //
0007 // Official repository: https://github.com/boostorg/url
0008 //
0009 
0010 #ifndef BOOST_URL_GRAMMAR_HEXDIG_CHARS_HPP
0011 #define BOOST_URL_GRAMMAR_HEXDIG_CHARS_HPP
0012 
0013 #include <boost/url/detail/config.hpp>
0014 #include <boost/url/grammar/detail/charset.hpp>
0015 
0016 namespace boost {
0017 namespace urls {
0018 namespace grammar {
0019 namespace implementation_defined {
0020 struct hexdig_chars_t
0021 {
0022     /** Determine if a character is a hexadecimal digit
0023 
0024         @param c The character to test
0025         @return `true` if `c` is a hexadecimal digit.
0026     */
0027     constexpr
0028     bool
0029     operator()(char c) const noexcept
0030     {
0031         return
0032             (c >= '0' && c <= '9') ||
0033             (c >= 'A' && c <= 'F') ||
0034             (c >= 'a' && c <= 'f');
0035     }
0036 
0037 #ifdef BOOST_URL_USE_SSE2
0038     char const*
0039     find_if(
0040         char const* first,
0041         char const* last) const noexcept
0042     {
0043         return detail::find_if_pred(
0044             *this, first, last);
0045     }
0046 
0047     char const*
0048     find_if_not(
0049         char const* first,
0050         char const* last) const noexcept
0051     {
0052         return detail::find_if_not_pred(
0053             *this, first, last);
0054     }
0055 #endif
0056 };
0057 }
0058 
0059 /** The set of hexadecimal digits
0060 
0061     @par Example
0062     Character sets are used with rules and the
0063     functions @ref find_if and @ref find_if_not.
0064     @code
0065     system::result< core::string_view > rv = parse( "8086FC19", token_rule( hexdig_chars ) );
0066     @endcode
0067 
0068     @par BNF
0069     @code
0070     HEXDIG      = DIGIT
0071                 / "A" / "B" / "C" / "D" / "E" / "F"
0072                 / "a" / "b" / "c" / "d" / "e" / "f"
0073     @endcode
0074 
0075     @note The RFCs are inconsistent on the case
0076     sensitivity of hexadecimal digits. Existing
0077     uses suggest case-insensitivity is a de-facto
0078     standard.
0079 
0080     @par Specification
0081     @li <a href="https://datatracker.ietf.org/doc/html/rfc5234#appendix-B.1"
0082         >B.1. Core Rules (rfc5234)</a>
0083     @li <a href="https://datatracker.ietf.org/doc/html/rfc7230#section-1.2"
0084         >1.2. Syntax Notation (rfc7230)</a>
0085     @li <a href="https://datatracker.ietf.org/doc/html/rfc5952#section-2.3"
0086         >2.3. Uppercase or Lowercase (rfc5952)</a>
0087     @li <a href="https://datatracker.ietf.org/doc/html/rfc5952#section-4.3"
0088         >4.3. Lowercase (rfc5952)</a>
0089 
0090     @see
0091         @ref find_if,
0092         @ref find_if_not,
0093         @ref hexdig_value,
0094         @ref parse,
0095         @ref token_rule.
0096 */
0097 constexpr implementation_defined::hexdig_chars_t hexdig_chars{};
0098 
0099 /** Return the decimal value of a hex character
0100 
0101     This function returns the decimal
0102     value of a hexadecimal character,
0103     or -1 if the argument is not a
0104     valid hexadecimal digit.
0105 
0106     @par BNF
0107     @code
0108     HEXDIG      = DIGIT
0109                 / "A" / "B" / "C" / "D" / "E" / "F"
0110                 / "a" / "b" / "c" / "d" / "e" / "f"
0111     @endcode
0112 
0113     @param ch The character to check
0114 
0115     @return The decimal value or -1
0116 */
0117 inline
0118 signed char
0119 hexdig_value(char ch) noexcept
0120 {
0121     // Idea for a switch statement to
0122     // minimize emitted assembly from
0123     // Glen Fernandes
0124     signed char res;
0125     switch(ch)
0126     {
0127     default:            res = -1; break;
0128     case '0':           res =  0; break;
0129     case '1':           res =  1; break;
0130     case '2':           res =  2; break;
0131     case '3':           res =  3; break;
0132     case '4':           res =  4; break;
0133     case '5':           res =  5; break;
0134     case '6':           res =  6; break;
0135     case '7':           res =  7; break;
0136     case '8':           res =  8; break;
0137     case '9':           res =  9; break;
0138     case 'a': case 'A': res = 10; break;
0139     case 'b': case 'B': res = 11; break;
0140     case 'c': case 'C': res = 12; break;
0141     case 'd': case 'D': res = 13; break;
0142     case 'e': case 'E': res = 14; break;
0143     case 'f': case 'F': res = 15; break;
0144     }
0145     return res;
0146 }
0147 
0148 } // grammar
0149 } // urls
0150 } // boost
0151 
0152 #endif