GCC Code Coverage Report


Directory: libs/url/
File: boost/url/grammar/ci_string.hpp
Date: 2024-02-29 20:02:56
Exec Total Coverage
Lines: 22 23 95.7%
Functions: 10 11 90.9%
Branches: 5 6 83.3%

Line Branch Exec Source
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 20609 to_lower(char c) noexcept
56 {
57 20609 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 187 to_upper(char c) noexcept
86 {
87 187 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
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 252 times.
504 if( detail::type_id<String0>() >
187 252 detail::type_id<String1>())
188 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
2/2
✓ Branch 2 taken 3 times.
✓ Branch 3 taken 7 times.
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
2/2
✓ Branch 2 taken 4 times.
✓ Branch 3 taken 5 times.
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 6 operator()(
305 String0 s0,
306 String1 s1) const noexcept
307 {
308 6 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
357