37 #ifdef ZTH_STACK_SWITCH
38 EXTERN_C ZTH_EXPORT
void*
39 zth_stack_switch(
void* stack,
size_t size,
void* (*f)(
void*) noexcept,
void* arg) noexcept;
41 # define zth_stack_switch(stack, size, f, arg) \
52 # if __cplusplus >= 201103L
56 # if __cplusplus < 201103L
57 # undef ZTH_STACK_SWITCH98
59 # define ZTH_STACK_SWITCH98 1
60 # elif !defined(ZTH_STACK_SWITCH98)
63 # define ZTH_STACK_SWITCH98 0
101 # if ZTH_STACK_SWITCH98
102 template <
typename R>
119 struct FunctionIO0<void> {
133 template <
typename R,
typename A1>
150 template <
typename A1>
151 struct FunctionIO1<void, A1> {
166 template <
typename R,
typename A1,
typename A2>
184 template <
typename A1,
typename A2>
185 struct FunctionIO2<void, A1, A2> {
201 template <
typename R,
typename A1,
typename A2,
typename A3>
219 template <
typename A1,
typename A2,
typename A3>
220 struct FunctionIO3<void, A1, A2, A3> {
223 void (*f)(A1, A2, A3);
237 # elif __cplusplus >= 201103L
239 template <
typename T>
241 using type =
typename std::decay<T>::type;
244 template <
typename T>
246 using type = std::reference_wrapper<typename std::decay<T>::type>;
249 template <
typename... A>
251 template <
typename R>
254 constexpr
static size_t size =
sizeof...(A);
257 template <
typename R,
typename A,
typename A_>
261 typename A::template function_type<R>*
f;
262 typename A_::tuple_type
a;
269 call(
typename SequenceGenerator<A::size>::type(), A());
274 template <
size_t... S,
typename... _A>
277 r = f(std::forward<_A>(std::get<S>(a))...);
281 template <
typename A,
typename A_>
285 typename A::template function_type<void>*
f;
286 typename A_::tuple_type
a;
292 call(
typename SequenceGenerator<A::size>::type(), A());
297 template <
size_t... S,
typename... _A>
300 f(std::forward<_A>(std::get<S>(a))...);
305 template <
typename F>
308 return (*
static_cast<F*
>(f))();
313 # if ZTH_STACK_SWITCH98
317 template <
typename R>
318 inline R
stack_switch(
void* stack,
size_t size, R (*f)())
320 impl::FunctionIO0<R> f_ = {{f}};
321 return *
static_cast<R*
>(
330 inline void stack_switch(
void* stack,
size_t size,
void (*f)())
332 impl::FunctionIO0<void> f_ = {{f}};
340 template <
typename R,
typename A1>
341 inline R
stack_switch(
void* stack,
size_t size, R (*f)(A1), A1 a1)
343 impl::FunctionIO1<R, A1> f_ = {{f, a1}};
344 return *
static_cast<R*
>(
352 template <
typename A1>
353 inline void stack_switch(
void* stack,
size_t size,
void (*f)(A1), A1 a1)
355 impl::FunctionIO1<void, A1> f_ = {{f, a1}};
363 template <
typename R,
typename A1,
typename A2>
364 inline R
stack_switch(
void* stack,
size_t size, R (*f)(A1, A2), A1 a1, A2 a2)
366 impl::FunctionIO2<R, A1, A2> f_ = {{f, a1, a2}};
367 return *
static_cast<R*
>(
375 template <
typename A1,
typename A2>
376 inline void stack_switch(
void* stack,
size_t size,
void (*f)(A1, A2), A1 a1, A2 a2)
378 impl::FunctionIO2<void, A1, A2> f_ = {{f, a1, a2}};
386 template <
typename R,
typename A1,
typename A2,
typename A3>
387 inline R
stack_switch(
void* stack,
size_t size, R (*f)(A1, A2, A3), A1 a1, A2 a2, A3 a3)
389 impl::FunctionIO3<R, A1, A2, A3> f_ = {{f, a1, a2, a3}};
390 return *
static_cast<R*
>(
398 template <
typename A1,
typename A2,
typename A3>
399 inline void stack_switch(
void* stack,
size_t size,
void (*f)(A1, A2, A3), A1 a1, A2 a2, A3 a3)
401 impl::FunctionIO3<void, A1, A2, A3> f_ = {{f, a1, a2, a3}};
405 # elif __cplusplus >= 201103L
412 template <
typename R,
typename... A,
typename... A_>
413 inline typename std::enable_if<!std::is_void<R>::value, R>::type
414 stack_switch(
void* stack,
size_t size, R (*f)(A...) noexcept, A_&&... a) noexcept
417 {f, {std::forward<A_>(a)...}}};
427 template <
typename... A,
typename... A_>
428 inline void stack_switch(
void* stack,
size_t size,
void (*f)(A...) noexcept, A_&&... a) noexcept
431 {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.
size_t stack_watermark_remaining(void *stack) noexcept
Return the remaining stack size that was never touched.
void stack_watermark_init(void *stack, size_t size) noexcept
Initialize the memory region for stack high water marking.
size_t stack_watermark_maxused(void *stack) noexcept
Return the high water mark of the stack.
size_t stack_watermark_size(void *stack) noexcept
Return the size of the given stack region.
void * stack_switch_fwd(void *f) noexcept
void context_switch(Context *from, Context *to) noexcept
Perform context switch.
void context_destroy(Context *context) noexcept
Destroy and cleanup a context.
int context_init() noexcept
One-time context mechanism initialization.
void context_deinit() noexcept
Final cleanup.
int context_create(Context *&context, ContextAttr const &attr) noexcept
Create a context.
size_t context_stack_usage(Context *context) noexcept
Return the high water mark of the stack of the given context.
The configuration of Zth.
constexpr ContextAttr(Entry entry=nullptr, EntryArg arg=EntryArg()) noexcept
std::tuple< typename Packed< A >::type... > tuple_type
A::template function_type< void > * f
void * operator()() noexcept
void * operator()() noexcept
A::template function_type< R > * f
std::reference_wrapper< typename std::decay< T >::type > type
typename std::decay< T >::type type