15 using char_type = char;
17 using fallback_char_type = fallback_encoder_type::char_type;
19 [[nodiscard]]
constexpr std::endian guess_endian(
void const *ptr,
size_t size, std::endian endian)
const noexcept
21 return std::endian::native;
24 template<
typename It,
typename EndIt>
28 return {code_point,
false};
31 template<
typename It,
typename EndIt>
37 if (not to_bool(cu & 0x80)) [[likely]] {
39 return {char_cast<char32_t>(cu),
true};
41 }
else if (it == last or (cu & 0xc0) == 0x80) [[unlikely]] {
45 return read_fallback(it, last);
48 auto length = narrow_cast<uint8_t>(std::countl_one(char_cast<uint8_t>(cu)));
49 auto todo = length - 2;
50 hi_axiom(length >= 2);
53 auto cp = char_cast<char32_t>(cu & (0x7f >> length));
59 if ((cu & 0xc0) != 0x80) [[unlikely]] {
63 return read_fallback(it, last);
69 return {0xfffd,
false};
76 if ((cu & 0xc0) != 0x80) [[unlikely]] {
79 return {0xfffd,
false};
85 valid &= cp < 0x11'0000;
87 valid &= cp < 0xd800 or cp >= 0xe000;
89 valid &= length == narrow_cast<uint8_t>((cp > 0x7f) + (cp > 0x7ff) + (cp > 0xffff) + 1);
90 if (not valid) [[unlikely]] {
91 return {0xfffd,
false};
99 hi_axiom(code_point < 0x11'0000);
100 hi_axiom(not(code_point >= 0xd800 and code_point < 0xe000));
102 return {narrow_cast<uint8_t>((code_point > 0x7f) + (code_point > 0x7ff) + (code_point > 0xffff) + 1),
true};
105 template<
typename It>
106 constexpr void write(
char32_t code_point, It &dst)
const noexcept
108 hi_axiom(code_point < 0x11'0000);
109 hi_axiom(not(code_point >= 0xd800 and code_point < 0xe000));
111 auto length = truncate<uint8_t>((code_point > 0x7f) + (code_point > 0x7ff) + (code_point > 0xffff));
112 if (
auto i = length) {
114 dst[i] = truncate<char8_t>((code_point & 0x3f) | 0x80);
118 code_point |= 0x780 >> length;
120 dst[0] = truncate<char8_t>(code_point);
124#if defined(HI_HAS_SSE2)
125 template<
typename It>
126 hi_force_inline __m128i read_ascii_chunk16(It it)
const noexcept
128 return _mm_loadu_si128(
reinterpret_cast<__m128i
const *
>(
std::addressof(*it)));
131 template<
typename It>
132 hi_force_inline
void write_ascii_chunk16(__m128i chunk, It dst)
const noexcept
134 _mm_storeu_si128(
reinterpret_cast<__m128i *
>(
std::addressof(*dst)), chunk);