37 using char_type = char32_t;
39 [[nodiscard]] std::endian guess_endian(
void const *ptr,
size_t size, std::endian endian)
const noexcept
41 hi_assert_not_null(ptr);
42 auto *ptr_ =
static_cast<uint8_t
const *
>(ptr);
43 hi_axiom_not_null(ptr_);
46 return std::endian::native;
49 if (ptr_[0] == 0x00 and ptr_[1] == 0x00 and ptr_[2] == 0xfe and ptr_[3] == 0xff) {
50 return std::endian::big;
51 }
else if (ptr_[0] == 0xff and ptr_[1] == 0xfe and ptr_[2] == 0x00 and ptr_[3] == 0x00) {
52 return std::endian::little;
57 for (
auto i = 0; i != size; ++i) {
58 count[i % 4] = ptr_[i] == 0 ? count[i % 4] + 1 : 0;
60 if (i % 4 == 0 and count[0] >= 8) {
61 return std::endian::big;
62 }
else if (i % 4 == 3 and count[3] >= 8) {
63 return std::endian::little;
71 template<
typename It,
typename EndIt>
76 if (
auto cu = *it++; cu < 0xd800) {
79 }
else if (cu < 0xe000) {
81 return {0xfffd,
false};
83 }
else if (cu < 0x11'0000) {
88 return {0xfffd,
false};
94 hi_axiom(code_point < 0x11'0000);
95 hi_axiom(not(code_point >= 0xd800 and code_point < 0xe000));
96 return {uint8_t{1},
true};
100 constexpr void write(
char32_t code_point, It& dst)
const noexcept
102 hi_axiom(code_point < 0x11'0000);
103 hi_axiom(not(code_point >= 0xd800 and code_point < 0xe000));
108#if defined(HI_HAS_SSE2)
109 template<
typename It>
110 hi_force_inline __m128i read_ascii_chunk16(It it)
const noexcept
113 auto const c0 = _mm_loadu_si128(
reinterpret_cast<__m128i
const *
>(
std::addressof(*it)));
115 auto const c1 = _mm_loadu_si128(
reinterpret_cast<__m128i
const *
>(
std::addressof(*it)));
117 auto const c2 = _mm_loadu_si128(
reinterpret_cast<__m128i
const *
>(
std::addressof(*it)));
119 auto const c3 = _mm_loadu_si128(
reinterpret_cast<__m128i
const *
>(
std::addressof(*it)));
121 auto const lo = _mm_packs_epi32(c0, c1);
122 auto const hi = _mm_packs_epi32(c2, c3);
130 auto const sign_lo = _mm_srai_epi16(lo, 15);
131 auto const sign_hi = _mm_srai_epi16(
hi, 15);
132 auto const sign = _mm_packs_epi16(sign_lo, sign_hi);
137 auto const chunk = _mm_packus_epi16(lo,
hi);
142 return _mm_or_si128(chunk, sign);
145 template<
typename It>
146 hi_force_inline
void write_ascii_chunk16(__m128i chunk, It dst)
const noexcept
148 auto const zero = _mm_setzero_si128();
149 auto const lo = _mm_unpacklo_epi8(chunk,
zero);
150 auto const hi = _mm_unpackhi_epi8(chunk,
zero);
152 auto const c0 = _mm_unpacklo_epi8(lo,
zero);
153 auto const c1 = _mm_unpackhi_epi8(lo,
zero);
154 auto const c2 = _mm_unpacklo_epi8(
hi,
zero);
155 auto const c3 = _mm_unpackhi_epi8(
hi,
zero);
157 _mm_storeu_si128(
reinterpret_cast<__m128i *
>(
std::addressof(*dst)), c0);
159 _mm_storeu_si128(
reinterpret_cast<__m128i *
>(
std::addressof(*dst)), c1);
161 _mm_storeu_si128(
reinterpret_cast<__m128i *
>(
std::addressof(*dst)), c2);
163 _mm_storeu_si128(
reinterpret_cast<__m128i *
>(
std::addressof(*dst)), c3);