1#ifndef ICU4X_DIPLOMAT_RUNTIME_CPP_H
2#define ICU4X_DIPLOMAT_RUNTIME_CPP_H
15#if __cplusplus >= 202002L
21#ifndef DIPLOMAT_LIFETIME_BOUND
22#if defined(__has_cpp_attribute)
23#if __has_cpp_attribute(msvc::lifetimebound)
24#define DIPLOMAT_LIFETIME_BOUND [[msvc::lifetimebound]]
25#elif __has_cpp_attribute(clang::lifetimebound)
26#define DIPLOMAT_LIFETIME_BOUND [[clang::lifetimebound]]
31#ifndef DIPLOMAT_LIFETIME_BOUND
32#define DIPLOMAT_LIFETIME_BOUND
41static_assert(
sizeof(
char) ==
sizeof(
uint8_t),
"your architecture's `char` is not 8 bits");
42static_assert(
sizeof(
char16_t) ==
sizeof(
uint16_t),
"your architecture's `char16_t` is not 16 bits");
43static_assert(
sizeof(
char32_t) ==
sizeof(
uint32_t),
"your architecture's `char32_t` is not 32 bits");
45typedef struct DiplomatWrite {
51 void (*flush)(
struct DiplomatWrite*);
55bool diplomat_is_str(
const char* buf,
size_t len);
57#define MAKE_SLICES(name, c_ty) \
58 typedef struct Diplomat##name##View { \
61 } Diplomat##name##View; \
62 typedef struct Diplomat##name##ViewMut { \
65 } Diplomat##name##ViewMut; \
66 typedef struct Diplomat##name##Array { \
69 } Diplomat##name##Array;
71#define MAKE_SLICES_AND_OPTIONS(name, c_ty) \
72 MAKE_SLICES(name, c_ty) \
73 typedef struct Option##name {union { c_ty ok; }; bool is_ok; } Option##name; \
74 typedef struct Option##name##View {union { Diplomat##name##View ok; }; bool is_ok; } Option##name##View; \
75 typedef struct Option##name##ViewMut {union { Diplomat##name##ViewMut ok; }; bool is_ok; } Option##name##ViewMut; \
76 typedef struct Option##name##Array {union { Diplomat##name##Array ok; }; bool is_ok; } Option##name##Array; \
100extern "C" inline void _flush(capi::DiplomatWrite* w) {
101 std::string*
string =
reinterpret_cast<std::string*
>(w->context);
102 string->resize(w->len);
106 std::string*
string =
reinterpret_cast<std::string*
>(
w->context);
108 w->cap =
string->length();
109 w->buf = &(*string)[0];
113extern "C" inline bool _grow(capi::DiplomatWrite* w,
size_t requested) {
114 return _grow_impl(w,
static_cast<uintptr_t
>(requested));
117inline capi::DiplomatWrite WriteFromString(std::string&
string) {
118 capi::DiplomatWrite w;
121 w.len =
string.length();
122 w.cap =
string.length();
124 w.grow_failed =
false;
141 static inline capi::DiplomatWrite
Construct(std::string&
t) {
142 return diplomat::WriteFromString(
t);
146template<
class T>
struct Ok {
196 return std::holds_alternative<Ok<T>>(this->val);
199 return std::holds_alternative<Err<E>>(this->val);
202 template<
typename U = T,
typename std::enable_if_t<!std::is_reference_v<U>, std::
nullptr_t> =
nullptr>
203 std::optional<T>
ok() && {
204 if (!this->is_ok()) {
207 return std::make_optional(std::move(std::get<
Ok<T>>(std::move(this->val)).
inner));
210 template<
typename U = E,
typename std::enable_if_t<!std::is_reference_v<U>, std::
nullptr_t> =
nullptr>
211 std::optional<E>
err() && {
212 if (!this->is_err()) {
215 return std::make_optional(std::move(std::get<
Err<E>>(std::move(this->val)).
inner));
219 template<
typename U = T,
typename std::enable_if_t<std::is_reference_v<U>, std::
nullptr_t> =
nullptr>
220 std::optional<std::reference_wrapper<std::remove_reference_t<T>>>
ok() && {
221 if (!this->is_ok()) {
224 return std::make_optional(std::reference_wrapper(std::forward<T>(std::get<
Ok<T>>(std::move(this->val)).
inner)));
227 template<
typename U = E,
typename std::enable_if_t<std::is_reference_v<U>, std::
nullptr_t> =
nullptr>
228 std::optional<std::reference_wrapper<std::remove_reference_t<E>>>
err() && {
229 if (!this->is_err()) {
232 return std::make_optional(std::reference_wrapper(std::forward<E>(std::get<
Err<E>>(std::move(this->val)).
inner)));
236 this->val =
Ok<T>(std::move(
t));
240 this->val =
Err<E>(std::move(
e));
243 template<
typename T2>
245 if (this->is_err()) {
256#if __cplusplus >= 202002L
259template<
class T, std::
size_t E = dynamic_extent>
using span = std::span<T, E>;
265template <
class T, std::
size_t Extent = dynamic_extent>
269 : data_(data), size_(size) {}
272 : data_(
o.data_), size_(
o.size_) {}
274 constexpr span(std::array<
typename std::remove_const_t<T>,
N> &
arr)
301template <
class CharT,
class Traits = std::
char_traits<CharT>>
307 using pointer =
typename std_string_view::pointer;
326 : data_{
s.data(),
s.size()} {}
329 data_ = {
s.data(),
s.size()};
341 std::conditional_t<std::is_same_v<value_type, char>,
342 capi::DiplomatStringView,
343 std::conditional_t<std::is_same_v<value_type, char16_t>,
344 capi::DiplomatString16View,
347 static_assert(!std::is_void_v<capi_type>,
348 "ABI compatible string_views are only supported for char and char16_t");
363template <
typename T,
typename =
void>
369struct as_ffi<T, std::
void_t<decltype(std::declval<std::remove_pointer_t<T>>().AsFFI())>> {
370 using type =
decltype(std::declval<std::remove_pointer_t<T>>().AsFFI());
375 using type =
decltype(std::declval<T>().AsFFI());
384template<
typename T,
typename =
void>
389#define MAKE_SLICE_CONVERTERS(name, c_ty) \
390 template<typename T> \
391 struct diplomat_c_span_convert<T, std::enable_if_t<std::is_same_v<T, span<const c_ty>>>> { \
392 using type = diplomat::capi::Diplomat##name##View; \
394 template<typename T> \
395 struct diplomat_c_span_convert<T, std::enable_if_t<std::is_same_v<T, span<c_ty>>>> { \
396 using type = diplomat::capi::Diplomat##name##ViewMut; \
399#if !defined(__sun) || !defined(_CHAR_IS_SIGNED)
423 static constexpr bool value =
false;
429 static constexpr bool value =
true;
438 static constexpr bool value =
false;
443 static constexpr bool value =
true;
453namespace fn_trait_helpers {
457 if constexpr(std::is_same_v<T, std::string_view>) {
458 return std::string_view{val.data, val.len};
459 }
else if constexpr (!std::is_same_v<T, diplomat_c_span_convert_t<T>>) {
460 return T{ val.data, val.len };
461 }
else if constexpr (!std::is_same_v<T, as_ffi_t<T>>) {
462 if constexpr (std::is_lvalue_reference_v<T>) {
463 return *std::remove_reference_t<T>::FromFFI(val);
468 return T::FromFFI(val);
478 if constexpr(std::is_same_v<T, std::string_view>) {
479 return {val.data(), val.size()};
480 }
else if constexpr (!std::is_same_v<T, diplomat_c_span_convert_t<T>>) {
487 }
else if constexpr(!std::is_same_v<T, as_ffi_t<T>>) {
494 template<
typename TOut,
typename T>
496 constexpr bool has_ok = !std::is_same_v<T, std::monostate>;
511 template<
typename T,
typename E,
typename TOut>
513 auto is_ok =
res.is_ok();
515 constexpr bool has_ok = !std::is_same_v<T, std::monostate>;
516 constexpr bool has_err = !std::is_same_v<E, std::monostate>;
523 auto val = std::move(
res).ok().value();
525 out.ok = replace_optional_ret<
decltype(
out.ok)>(val);
527 out.ok = replace_ret<T>(val);
532 if constexpr(has_err) {
534 auto val = std::move(res).err().value();
535 if constexpr(is_optional_v<E>) {
538 out.err = replace_ret<E>(val);
555 return (*
reinterpret_cast<const function_t *
>(
cb))(fn_trait_helpers::replace<Args>(
args)...);
558 template<
typename T,
typename E,
typename TOut>
562 return fn_trait_helpers::replace_result<T, E, TOut>(
res);
566 template<
typename T,
typename TOut>
567 static TOut c_run_callback_diplomat_option(
const void *cb, replace_fn_t<Args>... args) {
568 std::optional<T> ret = c_run_callback(cb, args...);
570 return fn_trait_helpers::replace_optional_ret<TOut>(ret);
578 if constexpr(std::is_pointer_v<Ret>) {
598template<
typename T>
struct inner { };
599template<
typename T>
struct inner<T*> {
using type = T; };
605 if constexpr(std::is_same_v<T,U>) {
608 return *std::move(
v);
613template<
typename T,
typename U =
void>
struct has_next : std::false_type {};
614template<
typename T>
struct has_next < T, std::
void_t<decltype(std::declval<T>().next())>> : std::true_type {};
620 static_assert(
has_next_v<T>,
"next_to_iter_helper may only be used with types implementing next()");
626 using reference = std::add_lvalue_reference_t<value_type>;
Definition diplomat_runtime.hpp:253
Definition diplomat_runtime.hpp:302
typename std_string_view::const_pointer const_pointer
Definition diplomat_runtime.hpp:308
constexpr basic_string_view_for_slice(const const_pointer s)
Definition diplomat_runtime.hpp:320
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:337
std::basic_string_view< CharT, Traits > std_string_view
Definition diplomat_runtime.hpp:304
typename std_string_view::size_type size_type
Definition diplomat_runtime.hpp:309
typename std_string_view::traits_type traits_type
Definition diplomat_runtime.hpp:305
constexpr basic_string_view_for_slice & operator=(const std_string_view &s) noexcept
Definition diplomat_runtime.hpp:328
typename std_string_view::difference_type difference_type
Definition diplomat_runtime.hpp:310
constexpr basic_string_view_for_slice(const std_string_view &s) noexcept
Definition diplomat_runtime.hpp:325
constexpr const_pointer data() const noexcept
Definition diplomat_runtime.hpp:336
constexpr basic_string_view_for_slice() noexcept
Definition diplomat_runtime.hpp:312
constexpr basic_string_view_for_slice(const const_pointer s, const size_type count)
Definition diplomat_runtime.hpp:317
typename std_string_view::pointer pointer
Definition diplomat_runtime.hpp:307
typename std_string_view::value_type value_type
Definition diplomat_runtime.hpp:306
constexpr std_string_view as_sv() const noexcept
Definition diplomat_runtime.hpp:334
Definition diplomat_runtime.hpp:182
std::optional< E > err() &&
Definition diplomat_runtime.hpp:211
void set_ok(T &&t)
Definition diplomat_runtime.hpp:235
std::optional< std::reference_wrapper< std::remove_reference_t< E > > > err() &&
Definition diplomat_runtime.hpp:228
bool is_err() const
Definition diplomat_runtime.hpp:198
result & operator=(result &&) noexcept=default
void set_err(E &&e)
Definition diplomat_runtime.hpp:239
result(Ok< T > &&v)
Definition diplomat_runtime.hpp:187
std::optional< std::reference_wrapper< std::remove_reference_t< T > > > ok() &&
Definition diplomat_runtime.hpp:220
result(const result &)=default
result(Err< E > &&v)
Definition diplomat_runtime.hpp:188
std::optional< T > ok() &&
Definition diplomat_runtime.hpp:203
result< T2, E > replace_ok(T2 &&t)
Definition diplomat_runtime.hpp:244
result & operator=(const result &)=default
std::variant< Ok< T >, Err< E > > val
Definition diplomat_runtime.hpp:184
Definition diplomat_runtime.hpp:266
constexpr T * end() const noexcept
Definition diplomat_runtime.hpp:285
constexpr T * data() const noexcept
Definition diplomat_runtime.hpp:277
void operator=(span< T > o)
Definition diplomat_runtime.hpp:287
constexpr span(T *data=nullptr, size_t size=Extent)
Definition diplomat_runtime.hpp:268
constexpr span(std::array< typename std::remove_const_t< T >, N > &arr)
Definition diplomat_runtime.hpp:274
constexpr size_t size() const noexcept
Definition diplomat_runtime.hpp:280
constexpr T * begin() const noexcept
Definition diplomat_runtime.hpp:284
constexpr span(const span< T > &o)
Definition diplomat_runtime.hpp:271
#define MAKE_SLICES_AND_OPTIONS(name, c_ty)
Definition diplomat_runtime.hpp:71
#define MAKE_SLICE_CONVERTERS(name, c_ty)
Definition diplomat_runtime.hpp:389
TOut replace_optional_ret(std::optional< T > optional)
Definition diplomat_runtime.hpp:495
replace_fn_t< T > replace_ret(T val)
Definition diplomat_runtime.hpp:477
T replace(replace_fn_t< T > val)
Definition diplomat_runtime.hpp:456
typename as_ffi< T >::type as_ffi_t
Definition diplomat_runtime.hpp:379
constexpr bool is_optional_v
Definition diplomat_runtime.hpp:447
bool _grow_impl(capi::DiplomatWrite *w, uintptr_t requested)
Definition diplomat_runtime.hpp:105
const U get_inner_if_present(T v)
Definition diplomat_runtime.hpp:604
constexpr bool is_unique_ptr_v
Definition diplomat_runtime.hpp:434
constexpr size_t dynamic_extent
Definition diplomat_runtime.hpp:264
std::conditional_t< std::is_same_v< T, std::string_view >, capi::DiplomatStringView, T > replace_string_view_t
Definition diplomat_runtime.hpp:382
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:451
constexpr bool has_next_v
Definition diplomat_runtime.hpp:615
typename diplomat_c_span_convert< T >::type diplomat_c_span_convert_t
Definition diplomat_runtime.hpp:419
Definition diplomat_runtime.hpp:164
Err(const T &i)
Definition diplomat_runtime.hpp:172
Err(T &&i)
Definition diplomat_runtime.hpp:168
T inner
Definition diplomat_runtime.hpp:165
Err(Err &&) noexcept=default
Definition diplomat_runtime.hpp:146
Ok(const T &i)
Definition diplomat_runtime.hpp:154
Ok(T &&i)
Definition diplomat_runtime.hpp:150
T inner
Definition diplomat_runtime.hpp:147
Ok(Ok &&) noexcept=default
static capi::DiplomatWrite Construct(std::string &t)
Definition diplomat_runtime.hpp:141
Definition diplomat_runtime.hpp:135
decltype(std::declval< T >().AsFFI()) type
Definition diplomat_runtime.hpp:375
Definition diplomat_runtime.hpp:364
T type
Definition diplomat_runtime.hpp:365
Definition diplomat_runtime.hpp:385
T type
Definition diplomat_runtime.hpp:386
std::function< fn_ptr_t > function_t
Definition diplomat_runtime.hpp:551
static T c_run_callback_diplomat_opaque(const void *cb, replace_fn_t< Args >... args)
Definition diplomat_runtime.hpp:575
static Ret c_run_callback(const void *cb, replace_fn_t< Args >... args)
Definition diplomat_runtime.hpp:554
fn_traits(function_t)
Definition diplomat_runtime.hpp:589
static void c_delete(const void *cb)
Definition diplomat_runtime.hpp:585
Definition diplomat_runtime.hpp:547
Definition diplomat_runtime.hpp:613
T type
Definition diplomat_runtime.hpp:599
T type
Definition diplomat_runtime.hpp:601
T type
Definition diplomat_runtime.hpp:600
Definition diplomat_runtime.hpp:598
Definition diplomat_runtime.hpp:437
T type
Definition diplomat_runtime.hpp:430
Definition diplomat_runtime.hpp:422
T type
Definition diplomat_runtime.hpp:424
Helper template enabling native iteration over unique ptrs to objects which implement next()
Definition diplomat_runtime.hpp:619
void operator++()
Definition diplomat_runtime.hpp:634
void operator++(int)
Definition diplomat_runtime.hpp:635
next_to_iter_helper(const next_to_iter_helper &o)
Definition diplomat_runtime.hpp:632
next_type _curr
Definition diplomat_runtime.hpp:643
bool operator!=(std::nullopt_t)
Definition diplomat_runtime.hpp:638
std::input_iterator_tag iterator_category
Definition diplomat_runtime.hpp:627
next_to_iter_helper(std::unique_ptr< T > &&ptr)
Definition diplomat_runtime.hpp:629
std::shared_ptr< T > _ptr
Definition diplomat_runtime.hpp:642
const value_type & operator*() const
Definition diplomat_runtime.hpp:636
std::add_lvalue_reference_t< value_type > reference
Definition diplomat_runtime.hpp:626
typename inner< next_type >::type value_type
Definition diplomat_runtime.hpp:624
decltype(std::declval< T >().next()) next_type
Definition diplomat_runtime.hpp:621