1#ifndef ICU4X_DIPLOMAT_RUNTIME_CPP_H
2#define ICU4X_DIPLOMAT_RUNTIME_CPP_H
16#if __cplusplus >= 202002L
22#ifndef DIPLOMAT_LIFETIME_BOUND
23#if defined(__has_cpp_attribute)
24#if __has_cpp_attribute(msvc::lifetimebound)
25#define DIPLOMAT_LIFETIME_BOUND [[msvc::lifetimebound]]
26#elif __has_cpp_attribute(clang::lifetimebound)
27#define DIPLOMAT_LIFETIME_BOUND [[clang::lifetimebound]]
32#ifndef DIPLOMAT_LIFETIME_BOUND
33#define DIPLOMAT_LIFETIME_BOUND
42static_assert(
sizeof(
char) ==
sizeof(
uint8_t),
"your architecture's `char` is not 8 bits");
43static_assert(
sizeof(
char16_t) ==
sizeof(
uint16_t),
"your architecture's `char16_t` is not 16 bits");
44static_assert(
sizeof(
char32_t) ==
sizeof(
uint32_t),
"your architecture's `char32_t` is not 32 bits");
46typedef struct DiplomatWrite {
52 void (*flush)(
struct DiplomatWrite*);
56bool diplomat_is_str(
const char* buf,
size_t len);
58#define MAKE_SLICES(name, c_ty) \
59 typedef struct Diplomat##name##View { \
62 } Diplomat##name##View; \
63 typedef struct Diplomat##name##ViewMut { \
66 } Diplomat##name##ViewMut; \
67 typedef struct Diplomat##name##Array { \
70 } Diplomat##name##Array;
72#define MAKE_SLICES_AND_OPTIONS(name, c_ty) \
73 MAKE_SLICES(name, c_ty) \
74 typedef struct Option##name {union { c_ty ok; }; bool is_ok; } Option##name; \
75 typedef struct Option##name##View {union { Diplomat##name##View ok; }; bool is_ok; } Option##name##View; \
76 typedef struct Option##name##ViewMut {union { Diplomat##name##ViewMut ok; }; bool is_ok; } Option##name##ViewMut; \
77 typedef struct Option##name##Array {union { Diplomat##name##Array ok; }; bool is_ok; } Option##name##Array; \
101extern "C" inline void _flush(capi::DiplomatWrite* w) {
102 std::string*
string =
reinterpret_cast<std::string*
>(w->context);
103 string->resize(w->len);
107 std::string*
string =
reinterpret_cast<std::string*
>(
w->context);
109 w->cap =
string->length();
110 w->buf = &(*string)[0];
114extern "C" inline bool _grow(capi::DiplomatWrite* w,
size_t requested) {
115 return _grow_impl(w,
static_cast<uintptr_t
>(requested));
118inline capi::DiplomatWrite WriteFromString(std::string&
string) {
119 capi::DiplomatWrite w;
122 w.len =
string.length();
123 w.cap =
string.length();
125 w.grow_failed =
false;
132 std::u16string*
string =
reinterpret_cast<std::u16string*
>(
w->context);
133 string->resize(
w->len /
sizeof(
char16_t));
137 std::u16string*
string =
reinterpret_cast<std::u16string*
>(
w->context);
140 w->cap =
string->length() *
sizeof(
char16_t);
141 w->buf =
reinterpret_cast<char*
>(&(*string)[0]);
150 capi::DiplomatWrite
w;
152 w.buf =
reinterpret_cast<char*
>(&
string[0]);
153 w.len =
string.length() *
sizeof(
char16_t);
154 w.cap =
string.length() *
sizeof(
char16_t);
156 w.grow_failed =
false;
164 std::vector<T>*
vec =
reinterpret_cast<std::vector<T>*
>(
w->context);
165 vec->resize(
w->len /
sizeof(T));
170 std::vector<T>*
vec =
reinterpret_cast<std::vector<T>*
>(
w->context);
173 w->cap =
vec->size() *
sizeof(T);
174 w->buf =
reinterpret_cast<char*
>(
vec->data());
185 capi::DiplomatWrite
w;
187 w.buf =
reinterpret_cast<char*
>(
vec.data());
188 w.len =
vec.size() *
sizeof(T);
189 w.cap =
vec.size() *
sizeof(T);
191 w.grow_failed =
false;
208 static inline capi::DiplomatWrite
Construct(std::string&
t) {
209 return diplomat::WriteFromString(
t);
214 static inline capi::DiplomatWrite
Construct(std::u16string&
t) {
220 static inline capi::DiplomatWrite
Construct(std::vector<T>&
t) {
225template<
class T>
struct Ok {
275 return std::holds_alternative<Ok<T>>(this->val);
278 return std::holds_alternative<Err<E>>(this->val);
281 template<
typename U = T,
typename std::enable_if_t<!std::is_reference_v<U>, std::
nullptr_t> =
nullptr>
282 std::optional<T>
ok() && {
283 if (!this->is_ok()) {
286 return std::make_optional(std::move(std::get<
Ok<T>>(std::move(this->val)).
inner));
289 template<
typename U = E,
typename std::enable_if_t<!std::is_reference_v<U>, std::
nullptr_t> =
nullptr>
290 std::optional<E>
err() && {
291 if (!this->is_err()) {
294 return std::make_optional(std::move(std::get<
Err<E>>(std::move(this->val)).
inner));
298 template<
typename U = T,
typename std::enable_if_t<std::is_reference_v<U>, std::
nullptr_t> =
nullptr>
299 std::optional<std::reference_wrapper<std::remove_reference_t<T>>>
ok() && {
300 if (!this->is_ok()) {
303 return std::make_optional(std::reference_wrapper(std::forward<T>(std::get<
Ok<T>>(std::move(this->val)).
inner)));
306 template<
typename U = E,
typename std::enable_if_t<std::is_reference_v<U>, std::
nullptr_t> =
nullptr>
307 std::optional<std::reference_wrapper<std::remove_reference_t<E>>>
err() && {
308 if (!this->is_err()) {
311 return std::make_optional(std::reference_wrapper(std::forward<E>(std::get<
Err<E>>(std::move(this->val)).
inner)));
315 this->val =
Ok<T>(std::move(
t));
319 this->val =
Err<E>(std::move(
e));
322 template<
typename T2>
324 if (this->is_err()) {
335#if __cplusplus >= 202002L
338template<
class T, std::
size_t E = dynamic_extent>
using span = std::span<T, E>;
344template <
class T, std::
size_t Extent = dynamic_extent>
348 : data_(data), size_(size) {}
351 : data_(
o.data_), size_(
o.size_) {}
353 constexpr span(std::array<
typename std::remove_const_t<T>,
N> &
arr)
380template <
class CharT,
class Traits = std::
char_traits<CharT>>
386 using pointer =
typename std_string_view::pointer;
405 : data_{
s.data(),
s.size()} {}
408 data_ = {
s.data(),
s.size()};
420 std::conditional_t<std::is_same_v<value_type, char>,
421 capi::DiplomatStringView,
422 std::conditional_t<std::is_same_v<value_type, char16_t>,
423 capi::DiplomatString16View,
426 static_assert(!std::is_void_v<capi_type>,
427 "ABI compatible string_views are only supported for char and char16_t");
442template <
typename T,
typename =
void>
448struct as_ffi<T, std::
void_t<decltype(std::declval<std::remove_pointer_t<T>>().AsFFI())>> {
449 using type =
decltype(std::declval<std::remove_pointer_t<T>>().AsFFI());
454 using type =
decltype(std::declval<T>().AsFFI());
463template<
typename T,
typename =
void>
468#define MAKE_SLICE_CONVERTERS(name, c_ty) \
469 template<typename T> \
470 struct diplomat_c_span_convert<T, std::enable_if_t<std::is_same_v<T, span<const c_ty>>>> { \
471 using type = diplomat::capi::Diplomat##name##View; \
473 template<typename T> \
474 struct diplomat_c_span_convert<T, std::enable_if_t<std::is_same_v<T, span<c_ty>>>> { \
475 using type = diplomat::capi::Diplomat##name##ViewMut; \
478#if !defined(__sun) || !defined(_CHAR_IS_SIGNED)
502 static constexpr bool value =
false;
508 static constexpr bool value =
true;
517 static constexpr bool value =
false;
522 static constexpr bool value =
true;
532namespace fn_trait_helpers {
536 if constexpr(std::is_same_v<T, std::string_view>) {
537 return std::string_view{val.data, val.len};
538 }
else if constexpr (!std::is_same_v<T, diplomat_c_span_convert_t<T>>) {
539 return T{ val.data, val.len };
540 }
else if constexpr (!std::is_same_v<T, as_ffi_t<T>>) {
541 if constexpr (std::is_lvalue_reference_v<T>) {
542 return *std::remove_reference_t<T>::FromFFI(val);
547 return T::FromFFI(val);
557 if constexpr(std::is_same_v<T, std::string_view>) {
558 return {val.data(), val.size()};
559 }
else if constexpr (!std::is_same_v<T, diplomat_c_span_convert_t<T>>) {
566 }
else if constexpr(!std::is_same_v<T, as_ffi_t<T>>) {
573 template<
typename TOut,
typename T>
575 constexpr bool has_ok = !std::is_same_v<T, std::monostate>;
590 template<
typename T,
typename E,
typename TOut>
592 auto is_ok =
res.is_ok();
594 constexpr bool has_ok = !std::is_same_v<T, std::monostate>;
595 constexpr bool has_err = !std::is_same_v<E, std::monostate>;
602 auto val = std::move(
res).ok().value();
604 out.ok = replace_optional_ret<
decltype(
out.ok)>(val);
606 out.ok = replace_ret<T>(val);
611 if constexpr(has_err) {
613 auto val = std::move(res).err().value();
614 if constexpr(is_optional_v<E>) {
617 out.err = replace_ret<E>(val);
634 return (*
reinterpret_cast<const function_t *
>(
cb))(fn_trait_helpers::replace<Args>(
args)...);
637 template<
typename T,
typename E,
typename TOut>
641 return fn_trait_helpers::replace_result<T, E, TOut>(
res);
645 template<
typename T,
typename TOut>
646 static TOut c_run_callback_diplomat_option(
const void *cb, replace_fn_t<Args>... args) {
647 std::optional<T> ret = c_run_callback(cb, args...);
649 return fn_trait_helpers::replace_optional_ret<TOut>(ret);
657 if constexpr(std::is_pointer_v<Ret>) {
677template<
typename T>
struct inner { };
678template<
typename T>
struct inner<T*> {
using type = T; };
684 if constexpr(std::is_same_v<T,U>) {
687 return *std::move(
v);
692template<
typename T,
typename U =
void>
struct has_next : std::false_type {};
693template<
typename T>
struct has_next < T, std::
void_t<decltype(std::declval<T>().next())>> : std::true_type {};
699 static_assert(
has_next_v<T>,
"next_to_iter_helper may only be used with types implementing next()");
705 using reference = std::add_lvalue_reference_t<value_type>;
Definition diplomat_runtime.hpp:332
Definition diplomat_runtime.hpp:381
typename std_string_view::const_pointer const_pointer
Definition diplomat_runtime.hpp:387
constexpr basic_string_view_for_slice(const const_pointer s)
Definition diplomat_runtime.hpp:399
constexpr basic_string_view_for_slice(const basic_string_view_for_slice &other) noexcept=default
constexpr basic_string_view_for_slice & operator=(const basic_string_view_for_slice &view) noexcept=default
constexpr size_type size() const noexcept
Definition diplomat_runtime.hpp:416
std::basic_string_view< CharT, Traits > std_string_view
Definition diplomat_runtime.hpp:383
typename std_string_view::size_type size_type
Definition diplomat_runtime.hpp:388
typename std_string_view::traits_type traits_type
Definition diplomat_runtime.hpp:384
constexpr basic_string_view_for_slice & operator=(const std_string_view &s) noexcept
Definition diplomat_runtime.hpp:407
typename std_string_view::difference_type difference_type
Definition diplomat_runtime.hpp:389
constexpr basic_string_view_for_slice(const std_string_view &s) noexcept
Definition diplomat_runtime.hpp:404
constexpr const_pointer data() const noexcept
Definition diplomat_runtime.hpp:415
constexpr basic_string_view_for_slice() noexcept
Definition diplomat_runtime.hpp:391
constexpr basic_string_view_for_slice(const const_pointer s, const size_type count)
Definition diplomat_runtime.hpp:396
typename std_string_view::pointer pointer
Definition diplomat_runtime.hpp:386
typename std_string_view::value_type value_type
Definition diplomat_runtime.hpp:385
constexpr std_string_view as_sv() const noexcept
Definition diplomat_runtime.hpp:413
Definition diplomat_runtime.hpp:261
std::optional< E > err() &&
Definition diplomat_runtime.hpp:290
void set_ok(T &&t)
Definition diplomat_runtime.hpp:314
std::optional< std::reference_wrapper< std::remove_reference_t< E > > > err() &&
Definition diplomat_runtime.hpp:307
bool is_err() const
Definition diplomat_runtime.hpp:277
result & operator=(result &&) noexcept=default
void set_err(E &&e)
Definition diplomat_runtime.hpp:318
result(Ok< T > &&v)
Definition diplomat_runtime.hpp:266
std::optional< std::reference_wrapper< std::remove_reference_t< T > > > ok() &&
Definition diplomat_runtime.hpp:299
result(const result &)=default
result(Err< E > &&v)
Definition diplomat_runtime.hpp:267
std::optional< T > ok() &&
Definition diplomat_runtime.hpp:282
result< T2, E > replace_ok(T2 &&t)
Definition diplomat_runtime.hpp:323
result & operator=(const result &)=default
std::variant< Ok< T >, Err< E > > val
Definition diplomat_runtime.hpp:263
Definition diplomat_runtime.hpp:345
constexpr T * end() const noexcept
Definition diplomat_runtime.hpp:364
constexpr T * data() const noexcept
Definition diplomat_runtime.hpp:356
void operator=(span< T > o)
Definition diplomat_runtime.hpp:366
constexpr span(T *data=nullptr, size_t size=Extent)
Definition diplomat_runtime.hpp:347
constexpr span(std::array< typename std::remove_const_t< T >, N > &arr)
Definition diplomat_runtime.hpp:353
constexpr size_t size() const noexcept
Definition diplomat_runtime.hpp:359
constexpr T * begin() const noexcept
Definition diplomat_runtime.hpp:363
constexpr span(const span< T > &o)
Definition diplomat_runtime.hpp:350
#define MAKE_SLICES_AND_OPTIONS(name, c_ty)
Definition diplomat_runtime.hpp:72
#define MAKE_SLICE_CONVERTERS(name, c_ty)
Definition diplomat_runtime.hpp:468
TOut replace_optional_ret(std::optional< T > optional)
Definition diplomat_runtime.hpp:574
replace_fn_t< T > replace_ret(T val)
Definition diplomat_runtime.hpp:556
T replace(replace_fn_t< T > val)
Definition diplomat_runtime.hpp:535
typename as_ffi< T >::type as_ffi_t
Definition diplomat_runtime.hpp:458
constexpr bool is_optional_v
Definition diplomat_runtime.hpp:526
bool _grow_u16string(capi::DiplomatWrite *w, size_t requested)
Definition diplomat_runtime.hpp:145
bool _grow_impl(capi::DiplomatWrite *w, uintptr_t requested)
Definition diplomat_runtime.hpp:106
const U get_inner_if_present(T v)
Definition diplomat_runtime.hpp:683
constexpr bool is_unique_ptr_v
Definition diplomat_runtime.hpp:513
constexpr size_t dynamic_extent
Definition diplomat_runtime.hpp:343
bool _grow_vector(capi::DiplomatWrite *w, size_t requested)
Definition diplomat_runtime.hpp:179
std::conditional_t< std::is_same_v< T, std::string_view >, capi::DiplomatStringView, T > replace_string_view_t
Definition diplomat_runtime.hpp:461
diplomat_c_span_convert_t< replace_string_view_t< as_ffi_t< T > > > replace_fn_t
Replace the argument types from the std::function with the argument types for th function pointer.
Definition diplomat_runtime.hpp:530
capi::DiplomatWrite WriteFromVector(std::vector< T > &vec)
Definition diplomat_runtime.hpp:184
void _flush_vector(capi::DiplomatWrite *w)
Definition diplomat_runtime.hpp:163
constexpr bool has_next_v
Definition diplomat_runtime.hpp:694
T maybe_null
The type may be a nullptr.
Definition diplomat_runtime.hpp:727
void _flush_u16string(capi::DiplomatWrite *w)
Definition diplomat_runtime.hpp:131
typename diplomat_c_span_convert< T >::type diplomat_c_span_convert_t
Definition diplomat_runtime.hpp:498
capi::DiplomatWrite WriteFromString16(std::u16string &string)
Definition diplomat_runtime.hpp:149
bool _grow_u16string_impl(capi::DiplomatWrite *w, uintptr_t requested)
Definition diplomat_runtime.hpp:136
bool _grow_vector_impl(capi::DiplomatWrite *w, uintptr_t requested)
Definition diplomat_runtime.hpp:169
Definition diplomat_runtime.hpp:243
Err(const T &i)
Definition diplomat_runtime.hpp:251
Err(T &&i)
Definition diplomat_runtime.hpp:247
T inner
Definition diplomat_runtime.hpp:244
Err(Err &&) noexcept=default
Definition diplomat_runtime.hpp:225
Ok(const T &i)
Definition diplomat_runtime.hpp:233
Ok(T &&i)
Definition diplomat_runtime.hpp:229
T inner
Definition diplomat_runtime.hpp:226
Ok(Ok &&) noexcept=default
static capi::DiplomatWrite Construct(std::string &t)
Definition diplomat_runtime.hpp:208
static capi::DiplomatWrite Construct(std::u16string &t)
Definition diplomat_runtime.hpp:214
static capi::DiplomatWrite Construct(std::vector< T > &t)
Definition diplomat_runtime.hpp:220
Definition diplomat_runtime.hpp:202
decltype(std::declval< T >().AsFFI()) type
Definition diplomat_runtime.hpp:454
Definition diplomat_runtime.hpp:443
T type
Definition diplomat_runtime.hpp:444
Definition diplomat_runtime.hpp:464
T type
Definition diplomat_runtime.hpp:465
std::function< fn_ptr_t > function_t
Definition diplomat_runtime.hpp:630
static T c_run_callback_diplomat_opaque(const void *cb, replace_fn_t< Args >... args)
Definition diplomat_runtime.hpp:654
static Ret c_run_callback(const void *cb, replace_fn_t< Args >... args)
Definition diplomat_runtime.hpp:633
fn_traits(function_t)
Definition diplomat_runtime.hpp:668
static void c_delete(const void *cb)
Definition diplomat_runtime.hpp:664
Definition diplomat_runtime.hpp:626
Definition diplomat_runtime.hpp:692
T type
Definition diplomat_runtime.hpp:678
T type
Definition diplomat_runtime.hpp:680
T type
Definition diplomat_runtime.hpp:679
Definition diplomat_runtime.hpp:677
Definition diplomat_runtime.hpp:516
T type
Definition diplomat_runtime.hpp:509
Definition diplomat_runtime.hpp:501
T type
Definition diplomat_runtime.hpp:503
Helper template enabling native iteration over unique ptrs to objects which implement next()
Definition diplomat_runtime.hpp:698
void operator++()
Definition diplomat_runtime.hpp:713
void operator++(int)
Definition diplomat_runtime.hpp:714
next_to_iter_helper(const next_to_iter_helper &o)
Definition diplomat_runtime.hpp:711
next_type _curr
Definition diplomat_runtime.hpp:722
bool operator!=(std::nullopt_t)
Definition diplomat_runtime.hpp:717
std::input_iterator_tag iterator_category
Definition diplomat_runtime.hpp:706
next_to_iter_helper(std::unique_ptr< T > &&ptr)
Definition diplomat_runtime.hpp:708
std::shared_ptr< T > _ptr
Definition diplomat_runtime.hpp:721
const value_type & operator*() const
Definition diplomat_runtime.hpp:715
std::add_lvalue_reference_t< value_type > reference
Definition diplomat_runtime.hpp:705
typename inner< next_type >::type value_type
Definition diplomat_runtime.hpp:703
decltype(std::declval< T >().next()) next_type
Definition diplomat_runtime.hpp:700