1#ifndef DIPLOMAT_RUNTIME_CPP_H
2#define DIPLOMAT_RUNTIME_CPP_H
11#if __cplusplus >= 202002L
22static_assert(
sizeof(char) ==
sizeof(uint8_t),
"your architecture's `char` is not 8 bits");
23static_assert(
sizeof(char16_t) ==
sizeof(uint16_t),
"your architecture's `char16_t` is not 16 bits");
24static_assert(
sizeof(char32_t) ==
sizeof(uint32_t),
"your architecture's `char32_t` is not 32 bits");
26typedef struct DiplomatWrite {
32 void (*flush)(
struct DiplomatWrite*);
33 bool (*grow)(
struct DiplomatWrite*, size_t);
36bool diplomat_is_str(
const char* buf,
size_t len);
38#define MAKE_SLICES(name, c_ty) \
39 typedef struct Diplomat##name##View { \
42 } Diplomat##name##View; \
43 typedef struct Diplomat##name##ViewMut { \
46 } Diplomat##name##ViewMut; \
47 typedef struct Diplomat##name##Array { \
50 } Diplomat##name##Array;
52#define MAKE_SLICES_AND_OPTIONS(name, c_ty) \
53 MAKE_SLICES(name, c_ty) \
54 typedef struct Option##name {union { c_ty ok; }; bool is_ok; } Option##name; \
55 typedef struct Option##name##View {union { Diplomat##name##View ok; }; bool is_ok; } Option##name##View; \
56 typedef struct Option##name##ViewMut {union { Diplomat##name##ViewMut ok; }; bool is_ok; } Option##name##ViewMut; \
57 typedef struct Option##name##Array {union { Diplomat##name##Array ok; }; bool is_ok; } Option##name##Array; \
81extern "C" inline void _flush(capi::DiplomatWrite* w) {
82 std::string*
string =
reinterpret_cast<std::string*
>(w->context);
83 string->resize(w->len);
86extern "C" inline bool _grow(capi::DiplomatWrite* w, uintptr_t requested) {
87 std::string*
string =
reinterpret_cast<std::string*
>(w->context);
88 string->resize(requested);
89 w->cap =
string->length();
90 w->buf = &(*string)[0];
95 capi::DiplomatWrite w;
98 w.len =
string.length();
99 w.cap =
string.length();
101 w.grow_failed =
false;
107template<
class T>
struct Ok {
112 template<typename X = T, typename = typename std::enable_if<std::is_trivially_copyable<X>::value>::type>
117 Ok& operator=(const
Ok&) = default;
118 Ok& operator=(
Ok&&) noexcept = default;
121template<class T> struct
Err {
126 template<typename X = T, typename = typename std::enable_if<std::is_trivially_copyable<X>::value>::type>
132 Err& operator=(
Err&&) noexcept = default;
135template<class T, class E>
138 std::variant<Ok<T>,
Err<E>> val;
149 return std::holds_alternative<Ok<T>>(this->val);
152 return std::holds_alternative<Err<E>>(this->val);
155 template<
typename U = T,
typename std::enable_if_t<!std::is_reference_v<U>, std::
nullptr_t> =
nullptr>
156 std::optional<T>
ok() && {
157 if (!this->is_ok()) {
160 return std::make_optional(std::move(std::get<
Ok<T>>(std::move(this->val)).
inner));
163 template<
typename U = E,
typename std::enable_if_t<!std::is_reference_v<U>, std::
nullptr_t> =
nullptr>
164 std::optional<E>
err() && {
165 if (!this->is_err()) {
168 return std::make_optional(std::move(std::get<
Err<E>>(std::move(this->val)).
inner));
172 template<
typename U = T,
typename std::enable_if_t<std::is_reference_v<U>, std::
nullptr_t> =
nullptr>
173 std::optional<std::reference_wrapper<std::remove_reference_t<T>>>
ok() && {
174 if (!this->is_ok()) {
177 return std::make_optional(std::reference_wrapper(std::forward<T>(std::get<
Ok<T>>(std::move(this->val)).
inner)));
180 template<
typename U = E,
typename std::enable_if_t<std::is_reference_v<U>, std::
nullptr_t> =
nullptr>
181 std::optional<std::reference_wrapper<std::remove_reference_t<E>>>
err() && {
182 if (!this->is_err()) {
185 return std::make_optional(std::reference_wrapper(std::forward<E>(std::get<
Err<E>>(std::move(this->val)).
inner)));
189 this->val =
Ok<T>(std::move(t));
193 this->val =
Err<E>(std::move(e));
196 template<
typename T2>
198 if (this->is_err()) {
209#if __cplusplus >= 202002L
211template<
class T>
using span = std::span<T>;
220 constexpr span(T* data,
size_t size)
221 : data_(data), size_(size) {}
223 constexpr span(std::array<
typename std::remove_const<T>::type, N>& arr)
224 : data_(const_cast<T*>(arr.data())), size_(N) {}
225 constexpr T*
data() const noexcept {
228 constexpr size_t size() const noexcept {
241template <
typename Ret,
typename... Args>
struct fn_traits<std::function<Ret(Args...)>> {
246 template <
typename T,
typename =
void>
251 template <
typename T>
252 struct as_ffi<T, std::void_t<decltype(&T::AsFFI)>> {
253 using type =
decltype(std::declval<T>().AsFFI());
268 if constexpr(std::is_same_v<T, std::string_view>) {
269 return std::string_view{val.data, val.len};
270 }
else if constexpr(!std::is_same_v<T, as_ffi_t<T>>) {
271 return T::FromFFI(val);
279 return (*
reinterpret_cast<const function_t *
>(cb))(replace<Args>(args)...);
283 delete reinterpret_cast<const function_t *
>(cb);
Definition: diplomat_runtime.hpp:206
Definition: diplomat_runtime.hpp:136
result(Err< E > &&v)
Definition: diplomat_runtime.hpp:141
result(const result &)=default
result & operator=(const result &)=default
result & operator=(result &&) noexcept=default
bool is_err() const
Definition: diplomat_runtime.hpp:151
result(Ok< T > &&v)
Definition: diplomat_runtime.hpp:140
std::optional< T > ok() &&
Definition: diplomat_runtime.hpp:156
std::optional< E > err() &&
Definition: diplomat_runtime.hpp:164
std::optional< std::reference_wrapper< std::remove_reference_t< E > > > err() &&
Definition: diplomat_runtime.hpp:181
void set_ok(T &&t)
Definition: diplomat_runtime.hpp:188
result< T2, E > replace_ok(T2 &&t)
Definition: diplomat_runtime.hpp:197
std::optional< std::reference_wrapper< std::remove_reference_t< T > > > ok() &&
Definition: diplomat_runtime.hpp:173
void set_err(E &&e)
Definition: diplomat_runtime.hpp:192
Definition: diplomat_runtime.hpp:217
constexpr T * data() const noexcept
Definition: diplomat_runtime.hpp:225
constexpr size_t size() const noexcept
Definition: diplomat_runtime.hpp:228
constexpr span(std::array< typename std::remove_const< T >::type, N > &arr)
Definition: diplomat_runtime.hpp:223
constexpr span(T *data, size_t size)
Definition: diplomat_runtime.hpp:220
#define MAKE_SLICES_AND_OPTIONS(name, c_ty)
Definition: diplomat_runtime.hpp:52
Definition: diplomat_runtime.hpp:17
bool _grow(capi::DiplomatWrite *w, uintptr_t requested)
Definition: diplomat_runtime.hpp:86
void _flush(capi::DiplomatWrite *w)
Definition: diplomat_runtime.hpp:81
capi::DiplomatWrite WriteFromString(std::string &string)
Definition: diplomat_runtime.hpp:94
Definition: diplomat_runtime.hpp:121
Err(T i)
Definition: diplomat_runtime.hpp:127
T inner
Definition: diplomat_runtime.hpp:122
Err(T &&i)
Definition: diplomat_runtime.hpp:123
Err(Err &&) noexcept=default
Definition: diplomat_runtime.hpp:107
Ok(T i)
Definition: diplomat_runtime.hpp:113
Ok(T &&i)
Definition: diplomat_runtime.hpp:109
T inner
Definition: diplomat_runtime.hpp:108
Ok(Ok &&) noexcept=default
T type
Definition: diplomat_runtime.hpp:248
Ret ret
Definition: diplomat_runtime.hpp:244
typename as_ffi< T >::type as_ffi_t
Definition: diplomat_runtime.hpp:257
fn_traits(function_t)
Definition: diplomat_runtime.hpp:286
std::conditional_t< std::is_same_v< T, std::string_view >, capi::DiplomatStringView, T > replace_string_view_t
Definition: diplomat_runtime.hpp:260
static T replace(replace_fn_t< T > val)
Definition: diplomat_runtime.hpp:267
std::function< fn_ptr_t > function_t
Definition: diplomat_runtime.hpp:243
static void c_delete(const void *cb)
Definition: diplomat_runtime.hpp:282
replace_string_view_t< as_ffi_t< T > > replace_fn_t
Definition: diplomat_runtime.hpp:263
static Ret c_run_callback(const void *cb, replace_fn_t< Args >... args)
Definition: diplomat_runtime.hpp:278
Ret(Args...) fn_ptr_t
Definition: diplomat_runtime.hpp:242
Definition: diplomat_runtime.hpp:240