27 using char_type = char32_t;
29 [[nodiscard]] std::endian guess_endian(
void const *ptr,
size_t size, std::endian endian)
const noexcept
31 hi_assert_not_null(ptr);
32 auto *ptr_ =
static_cast<uint8_t
const *
>(ptr);
33 hi_axiom_not_null(ptr_);
36 return std::endian::native;
39 if (ptr_[0] == 0x00 and ptr_[1] == 0x00 and ptr_[2] == 0xfe and ptr_[3] == 0xff) {
40 return std::endian::big;
41 }
else if (ptr_[0] == 0xff and ptr_[1] == 0xfe and ptr_[2] == 0x00 and ptr_[3] == 0x00) {
42 return std::endian::little;
47 for (
auto i = 0; i != size; ++i) {
48 count[i % 4] = ptr_[i] == 0 ? count[i % 4] + 1 : 0;
50 if (i % 4 == 0 and count[0] >= 8) {
51 return std::endian::big;
52 }
else if (i % 4 == 3 and count[3] >= 8) {
53 return std::endian::little;
61 template<
typename It,
typename EndIt>
66 if (
auto cu = *it++; cu < 0xd800) {
69 }
else if (cu < 0xe000) {
71 return {0xfffd,
false};
73 }
else if (cu < 0x11'0000) {
78 return {0xfffd,
false};
84 hi_axiom(code_point < 0x11'0000);
85 hi_axiom(not(code_point >= 0xd800 and code_point < 0xe000));
86 return {uint8_t{1},
true};
90 constexpr void write(
char32_t code_point, It& dst)
const noexcept
92 hi_axiom(code_point < 0x11'0000);
93 hi_axiom(not(code_point >= 0xd800 and code_point < 0xe000));
98#if defined(HI_HAS_SSE2)
100 hi_force_inline __m128i read_ascii_chunk16(It it)
const noexcept
103 hilet c0 = _mm_loadu_si128(
reinterpret_cast<__m128i
const *
>(
std::addressof(*it)));
105 hilet c1 = _mm_loadu_si128(
reinterpret_cast<__m128i
const *
>(
std::addressof(*it)));
107 hilet c2 = _mm_loadu_si128(
reinterpret_cast<__m128i
const *
>(
std::addressof(*it)));
109 hilet c3 = _mm_loadu_si128(
reinterpret_cast<__m128i
const *
>(
std::addressof(*it)));
111 hilet lo = _mm_packs_epi32(c0, c1);
112 hilet
hi = _mm_packs_epi32(c2, c3);
120 hilet sign_lo = _mm_srai_epi16(lo, 15);
121 hilet sign_hi = _mm_srai_epi16(
hi, 15);
122 hilet sign = _mm_packs_epi16(sign_lo, sign_hi);
127 hilet chunk = _mm_packus_epi16(lo,
hi);
132 return _mm_or_si128(chunk, sign);
135 template<
typename It>
136 hi_force_inline
void write_ascii_chunk16(__m128i chunk, It dst)
const noexcept
138 hilet
zero = _mm_setzero_si128();
139 hilet lo = _mm_unpacklo_epi8(chunk,
zero);
140 hilet
hi = _mm_unpackhi_epi8(chunk,
zero);
142 hilet c0 = _mm_unpacklo_epi8(lo,
zero);
143 hilet c1 = _mm_unpackhi_epi8(lo,
zero);
144 hilet c2 = _mm_unpacklo_epi8(
hi,
zero);
145 hilet c3 = _mm_unpackhi_epi8(
hi,
zero);
147 _mm_storeu_si128(
reinterpret_cast<__m128i *
>(
std::addressof(*dst)), c0);
149 _mm_storeu_si128(
reinterpret_cast<__m128i *
>(
std::addressof(*dst)), c1);
151 _mm_storeu_si128(
reinterpret_cast<__m128i *
>(
std::addressof(*dst)), c2);
153 _mm_storeu_si128(
reinterpret_cast<__m128i *
>(
std::addressof(*dst)), c3);