diff options
| -rw-r--r-- | docs/ccommon_api.md | 18 | ||||
| -rw-r--r-- | examples/forloops.c | 80 | ||||
| -rw-r--r-- | examples/prime.c | 16 | ||||
| -rw-r--r-- | include/stc/ccommon.h | 4 |
4 files changed, 100 insertions, 18 deletions
diff --git a/docs/ccommon_api.md b/docs/ccommon_api.md index 1b364e58..39200907 100644 --- a/docs/ccommon_api.md +++ b/docs/ccommon_api.md @@ -139,7 +139,7 @@ from a `c_auto` scope: ... } // for ``` -## Loop abstaction macros +## Loop abstraction macros ### c_forlist Iterate compound literal array elements. Additional to `i.ref`, you can access `i.data`, `i.size`, and `i.index` of the input list/element. @@ -193,7 +193,7 @@ c_forpair (id, count, csmap_ii, map) ``` ### c_forloop -Abstaction for iterating sequence of numbers. Like python's **for** *i* **in** *range()* loop. +Abstraction for iterating sequence of numbers. Like python's **for** *i* **in** *range()* loop. | Usage | Python equivalent | |:--------------------------------------------|:-------------------------------------| @@ -229,7 +229,7 @@ Iterate containers with stop-criteria and chained range filtering. | `c_flt_dropwhile(it, predicate)` | Drop items until predicate is false | | `c_flt_takewhile(it, predicate)` | Take items until predicate is false | -`it.index` holds the index of the source item. +`it.index` holds the index of the source item, and `it.count` the current number of items taken. ```c #define i_type IVec #define i_val int @@ -275,16 +275,16 @@ void crange_next(crange_iter* it); // 1. All primes less than 32: crange r1 = crange_from(3, 32, 2); printf("2"); // first prime -c_forfilter (i, crange, r1, - isPrime(*i.ref)) +c_forfilter (i, crange, r1 + , isPrime(*i.ref)) printf(" %lld", *i.ref); // 2 3 5 7 11 13 17 19 23 29 31 // 2. The 11 first primes: crange r2 = crange_make(3, INTMAX_MAX, 2); printf("2"); -c_forfilter (i, crange, r2, - isPrime(*i.ref) +c_forfilter (i, crange, r2 + , isPrime(*i.ref) , c_flt_take(10)) printf(" %lld", *i.ref); // 2 3 5 7 11 13 17 19 23 29 31 @@ -313,7 +313,7 @@ c_erase_if(k, cvec_i, *k.ref < 100); | `c_new (type, value)` | Move value to a new object on the heap | | `c_alloc (type)` | `(type *) c_malloc(sizeof(type))` | | `c_alloc_n (type, N)` | `(type *) c_malloc((N)*sizeof(type))` | -| `c_drop (ctype, &c1, ..., &cN)` | `ctype_drop(&c1); ... ctype_drop(&cN)` | +| `c_drop (ctype, &c1, ..., &cN)` | `ctype_drop(&c1); ... ctype_drop(&cN)` | | `c_make(type){value...}` | `(type){value...}` // c++ compatability | ```c @@ -329,7 +329,7 @@ c_drop(cstr, &a, &b); ``` ### General predefined template parameter functions -``` +```c int c_default_cmp(const Type*, const Type*); Type c_default_clone(Type val); // simple copy Type c_default_toraw(const Type* val); // dereference val diff --git a/examples/forloops.c b/examples/forloops.c new file mode 100644 index 00000000..f119e33a --- /dev/null +++ b/examples/forloops.c @@ -0,0 +1,80 @@ +#include <stdio.h>
+
+#define i_type IVec
+#define i_val int
+#include <stc/cstack.h>
+
+#define i_type IMap
+#define i_key int
+#define i_val int
+#include <stc/cmap.h>
+
+
+int main()
+{
+ puts("c_forloop:");
+ c_forloop (30) printf(" xx");
+ puts("");
+
+ c_forloop (i, 30) printf(" %lld", i);
+ puts("");
+
+ c_forloop (i, 30, 60) printf(" %lld", i);
+ puts("");
+
+ c_forloop (i, 30, 90, 2) printf(" %lld", i);
+
+
+ puts("\n\nc_forlist:");
+ c_forlist (i, int, {12, 23, 453, 65, 676})
+ printf(" %d", *i.ref);
+ puts("");
+
+ c_forlist (i, const char*, {"12", "23", "453", "65", "676"})
+ printf(" %s", *i.ref);
+ puts("");
+
+ c_forlist (i, const char*, {"12", "23", "453", "65", "676"})
+ printf(" %s", i.data[i.size - 1 - i.index]);
+
+
+ c_auto (IVec, vec)
+ c_auto (IMap, map)
+ {
+ c_forlist (i, int, {12, 23, 453, 65, 113, 215, 676, 34, 67, 20, 27, 66, 189, 45, 280, 199})
+ IVec_push(&vec, *i.ref);
+
+ c_forlist (i, IMap_value, {{12, 23}, {453, 65}, {676, 123}, {34, 67}})
+ IMap_push(&map, *i.ref);
+
+ puts("\n\nc_foreach:");
+ c_foreach (i, IVec, vec)
+ printf(" %d", *i.ref);
+ puts("");
+
+ c_foreach (i, IMap, map)
+ printf(" (%d %d)", i.ref->first, i.ref->second);
+
+ puts("\n\nc_forpair:");
+ c_forpair (key, val, IMap, map)
+ printf(" (%d %d)", *_.key, *_.val);
+
+ puts("\n\nc_forwhile:");
+ c_forwhile (i, IVec, vec, i.index < 3)
+ printf(" %d", *i.ref);
+
+ #define isOdd(i) (*i.ref & 1)
+
+ puts("\n\nc_forfilter:");
+ c_forfilter (i, IVec, vec,
+ c_flt_dropwhile(i, *i.ref != 65)
+ && c_flt_takewhile(i, *i.ref != 280)
+ && c_flt_dropwhile(i, isOdd(i))
+ && isOdd(i)
+ && c_flt_drop(i, 2)
+ , c_flt_take(i, 1))
+ printf(" %d", *i.ref);
+ puts("");
+ // 189
+ }
+}
diff --git a/examples/prime.c b/examples/prime.c index 12d33a9e..613048bf 100644 --- a/examples/prime.c +++ b/examples/prime.c @@ -33,16 +33,18 @@ int main(void) clock_t t2 = clock(); printf("number of primes: %" PRIuMAX ", time: %f\n", np, (t2 - t1) / (float)CLOCKS_PER_SEC); + puts("Show all the primes in the range [2, 1000):"); printf("2"); - for (size_t i = 3; i < 1000; i += 2) - if (cbits_test(&primes, i>>1)) printf(" %" PRIuMAX "", i); + c_forloop (i, 3, 1000, 2) + if (cbits_test(&primes, i>>1)) printf(" %lld", i); puts(""); - int k = 20; - c_forloop (i, n-1, 1, -2) { - if (k == 0) break; - else if (cbits_test(&primes, i>>1)) printf("%lld\n", i), k--; + puts("Show the last 50 primes using a temporary crange generator:"); + c_forfilter (i, crange, *(crange[]){crange_make(n - 1, 0, -2)} + , cbits_test(&primes, *i.ref>>1) + , c_flt_take(i, 50)) { + printf("%lld ", *i.ref); + if (i.count % 10 == 0) puts(""); } - puts(""); } } diff --git a/include/stc/ccommon.h b/include/stc/ccommon.h index 2edab5bc..1961833b 100644 --- a/include/stc/ccommon.h +++ b/include/stc/ccommon.h @@ -176,11 +176,11 @@ STC_INLINE char* c_strnstrn(const char *s, const char *needle, #define c_forfilter5(it, C, cnt, filter, whilepred) \ c_forfilter_s(it, C, C##_begin(&cnt), filter) if (!(whilepred)) break; else #define c_forfilter_s(it, C, start, filter) \ - c_foreach_s(it, C, start) if (!(filter)) ; else + c_foreach_s(it, C, start) if (!((filter) && ++it.count)) ; else #define c_foreach_s(i, C, start) \ for (struct {C##_iter it; C##_value *ref; \ - uint32_t s1[c_FLT_STACK+1], index; \ + uint32_t s1[c_FLT_STACK], index, count; \ uint8_t s2[c_FLT_STACK], 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) |
