File Coverage

utf8_advance_forward_unsafe.h
Criterion Covered Total %
statement 0 20 0.0
branch 0 18 0.0
condition n/a
subroutine n/a
pod n/a
total 0 38 0.0


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_ADVANCE_FORWARD_UNSAFE_H
24             #define UTF8_ADVANCE_FORWARD_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_advance_forward_unsafe -- advance forward by distance codepoints.
37             *
38             * src MUST point to well-formed UTF-8. No validation is performed.
39             *
40             * Returns the byte offset of the start of the codepoint distance positions
41             * ahead in src[0..len), or len if distance exceeds the number of codepoints
42             * in the buffer. If advanced is non-NULL, writes the number of codepoints
43             * actually advanced before stopping.
44             *
45             * Uses SIMD (when available) or SWAR to process 32-byte blocks in bulk.
46             * A 32-byte block contains at most 32 codepoints, so processing
47             * (distance - count) / 32 blocks at a time can never overshoot.
48             * Remaining 8-byte blocks use SWAR, then a scalar walk handles the
49             * final bytes.
50             */
51 0           static inline size_t utf8_advance_forward_unsafe(const char *src,
52             size_t len,
53             size_t distance,
54             size_t *advanced) {
55 0           const uint8_t *bytes = (const uint8_t *)src;
56 0           size_t pos = 0, count = 0;
57              
58 0 0         while (distance - count >= 32 && len - pos >= 32) {
    0          
59 0           size_t remain = (distance - count) / 32;
60 0           size_t avail = (len - pos) / 32;
61 0           size_t blocks = remain < avail ? remain : avail;
62             #ifdef UTF8_SIMD_AVAILABLE
63 0           count += utf8_simd_count_codepoints_Nx32(src + pos, blocks);
64             #else
65             count += utf8_swar_count_codepoints_Nx32(src + pos, blocks);
66             #endif
67 0           pos += blocks * 32;
68             }
69              
70 0 0         while (distance - count >= 8 && len - pos >= 8) {
    0          
71 0           count += utf8_swar_count_codepoints_1x8(bytes + pos);
72 0           pos += 8;
73             }
74              
75 0 0         while (pos < len && count < distance) {
    0          
76 0           count += ((int8_t)bytes[pos] > -65);
77 0           pos++;
78             }
79              
80 0 0         while (pos < len && (int8_t)bytes[pos] <= -65)
    0          
81 0           pos++;
82              
83 0 0         if (advanced)
84 0           *advanced = count;
85 0           return pos;
86             }
87              
88             #ifdef __cplusplus
89             }
90             #endif
91             #endif /* UTF8_ADVANCE_FORWARD_UNSAFE_H */