26 using char_type = char16_t;
28 [[nodiscard]] std::endian guess_endian(
void const *ptr,
size_t size, std::endian endian)
const noexcept
30 hi_assert_not_null(ptr);
31 auto *ptr_ =
static_cast<uint8_t
const *
>(ptr);
32 hi_axiom_not_null(ptr_);
35 return std::endian::native;
38 if (ptr_[0] == 0xfe and ptr_[1] == 0xff) {
39 return std::endian::big;
40 }
else if (ptr_[0] == 0xff and ptr_[1] == 0xfe) {
41 return std::endian::little;
46 for (
auto i = 0; i != size; ++i) {
47 count[i % 2] = ptr_[i] == 0 ? count[i % 2] + 1 : 0;
48 if (count[i % 2] >= 8) {
49 return i % 2 == 0 ? std::endian::big : std::endian::little;
57 template<
typename It,
typename EndIt>
62 if (
auto cu = *it++; cu < 0xd800) {
65 }
else if (cu < 0xdc00) {
68 return {0xfffd,
false};
73 if (cu >= 0xdc00 and cu < 0xe000) {
82 return {0xfffd,
false};
86 }
else if (cu < 0xe000) {
88 return {0xfffd,
false};
97 hi_axiom(code_point < 0x11'0000);
98 hi_axiom(not(code_point >= 0xd800 and code_point < 0xe000));
102 template<
typename It>
103 constexpr void write(
char32_t code_point, It& dst)
const noexcept
105 hi_axiom(code_point <= 0x10'ffff);
106 hi_axiom(not(code_point >= 0xd800 and code_point < 0xe000));
117#if defined(HI_HAS_SSE2)
118 template<
typename It>
119 hi_force_inline __m128i read_ascii_chunk16(It it)
const noexcept
122 hilet lo = _mm_loadu_si128(
reinterpret_cast<__m128i
const *
>(
std::addressof(*it)));
124 hilet
hi = _mm_loadu_si128(
reinterpret_cast<__m128i
const *
>(
std::addressof(*it)));
132 hilet sign_lo = _mm_srai_epi16(lo, 15);
133 hilet sign_hi = _mm_srai_epi16(
hi, 15);
134 hilet sign = _mm_packs_epi16(sign_lo, sign_hi);
139 hilet chunk = _mm_packus_epi16(lo,
hi);
144 return _mm_or_si128(chunk, sign);
147 template<
typename It>
148 hi_force_inline
void write_ascii_chunk16(__m128i chunk, It dst)
const noexcept
150 hilet
zero = _mm_setzero_si128();
151 hilet lo = _mm_unpacklo_epi8(chunk,
zero);
152 hilet
hi = _mm_unpackhi_epi8(chunk,
zero);
154 _mm_storeu_si128(
reinterpret_cast<__m128i *
>(
std::addressof(*dst)), lo);