1#ifndef ICU4X_DIPLOMAT_RUNTIME_CPP_H
2#define ICU4X_DIPLOMAT_RUNTIME_CPP_H
15#if __cplusplus >= 202002L
27static_assert(
sizeof(char) ==
sizeof(uint8_t),
"your architecture's `char` is not 8 bits");
28static_assert(
sizeof(char16_t) ==
sizeof(uint16_t),
"your architecture's `char16_t` is not 16 bits");
29static_assert(
sizeof(char32_t) ==
sizeof(uint32_t),
"your architecture's `char32_t` is not 32 bits");
31typedef struct DiplomatWrite {
37 void (*flush)(
struct DiplomatWrite*);
38 bool (*grow)(
struct DiplomatWrite*, size_t);
41bool diplomat_is_str(
const char* buf,
size_t len);
43#define MAKE_SLICES(name, c_ty) \
44 typedef struct Diplomat##name##View { \
47 } Diplomat##name##View; \
48 typedef struct Diplomat##name##ViewMut { \
51 } Diplomat##name##ViewMut; \
52 typedef struct Diplomat##name##Array { \
55 } Diplomat##name##Array;
57#define MAKE_SLICES_AND_OPTIONS(name, c_ty) \
58 MAKE_SLICES(name, c_ty) \
59 typedef struct Option##name {union { c_ty ok; }; bool is_ok; } Option##name; \
60 typedef struct Option##name##View {union { Diplomat##name##View ok; }; bool is_ok; } Option##name##View; \
61 typedef struct Option##name##ViewMut {union { Diplomat##name##ViewMut ok; }; bool is_ok; } Option##name##ViewMut; \
62 typedef struct Option##name##Array {union { Diplomat##name##Array ok; }; bool is_ok; } Option##name##Array; \
86extern "C" inline void _flush(capi::DiplomatWrite* w) {
87 std::string*
string =
reinterpret_cast<std::string*
>(w->context);
88 string->resize(w->len);
91extern "C" inline bool _grow(capi::DiplomatWrite* w, uintptr_t requested) {
92 std::string*
string =
reinterpret_cast<std::string*
>(w->context);
93 string->resize(requested);
94 w->cap =
string->length();
95 w->buf = &(*string)[0];
99inline capi::DiplomatWrite WriteFromString(std::string&
string) {
100 capi::DiplomatWrite w;
103 w.len =
string.length();
104 w.cap =
string.length();
106 w.grow_failed =
false;
123 static inline capi::DiplomatWrite
Construct(std::string& t) {
124 return diplomat::WriteFromString(t);
128template<
class T>
struct Ok {
135 template<typename X = T, typename = typename std::enable_if<std::is_trivially_copyable<X>::value>::type>
141 Ok& operator=(const
Ok&) = default;
142 Ok& operator=(
Ok&&) noexcept = default;
146template<class T> struct
Err {
153 template<typename X = T, typename = typename std::enable_if<std::is_trivially_copyable<X>::value>::type>
160 Err& operator=(
Err&&) noexcept = default;
165template<class T, class E>
170 template <
typename T_>
182 return std::holds_alternative<Ok<T>>(this->val);
185 return std::holds_alternative<Err<E>>(this->val);
188 template<
typename U = T,
typename std::enable_if_t<!std::is_reference_v<U>, std::
nullptr_t> =
nullptr>
189 std::optional<T>
ok() && {
190 if (!this->
is_ok()) {
193 return std::make_optional(std::move(std::get<
Ok<T>>(std::move(this->val)).
inner));
196 template<
typename U = E,
typename std::enable_if_t<!std::is_reference_v<U>, std::
nullptr_t> =
nullptr>
197 std::optional<E>
err() && {
201 return std::make_optional(std::move(std::get<
Err<E>>(std::move(this->val)).
inner));
205 template<
typename U = T,
typename std::enable_if_t<std::is_reference_v<U>, std::
nullptr_t> =
nullptr>
206 std::optional<std::reference_wrapper<std::remove_reference_t<T>>>
ok() && {
207 if (!this->
is_ok()) {
210 return std::make_optional(std::reference_wrapper(std::forward<T>(std::get<
Ok<T>>(std::move(this->val)).
inner)));
213 template<
typename U = E,
typename std::enable_if_t<std::is_reference_v<U>, std::
nullptr_t> =
nullptr>
214 std::optional<std::reference_wrapper<std::remove_reference_t<E>>>
err() && {
218 return std::make_optional(std::reference_wrapper(std::forward<E>(std::get<
Err<E>>(std::move(this->val)).
inner)));
222 this->val =
Ok<T>(std::move(t));
226 this->val =
Err<E>(std::move(e));
229 template<
typename T2>
242#if __cplusplus >= 202002L
245template<
class T, std::
size_t E = dynamic_extent>
using span = std::span<T, E>;
251template <
class T, std::
size_t Extent = dynamic_extent>
258 : data_(o.data_), size_(o.size_) {}
260 constexpr span(std::array<
typename std::remove_const_t<T>, N> &arr)
261 : data_(const_cast<T *>(arr.
data())), size_(N) {}
263 constexpr T*
data() const noexcept {
266 constexpr size_t size() const noexcept {
287template <
class CharT,
class Traits = std::
char_traits<CharT>>
293 using pointer =
typename std_string_view::pointer;
312 : data_{s.data(), s.size()} {}
315 data_ = {s.data(), s.size()};
327 std::conditional_t<std::is_same_v<value_type, char>,
328 capi::DiplomatStringView,
329 std::conditional_t<std::is_same_v<value_type, char16_t>,
330 capi::DiplomatString16View,
333 static_assert(!std::is_void_v<capi_type>,
334 "ABI compatible string_views are only supported for char and char16_t");
349template <
typename T,
typename =
void>
355struct as_ffi<T, std::void_t<decltype(std::declval<std::remove_pointer_t<T>>().AsFFI())>> {
356 using type =
decltype(std::declval<std::remove_pointer_t<T>>().AsFFI());
365template<
typename T,
typename =
void>
370#define MAKE_SLICE_CONVERTERS(name, c_ty) \
371 template<typename T> \
372 struct diplomat_c_span_convert<T, std::enable_if_t<std::is_same_v<T, span<const c_ty>>>> { \
373 using type = diplomat::capi::Diplomat##name##View; \
375 template<typename T> \
376 struct diplomat_c_span_convert<T, std::enable_if_t<std::is_same_v<T, span<c_ty>>>> { \
377 using type = diplomat::capi::Diplomat##name##ViewMut; \
402template <
typename Ret,
typename... Args>
struct fn_traits<std::function<Ret(Args...)>> {
410 if constexpr(std::is_same_v<T, std::string_view>) {
411 return std::string_view{val.data, val.len};
412 }
else if constexpr (!std::is_same_v<T, diplomat_c_span_convert_t<T>>) {
413 return T{ val.data, val.len };
414 }
else if constexpr (!std::is_same_v<T, as_ffi_t<T>>) {
415 if constexpr (std::is_lvalue_reference_v<T>) {
416 return *std::remove_reference_t<T>::FromFFI(val);
419 return T::FromFFI(val);
429 if constexpr(std::is_same_v<T, std::string_view>) {
430 return {val.data(), val.size()};
431 }
else if constexpr (!std::is_same_v<T, diplomat_c_span_convert_t<T>>) {
438 }
else if constexpr(!std::is_same_v<T, as_ffi_t<T>>) {
449 template<
typename T,
typename E,
typename TOut>
453 auto is_ok = res.
is_ok();
455 constexpr bool has_ok = !std::is_same_v<T, std::monostate>;
456 constexpr bool has_err = !std::is_same_v<E, std::monostate>;
461 if constexpr (has_ok) {
467 if constexpr(has_err) {
469 out.err = replace_ret<E>(std::get<Err<E>>(res.
val).inner);
477 template<
typename T,
typename TOut>
478 static TOut c_run_callback_diplomat_option(
const void *cb, replace_fn_t<Args>... args) {
479 constexpr bool has_ok = !std::is_same_v<T, std::monostate>;
481 std::optional<T> ret = c_run_callback(cb, args...);
483 bool is_ok = ret.has_value();
488 if constexpr(has_ok) {
490 out.ok = replace_ret<T>(ret.value());
505 delete reinterpret_cast<const function_t *
>(cb);
517template<
typename T>
struct inner { };
518template<
typename T>
struct inner<T*> {
using type = T; };
519template<
typename T>
struct inner<std::unique_ptr<T>> {
using type = T; };
520template<
typename T>
struct inner<std::optional<T>>{
using type = T; };
522template<typename T, typename U = typename inner<T>::type>
524 if constexpr(std::is_same_v<T,U>) {
527 return *std::move(v);
532template<
typename T,
typename U =
void>
struct has_next : std::false_type {};
533template<
typename T>
struct has_next < T, std::void_t<decltype(std::declval<T>().next())>> : std::true_type {};
539 static_assert(
has_next_v<T>,
"next_to_iter_helper may only be used with types implementing next()");
545 using reference = std::add_lvalue_reference_t<value_type>;
Definition diplomat_runtime.hpp:239
Definition diplomat_runtime.hpp:288
typename std_string_view::const_pointer const_pointer
Definition diplomat_runtime.hpp:294
constexpr basic_string_view_for_slice(const const_pointer s)
Definition diplomat_runtime.hpp:306
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:323
std::basic_string_view< CharT, Traits > std_string_view
Definition diplomat_runtime.hpp:290
typename std_string_view::size_type size_type
Definition diplomat_runtime.hpp:295
typename std_string_view::traits_type traits_type
Definition diplomat_runtime.hpp:291
constexpr basic_string_view_for_slice & operator=(const std_string_view &s) noexcept
Definition diplomat_runtime.hpp:314
typename std_string_view::difference_type difference_type
Definition diplomat_runtime.hpp:296
constexpr basic_string_view_for_slice(const std_string_view &s) noexcept
Definition diplomat_runtime.hpp:311
constexpr const_pointer data() const noexcept
Definition diplomat_runtime.hpp:322
constexpr basic_string_view_for_slice() noexcept
Definition diplomat_runtime.hpp:298
constexpr basic_string_view_for_slice(const const_pointer s, const size_type count)
Definition diplomat_runtime.hpp:303
typename std_string_view::pointer pointer
Definition diplomat_runtime.hpp:293
typename std_string_view::value_type value_type
Definition diplomat_runtime.hpp:292
constexpr std_string_view as_sv() const noexcept
Definition diplomat_runtime.hpp:320
Definition diplomat_runtime.hpp:166
std::optional< E > err() &&
Definition diplomat_runtime.hpp:197
void set_ok(T &&t)
Definition diplomat_runtime.hpp:221
std::optional< std::reference_wrapper< std::remove_reference_t< E > > > err() &&
Definition diplomat_runtime.hpp:214
bool is_err() const
Definition diplomat_runtime.hpp:184
result & operator=(result &&) noexcept=default
void set_err(E &&e)
Definition diplomat_runtime.hpp:225
friend struct fn_traits
Definition diplomat_runtime.hpp:171
result(Ok< T > &&v)
Definition diplomat_runtime.hpp:173
std::optional< std::reference_wrapper< std::remove_reference_t< T > > > ok() &&
Definition diplomat_runtime.hpp:206
result(const result &)=default
result(Err< E > &&v)
Definition diplomat_runtime.hpp:174
bool is_ok() const
Definition diplomat_runtime.hpp:181
std::optional< T > ok() &&
Definition diplomat_runtime.hpp:189
result< T2, E > replace_ok(T2 &&t)
Definition diplomat_runtime.hpp:230
result & operator=(const result &)=default
std::variant< Ok< T >, Err< E > > val
Definition diplomat_runtime.hpp:168
Definition diplomat_runtime.hpp:252
constexpr T * end() const noexcept
Definition diplomat_runtime.hpp:271
constexpr const string_view_for_slice * data() const noexcept
Definition diplomat_runtime.hpp:263
void operator=(span< T > o)
Definition diplomat_runtime.hpp:273
constexpr span(T *data=nullptr, size_t size=Extent)
Definition diplomat_runtime.hpp:254
constexpr span(std::array< typename std::remove_const_t< T >, N > &arr)
Definition diplomat_runtime.hpp:260
constexpr size_t size() const noexcept
Definition diplomat_runtime.hpp:266
constexpr T * begin() const noexcept
Definition diplomat_runtime.hpp:270
constexpr span(const span< T > &o)
Definition diplomat_runtime.hpp:257
#define MAKE_SLICES_AND_OPTIONS(name, c_ty)
Definition diplomat_runtime.hpp:57
#define MAKE_SLICE_CONVERTERS(name, c_ty)
Definition diplomat_runtime.hpp:370
Definition diplomat_runtime.hpp:22
std::conditional_t< std::is_same_v< T, std::string_view >, capi::DiplomatStringView, T > replace_string_view_t
Definition diplomat_runtime.hpp:363
const U get_inner_if_present(T v)
Definition diplomat_runtime.hpp:523
fn_traits(T) -> fn_traits< T >
constexpr size_t dynamic_extent
Definition diplomat_runtime.hpp:250
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:400
span< const string_view_for_slice > string_view_span
Definition diplomat_runtime.hpp:344
typename diplomat_c_span_convert< T >::type diplomat_c_span_convert_t
Definition diplomat_runtime.hpp:396
basic_string_view_for_slice< char16_t > u16string_view_for_slice
Definition diplomat_runtime.hpp:342
constexpr bool has_next_v
Definition diplomat_runtime.hpp:534
typename as_ffi< T >::type as_ffi_t
Definition diplomat_runtime.hpp:360
span< const u16string_view_for_slice > u16string_view_span
Definition diplomat_runtime.hpp:345
basic_string_view_for_slice< char > string_view_for_slice
Definition diplomat_runtime.hpp:341
Definition diplomat_runtime.hpp:146
Err(const T &i)
Definition diplomat_runtime.hpp:154
Err(T &&i)
Definition diplomat_runtime.hpp:150
T inner
Definition diplomat_runtime.hpp:147
Err(Err &&) noexcept=default
Definition diplomat_runtime.hpp:128
Ok(const T &i)
Definition diplomat_runtime.hpp:136
Ok(T &&i)
Definition diplomat_runtime.hpp:132
T inner
Definition diplomat_runtime.hpp:129
Ok(Ok &&) noexcept=default
static capi::DiplomatWrite Construct(std::string &t)
Definition diplomat_runtime.hpp:123
Definition diplomat_runtime.hpp:117
Definition diplomat_runtime.hpp:350
T type
Definition diplomat_runtime.hpp:351
Definition diplomat_runtime.hpp:366
T type
Definition diplomat_runtime.hpp:367
std::function< fn_ptr_t > function_t
Definition diplomat_runtime.hpp:404
static T c_run_callback_diplomat_opaque(const void *cb, replace_fn_t< Args >... args)
Definition diplomat_runtime.hpp:498
Ret(Args...) fn_ptr_t
Definition diplomat_runtime.hpp:403
static replace_fn_t< T > replace_ret(T val)
Definition diplomat_runtime.hpp:428
static Ret c_run_callback(const void *cb, replace_fn_t< Args >... args)
Definition diplomat_runtime.hpp:445
Ret ret
Definition diplomat_runtime.hpp:405
fn_traits(function_t)
Definition diplomat_runtime.hpp:508
static void c_delete(const void *cb)
Definition diplomat_runtime.hpp:504
static T replace(replace_fn_t< T > val)
Definition diplomat_runtime.hpp:409
Definition diplomat_runtime.hpp:163
Definition diplomat_runtime.hpp:532
T type
Definition diplomat_runtime.hpp:518
T type
Definition diplomat_runtime.hpp:520
T type
Definition diplomat_runtime.hpp:519
Definition diplomat_runtime.hpp:517
void operator++()
Definition diplomat_runtime.hpp:553
void operator++(int)
Definition diplomat_runtime.hpp:554
void difference_type
Definition diplomat_runtime.hpp:544
next_to_iter_helper(const next_to_iter_helper &o)
Definition diplomat_runtime.hpp:551
next_type _curr
Definition diplomat_runtime.hpp:562
bool operator!=(std::nullopt_t)
Definition diplomat_runtime.hpp:557
std::input_iterator_tag iterator_category
Definition diplomat_runtime.hpp:546
next_to_iter_helper(std::unique_ptr< T > &&ptr)
Definition diplomat_runtime.hpp:548
std::shared_ptr< T > _ptr
Definition diplomat_runtime.hpp:561
const value_type & operator*() const
Definition diplomat_runtime.hpp:555
std::add_lvalue_reference_t< value_type > reference
Definition diplomat_runtime.hpp:545
typename inner< next_type >::type value_type
Definition diplomat_runtime.hpp:543
decltype(std::declval< T >().next()) next_type
Definition diplomat_runtime.hpp:540