22 using char_type = char;
23 using fallback_encoder_type =
char_map<
"cp-1252">;
24 using fallback_char_type = fallback_encoder_type::char_type;
26 [[nodiscard]]
constexpr std::endian guess_endian(
void const *ptr,
size_t size, std::endian endian)
const noexcept
28 return std::endian::native;
31 template<
typename It,
typename EndIt>
34 hilet[code_point, valid] = fallback_encoder_type{}.read(it, last);
35 return {code_point,
false};
38 template<
typename It,
typename EndIt>
44 if (not to_bool(cu & 0x80)) [[likely]] {
46 return {char_cast<char32_t>(cu),
true};
48 }
else if (it == last or (cu & 0xc0) == 0x80) [[unlikely]] {
52 return read_fallback(it, last);
55 auto length = narrow_cast<uint8_t>(std::countl_one(char_cast<uint8_t>(cu)));
56 auto todo = length - 2;
57 hi_axiom(length >= 2);
60 auto cp = char_cast<char32_t>(cu & (0x7f >> length));
66 if ((cu & 0xc0) != 0x80) [[unlikely]] {
70 return read_fallback(it, last);
76 return {0xfffd,
false};
83 if ((cu & 0xc0) != 0x80) [[unlikely]] {
86 return {0xfffd,
false};
92 valid &= cp < 0x11'0000;
94 valid &= cp < 0xd800 or cp >= 0xe000;
96 valid &= length == narrow_cast<uint8_t>((cp > 0x7f) + (cp > 0x7ff) + (cp > 0xffff) + 1);
97 if (not valid) [[unlikely]] {
98 return {0xfffd,
false};
106 hi_axiom(code_point < 0x11'0000);
107 hi_axiom(not(code_point >= 0xd800 and code_point < 0xe000));
109 return {narrow_cast<uint8_t>((code_point > 0x7f) + (code_point > 0x7ff) + (code_point > 0xffff) + 1),
true};
112 template<
typename It>
113 constexpr void write(
char32_t code_point, It& dst)
const noexcept
115 hi_axiom(code_point < 0x11'0000);
116 hi_axiom(not(code_point >= 0xd800 and code_point < 0xe000));
118 auto length = truncate<uint8_t>((code_point > 0x7f) + (code_point > 0x7ff) + (code_point > 0xffff));
119 if (
auto i = length) {
121 dst[i] = truncate<char8_t>((code_point & 0x3f) | 0x80);
125 code_point |= 0x780 >> length;
127 dst[0] = truncate<char8_t>(code_point);
131#if defined(HI_HAS_SSE2)
132 template<
typename It>
133 hi_force_inline __m128i read_ascii_chunk16(It it)
const noexcept
135 return _mm_loadu_si128(
reinterpret_cast<__m128i
const *
>(
std::addressof(*it)));
138 template<
typename It>
139 hi_force_inline
void write_ascii_chunk16(__m128i chunk, It dst)
const noexcept
141 _mm_storeu_si128(
reinterpret_cast<__m128i *
>(
std::addressof(*dst)), chunk);