1#ifndef SIMDUTF_UTF16_TO_UTF32_H
2#define SIMDUTF_UTF16_TO_UTF32_H
7namespace utf16_to_utf32 {
9template <endianness big_endian>
10simdutf_constexpr23
size_t convert(
const char16_t *data,
size_t len,
11 char32_t *utf32_output) {
13 char32_t *start{utf32_output};
16 !match_system(big_endian) ? u16_swap_bytes(data[pos]) : data[pos];
17 if ((word & 0xF800) != 0xD800) {
19 *utf32_output++ = char32_t(word);
23 uint16_t diff = uint16_t(word - 0xD800);
30 uint16_t next_word = !match_system(big_endian)
31 ? u16_swap_bytes(data[pos + 1])
33 uint16_t diff2 = uint16_t(next_word - 0xDC00);
37 uint32_t value = (diff << 10) + diff2 + 0x10000;
38 *utf32_output++ = char32_t(value);
42 return utf32_output - start;
45template <endianness big_endian>
46simdutf_constexpr23 result convert_with_errors(
const char16_t *data,
size_t len,
47 char32_t *utf32_output) {
49 char32_t *start{utf32_output};
52 !match_system(big_endian) ? u16_swap_bytes(data[pos]) : data[pos];
53 if ((word & 0xF800) != 0xD800) {
55 *utf32_output++ = char32_t(word);
59 uint16_t diff = uint16_t(word - 0xD800);
61 return result(error_code::SURROGATE, pos);
64 return result(error_code::SURROGATE, pos);
66 uint16_t next_word = !match_system(big_endian)
67 ? u16_swap_bytes(data[pos + 1])
69 uint16_t diff2 = uint16_t(next_word - 0xDC00);
71 return result(error_code::SURROGATE, pos);
73 uint32_t value = (diff << 10) + diff2 + 0x10000;
74 *utf32_output++ = char32_t(value);
78 return result(error_code::SUCCESS, utf32_output - start);