From 400e5bd8ad2b2daef411e5530b6fda6158672829 Mon Sep 17 00:00:00 2001 From: Tyge Løvset Date: Mon, 27 Feb 2023 16:37:13 +0100 Subject: Enhanced c_with and c_scope macros. Improved coroutine.h and example. --- include/stc/algo/coroutine.h | 22 ++++++++++++++++------ include/stc/ccommon.h | 10 ++++++---- 2 files changed, 22 insertions(+), 10 deletions(-) (limited to 'include/stc') diff --git a/include/stc/algo/coroutine.h b/include/stc/algo/coroutine.h index da15aa5b..150fa9ec 100644 --- a/include/stc/algo/coroutine.h +++ b/include/stc/algo/coroutine.h @@ -60,13 +60,20 @@ int main(void) { */ #include +enum { + cco_state_final = -1, + cco_state_done = -2, + cco_state_illegal = -3, +}; + #define cco_begin(ctx) \ int *_state = &(ctx)->cco_state; \ switch (*_state) { \ - case 0: + case 0: \ + case cco_state_done:; #define cco_end(retval) \ - *_state = 0; break; \ + *_state = cco_state_done; break; \ default: assert(!"missing cco_final: or illegal state"); \ } \ return retval @@ -77,15 +84,18 @@ int main(void) { case __LINE__:; \ } while (0) -#define cco_yield_coroutine(ctx, corocall, retval) \ +#define cco_coroutine(corocall, ctx, retval) \ do { \ *_state = __LINE__; \ c_PASTE(cco, __LINE__): corocall; return retval; \ - case __LINE__:; if (cco_alive(ctx)) goto c_PASTE(cco, __LINE__); \ + case __LINE__: if (cco_alive(ctx)) goto c_PASTE(cco, __LINE__); \ } while (0) -#define cco_final case -1 +#define cco_final case cco_state_final +#define cco_stop(ctx) (((ctx)->cco_state = cco_alive(ctx) ? \ + cco_state_final : cco_state_illegal), ctx) +#define cco_reset(ctx) ((ctx)->cco_state = 0) +#define cco_done(ctx) ((ctx)->cco_state == cco_state_done) #define cco_alive(ctx) ((ctx)->cco_state > 0) -#define cco_stop(ctx) ((ctx)->cco_state = cco_alive(ctx) ? -1 : -2), ctx) #endif diff --git a/include/stc/ccommon.h b/include/stc/ccommon.h index 711a9c6d..d163b4ab 100644 --- a/include/stc/ccommon.h +++ b/include/stc/ccommon.h @@ -209,10 +209,12 @@ STC_INLINE char* cstrnstrn(const char *str, const char *needle, ; it.index < it.size; ++it.ref, ++it.index) #endif #define c_with(...) c_MACRO_OVERLOAD(c_with, __VA_ARGS__) -#define c_with_2(declvar, drop) for (declvar, **_c_i = NULL; !_c_i; ++_c_i, drop) -#define c_with_3(declvar, pred, drop) for (declvar, **_c_i = NULL; !_c_i && (pred); ++_c_i, drop) -#define c_scope(init, drop) for (int _c_i = (init, 1); _c_i; --_c_i, drop) -#define c_defer(...) for (int _c_i = 1; _c_i; --_c_i, __VA_ARGS__) +#define c_with_2(declvar, drop) for (declvar, *_i, **_ip = &_i; _ip; _ip = 0, drop) +#define c_with_3(declvar, pred, drop) for (declvar, *_i, **_ip = &_i; _ip && (pred); _ip = 0, drop) +#define c_scope(...) c_MACRO_OVERLOAD(c_scope, __VA_ARGS__) +#define c_scope_2(init, drop) for (int _i = (init, 1); _i; _i = 0, drop) +#define c_scope_3(init, pred, drop) for (int _i = (init, 1); _i && (pred); _i = 0, drop) +#define c_defer(...) for (int _i = 1; _i; _i = 0, __VA_ARGS__) #define c_auto(...) c_MACRO_OVERLOAD(c_auto, __VA_ARGS__) #define c_auto_2(C, a) \ -- cgit v1.2.3