GCC Code Coverage Report


Directory: libs/url/
File: libs/url/src/grammar/ci_string.cpp
Date: 2024-08-19 20:08:56
Exec Total Coverage
Lines: 56 57 98.2%
Functions: 4 4 100.0%
Branches: 23 24 95.8%

Line Branch Exec Source
1 //
2 // Copyright (c) 2019 Vinnie Falco (vinnie.falco@gmail.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
11 #include <boost/url/detail/config.hpp>
12 #include <boost/url/grammar/ci_string.hpp>
13
14 namespace boost {
15 namespace urls {
16 namespace grammar {
17
18 namespace detail {
19
20 //------------------------------------------------
21
22 // https://lemire.me/blog/2020/04/30/for-case-insensitive-string-comparisons-avoid-char-by-char-functions/
23 // https://github.com/lemire/Code-used-on-Daniel-Lemire-s-blog/blob/master/2020/04/30/tolower.cpp
24
25 bool
26 7 ci_is_equal(
27 core::string_view s0,
28 core::string_view s1) noexcept
29 {
30 7 auto n = s0.size();
31 7 auto p1 = s0.data();
32 7 auto p2 = s1.data();
33 char a, b;
34 // fast loop
35
2/2
✓ Branch 0 taken 8 times.
✓ Branch 1 taken 3 times.
11 while(n--)
36 {
37 8 a = *p1++;
38 8 b = *p2++;
39
2/2
✓ Branch 0 taken 4 times.
✓ Branch 1 taken 4 times.
8 if(a != b)
40 4 goto slow;
41 }
42 3 return true;
43 4 slow:
44 do
45 {
46
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
24 if( to_lower(a) !=
47 12 to_lower(b))
48 return false;
49 12 a = *p1++;
50 12 b = *p2++;
51 }
52
2/2
✓ Branch 0 taken 8 times.
✓ Branch 1 taken 4 times.
12 while(n--);
53 4 return true;
54 }
55
56 //------------------------------------------------
57
58 bool
59 5 ci_is_less(
60 core::string_view s0,
61 core::string_view s1) noexcept
62 {
63 5 auto p1 = s0.data();
64 5 auto p2 = s1.data();
65
2/2
✓ Branch 1 taken 15 times.
✓ Branch 2 taken 3 times.
18 for(auto n = s0.size();n--;)
66 {
67 15 auto c1 = to_lower(*p1++);
68 15 auto c2 = to_lower(*p2++);
69
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 13 times.
15 if(c1 != c2)
70 2 return c1 < c2;
71 }
72 // equal
73 3 return false;
74 }
75
76 } // detail
77
78 //------------------------------------------------
79
80 int
81 21 ci_compare(
82 core::string_view s0,
83 core::string_view s1) noexcept
84 {
85 int bias;
86 std::size_t n;
87
2/2
✓ Branch 1 taken 2 times.
✓ Branch 2 taken 19 times.
42 if( s0.size() <
88 21 s1.size())
89 {
90 2 bias = -1;
91 2 n = s0.size();
92 }
93 else
94 {
95
2/2
✓ Branch 1 taken 2 times.
✓ Branch 2 taken 17 times.
38 if( s0.size() >
96 19 s1.size())
97 2 bias = 1;
98 else
99 17 bias = 0;
100 19 n = s1.size();
101 }
102 21 auto it0 = s0.data();
103 21 auto it1 = s1.data();
104
2/2
✓ Branch 0 taken 29 times.
✓ Branch 1 taken 9 times.
38 while(n--)
105 {
106 auto c0 =
107 29 to_lower(*it0++);
108 auto c1 =
109 29 to_lower(*it1++);
110
2/2
✓ Branch 0 taken 17 times.
✓ Branch 1 taken 12 times.
29 if(c0 == c1)
111 17 continue;
112
2/2
✓ Branch 0 taken 8 times.
✓ Branch 1 taken 4 times.
12 if(c0 < c1)
113 8 return -1;
114 4 return 1;
115 }
116 9 return bias;
117 }
118
119 //------------------------------------------------
120
121 std::size_t
122 18 ci_digest(
123 core::string_view s) noexcept
124 {
125 // Only 4 and 8 byte sizes are supported
126 static_assert(
127 sizeof(std::size_t) == 4 ||
128 sizeof(std::size_t) == 8, "");
129 18 constexpr std::size_t prime = (
130 sizeof(std::size_t) == 8) ?
131 0x100000001B3ULL :
132 0x01000193UL;
133 18 constexpr std::size_t hash0 = (
134 sizeof(std::size_t) == 8) ?
135 0xcbf29ce484222325ULL :
136 0x811C9DC5UL;
137 18 auto hash = hash0;
138 18 auto p = s.data();
139 18 auto n = s.size();
140
2/2
✓ Branch 0 taken 38 times.
✓ Branch 1 taken 18 times.
56 for(;n--;++p)
141 {
142 // VFALCO NOTE Consider using a lossy
143 // to_lower which works 4 or 8 chars at a time.
144 38 hash = (to_lower(*p) ^ hash) * prime;
145 }
146 18 return hash;
147 }
148
149 } // grammar
150 } // urls
151 } // boost
152
153