summaryrefslogtreecommitdiffhomepage
path: root/misc/examples
diff options
context:
space:
mode:
author_Tradam <[email protected]>2023-09-08 01:29:47 +0000
committerGitHub <[email protected]>2023-09-08 01:29:47 +0000
commit3c76c7f3d5db3f9586a90d03f8fbb02d79de9acd (patch)
treeafbe4b540967223911f7c5de36559b82154f02f3 /misc/examples
parent0841165881871ee01b782129be681209aeed2423 (diff)
parent1a72205fe05c2375cfd380dd8381a8460d9ed8d1 (diff)
downloadSTC-modified-3c76c7f3d5db3f9586a90d03f8fbb02d79de9acd.tar.gz
STC-modified-3c76c7f3d5db3f9586a90d03f8fbb02d79de9acd.zip
Merge branch 'stclib:master' into modifiedHEADmodified
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.c42
-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.c39
-rw-r--r--misc/examples/coroutines.c106
-rw-r--r--misc/examples/coroutines/cointerleave.c62
-rw-r--r--misc/examples/coroutines/coread.c41
-rw-r--r--misc/examples/coroutines/coroutines.c112
-rw-r--r--misc/examples/coroutines/cotasks1.c100
-rw-r--r--misc/examples/coroutines/cotasks2.c98
-rw-r--r--misc/examples/coroutines/dining_philosophers.c105
-rw-r--r--misc/examples/coroutines/filetask.c80
-rw-r--r--misc/examples/coroutines/generator.c66
-rw-r--r--misc/examples/coroutines/scheduler.c67
-rw-r--r--misc/examples/coroutines/triples.c75
-rw-r--r--misc/examples/generator.c53
-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.c70
-rwxr-xr-xmisc/examples/make.sh37
-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.c68
-rw-r--r--misc/examples/new_list.c68
-rw-r--r--misc/examples/printspan.c57
-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.c45
-rw-r--r--misc/examples/rawptr_elements.c59
-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.cpp57
-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.c34
-rw-r--r--misc/examples/smartpointers/map_ptr.c34
-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.c90
-rw-r--r--misc/examples/spans/mdspan.c51
-rw-r--r--misc/examples/spans/multidim.c76
-rw-r--r--misc/examples/spans/printspan.c41
-rw-r--r--misc/examples/spans/submdspan.c44
-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.c69
-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(&copy.get); IPQue_pop(&copy.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};