File Coverage

utf8_distance_unsafe.h
Criterion Covered Total %
statement 9 13 69.2
branch 4 6 66.6
condition n/a
subroutine n/a
pod n/a
total 13 19 68.4


line stmt bran cond sub pod time code
1             /*
2             * Copyright (c) 2026 Christian Hansen
3             *
4             *
5             * Permission is hereby granted, free of charge, to any person obtaining a copy
6             * of this software and associated documentation files (the "Software"), to deal
7             * in the Software without restriction, including without limitation the rights
8             * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9             * copies of the Software, and to permit persons to whom the Software is
10             * furnished to do so, subject to the following conditions:
11             *
12             * The above copyright notice and this permission notice shall be included in all
13             * copies or substantial portions of the Software.
14             *
15             * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16             * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17             * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18             * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19             * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20             * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21             * SOFTWARE.
22             */
23             #ifndef UTF8_DISTANCE_UNSAFE_H
24             #define UTF8_DISTANCE_UNSAFE_H
25             #include
26             #include
27              
28             #include "utf8_swar.h"
29             #include "utf8_simd.h"
30              
31             #ifdef __cplusplus
32             extern "C" {
33             #endif
34              
35             /*
36             * utf8_distance_unsafe -- count the number of codepoints in src[0..len).
37             *
38             * src MUST point to well-formed UTF-8. No validation is performed.
39             *
40             * Uses SIMD (when available) or SWAR to process 32-byte blocks in bulk,
41             * then SWAR 8-byte blocks, then a scalar tail for the remaining 0-7 bytes.
42             */
43 31           static inline size_t utf8_distance_unsafe(const char *src, size_t len) {
44 31           const uint8_t *bytes = (const uint8_t *)src;
45 31           size_t pos = 0, count = 0;
46              
47 31           size_t n32 = len / 32;
48 31 50         if (n32) {
49             #ifdef UTF8_SIMD_AVAILABLE
50 0           count += utf8_simd_count_codepoints_Nx32(bytes, n32);
51             #else
52             count += utf8_swar_count_codepoints_Nx32(bytes, n32);
53             #endif
54 0           pos += n32 * 32;
55             }
56              
57 31 50         while (pos + 8 <= len) {
58 0           count += utf8_swar_count_codepoints_1x8(bytes + pos);
59 0           pos += 8;
60             }
61              
62 85 100         for (; pos < len; pos++)
63 54           count += ((int8_t)bytes[pos] > -65);
64              
65 31           return count;
66             }
67              
68             #ifdef __cplusplus
69             }
70             #endif
71             #endif /* UTF8_DISTANCE_UNSAFE_H */