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
85void context_deinit() noexcept;
88void context_destroy(
Context* context) noexcept;
89size_t context_stack_usage(
Context* context) noexcept;
91void stack_watermark_init(
void* stack,
size_t size) noexcept;
92size_t stack_watermark_size(
void* stack) noexcept;
93size_t stack_watermark_maxused(
void* stack) noexcept;
94size_t stack_watermark_remaining(
void* stack) noexcept;
100# if ZTH_STACK_SWITCH98
118struct FunctionIO0<void> {
132template <
typename R,
typename A1>
149template <
typename A1>
150struct FunctionIO1<void, A1> {
165template <
typename R,
typename A1,
typename A2>
183template <
typename A1,
typename A2>
184struct FunctionIO2<void, A1, A2> {
200template <
typename R,
typename A1,
typename A2,
typename A3>
218template <
typename A1,
typename A2,
typename A3>
219struct FunctionIO3<void, A1, A2, A3> {
222 void (*f)(A1, A2, A3);
236# elif __cplusplus >= 201103L
240 using type =
typename std::decay<T>::type;
245 using type = std::reference_wrapper<typename std::decay<T>::type>;
248template <
typename... A>
250 template <
typename R>
253 constexpr static size_t size =
sizeof...(A);
256template <
typename R,
typename A,
typename A_>
260 typename A::template function_type<R>*
f;
261 typename A_::tuple_type
a;
268 call(
typename SequenceGenerator<A::size>::type(), A());
273 template <
size_t... S,
typename... _A>
276 r = f(std::forward<_A>(std::get<S>(a))...);
280template <
typename A,
typename A_>
284 typename A::template function_type<void>*
f;
285 typename A_::tuple_type
a;
291 call(
typename SequenceGenerator<A::size>::type(), A());
296 template <
size_t... S,
typename... _A>
299 f(std::forward<_A>(std::get<S>(a))...);
307 return (*
static_cast<F*
>(f))();
312# if ZTH_STACK_SWITCH98
317inline R stack_switch(
void* stack,
size_t size, R (*f)())
319 impl::FunctionIO0<R> f_ = {{f}};
320 return *
static_cast<R*
>(
329inline void stack_switch(
void* stack,
size_t size,
void (*f)())
331 impl::FunctionIO0<void> f_ = {{f}};
339template <
typename R,
typename A1>
340inline R
stack_switch(
void* stack,
size_t size, R (*f)(A1), A1 a1)
342 impl::FunctionIO1<R, A1> f_ = {{f, a1}};
343 return *
static_cast<R*
>(
351template <
typename A1>
352inline void stack_switch(
void* stack,
size_t size,
void (*f)(A1), A1 a1)
354 impl::FunctionIO1<void, A1> f_ = {{f, a1}};
362template <
typename R,
typename A1,
typename A2>
363inline R
stack_switch(
void* stack,
size_t size, R (*f)(A1, A2), A1 a1, A2 a2)
365 impl::FunctionIO2<R, A1, A2> f_ = {{f, a1, a2}};
366 return *
static_cast<R*
>(
374template <
typename A1,
typename A2>
375inline void stack_switch(
void* stack,
size_t size,
void (*f)(A1, A2), A1 a1, A2 a2)
377 impl::FunctionIO2<void, A1, A2> f_ = {{f, a1, a2}};
385template <
typename R,
typename A1,
typename A2,
typename A3>
386inline R
stack_switch(
void* stack,
size_t size, R (*f)(A1, A2, A3), A1 a1, A2 a2, A3 a3)
388 impl::FunctionIO3<R, A1, A2, A3> f_ = {{f, a1, a2, a3}};
389 return *
static_cast<R*
>(
397template <
typename A1,
typename A2,
typename A3>
398inline void stack_switch(
void* stack,
size_t size,
void (*f)(A1, A2, A3), A1 a1, A2 a2, A3 a3)
400 impl::FunctionIO3<void, A1, A2, A3> f_ = {{f, a1, a2, a3}};
404# elif __cplusplus >= 201103L
411template <
typename R,
typename... A,
typename... A_>
412inline typename std::enable_if<!std::is_void<R>::value, R>::type
413stack_switch(
void* stack,
size_t size, R (*f)(A...)
noexcept, A_&&... a)
noexcept
416 {f, {std::forward<A_>(a)...}}};
418 zth_stack_switch(stack, size, &impl::stack_switch_fwd<
decltype(f_)>, &f_)));
426template <
typename... A,
typename... A_>
427inline void stack_switch(
void* stack,
size_t size,
void (*f)(A...)
noexcept, A_&&... a)
noexcept
430 {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.
The configuration of Zth.
constexpr ContextAttr(Entry entry_=nullptr, EntryArg arg_=EntryArg()) 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