81 std::array<T_result,
sizeof...(T_args)> result{};
83 const auto args = std::make_tuple(in_args...);
84 constexpr auto precedence =
expr::get_string_type_precedence<T_args...>();
86 [&] <size_t... index>(std::index_sequence<index...>)
88 const auto convert_arg = [&] <expr::any_string T>(
const size_t in_index,
const T& in_str)
90 if constexpr (expr::is_all_same_v<T_args...>)
92 if constexpr (expr::any_raw_string<T>)
95 result[in_index] = T_result(in_str);
100 result[in_index] = in_str;
105 if constexpr (std::is_same_v<T, T_result>)
108 result[in_index] = in_str;
113 result[in_index] = convert<T_result>(in_str);
118 (convert_arg(index, std::get<index>(args)), ...);
120 (std::make_index_sequence<
sizeof...(T_args)>{});
128 using src_char_t = expr::get_char_type_t<T_str>;
129 using dst_char_t = expr::get_char_type_t<T_result>;
130 using inferred_string_view_t = expr::inferred_string_view_t<T_str>;
132 inferred_string_view_t str_sv{};
134 if constexpr (std::ranges::range<T_str>)
136 str_sv = inferred_string_view_t(in_str.begin(), in_str.end());
138 else if constexpr (std::is_constructible_v<inferred_string_view_t,
const T_str&>)
140 str_sv = inferred_string_view_t(in_str);
147 if constexpr (std::is_same_v<src_char_t, dst_char_t>)
151 if (expr::is_char_encoding_type<src_char_t>(in_src_encoding) &&
152 expr::is_char_encoding_type<dst_char_t>(in_dst_encoding))
154 out_result = T_result(str_sv);
161 out_result = T_result();
165 const auto src_data = str_sv.data();
166 const auto src_length_in_chars = str_sv.size();
167 const auto src_length_in_bytes = src_length_in_chars *
sizeof(src_char_t);
169 const auto transcode = [&](
auto* out_buffer) -> size_t
171 if constexpr (
sizeof(src_char_t) == 1)
173 const auto src =
reinterpret_cast<
const char*>(src_data);
175 if constexpr (
sizeof(dst_char_t) == 1)
177 return src_length_in_bytes;
179 else if constexpr (
sizeof(dst_char_t) == 2)
182 return simdutf::utf16_length_from_utf8(src, src_length_in_chars);
184 return simdutf::convert_utf8_to_utf16(src, src_length_in_chars,
reinterpret_cast<
char16_t*>(out_buffer));
186 else if constexpr (
sizeof(dst_char_t) == 4)
189 return simdutf::utf32_length_from_utf8(src, src_length_in_chars);
191 return simdutf::convert_utf8_to_utf32(src, src_length_in_chars,
reinterpret_cast<
char32_t*>(out_buffer));
194 else if constexpr (
sizeof(src_char_t) == 2)
196 const auto src =
reinterpret_cast<
const char16_t*>(src_data);
198 if constexpr (
sizeof(dst_char_t) == 1)
201 return simdutf::utf8_length_from_utf16(src, src_length_in_chars);
203 return simdutf::convert_utf16_to_utf8(src, src_length_in_chars,
reinterpret_cast<
char*>(out_buffer));
205 else if constexpr (
sizeof(dst_char_t) == 2)
207 return src_length_in_bytes;
209 else if constexpr (
sizeof(dst_char_t) == 4)
212 return simdutf::utf32_length_from_utf16(src, src_length_in_chars);
214 return simdutf::convert_utf16_to_utf32(src, src_length_in_chars,
reinterpret_cast<
char32_t*>(out_buffer));
217 else if constexpr (
sizeof(src_char_t) == 4)
219 const auto src =
reinterpret_cast<
const char32_t*>(src_data);
221 if constexpr (
sizeof(dst_char_t) == 1)
224 return simdutf::utf8_length_from_utf32(src, src_length_in_chars);
226 return simdutf::convert_utf32_to_utf8(src, src_length_in_chars,
reinterpret_cast<
char*>(out_buffer));
228 else if constexpr (
sizeof(dst_char_t) == 2)
231 return simdutf::utf16_length_from_utf32(src, src_length_in_chars);
233 return simdutf::convert_utf32_to_utf16(src, src_length_in_chars,
reinterpret_cast<
char16_t*>(out_buffer));
235 else if constexpr (
sizeof(dst_char_t) == 4)
237 return src_length_in_bytes;
244 const auto expected_length = transcode(
static_cast<dst_char_t*>(
nullptr));
246 if (!expected_length)
249 size_t transcode_length{};
252 if (expected_length == src_length_in_bytes)
254 out_result =
expr::create_inferred_string<T_result>(str_sv);
255 transcode_length = expected_length;
259 out_result.resize(expected_length);
260 transcode_length = transcode(out_result.data());
263 if (!transcode_length)
268 else if (transcode_length < expected_length)
270 out_result.resize(transcode_length);
274 if (!out_result.capacity())
277 const auto dst_char_size = expr::get_encoding_char_size(in_dst_encoding);
283 auto needs_endian_swap =
false;
290 if constexpr (std::endian::native == std::endian::little)
292 needs_endian_swap = is_big_endian;
294 else if constexpr (std::endian::native == std::endian::big)
296 needs_endian_swap = !is_big_endian;
299 if (needs_endian_swap)
301 if (dst_char_size ==
sizeof(
char16_t))
303 auto chars =
reinterpret_cast<
const char16_t*>(out_result.data());
304 const auto chars_length = transcode_length;
306 for (size_t i = 0; i < chars_length; i++)
307 const_cast<
char16_t*>(chars)[i] =
mem::byteswap(chars[i]);
309 else if (dst_char_size ==
sizeof(
char32_t))
311 auto chars =
reinterpret_cast<
const char32_t*>(out_result.data());
312 const auto chars_length = transcode_length;
314 for (size_t i = 0; i < chars_length; i++)
315 const_cast<
char32_t*>(chars)[i] =
mem::byteswap(chars[i]);