diff options
| author | _Tradam <[email protected]> | 2023-09-08 01:29:47 +0000 |
|---|---|---|
| committer | GitHub <[email protected]> | 2023-09-08 01:29:47 +0000 |
| commit | 3c76c7f3d5db3f9586a90d03f8fbb02d79de9acd (patch) | |
| tree | afbe4b540967223911f7c5de36559b82154f02f3 /misc/examples | |
| parent | 0841165881871ee01b782129be681209aeed2423 (diff) | |
| parent | 1a72205fe05c2375cfd380dd8381a8460d9ed8d1 (diff) | |
| download | STC-modified-3c76c7f3d5db3f9586a90d03f8fbb02d79de9acd.tar.gz STC-modified-3c76c7f3d5db3f9586a90d03f8fbb02d79de9acd.zip | |
Diffstat (limited to 'misc/examples')
| -rw-r--r-- | misc/examples/algorithms/forfilter.c (renamed from misc/examples/forfilter.c) | 17 | ||||
| -rw-r--r-- | misc/examples/algorithms/forloops.c (renamed from misc/examples/forloops.c) | 134 | ||||
| -rw-r--r-- | misc/examples/algorithms/random.c | 42 | ||||
| -rw-r--r-- | misc/examples/algorithms/shape.c (renamed from misc/examples/shape.c) | 16 | ||||
| -rw-r--r-- | misc/examples/algorithms/shape.cpp (renamed from misc/examples/shape.cpp) | 0 | ||||
| -rw-r--r-- | misc/examples/bitsets/bits.c (renamed from misc/examples/bits.c) | 12 | ||||
| -rw-r--r-- | misc/examples/bitsets/bits2.c (renamed from misc/examples/bits2.c) | 6 | ||||
| -rw-r--r-- | misc/examples/bitsets/prime.c (renamed from misc/examples/prime.c) | 32 | ||||
| -rw-r--r-- | misc/examples/coread.c | 39 | ||||
| -rw-r--r-- | misc/examples/coroutines.c | 106 | ||||
| -rw-r--r-- | misc/examples/coroutines/cointerleave.c | 62 | ||||
| -rw-r--r-- | misc/examples/coroutines/coread.c | 41 | ||||
| -rw-r--r-- | misc/examples/coroutines/coroutines.c | 112 | ||||
| -rw-r--r-- | misc/examples/coroutines/cotasks1.c | 100 | ||||
| -rw-r--r-- | misc/examples/coroutines/cotasks2.c | 98 | ||||
| -rw-r--r-- | misc/examples/coroutines/dining_philosophers.c | 105 | ||||
| -rw-r--r-- | misc/examples/coroutines/filetask.c | 80 | ||||
| -rw-r--r-- | misc/examples/coroutines/generator.c | 66 | ||||
| -rw-r--r-- | misc/examples/coroutines/scheduler.c | 67 | ||||
| -rw-r--r-- | misc/examples/coroutines/triples.c | 75 | ||||
| -rw-r--r-- | misc/examples/generator.c | 53 | ||||
| -rw-r--r-- | misc/examples/hashmaps/birthday.c (renamed from misc/examples/birthday.c) | 6 | ||||
| -rw-r--r-- | misc/examples/hashmaps/books.c (renamed from misc/examples/books.c) | 3 | ||||
| -rw-r--r-- | misc/examples/hashmaps/hashmap.c (renamed from misc/examples/hashmap.c) | 1 | ||||
| -rw-r--r-- | misc/examples/hashmaps/new_map.c (renamed from misc/examples/new_map.c) | 15 | ||||
| -rw-r--r-- | misc/examples/hashmaps/phonebook.c (renamed from misc/examples/phonebook.c) | 4 | ||||
| -rw-r--r-- | misc/examples/hashmaps/unordered_set.c (renamed from misc/examples/unordered_set.c) | 3 | ||||
| -rw-r--r-- | misc/examples/hashmaps/vikings.c (renamed from misc/examples/vikings.c) | 15 | ||||
| -rw-r--r-- | misc/examples/linkedlists/intrusive.c (renamed from misc/examples/intrusive.c) | 9 | ||||
| -rw-r--r-- | misc/examples/linkedlists/list.c (renamed from misc/examples/list.c) | 13 | ||||
| -rw-r--r-- | misc/examples/linkedlists/list_erase.c (renamed from misc/examples/list_erase.c) | 6 | ||||
| -rw-r--r-- | misc/examples/linkedlists/list_splice.c (renamed from misc/examples/list_splice.c) | 9 | ||||
| -rw-r--r-- | misc/examples/linkedlists/new_list.c | 70 | ||||
| -rwxr-xr-x | misc/examples/make.sh | 37 | ||||
| -rw-r--r-- | misc/examples/mixed/astar.c (renamed from misc/examples/astar.c) | 8 | ||||
| -rw-r--r-- | misc/examples/mixed/complex.c (renamed from misc/examples/complex.c) | 12 | ||||
| -rw-r--r-- | misc/examples/mixed/convert.c (renamed from misc/examples/convert.c) | 10 | ||||
| -rw-r--r-- | misc/examples/mixed/demos.c (renamed from misc/examples/demos.c) | 31 | ||||
| -rw-r--r-- | misc/examples/mixed/inits.c (renamed from misc/examples/inits.c) | 16 | ||||
| -rw-r--r-- | misc/examples/mixed/read.c (renamed from misc/examples/read.c) | 10 | ||||
| -rw-r--r-- | misc/examples/multidim.c | 68 | ||||
| -rw-r--r-- | misc/examples/new_list.c | 68 | ||||
| -rw-r--r-- | misc/examples/printspan.c | 57 | ||||
| -rw-r--r-- | misc/examples/priorityqueues/functor.c (renamed from misc/examples/functor.c) | 39 | ||||
| -rw-r--r-- | misc/examples/priorityqueues/new_pque.c (renamed from misc/examples/new_pque.c) | 8 | ||||
| -rw-r--r-- | misc/examples/priorityqueues/priority.c (renamed from misc/examples/priority.c) | 10 | ||||
| -rw-r--r-- | misc/examples/queues/new_queue.c (renamed from misc/examples/new_queue.c) | 14 | ||||
| -rw-r--r-- | misc/examples/queues/queue.c (renamed from misc/examples/queue.c) | 14 | ||||
| -rw-r--r-- | misc/examples/random.c | 45 | ||||
| -rw-r--r-- | misc/examples/rawptr_elements.c | 59 | ||||
| -rw-r--r-- | misc/examples/regularexpressions/regex1.c (renamed from misc/examples/regex1.c) | 2 | ||||
| -rw-r--r-- | misc/examples/regularexpressions/regex2.c (renamed from misc/examples/regex2.c) | 6 | ||||
| -rw-r--r-- | misc/examples/regularexpressions/regex_match.c (renamed from misc/examples/regex_match.c) | 13 | ||||
| -rw-r--r-- | misc/examples/regularexpressions/regex_replace.c (renamed from misc/examples/regex_replace.c) | 8 | ||||
| -rw-r--r-- | misc/examples/sidebyside.cpp | 57 | ||||
| -rw-r--r-- | misc/examples/smartpointers/arc_containers.c (renamed from misc/examples/arc_containers.c) | 16 | ||||
| -rw-r--r-- | misc/examples/smartpointers/arc_demo.c (renamed from misc/examples/arc_demo.c) | 23 | ||||
| -rw-r--r-- | misc/examples/smartpointers/arcvec_erase.c (renamed from misc/examples/arcvec_erase.c) | 16 | ||||
| -rw-r--r-- | misc/examples/smartpointers/box.c (renamed from misc/examples/box.c) | 10 | ||||
| -rw-r--r-- | misc/examples/smartpointers/box2.c (renamed from misc/examples/box2.c) | 15 | ||||
| -rw-r--r-- | misc/examples/smartpointers/map_box.c | 34 | ||||
| -rw-r--r-- | misc/examples/smartpointers/map_ptr.c | 34 | ||||
| -rw-r--r-- | misc/examples/smartpointers/music_arc.c (renamed from misc/examples/music_arc.c) | 31 | ||||
| -rw-r--r-- | misc/examples/smartpointers/new_sptr.c (renamed from misc/examples/new_sptr.c) | 19 | ||||
| -rw-r--r-- | misc/examples/smartpointers/person_arc.c (renamed from misc/examples/person_arc.c) | 13 | ||||
| -rw-r--r-- | misc/examples/sortedmaps/csmap_erase.c (renamed from misc/examples/csmap_erase.c) | 5 | ||||
| -rw-r--r-- | misc/examples/sortedmaps/csmap_find.c (renamed from misc/examples/csmap_find.c) | 20 | ||||
| -rw-r--r-- | misc/examples/sortedmaps/csmap_insert.c (renamed from misc/examples/csmap_insert.c) | 20 | ||||
| -rw-r--r-- | misc/examples/sortedmaps/csset_erase.c (renamed from misc/examples/csset_erase.c) | 6 | ||||
| -rw-r--r-- | misc/examples/sortedmaps/gauss2.c (renamed from misc/examples/gauss2.c) | 11 | ||||
| -rw-r--r-- | misc/examples/sortedmaps/listmap.c (renamed from misc/examples/mmap.c) | 5 | ||||
| -rw-r--r-- | misc/examples/sortedmaps/mapmap.c (renamed from misc/examples/mapmap.c) | 2 | ||||
| -rw-r--r-- | misc/examples/sortedmaps/multimap.c (renamed from misc/examples/multimap.c) | 6 | ||||
| -rw-r--r-- | misc/examples/sortedmaps/new_smap.c (renamed from misc/examples/new_smap.c) | 9 | ||||
| -rw-r--r-- | misc/examples/sortedmaps/sorted_map.c (renamed from misc/examples/sorted_map.c) | 4 | ||||
| -rw-r--r-- | misc/examples/spans/matmult.c | 90 | ||||
| -rw-r--r-- | misc/examples/spans/mdspan.c | 51 | ||||
| -rw-r--r-- | misc/examples/spans/multidim.c | 76 | ||||
| -rw-r--r-- | misc/examples/spans/printspan.c | 41 | ||||
| -rw-r--r-- | misc/examples/spans/submdspan.c | 44 | ||||
| -rw-r--r-- | misc/examples/strings/cstr_match.c (renamed from misc/examples/cstr_match.c) | 5 | ||||
| -rw-r--r-- | misc/examples/strings/replace.c (renamed from misc/examples/replace.c) | 3 | ||||
| -rw-r--r-- | misc/examples/strings/splitstr.c (renamed from misc/examples/splitstr.c) | 5 | ||||
| -rw-r--r-- | misc/examples/strings/sso_map.c (renamed from misc/examples/sso_map.c) | 3 | ||||
| -rw-r--r-- | misc/examples/strings/sso_substr.c (renamed from misc/examples/sso_substr.c) | 12 | ||||
| -rw-r--r-- | misc/examples/strings/sview_split.c (renamed from misc/examples/sview_split.c) | 4 | ||||
| -rw-r--r-- | misc/examples/strings/utf8replace_c.c (renamed from misc/examples/utf8replace_c.c) | 5 | ||||
| -rw-r--r-- | misc/examples/strings/utf8replace_rs.rs (renamed from misc/examples/utf8replace_rs.rs) | 0 | ||||
| -rw-r--r-- | misc/examples/triples.c | 69 | ||||
| -rw-r--r-- | misc/examples/vectors/lower_bound.c (renamed from misc/examples/lower_bound.c) | 11 | ||||
| -rw-r--r-- | misc/examples/vectors/new_vec.c (renamed from misc/examples/new_vec.c) | 23 | ||||
| -rw-r--r-- | misc/examples/vectors/stack.c (renamed from misc/examples/stack.c) | 6 |
92 files changed, 1730 insertions, 1026 deletions
diff --git a/misc/examples/forfilter.c b/misc/examples/algorithms/forfilter.c index fbb7280f..c1426045 100644 --- a/misc/examples/forfilter.c +++ b/misc/examples/algorithms/forfilter.c @@ -1,12 +1,12 @@ #include <stdio.h> -#define i_extern +#define i_import #include <stc/cstr.h> +#define i_implement #include <stc/csview.h> -#include <stc/algo/filter.h> -#include <stc/algo/crange.h> +#include <stc/algorithm.h> #define i_type IVec -#define i_val int +#define i_key int #include <stc/cstack.h> // filters and transforms: @@ -17,7 +17,7 @@ void demo1(void) { - IVec vec = c_make(IVec, {0, 1, 2, 3, 4, 5, 80, 6, 7, 80, 8, 9, 80, + IVec vec = c_init(IVec, {0, 1, 2, 3, 4, 5, 80, 6, 7, 80, 8, 9, 80, 10, 11, 12, 13, 14, 15, 80, 16, 17}); c_forfilter (i, IVec, vec, flt_skipValue(i, 80)) @@ -54,7 +54,8 @@ fn main() { void demo2(void) { IVec vector = {0}; - c_forfilter (x, crange, crange_obj(INT64_MAX), + crange r = crange_init(INT64_MAX); + c_forfilter (x, crange, r, c_flt_skipwhile(x, *x.ref != 11) && (*x.ref % 2) != 0 && c_flt_take(x, 5) @@ -81,7 +82,7 @@ fn main() { } */ #define i_type SVec -#define i_valclass csview +#define i_keyclass csview #include <stc/cstack.h> void demo3(void) @@ -123,7 +124,7 @@ void demo5(void) { #define flt_even(i) ((*i.ref & 1) == 0) #define flt_mid_decade(i) ((*i.ref % 10) != 0) - crange R = crange_make(1963, INT32_MAX); + crange R = crange_init(1963, INT32_MAX); c_forfilter (i, crange, R, c_flt_skip(i,15) && diff --git a/misc/examples/forloops.c b/misc/examples/algorithms/forloops.c index 1fc00614..a83d4a53 100644 --- a/misc/examples/forloops.c +++ b/misc/examples/algorithms/forloops.c @@ -1,69 +1,65 @@ -#include <stdio.h>
-#include <stc/algo/filter.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_forrange:");
- c_forrange (30) printf(" xx");
- puts("");
-
- c_forrange (i, 30) printf(" %lld", i);
- puts("");
-
- c_forrange (i, 30, 60) printf(" %lld", i);
- puts("");
-
- c_forrange (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("");
-
- IVec vec = c_make(IVec, {12, 23, 453, 65, 113, 215, 676, 34, 67, 20, 27, 66, 189, 45, 280, 199});
- IMap map = c_make(IMap, {{12, 23}, {453, 65}, {676, 123}, {34, 67}});
-
- puts("\n\nc_foreach:");
- c_foreach (i, IVec, vec)
- printf(" %d", *i.ref);
-
- puts("\n\nc_foreach_r: reverse");
- c_foreach_rv (i, IVec, vec)
- printf(" %d", *i.ref);
-
- puts("\n\nc_foreach in map:");
- 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);
-
- #define isOdd(i) (*i.ref & 1)
-
- puts("\n\nc_forfilter:");
- c_forfilter (i, IVec, vec,
- isOdd(i) &&
- c_flt_skip(i, 4) &&
- c_flt_take(i, 4)
- ){
- printf(" %d", *i.ref);
- }
-
- IVec_drop(&vec);
- IMap_drop(&map);
-}
+#include <stdio.h> +#include <stc/algorithm.h> + +#define i_type IVec +#define i_key int +#include <stc/cstack.h> + +#define i_type IMap +#define i_key int +#define i_val int +#include <stc/cmap.h> + + +int main(void) +{ + puts("c_forrange:"); + c_forrange (30) printf(" xx"); + puts(""); + + c_forrange (i, 30) printf(" %lld", i); + puts(""); + + c_forrange (i, 30, 60) printf(" %lld", i); + puts(""); + + c_forrange (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(""); + + IVec vec = c_init(IVec, {12, 23, 453, 65, 113, 215, 676, 34, 67, 20, 27, 66, 189, 45, 280, 199}); + IMap map = c_init(IMap, {{12, 23}, {453, 65}, {676, 123}, {34, 67}}); + + puts("\n\nc_foreach:"); + c_foreach (i, IVec, vec) + printf(" %d", *i.ref); + + puts("\n\nc_foreach in map:"); + 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); + + #define isOdd(i) (*i.ref & 1) + + puts("\n\nc_forfilter:"); + c_forfilter (i, IVec, vec, + isOdd(i) && + c_flt_skip(i, 4) && + c_flt_take(i, 4) + ){ + printf(" %d", *i.ref); + } + + IVec_drop(&vec); + IMap_drop(&map); +} diff --git a/misc/examples/algorithms/random.c b/misc/examples/algorithms/random.c new file mode 100644 index 00000000..e457d329 --- /dev/null +++ b/misc/examples/algorithms/random.c @@ -0,0 +1,42 @@ +#include <stdio.h> +#include <time.h> +#include <stc/crand.h> + +int main(void) +{ + const long long N = 10000000, range = 1000000; + const uint64_t seed = (uint64_t)time(NULL); + crand_t rng = crand_init(seed); + clock_t t; + + printf("Compare speed of full and unbiased ranged random numbers...\n"); + long long sum = 0; + t = clock(); + c_forrange (N) { + sum += (int32_t)crand_u64(&rng); + } + t = clock() - t; + printf("full range\t\t: %f secs, %lld, avg: %f\n", + (double)t/CLOCKS_PER_SEC, N, (double)(sum/N)); + + crand_uniform_t dist1 = crand_uniform_init(0, range); + rng = crand_init(seed); + sum = 0; + t = clock(); + c_forrange (N) { + sum += crand_uniform(&rng, &dist1); // unbiased + } + t = clock() - t; + printf("unbiased 0-%lld\t: %f secs, %lld, avg: %f\n", + range, (double)t/CLOCKS_PER_SEC, N, (double)(sum/N)); + + sum = 0; + rng = crand_init(seed); + t = clock(); + c_forrange (N) { + sum += (int32_t)crand_u64(&rng) % (range + 1); // biased + } + t = clock() - t; + printf("biased 0-%lld \t: %f secs, %lld, avg: %f\n", + range, (double)t/CLOCKS_PER_SEC, N, (double)(sum/N)); +} diff --git a/misc/examples/shape.c b/misc/examples/algorithms/shape.c index d7116039..bd4bdd5a 100644 --- a/misc/examples/shape.c +++ b/misc/examples/algorithms/shape.c @@ -62,9 +62,9 @@ static void Triangle_draw(const Shape* shape) { const Triangle* self = DYN_CAST(Triangle, shape); printf("Triangle : (%g,%g), (%g,%g), (%g,%g)\n", - self->p[0].x, self->p[0].y, - self->p[1].x, self->p[1].y, - self->p[2].x, self->p[2].y); + (double)self->p[0].x, (double)self->p[0].y, + (double)self->p[1].x, (double)self->p[1].y, + (double)self->p[2].x, (double)self->p[2].y); } struct ShapeAPI Triangle_api = { @@ -76,7 +76,7 @@ struct ShapeAPI Triangle_api = { // ============================================================ #define i_type PointVec -#define i_val Point +#define i_key Point #include <stc/cstack.h> typedef struct { @@ -109,7 +109,7 @@ static void Polygon_draw(const Shape* shape) const Polygon* self = DYN_CAST(Polygon, shape); printf("Polygon :"); c_foreach (i, PointVec, self->points) - printf(" (%g,%g)", i.ref->x, i.ref->y); + printf(" (%g,%g)", (double)i.ref->x, (double)i.ref->y); puts(""); } @@ -122,8 +122,8 @@ struct ShapeAPI Polygon_api = { // ============================================================ #define i_type Shapes -#define i_val Shape* -#define i_valdrop(x) Shape_delete(*x) +#define i_key Shape* +#define i_keydrop(x) Shape_delete(*x) #define i_no_clone #include <stc/cstack.h> @@ -137,7 +137,7 @@ int main(void) { Shapes shapes = {0}; - Triangle* tri1 = c_new(Triangle, Triangle_from((Point){5, 7}, (Point){12, 7}, (Point){12, 20})); + Triangle* tri1 = c_new(Triangle, Triangle_from(c_LITERAL(Point){5, 7}, c_LITERAL(Point){12, 7}, c_LITERAL(Point){12, 20})); Polygon* pol1 = c_new(Polygon, Polygon_init()); Polygon* pol2 = c_new(Polygon, Polygon_init()); diff --git a/misc/examples/shape.cpp b/misc/examples/algorithms/shape.cpp index ea1f53d2..ea1f53d2 100644 --- a/misc/examples/shape.cpp +++ b/misc/examples/algorithms/shape.cpp diff --git a/misc/examples/bits.c b/misc/examples/bitsets/bits.c index 1323d4e7..e0a11346 100644 --- a/misc/examples/bits.c +++ b/misc/examples/bitsets/bits.c @@ -9,18 +9,18 @@ int main(void) cbits_drop(&set), cbits_drop(&s2) ){ - printf("count %" c_ZI ", %" c_ZI "\n", cbits_count(&set), cbits_size(&set)); + printf("count %lld, %lld\n", cbits_count(&set), cbits_size(&set)); cbits s1 = cbits_from("1110100110111"); char buf[256]; cbits_to_str(&s1, buf, 0, 255); - printf("buf: %s: %" c_ZI "\n", buf, cbits_count(&s1)); + printf("buf: %s: %lld\n", buf, cbits_count(&s1)); cbits_drop(&s1); cbits_reset(&set, 9); cbits_resize(&set, 43, false); printf(" str: %s\n", cbits_to_str(&set, buf, 0, 255)); - printf("%4" c_ZI ": ", cbits_size(&set)); + printf("%4lld: ", cbits_size(&set)); c_forrange (i, cbits_size(&set)) printf("%d", cbits_test(&set, i)); puts(""); @@ -30,12 +30,12 @@ int main(void) cbits_resize(&set, 93, false); cbits_resize(&set, 102, true); cbits_set_value(&set, 99, false); - printf("%4" c_ZI ": ", cbits_size(&set)); + printf("%4lld: ", cbits_size(&set)); c_forrange (i, cbits_size(&set)) printf("%d", cbits_test(&set, i)); puts("\nIterate:"); - printf("%4" c_ZI ": ", cbits_size(&set)); + printf("%4lld: ", cbits_size(&set)); c_forrange (i, cbits_size(&set)) printf("%d", cbits_test(&set, i)); puts(""); @@ -58,7 +58,7 @@ int main(void) puts(""); cbits_set_all(&set, false); - printf("%4" c_ZI ": ", cbits_size(&set)); + printf("%4lld: ", cbits_size(&set)); c_forrange (i, cbits_size(&set)) printf("%d", cbits_test(&set, i)); puts(""); diff --git a/misc/examples/bits2.c b/misc/examples/bitsets/bits2.c index b002af3c..de2f16f4 100644 --- a/misc/examples/bits2.c +++ b/misc/examples/bitsets/bits2.c @@ -5,14 +5,14 @@ #define i_capacity 80 // enable fixed bitset on the stack #include <stc/cbits.h> -int main() +int main(void) { Bits s1 = Bits_from("1110100110111"); - printf("size %" c_ZI "\n", Bits_size(&s1)); + printf("size %lld\n", Bits_size(&s1)); char buf[256]; Bits_to_str(&s1, buf, 0, 256); - printf("buf: %s: count=%" c_ZI "\n", buf, Bits_count(&s1)); + printf("buf: %s: count=%lld\n", buf, Bits_count(&s1)); Bits_reset(&s1, 8); printf(" s1: %s\n", Bits_to_str(&s1, buf, 0, 256)); diff --git a/misc/examples/prime.c b/misc/examples/bitsets/prime.c index d0887353..7e5a2b3f 100644 --- a/misc/examples/prime.c +++ b/misc/examples/bitsets/prime.c @@ -2,23 +2,23 @@ #include <math.h> #include <time.h> #include <stc/cbits.h> -#include <stc/algo/filter.h> -#include <stc/algo/crange.h> +#include <stc/algorithm.h> +typedef long long llong; -cbits sieveOfEratosthenes(int64_t n) +cbits sieveOfEratosthenes(llong n) { cbits bits = cbits_with_size(n/2 + 1, true); - int64_t q = (int64_t)sqrt((double) n) + 1; - for (int64_t i = 3; i < q; i += 2) { - int64_t j = i; + llong q = (llong)sqrt((double) n) + 1; + for (llong i = 3; i < q; i += 2) { + llong j = i; for (; j < n; j += 2) { if (cbits_test(&bits, j>>1)) { i = j; break; } } - for (int64_t j = i*i; j < n; j += i*2) + for (llong j = i*i; j < n; j += i*2) cbits_reset(&bits, j>>1); } return bits; @@ -26,15 +26,17 @@ cbits sieveOfEratosthenes(int64_t n) int main(void) { - int64_t n = 1000000000; - printf("Computing prime numbers up to %" c_ZI "\n", n); + llong n = 100000000; + printf("Computing prime numbers up to %lld\n", n); - clock_t t1 = clock(); + clock_t t = clock(); cbits primes = sieveOfEratosthenes(n + 1); - int64_t np = cbits_count(&primes); - clock_t t2 = clock(); - printf("Number of primes: %" c_ZI ", time: %f\n\n", np, (float)(t2 - t1) / (float)CLOCKS_PER_SEC); + llong np = cbits_count(&primes); + t = clock() - t; + + printf("Number of primes: %lld, time: %f\n\n", np, (double)t/CLOCKS_PER_SEC); + puts("Show all the primes in the range [2, 1000):"); printf("2"); c_forrange (i, 3, 1000, 2) @@ -42,7 +44,9 @@ int main(void) puts("\n"); puts("Show the last 50 primes using a temporary crange generator:"); - c_forfilter (i, crange, crange_obj(n - 1, 0, -2), + crange range = crange_init(n - 1, 0, -2); + + c_forfilter (i, crange, range, cbits_test(&primes, *i.ref/2) && c_flt_take(i, 50) ){ diff --git a/misc/examples/coread.c b/misc/examples/coread.c deleted file mode 100644 index 0a7f4816..00000000 --- a/misc/examples/coread.c +++ /dev/null @@ -1,39 +0,0 @@ -#include <stc/cstr.h> -#include <stc/algo/coroutine.h> -#include <errno.h> - -// Read file line by line using coroutines: - -struct file_nextline { - const char* filename; - int cco_state; - FILE* fp; - cstr line; -}; - -bool file_nextline(struct file_nextline* U) -{ - cco_begin(U) - U->fp = fopen(U->filename, "r"); - U->line = cstr_init(); - - while (cstr_getline(&U->line, U->fp)) - cco_yield(true); - - cco_final: // this label is required. - printf("finish\n"); - cstr_drop(&U->line); - fclose(U->fp); - cco_end(false); -} - -int main(void) -{ - struct file_nextline it = {__FILE__}; - int n = 0; - while (file_nextline(&it)) - { - printf("%3d %s\n", ++n, cstr_str(&it.line)); - //if (n == 10) cco_stop(&it); - } -} diff --git a/misc/examples/coroutines.c b/misc/examples/coroutines.c deleted file mode 100644 index b11b8532..00000000 --- a/misc/examples/coroutines.c +++ /dev/null @@ -1,106 +0,0 @@ -#include <stc/algo/coroutine.h> -#include <stdio.h> -#include <stdint.h> - -// Demonstrate to call another coroutine from a coroutine: -// First create prime generator, then call fibonacci sequence: - -bool is_prime(int64_t i) { - for (int64_t j=2; j*j <= i; ++j) - if (i % j == 0) return false; - return true; -} - -struct prime { - int count, idx; - int64_t result, pos; - int cco_state; -}; - -bool prime(struct prime* U) { - cco_begin(U); - if (U->result < 2) U->result = 2; - if (U->result == 2) { - if (U->count-- == 0) cco_return; - ++U->idx; - cco_yield(true); - } - U->result += !(U->result & 1); - for (U->pos = U->result; U->count > 0; U->pos += 2) { - if (is_prime(U->pos)) { - --U->count; - ++U->idx; - U->result = U->pos; - cco_yield(true); - } - } - cco_final: - printf("final prm\n"); - cco_end(false); -} - - -// Use coroutine to create a fibonacci sequence generator: - -struct fibonacci { - int count, idx; - int64_t result, b; - int cco_state; -}; - -bool fibonacci(struct fibonacci* F) { - assert(F->count < 94); - - cco_begin(F); - F->idx = 0; - F->result = 0; - F->b = 1; - for (;;) { - if (F->count-- == 0) - cco_return; - if (++F->idx > 1) { - int64_t sum = F->result + F->b; // NB! locals only lasts until next cco_yield! - F->result = F->b; - F->b = sum; - } - cco_yield(true); - } - cco_final: - printf("final fib\n"); - cco_end(false); -} - -// Combine - -struct combined { - struct prime prm; - struct fibonacci fib; - int cco_state; -}; - -bool combined(struct combined* C) { - cco_begin(C); - cco_yield(prime(&C->prm), &C->prm, true); - cco_yield(fibonacci(&C->fib), &C->fib, true); - - // Reuse the C->prm context and extend the count: - C->prm.count = 8; C->prm.result += 2; - cco_reset(&C->prm); - cco_yield(prime(&C->prm), &C->prm, true); - - cco_final: puts("final comb"); - cco_end(false); -} - -int main(void) { - struct combined comb = {.prm={.count=8}, .fib={14}}; - if (true) - while (combined(&comb)) - printf("Prime(%d)=%lld, Fib(%d)=%lld\n", - comb.prm.idx, (long long)comb.prm.result, - comb.fib.idx, (long long)comb.fib.result); - else - while (prime(&comb.prm)) - printf("Prime(%d)=%lld\n", - comb.prm.idx, (long long)comb.prm.result); -} diff --git a/misc/examples/coroutines/cointerleave.c b/misc/examples/coroutines/cointerleave.c new file mode 100644 index 00000000..80494176 --- /dev/null +++ b/misc/examples/coroutines/cointerleave.c @@ -0,0 +1,62 @@ +// https://www.youtube.com/watch?v=8sEe-4tig_A +#include <stdio.h> +#include <stc/coroutine.h> +#define i_type IVec +#define i_key int +#include <stc/cvec.h> + +struct GenValue { + IVec *v; + IVec_iter it; + int cco_state; +}; + +static int get_value(struct GenValue* g) +{ + cco_routine(g) { + for (g->it = IVec_begin(g->v); g->it.ref; IVec_next(&g->it)) + cco_yield_v(*g->it.ref); + } + return -1; +} + +struct Generator { + struct GenValue x, y; + int cco_state; + int value; +}; + +cco_result interleaved(struct Generator* g) +{ + cco_routine(g) { + while (!(cco_done(&g->x) & cco_done(&g->y))) { + g->value = get_value(&g->x); + if (!cco_done(&g->x)) + cco_yield(); + + g->value = get_value(&g->y); + if (!cco_done(&g->y)) + cco_yield(); + } + } + return CCO_DONE; +} + +void Use(void) +{ + IVec a = c_init(IVec, {2, 4, 6, 8, 10, 11}); + IVec b = c_init(IVec, {3, 5, 7, 9}); + + struct Generator g = {{&a}, {&b}}; + + cco_blocking_call(interleaved(&g)) { + printf("%d ", g.value); + } + puts(""); + c_drop(IVec, &a, &b); +} + +int main(void) +{ + Use(); +} diff --git a/misc/examples/coroutines/coread.c b/misc/examples/coroutines/coread.c new file mode 100644 index 00000000..6d3acdd7 --- /dev/null +++ b/misc/examples/coroutines/coread.c @@ -0,0 +1,41 @@ +#define i_implement +#include <stc/cstr.h> +#include <stc/coroutine.h> +#include <errno.h> + +// Read file line by line using coroutines: + +struct file_read { + const char* filename; + int cco_state; + FILE* fp; + cstr line; +}; + +int file_read(struct file_read* g) +{ + cco_routine(g) { + g->fp = fopen(g->filename, "r"); + if (!g->fp) cco_return; + g->line = cstr_init(); + + cco_await(!cstr_getline(&g->line, g->fp)); + + cco_final: + printf("finish\n"); + cstr_drop(&g->line); + if (g->fp) fclose(g->fp); + } + return 0; +} + +int main(void) +{ + struct file_read g = {__FILE__}; + int n = 0; + cco_blocking_call(file_read(&g)) + { + printf("%3d %s\n", ++n, cstr_str(&g.line)); + //if (n == 10) cco_stop(&g); + } +} diff --git a/misc/examples/coroutines/coroutines.c b/misc/examples/coroutines/coroutines.c new file mode 100644 index 00000000..802a976a --- /dev/null +++ b/misc/examples/coroutines/coroutines.c @@ -0,0 +1,112 @@ +#include <stc/coroutine.h> +#include <stdio.h> +#include <stdint.h> + +// Demonstrate to call another coroutine from a coroutine: +// First create prime generator, then call fibonacci sequence: + +bool is_prime(long long i) { + for (long long j=2; j*j <= i; ++j) + if (i % j == 0) return false; + return true; +} + +struct prime { + int count, idx; + long long result, pos; + int cco_state; +}; + +int prime(struct prime* g) { + cco_routine(g) { + if (g->result < 2) g->result = 2; + if (g->result == 2) { + if (g->count-- == 0) cco_return; + ++g->idx; + cco_yield(); + } + g->result += !(g->result & 1); + for (g->pos = g->result; g->count > 0; g->pos += 2) { + if (is_prime(g->pos)) { + --g->count; + ++g->idx; + g->result = g->pos; + cco_yield(); + } + } + cco_final: + printf("final prm\n"); + } + return 0; +} + + +// Use coroutine to create a fibonacci sequence generator: + +struct fibonacci { + int count, idx; + long long result, b; + int cco_state; +}; + +int fibonacci(struct fibonacci* g) { + assert(g->count < 94); + + long long sum; + cco_routine(g) { + g->idx = 0; + g->result = 0; + g->b = 1; + for (;;) { + if (g->count-- == 0) + cco_return; + if (++g->idx > 1) { + // NB! locals lasts only until next yield/await! + sum = g->result + g->b; + g->result = g->b; + g->b = sum; + } + cco_yield(); + } + cco_final: + printf("final fib\n"); + } + return 0; +} + +// Combine + +struct combined { + struct prime prm; + struct fibonacci fib; + int cco_state; +}; + +int combined(struct combined* g) { + cco_routine(g) { + cco_await_call(prime(&g->prm)); + cco_await_call(fibonacci(&g->fib)); + + // Reuse the g->prm context and extend the count: + g->prm.count = 8, g->prm.result += 2; + cco_reset(&g->prm); + cco_await_call(prime(&g->prm)); + + cco_final: + puts("final combined"); + } + return 0; +} + +int main(void) +{ + struct combined c = {.prm={.count=8}, .fib={14}}; + int res; + + cco_blocking_call(res = combined(&c)) { + if (res == CCO_YIELD) + printf("Prime(%d)=%lld, Fib(%d)=%lld\n", + c.prm.idx, c.prm.result, + c.fib.idx, c.fib.result); + } +} diff --git a/misc/examples/coroutines/cotasks1.c b/misc/examples/coroutines/cotasks1.c new file mode 100644 index 00000000..cffd6620 --- /dev/null +++ b/misc/examples/coroutines/cotasks1.c @@ -0,0 +1,100 @@ +// https://mariusbancila.ro/blog/2020/06/22/a-cpp20-coroutine-example/ + +#include <time.h> +#include <stdio.h> +#define i_static +#include <stc/cstr.h> +#include <stc/coroutine.h> + +struct next_value { + int val; + int cco_state; + cco_timer tm; +}; + +int next_value(struct next_value* co) +{ + cco_routine (co) { + while (true) { + cco_await_timer(&co->tm, 1 + rand() % 2); + co->val = rand(); + cco_yield(); + } + } + return 0; +} + +void print_time() +{ + time_t now = time(NULL); + char mbstr[64]; + strftime(mbstr, sizeof(mbstr), "[%H:%M:%S]", localtime(&now)); + printf("%s ", mbstr); +} + +// PRODUCER + +struct produce_items { + struct next_value next; + cstr text; + int cco_state; +}; + +int produce_items(struct produce_items* p) +{ + cco_routine (p) { + p->text = cstr_init(); + while (true) + { + cco_await(next_value(&p->next) != CCO_AWAIT); + cstr_printf(&p->text, "item %d", p->next.val); + print_time(); + printf("produced %s\n", cstr_str(&p->text)); + cco_yield(); + } + cco_final: + cstr_drop(&p->text); + puts("done produce"); + } + return 0; +} + +// CONSUMER + +struct consume_items { + int n, i; + int cco_state; +}; + +int consume_items(struct consume_items* c, struct produce_items* p) +{ + cco_routine (c) { + for (c->i = 1; c->i <= c->n; ++c->i) + { + printf("consume #%d\n", c->i); + cco_await(produce_items(p) != CCO_AWAIT); + print_time(); + printf("consumed %s\n", cstr_str(&p->text)); + } + cco_final: + puts("done consume"); + } + return 0; +} + +int main(void) +{ + struct produce_items produce = {0}; + struct consume_items consume = {.n=5}; + int count = 0; + + cco_blocking_call(consume_items(&consume, &produce)) + { + ++count; + //cco_sleep(0.001); + //if (consume.i == 3) cco_stop(&consume); + } + cco_stop(&produce); + produce_items(&produce); + printf("count: %d\n", count); +}
\ No newline at end of file diff --git a/misc/examples/coroutines/cotasks2.c b/misc/examples/coroutines/cotasks2.c new file mode 100644 index 00000000..558df118 --- /dev/null +++ b/misc/examples/coroutines/cotasks2.c @@ -0,0 +1,98 @@ +// https://mariusbancila.ro/blog/2020/06/22/a-cpp20-coroutine-example/ + +#include <time.h> +#include <stdio.h> +#define i_static +#include <stc/cstr.h> +#include <stc/coroutine.h> + +cco_task_struct (next_value, + int val; + cco_timer tm; +); + +int next_value(struct next_value* co, cco_runtime* rt) +{ + cco_routine (co) { + while (true) { + cco_await_timer(&co->tm, 1 + rand() % 2); + co->val = rand(); + cco_yield(); + } + } + return 0; +} + +void print_time() +{ + time_t now = time(NULL); + char mbstr[64]; + strftime(mbstr, sizeof(mbstr), "[%H:%M:%S]", localtime(&now)); + printf("%s ", mbstr); +} + +// PRODUCER + +cco_task_struct (produce_items, + struct next_value next; + cstr text; +); + +int produce_items(struct produce_items* p, cco_runtime* rt) +{ + cco_routine (p) { + p->text = cstr_init(); + p->next.cco_func = next_value; + while (true) + { + // await for next CCO_YIELD (or CCO_DONE) in next_value + cco_await_task(&p->next, rt, CCO_YIELD); + cstr_printf(&p->text, "item %d", p->next.val); + print_time(); + printf("produced %s\n", cstr_str(&p->text)); + cco_yield(); + } + + cco_final: + cstr_drop(&p->text); + puts("done produce"); + } + return 0; +} + +// CONSUMER + +cco_task_struct (consume_items, + int n, i; + struct produce_items produce; +); + +int consume_items(struct consume_items* c, cco_runtime* rt) +{ + cco_routine (c) { + c->produce.cco_func = produce_items; + + for (c->i = 1; c->i <= c->n; ++c->i) + { + printf("consume #%d\n", c->i); + cco_await_task(&c->produce, rt, CCO_YIELD); + print_time(); + printf("consumed %s\n", cstr_str(&c->produce.text)); + } + + cco_final: + cco_stop(&c->produce); + cco_resume_task(&c->produce, rt); + puts("done consume"); + } + return 0; +} + +int main(void) +{ + struct consume_items consume = { + .cco_func = consume_items, + .n = 5, + }; + cco_blocking_task(&consume); +} diff --git a/misc/examples/coroutines/dining_philosophers.c b/misc/examples/coroutines/dining_philosophers.c new file mode 100644 index 00000000..d353b3b9 --- /dev/null +++ b/misc/examples/coroutines/dining_philosophers.c @@ -0,0 +1,105 @@ +// https://en.wikipedia.org/wiki/Dining_philosophers_problem +#include <stdio.h> +#include <time.h> +#include <stc/crand.h> +#include <stc/coroutine.h> + +// Define the number of philosophers and forks +enum { + num_philosophers = 5, + num_forks = num_philosophers, +}; + +struct Philosopher { + int id; + cco_timer tm; + cco_sem* left_fork; + cco_sem* right_fork; + int cco_state; // required +}; + +struct Dining { + // Define semaphores for the forks + cco_sem forks[num_forks]; + struct Philosopher ph[num_philosophers]; + int cco_state; // required +}; + + +// Philosopher coroutine +int philosopher(struct Philosopher* p) +{ + double duration; + cco_routine(p) { + while (1) { + duration = 1.0 + crandf()*2.0; + printf("Philosopher %d is thinking for %.0f minutes...\n", p->id, duration*10); + cco_await_timer(&p->tm, duration); + + printf("Philosopher %d is hungry...\n", p->id); + cco_await_sem(p->left_fork); + cco_await_sem(p->right_fork); + + duration = 0.5 + crandf(); + printf("Philosopher %d is eating for %.0f minutes...\n", p->id, duration*10); + cco_await_timer(&p->tm, duration); + + cco_sem_release(p->left_fork); + cco_sem_release(p->right_fork); + } + + cco_final: + printf("Philosopher %d finished\n", p->id); + } + return 0; +} + + +// Dining coroutine +int dining(struct Dining* d) +{ + cco_routine(d) { + for (int i = 0; i < num_forks; ++i) + cco_sem_set(&d->forks[i], 1); // all forks available + for (int i = 0; i < num_philosophers; ++i) { + cco_reset(&d->ph[i]); + d->ph[i].id = i + 1; + d->ph[i].left_fork = &d->forks[i]; + d->ph[i].right_fork = &d->forks[(i + 1) % num_forks]; + } + + while (1) { + // per-"frame" logic resume each philosopher + for (int i = 0; i < num_philosophers; ++i) { + philosopher(&d->ph[i]); + } + cco_yield(); // suspend, return control back to main + } + + cco_final: + for (int i = 0; i < num_philosophers; ++i) { + cco_stop(&d->ph[i]); + philosopher(&d->ph[i]); + } + puts("Dining finished"); + } + return 0; +} + +int main(void) +{ + struct Dining dine; + cco_reset(&dine); + int n=0; + cco_timer tm = cco_timer_from(15.0); // seconds + csrand((uint64_t)time(NULL)); + + cco_blocking_call(dining(&dine)) + { + if (cco_timer_expired(&tm)) + cco_stop(&dine); + cco_sleep(0.001); + ++n; + } + printf("n=%d\n", n); +} diff --git a/misc/examples/coroutines/filetask.c b/misc/examples/coroutines/filetask.c new file mode 100644 index 00000000..9650cb60 --- /dev/null +++ b/misc/examples/coroutines/filetask.c @@ -0,0 +1,80 @@ +// https://github.com/lewissbaker/cppcoro#taskt + +#include <time.h> +#include <stdio.h> +#define i_static +#include <stc/cstr.h> +#include <stc/coroutine.h> + +cco_task_struct(file_read, + const char* path; + cstr line; + FILE* fp; + cco_timer tm; +); + +int file_read(struct file_read* co, cco_runtime* rt) +{ + cco_routine (co) { + co->fp = fopen(co->path, "r"); + co->line = cstr_init(); + + while (true) { + // emulate async io: await 10ms per line + cco_await_timer(&co->tm, 0.010); + + if (!cstr_getline(&co->line, co->fp)) + break; + cco_yield(); + } + + cco_final: + fclose(co->fp); + cstr_drop(&co->line); + puts("done file_read"); + } + return 0; +} + +cco_task_struct(count_line, + cstr path; + struct file_read reader; + int lineCount; +); + +int count_line(struct count_line* co, cco_runtime* rt) +{ + cco_routine (co) { + co->reader.cco_func = file_read; + co->reader.path = cstr_str(&co->path); + while (true) + { + // await for next CCO_YIELD (or CCO_DONE) in file_read() + cco_await_task(&co->reader, rt, CCO_YIELD); + if (rt->result == CCO_DONE) break; + co->lineCount += 1; + cco_yield(); + } + + cco_final: + cstr_drop(&co->path); + puts("done count_line"); + } + return 0; +} + +int main(void) +{ + // Creates a new task + struct count_line countTask = { + .cco_func = count_line, + .path = cstr_from(__FILE__), + }; + + // Execute coroutine as top-level blocking + int loop = 0; + cco_blocking_task(&countTask) { ++loop; } + + printf("line count = %d\n", countTask.lineCount); + printf("exec count = %d\n", loop); +} diff --git a/misc/examples/coroutines/generator.c b/misc/examples/coroutines/generator.c new file mode 100644 index 00000000..96498498 --- /dev/null +++ b/misc/examples/coroutines/generator.c @@ -0,0 +1,66 @@ +// https://quuxplusone.github.io/blog/2019/03/06/pythagorean-triples/ + +#include <stdio.h> +#include <stc/coroutine.h> +#include <stc/algorithm.h> + +typedef struct { + int max_triples; + int a, b, c; +} Triple; + +// Create an iterable generator over Triple with count items. +// Requires coroutine Triple_next() and function Triple_begin() to be defined. +cco_iter_struct(Triple, + int count; +); + +int Triple_next(Triple_iter* it) { + Triple* g = it->ref; // note: before cco_routine + cco_routine(it) + { + for (g->c = 5;; ++g->c) { + for (g->a = 1; g->a < g->c; ++g->a) { + for (g->b = g->a; g->b < g->c; ++g->b) { + if (g->a*g->a + g->b*g->b == g->c*g->c) { + if (it->count++ == g->max_triples) + cco_return; + cco_yield(); + } + } + } + } + cco_final: + it->ref = NULL; // stop the iterator + } + return 0; +} + +Triple_iter Triple_begin(Triple* g) { + Triple_iter it = {.ref=g}; + Triple_next(&it); + return it; +} + + +int main(void) +{ + puts("Pythagorean triples.\nGet max 200 triples with c < 50:"); + Triple triple = {.max_triples=200}; + + c_foreach (i, Triple, triple) { + if (i.ref->c < 50) + printf("%u: (%d, %d, %d)\n", i.count, i.ref->a, i.ref->b, i.ref->c); + else + cco_stop(&i); + } + + puts("\nGet the 10 first triples with odd a's and a <= 20:"); + c_forfilter (i, Triple, triple, + i.ref->a <= 20 && + (i.ref->a & 1) && + c_flt_take(i, 10) + ){ + printf("%d: (%d, %d, %d)\n", c_flt_getcount(i), i.ref->a, i.ref->b, i.ref->c); + } +} diff --git a/misc/examples/coroutines/scheduler.c b/misc/examples/coroutines/scheduler.c new file mode 100644 index 00000000..be1810d2 --- /dev/null +++ b/misc/examples/coroutines/scheduler.c @@ -0,0 +1,67 @@ +// https://www.youtube.com/watch?v=8sEe-4tig_A +#include <stdio.h> +#include <stc/coroutine.h> + +#define i_type cco_tasks +#define i_key cco_task* +#define i_keydrop(x) { puts("free task"); free(*x); } +#define i_no_clone +#include <stc/cqueue.h> + +typedef struct { + cco_tasks tasks; +} cco_scheduler; + +void cco_scheduler_drop(cco_scheduler* sched) { + cco_tasks_drop(&sched->tasks); +} + +int cco_scheduler_run(cco_scheduler* sched) { + while (!cco_tasks_empty(&sched->tasks)) { + cco_task* task = cco_tasks_pull(&sched->tasks); + if (cco_resume_task(task, NULL)) + cco_tasks_push(&sched->tasks, task); + else + cco_tasks_value_drop(&task); + } + return 0; +} + +static int taskA(cco_task* task, cco_runtime* rt) { + cco_routine(task) { + puts("Hello, from task A"); + cco_yield(); + puts("A is back doing work"); + cco_yield(); + puts("A is back doing more work"); + cco_yield(); + puts("A is back doing even more work"); + } + return 0; +} + +static int taskB(cco_task* task, cco_runtime* rt) { + cco_routine(task) { + puts("Hello, from task B"); + cco_yield(); + puts("B is back doing work"); + cco_yield(); + puts("B is back doing more work"); + } + return 0; +} + +void Use(void) { + cco_scheduler sched = {.tasks = c_init(cco_tasks, { + c_new(cco_task, {.cco_func=taskA}), + c_new(cco_task, {.cco_func=taskB}), + })}; + + cco_scheduler_run(&sched); + cco_scheduler_drop(&sched); +} + +int main(void) +{ + Use(); +} diff --git a/misc/examples/coroutines/triples.c b/misc/examples/coroutines/triples.c new file mode 100644 index 00000000..d6ce2791 --- /dev/null +++ b/misc/examples/coroutines/triples.c @@ -0,0 +1,75 @@ +// https://quuxplusone.github.io/blog/2019/03/06/pythagorean-triples/ + +#include <stdio.h> +#include <stc/coroutine.h> + +void triples_vanilla(int max_c) { + for (int c = 5, i = 0;; ++c) { + for (int a = 1; a < c; ++a) { + for (int b = a + 1; b < c; ++b) { + if ((int64_t)a*a + (int64_t)b*b == (int64_t)c*c) { + if (c > max_c) + goto done; + printf("%d: {%d, %d, %d}\n", ++i, a, b, c); + } + } + } + } + done:; +} + +struct triples { + int max_c; + int a, b, c; + int cco_state; +}; + +int triples_coro(struct triples* t) { + cco_routine(t) { + for (t->c = 5;; ++t->c) { + for (t->a = 1; t->a < t->c; ++t->a) { + for (t->b = t->a + 1; t->b < t->c; ++t->b) { + if ((int64_t)t->a * t->a + + (int64_t)t->b * t->b == + (int64_t)t->c * t->c) + { + if (t->c > t->max_c) + cco_return; + cco_yield(); + } + } + } + } + cco_final: + puts("done"); + } + return 0; +} + +int gcd(int a, int b) { + while (b) { + int t = a % b; + a = b; + b = t; + } + return a; +} + +int main(void) +{ + puts("Vanilla triples:"); + triples_vanilla(20); + + puts("\nCoroutine triples with GCD = 1:"); + struct triples t = {.max_c = 100}; + int n = 0; + + cco_blocking_call(triples_coro(&t)) { + if (gcd(t.a, t.b) > 1) + continue; + if (++n <= 20) + printf("%d: {%d, %d, %d}\n", n, t.a, t.b, t.c); + else + cco_stop(&t); + } +} diff --git a/misc/examples/generator.c b/misc/examples/generator.c deleted file mode 100644 index 2bccc489..00000000 --- a/misc/examples/generator.c +++ /dev/null @@ -1,53 +0,0 @@ -// https://quuxplusone.github.io/blog/2019/03/06/pythagorean-triples/ - -#include <stc/algo/coroutine.h> -#include <stdio.h> - -typedef struct { - int n; - int a, b, c; -} Triple_value, Triple; - -typedef struct { - Triple_value* ref; - int cco_state; -} Triple_iter; - -bool Triple_next(Triple_iter* it) { - Triple_value* t = it->ref; - cco_begin(it); - for (t->c = 1;; ++t->c) { - for (t->a = 1; t->a < t->c; ++t->a) { - for (t->b = t->a; t->b < t->c; ++t->b) { - if (t->a*t->a + t->b*t->b == t->c*t->c) { - if (t->n-- == 0) cco_return; - cco_yield(true); - } - } - } - } - cco_final: - it->ref = NULL; - cco_end(false); -} - -Triple_iter Triple_begin(Triple* t) { - Triple_iter it = {t}; - if (t->n > 0) Triple_next(&it); - else it.ref = NULL; - return it; -} - - -int main() -{ - puts("Pythagorean triples with c < 100:"); - Triple t = {INT32_MAX}; - c_foreach (i, Triple, t) - { - if (i.ref->c < 100) - printf("%u: (%d, %d, %d)\n", INT32_MAX - i.ref->n + 1, i.ref->a, i.ref->b, i.ref->c); - else - cco_stop(&i); - } -} diff --git a/misc/examples/birthday.c b/misc/examples/hashmaps/birthday.c index c301128a..4742cb45 100644 --- a/misc/examples/birthday.c +++ b/misc/examples/hashmaps/birthday.c @@ -13,8 +13,8 @@ static uint64_t seed = 12345; static void test_repeats(void) { enum {BITS = 46, BITS_TEST = BITS/2 + 2}; - const static uint64_t N = 1ull << BITS_TEST; - const static uint64_t mask = (1ull << BITS) - 1; + static const uint64_t N = 1ull << BITS_TEST; + static const uint64_t mask = (1ull << BITS) - 1; printf("birthday paradox: value range: 2^%d, testing repeats of 2^%d values\n", BITS, BITS_TEST); crand_t rng = crand_init(seed); @@ -60,7 +60,7 @@ void test_distribution(void) cmap_x_drop(&map); } -int main() +int main(void) { seed = (uint64_t)time(NULL); test_distribution(); diff --git a/misc/examples/books.c b/misc/examples/hashmaps/books.c index a62769b0..1fd57f27 100644 --- a/misc/examples/books.c +++ b/misc/examples/hashmaps/books.c @@ -1,4 +1,5 @@ // https://doc.rust-lang.org/std/collections/struct.HashMap.html +#define i_implement #include <stc/cstr.h> #define i_key_str #define i_val_str @@ -6,7 +7,7 @@ // Type inference lets us omit an explicit type signature (which // would be `HashMap<String, String>` in this example). -int main() +int main(void) { cmap_str book_reviews = {0}; diff --git a/misc/examples/hashmap.c b/misc/examples/hashmaps/hashmap.c index 47a3bcff..cf11b7f7 100644 --- a/misc/examples/hashmap.c +++ b/misc/examples/hashmaps/hashmap.c @@ -1,4 +1,5 @@ // https://doc.rust-lang.org/rust-by-example/std/hash.html +#define i_implement #include <stc/cstr.h> #define i_key_str #define i_val_str diff --git a/misc/examples/new_map.c b/misc/examples/hashmaps/new_map.c index 3a4f934d..de990040 100644 --- a/misc/examples/new_map.c +++ b/misc/examples/hashmaps/new_map.c @@ -1,12 +1,13 @@ +#define i_implement #include <stc/cstr.h> #include <stc/forward.h> forward_cmap(cmap_pnt, struct Point, int); -struct MyStruct { +typedef struct MyStruct { cmap_pnt pntmap; cstr name; -} typedef MyStruct; +} MyStruct; // int => int map #define i_key int @@ -14,7 +15,7 @@ struct MyStruct { #include <stc/cmap.h> // Point => int map -struct Point { int x, y; } typedef Point; +typedef struct Point { int x, y; } Point; int point_cmp(const Point* a, const Point* b) { int c = a->x - b->x; @@ -40,20 +41,20 @@ int point_cmp(const Point* a, const Point* b) { #include <stc/cset.h> -int main() +int main(void) { - cmap_pnt pmap = c_make(cmap_pnt, {{{42, 14}, 1}, {{32, 94}, 2}, {{62, 81}, 3}}); + cmap_pnt pmap = c_init(cmap_pnt, {{{42, 14}, 1}, {{32, 94}, 2}, {{62, 81}, 3}}); c_foreach (i, cmap_pnt, pmap) printf(" (%d, %d: %d)", i.ref->first.x, i.ref->first.y, i.ref->second); puts(""); - cmap_str smap = c_make(cmap_str, { + cmap_str smap = c_init(cmap_str, { {"Hello, friend", "long time no see"}, {"So long", "see you around"}, }); - cset_str sset = c_make(cset_str, { + cset_str sset = c_init(cset_str, { "Hello, friend", "Nice to see you again", "So long", diff --git a/misc/examples/phonebook.c b/misc/examples/hashmaps/phonebook.c index c0007cb7..faf7566e 100644 --- a/misc/examples/phonebook.c +++ b/misc/examples/hashmaps/phonebook.c @@ -20,7 +20,7 @@ // IN THE SOFTWARE. // Program to emulates the phone book. - +#define i_implement #include <stc/cstr.h> #define i_key_str @@ -38,7 +38,7 @@ void print_phone_book(cmap_str phone_book) int main(int argc, char **argv) { - cmap_str phone_book = c_make(cmap_str, { + cmap_str phone_book = c_init(cmap_str, { {"Lilia Friedman", "(892) 670-4739"}, {"Tariq Beltran", "(489) 600-7575"}, {"Laiba Juarez", "(303) 885-5692"}, diff --git a/misc/examples/unordered_set.c b/misc/examples/hashmaps/unordered_set.c index 61f9cc1f..dd899d78 100644 --- a/misc/examples/unordered_set.c +++ b/misc/examples/hashmaps/unordered_set.c @@ -1,10 +1,11 @@ // https://iq.opengenus.org/containers-cpp-stl/ // C program to demonstrate various function of stc cset +#define i_implement #include <stc/cstr.h> #define i_key_str #include <stc/cset.h> -int main() +int main(void) { // declaring set for storing string data-type cset_str stringSet = {0}; diff --git a/misc/examples/vikings.c b/misc/examples/hashmaps/vikings.c index abb909c3..cef17a04 100644 --- a/misc/examples/vikings.c +++ b/misc/examples/hashmaps/vikings.c @@ -1,3 +1,4 @@ +#define i_implement #include <stc/cstr.h> typedef struct Viking { @@ -36,19 +37,19 @@ static inline RViking Viking_toraw(const Viking* vp) { #define i_rawclass RViking // lookup type #define i_keyfrom Viking_from #define i_opt c_no_clone -#define i_hash(rp) cstrhash(rp->name) ^ cstrhash(rp->country) +#define i_hash(rp) stc_strhash(rp->name) ^ stc_strhash(rp->country) #define i_val int // mapped type #include <stc/cmap.h> -int main() +int main(void) { Vikings vikings = {0}; - Vikings_emplace(&vikings, (RViking){"Einar", "Norway"}, 20); - Vikings_emplace(&vikings, (RViking){"Olaf", "Denmark"}, 24); - Vikings_emplace(&vikings, (RViking){"Harald", "Iceland"}, 12); - Vikings_emplace(&vikings, (RViking){"Björn", "Sweden"}, 10); + Vikings_emplace(&vikings, c_LITERAL(RViking){"Einar", "Norway"}, 20); + Vikings_emplace(&vikings, c_LITERAL(RViking){"Olaf", "Denmark"}, 24); + Vikings_emplace(&vikings, c_LITERAL(RViking){"Harald", "Iceland"}, 12); + Vikings_emplace(&vikings, c_LITERAL(RViking){"Björn", "Sweden"}, 10); - Vikings_value* v = Vikings_get_mut(&vikings, (RViking){"Einar", "Norway"}); + Vikings_value* v = Vikings_get_mut(&vikings, c_LITERAL(RViking){"Einar", "Norway"}); v->second += 3; // add 3 hp points to Einar c_forpair (vk, hp, Vikings, vikings) { diff --git a/misc/examples/intrusive.c b/misc/examples/linkedlists/intrusive.c index 0d503575..edb072c7 100644 --- a/misc/examples/intrusive.c +++ b/misc/examples/linkedlists/intrusive.c @@ -3,8 +3,9 @@ #include <stdio.h> #define i_type List -#define i_val int -#include <stc/clist.h> +#define i_key int +#define i_use_cmp +#include <stc/clist.h> void printList(List list) { printf("list:"); @@ -13,10 +14,10 @@ void printList(List list) { puts(""); } -int main() { +int main(void) { List list = {0}; c_forlist (i, int, {6, 9, 3, 1, 7, 4, 5, 2, 8}) - List_push_back_node(&list, c_new(List_node, {0, *i.ref})); + List_push_back_node(&list, c_new(List_node, {.value=*i.ref})); printList(list); diff --git a/misc/examples/list.c b/misc/examples/linkedlists/list.c index 363d7fec..e83dc6b2 100644 --- a/misc/examples/list.c +++ b/misc/examples/linkedlists/list.c @@ -1,20 +1,21 @@ #include <stdio.h> #include <time.h> -#include <stc/algo/filter.h> +#include <stc/algorithm.h> #include <stc/crand.h> #define i_type DList -#define i_val double +#define i_key double +#define i_use_cmp #include <stc/clist.h> -int main() { +int main(void) { const int n = 3000000; DList list = {0}; - crand_t rng = crand_init(1234567); + csrand(1234567); int m = 0; c_forrange (n) - DList_push_back(&list, crand_f64(&rng)*n + 100), ++m; + DList_push_back(&list, crandf()*n + 100), ++m; double sum = 0.0; printf("sumarize %d:\n", m); @@ -34,7 +35,7 @@ int main() { puts(""); DList_drop(&list); - list = c_make(DList, {10, 20, 30, 40, 30, 50}); + list = c_init(DList, {10, 20, 30, 40, 30, 50}); const double* v = DList_get(&list, 30); printf("found: %f\n", *v); diff --git a/misc/examples/list_erase.c b/misc/examples/linkedlists/list_erase.c index 0201c2d9..211c5a5d 100644 --- a/misc/examples/list_erase.c +++ b/misc/examples/linkedlists/list_erase.c @@ -2,12 +2,12 @@ #include <stdio.h> #define i_type IList -#define i_val int +#define i_key int #include <stc/clist.h> -int main () +int main(void) { - IList L = c_make(IList, {10, 20, 30, 40, 50}); + IList L = c_init(IList, {10, 20, 30, 40, 50}); c_foreach (x, IList, L) printf("%d ", *x.ref); diff --git a/misc/examples/list_splice.c b/misc/examples/linkedlists/list_splice.c index baebca29..f1fd6e1f 100644 --- a/misc/examples/list_splice.c +++ b/misc/examples/linkedlists/list_splice.c @@ -1,8 +1,7 @@ #include <stdio.h> -#define i_val int +#define i_key int #define i_tag i -#define i_extern // define _clist_mergesort() once #include <stc/clist.h> void print_ilist(const char* s, clist_i list) @@ -14,10 +13,10 @@ void print_ilist(const char* s, clist_i list) puts(""); } -int main () +int main(void) { - clist_i list1 = c_make(clist_i, {1, 2, 3, 4, 5}); - clist_i list2 = c_make(clist_i, {10, 20, 30, 40, 50}); + clist_i list1 = c_init(clist_i, {1, 2, 3, 4, 5}); + clist_i list2 = c_init(clist_i, {10, 20, 30, 40, 50}); print_ilist("list1:", list1); print_ilist("list2:", list2); diff --git a/misc/examples/linkedlists/new_list.c b/misc/examples/linkedlists/new_list.c new file mode 100644 index 00000000..7518929a --- /dev/null +++ b/misc/examples/linkedlists/new_list.c @@ -0,0 +1,70 @@ +#include <stdio.h> +#include <stc/forward.h> + +forward_clist(clist_i32, int); +forward_clist(clist_pnt, struct Point); + +typedef struct { + clist_i32 intlist; + clist_pnt pntlist; +} MyStruct; + +#define i_key int +#define i_tag i32 +#define i_is_forward +#include <stc/clist.h> + +typedef struct Point { int x, y; } Point; +int point_cmp(const Point* a, const Point* b) { + int c = a->x - b->x; + return c ? c : a->y - b->y; +} + +#define i_key Point +#define i_cmp point_cmp +#define i_is_forward +#define i_tag pnt +#include <stc/clist.h> + +#define i_key float +#define i_use_cmp // use < and == operators for comparison +#include <stc/clist.h> + +void MyStruct_drop(MyStruct* s); +#define i_type MyList +#define i_key MyStruct +#define i_keydrop MyStruct_drop // define drop function +#define i_no_clone // must explicitely exclude or define cloning support because of drop. +#include <stc/clist.h> + +void MyStruct_drop(MyStruct* s) { + clist_i32_drop(&s->intlist); + clist_pnt_drop(&s->pntlist); +} + + +int main(void) +{ + MyStruct my = {0}; + clist_i32_push_back(&my.intlist, 123); + clist_pnt_push_back(&my.pntlist, c_LITERAL(Point){123, 456}); + MyStruct_drop(&my); + + clist_pnt plist = c_init(clist_pnt, {{42, 14}, {32, 94}, {62, 81}}); + clist_pnt_sort(&plist); + + c_foreach (i, clist_pnt, plist) + printf(" (%d %d)", i.ref->x, i.ref->y); + puts(""); + clist_pnt_drop(&plist); + + + clist_float flist = c_init(clist_float, {123.3f, 321.2f, -32.2f, 78.2f}); + clist_float_sort(&flist); + + c_foreach (i, clist_float, flist) + printf(" %g", (double)*i.ref); + + puts(""); + clist_float_drop(&flist); +} diff --git a/misc/examples/make.sh b/misc/examples/make.sh index 0297e5a1..b362f275 100755 --- a/misc/examples/make.sh +++ b/misc/examples/make.sh @@ -1,20 +1,19 @@ #!/bin/sh if [ "$(uname)" = 'Linux' ]; then - sanitize='-fsanitize=address' + sanitize='-fsanitize=address -fsanitize=undefined -fsanitize-trap' clibs='-lm' # -pthread oflag='-o ' fi -cc=gcc; cflags="-s -O3 -std=c99 -Wconversion -Wpedantic -Wall -Wsign-compare -Wwrite-strings" -#cc=gcc; cflags="-g -std=c99 -Werror -Wfatal-errors -Wpedantic -Wall $sanitize" -#cc=tcc; cflags="-Wall -std=c99" -#cc=clang; cflags="-s -O2 -std=c99 -Werror -Wfatal-errors -Wpedantic -Wall -Wno-unused-function -Wsign-compare -Wwrite-strings" -#cc=gcc; cflags="-x c++ -s -O2 -Wall -std=c++20" -#cc=g++; cflags="-x c++ -s -O2 -Wall" -#cc=cl; cflags="-O2 -nologo -W3 -MD" -#cc=cl; cflags="-nologo -TP" -#cc=cl; cflags="-nologo -std:c11" +cc=gcc; cflags="-std=c99 -s -O3 -Wall -Wextra -Wpedantic -Wconversion -Wwrite-strings -Wdouble-promotion -Wno-unused-parameter -Wno-maybe-uninitialized -Wno-implicit-fallthrough -Wno-missing-field-initializers" +#cc=gcc; cflags="-std=c99 -g -Werror -Wfatal-errors -Wpedantic -Wall $sanitize" +#cc=tcc; cflags="-std=c99 -Wall" +#cc=clang; cflags="-std=c99 -s -O3 -Wall -Wextra -Wpedantic -Wconversion -Wwrite-strings -Wdouble-promotion -Wno-unused-parameter -Wno-unused-function -Wno-implicit-fallthrough -Wno-missing-field-initializers" +#cc=gcc; cflags="-x c++ -std=c++20 -O2 -s -Wall" +#cc=cl; cflags="-nologo -O2 -MD -W3 -wd4003" +#cc=cl; cflags="-nologo -TP -std:c++20 -wd4003" +#cc=cl; cflags="-nologo -std:c11 -wd4003" if [ "$cc" = "cl" ]; then oflag='/Fe:' @@ -38,18 +37,20 @@ else fi if [ $run = 0 ] ; then - for i in *.c ; do - echo $comp -I../../include $i $clibs $oflag$(basename $i .c).exe - $comp -I../../include $i $clibs $oflag$(basename $i .c).exe + for i in */*.c ; do + out=$(basename $i .c).exe + #out=$(dirname $i)/$(basename $i .c).exe + echo $comp -I../../include $i $clibs $oflag$out + $comp -I../../include $i $clibs $oflag$out done else - for i in *.c ; do + for i in */*.c ; do echo $comp -I../../include $i $clibs $comp -I../../include $i $clibs - if [ -f $(basename -s .c $i).exe ]; then ./$(basename -s .c $i).exe; fi - if [ -f ./a.exe ]; then ./a.exe; fi - if [ -f ./a.out ]; then ./a.out; fi + out=$(basename $i .c).exe + #out=$(dirname $i)/$(basename $i .c).exe + if [ -f $out ]; then ./$out; fi done fi -rm -f a.out *.o *.obj # *.exe +#rm -f a.out *.o *.obj # *.exe diff --git a/misc/examples/astar.c b/misc/examples/mixed/astar.c index 7dd12d50..d15a9ed7 100644 --- a/misc/examples/astar.c +++ b/misc/examples/mixed/astar.c @@ -4,6 +4,7 @@ // This is a reimplementation of the CTL example to STC: // https://github.com/glouw/ctl/blob/master/examples/astar.c // https://www.redblobgames.com/pathfinding/a-star/introduction.html +#define i_implement #include <stc/cstr.h> #include <stdio.h> @@ -19,7 +20,7 @@ point; point point_init(int x, int y, int width) { - return (point) { x, y, 0, width }; + return c_LITERAL(point){ x, y, 0, width }; } int @@ -55,12 +56,11 @@ point_key_cmp(const point* a, const point* b) return (i == j) ? 0 : (i < j) ? -1 : 1; } -#define i_val point +#define i_key point #define i_cmp point_cmp_priority #include <stc/cpque.h> -#define i_val point -#define i_opt c_no_cmp +#define i_key point #include <stc/cdeq.h> #define i_key point diff --git a/misc/examples/complex.c b/misc/examples/mixed/complex.c index 7dde981d..9fcbc417 100644 --- a/misc/examples/complex.c +++ b/misc/examples/mixed/complex.c @@ -5,17 +5,15 @@ // using StackList = std::stack<FloatStack>; // using ListMap = std::unordered_map<int, std::forward_list<StackList>>; // using MapMap = std::unordered_map<std::string, ListMap>; - +#define i_implement #include <stc/cstr.h> - #define i_type FloatStack -#define i_val float +#define i_key float #include <stc/cstack.h> #define i_type StackList -#define i_valclass FloatStack // "class" picks up _clone, _drop -#define i_opt c_no_cmp // no FloatStack_cmp() +#define i_keyclass FloatStack // "class" picks up _clone, _drop, _cmp #include <stc/clist.h> #define i_type ListMap @@ -29,7 +27,7 @@ #include <stc/cmap.h> -int main() +int main(void) { MapMap mmap = {0}; @@ -44,7 +42,7 @@ int main() const ListMap* lmap_p = MapMap_at(&mmap, "first"); const StackList* list_p = ListMap_at(lmap_p, 42); const FloatStack* stack_p = StackList_back(list_p); - printf("value is: %f\n", *FloatStack_at(stack_p, 3)); // pi + printf("value is: %f\n", (double)*FloatStack_at(stack_p, 3)); // pi MapMap_drop(&mmap); } diff --git a/misc/examples/convert.c b/misc/examples/mixed/convert.c index 0f09e830..fa64560e 100644 --- a/misc/examples/convert.c +++ b/misc/examples/mixed/convert.c @@ -1,17 +1,17 @@ +#define i_implement #include <stc/cstr.h> #define i_key_str #define i_val_str #include <stc/cmap.h> -#define i_val_str +#define i_key_str #include <stc/cvec.h> -#define i_val_str -#define i_extern // define _clist_mergesort() once +#define i_key_str #include <stc/clist.h> -int main() +int main(void) { cmap_str map, mclone; cvec_str keys = {0}, values = {0}; @@ -24,7 +24,7 @@ int main() cvec_str_drop(&values), clist_str_drop(&list) ){ - map = c_make(cmap_str, { + map = c_init(cmap_str, { {"green", "#00ff00"}, {"blue", "#0000ff"}, {"yellow", "#ffff00"}, diff --git a/misc/examples/demos.c b/misc/examples/mixed/demos.c index de92e378..43c9a7ae 100644 --- a/misc/examples/demos.c +++ b/misc/examples/mixed/demos.c @@ -1,6 +1,7 @@ +#define i_implement #include <stc/cstr.h> -void stringdemo1() +void stringdemo1(void) { cstr cs = cstr_lit("one-nine-three-seven-five"); printf("%s.\n", cstr_str(&cs)); @@ -27,34 +28,35 @@ void stringdemo1() cstr_drop(&cs); } -#define i_val int64_t +#define i_key long long #define i_tag ix #include <stc/cvec.h> -void vectordemo1() +void vectordemo1(void) { cvec_ix bignums = cvec_ix_with_capacity(100); cvec_ix_reserve(&bignums, 100); for (int i = 10; i <= 100; i += 10) cvec_ix_push(&bignums, i * i); - printf("erase - %d: %" PRIu64 "\n", 3, bignums.data[3]); + printf("erase - %d: %lld\n", 3, bignums.data[3]); cvec_ix_erase_n(&bignums, 3, 1); // erase index 3 cvec_ix_pop(&bignums); // erase the last cvec_ix_erase_n(&bignums, 0, 1); // erase the first for (int i = 0; i < cvec_ix_size(&bignums); ++i) { - printf("%d: %" PRIu64 "\n", i, bignums.data[i]); + printf("%d: %lld\n", i, bignums.data[i]); } cvec_ix_drop(&bignums); } -#define i_val_str +#define i_key_str +#define i_use_cmp #include <stc/cvec.h> -void vectordemo2() +void vectordemo2(void) { cvec_str names = {0}; cvec_str_emplace_back(&names, "Mary"); @@ -71,11 +73,12 @@ void vectordemo2() cvec_str_drop(&names); } -#define i_val int +#define i_key int #define i_tag ix +#define i_use_cmp #include <stc/clist.h> -void listdemo1() +void listdemo1(void) { clist_ix nums = {0}, nums2 = {0}; for (int i = 0; i < 10; ++i) @@ -107,7 +110,7 @@ void listdemo1() #define i_tag i #include <stc/cset.h> -void setdemo1() +void setdemo1(void) { cset_i nums = {0}; cset_i_insert(&nums, 8); @@ -123,7 +126,7 @@ void setdemo1() #define i_tag ii #include <stc/cmap.h> -void mapdemo1() +void mapdemo1(void) { cmap_ii nums = {0}; cmap_ii_insert(&nums, 8, 64); @@ -137,7 +140,7 @@ void mapdemo1() #define i_tag si #include <stc/cmap.h> -void mapdemo2() +void mapdemo2(void) { cmap_si nums = {0}; cmap_si_emplace_or_assign(&nums, "Hello", 64); @@ -159,7 +162,7 @@ void mapdemo2() #define i_val_str #include <stc/cmap.h> -void mapdemo3() +void mapdemo3(void) { cmap_str table = {0}; cmap_str_emplace(&table, "Map", "test"); @@ -179,7 +182,7 @@ void mapdemo3() cmap_str_drop(&table); // frees key and value cstrs, and hash table. } -int main() +int main(void) { printf("\nSTRINGDEMO1\n"); stringdemo1(); printf("\nVECTORDEMO1\n"); vectordemo1(); diff --git a/misc/examples/inits.c b/misc/examples/mixed/inits.c index 81bcdd3e..53a49f1f 100644 --- a/misc/examples/inits.c +++ b/misc/examples/mixed/inits.c @@ -1,3 +1,4 @@ +#define i_implement #include <stc/cstr.h> #define i_key int @@ -17,18 +18,17 @@ inline static int ipair_cmp(const ipair_t* a, const ipair_t* b) { } -#define i_val ipair_t +#define i_key ipair_t #define i_cmp ipair_cmp #define i_tag ip #include <stc/cvec.h> -#define i_val ipair_t +#define i_key ipair_t #define i_cmp ipair_cmp #define i_tag ip -#define i_extern // define _clist_mergesort() once #include <stc/clist.h> -#define i_val float +#define i_key float #define i_tag f #include <stc/cpque.h> @@ -45,7 +45,7 @@ int main(void) puts("\npop and show high priorites first:"); while (! cpque_f_empty(&floats)) { - printf("%.1f ", *cpque_f_top(&floats)); + printf("%.1f ", (double)*cpque_f_top(&floats)); cpque_f_pop(&floats); } puts("\n"); @@ -66,7 +66,7 @@ int main(void) // CMAP CNT - cmap_cnt countries = c_make(cmap_cnt, { + cmap_cnt countries = c_init(cmap_cnt, { {"Norway", 100}, {"Denmark", 50}, {"Iceland", 10}, @@ -88,7 +88,7 @@ int main(void) // CVEC PAIR - cvec_ip pairs1 = c_make(cvec_ip, {{5, 6}, {3, 4}, {1, 2}, {7, 8}}); + cvec_ip pairs1 = c_init(cvec_ip, {{5, 6}, {3, 4}, {1, 2}, {7, 8}}); cvec_ip_sort(&pairs1); c_foreach (i, cvec_ip, pairs1) @@ -98,7 +98,7 @@ int main(void) // CLIST PAIR - clist_ip pairs2 = c_make(clist_ip, {{5, 6}, {3, 4}, {1, 2}, {7, 8}}); + clist_ip pairs2 = c_init(clist_ip, {{5, 6}, {3, 4}, {1, 2}, {7, 8}}); clist_ip_sort(&pairs2); c_foreach (i, clist_ip, pairs2) diff --git a/misc/examples/read.c b/misc/examples/mixed/read.c index 4efdcfeb..de04fd31 100644 --- a/misc/examples/read.c +++ b/misc/examples/mixed/read.c @@ -1,19 +1,21 @@ +#define i_implement #include <stc/cstr.h> -#define i_val_str +#include <stc/algo/raii.h> +#define i_key_str #include <stc/cvec.h> #include <errno.h> cvec_str read_file(const char* name) { - cvec_str vec = cvec_str_init(); + cvec_str vec = {0}; c_with (FILE* f = fopen(name, "r"), fclose(f)) - c_with (cstr line = cstr_NULL, cstr_drop(&line)) + c_with (cstr line = {0}, cstr_drop(&line)) while (cstr_getline(&line, f)) cvec_str_push(&vec, cstr_clone(line)); return vec; } -int main() +int main(void) { int n = 0; c_with (cvec_str vec = read_file(__FILE__), cvec_str_drop(&vec)) diff --git a/misc/examples/multidim.c b/misc/examples/multidim.c deleted file mode 100644 index 3980e6d8..00000000 --- a/misc/examples/multidim.c +++ /dev/null @@ -1,68 +0,0 @@ -// Example based on https://en.cppreference.com/w/cpp/container/mdspan -#define i_val int -#include <stc/cstack.h> -#include <stc/cspan.h> -#include <stdio.h> - -using_cspan3(ispan, int); - -int main() -{ - cstack_int v = c_make(cstack_int, {1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24}); - - // View data as contiguous memory representing 24 ints - ispan ms1 = cspan_from(&v); - - // View the same data as a 3D array 2 x 3 x 4 - ispan3 ms3 = cspan_md(v.data, 2, 3, 4); - - puts("ms3:"); - for (int i=0; i != ms3.shape[0]; i++) { - for (int j=0; j != ms3.shape[1]; j++) { - for (int k=0; k != ms3.shape[2]; k++) { - printf(" %2d", *cspan_at(&ms3, i, j, k)); - } - puts(""); - } - puts(""); - } - puts("ss3 = ms3[:, 1:3, 1:3]"); - ispan3 ss3 = ms3; - //cspan_slice(&ss3, {c_ALL}, {1,3}, {1,3}); - ss3 = cspan_slice(ispan3, &ms3, {c_ALL}, {1,3}, {1,3}); - - for (int i=0; i != ss3.shape[0]; i++) { - for (int j=0; j != ss3.shape[1]; j++) { - for (int k=0; k != ss3.shape[2]; k++) { - printf(" %2d", *cspan_at(&ss3, i, j, k)); - } - puts(""); - } - puts(""); - } - - puts("Iterate ss3 flat:"); - c_foreach (i, ispan3, ss3) - printf(" %d", *i.ref); - puts(""); - - ispan2 ms2 = cspan_submd3(&ms3, 0); - - // write data using 2D view - for (int i=0; i != ms2.shape[0]; i++) - for (int j=0; j != ms2.shape[1]; j++) - *cspan_at(&ms2, i, j) = i*1000 + j; - - puts("\nview data as 1D view:"); - for (int i=0; i != cspan_size(&ms1); i++) - printf(" %d", *cspan_at(&ms1, i)); - puts(""); - - puts("iterate subspan ms3[1]:"); - ispan2 sub = cspan_submd3(&ms3, 1); - c_foreach (i, ispan2, sub) - printf(" %d", *i.ref); - puts(""); - - cstack_int_drop(&v); -} diff --git a/misc/examples/new_list.c b/misc/examples/new_list.c deleted file mode 100644 index 8b291d34..00000000 --- a/misc/examples/new_list.c +++ /dev/null @@ -1,68 +0,0 @@ -#include <stdio.h> -#include <stc/forward.h> - -forward_clist(clist_i32, int); -forward_clist(clist_pnt, struct Point); - -typedef struct { - clist_i32 intlst; - clist_pnt pntlst; -} MyStruct; - -#define i_val int -#define i_tag i32 -#define i_is_forward -#include <stc/clist.h> - -typedef struct Point { int x, y; } Point; -int point_cmp(const Point* a, const Point* b) { - int c = a->x - b->x; - return c ? c : a->y - b->y; -} - -#define i_val Point -#define i_cmp point_cmp -#define i_is_forward -#define i_tag pnt -#include <stc/clist.h> - -#define i_val float -#include <stc/clist.h> - -void MyStruct_drop(MyStruct* s); -#define i_type MyList -#define i_valclass MyStruct // i_valclass uses MyStruct_drop -#define i_opt c_no_clone|c_no_cmp -#include <stc/clist.h> - -void MyStruct_drop(MyStruct* s) { - clist_i32_drop(&s->intlst); - clist_pnt_drop(&s->pntlst); -} - - -int main() -{ - MyStruct my = {0}; - clist_i32_push_back(&my.intlst, 123); - clist_pnt_push_back(&my.pntlst, (Point){123, 456}); - MyStruct_drop(&my); - - clist_pnt plst = c_make(clist_pnt, {{42, 14}, {32, 94}, {62, 81}}); - clist_pnt_sort(&plst); - - c_foreach (i, clist_pnt, plst) - printf(" (%d %d)", i.ref->x, i.ref->y); - puts(""); - clist_pnt_drop(&plst); - - - clist_float flst = c_make(clist_float, {123.3f, 321.2f, -32.2f, 78.2f}); - clist_float_sort(&flst); - - c_foreach (i, clist_float, flst) - printf(" %g", *i.ref); - - puts(""); - clist_float_drop(&flst); -} diff --git a/misc/examples/printspan.c b/misc/examples/printspan.c deleted file mode 100644 index 7459ac77..00000000 --- a/misc/examples/printspan.c +++ /dev/null @@ -1,57 +0,0 @@ -// printspan.c - -#include <stdio.h> -#include <stc/cstr.h> -#define i_val int -#include <stc/cvec.h> -#define i_val int -#include <stc/cstack.h> -#define i_val int -#include <stc/cdeq.h> -#define i_val_str -#include <stc/csset.h> -#include <stc/cspan.h> - -using_cspan(intspan, int, 1); - -void printMe(intspan container) { - printf("%d:", (int)cspan_size(&container)); - c_foreach (e, intspan, container) - printf(" %d", *e.ref); - puts(""); -} - -int main() -{ - intspan sp1 = cspan_make(intspan, {1, 2}); - printMe( sp1 ); - - printMe( c_make(intspan, {1, 2, 3}) ); - - int arr[] = {1, 2, 3, 4, 5, 6}; - intspan sp2 = cspan_from_array(arr); - printMe( (intspan)cspan_subspan(&sp2, 1, 4) ); - - cvec_int vec = c_make(cvec_int, {1, 2, 3, 4, 5}); - printMe( (intspan)cspan_from(&vec) ); - - printMe( sp2 ); - - cstack_int stk = c_make(cstack_int, {1, 2, 3, 4, 5, 6, 7}); - printMe( (intspan)cspan_from(&stk) ); - - cdeq_int deq = c_make(cdeq_int, {1, 2, 3, 4, 5, 6, 7, 8}); - printMe( (intspan)cspan_from(&deq) ); - - csset_str set = c_make(csset_str, {"5", "7", "4", "3", "8", "2", "1", "9", "6"}); - printf("%d:", (int)csset_str_size(&set)); - c_foreach (e, csset_str, set) - printf(" %s", cstr_str(e.ref)); - puts(""); - - // cleanup - cvec_int_drop(&vec); - cstack_int_drop(&stk); - cdeq_int_drop(&deq); - csset_str_drop(&set); -} diff --git a/misc/examples/functor.c b/misc/examples/priorityqueues/functor.c index c0a4f8e8..e3bde1dd 100644 --- a/misc/examples/functor.c +++ b/misc/examples/priorityqueues/functor.c @@ -1,22 +1,22 @@ // Implements c++ example: https://en.cppreference.com/w/cpp/container/priority_queue // Example of per-instance less-function on a single priority queue type // -// Note: i_less: has self for cpque types only -// i_cmp: has self for csmap and csset types only -// i_hash/i_eq: has self for cmap and cset types only #include <stdio.h> #define i_type IPQue -#define i_val int -#define i_extend bool (*less)(const int*, const int*); -#define i_less(x, y) c_getcon(self)->less(x, y) -#define i_con cpque +#define i_base cpque +#define i_key int +#define i_extend bool(*less)(const int*, const int*); +#define i_less(x, y) c_extend()->less(x, y) +// Note: i_less: c_extend() accessible for cpque types +// i_cmp: c_extend() accessible for csmap and csset types +// i_hash/i_eq: c_extend() accessible for cmap and cset types #include <stc/extend.h> void print_queue(const char* name, IPQue_ext q) { // NB: make a clone because there is no way to traverse - // priority_queue's content without erasing the queue. + // priority queue's content without erasing the queue. IPQue_ext copy = {q.less, IPQue_clone(q.get)}; for (printf("%s: \t", name); !IPQue_empty(©.get); IPQue_pop(©.get)) @@ -30,28 +30,27 @@ static bool int_less(const int* x, const int* y) { return *x < *y; } static bool int_greater(const int* x, const int* y) { return *x > *y; } static bool int_lambda(const int* x, const int* y) { return (*x ^ 1) < (*y ^ 1); } -int main() +int main(void) { const int data[] = {1,8,5,6,3,4,0,9,7,2}, n = c_arraylen(data); printf("data: \t"); - c_forrange (i, n) - printf("%d ", data[i]); + c_forrange (i, n) printf("%d ", data[i]); puts(""); - IPQue_ext q1 = {int_less}; // Max priority queue - IPQue_ext minq1 = {int_greater}; // Min priority queue - IPQue_ext q5 = {int_lambda}; // Using lambda to compare elements. - c_forrange (i, n) - IPQue_push(&q1.get, data[i]); + // Max priority queue + IPQue_ext q1 = {.less=int_less}; + IPQue_put_n(&q1.get, data, n); print_queue("q1", q1); - c_forrange (i, n) - IPQue_push(&minq1.get, data[i]); + // Min priority queue + IPQue_ext minq1 = {.less=int_greater}; + IPQue_put_n(&minq1.get, data, n); print_queue("minq1", minq1); - c_forrange (i, n) - IPQue_push(&q5.get, data[i]); + // Using lambda to compare elements. + IPQue_ext q5 = {.less=int_lambda}; + IPQue_put_n(&q5.get, data, n); print_queue("q5", q5); c_drop(IPQue, &q1.get, &minq1.get, &q5.get); diff --git a/misc/examples/new_pque.c b/misc/examples/priorityqueues/new_pque.c index 9147e3f2..16823bb6 100644 --- a/misc/examples/new_pque.c +++ b/misc/examples/priorityqueues/new_pque.c @@ -1,16 +1,16 @@ #include <stdio.h> -struct Point { int x, y; } typedef Point; +typedef struct Point { int x, y; } Point; #define i_type PointQ -#define i_val Point +#define i_key Point #define i_less(a, b) a->x < b->x || (a->x == b->x && a->y < b->y) #include <stc/cpque.h> -int main() +int main(void) { - PointQ pque = c_make(PointQ, {{23, 80}, {12, 32}, {54, 74}, {12, 62}}); + PointQ pque = c_init(PointQ, {{23, 80}, {12, 32}, {54, 74}, {12, 62}}); // print for (; !PointQ_empty(&pque); PointQ_pop(&pque)) { diff --git a/misc/examples/priority.c b/misc/examples/priorityqueues/priority.c index 95dd3183..18684e73 100644 --- a/misc/examples/priority.c +++ b/misc/examples/priorityqueues/priority.c @@ -3,29 +3,29 @@ #include <time.h> #include <stc/crand.h> -#define i_val int64_t +#define i_key int64_t #define i_cmp -c_default_cmp // min-heap (increasing values) #define i_tag i #include <stc/cpque.h> -int main() { +int main(void) { intptr_t N = 10000000; crand_t rng = crand_init((uint64_t)time(NULL)); - crand_unif_t dist = crand_unif_init(0, N * 10); + crand_uniform_t dist = crand_uniform_init(0, N * 10); cpque_i heap = {0}; // Push ten million random numbers to priority queue printf("Push %" c_ZI " numbers\n", N); c_forrange (N) - cpque_i_push(&heap, crand_unif(&rng, &dist)); + cpque_i_push(&heap, crand_uniform(&rng, &dist)); // push some negative numbers too. c_forlist (i, int, {-231, -32, -873, -4, -343}) cpque_i_push(&heap, *i.ref); c_forrange (N) - cpque_i_push(&heap, crand_unif(&rng, &dist)); + cpque_i_push(&heap, crand_uniform(&rng, &dist)); puts("Extract the hundred smallest."); c_forrange (100) { diff --git a/misc/examples/new_queue.c b/misc/examples/queues/new_queue.c index 916f4dbc..3904c50c 100644 --- a/misc/examples/new_queue.c +++ b/misc/examples/queues/new_queue.c @@ -5,37 +5,37 @@ forward_cqueue(cqueue_pnt, struct Point); -struct Point { int x, y; } typedef Point; +typedef struct Point { int x, y; } Point; int point_cmp(const Point* a, const Point* b) { int c = c_default_cmp(&a->x, &b->x); return c ? c : c_default_cmp(&a->y, &b->y); } -#define i_val Point +#define i_key Point #define i_cmp point_cmp #define i_is_forward #define i_tag pnt #include <stc/cqueue.h> #define i_type IQ -#define i_val int +#define i_key int #include <stc/cqueue.h> -int main() { +int main(void) { int n = 50000000; crand_t rng = crand_init((uint64_t)time(NULL)); - crand_unif_t dist = crand_unif_init(0, n); + crand_uniform_t dist = crand_uniform_init(0, n); IQ Q = {0}; // Push 50'000'000 random numbers onto the queue. c_forrange (n) - IQ_push(&Q, (int)crand_unif(&rng, &dist)); + IQ_push(&Q, (int)crand_uniform(&rng, &dist)); // Push or pop on the queue 50 million times printf("befor: size %" c_ZI ", capacity %" c_ZI "\n", IQ_size(&Q), IQ_capacity(&Q)); c_forrange (n) { - int r = (int)crand_unif(&rng, &dist); + int r = (int)crand_uniform(&rng, &dist); if (r & 3) IQ_push(&Q, r); else diff --git a/misc/examples/queue.c b/misc/examples/queues/queue.c index 83c18d09..5b1f7606 100644 --- a/misc/examples/queue.c +++ b/misc/examples/queues/queue.c @@ -1,26 +1,26 @@ #include <stc/crand.h> #include <stdio.h> -#define i_val int +#define i_key int #define i_tag i #include <stc/cqueue.h> -int main() { - int n = 100000000; - crand_unif_t dist; +int main(void) { + int n = 1000000; + crand_uniform_t dist; crand_t rng = crand_init(1234); - dist = crand_unif_init(0, n); + dist = crand_uniform_init(0, n); cqueue_i queue = {0}; // Push ten million random numbers onto the queue. c_forrange (n) - cqueue_i_push(&queue, (int)crand_unif(&rng, &dist)); + cqueue_i_push(&queue, (int)crand_uniform(&rng, &dist)); // Push or pop on the queue ten million times printf("%d\n", n); c_forrange (n) { // forrange uses initial n only. - int r = (int)crand_unif(&rng, &dist); + int r = (int)crand_uniform(&rng, &dist); if (r & 1) ++n, cqueue_i_push(&queue, r); else diff --git a/misc/examples/random.c b/misc/examples/random.c deleted file mode 100644 index ea9c483e..00000000 --- a/misc/examples/random.c +++ /dev/null @@ -1,45 +0,0 @@ -#include <stdio.h> -#include <time.h> -#include <stc/crand.h> - -int main() -{ - const size_t N = 1000000000; - const uint64_t seed = (uint64_t)time(NULL), range = 1000000; - crand_t rng = crand_init(seed); - - int64_t sum; - clock_t diff, before; - - printf("Compare speed of full and unbiased ranged random numbers...\n"); - sum = 0; - before = clock(); - c_forrange (N) { - sum += (uint32_t)crand_u64(&rng); - } - diff = clock() - before; - printf("full range\t\t: %f secs, %" c_ZI ", avg: %f\n", - (float)diff / CLOCKS_PER_SEC, N, (float)sum / (float)N); - - crand_unif_t dist1 = crand_unif_init(0, range); - rng = crand_init(seed); - sum = 0; - before = clock(); - c_forrange (N) { - sum += crand_unif(&rng, &dist1); // unbiased - } - diff = clock() - before; - printf("unbiased 0-%" PRIu64 "\t: %f secs, %" c_ZI ", avg: %f\n", - range, (float)diff/CLOCKS_PER_SEC, N, (float)sum / (float)N); - - sum = 0; - rng = crand_init(seed); - before = clock(); - c_forrange (N) { - sum += (int64_t)(crand_u64(&rng) % (range + 1)); // biased - } - diff = clock() - before; - printf("biased 0-%" PRIu64 " \t: %f secs, %" c_ZI ", avg: %f\n", - range, (float)diff / CLOCKS_PER_SEC, N, (float)sum / (float)N); - -} diff --git a/misc/examples/rawptr_elements.c b/misc/examples/rawptr_elements.c deleted file mode 100644 index 01bcdc44..00000000 --- a/misc/examples/rawptr_elements.c +++ /dev/null @@ -1,59 +0,0 @@ -#include <stc/ccommon.h> -#include <stdio.h> - -#include <stc/cstr.h> - -// Create cmap of cstr => long* -#define i_type SIPtrMap -#define i_key_str -#define i_val long* -#define i_valraw long -#define i_valfrom(raw) c_new(long, raw) -#define i_valto(x) **x -#define i_valclone(x) c_new(long, *x) -#define i_valdrop(x) c_free(*x) -#include <stc/cmap.h> - -// Alternatively, using cbox: -#define i_type IBox -#define i_val long -#include <stc/cbox.h> // unique_ptr<long> alike. - -// cmap of cstr => IBox -#define i_type SIBoxMap -#define i_key_str -#define i_valboxed IBox // i_valboxed: use properties from IBox automatically -#include <stc/cmap.h> - -int main() -{ - // These have the same behaviour, except IBox has a get member: - SIPtrMap map1 = {0}; - SIBoxMap map2 = {0}; - - printf("\nMap cstr => long*:\n"); - SIPtrMap_insert(&map1, cstr_from("Test1"), c_new(long, 1)); - SIPtrMap_insert(&map1, cstr_from("Test2"), c_new(long, 2)); - - // Emplace implicitly creates cstr from const char* and an owned long* from long! - SIPtrMap_emplace(&map1, "Test3", 3); - SIPtrMap_emplace(&map1, "Test4", 4); - - c_forpair (name, number, SIPtrMap, map1) - printf("%s: %ld\n", cstr_str(_.name), **_.number); - - puts("\nMap cstr => IBox:"); - SIBoxMap_insert(&map2, cstr_from("Test1"), IBox_make(1)); - SIBoxMap_insert(&map2, cstr_from("Test2"), IBox_make(2)); - - // Emplace implicitly creates cstr from const char* and IBox from long! - SIBoxMap_emplace(&map2, "Test3", 3); - SIBoxMap_emplace(&map2, "Test4", 4); - - c_forpair (name, number, SIBoxMap, map2) - printf("%s: %ld\n", cstr_str(_.name), *_.number->get); - puts(""); - - SIPtrMap_drop(&map1); - SIBoxMap_drop(&map2); -} diff --git a/misc/examples/regex1.c b/misc/examples/regularexpressions/regex1.c index 4a56b8ac..d8032358 100644 --- a/misc/examples/regex1.c +++ b/misc/examples/regularexpressions/regex1.c @@ -1,4 +1,4 @@ -#define i_extern +#define i_import #include <stc/cregex.h> int main(int argc, char* argv[]) diff --git a/misc/examples/regex2.c b/misc/examples/regularexpressions/regex2.c index 3133f7c2..a798b1a1 100644 --- a/misc/examples/regex2.c +++ b/misc/examples/regularexpressions/regex2.c @@ -1,7 +1,7 @@ -#define i_extern +#define i_import #include <stc/cregex.h> -int main() +int main(void) { struct { const char *pattern, *input; } s[] = { {"(\\d\\d\\d\\d)[-_](1[0-2]|0[1-9])[-_](3[01]|[12][0-9]|0[1-9])", @@ -26,7 +26,7 @@ int main() printf("\ninput: %s\n", s[i].input); c_formatch (j, &re, s[i].input) { - c_forrange (k, cregex_captures(&re)) + c_forrange (k, cregex_captures(&re) + 1) printf(" submatch %lld: %.*s\n", k, c_SV(j.match[k])); } } diff --git a/misc/examples/regex_match.c b/misc/examples/regularexpressions/regex_match.c index def0ae7a..9106ffbd 100644 --- a/misc/examples/regex_match.c +++ b/misc/examples/regularexpressions/regex_match.c @@ -1,11 +1,12 @@ -#define i_extern +#define i_import #include <stc/cregex.h> +#define i_implement #include <stc/csview.h> -#define i_val float +#define i_key float #include <stc/cstack.h> -int main() +int main(void) { // Lets find the first sequence of digits in a string const char *str = "Hello numeric world, there are 24 hours in a day, 3600 seconds in an hour." @@ -21,13 +22,13 @@ int main() // extract and convert all numbers in str to floats c_formatch (i, &re, str) - cstack_float_push(&vec, (float)atof(i.match[0].str)); + cstack_float_push(&vec, (float)atof(i.match[0].buf)); c_foreach (i, cstack_float, vec) - printf(" %g\n", *i.ref); + printf(" %g\n", (double)*i.ref); // extracts the numbers only to a comma separated string. - cstr nums = cregex_replace_sv(&re, csview_from(str), " $0,", 0, NULL, CREG_R_STRIP); + cstr nums = cregex_replace_sv(&re, csview_from(str), " $0,", 0, NULL, CREG_STRIP); printf("\n%s\n", cstr_str(&nums)); cstr_drop(&nums); diff --git a/misc/examples/regex_replace.c b/misc/examples/regularexpressions/regex_replace.c index d3952f50..087387d7 100644 --- a/misc/examples/regex_replace.c +++ b/misc/examples/regularexpressions/regex_replace.c @@ -1,18 +1,18 @@ -#define i_extern +#define i_import #include <stc/cregex.h> #include <stc/csview.h> bool add_10_years(int i, csview match, cstr* out) { if (i == 1) { // group 1 matches year int year; - sscanf(match.str, "%4d", &year); // scan 4 chars only + sscanf(match.buf, "%4d", &year); // scan 4 chars only cstr_printf(out, "%04d", year + 10); return true; } return false; } -int main() +int main(void) { const char* pattern = "\\b(\\d\\d\\d\\d)-(1[0-2]|0[1-9])-(3[01]|[12][0-9]|0[1-9])\\b"; const char* input = "start date: 2015-12-31, end date: 2022-02-28"; @@ -47,7 +47,7 @@ int main() printf("euros: %s\n", cstr_str(&str)); /* Strip out everything but the matches */ - cstr_take(&str, cregex_replace_sv(&re, csview_from(input), "$3.$2.$1;", 0, NULL, CREG_R_STRIP)); + cstr_take(&str, cregex_replace_sv(&re, csview_from(input), "$3.$2.$1;", 0, NULL, CREG_STRIP)); printf("strip: %s\n", cstr_str(&str)); /* Wrap all words in ${} */ diff --git a/misc/examples/sidebyside.cpp b/misc/examples/sidebyside.cpp deleted file mode 100644 index a7c1008c..00000000 --- a/misc/examples/sidebyside.cpp +++ /dev/null @@ -1,57 +0,0 @@ -#include <iostream> -#include <map> -#include <string> -#include <stc/cstr.h> - -#define i_type IIMap -#define i_key int -#define i_val int -#include <stc/csmap.h> - -#define i_type SIMap -#define i_key_str -#define i_val int -#include <stc/cmap.h> - -int main() { - { - std::map<int, int> hist; - hist.emplace(12, 100).first->second += 1; - hist.emplace(13, 100).first->second += 1; - hist.emplace(12, 100).first->second += 1; - - for (auto i: hist) - std::cout << i.first << ", " << i.second << std::endl; - std::cout << std::endl; - } - { - IIMap hist = {0}; - IIMap_insert(&hist, 12, 100).ref->second += 1; - IIMap_insert(&hist, 13, 100).ref->second += 1; - IIMap_insert(&hist, 12, 100).ref->second += 1; - - c_foreach (i, IIMap, hist) - printf("%d, %d\n", i.ref->first, i.ref->second); - puts(""); - IIMap_drop(&hist); - } - // =================================================== - { - std::map<std::string, int> food = - {{"burger", 5}, {"pizza", 12}, {"steak", 15}}; - - for (auto i: food) - std::cout << i.first << ", " << i.second << std::endl; - std::cout << std::endl; - } - { - SIMap food = {0}; - c_forlist (i, SIMap_raw, {{"burger", 5}, {"pizza", 12}, {"steak", 15}}) - SIMap_emplace(&food, i.ref->first, i.ref->second); - - c_foreach (i, SIMap, food) - printf("%s, %d\n", cstr_str(&i.ref->first), i.ref->second); - puts(""); - SIMap_drop(&food); - } -} diff --git a/misc/examples/arc_containers.c b/misc/examples/smartpointers/arc_containers.c index 84ba8dda..79211d2b 100644 --- a/misc/examples/arc_containers.c +++ b/misc/examples/smartpointers/arc_containers.c @@ -1,6 +1,6 @@ // Create a stack and a list of shared pointers to maps, // and demonstrate sharing and cloning of maps. -#define i_static +#define i_implement #include <stc/cstr.h> #define i_type Map #define i_key_str // strings @@ -9,23 +9,21 @@ #include <stc/csmap.h> #define i_type Arc // (atomic) ref. counted type -#define i_val Map -#define i_valdrop(p) (printf("drop Arc:\n"), Map_drop(p)) +#define i_key Map +#define i_keydrop(p) (printf("drop Arc:\n"), Map_drop(p)) // no need for atomic ref. count in single thread: -#define i_opt c_no_atomic|c_no_cmp|c_no_clone +#define i_opt c_no_atomic #include <stc/carc.h> #define i_type Stack -#define i_valboxed Arc // define i_valboxed for carc/cbox value (not i_val) -#define i_opt c_no_cmp +#define i_keyboxed Arc // use i_keyboxed for carc/cbox key #include <stc/cvec.h> #define i_type List -#define i_valboxed Arc // as above -#define i_opt c_no_cmp +#define i_keyboxed Arc // as above #include <stc/clist.h> -int main() +int main(void) { Stack stack = {0}; List list = {0}; diff --git a/misc/examples/arc_demo.c b/misc/examples/smartpointers/arc_demo.c index 2339adbb..a66d84b0 100644 --- a/misc/examples/arc_demo.c +++ b/misc/examples/smartpointers/arc_demo.c @@ -6,27 +6,32 @@ void int_drop(int* x) { } // carc implements its own clone method using reference counting, -// so 'i_valclone' is not required to be defined (ignored). +// so 'i_keyclone' is not required to be defined (ignored). #define i_type Arc // set type name to be defined (instead of 'carc_int') -#define i_val int -#define i_valdrop int_drop // optional, just to display the elements destroyed -#define i_no_clone // required because of valdrop +#define i_key int +#define i_keydrop int_drop // optional, just to display the elements destroyed +#define i_use_cmp // use int comparison (x < y, x == y). #include <stc/carc.h> // Arc -#define i_keyboxed Arc // note: use i_keyboxed instead of i_key for carc/cbox elements +#define i_keyboxed Arc // note: use i_keyboxed instead of i_key for carc/cbox elements #include <stc/csset.h> // csset_Arc (like: std::set<std::shared_ptr<int>>) -#define i_valboxed Arc // note: as above. +#define i_keyboxed Arc // note: as above. +#define i_use_cmp #include <stc/cvec.h> // cvec_Arc (like: std::vector<std::shared_ptr<int>>) -int main() +int main(void) { const int years[] = {2021, 2012, 2022, 2015}; cvec_Arc vec = {0}; - c_forrange (i, c_arraylen(years)) - cvec_Arc_push(&vec, Arc_from(years[i])); + c_forrange (i, c_arraylen(years)) { + cvec_Arc_emplace(&vec, years[i]); + // cvec_Arc_push(&vec, Arc_from(years[i])); // alt. + } + + cvec_Arc_sort(&vec); printf("vec:"); c_foreach (i, cvec_Arc, vec) diff --git a/misc/examples/arcvec_erase.c b/misc/examples/smartpointers/arcvec_erase.c index 3bf41559..0526b6a0 100644 --- a/misc/examples/arcvec_erase.c +++ b/misc/examples/smartpointers/arcvec_erase.c @@ -3,23 +3,25 @@ void show_drop(int* x) { printf("drop: %d\n", *x); } #define i_type Arc -#define i_val int -#define i_valdrop show_drop -#define i_no_clone // required because of valdrop +#define i_key int +#define i_keydrop show_drop +#define i_use_cmp // enable sort/search for int type #include <stc/carc.h> // Shared pointer to int #define i_type Vec -#define i_valboxed Arc +#define i_keyboxed Arc +#define i_use_cmp #include <stc/cvec.h> // Vec: cvec<Arc> -int main() +int main(void) { - Vec vec = c_make(Vec, {2012, 1990, 2012, 2019, 2015}); + Vec vec = c_init(Vec, {2012, 1990, 2012, 2019, 2015}); // clone the second 2012 and push it back. // note: cloning make sure that vec.data[2] has ref count 2. - Vec_push(&vec, Arc_clone(vec.data[2])); + Vec_push(&vec, Arc_clone(vec.data[2])); // => share vec.data[2] + Vec_emplace(&vec, *vec.data[2].get); // => deep-copy vec.data[2] printf("vec before erase :"); c_foreach (i, Vec, vec) diff --git a/misc/examples/box.c b/misc/examples/smartpointers/box.c index 9954883c..5c8018d4 100644 --- a/misc/examples/box.c +++ b/misc/examples/smartpointers/box.c @@ -1,10 +1,11 @@ /* cbox: heap allocated boxed type */ +#define i_implement #include <stc/cstr.h> typedef struct { cstr name, last; } Person; Person Person_make(const char* name, const char* last) { - return (Person){.name = cstr_from(name), .last = cstr_from(last)}; + return c_LITERAL(Person){.name = cstr_from(name), .last = cstr_from(last)}; } uint64_t Person_hash(const Person* a) { @@ -28,14 +29,15 @@ void Person_drop(Person* p) { } #define i_type PBox -#define i_valclass Person // "class" binds _cmp, _clone, _drop functions. +#define i_keyclass Person // "class" binds _cmp, _clone, _drop functions. +#define i_use_cmp #include <stc/cbox.h> #define i_type Persons -#define i_valboxed PBox // "arcbox" informs that PBox is a smart pointer. +#define i_keyboxed PBox // "arcbox" informs that PBox is a smart pointer. #include <stc/csset.h> -int main() +int main(void) { Persons vec = {0}; PBox p = PBox_from(Person_make("Laura", "Palmer")); diff --git a/misc/examples/box2.c b/misc/examples/smartpointers/box2.c index cba255d2..9b782c74 100644 --- a/misc/examples/box2.c +++ b/misc/examples/smartpointers/box2.c @@ -13,27 +13,24 @@ typedef struct { Point bottom_right; } Rectangle; -#define i_val Point -#define i_no_cmp +#define i_key Point #include <stc/cbox.h> // cbox_Point -#define i_val Rectangle -#define i_no_cmp +#define i_key Rectangle #include <stc/cbox.h> // cbox_Rectangle // Box in box: -#define i_valboxed cbox_Point // NB: use i_valboxed when value is a cbox or carc! #define i_type BoxBoxPoint -#define i_no_cmp +#define i_keyboxed cbox_Point // NB: use i_keyboxed when value is a cbox or carc! #include <stc/cbox.h> // BoxBoxPoint Point origin(void) { - return (Point){ .x=1.0, .y=2.0 }; + return c_LITERAL(Point){ .x=1.0, .y=2.0 }; } cbox_Point boxed_origin(void) { // Allocate this point on the heap, and return a pointer to it - return cbox_Point_make((Point){ .x=1.0, .y=2.0 }); + return cbox_Point_make(c_LITERAL(Point){ .x=1.0, .y=2.0 }); } @@ -46,7 +43,7 @@ int main(void) { }; // Heap allocated rectangle - cbox_Rectangle boxed_rectangle = cbox_Rectangle_make((Rectangle){ + cbox_Rectangle boxed_rectangle = cbox_Rectangle_make(c_LITERAL(Rectangle){ .top_left = origin(), .bottom_right = { .x=3.0, .y=-4.0 } }); diff --git a/misc/examples/smartpointers/map_box.c b/misc/examples/smartpointers/map_box.c new file mode 100644 index 00000000..f651b302 --- /dev/null +++ b/misc/examples/smartpointers/map_box.c @@ -0,0 +1,34 @@ +#include <stc/ccommon.h> +#include <stdio.h> +#define i_implement +#include <stc/cstr.h> + +#define i_type IBox +#define i_key long +#include <stc/cbox.h> // unique_ptr<long> alike. + +// cmap of cstr => IBox +#define i_type Boxmap +#define i_key_str +#define i_valboxed IBox // i_valboxed: use properties from IBox automatically +#include <stc/cmap.h> + + +int main(void) +{ + Boxmap map = {0}; + + puts("Map cstr => IBox:"); + Boxmap_insert(&map, cstr_from("Test1"), IBox_make(1)); + Boxmap_insert(&map, cstr_from("Test2"), IBox_make(2)); + + // Simpler: emplace() implicitly creates cstr from const char* and IBox from long! + Boxmap_emplace(&map, "Test3", 3); + Boxmap_emplace(&map, "Test4", 4); + + c_forpair (name, number, Boxmap, map) + printf("%s: %ld\n", cstr_str(_.name), *_.number->get); + puts(""); + + Boxmap_drop(&map); +} diff --git a/misc/examples/smartpointers/map_ptr.c b/misc/examples/smartpointers/map_ptr.c new file mode 100644 index 00000000..453322c5 --- /dev/null +++ b/misc/examples/smartpointers/map_ptr.c @@ -0,0 +1,34 @@ +#include <stc/ccommon.h> +#include <stdio.h> +#define i_implement +#include <stc/cstr.h> + +// cmap of cstr => long* +#define i_type Ptrmap +#define i_key_str +#define i_val long* +#define i_valraw long +#define i_valfrom(raw) c_new(long, raw) +#define i_valto(x) **x +#define i_valclone(x) c_new(long, *x) +#define i_valdrop(x) c_free(*x) +#include <stc/cmap.h> + +int main(void) +{ + Ptrmap map = {0}; + + puts("Map cstr => long*:"); + Ptrmap_insert(&map, cstr_from("Test1"), c_new(long, 1)); + Ptrmap_insert(&map, cstr_from("Test2"), c_new(long, 2)); + + // Simple: emplace() implicitly creates cstr from const char* and an owned long* from long! + Ptrmap_emplace(&map, "Test3", 3); + Ptrmap_emplace(&map, "Test4", 4); + + c_forpair (name, number, Ptrmap, map) + printf("%s: %ld\n", cstr_str(_.name), **_.number); + puts(""); + + Ptrmap_drop(&map); +} diff --git a/misc/examples/music_arc.c b/misc/examples/smartpointers/music_arc.c index 3714e1d5..e9ebbbfe 100644 --- a/misc/examples/music_arc.c +++ b/misc/examples/smartpointers/music_arc.c @@ -1,5 +1,6 @@ // shared_ptr-examples.cpp // based on https://docs.microsoft.com/en-us/cpp/cpp/how-to-create-and-use-shared-ptr-instances?view=msvc-160 +#define i_implement #include <stc/cstr.h> typedef struct @@ -11,8 +12,8 @@ typedef struct int Song_cmp(const Song* x, const Song* y) { return cstr_cmp(&x->title, &y->title); } -Song Song_make(const char* artist, const char* title) - { return (Song){cstr_from(artist), cstr_from(title)}; } +Song Song_init(const char* artist, const char* title) + { return c_LITERAL(Song){cstr_from(artist), cstr_from(title)}; } void Song_drop(Song* s) { printf("drop: %s\n", cstr_str(&s->title)); @@ -21,21 +22,21 @@ void Song_drop(Song* s) { // Define the shared pointer: #define i_type SongArc -#define i_valclass Song -#define i_opt c_no_hash // arc require hash fn, disable as we don't need it. +#define i_keyclass Song +#define i_opt c_use_cmp|c_no_hash #include <stc/carc.h> // ... and a vector of them #define i_type SongVec -#define i_valboxed SongArc // use i_valboxed on carc / cbox instead of i_val -#include <stc/cstack.h> +#define i_keyboxed SongArc // use i_keyboxed on carc / cbox (instead of i_key) +#include <stc/cvec.h> -void example3() +void example3(void) { - SongVec vec1 = c_make(SongVec, { - Song_make("Bob Dylan", "The Times They Are A Changing"), - Song_make("Aretha Franklin", "Bridge Over Troubled Water"), - Song_make("Thalia", "Entre El Mar y Una Estrella") + SongVec vec1 = c_init(SongVec, { + Song_init("Bob Dylan", "The Times They Are A Changing"), + Song_init("Aretha Franklin", "Bridge Over Troubled Water"), + Song_init("Thalia", "Entre El Mar y Una Estrella") }); SongVec vec2 = {0}; @@ -46,8 +47,8 @@ void example3() // Add a few more to vec2. We can use emplace when creating new entries // Emplace calls SongArc_from() on the argument to create the Arc: - SongVec_emplace(&vec2, Song_make("Michael Jackson", "Billie Jean")); - SongVec_emplace(&vec2, Song_make("Rihanna", "Stay")); + SongVec_emplace(&vec2, Song_init("Michael Jackson", "Billie Jean")); + SongVec_emplace(&vec2, Song_init("Rihanna", "Stay")); // We now have two vectors with some shared, some unique entries. c_forlist (i, SongVec, {vec1, vec2}) { @@ -60,7 +61,7 @@ void example3() c_drop(SongVec, &vec1, &vec2); } -int main() +int main(void) { example3(); -} +}
\ No newline at end of file diff --git a/misc/examples/new_sptr.c b/misc/examples/smartpointers/new_sptr.c index 1b72e4f5..50e28ae2 100644 --- a/misc/examples/new_sptr.c +++ b/misc/examples/smartpointers/new_sptr.c @@ -1,3 +1,4 @@ +#define i_implement #include <stc/cstr.h> typedef struct { cstr name, last; } Person; @@ -8,28 +9,28 @@ int Person_cmp(const Person* a, const Person* b); uint64_t Person_hash(const Person* p); #define i_type PersonArc -#define i_valclass Person // "class" ensure Person_drop will be called -#define i_cmp Person_cmp // enable carc object comparisons (not ptr to obj) -#define i_hash Person_hash // enable carc object hash (not ptr to obj) +#define i_keyclass Person // "class" assume _clone, _drop, _cmp, _hash is defined. +#define i_use_cmp #include <stc/carc.h> #define i_type IPtr -#define i_val int -#define i_valdrop(x) printf("drop: %d\n", *x) -#define i_no_clone +#define i_key int +#define i_keydrop(x) printf("drop: %d\n", *x) +#define i_use_cmp #include <stc/carc.h> #define i_type IPStack -#define i_valboxed IPtr +#define i_keyboxed IPtr #include <stc/cstack.h> #define i_type PASet -#define i_valboxed PersonArc +#define i_keyboxed PersonArc #include <stc/cset.h> Person Person_make(const char* name, const char* last) { - return (Person){.name = cstr_from(name), .last = cstr_from(last)}; + Person p = {.name = cstr_from(name), .last = cstr_from(last)}; + return p; } int Person_cmp(const Person* a, const Person* b) { diff --git a/misc/examples/person_arc.c b/misc/examples/smartpointers/person_arc.c index 620d311f..11040cd2 100644 --- a/misc/examples/person_arc.c +++ b/misc/examples/smartpointers/person_arc.c @@ -1,10 +1,12 @@ /* cbox: heap allocated boxed type */ +#define i_implement #include <stc/cstr.h> typedef struct { cstr name, last; } Person; Person Person_make(const char* name, const char* last) { - return (Person){.name = cstr_from(name), .last = cstr_from(last)}; + Person p = {.name = cstr_from(name), .last = cstr_from(last)}; + return p; } int Person_cmp(const Person* a, const Person* b) { @@ -28,16 +30,17 @@ void Person_drop(Person* p) { } #define i_type PSPtr -#define i_valclass Person // ensure Person_drop -#define i_cmp Person_cmp // specify object cmp, instead of ptr cmp for arc. +#define i_keyclass Person // ensure Person_drop +#define i_use_cmp #include <stc/carc.h> #define i_type Persons -#define i_valboxed PSPtr // binds PSPtr_cmp, PSPtr_drop... +#define i_keyboxed PSPtr // binds PSPtr_cmp, PSPtr_drop... +#define i_use_cmp #include <stc/cvec.h> -int main() +int main(void) { PSPtr p = PSPtr_from(Person_make("Laura", "Palmer")); PSPtr q = PSPtr_from(Person_clone(*p.get)); // deep copy diff --git a/misc/examples/csmap_erase.c b/misc/examples/sortedmaps/csmap_erase.c index 697e6c09..8d4eeae3 100644 --- a/misc/examples/csmap_erase.c +++ b/misc/examples/sortedmaps/csmap_erase.c @@ -1,5 +1,6 @@ // map_erase.c // From C++ example: https://docs.microsoft.com/en-us/cpp/standard-library/map-class?view=msvc-160#example-16 +#define i_implement #include <stc/cstr.h> #include <stdio.h> @@ -15,7 +16,7 @@ void printmap(mymap m) printf("\nsize() == %" c_ZI "\n\n", mymap_size(&m)); } -int main() +int main(void) { mymap m1 = {0}; @@ -34,7 +35,7 @@ int main() printmap(m1); // Fill in some data to test with - mymap m2 = c_make(mymap, { + mymap m2 = c_init(mymap, { {10, "Bob"}, {11, "Rob"}, {12, "Robert"}, diff --git a/misc/examples/csmap_find.c b/misc/examples/sortedmaps/csmap_find.c index c417567a..c392338d 100644 --- a/misc/examples/csmap_find.c +++ b/misc/examples/sortedmaps/csmap_find.c @@ -1,5 +1,6 @@ // This implements the c++ std::map::find example at: // https://docs.microsoft.com/en-us/cpp/standard-library/map-class?view=msvc-160#example-17 +#define i_implement #include <stc/cstr.h> #define i_key int @@ -7,8 +8,7 @@ #define i_tag istr #include <stc/csmap.h> -#define i_val csmap_istr_raw -#define i_opt c_no_cmp +#define i_key csmap_istr_raw #define i_tag istr #include <stc/cvec.h> @@ -40,21 +40,21 @@ void findit(csmap_istr c, csmap_istr_key val) } } -int main() +int main(void) { - csmap_istr m1 = c_make(csmap_istr, {{40, "Zr"}, {45, "Rh"}}); + csmap_istr m1 = c_init(csmap_istr, {{40, "Zr"}, {45, "Rh"}}); cvec_istr v = {0}; puts("The starting map m1 is (key, value):"); print_collection_csmap_istr(&m1); typedef cvec_istr_value pair; - cvec_istr_push(&v, (pair){43, "Tc"}); - cvec_istr_push(&v, (pair){41, "Nb"}); - cvec_istr_push(&v, (pair){46, "Pd"}); - cvec_istr_push(&v, (pair){42, "Mo"}); - cvec_istr_push(&v, (pair){44, "Ru"}); - cvec_istr_push(&v, (pair){44, "Ru"}); // attempt a duplicate + cvec_istr_push(&v, c_LITERAL(pair){43, "Tc"}); + cvec_istr_push(&v, c_LITERAL(pair){41, "Nb"}); + cvec_istr_push(&v, c_LITERAL(pair){46, "Pd"}); + cvec_istr_push(&v, c_LITERAL(pair){42, "Mo"}); + cvec_istr_push(&v, c_LITERAL(pair){44, "Ru"}); + cvec_istr_push(&v, c_LITERAL(pair){44, "Ru"}); // attempt a duplicate puts("Inserting the following vector data into m1:"); print_collection_cvec_istr(&v); diff --git a/misc/examples/csmap_insert.c b/misc/examples/sortedmaps/csmap_insert.c index 3da245c7..04b8ddc6 100644 --- a/misc/examples/csmap_insert.c +++ b/misc/examples/sortedmaps/csmap_insert.c @@ -5,14 +5,14 @@ #define i_tag ii // Map of int => int #include <stc/csmap.h> +#define i_implement #include <stc/cstr.h> #define i_key int #define i_val_str #define i_tag istr // Map of int => cstr #include <stc/csmap.h> -#define i_val csmap_ii_raw -#define i_opt c_no_cmp +#define i_key csmap_ii_raw #define i_tag ii #include <stc/cvec.h> @@ -28,12 +28,12 @@ void print_istr(csmap_istr map) { puts(""); } -int main() +int main(void) { // insert single values csmap_ii m1 = {0}; csmap_ii_insert(&m1, 1, 10); - csmap_ii_push(&m1, (csmap_ii_value){2, 20}); + csmap_ii_push(&m1, c_LITERAL(csmap_ii_value){2, 20}); puts("The original key and mapped values of m1 are:"); print_ii(m1); @@ -60,11 +60,11 @@ int main() csmap_ii m2 = {0}; cvec_ii v = {0}; typedef cvec_ii_value ipair; - cvec_ii_push(&v, (ipair){43, 294}); - cvec_ii_push(&v, (ipair){41, 262}); - cvec_ii_push(&v, (ipair){45, 330}); - cvec_ii_push(&v, (ipair){42, 277}); - cvec_ii_push(&v, (ipair){44, 311}); + cvec_ii_push(&v, c_LITERAL(ipair){43, 294}); + cvec_ii_push(&v, c_LITERAL(ipair){41, 262}); + cvec_ii_push(&v, c_LITERAL(ipair){45, 330}); + cvec_ii_push(&v, c_LITERAL(ipair){42, 277}); + cvec_ii_push(&v, c_LITERAL(ipair){44, 311}); puts("Inserting the following vector data into m2:"); c_foreach (e, cvec_ii, v) @@ -96,7 +96,7 @@ int main() csmap_ii m4 = {0}; // Insert the elements from an initializer_list - m4 = c_make(csmap_ii, {{4, 44}, {2, 22}, {3, 33}, {1, 11}, {5, 55}}); + m4 = c_init(csmap_ii, {{4, 44}, {2, 22}, {3, 33}, {1, 11}, {5, 55}}); puts("After initializer_list insertion, m4 contains:"); print_ii(m4); puts(""); diff --git a/misc/examples/csset_erase.c b/misc/examples/sortedmaps/csset_erase.c index 9fa40682..9c7f5e1a 100644 --- a/misc/examples/csset_erase.c +++ b/misc/examples/sortedmaps/csset_erase.c @@ -3,9 +3,9 @@ #define i_key int #include <stc/csset.h> -int main() +int main(void) { - csset_int set = c_make(csset_int, {30, 20, 80, 40, 60, 90, 10, 70, 50}); + csset_int set = c_init(csset_int, {30, 20, 80, 40, 60, 90, 10, 70, 50}); c_foreach (k, csset_int, set) printf(" %d", *k.ref); @@ -38,4 +38,4 @@ int main() puts(""); csset_int_drop(&set); -}
\ No newline at end of file +} diff --git a/misc/examples/gauss2.c b/misc/examples/sortedmaps/gauss2.c index df709d03..02ce4bc5 100644 --- a/misc/examples/gauss2.c +++ b/misc/examples/sortedmaps/gauss2.c @@ -1,33 +1,34 @@ #include <stdio.h> #include <time.h> -#include <stc/crand.h> +#define i_implement #include <stc/cstr.h> +#include <stc/crand.h> // Declare int -> int sorted map. #define i_key int #define i_val int #include <stc/csmap.h> -int main() +int main(void) { enum {N = 5000000}; uint64_t seed = (uint64_t)time(NULL); crand_t rng = crand_init(seed); - const double Mean = round(crand_f64(&rng)*98.f - 49.f), StdDev = crand_f64(&rng)*10.f + 1.f, Scale = 74.f; + const double Mean = round(crand_f64(&rng)*98.0 - 49.0), StdDev = crand_f64(&rng)*10.0 + 1.0, Scale = 74.0; printf("Demo of gaussian / normal distribution of %d random samples\n", N); printf("Mean %f, StdDev %f\n", Mean, StdDev); // Setup random engine with normal distribution. - crand_norm_t dist = crand_norm_init(Mean, StdDev); + crand_normal_t dist = crand_normal_init(Mean, StdDev); // Create and init histogram map with defered destruct csmap_int hist = {0}; cstr bar = {0}; c_forrange (N) { - int index = (int)round(crand_norm(&rng, &dist)); + int index = (int)round(crand_normal(&rng, &dist)); csmap_int_insert(&hist, index, 0).ref->second += 1; } diff --git a/misc/examples/mmap.c b/misc/examples/sortedmaps/listmap.c index 0394a2df..04a605a7 100644 --- a/misc/examples/mmap.c +++ b/misc/examples/sortedmaps/listmap.c @@ -2,8 +2,9 @@ // https://en.cppreference.com/w/cpp/container/multimap/insert // Multimap entries +#define i_implement #include <stc/cstr.h> -#define i_val_str +#define i_key_str #include <stc/clist.h> // Map of int => clist_str. @@ -29,7 +30,7 @@ void insert(Multimap* mmap, int key, const char* str) clist_str_emplace_back(list, str); } -int main() +int main(void) { Multimap mmap = {0}; diff --git a/misc/examples/mapmap.c b/misc/examples/sortedmaps/mapmap.c index 668da5de..d3065659 100644 --- a/misc/examples/mapmap.c +++ b/misc/examples/sortedmaps/mapmap.c @@ -1,5 +1,5 @@ // create a structure like: std::map<std::string, std::map<std::string, std::string>>: - +#define i_implement #include <stc/cstr.h> // People: std::map<std::string, std::string> diff --git a/misc/examples/multimap.c b/misc/examples/sortedmaps/multimap.c index d8981a81..a4490f91 100644 --- a/misc/examples/multimap.c +++ b/misc/examples/sortedmaps/multimap.c @@ -1,3 +1,4 @@ +#define i_implement #include <stc/cstr.h> // Olympics multimap example @@ -39,7 +40,8 @@ OlympicLoc OlympicLoc_clone(OlympicLoc loc); void OlympicLoc_drop(OlympicLoc* self); // Create a clist<OlympicLoc>, can be sorted by year. -#define i_valclass OlympicLoc // binds _cmp, _clone and _drop. +#define i_keyclass OlympicLoc // binds _cmp, _clone and _drop. +#define i_use_cmp #define i_tag OL #include <stc/clist.h> @@ -65,7 +67,7 @@ void OlympicLoc_drop(OlympicLoc* self) { } -int main() +int main(void) { // Define the multimap with destructor defered to when block is completed. csmap_OL multimap = {0}; diff --git a/misc/examples/new_smap.c b/misc/examples/sortedmaps/new_smap.c index d8245b8b..ee946c9a 100644 --- a/misc/examples/new_smap.c +++ b/misc/examples/sortedmaps/new_smap.c @@ -1,3 +1,4 @@ +#define i_implement #include <stc/cstr.h> #include <stc/forward.h> @@ -10,7 +11,7 @@ typedef struct { } MyStruct; // Point => int map -struct Point { int x, y; } typedef Point; +typedef struct Point { int x, y; } Point; int point_cmp(const Point* a, const Point* b) { int c = a->x - b->x; return c ? c : a->y - b->y; @@ -35,14 +36,14 @@ int point_cmp(const Point* a, const Point* b) { #include <stc/csset.h> -int main() +int main(void) { - PMap pmap = c_make(PMap, { + PMap pmap = c_init(PMap, { {{42, 14}, 1}, {{32, 94}, 2}, {{62, 81}, 3}, }); - SMap smap = c_make(SMap, { + SMap smap = c_init(SMap, { {"Hello, friend", "this is the mapped value"}, {"The brown fox", "jumped"}, {"This is the time", "for all good things"}, diff --git a/misc/examples/sorted_map.c b/misc/examples/sortedmaps/sorted_map.c index ae9b45a4..89381554 100644 --- a/misc/examples/sorted_map.c +++ b/misc/examples/sortedmaps/sorted_map.c @@ -1,11 +1,11 @@ // https://iq.opengenus.org/containers-cpp-stl/ +#include <stdio.h> #define i_key int #define i_val int #include <stc/csmap.h> -#include <stdio.h> -int main() +int main(void) { // empty map containers diff --git a/misc/examples/spans/matmult.c b/misc/examples/spans/matmult.c new file mode 100644 index 00000000..ec992ff9 --- /dev/null +++ b/misc/examples/spans/matmult.c @@ -0,0 +1,90 @@ +// https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2023/p2642r2.html +// C99: +#include <stdio.h> +#include <time.h> +#include <stc/cspan.h> + +using_cspan3(Mat, double); +typedef Mat2 OutMat; +typedef struct { Mat2 m00, m01, m10, m11; } Partition; + +Partition partition(Mat2 A) +{ + int32_t M = A.shape[0]; + int32_t N = A.shape[1]; + return (Partition){ + .m00 = cspan_slice(Mat2, &A, {0, M/2}, {0, N/2}), + .m01 = cspan_slice(Mat2, &A, {0, M/2}, {N/2, N}), + .m10 = cspan_slice(Mat2, &A, {M/2, M}, {0, N/2}), + .m11 = cspan_slice(Mat2, &A, {M/2, M}, {N/2, N}), + }; +} + +// Slow generic implementation +void base_case_matrix_product(Mat2 A, Mat2 B, OutMat C) +{ + for (int j = 0; j < C.shape[1]; ++j) { + for (int i = 0; i < C.shape[0]; ++i) { + Mat2_value C_ij = 0; + for (int k = 0; k < A.shape[1]; ++k) { + C_ij += *cspan_at(&A, i,k) * *cspan_at(&B, k,j); + } + *cspan_at(&C, i,j) += C_ij; + } + } +} + +void recursive_matrix_product(Mat2 A, Mat2 B, OutMat C) +{ + // Some hardware-dependent constant + enum {recursion_threshold = 32}; + if (C.shape[0] <= recursion_threshold || C.shape[1] <= recursion_threshold) { + base_case_matrix_product(A, B, C); + } else { + Partition c = partition(C), + a = partition(A), + b = partition(B); + recursive_matrix_product(a.m00, b.m00, c.m00); + recursive_matrix_product(a.m01, b.m10, c.m00); + recursive_matrix_product(a.m10, b.m00, c.m10); + recursive_matrix_product(a.m11, b.m10, c.m10); + recursive_matrix_product(a.m00, b.m01, c.m01); + recursive_matrix_product(a.m01, b.m11, c.m01); + recursive_matrix_product(a.m10, b.m01, c.m11); + recursive_matrix_product(a.m11, b.m11, c.m11); + } +} + + +#define i_type Values +#define i_val double +#include <stc/cstack.h> +#include <stc/crand.h> + +int main(void) +{ + enum {N = 10, D = 256}; + + Values values = {0}; + for (int i=0; i < N*D*D; ++i) + Values_push(&values, (crandf() - 0.5)*4.0); + + double out[D*D]; + Mat3 data = cspan_md_layout(c_ROWMAJOR, values.data, N, D, D); + OutMat c = cspan_md_layout(c_COLMAJOR, out, D, D); + Mat2 a = cspan_submd3(&data, 0); + + clock_t t = clock(); + for (int i=1; i<N; ++i) { + Mat2 b = cspan_submd3(&data, i); + memset(out, 0, sizeof out); + recursive_matrix_product(a, b, c); + //base_case_matrix_product(a, b, c); + } + t = clock() - t; + + double sum = 0.0; + c_foreach (i, Mat2, c) sum += *i.ref; + printf("sum=%.16g, %f ms\n", sum, (double)t*1000.0/CLOCKS_PER_SEC); + Values_drop(&values); +} diff --git a/misc/examples/spans/mdspan.c b/misc/examples/spans/mdspan.c new file mode 100644 index 00000000..630ffddb --- /dev/null +++ b/misc/examples/spans/mdspan.c @@ -0,0 +1,51 @@ +#include <stdio.h> +#include <stc/cspan.h> +#include <stdlib.h> + +using_cspan3(DSpan, double); + +int main(void) { + const int nx=5, ny=4, nz=3; + double* data = c_new_n(double, nx*ny*nz); + + printf("\nMultidim span ms[5, 4, 3], fortran ordered"); + DSpan3 ms = cspan_md_layout(c_COLMAJOR, data, nx, ny, nz); + + int idx = 0; + for (int i = 0; i < ms.shape[0]; ++i) + for (int j = 0; j < ms.shape[1]; ++j) + for (int k = 0; k < ms.shape[2]; ++k) + *cspan_at(&ms, i, j, k) = ++idx; + + cspan_transpose(&ms); + + printf(", transposed:\n\n"); + for (int i = 0; i < ms.shape[0]; ++i) { + for (int j = 0; j < ms.shape[1]; ++j) { + for (int k = 0; k < ms.shape[2]; ++k) + printf(" %3g", *cspan_at(&ms, i, j, k)); + puts(""); + } + puts(""); + } + + DSpan2 sub; + + puts("Slicing:"); + printf("\nms[0, :, :] "); + sub = cspan_slice(DSpan2, &ms, {0}, {c_ALL}, {c_ALL}); + c_foreach (i, DSpan2, sub) printf(" %g", *i.ref); + puts(""); + + printf("\nms[:, 0, :] "); + sub = cspan_slice(DSpan2, &ms, {c_ALL}, {0}, {c_ALL}); + c_foreach (i, DSpan2, sub) printf(" %g", *i.ref); + puts(""); + + sub = cspan_slice(DSpan2, &ms, {c_ALL}, {c_ALL}, {0}); + printf("\nms[:, :, 0] "); + c_foreach (i, DSpan2, sub) printf(" %g", *i.ref); + puts(""); + + free(data); +} diff --git a/misc/examples/spans/multidim.c b/misc/examples/spans/multidim.c new file mode 100644 index 00000000..70fda7e2 --- /dev/null +++ b/misc/examples/spans/multidim.c @@ -0,0 +1,76 @@ +// Example based on https://en.cppreference.com/w/cpp/container/mdspan +#define i_val int +#include <stc/cstack.h> +#define i_implement +#include <stc/cspan.h> +#include <stdio.h> + +using_cspan3(ispan, int); + +void print2d(ispan2 ms2) { + for (int i=0; i < ms2.shape[0]; i++) { + for (int j=0; j < ms2.shape[1]; j++) + printf(" %3d", *cspan_at(&ms2, i, j)); + puts(""); + } +} + +void print3d(ispan3 ms3) { + for (int i=0; i < ms3.shape[0]; i++) { + for (int j=0; j < ms3.shape[1]; j++) { + for (int k=0; k < ms3.shape[2]; k++) + printf(" %3d", *cspan_at(&ms3, i, j, k)); + puts(""); + } + puts(""); + } +} + +int main(void) +{ + cstack_int v = c_init(cstack_int, {1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24}); + + // Create 1d span from a compatibel container + ispan ms1 = cspan_from(&v); + + // Create a 3D mdspan 2 x 3 x 4 + ispan3 ms3 = cspan_md(v.data, 2, 3, 4); + + puts("ms3:"); + print3d(ms3); + + // Take a slice of md3 + ispan3 ss3 = cspan_slice(ispan3, &ms3, {c_ALL}, {1,3}, {1,3}); + puts("ss3 = ms3[:, 1:3, 1:3]"); + print3d(ss3); + + puts("Iterate ss3 flat:"); + c_foreach (i, ispan3, ss3) printf(" %d", *i.ref); + puts(""); + + // submd3 span reduces rank depending on number of arguments + ispan2 ms2 = cspan_submd3(&ms3, 1); + + // Change data on the 2d subspan + for (int i=0; i != ms2.shape[0]; i++) + for (int j=0; j != ms2.shape[1]; j++) + *cspan_at(&ms2, i, j) = (i + 1)*100 + j; + + puts("\nms2 = ms3[1] with updated data:"); + print2d(ms2); + puts(""); + + puts("\nOriginal s1 span with updated data:"); + c_foreach (i, ispan, ms1) printf(" %d", *i.ref); + puts(""); + + puts("\nOriginal ms3 span with updated data:"); + print3d(ms3); + + puts("col = ms3[1, :, 2]"); + ispan col = cspan_slice(ispan, &ms3, {1}, {c_ALL}, {2}); + c_foreach (i, ispan, col) printf(" %d", *i.ref); + puts(""); + + cstack_int_drop(&v); +} diff --git a/misc/examples/spans/printspan.c b/misc/examples/spans/printspan.c new file mode 100644 index 00000000..b6999b61 --- /dev/null +++ b/misc/examples/spans/printspan.c @@ -0,0 +1,41 @@ +// https://www.modernescpp.com/index.php/c-20-std-span/ + +#include <stdio.h> +#define i_key int +#include <stc/cvec.h> + +#define i_key int +#include <stc/cstack.h> + +#include <stc/cspan.h> +using_cspan(intspan, int); + + +void printMe(intspan container) { + printf("%d:", (int)cspan_size(&container)); + c_foreach (e, intspan, container) + printf(" %d", *e.ref); + puts(""); +} + + +int main(void) +{ + printMe( c_init(intspan, {1, 2, 3, 4}) ); + + int arr[] = {1, 2, 3, 4, 5}; + printMe( (intspan)cspan_from_array(arr) ); + + cvec_int vec = c_init(cvec_int, {1, 2, 3, 4, 5, 6}); + printMe( (intspan)cspan_from(&vec) ); + + cstack_int stk = c_init(cstack_int, {1, 2, 3, 4, 5, 6, 7}); + printMe( (intspan)cspan_from(&stk) ); + + intspan spn = c_init(intspan, {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12}); + printMe( (intspan)cspan_subspan(&spn, 2, 8) ); + + // cleanup + cvec_int_drop(&vec); + cstack_int_drop(&stk); +} diff --git a/misc/examples/spans/submdspan.c b/misc/examples/spans/submdspan.c new file mode 100644 index 00000000..0752dfa1 --- /dev/null +++ b/misc/examples/spans/submdspan.c @@ -0,0 +1,44 @@ +// https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2022/p2630r0.html +// C99: +#include <stdio.h> +#include <stc/cspan.h> + +using_cspan3(span, double); // shorthand for defining span, span2, span3 + +// Set all elements of a rank-2 mdspan to zero. +void zero_2d(span2 grid2d) { + (void)c_static_assert(cspan_rank(&grid2d) == 2); + for (int i = 0; i < grid2d.shape[0]; ++i) { + for (int j = 0; j < grid2d.shape[1]; ++j) { + *cspan_at(&grid2d, i,j) = 0; + } + } +} + +void zero_surface(span3 grid3d) { + (void)c_static_assert(cspan_rank(&grid3d) == 3); + zero_2d(cspan_slice(span2, &grid3d, {0}, {c_ALL}, {c_ALL})); + zero_2d(cspan_slice(span2, &grid3d, {c_ALL}, {0}, {c_ALL})); + zero_2d(cspan_slice(span2, &grid3d, {c_ALL}, {c_ALL}, {0})); + zero_2d(cspan_slice(span2, &grid3d, {grid3d.shape[0]-1}, {c_ALL}, {c_ALL})); + zero_2d(cspan_slice(span2, &grid3d, {c_ALL}, {grid3d.shape[1]-1}, {c_ALL})); + zero_2d(cspan_slice(span2, &grid3d, {c_ALL}, {c_ALL}, {grid3d.shape[2]-1})); +} + +int main() { + double arr[3*4*5]; + for (int i=0; i<c_arraylen(arr); ++i) arr[i] = i + 1.0; + + span3 md = cspan_md(arr, 3, 4, 5); + + zero_surface(md); + + for (int i = 0; i < md.shape[0]; i++) { + for (int j = 0; j < md.shape[1]; j++) { + for (int k = 0; k < md.shape[2]; k++) + printf(" %2g", *cspan_at(&md, i,j,k)); + puts(""); + } + puts(""); + } +} diff --git a/misc/examples/cstr_match.c b/misc/examples/strings/cstr_match.c index 58cf8884..80013019 100644 --- a/misc/examples/cstr_match.c +++ b/misc/examples/strings/cstr_match.c @@ -1,10 +1,11 @@ +#define i_implement #include <stc/cstr.h> #include <stc/csview.h> #include <stdio.h> -int main() +int main(void) { - cstr ss = cstr_lit("The quick brown fox jumps over the lazy dog.JPG"); + cstr ss = cstr_from("The quick brown fox jumps over the lazy dog.JPG"); intptr_t pos = cstr_find_at(&ss, 0, "brown"); printf("%" c_ZI " [%s]\n", pos, pos == c_NPOS ? "<NULL>" : cstr_str(&ss) + pos); diff --git a/misc/examples/replace.c b/misc/examples/strings/replace.c index cf5b45cb..59a56bf7 100644 --- a/misc/examples/replace.c +++ b/misc/examples/strings/replace.c @@ -1,6 +1,7 @@ +#define i_implement #include <stc/cstr.h> -int main () +int main(void) { const char *base = "this is a test string."; const char *s2 = "n example"; diff --git a/misc/examples/splitstr.c b/misc/examples/strings/splitstr.c index 2bc6fc07..ef7ed174 100644 --- a/misc/examples/splitstr.c +++ b/misc/examples/strings/splitstr.c @@ -1,9 +1,10 @@ #include <stdio.h> -#define i_extern // cstr + utf8 functions +#define i_import // cstr + utf8 functions #include <stc/cregex.h> +#define i_implement #include <stc/csview.h> -int main() +int main(void) { puts("Split with c_fortoken (csview):"); diff --git a/misc/examples/sso_map.c b/misc/examples/strings/sso_map.c index 70450e21..4f84b651 100644 --- a/misc/examples/sso_map.c +++ b/misc/examples/strings/sso_map.c @@ -1,9 +1,10 @@ +#define i_implement #include <stc/cstr.h> #define i_key_str #define i_val_str #include <stc/cmap.h> -int main() +int main(void) { cmap_str m = {0}; cmap_str_emplace(&m, "Test short", "This is a short string"); diff --git a/misc/examples/sso_substr.c b/misc/examples/strings/sso_substr.c index 4b2dbcc8..70d34440 100644 --- a/misc/examples/sso_substr.c +++ b/misc/examples/strings/sso_substr.c @@ -1,18 +1,20 @@ +#define i_implement #include <stc/cstr.h> +#define i_implement #include <stc/csview.h> -int main () +int main(void) { - cstr str = cstr_lit("We think in generalities, but we live in details."); + cstr str = cstr_from("We think in generalities, but we live in details."); csview sv1 = cstr_substr_ex(&str, 3, 5); // "think" - intptr_t pos = cstr_find(&str, "live"); // position of "live" + intptr_t pos = cstr_find(&str, "live"); // position of "live" csview sv2 = cstr_substr_ex(&str, pos, 4); // "live" csview sv3 = cstr_slice_ex(&str, -8, -1); // "details" printf("%.*s, %.*s, %.*s\n", c_SV(sv1), c_SV(sv2), c_SV(sv3)); cstr_assign(&str, "apples are green or red"); - cstr s2 = cstr_from_sv(cstr_substr_ex(&str, -3, 3)); // "red" - cstr s3 = cstr_from_sv(cstr_substr_ex(&str, 0, 6)); // "apples" + cstr s2 = cstr_from_sv(cstr_substr_ex(&str, -3, 3)); // "red" + cstr s3 = cstr_from_sv(cstr_substr_ex(&str, 0, 6)); // "apples" printf("%s %s: %d, %d\n", cstr_str(&s2), cstr_str(&s3), cstr_is_long(&str), cstr_is_long(&s2)); c_drop (cstr, &str, &s2, &s3); diff --git a/misc/examples/sview_split.c b/misc/examples/strings/sview_split.c index 31a28e51..ac275da0 100644 --- a/misc/examples/sview_split.c +++ b/misc/examples/strings/sview_split.c @@ -1,7 +1,9 @@ +#define i_implement #include <stc/cstr.h> +#define i_implement #include <stc/csview.h> -int main() +int main(void) { // No memory allocations or string length calculations! const csview date = c_sv("2021/03/12"); diff --git a/misc/examples/utf8replace_c.c b/misc/examples/strings/utf8replace_c.c index 3cde8701..317313b0 100644 --- a/misc/examples/utf8replace_c.c +++ b/misc/examples/strings/utf8replace_c.c @@ -1,6 +1,7 @@ +#define i_implement #include <stc/cstr.h> -int main() +int main(void) { cstr hello = cstr_lit("hell😀 w😀rld"); printf("%s\n", cstr_str(&hello)); @@ -14,7 +15,7 @@ int main() printf("%s\n", cstr_str(&hello)); c_foreach (c, cstr, hello) - printf("%.*s,", c_SV(c.u8.chr)); + printf("%.*s,", c_SV(c.chr)); cstr str = cstr_lit("scooby, dooby doo"); cstr_replace(&str, "oo", "00"); diff --git a/misc/examples/utf8replace_rs.rs b/misc/examples/strings/utf8replace_rs.rs index 8b163b4e..8b163b4e 100644 --- a/misc/examples/utf8replace_rs.rs +++ b/misc/examples/strings/utf8replace_rs.rs diff --git a/misc/examples/triples.c b/misc/examples/triples.c deleted file mode 100644 index 520bf012..00000000 --- a/misc/examples/triples.c +++ /dev/null @@ -1,69 +0,0 @@ -// https://quuxplusone.github.io/blog/2019/03/06/pythagorean-triples/ - -#include <stc/algo/coroutine.h> -#include <stdio.h> - -void triples_vanilla(int n) { - for (int c = 5; n; ++c) { - for (int a = 1; a < c; ++a) { - for (int b = a + 1; b < c; ++b) { - if ((int64_t)a*a + (int64_t)b*b == (int64_t)c*c) { - printf("{%d, %d, %d}\n", a, b, c); - if (--n == 0) goto done; - } - } - } - } - done:; -} - -struct triples { - int n; - int a, b, c; - int cco_state; -}; - -bool triples_next(struct triples* I) { - cco_begin(I); - for (I->c = 5; I->n; ++I->c) { - for (I->a = 1; I->a < I->c; ++I->a) { - for (I->b = I->a + 1; I->b < I->c; ++I->b) { - if ((int64_t)I->a*I->a + (int64_t)I->b*I->b == (int64_t)I->c*I->c) { - cco_yield(true); - if (--I->n == 0) cco_return; - } - } - } - } - cco_final: - puts("done"); - cco_end(false); -} - -int gcd(int a, int b) { - while (b) { - int t = a % b; - a = b; - b = t; - } - return a; -} - -int main() -{ - puts("Vanilla triples:"); - triples_vanilla(6); - - puts("\nCoroutine triples:"); - struct triples t = {INT32_MAX}; - int n = 0; - - while (triples_next(&t)) { - if (gcd(t.a, t.b) > 1) - continue; - if (t.c < 100) - printf("%d: {%d, %d, %d}\n", ++n, t.a, t.b, t.c); - else - cco_stop(&t); - } -} diff --git a/misc/examples/lower_bound.c b/misc/examples/vectors/lower_bound.c index 6ec7544c..09cf2008 100644 --- a/misc/examples/lower_bound.c +++ b/misc/examples/vectors/lower_bound.c @@ -1,17 +1,18 @@ #include <stdio.h> -#define i_val int +#define i_key int +#define i_use_cmp #include <stc/cvec.h> -#define i_val int +#define i_key int #include <stc/csset.h> -int main() +int main(void) { // TEST SORTED VECTOR { int key, *res; - cvec_int vec = c_make(cvec_int, {40, 600, 1, 7000, 2, 500, 30}); + cvec_int vec = c_init(cvec_int, {40, 600, 1, 7000, 2, 500, 30}); cvec_int_sort(&vec); @@ -40,7 +41,7 @@ int main() // TEST SORTED SET { int key, *res; - csset_int set = c_make(csset_int, {40, 600, 1, 7000, 2, 500, 30}); + csset_int set = c_init(csset_int, {40, 600, 1, 7000, 2, 500, 30}); key = 100; res = csset_int_lower_bound(&set, key).ref; diff --git a/misc/examples/new_vec.c b/misc/examples/vectors/new_vec.c index df443b7f..88efd55a 100644 --- a/misc/examples/new_vec.c +++ b/misc/examples/vectors/new_vec.c @@ -4,32 +4,33 @@ forward_cvec(cvec_i32, int); forward_cvec(cvec_pnt, struct Point); -struct MyStruct { +typedef struct MyStruct { cvec_i32 intvec; cvec_pnt pntvec; -} typedef MyStruct; +} MyStruct; -#define i_val int -#define i_is_forward +#define i_key int #define i_tag i32 +#define i_is_forward #include <stc/cvec.h> typedef struct Point { int x, y; } Point; -#define i_val Point +#define i_key Point +#define i_tag pnt #define i_less(a, b) a->x < b->x || (a->x == b->x && a->y < b->y) +#define i_eq(a, b) a->x == b->x && a->y == b->y #define i_is_forward -#define i_tag pnt #include <stc/cvec.h> -int main() +int main(void) { MyStruct my = {0}; - cvec_pnt_push(&my.pntvec, (Point){42, 14}); - cvec_pnt_push(&my.pntvec, (Point){32, 94}); - cvec_pnt_push(&my.pntvec, (Point){62, 81}); - cvec_pnt_push(&my.pntvec, (Point){32, 91}); + cvec_pnt_push(&my.pntvec, c_LITERAL(Point){42, 14}); + cvec_pnt_push(&my.pntvec, c_LITERAL(Point){32, 94}); + cvec_pnt_push(&my.pntvec, c_LITERAL(Point){62, 81}); + cvec_pnt_push(&my.pntvec, c_LITERAL(Point){32, 91}); cvec_pnt_sort(&my.pntvec); diff --git a/misc/examples/stack.c b/misc/examples/vectors/stack.c index c817e1ae..6297fb6f 100644 --- a/misc/examples/stack.c +++ b/misc/examples/vectors/stack.c @@ -3,14 +3,14 @@ #define i_tag i #define i_capacity 100 -#define i_val int +#define i_key int #include <stc/cstack.h> #define i_tag c -#define i_val char +#define i_key char #include <stc/cstack.h> -int main() { +int main(void) { cstack_i stack = {0}; cstack_c chars = {0}; |
