GCC Code Coverage Report


Directory: libs/url/
File: include/boost/url/grammar/hexdig_chars.hpp
Date: 2025-04-22 15:26:26
Exec Total Coverage
Lines: 30 30 100.0%
Functions: 4 4 100.0%
Branches: 29 29 100.0%

Line Branch Exec Source
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
20 /** The set of hexadecimal digits
21
22 @par Example
23 Character sets are used with rules and the
24 functions @ref find_if and @ref find_if_not.
25 @code
26 system::result< core::string_view > rv = parse( "8086FC19", token_rule( hexdig_chars ) );
27 @endcode
28
29 @par BNF
30 @code
31 HEXDIG = DIGIT
32 / "A" / "B" / "C" / "D" / "E" / "F"
33 / "a" / "b" / "c" / "d" / "e" / "f"
34 @endcode
35
36 @note The RFCs are inconsistent on the case
37 sensitivity of hexadecimal digits. Existing
38 uses suggest case-insensitivity is a de-facto
39 standard.
40
41 @par Specification
42 @li <a href="https://datatracker.ietf.org/doc/html/rfc5234#appendix-B.1"
43 >B.1. Core Rules (rfc5234)</a>
44 @li <a href="https://datatracker.ietf.org/doc/html/rfc7230#section-1.2"
45 >1.2. Syntax Notation (rfc7230)</a>
46 @li <a href="https://datatracker.ietf.org/doc/html/rfc5952#section-2.3"
47 >2.3. Uppercase or Lowercase (rfc5952)</a>
48 @li <a href="https://datatracker.ietf.org/doc/html/rfc5952#section-4.3"
49 >4.3. Lowercase (rfc5952)</a>
50
51 @see
52 @ref find_if,
53 @ref find_if_not,
54 @ref hexdig_value,
55 @ref parse,
56 @ref token_rule.
57 */
58 #ifdef BOOST_URL_DOCS
59 constexpr __implementation_defined__ hexdig_chars;
60 #else
61 namespace implementation_defined {
62 struct hexdig_chars_t
63 {
64 /** Determine if a character is a hexadecimal digit
65
66 @param c The character to test
67 @return `true` if `c` is a hexadecimal digit.
68 */
69 constexpr
70 bool
71 3411 operator()(char c) const noexcept
72 {
73 return
74
4/4
✓ Branch 0 taken 825 times.
✓ Branch 1 taken 553 times.
✓ Branch 2 taken 782 times.
✓ Branch 3 taken 2076 times.
3411 (c >= '0' && c <= '9') ||
75
6/6
✓ Branch 0 taken 1378 times.
✓ Branch 1 taken 2033 times.
✓ Branch 2 taken 539 times.
✓ Branch 3 taken 243 times.
✓ Branch 4 taken 379 times.
✓ Branch 5 taken 2236 times.
7201 (c >= 'A' && c <= 'F') ||
76
2/2
✓ Branch 0 taken 225 times.
✓ Branch 1 taken 154 times.
3790 (c >= 'a' && c <= 'f');
77 }
78
79 #ifdef BOOST_URL_USE_SSE2
80 char const*
81 256 find_if(
82 char const* first,
83 char const* last) const noexcept
84 {
85 256 return detail::find_if_pred(
86 256 *this, first, last);
87 }
88
89 char const*
90 272 find_if_not(
91 char const* first,
92 char const* last) const noexcept
93 {
94 272 return detail::find_if_not_pred(
95 272 *this, first, last);
96 }
97 #endif
98 };
99 }
100
101 /** The set of hexadecimal digits
102
103 @par Example
104 Character sets are used with rules and the
105 functions @ref find_if and @ref find_if_not.
106 @code
107 system::result< core::string_view > rv = parse( "8086FC19", token_rule( hexdig_chars ) );
108 @endcode
109
110 @par BNF
111 @code
112 HEXDIG = DIGIT
113 / "A" / "B" / "C" / "D" / "E" / "F"
114 / "a" / "b" / "c" / "d" / "e" / "f"
115 @endcode
116
117 @note The RFCs are inconsistent on the case
118 sensitivity of hexadecimal digits. Existing
119 uses suggest case-insensitivity is a de-facto
120 standard.
121
122 @par Specification
123 @li <a href="https://datatracker.ietf.org/doc/html/rfc5234#appendix-B.1"
124 >B.1. Core Rules (rfc5234)</a>
125 @li <a href="https://datatracker.ietf.org/doc/html/rfc7230#section-1.2"
126 >1.2. Syntax Notation (rfc7230)</a>
127 @li <a href="https://datatracker.ietf.org/doc/html/rfc5952#section-2.3"
128 >2.3. Uppercase or Lowercase (rfc5952)</a>
129 @li <a href="https://datatracker.ietf.org/doc/html/rfc5952#section-4.3"
130 >4.3. Lowercase (rfc5952)</a>
131
132 @see
133 @ref find_if,
134 @ref find_if_not,
135 @ref hexdig_value,
136 @ref parse,
137 @ref token_rule.
138 */
139 constexpr implementation_defined::hexdig_chars_t hexdig_chars{};
140 #endif
141
142 // VFALCO We can declare
143 // these later if needed
144 //
145 //struct hexdig_upper_chars;
146 //struct hexdig_lower_chars;
147
148 /** Return the decimal value of a hex character
149
150 This function returns the decimal
151 value of a hexadecimal character,
152 or -1 if the argument is not a
153 valid hexadecimal digit.
154
155 @par BNF
156 @code
157 HEXDIG = DIGIT
158 / "A" / "B" / "C" / "D" / "E" / "F"
159 / "a" / "b" / "c" / "d" / "e" / "f"
160 @endcode
161
162 @param ch The character to check
163
164 @return The decimal value or -1
165 */
166 inline
167 signed char
168 8270 hexdig_value(char ch) noexcept
169 {
170 // Idea for switch statement to
171 // minimize emitted assembly from
172 // Glen Fernandes
173 signed char res;
174
17/17
✓ Branch 0 taken 954 times.
✓ Branch 1 taken 1148 times.
✓ Branch 2 taken 704 times.
✓ Branch 3 taken 1507 times.
✓ Branch 4 taken 761 times.
✓ Branch 5 taken 336 times.
✓ Branch 6 taken 256 times.
✓ Branch 7 taken 430 times.
✓ Branch 8 taken 233 times.
✓ Branch 9 taken 200 times.
✓ Branch 10 taken 84 times.
✓ Branch 11 taken 310 times.
✓ Branch 12 taken 133 times.
✓ Branch 13 taken 188 times.
✓ Branch 14 taken 194 times.
✓ Branch 15 taken 398 times.
✓ Branch 16 taken 434 times.
8270 switch(ch)
175 {
176 954 default: res = -1; break;
177 1148 case '0': res = 0; break;
178 704 case '1': res = 1; break;
179 1507 case '2': res = 2; break;
180 761 case '3': res = 3; break;
181 336 case '4': res = 4; break;
182 256 case '5': res = 5; break;
183 430 case '6': res = 6; break;
184 233 case '7': res = 7; break;
185 200 case '8': res = 8; break;
186 84 case '9': res = 9; break;
187 310 case 'a': case 'A': res = 10; break;
188 133 case 'b': case 'B': res = 11; break;
189 188 case 'c': case 'C': res = 12; break;
190 194 case 'd': case 'D': res = 13; break;
191 398 case 'e': case 'E': res = 14; break;
192 434 case 'f': case 'F': res = 15; break;
193 }
194 8270 return res;
195 }
196
197 } // grammar
198 } // urls
199 } // boost
200
201 #endif
202