ICU4X
International Components for Unicode
Loading...
Searching...
No Matches
diplomat_runtime.hpp
Go to the documentation of this file.
1#ifndef ICU4X_DIPLOMAT_RUNTIME_CPP_H
2#define ICU4X_DIPLOMAT_RUNTIME_CPP_H
3
4#include <optional>
5#include <string>
6#include <string_view>
7#include <type_traits>
8#include <variant>
9#include <cstdint>
10#include <functional>
11#include <memory>
12#include <limits>
13
14
15#if __cplusplus >= 202002L
16#include <span>
17#else
18#include <array>
19#endif
20
21namespace icu4x {
22namespace diplomat {
23
24namespace capi {
25extern "C" {
26
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");
30
31typedef struct DiplomatWrite {
32 void* context;
33 char* buf;
34 size_t len;
35 size_t cap;
36 bool grow_failed;
37 void (*flush)(struct DiplomatWrite*);
38 bool (*grow)(struct DiplomatWrite*, size_t);
39} DiplomatWrite;
40
41bool diplomat_is_str(const char* buf, size_t len);
42
43#define MAKE_SLICES(name, c_ty) \
44 typedef struct Diplomat##name##View { \
45 const c_ty* data; \
46 size_t len; \
47 } Diplomat##name##View; \
48 typedef struct Diplomat##name##ViewMut { \
49 c_ty* data; \
50 size_t len; \
51 } Diplomat##name##ViewMut; \
52 typedef struct Diplomat##name##Array { \
53 const c_ty* data; \
54 size_t len; \
55 } Diplomat##name##Array;
56
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; \
63
65MAKE_SLICES_AND_OPTIONS(U8, uint8_t)
66MAKE_SLICES_AND_OPTIONS(I16, int16_t)
67MAKE_SLICES_AND_OPTIONS(U16, uint16_t)
68MAKE_SLICES_AND_OPTIONS(I32, int32_t)
69MAKE_SLICES_AND_OPTIONS(U32, uint32_t)
70MAKE_SLICES_AND_OPTIONS(I64, int64_t)
71MAKE_SLICES_AND_OPTIONS(U64, uint64_t)
72MAKE_SLICES_AND_OPTIONS(Isize, intptr_t)
73MAKE_SLICES_AND_OPTIONS(Usize, size_t)
75MAKE_SLICES_AND_OPTIONS(F64, double)
77MAKE_SLICES_AND_OPTIONS(Char, char32_t)
78MAKE_SLICES_AND_OPTIONS(String, char)
79MAKE_SLICES_AND_OPTIONS(String16, char16_t)
80MAKE_SLICES_AND_OPTIONS(Strings, DiplomatStringView)
81MAKE_SLICES_AND_OPTIONS(Strings16, DiplomatString16View)
82
83} // extern "C"
84} // namespace capi
85
86extern "C" inline void _flush(capi::DiplomatWrite* w) {
87 std::string* string = reinterpret_cast<std::string*>(w->context);
88 string->resize(w->len);
89}
90
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];
96 return true;
97}
98
99inline capi::DiplomatWrite WriteFromString(std::string& string) {
100 capi::DiplomatWrite w;
101 w.context = &string;
102 w.buf = &string[0];
103 w.len = string.length();
104 w.cap = string.length();
105 // Will never become true, as _grow is infallible.
106 w.grow_failed = false;
107 w.flush = _flush;
108 w.grow = _grow;
109 return w;
110}
111
112// This "trait" allows one to use _write() methods to efficiently
113// write to a custom string type. To do this you need to write a specialized
114// `WriteTrait<YourType>` (see WriteTrait<std::string> below)
115// that is capable of constructing a DiplomatWrite, which can wrap
116// your string type with appropriate resize/flush functionality.
117template<typename T> struct WriteTrait {
118 // Fill in this method on a specialization to implement this trait
119 // static inline capi::DiplomatWrite Construct(T& t);
120};
121
122template<> struct WriteTrait<std::string> {
123 static inline capi::DiplomatWrite Construct(std::string& t) {
124 return diplomat::WriteFromString(t);
125 }
126};
127
128template<class T> struct Ok {
130
131 // Move constructor always allowed
132 Ok(T&& i): inner(std::forward<T>(i)) {}
133
134 // copy constructor allowed only for trivially copyable types
135 template<typename X = T, typename = typename std::enable_if<std::is_trivially_copyable<X>::value>::type>
136 Ok(const T& i) : inner(i) {}
137
138 Ok() = default;
139 Ok(Ok&&) noexcept = default;
140 Ok(const Ok &) = default;
141 Ok& operator=(const Ok&) = default;
142 Ok& operator=(Ok&&) noexcept = default;
143};
144
145
146template<class T> struct Err {
148
149 // Move constructor always allowed
150 Err(T&& i): inner(std::forward<T>(i)) {}
151
152 // copy constructor allowed only for trivially copyable types
153 template<typename X = T, typename = typename std::enable_if<std::is_trivially_copyable<X>::value>::type>
154 Err(const T& i) : inner(i) {}
155
156 Err() = default;
157 Err(Err&&) noexcept = default;
158 Err(const Err &) = default;
159 Err& operator=(const Err&) = default;
160 Err& operator=(Err&&) noexcept = default;
161};
162
163template <typename T> struct fn_traits;
164
165template<class T, class E>
166class result {
167protected:
168 std::variant<Ok<T>, Err<E>> val;
169public:
170 template <typename T_>
171 friend struct fn_traits;
172
173 result(Ok<T>&& v): val(std::move(v)) {}
174 result(Err<E>&& v): val(std::move(v)) {}
175 result() = default;
176 result(const result &) = default;
177 result& operator=(const result&) = default;
178 result& operator=(result&&) noexcept = default;
179 result(result &&) noexcept = default;
180 ~result() = default;
181 bool is_ok() const {
182 return std::holds_alternative<Ok<T>>(this->val);
183 }
184 bool is_err() const {
185 return std::holds_alternative<Err<E>>(this->val);
186 }
187
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()) {
191 return std::nullopt;
192 }
193 return std::make_optional(std::move(std::get<Ok<T>>(std::move(this->val)).inner));
194 }
195
196 template<typename U = E, typename std::enable_if_t<!std::is_reference_v<U>, std::nullptr_t> = nullptr>
197 std::optional<E> err() && {
198 if (!this->is_err()) {
199 return std::nullopt;
200 }
201 return std::make_optional(std::move(std::get<Err<E>>(std::move(this->val)).inner));
202 }
203
204 // std::optional does not work with reference types directly, so wrap them if present
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()) {
208 return std::nullopt;
209 }
210 return std::make_optional(std::reference_wrapper(std::forward<T>(std::get<Ok<T>>(std::move(this->val)).inner)));
211 }
212
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() && {
215 if (!this->is_err()) {
216 return std::nullopt;
217 }
218 return std::make_optional(std::reference_wrapper(std::forward<E>(std::get<Err<E>>(std::move(this->val)).inner)));
219 }
220
221 void set_ok(T&& t) {
222 this->val = Ok<T>(std::move(t));
223 }
224
225 void set_err(E&& e) {
226 this->val = Err<E>(std::move(e));
227 }
228
229 template<typename T2>
231 if (this->is_err()) {
232 return result<T2, E>(Err<E>(std::get<Err<E>>(std::move(this->val))));
233 } else {
234 return result<T2, E>(Ok<T2>(std::move(t)));
235 }
236 }
237};
238
239class Utf8Error {};
240
241// Use custom std::span on C++17, otherwise use std::span
242#if __cplusplus >= 202002L
243
244constexpr std::size_t dynamic_extent = std::dynamic_extent;
245template<class T, std::size_t E = dynamic_extent> using span = std::span<T, E>;
246
247#else // __cplusplus < 202002L
248
249// C++-17-compatible-ish std::span
250constexpr size_t dynamic_extent = std::numeric_limits<std::size_t>::max();
251template <class T, std::size_t Extent = dynamic_extent>
252class span {
253public:
254 constexpr span(T *data = nullptr, size_t size = Extent)
255 : data_(data), size_(size) {}
256
257 constexpr span(const span<T> &o)
258 : data_(o.data_), size_(o.size_) {}
259 template <size_t N>
260 constexpr span(std::array<typename std::remove_const_t<T>, N> &arr)
261 : data_(const_cast<T *>(arr.data())), size_(N) {}
262
263 constexpr T* data() const noexcept {
264 return this->data_;
265 }
266 constexpr size_t size() const noexcept {
267 return this->size_;
268 }
269
270 constexpr T *begin() const noexcept { return data(); }
271 constexpr T *end() const noexcept { return data() + size(); }
272
274 data_ = o.data_;
275 size_ = o.size_;
276 }
277
278private:
279 T* data_;
280 size_t size_;
281};
282
283#endif // __cplusplus >= 202002L
284
285// An ABI stable std::basic_string_view equivalent for the case of string
286// views in slices
287template <class CharT, class Traits = std::char_traits<CharT>>
289public:
290 using std_string_view = std::basic_string_view<CharT, Traits>;
291 using traits_type = typename std_string_view::traits_type;
292 using value_type = typename std_string_view::value_type;
293 using pointer = typename std_string_view::pointer;
294 using const_pointer = typename std_string_view::const_pointer;
295 using size_type = typename std_string_view::size_type;
296 using difference_type = typename std_string_view::difference_type;
297
300
301 constexpr basic_string_view_for_slice(const basic_string_view_for_slice& other) noexcept = default;
302
305
308
309 constexpr basic_string_view_for_slice& operator=(const basic_string_view_for_slice& view) noexcept = default;
310
311 constexpr basic_string_view_for_slice(const std_string_view& s) noexcept
312 : data_{s.data(), s.size()} {}
313
315 data_ = {s.data(), s.size()};
316 return *this;
317 }
318
319 constexpr operator std_string_view() const noexcept { return {data(), size()}; }
320 constexpr std_string_view as_sv() const noexcept { return *this; }
321
322 constexpr const_pointer data() const noexcept { return data_.data; }
323 constexpr size_type size() const noexcept { return data_.len; }
324
325private:
326 using capi_type =
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,
331 void>>;
332
333 static_assert(!std::is_void_v<capi_type>,
334 "ABI compatible string_views are only supported for char and char16_t");
335
336 capi_type data_;
337};
338
339// We only implement these specialisations as diplomat doesn't provide c abi
340// types for others
343
346
347// Interop between std::function & our C Callback wrapper type
348
349template <typename T, typename = void>
350struct as_ffi {
351 using type = T;
352};
353
354template <typename T>
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());
357};
358
359template<typename T>
360using as_ffi_t = typename as_ffi<T>::type;
361
362template<typename T>
363using replace_string_view_t = std::conditional_t<std::is_same_v<T, std::string_view>, capi::DiplomatStringView, T>;
364
365template<typename T, typename = void>
367 using type = T;
368};
369
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; \
374 }; \
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; \
378 }; \
379
380MAKE_SLICE_CONVERTERS(I8, int8_t)
381MAKE_SLICE_CONVERTERS(U8, uint8_t)
382MAKE_SLICE_CONVERTERS(I16, int16_t)
383MAKE_SLICE_CONVERTERS(U16, uint16_t)
384MAKE_SLICE_CONVERTERS(I32, int32_t)
385MAKE_SLICE_CONVERTERS(U32, uint32_t)
386MAKE_SLICE_CONVERTERS(I64, int64_t)
387MAKE_SLICE_CONVERTERS(U64, uint64_t)
388MAKE_SLICE_CONVERTERS(F32, float)
389MAKE_SLICE_CONVERTERS(F64, double)
390MAKE_SLICE_CONVERTERS(Bool, bool)
391MAKE_SLICE_CONVERTERS(Char, char32_t)
392MAKE_SLICE_CONVERTERS(String, char)
393MAKE_SLICE_CONVERTERS(String16, char16_t)
394
395template<typename T>
397
399template<typename T>
401
402template <typename Ret, typename... Args> struct fn_traits<std::function<Ret(Args...)>> {
403 using fn_ptr_t = Ret(Args...);
404 using function_t = std::function<fn_ptr_t>;
405 using ret = Ret;
406
407 // For a given T, creates a function that take in the C ABI version & return the C++ type.
408 template<typename T>
409 static T replace(replace_fn_t<T> val) {
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);
417 }
418 else {
419 return T::FromFFI(val);
420 }
421 }
422 else {
423 return val;
424 }
425 }
426
427 template<typename T>
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>>) {
432 // Can we convert straight away to our slice type, or (in the case of ABI compatible structs), do we have to do a reinterpret cast?
433 if constexpr(std::is_same_v<decltype(std::declval<T>().data()), decltype(replace_fn_t<T>::data)>) {
434 return replace_fn_t<T> { val.data(), val.size() };
435 } else {
436 return replace_fn_t<T> { reinterpret_cast<decltype(replace_fn_t<T>::data)>(val.data()), val.size() };
437 }
438 } else if constexpr(!std::is_same_v<T, as_ffi_t<T>>) {
439 return val.AsFFI();
440 } else {
441 return val;
442 }
443 }
444
445 static Ret c_run_callback(const void *cb, replace_fn_t<Args>... args) {
446 return (*reinterpret_cast<const function_t *>(cb))(replace<Args>(args)...);
447 }
448
449 template<typename T, typename E, typename TOut>
450 static TOut c_run_callback_result(const void *cb, replace_fn_t<Args>... args) {
451 result<T, E> res = c_run_callback(cb, args...);
452
453 auto is_ok = res.is_ok();
454
455 constexpr bool has_ok = !std::is_same_v<T, std::monostate>;
456 constexpr bool has_err = !std::is_same_v<E, std::monostate>;
457
458 TOut out;
459 out.is_ok = is_ok;
460
461 if constexpr (has_ok) {
462 if (is_ok) {
463 out.ok = replace_ret<T>(std::get<Ok<T>>(res.val).inner);
464 }
465 }
466
467 if constexpr(has_err) {
468 if (!is_ok) {
469 out.err = replace_ret<E>(std::get<Err<E>>(res.val).inner);
470 }
471 }
472
473 return out;
474 }
475
476 // For DiplomatOption<>
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>;
480
481 std::optional<T> ret = c_run_callback(cb, args...);
482
483 bool is_ok = ret.has_value();
484
485 TOut out;
486 out.is_ok = is_ok;
487
488 if constexpr(has_ok) {
489 if (is_ok) {
490 out.ok = replace_ret<T>(ret.value());
491 }
492 }
493 return out;
494 }
495
496 // All we need to do is just convert one pointer to another, while keeping the arguments the same:
497 template<typename T>
498 static T c_run_callback_diplomat_opaque(const void* cb, replace_fn_t<Args>... args) {
499 Ret out = c_run_callback(cb, args...);
500
501 return out->AsFFI();
502 }
503
504 static void c_delete(const void *cb) {
505 delete reinterpret_cast<const function_t *>(cb);
506 }
507
508 fn_traits(function_t) {} // Allows less clunky construction (avoids decltype)
509};
510
511// additional deduction guide required
512template<class T>
514
515// Trait for extracting inner types from either T*, std::optional, or std::unique_ptr.
516// These are the three potential types returned by next() functions
517template<typename T> struct inner { /* only T*, std::optional, and std::unique_ptr are supported */ };
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; };
521
522template<typename T, typename U = typename inner<T>::type>
523inline const U get_inner_if_present(T v) {
524 if constexpr(std::is_same_v<T,U>) {
525 return std::move(v);
526 } else {
527 return *std::move(v);
528 }
529}
530
531// Adapter for iterator types
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 {};
534template<typename T> constexpr bool has_next_v = has_next<T>::value;
535
537template<typename T>
539 static_assert(has_next_v<T>, "next_to_iter_helper may only be used with types implementing next()");
540 using next_type = decltype(std::declval<T>().next());
541
542 // STL Iterator trait definitions
544 using difference_type = void;
545 using reference = std::add_lvalue_reference_t<value_type>;
546 using iterator_category = std::input_iterator_tag;
547
548 next_to_iter_helper(std::unique_ptr<T>&& ptr) : _ptr(std::move(ptr)), _curr(_ptr->next()) {}
549
550 // https://en.cppreference.com/w/cpp/named_req/InputIterator requires that the type be copyable
552
553 void operator++() { _curr = _ptr->next(); }
554 void operator++(int) { ++(*this); }
555 const value_type& operator*() const { return *_curr; }
556
557 bool operator!=(std::nullopt_t) {
558 return (bool)_curr;
559 }
560
561 std::shared_ptr<T> _ptr; // shared to satisfy the copyable requirement
563};
564
565} // namespace diplomat
566} // namespace icu4x
567#endif
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 Bidi.d.hpp:13
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