1#ifndef SIMDUTF_VALID_UTF8_TO_UTF32_H
2#define SIMDUTF_VALID_UTF8_TO_UTF32_H
9namespace utf8_to_utf32 {
11template <
typename InputPtr>
12#if SIMDUTF_CPLUSPLUS20
13 requires simdutf::detail::indexes_into_byte_like<InputPtr>
15simdutf_constexpr23
size_t convert_valid(InputPtr data,
size_t len,
16 char32_t *utf32_output) {
18 char32_t *start{utf32_output};
20#if SIMDUTF_CPLUSPLUS23
28 ::memcpy(&v, data + pos,
sizeof(uint64_t));
29 if ((v & 0x8080808080808080) == 0) {
30 size_t final_pos = pos + 8;
31 while (pos < final_pos) {
32 *utf32_output++ = uint8_t(data[pos]);
39 auto leading_byte = uint8_t(data[pos]);
40 if (leading_byte < 0b10000000) {
42 *utf32_output++ = char32_t(leading_byte);
44 }
else if ((leading_byte & 0b11100000) == 0b11000000) {
49 *utf32_output++ = char32_t(((leading_byte & 0b00011111) << 6) |
50 (uint8_t(data[pos + 1]) & 0b00111111));
52 }
else if ((leading_byte & 0b11110000) == 0b11100000) {
57 *utf32_output++ = char32_t(((leading_byte & 0b00001111) << 12) |
58 ((uint8_t(data[pos + 1]) & 0b00111111) << 6) |
59 (uint8_t(data[pos + 2]) & 0b00111111));
61 }
else if ((leading_byte & 0b11111000) == 0b11110000) {
66 uint32_t code_word = ((leading_byte & 0b00000111) << 18) |
67 ((uint8_t(data[pos + 1]) & 0b00111111) << 12) |
68 ((uint8_t(data[pos + 2]) & 0b00111111) << 6) |
69 (uint8_t(data[pos + 3]) & 0b00111111);
70 *utf32_output++ = char32_t(code_word);
77 return utf32_output - start;
helpers placed in namespace detail are not a part of the public API