1#ifndef DIPLOMAT_RUNTIME_CPP_H
2#define DIPLOMAT_RUNTIME_CPP_H
15#if __cplusplus >= 202002L
26static_assert(
sizeof(char) ==
sizeof(uint8_t),
"your architecture's `char` is not 8 bits");
27static_assert(
sizeof(char16_t) ==
sizeof(uint16_t),
"your architecture's `char16_t` is not 16 bits");
28static_assert(
sizeof(char32_t) ==
sizeof(uint32_t),
"your architecture's `char32_t` is not 32 bits");
30typedef struct DiplomatWrite {
36 void (*flush)(
struct DiplomatWrite*);
37 bool (*grow)(
struct DiplomatWrite*, size_t);
40bool diplomat_is_str(
const char* buf,
size_t len);
42#define MAKE_SLICES(name, c_ty) \
43 typedef struct Diplomat##name##View { \
46 } Diplomat##name##View; \
47 typedef struct Diplomat##name##ViewMut { \
50 } Diplomat##name##ViewMut; \
51 typedef struct Diplomat##name##Array { \
54 } Diplomat##name##Array;
56#define MAKE_SLICES_AND_OPTIONS(name, c_ty) \
57 MAKE_SLICES(name, c_ty) \
58 typedef struct Option##name {union { c_ty ok; }; bool is_ok; } Option##name; \
59 typedef struct Option##name##View {union { Diplomat##name##View ok; }; bool is_ok; } Option##name##View; \
60 typedef struct Option##name##ViewMut {union { Diplomat##name##ViewMut ok; }; bool is_ok; } Option##name##ViewMut; \
61 typedef struct Option##name##Array {union { Diplomat##name##Array ok; }; bool is_ok; } Option##name##Array; \
85extern "C" inline void _flush(capi::DiplomatWrite* w) {
86 std::string*
string =
reinterpret_cast<std::string*
>(w->context);
87 string->resize(w->len);
90extern "C" inline bool _grow(capi::DiplomatWrite* w, uintptr_t requested) {
91 std::string*
string =
reinterpret_cast<std::string*
>(w->context);
92 string->resize(requested);
93 w->cap =
string->length();
94 w->buf = &(*string)[0];
98inline capi::DiplomatWrite WriteFromString(std::string&
string) {
99 capi::DiplomatWrite w;
102 w.len =
string.length();
103 w.cap =
string.length();
105 w.grow_failed =
false;
111template<
class T>
struct Ok {
116 template<typename X = T, typename = typename std::enable_if<std::is_trivially_copyable<X>::value>::type>
121 Ok& operator=(const
Ok&) = default;
122 Ok& operator=(
Ok&&) noexcept = default;
125template<class T> struct
Err {
130 template<typename X = T, typename = typename std::enable_if<std::is_trivially_copyable<X>::value>::type>
136 Err& operator=(
Err&&) noexcept = default;
139template<class T, class E>
142 std::variant<Ok<T>,
Err<E>> val;
153 return std::holds_alternative<Ok<T>>(this->val);
156 return std::holds_alternative<Err<E>>(this->val);
159 template<
typename U = T,
typename std::enable_if_t<!std::is_reference_v<U>, std::
nullptr_t> =
nullptr>
160 std::optional<T>
ok() && {
161 if (!this->
is_ok()) {
164 return std::make_optional(std::move(std::get<
Ok<T>>(std::move(this->val)).
inner));
167 template<
typename U = E,
typename std::enable_if_t<!std::is_reference_v<U>, std::
nullptr_t> =
nullptr>
168 std::optional<E>
err() && {
172 return std::make_optional(std::move(std::get<
Err<E>>(std::move(this->val)).
inner));
176 template<
typename U = T,
typename std::enable_if_t<std::is_reference_v<U>, std::
nullptr_t> =
nullptr>
177 std::optional<std::reference_wrapper<std::remove_reference_t<T>>>
ok() && {
178 if (!this->
is_ok()) {
181 return std::make_optional(std::reference_wrapper(std::forward<T>(std::get<
Ok<T>>(std::move(this->val)).
inner)));
184 template<
typename U = E,
typename std::enable_if_t<std::is_reference_v<U>, std::
nullptr_t> =
nullptr>
185 std::optional<std::reference_wrapper<std::remove_reference_t<E>>>
err() && {
189 return std::make_optional(std::reference_wrapper(std::forward<E>(std::get<
Err<E>>(std::move(this->val)).
inner)));
193 this->val =
Ok<T>(std::move(t));
197 this->val =
Err<E>(std::move(e));
200 template<
typename T2>
213#if __cplusplus >= 202002L
216template<
class T, std::
size_t E = dynamic_extent>
using span = std::span<T, E>;
222template <
class T, std::
size_t Extent = dynamic_extent>
229 : data_(o.data_), size_(o.size_) {}
231 constexpr span(std::array<
typename std::remove_const_t<T>, N> &arr)
232 : data_(const_cast<T *>(arr.
data())), size_(N) {}
234 constexpr T*
data() const noexcept {
237 constexpr size_t size() const noexcept {
258template <
typename T,
typename =
void>
264struct as_ffi<T, std::void_t<decltype(std::declval<std::remove_pointer_t<T>>().AsFFI())>> {
265 using type =
decltype(std::declval<std::remove_pointer_t<T>>().AsFFI());
275using replace_ref_with_ptr_t = std::conditional_t<std::is_reference_v<T>, std::add_pointer_t<std::remove_reference_t<T>>, T>;
282template <
typename Ret,
typename... Args>
struct fn_traits<std::function<Ret(Args...)>> {
290 if constexpr(std::is_same_v<T, std::string_view>) {
291 return std::string_view{val.data, val.len};
292 }
else if constexpr (!std::is_same_v<T, as_ffi_t<T>>) {
293 if constexpr (std::is_lvalue_reference_v<T>) {
294 return *std::remove_reference_t<T>::FromFFI(val);
297 return T::FromFFI(val);
310 delete reinterpret_cast<const function_t *
>(cb);
323template<
typename T>
struct inner<std::unique_ptr<T>> {
using type = T; };
324template<
typename T>
struct inner<std::optional<T>>{
using type = T; };
326template<typename T, typename U = typename inner<T>::type>
328 if constexpr(std::is_same_v<T,U>) {
331 return *std::move(v);
336template<
typename T,
typename U =
void>
struct has_next : std::false_type {};
337template<
typename T>
struct has_next < T, std::void_t<decltype(std::declval<T>().next())>> : std::true_type {};
343 static_assert(
has_next_v<T>,
"next_to_iter_helper may only be used with types implementing next()");
349 using reference = std::add_lvalue_reference_t<value_type>;
Definition diplomat_runtime.hpp:210
result(Err< E > &&v)
Definition diplomat_runtime.hpp:145
result(const result &)=default
result & operator=(const result &)=default
result & operator=(result &&) noexcept=default
bool is_err() const
Definition diplomat_runtime.hpp:155
result(Ok< T > &&v)
Definition diplomat_runtime.hpp:144
std::optional< T > ok() &&
Definition diplomat_runtime.hpp:160
std::optional< E > err() &&
Definition diplomat_runtime.hpp:168
std::optional< std::reference_wrapper< std::remove_reference_t< E > > > err() &&
Definition diplomat_runtime.hpp:185
void set_ok(T &&t)
Definition diplomat_runtime.hpp:192
bool is_ok() const
Definition diplomat_runtime.hpp:152
result< T2, E > replace_ok(T2 &&t)
Definition diplomat_runtime.hpp:201
std::optional< std::reference_wrapper< std::remove_reference_t< T > > > ok() &&
Definition diplomat_runtime.hpp:177
void set_err(E &&e)
Definition diplomat_runtime.hpp:196
Definition diplomat_runtime.hpp:223
void operator=(span< T > o)
Definition diplomat_runtime.hpp:244
constexpr T * data() const noexcept
Definition diplomat_runtime.hpp:234
constexpr T * begin() const noexcept
Definition diplomat_runtime.hpp:241
constexpr span(T *data=nullptr, size_t size=Extent)
Definition diplomat_runtime.hpp:225
constexpr span(const span< T > &o)
Definition diplomat_runtime.hpp:228
constexpr span(std::array< typename std::remove_const_t< T >, N > &arr)
Definition diplomat_runtime.hpp:231
constexpr size_t size() const noexcept
Definition diplomat_runtime.hpp:237
constexpr T * end() const noexcept
Definition diplomat_runtime.hpp:242
#define MAKE_SLICES_AND_OPTIONS(name, c_ty)
Definition diplomat_runtime.hpp:56
Definition diplomat_runtime.hpp:21
constexpr bool has_next_v
Definition diplomat_runtime.hpp:338
std::conditional_t< std::is_reference_v< T >, std::add_pointer_t< std::remove_reference_t< T > >, T > replace_ref_with_ptr_t
Definition diplomat_runtime.hpp:275
std::conditional_t< std::is_same_v< T, std::string_view >, capi::DiplomatStringView, T > replace_string_view_t
Definition diplomat_runtime.hpp:272
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:279
const U get_inner_if_present(T v)
Definition diplomat_runtime.hpp:327
constexpr size_t dynamic_extent
Definition diplomat_runtime.hpp:221
typename as_ffi< T >::type as_ffi_t
Definition diplomat_runtime.hpp:269
fn_traits(T) -> fn_traits< T >
Definition diplomat_runtime.hpp:125
Err(T i)
Definition diplomat_runtime.hpp:131
T inner
Definition diplomat_runtime.hpp:126
Err(T &&i)
Definition diplomat_runtime.hpp:127
Err(Err &&) noexcept=default
Definition diplomat_runtime.hpp:111
Ok(T i)
Definition diplomat_runtime.hpp:117
Ok(T &&i)
Definition diplomat_runtime.hpp:113
T inner
Definition diplomat_runtime.hpp:112
Ok(Ok &&) noexcept=default
Definition diplomat_runtime.hpp:259
T type
Definition diplomat_runtime.hpp:260
Ret ret
Definition diplomat_runtime.hpp:285
fn_traits(function_t)
Definition diplomat_runtime.hpp:313
static T replace(replace_fn_t< T > val)
Definition diplomat_runtime.hpp:289
std::function< fn_ptr_t > function_t
Definition diplomat_runtime.hpp:284
static void c_delete(const void *cb)
Definition diplomat_runtime.hpp:309
static Ret c_run_callback(const void *cb, replace_fn_t< Args >... args)
Definition diplomat_runtime.hpp:305
Ret(Args...) fn_ptr_t
Definition diplomat_runtime.hpp:283
Definition diplomat_runtime.hpp:281
Definition diplomat_runtime.hpp:336
T type
Definition diplomat_runtime.hpp:324
T type
Definition diplomat_runtime.hpp:323
Definition diplomat_runtime.hpp:322
T type
Definition diplomat_runtime.hpp:322
next_type _curr
Definition diplomat_runtime.hpp:366
typename inner< next_type >::type value_type
Definition diplomat_runtime.hpp:347
decltype(std::declval< T >().next()) next_type
Definition diplomat_runtime.hpp:344
std::add_lvalue_reference_t< value_type > reference
Definition diplomat_runtime.hpp:349
std::input_iterator_tag iterator_category
Definition diplomat_runtime.hpp:350
void operator++()
Definition diplomat_runtime.hpp:357
bool operator!=(std::nullopt_t)
Definition diplomat_runtime.hpp:361
void difference_type
Definition diplomat_runtime.hpp:348
next_to_iter_helper(std::unique_ptr< T > &&ptr)
Definition diplomat_runtime.hpp:352
std::shared_ptr< T > _ptr
Definition diplomat_runtime.hpp:365
next_to_iter_helper(const next_to_iter_helper &o)
Definition diplomat_runtime.hpp:355
void operator++(int)
Definition diplomat_runtime.hpp:358
const value_type & operator*() const
Definition diplomat_runtime.hpp:359