summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorTyge Løvset <[email protected]>2022-09-23 21:00:48 +0200
committerTyge Løvset <[email protected]>2022-09-23 21:00:48 +0200
commitb6f75794b2fee2d65f886e84c399d1b8927ff04a (patch)
tree553643b1a90ee86f1198c33dc80fb52c770c5184
parent2c83996f1ad7ac7176833d1ecb76f59120bf52cd (diff)
downloadSTC-modified-b6f75794b2fee2d65f886e84c399d1b8927ff04a.tar.gz
STC-modified-b6f75794b2fee2d65f886e84c399d1b8927ff04a.zip
- Finished c_forfilter() functionality.
- Added c_forloop(), similar to c_forrange(), but same access to elements as other c_for-loops, i.e. *i.ref (but also i.val works).
-rw-r--r--examples/forfilter.c13
-rw-r--r--include/stc/ccommon.h28
2 files changed, 31 insertions, 10 deletions
diff --git a/examples/forfilter.c b/examples/forfilter.c
index 409d83e3..955596cd 100644
--- a/examples/forfilter.c
+++ b/examples/forfilter.c
@@ -12,9 +12,7 @@
#include <stc/cstack.h>
// filters and transforms:
-#define flt_drop(i, n) (i.index >= (n))
#define flt_remove(i, x) (*i.ref != (x))
-#define flt_take(i, n) (i.count < (n))
#define flt_even(i) ((*i.ref & 1) == 0)
#define trf_square(i) (*i.ref * *i.ref)
@@ -24,15 +22,16 @@ void demo1(void)
c_forlist (i, int, {0, 1, 2, 3, 4, 5, 80, 6, 7, 80, 8, 9, 80, 10, 11, 12, 13, 14, 15, 80, 16, 17})
IVec_push(&vec, *i.ref);
- c_forfilter (i, IVec, vec, *i.ref != 80)
+ c_forfilter (i, IVec, vec, flt_remove(i, 80))
printf(" %d", *i.ref);
puts("");
int res, sum = 0;
- c_forfilter (i, IVec, vec, flt_drop(i, 3)
- && flt_even(i)
- && flt_remove(i, 80)
- , flt_take(i, 5)) {
+ c_forfilter (i, IVec, vec, c_flt_drop(i, 3)
+ && flt_even(i)
+ && flt_remove(i, 80)
+ //&& c_flt_take(i, 5)
+ , c_flt_taketotal(i, 5)) {
sum += res = trf_square(i);
printf(" %d", res);
}
diff --git a/include/stc/ccommon.h b/include/stc/ccommon.h
index 08445dae..c368fdf9 100644
--- a/include/stc/ccommon.h
+++ b/include/stc/ccommon.h
@@ -170,20 +170,29 @@ STC_INLINE char* c_strnstrn(const char *s, const char *needle,
for (C##_iter it = start, *_endref = (C##_iter*)(finish).ref \
; it.ref != (C##_value*)_endref; C##_next(&it))
+#define c_FLT_STACK 5
+
+#define c_flt_drop(i, n) (++(i).dropped[(i).dn++] > (n))
+#define c_flt_dropwhile(i, pred) ((i).dropwhile |= !(pred))
+#define c_flt_take(i, n) (++(i).taken[(i).tn++] <= (n))
+#define c_flt_taketotal(i, n) ((i).total < (n))
+
#define c_forfilter(...) c_MACRO_OVERLOAD(c_forfilter, __VA_ARGS__)
#define c_forfilter4(it, C, cnt, filter) \
c_forfilter5(it, C, cnt, filter, true)
#define c_forfilter5(it, C, cnt, filter, cond) \
c_forfilter_s(it, C, C##_begin(&cnt), filter, cond)
#define c_forfilter_s(it, C, start, filter, cond) \
- c_forwhile_s(it, C, start, cond) if (!((filter) && ++it.count)) ; else
+ c_forwhile_s(it, C, start, cond) if (!((filter) && ++it.total)) ; else
#define c_forwhile(i, C, cnt, cond) \
c_forwhile_s(i, C, C##_begin(&cnt), cond)
#define c_forwhile_s(i, C, start, cond) \
- for (struct {C##_iter it; const C##_value *ref; size_t index, count;} \
+ for (struct {C##_iter it; const C##_value *ref; \
+ uint32_t index, total, taken[c_FLT_STACK], dropped[c_FLT_STACK]; \
+ int8_t dn, tn; bool dropwhile;} \
i = {.it=start, .ref=i.it.ref}; i.ref && (cond) \
- ; C##_next(&i.it), i.ref = i.it.ref, ++i.index)
+ ; C##_next(&i.it), i.ref = i.it.ref, ++i.index, i.dn=0, i.tn=0)
#define c_forpair(key, val, C, cnt) /* structured binding */ \
for (struct {C##_iter _it; const C##_key* key; C##_mapped* val;} _ = {C##_begin(&cnt)} \
@@ -200,6 +209,19 @@ STC_INLINE char* c_strnstrn(const char *s, const char *needle,
for (itype i=start, _inc=step, _end=(stop) - (0 < _inc) \
; (i <= _end) == (0 < _inc); i += _inc)
+#define c_forloop(...) c_MACRO_OVERLOAD(c_forloop, __VA_ARGS__)
+#define c_forloop1(stop) c_forloop4(_c_i, size_t, 0, stop)
+#define c_forloop2(i, stop) c_forloop4(i, size_t, 0, stop)
+#define c_forloop3(i, itype, stop) c_forloop4(i, itype, 0, stop)
+#define c_forloop4(i, itype, start, stop) \
+ for (struct {itype val, _end, *ref;} \
+ i = {.val=start, ._end=stop, .ref=&i.val} \
+ ; i.val < i._end; ++i.val)
+#define c_forloop5(i, itype, start, stop, step) \
+ for (struct {itype val, _inc, _end, *ref;} \
+ i = {.val=start, ._inc=step, ._end=(stop) - (0 < i._inc), .ref=&i.val} \
+ ; (i.val > i._end) ^ (i._inc > 0); i.val += i._inc)
+
#define c_forlist(it, T, ...) \
for (struct {T* data; T* ref; size_t index;} \
it = {.data=(T[])__VA_ARGS__, .ref=it.data} \