13 using char_type = char32_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] == 0x00 and ptr_[1] == 0x00 and ptr_[2] == 0xfe and ptr_[3] == 0xff) {
25 return std::endian::big;
26 }
else if (ptr_[0] == 0xff and ptr_[1] == 0xfe and ptr_[2] == 0x00 and ptr_[3] == 0x00) {
27 return std::endian::little;
32 for (
auto i = 0; i != size; ++i) {
33 count[i % 4] = ptr_[i] == 0 ? count[i % 4] + 1 : 0;
35 if (i % 4 == 0 and count[0] >= 8) {
36 return std::endian::big;
37 }
else if (i % 4 == 3 and count[3] >= 8) {
38 return std::endian::little;
46 template<
typename It,
typename EndIt>
51 if (
auto cu = *it++; cu < 0xd800) {
54 }
else if (cu < 0xe000) {
56 return {0xfffd,
false};
58 }
else if (cu < 0x11'0000) {
63 return {0xfffd,
false};
69 hi_axiom(code_point < 0x11'0000);
70 hi_axiom(not(code_point >= 0xd800 and code_point < 0xe000));
71 return {uint8_t{1},
true};
75 constexpr void write(
char32_t code_point, It& dst)
const noexcept
77 hi_axiom(code_point < 0x11'0000);
78 hi_axiom(not(code_point >= 0xd800 and code_point < 0xe000));
83#if defined(HI_HAS_SSE2)
85 hi_force_inline __m128i read_ascii_chunk16(It it)
const noexcept
96 hilet lo = _mm_packs_epi32(c0, c1);
97 hilet hi = _mm_packs_epi32(c2, c3);
105 hilet sign_lo = _mm_srai_epi16(lo, 15);
106 hilet sign_hi = _mm_srai_epi16(hi, 15);
107 hilet sign = _mm_packs_epi16(sign_lo, sign_hi);
112 hilet chunk = _mm_packus_epi16(lo, hi);
117 return _mm_or_si128(chunk, sign);
120 template<
typename It>
121 hi_force_inline
void write_ascii_chunk16(__m128i chunk, It dst)
const noexcept
123 hilet zero = _mm_setzero_si128();
124 hilet lo = _mm_unpacklo_epi8(chunk, zero);
125 hilet hi = _mm_unpackhi_epi8(chunk, zero);
127 hilet c0 = _mm_unpacklo_epi8(lo, zero);
128 hilet c1 = _mm_unpackhi_epi8(lo, zero);
129 hilet c2 = _mm_unpacklo_epi8(hi, zero);
130 hilet c3 = _mm_unpackhi_epi8(hi, zero);
132 _mm_storeu_si128(
reinterpret_cast<__m128i *
>(
std::addressof(*dst)), c0);
134 _mm_storeu_si128(
reinterpret_cast<__m128i *
>(
std::addressof(*dst)), c1);
136 _mm_storeu_si128(
reinterpret_cast<__m128i *
>(
std::addressof(*dst)), c2);
138 _mm_storeu_si128(
reinterpret_cast<__m128i *
>(
std::addressof(*dst)), c3);