36 using char_type = char16_t;
38 [[nodiscard]] std::endian guess_endian(
void const *ptr,
size_t size, std::endian endian)
const noexcept
40 hi_assert_not_null(ptr);
41 auto *ptr_ =
static_cast<uint8_t
const *
>(ptr);
42 hi_axiom_not_null(ptr_);
45 return std::endian::native;
48 if (ptr_[0] == 0xfe and ptr_[1] == 0xff) {
49 return std::endian::big;
50 }
else if (ptr_[0] == 0xff and ptr_[1] == 0xfe) {
51 return std::endian::little;
56 for (
auto i = 0; i != size; ++i) {
57 count[i % 2] = ptr_[i] == 0 ? count[i % 2] + 1 : 0;
58 if (count[i % 2] >= 8) {
59 return i % 2 == 0 ? std::endian::big : std::endian::little;
67 template<
typename It,
typename EndIt>
72 if (
auto cu = *it++; cu < 0xd800) {
73 return {char_cast<char32_t>(cu),
true};
75 }
else if (cu < 0xdc00) {
78 return {0xfffd,
false};
81 auto cp = char_cast<char32_t>(cu & 0x03ff);
83 if (cu >= 0xdc00 and cu < 0xe000) {
92 return {0xfffd,
false};
96 }
else if (cu < 0xe000) {
98 return {0xfffd,
false};
107 hi_axiom(code_point < 0x11'0000);
108 hi_axiom(not(code_point >= 0xd800 and code_point < 0xe000));
109 return {truncate<uint8_t>((code_point >= 0x01'0000) + 1),
true};
112 template<
typename It>
113 constexpr void write(
char32_t code_point, It& dst)
const noexcept
115 hi_axiom(code_point <= 0x10'ffff);
116 hi_axiom(not(code_point >= 0xd800 and code_point < 0xe000));
118 if (
auto const tmp = truncate<int32_t>(code_point) - 0x1'0000; tmp >= 0) {
119 *dst++ = char_cast<char16_t>((tmp >> 10) + 0xd800);
120 *dst++ = char_cast<char16_t>((tmp & 0x3ff) + 0xdc00);
123 *dst++ = char_cast<char16_t>(code_point);
127#if defined(HI_HAS_SSE2)
128 template<
typename It>
129 hi_force_inline __m128i read_ascii_chunk16(It it)
const noexcept
132 auto const lo = _mm_loadu_si128(
reinterpret_cast<__m128i
const *
>(
std::addressof(*it)));
134 auto const hi = _mm_loadu_si128(
reinterpret_cast<__m128i
const *
>(
std::addressof(*it)));
142 auto const sign_lo = _mm_srai_epi16(lo, 15);
143 auto const sign_hi = _mm_srai_epi16(
hi, 15);
144 auto const sign = _mm_packs_epi16(sign_lo, sign_hi);
149 auto const chunk = _mm_packus_epi16(lo,
hi);
154 return _mm_or_si128(chunk, sign);
157 template<
typename It>
158 hi_force_inline
void write_ascii_chunk16(__m128i chunk, It dst)
const noexcept
160 auto const zero = _mm_setzero_si128();
161 auto const lo = _mm_unpacklo_epi8(chunk,
zero);
162 auto const hi = _mm_unpackhi_epi8(chunk,
zero);
164 _mm_storeu_si128(
reinterpret_cast<__m128i *
>(
std::addressof(*dst)), lo);