98 using char_type = char;
100 [[nodiscard]]
constexpr std::endian guess_endian(
void const *ptr,
size_t size, std::endian endian)
const noexcept
102 return std::endian::native;
105 template<
typename It,
typename EndIt>
109 hi_axiom(it != last);
110 auto const c = char_cast<char8_t>(*it++);
112 case 0x80:
return {0x20ac,
true};
113 case 0x81:
return {0x81,
true};
114 case 0x82:
return {0x201a,
true};
115 case 0x83:
return {0x0192,
true};
116 case 0x84:
return {0x201e,
true};
117 case 0x85:
return {0x2026,
true};
118 case 0x86:
return {0x2020,
true};
119 case 0x87:
return {0x2021,
true};
120 case 0x88:
return {0x02c6,
true};
121 case 0x89:
return {0x2030,
true};
122 case 0x8a:
return {0x0160,
true};
123 case 0x8b:
return {0x2039,
true};
124 case 0x8c:
return {0x0152,
true};
125 case 0x8d:
return {0x8d,
true};
126 case 0x8e:
return {0x017d,
true};
127 case 0x8f:
return {0x8f,
true};
129 case 0x90:
return {0x90,
true};
130 case 0x91:
return {0x2018,
true};
131 case 0x92:
return {0x2019,
true};
132 case 0x93:
return {0x201c,
true};
133 case 0x94:
return {0x201d,
true};
134 case 0x95:
return {0x2022,
true};
135 case 0x96:
return {0x2013,
true};
136 case 0x97:
return {0x2014,
true};
137 case 0x98:
return {0x02dc,
true};
138 case 0x99:
return {0x2122,
true};
139 case 0x9a:
return {0x0161,
true};
140 case 0x9b:
return {0x203a,
true};
141 case 0x9c:
return {0x0153,
true};
142 case 0x9d:
return {0x9d,
true};
143 case 0x9e:
return {0x017e,
true};
144 case 0x9f:
return {0x0178,
true};
145 default:
return {c,
true};
150 constexpr static auto range_0000_02DC = detail::cp_1252_make_table_0000_02DC();
151 constexpr static auto range_2000_2122 = detail::cp_1252_make_table_2000_2122();
155 hi_axiom(code_point < 0x11'0000);
156 hi_axiom(not(code_point >= 0xd800 and code_point < 0xe000));
158 if (code_point < 0x2dd) {
159 if (code_point == 0x3f) {
160 return {uint8_t{1},
true};
162 return {uint8_t{1}, range_0000_02DC[code_point] != 0x3f};
164 }
else if (code_point < 0x2000) {
165 return {uint8_t{1},
false};
167 }
else if (code_point < 0x2123) {
168 return {uint8_t{1}, range_2000_2122[wide_cast<size_t>(code_point) - 0x2000] != 0x3f};
171 return {uint8_t{1},
false};
175 template<
typename It>
176 constexpr void write(
char32_t code_point, It& dst)
const noexcept
178 hi_axiom(code_point < 0x11'0000);
179 hi_axiom(not(code_point >= 0xd800 and code_point < 0xe000));
181 if (code_point < 0x2dd) {
182 *dst++ = char_cast<char_type>(range_0000_02DC[code_point]);
184 }
else if (code_point < 0x2000) {
185 *dst++ = char_cast<char_type>(0x3f);
187 }
else if (code_point < 0x2123) {
188 *dst++ = char_cast<char_type>(range_2000_2122[code_point - 0x2000]);
191 *dst++ = char_cast<char_type>(0x3f);
195#if defined(HI_HAS_SSE2)
196 template<
typename It>
197 hi_force_inline __m128i read_ascii_chunk16(It it)
const noexcept
199 return _mm_loadu_si128(
reinterpret_cast<__m128i
const *
>(
std::addressof(*it)));
202 template<
typename It>
203 hi_force_inline
void write_ascii_chunk16(__m128i chunk, It dst)
const noexcept
205 _mm_storeu_si128(
reinterpret_cast<__m128i *
>(
std::addressof(*dst)), chunk);