36#ifdef ZTH_STACK_SWITCH
37EXTERN_C ZTH_EXPORT
void*
38zth_stack_switch(
void* stack,
size_t size,
void* (*f)(
void*)
noexcept,
void* arg)
noexcept;
40# define zth_stack_switch(stack, size, f, arg) \
51# if __cplusplus >= 201103L
55# if __cplusplus < 201103L
56# undef ZTH_STACK_SWITCH98
58# define ZTH_STACK_SWITCH98 1
59# elif !defined(ZTH_STACK_SWITCH98)
62# define ZTH_STACK_SWITCH98 0
90 constexpr Stack(
void* p_,
size_t size_) noexcept
91 :
p(
static_cast<char*
>(p_))
95 constexpr explicit Stack(
size_t size_ = 0) noexcept
100 constexpr operator bool() const noexcept
102 return p !=
nullptr &&
size > 0;
110void context_deinit() noexcept;
113void context_destroy(
Context* context) noexcept;
114size_t context_stack_usage(
Context* context) noexcept;
116void stack_watermark_init(
void* stack,
size_t size) noexcept;
117size_t stack_watermark_size(
void* stack) noexcept;
118size_t stack_watermark_maxused(
void* stack) noexcept;
119size_t stack_watermark_remaining(
void* stack) noexcept;
125# if ZTH_STACK_SWITCH98
143struct FunctionIO0<void> {
157template <
typename R,
typename A1>
174template <
typename A1>
175struct FunctionIO1<void, A1> {
190template <
typename R,
typename A1,
typename A2>
208template <
typename A1,
typename A2>
209struct FunctionIO2<void, A1, A2> {
225template <
typename R,
typename A1,
typename A2,
typename A3>
243template <
typename A1,
typename A2,
typename A3>
244struct FunctionIO3<void, A1, A2, A3> {
247 void (*f)(A1, A2, A3);
261# elif __cplusplus >= 201103L
265 using type =
typename std::decay<T>::type;
270 using type = std::reference_wrapper<typename std::decay<T>::type>;
273template <
typename... A>
275 template <
typename R>
278 constexpr static size_t size =
sizeof...(A);
281template <
typename R,
typename A,
typename A_>
285 typename A::template function_type<R>*
f;
286 typename A_::tuple_type
a;
293 call(
typename SequenceGenerator<A::size>::type(), A());
298 template <
size_t... S,
typename... _A>
301 r = f(std::forward<_A>(std::get<S>(a))...);
305template <
typename A,
typename A_>
309 typename A::template function_type<void>*
f;
310 typename A_::tuple_type
a;
316 call(
typename SequenceGenerator<A::size>::type(), A());
321 template <
size_t... S,
typename... _A>
324 f(std::forward<_A>(std::get<S>(a))...);
332 return (*
static_cast<F*
>(f))();
337# if ZTH_STACK_SWITCH98
342inline R stack_switch(
void* stack,
size_t size, R (*f)())
344 impl::FunctionIO0<R> f_ = {{f}};
345 return *
static_cast<R*
>(
354inline void stack_switch(
void* stack,
size_t size,
void (*f)())
356 impl::FunctionIO0<void> f_ = {{f}};
364template <
typename R,
typename A1>
365inline R
stack_switch(
void* stack,
size_t size, R (*f)(A1), A1 a1)
367 impl::FunctionIO1<R, A1> f_ = {{f, a1}};
368 return *
static_cast<R*
>(
376template <
typename A1>
377inline void stack_switch(
void* stack,
size_t size,
void (*f)(A1), A1 a1)
379 impl::FunctionIO1<void, A1> f_ = {{f, a1}};
387template <
typename R,
typename A1,
typename A2>
388inline R
stack_switch(
void* stack,
size_t size, R (*f)(A1, A2), A1 a1, A2 a2)
390 impl::FunctionIO2<R, A1, A2> f_ = {{f, a1, a2}};
391 return *
static_cast<R*
>(
399template <
typename A1,
typename A2>
400inline void stack_switch(
void* stack,
size_t size,
void (*f)(A1, A2), A1 a1, A2 a2)
402 impl::FunctionIO2<void, A1, A2> f_ = {{f, a1, a2}};
410template <
typename R,
typename A1,
typename A2,
typename A3>
411inline R
stack_switch(
void* stack,
size_t size, R (*f)(A1, A2, A3), A1 a1, A2 a2, A3 a3)
413 impl::FunctionIO3<R, A1, A2, A3> f_ = {{f, a1, a2, a3}};
414 return *
static_cast<R*
>(
422template <
typename A1,
typename A2,
typename A3>
423inline void stack_switch(
void* stack,
size_t size,
void (*f)(A1, A2, A3), A1 a1, A2 a2, A3 a3)
425 impl::FunctionIO3<void, A1, A2, A3> f_ = {{f, a1, a2, a3}};
429# elif __cplusplus >= 201103L
436template <
typename R,
typename... A,
typename... A_>
437inline typename std::enable_if<!std::is_void<R>::value, R>::type
438stack_switch(
void* stack,
size_t size, R (*f)(A...)
noexcept, A_&&... a)
noexcept
441 {f, {std::forward<A_>(a)...}}};
443 zth_stack_switch(stack, size, &impl::stack_switch_fwd<
decltype(f_)>, &f_)));
451template <
typename... A,
typename... A_>
452inline void stack_switch(
void* stack,
size_t size,
void (*f)(A...)
noexcept, A_&&... a)
noexcept
455 {f, {std::forward<A_>(a)...}}};
#define zth_stack_switch(stack, size, f, arg)
Call the function f using the new stack pointer.
std::enable_if<!std::is_void< R >::value, R >::type stack_switch(void *stack, size_t size, R(*f)(A...) noexcept, A_ &&... a) noexcept
Call the function f using the new stack pointer.
void * stack_switch_fwd(void *f) noexcept
int context_init() noexcept
One-time context mechanism initialization.
constexpr ContextAttr(Entry entry_=nullptr, EntryArg arg_=EntryArg(), size_t stackSize_=Config::DefaultFiberStackSize) noexcept
static size_t const DefaultFiberStackSize
Default fiber stack size in bytes.
constexpr Stack(void *p_, size_t size_) noexcept
constexpr Stack(size_t size_=0) noexcept
std::tuple< typename Packed< A >::type... > tuple_type
void * operator()() noexcept
A::template function_type< void > * f
void * operator()() noexcept
A::template function_type< R > * f
std::reference_wrapper< typename std::decay< T >::type > type
typename std::decay< T >::type type