include/boost/url/grammar/hexdig_chars.hpp

100.0% Lines (30/30) 100.0% List of functions (4/4)
hexdig_chars.hpp
f(x) Functions (4)
Line TLA Hits Source Code
1 //
2 // Copyright (c) 2021 Vinnie Falco (vinnie dot falco at gmail dot com)
3 //
4 // Distributed under the Boost Software License, Version 1.0. (See accompanying
5 // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
6 //
7 // Official repository: https://github.com/boostorg/url
8 //
9
10 #ifndef BOOST_URL_GRAMMAR_HEXDIG_CHARS_HPP
11 #define BOOST_URL_GRAMMAR_HEXDIG_CHARS_HPP
12
13 #include <boost/url/detail/config.hpp>
14 #include <boost/url/grammar/detail/charset.hpp>
15
16 namespace boost {
17 namespace urls {
18 namespace grammar {
19 namespace implementation_defined {
20 struct hexdig_chars_t
21 {
22 /** Determine if a character is a hexadecimal digit
23
24 @param c The character to test
25 @return `true` if `c` is a hexadecimal digit.
26 */
27 constexpr
28 bool
29 4124x operator()(char c) const noexcept
30 {
31 return
32 4124x (c >= '0' && c <= '9') ||
33 8777x (c >= 'A' && c <= 'F') ||
34 4653x (c >= 'a' && c <= 'f');
35 }
36
37 #ifdef BOOST_URL_USE_SSE2
38 char const*
39 256x find_if(
40 char const* first,
41 char const* last) const noexcept
42 {
43 256x return detail::find_if_pred(
44 256x *this, first, last);
45 }
46
47 char const*
48 272x find_if_not(
49 char const* first,
50 char const* last) const noexcept
51 {
52 272x return detail::find_if_not_pred(
53 272x *this, first, last);
54 }
55 #endif
56 };
57 }
58
59 /** The set of hexadecimal digits
60
61 @par Example
62 Character sets are used with rules and the
63 functions @ref find_if and @ref find_if_not.
64 @code
65 system::result< core::string_view > rv = parse( "8086FC19", token_rule( hexdig_chars ) );
66 @endcode
67
68 @par BNF
69 @code
70 HEXDIG = DIGIT
71 / "A" / "B" / "C" / "D" / "E" / "F"
72 / "a" / "b" / "c" / "d" / "e" / "f"
73 @endcode
74
75 @note The RFCs are inconsistent on the case
76 sensitivity of hexadecimal digits. Existing
77 uses suggest case-insensitivity is a de-facto
78 standard.
79
80 @par Specification
81 @li <a href="https://datatracker.ietf.org/doc/html/rfc5234#appendix-B.1"
82 >B.1. Core Rules (rfc5234)</a>
83 @li <a href="https://datatracker.ietf.org/doc/html/rfc7230#section-1.2"
84 >1.2. Syntax Notation (rfc7230)</a>
85 @li <a href="https://datatracker.ietf.org/doc/html/rfc5952#section-2.3"
86 >2.3. Uppercase or Lowercase (rfc5952)</a>
87 @li <a href="https://datatracker.ietf.org/doc/html/rfc5952#section-4.3"
88 >4.3. Lowercase (rfc5952)</a>
89
90 @see
91 @ref find_if,
92 @ref find_if_not,
93 @ref hexdig_value,
94 @ref parse,
95 @ref token_rule.
96 */
97 constexpr implementation_defined::hexdig_chars_t hexdig_chars{};
98
99 /** Return the decimal value of a hex character
100
101 This function returns the decimal
102 value of a hexadecimal character,
103 or -1 if the argument is not a
104 valid hexadecimal digit.
105
106 @par BNF
107 @code
108 HEXDIG = DIGIT
109 / "A" / "B" / "C" / "D" / "E" / "F"
110 / "a" / "b" / "c" / "d" / "e" / "f"
111 @endcode
112
113 @param ch The character to check
114
115 @return The decimal value or -1
116 */
117 inline
118 signed char
119 907835x hexdig_value(char ch) noexcept
120 {
121 // Idea for a switch statement to
122 // minimize emitted assembly from
123 // Glen Fernandes
124 signed char res;
125 907835x switch(ch)
126 {
127 1253x default: res = -1; break;
128 121912x case '0': res = 0; break;
129 919x case '1': res = 1; break;
130 147555x case '2': res = 2; break;
131 93464x case '3': res = 3; break;
132 484x case '4': res = 4; break;
133 117903x case '5': res = 5; break;
134 23837x case '6': res = 6; break;
135 69861x case '7': res = 7; break;
136 373x case '8': res = 8; break;
137 23248x case '9': res = 9; break;
138 23725x case 'a': case 'A': res = 10; break;
139 47034x case 'b': case 'B': res = 11; break;
140 68913x case 'c': case 'C': res = 12; break;
141 69749x case 'd': case 'D': res = 13; break;
142 46897x case 'e': case 'E': res = 14; break;
143 50708x case 'f': case 'F': res = 15; break;
144 }
145 907835x return res;
146 }
147
148 } // grammar
149 } // urls
150 } // boost
151
152 #endif
153