1#ifndef SIMDUTF_IMPLEMENTATION_H
2#define SIMDUTF_IMPLEMENTATION_H
3#if !defined(SIMDUTF_NO_THREADS)
6#ifdef SIMDUTF_INTERNAL_TESTS
9#include "simdutf/common_defs.h"
10#include "simdutf/compiler_check.h"
11#include "simdutf/encoding_types.h"
12#include "simdutf/error.h"
13#include "simdutf/internal/isadetection.h"
18 #include <type_traits>
32#ifndef SIMDUTF_FEATURE_DETECT_ENCODING
33 #define SIMDUTF_FEATURE_DETECT_ENCODING 1
35#ifndef SIMDUTF_FEATURE_ASCII
36 #define SIMDUTF_FEATURE_ASCII 1
38#ifndef SIMDUTF_FEATURE_LATIN1
39 #define SIMDUTF_FEATURE_LATIN1 1
41#ifndef SIMDUTF_FEATURE_UTF8
42 #define SIMDUTF_FEATURE_UTF8 1
44#ifndef SIMDUTF_FEATURE_UTF16
45 #define SIMDUTF_FEATURE_UTF16 1
47#ifndef SIMDUTF_FEATURE_UTF32
48 #define SIMDUTF_FEATURE_UTF32 1
50#ifndef SIMDUTF_FEATURE_BASE64
51 #define SIMDUTF_FEATURE_BASE64 1
59constexpr std::size_t min(std::size_t a, std::size_t b) {
62template <
typename T,
typename U>
63constexpr std::size_t min(
const T &a,
const U &b) =
delete;
68#if SIMDUTF_CPLUSPLUS23
69 #include <simdutf/constexpr_ptr.h>
81concept byte_like = std::is_same_v<T, std::byte> ||
82 std::is_same_v<T, char> ||
83 std::is_same_v<T, signed char> ||
84 std::is_same_v<T, unsigned char> ||
85 std::is_same_v<T, char8_t>;
88concept is_byte_like = byte_like<std::remove_cvref_t<T>>;
91concept is_pointer = std::is_pointer_v<T>;
99concept input_span_of_byte_like =
requires(
const T &t) {
100 { t.size() }
noexcept -> std::convertible_to<std::size_t>;
101 { t.data() }
noexcept -> is_pointer;
102 { *t.data() }
noexcept -> is_byte_like;
106concept is_mutable = !std::is_const_v<std::remove_reference_t<T>>;
112concept output_span_of_byte_like =
requires(T &t) {
113 { t.size() }
noexcept -> std::convertible_to<std::size_t>;
114 { t.data() }
noexcept -> is_pointer;
115 { *t.data() }
noexcept -> is_byte_like;
116 { *t.data() }
noexcept -> is_mutable;
124template <
class InputPtr>
125concept indexes_into_byte_like =
requires(InputPtr p) {
126 { std::decay_t<
decltype(p[0])>{} } -> simdutf::detail::byte_like;
128template <
class InputPtr>
129concept indexes_into_utf16 =
requires(InputPtr p) {
130 { std::decay_t<
decltype(p[0])>{} } -> std::same_as<char16_t>;
132template <
class InputPtr>
133concept indexes_into_utf32 =
requires(InputPtr p) {
134 { std::decay_t<
decltype(p[0])>{} } -> std::same_as<char32_t>;
137template <
class InputPtr>
138concept index_assignable_from_char =
requires(InputPtr p,
char s) {
146template <
class InputPtr>
147concept indexes_into_uint32 =
requires(InputPtr p) {
148 { std::decay_t<
decltype(p[0])>{} } -> std::same_as<std::uint32_t>;
156#include <simdutf/scalar/swap_bytes.h>
157#include <simdutf/scalar/ascii.h>
158#include <simdutf/scalar/atomic_util.h>
159#include <simdutf/scalar/latin1.h>
160#include <simdutf/scalar/latin1_to_utf16/latin1_to_utf16.h>
161#include <simdutf/scalar/latin1_to_utf32/latin1_to_utf32.h>
162#include <simdutf/scalar/latin1_to_utf8/latin1_to_utf8.h>
163#include <simdutf/scalar/utf16.h>
164#include <simdutf/scalar/utf16_to_latin1/utf16_to_latin1.h>
165#include <simdutf/scalar/utf16_to_latin1/valid_utf16_to_latin1.h>
166#include <simdutf/scalar/utf16_to_utf32/utf16_to_utf32.h>
167#include <simdutf/scalar/utf16_to_utf32/valid_utf16_to_utf32.h>
168#include <simdutf/scalar/utf16_to_utf8/utf16_to_utf8.h>
169#include <simdutf/scalar/utf16_to_utf8/valid_utf16_to_utf8.h>
170#include <simdutf/scalar/utf32.h>
171#include <simdutf/scalar/utf32_to_latin1/utf32_to_latin1.h>
172#include <simdutf/scalar/utf32_to_latin1/valid_utf32_to_latin1.h>
173#include <simdutf/scalar/utf32_to_utf16/utf32_to_utf16.h>
174#include <simdutf/scalar/utf32_to_utf16/valid_utf32_to_utf16.h>
175#include <simdutf/scalar/utf32_to_utf8/utf32_to_utf8.h>
176#include <simdutf/scalar/utf32_to_utf8/valid_utf32_to_utf8.h>
177#include <simdutf/scalar/utf8.h>
178#include <simdutf/scalar/utf8_to_latin1/utf8_to_latin1.h>
179#include <simdutf/scalar/utf8_to_latin1/valid_utf8_to_latin1.h>
180#include <simdutf/scalar/utf8_to_utf16/utf8_to_utf16.h>
181#include <simdutf/scalar/utf8_to_utf16/valid_utf8_to_utf16.h>
182#include <simdutf/scalar/utf8_to_utf32/utf8_to_utf32.h>
183#include <simdutf/scalar/utf8_to_utf32/valid_utf8_to_utf32.h>
190#if SIMDUTF_FEATURE_DETECT_ENCODING
201simdutf_warn_unused simdutf::encoding_type
203simdutf_really_inline simdutf_warn_unused simdutf::encoding_type
219simdutf_really_inline simdutf_warn_unused simdutf::encoding_type
221 const detail::input_span_of_byte_like
auto &input)
noexcept {
239 size_t length)
noexcept;
240simdutf_really_inline simdutf_warn_unused
int
245simdutf_really_inline simdutf_warn_unused
int
246detect_encodings(
const detail::input_span_of_byte_like
auto &input)
noexcept {
253#if SIMDUTF_FEATURE_UTF8 || SIMDUTF_FEATURE_DETECT_ENCODING
265simdutf_warn_unused
bool validate_utf8(
const char *buf,
size_t len)
noexcept;
267simdutf_constexpr23 simdutf_really_inline simdutf_warn_unused
bool
268validate_utf8(
const detail::input_span_of_byte_like
auto &input)
noexcept {
269 #if SIMDUTF_CPLUSPLUS23
271 return scalar::utf8::validate(
272 detail::constexpr_cast_ptr<uint8_t>(input.data()), input.size());
276 return validate_utf8(
reinterpret_cast<const char *
>(input.data()),
283#if SIMDUTF_FEATURE_UTF8
297 size_t len)
noexcept;
299simdutf_really_inline simdutf_constexpr23 simdutf_warn_unused
result
301 const detail::input_span_of_byte_like
auto &input)
noexcept {
302 #if SIMDUTF_CPLUSPLUS23
304 return scalar::utf8::validate_with_errors(
305 detail::constexpr_cast_ptr<uint8_t>(input.data()), input.size());
310 reinterpret_cast<const char *
>(input.data()), input.size());
316#if SIMDUTF_FEATURE_ASCII
328simdutf_really_inline simdutf_warn_unused simdutf_constexpr23
bool
329validate_ascii(
const detail::input_span_of_byte_like
auto &input)
noexcept {
330 #if SIMDUTF_CPLUSPLUS23
332 return scalar::ascii::validate(
333 detail::constexpr_cast_ptr<std::uint8_t>(input.data()), input.size());
337 return validate_ascii(
reinterpret_cast<const char *
>(input.data()),
357 size_t len)
noexcept;
359simdutf_really_inline simdutf_warn_unused simdutf_constexpr23
result
361 const detail::input_span_of_byte_like
auto &input)
noexcept {
362 #if SIMDUTF_CPLUSPLUS23
364 return scalar::ascii::validate_with_errors(
365 detail::constexpr_cast_ptr<std::uint8_t>(input.data()), input.size());
370 reinterpret_cast<const char *
>(input.data()), input.size());
376#if SIMDUTF_FEATURE_UTF16 && SIMDUTF_FEATURE_ASCII
389 size_t len)
noexcept;
391simdutf_really_inline simdutf_warn_unused simdutf_constexpr23
bool
393 #if SIMDUTF_CPLUSPLUS23
395 return scalar::utf16::validate_as_ascii<endianness::NATIVE>(input.data(),
417 size_t len)
noexcept;
419simdutf_really_inline simdutf_warn_unused simdutf_constexpr23
bool
421 #if SIMDUTF_CPLUSPLUS23
423 return scalar::utf16::validate_as_ascii<endianness::BIG>(input.data(),
445 size_t len)
noexcept;
447simdutf_really_inline simdutf_warn_unused simdutf_constexpr23
bool
449 #if SIMDUTF_CPLUSPLUS23
451 return scalar::utf16::validate_as_ascii<endianness::LITTLE>(input.data(),
462#if SIMDUTF_FEATURE_UTF16
478 size_t len)
noexcept;
480simdutf_really_inline simdutf_warn_unused simdutf_constexpr23
bool
482 #if SIMDUTF_CPLUSPLUS23
484 return scalar::utf16::validate<endianness::NATIVE>(input.data(),
495#if SIMDUTF_FEATURE_UTF16 || SIMDUTF_FEATURE_DETECT_ENCODING
511 size_t len)
noexcept;
513simdutf_really_inline simdutf_constexpr23 simdutf_warn_unused
bool
515 #if SIMDUTF_CPLUSPLUS23
517 return scalar::utf16::validate<endianness::LITTLE>(input.data(),
528#if SIMDUTF_FEATURE_UTF16
544 size_t len)
noexcept;
546simdutf_really_inline simdutf_warn_unused simdutf_constexpr23
bool
548 #if SIMDUTF_CPLUSPLUS23
550 return scalar::utf16::validate<endianness::BIG>(input.data(), input.size());
577 size_t len)
noexcept;
579simdutf_really_inline simdutf_warn_unused simdutf_constexpr23
result
581 #if SIMDUTF_CPLUSPLUS23
583 return scalar::utf16::validate_with_errors<endianness::NATIVE>(
584 input.data(), input.size());
610 size_t len)
noexcept;
612simdutf_really_inline simdutf_warn_unused simdutf_constexpr23
result
614 #if SIMDUTF_CPLUSPLUS23
616 return scalar::utf16::validate_with_errors<endianness::LITTLE>(
617 input.data(), input.size());
643 size_t len)
noexcept;
645simdutf_really_inline simdutf_warn_unused simdutf_constexpr23
result
647 #if SIMDUTF_CPLUSPLUS23
649 return scalar::utf16::validate_with_errors<endianness::BIG>(input.data(),
672 char16_t *output)
noexcept;
674simdutf_really_inline simdutf_constexpr23
void
676 std::span<char16_t> output)
noexcept {
677 #if SIMDUTF_CPLUSPLUS23
679 scalar::utf16::to_well_formed_utf16<endianness::LITTLE>(
680 input.data(), input.size(), output.data());
702 char16_t *output)
noexcept;
704simdutf_really_inline simdutf_constexpr23
void
706 std::span<char16_t> output)
noexcept {
707 #if SIMDUTF_CPLUSPLUS23
709 scalar::utf16::to_well_formed_utf16<endianness::BIG>(
710 input.data(), input.size(), output.data());
732 char16_t *output)
noexcept;
734simdutf_really_inline simdutf_constexpr23
void
736 std::span<char16_t> output)
noexcept {
737 #if SIMDUTF_CPLUSPLUS23
739 scalar::utf16::to_well_formed_utf16<endianness::NATIVE>(
740 input.data(), input.size(), output.data());
751#if SIMDUTF_FEATURE_UTF32 || SIMDUTF_FEATURE_DETECT_ENCODING
767 size_t len)
noexcept;
769simdutf_really_inline simdutf_warn_unused simdutf_constexpr23
bool
771 #if SIMDUTF_CPLUSPLUS23
773 return scalar::utf32::validate(
774 detail::constexpr_cast_ptr<std::uint32_t>(input.data()), input.size());
784#if SIMDUTF_FEATURE_UTF32
802 size_t len)
noexcept;
804simdutf_really_inline simdutf_warn_unused simdutf_constexpr23
result
806 #if SIMDUTF_CPLUSPLUS23
808 return scalar::utf32::validate_with_errors(
809 detail::constexpr_cast_ptr<std::uint32_t>(input.data()), input.size());
819#if SIMDUTF_FEATURE_UTF8 && SIMDUTF_FEATURE_LATIN1
832 char *utf8_output)
noexcept;
834simdutf_really_inline simdutf_warn_unused simdutf_constexpr23
size_t
836 const detail::input_span_of_byte_like
auto &latin1_input,
837 detail::output_span_of_byte_like
auto &&utf8_output)
noexcept {
838 #if SIMDUTF_CPLUSPLUS23
840 return scalar::latin1_to_utf8::convert(
841 detail::constexpr_cast_ptr<char>(latin1_input.data()),
843 detail::constexpr_cast_writeptr<char>(utf8_output.data()));
848 reinterpret_cast<const char *
>(latin1_input.data()),
849 latin1_input.size(),
reinterpret_cast<char *
>(utf8_output.data()));
873simdutf_warn_unused
size_t
875 size_t utf8_len)
noexcept;
877simdutf_really_inline simdutf_warn_unused simdutf_constexpr23
size_t
879 const detail::input_span_of_byte_like
auto &input,
880 detail::output_span_of_byte_like
auto &&utf8_output)
noexcept {
887 #if SIMDUTF_CPLUSPLUS23
889 return scalar::latin1_to_utf8::convert_safe_constexpr(
890 input.data(), input.size(), utf8_output.data(), utf8_output.size());
895 reinterpret_cast<const char *
>(input.data()), input.size(),
896 reinterpret_cast<char *
>(utf8_output.data()), utf8_output.size());
915 const char *input,
size_t length,
char *utf8_output,
916 size_t utf8_len)
noexcept;
918simdutf_really_inline simdutf_warn_unused simdutf_constexpr23
full_result
920 const detail::input_span_of_byte_like
auto &input,
921 detail::output_span_of_byte_like
auto &&utf8_output)
noexcept {
922 #if SIMDUTF_CPLUSPLUS23
924 return scalar::latin1_to_utf8::convert_safe_with_details_constexpr(
925 input.data(), input.size(), utf8_output.data(), utf8_output.size());
930 reinterpret_cast<const char *
>(input.data()), input.size(),
931 reinterpret_cast<char *
>(utf8_output.data()), utf8_output.size());
937#if SIMDUTF_FEATURE_UTF16 && SIMDUTF_FEATURE_LATIN1
949 const char *input,
size_t length,
char16_t *utf16_output)
noexcept;
951simdutf_really_inline simdutf_warn_unused simdutf_constexpr23
size_t
953 const detail::input_span_of_byte_like
auto &latin1_input,
954 std::span<char16_t> utf16_output)
noexcept {
955 #if SIMDUTF_CPLUSPLUS23
957 return scalar::latin1_to_utf16::convert<endianness::LITTLE>(
958 latin1_input.data(), latin1_input.size(), utf16_output.data());
963 reinterpret_cast<const char *
>(latin1_input.data()),
964 latin1_input.size(), utf16_output.data());
980 const char *input,
size_t length,
char16_t *utf16_output)
noexcept;
982simdutf_really_inline simdutf_warn_unused simdutf_constexpr23
size_t
984 std::span<char16_t> output)
noexcept {
985 #if SIMDUTF_CPLUSPLUS23
987 return scalar::latin1_to_utf16::convert<endianness::BIG>(
988 input.data(), input.size(), output.data());
993 reinterpret_cast<const char *
>(input.data()), input.size(),
1006simdutf_really_inline simdutf_warn_unused simdutf_constexpr23
size_t
1019simdutf_really_inline simdutf_warn_unused simdutf_constexpr23
size_t
1025#if SIMDUTF_FEATURE_UTF32 && SIMDUTF_FEATURE_LATIN1
1037 const char *input,
size_t length,
char32_t *utf32_buffer)
noexcept;
1039simdutf_really_inline simdutf_warn_unused simdutf_constexpr23
size_t
1041 const detail::input_span_of_byte_like
auto &latin1_input,
1042 std::span<char32_t> utf32_output)
noexcept {
1043 #if SIMDUTF_CPLUSPLUS23
1045 return scalar::latin1_to_utf32::convert(
1046 latin1_input.data(), latin1_input.size(), utf32_output.data());
1051 reinterpret_cast<const char *
>(latin1_input.data()),
1052 latin1_input.size(), utf32_output.data());
1058#if SIMDUTF_FEATURE_UTF8 && SIMDUTF_FEATURE_LATIN1
1073 char *latin1_output)
noexcept;
1075simdutf_really_inline simdutf_warn_unused simdutf_constexpr23
size_t
1077 const detail::input_span_of_byte_like
auto &input,
1078 detail::output_span_of_byte_like
auto &&output)
noexcept {
1079 #if SIMDUTF_CPLUSPLUS23
1081 return scalar::utf8_to_latin1::convert(input.data(), input.size(),
1088 reinterpret_cast<char *
>(output.data()));
1094#if SIMDUTF_FEATURE_UTF8 && SIMDUTF_FEATURE_UTF16
1109 const char *input,
size_t length,
char16_t *utf16_output)
noexcept;
1111simdutf_really_inline simdutf_warn_unused simdutf_constexpr23
size_t
1113 std::span<char16_t> output)
noexcept {
1114 #if SIMDUTF_CPLUSPLUS23
1116 return scalar::utf8_to_utf16::convert<endianness::NATIVE>(
1117 input.data(), input.size(), output.data());
1122 input.size(), output.data());
1145 const char16_t *input,
size_t length)
noexcept;
1147simdutf_really_inline simdutf_constexpr23 simdutf_warn_unused
result
1149 std::span<const char16_t> valid_utf16_input)
noexcept {
1150 #if SIMDUTF_CPLUSPLUS23
1152 return scalar::utf16::utf8_length_from_utf16_with_replacement<
1153 endianness::LITTLE>(valid_utf16_input.data(), valid_utf16_input.size());
1158 valid_utf16_input.size());
1181 const char16_t *input,
size_t length)
noexcept;
1183simdutf_really_inline simdutf_warn_unused simdutf_constexpr23
result
1185 std::span<const char16_t> valid_utf16_input)
noexcept {
1186 #if SIMDUTF_CPLUSPLUS23
1188 return scalar::utf16::utf8_length_from_utf16_with_replacement<
1189 endianness::BIG>(valid_utf16_input.data(), valid_utf16_input.size());
1194 valid_utf16_input.size());
1201#if SIMDUTF_FEATURE_UTF16 && SIMDUTF_FEATURE_LATIN1
1211 const char *input,
size_t length,
char16_t *utf16_output)
noexcept;
1213simdutf_really_inline simdutf_warn_unused simdutf_constexpr23
size_t
1215 std::span<char16_t> output)
noexcept {
1216 #if SIMDUTF_CPLUSPLUS23
1218 return scalar::latin1_to_utf16::convert<endianness::NATIVE>(
1219 input.data(), input.size(), output.data());
1224 input.size(), output.data());
1230#if SIMDUTF_FEATURE_UTF8 && SIMDUTF_FEATURE_UTF16
1244 const char *input,
size_t length,
char16_t *utf16_output)
noexcept;
1246simdutf_really_inline simdutf_warn_unused simdutf_constexpr23
size_t
1248 std::span<char16_t> utf16_output)
noexcept {
1249 #if SIMDUTF_CPLUSPLUS23
1251 return scalar::utf8_to_utf16::convert<endianness::LITTLE>(
1252 utf8_input.data(), utf8_input.size(), utf16_output.data());
1257 reinterpret_cast<const char *
>(utf8_input.data()), utf8_input.size(),
1258 utf16_output.data());
1276 const char *input,
size_t length,
char16_t *utf16_output)
noexcept;
1278simdutf_really_inline simdutf_warn_unused simdutf_constexpr23
size_t
1280 std::span<char16_t> utf16_output)
noexcept {
1282 #if SIMDUTF_CPLUSPLUS23
1284 return scalar::utf8_to_utf16::convert<endianness::BIG>(
1285 utf8_input.data(), utf8_input.size(), utf16_output.data());
1290 reinterpret_cast<const char *
>(utf8_input.data()), utf8_input.size(),
1291 utf16_output.data());
1297#if SIMDUTF_FEATURE_UTF8 && SIMDUTF_FEATURE_LATIN1
1315 const char *input,
size_t length,
char *latin1_output)
noexcept;
1317simdutf_really_inline simdutf_warn_unused simdutf_constexpr23
result
1319 const detail::input_span_of_byte_like
auto &utf8_input,
1320 detail::output_span_of_byte_like
auto &&latin1_output)
noexcept {
1321 #if SIMDUTF_CPLUSPLUS23
1323 return scalar::utf8_to_latin1::convert_with_errors(
1324 utf8_input.data(), utf8_input.size(), latin1_output.data());
1329 reinterpret_cast<const char *
>(utf8_input.data()), utf8_input.size(),
1330 reinterpret_cast<char *
>(latin1_output.data()));
1336#if SIMDUTF_FEATURE_UTF8 && SIMDUTF_FEATURE_UTF16
1353 const char *input,
size_t length,
char16_t *utf16_output)
noexcept;
1355simdutf_really_inline simdutf_warn_unused simdutf_constexpr23
result
1357 const detail::input_span_of_byte_like
auto &utf8_input,
1358 std::span<char16_t> utf16_output)
noexcept {
1359 #if SIMDUTF_CPLUSPLUS23
1361 return scalar::utf8_to_utf16::convert_with_errors<endianness::NATIVE>(
1362 utf8_input.data(), utf8_input.size(), utf16_output.data());
1367 reinterpret_cast<const char *
>(utf8_input.data()), utf8_input.size(),
1368 utf16_output.data());
1388 const char *input,
size_t length,
char16_t *utf16_output)
noexcept;
1390simdutf_really_inline simdutf_warn_unused simdutf_constexpr23
result
1392 const detail::input_span_of_byte_like
auto &utf8_input,
1393 std::span<char16_t> utf16_output)
noexcept {
1394 #if SIMDUTF_CPLUSPLUS23
1396 return scalar::utf8_to_utf16::convert_with_errors<endianness::LITTLE>(
1397 utf8_input.data(), utf8_input.size(), utf16_output.data());
1402 reinterpret_cast<const char *
>(utf8_input.data()), utf8_input.size(),
1403 utf16_output.data());
1423 const char *input,
size_t length,
char16_t *utf16_output)
noexcept;
1425simdutf_really_inline simdutf_warn_unused simdutf_constexpr23
result
1427 const detail::input_span_of_byte_like
auto &utf8_input,
1428 std::span<char16_t> utf16_output)
noexcept {
1429 #if SIMDUTF_CPLUSPLUS23
1431 return scalar::utf8_to_utf16::convert_with_errors<endianness::BIG>(
1432 utf8_input.data(), utf8_input.size(), utf16_output.data());
1437 reinterpret_cast<const char *
>(utf8_input.data()), utf8_input.size(),
1438 utf16_output.data());
1444#if SIMDUTF_FEATURE_UTF8 && SIMDUTF_FEATURE_UTF32
1458 const char *input,
size_t length,
char32_t *utf32_output)
noexcept;
1460simdutf_really_inline simdutf_warn_unused simdutf_constexpr23
size_t
1462 std::span<char32_t> utf32_output)
noexcept {
1463 #if SIMDUTF_CPLUSPLUS23
1465 return scalar::utf8_to_utf32::convert(utf8_input.data(), utf8_input.size(),
1466 utf32_output.data());
1471 reinterpret_cast<const char *
>(utf8_input.data()), utf8_input.size(),
1472 utf32_output.data());
1492 const char *input,
size_t length,
char32_t *utf32_output)
noexcept;
1494simdutf_really_inline simdutf_warn_unused simdutf_constexpr23
result
1496 const detail::input_span_of_byte_like
auto &utf8_input,
1497 std::span<char32_t> utf32_output)
noexcept {
1498 #if SIMDUTF_CPLUSPLUS23
1500 return scalar::utf8_to_utf32::convert_with_errors(
1501 utf8_input.data(), utf8_input.size(), utf32_output.data());
1506 reinterpret_cast<const char *
>(utf8_input.data()), utf8_input.size(),
1507 utf32_output.data());
1513#if SIMDUTF_FEATURE_UTF8 && SIMDUTF_FEATURE_LATIN1
1534 const char *input,
size_t length,
char *latin1_output)
noexcept;
1536simdutf_really_inline simdutf_warn_unused simdutf_constexpr23
size_t
1538 const detail::input_span_of_byte_like
auto &valid_utf8_input,
1539 detail::output_span_of_byte_like
auto &&latin1_output)
noexcept {
1540 #if SIMDUTF_CPLUSPLUS23
1542 return scalar::utf8_to_latin1::convert_valid(
1543 valid_utf8_input.data(), valid_utf8_input.size(), latin1_output.data());
1548 reinterpret_cast<const char *
>(valid_utf8_input.data()),
1549 valid_utf8_input.size(), latin1_output.data());
1555#if SIMDUTF_FEATURE_UTF8 && SIMDUTF_FEATURE_UTF16
1567 const char *input,
size_t length,
char16_t *utf16_buffer)
noexcept;
1569simdutf_really_inline simdutf_warn_unused simdutf_constexpr23
size_t
1571 const detail::input_span_of_byte_like
auto &valid_utf8_input,
1572 std::span<char16_t> utf16_output)
noexcept {
1573 #if SIMDUTF_CPLUSPLUS23
1575 return scalar::utf8_to_utf16::convert_valid<endianness::NATIVE>(
1576 valid_utf8_input.data(), valid_utf8_input.size(), utf16_output.data());
1581 reinterpret_cast<const char *
>(valid_utf8_input.data()),
1582 valid_utf8_input.size(), utf16_output.data());
1598 const char *input,
size_t length,
char16_t *utf16_buffer)
noexcept;
1600simdutf_really_inline simdutf_warn_unused simdutf_constexpr23
size_t
1602 const detail::input_span_of_byte_like
auto &valid_utf8_input,
1603 std::span<char16_t> utf16_output)
noexcept {
1605 #if SIMDUTF_CPLUSPLUS23
1607 return scalar::utf8_to_utf16::convert_valid<endianness::LITTLE>(
1608 valid_utf8_input.data(), valid_utf8_input.size(), utf16_output.data());
1613 reinterpret_cast<const char *
>(valid_utf8_input.data()),
1614 valid_utf8_input.size(), utf16_output.data());
1630 const char *input,
size_t length,
char16_t *utf16_buffer)
noexcept;
1632simdutf_really_inline simdutf_warn_unused simdutf_constexpr23
size_t
1634 const detail::input_span_of_byte_like
auto &valid_utf8_input,
1635 std::span<char16_t> utf16_output)
noexcept {
1636 #if SIMDUTF_CPLUSPLUS23
1638 return scalar::utf8_to_utf16::convert_valid<endianness::BIG>(
1639 valid_utf8_input.data(), valid_utf8_input.size(), utf16_output.data());
1644 reinterpret_cast<const char *
>(valid_utf8_input.data()),
1645 valid_utf8_input.size(), utf16_output.data());
1651#if SIMDUTF_FEATURE_UTF8 && SIMDUTF_FEATURE_UTF32
1663 const char *input,
size_t length,
char32_t *utf32_buffer)
noexcept;
1665simdutf_really_inline simdutf_warn_unused simdutf_constexpr23
size_t
1667 const detail::input_span_of_byte_like
auto &valid_utf8_input,
1668 std::span<char32_t> utf32_output)
noexcept {
1669 #if SIMDUTF_CPLUSPLUS23
1671 return scalar::utf8_to_utf32::convert_valid(
1672 valid_utf8_input.data(), valid_utf8_input.size(), utf32_output.data());
1677 reinterpret_cast<const char *
>(valid_utf8_input.data()),
1678 valid_utf8_input.size(), utf32_output.data());
1684#if SIMDUTF_FEATURE_UTF8 && SIMDUTF_FEATURE_LATIN1
1694 size_t length)
noexcept;
1696simdutf_really_inline simdutf_warn_unused simdutf_constexpr23
size_t
1698 const detail::input_span_of_byte_like
auto &latin1_input)
noexcept {
1699 #if SIMDUTF_CPLUSPLUS23
1701 return scalar::latin1_to_utf8::utf8_length_from_latin1(latin1_input.data(),
1702 latin1_input.size());
1707 reinterpret_cast<const char *
>(latin1_input.data()),
1708 latin1_input.size());
1727 size_t length)
noexcept;
1729simdutf_really_inline simdutf_warn_unused simdutf_constexpr23
size_t
1731 const detail::input_span_of_byte_like
auto &valid_utf8_input)
noexcept {
1732 #if SIMDUTF_CPLUSPLUS23
1734 return scalar::utf8::count_code_points(valid_utf8_input.data(),
1735 valid_utf8_input.size());
1740 reinterpret_cast<const char *
>(valid_utf8_input.data()),
1741 valid_utf8_input.size());
1747#if SIMDUTF_FEATURE_UTF8 && SIMDUTF_FEATURE_UTF16
1763 size_t length)
noexcept;
1765simdutf_really_inline simdutf_warn_unused simdutf_constexpr23
size_t
1767 const detail::input_span_of_byte_like
auto &valid_utf8_input)
noexcept {
1768 #if SIMDUTF_CPLUSPLUS23
1770 return scalar::utf8::utf16_length_from_utf8(valid_utf8_input.data(),
1771 valid_utf8_input.size());
1776 reinterpret_cast<const char *
>(valid_utf8_input.data()),
1777 valid_utf8_input.size());
1783#if SIMDUTF_FEATURE_UTF8 && SIMDUTF_FEATURE_UTF32
1801 size_t length)
noexcept;
1803simdutf_really_inline simdutf_warn_unused simdutf_constexpr23
size_t
1805 const detail::input_span_of_byte_like
auto &valid_utf8_input)
noexcept {
1807 #if SIMDUTF_CPLUSPLUS23
1809 return scalar::utf8::count_code_points(valid_utf8_input.data(),
1810 valid_utf8_input.size());
1815 reinterpret_cast<const char *
>(valid_utf8_input.data()),
1816 valid_utf8_input.size());
1822#if SIMDUTF_FEATURE_UTF8 && SIMDUTF_FEATURE_UTF16
1840 char *utf8_buffer)
noexcept;
1842simdutf_really_inline simdutf_warn_unused simdutf_constexpr23
size_t
1844 std::span<const char16_t> utf16_input,
1845 detail::output_span_of_byte_like
auto &&utf8_output)
noexcept {
1846 #if SIMDUTF_CPLUSPLUS23
1848 return scalar::utf16_to_utf8::convert<endianness::NATIVE>(
1849 utf16_input.data(), utf16_input.size(), utf8_output.data());
1854 reinterpret_cast<char *
>(utf8_output.data()));
1885 size_t utf8_len)
noexcept;
1887simdutf_really_inline simdutf_warn_unused simdutf_constexpr23
size_t
1889 std::span<const char16_t> utf16_input,
1890 detail::output_span_of_byte_like
auto &&utf8_output)
noexcept {
1897 #if SIMDUTF_CPLUSPLUS23
1900 scalar::utf16_to_utf8::convert_with_errors<endianness::NATIVE, true>(
1901 utf16_input.data(), utf16_input.size(), utf8_output.data(),
1902 utf8_output.size());
1903 if (r.error != error_code::SUCCESS &&
1904 r.error != error_code::OUTPUT_BUFFER_TOO_SMALL) {
1907 return r.output_count;
1912 utf16_input.data(), utf16_input.size(),
1913 reinterpret_cast<char *
>(utf8_output.data()), utf8_output.size());
1934 const char16_t *input,
size_t length,
char *utf8_output,
1935 size_t utf8_len)
noexcept;
1937simdutf_really_inline simdutf_warn_unused simdutf_constexpr23
full_result
1939 std::span<const char16_t> utf16_input,
1940 detail::output_span_of_byte_like
auto &&utf8_output)
noexcept {
1941 #if SIMDUTF_CPLUSPLUS23
1943 if (utf16_input.empty()) {
1946 return scalar::utf16_to_utf8::convert_with_errors<endianness::NATIVE, true>(
1947 utf16_input.data(), utf16_input.size(), utf8_output.data(),
1948 utf8_output.size());
1953 utf16_input.data(), utf16_input.size(),
1954 reinterpret_cast<char *
>(utf8_output.data()), utf8_output.size());
1960#if SIMDUTF_FEATURE_UTF16 && SIMDUTF_FEATURE_LATIN1
1977 const char16_t *input,
size_t length,
char *latin1_buffer)
noexcept;
1979simdutf_really_inline simdutf_warn_unused simdutf_constexpr23
size_t
1981 std::span<const char16_t> utf16_input,
1982 detail::output_span_of_byte_like
auto &&latin1_output)
noexcept {
1983 #if SIMDUTF_CPLUSPLUS23
1985 return scalar::utf16_to_latin1::convert<endianness::NATIVE>(
1986 utf16_input.data(), utf16_input.size(), latin1_output.data());
1991 utf16_input.data(), utf16_input.size(),
1992 reinterpret_cast<char *
>(latin1_output.data()));
2014 const char16_t *input,
size_t length,
char *latin1_buffer)
noexcept;
2016simdutf_really_inline simdutf_warn_unused simdutf_constexpr23
size_t
2018 std::span<const char16_t> utf16_input,
2019 detail::output_span_of_byte_like
auto &&latin1_output)
noexcept {
2020 #if SIMDUTF_CPLUSPLUS23
2022 return scalar::utf16_to_latin1::convert<endianness::LITTLE>(
2023 utf16_input.data(), utf16_input.size(), latin1_output.data());
2028 utf16_input.data(), utf16_input.size(),
2029 reinterpret_cast<char *
>(latin1_output.data()));
2049 const char16_t *input,
size_t length,
char *latin1_buffer)
noexcept;
2051simdutf_really_inline simdutf_warn_unused simdutf_constexpr23
size_t
2053 std::span<const char16_t> utf16_input,
2054 detail::output_span_of_byte_like
auto &&latin1_output)
noexcept {
2055 #if SIMDUTF_CPLUSPLUS23
2057 return scalar::utf16_to_latin1::convert<endianness::BIG>(
2058 utf16_input.data(), utf16_input.size(), latin1_output.data());
2063 utf16_input.data(), utf16_input.size(),
2064 reinterpret_cast<char *
>(latin1_output.data()));
2070#if SIMDUTF_FEATURE_UTF8 && SIMDUTF_FEATURE_UTF16
2087 char *utf8_buffer)
noexcept;
2089simdutf_really_inline simdutf_warn_unused simdutf_constexpr23
size_t
2091 std::span<const char16_t> utf16_input,
2092 detail::output_span_of_byte_like
auto &&utf8_output)
noexcept {
2093 #if SIMDUTF_CPLUSPLUS23
2095 return scalar::utf16_to_utf8::convert<endianness::LITTLE>(
2096 utf16_input.data(), utf16_input.size(), utf8_output.data());
2101 utf16_input.data(), utf16_input.size(),
2102 reinterpret_cast<char *
>(utf8_output.data()));
2123 char *utf8_buffer)
noexcept;
2125simdutf_really_inline simdutf_warn_unused simdutf_constexpr23
size_t
2127 std::span<const char16_t> utf16_input,
2128 detail::output_span_of_byte_like
auto &&utf8_output)
noexcept {
2129 #if SIMDUTF_CPLUSPLUS23
2131 return scalar::utf16_to_utf8::convert<endianness::BIG>(
2132 utf16_input.data(), utf16_input.size(), utf8_output.data());
2137 utf16_input.data(), utf16_input.size(),
2138 reinterpret_cast<char *
>(utf8_output.data()));
2144#if SIMDUTF_FEATURE_UTF16 && SIMDUTF_FEATURE_LATIN1
2162 const char16_t *input,
size_t length,
char *latin1_buffer)
noexcept;
2164simdutf_really_inline simdutf_warn_unused simdutf_constexpr23
result
2166 std::span<const char16_t> utf16_input,
2167 detail::output_span_of_byte_like
auto &&latin1_output)
noexcept {
2168 #if SIMDUTF_CPLUSPLUS23
2170 return scalar::utf16_to_latin1::convert_with_errors<endianness::NATIVE>(
2171 utf16_input.data(), utf16_input.size(), latin1_output.data());
2176 utf16_input.data(), utf16_input.size(),
2177 reinterpret_cast<char *
>(latin1_output.data()));
2198 const char16_t *input,
size_t length,
char *latin1_buffer)
noexcept;
2200simdutf_really_inline simdutf_warn_unused simdutf_constexpr23
result
2202 std::span<const char16_t> utf16_input,
2203 detail::output_span_of_byte_like
auto &&latin1_output)
noexcept {
2204 #if SIMDUTF_CPLUSPLUS23
2206 return scalar::utf16_to_latin1::convert_with_errors<endianness::LITTLE>(
2207 utf16_input.data(), utf16_input.size(), latin1_output.data());
2212 utf16_input.data(), utf16_input.size(),
2213 reinterpret_cast<char *
>(latin1_output.data()));
2236 const char16_t *input,
size_t length,
char *latin1_buffer)
noexcept;
2238simdutf_really_inline simdutf_warn_unused simdutf_constexpr23
result
2240 std::span<const char16_t> utf16_input,
2241 detail::output_span_of_byte_like
auto &&latin1_output)
noexcept {
2242 #if SIMDUTF_CPLUSPLUS23
2244 return scalar::utf16_to_latin1::convert_with_errors<endianness::BIG>(
2245 utf16_input.data(), utf16_input.size(), latin1_output.data());
2250 utf16_input.data(), utf16_input.size(),
2251 reinterpret_cast<char *
>(latin1_output.data()));
2257#if SIMDUTF_FEATURE_UTF8 && SIMDUTF_FEATURE_UTF16
2276 const char16_t *input,
size_t length,
char *utf8_buffer)
noexcept;
2278simdutf_really_inline simdutf_warn_unused simdutf_constexpr23
result
2280 std::span<const char16_t> utf16_input,
2281 detail::output_span_of_byte_like
auto &&utf8_output)
noexcept {
2282 #if SIMDUTF_CPLUSPLUS23
2284 return scalar::utf16_to_utf8::convert_with_errors<endianness::NATIVE>(
2285 utf16_input.data(), utf16_input.size(), utf8_output.data());
2290 utf16_input.data(), utf16_input.size(),
2291 reinterpret_cast<char *
>(utf8_output.data()));
2313 const char16_t *input,
size_t length,
char *utf8_buffer)
noexcept;
2315simdutf_really_inline simdutf_warn_unused simdutf_constexpr23
result
2317 std::span<const char16_t> utf16_input,
2318 detail::output_span_of_byte_like
auto &&utf8_output)
noexcept {
2319 #if SIMDUTF_CPLUSPLUS23
2321 return scalar::utf16_to_utf8::convert_with_errors<endianness::LITTLE>(
2322 utf16_input.data(), utf16_input.size(), utf8_output.data());
2327 utf16_input.data(), utf16_input.size(),
2328 reinterpret_cast<char *
>(utf8_output.data()));
2350 const char16_t *input,
size_t length,
char *utf8_buffer)
noexcept;
2352simdutf_really_inline simdutf_warn_unused simdutf_constexpr23
result
2354 std::span<const char16_t> utf16_input,
2355 detail::output_span_of_byte_like
auto &&utf8_output)
noexcept {
2356 #if SIMDUTF_CPLUSPLUS23
2358 return scalar::utf16_to_utf8::convert_with_errors<endianness::BIG>(
2359 utf16_input.data(), utf16_input.size(), utf8_output.data());
2364 utf16_input.data(), utf16_input.size(),
2365 reinterpret_cast<char *
>(utf8_output.data()));
2385 const char16_t *input,
size_t length,
char *utf8_buffer)
noexcept;
2387simdutf_really_inline simdutf_warn_unused simdutf_constexpr23
size_t
2389 std::span<const char16_t> utf16_input,
2390 detail::output_span_of_byte_like
auto &&utf8_output)
noexcept {
2391 #if SIMDUTF_CPLUSPLUS23
2393 return scalar::utf16_to_utf8::convert_with_replacement<endianness::LITTLE>(
2394 utf16_input.data(), utf16_input.size(), utf8_output.data());
2399 utf16_input.data(), utf16_input.size(),
2400 reinterpret_cast<char *
>(utf8_output.data()));
2420 const char16_t *input,
size_t length,
char *utf8_buffer)
noexcept;
2422simdutf_really_inline simdutf_warn_unused simdutf_constexpr23
size_t
2424 std::span<const char16_t> utf16_input,
2425 detail::output_span_of_byte_like
auto &&utf8_output)
noexcept {
2426 #if SIMDUTF_CPLUSPLUS23
2428 return scalar::utf16_to_utf8::convert_with_replacement<endianness::BIG>(
2429 utf16_input.data(), utf16_input.size(), utf8_output.data());
2434 utf16_input.data(), utf16_input.size(),
2435 reinterpret_cast<char *
>(utf8_output.data()));
2455 const char16_t *input,
size_t length,
char *utf8_buffer)
noexcept;
2457simdutf_really_inline simdutf_warn_unused simdutf_constexpr23
size_t
2459 std::span<const char16_t> utf16_input,
2460 detail::output_span_of_byte_like
auto &&utf8_output)
noexcept {
2461 #if SIMDUTF_CPLUSPLUS23
2463 return scalar::utf16_to_utf8::convert_with_replacement<endianness::NATIVE>(
2464 utf16_input.data(), utf16_input.size(), utf8_output.data());
2469 utf16_input.data(), utf16_input.size(),
2470 reinterpret_cast<char *
>(utf8_output.data()));
2491 const char16_t *input,
size_t length,
char *utf8_output,
2492 size_t utf8_len)
noexcept;
2494simdutf_really_inline simdutf_warn_unused simdutf_constexpr23
full_result
2496 std::span<const char16_t> utf16_input,
2497 detail::output_span_of_byte_like
auto &&utf8_output)
noexcept {
2498 #if SIMDUTF_CPLUSPLUS23
2500 return scalar::utf16_to_utf8::convert_with_replacement_safe<
2501 endianness::NATIVE>(utf16_input.data(), utf16_input.size(),
2502 utf8_output.data(), utf8_output.size());
2507 utf16_input.data(), utf16_input.size(),
2508 reinterpret_cast<char *
>(utf8_output.data()), utf8_output.size());
2514#if SIMDUTF_FEATURE_UTF8 && SIMDUTF_FEATURE_UTF16
2529 const char16_t *input,
size_t length,
char *utf8_buffer)
noexcept;
2531simdutf_really_inline simdutf_warn_unused simdutf_constexpr23
size_t
2533 std::span<const char16_t> valid_utf16_input,
2534 detail::output_span_of_byte_like
auto &&utf8_output)
noexcept {
2535 #if SIMDUTF_CPLUSPLUS23
2537 return scalar::utf16_to_utf8::convert_valid<endianness::NATIVE>(
2538 valid_utf16_input.data(), valid_utf16_input.size(), utf8_output.data());
2543 valid_utf16_input.data(), valid_utf16_input.size(),
2544 reinterpret_cast<char *
>(utf8_output.data()));
2550#if SIMDUTF_FEATURE_UTF16 && SIMDUTF_FEATURE_LATIN1
2571 const char16_t *input,
size_t length,
char *latin1_buffer)
noexcept;
2573simdutf_really_inline simdutf_warn_unused simdutf_constexpr23
size_t
2575 std::span<const char16_t> valid_utf16_input,
2576 detail::output_span_of_byte_like
auto &&latin1_output)
noexcept {
2577 #if SIMDUTF_CPLUSPLUS23
2579 return scalar::utf16_to_latin1::convert_valid_impl<endianness::NATIVE>(
2580 detail::constexpr_cast_ptr<uint16_t>(valid_utf16_input.data()),
2581 valid_utf16_input.size(),
2582 detail::constexpr_cast_writeptr<char>(latin1_output.data()));
2587 valid_utf16_input.data(), valid_utf16_input.size(),
2588 reinterpret_cast<char *
>(latin1_output.data()));
2613 const char16_t *input,
size_t length,
char *latin1_buffer)
noexcept;
2615simdutf_really_inline simdutf_constexpr23 simdutf_warn_unused
size_t
2617 std::span<const char16_t> valid_utf16_input,
2618 detail::output_span_of_byte_like
auto &&latin1_output)
noexcept {
2619 #if SIMDUTF_CPLUSPLUS23
2621 return scalar::utf16_to_latin1::convert_valid_impl<endianness::LITTLE>(
2622 detail::constexpr_cast_ptr<uint16_t>(valid_utf16_input.data()),
2623 valid_utf16_input.size(),
2624 detail::constexpr_cast_writeptr<char>(latin1_output.data()));
2629 valid_utf16_input.data(), valid_utf16_input.size(),
2630 reinterpret_cast<char *
>(latin1_output.data()));
2655 const char16_t *input,
size_t length,
char *latin1_buffer)
noexcept;
2657simdutf_really_inline simdutf_constexpr23 simdutf_warn_unused
size_t
2659 std::span<const char16_t> valid_utf16_input,
2660 detail::output_span_of_byte_like
auto &&latin1_output)
noexcept {
2661 #if SIMDUTF_CPLUSPLUS23
2663 return scalar::utf16_to_latin1::convert_valid_impl<endianness::BIG>(
2664 detail::constexpr_cast_ptr<uint16_t>(valid_utf16_input.data()),
2665 valid_utf16_input.size(),
2666 detail::constexpr_cast_writeptr<char>(latin1_output.data()));
2671 valid_utf16_input.data(), valid_utf16_input.size(),
2672 reinterpret_cast<char *
>(latin1_output.data()));
2678#if SIMDUTF_FEATURE_UTF8 && SIMDUTF_FEATURE_UTF16
2693 const char16_t *input,
size_t length,
char *utf8_buffer)
noexcept;
2695simdutf_really_inline simdutf_warn_unused simdutf_constexpr23
size_t
2697 std::span<const char16_t> valid_utf16_input,
2698 detail::output_span_of_byte_like
auto &&utf8_output)
noexcept {
2699 #if SIMDUTF_CPLUSPLUS23
2701 return scalar::utf16_to_utf8::convert_valid<endianness::NATIVE>(
2702 valid_utf16_input.data(), valid_utf16_input.size(), utf8_output.data());
2707 valid_utf16_input.data(), valid_utf16_input.size(),
2708 reinterpret_cast<char *
>(utf8_output.data()));
2727 const char16_t *input,
size_t length,
char *utf8_buffer)
noexcept;
2729simdutf_really_inline simdutf_warn_unused simdutf_constexpr23
size_t
2731 std::span<const char16_t> valid_utf16_input,
2732 detail::output_span_of_byte_like
auto &&utf8_output)
noexcept {
2733 #if SIMDUTF_CPLUSPLUS23
2735 return scalar::utf16_to_utf8::convert_valid<endianness::BIG>(
2736 valid_utf16_input.data(), valid_utf16_input.size(), utf8_output.data());
2741 valid_utf16_input.data(), valid_utf16_input.size(),
2742 reinterpret_cast<char *
>(utf8_output.data()));
2748#if SIMDUTF_FEATURE_UTF16 && SIMDUTF_FEATURE_UTF32
2765 const char16_t *input,
size_t length,
char32_t *utf32_buffer)
noexcept;
2767simdutf_really_inline simdutf_warn_unused simdutf_constexpr23
size_t
2769 std::span<char32_t> utf32_output)
noexcept {
2771 #if SIMDUTF_CPLUSPLUS23
2773 return scalar::utf16_to_utf32::convert<endianness::NATIVE>(
2774 utf16_input.data(), utf16_input.size(), utf32_output.data());
2779 utf32_output.data());
2799 const char16_t *input,
size_t length,
char32_t *utf32_buffer)
noexcept;
2801simdutf_really_inline simdutf_warn_unused simdutf_constexpr23
size_t
2803 std::span<char32_t> utf32_output)
noexcept {
2804 #if SIMDUTF_CPLUSPLUS23
2806 return scalar::utf16_to_utf32::convert<endianness::LITTLE>(
2807 utf16_input.data(), utf16_input.size(), utf32_output.data());
2812 utf32_output.data());
2832 const char16_t *input,
size_t length,
char32_t *utf32_buffer)
noexcept;
2834simdutf_really_inline simdutf_warn_unused simdutf_constexpr23
size_t
2836 std::span<char32_t> utf32_output)
noexcept {
2837 #if SIMDUTF_CPLUSPLUS23
2839 return scalar::utf16_to_utf32::convert<endianness::BIG>(
2840 utf16_input.data(), utf16_input.size(), utf32_output.data());
2845 utf32_output.data());
2868 const char16_t *input,
size_t length,
char32_t *utf32_buffer)
noexcept;
2870simdutf_really_inline simdutf_warn_unused simdutf_constexpr23
result
2872 std::span<char32_t> utf32_output)
noexcept {
2873 #if SIMDUTF_CPLUSPLUS23
2875 return scalar::utf16_to_utf32::convert_with_errors<endianness::NATIVE>(
2876 utf16_input.data(), utf16_input.size(), utf32_output.data());
2881 utf16_input.data(), utf16_input.size(), utf32_output.data());
2903 const char16_t *input,
size_t length,
char32_t *utf32_buffer)
noexcept;
2905simdutf_really_inline simdutf_warn_unused simdutf_constexpr23
result
2907 std::span<const char16_t> utf16_input,
2908 std::span<char32_t> utf32_output)
noexcept {
2909 #if SIMDUTF_CPLUSPLUS23
2911 return scalar::utf16_to_utf32::convert_with_errors<endianness::LITTLE>(
2912 utf16_input.data(), utf16_input.size(), utf32_output.data());
2917 utf16_input.data(), utf16_input.size(), utf32_output.data());
2939 const char16_t *input,
size_t length,
char32_t *utf32_buffer)
noexcept;
2941simdutf_really_inline simdutf_warn_unused simdutf_constexpr23
result
2943 std::span<const char16_t> utf16_input,
2944 std::span<char32_t> utf32_output)
noexcept {
2945 #if SIMDUTF_CPLUSPLUS23
2947 return scalar::utf16_to_utf32::convert_with_errors<endianness::BIG>(
2948 utf16_input.data(), utf16_input.size(), utf32_output.data());
2953 utf16_input.data(), utf16_input.size(), utf32_output.data());
2973 const char16_t *input,
size_t length,
char32_t *utf32_buffer)
noexcept;
2975simdutf_really_inline simdutf_warn_unused simdutf_constexpr23
size_t
2977 std::span<char32_t> utf32_output)
noexcept {
2978 #if SIMDUTF_CPLUSPLUS23
2980 return scalar::utf16_to_utf32::convert_valid<endianness::NATIVE>(
2981 valid_utf16_input.data(), valid_utf16_input.size(),
2982 utf32_output.data());
2987 valid_utf16_input.size(),
2988 utf32_output.data());
3007 const char16_t *input,
size_t length,
char32_t *utf32_buffer)
noexcept;
3009simdutf_really_inline simdutf_warn_unused simdutf_constexpr23
size_t
3011 std::span<char32_t> utf32_output)
noexcept {
3012 #if SIMDUTF_CPLUSPLUS23
3014 return scalar::utf16_to_utf32::convert_valid<endianness::LITTLE>(
3015 valid_utf16_input.data(), valid_utf16_input.size(),
3016 utf32_output.data());
3021 valid_utf16_input.size(),
3022 utf32_output.data());
3041 const char16_t *input,
size_t length,
char32_t *utf32_buffer)
noexcept;
3043simdutf_really_inline simdutf_warn_unused simdutf_constexpr23
size_t
3045 std::span<char32_t> utf32_output)
noexcept {
3046 #if SIMDUTF_CPLUSPLUS23
3048 return scalar::utf16_to_utf32::convert_valid<endianness::BIG>(
3049 valid_utf16_input.data(), valid_utf16_input.size(),
3050 utf32_output.data());
3055 valid_utf16_input.size(),
3056 utf32_output.data());
3062#if SIMDUTF_FEATURE_UTF8 && SIMDUTF_FEATURE_UTF16
3075 size_t length)
noexcept;
3077simdutf_really_inline simdutf_warn_unused simdutf_constexpr23
size_t
3079 #if SIMDUTF_CPLUSPLUS23
3081 return scalar::utf16::utf8_length_from_utf16<endianness::NATIVE>(
3082 valid_utf16_input.data(), valid_utf16_input.size());
3087 valid_utf16_input.size());
3111 const char16_t *input,
size_t length)
noexcept;
3113simdutf_really_inline simdutf_warn_unused simdutf_constexpr23
result
3115 std::span<const char16_t> valid_utf16_input)
noexcept {
3116 #if SIMDUTF_CPLUSPLUS23
3118 return scalar::utf16::utf8_length_from_utf16_with_replacement<
3119 endianness::NATIVE>(valid_utf16_input.data(), valid_utf16_input.size());
3124 valid_utf16_input.size());
3141 size_t length)
noexcept;
3143simdutf_really_inline simdutf_constexpr23 simdutf_warn_unused
size_t
3145 #if SIMDUTF_CPLUSPLUS23
3147 return scalar::utf16::utf8_length_from_utf16<endianness::LITTLE>(
3148 valid_utf16_input.data(), valid_utf16_input.size());
3153 valid_utf16_input.size());
3170 size_t length)
noexcept;
3172simdutf_really_inline simdutf_warn_unused simdutf_constexpr23
size_t
3174 #if SIMDUTF_CPLUSPLUS23
3176 return scalar::utf16::utf8_length_from_utf16<endianness::BIG>(
3177 valid_utf16_input.data(), valid_utf16_input.size());
3182 valid_utf16_input.size());
3188#if SIMDUTF_FEATURE_UTF8 && SIMDUTF_FEATURE_UTF32
3204 char *utf8_buffer)
noexcept;
3206simdutf_really_inline simdutf_warn_unused simdutf_constexpr23
size_t
3208 std::span<const char32_t> utf32_input,
3209 detail::output_span_of_byte_like
auto &&utf8_output)
noexcept {
3210 #if SIMDUTF_CPLUSPLUS23
3212 return scalar::utf32_to_utf8::convert(
3213 utf32_input.data(), utf32_input.size(), utf8_output.data());
3218 reinterpret_cast<char *
>(utf8_output.data()));
3240 const char32_t *input,
size_t length,
char *utf8_buffer)
noexcept;
3242simdutf_really_inline simdutf_warn_unused simdutf_constexpr23
result
3244 std::span<const char32_t> utf32_input,
3245 detail::output_span_of_byte_like
auto &&utf8_output)
noexcept {
3246 #if SIMDUTF_CPLUSPLUS23
3248 return scalar::utf32_to_utf8::convert_with_errors(
3249 utf32_input.data(), utf32_input.size(), utf8_output.data());
3254 utf32_input.data(), utf32_input.size(),
3255 reinterpret_cast<char *
>(utf8_output.data()));
3274 const char32_t *input,
size_t length,
char *utf8_buffer)
noexcept;
3276simdutf_really_inline simdutf_warn_unused simdutf_constexpr23
size_t
3278 std::span<const char32_t> valid_utf32_input,
3279 detail::output_span_of_byte_like
auto &&utf8_output)
noexcept {
3280 #if SIMDUTF_CPLUSPLUS23
3282 return scalar::utf32_to_utf8::convert_valid(
3283 valid_utf32_input.data(), valid_utf32_input.size(), utf8_output.data());
3288 valid_utf32_input.data(), valid_utf32_input.size(),
3289 reinterpret_cast<char *
>(utf8_output.data()));
3295#if SIMDUTF_FEATURE_UTF16 && SIMDUTF_FEATURE_UTF32
3311 const char32_t *input,
size_t length,
char16_t *utf16_buffer)
noexcept;
3313simdutf_really_inline simdutf_warn_unused simdutf_constexpr23
size_t
3315 std::span<char16_t> utf16_output)
noexcept {
3316 #if SIMDUTF_CPLUSPLUS23
3318 return scalar::utf32_to_utf16::convert<endianness::NATIVE>(
3319 utf32_input.data(), utf32_input.size(), utf16_output.data());
3324 utf16_output.data());
3343 const char32_t *input,
size_t length,
char16_t *utf16_buffer)
noexcept;
3345simdutf_really_inline simdutf_warn_unused simdutf_constexpr23
size_t
3347 std::span<char16_t> utf16_output)
noexcept {
3348 #if SIMDUTF_CPLUSPLUS23
3350 return scalar::utf32_to_utf16::convert<endianness::LITTLE>(
3351 utf32_input.data(), utf32_input.size(), utf16_output.data());
3356 utf16_output.data());
3362#if SIMDUTF_FEATURE_UTF32 && SIMDUTF_FEATURE_LATIN1
3378 const char32_t *input,
size_t length,
char *latin1_buffer)
noexcept;
3380simdutf_really_inline simdutf_warn_unused simdutf_constexpr23
size_t
3382 std::span<const char32_t> utf32_input,
3383 detail::output_span_of_byte_like
auto &&latin1_output)
noexcept {
3384 #if SIMDUTF_CPLUSPLUS23
3386 return scalar::utf32_to_latin1::convert(
3387 utf32_input.data(), utf32_input.size(), latin1_output.data());
3392 utf32_input.data(), utf32_input.size(),
3393 reinterpret_cast<char *
>(latin1_output.data()));
3416 const char32_t *input,
size_t length,
char *latin1_buffer)
noexcept;
3418simdutf_really_inline simdutf_warn_unused simdutf_constexpr23
result
3420 std::span<const char32_t> utf32_input,
3421 detail::output_span_of_byte_like
auto &&latin1_output)
noexcept {
3422 #if SIMDUTF_CPLUSPLUS23
3424 return scalar::utf32_to_latin1::convert_with_errors(
3425 utf32_input.data(), utf32_input.size(), latin1_output.data());
3430 utf32_input.data(), utf32_input.size(),
3431 reinterpret_cast<char *
>(latin1_output.data()));
3457 const char32_t *input,
size_t length,
char *latin1_buffer)
noexcept;
3459simdutf_really_inline simdutf_constexpr23 simdutf_warn_unused
size_t
3461 std::span<const char32_t> valid_utf32_input,
3462 detail::output_span_of_byte_like
auto &&latin1_output)
noexcept {
3463 #if SIMDUTF_CPLUSPLUS23
3465 return scalar::utf32_to_latin1::convert_valid(
3466 detail::constexpr_cast_ptr<uint32_t>(valid_utf32_input.data()),
3467 valid_utf32_input.size(),
3468 detail::constexpr_cast_writeptr<char>(latin1_output.data()));
3473 valid_utf32_input.data(), valid_utf32_input.size(),
3474 reinterpret_cast<char *
>(latin1_output.data()));
3491simdutf_warn_unused simdutf_really_inline simdutf_constexpr23
size_t
3504simdutf_warn_unused simdutf_really_inline simdutf_constexpr23
size_t
3510#if SIMDUTF_FEATURE_UTF16 && SIMDUTF_FEATURE_UTF32
3525 const char32_t *input,
size_t length,
char16_t *utf16_buffer)
noexcept;
3527simdutf_really_inline simdutf_warn_unused simdutf_constexpr23
size_t
3529 std::span<char16_t> utf16_output)
noexcept {
3530 #if SIMDUTF_CPLUSPLUS23
3532 return scalar::utf32_to_utf16::convert<endianness::BIG>(
3533 utf32_input.data(), utf32_input.size(), utf16_output.data());
3538 utf16_output.data());
3561 const char32_t *input,
size_t length,
char16_t *utf16_buffer)
noexcept;
3563simdutf_really_inline simdutf_warn_unused simdutf_constexpr23
result
3565 std::span<char16_t> utf16_output)
noexcept {
3566 #if SIMDUTF_CPLUSPLUS23
3568 return scalar::utf32_to_utf16::convert_with_errors<endianness::NATIVE>(
3569 utf32_input.data(), utf32_input.size(), utf16_output.data());
3574 utf32_input.data(), utf32_input.size(), utf16_output.data());
3596 const char32_t *input,
size_t length,
char16_t *utf16_buffer)
noexcept;
3598simdutf_really_inline simdutf_warn_unused simdutf_constexpr23
result
3600 std::span<const char32_t> utf32_input,
3601 std::span<char16_t> utf16_output)
noexcept {
3602 #if SIMDUTF_CPLUSPLUS23
3604 return scalar::utf32_to_utf16::convert_with_errors<endianness::LITTLE>(
3605 utf32_input.data(), utf32_input.size(), utf16_output.data());
3610 utf32_input.data(), utf32_input.size(), utf16_output.data());
3632 const char32_t *input,
size_t length,
char16_t *utf16_buffer)
noexcept;
3634simdutf_really_inline simdutf_warn_unused simdutf_constexpr23
result
3636 std::span<const char32_t> utf32_input,
3637 std::span<char16_t> utf16_output)
noexcept {
3638 #if SIMDUTF_CPLUSPLUS23
3640 return scalar::utf32_to_utf16::convert_with_errors<endianness::BIG>(
3641 utf32_input.data(), utf32_input.size(), utf16_output.data());
3646 utf32_input.data(), utf32_input.size(), utf16_output.data());
3665 const char32_t *input,
size_t length,
char16_t *utf16_buffer)
noexcept;
3667simdutf_really_inline simdutf_warn_unused simdutf_constexpr23
size_t
3669 std::span<char16_t> utf16_output)
noexcept {
3671 #if SIMDUTF_CPLUSPLUS23
3673 return scalar::utf32_to_utf16::convert_valid<endianness::NATIVE>(
3674 valid_utf32_input.data(), valid_utf32_input.size(),
3675 utf16_output.data());
3680 valid_utf32_input.size(),
3681 utf16_output.data());
3700 const char32_t *input,
size_t length,
char16_t *utf16_buffer)
noexcept;
3702simdutf_really_inline simdutf_warn_unused simdutf_constexpr23
size_t
3704 std::span<char16_t> utf16_output)
noexcept {
3705 #if SIMDUTF_CPLUSPLUS23
3707 return scalar::utf32_to_utf16::convert_valid<endianness::LITTLE>(
3708 valid_utf32_input.data(), valid_utf32_input.size(),
3709 utf16_output.data());
3714 valid_utf32_input.size(),
3715 utf16_output.data());
3734 const char32_t *input,
size_t length,
char16_t *utf16_buffer)
noexcept;
3736simdutf_really_inline simdutf_warn_unused simdutf_constexpr23
size_t
3738 std::span<char16_t> utf16_output)
noexcept {
3739 #if SIMDUTF_CPLUSPLUS23
3741 return scalar::utf32_to_utf16::convert_valid<endianness::BIG>(
3742 valid_utf32_input.data(), valid_utf32_input.size(),
3743 utf16_output.data());
3748 valid_utf32_input.size(),
3749 utf16_output.data());
3755#if SIMDUTF_FEATURE_UTF16
3770 char16_t *output)
noexcept;
3772simdutf_really_inline simdutf_constexpr23
void
3774 std::span<char16_t> utf16_output)
noexcept {
3775 #if SIMDUTF_CPLUSPLUS23
3777 return scalar::utf16::change_endianness_utf16(
3778 utf16_input.data(), utf16_input.size(), utf16_output.data());
3783 utf16_output.data());
3789#if SIMDUTF_FEATURE_UTF8 && SIMDUTF_FEATURE_UTF32
3802 size_t length)
noexcept;
3804simdutf_really_inline simdutf_warn_unused simdutf_constexpr23
size_t
3806 #if SIMDUTF_CPLUSPLUS23
3808 return scalar::utf32::utf8_length_from_utf32(valid_utf32_input.data(),
3809 valid_utf32_input.size());
3814 valid_utf32_input.size());
3820#if SIMDUTF_FEATURE_UTF16 && SIMDUTF_FEATURE_UTF32
3833 size_t length)
noexcept;
3835simdutf_really_inline simdutf_warn_unused simdutf_constexpr23
size_t
3837 #if SIMDUTF_CPLUSPLUS23
3839 return scalar::utf32::utf16_length_from_utf32(valid_utf32_input.data(),
3840 valid_utf32_input.size());
3845 valid_utf32_input.size());
3866 size_t length)
noexcept;
3868simdutf_really_inline simdutf_warn_unused simdutf_constexpr23
size_t
3870 #if SIMDUTF_CPLUSPLUS23
3872 return scalar::utf16::utf32_length_from_utf16<endianness::NATIVE>(
3873 valid_utf16_input.data(), valid_utf16_input.size());
3878 valid_utf16_input.size());
3899 size_t length)
noexcept;
3901simdutf_really_inline simdutf_warn_unused simdutf_constexpr23
size_t
3903 std::span<const char16_t> valid_utf16_input)
noexcept {
3904 #if SIMDUTF_CPLUSPLUS23
3906 return scalar::utf16::utf32_length_from_utf16<endianness::LITTLE>(
3907 valid_utf16_input.data(), valid_utf16_input.size());
3912 valid_utf16_input.size());
3933 size_t length)
noexcept;
3935simdutf_really_inline simdutf_warn_unused simdutf_constexpr23
size_t
3937 std::span<const char16_t> valid_utf16_input)
noexcept {
3938 #if SIMDUTF_CPLUSPLUS23
3940 return scalar::utf16::utf32_length_from_utf16<endianness::BIG>(
3941 valid_utf16_input.data(), valid_utf16_input.size());
3946 valid_utf16_input.size());
3952#if SIMDUTF_FEATURE_UTF16
3968 size_t length)
noexcept;
3970simdutf_really_inline simdutf_warn_unused simdutf_constexpr23
size_t
3971count_utf16(std::span<const char16_t> valid_utf16_input)
noexcept {
3972 #if SIMDUTF_CPLUSPLUS23
3974 return scalar::utf16::count_code_points<endianness::NATIVE>(
3975 valid_utf16_input.data(), valid_utf16_input.size());
3979 return count_utf16(valid_utf16_input.data(), valid_utf16_input.size());
3999 size_t length)
noexcept;
4001simdutf_really_inline simdutf_warn_unused simdutf_constexpr23
size_t
4002count_utf16le(std::span<const char16_t> valid_utf16_input)
noexcept {
4003 #if SIMDUTF_CPLUSPLUS23
4005 return scalar::utf16::count_code_points<endianness::LITTLE>(
4006 valid_utf16_input.data(), valid_utf16_input.size());
4010 return count_utf16le(valid_utf16_input.data(), valid_utf16_input.size());
4030 size_t length)
noexcept;
4032simdutf_really_inline simdutf_warn_unused simdutf_constexpr23
size_t
4033count_utf16be(std::span<const char16_t> valid_utf16_input)
noexcept {
4034 #if SIMDUTF_CPLUSPLUS23
4036 return scalar::utf16::count_code_points<endianness::BIG>(
4037 valid_utf16_input.data(), valid_utf16_input.size());
4041 return count_utf16be(valid_utf16_input.data(), valid_utf16_input.size());
4047#if SIMDUTF_FEATURE_UTF8
4061 size_t length)
noexcept;
4063simdutf_really_inline simdutf_warn_unused simdutf_constexpr23
size_t count_utf8(
4064 const detail::input_span_of_byte_like
auto &valid_utf8_input)
noexcept {
4065 #if SIMDUTF_CPLUSPLUS23
4067 return scalar::utf8::count_code_points(valid_utf8_input.data(),
4068 valid_utf8_input.size());
4072 return count_utf8(
reinterpret_cast<const char *
>(valid_utf8_input.data()),
4073 valid_utf8_input.size());
4094simdutf_really_inline simdutf_warn_unused simdutf_constexpr23
size_t
4096 const detail::input_span_of_byte_like
auto &valid_utf8_input)
noexcept {
4097 #if SIMDUTF_CPLUSPLUS23
4099 return scalar::utf8::trim_partial_utf8(valid_utf8_input.data(),
4100 valid_utf8_input.size());
4105 reinterpret_cast<const char *
>(valid_utf8_input.data()),
4106 valid_utf8_input.size());
4112#if SIMDUTF_FEATURE_UTF16
4130simdutf_really_inline simdutf_warn_unused simdutf_constexpr23
size_t
4132 #if SIMDUTF_CPLUSPLUS23
4134 return scalar::utf16::trim_partial_utf16<endianness::BIG>(
4135 valid_utf16_input.data(), valid_utf16_input.size());
4140 valid_utf16_input.size());
4162simdutf_really_inline simdutf_warn_unused simdutf_constexpr23
size_t
4164 #if SIMDUTF_CPLUSPLUS23
4166 return scalar::utf16::trim_partial_utf16<endianness::LITTLE>(
4167 valid_utf16_input.data(), valid_utf16_input.size());
4172 valid_utf16_input.size());
4194simdutf_really_inline simdutf_warn_unused simdutf_constexpr23
size_t
4196 #if SIMDUTF_CPLUSPLUS23
4198 return scalar::utf16::trim_partial_utf16<endianness::NATIVE>(
4199 valid_utf16_input.data(), valid_utf16_input.size());
4204 valid_utf16_input.size());
4210#if SIMDUTF_FEATURE_BASE64 || SIMDUTF_FEATURE_UTF16 || \
4211 SIMDUTF_FEATURE_DETECT_ENCODING
4212 #ifndef SIMDUTF_NEED_TRAILING_ZEROES
4213 #define SIMDUTF_NEED_TRAILING_ZEROES 1
4218#if SIMDUTF_FEATURE_BASE64
4223constexpr uint64_t base64_reverse_padding =
4225enum base64_options : uint64_t {
4228 base64_default_no_padding =
4230 base64_reverse_padding,
4231 base64_url_with_padding =
4232 base64_url | base64_reverse_padding,
4233 base64_default_accept_garbage =
4236 base64_url_accept_garbage =
4239 base64_default_or_url =
4241 base64_default_or_url_accept_garbage =
4250enum last_chunk_handling_options : uint64_t {
4254 stop_before_partial =
4260inline simdutf_constexpr23
bool
4261is_partial(last_chunk_handling_options options) {
4262 return (options == stop_before_partial) || (options == only_full_chunks);
4266simdutf_warn_unused
const char *find(
const char *start,
const char *end,
4267 char character)
noexcept;
4268simdutf_warn_unused
const char16_t *
4269find(
const char16_t *start,
const char16_t *end,
char16_t character)
noexcept;
4282simdutf_warn_unused simdutf_really_inline simdutf_constexpr23
const char *
4283find(
const char *start,
const char *end,
char character)
noexcept {
4284 #if SIMDUTF_CPLUSPLUS23
4286 for (; start != end; ++start)
4287 if (*start == character)
4293 return detail::find(start, end, character);
4296simdutf_warn_unused simdutf_really_inline simdutf_constexpr23
const char16_t *
4297find(
const char16_t *start,
const char16_t *end,
char16_t character)
noexcept {
4300 #if SIMDUTF_CPLUSPLUS23
4302 for (; start != end; ++start)
4303 if (*start == character)
4309 return detail::find(start, end, character);
4314 #include <simdutf/base64_tables.h>
4315 #include <simdutf/scalar/base64.h>
4319inline std::string_view to_string(base64_options options) {
4321 case base64_default:
4322 return "base64_default";
4324 return "base64_url";
4325 case base64_reverse_padding:
4326 return "base64_reverse_padding";
4327 case base64_url_with_padding:
4328 return "base64_url_with_padding";
4329 case base64_default_accept_garbage:
4330 return "base64_default_accept_garbage";
4331 case base64_url_accept_garbage:
4332 return "base64_url_accept_garbage";
4333 case base64_default_or_url:
4334 return "base64_default_or_url";
4335 case base64_default_or_url_accept_garbage:
4336 return "base64_default_or_url_accept_garbage";
4341inline std::string_view to_string(last_chunk_handling_options options) {
4347 case stop_before_partial:
4348 return "stop_before_partial";
4349 case only_full_chunks:
4350 return "only_full_chunks";
4368simdutf_warn_unused
size_t
4371simdutf_really_inline simdutf_warn_unused simdutf_constexpr23
size_t
4373 const detail::input_span_of_byte_like
auto &input)
noexcept {
4374 #if SIMDUTF_CPLUSPLUS23
4376 return scalar::base64::maximal_binary_length_from_base64(
4377 detail::constexpr_cast_ptr<uint8_t>(input.data()), input.size());
4382 reinterpret_cast<const char *
>(input.data()), input.size());
4402 const char16_t *input,
size_t length)
noexcept;
4404simdutf_really_inline simdutf_warn_unused simdutf_constexpr23
size_t
4406 #if SIMDUTF_CPLUSPLUS23
4408 return scalar::base64::maximal_binary_length_from_base64(input.data(),
4433 size_t length)
noexcept;
4435simdutf_really_inline simdutf_warn_unused simdutf_constexpr23
size_t
4437 const detail::input_span_of_byte_like
auto &input)
noexcept {
4438 #if SIMDUTF_CPLUSPLUS23
4440 return scalar::base64::binary_length_from_base64(input.data(),
4446 reinterpret_cast<const char *
>(input.data()), input.size());
4467 size_t length)
noexcept;
4469simdutf_really_inline simdutf_warn_unused simdutf_constexpr23
size_t
4471 #if SIMDUTF_CPLUSPLUS23
4473 return scalar::base64::binary_length_from_base64(input.data(),
4538 const char *input,
size_t length,
char *output,
4539 base64_options options = base64_default,
4540 last_chunk_handling_options last_chunk_options = loose)
noexcept;
4542simdutf_really_inline simdutf_warn_unused simdutf_constexpr23
result
4544 const detail::input_span_of_byte_like
auto &input,
4545 detail::output_span_of_byte_like
auto &&binary_output,
4546 base64_options options = base64_default,
4547 last_chunk_handling_options last_chunk_options = loose)
noexcept {
4548 #if SIMDUTF_CPLUSPLUS23
4550 return scalar::base64::base64_to_binary_details_impl(
4551 input.data(), input.size(), binary_output.data(), options,
4552 last_chunk_options);
4558 reinterpret_cast<char *
>(binary_output.data()),
4559 options, last_chunk_options);
4572 size_t length, base64_options options = base64_default)
noexcept {
4573 return scalar::base64::base64_length_from_binary(length, options);
4586inline simdutf_warn_unused simdutf_constexpr23
size_t
4588 size_t length, base64_options options = base64_default,
4590 return scalar::base64::base64_length_from_binary_with_lines(length, options,
4616 base64_options options = base64_default)
noexcept;
4618simdutf_really_inline simdutf_warn_unused simdutf_constexpr23
size_t
4620 detail::output_span_of_byte_like
auto &&binary_output,
4621 base64_options options = base64_default)
noexcept {
4622 #if SIMDUTF_CPLUSPLUS23
4624 return scalar::base64::tail_encode_base64(
4625 binary_output.data(), input.data(), input.size(), options);
4630 reinterpret_cast<const char *
>(input.data()), input.size(),
4631 reinterpret_cast<char *
>(binary_output.data()), options);
4663 base64_options options = base64_default)
noexcept;
4665simdutf_really_inline simdutf_warn_unused simdutf_constexpr23
size_t
4667 const detail::input_span_of_byte_like
auto &input,
4668 detail::output_span_of_byte_like
auto &&binary_output,
4670 base64_options options = base64_default)
noexcept {
4671 #if SIMDUTF_CPLUSPLUS23
4673 return scalar::base64::tail_encode_base64_impl<true>(
4674 binary_output.data(), input.data(), input.size(), options, line_length);
4679 reinterpret_cast<const char *
>(input.data()), input.size(),
4680 reinterpret_cast<char *
>(binary_output.data()), line_length, options);
4685 #if SIMDUTF_ATOMIC_REF
4728atomic_binary_to_base64(
const char *input,
size_t length,
char *output,
4729 base64_options options = base64_default)
noexcept;
4731simdutf_really_inline simdutf_warn_unused
size_t
4732atomic_binary_to_base64(
const detail::input_span_of_byte_like
auto &input,
4733 detail::output_span_of_byte_like
auto &&binary_output,
4734 base64_options options = base64_default)
noexcept {
4735 return atomic_binary_to_base64(
4736 reinterpret_cast<const char *
>(input.data()), input.size(),
4737 reinterpret_cast<char *
>(binary_output.data()), options);
4798simdutf_warn_unused result
4800 base64_options options = base64_default,
4801 last_chunk_handling_options last_chunk_options =
4802 last_chunk_handling_options::loose)
noexcept;
4804simdutf_really_inline simdutf_warn_unused simdutf_constexpr23
result
4806 std::span<const char16_t> input,
4807 detail::output_span_of_byte_like
auto &&binary_output,
4808 base64_options options = base64_default,
4809 last_chunk_handling_options last_chunk_options = loose)
noexcept {
4810 #if SIMDUTF_CPLUSPLUS23
4812 return scalar::base64::base64_to_binary_details_impl(
4813 input.data(), input.size(), binary_output.data(), options,
4814 last_chunk_options);
4819 reinterpret_cast<char *
>(binary_output.data()),
4820 options, last_chunk_options);
4872simdutf_warn_unused full_result
4874 base64_options options = base64_default,
4875 last_chunk_handling_options last_chunk_options =
4876 last_chunk_handling_options::loose)
noexcept;
4878simdutf_really_inline simdutf_warn_unused simdutf_constexpr23
full_result
4880 const detail::input_span_of_byte_like
auto &input,
4881 detail::output_span_of_byte_like
auto &&binary_output,
4882 base64_options options = base64_default,
4883 last_chunk_handling_options last_chunk_options = loose)
noexcept {
4884 #if SIMDUTF_CPLUSPLUS23
4886 return scalar::base64::base64_to_binary_details_impl(
4887 input.data(), input.size(), binary_output.data(), options,
4888 last_chunk_options);
4893 reinterpret_cast<const char *
>(input.data()), input.size(),
4894 reinterpret_cast<char *
>(binary_output.data()), options,
4895 last_chunk_options);
4948simdutf_warn_unused full_result
4950 base64_options options = base64_default,
4951 last_chunk_handling_options last_chunk_options =
4952 last_chunk_handling_options::loose)
noexcept;
4954simdutf_really_inline simdutf_warn_unused simdutf_constexpr23
full_result
4956 std::span<const char16_t> input,
4957 detail::output_span_of_byte_like
auto &&binary_output,
4958 base64_options options = base64_default,
4959 last_chunk_handling_options last_chunk_options = loose)
noexcept {
4960 #if SIMDUTF_CPLUSPLUS23
4962 return scalar::base64::base64_to_binary_details_impl(
4963 input.data(), input.size(), binary_output.data(), options,
4964 last_chunk_options);
4969 input.data(), input.size(),
4970 reinterpret_cast<char *
>(binary_output.data()), options,
4971 last_chunk_options);
4986simdutf_warn_unused simdutf_really_inline simdutf_constexpr23
bool
4988 return scalar::base64::is_ignorable(input, options);
4990simdutf_warn_unused simdutf_really_inline simdutf_constexpr23
bool
4992 base64_options options = base64_default)
noexcept {
4993 return scalar::base64::is_ignorable(input, options);
5007simdutf_warn_unused simdutf_really_inline simdutf_constexpr23
bool
5008base64_valid(
char input, base64_options options = base64_default)
noexcept {
5009 return scalar::base64::is_base64(input, options);
5011simdutf_warn_unused simdutf_really_inline simdutf_constexpr23
bool
5012base64_valid(
char16_t input, base64_options options = base64_default)
noexcept {
5013 return scalar::base64::is_base64(input, options);
5025simdutf_warn_unused simdutf_really_inline simdutf_constexpr23
bool
5027 base64_options options = base64_default)
noexcept {
5028 return scalar::base64::is_base64_or_padding(input, options);
5030simdutf_warn_unused simdutf_really_inline simdutf_constexpr23
bool
5032 base64_options options = base64_default)
noexcept {
5033 return scalar::base64::is_base64_or_padding(input, options);
5107simdutf_warn_unused result
5109 size_t &outlen, base64_options options = base64_default,
5110 last_chunk_handling_options last_chunk_options =
5111 last_chunk_handling_options::loose,
5112 bool decode_up_to_bad_char =
false) noexcept;
5115simdutf_warn_unused
result
5117 size_t &outlen, base64_options options = base64_default,
5118 last_chunk_handling_options last_chunk_options =
5119 last_chunk_handling_options::loose,
5120 bool decode_up_to_bad_char = false) noexcept;
5123 #if SIMDUTF_ATOMIC_REF
5163simdutf_warn_unused
result atomic_base64_to_binary_safe(
5164 const char *input,
size_t length,
char *output,
size_t &outlen,
5165 base64_options options = base64_default,
5166 last_chunk_handling_options last_chunk_options =
5167 last_chunk_handling_options::loose,
5168 bool decode_up_to_bad_char =
false) noexcept;
5169simdutf_warn_unused
result atomic_base64_to_binary_safe(
5170 const
char16_t *input,
size_t length,
char *output,
size_t &outlen,
5171 base64_options options = base64_default,
5172 last_chunk_handling_options last_chunk_options = loose,
5173 bool decode_up_to_bad_char = false) noexcept;
5179simdutf_really_inline simdutf_warn_unused std::tuple<result, std::size_t>
5180atomic_base64_to_binary_safe(
5181 const detail::input_span_of_byte_like
auto &binary_input,
5182 detail::output_span_of_byte_like
auto &&output,
5183 base64_options options = base64_default,
5184 last_chunk_handling_options last_chunk_options =
5185 last_chunk_handling_options::loose,
5186 bool decode_up_to_bad_char =
false) noexcept {
5187 size_t outlen = output.size();
5188 auto ret = atomic_base64_to_binary_safe(
5189 reinterpret_cast<const char *
>(binary_input.data()), binary_input.size(),
5190 reinterpret_cast<char *
>(output.data()), outlen, options,
5191 last_chunk_options, decode_up_to_bad_char);
5192 return {ret, outlen};
5198simdutf_warn_unused std::tuple<result, std::size_t>
5199atomic_base64_to_binary_safe(
5200 std::span<const char16_t> base64_input,
5201 detail::output_span_of_byte_like
auto &&binary_output,
5202 base64_options options = base64_default,
5203 last_chunk_handling_options last_chunk_options = loose,
5204 bool decode_up_to_bad_char =
false) noexcept {
5205 size_t outlen = binary_output.size();
5206 auto ret = atomic_base64_to_binary_safe(
5207 base64_input.data(), base64_input.size(),
5208 reinterpret_cast<char *
>(binary_output.data()), outlen, options,
5209 last_chunk_options, decode_up_to_bad_char);
5210 return {ret, outlen};
5235 virtual std::string_view
name() const noexcept {
return _name; }
5246 virtual std::string_view
description() const noexcept {
return _description; }
5259#if SIMDUTF_FEATURE_DETECT_ENCODING
5267 size_t length)
const noexcept;
5276 size_t length)
const noexcept = 0;
5286 virtual uint32_t required_instruction_sets()
const {
5287 return _required_instruction_sets;
5290#if SIMDUTF_FEATURE_UTF8 || SIMDUTF_FEATURE_DETECT_ENCODING
5301 size_t len)
const noexcept = 0;
5304#if SIMDUTF_FEATURE_UTF8
5317 simdutf_warn_unused
virtual result
5321#if SIMDUTF_FEATURE_ASCII
5331 simdutf_warn_unused
virtual bool
5346 simdutf_warn_unused
virtual result
5351#if SIMDUTF_FEATURE_UTF16 && SIMDUTF_FEATURE_ASCII
5363 simdutf_warn_unused
virtual bool
5377 simdutf_warn_unused
virtual bool
5381#if SIMDUTF_FEATURE_UTF16 || SIMDUTF_FEATURE_DETECT_ENCODING
5396 simdutf_warn_unused
virtual bool
5400#if SIMDUTF_FEATURE_UTF16
5415 simdutf_warn_unused
virtual bool
5434 simdutf_warn_unused
virtual result
5436 size_t len)
const noexcept = 0;
5454 simdutf_warn_unused
virtual result
5456 size_t len)
const noexcept = 0;
5470 char16_t *output)
const noexcept = 0;
5484 char16_t *output)
const noexcept = 0;
5487#if SIMDUTF_FEATURE_UTF32 || SIMDUTF_FEATURE_DETECT_ENCODING
5500 simdutf_warn_unused
virtual bool
5504#if SIMDUTF_FEATURE_UTF32
5520 simdutf_warn_unused
virtual result
5522 size_t len)
const noexcept = 0;
5525#if SIMDUTF_FEATURE_UTF8 && SIMDUTF_FEATURE_LATIN1
5536 simdutf_warn_unused
virtual size_t
5538 char *utf8_output)
const noexcept = 0;
5541#if SIMDUTF_FEATURE_UTF16 && SIMDUTF_FEATURE_LATIN1
5552 simdutf_warn_unused
virtual size_t
5554 char16_t *utf16_output)
const noexcept = 0;
5566 simdutf_warn_unused
virtual size_t
5568 char16_t *utf16_output)
const noexcept = 0;
5571#if SIMDUTF_FEATURE_UTF32 && SIMDUTF_FEATURE_LATIN1
5582 simdutf_warn_unused
virtual size_t
5584 char32_t *utf32_buffer)
const noexcept = 0;
5587#if SIMDUTF_FEATURE_UTF8 && SIMDUTF_FEATURE_LATIN1
5600 simdutf_warn_unused
virtual size_t
5602 char *latin1_output)
const noexcept = 0;
5620 simdutf_warn_unused
virtual result
5622 char *latin1_output)
const noexcept = 0;
5643 simdutf_warn_unused
virtual size_t
5645 char *latin1_output)
const noexcept = 0;
5648#if SIMDUTF_FEATURE_UTF8 && SIMDUTF_FEATURE_UTF16
5661 simdutf_warn_unused
virtual size_t
5663 char16_t *utf16_output)
const noexcept = 0;
5677 simdutf_warn_unused
virtual size_t
5679 char16_t *utf16_output)
const noexcept = 0;
5697 const char *input,
size_t length,
5698 char16_t *utf16_output)
const noexcept = 0;
5716 const char *input,
size_t length,
5717 char16_t *utf16_output)
const noexcept = 0;
5738 const char16_t *input,
size_t length)
const noexcept = 0;
5760 const char16_t *input,
size_t length)
const noexcept = 0;
5764#if SIMDUTF_FEATURE_UTF8 && SIMDUTF_FEATURE_UTF32
5777 simdutf_warn_unused
virtual size_t
5779 char32_t *utf32_output)
const noexcept = 0;
5795 simdutf_warn_unused
virtual result
5797 char32_t *utf32_output)
const noexcept = 0;
5800#if SIMDUTF_FEATURE_UTF8 && SIMDUTF_FEATURE_UTF16
5811 simdutf_warn_unused
virtual size_t
5813 char16_t *utf16_buffer)
const noexcept = 0;
5825 simdutf_warn_unused
virtual size_t
5827 char16_t *utf16_buffer)
const noexcept = 0;
5830#if SIMDUTF_FEATURE_UTF8 && SIMDUTF_FEATURE_UTF32
5841 simdutf_warn_unused
virtual size_t
5843 char32_t *utf32_buffer)
const noexcept = 0;
5846#if SIMDUTF_FEATURE_UTF8 && SIMDUTF_FEATURE_UTF16
5859 simdutf_warn_unused
virtual size_t
5863#if SIMDUTF_FEATURE_UTF8 && SIMDUTF_FEATURE_UTF32
5878 simdutf_warn_unused
virtual size_t
5882#if SIMDUTF_FEATURE_UTF16 && SIMDUTF_FEATURE_LATIN1
5899 simdutf_warn_unused
virtual size_t
5901 char *latin1_buffer)
const noexcept = 0;
5919 simdutf_warn_unused
virtual size_t
5921 char *latin1_buffer)
const noexcept = 0;
5942 simdutf_warn_unused
virtual result
5944 char *latin1_buffer)
const noexcept = 0;
5965 simdutf_warn_unused
virtual result
5967 char *latin1_buffer)
const noexcept = 0;
5989 simdutf_warn_unused
virtual size_t
5991 char *latin1_buffer)
const noexcept = 0;
6013 simdutf_warn_unused
virtual size_t
6015 char *latin1_buffer)
const noexcept = 0;
6018#if SIMDUTF_FEATURE_UTF8 && SIMDUTF_FEATURE_UTF16
6034 simdutf_warn_unused
virtual size_t
6036 char *utf8_buffer)
const noexcept = 0;
6053 simdutf_warn_unused
virtual size_t
6055 char *utf8_buffer)
const noexcept = 0;
6075 simdutf_warn_unused
virtual result
6077 char *utf8_buffer)
const noexcept = 0;
6097 simdutf_warn_unused
virtual result
6099 char *utf8_buffer)
const noexcept = 0;
6117 const char16_t *input,
size_t length,
6118 char *utf8_buffer)
const noexcept = 0;
6136 const char16_t *input,
size_t length,
6137 char *utf8_buffer)
const noexcept = 0;
6153 simdutf_warn_unused
virtual size_t
6155 char *utf8_buffer)
const noexcept = 0;
6171 simdutf_warn_unused
virtual size_t
6173 char *utf8_buffer)
const noexcept = 0;
6176#if SIMDUTF_FEATURE_UTF16 && SIMDUTF_FEATURE_UTF32
6192 simdutf_warn_unused
virtual size_t
6194 char32_t *utf32_buffer)
const noexcept = 0;
6211 simdutf_warn_unused
virtual size_t
6213 char32_t *utf32_buffer)
const noexcept = 0;
6234 const char16_t *input,
size_t length,
6235 char32_t *utf32_buffer)
const noexcept = 0;
6256 const char16_t *input,
size_t length,
6257 char32_t *utf32_buffer)
const noexcept = 0;
6273 simdutf_warn_unused
virtual size_t
6275 char32_t *utf32_buffer)
const noexcept = 0;
6291 simdutf_warn_unused
virtual size_t
6293 char32_t *utf32_buffer)
const noexcept = 0;
6296#if SIMDUTF_FEATURE_UTF8 && SIMDUTF_FEATURE_UTF16
6311 simdutf_warn_unused
virtual size_t
6313 size_t length)
const noexcept = 0;
6329 simdutf_warn_unused
virtual size_t
6331 size_t length)
const noexcept = 0;
6334#if SIMDUTF_FEATURE_UTF32 && SIMDUTF_FEATURE_LATIN1
6351 simdutf_warn_unused
virtual size_t
6353 char *latin1_buffer)
const noexcept = 0;
6356#if SIMDUTF_FEATURE_UTF32 && SIMDUTF_FEATURE_LATIN1
6376 simdutf_warn_unused
virtual result
6378 char *latin1_buffer)
const noexcept = 0;
6400 simdutf_warn_unused
virtual size_t
6402 char *latin1_buffer)
const noexcept = 0;
6405#if SIMDUTF_FEATURE_UTF8 && SIMDUTF_FEATURE_UTF32
6421 simdutf_warn_unused
virtual size_t
6423 char *utf8_buffer)
const noexcept = 0;
6442 simdutf_warn_unused
virtual result
6444 char *utf8_buffer)
const noexcept = 0;
6460 simdutf_warn_unused
virtual size_t
6462 char *utf8_buffer)
const noexcept = 0;
6465#if SIMDUTF_FEATURE_UTF16 && SIMDUTF_FEATURE_LATIN1
6475 simdutf_warn_unused
virtual size_t
6481#if SIMDUTF_FEATURE_UTF16 && SIMDUTF_FEATURE_UTF32
6497 simdutf_warn_unused
virtual size_t
6499 char16_t *utf16_buffer)
const noexcept = 0;
6516 simdutf_warn_unused
virtual size_t
6518 char16_t *utf16_buffer)
const noexcept = 0;
6539 const char32_t *input,
size_t length,
6540 char16_t *utf16_buffer)
const noexcept = 0;
6561 const char32_t *input,
size_t length,
6562 char16_t *utf16_buffer)
const noexcept = 0;
6578 simdutf_warn_unused
virtual size_t
6580 char16_t *utf16_buffer)
const noexcept = 0;
6596 simdutf_warn_unused
virtual size_t
6598 char16_t *utf16_buffer)
const noexcept = 0;
6601#if SIMDUTF_FEATURE_UTF16
6617 char16_t *output)
const noexcept = 0;
6620#if SIMDUTF_FEATURE_UTF8 && SIMDUTF_FEATURE_LATIN1
6629 simdutf_warn_unused
virtual size_t
6633#if SIMDUTF_FEATURE_UTF8 && SIMDUTF_FEATURE_UTF32
6646 simdutf_warn_unused
virtual size_t
6648 size_t length)
const noexcept = 0;
6651#if SIMDUTF_FEATURE_UTF32 && SIMDUTF_FEATURE_LATIN1
6663 simdutf_warn_unused
virtual size_t
6669#if SIMDUTF_FEATURE_UTF8 && SIMDUTF_FEATURE_LATIN1
6681 simdutf_warn_unused
virtual size_t
6685#if SIMDUTF_FEATURE_UTF16 && SIMDUTF_FEATURE_LATIN1
6700 simdutf_warn_unused
virtual size_t
6706#if SIMDUTF_FEATURE_UTF16 && SIMDUTF_FEATURE_UTF32
6719 simdutf_warn_unused
virtual size_t
6721 size_t length)
const noexcept = 0;
6724#if SIMDUTF_FEATURE_UTF32 && SIMDUTF_FEATURE_LATIN1
6733 simdutf_warn_unused
virtual size_t
6739#if SIMDUTF_FEATURE_UTF16 && SIMDUTF_FEATURE_UTF32
6757 simdutf_warn_unused
virtual size_t
6759 size_t length)
const noexcept = 0;
6778 simdutf_warn_unused
virtual size_t
6780 size_t length)
const noexcept = 0;
6783#if SIMDUTF_FEATURE_UTF16
6799 simdutf_warn_unused
virtual size_t
6817 simdutf_warn_unused
virtual size_t
6821#if SIMDUTF_FEATURE_UTF8
6834 simdutf_warn_unused
virtual size_t
6838#if SIMDUTF_FEATURE_BASE64
6853 const char *input,
size_t length)
const noexcept;
6870 const char16_t *input,
size_t length)
const noexcept;
6884 simdutf_warn_unused
virtual size_t
6900 simdutf_warn_unused
virtual size_t
6902 size_t length)
const noexcept;
6937 simdutf_warn_unused
virtual result
6939 base64_options options = base64_default,
6940 last_chunk_handling_options last_chunk_options =
6941 last_chunk_handling_options::loose)
const noexcept = 0;
6976 const char *input,
size_t length,
char *output,
6977 base64_options options = base64_default,
6978 last_chunk_handling_options last_chunk_options =
6979 last_chunk_handling_options::loose)
const noexcept = 0;
7015 simdutf_warn_unused
virtual result
7017 base64_options options = base64_default,
7018 last_chunk_handling_options last_chunk_options =
7019 last_chunk_handling_options::loose)
const noexcept = 0;
7054 const char16_t *input,
size_t length,
char *output,
7055 base64_options options = base64_default,
7056 last_chunk_handling_options last_chunk_options =
7057 last_chunk_handling_options::loose)
const noexcept = 0;
7068 size_t length, base64_options options = base64_default)
const noexcept;
7093 base64_options options = base64_default)
const noexcept = 0;
7121 const char *input,
size_t length,
char *output,
7123 base64_options options = base64_default)
const noexcept = 0;
7135 virtual const char *
find(
const char *start,
const char *end,
7136 char character)
const noexcept = 0;
7137 virtual const char16_t *
find(
const char16_t *start,
const char16_t *end,
7138 char16_t character)
const noexcept = 0;
7141#ifdef SIMDUTF_INTERNAL_TESTS
7150 struct TestProcedure {
7152 std::string_view name;
7158 virtual std::vector<TestProcedure> internal_tests()
const;
7171 uint32_t required_instruction_sets)
7173 _required_instruction_sets(required_instruction_sets) {}
7176 ~implementation() =
default;
7187 const char *_description;
7192 const uint32_t _required_instruction_sets;
7201class available_implementation_list {
7204 simdutf_really_inline available_implementation_list() {}
7206 size_t size() const noexcept;
7208 const implementation *const *begin() const noexcept;
7210 const implementation *const *end() const noexcept;
7225 const implementation *operator[](std::string_view name) const noexcept {
7226 for (
const implementation *impl : *this) {
7227 if (impl->name() == name) {
7247 const implementation *detect_best_supported() const noexcept;
7250template <typename T> class atomic_ptr {
7252 atomic_ptr(T *_ptr) : ptr{_ptr} {}
7254#if defined(SIMDUTF_NO_THREADS)
7255 operator const T *()
const {
return ptr; }
7256 const T &operator*()
const {
return *ptr; }
7257 const T *operator->()
const {
return ptr; }
7259 operator T *() {
return ptr; }
7260 T &operator*() {
return *ptr; }
7261 T *operator->() {
return ptr; }
7262 atomic_ptr &operator=(T *_ptr) {
7268 operator const T *()
const {
return ptr.load(); }
7269 const T &operator*()
const {
return *ptr; }
7270 const T *operator->()
const {
return ptr.load(); }
7272 operator T *() {
return ptr.load(); }
7273 T &operator*() {
return *ptr; }
7274 T *operator->() {
return ptr.load(); }
7275 atomic_ptr &operator=(T *_ptr) {
7283#if defined(SIMDUTF_NO_THREADS)
7286 std::atomic<T *> ptr;
7290class detect_best_supported_implementation_on_first_use;
7297extern SIMDUTF_DLLIMPORTEXPORT
const internal::available_implementation_list &
7306extern SIMDUTF_DLLIMPORTEXPORT internal::atomic_ptr<const implementation> &
7311#if SIMDUTF_FEATURE_BASE64
7313 #include <simdutf/base64_implementation.h>
7321simdutf_really_inline
7322 simdutf_constexpr23 simdutf_warn_unused std::tuple<result, std::size_t>
7324 const detail::input_span_of_byte_like
auto &input,
7325 detail::output_span_of_byte_like
auto &&binary_output,
7326 base64_options options = base64_default,
7327 last_chunk_handling_options last_chunk_options = loose,
7328 bool decode_up_to_bad_char =
false) noexcept {
7329 size_t outlen = binary_output.size();
7330 #if SIMDUTF_CPLUSPLUS23
7332 using CInput = std::decay_t<
decltype(*input.data())>;
7333 static_assert(std::is_same_v<CInput, char>,
7334 "sorry, the constexpr implementation is for now limited to "
7335 "input of type char");
7336 using COutput = std::decay_t<
decltype(*binary_output.data())>;
7337 static_assert(std::is_same_v<COutput, char>,
7338 "sorry, the constexpr implementation is for now limited to "
7339 "output of type char");
7340 auto r = base64_to_binary_safe_impl(
7341 input.data(), input.size(), binary_output.data(), outlen, options,
7342 last_chunk_options, decode_up_to_bad_char);
7347 auto r = base64_to_binary_safe_impl<char>(
7348 reinterpret_cast<const char *
>(input.data()), input.size(),
7349 reinterpret_cast<char *
>(binary_output.data()), outlen, options,
7350 last_chunk_options, decode_up_to_bad_char);
7360simdutf_really_inline
7361 simdutf_warn_unused simdutf_constexpr23 std::tuple<result, std::size_t>
7363 std::span<const char16_t> input,
7364 detail::output_span_of_byte_like
auto &&binary_output,
7365 base64_options options = base64_default,
7366 last_chunk_handling_options last_chunk_options = loose,
7367 bool decode_up_to_bad_char =
false) noexcept {
7368 size_t outlen = binary_output.size();
7369 #if SIMDUTF_CPLUSPLUS23
7371 auto r = base64_to_binary_safe_impl(
7372 input.data(), input.size(), binary_output.data(), outlen, options,
7373 last_chunk_options, decode_up_to_bad_char);
7379 input.data(), input.size(),
7380 reinterpret_cast<char *
>(binary_output.data()), outlen, options,
7381 last_chunk_options, decode_up_to_bad_char);
7392#if SIMDUTF_CPLUSPLUS23 && SIMDUTF_FEATURE_BASE64
7401template <std::
size_t N>
struct base64_literal_helper {
7402 std::array<char, N - 1> storage{};
7403 static constexpr std::size_t size() noexcept {
return N - 1; }
7404 consteval base64_literal_helper(
const char (&str)[N]) {
7405 for (std::size_t i = 0; i < size(); i++) {
7406 storage[i] = str[i];
7411template <std::
size_t InputLen>
struct base64_decode_result {
7412 static constexpr std::size_t max_out = (InputLen + 3) / 4 * 3;
7413 std::array<char, max_out> buffer{};
7414 std::size_t output_count{};
7417template <std::
size_t InputLen>
7418consteval auto base64_decode_literal(
const char *str) {
7419 base64_decode_result<InputLen> result{};
7420 auto r = scalar::base64::base64_to_binary_details_impl(
7421 str, InputLen, result.buffer.data(), base64_default, loose);
7422 if (r.error != error_code::SUCCESS) {
7423 #if __cpp_lib_unreachable >= 202202L
7427 throw "invalid base64 input in _base64 literal";
7430 result.output_count = r.output_count;
7434template <base64_literal_helper a>
consteval auto base64_make_array() {
7435 constexpr auto decoded = base64_decode_literal<a.size()>(a.storage.data());
7436 std::array<char, decoded.output_count> ret{};
7437 for (std::size_t i = 0; i < decoded.output_count; i++) {
7438 ret[i] = decoded.buffer[i];
7456template <detail::base64_literal_helper a>
consteval auto operator""_base64() {
7457 return detail::base64_make_array<a>();
An implementation of simdutf for a particular CPU architecture.
virtual simdutf_warn_unused size_t convert_valid_utf32_to_latin1(const char32_t *input, size_t length, char *latin1_buffer) const noexcept=0
Convert valid UTF-32 string into Latin1 string.
virtual simdutf_warn_unused size_t binary_length_from_base64(const char *input, size_t length) const noexcept
Compute the binary length from a base64 input with ASCII spaces.
virtual const char * find(const char *start, const char *end, char character) const noexcept=0
Find the first occurrence of a character in a string.
virtual simdutf_warn_unused size_t convert_valid_utf8_to_utf16le(const char *input, size_t length, char16_t *utf16_buffer) const noexcept=0
Convert valid UTF-8 string into UTF-16LE string.
virtual simdutf_warn_unused size_t latin1_length_from_utf16(size_t length) const noexcept
Compute the number of bytes that this UTF-16LE/BE string would require in Latin1 format.
virtual simdutf_warn_unused size_t convert_utf16le_to_utf8_with_replacement(const char16_t *input, size_t length, char *utf8_buffer) const noexcept=0
Convert possibly broken UTF-16LE string into UTF-8 string, replacing unpaired surrogates with the Uni...
virtual simdutf_warn_unused size_t binary_length_from_base64(const char16_t *input, size_t length) const noexcept
Compute the binary length from a base64 input with ASCII spaces.
virtual simdutf_warn_unused size_t utf32_length_from_utf16be(const char16_t *input, size_t length) const noexcept=0
Compute the number of bytes that this UTF-16BE string would require in UTF-32 format.
virtual simdutf_warn_unused size_t convert_utf8_to_utf16be(const char *input, size_t length, char16_t *utf16_output) const noexcept=0
Convert possibly broken UTF-8 string into UTF-16BE string.
virtual simdutf_warn_unused size_t convert_utf16le_to_utf32(const char16_t *input, size_t length, char32_t *utf32_buffer) const noexcept=0
Convert possibly broken UTF-16LE string into UTF-32 string.
virtual simdutf_warn_unused size_t convert_valid_utf16be_to_utf32(const char16_t *input, size_t length, char32_t *utf32_buffer) const noexcept=0
Convert valid UTF-16LE string into UTF-32BE string.
virtual std::string_view name() const noexcept
The name of this implementation.
virtual simdutf_warn_unused size_t convert_valid_utf16be_to_utf8(const char16_t *input, size_t length, char *utf8_buffer) const noexcept=0
Convert valid UTF-16BE string into UTF-8 string.
virtual simdutf_warn_unused size_t convert_latin1_to_utf16le(const char *input, size_t length, char16_t *utf16_output) const noexcept=0
Convert possibly Latin1 string into UTF-16LE string.
virtual simdutf_warn_unused bool validate_utf16be(const char16_t *buf, size_t len) const noexcept=0
Validate the UTF-16BE string.
virtual simdutf_warn_unused result convert_utf16be_to_latin1_with_errors(const char16_t *input, size_t length, char *latin1_buffer) const noexcept=0
Convert possibly broken UTF-16BE string into Latin1 string.
virtual simdutf_warn_unused full_result base64_to_binary_details(const char *input, size_t length, char *output, base64_options options=base64_default, last_chunk_handling_options last_chunk_options=last_chunk_handling_options::loose) const noexcept=0
Convert a base64 input to a binary output while returning more details than base64_to_binary.
virtual simdutf_warn_unused size_t convert_valid_utf16le_to_utf32(const char16_t *input, size_t length, char32_t *utf32_buffer) const noexcept=0
Convert valid UTF-16LE string into UTF-32 string.
virtual simdutf_warn_unused size_t latin1_length_from_utf8(const char *input, size_t length) const noexcept=0
Compute the number of bytes that this UTF-8 string would require in Latin1 format.
virtual simdutf_warn_unused result convert_utf32_to_latin1_with_errors(const char32_t *input, size_t length, char *latin1_buffer) const noexcept=0
Convert possibly broken UTF-32 string into Latin1 string and stop on error.
virtual simdutf_warn_unused size_t utf8_length_from_utf32(const char32_t *input, size_t length) const noexcept=0
Compute the number of bytes that this UTF-32 string would require in UTF-8 format.
virtual simdutf_warn_unused size_t convert_latin1_to_utf16be(const char *input, size_t length, char16_t *utf16_output) const noexcept=0
Convert Latin1 string into UTF-16BE string.
virtual simdutf_warn_unused size_t latin1_length_from_utf32(size_t length) const noexcept
Compute the number of bytes that this UTF-32 string would require in Latin1 format.
virtual simdutf_warn_unused full_result base64_to_binary_details(const char16_t *input, size_t length, char *output, base64_options options=base64_default, last_chunk_handling_options last_chunk_options=last_chunk_handling_options::loose) const noexcept=0
Convert a base64 input to a binary output while returning more details than base64_to_binary.
virtual simdutf_warn_unused size_t convert_utf32_to_utf16le(const char32_t *input, size_t length, char16_t *utf16_buffer) const noexcept=0
Convert possibly broken UTF-32 string into UTF-16LE string.
virtual simdutf_warn_unused size_t utf16_length_from_utf32(const char32_t *input, size_t length) const noexcept=0
Compute the number of two-byte code units that this UTF-32 string would require in UTF-16 format.
virtual simdutf_warn_unused size_t count_utf8(const char *input, size_t length) const noexcept=0
Count the number of code points (characters) in the string assuming that it is valid.
virtual simdutf_warn_unused size_t convert_valid_utf32_to_utf16be(const char32_t *input, size_t length, char16_t *utf16_buffer) const noexcept=0
Convert valid UTF-32 string into UTF-16BE string.
virtual simdutf_warn_unused size_t utf32_length_from_utf8(const char *input, size_t length) const noexcept=0
Compute the number of 4-byte code units that this UTF-8 string would require in UTF-32 format.
virtual simdutf_warn_unused size_t convert_valid_utf16le_to_utf8(const char16_t *input, size_t length, char *utf8_buffer) const noexcept=0
Convert valid UTF-16LE string into UTF-8 string.
virtual void to_well_formed_utf16le(const char16_t *input, size_t len, char16_t *output) const noexcept=0
Copies the UTF-16LE string while replacing mismatched surrogates with the Unicode replacement charact...
virtual simdutf_warn_unused result convert_utf32_to_utf16be_with_errors(const char32_t *input, size_t length, char16_t *utf16_buffer) const noexcept=0
Convert possibly broken UTF-32 string into UTF-16BE string and stop on error.
virtual simdutf_warn_unused result validate_utf8_with_errors(const char *buf, size_t len) const noexcept=0
Validate the UTF-8 string and stop on errors.
virtual simdutf_warn_unused size_t utf8_length_from_utf16le(const char16_t *input, size_t length) const noexcept=0
Compute the number of bytes that this UTF-16LE string would require in UTF-8 format.
virtual size_t binary_to_base64_with_lines(const char *input, size_t length, char *output, size_t line_length=simdutf::default_line_length, base64_options options=base64_default) const noexcept=0
Convert a binary input to a base64 output with lines of given length.
virtual simdutf_warn_unused size_t convert_utf16be_to_utf8(const char16_t *input, size_t length, char *utf8_buffer) const noexcept=0
Convert possibly broken UTF-16BE string into UTF-8 string.
virtual simdutf_warn_unused size_t convert_utf8_to_utf16le(const char *input, size_t length, char16_t *utf16_output) const noexcept=0
Convert possibly broken UTF-8 string into UTF-16LE string.
virtual simdutf_warn_unused result convert_utf16le_to_latin1_with_errors(const char16_t *input, size_t length, char *latin1_buffer) const noexcept=0
Convert possibly broken UTF-16LE string into Latin1 string.
virtual simdutf_warn_unused result utf8_length_from_utf16le_with_replacement(const char16_t *input, size_t length) const noexcept=0
Compute the number of bytes that this UTF-16LE string would require in UTF-8 format even when the UTF...
virtual simdutf_warn_unused result validate_utf16le_with_errors(const char16_t *buf, size_t len) const noexcept=0
Validate the UTF-16LE string and stop on error.
virtual simdutf_warn_unused result convert_utf16be_to_utf8_with_errors(const char16_t *input, size_t length, char *utf8_buffer) const noexcept=0
Convert possibly broken UTF-16BE string into UTF-8 string and stop on error.
virtual size_t binary_to_base64(const char *input, size_t length, char *output, base64_options options=base64_default) const noexcept=0
Convert a binary input to a base64 output.
virtual simdutf_warn_unused result utf8_length_from_utf16be_with_replacement(const char16_t *input, size_t length) const noexcept=0
Compute the number of bytes that this UTF-16BE string would require in UTF-8 format even when the UTF...
virtual simdutf_warn_unused size_t convert_latin1_to_utf32(const char *input, size_t length, char32_t *utf32_buffer) const noexcept=0
Convert Latin1 string into UTF-32 string.
virtual simdutf_warn_unused result convert_utf8_to_utf32_with_errors(const char *input, size_t length, char32_t *utf32_output) const noexcept=0
Convert possibly broken UTF-8 string into UTF-32 string and stop on error.
virtual simdutf_warn_unused size_t convert_valid_utf32_to_utf8(const char32_t *input, size_t length, char *utf8_buffer) const noexcept=0
Convert valid UTF-32 string into UTF-8 string.
virtual simdutf_warn_unused size_t utf32_length_from_latin1(size_t length) const noexcept
Return the number of bytes that this UTF-32 string would require in Latin1 format.
virtual std::string_view description() const noexcept
The description of this implementation.
virtual simdutf_warn_unused bool validate_utf16le(const char16_t *buf, size_t len) const noexcept=0
Validate the UTF-16LE string.This function may be best when you expect the input to be almost always ...
virtual simdutf_warn_unused result convert_utf8_to_utf16le_with_errors(const char *input, size_t length, char16_t *utf16_output) const noexcept=0
Convert possibly broken UTF-8 string into UTF-16LE string and stop on error.
virtual simdutf_warn_unused size_t count_utf16le(const char16_t *input, size_t length) const noexcept=0
Count the number of code points (characters) in the string assuming that it is valid.
virtual simdutf_warn_unused size_t convert_utf16be_to_utf32(const char16_t *input, size_t length, char32_t *utf32_buffer) const noexcept=0
Convert possibly broken UTF-16BE string into UTF-32 string.
virtual simdutf_warn_unused size_t convert_valid_utf16le_to_latin1(const char16_t *input, size_t length, char *latin1_buffer) const noexcept=0
Convert valid UTF-16LE string into Latin1 string.
virtual simdutf_warn_unused size_t convert_utf32_to_latin1(const char32_t *input, size_t length, char *latin1_buffer) const noexcept=0
Convert possibly broken UTF-32 string into Latin1 string.
virtual simdutf_warn_unused size_t convert_valid_utf16be_to_latin1(const char16_t *input, size_t length, char *latin1_buffer) const noexcept=0
Convert valid UTF-16BE string into Latin1 string.
bool supported_by_runtime_system() const
The instruction sets this implementation is compiled against and the current CPU match.
virtual simdutf_warn_unused size_t convert_valid_utf8_to_utf32(const char *input, size_t length, char32_t *utf32_buffer) const noexcept=0
Convert valid UTF-8 string into UTF-32 string.
virtual simdutf_warn_unused size_t convert_utf16le_to_latin1(const char16_t *input, size_t length, char *latin1_buffer) const noexcept=0
Convert possibly broken UTF-16LE string into Latin1 string.
virtual simdutf_warn_unused result validate_utf16be_with_errors(const char16_t *buf, size_t len) const noexcept=0
Validate the UTF-16BE string and stop on error.
virtual simdutf_warn_unused result convert_utf16le_to_utf8_with_errors(const char16_t *input, size_t length, char *utf8_buffer) const noexcept=0
Convert possibly broken UTF-16LE string into UTF-8 string and stop on error.
virtual simdutf_warn_unused result convert_utf16be_to_utf32_with_errors(const char16_t *input, size_t length, char32_t *utf32_buffer) const noexcept=0
Convert possibly broken UTF-16BE string into UTF-32 string and stop on error.
virtual simdutf_warn_unused result base64_to_binary(const char *input, size_t length, char *output, base64_options options=base64_default, last_chunk_handling_options last_chunk_options=last_chunk_handling_options::loose) const noexcept=0
Convert a base64 input to a binary output.
virtual simdutf_warn_unused bool validate_utf16be_as_ascii(const char16_t *buf, size_t len) const noexcept=0
Validate the ASCII string as a UTF-16BE sequence.
virtual simdutf_warn_unused size_t convert_utf32_to_utf16be(const char32_t *input, size_t length, char16_t *utf16_buffer) const noexcept=0
Convert possibly broken UTF-32 string into UTF-16BE string.
virtual simdutf_warn_unused result validate_utf32_with_errors(const char32_t *buf, size_t len) const noexcept=0
Validate the UTF-32 string and stop on error.
virtual simdutf_warn_unused size_t utf32_length_from_utf16le(const char16_t *input, size_t length) const noexcept=0
Compute the number of bytes that this UTF-16LE string would require in UTF-32 format.
virtual void change_endianness_utf16(const char16_t *input, size_t length, char16_t *output) const noexcept=0
Change the endianness of the input.
virtual simdutf_warn_unused size_t convert_valid_utf8_to_utf16be(const char *input, size_t length, char16_t *utf16_buffer) const noexcept=0
Convert valid UTF-8 string into UTF-16BE string.
virtual simdutf_warn_unused size_t convert_valid_utf8_to_latin1(const char *input, size_t length, char *latin1_output) const noexcept=0
Convert valid UTF-8 string into latin1 string.
simdutf_warn_unused size_t maximal_binary_length_from_base64(const char *input, size_t length) const noexcept
Provide the maximal binary length in bytes given the base64 input.
virtual simdutf_warn_unused size_t convert_valid_utf32_to_utf16le(const char32_t *input, size_t length, char16_t *utf16_buffer) const noexcept=0
Convert valid UTF-32 string into UTF-16LE string.
virtual simdutf_warn_unused result validate_ascii_with_errors(const char *buf, size_t len) const noexcept=0
Validate the ASCII string and stop on error.
virtual simdutf_warn_unused bool validate_utf8(const char *buf, size_t len) const noexcept=0
Validate the UTF-8 string.
virtual simdutf_warn_unused size_t convert_utf8_to_utf32(const char *input, size_t length, char32_t *utf32_output) const noexcept=0
Convert possibly broken UTF-8 string into UTF-32 string.
simdutf_warn_unused size_t maximal_binary_length_from_base64(const char16_t *input, size_t length) const noexcept
Provide the maximal binary length in bytes given the base64 input.
virtual simdutf_warn_unused bool validate_utf32(const char32_t *buf, size_t len) const noexcept=0
Validate the UTF-32 string.
virtual simdutf_warn_unused result convert_utf16le_to_utf32_with_errors(const char16_t *input, size_t length, char32_t *utf32_buffer) const noexcept=0
Convert possibly broken UTF-16LE string into UTF-32 string and stop on error.
virtual simdutf_warn_unused size_t convert_utf16be_to_utf8_with_replacement(const char16_t *input, size_t length, char *utf8_buffer) const noexcept=0
Convert possibly broken UTF-16BE string into UTF-8 string, replacing unpaired surrogates with the Uni...
virtual simdutf_warn_unused size_t convert_utf16le_to_utf8(const char16_t *input, size_t length, char *utf8_buffer) const noexcept=0
Convert possibly broken UTF-16LE string into UTF-8 string.
virtual simdutf_warn_unused size_t utf8_length_from_utf16be(const char16_t *input, size_t length) const noexcept=0
Compute the number of bytes that this UTF-16BE string would require in UTF-8 format.
virtual simdutf_warn_unused size_t convert_utf32_to_utf8(const char32_t *input, size_t length, char *utf8_buffer) const noexcept=0
Convert possibly broken UTF-32 string into UTF-8 string.
virtual simdutf_warn_unused size_t convert_utf16be_to_latin1(const char16_t *input, size_t length, char *latin1_buffer) const noexcept=0
Convert possibly broken UTF-16BE string into Latin1 string.
virtual simdutf_warn_unused size_t convert_utf8_to_latin1(const char *input, size_t length, char *latin1_output) const noexcept=0
Convert possibly broken UTF-8 string into latin1 string.
virtual simdutf_warn_unused result base64_to_binary(const char16_t *input, size_t length, char *output, base64_options options=base64_default, last_chunk_handling_options last_chunk_options=last_chunk_handling_options::loose) const noexcept=0
Convert a base64 input to a binary output.
simdutf_warn_unused size_t base64_length_from_binary(size_t length, base64_options options=base64_default) const noexcept
Provide the base64 length in bytes given the length of a binary input.
virtual int detect_encodings(const char *input, size_t length) const noexcept=0
This function will try to detect the possible encodings in one pass.
virtual simdutf_warn_unused size_t count_utf16be(const char16_t *input, size_t length) const noexcept=0
Count the number of code points (characters) in the string assuming that it is valid.
virtual simdutf_warn_unused result convert_utf32_to_utf8_with_errors(const char32_t *input, size_t length, char *utf8_buffer) const noexcept=0
Convert possibly broken UTF-32 string into UTF-8 string and stop on error.
virtual simdutf_warn_unused bool validate_utf16le_as_ascii(const char16_t *buf, size_t len) const noexcept=0
Validate the ASCII string as a UTF-16LE sequence.
virtual void to_well_formed_utf16be(const char16_t *input, size_t len, char16_t *output) const noexcept=0
Copies the UTF-16BE string while replacing mismatched surrogates with the Unicode replacement charact...
virtual simdutf_warn_unused bool validate_ascii(const char *buf, size_t len) const noexcept=0
Validate the ASCII string.
virtual simdutf_warn_unused size_t utf16_length_from_utf8(const char *input, size_t length) const noexcept=0
Compute the number of 2-byte code units that this UTF-8 string would require in UTF-16LE format.
virtual simdutf_warn_unused result convert_utf8_to_utf16be_with_errors(const char *input, size_t length, char16_t *utf16_output) const noexcept=0
Convert possibly broken UTF-8 string into UTF-16BE string and stop on error.
virtual simdutf_warn_unused result convert_utf8_to_latin1_with_errors(const char *input, size_t length, char *latin1_output) const noexcept=0
Convert possibly broken UTF-8 string into latin1 string with errors.
virtual simdutf_warn_unused size_t utf16_length_from_latin1(size_t length) const noexcept
Return the number of bytes that this UTF-16 string would require in Latin1 format.
virtual simdutf_warn_unused result convert_utf32_to_utf16le_with_errors(const char32_t *input, size_t length, char16_t *utf16_buffer) const noexcept=0
Convert possibly broken UTF-32 string into UTF-16LE string and stop on error.
virtual simdutf_warn_unused size_t convert_latin1_to_utf8(const char *input, size_t length, char *utf8_output) const noexcept=0
Convert Latin1 string into UTF-8 string.
virtual encoding_type autodetect_encoding(const char *input, size_t length) const noexcept
This function will try to detect the encoding.
virtual simdutf_warn_unused size_t utf8_length_from_latin1(const char *input, size_t length) const noexcept=0
Return the number of bytes that this Latin1 string would require in UTF-8 format.
helpers placed in namespace detail are not a part of the public API
simdutf_warn_unused simdutf_really_inline simdutf_constexpr23 size_t utf32_length_from_latin1(size_t length) noexcept
Compute the number of bytes that this Latin1 string would require in UTF-32 format.
simdutf_warn_unused size_t convert_utf16_to_latin1(const char16_t *input, size_t length, char *latin1_buffer) noexcept
Using native endianness, convert possibly broken UTF-16 string into Latin1 string.
simdutf_warn_unused size_t convert_valid_utf16_to_utf8(const char16_t *input, size_t length, char *utf8_buffer) noexcept
Using native endianness, convert valid UTF-16 string into UTF-8 string.
simdutf_warn_unused bool validate_utf16be(const char16_t *buf, size_t len) noexcept
Validate the UTF-16BE string.
simdutf_warn_unused size_t convert_valid_utf16_to_latin1(const char16_t *input, size_t length, char *latin1_buffer) noexcept
Using native endianness, convert UTF-16 string into Latin1 string.
simdutf_warn_unused size_t convert_valid_utf16le_to_utf8(const char16_t *input, size_t length, char *utf8_buffer) noexcept
Convert valid UTF-16LE string into UTF-8 string.
simdutf_warn_unused simdutf_constexpr23 size_t base64_length_from_binary(size_t length, base64_options options=base64_default) noexcept
Provide the base64 length in bytes given the length of a binary input.
simdutf_warn_unused simdutf_really_inline simdutf_constexpr23 bool base64_ignorable(char input, base64_options options=base64_default) noexcept
Check if a character is an ignorable base64 character.
simdutf_warn_unused bool validate_utf16_as_ascii(const char16_t *buf, size_t len) noexcept
Validate the ASCII string as a UTF-16 sequence.
simdutf_warn_unused bool validate_utf16le(const char16_t *buf, size_t len) noexcept
Validate the UTF-16LE string.
simdutf_warn_unused size_t utf8_length_from_utf32(const char32_t *input, size_t length) noexcept
Compute the number of bytes that this UTF-32 string would require in UTF-8 format.
simdutf_warn_unused simdutf_really_inline simdutf_constexpr23 const char * find(const char *start, const char *end, char character) noexcept
Find the first occurrence of a character in a string.
simdutf_warn_unused result base64_to_binary_safe(const char *input, size_t length, char *output, size_t &outlen, base64_options options=base64_default, last_chunk_handling_options last_chunk_options=last_chunk_handling_options::loose, bool decode_up_to_bad_char=false) noexcept
Convert a base64 input to a binary output.
simdutf_warn_unused size_t convert_utf16be_to_utf8_with_replacement(const char16_t *input, size_t length, char *utf8_buffer) noexcept
Convert possibly broken UTF-16BE string into UTF-8 string, replacing unpaired surrogates with the Uni...
simdutf_warn_unused size_t convert_utf8_to_utf32(const char *input, size_t length, char32_t *utf32_output) noexcept
Convert possibly broken UTF-8 string into UTF-32 string.
simdutf_warn_unused size_t convert_valid_utf16le_to_utf32(const char16_t *input, size_t length, char32_t *utf32_buffer) noexcept
Convert valid UTF-16LE string into UTF-32 string.
simdutf_warn_unused size_t utf32_length_from_utf16le(const char16_t *input, size_t length) noexcept
Compute the number of bytes that this UTF-16LE string would require in UTF-32 format.
constexpr size_t default_line_length
default line length for base64 encoding with lines
size_t binary_to_base64(const char *input, size_t length, char *output, base64_options options=base64_default) noexcept
Convert a binary input to a base64 output.
simdutf_warn_unused result base64_to_binary(const char *input, size_t length, char *output, base64_options options=base64_default, last_chunk_handling_options last_chunk_options=loose) noexcept
Convert a base64 input to a binary output.
SIMDUTF_DLLIMPORTEXPORT internal::atomic_ptr< const implementation > & get_active_implementation()
The active implementation.
simdutf_warn_unused size_t convert_utf16be_to_latin1(const char16_t *input, size_t length, char *latin1_buffer) noexcept
Convert possibly broken UTF-16BE string into Latin1 string.
simdutf_warn_unused size_t convert_utf16le_to_utf8(const char16_t *input, size_t length, char *utf8_buffer) noexcept
Convert possibly broken UTF-16LE string into UTF-8 string.
simdutf_warn_unused bool validate_utf16le_as_ascii(const char16_t *buf, size_t len) noexcept
Validate the ASCII string as a UTF-16LE sequence.
simdutf_warn_unused size_t convert_valid_utf8_to_latin1(const char *input, size_t length, char *latin1_output) noexcept
Convert valid UTF-8 string into latin1 string.
simdutf_warn_unused size_t convert_utf8_to_utf16le(const char *input, size_t length, char16_t *utf16_output) noexcept
Convert possibly broken UTF-8 string into UTF-16LE string.
simdutf_warn_unused size_t convert_valid_utf16be_to_utf8(const char16_t *input, size_t length, char *utf8_buffer) noexcept
Convert valid UTF-16BE string into UTF-8 string.
simdutf_warn_unused full_result convert_latin1_to_utf8_safe_with_details(const char *input, size_t length, char *utf8_output, size_t utf8_len) noexcept
Convert a Latin1 string into a size-limited UTF-8 buffer and report how much input was consumed and o...
simdutf_warn_unused size_t convert_latin1_to_utf32(const char *input, size_t length, char32_t *utf32_buffer) noexcept
Convert Latin1 string into UTF-32 string.
simdutf_warn_unused size_t convert_utf16_to_utf8(const char16_t *input, size_t length, char *utf8_buffer) noexcept
Using native endianness, convert possibly broken UTF-16 string into UTF-8 string.
simdutf_warn_unused size_t convert_utf16le_to_utf32(const char16_t *input, size_t length, char32_t *utf32_buffer) noexcept
Convert possibly broken UTF-16LE string into UTF-32 string.
simdutf_warn_unused result convert_utf16be_to_utf8_with_errors(const char16_t *input, size_t length, char *utf8_buffer) noexcept
Convert possibly broken UTF-16BE string into UTF-8 string and stop on error.
simdutf_warn_unused size_t convert_valid_utf8_to_utf32(const char *input, size_t length, char32_t *utf32_buffer) noexcept
Convert valid UTF-8 string into UTF-32 string.
simdutf_warn_unused result convert_utf32_to_utf8_with_errors(const char32_t *input, size_t length, char *utf8_buffer) noexcept
Convert possibly broken UTF-32 string into UTF-8 string and stop on error.
simdutf_warn_unused result validate_utf16be_with_errors(const char16_t *buf, size_t len) noexcept
Validate the UTF-16BE string and stop on error.
simdutf_warn_unused size_t convert_utf16_to_utf8_with_replacement(const char16_t *input, size_t length, char *utf8_buffer) noexcept
Convert possibly broken UTF-16 string (native endianness) into UTF-8 string, replacing unpaired surro...
SIMDUTF_DLLIMPORTEXPORT const internal::available_implementation_list & get_available_implementations()
The list of available implementations compiled into simdutf.
simdutf_warn_unused size_t convert_utf32_to_utf16le(const char32_t *input, size_t length, char16_t *utf16_buffer) noexcept
Convert possibly broken UTF-32 string into UTF-16LE string.
simdutf_really_inline simdutf_warn_unused simdutf_constexpr23 size_t utf16_length_from_latin1(size_t length) noexcept
Compute the number of code units that this Latin1 string would require in UTF-16 format.
simdutf_warn_unused simdutf_really_inline simdutf_constexpr23 bool base64_valid_or_padding(char input, base64_options options=base64_default) noexcept
Check if a character is a valid base64 character or the padding character ('=').
void change_endianness_utf16(const char16_t *input, size_t length, char16_t *output) noexcept
Change the endianness of the input.
simdutf_warn_unused result utf8_length_from_utf16_with_replacement(const char16_t *input, size_t length) noexcept
Using native endianness; compute the number of bytes that this UTF-16 string would require in UTF-8 f...
simdutf_warn_unused full_result convert_utf16_to_utf8_with_replacement_safe(const char16_t *input, size_t length, char *utf8_output, size_t utf8_len) noexcept
Convert a possibly broken UTF-16 string into a size-limited UTF-8 buffer, replacing unpaired surrogat...
simdutf_warn_unused result utf8_length_from_utf16le_with_replacement(const char16_t *input, size_t length) noexcept
Compute the number of bytes that this UTF-16LE string would require in UTF-8 format even when the UTF...
simdutf_warn_unused full_result base64_to_binary_details(const char *input, size_t length, char *output, base64_options options=base64_default, last_chunk_handling_options last_chunk_options=last_chunk_handling_options::loose) noexcept
Convert a base64 input to a binary output while returning more details than base64_to_binary.
simdutf_warn_unused size_t convert_utf16be_to_utf32(const char16_t *input, size_t length, char32_t *utf32_buffer) noexcept
Convert possibly broken UTF-16BE string into UTF-32 string.
simdutf_warn_unused size_t utf8_length_from_latin1(const char *input, size_t length) noexcept
Return the number of bytes that this Latin1 string would require in UTF-8 format.
simdutf_warn_unused result convert_utf8_to_utf16le_with_errors(const char *input, size_t length, char16_t *utf16_output) noexcept
Convert possibly broken UTF-8 string into UTF-16LE string and stop on error.
simdutf_warn_unused size_t count_utf16be(const char16_t *input, size_t length) noexcept
Count the number of code points (characters) in the string assuming that it is valid.
simdutf_warn_unused bool validate_utf8(const char *buf, size_t len) noexcept
Validate the UTF-8 string.
simdutf_warn_unused bool validate_utf16(const char16_t *buf, size_t len) noexcept
Using native endianness; Validate the UTF-16 string.
simdutf_warn_unused result convert_utf16be_to_utf32_with_errors(const char16_t *input, size_t length, char32_t *utf32_buffer) noexcept
Convert possibly broken UTF-16BE string into UTF-32 string and stop on error.
simdutf_warn_unused size_t utf8_length_from_utf16le(const char16_t *input, size_t length) noexcept
Compute the number of bytes that this UTF-16LE string would require in UTF-8 format.
simdutf_warn_unused size_t count_utf8(const char *input, size_t length) noexcept
Count the number of code points (characters) in the string assuming that it is valid.
simdutf_warn_unused bool validate_utf32(const char32_t *buf, size_t len) noexcept
Validate the UTF-32 string.
simdutf_warn_unused result convert_utf16le_to_utf8_with_errors(const char16_t *input, size_t length, char *utf8_buffer) noexcept
Convert possibly broken UTF-16LE string into UTF-8 string and stop on error.
simdutf_warn_unused result utf8_length_from_utf16be_with_replacement(const char16_t *input, size_t length) noexcept
Compute the number of bytes that this UTF-16BE string would require in UTF-8 format even when the UTF...
simdutf_warn_unused size_t convert_valid_utf8_to_utf16be(const char *input, size_t length, char16_t *utf16_buffer) noexcept
Convert valid UTF-8 string into UTF-16BE string.
simdutf_warn_unused size_t utf8_length_from_utf16be(const char16_t *input, size_t length) noexcept
Compute the number of bytes that this UTF-16BE string would require in UTF-8 format.
simdutf_warn_unused result convert_utf32_to_utf16_with_errors(const char32_t *input, size_t length, char16_t *utf16_buffer) noexcept
Using native endianness, convert possibly broken UTF-32 string into UTF-16 string and stop on error.
simdutf_warn_unused size_t trim_partial_utf16(const char16_t *input, size_t length)
Given a valid UTF-16 string having a possibly truncated last character, this function checks the end ...
simdutf_warn_unused result convert_utf32_to_latin1_with_errors(const char32_t *input, size_t length, char *latin1_buffer) noexcept
Convert possibly broken UTF-32 string into Latin1 string and stop on error.
simdutf_warn_unused size_t convert_valid_utf32_to_utf16le(const char32_t *input, size_t length, char16_t *utf16_buffer) noexcept
Convert valid UTF-32 string into UTF-16LE string.
simdutf_warn_unused size_t convert_valid_utf16le_to_latin1(const char16_t *input, size_t length, char *latin1_buffer) noexcept
Convert valid UTF-16LE string into Latin1 string.
simdutf_warn_unused size_t convert_valid_utf8_to_utf16(const char *input, size_t length, char16_t *utf16_buffer) noexcept
Using native endianness, convert valid UTF-8 string into a UTF-16 string.
simdutf_warn_unused size_t count_utf16(const char16_t *input, size_t length) noexcept
Count the number of code points (characters) in the string assuming that it is valid.
simdutf_warn_unused result convert_utf32_to_utf16le_with_errors(const char32_t *input, size_t length, char16_t *utf16_buffer) noexcept
Convert possibly broken UTF-32 string into UTF-16LE string and stop on error.
simdutf_warn_unused size_t convert_latin1_to_utf8(const char *input, size_t length, char *utf8_output) noexcept
Convert Latin1 string into UTF-8 string.
simdutf_warn_unused result convert_utf16_to_utf8_with_errors(const char16_t *input, size_t length, char *utf8_buffer) noexcept
Using native endianness, convert possibly broken UTF-16 string into UTF-8 string and stop on error.
simdutf_warn_unused size_t convert_utf16le_to_utf8_with_replacement(const char16_t *input, size_t length, char *utf8_buffer) noexcept
Convert possibly broken UTF-16LE string into UTF-8 string, replacing unpaired surrogates with the Uni...
simdutf_warn_unused size_t maximal_binary_length_from_base64(const char *input, size_t length) noexcept
Provide the maximal binary length in bytes given the base64 input.
simdutf_warn_unused result convert_utf8_to_utf16_with_errors(const char *input, size_t length, char16_t *utf16_output) noexcept
Using native endianness, convert possibly broken UTF-8 string into UTF-16 string and stop on error.
simdutf_warn_unused bool validate_utf16be_as_ascii(const char16_t *buf, size_t len) noexcept
Validate the ASCII string as a UTF-16BE sequence.
simdutf_warn_unused result convert_utf8_to_utf16be_with_errors(const char *input, size_t length, char16_t *utf16_output) noexcept
Convert possibly broken UTF-8 string into UTF-16BE string and stop on error.
simdutf_really_inline simdutf_warn_unused simdutf_constexpr23 size_t latin1_length_from_utf16(size_t length) noexcept
Compute the number of bytes that this UTF-16 string would require in Latin1 format.
simdutf_warn_unused result convert_utf16le_to_latin1_with_errors(const char16_t *input, size_t length, char *latin1_buffer) noexcept
Convert possibly broken UTF-16LE string into Latin1 string.
simdutf_warn_unused result convert_utf16_to_utf32_with_errors(const char16_t *input, size_t length, char32_t *utf32_buffer) noexcept
Using native endianness, convert possibly broken UTF-16 string into UTF-32 string and stop on error.
simdutf_warn_unused result convert_utf8_to_latin1_with_errors(const char *input, size_t length, char *latin1_output) noexcept
Convert possibly broken UTF-8 string into latin1 string with errors.
simdutf_warn_unused size_t utf32_length_from_utf8(const char *input, size_t length) noexcept
Compute the number of 4-byte code units that this UTF-8 string would require in UTF-32 format.
simdutf_warn_unused result validate_utf8_with_errors(const char *buf, size_t len) noexcept
Validate the UTF-8 string and stop on error.
simdutf_warn_unused size_t latin1_length_from_utf8(const char *input, size_t length) noexcept
Compute the number of bytes that this UTF-8 string would require in Latin1 format.
simdutf_warn_unused size_t convert_utf16be_to_utf8(const char16_t *input, size_t length, char *utf8_buffer) noexcept
Convert possibly broken UTF-16BE string into UTF-8 string.
simdutf_warn_unused size_t convert_valid_utf32_to_utf16(const char32_t *input, size_t length, char16_t *utf16_buffer) noexcept
Using native endianness, convert valid UTF-32 string into a UTF-16 string.
simdutf_warn_unused size_t utf32_length_from_utf16be(const char16_t *input, size_t length) noexcept
Compute the number of bytes that this UTF-16BE string would require in UTF-32 format.
simdutf_warn_unused size_t convert_latin1_to_utf16be(const char *input, size_t length, char16_t *utf16_output) noexcept
Convert Latin1 string into UTF-16BE string.
simdutf_warn_unused size_t utf16_length_from_utf8(const char *input, size_t length) noexcept
Compute the number of 2-byte code units that this UTF-8 string would require in UTF-16LE format.
simdutf_warn_unused size_t convert_utf8_to_latin1(const char *input, size_t length, char *latin1_output) noexcept
Convert possibly broken UTF-8 string into latin1 string.
simdutf_warn_unused size_t convert_valid_utf16be_to_latin1(const char16_t *input, size_t length, char *latin1_buffer) noexcept
Convert valid UTF-16BE string into Latin1 string.
void to_well_formed_utf16le(const char16_t *input, size_t len, char16_t *output) noexcept
Fixes an ill-formed UTF-16LE string by replacing mismatched surrogates with the Unicode replacement c...
simdutf_warn_unused simdutf_really_inline simdutf_constexpr23 size_t latin1_length_from_utf32(size_t length) noexcept
Compute the number of bytes that this UTF-32 string would require in Latin1 format.
simdutf_warn_unused size_t convert_utf16_to_utf32(const char16_t *input, size_t length, char32_t *utf32_buffer) noexcept
Using native endianness, convert possibly broken UTF-16 string into UTF-32 string.
simdutf_warn_unused size_t trim_partial_utf16le(const char16_t *input, size_t length)
Given a valid UTF-16LE string having a possibly truncated last character, this function checks the en...
simdutf_warn_unused size_t count_utf16le(const char16_t *input, size_t length) noexcept
Count the number of code points (characters) in the string assuming that it is valid.
simdutf_warn_unused result validate_utf16_with_errors(const char16_t *buf, size_t len) noexcept
Using native endianness; Validate the UTF-16 string and stop on error.
simdutf_warn_unused result convert_utf8_to_utf32_with_errors(const char *input, size_t length, char32_t *utf32_output) noexcept
Convert possibly broken UTF-8 string into UTF-32 string and stop on error.
void to_well_formed_utf16be(const char16_t *input, size_t len, char16_t *output) noexcept
Fixes an ill-formed UTF-16BE string by replacing mismatched surrogates with the Unicode replacement c...
simdutf_warn_unused result validate_utf16le_with_errors(const char16_t *buf, size_t len) noexcept
Validate the UTF-16LE string and stop on error.
simdutf_warn_unused size_t convert_valid_utf16_to_utf32(const char16_t *input, size_t length, char32_t *utf32_buffer) noexcept
Using native endianness, convert valid UTF-16 string into UTF-32 string.
simdutf_warn_unused full_result convert_utf16_to_utf8_safe_with_details(const char16_t *input, size_t length, char *utf8_output, size_t utf8_len) noexcept
Convert a possibly broken UTF-16 string into a size-limited UTF-8 buffer and report how much input wa...
simdutf_warn_unused result convert_utf16_to_latin1_with_errors(const char16_t *input, size_t length, char *latin1_buffer) noexcept
Using native endianness, convert possibly broken UTF-16 string into Latin1 string.
simdutf_warn_unused size_t convert_utf16le_to_latin1(const char16_t *input, size_t length, char *latin1_buffer) noexcept
Convert possibly broken UTF-16LE string into Latin1 string.
simdutf_warn_unused size_t convert_valid_utf32_to_latin1(const char32_t *input, size_t length, char *latin1_buffer) noexcept
Convert valid UTF-32 string into Latin1 string.
simdutf_warn_unused size_t binary_length_from_base64(const char *input, size_t length) noexcept
Compute the binary length from a base64 input.
simdutf_warn_unused int detect_encodings(const char *input, size_t length) noexcept
Autodetect the possible encodings of the input in one pass.
simdutf_warn_unused size_t convert_valid_utf32_to_utf8(const char32_t *input, size_t length, char *utf8_buffer) noexcept
Convert valid UTF-32 string into UTF-8 string.
size_t binary_to_base64_with_lines(const char *input, size_t length, char *output, size_t line_length=simdutf::default_line_length, base64_options options=base64_default) noexcept
Convert a binary input to a base64 output with line breaks.
simdutf_warn_unused result convert_utf16be_to_latin1_with_errors(const char16_t *input, size_t length, char *latin1_buffer) noexcept
Convert possibly broken UTF-16BE string into Latin1 string.
simdutf_warn_unused simdutf_constexpr23 size_t base64_length_from_binary_with_lines(size_t length, base64_options options=base64_default, size_t line_length=default_line_length) noexcept
Provide the base64 length in bytes given the length of a binary input, taking into account line break...
simdutf_warn_unused size_t trim_partial_utf16be(const char16_t *input, size_t length)
Given a valid UTF-16BE string having a possibly truncated last character, this function checks the en...
simdutf_warn_unused size_t convert_utf32_to_utf16(const char32_t *input, size_t length, char16_t *utf16_buffer) noexcept
Using native endianness, convert possibly broken UTF-32 string into a UTF-16 string.
simdutf_warn_unused result validate_utf32_with_errors(const char32_t *buf, size_t len) noexcept
Validate the UTF-32 string and stop on error.
simdutf_warn_unused size_t convert_valid_utf8_to_utf16le(const char *input, size_t length, char16_t *utf16_buffer) noexcept
Convert valid UTF-8 string into UTF-16LE string.
simdutf_warn_unused size_t convert_latin1_to_utf8_safe(const char *input, size_t length, char *utf8_output, size_t utf8_len) noexcept
Convert Latin1 string into UTF-8 string with output limit.
simdutf_warn_unused size_t convert_utf8_to_utf16be(const char *input, size_t length, char16_t *utf16_output) noexcept
Convert possibly broken UTF-8 string into UTF-16BE string.
simdutf_warn_unused simdutf_really_inline simdutf_constexpr23 bool base64_valid(char input, base64_options options=base64_default) noexcept
Check if a character is a valid base64 character.
simdutf_warn_unused size_t convert_utf16_to_utf8_safe(const char16_t *input, size_t length, char *utf8_output, size_t utf8_len) noexcept
Using native endianness, convert possibly broken UTF-16 string into UTF-8 string with output limit.
simdutf_warn_unused result convert_utf32_to_utf16be_with_errors(const char32_t *input, size_t length, char16_t *utf16_buffer) noexcept
Convert possibly broken UTF-32 string into UTF-16BE string and stop on error.
simdutf_warn_unused size_t convert_utf32_to_utf8(const char32_t *input, size_t length, char *utf8_buffer) noexcept
Convert possibly broken UTF-32 string into UTF-8 string.
simdutf_warn_unused size_t utf32_length_from_utf16(const char16_t *input, size_t length) noexcept
Using native endianness; Compute the number of bytes that this UTF-16 string would require in UTF-32 ...
simdutf_warn_unused size_t convert_valid_utf16be_to_utf32(const char16_t *input, size_t length, char32_t *utf32_buffer) noexcept
Convert valid UTF-16BE string into UTF-32 string.
simdutf_warn_unused size_t convert_valid_utf32_to_utf16be(const char32_t *input, size_t length, char16_t *utf16_buffer) noexcept
Convert valid UTF-32 string into UTF-16BE string.
simdutf_warn_unused result convert_utf16le_to_utf32_with_errors(const char16_t *input, size_t length, char32_t *utf32_buffer) noexcept
Convert possibly broken UTF-16LE string into UTF-32 string and stop on error.
simdutf_warn_unused result validate_ascii_with_errors(const char *buf, size_t len) noexcept
Validate the ASCII string and stop on error.
simdutf_warn_unused size_t trim_partial_utf8(const char *input, size_t length)
Given a valid UTF-8 string having a possibly truncated last character, this function checks the end o...
simdutf_warn_unused size_t convert_latin1_to_utf16le(const char *input, size_t length, char16_t *utf16_output) noexcept
Convert possibly Latin1 string into UTF-16LE string.
simdutf_warn_unused size_t convert_utf8_to_utf16(const char *input, size_t length, char16_t *utf16_output) noexcept
Using native endianness, convert possibly broken UTF-8 string into a UTF-16 string.
simdutf_warn_unused size_t convert_latin1_to_utf16(const char *input, size_t length, char16_t *utf16_output) noexcept
Using native endianness, convert a Latin1 string into a UTF-16 string.
simdutf_warn_unused bool validate_ascii(const char *buf, size_t len) noexcept
Validate the ASCII string.
simdutf_warn_unused size_t convert_utf32_to_latin1(const char32_t *input, size_t length, char *latin1_buffer) noexcept
Convert possibly broken UTF-32 string into Latin1 string.
simdutf_warn_unused size_t utf8_length_from_utf16(const char16_t *input, size_t length) noexcept
Using native endianness; Compute the number of bytes that this UTF-16 string would require in UTF-8 f...
void to_well_formed_utf16(const char16_t *input, size_t len, char16_t *output) noexcept
Fixes an ill-formed UTF-16 string by replacing mismatched surrogates with the Unicode replacement cha...
simdutf_warn_unused size_t convert_utf32_to_utf16be(const char32_t *input, size_t length, char16_t *utf16_buffer) noexcept
Convert possibly broken UTF-32 string into UTF-16BE string.
simdutf_warn_unused simdutf::encoding_type autodetect_encoding(const char *input, size_t length) noexcept
Autodetect the encoding of the input, a single encoding is recommended.
simdutf_warn_unused size_t utf16_length_from_utf32(const char32_t *input, size_t length) noexcept
Compute the number of two-byte code units that this UTF-32 string would require in UTF-16 format.