13 using char_type = char16_t;
15 [[nodiscard]] std::endian guess_endian(
void const *ptr,
size_t size, std::endian endian)
const noexcept
17 hi_axiom(ptr !=
nullptr);
18 auto *ptr_ =
reinterpret_cast<uint8_t
const *
>(ptr);
21 return std::endian::native;
24 if (ptr_[0] == 0xfe and ptr_[1] == 0xff) {
25 return std::endian::big;
26 }
else if (ptr_[0] == 0xff and ptr_[1] == 0xfe) {
27 return std::endian::little;
32 for (
auto i = 0; i != size; ++i) {
33 count[i % 2] = ptr_[i] == 0 ? count[i % 2] + 1 : 0;
34 if (count[i % 2] >= 8) {
35 return i % 2 == 0 ? std::endian::big : std::endian::little;
43 template<
typename It,
typename EndIt>
48 if (
auto cu = *it++; cu < 0xd800) {
49 return {char_cast<char32_t>(cu),
true};
51 }
else if (cu < 0xdc00) {
54 return {0xfffd,
false};
57 auto cp = char_cast<char32_t>(cu & 0x03ff);
59 if (cu >= 0xdc00 and cu < 0xe000) {
68 return {0xfffd,
false};
72 }
else if (cu < 0xe000) {
74 return {0xfffd,
false};
83 hi_axiom(code_point < 0x11'0000);
84 hi_axiom(not(code_point >= 0xd800 and code_point < 0xe000));
85 return {truncate<uint8_t>((code_point >= 0x01'0000) + 1),
true};
89 constexpr void write(
char32_t code_point, It& dst)
const noexcept
91 hi_axiom(code_point <= 0x10'ffff);
92 hi_axiom(not(code_point >= 0xd800 and code_point < 0xe000));
94 if (
auto tmp = truncate<int32_t>(code_point) - 0x1'0000; tmp >= 0) {
95 *dst++ = char_cast<char16_t>((tmp >> 10) + 0xd800);
96 *dst++ = char_cast<char16_t>((tmp & 0x3ff) + 0xdc00);
99 *dst++ = char_cast<char16_t>(code_point);
103#if defined(HI_HAS_SSE2)
104 template<
typename It>
105 hi_force_inline __m128i read_ascii_chunk16(It it)
const noexcept
108 auto lo = _mm_loadu_si128(
reinterpret_cast<__m128i
const *
>(
std::addressof(*it)));
110 auto hi = _mm_loadu_si128(
reinterpret_cast<__m128i
const *
>(
std::addressof(*it)));
118 auto sign_lo = _mm_srai_epi16(lo, 15);
119 auto sign_hi = _mm_srai_epi16(hi, 15);
120 auto sign = _mm_packs_epi16(sign_lo, sign_hi);
125 auto chunk = _mm_packus_epi16(lo, hi);
130 return _mm_or_si128(chunk, sign);
133 template<
typename It>
134 hi_force_inline
void write_ascii_chunk16(__m128i chunk, It dst)
const noexcept
136 auto zero = _mm_setzero_si128();
137 auto lo = _mm_unpacklo_epi8(chunk, zero);
138 auto hi = _mm_unpackhi_epi8(chunk, zero);
140 _mm_storeu_si128(
reinterpret_cast<__m128i *
>(
std::addressof(*dst)), lo);
142 _mm_storeu_si128(
reinterpret_cast<__m128i *
>(
std::addressof(*dst)), hi);