From ecc0b2108cffeb725e3b8e2574b6fb7927dfd96e Mon Sep 17 00:00:00 2001 From: Tyge Løvset Date: Tue, 7 Mar 2023 22:26:36 +0100 Subject: Improved/simplified c_forfilter (): last optional parameter gone. Now c_flt_take() and c_flt_takewhile() breaks the loop always. c11/fmt.h : renamed fmt_freebuffer(buf) => fmt_destroy(buf). --- include/c11/fmt.h | 18 +++++++++++------ include/stc/algo/crange.h | 2 +- include/stc/algo/filter.h | 50 ++++++++++++++++++++++++++++------------------- include/stc/cspan.h | 2 +- 4 files changed, 44 insertions(+), 28 deletions(-) (limited to 'include') diff --git a/include/c11/fmt.h b/include/c11/fmt.h index 435193f8..a6f7985c 100644 --- a/include/c11/fmt.h +++ b/include/c11/fmt.h @@ -6,14 +6,14 @@ VER 2.0: NEW API: void fmt_print(fmt, ...); void fmt_println(fmt, ...); void fmt_printd(dest, fmt, ...); -void fmt_freebuffer(fmt_buffer* buf); +void fmt_destroy(fmt_buffer* buf); dest - destination, one of: FILE* fp Write to a file char* strbuf Write to a pre-allocated string buffer fmt_buffer* buf Auto realloc the needed memory (safe). Set buf->stream=1 for stream-mode. - Call fmt_freebuffer(buf) after usage. + Call fmt_destroy(buf) after usage. fmt - format string {} Auto-detected format. If :MOD is not specified, @@ -55,7 +55,7 @@ int main() { fmt_print("{}, len={}, cap={}\n", out->data, out->len, out->cap); fmt_printd(out, "{} {}", ", Pi squared is:", pi*pi); fmt_print("{}, len={}, cap={}\n", out->data, out->len, out->cap); - fmt_freebuffer(out); + fmt_destroy(out); } */ #include @@ -91,7 +91,7 @@ typedef struct { _Bool stream; } fmt_buffer; -FMT_API void fmt_freebuffer(fmt_buffer* buf); +FMT_API void fmt_destroy(fmt_buffer* buf); FMT_API int _fmt_parse(char* p, int nargs, const char *fmt, ...); FMT_API void _fmt_bprint(fmt_buffer*, const char* fmt, ...); @@ -99,11 +99,17 @@ FMT_API void _fmt_bprint(fmt_buffer*, const char* fmt, ...); #define FMT_MAX 256 #endif +#ifdef FMT_SHORTS +#define print(...) fmt_printd(stdout, __VA_ARGS__) +#define println(...) fmt_printd((fmt_buffer*)0, __VA_ARGS__) +#define printd fmt_printd +#endif + #define fmt_print(...) fmt_printd(stdout, __VA_ARGS__) #define fmt_println(...) fmt_printd((fmt_buffer*)0, __VA_ARGS__) +#define fmt_printd(...) fmt_OVERLOAD(fmt_printd, __VA_ARGS__) /* Primary function. */ -#define fmt_printd(...) fmt_OVERLOAD(fmt_printd, __VA_ARGS__) #define fmt_printd2(to, fmt) \ do { char _fs[FMT_MAX]; int _n = _fmt_parse(_fs, 0, fmt); \ fmt_OK(_n == 0); _fmt_fn(to)(to, fmt); } while (0) @@ -189,7 +195,7 @@ FMT_API void _fmt_bprint(fmt_buffer*, const char* fmt, ...); #include #include -FMT_API void fmt_freebuffer(fmt_buffer* buf) { +FMT_API void fmt_destroy(fmt_buffer* buf) { free(buf->data); } diff --git a/include/stc/algo/crange.h b/include/stc/algo/crange.h index 1b840516..4fc957b6 100644 --- a/include/stc/algo/crange.h +++ b/include/stc/algo/crange.h @@ -36,7 +36,7 @@ int main() int a = 100, b = INT32_MAX; c_forfilter (i, crange, crange_obj(a, b, 8) , i.index > 10 - , c_flt_take(i, 3)) + && c_flt_take(i, 3)) printf(" %lld", *i.ref); puts(""); } diff --git a/include/stc/algo/filter.h b/include/stc/algo/filter.h index 6f8e1654..48a36d9b 100644 --- a/include/stc/algo/filter.h +++ b/include/stc/algo/filter.h @@ -36,9 +36,9 @@ int main() puts(""); c_forfilter (i, cstack_int, stk - , c_flt_skipwhile(i, *i.ref < 3) - && (*i.ref & 1) == 0 // even only - , c_flt_take(i, 2)) // break after 2 + , c_flt_skipwhile(i, *i.ref < 3) + && (*i.ref & 1) == 0 // even only + && c_flt_take(i, 2)) // break after 2 printf(" %d", *i.ref); puts(""); } @@ -53,27 +53,37 @@ int main() #define c_NFILTERS 32 #endif -#define c_flt_take(i, n) (c_flt_count(i) <= (n)) +#define c_flt_take(i, n) _flt_take(&(i).b, n) #define c_flt_skip(i, n) (c_flt_count(i) > (n)) -#define c_flt_skipwhile(i, pred) ((i).s2[(i).s2top++] |= !(pred)) -#define c_flt_takewhile(i, pred) !c_flt_skipwhile(i, pred) -#define c_flt_last(i) (i).s1[(i).s1top-1] -#define c_flt_count(i) ++(i).s1[(i).s1top++] +#define c_flt_skipwhile(i, pred) ((i).b.s2[(i).b.s2top++] |= !(pred)) +#define c_flt_takewhile(i, pred) _flt_takewhile(&(i).b, pred) +#define c_flt_last(i) (i).b.s1[(i).b.s1top-1] +#define c_flt_count(i) ++(i).b.s1[(i).b.s1top++] -#define c_forfilter(...) c_MACRO_OVERLOAD(c_forfilter, __VA_ARGS__) +#define c_forfilter(i, C, cnt, filter) \ + for (struct {struct _flt_base b; C##_iter it; C##_value *ref;} \ + i = {.it=C##_begin(&cnt), .ref=i.it.ref} ; !i.b.done & (i.ref != NULL) ; \ + C##_next(&i.it), i.ref = i.it.ref, i.b.s1top=0, i.b.s2top=0) \ + if (!(filter)) ; else -#define c_forfilter_4(i, C, cnt, filter) \ - c_forfilter_B(i, C, C##_begin(&cnt), filter) +// ----- -#define c_forfilter_5(i, C, cnt, filter, cond) \ - c_forfilter_B(i, C, C##_begin(&cnt), filter) if (!(cond)) break; else +struct _flt_base { + uint32_t s1[c_NFILTERS]; + bool s2[c_NFILTERS], done; + uint8_t s1top, s2top; +}; -#define c_forfilter_B(i, C, start, filter) \ - for (struct {C##_iter it; C##_value *ref; \ - uint32_t s1[c_NFILTERS], index; \ - bool s2[c_NFILTERS]; uint8_t s1top, s2top;} \ - i = {.it=start, .ref=i.it.ref}; i.it.ref \ - ; C##_next(&i.it), i.ref = i.it.ref, ++i.index, i.s1top=0, i.s2top=0) \ - if (!(filter)) ; else +static inline bool _flt_take(struct _flt_base* b, uint32_t n) { + uint32_t k = ++b->s1[b->s1top++]; + b->done |= (k >= n); + return k <= n; +} + +static inline bool _flt_takewhile(struct _flt_base* b, bool pred) { + bool skip = (b->s2[b->s2top++] |= !pred); + b->done |= skip; + return !skip; +} #endif diff --git a/include/stc/cspan.h b/include/stc/cspan.h index c6df51af..00313540 100644 --- a/include/stc/cspan.h +++ b/include/stc/cspan.h @@ -50,7 +50,7 @@ int demo2() { c_forfilter (i, Intspan, span, , c_flt_skipwhile(i, *i.ref < 25) && (*i.ref & 1) == 0 // even only - , c_flt_take(i, 2)) // break after 2 + && c_flt_take(i, 2)) // break after 2 printf(" %d", *i.ref); puts(""); } -- cgit v1.2.3