simdutf 9.0.0
Unicode at GB/s.
Loading...
Searching...
No Matches
valid_utf32_to_latin1.h
1#ifndef SIMDUTF_VALID_UTF32_TO_LATIN1_H
2#define SIMDUTF_VALID_UTF32_TO_LATIN1_H
3
4#include <cstring>
5
6namespace simdutf {
7namespace scalar {
8namespace {
9namespace utf32_to_latin1 {
10
11template <typename ReadPtr, typename WritePtr>
12simdutf_constexpr23 size_t convert_valid(ReadPtr data, size_t len,
13 WritePtr latin1_output) {
14 static_assert(
15 std::is_same<typename std::decay<decltype(*data)>::type, uint32_t>::value,
16 "dereferencing the data pointer must result in a uint32_t");
17 auto start = latin1_output;
18 uint32_t utf32_char;
19 size_t pos = 0;
20
21 while (pos < len) {
22 utf32_char = data[pos];
23
24#if SIMDUTF_CPLUSPLUS23
25 // avoid using the 8 byte at a time optimization in constant evaluation
26 // mode. memcpy can't be used and replacing it with bitwise or gave worse
27 // codegen (when not during constant evaluation).
28 if !consteval {
29#endif
30 if (pos + 2 <= len) {
31 // if it is safe to read 8 more bytes, check that they are Latin1
32 uint64_t v;
33 std::memcpy(&v, data + pos, sizeof(uint64_t));
34 if ((v & 0xFFFFFF00FFFFFF00) == 0) {
35 *latin1_output++ = char(data[pos]);
36 *latin1_output++ = char(data[pos + 1]);
37 pos += 2;
38 continue;
39 } else {
40 // output can not be represented in latin1
41 return 0;
42 }
43 }
44#if SIMDUTF_CPLUSPLUS23
45 } // if ! consteval
46#endif
47 if ((utf32_char & 0xFFFFFF00) == 0) {
48 *latin1_output++ = char(utf32_char);
49 } else {
50 // output can not be represented in latin1
51 return 0;
52 }
53 pos++;
54 }
55 return latin1_output - start;
56}
57
58simdutf_really_inline size_t convert_valid(const char32_t *buf, size_t len,
59 char *latin1_output) {
60 return convert_valid(reinterpret_cast<const uint32_t *>(buf), len,
61 latin1_output);
62}
63
64} // namespace utf32_to_latin1
65} // unnamed namespace
66} // namespace scalar
67} // namespace simdutf
68
69#endif
helpers placed in namespace detail are not a part of the public API